/* ── ChatDock — persistent bottom-corner mini-chat ───────────────────────
   Mounted once in the App shell (public/app/app.js), outside the route
   table — survives hash navigation with its state intact. Hidden entirely
   (component returns null) for guests, on /messages, and on mobile
   (<=700px — the full Messages page is the mobile surface). Monochrome +
   one accent (the unread badge / send button), layered dark-chrome header
   to match the sidebar/top-bar chrome, dense like the rest of the app. */
.cc-chatdock { position: fixed; right: 22px; bottom: 22px; z-index: 90; display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }

.cc-chatdock-launcher {
  width: 52px; height: 52px; border-radius: 50%; border: 1px solid var(--cc-chrome-line);
  background: var(--cc-chrome); color: var(--cc-chrome-ink); display: flex; align-items: center;
  justify-content: center; position: relative; box-shadow: 0 10px 26px -10px rgba(20,18,12,.4), 0 2px 8px rgba(20,18,12,.15);
  flex-shrink: 0; transition: transform .12s ease, box-shadow .12s ease;
}
.cc-chatdock-launcher:hover { transform: translateY(-1px); box-shadow: 0 14px 30px -10px rgba(20,18,12,.46), 0 2px 8px rgba(20,18,12,.18); }
/* Corner badge on the dock's floating launcher — its ring pins to the light
   canvas, so a quiet ink pill (not a solid accent block) reads on both the
   dark launcher and the canvas it overlaps (de-accented, 2026-07-16
   design-canon pass). */
.cc-chatdock-badge {
  /* Pinned INSIDE the launcher (like .cc-bell-badge, top:1/right:1) — any
     overhang past the control's box, whether via negative insets or a
     transform, is painted ink outside the control and fails the text-box
     contract at large font sizes (22 probe findings at font-20). */
  position: absolute; top: 2px; right: 2px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--cc-radius-pill); background: var(--cc-ink); color: var(--cc-surface);
  font: 700 10.5px/18px var(--cc-font); text-align: center; box-shadow: 0 0 0 2px var(--cc-canvas);
}

.cc-chatdock-panel {
  width: 360px; max-width: calc(100vw - 44px); height: 480px; max-height: calc(100vh - 110px);
  display: flex; flex-direction: column; background: var(--cc-surface); border: 1px solid var(--cc-line);
  border-radius: var(--cc-radius-lg); overflow: hidden; box-shadow: 0 24px 60px -20px rgba(20,18,12,.35), 0 4px 14px rgba(20,18,12,.12);
  animation: cc-chatdock-in .14s ease;
}
@keyframes cc-chatdock-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

.cc-chatdock-hd {
  flex-shrink: 0; display: flex; align-items: center; gap: 9px; padding: 12px 12px 12px 16px;
  background: var(--cc-chrome); color: var(--cc-chrome-ink); font: 700 13.5px/1.2 var(--cc-font);
}
.cc-chatdock-hd .who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cc-chatdock-hd .who .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-chatdock-hd .who .typing { font: 500 11px/1.3 var(--cc-font-soft); color: var(--cc-accent-onchrome); }
.cc-chatdock-hd span:first-child:not(.who) { flex: 1; }
.cc-chatdock-back, .cc-chatdock-x {
  width: 26px; height: 26px; border-radius: var(--cc-radius-sm); border: 0; background: transparent;
  color: var(--cc-chrome-soft); display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.cc-chatdock-back:hover, .cc-chatdock-x:hover { background: var(--cc-chrome-2); color: var(--cc-chrome-ink); }

.cc-chatdock-list { flex: 1; overflow-y: auto; }
.cc-chatdock-empty { flex: 1; display: flex; align-items: center; justify-content: center; padding: 30px; color: var(--cc-muted); font-size: 12.5px; }
.cc-chatdock-convo {
  width: 100%; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border: 0;
  border-bottom: 1px solid var(--cc-line-soft); background: none; text-align: left;
}
.cc-chatdock-convo:hover { background: var(--cc-surface-2); }
.cc-chatdock-convo .meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cc-chatdock-convo .nm { font: 600 13px/1.3 var(--cc-font); color: var(--cc-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-chatdock-convo .snip { font: 500 11.5px/1.35 var(--cc-font-soft); color: var(--cc-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Unread dot in the dock's conversation list (white panel ground) — quiet ink
   pill, matching .cc-convo-unread's treatment (de-accented, 2026-07-16
   design-canon pass). */
.cc-chatdock-dot {
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--cc-radius-pill); background: var(--cc-ink);
  color: var(--cc-surface); font: 700 10px/16px var(--cc-font); text-align: center; flex-shrink: 0;
}
.cc-chatdock-seeall {
  flex-shrink: 0; width: 100%; padding: 10px; border: 0; border-top: 1px solid var(--cc-line);
  background: var(--cc-surface-2); color: var(--cc-soft); font: 600 12px/1.2 var(--cc-font-soft); text-align: center;
}
.cc-chatdock-seeall:hover { color: var(--cc-ink); }

.cc-chatdock-bubbles { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 8px; }
.cc-chatdock-bubble { max-width: 82%; padding: 8px 11px; border-radius: 14px; font: 400 13px/1.42 var(--cc-font-soft); }
.cc-chatdock-bubble.them { align-self: flex-start; background: var(--cc-surface-2); border: 1px solid var(--cc-line-soft); border-bottom-left-radius: 4px; color: var(--cc-ink); }
.cc-chatdock-bubble.me { align-self: flex-end; background: var(--cc-ink); color: var(--cc-surface); border-bottom-right-radius: 4px; }

/* Classed .cc-input (sweep chunk 2, 2026-07-16) so it rides the global field
   canon (calm.css §8: neutral --cc-field-line at rest, ink ring on focus)
   instead of hand-carrying the same strokes directly — this block keeps only
   what makes the dock's field distinct from a standard one (size, shape,
   tint); the old rest-state border and the whole :focus rule duplicated
   .cc-input exactly and are dropped. */
.cc-chatdock-composer { flex-shrink: 0; display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--cc-line); align-items: center; }
.cc-chatdock-composer input {
  flex: 1; min-width: 0; border-radius: var(--cc-radius-md); padding: 8px 11px;
  font: 400 13px/1.3 var(--cc-font-soft); background: var(--cc-canvas);
}
/* Placeholder + ink focus ride the global .cc-input canon (the input is
   classed .cc-input, sweep chunk 2); #244's interim bare-selector copies
   were dropped in the merge. Rest background stays local above. */
.cc-chatdock-composer .cc-btn { flex-shrink: 0; padding: 8px 10px; }

@media (max-width: 700px) {
  /* Mobile: the full Messages page is the mobile chat surface — the dock's
     component returns null under this breakpoint (see CC.ui.ChatDock's
     matchMedia guard), so this rule is a belt-and-suspenders backstop only. */
  .cc-chatdock { display: none; }
}

/* ════════════════════════════════════════════════════════════════════
   CALLSHEET PRO — job-board paywall (PR3b)
   Dark until app_settings.pro_gate flips (all classes below are only ever
   attached when the server actually sent a locked payload or a Pro-gated
   viewer state). Monochrome everywhere except the two sanctioned accent
   spots: the banner's "Unlock Pro" CTA and the upgrade modal's "Continue".
   ════════════════════════════════════════════════════════════════════ */

/* Upgrade modal — monochrome Monthly/Yearly segments (.cc-seg / .cc-seg-opt
   already carry the app's one selection-state treatment); the yearly badge
   and the primary "Continue" button are the only colour on this surface. */
.cc-promodal-seg { margin: 14px 0 4px; }
.cc-promodal-optcol { display: flex; flex-direction: column; align-items: center; gap: 3px; padding-top: 10px; padding-bottom: 10px; }
.cc-promodal-badge { display: inline-block; font: 700 9.5px/1 var(--cc-font-soft); letter-spacing: .04em; text-transform: uppercase; color: var(--cc-ok-ink); background: var(--cc-ok-bg); border-radius: var(--cc-radius-sm); padding: 2px 6px; }

/* Board banner card — same footprint as a GigCard so it sits in the grid
   without its own layout math; accent CTA is the ONE sanctioned spot here
   (money/go rule). */
/* Full-width row at the top of the single-column board list (it used to be a
   grid card and borrowed cc-gigcard's radius — it stands alone now). */
.cc-probanner { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 16px; background: var(--cc-grad-accent); color: #fff; border: 0; border-radius: var(--cc-radius-lg); }
@media (max-width: 640px) { .cc-probanner { flex-direction: column; align-items: stretch; } }
.cc-probanner-body h3 { margin: 0 0 8px; font: 700 16px/1.3 var(--cc-font); letter-spacing: -.01em; }
.cc-probanner-stat { font: 500 12.5px/1 var(--cc-font-soft); color: rgba(255,255,255,.86); }
.cc-probanner-stat b { font-family: var(--cc-font); font-size: 15px; }
.cc-probanner .cc-btn.primary { align-self: flex-start; background: #fff; color: var(--cc-ink); border: 0; }

/* Locked list-card byline (GigCard/GigRow/FeedGigCard) — a role word + lock
   glyph standing in for the redacted poster name. Inherits the parent's
   existing meta-row spacing (.cc-gc-meta span / .cc-l2), no bespoke layout. */
.cc-gc-prorole { font-weight: 600; }

/* Invitations tab badge (mirrors the sidebar's small count bubble). */
.cc-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; margin-left: 5px; padding: 0 4px; border-radius: var(--cc-radius-pill); background: var(--cc-ink); color: var(--cc-surface); font: 700 10px/16px var(--cc-font); }
.cc-tab.on .cc-tab-badge { background: var(--cc-accent); color: #fff; }
.cc-invite-note { margin-top: 4px; font: 500 12.5px/1.4 var(--cc-font-soft); color: var(--cc-muted); font-style: italic; }

/* Detail-pane veil ("the description area") — a quiet bordered panel, no
   backdrop-blur (matches the callsheet-premium no-pill/crisp-radii pass:
   var(--cc-radius-md), not a soft glass card). */
.cc-provei-meta { display: flex; align-items: center; gap: 5px; font: 500 11.5px/1.3 var(--cc-font-soft); margin-bottom: 8px; }
.cc-provei-panel { background: var(--cc-surface-2); border: 1px dashed var(--cc-line); border-radius: var(--cc-radius-md); padding: 16px; }
.cc-provei-copy { margin: 0 0 12px; font: 500 13.5px/1.5 var(--cc-font-soft); color: var(--cc-soft); }
.cc-provei-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.cc-provei-out { margin: 0; font: 600 12.5px/1.4 var(--cc-font-soft); color: var(--cc-warn-ink); }
.cc-provei-railcta { display: flex; flex-direction: column; gap: 8px; }
.cc-provei-railcta .cc-hint { margin: 0; }

/* Settings → Membership card. */
.cc-mem-status { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.cc-mem-status-id { flex: 1; min-width: 0; }
.cc-mem-status-id .nm { font: 700 15px/1.3 var(--cc-font); }
.cc-mem-status-id .ln { font: 500 12.5px/1.4 var(--cc-font-soft); margin-top: 2px; }
.cc-mem-stats { margin: 14px 0; }
.cc-mem-benefits { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 14px; }
.cc-mem-benefit { border: 1px solid var(--cc-line); border-radius: var(--cc-radius-md); padding: 13px 14px; }
.cc-mem-benefit .t { font: 500 13px/1.45 var(--cc-font-soft); color: var(--cc-soft); margin-bottom: 8px; }
.cc-mem-manage { border-top: 1px solid var(--cc-line); padding-top: 12px; margin-top: 4px; }
.cc-mem-losslist { margin: 10px 0 0; padding-left: 20px; font: 500 13px/1.6 var(--cc-font-soft); color: var(--cc-soft); }
@media (max-width: 640px) { .cc-mem-benefits { grid-template-columns: 1fr; } }
/* ═══════════════════════ end CALLSHEET PRO ═══════════════════════ */

/* ============================================================
   Board frame lock (user-walk audit finding 4).
   On the desktop job board the DOCUMENT used to scroll ~354px
   behind the app shell — wheel scroll detached the header/sidebar
   (blank band), pushed the rail's Apply below a 720px fold, and
   the Apply modal centered on the scrolled document.
   Fix, mirroring the Messages pattern (.cc-main:has(.cc-msgs)):
   whenever the board split is on screen, the shell column is
   viewport-bound and non-scrolling; the card LIST scrolls
   internally; the DETAIL PANE is a flex column whose brief
   scrolls inside .cc-embed-gig-scroll with the .cc-gd-applybar
   CTA pinned at the pane bottom — Apply always visible.
   Scoped by :has(.cc-boardsplit): only the board tab renders that
   class, so every other route/tab keeps natural page scroll, and
   the ≤980px list-only behavior is untouched (the media query
   never applies there; the panel is display:none anyway).
   ============================================================ */
@media (min-width: 981px) {
  .cc-main:has(.cc-boardsplit) { height: 100vh; overflow: hidden; }
  .cc-body:has(.cc-boardsplit) { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; }
  .cc-body:has(.cc-boardsplit) > .cc-maxw { display: flex; flex-direction: column; flex: 1; min-height: 0; width: 100%; }
  /* chrome above the split (tabs, header, apply-allowance hint, filter row)
     keeps its natural height; the split takes the remainder */
  .cc-maxw:has(.cc-boardsplit) > .cc-tabs, .cc-maxw:has(.cc-boardsplit) > .cc-hdr,
  .cc-maxw:has(.cc-boardsplit) > .cc-applyhint,
  .cc-maxw:has(.cc-boardsplit) > .cc-ocdisc, .cc-maxw:has(.cc-boardsplit) > .cc-ocsort { flex-shrink: 0; }
  .cc-boardsplit { flex: 1; min-height: 0; grid-template-rows: minmax(0, 1fr); }
  .cc-boardsplit > .cc-split2-list { height: 100%; min-height: 0; overflow-y: auto; padding-bottom: 22px; }
  .cc-boardsplit > .cc-split2-list::-webkit-scrollbar { width: 8px; }
  .cc-boardsplit > .cc-split2-list::-webkit-scrollbar-thumb { background: var(--cc-line); border-radius: 8px; }
  /* the panel stops being a document-sticky scroller — it IS the pane now */
  .cc-boardsplit > .cc-split2-panel { position: static; top: auto; max-height: none; height: 100%; min-height: 0;
    overflow: hidden; display: flex; flex-direction: column; padding-bottom: 4px; }
  .cc-boardsplit .cc-split2-panel > .cc-embed-gig { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .cc-boardsplit .cc-embed-gig-scroll { flex: 1; min-height: 0; overflow-y: auto; }
  .cc-boardsplit .cc-embed-gig-scroll::-webkit-scrollbar { width: 8px; }
  .cc-boardsplit .cc-embed-gig-scroll::-webkit-scrollbar-thumb { background: var(--cc-line); border-radius: 8px; }
}
/* The pinned CTA bar — bottom edge of the elevated pane sheet. Outside the
   media query so the sheet stays coherent if the pane ever renders narrow. */
.cc-gd-applybar { flex-shrink: 0; padding: 12px 16px; border-top: 1px solid var(--cc-line); background: var(--cc-surface); }
.cc-gd-applybar .cc-applied { margin-bottom: 8px; }

/* ═══════════════════════════════════════════════════════════════
   OPEN CALLS · master-detail v2 (redesign sprint, 2026-07-14)
   Finder-style split: the feed holds ~48% while a call is open on
   the right; the cover-band × collapses the detail and the feed
   expands to full width (flex-basis animates 420ms). Feed rows are
   dense single-line rows — type tag · title · company/location/
   dates meta · rate · chevron. Selection reads as the calm skin's
   terracotta tint: no left stripes, no outline ring. The detail
   hero gains a cover band, a category eyebrow, and a 4-cell meta
   grid whose Rate cell is the money spot.
   ═══════════════════════════════════════════════════════════════ */

/* — the split becomes flex so the feed's flex-basis can animate —
   (the earlier grid-template-columns rules on .cc-boardsplit go
   inert under display:flex; .cc-split2 grid still serves Crew) */
.cc-boardsplit { display: flex; align-items: stretch; }
.cc-boardsplit > .cc-split2-list {
  flex: 0 0 48%; min-width: 0;
  transition: flex-basis .42s cubic-bezier(.22,.61,.36,1);
}
.cc-boardsplit.closed > .cc-split2-list { flex-basis: 100%; padding-right: 0; }
.cc-boardsplit > .cc-split2-panel { flex: 1 1 0; min-width: 0; }
/* the detail slides in from the right when the pane (re)opens */
@keyframes cc-ocall-in { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
.cc-boardsplit > .cc-split2-panel.cc-fly { animation: cc-ocall-in .42s cubic-bezier(.22,.61,.36,1); }
@media (max-width: 980px) {
  .cc-boardsplit > .cc-split2-list { flex-basis: 100%; padding-right: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cc-boardsplit > .cc-split2-list { transition: none; }
  .cc-boardsplit > .cc-split2-panel.cc-fly { animation: none; }
}

/* — the Airbnb pill is the board's one search control; the feed fills
     chronologically beneath it until the go button applies criteria.
     FULLY round white capsule (the pill is the sanctioned pill), ink text,
     segment dividers; Sort rides inline to its right — */
.cc-ocdisc { padding: 2px 0 12px; display: flex; align-items: center; gap: 14px; }
.cc-ocdisc .cc-disc { flex: 1; min-width: 0; background: #fff; border-radius: 999px; }
.cc-ocdisc .cc-disc-seg:first-child { border-radius: 999px 0 0 999px; }
.cc-ocdisc .cc-disc-seg input { color: var(--cc-ink); }
.cc-ocdisc .cc-fsort { flex-shrink: 0; }

/* — feed rows (reworks the Nova card into a dense single-line row;
     the old thumb/name/desc rules above go inert with the markup) —
   White is the default card, always (Tomas 2026-07-15, replaces the #224
   chip-bg inversion): unselected rows sit on the plain white surface with a
   neutral hairline; hover is a subtle neutral moment, the hairline steps one
   shade darker toward ink — never a color moment. Selected earns the one
   accent: a terracotta ring, not a fill swap or a lift-only shadow — a 1px
   border + 1px ring for a dense edge, fading out through a soft 4px tint
   ring and a diffuse glow. */
.cc-ngc { align-items: center; gap: 12px; padding: 13px 15px; background: var(--cc-surface); border-color: var(--cc-line); box-shadow: none; }
.cc-ngc:hover { border-color: color-mix(in srgb, var(--cc-line) 78%, var(--cc-ink)); }
.cc-ngc.sel { outline: 0; background: var(--cc-surface); border-color: var(--cc-accent); box-shadow: 0 0 0 1px var(--cc-accent), 0 0 0 4px color-mix(in srgb, var(--cc-accent) 20%, transparent), 0 0 16px 2px color-mix(in srgb, var(--cc-accent) 12%, transparent); }
.cc-ngc.sel:hover { border-color: var(--cc-accent); }
.cc-ngc-l1 { display: flex; align-items: center; gap: 8px; min-width: 0; }
.cc-ngc-tag {
  font: 700 9.5px/1 var(--cc-font); letter-spacing: .05em; text-transform: uppercase;
  color: var(--cc-soft); background: var(--cc-chip); border-radius: var(--cc-radius-sm);
  padding: 4px 7px; flex-shrink: 0; white-space: nowrap;
}
.cc-ngc-ttl {
  /* Oversized + LIGHT (Tomas: not the heavy header font) — single line +
     ellipsis on desktop; wraps to a 2-line clamp on phones below. */
  font: 400 17px/1.35 var(--cc-font-soft); color: var(--cc-ink); margin: 0;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cc-ngc-ttl b { font-family: inherit; font-weight: 500; }  /* quiet emphasis, no bold slabs */
.cc-ngc-meta {
  display: flex; align-items: center; gap: 6px; margin-top: 6px; min-width: 0;
  font: 500 12px/1.3 var(--cc-font-soft); color: var(--cc-muted);
  white-space: nowrap; overflow: hidden;
}
.cc-ngc-meta > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cc-ngc-meta > .dot { flex-shrink: 0; color: var(--cc-faint); }
.cc-ngc-meta .cc-ngc-prorole { display: inline-flex; align-items: center; gap: 5px; }
.cc-ngc-side { justify-content: center; }
.cc-ngc-chev { color: var(--cc-faint); flex-shrink: 0; }

/* — detail hero: cover band + eyebrow + 4-cell meta grid — */
.cc-gigd-cover {
  position: relative; height: 148px;
  margin: -16px -18px 14px;              /* full-bleed vs .cc-gdcard 16/18px padding */
  /* token, not a literal — the premium pass rounds every sheet at
     --cc-radius-lg (10px); a hardcoded 20px left white corner notches
     peeking past the dark band */
  border-radius: var(--cc-radius-lg) var(--cc-radius-lg) 0 0;
  background: var(--cc-chrome) center/cover no-repeat;
}
.cc-embed-gig .cc-gigd-cover { margin: -16px -20px 14px; }  /* flattened pane pads 16/20px */
.cc-gigd-x {
  position: absolute; top: 10px; left: 10px; width: 30px; height: 30px;
  border-radius: 8px; border: 0; cursor: pointer;
  background: rgba(20,18,12,.55); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.cc-gigd-x:hover { background: rgba(20,18,12,.78); }
.cc-gigd-posted {
  position: absolute; top: 14px; right: 14px; max-width: 45%; text-align: right;
  font: 700 9.5px/1.5 var(--cc-font); letter-spacing: .08em; text-transform: uppercase;
  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.45);
}
/* Metadata eyebrow on every gig detail — neutral (de-accented, 2026-07-16
   design-canon pass); the weight/caps/tracking already carry it. */
.cc-gigd-eyebrow {
  font: 700 10.5px/1.5 var(--cc-font); letter-spacing: .08em; text-transform: uppercase;
  color: var(--cc-ink);
}
.cc-gigd-hero .cc-gigd-ttl { margin-top: 6px; }
/* Oversized, thinner display title (was 700 22px — read as a heavy slab) */
.cc-gigd-ttl { font: 500 27px/1.22 var(--cc-font); letter-spacing: -.02em; }
.cc-gigd-by { margin-top: 5px; font: 500 13px/1.4 var(--cc-font-soft); color: var(--cc-soft); display: flex; align-items: center; gap: 6px; }
.cc-gigd-by i { color: var(--cc-faint); }
.cc-gigd-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 14px;
  border: 1px solid var(--cc-line-soft); border-radius: 10px; overflow: hidden;
}
.cc-gigd-grid .cell { padding: 10px 12px; border-right: 1px solid var(--cc-line-soft); min-width: 0; }
.cc-gigd-grid .cell:last-child { border-right: 0; }
.cc-gigd-grid .k {
  font: 600 9.5px/1 var(--cc-font-soft); letter-spacing: .07em; text-transform: uppercase;
  color: var(--cc-faint);
}
.cc-gigd-grid .v {
  margin-top: 5px; font: 700 13.5px/1.25 var(--cc-font); color: var(--cc-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Rate is static info, not an affordance (Tomas 2026-07-15): it reads
   exactly like its sibling cells in the grid, no accent tint. */
/* The EMBEDDED pane is ~half the split — below a 1280px viewport its 4-up
   grid squeezed the Rate cell (the money spot) into a misleading truncation
   ("$1,000–1,2…"). Fall to 2×2 while the pane is narrow. */
@media (max-width: 1280px) {
  .cc-embed-gig .cc-gigd-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cc-embed-gig .cc-gigd-grid .cell:nth-child(even) { border-right: 0; }
  .cc-embed-gig .cc-gigd-grid .cell:nth-child(-n+2) { border-bottom: 1px solid var(--cc-line-soft); }
}
@media (max-width: 640px) {
  .cc-gigd-cover { margin: -14px -15px 12px; }
  .cc-gigd-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cc-gigd-grid .cell:nth-child(even) { border-right: 0; }
  .cc-gigd-grid .cell:nth-child(-n+2) { border-bottom: 1px solid var(--cc-line-soft); }
  /* Feed rows re-stack on phones (app-grade legibility): tag line, then the
     title WRAPS to a 2-line clamp (no more "Mu…" fragments), meta line, then
     rate + ago·applied as the last row. */
  .cc-ngc { flex-wrap: wrap; row-gap: 0; }
  .cc-ngc-main { flex: 1 1 100%; }
  .cc-ngc-l1 { flex-wrap: wrap; }
  .cc-ngc-ttl {
    flex: 1 1 100%; margin-top: 7px;
    white-space: normal; text-overflow: clip;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  }
  .cc-ngc-side { flex-direction: row; align-items: baseline; gap: 8px; margin-top: 7px; }
  .cc-ngc-chev { display: none; }
  .cc-gigd-ttl { font-size: 23px; }
}

/* Credentials-offered banner — gig DETAIL view only (cards stay chip-free).
   Full-width strip, the one positive/"go" status color in the app (--cc-ok-*,
   already the "available"/travel-covered treatment elsewhere — never a new
   hardcoded hex, never the terracotta/vermilion accents). Doubled class on
   the background rule for the same reason as .cc-gigd-gate.cc-gigd-gate
   above: `.cc-gigd-main > .cc-gdcard` (and the embedded-pane equivalent)
   force `background: transparent` at 2-class specificity, which otherwise
   beats a plain single-class `.cc-gigd-credbanner` rule and the banner
   would render invisible (flat, uncolored). */
.cc-gigd-credbanner { display: flex; align-items: flex-start; gap: 10px; color: var(--cc-ok-ink); }
.cc-gigd-credbanner.cc-gigd-credbanner { background: var(--cc-ok-bg); }
.cc-gigd-credbanner i { color: var(--cc-ok-ink); flex-shrink: 0; margin-top: 1px; }
.cc-gigd-credbanner-ttl { font: 700 13.5px/1.3 var(--cc-font); color: var(--cc-ok-ink); }
.cc-gigd-credbanner-sub { margin-top: 2px; font: 500 12.5px/1.4 var(--cc-font-soft); color: var(--cc-ok-ink); }

/* — pinned bar becomes the Apply + Save pair on the embedded pane — */
.cc-gd-applybar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.cc-gd-applybar > div { flex: 1 1 auto; min-width: 0; }
.cc-gd-applybar > .cc-gdcta { width: auto; flex: 1 1 auto; }
.cc-gd-applybar .cc-gdquiet { margin-top: 0; }   /* stacked-rail spacing, not a flex-row concern */
.cc-gd-applybar .cc-save.wide { width: auto; flex: 0 0 auto; margin-top: 0; }
.cc-gd-applybar .cc-applied { margin-bottom: 0; }

/* — airy pass (Tomas: light and airy, not condensed) — */
.cc-ngc { padding: 17px 18px; }
.cc-ngclist { gap: 12px; }
/* No visible scrollbars in this century — inner app scrollers scroll
   silently (wheel/trackpad/touch still work; this hides the chrome). */
.cc-boardsplit > .cc-split2-list, .cc-embed-gig-scroll, .cc-split2-panel,
.cc-home-rail, .cc-fpop-list, .cc-combo-menu, .cc-rolemenu-scroll, .cc-postmodal-body {
  scrollbar-width: none; -ms-overflow-style: none;
}
.cc-boardsplit > .cc-split2-list::-webkit-scrollbar, .cc-embed-gig-scroll::-webkit-scrollbar,
.cc-split2-panel::-webkit-scrollbar, .cc-home-rail::-webkit-scrollbar,
.cc-fpop-list::-webkit-scrollbar, .cc-combo-menu::-webkit-scrollbar,
.cc-rolemenu-scroll::-webkit-scrollbar,
.cc-postmodal-body::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* — Post a job step 1: clean 2-col stacked fields (replaces the mad-lib) — */
.cc-postgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; margin: 6px 0 14px; }
.cc-postgrid .cc-field { margin: 0; }
.cc-postgrid .cc-field > label { display: flex; align-items: baseline; }
.cc-lbl-swap { margin-left: auto; background: none; border: 0; padding: 1px 0; cursor: pointer;
  font: 500 11.5px/1.3 var(--cc-font-soft); color: var(--cc-muted); text-decoration: underline; }
.cc-lbl-swap:hover { color: var(--cc-ink); }
.cc-dates2 { display: flex; align-items: center; gap: 8px; }
.cc-dates2 .cc-input { flex: 1; min-width: 0; }
.cc-dates2 .d { color: var(--cc-faint); }
.cc-dates-flex { display: flex; align-items: center; color: var(--cc-soft); }
.cc-postgrid .cc-rolepick, .cc-postgrid .cc-evpick { width: 100%; }
@media (max-width: 640px) { .cc-postgrid { grid-template-columns: 1fr; } }

/* Region escape (tour projectType) — free-text + quick-pick chips that just
   fill the input. Monochrome, no accent (DESIGN_BIBLE rule 2). Tomas 2026-07-15. */
.cc-regionchips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.cc-regionchip { font: 600 12px/1 var(--cc-font-soft); color: var(--cc-soft); background: var(--cc-chip);
  border: 0; border-radius: var(--cc-radius-sm); padding: 6px 10px; cursor: pointer; }
.cc-regionchip:hover { color: var(--cc-ink); }
/* "List on the {festival}'s event page" — sits under the event/festival picker. */
.cc-listcheck { display: flex; margin-top: 9px; }

/* — SINGLE ROW PER ITEM (Tomas, 2026-07-15): no multi-column card grids
     anywhere — events, jobs, contractors, saved. Every item gets its own
     full-width row. — */
.cc-clist, .cc-browsegrid, .cc-browsegrid.cc-evlist { grid-template-columns: 1fr !important; }
/* ═══════════════ end OPEN CALLS master-detail v2 ═══════════════ */

/* ═══ OPEN CALLS · NOVA airy pass (2026-07-15, Tomas's north star) ═══
   Rows become roomy cards: face + name header, ago + rate PILL right,
   sentence title in the display face (wraps, no ellipsis), 2-line teaser.
   The board header row is gone — search pill, sort and Post live in the
   tabs row. Step-1 post form is the oversized stacked sentence. */

/* pill row: the capsule is truly centered; Post rides the right edge */
.cc-ocbar { display: grid; grid-template-columns: 1fr minmax(0, 720px) 1fr; align-items: center; gap: 14px; margin-bottom: 14px; }
.cc-ocbar .cc-ocdisc { grid-column: 2; padding: 0; }
.cc-ocbar-right { grid-column: 3; justify-self: end; }
.cc-ocbar .cc-btn { white-space: nowrap; }
@media (max-width: 980px) {
  .cc-ocbar { grid-template-columns: 1fr; }
  .cc-ocbar .cc-ocdisc, .cc-ocbar-right { grid-column: 1; justify-self: stretch; }
  /* pill re-stacks inside the new bar (same treatment the old tabs-row
     container had): segments full-width, labeled Search bar, sort wraps */
  .cc-ocbar .cc-ocdisc { flex-wrap: wrap; }
  .cc-ocbar .cc-ocdisc .cc-fsort { margin-left: auto; }
  .cc-ocbar .cc-disc { flex-wrap: wrap; }
  .cc-ocbar .cc-disc-seg { flex: 1 1 100%; min-width: 0; padding: 9px 16px; }
  .cc-ocbar .cc-disc-when { flex-wrap: wrap; }
  .cc-ocbar .cc-disc-go { width: 100%; height: auto; margin: 6px; }
}
/* tabs sit above the feed column */
.cc-octabs2 { margin: 2px 0 12px; }
.cc-boardsplit .cc-octabs2 { margin-top: 0; }
/* legacy (kept so old cached css can't orphan markup) */
.cc-octabs { display: flex; align-items: center; }
.cc-octabs .cc-tab { white-space: nowrap; flex-shrink: 0; }
.cc-octabs-tools .cc-btn { white-space: nowrap; flex-shrink: 0; }
.cc-octabs-tools { margin-left: auto; flex: 1 1 auto; max-width: 860px; display: flex; align-items: center; gap: 12px; padding-left: 24px; }
.cc-octabs-tools .cc-ocdisc { flex: 1 1 auto; min-width: 0; padding: 0 0 6px; }
.cc-octabs .cc-disc-seg { padding: 4px 16px; }
.cc-octabs .cc-disc-go { width: 38px; height: 38px; margin: 4px; }
@media (max-width: 980px) {
  .cc-octabs { flex-wrap: wrap; }
  .cc-octabs-tools { flex-basis: 100%; padding-left: 0; margin-top: 8px; flex-wrap: wrap; max-width: none; }
  .cc-octabs-tools > * { min-width: 0; max-width: 100%; }
  .cc-octabs-tools .cc-ocdisc { flex-basis: 100%; flex-wrap: wrap; }
  .cc-octabs-tools .cc-ocdisc .cc-fsort { margin-left: auto; }
  /* revert the compact-pill overrides — the stacked mobile pill needs its
     full-width segments + labeled Search bar back */
  .cc-octabs .cc-disc-seg { padding: 9px 16px; }
  .cc-octabs .cc-disc-go { width: 100%; height: auto; margin: 6px; }
  /* belt + braces: if the capsule can't fit its three segments, the segments
     wrap instead of pushing the page wide */
  .cc-octabs .cc-disc { flex-wrap: wrap; }
  .cc-octabs .cc-disc-seg { flex: 1 1 100%; min-width: 0; }
  .cc-octabs .cc-disc-when { flex-wrap: wrap; }
}

/* rows: block cards, real air */
.cc-ngclist { gap: 16px; }
.cc-ngc { display: block; padding: 18px 20px; border-radius: 14px; border-color: var(--cc-line); }
.cc-ngc-top { display: flex; align-items: center; gap: 10px; }
.cc-ngc-id { flex: 1; min-width: 0; }
.cc-ngc-side { display: flex; flex-direction: row; align-items: center; gap: 10px; flex-shrink: 0; margin: 0; }
.cc-ngc-rate { background: var(--cc-chip); border-radius: 9px; padding: 6px 11px; }
.cc-ngc-rate .cc-money { font: 700 13px/1 var(--cc-font); color: var(--cc-ink); }
.cc-ngc-rate .cc-money small { color: var(--cc-muted); }
.cc-ngc-body { display: flex; gap: 14px; margin-top: 12px; }
/* inline photo: full card width, the card just gets taller */
.cc-ngc-photo { margin-top: 12px; height: 210px; border-radius: 10px; background-size: cover; background-position: center; }
.cc-ngc-main { flex: 1; min-width: 0; }
.cc-ngc-ttl {
  font: 400 16.5px/1.45 var(--cc-font); letter-spacing: -.005em; color: var(--cc-ink);
  margin: 0; white-space: normal; overflow: visible; text-overflow: clip; display: block;
}
.cc-ngc-ttl b { font-family: var(--cc-font); font-weight: 700; }
.cc-ngc-desc {
  font: 400 13px/1.5 var(--cc-font-soft); color: var(--cc-soft); margin-top: 6px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.cc-ngc-more { color: var(--cc-accent-ink); font-weight: 600; white-space: nowrap; }
@media (max-width: 640px) {
  .cc-ngc { padding: 15px 16px; }
  .cc-ngc-thumb { width: 64px; }
  .cc-ngc-ttl { font-size: 15.5px; }
}

/* step-1 oversized sentence */
.cc-bigml { margin: 10px 0 18px; }
.cc-bigml-lead { font: 500 15px/1.4 var(--cc-font-soft); color: var(--cc-soft); margin-bottom: 10px; }
.cc-bigml-line { display: flex; align-items: baseline; gap: 14px; margin-bottom: 10px; min-height: 40px; }
.cc-bigml-line .w { font: 400 26px/1.25 var(--cc-font); color: var(--cc-ink); flex-shrink: 0; }
.cc-bigml-blank {
  background: none; border: 0; outline: 0; min-width: 0; flex: 0 1 auto; padding: 0;
  font: 600 26px/1.25 var(--cc-font); letter-spacing: -.01em; color: var(--cc-accent-ink);
}
input.cc-bigml-blank { flex: 1 1 auto; }
.cc-bigml-blank::placeholder { color: var(--cc-ph); font-weight: 500; }
.cc-bigml-line .cc-rolepick, .cc-bigml-line .cc-evpick { flex: 1 1 auto; min-width: 0; }
.cc-bigml-line .cc-rolepick input, .cc-bigml-line .cc-evpick input {
  width: 100%; background: none; border: 0; outline: 0; padding: 0;
  font: 600 26px/1.25 var(--cc-font); letter-spacing: -.01em; color: var(--cc-accent-ink);
}
select.cc-bigml-blank { appearance: none; -webkit-appearance: none; cursor: pointer; }
.cc-bigml-dates { display: flex; align-items: baseline; gap: 10px; flex: 1 1 auto; min-width: 0; }
.cc-bigml-dates .cc-madlib-date { width: 5.6em; flex: 0 1 auto; }
.cc-bigml-flex { color: var(--cc-accent-ink); }
.cc-bigml-line .cc-lbl-swap { align-self: center; }
@media (max-width: 640px) {
  .cc-bigml-line .w, .cc-bigml-blank, .cc-bigml-line .cc-rolepick input, .cc-bigml-line .cc-evpick input { font-size: 21px; }
}
/* ═══ end OPEN CALLS NOVA airy pass ═══ */


/* ============================================================
   Landing 5a — logged-out hero demo (vignette + flag-gated ticker).
   Accent budget on this page is EXACTLY four: wordmark dot, hero
   liquidity pulse dot, the Sign-up CTA, the vignette's one "Book"
   tag. Everything else stays ink / soft / muted.
   ============================================================ */
.cc-herobig.five-a { border-radius: 24px; padding: 0; display: flex; flex-direction: column; }
.cc-hb-cols { display: grid; grid-template-columns: 1.05fr .95fr; gap: 44px; align-items: center; padding: 54px 48px 58px; }
.cc-herobig.five-a .cc-herobig-in { max-width: none; min-width: 0; }
.cc-herobig.five-a h1 { font: 800 clamp(36px, 4.8vw, 64px)/1.02 var(--cc-font); letter-spacing: -.035em; }

/* Hero liquidity line — the page's one pulse dot. Honest numbers or silence. */
.cc-hb-liq { display: inline-flex; align-items: center; gap: 9px; margin-bottom: 18px;
  font: 500 13px/1.2 var(--cc-font-soft); color: var(--cc-chrome-soft); }
.cc-hb-liq b { font: 700 13px/1 var(--cc-font); color: var(--cc-chrome-ink); }
.cc-hb-liq .cc-liq-sep { opacity: .6; }
.cc-hb-liq .cc-liq-dot { animation: cc-liq-pulse 2.2s ease-in-out infinite; }
/* Halo uses --acc to MATCH the dot fill (.cc-liq-dot resolves to --acc): the
   logged-out front door defaults to data-theme=forest, which greens --cc-accent
   but leaves --acc orange — using --cc-accent here gave an orange dot a green
   halo. Applies to both the landing and auth pulse dots. */
@keyframes cc-liq-pulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 24%, transparent); }
  50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--acc) 9%, transparent); }
}

/* The vignette — a display-only demo of the search → results moment.
   Every click target inside routes to /signup. */
.cc-lv { min-width: 0; }
.cc-lv-disc { max-width: none; margin: 0 0 12px; cursor: pointer;
  box-shadow: 0 18px 36px -18px rgba(0,0,0,.5); }
.cc-lv-disc .cc-disc-seg { padding: 9px 15px; }
.cc-lv-disc .val { font: 600 12.5px/1.2 var(--cc-font); color: var(--cc-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Neutral (NOT accent) search circle — the accent budget is spent elsewhere. */
.cc-lv-go { align-self: center; margin: 5px; width: 38px; height: 38px; flex-shrink: 0; border-radius: 50%;
  background: var(--cc-ink); color: var(--cc-surface);
  display: flex; align-items: center; justify-content: center; }
.cc-lv-stack { display: flex; flex-direction: column; gap: 8px; }
.cc-lv-card { display: flex; align-items: center; gap: 11px; padding: 10px 12px; cursor: pointer;
  background: var(--cc-surface); border-radius: 14px;
  box-shadow: 0 16px 32px -18px rgba(0,0,0,.55);
  opacity: 0; transform: translateY(14px);
  animation: cc-lv-rise .5s cubic-bezier(.22,.61,.36,1) forwards; }
.cc-lv-card:nth-child(1) { animation-delay: .05s; }
.cc-lv-card:nth-child(2) { animation-delay: .2s; }
.cc-lv-card:nth-child(3) { animation-delay: .35s; }
@keyframes cc-lv-rise { to { opacity: 1; transform: translateY(0); } }
.cc-lv-id { flex: 1; min-width: 0; }
.cc-lv-id .n { font: 700 13.5px/1.2 var(--cc-font); color: var(--cc-ink); }
.cc-lv-id .m { font: 500 11.5px/1.3 var(--cc-font-soft); color: var(--cc-soft); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cc-lv-tag { flex-shrink: 0; font: 700 11px/1 var(--cc-font); padding: 6px 11px;
  border-radius: var(--cc-radius-pill); background: var(--cc-chip); color: var(--cc-soft); }
/* "Book" tag on the landing vignette's demo gig cards — decorative chrome in a
   display-only animation (every click routes to /signup), not a real CTA or
   identity mark, so it doesn't earn the accent; same neutral chip as the
   default tag. */
.cc-lv-tag.acc { background: var(--cc-chip); color: var(--cc-soft); }
.cc-lv-tag.ok { background: var(--cc-ok-bg); color: var(--cc-ok-ink); }
/* The third result "just got booked": the tag flips in once, after the rise. */
.cc-lv-tag.flip { transform-origin: 50% 100%; animation: cc-lv-flip .55s 1.5s cubic-bezier(.22,.61,.36,1) both; }
@keyframes cc-lv-flip { from { opacity: 0; transform: rotateX(86deg); } to { opacity: 1; transform: rotateX(0); } }
.cc-lv-cap { margin-top: 10px; font: 500 11.5px/1 var(--cc-font-soft); color: var(--cc-chrome-ink); opacity: .45; }

/* Hero-base ticker of real open calls (flag-gated; ships dark). */
.cc-lv-ticker { border-top: 1px solid color-mix(in srgb, var(--cc-chrome-ink) 14%, transparent);
  background: rgba(10, 8, 5, .55); overflow: hidden; cursor: pointer; }
.cc-lv-track { display: flex; width: max-content; animation: cc-lv-scroll 36s linear infinite; }
.cc-lv-ticker:hover .cc-lv-track { animation-play-state: paused; }
.cc-lv-run { display: flex; }
.cc-lv-tick { display: inline-flex; align-items: baseline; gap: 8px; padding: 12px 24px; white-space: nowrap;
  font: 500 12px/1 var(--cc-font-soft); color: var(--cc-chrome-ink); }
.cc-lv-tick b { font: 700 9.5px/1 var(--cc-font); letter-spacing: .09em; color: var(--cc-chrome-soft); }
@keyframes cc-lv-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Landing-only gig card — flat caps scope, display role, fogged details,
   crisp $•••budget footer. Hover: 4px lift + deeper shadow. */
.cc-lgc { background: var(--cc-surface); border: 1px solid var(--cc-line); border-radius: 20px;
  padding: 15px 16px; overflow: hidden; cursor: pointer; text-align: left;
  display: flex; flex-direction: column;
  box-shadow: var(--cc-shadow-card);
  transition: transform .25s cubic-bezier(.22,.61,.36,1), box-shadow .25s cubic-bezier(.22,.61,.36,1); }
.cc-lgc:hover { transform: translateY(-4px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 24px 46px -18px rgba(45,38,28,.3), 0 2px 6px rgba(45,38,28,.08); }
.cc-lgc-scope { font: 700 9.5px/1 var(--cc-font); letter-spacing: .09em; text-transform: uppercase; color: var(--cc-faint); }
.cc-lgc-role { margin-top: 8px; font: 800 17px/1.15 var(--cc-font); letter-spacing: -.02em; color: var(--cc-ink); }
.cc-lgc-ttl { margin-top: 3px; font: 500 12.5px/1.35 var(--cc-font-soft); color: var(--cc-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cc-lgc-fog { margin-top: 9px; }
.cc-lgc-foot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--cc-line-soft);
  display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cc-lgc-rate { font: 800 15px/1 var(--cc-font); color: var(--cc-ink); }
.cc-lgc-rate small { font: 600 10px/1 var(--cc-font-soft); color: var(--cc-muted); margin-left: 3px; }
.cc-lgc-signin { font: 600 11.5px/1 var(--cc-font-soft); color: var(--cc-muted); }

/* Mobile: copy stacks over the vignette; the ticker keeps looping. The grid
   drops to 1-up in the SAME band the hero stacks (the pre-existing rule only
   fires at ≤640px, which would leave 641–700px 2-up under a stacked hero). */
@media (max-width: 700px) {
  .cc-hb-cols { grid-template-columns: 1fr; gap: 30px; padding: 34px 20px 38px; }
  .cc-herobig.five-a h1 { font-size: 34px; }
  .cc-lv-disc .cc-disc-seg { padding: 8px 11px; }
  .cc-lv-disc .val { font-size: 11.5px; }
  .cc-landing-grid { grid-template-columns: 1fr; }
}

/* Reduced motion: no rise, no flip, no scroll, no pulse — everything static. */
@media (prefers-reduced-motion: reduce) {
  .cc-lv-card { animation: none; opacity: 1; transform: none; }
  .cc-lv-tag.flip { animation: none; }
  .cc-lv-track { animation: none; }
  .cc-hb-liq .cc-liq-dot { animation: none; }
  .cc-chatdock-panel { animation: none; }
}

/* ═══════════ Premium landing (CC.flags.landingPremium — ships dark) ═══════════
   Light hero + tilted photo frames, white who's-going band, dark CTA band,
   footer. Spec + provenance: docs/design-handoff/08-landing-premium.md.
   Front-door rule: accent = the --acc family (never --cc-accent) out here. */
.cc-lp-browse { border: 0; background: none; cursor: pointer; font: 600 12.5px/1 var(--cc-font-soft); color: var(--cc-soft); padding: 8px 10px; }
.cc-lp-browse:hover { color: var(--cc-ink); }

.cc-lp-hero { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 44px; align-items: center;
  max-width: 1120px; margin: 0 auto; padding: 44px 28px 58px; }
.cc-lp .cc-hb-liq { color: var(--cc-soft); margin-bottom: 12px; }
.cc-lp .cc-hb-liq b { color: var(--cc-ink); }
.cc-lp-kick { font: 500 14px/1.4 var(--cc-font-soft); color: var(--cc-soft); }
.cc-lp-hero h1 { margin: 6px 0 0; font: 800 54px/1.02 var(--cc-font); letter-spacing: -.035em; color: var(--cc-ink); }
.cc-lp-dot { color: var(--acc); }
.cc-lp-hero p { margin: 16px 0 0; max-width: 400px; font: 500 14.5px/1.55 var(--cc-font-soft); color: var(--cc-soft); }
.cc-lp-hero p b { color: var(--cc-ink); }
.cc-lp-cta { display: flex; align-items: center; gap: 14px; margin-top: 26px; }
.cc-lp-go { width: 46px; height: 46px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--cc-grad-accent); color: #fff; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 14px -6px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.25); }
.cc-lp-go:hover { filter: brightness(1.05); }
.cc-lp-signup { border: 0; background: none; cursor: pointer; text-align: left; display: flex; flex-direction: column; gap: 3px;
  font: 700 14px/1.2 var(--cc-font); color: var(--cc-ink); padding: 6px 2px; }
.cc-lp-signup small { font: 500 11px/1 var(--cc-font-soft); color: var(--cc-muted); }
.cc-lp-login { border: 0; background: none; cursor: pointer; font: 600 13px/1 var(--cc-font-soft); color: var(--cc-soft); padding: 10px 12px; }
.cc-lp-login:hover { color: var(--cc-ink); }

/* Tilted photo frames — white polaroid lip, warm hairline, one crisp step.
   data-theme is set on <html> from localStorage before this page even
   renders (see index.html bootstrap), so a signed-out visitor who chose
   midnight still sees this landing frame in midnight — literal inset
   needs the same guard as the card fixes above or it's the same white-lip
   bug on the "polaroid" card. */
.cc-lp-frames { position: relative; min-height: 360px; }
.cc-lp-frame { position: absolute; margin: 0; background: var(--cc-surface); border: 1px solid var(--cc-line); border-radius: 10px;
  padding: 8px 8px 9px; box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 6px 16px -10px rgba(45,38,28,.28), 0 1px 3px rgba(45,38,28,.07); }
[data-theme="midnight"] .cc-lp-frame { box-shadow: 0 6px 16px -10px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.3); }
.cc-lp-frame.a { width: 190px; transform: rotate(-6deg); left: 0; top: 2%; z-index: 2; }
.cc-lp-frame.b { width: 290px; transform: rotate(2.5deg); right: 0; top: 0; }
.cc-lp-frame.c { width: 215px; transform: rotate(-2deg); left: 32%; bottom: 0; z-index: 3; }
.cc-lp-photo { border-radius: 6px; background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center; color: var(--cc-faint); }
.cc-lp-frame.a .cc-lp-photo { height: 185px; }
.cc-lp-frame.b .cc-lp-photo { height: 225px; }
.cc-lp-frame.c .cc-lp-photo { height: 145px; }
.cc-lp-photo.ph { background: linear-gradient(135deg, var(--cc-surface-2), var(--cc-chip) 55%, #E3DCCC); }
.cc-lp-frame-cap { margin-top: 7px; text-align: center; font: 600 9.5px/1 var(--cc-font-soft);
  letter-spacing: .06em; text-transform: uppercase; color: var(--cc-faint); }

/* Who's-going band — the vignette demo relocated onto a white band. */
.cc-lp-going { background: var(--cc-surface); border-top: 1px solid var(--cc-line-soft); border-bottom: 1px solid var(--cc-line-soft); padding: 40px 28px 46px; }
.cc-lp-going-head { max-width: 1120px; margin: 0 auto 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.cc-lp-going-head h2 { margin: 0; font: 800 24px/1.15 var(--cc-font); letter-spacing: -.02em; color: var(--cc-ink); }
.cc-lp-going-cap { font: 500 12px/1.4 var(--cc-font-soft); color: var(--cc-muted); }
.cc-lp-going-cols { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 34px; align-items: start; }
.cc-lp-disc { max-width: none; box-shadow: none; border: 1px solid var(--cc-line); cursor: pointer; }
.cc-lp-disc .cc-lv-go { background: var(--cc-grad-accent); color: #fff; }
.cc-lp-roles { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.cc-lp-rolechip { cursor: pointer; background: var(--cc-surface); border: 1px solid var(--cc-line); border-radius: var(--cc-radius-pill);
  padding: 8px 12px; font: 600 12px/1 var(--cc-font-soft); color: var(--cc-soft); }
.cc-lp-rolechip:hover { color: var(--cc-ink); border-color: var(--cc-ink); }
/* Roster rows: border-carried on white (no dark-ground fog), static (no rise). */
.cc-lp-stack .cc-lv-card { background: var(--cc-surface); border: 1px solid var(--cc-line); border-radius: 10px;
  box-shadow: var(--cc-shadow-card); animation: none; opacity: 1; transform: none; }

/* Projects grid: shared with 5a; premium adds the perk + lock (see JSX). */
.cc-lgc-perk { display: inline-flex; align-items: center; gap: 3px; margin-left: 8px; color: var(--cc-ok-ink); }
.cc-lgc-rate .ti { font-size: 11px; color: var(--cc-muted); margin-right: 3px; }

/* Dark CTA band — chrome sheet warming to accent on the right. */
.cc-lp-band { position: relative; overflow: hidden; max-width: 1120px; margin: 42px auto; border-radius: 14px;
  background: linear-gradient(100deg, var(--cc-chrome) 0%, var(--cc-chrome) 52%, #6B4A33 84%, var(--acc) 125%);
  padding: 34px 38px; display: flex; align-items: center; gap: 28px; }
.cc-lp-band-photo { position: absolute; inset: 0 0 0 38%; background-size: cover; background-position: center; opacity: .35;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 45%); mask-image: linear-gradient(90deg, transparent, #000 45%); }
.cc-lp-band-copy { position: relative; flex: 1; min-width: 0; }
.cc-lp-band-kick { font: 700 10.5px/1 var(--cc-font); letter-spacing: .09em; text-transform: uppercase; color: var(--cc-accent-onchrome); }
.cc-lp-band h2 { margin: 10px 0 0; font: 800 26px/1.12 var(--cc-font); letter-spacing: -.02em; color: var(--cc-chrome-ink); max-width: 440px; }
.cc-lp-band p { margin: 10px 0 0; font: 500 13px/1.4 var(--cc-font-soft); color: var(--cc-chrome-soft); }
.cc-lp-band p b { color: var(--cc-chrome-ink); }
.cc-lp-band-cta { position: relative; flex-shrink: 0; }

.cc-lp-foot { max-width: 1120px; margin: 0 auto; padding: 18px 28px 30px; display: flex; align-items: center;
  justify-content: space-between; gap: 14px; border-top: 1px solid var(--cc-line-soft); }
.cc-lp-foot .cc-wm { font-size: 16px; }
.cc-lp-foot-line { font: 500 12px/1.4 var(--cc-font-soft); color: var(--cc-muted); }

@media (max-width: 900px) {
  .cc-lp-browse { display: none; }
  .cc-lp-hero { grid-template-columns: 1fr; gap: 30px; padding: 28px 20px 40px; }
  .cc-lp-hero h1 { font-size: 38px; }
  .cc-lp-frames { min-height: 250px; }
  .cc-lp-frame.a { width: 145px; }
  .cc-lp-frame.b { width: 215px; }
  .cc-lp-frame.c { width: 165px; }
  .cc-lp-frame.a .cc-lp-photo { height: 140px; }
  .cc-lp-frame.b .cc-lp-photo { height: 165px; }
  .cc-lp-frame.c .cc-lp-photo { height: 110px; }
  .cc-lp-going-cols { grid-template-columns: 1fr; }
  .cc-lp-band { flex-direction: column; align-items: flex-start; margin: 30px 20px; }
}

/* ════════════════════════════════════════════════════════════════════
   PREMIUM PASS · de-pill + crisp controls
   --------------------------------------------------------------------
   One reversible block: delete it and the app reverts to the soft
   pill-heavy skin. Token-driven wherever the app already rides tokens;
   explicit overrides only where values were hardcoded upstream.
   Three decisions:
   1 · De-pill — --cc-radius-pill → 8px. Every filter chip, status pill,
       sort option, discovery capsule, credit pill, req/skill chip,
       badge and kicker becomes a crisp rectangle. Genuine circles
       (avatars, dots, round icon buttons, count bubbles) are guarded
       below and stay round.
   2 · One face — --cc-font-soft → var(--cc-font). Schibsted carries
       everything; hierarchy comes from weight + color, not a second
       family. Micro-labels keep their existing de-tracking.
   3 · Crisp edge — --cc-shadow-card retuned to a whisper (card fog
       removed app-wide), the edge carried by the calm skin's neutral
       --cc-line (warm tan retired, Tomas 2026-07-15), large-card radius
       crisped, hovers flattened to a crisp lift. Midnight and the legacy
       cool palettes keep their own lines; row/table dividers ride
       --cc-line-soft and stay light.
   ════════════════════════════════════════════════════════════════════ */

/* —— tokens —— */
:root {
  --cc-radius-pill: 8px;
  --cc-radius-lg: 10px;
  --cc-font-soft: var(--cc-font);
}
/* --cc-shadow-card lives in its own guarded rule, NOT the shared :root above.
   TRAP: this file loads after tokens.css, and an unguarded :root re-declare
   here ties on specificity with tokens.css's [data-theme="midnight"] block —
   later cascade wins, so a bare :root would silently defeat midnight's own
   whisper inset (rgba(255,255,255,.04)) with this 70%-white one, painting a
   glowing top edge on every dark card. Guarded the same way. */
:root:not([data-theme="midnight"]) {
  --cc-shadow-card: inset 0 1px 0 rgba(255,255,255,.7), 0 1px 2px rgba(45,38,28,.08);
}
/* —— 1a · de-pill: the 12 hardcoded 999px holdouts —— */
.cc-landing-liq,
.cc-inv-termstag,
.cc-hsec-pill,
.cc-avail-badge,
.cc-connect,
.cc-back,
.cc-create-in,
.cc-create .cc-create-top .cc-btn.primary,
.cc-create-chip,
.cc-create-up .cc-drop,
.cc-feedctl-seg { border-radius: var(--cc-radius-pill); }
/* Mobile discovery capsule hardcoded its own rounding — match the crisp set. */
@media (max-width: 760px) {
  .cc-disc, .cc-disc-hero .cc-disc { border-radius: var(--cc-radius-lg); }
  .cc-disc-seg, .cc-disc-seg:first-child { border-radius: var(--cc-radius-pill); }
}

/* —— 1b · genuine circles that rode the pill token: stay round —— */
.cc-msgbadge, .cc-convo-unread, .cc-chatdock-badge, .cc-chatdock-dot { border-radius: 999px; }
/* Skeletons: Sk now marks equal-sided round stand-ins (avatars, round
   buttons) with .rr — real avatars are 50% circles, their shimmer too. */
.cc-skel.rr { border-radius: 50%; }

/* —— 2 · one face: the lone rule tuned to the old soft face's wide fit —— */
.cc-vendor-name { letter-spacing: 0; }

/* —— 3a · crisp large cards: the Language-A 20px family (hardcoded, so the
       --cc-radius-lg flip can't reach them) —— */
.cc-hcard, .cc-offer, .cc-rprofile, .cc-rc, .cc-gigcard, .cc-gdcard, .cc-evcard,
.cc-evpanel, .cc-cwc, .cc-bk-tbl, .cc-invstat, .cc-inv-list, .cc-invoice,
.cc-appl-list, .cc-tourd-card, .cc-auth-card, .cc-lgc, .cc-home-rail,
.cc-jobs .cc-split2-panel .cc-embed, .cc-crewb .cc-split2-panel .cc-embed,
.cc-maxw.cc-prof .cc-card, .cc-savedv .cc-list, .cc-srch .cc-list,
.cc-invv .cc-card.cc-form, .cc-msgs .cc-msg, .cc-availc .cc-card,
.cc-tourp .cc-card, .cc-tourp .cc-tbl-wrap, .cc-setts .cc-card,
.cc-phv .cc-state, .cc-landing-projects > .cc-state { border-radius: var(--cc-radius-lg); }

/* —— 3b · overlays: crisp but still clearly floating —— */
.cc-modal { border-radius: 12px; }
.cc-menu, .cc-themepop, .cc-combo-menu { border-radius: 10px; }
.cc-themepop { border-color: #E4E3DF; } /* always-light popover, literal hexes by design */

/* —— 3c · cards that baked the OLD token fog inline: back onto the token —— */
.cc-offer, .cc-rprofile { box-shadow: var(--cc-shadow-card); }

/* —— 3d · elevated sheets: keep one step of depth, lose the fog —— */
.cc-embed,
.cc-jobs .cc-split2-panel .cc-embed, .cc-crewb .cc-split2-panel .cc-embed,
.cc-evpanel, .cc-invoice, .cc-invoice-mini,
.cc-disc-hero .cc-disc {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 6px 16px -10px rgba(45,38,28,.22), 0 1px 3px rgba(45,38,28,.06);
}
/* Literal (not token-driven) like the rest of 3d/3e, so it needs its own
   midnight guard — same white-lip trap as --cc-shadow-card above, just
   hand-rolled here. Matches the existing [data-theme="midnight"] .cc-modal
   precedent a few hundred lines up: drop the inset, keep the drop shadow. */
[data-theme="midnight"] .cc-embed,
[data-theme="midnight"] .cc-jobs .cc-split2-panel .cc-embed,
[data-theme="midnight"] .cc-crewb .cc-split2-panel .cc-embed,
[data-theme="midnight"] .cc-evpanel, [data-theme="midnight"] .cc-invoice,
[data-theme="midnight"] .cc-invoice-mini,
[data-theme="midnight"] .cc-disc-hero .cc-disc {
  box-shadow: 0 6px 16px -10px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.3);
}

/* —— 3e · hover/selected fog → crisp lift —— */
.cc-gigcard:hover, .cc-evcard:hover, .cc-cwc:hover {
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 3px 8px -2px rgba(45,38,28,.14), 0 1px 2px rgba(45,38,28,.07);
}
.cc-lgc:hover {
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 4px 10px -2px rgba(45,38,28,.16), 0 1px 2px rgba(45,38,28,.08);
}
.cc-gigcard.sel, .cc-evcard.sel, .cc-cwc.sel {
  box-shadow: 0 0 0 3px var(--cc-surface), 0 2px 6px -2px rgba(45,38,28,.18);
}
.cc-jobpost:hover { box-shadow: 0 3px 10px -6px rgba(45,38,28,.25); }
/* Same trap, hover state: same white lip would flash on hover over a dark
   card even with the resting state fixed above. */
[data-theme="midnight"] .cc-gigcard:hover, [data-theme="midnight"] .cc-evcard:hover,
[data-theme="midnight"] .cc-cwc:hover {
  box-shadow: 0 3px 8px -2px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.3);
}
[data-theme="midnight"] .cc-lgc:hover {
  box-shadow: 0 4px 10px -2px rgba(0,0,0,.48), 0 1px 2px rgba(0,0,0,.32);
}
/* ═══════════════════════ end PREMIUM PASS ═══════════════════════ */

/* ═══ SEARCH PILL unification + quick-bar (2026-07-15, after the premium
   pass so its radius re-token can't square the capsules; no accent vars —
   the landing accent-budget guard scans everything below Landing 5a) ═══ */
/* Every search is the SAME white Airbnb capsule, centered where it lives. */
.cc-disc, .cc-disc-hero .cc-disc { background: #fff; border-radius: 999px; }
.cc-disc-seg:first-child { border-radius: 999px 0 0 999px; }
.cc-disc-wrap .cc-disc { margin: 0 auto; }
/* board tabs row: the pill centers between the tabs and Post a gig */
.cc-octabs-tools { justify-content: center; }
/* top-bar global search: same capsule, centered in the chrome */
.cc-top .cc-search, .cc-topbar .cc-search {
  background: var(--cc-surface); border: 1px solid var(--cc-surface); border-radius: 999px;
  flex: 0 1 460px; margin-left: auto; margin-right: auto;
}
.cc-top .cc-search input, .cc-topbar .cc-search input { color: var(--cc-ink); }
.cc-search-kbd { color: var(--cc-muted); }
/* quick-bar controls */
.cc-rc-head .cc-rc-x {
  margin-left: 6px; width: 22px; height: 22px; border: 0; border-radius: 50%;
  background: none; color: #A09B90; display: inline-flex; align-items: center;
  justify-content: center; cursor: pointer; flex-shrink: 0; opacity: 0;
  transition: opacity .12s ease;
}
.cc-rc:hover .cc-rc-x { opacity: 1; }
.cc-rc-x:hover { background: var(--cc-surface-2); color: var(--cc-ink); }
.cc-rc-head { display: flex; align-items: center; }
.cc-rc-head .cc-rc-all { margin-left: auto; }
.cc-rc-adds { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.cc-rc-add {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: var(--cc-surface); border: 1px solid var(--cc-line-soft); border-radius: 999px;
  padding: 7px 13px; font: 500 12.5px/1 inherit; color: var(--cc-soft);
}
.cc-rc-add:hover { color: var(--cc-ink); border-color: var(--cc-line); }
/* card strokes: quiet hairline at rest (var(--cc-line), no override — the
   black ink border read as wireframe/outlined). Hover/focus steps ONE shade
   darker (still warm-neutral, no color moment) — the vermilion take shipped
   hours ago read as too much; Tomas wants subtle only (Tomas 2026-07-15).
   The transition lives on the BASE selectors so the fade runs both ways —
   on the hover rule alone, un-hovering snaps. */
.cc-hcard, .cc-rc, .cc-rprofile, .cc-jobs .cc-split2-panel .cc-embed, .cc-crewb .cc-split2-panel .cc-embed {
  transition: border-color .15s ease;
}
.cc-hcard:hover, .cc-hcard:focus-within, .cc-rc:hover, .cc-rc:focus-within, .cc-rprofile:hover, .cc-rprofile:focus-within, .cc-jobs .cc-split2-panel .cc-embed:hover, .cc-jobs .cc-split2-panel .cc-embed:focus-within, .cc-crewb .cc-split2-panel .cc-embed:hover, .cc-crewb .cc-split2-panel .cc-embed:focus-within {
  border-color: color-mix(in srgb, var(--cc-line) 78%, var(--cc-ink));
}
/* charcount clipped against the textarea edge — give it its own line */
.cc-charcount { margin-top: 4px; line-height: 1.4; padding: 0 2px 2px 0; }
/* ═══ end SEARCH PILL unification + quick-bar ═══ */

/* top-bar search: the WRAPPER is the flex child — center the capsule inside
   it (the earlier margin:auto sat on the label and had no room to act) */
.cc-search-wrap { flex: 1 1 auto; display: flex; justify-content: center; min-width: 0; }
.cc-search-wrap .cc-search { width: min(460px, 100%); }

/* WIZARD · Nova-north-star pass REMOVED (sandbox design revert, 2026-07-15)
   — the July 8 v3 wizard look (CC.views.PostGig) is the approved target for
   this component, so the Nova skin + PROPORTIONS scale that were scoped to
   .cc-postmodal are reverted here. The base .cc-postmodal / .cc-seg /
   .cc-raterange / .cc-formkick rules (unchanged, earlier in this file) now
   govern the wizard, which IS the July 8 look. Global field-stroke / nav
   tokens are deliberately left alone (Tomas's standing call). */
/* ═══ BOARD SEARCH: hero → docked choreography + isolated search row
   (2026-07-15, Tomas: "enlarge the search pill by 75%, drop it down … once
   you hit enter it animates to where it is now, but 25% larger … put the sort
   field on the right side of open calls and applications so the search bar is
   isolated"). ONE reversible block, appended last so nothing upstream can
   out-cascade it; all scoped to .cc-jobs so Crew/landing capsules are untouched.

   Sizes are REAL layout values (max-width / padding / font-size / diameter /
   margin) — NOT transform: scale — because the button-box probe measures real
   boxes and transform-scaled text overflows its layout box. Reference = the
   original base pill (input 13.5px, label 10px, seg-pad 9/20, go 46px, ≤720px
   wide) — the .cc-disc max-width 720px grid column this all traces back to.
     · docked  = that original base size (Tomas 2026-07-15: pulled back down
       from the interim 1.25× — the resting bar is the same size it always was)
     · hero    ≈ 1.25× that (25% over original, dropped down, the fresh-visit
       moment; submit animates it back down to the original docked size) ═══ */

/* The search row is the pill ALONE now (Sort + Post moved to the tabs row),
   so drop the old 3-column grid: a single centered capsule whose WIDTH is the
   per-state max-width lever. */
.cc-jobs .cc-ocbar { display: block; margin-bottom: 14px; }
.cc-jobs .cc-ocbar .cc-ocdisc { justify-content: center; padding: 0; }

/* One-shot animation on the REAL properties that change between the two states
   (~.35s). These sit on the base elements so they only fire on the class flip
   (hero→docked) — the initial mount already renders in its final state, so
   there's no first-paint animation. Layout below shifts up as it docks; that's
   the intended motion. */
.cc-jobs .cc-ocbar,
.cc-jobs .cc-ocdisc .cc-disc,
.cc-jobs .cc-ocdisc .cc-disc-seg,
.cc-jobs .cc-ocdisc .cc-disc-seg .lbl,
.cc-jobs .cc-ocdisc .cc-disc-seg input,
.cc-jobs .cc-ocdisc .cc-disc-go {
  transition: max-width .35s cubic-bezier(.4, 0, .2, 1), padding .35s cubic-bezier(.4, 0, .2, 1),
              font-size .35s cubic-bezier(.4, 0, .2, 1), width .35s cubic-bezier(.4, 0, .2, 1),
              height .35s cubic-bezier(.4, 0, .2, 1), margin .35s cubic-bezier(.4, 0, .2, 1),
              box-shadow .35s cubic-bezier(.4, 0, .2, 1);
}
@media (prefers-reduced-motion: reduce) {
  .cc-jobs .cc-ocbar,
  .cc-jobs .cc-ocdisc .cc-disc,
  .cc-jobs .cc-ocdisc .cc-disc-seg,
  .cc-jobs .cc-ocdisc .cc-disc-seg .lbl,
  .cc-jobs .cc-ocdisc .cc-disc-seg input,
  .cc-jobs .cc-ocdisc .cc-disc-go { transition: none; }
}

/* The enlargement only makes sense where there's room — desktop. At ≤980px the
   board is single-column and the capsule already stacks its segments full-width
   (existing .cc-ocbar mobile rules); there, hero == docked == today's stacked
   pill, so the hero can't blow the capsule wrap or leak page-width. */
@media (min-width: 981px) {
  /* DOCKED — the resting bar, the original base size. */
  .cc-jobs .cc-ocbar-docked { margin: 0 auto 14px; }
  .cc-jobs .cc-ocbar-docked .cc-ocdisc .cc-disc { max-width: 720px; }
  .cc-jobs .cc-ocbar-docked .cc-ocdisc .cc-disc-seg { padding: 9px 20px; }
  .cc-jobs .cc-ocbar-docked .cc-ocdisc .cc-disc-seg .lbl { font-size: 10px; }
  .cc-jobs .cc-ocbar-docked .cc-ocdisc .cc-disc-seg input { font-size: 13.5px; }
  .cc-jobs .cc-ocbar-docked .cc-ocdisc .cc-disc-go { width: 46px; height: 46px; }

  /* HERO — big + dropped down, ~25% over the original size. */
  .cc-jobs .cc-ocbar-hero { margin: 42px auto 30px; }
  .cc-jobs .cc-ocbar-hero .cc-ocdisc .cc-disc {
    max-width: 748px;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 22px 44px -20px rgba(45, 38, 28, .22), 0 2px 5px rgba(45, 38, 28, .06);
  }
  .cc-jobs .cc-ocbar-hero .cc-ocdisc .cc-disc-seg { padding: 11px 24px; }
  .cc-jobs .cc-ocbar-hero .cc-ocdisc .cc-disc-seg .lbl { font-size: 11px; }
  .cc-jobs .cc-ocbar-hero .cc-ocdisc .cc-disc-seg input { font-size: 16px; }
  .cc-jobs .cc-ocbar-hero .cc-ocdisc .cc-disc-go { width: 50px; height: 50px; }
}

/* Sort + Post a gig now ride the RIGHT of the Open-calls / Applications tabs
   row, so the search bar reads isolated. Bottom-align so the tabs' active
   underline stays glued to the row's border-bottom even if a tool is taller. */
.cc-jobs .cc-octabs2 { align-items: flex-end; }
.cc-octabs-right { margin-left: auto; display: flex; align-items: center; gap: 10px; padding-bottom: 4px; }
.cc-octabs-right .cc-btn { white-space: nowrap; flex-shrink: 0; }
/* .cc-fsort's margin-left:auto was for the old in-pill placement — the group
   already right-aligns itself, so neutralize it here. */
.cc-octabs-right .cc-fsort { margin-left: 0; }
@media (max-width: 760px) {
  /* Let the tools wrap under the tabs instead of leaking page width at 390px. */
  .cc-jobs .cc-octabs2 { flex-wrap: wrap; }
  .cc-octabs-right { padding-bottom: 0; margin-top: 8px; }
}
/* Split view: the detail pane owns half the width, so the LIST column is
   ~460px — tabs + sort + Post a gig can't share a line there ("Open calls"
   wrapped, the button clipped under the pane). Same wrap treatment as
   mobile, keyed off the split being open rather than the viewport. */
.cc-boardsplit:not(.closed) .cc-octabs2 { flex-wrap: wrap; }
.cc-boardsplit:not(.closed) .cc-octabs-right { padding-bottom: 0; margin-top: 8px; }
/* ═══ end BOARD SEARCH hero → docked ═══ */

/* Search-pill inner divider goes black (Tomas 2026-07-15: sharp B&W — the
   Role|Where|When accent line can be black). Token-driven off --cc-ink so
   midnight still resolves correctly; only the color changes, the existing
   22%-inset hairline geometry (base rule above, ~L2534) is untouched. */
.cc-disc-seg + .cc-disc-seg::before { background: var(--cc-ink); }

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE LANDING FIX PASS (fix/mobile-landing) — deliberately the LAST
   block in the file.
   ------------------------------------------------------------------------
   The "SEARCH PILL unification" pass above (~line 5731) added an
   UNCONDITIONAL `.cc-disc, .cc-disc-hero .cc-disc { border-radius: 999px;
   background: #fff; }` — a hardcoded literal, not the --cc-radius-pill
   token — with the same specificity as, but later source order than, the
   ≤760px de-pill softener at ~5651. Equal specificity + later position
   wins at EVERY viewport, so it silently undid the stacked-mobile
   treatment and turned the hero search into a full ellipse ("blob") with
   a hardcoded-white capsule (the exact midnight-readability trap already
   called out at ~line 2511). Every rule below is scoped inside a
   max-width query, so desktop is byte-for-byte unaffected; it only wins
   the mobile cascade by sitting later in the file than the offender.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 760px) {
  /* Re-assert the SAME token-driven values the de-pill pass already
     settled on at ~5651-5652 (var(--cc-radius-lg)=10px, var(--cc-radius-
     pill)=8px post de-pill) — just positioned after the hardcoded 999px
     literal so they win. Surface token, not #fff, for theme safety. */
  .cc-disc, .cc-disc-hero .cc-disc { border-radius: var(--cc-radius-lg); background: var(--cc-surface); }
  .cc-disc-seg, .cc-disc-seg:first-child { border-radius: var(--cc-radius-pill); }

  /* The logged-in board's docked search card ('.cc-ocdisc .cc-disc',
     ~app.css:5092) hardcodes its OWN unconditional 999px/#fff at
     specificity (0,2,0) — one class higher than the re-assert directly
     above, so it silently won the mobile cascade on /gigs and /jobs and
     rendered as a full ellipse blob. Match its specificity here (still
     inside this media query, still after it in source) so this wins. */
  .cc-ocdisc .cc-disc, .cc-disc-hero .cc-disc { border-radius: var(--cc-radius-lg); background: var(--cc-surface); }
  /* Same story for the board's first-segment cap: '.cc-ocdisc .cc-disc-
     seg:first-child' (~app.css:5093) is (0,3,0) and kept a 999px-rounded
     left edge — a pill cap glued onto an otherwise crisp stacked column.
     Match its specificity too. */
  .cc-ocdisc .cc-disc-seg:first-child { border-radius: var(--cc-radius-pill); }
  /* The board's go button collapsed too: '.cc-ocbar .cc-disc-go'
     (~app.css:5284, inside its OWN ≤980px query) sets height:auto at
     (0,2,0) — one class higher than the existing ~4525 fix's plain
     '.cc-disc-go' (0,1,0) — so on /gigs and /jobs the "Search" button
     shrank to a ~20px sliver (just the ::after text's line box, no
     button chrome) instead of the full-width 46px bar. Match its
     specificity so the real button height wins again. */
  .cc-ocbar .cc-disc-go { width: 100%; height: 46px; margin: 8px 0 0; align-self: stretch; }

  /* .cc-lv-go (the landing-vignette search dot) is a bare SPAN, not
     .cc-disc-go — the existing ≤760px "full-width Search bar" fix at
     app.css ~4525 targets the .cc-disc-go class only, so it never
     reached this one and it floated as a lone 38px circle under the
     stacked ROLE/WHERE/WHEN segments. Mirror the .cc-disc-go mobile
     pattern exactly: full-width bar + a "Search" label. Purely
     decorative (aria-hidden — the whole .cc-disc is the real click
     target via CC.ui.clickable), so no markup change needed; color
     inherits from whichever variant is active (neutral ink circle here,
     or var(--cc-grad-accent) on .cc-lp-disc .cc-lv-go). */
  .cc-lv-go {
    width: 100%; height: 46px; border-radius: var(--cc-radius-md);
    margin: 8px 0 0; align-self: stretch; gap: 8px;
  }
  .cc-lv-go::after { content: 'Search'; font: 600 14px/1.2 var(--cc-font); }

  /* Tight-button glyph safety (line-height >= 1.2, never bare /1) —
     mobile-only per the desktop-pixel-identical rule; matches the /1.2
     convention already used at app.css:2533 (.cc-disc-seg input). */
  .cc-landing-actions .cc-btn,
  .cc-landing-foot .cc-btn.lg,
  .cc-create .cc-create-top .cc-btn.primary,
  .cc-jobpost .cc-btn.primary.sm { line-height: 1.2; }

  /* Micro-label legibility floor: '.cc-disc-seg .lbl' (~app.css:2529) and
     '.cc-auth-demo .lbl' (~app.css:4157) are both unconditional (0,2,0)
     and compute 10px / 10.5px respectively at phone widths — below a
     comfortable reading floor for an all-caps micro-label. Same
     specificity, later in the file, so this wins; keep the existing font
     shorthand style (weight/family/tracking) and just lift the size. */
  .cc-disc-seg .lbl { font: 600 11px/1.2 var(--cc-font-soft); letter-spacing: .1em; text-transform: uppercase; }
  .cc-auth-demo .lbl { font: 600 11px/1.2 var(--cc-font-soft); letter-spacing: .1em; text-transform: uppercase; }
}

@media (max-width: 430px) {
  /* Crew-card meta line ("Monitor Engineer · ★ 4.9 · Already going") was
     silently ellipsis-truncating the rating/availability half at every
     phone width, even at default font size. Let it wrap to a second
     line instead of clipping content — the row already has room to grow
     (.cc-lv-card centers its children). */
  .cc-lv-id .m { white-space: normal; overflow: visible; text-overflow: clip; }
}

@media (max-width: 400px) {
  /* GigBoard header (/jobs and /gigs share tabsRow): Sort (~202px) +
     Post a gig (~112px) don't fit the row's slot at 320px and pushed
     "Post a gig" past the viewport edge (clipped to "+ Post a"). Let
     Post a gig wrap under Sort — each fits its own line comfortably.
     flex-wrap only engages once content overflows, so this is a no-op
     at ≥375px, where the row already fit cleanly. */
  .cc-octabs-right { flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
}
/* ═══ end MOBILE LANDING FIX PASS ═══ */

/* ═══════════════════════════════════════════════════════════════════════
   TOP BAR ICON BUDGET — 320px × crew persona × drill-in routes
   ------------------------------------------------------------------------
   The worst-case bar (crew's extra Credits pill + a drill-in route's back
   arrow) carries ~372px of controls at a 320px viewport — measured live:
   the account chip's right edge lands at 351px (or ~377px once the search
   wrap's flex-crush is fixed), clipping it off-screen with no scrollbar —
   an invisible, unreachable control. The ≤400px compaction pass (~line
   4665) already flagged that closing this needs an icon DROPPED, not more
   padding shaved (tap targets are at their floor). So, by usage frequency
   and redundancy, two controls collapse instead of squeezing the rest:

   1) The theme palette leaves the top bar on ALL phones (≤640px) — it's a
      set-once control. It moves into the account menu (RoleSwitcher in
      components.js renders a .cc-menu-theme section, hidden by the base
      rule below until this query reveals it), reusing the popover's own
      .cc-lookgrid rows. One home per form factor; frees ~37px everywhere,
      which also gives the 375-430px range real headroom.

   2) The "+" Post-a-job button hid at ≤360px ONLY (narrowest phones) —
      RETIRED (2026-07-16): with both economy pills gone (see below) the
      "+" fits at every width, so this collapse is no longer needed.
      RE-INSTATED (round 5, 2026-07-16): adding the Home icon (burger ·
      search · + · home · jobs · messages · bell · account) puts one more
      33px+gap control back in the bar. Measured live at 320px/crew/
      drill-in with Home in place: the account chip's right edge lands at
      333px — 13px off-screen with no scrollbar, the exact invisible-
      control failure mode this section exists to prevent. Same fix as
      before and the same rationale for picking THIS control: the burger
      rail's full-width "Post a job" dock button (CreateMenu
      variant="dock") keeps the action two taps away, so 320-360px phones
      lose nothing but a shortcut; 375px+ phones keep the top-bar "+".

   Kept on purpose: envelope + bell (live badges, high frequency), back
   arrow, burger, search, home. Measured after re-instating the ≤360px
   "+" collapse (crew, #/settings, drill-in, 320px): account chip right
   edge back at 300px, 20px margin at 360/375/430, docScrollWidth clamped.

   Rule (2026-07-16): economy counters (applies-left, pro-unlocks) never
   render in the top bar — counts stay contextual (account-menu stats row,
   gig-detail apply/unlock CTAs, board banner). So pro-gate go-live no
   longer threatens this budget on its own — see the Home-icon note above
   for what DOES.
   ═══════════════════════════════════════════════════════════════════════ */
.cc-menu-theme { display: none; }
@media (max-width: 860px) {
  /* Surfaced while measuring: the burger — the ONLY nav opener on phones —
     paints in var(--cc-soft) (page ink, from its light-bar-era base rule at
     ~line 652) on the Phase-2 dark chrome bar: computed 27,25,21 on 27,25,21,
     literally invisible on the standard look. Use the chrome palette like
     its top-bar siblings (.cc-bell) so it reads on every look. */
  .cc-burger { color: var(--cc-chrome-soft); }
}
@media (max-width: 640px) {
  .cc-themepop-wrap { display: none; }
  .cc-menu-theme { display: block; border-top: 1px solid var(--cc-line); margin-top: 4px; padding-top: 4px; }
}
/* Re-instated round 5 (2026-07-16, see note 2 above): the Home icon pushed
   the 320px worst case back over budget. Narrowest phones drop the
   top-bar "+" — the burger rail's own full-width "Post a job" dock button
   keeps the action reachable in two taps. */
@media (max-width: 360px) {
  .cc-topcreate { display: none; }
}
/* Round 5, continued: the ≤360px collapse above only covers the TOP-LEVEL-
   route worst case (no back arrow). A DRILL-IN route adds the back arrow
   ON TOP OF Home, and that combination overflows across a much wider band
   than 360px, and by more than hiding "+" alone buys back — measured live
   (crew, #/settings, "+" already hidden by the rule above): 320px still
   overflows by 13px. Widening the ≤360px query doesn't help there (the
   deficit persists even with "+" gone); it also doesn't help 375-430px,
   where "+" is still visible and its own removal wouldn't even apply
   (icons/gaps grow at the >400px breakpoint faster than the viewport
   does — worst measured -4px at 430px, a real device width: iPhone 14/15
   Pro Max). Top-level routes (no back arrow) stay clear through this
   whole band (408px right edge at 430px, 22px margin) — it's specifically
   back-arrow+Home that doesn't fit. Of the two, Home is the one to drop:
   a drill-in page already carries its own way back, and every one of
   Home's actual destinations (feed, dashboard) is reachable from there in
   one tap via the burger rail regardless. Scope the same :has() idiom as
   .cc-modal-bg:has(.cc-postmodal) (ROUND 2 block below) so it only fires
   alongside a back arrow — top-level routes keep Home at every width, and
   375-640px drill-ins keep the top-bar "+" too, since removing Home alone
   is enough. Re-verified clear at every width 320-640 with a back arrow
   showing after this rule (24px+ margin throughout, "+" hide above still
   independently covers the ≤360px top-level case). */
@media (max-width: 640px) {
  .cc-top:has(.cc-topback) .cc-homebtn { display: none; }
}
/* ═══ end TOP BAR ICON BUDGET ═══ */
/* ═══════════════════════════════════════════════════════════════════════
   MOBILE FIX PASS ROUND 2 (rescued 2026-07-16) — deliberately the LAST
   block in the file, so it wins any equal-specificity cascade fight with
   earlier unguarded rules. Everything here is scoped inside a max-width
   query; desktop is byte-for-byte unaffected.

   Provenance: authored + verified in the 2026-07-15 mobile round's session
   (fixes 2/3/4 of its four-item pass); extracted and shipped from here
   because it was stranded uncommitted in that session's scratchpad
   worktree. Its fix 1 (theme-popover left-edge clamp) and its ≤430px
   icon-squeeze are NOT carried over: both became dead rules once the
   palette moved into the account menu at ≤640px (#250) and the economy
   counter pills left the top bar entirely (counters-off-topbar, Tomas
   2026-07-16) — the bar now fits every width at full tap-target sizes.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* 2) Back button / collapsed search overlap on drill-in routes (Settings,
     wizard, …). Root cause: two LATER, UNGUARDED (no media query)
     `.cc-search-wrap` rules — one from the "Phase 2 chrome" .cc-top
     rewrite (~line 2110: flex:1;max-width:420px;position:relative) and
     one from the 2026-07-15 "SEARCH PILL unification" pass (~line 5826:
     flex:1 1 auto;display:flex;justify-content:center;min-width:0) — sit
     later in source than this file's OWN ≤640px reset (~line 1195) at
     equal specificity, so they silently win on mobile too. The
     min-width:0 in particular removes the flex item's default min-width
     floor, so under icon-budget pressure the wrap gets crushed toward
     0px, dragging the 36px collapsed search circle left until it overlaps
     the adjacent back arrow. Re-assert every property both offending
     rules touch, one more time, after both of them. This also restores
     .cc-search-wrap to position:static, which is what makes
     .cc-search.expanded's `left:14px;right:14px` resolve against the
     full-width .cc-top bar instead of the crushed wrap. */
  .cc-search-wrap {
    flex: 0 0 auto; max-width: none; position: static;
    display: block; justify-content: normal; min-width: 0;
  }

  /* 3) Expand animation + a visible, discoverable close (X). The collapse/
     expand toggle worked but snapped instantly (no transition anywhere
     near .cc-search), and the only ways to close it were onBlur / Enter /
     Escape — none of them a visible affordance ("obvious x button to
     close out of the animated text input field"). The expanded box is
     already laid out at its final position:absolute rect the instant the
     class flips (no valid "from" value exists for left/right coming out
     of the collapsed box's position:static, so transitioning those two
     properties directly wouldn't animate) — so the open motion is done
     with a clip-path reveal instead: the box is already full-size and
     positioned, and the animation just wipes the reveal from the left
     edge (near where the collapsed circle sat) across to the right,
     rounded to match the field's own corners. Reduced-motion users get a
     plain instant show. The close button is only ever rendered by React
     while .expanded is applied (TopBar in components.js), so it never
     reaches desktop. */
  .cc-search.expanded {
    animation: cc-search-open .22s cubic-bezier(.4, 0, .2, 1) both;
    /* Caught by the rescue's CDP walk: the unguarded `.cc-search-wrap
       .cc-search { width: min(460px, 100%) }` (~line 5831, the #210 search
       pill pass) ties width at (0,2,0) — equal specificity, later source —
       beating the ≤640 expanded rule's width:auto (~line 1205), so the
       expanded box obeyed left:14px but IGNORED right:14px and hung 2px
       past the viewport at 320/375. Re-assert width here, after it, so
       both insets bind again. */
    width: auto;
  }
  .cc-search-x {
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0; width: 26px; height: 26px; margin-left: 2px;
    border: 0; border-radius: 50%; background: none; cursor: pointer;
    color: var(--cc-chrome-soft);
  }
  .cc-search-x:hover, .cc-search-x:focus-visible { background: var(--cc-chrome-line); color: var(--cc-chrome-ink); }
}
@keyframes cc-search-open {
  from { clip-path: inset(0 62% 0 0 round 12px); }
  to   { clip-path: inset(0 0 0 0 round 12px); }
}
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  .cc-search.expanded { animation: none; }
}

@media (max-width: 640px) {
  /* 4) Wizard (.cc-postmodal) close control could render above the fold.
     .cc-modal-bg switches to align-items:flex-end on mobile (a bottom
     sheet) while .cc-postmodal caps itself at max-height:92vh — computed
     against the browser's LARGE/layout viewport, not whatever's actually
     visible once the address bar/toolbar are expanded (their default
     state right after a tap, before any scroll gesture has collapsed
     them). Because the sheet is bottom-anchored, any shortfall between
     the layout and visual viewport eats into the sheet's TOP first — the
     header, which carries the only ✕. Dock the sheet to the top instead
     (so there's no bottom-anchored gap for chrome to eat into) and use
     100svh (small-viewport-height, guaranteed to fit within the smallest
     space mobile chrome will ever leave) as a progressive-enhancement
     max-height; browsers without svh support silently ignore that line
     and keep the 92vh fallback right above it. Belt-and-suspenders: pin
     the header itself so a future refactor of what scrolls inside the
     sheet can't push it away either. */
  .cc-modal-bg:has(.cc-postmodal) { align-items: flex-start; }
  .cc-postmodal { max-height: 92vh; max-height: 100svh; }
  .cc-postmodal-head { position: sticky; top: 0; z-index: 2; background: var(--cc-surface); }

  /* The ✕'s tap target was ~26x26px (18px icon + 4px padding) at low
     contrast (--cc-muted) — easy to miss in the corner of a tall sheet.
     Enlarge just the hit box (negative margin keeps it visually anchored
     against the head's existing padding) without touching desktop. */
  .cc-postmodal-head .cc-modal-x { padding: 11px; margin: -11px -8px 0 0; }
}
/* ═══ end MOBILE FIX PASS ROUND 2 ═══ */

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE FIX PASS ROUND 3 — deliberately the LAST block in the file
   (recon already measured everything; this only implements).
   ------------------------------------------------------------------------
   1) iOS-ZOOM INPUT FLOOR (Tomas: "when you tap search, it zooms in on
      the page"). iOS Safari auto-zooms the viewport on focus whenever a
      form control's COMPUTED font-size is <16px. Every text-bearing
      field in the app sits below that floor on phones — .cc-input/
      .cc-select/.cc-textarea at 13.5px (~line 2443), .cc-search input at
      13.5px (inherited via font:inherit from .cc-search, ~line 2131),
      .cc-create-in at 13.5px (~line 4726), the login/signup .cc-fld
      input+select at 14px (~line 625), the discovery-search .cc-disc-seg
      input at 13.5px (~lines 817/2573), and Settings' own higher-
      specificity .cc-setts-invrow .cc-input at 13px (~line 4086, two
      classes — needs matching specificity to win, a plain .cc-input
      re-assert isn't enough). Bumping to exactly 16px is the minimum
      that clears the WebKit threshold without visibly changing the type
      scale more than necessary. Desktop is untouched (media-gated).
      (The .cc-jobs hero disc input's OWN 16px at ~line 5914 already
      satisfies this — it lives inside a min-width:981px desktop query,
      so it doesn't do any of this block's mobile work, but it's already
      compliant and harmless to leave.)
   2) TOP-BAR JOBS ICON — see the .cc-jobsbtn rule below.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .cc-input, .cc-textarea, .cc-select,
  .cc-search input,
  .cc-create-in,
  .cc-fld input, .cc-fld select,
  .cc-disc-seg input,
  .cc-setts-invrow .cc-input,
  /* Bare (un-classed) sort <select>s the first pass missed — iOS zooms on
     select focus below 16px too. The .cc-jobs/.cc-crewb-scoped variants
     (~line 2623) are (0,2,1), so they're listed at matching specificity. */
  .cc-sortwrap select, .cc-feedctl-sort select,
  .cc-jobs .cc-sortwrap select, .cc-crewb .cc-sortwrap select {
    font-size: 16px;
  }
  /* .cc-create-in hardcodes line-height:1 (~line 4726, a pill-shaped
     single-line field) — fine at 13.5px but tight enough at 16px to
     nick descenders (g/y/p) in the placeholder. Re-assert the same
     ≥1.2 floor the app's other text-box rules already use (e.g.
     .cc-disc-seg input's own /1.2, ~line 817) rather than leaving the
     shorthand's line-height:1 in place. Every other field in this list
     already inherits an unconstrained ("normal") line-height that
     scales with its own font-size, so only this one needs it. */
  .cc-create-in { line-height: 1.2; }
  /* Handle-claim field (Settings): the "callsheet.gg/u/" prefix span has no
     font-size of its own, so the OS text-size boost (probe's font-20 sweep)
     grows it until the flex-sibling input clips to ~68px ("yourr…"). Pin the
     prefix — it's decorative context, not user input — and give the input
     the flex min-width floor so it always keeps the leftover width. */
  .cc-ig-input .at { flex-shrink: 0; font-size: 12.5px; }
  .cc-ig-input .cc-input { min-width: 0; }
}

/* Top-bar Jobs shortcut — reveal on phones (base display:none is set
   near .cc-msgbtn, ~line 1613). Same .cc-bell icon-button shell as the
   message envelope / bell it sits next to. */
@media (max-width: 640px) {
  .cc-jobsbtn { display: flex; }
}
/* ═══ end MOBILE FIX PASS ROUND 3 ═══ */

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE FIX PASS ROUND 4 — deliberately the LAST block in the file.
   ------------------------------------------------------------------------
   1) Own-profile section order (Skills/Events/Links above Activity) is a
      JSX reorder in views.js (CrewProfile) — Activity now renders as its
      own full-width row below the .cc-pcols 2-column grid instead of
      mid-column-1, so it can no longer land ~2-3 screens above the
      identity-fact cards once the grid collapses to one column. No CSS
      needed for that fix.
   2) NOTIFICATIONS DROPDOWN clipped off the LEFT edge at 320-430px — the
      bell's `.cc-rswrap` sits ~2/3 across the bar (NOT flush against the
      viewport edge; the avatar chip sits further right), while
      `.cc-notemenu` is a wide (320-360px) `right:0`-anchored panel
      (base rules ~line 60/700) — so it opens leftward and ~50px clips
      off-screen. Same idiom as the mobile expanded search overlay
      (`.cc-search.expanded`, ROUND 3 block above): cancel the wrapper's
      own `position:relative` so `.cc-notemenu`'s `position:absolute`
      resolves against `.cc-top` (sticky — the next positioned ancestor,
      Bell renders as a direct child of it) instead of the narrow wrap,
      then pin it to the viewport with symmetric insets.
   3) TOP-BAR ICON SPACING irregular at ≤640px — the base `.cc-rswrap`
      rule (~line 53) carries `margin-left:auto`, meant to push exactly
      ONE right-aligned cluster away from `.cc-spacer`. On phones the
      spacer is switched off (`.cc-spacer{display:none}`) in favour of
      `.cc-top{gap:8px}` doing the even-spacing job — but THREE separate
      elements share the `.cc-rswrap` class (ThemePopover, Bell,
      RoleSwitcher/avatar) and each independently claims the row's
      leftover space at its own position, producing an irregular
      ~4px/34px/33px gap pattern instead of one uniform 8px. Cancelling
      the auto-margin on every `.cc-rswrap` and re-adding it ONLY on the
      LAST one (RoleSwitcher/avatar, always last in DOM order — see the
      TopBar render order in components.js) lets `gap` do the even-
      spacing job for burger→search→create→jobs→msg→bell, while the
      avatar still claims the row's leftover space to stay pinned at the
      right edge, same as before (just from one element instead of three).
   4) COMPOSER PLACEHOLDER truncation — see the JSX note in views.js
      (FeedComposer) for the string choice. Here: reclaim the camera
      button's reserved 38px+gap slot while the box is idle (it normally
      holds that space open at ALL widths so the row never jumps when you
      focus it — see the PhotoPicker comment above, ~line 4776 — but on a
      phone the input is already down to ~37-92px and needs every pixel
      more than it needs zero-jump). `text-overflow:ellipsis` on the input
      itself is the belt-and-suspenders: whatever's left always ends on a
      clean "…" instead of a raw mid-word cut, even under the OS's largest
      text-size setting.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .cc-rswrap { margin-left: 0; }
  .cc-top > .cc-rswrap:last-of-type { margin-left: auto; }

  /* Break the bell's own positioned-ancestor status so its dropdown
     resolves against .cc-top instead (see note 2 above). */
  .cc-bellwrap { position: static; }
  .cc-notemenu {
    position: absolute; left: 14px; right: 14px; top: calc(100% + 6px);
    width: auto; min-width: 0; max-width: none;
  }

  .cc-create-in { overflow: hidden; text-overflow: ellipsis; }
  .cc-create-cam:not(.show) { width: 0; margin-right: -9px; padding: 0; }
  /* Post's own padding (11px 18px, ~line 4757) is generous desktop tap-
     target sizing — the composer row can't spare 36px of it once the
     camera slot is reclaimed above, so trim it here. "Post" still reads
     fine at 9px/12px; the button stays a comfortable ~34px tall tap
     target either way. Buys back a few px of margin for the placeholder
     fit above 320px's razor-thin budget. */
  .cc-create .cc-create-top .cc-btn.primary { padding: 9px 12px; }
}
/* ═══ end MOBILE FIX PASS ROUND 4 ═══ */

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE FIX PASS ROUND 5 — deliberately the LAST block in the file.
   ------------------------------------------------------------------------
   1) SEARCH ✕ FOCUS — no CSS change; see components.js (the ✕'s onClick)
      for the fix. Confirmed here first: nothing in this file ties
      .cc-search/.cc-search-wrap's expanded look to :focus or
      :focus-within (grepped) — the collapse is class-driven only, so the
      real-device stuck-open bug was the still-focused input, not CSS.
   2) TOP-BAR HOME ICON (Tomas, real iPhone: burger · search · + · home ·
      jobs · messages · bell · account). Same reveal idiom as Jobs (Round
      3, ~line 6307) — base display:none lives with Jobs' own near
      .cc-msgbtn, revealed here.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .cc-homebtn { display: flex; }
}
/* ═══ end MOBILE FIX PASS ROUND 5 ═══ */

/* ═══════════════════════════════════════════════════════════════════════
   === ACCT MOBILE R5 ===
   Accounting round 5 — mobile walk (375px primary, 320px spot-check) of
   Dashboard/Invoices/New-invoice/InvoiceDetail/Estimates/Expenses/Clients/
   Reports/Settings. Real findings, measured via a headless CDP walk under
   the `working` (fr_marcus) demo persona (the `hiring` default persona has
   zero seeded invoices/clients/expenses/gear — nothing to actually drive):

   1) .acct-line (InvoiceForm/EstimateForm line-item row) — the desktop/
      tablet 6-column grid (name, category, qty, price, amount, remove)
      keeps fixed pixel widths for 5 of its 6 columns; on a phone the
      minmax(0,1fr) item-name/RolePicker column has nothing left and
      measured 0px wide (confirmed 0–36px all the way from 320px up to a
      ~530px container) — not just visually cramped: the RolePicker's own
      dropdown menu sizes to that same ~0px parent, so its "Use “…”"
      custom-entry option rendered 96–183px of text inside a ~24px box, a
      real button-box-contract violation (probe: `h-overflow 96>24` /
      `183>24`). The Amount figure and the remove (×) button additionally
      render past the 6th squeezed column's edge, past the viewport, and
      are only reachable by discovering a swipe inside the form card (it
      absorbs the overflow via the app-wide mobile `.cc-card{overflow-x:
      auto}` fallback — contained, but nothing hints it's there). Fix:
      stack each line into two full-width rows (name, then category) plus
      a qty/price row and an amount/remove row, via grid-area placement on
      the EXISTING DOM order (acct.js untouched) rather than a 6-across
      squeeze.
   2) .acct-editor-head — the "New invoice"/"New estimate" title vs. the
      Invoice|Estimate kind-toggle share a non-wrapping flex row; the
      toggle's "Estimate" segment gets pushed off the card's (scrollable,
      not visibly so) right edge and reads as clipped to "Estimat". Let it
      wrap under the title instead.
   3) .acct-doc-frame (InvoiceDetail's on-page document — "exactly what
      Download PDF makes", per acct.js) — invoice-doc.js is inline-styled
      HTML built for a fixed ~760px canvas (byte-identical to the PDF), on
      purpose not responsive. `.acct-doc-frame{width:100%}` squeezes it
      down to the card's ~270–300px mobile width instead, starving its
      two-column header table (title vs. total figure) — the columns
      visibly collide/overlap rather than cleanly overflowing. The doc's
      own stage (.acct-doc-stage) already carries overflow-x:auto for
      exactly this shape of content; restoring the frame's natural width
      lets the doc lay out correctly (matching the PDF) and pan inside
      that existing scroll container instead of visually breaking.
   4) .acct-totals-fig — "Subtotal … · Tax … · Total $X" wrapped between
      "Total" and its figure at narrow widths. Keep that pair together.
   5) .acct-hero (every accounting PageHero) — align-items:flex-end can
      bottom-anchor a short 2-control action group (e.g. Reports' year
      picker + Print, which itself wraps to 2 rows) against a shorter
      title, so the first control floats visually above the heading with
      nothing broken but a confusing read. flex-start reads top-down.
   6) .acct-plaintable (Dashboard "Needs attention"/"Income by category",
      Reports' P&L category cards) — a plain <table>, not the .cc-tbl-wrap
      primitive; tightened cell padding/font and truncated the two
      free-text columns so real rows fit the mobile card without leaning
      on the app-wide `.cc-card{overflow-x:auto}` fallback.

   Verified CSS-only, mobile-only (all under max-width media queries);
   desktop is untouched. One item could NOT be fixed here and needs JSX —
   see the report: the RolePicker's Qty/Price line-item fields have no
   persistent label (only a placeholder, which never shows once a value
   is typed) — pre-existing on desktop too, not a regression, not fixed.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) { /* raised from 560 — must cover the whole range the old 6-col rule owned */
  .acct-line {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "name name"
      "cat cat"
      "qty price"
      "amt del";
    row-gap: 8px;
    column-gap: 8px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--cc-line);
  }
  .acct-lines { gap: 4px; }
  .acct-line > *:nth-child(1) { grid-area: name; }
  .acct-line > *:nth-child(2) { grid-area: cat; }
  .acct-line > *:nth-child(3) { grid-area: qty; }
  .acct-line > *:nth-child(4) { grid-area: price; }
  .acct-line > *:nth-child(5) { grid-area: amt; }
  .acct-line > *:nth-child(6) {
    grid-area: del; justify-self: end;
    /* enlarge the tap target ~14px icon -> ~36px hit area without
       changing its visual size (negative margin cancels the padding). */
    padding: 11px; margin: -11px;
  }

  .acct-editor-head { flex-wrap: wrap; }
  .acct-totals-fig b { white-space: nowrap; }
}

@media (max-width: 640px) {
  .acct-doc-frame { width: auto; min-width: 760px; }
  .acct-hero { align-items: flex-start; }
  .acct-plaintable td { padding: 7px 6px; font-size: 12.5px; }
  .acct-plaintable td:nth-child(2) { max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .acct-plaintable td:nth-child(3) { max-width: 88px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
/* ═══ end ACCT MOBILE R5 ═══ */

/* ═══════════════════════════════════════════════════════════════════════
   === ACCT MOBILE TABS (round 7 — Tomas: mobile tab bar, no h-scroll) ===
   Two mobile-only additions inside acct.js's own pages (the nav bar itself
   is the ACCT SUB-NAV block above): a segmented Invoices/Estimates/Expenses
   switcher (keeps those three living contextually inside the mobile
   Invoices tab) and the Dashboard tool-card grid (the one mobile path to
   every tool, incl. Settings, which has no bar tab). Mobile-first: visible
   by default, hidden ≥861px (desktop pages render neither — they already
   have the acct-tabs/acct-pills and full dash-grid for the same jobs).
   ═══════════════════════════════════════════════════════════════════════ */
/* Sibling cards (round 8 — Tomas: "in page cards, not another nav bar
   inside"): on each of Invoices/Estimates/Expenses, two compact cards link
   to the OTHER two tools, dashboard tool-card idiom. */
.acct-sibcards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 14px; }

.acct-toolgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 18px; }
.acct-toolcard {
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start; min-width: 0;
  background: var(--cc-surface); border: 1px solid var(--cc-line); border-radius: var(--cc-radius-lg);
  padding: 14px; min-height: 40px; text-align: left; cursor: pointer;
}
.acct-toolcard-nm { font: 700 13.5px/1.2 var(--cc-font); color: var(--cc-ink); }
.acct-toolcard-stat {
  font: 500 12px/1.3 var(--cc-font-soft); color: var(--cc-soft);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (min-width: 861px) {
  .acct-sibcards, .acct-toolgrid { display: none; }
}
/* ═══ end ACCT MOBILE TABS ═══ */
/* ═══ iOS VIEWPORT SWEEP 2026-07-18 (Tomas, real iPhone: the Book-offer form
   "escapes the page") — the #282 drawer bug CLASS, hunted app-wide.
   vh sizes by the LAYOUT viewport, which on iOS Safari includes the strip
   behind the browser chrome; any overlay or height-locked panel sized with
   vh can push its heading above the visible top or hide its bottom-pinned
   controls behind the toolbar. dvh tracks the VISIBLE viewport; every vh
   line stays as the older-browser fallback.

   The Book-offer bug precisely: .cc-modal max-height:90vh + the phone
   bottom-sheet anchoring (.cc-modal-bg align-items:flex-end) hung a
   layout-viewport-sized sheet from behind Safari's toolbar — the footer
   (Cancel / Send offer) sat under the browser chrome and the heading was
   pushed off the top. ═══ */

/* Modal shell — every .cc-modal overlay app-wide. Overlay = visible height
   (flex-end then lands above the browser chrome); sheet capped to the
   visible height; safe-area pad clears the home indicator on phones. */
.cc-modal-bg { height: 100vh; height: 100dvh; }
.cc-modal { max-height: 90vh; max-height: calc(100dvh - 56px); }
@media (max-width: 640px) {
  .cc-modal-bg { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
}

/* Height-locked screens: the 100vh lock put the bottom-pinned composer /
   input row behind the toolbar on phones. */
.cc-main:has(.cc-msgs) { height: 100vh; height: 100dvh; }
.cc-main:has(.cc-boardsplit) { height: 100vh; height: 100dvh; }

/* Floating chat dock + lightbox: caps follow the visible viewport so their
   lower edge (input row / caption) stays reachable. */
.cc-chatdock-panel { max-height: calc(100vh - 110px); max-height: calc(100dvh - 110px); }
.cc-lb-fig { max-height: 88vh; max-height: 88dvh; }
.cc-lb-fig img { max-height: 80vh; max-height: 80dvh; }
.cc-lb-video { max-height: 80vh; max-height: 80dvh; }
/* ═══ end iOS VIEWPORT SWEEP ═══ */

