/* ============================================================
   Docket — design tokens
   Studio blueprint: ink ultramarine accent, neutrals biased blue,
   disciplines coloured by data (agencies define their own).
   ============================================================ */
:root{
  --paper:#F2F4F9; --surface:#FFFFFF; --surface-2:#F7F8FC;
  --rule:#DFE3EF; --rule-soft:#EAEDF6;
  --ink:#141827; --ink-2:#4A5168; --ink-3:#7A8199;
  /* Accent shares the landing page's violet, instead of the app's own
     unrelated blue — same brand, front stage and back office. */
  --accent:#7C3AED; --accent-2:#6425C9; --accent-wash:#F1E8FD; --on-accent:#fff;
  --grad:linear-gradient(135deg,#8328E2 0%,#CC29A7 50%,#EA5255 100%);
  --good:#0F7A4E; --good-wash:#E2F3EA;
  --warn:#A9660A; --warn-wash:#FBEEDA;
  --crit:#C22F26; --crit-wash:#FBE6E4;
  --display:"Helvetica Neue",Helvetica,"Arial Nova",Arial,sans-serif;
  --body:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  --shadow:0 1px 2px rgba(20,24,39,.06), 0 8px 24px -12px rgba(20,24,39,.18);
  --shadow-lg:0 2px 4px rgba(20,24,39,.08), 0 24px 56px -20px rgba(20,24,39,.32);
  --radius:9px; --hour:46px;
}
@media (prefers-color-scheme:dark){
  :root{
    --paper:#0C0F17; --surface:#141824; --surface-2:#1A1F2D;
    --rule:#283043; --rule-soft:#242B3A;
    --ink:#E8EBF4; --ink-2:#A6AEC5; --ink-3:#767F98;
    --accent:#A78BFA; --accent-2:#C4A6FF; --accent-wash:#241A3D; --on-accent:#170F28;
    --good:#4BC98C; --good-wash:#12291F;
    --warn:#E0A343; --warn-wash:#2C2214;
    --crit:#F0776C; --crit-wash:#2E1918;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
    --shadow-lg:0 2px 4px rgba(0,0,0,.5), 0 24px 56px -18px rgba(0,0,0,.75);
  }
}
:root[data-theme="dark"]{
  --paper:#0C0F17; --surface:#141824; --surface-2:#1A1F2D;
  --rule:#283043; --rule-soft:#242B3A;
  --ink:#E8EBF4; --ink-2:#A6AEC5; --ink-3:#767F98;
  --accent:#A78BFA; --accent-2:#C4A6FF; --accent-wash:#241A3D; --on-accent:#170F28;
  --good:#4BC98C; --good-wash:#12291F;
  --warn:#E0A343; --warn-wash:#2C2214;
  --crit:#F0776C; --crit-wash:#2E1918;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
  --shadow-lg:0 2px 4px rgba(0,0,0,.5), 0 24px 56px -18px rgba(0,0,0,.75);
}
:root[data-theme="light"]{
  --paper:#F2F4F9; --surface:#FFFFFF; --surface-2:#F7F8FC;
  --rule:#DFE3EF; --rule-soft:#EAEDF6;
  --ink:#141827; --ink-2:#4A5168; --ink-3:#7A8199;
  --accent:#7C3AED; --accent-2:#6425C9; --accent-wash:#F1E8FD; --on-accent:#fff;
  --good:#0F7A4E; --good-wash:#E2F3EA;
  --warn:#A9660A; --warn-wash:#FBEEDA;
  --crit:#C22F26; --crit-wash:#FBE6E4;
  --shadow:0 1px 2px rgba(20,24,39,.06), 0 8px 24px -12px rgba(20,24,39,.18);
  --shadow-lg:0 2px 4px rgba(20,24,39,.08), 0 24px 56px -20px rgba(20,24,39,.32);
}

*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;font-family:var(--body);font-size:14px;line-height:1.5;color:var(--ink);
  background:var(--paper);-webkit-font-smoothing:antialiased}
button{font:inherit;color:inherit;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
[hidden]{display:none !important}
@media (prefers-reduced-motion:reduce){*{animation:none !important;transition:none !important}}

/* ---------- atoms ---------- */
.eyebrow{font-family:var(--display);font-size:10px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3)}
.mono,.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
.num{letter-spacing:-.02em}
.pill{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;
  padding:2px 8px;border-radius:999px;white-space:nowrap}
.pill-good{background:var(--good-wash);color:var(--good)}
.pill-warn{background:var(--warn-wash);color:var(--warn)}
.pill-crit{background:var(--crit-wash);color:var(--crit)}
.pill-accent{background:var(--accent-wash);color:var(--accent)}
.pill-neutral{background:var(--surface-2);color:var(--ink-2);border:1px solid var(--rule)}
.dot{width:7px;height:7px;border-radius:50%;flex:none;display:inline-block}
.spacer{flex:1 1 auto}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;border:1px solid var(--rule);
  background:var(--surface);color:var(--ink);padding:8px 13px;border-radius:7px;font-size:13px;
  font-weight:600;transition:background .14s,border-color .14s,transform .1s;white-space:nowrap}
.btn:hover{background:var(--surface-2);border-color:var(--ink-3)}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.btn-primary:hover{background:var(--accent-2);border-color:var(--accent-2)}
.btn-danger{color:var(--crit);border-color:var(--rule)}
.btn-danger:hover{background:var(--crit-wash);border-color:var(--crit)}
.btn-sm{padding:4px 9px;font-size:12px;border-radius:6px}
/* Stopping a timer isn't destructive, so it shouldn't wear the danger red —
   but it is the one action on the row with a running clock behind it. */
.btn-warn{color:var(--warn);border-color:var(--warn)}
.btn-warn:hover{background:var(--warn-wash,var(--surface-2));border-color:var(--warn)}

/* ---- running timer chip (topbar) ---- */
.timer-chip{display:flex;align-items:center;gap:10px;padding:5px 6px 5px 12px;
  border:1px solid var(--rule);border-radius:999px;background:var(--surface);
  box-shadow:var(--shadow-sm,none)}
.timer-chip[hidden]{display:none}
.timer-dot{width:8px;height:8px;border-radius:50%;background:var(--warn);flex:none;
  animation:timerPulse 2s ease-in-out infinite}
@keyframes timerPulse{50%{opacity:.35}}
.timer-body{display:flex;flex-direction:column;line-height:1.2;min-width:0}
/* tabular figures so the seconds ticking over doesn't jiggle the layout */
.timer-elapsed{font-family:var(--mono);font-size:13px;font-weight:600;color:var(--ink);
  font-variant-numeric:tabular-nums}
.timer-asset{font-size:11px;color:var(--ink-3);max-width:150px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
@media (max-width:720px){
  /* on a phone the elapsed time is the part that matters; the job name is
     already visible on the screen you started it from */
  .timer-asset{display:none}
}
.btn[disabled]{opacity:.5;cursor:not-allowed}
.btn-ghost{border-color:transparent;background:transparent;color:var(--ink-2)}
.btn-ghost:hover{background:var(--surface-2);color:var(--ink)}

.card{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow)}
.track{height:6px;background:var(--rule-soft);border-radius:99px;overflow:hidden}
.track span{display:block;height:100%;border-radius:99px}
.spin{width:14px;height:14px;border:2px solid currentColor;border-right-color:transparent;
  border-radius:50%;animation:spin .7s linear infinite;flex:none;display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- boot / auth ----------
   The pipeline sweep: a line fills left-to-right and each stop lights up
   as it's reached, looping — Book → Log → Approve → Bill is the actual
   product loop, so the loading screen explains what Docket does instead
   of just spinning. Duration is indeterminate (we don't know how long the
   workspace fetch takes), so this loops until #boot is hidden. */
.boot{min-height:100vh;display:grid;place-items:center;color:var(--ink-3);font-size:13.5px;
  background:linear-gradient(180deg,#FCEFEC 0%,#F5F1F8 100%)}
.boot-pipe{display:flex;flex-direction:column;align-items:center;gap:16px;width:min(300px,80vw)}
.boot-track{position:relative;width:100%;height:4px;border-radius:99px;background:#E7DCE4;margin:13px 0}
.boot-fill{position:absolute;top:0;left:0;height:100%;border-radius:99px;width:0;
  background:linear-gradient(96deg,#7C3AED 0%,#B14FD8 50%,#F2734E 100%);
  animation:bootFill 3.2s cubic-bezier(.4,0,.2,1) infinite}
@keyframes bootFill{0%{width:0%}65%{width:100%}100%{width:100%}}
.boot-node{position:absolute;top:50%;width:26px;height:26px;margin:-13px 0 0 -13px;border-radius:50%;
  background:#fff;border:2px solid #E7DCE4;display:grid;place-items:center;color:#B8ADB3;
  animation:bootNode 3.2s ease infinite}
.boot-node svg{width:12px;height:12px}
@keyframes bootNode{
  0%,3%{background:#fff;border-color:#E7DCE4;color:#B8ADB3;transform:translate(-50%,-50%) scale(1)}
  7%{background:linear-gradient(135deg,#7C3AED,#B14FD8);border-color:transparent;color:#fff;
    transform:translate(-50%,-50%) scale(1.22)}
  14%,90%{background:linear-gradient(135deg,#7C3AED,#B14FD8);border-color:transparent;color:#fff;
    transform:translate(-50%,-50%) scale(1)}
  96%,100%{background:#fff;border-color:#E7DCE4;color:#B8ADB3;transform:translate(-50%,-50%) scale(1)}
}
.boot-labels{display:flex;justify-content:space-between;width:100%;font-size:11.5px;
  font-weight:650;color:#B8ADB3}
.boot-label{animation:bootLabel 3.2s ease infinite}
@keyframes bootLabel{0%,3%{color:#B8ADB3}7%,90%{color:var(--ink)}96%,100%{color:#B8ADB3}}
.boot-caption{font-size:13px;color:var(--ink-2);min-height:1.4em}
@media (prefers-reduced-motion:reduce){
  .boot-fill,.boot-node,.boot-label{animation:none}
  .boot-fill{width:100%}
  .boot-node{color:#fff;background:linear-gradient(135deg,#7C3AED,#B14FD8);border-color:transparent}
  .boot-label{color:var(--ink)}
}
.auth{min-height:100vh;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
@media (max-width:880px){.auth{grid-template-columns:minmax(0,1fr)}.auth-brand{display:none}}
/* fixed dark: --ink is a text colour and inverts under dark mode */
.auth-brand{background:#111624;color:#fff;padding:48px;display:flex;flex-direction:column;
  gap:28px;justify-content:space-between}
.brand-row{display:flex;align-items:center;gap:11px}
/* The aperture mark is the tile — it carries its own gradient and its own
   corner radius — so this is just a box to sit in, not a coloured square
   behind it. */
.brand-mark{width:34px;height:34px;display:grid;place-items:center;flex:none}
.brand-mark svg{width:100%;height:100%;display:block}
.brand-name{font-family:var(--display);font-weight:700;font-size:19px;letter-spacing:-.03em;line-height:1}
.brand-sub{font-size:11px;opacity:.6}
.auth-pitch{font-family:var(--display);font-size:32px;font-weight:700;letter-spacing:-.035em;
  line-height:1.12;max-width:15ch;text-wrap:balance;margin:0}
.auth-points{display:flex;flex-direction:column;gap:13px;font-size:13.5px;opacity:.75;max-width:40ch;margin-top:22px}
.auth-points div{display:flex;gap:10px}
.auth-points b{color:#fff;font-weight:600}
.auth-foot{font-size:11.5px;opacity:.45;font-family:var(--mono)}
.auth-panel{display:grid;place-items:center;padding:32px 24px}
.auth-card{width:100%;max-width:400px;display:flex;flex-direction:column;gap:18px}
.auth-title{font-family:var(--display);font-size:25px;font-weight:700;letter-spacing:-.03em;
  margin:0;line-height:1.1}
.auth-sub{font-size:13.5px;color:var(--ink-2);margin:6px 0 0}
.seg{display:flex;background:var(--surface-2);border:1px solid var(--rule);border-radius:9px;padding:3px;gap:3px}
.seg button{flex:1;border:0;background:transparent;padding:8px;border-radius:6px;font-size:13px;
  font-weight:600;color:var(--ink-3)}
.seg button[aria-selected="true"]{background:var(--surface);color:var(--ink);box-shadow:var(--shadow)}
.msg{border-radius:8px;padding:11px 13px;font-size:13px;line-height:1.45}
.msg-err{background:var(--crit-wash);color:var(--crit);border:1px solid var(--crit)}
.msg-ok{background:var(--good-wash);color:var(--good);border:1px solid var(--good)}

/* ---------- auth modal (sign in / create agency, over the landing page) ---------- */
.auth-modal-scrim{position:fixed;inset:0;z-index:100;background:rgba(10,13,22,.5);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;padding:24px;opacity:0;transition:opacity .18s}
.auth-modal-scrim.open{opacity:1}
.auth-modal{position:relative;width:100%;max-width:420px;background:var(--surface);border:1px solid var(--rule);
  border-radius:14px;box-shadow:var(--shadow-lg);padding:30px 26px 26px;max-height:88vh;overflow-y:auto;
  transform:translateY(8px) scale(.98);transition:transform .18s}
.auth-modal-scrim.open .auth-modal{transform:none}
.auth-modal .close{position:absolute;top:14px;right:14px}
body.modal-open{overflow:hidden}

/* fixed light palette matching the landing page (.lp tokens) — ignores dark-mode vars on purpose */
.auth-modal-scrim{background:rgba(22,19,24,.45)}
.auth-modal{background:#FFFFFF;border:1px solid #EEDCD7;border-radius:16px;
  box-shadow:0 2px 4px rgba(60,30,40,.06),0 18px 40px -18px rgba(60,30,40,.22)}
.auth-modal .close{width:32px;height:32px;border-radius:50%;border:1px solid #EEDCD7;
  background:#FFFFFF;color:#161318;display:grid;place-items:center;transition:box-shadow .12s,transform .12s}
.auth-modal .close:hover{box-shadow:0 1px 2px rgba(60,30,40,.05),0 6px 16px -8px rgba(60,30,40,.14);transform:translateY(-1px)}
.auth-modal .auth-title{color:#161318;font-family:var(--display)}
.auth-modal .auth-sub{color:#5B535F}
.auth-modal .seg{background:#FBE7E2;border:1px solid #EEDCD7;border-radius:999px;padding:4px}
.auth-modal .seg button{color:#8C8391;border-radius:999px}
.auth-modal .seg button[aria-selected="true"]{background:#FFFFFF;color:#161318;
  box-shadow:0 1px 2px rgba(60,30,40,.05),0 6px 16px -8px rgba(60,30,40,.14)}
.auth-modal .field label{color:#8C8391}
.auth-modal .field input,.auth-modal .field select,.auth-modal .field textarea{
  color:#161318;background:#FFFFFF;border:1px solid #EEDCD7;border-radius:10px}
.auth-modal .field input:focus,.auth-modal .field select:focus,.auth-modal .field textarea:focus{
  border-color:#7C3AED;box-shadow:0 0 0 3px rgba(124,58,237,.15)}
.auth-modal .msg-err{background:#FBEAE6;color:#C23A2C;border:1px solid #F0C9C0}
.auth-modal .msg-ok{background:#E9F6EF;color:#12996A;border:1px solid #BFE6D4}
.auth-modal .hint{color:#8C8391}
.auth-modal .btn-primary{background:linear-gradient(96deg,#7C3AED 0%,#B14FD8 38%,#F2734E 100%);
  border:0;color:#fff;border-radius:999px;padding:12px 18px;font-weight:600;transition:filter .12s,box-shadow .12s}
.auth-modal .btn-primary:hover{filter:brightness(1.05);
  box-shadow:0 1px 2px rgba(60,30,40,.05),0 6px 16px -8px rgba(60,30,40,.14)}
.auth-modal .btn-ghost{color:#7C3AED;border-color:transparent;background:transparent}
.auth-modal .btn-ghost:hover{background:#FBE7E2;color:#161318}

/* ---------- forms ---------- */
form{display:flex;flex-direction:column;gap:13px}
.field{display:flex;flex-direction:column;gap:5px}
.field label{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3);font-weight:650}
.field input,.field select,.field textarea{font:inherit;font-size:14px;color:var(--ink);
  background:var(--surface);border:1px solid var(--rule);border-radius:8px;padding:10px 12px;width:100%}
.field textarea{resize:vertical;min-height:60px;font-size:13px}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);outline:none;
  box-shadow:0 0 0 3px var(--accent-wash)}
.hint{font-size:11.5px;color:var(--ink-3);line-height:1.45}
.pwd-wrap{position:relative}
.pwd-wrap input{padding-right:40px}
.pwd-eye{position:absolute;top:50%;right:4px;transform:translateY(-50%);width:32px;height:32px;
  border:0;background:none;border-radius:6px;display:flex;align-items:center;justify-content:center;
  color:var(--ink-3);cursor:pointer}
.pwd-eye:hover{color:var(--ink-2);background:var(--surface-2)}
.linklike{border:0;background:none;padding:0;font:inherit;font-size:inherit;color:var(--accent);
  cursor:pointer;text-decoration:none}
.linklike:hover{text-decoration:underline}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:11px}
@media (max-width:520px){.row2{grid-template-columns:1fr}}
.stepper-in{display:flex;align-items:stretch;border:1px solid var(--rule);border-radius:8px;
  overflow:hidden;background:var(--surface)}
.stepper-in button{border:0;background:transparent;width:38px;font-size:17px;color:var(--ink-2);font-weight:600}
.stepper-in button:hover{background:var(--surface-2);color:var(--ink)}
.stepper-in output{flex:1;display:grid;place-items:center;font-family:var(--mono);font-size:15px;font-weight:600}
.chips{display:flex;gap:6px;flex-wrap:wrap}
.chip-btn{border:1px solid var(--rule);background:var(--surface);border-radius:6px;padding:4px 9px;
  font-family:var(--mono);font-size:11.5px;font-weight:600;color:var(--ink-2)}
.chip-btn:hover{border-color:var(--accent);color:var(--accent)}
.chip-btn[aria-pressed="true"]{border-color:var(--accent);background:var(--accent-wash);color:var(--accent)}
.sw{width:40px;height:22px;border-radius:99px;border:0;background:var(--rule);position:relative;
  flex:none;transition:background .16s}
.sw::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;
  background:var(--surface);box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .16s}
.sw[aria-checked="true"]{background:var(--accent)}
.sw[aria-checked="true"]::after{transform:translateX(18px)}
.toggle{display:flex;align-items:center;justify-content:space-between;gap:12px;border:1px solid var(--rule);
  border-radius:8px;padding:10px 12px;background:var(--surface-2)}
.toggle-txt{font-size:12.5px;font-weight:600}
.toggle-sub{font-size:11px;color:var(--ink-3);margin-top:1px}

/* ---------- app shell ---------- */
.app{min-height:100vh;display:grid;grid-template-columns:232px minmax(0,1fr)}
.rail{background:var(--surface);border-right:1px solid var(--rule);display:flex;flex-direction:column;
  gap:2px;padding:16px 12px;position:sticky;top:0;height:100vh;overflow-y:auto}
.rail-brand{display:flex;align-items:center;gap:10px;padding:2px 6px 16px}
.rail-agency{font-size:11px;color:var(--ink-3);padding:0 6px 12px;border-bottom:1px solid var(--rule-soft);
  margin-bottom:8px}
.rail-agency b{display:block;font-size:13px;color:var(--ink);font-weight:650;margin-bottom:1px}
.nav-group{padding:12px 6px 5px}
.nav-item{position:relative;display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px 8px 13px;border:0;
  background:transparent;border-radius:7px;font-size:13.5px;font-weight:500;color:var(--ink-2);
  text-align:left;transition:background .14s,color .14s}
.nav-item:hover{background:var(--surface-2);color:var(--ink)}
.nav-item[aria-current="page"]{background:var(--accent-wash);color:var(--accent);font-weight:650}
/* a thin gradient edge on the active item — same mark as the landing
   page's hero and CTAs, kept small so the rail still reads as one navy
   surface rather than turning into another gradient-everywhere screen */
.nav-item[aria-current="page"]::before{content:'';position:absolute;left:2px;top:4px;bottom:4px;
  width:3px;border-radius:2px;background:var(--grad)}
.nav-icon{width:16px;height:16px;flex:none;opacity:.85}
.nav-badge{margin-left:auto;font-family:var(--mono);font-size:10.5px;font-weight:700;
  background:var(--crit);color:#fff;border-radius:999px;padding:1px 6px}
.rail-foot{margin-top:auto;padding-top:16px;border-top:1px solid var(--rule-soft);
  display:flex;flex-direction:column;gap:8px}

.main{min-width:0;display:flex;flex-direction:column}
.topbar{position:sticky;top:0;z-index:30;background:color-mix(in oklab,var(--paper) 88%,transparent);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--rule);display:flex;align-items:center;
  gap:12px;padding:10px 22px;flex-wrap:wrap}
.who{display:flex;align-items:center;gap:9px}
.avatar{width:30px;height:30px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-family:var(--display);font-size:11.5px;font-weight:700;color:#fff;background:var(--accent)}
.who-name{font-size:13px;font-weight:650;line-height:1.15}
.who-role{font-size:10.5px;color:var(--ink-3);line-height:1.2}
.iconbtn{border:1px solid var(--rule);background:var(--surface);border-radius:7px;width:32px;height:32px;
  display:grid;place-items:center;color:var(--ink-2)}
.iconbtn:hover{color:var(--ink);background:var(--surface-2)}
/* only ever shown under the 900px breakpoint, once the rail becomes an
   off-canvas panel instead of a permanent column */
.navToggle{display:none;flex:none}

.page{padding:22px;display:flex;flex-direction:column;gap:16px;max-width:1500px;width:100%}
.page-head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap}
.page-title{font-family:var(--display);font-size:26px;font-weight:700;letter-spacing:-.035em;
  line-height:1.05;margin:0;text-wrap:balance}
.page-sub{font-size:13px;color:var(--ink-2);margin:5px 0 0;max-width:64ch}

@media (max-width:900px){
  .app{grid-template-columns:minmax(0,1fr)}
  .navToggle{display:grid}
  /* off-canvas panel behind a hamburger, not a squeezed-in copy of the
     desktop rail — full nav (agency line, groups, sign out) stays intact,
     it just lives off-screen until opened */
  .rail{position:fixed;top:0;left:0;bottom:0;width:min(260px,82vw);height:100vh;z-index:95;
    transform:translateX(-100%);transition:transform .22s cubic-bezier(.3,.8,.3,1);
    box-shadow:var(--shadow-lg);border-right:1px solid var(--rule)}
  .rail.open{transform:none}
  .nav-item{width:100%;white-space:normal}
  .page{padding:16px 14px}
  .topbar{padding:10px 14px}
}

/* ---------- empty states ---------- */
.empty{background:var(--surface);border:1px dashed var(--rule);border-radius:var(--radius);
  padding:36px 24px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:10px}
.empty h3{font-family:var(--display);font-size:17px;font-weight:700;letter-spacing:-.02em;margin:0}
.empty p{font-size:13px;color:var(--ink-2);margin:0;max-width:52ch;line-height:1.55}
.empty .btn{margin-top:6px}

/* ---------- tiles ---------- */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px}
.tile{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  padding:13px 14px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:3px}
.tile-val{font-family:var(--mono);font-size:24px;font-weight:600;letter-spacing:-.04em;line-height:1.1}
.tile-lab{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);font-weight:650}
.tile-note{font-size:11.5px;color:var(--ink-2);margin-top:4px}

/* ---------- tables ---------- */
.table{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);overflow:hidden}
.table-head{display:flex;align-items:center;gap:11px;padding:12px 15px;
  border-bottom:1px solid var(--rule-soft);background:var(--surface-2);flex-wrap:wrap}
.scroll-x{overflow-x:auto}
table{width:100%;border-collapse:collapse;color:var(--ink)}
th{font-family:var(--display);font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);text-align:left;padding:9px 13px;background:var(--surface-2);
  border-bottom:1px solid var(--rule);white-space:nowrap}
td{padding:11px 13px;border-bottom:1px solid var(--rule-soft);font-size:13px;color:var(--ink);
  vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--surface-2)}
td.r,th.r{text-align:right}
.person{display:flex;align-items:center;gap:9px}
.person .avatar{width:26px;height:26px;font-size:10px}

/* ---------- calendar ---------- */
.calwrap{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);overflow:hidden}
.cal{min-width:900px}
.cal-head{display:grid;grid-template-columns:56px repeat(7,minmax(0,1fr));border-bottom:1px solid var(--rule)}
.cal-head .gut{border-right:1px solid var(--rule-soft)}
.dayhead{padding:9px 10px 8px;border-right:1px solid var(--rule-soft);display:flex;
  flex-direction:column;gap:5px}
.dayhead:last-child{border-right:0}
.dayhead.today{background:var(--accent-wash)}
.dayhead.weekend{background:var(--surface-2)}
.dh-top{display:flex;align-items:baseline;gap:6px}
.dh-dow{font-family:var(--display);font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.dayhead.today .dh-dow{color:var(--accent)}
.dh-date{font-family:var(--mono);font-size:15px;font-weight:600;letter-spacing:-.03em}
.dh-hrs{margin-left:auto;font-family:var(--mono);font-size:12.5px;font-weight:600}
.dh-hrs.under{color:var(--warn)}
.dh-hrs.none{color:var(--crit)}
.cal-body{display:grid;grid-template-columns:56px repeat(7,minmax(0,1fr));position:relative}
.gutter{border-right:1px solid var(--rule-soft);position:relative}
.gutter b{position:absolute;right:7px;transform:translateY(-50%);font-family:var(--mono);
  font-size:10.5px;color:var(--ink-3);font-weight:500}
.gutter b:last-child{transform:translateY(-100%)}
.daycol{position:relative;border-right:1px solid var(--rule-soft);cursor:crosshair;
  background-image:repeating-linear-gradient(to bottom,var(--rule-soft) 0 1px,transparent 1px var(--hour))}
.daycol:last-child{border-right:0}
.daycol.weekend{background-color:var(--surface-2)}
.daycol.today{background-color:color-mix(in oklab,var(--accent) 4%,transparent)}
.ev{position:absolute;left:3px;right:3px;border-radius:6px;padding:5px 7px 5px 9px;overflow:hidden;
  text-align:left;border:1px solid transparent;display:flex;flex-direction:column;gap:1px;z-index:4;
  transition:box-shadow .14s}
.ev:hover{box-shadow:var(--shadow-lg);z-index:7}
.ev::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--ec)}
.ev-logged{background:color-mix(in oklab,var(--ec) 13%,var(--surface));
  border-color:color-mix(in oklab,var(--ec) 34%,transparent)}
.ev-planned{background:var(--surface);border:1px dashed color-mix(in oklab,var(--ec) 55%,transparent);
  background-image:repeating-linear-gradient(135deg,color-mix(in oklab,var(--ec) 11%,transparent) 0 5px,transparent 5px 10px)}
.ev-approved{box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--good) 45%,transparent)}
.ev-job{font-family:var(--mono);font-size:9.5px;font-weight:600;color:var(--ink-3)}
.ev-name{font-size:11.5px;font-weight:600;line-height:1.25;color:var(--ink)}
.ev-meta{margin-top:auto;display:flex;align-items:center;gap:5px;font-family:var(--mono);
  font-size:10px;color:var(--ink-2)}
.ev-nb{font-size:9px;font-weight:700;letter-spacing:.06em;color:var(--ink-3);
  border:1px solid var(--rule);border-radius:3px;padding:0 3px}
.ev-sm{padding-top:4px;padding-bottom:4px}
.ev-sm .ev-name{display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.2}
.ev-tiny{padding:2px 6px 2px 8px;justify-content:center}
.ev-tiny .ev-name{font-size:10.5px;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ev-tiny .ev-job,.ev-tiny .ev-meta{display:none}
.legend{display:flex;gap:16px;flex-wrap:wrap;padding:11px 14px;border-top:1px solid var(--rule);
  background:var(--surface-2);align-items:center;font-size:11.5px;color:var(--ink-2)}
.legend span{display:flex;align-items:center;gap:6px}
.lg-sw{width:20px;height:12px;border-radius:3px;flex:none}
.weekbar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;background:var(--surface);
  border:1px solid var(--rule);border-radius:var(--radius);padding:12px 14px;box-shadow:var(--shadow)}
.weeklabel{font-family:var(--display);font-weight:650;font-size:14.5px;letter-spacing:-.015em;min-width:170px}
.meters{display:flex;gap:22px;align-items:center;flex-wrap:wrap}
.meter{min-width:112px}
.meter-top{display:flex;align-items:baseline;gap:5px}
.meter-val{font-family:var(--mono);font-size:19px;font-weight:600;letter-spacing:-.03em;line-height:1}
.meter-of{font-size:11.5px;color:var(--ink-3);font-family:var(--mono)}
.meter-lab{font-size:10.5px;color:var(--ink-3);letter-spacing:.06em;text-transform:uppercase;
  font-weight:650;margin-top:4px}

/* ---------- traffic board ---------- */
/* Traffic & Schedules splits into two columns at the very top of the page rather
   than below the week nav. Everything you read — heading, tiles, week nav,
   the board itself — goes down the left; the queue of work nobody has been
   booked onto gets the full right-hand column. That queue is where an
   agency's briefs sit between arriving and being assigned, so it is the one
   thing on this screen that genuinely fills up, and it was the one thing
   boxed into a short panel while the top-right of the page sat empty. */
.board-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-items:start}
.board-layout.has-aside{grid-template-columns:minmax(0,1fr) 340px}
.board-main{min-width:0;display:flex;flex-direction:column;gap:16px}
.board-aside{min-width:0}
/* Below this the two columns stack and the queue sits under the board.
   A media query rather than the width check this used to do in JS at render
   time, so turning a laptop or dragging the window resizes it. */
@media (max-width:1180px){.board-layout.has-aside{grid-template-columns:minmax(0,1fr)}}

/* Pinned under the topbar, because dragging a card onto a day is the whole
   interaction and it cannot happen once the card has scrolled away. Only
   the list scrolls; the title and the instruction hold their place.
   85px is where the queue already sits — the sticky topbar (63px) plus the
   page's 22px padding — so pinning it makes it stay put rather than jump,
   and the height leaves the same 22px at the bottom. Both numbers have to
   move together if .topbar or .page padding ever changes. */
@media (min-width:1181px){
  .board-queue{position:sticky;top:85px;max-height:calc(100vh - 107px)}
}
.queue-list{display:flex;flex-direction:column;gap:6px;overflow-y:auto;min-height:0;flex:1;padding-right:2px}
.queue-sum{font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}

.board{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);overflow:hidden}
.board-inner{min-width:940px}
.brow{display:grid;grid-template-columns:196px repeat(5,minmax(0,1fr)) 88px;border-bottom:1px solid var(--rule-soft)}
.brow:last-child{border-bottom:0}
.brow.head{background:var(--surface-2);border-bottom:1px solid var(--rule)}
.bcell{padding:9px 10px;border-right:1px solid var(--rule-soft)}
.bcell:last-child{border-right:0}
.brow.head .bcell{font-family:var(--display);font-size:10.5px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.bslot{position:relative;min-height:62px;cursor:pointer;transition:background .12s}
.bslot:hover{background:var(--accent-wash)}
.bslot.over{background:color-mix(in oklab,var(--crit) 7%,transparent)}
.bchip{display:flex;align-items:center;gap:5px;border-radius:4px;padding:3px 5px;margin-bottom:3px;
  background:color-mix(in oklab,var(--cc) 13%,transparent);border-left:2.5px solid var(--cc);
  font-size:10.5px;line-height:1.25;cursor:pointer}
.bchip span{font-family:var(--mono);font-size:10px;font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;flex:0 1 auto}
.bchip b{font-family:var(--mono);font-weight:600;margin-left:auto;color:var(--ink-2);flex:none}
.bchip-movable{cursor:grab}
.bchip-movable:hover{box-shadow:0 0 0 1px var(--cc)}
.bchip-movable:active{cursor:grabbing}
.bchip.is-dragging{opacity:.4}
.bload{position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--rule-soft)}
.bload i{display:block;height:100%}
.btot{display:flex;flex-direction:column;gap:3px;align-items:flex-start}
.btot-h{font-family:var(--mono);font-size:14px;font-weight:600;letter-spacing:-.02em}

/* ---------- clients / campaigns ---------- */
.stack{display:flex;flex-direction:column;gap:12px}
.clientcard{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);overflow:hidden}
.cl-head{display:flex;align-items:center;gap:12px;padding:13px 15px;border-bottom:1px solid var(--rule-soft);
  background:var(--surface-2);flex-wrap:wrap}
.cl-badge{width:38px;height:38px;border-radius:8px;flex:none;display:grid;place-items:center;
  font-family:var(--display);font-size:13px;font-weight:700;color:#fff;background:var(--accent)}
.cl-name{font-family:var(--display);font-size:16px;font-weight:700;letter-spacing:-.025em;line-height:1.15}
.cl-meta{font-size:11.5px;color:var(--ink-3);margin-top:2px;display:flex;gap:10px;flex-wrap:wrap}
.camprow{display:grid;grid-template-columns:minmax(0,1fr) 210px 120px 150px;gap:16px;align-items:center;
  padding:12px 15px;border-bottom:1px solid var(--rule-soft);width:100%;text-align:left;
  border-left:0;border-right:0;border-top:0;background:transparent;transition:background .12s}
.camprow:last-of-type{border-bottom:0}
.camprow:hover{background:var(--surface-2)}
.cr-name{font-size:13.5px;font-weight:650;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cr-sub{font-size:11.5px;color:var(--ink-3);margin-top:3px;display:flex;gap:10px;flex-wrap:wrap}
.cr-fig{font-family:var(--mono);font-size:12.5px;display:flex;justify-content:space-between;gap:8px}
.cr-right{display:flex;justify-content:flex-end;gap:7px;align-items:center}
.cl-foot{padding:11px 15px;background:var(--surface-2);border-top:1px solid var(--rule-soft);
  display:flex;gap:9px;align-items:center;flex-wrap:wrap}
.jobcode{font-family:var(--mono);font-size:11.5px;font-weight:700;background:var(--ink);
  color:var(--paper);padding:2px 7px;border-radius:4px}
@media (max-width:1080px){
  .camprow{grid-template-columns:minmax(0,1fr) 1fr;row-gap:10px}
  .cr-right{grid-column:1/-1;justify-content:flex-start}
}

/* budget bar */
.burn{position:relative;height:9px;border-radius:99px;background:var(--rule-soft);overflow:hidden}
.burn i{position:absolute;top:0;bottom:0;border-radius:99px}
.bb-burn{height:14px}
.crumb{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink-3);background:transparent;
  border:0;padding:0;margin-bottom:4px}
.crumb:hover{color:var(--accent)}
.bigbudget{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:16px;align-items:start}
@media (max-width:1080px){.bigbudget{grid-template-columns:minmax(0,1fr)}}
.panel{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:16px;display:flex;flex-direction:column;gap:13px}
.panel-title{font-family:var(--display);font-size:14.5px;font-weight:700;letter-spacing:-.02em;margin:0}
.bb-figures{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:14px}
.bb-f b{display:block;font-family:var(--mono);font-size:20px;font-weight:600;letter-spacing:-.04em;line-height:1.1}
.bb-f span{font-size:10px;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3);font-weight:650}
.bb-key{display:flex;gap:16px;flex-wrap:wrap;font-size:11.5px;color:var(--ink-2);align-items:center}
.bb-key i{width:16px;height:9px;border-radius:2px;display:inline-block;flex:none}
.alert{display:flex;align-items:center;gap:12px;padding:11px 14px;border-radius:var(--radius);
  border:1px solid var(--warn);background:var(--warn-wash)}
.alert-title{font-size:13px;font-weight:650;color:var(--ink)}
.alert-body{font-size:12.5px;color:var(--ink-2)}

/* rate cards */
.grid-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:12px}
.ratecard{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:14px;display:flex;flex-direction:column;gap:11px}
.rc-head{display:flex;align-items:flex-start;gap:9px;flex-wrap:wrap}
.rc-name{font-family:var(--display);font-size:15px;font-weight:650;letter-spacing:-.02em;line-height:1.2}
.rc-rates{display:grid;grid-template-columns:repeat(auto-fit,minmax(78px,1fr));gap:9px}
.rc-rates b{display:block;font-family:var(--mono);font-size:14px;font-weight:600;letter-spacing:-.03em}
.rc-rates span{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);
  font-weight:650;white-space:nowrap;display:flex;align-items:center;gap:4px}
.raterows{display:flex;flex-direction:column;gap:7px}
.raterow{display:grid;grid-template-columns:minmax(0,1fr) 108px;gap:10px;align-items:center}
.raterow label{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:600;min-width:0}
.raterow input{font:inherit;font-family:var(--mono);font-size:13px;color:var(--ink);
  background:var(--surface);border:1px solid var(--rule);border-radius:7px;padding:7px 9px;
  width:100%;text-align:right}

/* reminders */
.rules{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:12px}
.rule{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:14px;display:flex;flex-direction:column;gap:10px;transition:opacity .18s}
.rule.off{opacity:.55}
.rule-top{display:flex;align-items:flex-start;gap:11px}
.rule-name{font-family:var(--display);font-size:14.5px;font-weight:650;letter-spacing:-.02em;line-height:1.2}
.rule-when{font-family:var(--mono);font-size:11.5px;color:var(--accent);margin-top:3px}
.rule-desc{font-size:12.5px;color:var(--ink-2);line-height:1.5}
.ch{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 8px;
  border-radius:5px;background:var(--surface-2);border:1px solid var(--rule);color:var(--ink-2)}

/* ---------- drawer ---------- */
.scrim{position:fixed;inset:0;background:rgba(10,13,22,.42);backdrop-filter:blur(2px);z-index:80;
  opacity:0;pointer-events:none;transition:opacity .2s}
.scrim.open{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(430px,100%);z-index:90;background:var(--surface);
  border-left:1px solid var(--rule);box-shadow:var(--shadow-lg);transform:translateX(102%);
  transition:transform .24s cubic-bezier(.3,.8,.3,1);display:flex;flex-direction:column}
.drawer.open{transform:none}
.drawer.drawer-wide{width:min(680px,92vw)}
/* on a phone every drawer — including the wide asset-review one — should
   be the full screen, flush on every edge, not a card floating short of it */
@media (max-width:600px){
  .drawer,.drawer.drawer-wide{width:100%;border-left:0}
}
.dr-head{display:flex;align-items:flex-start;gap:12px;padding:16px 18px;border-bottom:1px solid var(--rule)}
.dr-title{font-family:var(--display);font-size:17px;font-weight:700;letter-spacing:-.03em;margin:0;line-height:1.15}
.dr-sub{font-size:12px;color:var(--ink-3);margin-top:3px}
.dr-body{padding:16px 18px;display:flex;flex-direction:column;gap:13px;overflow-y:auto;flex:1}
.dr-foot{padding:13px 18px;border-top:1px solid var(--rule);display:flex;gap:9px;background:var(--surface-2)}
.dr-foot .btn{flex:1}
/* the auto margin lives on #drHeadAction, not here, so an optional header
   action button can sit flush against Close as one right-aligned group
   instead of splitting the leftover space between the two */
#drHeadAction{margin-left:auto;display:flex;align-items:center}
.close{border:1px solid var(--rule);background:var(--surface);width:30px;height:30px;border-radius:7px;
  display:grid;place-items:center;flex:none;color:var(--ink-2)}
.valuebox{display:flex;justify-content:space-between;align-items:baseline;border-top:1px dashed var(--rule);
  padding-top:11px}
.vb-l{font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3);font-weight:650}
.vb-v{font-family:var(--mono);font-size:19px;font-weight:600;letter-spacing:-.03em}
.confirmbox{border:1px solid var(--accent);background:var(--accent-wash);border-radius:8px;padding:11px 12px;
  font-size:12.5px;color:var(--ink-2);line-height:1.5}
.confirmbox strong{color:var(--ink)}
.discadd{border:1px dashed var(--accent);background:var(--accent-wash);border-radius:8px;padding:11px;
  display:flex;flex-direction:column;gap:8px}
.discadd input{font:inherit;font-size:13px;color:var(--ink);background:var(--surface);
  border:1px solid var(--rule);border-radius:7px;padding:8px 9px;width:100%}

/* ---------- invoice builder ---------- */
.inv-lines{display:flex;flex-direction:column;border:1px solid var(--rule);border-radius:8px;overflow:hidden}
.inv-line{display:flex;gap:11px;align-items:flex-start;padding:10px 12px;cursor:pointer;
  border-bottom:1px solid var(--rule-soft);background:var(--surface);transition:background .12s}
.inv-line:last-child{border-bottom:0}
.inv-line:hover{background:var(--surface-2)}
.inv-line.off{opacity:.45}
.inv-line input[type="checkbox"]{margin-top:3px;width:15px;height:15px;flex:none;accent-color:var(--accent)}
.inv-line > span:nth-child(2){display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.inv-asset{font-size:13px;font-weight:650;display:flex;align-items:center;gap:7px}
.inv-meta{font-size:11.5px;color:var(--ink-3);font-family:var(--mono)}
.inv-amt{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex:none;text-align:right}
.inv-totals{display:flex;flex-direction:column;gap:6px;border-top:1px dashed var(--rule);padding-top:12px}
.inv-totals > div{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;color:var(--ink-2)}
.inv-totals .inv-grand{border-top:1px solid var(--rule);padding-top:9px;margin-top:3px;
  font-size:15px;font-weight:650;color:var(--ink)}
.inv-totals .inv-grand b{font-size:19px;letter-spacing:-.03em}

/* ---------- financial pipeline ---------- */
.fin{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px}
.fin-step{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:14px;display:flex;flex-direction:column;gap:4px;position:relative}
/* a left rail carries the state, so it reads without relying on colour alone */
.fin-step::before{content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;
  border-radius:0 3px 3px 0;background:var(--rule)}
.fin-step.blocked::before{background:var(--crit)}
.fin-step.active::before{background:var(--accent)}
.fin-step.done::before{background:var(--good)}
.fin-lab{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);font-weight:650}
.fin-step.blocked .fin-lab{color:var(--crit)}
.fin-val{font-family:var(--mono);font-size:22px;font-weight:600;letter-spacing:-.04em;line-height:1.15}
.fin-note{font-size:11.5px;color:var(--ink-2);line-height:1.45}
.fin-step .btn{margin-top:8px;align-self:flex-start}
.fin-step .pill{align-self:flex-start;margin-top:6px}

/* ---------- drag to book ---------- */
.drag-card{border:1px solid var(--rule);border-radius:7px;padding:8px 10px;font-size:12.5px;
  cursor:grab;transition:border-color .12s,background .12s,transform .1s}
.drag-card:hover{border-color:var(--accent);background:var(--surface-2)}
.drag-card:active{cursor:grabbing}
.drag-card.is-dragging{opacity:.4;transform:scale(.98)}
.drag-card-head{cursor:pointer}
.drag-card-detail{margin-top:2px;padding-top:8px;border-top:1px dashed var(--rule-soft)}
/* an unbriefed asset with nothing booked yet — not a drag target, just a
   click target to open the brief */
.drag-card-locked{cursor:pointer}
.drag-card-locked:hover{border-color:var(--rule);background:transparent}
.drag-card-locked .drag-card-head{cursor:pointer}
/* while a drag is in flight, show every cell as a candidate */
body.dragging .bslot{outline:1px dashed color-mix(in oklab,var(--accent) 45%,transparent);
  outline-offset:-3px}
body.dragging .bslot:hover{background:var(--accent-wash)}
.bslot.drop-ok{background:var(--accent-wash) !important;
  box-shadow:inset 0 0 0 2px var(--accent)}
.bslot.drop-full{background:var(--crit-wash) !important;
  box-shadow:inset 0 0 0 2px var(--crit)}

/* ---------- approval detail ---------- */
.detail-row td{background:var(--surface-2);border-bottom:1px solid var(--rule)}
.detail{display:flex;flex-direction:column;padding:4px 0 0}
.detail-day{display:flex;align-items:center;gap:9px;padding:8px 14px 6px;
  font-family:var(--display);font-size:10.5px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);border-top:1px solid var(--rule-soft)}
.detail-day:first-child{border-top:0}
.detail-dow{letter-spacing:.1em}
.detail-line{display:flex;gap:11px;align-items:flex-start;padding:9px 14px;cursor:pointer;
  border-radius:7px;margin:0 8px 2px;transition:background .12s}
.detail-line:hover{background:var(--surface)}
.detail-line.locked{opacity:.6;cursor:default}
.detail-line > span:nth-child(2){display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.detail-line input[type="checkbox"]{margin-top:3px;width:15px;height:15px;flex:none;accent-color:var(--accent)}
.detail-asset{font-size:13px;font-weight:650;display:flex;align-items:center;gap:7px}
.detail-meta{font-size:11.5px;color:var(--ink-3);font-family:var(--mono)}
.detail-note{font-size:12px;color:var(--ink-2);line-height:1.45;margin-top:2px}
.detail-nonote{color:var(--warn);font-style:italic}
.detail-right{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex:none;text-align:right}
.detail-foot{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:11px 14px;
  border-top:1px solid var(--rule-soft);margin-top:4px}
.detail-foot .hint{margin-left:auto;max-width:38ch;text-align:right}
@media (max-width:760px){
  .detail-foot .hint{margin-left:0;text-align:left;max-width:none}
}

/* ---------- notifications ---------- */
.bell-wrap{position:relative}
.bell-count{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;padding:0 4px;
  border-radius:99px;background:var(--crit);color:#fff;font-family:var(--mono);font-size:9.5px;
  font-weight:700;display:grid;place-items:center;line-height:1;border:2px solid var(--paper)}
.note-panel{position:absolute;top:40px;right:0;width:min(360px,90vw);z-index:60;background:var(--surface);
  border:1px solid var(--rule);border-radius:var(--radius);box-shadow:var(--shadow-lg);overflow:hidden}
.note-head{padding:11px 14px;border-bottom:1px solid var(--rule-soft);background:var(--surface-2)}
.note-list{max-height:min(420px,60vh);overflow-y:auto}
.note-empty{padding:24px 16px;font-size:12.5px;color:var(--ink-3);line-height:1.55;text-align:center}
.note{display:flex;gap:11px;width:100%;text-align:left;padding:11px 14px;border:0;background:transparent;
  border-bottom:1px solid var(--rule-soft);align-items:flex-start;transition:background .12s}
.note:last-child{border-bottom:0}
.note:hover{background:var(--surface-2)}
.note.unread{background:color-mix(in oklab,var(--accent) 6%,transparent)}
.note.unread:hover{background:color-mix(in oklab,var(--accent) 10%,transparent)}
.note-icon{width:16px;height:16px;flex:none;margin-top:2px;color:var(--ink-3)}
.note.unread .note-icon{color:var(--accent)}
.note-body{display:flex;flex-direction:column;gap:2px;min-width:0}
.note-title{font-size:13px;font-weight:650;line-height:1.35}
.note-sub{font-size:11.5px;color:var(--ink-2);line-height:1.45}
.note-time{font-size:10.5px;color:var(--ink-3);font-family:var(--mono);margin-top:2px}

/* ---------- toasts ---------- */
.toasts{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:120;display:flex;
  flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.toast{background:var(--ink);color:var(--paper);border-radius:8px;padding:10px 15px;font-size:13px;
  font-weight:600;box-shadow:var(--shadow-lg);display:flex;align-items:center;gap:9px;
  animation:tin .26s cubic-bezier(.2,.9,.3,1);max-width:min(90vw,460px)}
.toast.bad{background:var(--crit);color:#fff}
@keyframes tin{from{opacity:0;transform:translateY(10px) scale(.97)}}

/* ============================================================
   Client-facing invoice.
   Deliberately committed to a light, paper-like look in both themes:
   this is a document a client prints and files, not part of the app's
   dark UI. It must look the same on screen and on paper.
   ============================================================ */
.invoice-page{min-height:100vh;background:#EEF0F5;padding:32px 20px 64px;display:flex;
  flex-direction:column;align-items:center;gap:16px}
.invoice-actions{width:min(820px,100%);display:flex;justify-content:flex-end}
.invoice{width:min(820px,100%);background:#fff;color:#141827;border-radius:10px;
  box-shadow:0 2px 4px rgba(20,24,39,.08),0 24px 56px -24px rgba(20,24,39,.3);
  padding:48px 52px;font-size:14px;line-height:1.6}
.inv-head{display:flex;justify-content:space-between;align-items:flex-start;gap:24px;
  padding-bottom:26px;border-bottom:2px solid #141827;flex-wrap:wrap}
.inv-doc{font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:#7A8199}
.inv-head h1{font-family:var(--display);font-size:32px;font-weight:700;letter-spacing:-.035em;
  margin:4px 0 0;color:#141827}
.inv-stamp{display:inline-block;margin-top:8px;font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;padding:3px 10px;border-radius:4px}
.inv-stamp.paid{background:#E2F3EA;color:#0F7A4E;border:1px solid #0F7A4E}
.inv-stamp.over{background:#FBE6E4;color:#C22F26;border:1px solid #C22F26}
.inv-stamp.draft{background:#FBEEDA;color:#A9660A;border:1px solid #A9660A}
.inv-from{text-align:right;display:flex;flex-direction:column;gap:2px}
.inv-from strong{font-size:16px;font-weight:700}
/* Sans by default since 0033: this used to hold a VAT number and nothing
   else, where mono was right. An address and a website in monospace read
   like a config file. The numbers that are still worth aligning keep it. */
.inv-from span{font-size:12px;color:#4A5168;line-height:1.5}
.inv-from .inv-num{font-family:var(--mono);font-size:11.5px}
.inv-parties{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:22px;
  padding:26px 0;border-bottom:1px solid #DFE3EF}
.inv-parties > div{display:flex;flex-direction:column;gap:2px}
.inv-parties strong{font-size:14px;font-weight:650}
.inv-parties span:not(.inv-lbl){font-size:12.5px;color:#4A5168}
.inv-lbl{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:#7A8199;margin-bottom:3px}
.inv-table{width:100%;border-collapse:collapse;margin:26px 0 0}
.inv-table th{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:#7A8199;text-align:left;padding:0 0 10px;border-bottom:1px solid #DFE3EF;background:none}
.inv-table td{padding:14px 0;border-bottom:1px solid #EAEDF6;font-size:13.5px;color:#141827;
  vertical-align:top}
.inv-table .r,.inv-table th.r{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.inv-disc{font-size:11.5px;color:#7A8199}
.inv-sum{display:flex;flex-direction:column;gap:8px;margin:22px 0 0;margin-left:auto;
  width:min(320px,100%)}
.inv-sum > div{display:flex;justify-content:space-between;font-size:13.5px;color:#4A5168;
  font-variant-numeric:tabular-nums}
.inv-sum > div span:last-child{font-family:var(--mono)}
.inv-sum .inv-due{border-top:2px solid #141827;padding-top:11px;margin-top:4px;
  font-size:17px;font-weight:700;color:#141827}
.inv-notes{margin-top:32px;padding-top:20px;border-top:1px solid #DFE3EF}
.inv-notes p{margin:4px 0 0;font-size:13px;color:#4A5168}
/* How to pay (0033). Boxed rather than run on after the notes: it is the
   one block on the page the client has to act on, and an account number
   they have to hunt for is how an invoice sits unpaid for a fortnight. */
.inv-bank{margin-top:26px;padding:16px 18px;border:1px solid #DFE3EF;border-radius:8px;
  background:#F7F9FC}
.inv-bank p{margin:5px 0 0;font-size:13px;color:#141827;line-height:1.55}
.inv-ref{display:block;margin-top:9px;font-size:11.5px;color:#7A8199}
.inv-foot{margin-top:36px;padding-top:18px;border-top:1px solid #EAEDF6;
  font-size:11.5px;color:#7A8199}
/* Capped by height, not width, so a wide wordmark and a square badge both
   sit on the same baseline as the name beneath them. object-fit keeps a
   logo of any proportion inside that box without distorting it. */
.inv-logo{max-height:46px;max-width:190px;object-fit:contain;object-position:right;
  margin-bottom:9px;display:block;margin-left:auto}

/* ---------- agency letterhead, on the settings screen ----------
   A preview of the printed header, so filling these fields in has visible
   consequences without raising a test invoice to find out. */
.letterhead{display:flex;gap:18px;align-items:flex-start;flex-wrap:wrap}
/* White whatever the theme is, and so is the picker below. A logo is drawn
   for the invoice, and the invoice is always light — previewing a
   dark-text wordmark on a dark tile shows the person a logo that looks
   broken and a client who will never see it that way. */
.letterhead-mark{width:104px;height:64px;flex:none;border:1px solid var(--rule);border-radius:8px;
  display:grid;place-items:center;overflow:hidden;background:#fff}
.letterhead-mark img{max-width:88px;max-height:52px;object-fit:contain}
.letterhead-mark span{font-size:10.5px;color:var(--ink-3)}
.letterhead-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.letterhead-body strong{font-size:14.5px;font-weight:700}
.letterhead-body span{font-size:12px;color:var(--ink-2);line-height:1.5}
.letterhead-bank{display:flex;flex-direction:column;gap:3px;font-size:12px;color:var(--ink-2);
  border-left:2px solid var(--rule);padding-left:14px;line-height:1.5}
.letterhead-bank .inv-lbl{color:var(--ink-3)}
@media (max-width:640px){.letterhead-bank{border-left:0;padding-left:0}}

/* Logo picker in the agency profile drawer. */
.logo-pick{display:flex;gap:13px;align-items:center;flex-wrap:wrap}
.logo-shot{width:120px;height:70px;flex:none;border:1px solid var(--rule);border-radius:8px;
  display:grid;place-items:center;overflow:hidden;background:#fff}
.logo-shot img{max-width:104px;max-height:58px;object-fit:contain}
.logo-shot span{font-size:11px;color:#7A8199}

/* ---------- campaign report ----------
   Rides on .invoice for the page itself (white, dark ink, tabular figures)
   and only adds what an invoice has no use for: section headings and rows
   of figures. Printed colours are literal rather than themed — this is a
   document that leaves the app, so it must not follow the reader's theme. */
.rep-code{font-family:var(--mono);font-size:12px;color:#7A8199;margin-top:6px}
.rep-sec{font-family:var(--display);font-size:12px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:#7A8199;margin:34px 0 0;padding-bottom:8px;
  border-bottom:1px solid #DFE3EF}
.rep-figs{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:18px;margin-top:16px}
.rep-figs-sm{margin-top:14px;padding-top:14px;border-top:1px dashed #DFE3EF}
.rep-fig{display:flex;flex-direction:column;gap:3px}
.rep-fig b{font-family:var(--mono);font-size:19px;font-weight:600;letter-spacing:-.03em;
  color:#141827;font-variant-numeric:tabular-nums}
.rep-figs-sm .rep-fig b{font-size:15px}
.rep-fig span{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;
  color:#7A8199;font-weight:650}
.rep-note{margin:14px 0 0;font-size:12.5px;color:#4A5168}
.rep-warn{border-left:3px solid #A9660A;padding-left:11px;color:#A9660A}
.report .inv-table tfoot td{border-top:2px solid #141827;border-bottom:0;padding-top:12px}

/* printing an invoice from inside the app: hide the app, show the document */
.print-only{display:none}
@media print{
  body.printing-invoice > *{display:none !important}
  body.printing-invoice #printInvoice{display:block !important;box-shadow:none;
    border-radius:0;width:100%;padding:0;background:#fff;color:#141827}
  body.printing-invoice{background:#fff}
  /* Same treatment for the report. Sections and table rows are kept off
     page breaks — a heading stranded at the foot of a page, or a person's
     row split from the assets underneath it, reads as a broken document. */
  body.printing-report > *{display:none !important}
  body.printing-report #printReport{display:block !important;box-shadow:none;
    border-radius:0;width:100%;padding:0;background:#fff;color:#141827}
  body.printing-report{background:#fff}
  .rep-sec{break-after:avoid;page-break-after:avoid}
  .rep-figs,.report tr{break-inside:avoid;page-break-inside:avoid}
  .report .inv-table thead{display:table-header-group}
  .inv-stamp.draft{background:#FBEEDA;color:#A9660A;border:1px solid #A9660A}
  /* The payment block is tinted, and browsers drop background colour when
     printing unless told otherwise. Losing it here would merge the one
     block the client has to act on into the page around it. */
  .inv-bank{break-inside:avoid;page-break-inside:avoid;
    -webkit-print-color-adjust:exact;print-color-adjust:exact}
  .inv-logo{max-height:40px}
  .no-print{display:none !important}
  .invoice-page{background:#fff;padding:0;display:block}
  .invoice{box-shadow:none;border-radius:0;width:100%;padding:0;font-size:12px}
  .inv-head h1{font-size:26px}
  @page{margin:18mm}
}

/* the landing page's visible sign-in, next to the icon buttons */
.lp .lp-signin{border:1px solid var(--line);background:var(--card);border-radius:999px;
  padding:12px 22px;font-size:15px;font-weight:600;color:var(--ink);
  transition:transform .12s,box-shadow .16s}
.lp .lp-signin:hover{transform:translateY(-1px);box-shadow:var(--shadow-s)}
/* mobile: swap the two unlabelled icon circles for the one clear "Log in"
   text link instead of hiding it — a label reads better than icon-only
   on a phone-width nav */
@media (max-width:520px){
  .lp-icons .lp-ico{display:none}
  .lp .lp-signin{display:inline-flex;border:0;background:none;box-shadow:none;padding:8px 4px}
}

/* ---------------- approvals ---------------- */
.ap-tasks{display:flex;flex-direction:column;gap:1px;background:var(--rule-soft)}
.approval-card{background:var(--surface);display:flex;flex-direction:column}
.ap-head{display:flex;align-items:center;gap:10px;padding:11px 15px;cursor:pointer;transition:background .12s}
.ap-head:hover{background:var(--surface-2)}
.ap-chevron{flex:none;color:var(--ink-3);transition:transform .15s}
.ap-chevron.open{transform:rotate(90deg)}
.ap-grid{display:flex;flex-wrap:wrap;gap:8px;padding:0 15px 13px}
.ap-tile{width:110px;flex:none;display:flex;flex-direction:column;border:1px solid var(--rule);
  border-radius:8px;overflow:hidden;background:var(--surface);text-align:left}
.ap-file-tile:hover{border-color:var(--accent)}
.ap-tile-thumb{position:relative;width:100%;height:74px;background:var(--surface-2);
  display:flex;align-items:center;justify-content:center;color:var(--ink-3)}
.ap-tile-thumb img,.ap-tile-thumb video{width:100%;height:100%;object-fit:cover;display:block}
.ap-tile-play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  color:#fff;background:rgba(0,0,0,.28)}
.ap-tile-meta{padding:6px 8px 8px;display:flex;flex-direction:column;gap:5px}
.ap-tile-name{font-size:11px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ap-tile-meta .pill{align-self:flex-start;font-size:10px}
.ap-progress-track{height:4px}
.ap-progress-track span{transition:width .18s linear}
.ap-progress-pct{font-family:var(--mono);font-size:10px;color:var(--ink-3)}
.ap-tile-drop{align-items:center;justify-content:center;gap:6px;height:126px;border:1.5px dashed var(--rule);
  color:var(--ink-3);font-size:11px;font-weight:600;cursor:pointer;transition:border-color .14s,background .14s,color .14s}
.ap-tile-drop:hover,.ap-tile-drop.drag-over{border-color:var(--accent);color:var(--accent);background:var(--accent-wash)}
.ap-ref-tile{position:relative;cursor:pointer}
.ap-ref-remove{position:absolute;top:5px;right:5px;width:19px;height:19px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.55);color:#fff;
  border:0;padding:0;line-height:0;opacity:0;transition:opacity .12s,background .12s}
.ap-ref-remove:hover{background:rgba(0,0,0,.8)}
.ap-ref-tile:hover .ap-ref-remove,.ap-ref-remove:focus-visible{opacity:1}
.ap-preview{display:flex;justify-content:center;background:var(--surface-2);border:1px solid var(--rule-soft);
  border-radius:10px;padding:10px;min-height:80px;align-items:center}
.ap-preview img,.ap-preview video{max-width:100%;max-height:420px;border-radius:6px;display:block}
.divider{height:1px;background:var(--rule-soft);border:0;margin:0}
.ap-versions{display:flex;gap:6px;flex-wrap:wrap}
.ap-versions .pill{cursor:pointer;border:1.5px solid transparent;font-family:var(--mono)}
.ap-versions .pill:hover{filter:brightness(1.08)}
.ap-versions .pill.ap-version-active{border-color:var(--ink)}

/* Media lightbox — opens *over* the brief drawer, so it sits above both the
   drawer (90) and its scrim (80), but below toasts (120) so an error raised
   while it is open is still readable. Deliberately dark in both themes, like
   every other media viewer: a light surround changes how the artwork reads,
   and these are reference images people are judging. */
.lightbox-scrim{position:fixed;inset:0;z-index:110;background:rgba(8,6,10,.86);
  backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;
  padding:28px;animation:lbIn .16s ease-out}
@keyframes lbIn{from{opacity:0}}
.lightbox-box{position:relative;display:flex;align-items:center;justify-content:center;
  max-width:min(1080px,92vw);max-height:88vh;animation:lbPop .18s cubic-bezier(.2,.8,.3,1)}
@keyframes lbPop{from{opacity:0;transform:scale(.97)}}
.lightbox-box img,.lightbox-box video{max-width:min(1080px,92vw);max-height:88vh;
  width:auto;height:auto;object-fit:contain;display:block;border-radius:10px;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.7)}
/* aspect-ratio rather than the old padding-top hack — the embed has no
   intrinsic size, so without it the iframe collapses to nothing */
.lightbox-embed{width:min(1080px,92vw);aspect-ratio:16/9;max-height:88vh}
.lightbox-embed iframe{width:100%;height:100%;border:0;border-radius:10px;display:block;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.7)}
/* absolute against the scrim (which is fixed at inset:0, so this is the
   viewport corner) rather than on the box: an image sized to its own aspect
   ratio can leave the box edge anywhere, and the close button should not
   move with it. Not `fixed` either — see the note in openMediaLightbox. */
.lightbox-close{position:absolute;top:16px;right:16px;width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;border:0;padding:0;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font-size:15px;line-height:1;
  transition:background .14s,transform .12s}
.lightbox-close:hover{background:rgba(255,255,255,.26);transform:scale(1.06)}
.lightbox-close:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media (max-width:640px){
  .lightbox-scrim{padding:14px}
  .lightbox-close{top:10px;right:10px}
}
.ap-thread{display:flex;flex-direction:column;gap:9px}
.ap-comment{border:1px solid var(--rule-soft);border-radius:8px;padding:8px 10px;font-size:12.5px;
  background:var(--surface)}
.ap-comment-head{display:flex;justify-content:space-between;gap:8px;font-size:11px;color:var(--ink-3);
  margin-bottom:3px}
.ap-comment-head strong{color:var(--ink-2);font-weight:650}
.timer-discard{width:26px;height:26px;color:var(--ink-3)}
.timer-discard:hover{color:var(--crit)}

/* ---- custom invoice lines (builder) ---- */
.inv-custom{display:grid;grid-template-columns:1fr 66px 110px auto auto;gap:7px;align-items:center;
  padding:8px;border:1px solid var(--rule);border-radius:8px;background:var(--surface);margin-bottom:7px}
.inv-custom input{width:100%}
.inv-custom-amt{font-size:13px;font-weight:600;color:var(--ink);white-space:nowrap;text-align:right;min-width:88px}
@media (max-width:560px){
  /* the description needs the full width on a phone; qty/price/amount ride
     underneath rather than being squeezed to a few characters each */
  .inv-custom{grid-template-columns:1fr 1fr;grid-template-areas:'d d' 'q u' 'a r'}
  .inv-custom > *:nth-child(1){grid-area:d}
  .inv-custom > *:nth-child(2){grid-area:q}
  .inv-custom > *:nth-child(3){grid-area:u}
  .inv-custom > *:nth-child(4){grid-area:a;text-align:left}
  .inv-custom > *:nth-child(5){grid-area:r}
}

/* Shown when the deployed app.js has moved on from what this tab is running.
   Fixed to the bottom so it cannot be lost behind a scrolled view. */
.update-bar{position:fixed;left:50%;bottom:20px;transform:translateX(-50%);z-index:130;
  display:flex;align-items:center;gap:12px;padding:9px 10px 9px 16px;border-radius:999px;
  background:var(--ink);color:var(--paper);font-size:13px;font-weight:500;
  box-shadow:0 8px 28px -8px rgba(0,0,0,.5)}
.update-bar .btn{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}

/* A person's name on Traffic & Schedules opens their full calendar. */
.bperson{cursor:pointer;border-radius:8px;transition:background .12s}
.bperson:hover{background:var(--surface-2)}
.bperson:hover .who-name{color:var(--accent)}

/* A day that has already happened is closed for scheduling. Muted rather
   than hidden — the hours that were worked still need to be readable. */
.bslot-past{background:repeating-linear-gradient(135deg,transparent 0 6px,var(--rule-soft) 6px 7px);
  cursor:not-allowed}
.bslot-past .bchip{opacity:.55}
.bslot.drop-shut{outline:2px dashed var(--crit);outline-offset:-2px;background:var(--crit-wash)}

/* ---- approval review: thread scrolls, composer stays reachable ---- */
.ap-thread-head{display:flex;align-items:baseline;gap:8px}
.ap-thread-count{font-family:var(--mono);font-size:11px;color:var(--ink-3)}
/* Its own scroll box. Without this the thread grew unbounded and pushed the
   reply box off the end of a very long page. */
/* Inside .ap-review the thread is the only thing that scrolls, so it takes
   the leftover height rather than guessing at a vh figure that collapses on
   a short screen. The standalone max-height is the fallback for any other
   context. */
/* deliberately not scroll-behavior:smooth — the thread should *open* at the
   newest note, not animate its way there while you are reading */
.ap-thread{max-height:380px;overflow-y:auto;padding-right:4px;
  display:flex;flex-direction:column;gap:9px}
.ap-comment{border:1px solid var(--rule-soft);border-radius:10px;padding:10px 12px;
  background:var(--surface-2)}
/* Your own notes read as yours without needing to check the name each time. */
.ap-comment.own{background:var(--accent-wash);border-color:color-mix(in oklab,var(--accent) 30%,transparent)}
.ap-comment-head{margin-bottom:4px}
.ap-comment-body{font-size:13px;line-height:1.55;color:var(--ink);white-space:pre-wrap}
.ap-composer{background:var(--surface);padding-top:10px;margin-top:2px;
  display:flex;flex-direction:column;gap:8px;border-top:1px solid var(--rule-soft)}
.ap-composer .btn{align-self:flex-start}

/* The review drawer is a frame, not a page: the file and the reply box hold
   their positions and only the conversation moves. Without this the thread
   grew unbounded, pushed the reply two thousand pixels down the scroll, and
   the way to respond became the hardest thing in the drawer to reach.

   .dr-body wraps body()'s return value in one node, so the frame lives on
   that node (.ap-frame) rather than on .dr-body itself. */
.dr-body.ap-review{overflow:hidden}
.ap-frame{display:flex;flex-direction:column;gap:11px;flex:1;min-height:0;overflow:hidden}
.ap-frame > .ap-preview{flex:0 1 auto;min-height:100px;overflow:hidden}
.ap-frame > .ap-preview img,
.ap-frame > .ap-preview video{max-height:100%;width:auto;object-fit:contain}
.ap-frame > .ap-thread{flex:1 1 40%;min-height:110px;max-height:none}
.ap-frame > .ap-versions,
.ap-frame > .divider,
.ap-frame > .ap-thread-head,
.ap-frame > .ap-composer,
.ap-frame > .hint{flex:0 0 auto}

/* ---- download affordances on private files ---- */
.ap-meta-row{display:flex;align-items:center;gap:10px}
.ap-meta-row .hint{flex:1;min-width:0}
/* Sits beside the remove button on a reference tile, and stays visible for
   people who cannot edit — downloading a moodboard is not an edit. */
.ap-ref-dl{position:absolute;top:5px;right:5px;width:19px;height:19px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.55);color:#fff;
  border:0;padding:0;line-height:0;opacity:0;transition:opacity .12s,background .12s}
.ap-ref-dl:hover{background:rgba(0,0,0,.8)}
.ap-ref-tile:hover .ap-ref-dl,.ap-ref-dl:focus-visible{opacity:1}
/* when both are present the remove button shifts left so they do not stack */
.ap-ref-tile:has(.ap-ref-dl) .ap-ref-remove{right:29px}
.lightbox-dl{position:absolute;top:16px;right:62px;padding:7px 14px;border-radius:999px;
  border:0;cursor:pointer;background:rgba(255,255,255,.14);color:#fff;font-size:13px;font-weight:500;
  transition:background .14s}
.lightbox-dl:hover{background:rgba(255,255,255,.26)}
.lightbox-dl:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media (max-width:640px){ .lightbox-dl{top:10px;right:54px;padding:6px 11px;font-size:12px} }

/* ---- brief fields that grow, then offer the rest ---- */
.brief-wrap{position:relative;display:flex;flex-direction:column}
.brief-ta{resize:vertical;overflow:hidden;transition:height .16s ease}
/* A fade at the cut edge, so a clipped brief reads as continuing rather
   than as one that simply ends mid-sentence. */
.brief-wrap.is-clipped::after{content:'';position:absolute;left:1px;right:1px;bottom:30px;height:44px;
  pointer-events:none;border-radius:0 0 8px 8px;
  background:linear-gradient(transparent,var(--surface))}
.brief-more{align-self:flex-start;margin-top:6px;padding:3px 0;border:0;background:none;cursor:pointer;
  color:var(--accent);font-size:12px;font-weight:600;font-family:inherit}
.brief-more:hover{text-decoration:underline}
.brief-more[hidden]{display:none}

/* The add-a-link tile turns into its own small form, so adding a reference
   never navigates away from the brief being written. */
.ap-tile.ap-tile-form{width:220px;height:auto;align-items:stretch;justify-content:flex-start;
  gap:6px;padding:9px;cursor:default;border-style:solid;border-color:var(--accent)}
.ap-tile-form input{width:100%;font-size:12px;padding:6px 8px}
.ap-link-actions{display:flex;gap:6px;margin-top:2px}
.ap-link-actions .btn{flex:1}
