/* campaign boards: kanban columns, cards, drag states, tap-to-move.
   Compend rules: sharp corners everywhere, solid colors only, flat
   fills, no see-through, no blur, no glow, no drop shade. Green is
   the only accent, for the drag target and the select status. */
#campaignView .wbkanban {
  display: grid;
  grid-template-columns: repeat(3, minmax(220px, 1fr));
  gap: 12px;
  margin: 8px 0 22px;
  align-items: start;
  overflow-x: auto;
}
#campaignView .wbcol {
  border: 1px solid #0d0d0d;
  background: #fff;
  min-width: 0;
}
#campaignView .wbcol.wbdrop {
  border-color: var(--cp-green);
  background: #f2f7f2;
}
#campaignView .wbcolhead {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: #737373;
  margin: 0;
  padding: 8px 10px;
  border-bottom: 1px solid #0d0d0d;
}
#campaignView .wbcolbody {
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
#campaignView .wbempty {
  color: #737373;
  font-size: 13px;
  margin: 4px 2px;
}
#campaignView .wbcard {
  border: 1px solid var(--cp-rule);
  background: #fff;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
#campaignView .wbcard[draggable="true"] {
  cursor: grab;
}
#campaignView .wbcard.wbdragging {
  border-color: var(--cp-green);
}
#campaignView .wbtop {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}
#campaignView .wbface {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #f2f0ef;
  overflow: hidden;
  flex: none;
  vertical-align: middle;
}
#campaignView .wbface .ini {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #555;
}
#campaignView .wbface img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
#campaignView .wbnamewrap {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}
#campaignView .wbname {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: break-word;
}
#campaignView .wbhandle {
  font-size: 13px;
  color: #737373;
}
#campaignView .wbresptext,
#campaignView .wbcalltext,
#campaignView .wbconcept,
#campaignView .wbmeta,
#campaignView .wbnotes {
  font-size: 14px;
  line-height: 1.5;
  overflow-wrap: break-word;
}
#campaignView .wbmeta,
#campaignView .wbnotes,
#campaignView .wbday {
  color: #737373;
  font-size: 13px;
}
#campaignView .wbday {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: 11px;
}
#campaignView .wbthumb {
  width: 100%;
  max-height: 180px;
  object-fit: cover;
  display: block;
}
/* short values in cards and rows read as text with a hairline under
   them, not as boxed form fields: edit-by-default should read as
   text, and only the long prose fields get a solid box. */
#campaignView .wbcard input,
#campaignView .wbcard textarea,
#campaignView .wbcoladd input,
#campaignView .wbrow input,
#campaignView .wblook input,
#campaignView .wblook textarea {
  font-family: var(--cp-sans);
  font-size: 14px;
  color: var(--cp-ink);
  background: transparent;
  border: none;
  border-bottom: 1px solid #bbb;
  border-radius: 0;
  padding: 4px 0;
  width: 100%;
  box-sizing: border-box;
}
/* shot concept and notes are long text: growing textareas, no box. */
#campaignView .wbshotconcept { font-size: 15px; line-height: 1.5; }
#campaignView .wbshotnotes { font-size: 13px; line-height: 1.5; color: #737373; }
#campaignView .wbshotconcept, #campaignView .wbshotnotes, #campaignView textarea.wbeventtitle { resize: none; overflow: hidden; }
/* format and product share one quiet row; the image link is a small
   grey line, not a field. */
#campaignView .wbshotmeta { display: flex; gap: 10px; }
#campaignView .wbshotmeta input { flex: 1; min-width: 0; }
#campaignView .wbshotsample { font-size: 13px; color: #737373; }
#campaignView .wbshotday { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: #737373; }
#campaignView .wbcardfoot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
#campaignView .wbcardfoot .wbmove {
  margin-left: auto;
  font-size: 13px;
  color: #737373;
}
#campaignView .wbmove .wbmovelabel {
  color: #737373;
}
#campaignView .wbmoveopt {
  border: none;
  background: transparent;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 13px;
  color: var(--cp-ink);
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}
#campaignView .wbvote,
#campaignView .wbremove,
#campaignView .wbupload,
#campaignView .wbshotupload,
#campaignView .wbadd,
#campaignView .wbfind {
  border: none;
  background: transparent;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 14px;
  color: var(--cp-ink);
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}
#campaignView .wbremove {
  color: #999;
  text-decoration: none;
  font-size: 16px;
  line-height: 1;
}
#campaignView .wbvotes {
  font-size: 13px;
  color: #737373;
}
#campaignView .wbstat {
  font-size: 13px;
  color: #737373;
}
#campaignView .wbstat.select,
#campaignView .wbstat.done {
  color: var(--cp-green);
}
#campaignView .wbcoladd {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  padding: 8px 10px;
  border-top: 1px solid var(--cp-rule);
}
#campaignView .wbcoladd .wbfindlabel {
  font-size: 13px;
  color: #737373;
}
#campaignView .wbcoladd input {
  flex: 1;
  min-width: 0;
}
#campaignView .wbadd {
  margin: 0 0 22px;
}
#campaignView .wbrows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0 12px;
}
#campaignView .wbrow {
  display: flex;
  gap: 8px;
  align-items: center;
}
#campaignView .wbrow input {
  flex: 1;
  min-width: 0;
}
#campaignView .wbline {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid #f2f0ef;
  font-size: 14px;
  overflow-wrap: break-word;
}
#campaignView .wbline .wbnote {
  color: #737373;
  font-size: 13px;
}
#campaignView .wbline .wbthumb {
  width: 48px;
  height: 48px;
  max-height: 48px;
  flex: none;
}
#campaignView .wbline a {
  color: var(--cp-ink);
  overflow-wrap: break-word;
}
/* costs as rows, not a text box: label, amount, remove. The total
   sits under the same columns, behind a rule. */
#campaignView .wbrow .wbcostlabel { flex: 1; min-width: 0; }
#campaignView .wbrow input.wbcostamount { flex: none; width: 110px; text-align: right; }
#campaignView .wbrow .wbcostamount { flex: none; width: 110px; text-align: right; }
#campaignView .wbcosttotal { border-top: 1px solid #0d0d0d; padding-top: 8px; margin-top: 4px; font-weight: 700; }
#campaignView .wblooks {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  margin: 8px 0 12px;
}
#campaignView .wblook {
  position: relative;
  min-width: 0;
}
#campaignView .wblookphoto {
  width: 100%;
  height: auto;
  display: block;
}
/* the one control on a look in the feed: a small solid white square
   with a black x, top right over the photo. */
#campaignView .wblookx {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  background: #fff;
  color: #0d0d0d;
  border: none;
  border-radius: 0;
  font-size: 18px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}
#campaignView .wblookempty {
  color: #737373;
  font-size: 14px;
}
#campaignView .wblook textarea {
  resize: none;
  overflow: hidden;
}
/* team, by role: one section per role, cards in a grid that fits
   as many 240px cards as the width allows. Sections after the first
   sit under a hairline, so the roster reads as even groups. */
#campaignView .wbrole {
  margin: 0 0 14px;
}
#campaignView .wbrole + .wbrole {
  border-top: 1px solid #f2f0ef;
  padding-top: 12px;
}
#campaignView .wbrolehead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0 0 8px;
  padding: 0;
}
#campaignView .wbrolehead h3 {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--cp-mute);
  margin: 0;
  padding: 0;
}
#campaignView .wbrolebody {
  display: block;
  margin: 0 0 4px;
}
/* a team card is two rows: face and first name, then a foot with
   the status links and the vote. The face is larger than the 36px
   used elsewhere, so the person leads the card, not the controls. */
/* no box per person: a member is a plain row, and a dashed line
   separates consecutive members of the same role. */
#campaignView .wbteam { border: none; padding: 12px 0; gap: 6px; }
#campaignView .wbteam + .wbteam { border-top: 1px dashed var(--cp-rule); }
#campaignView .wbteam .wbface { width: 44px; height: 44px; }
#campaignView .wbteam .wbface .ini { font-size: 13px; }
#campaignView .wbrespline { display: flex; gap: 10px; align-items: baseline; }
#campaignView .wbrespline .wbresp { flex: 1; min-width: 0; }
#campaignView .wbrespline .wbresptext { flex: 1; min-width: 0; }
#campaignView .wbrespline .wbcall { width: 92px; flex: none; }
#campaignView .wbrespline .wbcalltext { color: #737373; flex: none; }
#campaignView .wbteam .wbcardfoot .wbvote,
#campaignView .wbteam .wbcardfoot .wbvotes { margin-left: auto; }
#campaignView .wbteam .wbvote { text-decoration: none; color: #737373; }
/* team reel: one scrolling row of a teammate's images under their
   card. Same width only: every image is the same width and keeps
   its own height, nothing cropped, the row breathes. */
#campaignView .wbteamreel {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  overflow-x: auto;
  margin-top: 2px;
  padding-bottom: 2px;
}
#campaignView .wbteamreelimg {
  width: 96px;
  flex: none;
  height: auto;
  display: block;
  cursor: zoom-in;
  background: #e5e2df;
}
/* status links on a card: plain text, active bold and underlined. */
#campaignView .wbstatlinks {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13px;
  color: #737373;
}
/* phone: a team card is one row, face and first name on the left,
   status and vote on the right. Stacked, the full-width card leaves
   its right two-thirds empty. */
@media (max-width: 759px) {
  #campaignView .wbteam { flex-direction: row; align-items: center; flex-wrap: wrap; }
  #campaignView .wbteam .wbcardfoot { margin-left: auto; }
  /* the reel drops to its own line under the face and foot. */
  #campaignView .wbteamreel { flex-basis: 100%; }
}
#campaignView .wbstatlinks button {
  border: none;
  background: transparent;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 13px;
  color: #555;
  padding: 0;
  cursor: pointer;
}
#campaignView .wbstatlinks button.on {
  color: var(--cp-ink);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* shots, visual: one column by default, two on wide desktop. */
#campaignView .wbshotgrid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  margin: 8px 0 22px;
}
#campaignView .wbshot {
  border: none;
  background: transparent;
  padding: 0;
}
#campaignView .wbshotimg {
  width: 100%;
  height: auto;
  display: block;
}
#campaignView .wbshotempty {
  color: #737373;
  font-size: 14px;
}
/* a shot with no image yet: the whole image area is the upload
   target, a large framed drop zone, not a grey line. It is the same
   upload button as the foot control, so the existing wiring applies. */
#campaignView .wbshotdrop {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 180px;
  width: 100%;
  border: 1px solid #0d0d0d;
  background: #fff;
  text-decoration: none;
  font-size: 15px;
  color: #737373;
  cursor: pointer;
}
#campaignView .wbrefstrip {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
#campaignView .wbaddnote {
  border: none;
  background: transparent;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 13px;
  color: #737373;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 4px 0;
  cursor: pointer;
  text-align: left;
}
#campaignView .wbrefstrip img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  display: block;
}
#campaignView .wbshot.wbdrop {
  border-color: var(--cp-green);
}
/* timeline: a real designed timeline, not a form list. Dates sit in
   a fixed right-aligned column, a vertical ink rule runs down the
   gap between date and content, and each event carries a small
   square tick on the rule. Titles are the entry; time, link, and the
   deadline marker sit quiet underneath. On phone the rule and ticks
   go away and the date stacks above its entry. */
/* timeline as a plain list: one line per event, date and title
   inline, no rule, no ticks, no date column. Reads the same on
   phone and desktop. */
#campaignView .wbevents { margin: 8px 0 22px; }
#campaignView .wbevent {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid #f2f0ef;
  flex-wrap: wrap;
}
#campaignView .wbeventdate {
  font-size: 13px;
  font-weight: 700;
  color: var(--cp-ink);
  white-space: nowrap;
  flex: none;
}
#campaignView .wbeventtitle {
  font-size: 15px;
  line-height: 1.5;
  overflow-wrap: break-word;
  min-width: 0;
  flex: 1;
}
#campaignView .wbevent input,
#campaignView .wbeventadd input {
  font-family: var(--cp-sans);
  font-size: 14px;
  color: var(--cp-ink);
  background: transparent;
  border: none;
  border-bottom: 1px solid #bbb;
  border-radius: 0;
  padding: 2px 0;
  box-sizing: border-box;
}
#campaignView input.wbeventdate { width: 140px; flex: none; border: none; border-bottom: 1px solid #bbb; background: transparent; padding: 2px 0; font-weight: 700; }
#campaignView textarea.wbeventtitle {
  flex: 1;
  min-width: 120px;
  font-size: 15px;
  line-height: 1.5;
  border: none;
  border-bottom: 1px solid #bbb;
  background: transparent;
  padding: 2px 0;
  border-radius: 0;
}
#campaignView .wbeventdeadline {
  border: none;
  background: transparent;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 13px;
  color: #555;
  padding: 0;
  cursor: pointer;
  flex: none;
}
#campaignView .wbeventdeadline.on {
  color: var(--cp-green);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}
#campaignView .wbeventadd {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin: 10px 0 22px;
}
#campaignView .wbeventadd #wbEventDate { width: 140px; }
#campaignView .wbeventadd #wbEventTitle { flex: 1; min-width: 120px; }
/* location photo on the brief page: one image, next to the text. */
#campaignView .wblocphoto {
  width: 100%;
  height: auto;
  display: block;
  margin: 8px 0;
  aspect-ratio: 1.4;
  background: #e5e2df;
}
/* no location photo yet: a large framed area in the location block,
   the same upload control as the small button, so the wiring applies. */
#campaignView .wblocempty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  width: 100%;
  border: 1px solid #0d0d0d;
  background: #fff;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 15px;
  color: #737373;
  cursor: pointer;
  margin: 8px 0;
}
/* wardrobe row thumbs: one small photo per item. */
#campaignView .wbrow .wbthumb {
  width: 48px;
  height: 48px;
  max-height: 48px;
  object-fit: cover;
  flex: none;
}
/* styling photos are the upload affordance: tap a photo to change
   it. An item with no photo yet gets a framed clickable placeholder
   instead, same pattern as the location photo area. */
#campaignView .wbthumb[data-kind],
#campaignView .wblookphoto { cursor: pointer; }
#campaignView .wbphotoempty {
  border: 1px solid #0d0d0d;
  background: #fff;
  border-radius: 0;
  font-family: var(--cp-sans);
  font-size: 14px;
  color: #737373;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
#campaignView .wbrow .wbphotoempty {
  width: 48px;
  height: 48px;
  min-height: 48px;
  flex: none;
}
#campaignView .wblook .wbphotoempty {
  width: 100%;
  min-height: 120px;
}
@media (min-width: 1000px) {
  #campaignView .wbshotgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
/* ---- desktop layout: the photo grids get more columns; the content
   frame (compend.css, .campdetail) caps the width. Phone stacks. ---- */
@media (min-width: 1000px) {
  /* location: photos in two columns. */
  #campaignView .wblocphotos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin: 8px 0 12px;
  }
  #campaignView .wblocphotos .wblocphoto { margin: 0; }
  /* styling: looks as a four-column contact sheet. */
  #campaignView .wblooks {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  /* shoot: three shots across, contact-sheet frames. */
  #campaignView .wbshotgrid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 700px) {
  #campaignView .wbkanban {
    grid-template-columns: minmax(0, 1fr);
  }
  #campaignView .wblooks {
    grid-template-columns: minmax(0, 1fr);
  }
  #campaignView .wbrow {
    flex-wrap: wrap;
  }
}

/* product grid: cards in three columns on desktop, one on phone. */
#campaignView .wbprodgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin: 8px 0 12px;
}
/* product on desktop: four across. This block sits after the base
   rule on purpose: same selector, later wins. */
@media (min-width: 1000px) {
  #campaignView .wbprodgrid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
#campaignView .wbproduct {
  position: relative;
  min-width: 0;
}
#campaignView .wbprodphoto {
  width: 100%;
  height: auto;
  display: block;
}
#campaignView .wbproduct .wbphotoempty {
  width: 100%;
  min-height: 120px;
}
@media (max-width: 999px) {
  #campaignView .wbprodgrid {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* roomier kanban on desktop, where the board has the width. */
@media (min-width: 1000px) {
  #campaignView .wbkanban {
    gap: 16px;
  }
}

/* moodboard tab remove: a small x beside the tab, edit mode only. The
   wrap keeps tab and x together in the tab bar's flex row. */
.cdmoodtabwrap { display: inline-flex; align-items: flex-end; flex: none; margin-right: 6px; }
.cdmoodtabwrap button.cdmoodtab { margin-right: 0; }
button.cdmoodrm { border: none; background: transparent; border-radius: 0; font-family: var(--cp-sans); font-size: 14px; color: #999; padding: 0 2px 8px 6px; cursor: pointer; line-height: 1; }
button.cdmoodrm:hover { color: var(--cp-ink); }
/* moodboard fill actions: how a board gets photos, under its wall. */
.cdmoodadd { font-family: var(--cp-sans); font-size: 14px; color: var(--cp-mute); margin: 10px 0 4px; }
.cdmoodadd button { border: none; background: transparent; border-radius: 0; font-family: var(--cp-sans); font-size: 14px; color: var(--cp-ink); text-decoration: underline; text-underline-offset: 3px; padding: 0; cursor: pointer; }
/* collection picker: the account's collections as plain name links. */
.cdmoodcollist { margin: 8px 0 0; }
.cdmoodcollist:empty { margin: 0; }
.cdmoodcoll { display: block; border: none; background: transparent; border-radius: 0; font-family: var(--cp-sans); font-size: 14px; color: var(--cp-ink); text-decoration: underline; text-underline-offset: 3px; padding: 2px 0; cursor: pointer; text-align: left; }
/* invite: owner-only email row at the end of the Team tab. */
#campaignView .wbinvite { margin-top: 12px; }
#campaignView .wbinviterow { display: flex; gap: 8px; align-items: baseline; margin-top: 8px; }
#campaignView .wbinviteemail { flex: 1; min-width: 0; border: none; border-bottom: 1px solid var(--cp-dash); border-radius: 0; background: transparent; padding: 8px 0; font-family: var(--cp-sans); font-size: 15px; line-height: 1.6; color: var(--cp-ink); outline: none; }
#campaignView .wbinviteemail:focus { border-bottom-color: var(--cp-ink); }
#campaignView .wbinvitego { background: #0d0d0d; color: #fff; border: none; border-radius: 0; font-family: var(--cp-sans); font-size: 13px; font-weight: 500; padding: 9px 16px; cursor: pointer; flex: none; }
#campaignView .wbinvitemsg { font-size: 13px; color: #737373; margin-top: 10px; line-height: 1.6; word-break: break-all; }
#campaignView .wbinvitemsg a { color: var(--cp-ink); }
#campaignView .wbinvitecopy, #campaignView .wbinvitemail { background: transparent; border: none; border-radius: 0; font-family: var(--cp-sans); font-size: 13px; color: var(--cp-ink); text-decoration: underline; text-underline-offset: 3px; padding: 0; cursor: pointer; }
/* access list: one row per person with access, face + handle or email,
   owner tag or a red remove ×. */
#campaignView .wbaccess { margin-top: 20px; }
#campaignView .wbaccessrow { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
#campaignView .wbaccessrow .wbface { width: 28px; height: 28px; flex: none; }
#campaignView .wbaccessrow .wbface .ini { font-size: 10px; }
#campaignView .wbaccesslabel { font-size: 14px; }
#campaignView .wbaccessowner { font-size: 12px; color: #737373; margin-left: auto; }
#campaignView .wbaccessremove { background: transparent; border: none; border-radius: 0; font-family: var(--cp-sans); font-size: 16px; color: #b3261e; cursor: pointer; padding: 0; margin-left: auto; line-height: 1; }
