/* ═══════════════════════════════════════════════════════════════════════
   The back-office screens: login, apply, team, dashboards.

   Same tokens as the public site — these are the same product, and a
   portal that looks like a different company is the commonest way a
   studio site loses the thread after sign-in. What changes is density:
   the marketing pages breathe, an app the team works in all day does not.
   ═══════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────── login & apply ── */
/* These two are screens, not documents: the page itself never scrolls.
   If a step is taller than the viewport, the form column scrolls inside
   its own panel and the art panel stays put. */
/* One screen, every device. The art panel is a static header, the form
   sits under it, and the whole thing fits 100svh — on a phone the type
   simply gets smaller rather than the page getting longer.
   (Two earlier attempts failed differently: position:fixed on the body
   broke the grid, and sizing everything in vh made it enormous on a
   tall phone. Fixed pixel steps per breakpoint is what actually works.) */
html:has(body.auth){height:100%;overflow:hidden}
body.auth{padding:0;margin:0;height:100svh;overflow:hidden}
.split{display:grid;grid-template-columns:1.05fr .95fr;height:100svh;overflow:hidden}
.split--rev{grid-template-columns:.95fr 1.05fr}
.split--rev .split__art{order:2}
.split--rev .split__form{order:1}
@media (max-width:900px){
  .split,.split--rev{grid-template-columns:1fr}
  .split--rev .split__art{order:1} .split--rev .split__form{order:2}
  .split__art{min-height:auto;padding-block:clamp(80px,14vw,120px) clamp(40px,6vw,60px)}
}

.split__art{position:relative;overflow:hidden;display:flex;align-items:center;
  padding:clamp(40px,5vw,72px);
  background:linear-gradient(158deg,#EDEAFB 0%,#E4EFF3 44%,#F8EBEE 100%)}
.art--hot{background:linear-gradient(158deg,#FDEEE1 0%,#F6ECF6 48%,#E6EFF9 100%)}
.split__artin{position:relative;z-index:2;max-width:30rem;display:flex;flex-direction:column;gap:20px}
.split__artin p{margin:0;color:var(--ink-2);font-size:17.5px;line-height:1.55;max-width:34ch}
.a1{top:8%;right:-8%;width:clamp(160px,22vw,320px);aspect-ratio:1;background:var(--lav);
  border-radius:46% 54% 52% 48%/50% 44% 56% 50%}
.a2{bottom:10%;right:16%;width:clamp(56px,7vw,104px);aspect-ratio:1;background:var(--hot);
  border-radius:26px;transform:rotate(18deg)}
.a3{top:26%;left:-4%;width:clamp(60px,8vw,120px);aspect-ratio:1;background:var(--sage);border-radius:50%}
/* The dashed route belongs on the marketing pages, where it means the
   journey through a project. On a login screen it points at nothing. */
.art__dash{display:none}

.authmark{display:inline-flex;align-items:center;gap:11px;font-weight:900;font-size:20px;
  letter-spacing:-.03em;margin-bottom:8px}
.authmark img{border-radius:10px}
.authpts{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:11px}
.authpts li{display:flex;gap:11px;align-items:flex-start;font-size:16px;font-weight:600;color:var(--ink-2)}
.authpts i{color:var(--brand);font-size:19px;flex-shrink:0;margin-top:1px}

.split__form{display:flex;align-items:center;justify-content:center;padding:clamp(30px,5vw,72px);
  background:var(--card);min-height:0}
.split__art{overflow:hidden}
.authbox{width:100%;max-width:26.5rem;display:flex;flex-direction:column;gap:6px}
.h1--auth{font-size:clamp(40px,6vw,62px);margin-bottom:20px}
.form__aux{display:flex;justify-content:space-between;align-items:center;gap:12px;
  font-size:14.5px;font-weight:600;margin:2px 0 4px}
.form__aux a{color:var(--brand)}
.check{flex-direction:row!important;align-items:center;gap:11px!important;font-size:14.5px!important;
  color:var(--ink-2);cursor:pointer;user-select:none}
.check input{position:absolute;opacity:0;width:0;height:0}
.check span{position:relative;padding-inline-start:30px;font-weight:600}
.check span::before{content:"";position:absolute;inset-inline-start:0;top:50%;transform:translateY(-50%);
  width:21px;height:21px;border-radius:7px;border:2px solid var(--line);background:var(--card);
  transition:background .2s,border-color .2s}
.check span::after{content:"";position:absolute;inset-inline-start:7px;top:50%;
  width:6px;height:11px;border:solid #fff;border-width:0 2.5px 2.5px 0;
  transform:translateY(-62%) rotate(45deg) scale(.4);opacity:0;transition:opacity .2s,transform .25s}
.check input:checked + span::before{background:var(--brand);border-color:var(--brand)}
.check input:checked + span::after{opacity:1;transform:translateY(-62%) rotate(45deg) scale(1)}
.check input:focus-visible + span::before{outline:3px solid var(--brand);outline-offset:3px}
/* 2 Sep: the checkbox itself is invisible (opacity:0, above) — the fake
   box in ::before is what a "required and unchecked" state has to mark.
   Same shake as site.css's .form input.is-bad, on the visible box instead. */
.check input.is-bad + span::before{border-color:#B3261E;animation:formshake .4s}
/* A native select renders as the operating system's control and looks
   like nothing else on the page. Stripped and redrawn with our chevron. */
.selwrap{position:relative;display:block}
.selwrap::after{content:"";position:absolute;inset-inline-end:18px;top:50%;width:9px;height:9px;
  border:solid var(--ink-2);border-width:0 2.5px 2.5px 0;
  transform:translateY(-70%) rotate(45deg);pointer-events:none}
.form select{-webkit-appearance:none;appearance:none;width:100%;cursor:pointer;
  font:inherit;font-size:16px;font-weight:600;color:var(--ink);background:var(--card-2);
  border:2px solid var(--line);border-radius:15px;padding:14px 44px 14px 15px;
  transition:border-color .22s,background .22s}
.form select:hover{border-color:var(--ink-3)}
.form select:focus{outline:none;border-color:var(--brand);background:var(--card)}
.authalt{margin:14px 0 0;text-align:center;font-size:15px;font-weight:600;color:var(--ink-2)}
.authalt a{color:var(--brand)}
.steps{display:flex;gap:7px;margin-bottom:14px}
.steps i{height:5px;flex:1;border-radius:99px;background:var(--line)}
.steps i.on{background:var(--brand)}

/* ──────────────────────────────────────────────────────── team ── */
.team{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
  gap:clamp(16px,2.4vw,28px);margin-bottom:clamp(60px,8vw,110px)}
.tm{position:relative;background:var(--card);border:2px solid var(--line);border-radius:28px;
  padding:clamp(26px,3vw,36px);overflow:hidden;
  transition:transform .42s cubic-bezier(.16,1,.3,1),box-shadow .42s,border-color .3s}
.tm::before{content:"";position:absolute;top:-46%;right:-26%;width:74%;aspect-ratio:1;
  background:var(--lav);border-radius:50%;transition:transform .55s cubic-bezier(.16,1,.3,1)}
.tm:nth-child(2)::before{background:var(--blush)}
.tm:nth-child(3)::before{background:var(--sage)}
.tm:hover{transform:translateY(-10px);box-shadow:var(--sh-lg);border-color:transparent}
.tm:hover::before{transform:scale(1.5) translate(-6%,10%)}
.tm > *{position:relative;z-index:2}
/* A real photo slot. Until a photograph is dropped in, the initial
   stands in — but the frame is the final size, so adding the picture
   later changes nothing about the layout. */
.tm__ph{position:relative;width:112px;height:112px;border-radius:28px;background:var(--card-2);
  border:3px solid var(--ink);display:flex;align-items:center;justify-content:center;
  font-weight:900;font-size:40px;letter-spacing:-.04em;color:var(--ink);overflow:hidden;
  transition:transform .42s cubic-bezier(.16,1,.3,1),border-color .3s}
.tm__ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.tm:hover .tm__ph{border-color:var(--brand)}
.tm:hover .tm__ph{transform:rotate(-6deg) scale(1.06)}
.tm__rule{width:56px;height:3px;border-radius:99px;background:var(--ink);margin:20px 0 16px;
  transition:width .42s cubic-bezier(.16,1,.3,1)}
.tm:hover .tm__rule{width:104px;background:var(--brand)}
.tm h3{margin:0;font-weight:900;font-size:clamp(22px,2.4vw,27px);letter-spacing:-.034em}
.tm__role{margin:4px 0 0;font-family:"Mono",ui-monospace,monospace;font-size:11px;font-weight:700;
  letter-spacing:.15em;text-transform:uppercase;color:var(--brand-2)}
.tm__tag{margin:12px 0 0;font-size:16px;font-weight:700;color:var(--ink)}
/* The bio used to grow the card on hover, which reflowed the grid and
   pushed everything below it down the page — worst on the longest bio.
   It is now an overlay inside a fixed-height card: nothing outside the
   card can move, whatever the length of the text. */
.tm{min-height:430px}
.tm__bio{position:absolute;left:0;right:0;bottom:0;z-index:4;
  margin:0;padding:clamp(24px,3vw,34px);
  background:linear-gradient(180deg,rgba(252,251,254,0) 0%,var(--card) 16%);
  color:var(--ink-2);font-size:15.5px;line-height:1.58;
  max-height:76%;overflow:auto;
  opacity:0;transform:translateY(14px);pointer-events:none;
  transition:opacity .38s ease,transform .42s cubic-bezier(.16,1,.3,1)}
.tm:hover .tm__bio,.tm:focus-within .tm__bio{opacity:1;transform:none;pointer-events:auto}

/* ══════════════════════════════════════════════════ dashboards ══ */
body.app{padding:0;background:var(--s-bg)}
.appshell{min-height:100svh;display:flex;flex-direction:column}

/* the dark window bar across the top, per the reference */
.appbar{position:sticky;top:0;z-index:100;display:flex;align-items:center;gap:18px;
  padding:12px clamp(14px,2.2vw,26px);background:var(--ink);color:#fff}
.appbar__mark{display:flex;align-items:center;gap:10px;font-weight:900;font-size:17px;letter-spacing:-.03em}
.appbar__mark img{border-radius:8px}
.appbar__nav{display:flex;align-items:center;gap:2px;margin-inline:auto;
  background:rgba(255,255,255,.07);border-radius:999px;padding:5px}
.appbar__nav a{display:inline-flex;align-items:center;gap:8px;padding:9px 16px;border-radius:999px;
  font-size:14px;font-weight:700;color:rgba(255,255,255,.66);transition:background .2s,color .2s}
.appbar__nav a:hover{color:#fff;background:rgba(255,255,255,.1)}
.appbar__nav a.on{background:#fff;color:var(--ink)}
.appbar__nav i{font-size:17px}
@media (max-width:900px){ .appbar__nav{display:none} }
.appbar__end{display:flex;align-items:center;gap:8px}
.iconbtn{position:relative;width:40px;height:40px;border-radius:13px;border:0;cursor:pointer;
  background:rgba(255,255,255,.09);color:#fff;display:flex;align-items:center;justify-content:center}
.iconbtn i{font-size:19px}
.iconbtn .dot{position:absolute;top:9px;right:10px;width:8px;height:8px;border-radius:99px;
  background:var(--hot);border:2px solid var(--ink)}
.avatarbtn{display:flex;align-items:center;gap:8px;border:0;cursor:pointer;padding:5px 10px 5px 5px;
  border-radius:999px;background:rgba(255,255,255,.09);color:#fff}
.avatar{width:30px;height:30px;border-radius:999px;background:var(--brand);display:flex;
  align-items:center;justify-content:center;font-weight:900;font-size:13px}

.apppage{flex:1;padding:clamp(20px,2.6vw,34px) clamp(14px,2.2vw,30px) 60px;
  max-width:1560px;width:100%;margin:0 auto}
.apphead{display:flex;flex-wrap:wrap;gap:16px;justify-content:space-between;align-items:flex-end;
  margin-bottom:clamp(18px,2.4vw,28px)}
.apphead h1{margin:0;font-weight:900;font-size:clamp(28px,3.4vw,40px);letter-spacing:-.04em}
.apphead p{margin:4px 0 0;color:var(--ink-2);font-size:16px}
.apphead__tools{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.search{display:flex;align-items:center;gap:10px;background:var(--card);border:2px solid var(--line);
  border-radius:16px;padding:11px 16px;min-width:min(300px,70vw)}
.search i{color:var(--ink-3);font-size:18px}
.search input{border:0;background:none;font:inherit;font-size:15px;flex:1;outline:none}

.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(10px,1.4vw,16px);
  margin-bottom:clamp(12px,1.6vw,18px)}
@media (max-width:900px){ .kpis{grid-template-columns:repeat(2,1fr)} }
.kpi{background:var(--card);border-radius:22px;padding:20px 22px;display:flex;flex-direction:column;gap:5px;
  box-shadow:var(--sh-sm);position:relative;overflow:hidden;
  transition:transform .3s cubic-bezier(.16,1,.3,1)}
.kpi:hover{transform:translateY(-4px)}
.kpi::after{content:"";position:absolute;top:-30%;right:-14%;width:52%;aspect-ratio:1;
  border-radius:50%;opacity:.5}
.kpi.brand::after{background:var(--lav)} .kpi.hot::after{background:var(--s-warn-bg)}
.kpi.mint::after{background:var(--sage)} .kpi.violet::after{background:var(--s-violet-bg)}
.kpi span{position:relative;font-family:"Mono",ui-monospace,monospace;font-size:10px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.kpi b{position:relative;font-weight:900;font-size:clamp(26px,3vw,36px);letter-spacing:-.04em}

.panels{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(10px,1.4vw,16px)}
/* The panel is a surface, not a grid item. It used to carry
   `grid-column:span 6` itself — the twelve-column `.panels` layout baked
   into the component — so dropping two panels into any other grid made each
   one demand six columns and take the whole row on its own. The spans
   belong to the parent that defines the columns. */
.pnl{background:var(--card);border-radius:24px;padding:clamp(18px,2.2vw,26px);box-shadow:var(--sh-sm);
  display:flex;flex-direction:column;gap:14px;min-height:240px}
.panels > .pnl{grid-column:span 6}
.panels > .pnl.wide{grid-column:span 8} .panels > .pnl.narrow{grid-column:span 4}
@media (max-width:1000px){ .panels > .pnl,.panels > .pnl.wide,.panels > .pnl.narrow{grid-column:span 12} }
.pnl__h{display:flex;align-items:center;justify-content:space-between;gap:12px}
.pnl__h h2{margin:0;font-weight:900;font-size:19px;letter-spacing:-.03em}
.pnl__h a{font-size:13.5px;font-weight:700;color:var(--brand)}
.rows{display:flex;flex-direction:column;gap:9px}
.row{display:flex;align-items:center;gap:13px;padding:12px 14px;border-radius:15px;background:var(--card-2)}
.row__sw{width:38px;height:38px;border-radius:12px;flex-shrink:0}
.row b{font-weight:800;font-size:15.5px;letter-spacing:-.02em}
.row span{display:block;font-size:13px;color:var(--ink-2)}
/* The status pill. Was scoped to `.row`; the project cards need the same
   thing outside a row, so the look lives on `.pill` and only the shunt to
   the right stays with the row. */
.pill{font-family:"Mono",ui-monospace,monospace;font-size:9.5px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;padding:5px 11px;border-radius:999px;
  background:var(--card-2);color:var(--ink-2);white-space:nowrap}
.row .pill{margin-inline-start:auto;background:var(--lav);color:var(--brand-2)}
.pill.i{background:var(--lav);color:var(--brand-2)}
.pill.g,.row .pill.g{background:var(--sage);color:var(--mint,#03363D)}
.pill.o,.row .pill.o{background:var(--s-warn-bg);color:var(--s-warn-ink)}
.pill.r{background:var(--s-bad-bg);color:var(--s-bad-ink)}
.spark{display:flex;align-items:flex-end;gap:5px;height:110px;margin-top:auto}
.spark i{flex:1;border-radius:6px 6px 3px 3px;background:var(--lav);transition:background .3s}
.spark i.hi{background:var(--brand)}


/* The apply textarea overflowed its card: no width, and a horizontal
   resize grip the user could drag past the edge. */
.form textarea{width:100%;max-width:100%;resize:vertical;min-height:110px}
.form input,.form select,.form textarea{max-width:100%}
.authbox{min-width:0}
.opt{font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);margin-inline-start:6px}


/* ═══════════════════════════════════════════ the apply wizard ══ */
/* The questions were all on one page; the real application is stepped,
   and asking eight things at once is the fastest way to lose someone. */
.wiz{position:relative}
/* A <fieldset> will not shrink below its content's intrinsic width
   unless min-width is set — that is a UA rule, not a cascade problem,
   which is why the inputs kept spilling out of the card here while the
   login form (no fieldset) was fine all along. */
.wstep{border:0;margin:0;padding:0;min-width:0;display:none;flex-direction:column;gap:14px}
.wstep > *{min-width:0}
.form__row{min-width:0}
.form__row > label{min-width:0}
.wstep.is-on{display:flex;animation:stepIn .42s cubic-bezier(.16,1,.3,1)}
@keyframes stepIn{from{opacity:0;transform:translateX(14px)}to{opacity:1;transform:none}}
.wnav{display:flex;gap:10px;margin-top:6px}
/* The last step's label ran to three lines inside a flex:1 button and
   turned it into a slab. Buttons size to their text now. */
.wnav .btn{justify-content:center;white-space:nowrap;flex:0 1 auto}
.wnav [data-next]{flex:1}
/* Superseded by the global [hidden]{display:none!important} in site.css,
   kept because this file is also loaded on its own in the app screens. */
.wnav .btn[hidden]{display:none}
.steps i{transition:background .35s}

/* ── our own dropdown ──────────────────────────────────────────── */
/* A native <select> renders its option list as an operating-system
   window: CSS cannot touch it, which is why it looked like Windows in
   the middle of the page. This is a button plus a list we own. */
.dd{position:relative;display:flex;flex-direction:column;gap:7px}
.dd__lab{font-size:13.5px;font-weight:700;color:var(--ink-2)}
.dd__btn{width:100%;text-align:start;cursor:pointer;font:inherit;font-size:16px;font-weight:600;
  color:var(--ink);background:var(--card-2);border:2px solid var(--line);border-radius:15px;
  padding:14px 44px 14px 15px;position:relative;transition:border-color .22s,background .22s}
.dd__btn:hover{border-color:var(--ink-3)}
.dd.is-open .dd__btn{border-color:var(--brand);background:var(--card)}
.dd__btn:focus-visible{outline:3px solid var(--brand);outline-offset:3px}
.dd__btn::after{content:"";position:absolute;inset-inline-end:18px;top:50%;width:9px;height:9px;
  border:solid var(--ink-2);border-width:0 2.5px 2.5px 0;
  transform:translateY(-70%) rotate(45deg);transition:transform .28s}
.dd.is-open .dd__btn::after{transform:translateY(-30%) rotate(225deg)}
.dd__list{position:absolute;z-index:30;top:calc(100% + 8px);left:0;right:0;
  background:var(--card);border:2px solid var(--brand);border-radius:18px;padding:6px;
  box-shadow:var(--sh);display:flex;flex-direction:column;gap:2px;
  opacity:0;transform:translateY(-8px) scale(.98);pointer-events:none;transform-origin:top;
  transition:opacity .22s,transform .28s cubic-bezier(.16,1,.3,1)}
.dd.is-open .dd__list{opacity:1;transform:none;pointer-events:auto}
.dd__opt{text-align:start;cursor:pointer;font:inherit;font-size:15.5px;font-weight:600;
  border:0;background:none;color:var(--ink-2);border-radius:12px;padding:12px 14px;
  transition:background .16s,color .16s}
.dd__opt:hover{background:var(--card-2);color:var(--ink)}
.dd__opt.on{background:var(--lav);color:var(--brand-2);font-weight:800}
.dd__opt:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}


/* ═════════════════════════════════════════ deadline calendar ══ */
.cal__native{display:none}
/* A dropdown of vague ranges does not help anyone schedule. A real date
   does — and the note under it is the honest part: the nearer the date,
   the likelier the answer is no. */
/* Inline, the calendar shoved everything below it down the card. It is
   a popover now: closed by default, floating, so opening it moves nothing. */
.cal{position:relative;display:flex;flex-direction:column;gap:7px}
/* Below the trigger, the calendar ran off the bottom of the card and
   made the page scroll to reach it. It opens to the side instead, and
   only falls back underneath when there is no room beside it. */
.cal__pop{position:absolute;z-index:40;top:-10px;left:calc(100% + 14px);width:312px;
  background:var(--card);border:2px solid var(--brand);border-radius:18px;padding:14px;
  box-shadow:var(--sh);opacity:0;transform:translateY(-8px) scale(.98);pointer-events:none;
  transform-origin:top;transition:opacity .22s,transform .28s cubic-bezier(.16,1,.3,1)}
.cal.is-open .cal__pop{opacity:1;transform:none;pointer-events:auto}
@media (max-width:1180px){
  .cal__pop{top:calc(100% + 8px);left:0;width:min(312px,100%)}
}
.cal.is-open .dd__btn{border-color:var(--brand);background:var(--card)}
.cal__warn{margin:12px 0 0}
.cal__top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}
.cal__mo{font-weight:800;font-size:16px;letter-spacing:-.02em}
.cal__nav{display:flex;gap:6px}
.cal__nav button{width:32px;height:32px;border-radius:10px;border:2px solid var(--line);
  background:var(--card);cursor:pointer;color:var(--ink-2);display:flex;align-items:center;
  justify-content:center;font:inherit;font-weight:800;transition:border-color .2s,color .2s}
.cal__nav button:hover{border-color:var(--ink);color:var(--ink)}
.cal__grid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
.cal__dow{font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding:4px 0}
.cal__d{aspect-ratio:1;border:0;background:none;border-radius:10px;cursor:pointer;font:inherit;
  font-size:14px;font-weight:700;color:var(--ink-2);display:flex;align-items:center;
  justify-content:center;position:relative;transition:background .18s,color .18s}
.cal__d:hover:not(:disabled){background:var(--lav);color:var(--brand-2)}
.cal__d:disabled{color:var(--ink-3);opacity:.35;cursor:default}
.cal__d.is-sel{background:var(--brand);color:#fff}
.cal__d.is-tight:not(.is-sel){box-shadow:inset 0 0 0 2px #F5C08A}
.cal__d.empty{visibility:hidden}
.cal__out{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:14.5px;font-weight:700}
.cal__out b{color:var(--brand)}
.cal__warn{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink-2);
  background:var(--s-warn-bg);border-radius:12px;padding:11px 14px}
.cal__warn b{color:var(--s-warn-ink)}


/* Step two is the tallest; it scrolls on its own rather than growing
   the card past the viewport. */
/* The step had its own scrollbar, which is still scrolling as far as
   anyone using it is concerned. It fits instead. */
.wstep{min-width:0;overflow:visible}

/* review + sent */
.revlede{margin:0 0 4px;font-size:14.5px;font-weight:700;color:var(--ink-2)}
.review{margin:0;display:flex;flex-direction:column;gap:1px;background:var(--line);
  border:2px solid var(--line);border-radius:16px;overflow:hidden}
.review div{background:var(--card);padding:13px 16px;display:flex;gap:14px;
  justify-content:space-between;align-items:baseline}
.review dt{font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);flex-shrink:0}
.review dd{margin:0;font-size:15px;font-weight:700;text-align:end;word-break:break-word}
.review dd.none{color:var(--ink-3);font-weight:600}
.sent{display:flex;flex-direction:column;gap:14px;align-items:flex-start;
  animation:stepIn .5s cubic-bezier(.16,1,.3,1)}
.sent__tick{width:76px;height:76px;border-radius:999px;background:var(--mint,#2FA89A);
  display:flex;align-items:center;justify-content:center;color:#fff;
  box-shadow:0 18px 40px -14px rgba(47,168,154,.7)}
.sent__tick i{font-size:36px}
.sent h2{margin:0;font-weight:900;font-size:clamp(34px,5vw,48px);letter-spacing:-.04em}
.sent p{margin:0;font-size:16.5px;line-height:1.6;color:var(--ink-2)}
.sent b{color:var(--ink);font-weight:800}
.sent__note{font-family:"Mono",ui-monospace,monospace;font-size:10.5px!important;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}


/* ═════════════════════════════════════════ mobile · back office ══ */
@media (max-width:820px){
  /* ONE SCREEN. A compact static header, then the form, both inside
     100svh. Type steps down; the page never grows. */
  .split,.split--rev{grid-template-columns:1fr;grid-template-rows:auto 1fr;height:100svh}
  .split--rev .split__art{order:1} .split--rev .split__form{order:2}
  /* A decorative panel taking a third of a phone screen is why the
     buttons fell off the bottom. It is a strip now. */
  /* The 44px on top was clearance for the preview banner that used to be
     pinned there. The banner is gone; so is the clearance. */
  .split__art{padding:20px 18px 12px;min-height:0;align-items:flex-start}
  .split__artin{gap:8px;max-height:none}
  .split__artin .authpts,.split__artin .applysteps,.split__artin p{display:none}
  .split__artin .h2{font-size:clamp(19px,5.4vw,25px);line-height:1.02}
  .authmark{font-size:15px;gap:9px;margin-bottom:0}
  .authmark img{width:26px;height:26px}
  .a1{width:120px} .a2{width:40px} .a3{width:44px}

  /* Scrolling the whole panel was the bug, not the safety net: the nav
     buttons live inside it, so the one thing that had to stay on screen
     was the first thing to leave. The panel is fixed now. Inside it the
     card is a column — heading, step, then the buttons pinned to the
     bottom by `margin-top:auto`. The buttons are part of the frame, so
     no amount of content in a step can push them off. */
  .split__form{padding:11px 17px 14px;align-items:stretch;overflow:hidden}
  /* Centred: the card sizes to whatever the current step actually holds,
     then sits centered in the fixed panel — not stretched to the tallest
     step's height with the difference left as dead air under a short one.
     2 Sep, Elad: "the date section is too long" turned out to be exactly
     that — flex:1 here plus margin-top:auto on .wnav (below) used to force
     every step's card to the panel's full height so the buttons landed on
     the same pixel regardless of step; on step 2 (two dropdowns and a
     date) that meant a few hundred px of nothing between the date field
     and the buttons. Buttons now sit right under whichever step is
     showing, and the card recentres itself per step instead of staying
     pinned edge-to-edge. */
  .authbox{max-width:none;height:auto;max-height:100%;min-height:0;justify-content:center}
  /* The card carried its desktop padding (24px top and bottom) onto a
     phone, where 48px is most of a step's spare room. */
  .form{padding:15px 15px 16px;border-radius:22px;max-height:100%}
  .wiz{flex:0 1 auto;min-height:0}
  /* Shrinkable, so a step gives way before the frame does. 2 Sep: "gives
     way" was the bug — flex-shrink let the step report a box smaller than
     its own fields on a short phone (step 1's five fields, worst of it),
     and the real content painted past that shrunk box straight over the
     buttons, which had already been placed as if the step were its
     reported (wrong) height. Step 4's review already scrolls inside
     itself rather than doing this; the same fix, on every step except
     step 2 — its dropdown option list is absolutely positioned *inside*
     the step, and a scrolling step clips the list the moment it opens. */
  .wstep.is-on{flex:0 1 auto;min-height:0}
  .wstep.is-on:not([data-step="1"]){overflow-y:auto}
  .wnav{margin-top:auto;padding-top:7px}
  .authbox .eyebrow{font-size:9.5px;padding:6px 13px;margin-bottom:10px}
  .h1--auth{font-size:23px;margin-bottom:9px}
  .steps{margin-bottom:10px;gap:5px}
  .steps i{height:4px}

  .form{gap:7px}
  .form label{gap:4px;font-size:11.5px}
  /* 16px exactly, and never less. iOS Safari zooms the page in when you
     focus a field smaller than that, and a zoomed page is a scrolling
     page — the one thing this whole screen is built to avoid. The height
     comes out of the padding instead, where it costs nothing. */
  .form input,.form textarea,.dd__btn{padding:9px 13px;font-size:16px;border-radius:12px}
  .form textarea{min-height:52px}
  .form__row{gap:9px}
  .opt{font-size:8.5px}
  .check span{font-size:13px;padding-inline-start:26px}
  .check span::before{width:18px;height:18px}
  .btn{padding:12px 20px;font-size:14.5px;border-radius:15px}
  .wnav{gap:8px}
  .form__note{font-size:8.5px;line-height:1.35}
  .authalt{margin-top:9px;font-size:13px}

  .review div{padding:9px 13px}
  .review dt{font-size:8.5px} .review dd{font-size:13px}
  .revlede{font-size:12.5px}
  .sent{gap:10px} .sent__tick{width:54px;height:54px}
  .sent__tick i{font-size:26px}
  .sent h2{font-size:30px} .sent p{font-size:14px}
  .sent__note{font-size:8.5px}

  /* team */
  .team{grid-template-columns:1fr;gap:14px}
  .tm{min-height:0;padding:24px}
  .tm__bio{position:static;max-height:none;opacity:1;transform:none;pointer-events:auto;
    padding:0;margin-top:12px;background:none;overflow:visible}

  /* dashboards get a bottom tab bar */
  .appbar{padding:10px 14px}
  .appbar__mark b{display:none}
  .appbar__nav{display:flex;position:fixed;left:12px;right:12px;bottom:12px;top:auto;
    margin:0;background:var(--ink);border-radius:20px;padding:6px;
    box-shadow:0 20px 44px -14px rgba(var(--s-tint),.6);justify-content:space-around;z-index:120}
  .appbar__nav a{flex-direction:column;gap:3px;font-size:10px;padding:8px 6px;flex:1;text-align:center}
  .appbar__nav i{font-size:19px}
  .apppage{padding:18px 14px 110px}
  .apphead{align-items:stretch}
  .apphead h1{font-size:clamp(26px,8vw,34px)}
  .apphead__tools{flex-direction:column;align-items:stretch}
  .search{min-width:0}
  .kpis{grid-template-columns:1fr 1fr;gap:9px}
  .kpi{padding:16px 17px;border-radius:18px}
  .kpi b{font-size:26px}
  .panels > .pnl,.panels > .pnl.wide,.panels > .pnl.narrow{grid-column:span 12}
  .pnl{min-height:0;border-radius:20px}
  .row{padding:11px 12px}
  .row b{font-size:14.5px}
}

/* On a phone the date goes to the operating system's own picker — the
   iOS wheel is better than anything drawn here and it is what people
   already know. The custom calendar stays on desktop. */
@media (max-width:820px){
  .cal [data-caltrig],.cal__pop{display:none!important}
  /* 2 Sep, round two: smaller font-size wasn't enough — on a Hebrew-locale
     phone the filled-in native date input renders *itself* wider than its
     own 100% width once it holds a value ("2 בספטמבר 2026" apparently has
     an intrinsic minimum width Safari won't shrink below), not just its
     internal text overflowing a correctly-sized box. CSS width can't force
     a native control smaller than that; overflow:hidden on the wrapper
     clips whatever spills past it instead, so the card's edge is a hard
     boundary regardless of what iOS decides this input's real width is. */
  .cal__native{display:block;min-width:0;overflow:hidden;border-radius:12px}
  .cal__native input{width:100%;min-width:0;font:inherit;font-size:14.5px;font-weight:600;
    color:var(--ink);background:var(--card-2);border:2px solid var(--line);border-radius:12px;
    padding:10px 11px;box-sizing:border-box}
  .cal__native input:focus{outline:none;border-color:var(--brand)}
}
@media (max-width:420px){
  .appbar__nav a span,.appbar__nav a{font-size:9.5px}
  .kpis{grid-template-columns:1fr}
}

/* ── short screens ─────────────────────────────────────────────── */
/* Width was never the problem here; height was. A 667px iPhone SE and a
   640px Android have the same width as the phones that fit, and 200px
   less to fit it in, so the compaction keys off height. Everything below
   buys back vertical space and nothing else. */
@media (max-width:820px) and (max-height:750px){
  .split__art{padding:15px 17px 7px}
  .split__artin{gap:4px}
  .split__artin .h2{font-size:clamp(17px,4.8vw,21px)}
  .authmark{font-size:14px;gap:8px}
  .authmark img{width:22px;height:22px}
  .split__form{padding:8px 15px 11px}
  .h1--auth{font-size:20px;margin-bottom:6px}
  .authbox .eyebrow{margin-bottom:7px}
  .steps{margin-bottom:7px}
  .form{padding:12px 13px 13px;gap:6px}
  .form input,.form textarea,.dd__btn,.cal__native input{padding:7px 12px}
  .form textarea{min-height:44px}
  .form__row{gap:7px}
  .btn{padding:10px 18px;font-size:14px}
  .wnav{padding-top:5px}
  .authalt{margin-top:7px}
  .revlede{font-size:12px;margin-bottom:0}
  .review div{padding:7px 11px}
}

/* Ten fields read back on a 640px screen is more than a screen holds, and
   shrinking the text until it does would make the check-it-over step the
   hardest thing on the site to read. The list scrolls instead — inside
   its own box, under a fade that says there is more, while the Back and
   Send buttons stay put below it. Only this step ever does this. */
.wstep[data-step="3"].is-on{position:relative}
@media (max-width:820px){
  .wstep[data-step="3"].is-on .review{overflow-y:auto;min-height:0;
    -webkit-overflow-scrolling:touch}
  /* The fade is only honest while there is something below it, so it is
     driven by the scroll position, not left painted over the last row. */
  .review.has-more{-webkit-mask-image:linear-gradient(#000 calc(100% - 26px),transparent);
    mask-image:linear-gradient(#000 calc(100% - 26px),transparent)}
}

/* the art column keeps its own scroll off the page */
.split__artin{max-height:100%;overflow:hidden}


/* ═══════════════════════════════════════════ admin · projects ══ */
/* Rebuilt from app/dashboard/admin/projects/page.tsx: three stats, a card
   grid beside a status donut, milestones and recent activity underneath. */
.kpis--3{grid-template-columns:repeat(3,1fr)}

/* Filter row. Not on the real page — added because a grid with no way to
   narrow it is the first thing that breaks as the studio takes on work. */
.pjfilter{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:clamp(12px,1.6vw,18px)}
.pjfilter button{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font:inherit;
  font-size:14px;font-weight:700;color:var(--ink-2);background:var(--card);
  border:2px solid var(--line);border-radius:999px;padding:8px 15px;
  transition:border-color .22s,color .22s,background .22s}
.pjfilter button:hover{border-color:var(--ink-3);color:var(--ink)}
/* color:var(--card), not a literal #fff — .on is a selected tab, not a
   fixed-dark chip like .toast, so it should invert cleanly with the theme:
   dark pill/light text in light mode, and in dark mode --ink flips to
   near-white while --card stays a dark navy, which keeps this a filled pill
   with readable text instead of white-on-near-white. */
.pjfilter button.on{background:var(--ink);border-color:var(--ink);color:var(--card)}
.pjfilter button i{font-style:normal;font-family:"Mono",ui-monospace,monospace;font-size:10.5px;
  font-weight:700;opacity:.6}

.pjlayout{display:grid;grid-template-columns:minmax(0,1fr) clamp(260px,24vw,330px);
  gap:clamp(12px,1.6vw,18px);align-items:start}
.pjside{position:sticky;top:clamp(12px,2vw,22px)}
.pjgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(10px,1.4vw,16px)}

.pj{display:flex;flex-direction:column;background:var(--card);border:2px solid var(--line);
  border-radius:22px;padding:clamp(16px,1.8vw,22px);
  transition:border-color .28s,box-shadow .28s,transform .28s cubic-bezier(.16,1,.3,1)}
.pj:hover{border-color:var(--ink-3);box-shadow:var(--sh-sm);transform:translateY(-3px)}
.pj.is-hidden{display:none}
.pj__top{display:flex;align-items:flex-start;gap:12px}
.pj__sw{width:38px;height:38px;border-radius:12px;flex-shrink:0;border:1px solid rgba(var(--s-tint),.08)}
.pj__id{min-width:0;flex:1}
.pj__id b{display:block;font-weight:800;font-size:16.5px;letter-spacing:-.025em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pj__id span{display:block;font-size:13px;color:var(--ink-3)}
/* Two lines, then stop. The real page clamps this too — descriptions run to
   a paragraph and a card grid cannot have rows of different heights. */
.pj__desc{margin:13px 0 0;font-size:14px;line-height:1.5;color:var(--ink-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

.pj__bar{height:6px;border-radius:99px;background:var(--card-2);overflow:hidden;margin-top:auto;
  padding-top:0;margin-block-start:16px}
.pj__bar i{display:block;height:100%;border-radius:99px;background:var(--brand)}
.pj__prog{display:flex;justify-content:space-between;gap:10px;margin-top:7px;
  font-size:12px;color:var(--ink-3)}

.pj__meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:14px;padding-top:14px;
  border-top:1px solid var(--line);font-size:12.5px;color:var(--ink-3)}
.pj__who,.pj__tier{display:inline-flex;align-items:center;gap:6px}
.pj__tier{border:1px solid var(--line);border-radius:999px;padding:3px 10px}
.pj__meta svg{width:14px;height:14px}
.pj__foot{display:flex;justify-content:space-between;gap:10px;margin-top:11px;
  font-size:12px;color:var(--ink-3)}
/* Money owed is the one thing on this card worth interrupting a scan for. */
.pj__foot .is-owed{color:var(--s-warn-ink);font-weight:700}

.pjempty{display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;
  border:2px dashed var(--line);border-radius:22px;padding:48px 24px;margin:0;
  color:var(--ink-3);font-size:15px}
.pjempty svg{width:30px;height:30px}

/* the status donut */
.pnl--flat{box-shadow:none;border:2px solid var(--line)}
.donut{display:flex;flex-direction:column;align-items:center;gap:18px}
.donut__ring{width:min(170px,60%);aspect-ratio:1;border-radius:999px;display:flex;
  align-items:center;justify-content:center}
.donut__hole{width:64%;aspect-ratio:1;border-radius:999px;background:var(--card);
  display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1}
.donut__hole b{font-size:30px;font-weight:900;letter-spacing:-.04em}
.donut__hole span{font-size:11px;color:var(--ink-3);margin-top:3px}
.donut__key{list-style:none;margin:0;padding:0;width:100%;display:flex;flex-direction:column;gap:8px}
.donut__key li{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--ink-2)}
.donut__key span{width:10px;height:10px;border-radius:3px;flex-shrink:0}
.donut__key b{margin-inline-start:auto;font-family:"Mono",ui-monospace,monospace;font-size:12px;
  color:var(--ink)}

.pjrow{display:grid;grid-template-columns:1fr 1fr;gap:clamp(10px,1.4vw,16px);
  margin-top:clamp(12px,1.6vw,18px)}

@media (max-width:1100px){
  /* The donut goes under the grid rather than squeezing both. */
  .pjlayout{grid-template-columns:1fr}
  .pjside{position:static;top:auto}
  .donut{flex-direction:row;justify-content:space-between}
  .donut__key{width:auto;flex:1;max-width:340px}
}
@media (max-width:820px){
  .kpis--3{grid-template-columns:1fr 1fr}
  .pjgrid,.pjrow{grid-template-columns:1fr}
  .donut{flex-direction:column}
  .donut__key{max-width:none}
  .pjfilter{overflow-x:auto;flex-wrap:nowrap;padding-bottom:4px;
    scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .pjfilter::-webkit-scrollbar{display:none}
  .pjfilter button{flex:0 0 auto}
}


/* ═════════════════════════════════════ the dashboard kit ══ */
/* Built from the three references in refs/dashboard-references.md. What all
   three do that our screens did not: a stat card carries a visualisation, a
   number carries a delta, and exactly one surface per page is dark so the eye
   knows where to land. Their palettes are theirs — this is ours. */

/* ── stat card ─────────────────────────────────────────────────── */
.stat{position:relative;overflow:hidden;background:var(--card);border-radius:22px;
  padding:18px 20px;box-shadow:var(--sh-sm);display:flex;flex-direction:column;gap:4px;
  transition:transform .3s cubic-bezier(.16,1,.3,1),box-shadow .3s}
.stat:hover{transform:translateY(-4px);box-shadow:var(--sh)}
.stat__l{font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.stat__v{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.stat__v b{font-weight:900;font-size:clamp(25px,2.9vw,34px);letter-spacing:-.04em;line-height:1}
/* The delta chip. A number on its own says nothing; "+12.5% from last month"
   is what makes it worth putting on a dashboard at all. */
.chip{display:inline-flex;align-items:center;gap:4px;border-radius:999px;padding:3px 9px;
  font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;letter-spacing:.06em;
  background:var(--sage);color:var(--mint,#03363D);white-space:nowrap}
.chip.dn{background:var(--s-bad-bg);color:var(--s-bad-ink)}
.chip.flat{background:var(--card-2);color:var(--ink-3)}
.stat__h{margin:2px 0 0;font-size:12.5px;color:var(--ink-3)}

/* the visualisation inside a stat card */
.viz{margin-top:12px;height:44px;display:flex;align-items:flex-end;gap:4px}
.viz i{flex:1;border-radius:4px 4px 2px 2px;background:var(--lav);min-height:3px}
.viz i.hi{background:var(--brand)}
.viz--line{display:block;height:44px}
.viz--line svg{width:100%;height:100%;overflow:visible}
.viz--line path{fill:none;stroke:var(--brand);stroke-width:2.4;stroke-linecap:round;
  stroke-linejoin:round}
.viz--line path.fill{fill:var(--lav);stroke:none;opacity:.6}
/* a ring, for one-of-many progress */
.ring{--p:0;width:52px;height:52px;border-radius:999px;flex-shrink:0;
  background:conic-gradient(var(--brand) calc(var(--p) * 1%),var(--card-2) 0);
  display:flex;align-items:center;justify-content:center}
.ring b{width:38px;height:38px;border-radius:999px;background:var(--card);
  display:flex;align-items:center;justify-content:center;font-size:12.5px;font-weight:800}

/* ── segmented toggle ──────────────────────────────────────────── */
.seg{display:inline-flex;gap:2px;padding:3px;background:var(--card-2);border-radius:999px}
.seg button{border:0;cursor:pointer;font:inherit;font-size:12.5px;font-weight:700;
  color:var(--ink-3);background:none;border-radius:999px;padding:6px 13px;
  transition:background .22s,color .22s}
.seg button.on{background:var(--card);color:var(--ink);box-shadow:var(--sh-sm)}

/* ── the one dark surface ──────────────────────────────────────── */
/* Once per page. Twice and it stops meaning "look here" and starts meaning
   "this product has a dark theme", which it does not. */
.focus{background:var(--ink);color:#fff;border-radius:24px;padding:clamp(18px,2.2vw,26px);
  display:flex;flex-direction:column;gap:14px;position:relative;overflow:hidden}
.focus::after{content:"";position:absolute;top:-40%;right:-12%;width:46%;aspect-ratio:1;
  border-radius:50%;background:var(--brand);opacity:.28;filter:blur(10px)}
.focus > *{position:relative;z-index:1}
.focus__h{display:flex;align-items:center;justify-content:space-between;gap:12px}
.focus__h h2{margin:0;font-weight:900;font-size:19px;letter-spacing:-.03em}
.focus__h a{font-size:13px;font-weight:700;color:#fff;opacity:.72}
.focus .row{background:rgba(255,255,255,.08)}
.focus .row b{color:#fff}
.focus .row span{color:rgba(255,255,255,.62)}
.focus .row.on{background:var(--brand)}
.focus .row.on span{color:rgba(255,255,255,.82)}
.focus .pill{background:rgba(255,255,255,.16);color:#fff}

/* ── data table ────────────────────────────────────────────────── */
/* eProduct's table, with its one good idea: the selected row is filled, not
   tinted. A tint reads as hover; a fill reads as "this is the one". */
.tbl{width:100%;border-collapse:separate;border-spacing:0 6px;font-size:14px}
.tbl th{text-align:start;font-family:"Mono",ui-monospace,monospace;font-size:9.5px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  padding:0 14px 4px;white-space:nowrap}
.tbl td{background:var(--card-2);padding:13px 14px;vertical-align:middle}
.tbl tr td:first-child{border-radius:14px 0 0 14px}
.tbl tr td:last-child{border-radius:0 14px 14px 0}
.tbl tbody tr{cursor:pointer}
.tbl tbody tr:hover td{background:var(--lav)}
.tbl tbody tr.on td{background:var(--brand);color:#fff}
.tbl tbody tr.on .t__sub,.tbl tbody tr.on .dot span{color:rgba(255,255,255,.78)}
.tbl tbody tr.on .pill{background:rgba(255,255,255,.2);color:#fff}
.t__who{display:flex;align-items:center;gap:10px;min-width:0}
.t__av{width:30px;height:30px;border-radius:999px;flex-shrink:0;display:flex;
  align-items:center;justify-content:center;font-size:12px;font-weight:800;color:#fff}
.t__name{font-weight:700;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.t__sub{display:block;font-size:12px;color:var(--ink-3)}
.dot{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.dot i{width:7px;height:7px;border-radius:999px;flex-shrink:0}
.tblfoot{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-top:12px;font-size:12.5px;color:var(--ink-3)}

/* ── mobile ────────────────────────────────────────────────────── */
@media (max-width:820px){
  .stat{padding:15px 16px;border-radius:18px}
  .viz{height:34px}
  .focus{border-radius:20px}
  /* A seven-column table does not become a phone layout by shrinking. Each
     row becomes a block: who on top, the rest as labelled pairs underneath.
     The header row goes away because every cell carries its own label. */
  .tbl,.tbl tbody,.tbl tr,.tbl td{display:block;width:100%}
  .tbl thead{display:none}
  .tbl{border-spacing:0}
  .tbl tbody tr{background:var(--card-2);border-radius:16px;padding:13px 14px;
    margin-bottom:8px}
  .tbl tbody tr.on{background:var(--brand);color:#fff}
  .tbl tbody tr.on td{background:none}
  .tbl td{background:none;padding:0;display:flex;align-items:center;
    justify-content:space-between;gap:12px}
  .tbl td + td{margin-top:9px;padding-top:9px;border-top:1px solid rgba(var(--s-tint),.07)}
  .tbl tbody tr.on td + td{border-top-color:rgba(255,255,255,.16)}
  .tbl td::before{content:attr(data-l);font-family:"Mono",ui-monospace,monospace;
    font-size:9px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
    color:var(--ink-3)}
  .tbl tbody tr.on td::before{color:rgba(255,255,255,.62)}
  /* the person is the row's title, so it keeps the full width and no label */
  .tbl td.t__cell{justify-content:flex-start}
  .tbl td.t__cell::before{display:none}
}

/* ── admin overview layout ─────────────────────────────────────── */
.adminrow{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  gap:clamp(10px,1.4vw,16px);align-items:start;margin-bottom:clamp(12px,1.6vw,18px)}
.chartrow{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);
  gap:clamp(10px,1.4vw,16px);margin-bottom:clamp(12px,1.6vw,18px)}
.bigchart{height:clamp(150px,17vw,210px);margin-top:auto}
.bigchart svg{width:100%;height:100%;display:block;overflow:visible}
.legend{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px 20px;
  font-size:13px;color:var(--ink-2)}
.legend li{display:flex;align-items:center;gap:8px}
.legend span{width:10px;height:10px;border-radius:3px}

@media (max-width:1000px){
  .adminrow,.chartrow{grid-template-columns:1fr}
}

/* ── worker queue + job detail ─────────────────────────────────── */
.queue{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);
  gap:clamp(10px,1.4vw,16px);align-items:start;margin-bottom:clamp(12px,1.6vw,18px)}
.jd{background:var(--card);border:2px solid var(--line);border-radius:24px;
  padding:clamp(18px,2.2vw,26px);position:sticky;top:clamp(12px,2vw,22px)}
.jd__tag{display:inline-block;background:var(--lav);color:var(--brand-2);border-radius:999px;
  padding:6px 13px;font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase}
.jd h3{margin:14px 0 0;font-weight:900;font-size:clamp(22px,2.4vw,28px);letter-spacing:-.035em}
.jd p{margin:9px 0 0;font-size:14.5px;line-height:1.55;color:var(--ink-2)}
.jd dl{margin:18px 0 0;display:grid;grid-template-columns:1fr 1fr;gap:12px}
.jd dl > div{display:flex;flex-direction:column;gap:3px}
.jd dt{font-family:"Mono",ui-monospace,monospace;font-size:9px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.jd dd{margin:0;font-size:14.5px;font-weight:700}
.jd__act{display:flex;flex-wrap:wrap;gap:9px;margin-top:20px}
.jd__act .btn{padding:12px 20px;font-size:14.5px;border-radius:15px;flex:1;justify-content:center}

@media (max-width:1000px){
  .queue{grid-template-columns:1fr}
  .jd{position:static;top:auto}
}
.ring b i{display:flex;color:var(--brand)}
.ring b svg{width:17px;height:17px;stroke-width:2.6}

/* ── client dashboard ──────────────────────────────────────────── */
/* The airy one. A client checks in occasionally and wants to know it is
   moving — so more white, fewer numbers, and one project at full size
   instead of a list with one row in it. */
.apppage--airy{max-width:1060px}
.cl{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);
  gap:clamp(10px,1.4vw,16px);align-items:start;margin-bottom:clamp(12px,1.6vw,18px)}
.cl__main{background:var(--card);border-radius:26px;padding:clamp(20px,2.6vw,32px);
  box-shadow:var(--sh-sm)}
.cl__top{display:flex;align-items:flex-start;gap:14px}
.cl__sw{width:46px;height:46px;border-radius:15px;flex-shrink:0;display:flex;
  align-items:center;justify-content:center;color:#fff;font-weight:900;font-size:19px}
.cl__id{flex:1;min-width:0}
.cl__id h2{margin:0;font-weight:900;font-size:clamp(24px,2.8vw,32px);letter-spacing:-.04em}
.cl__id p{margin:6px 0 0;font-size:15px;line-height:1.5;color:var(--ink-2)}

.cl__prog{display:flex;align-items:center;gap:18px;margin-top:26px;padding-top:24px;
  border-top:1px solid var(--line)}
.ring--lg{width:88px;height:88px}
.ring--lg b{width:66px;height:66px;font-size:19px;font-weight:900;letter-spacing:-.03em}
.cl__progtext{flex:1;min-width:0}
.cl__progtext b{display:block;font-weight:800;font-size:17px;letter-spacing:-.025em}
.cl__progtext span{display:block;font-size:13.5px;color:var(--ink-3);margin-top:3px}
.cl__bar{height:7px;border-radius:99px;background:var(--card-2);overflow:hidden;margin-top:12px}
.cl__bar i{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--brand),#8E5BFF)}

/* The route again, in miniature — the same five beats the public site
   promises, so the portal is visibly the thing that was sold. */
.cl__steps{list-style:none;margin:24px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:10px}
.cl__steps li{display:flex;align-items:center;gap:8px;border-radius:999px;padding:8px 14px;
  background:var(--card-2);color:var(--ink-3);font-size:13.5px;font-weight:700}
.cl__steps svg{width:14px;height:14px}
/* the marker for a step not yet reached, and the one in progress */
.cl__steps em{width:7px;height:7px;border-radius:999px;background:currentColor;opacity:.45}
.cl__steps .now em{opacity:1;box-shadow:0 0 0 4px rgba(255,255,255,.28)}
.cl__steps .done{background:var(--sage);color:var(--mint,#03363D)}
.cl__steps .now{background:var(--brand);color:#fff}

.cl__side{display:flex;flex-direction:column;gap:clamp(10px,1.4vw,16px)}
.cl__pay{margin-top:14px;width:100%;justify-content:center;padding:13px 20px;
  font-size:15px;border-radius:15px}

.cl__prev{margin-bottom:clamp(12px,1.6vw,18px)}
.cl__frame{border-radius:16px;overflow:hidden;background:var(--card)}
.cl__bar2{display:flex;align-items:center;gap:6px;padding:10px 13px;background:var(--card-2)}
.cl__bar2 i{width:9px;height:9px;border-radius:999px;background:var(--line)}
.cl__bar2 span{margin-inline-start:10px;font-family:"Mono",ui-monospace,monospace;
  font-size:11px;color:var(--ink-3)}
.cl__shot{aspect-ratio:16/8;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:6px;color:#fff}
.cl__shot b{font-weight:900;font-size:clamp(24px,3vw,36px);letter-spacing:-.04em}
.cl__shot span{font-size:14px;opacity:.72}
.cl__note{margin:0;font-size:13.5px;color:rgba(255,255,255,.66)}

@media (max-width:900px){
  .cl{grid-template-columns:1fr}
}
@media (max-width:520px){
  .cl__prog{flex-direction:column;align-items:flex-start;gap:14px}
  .cl__progtext{width:100%}
  .cl__steps{gap:7px}
  .cl__steps li{font-size:12.5px;padding:7px 11px}
}

@media (max-width:430px){
  /* Two flex:1 buttons in a 390px column leaves each about 150px, and
     "Open sandbox" breaks across two lines inside its own pill. One per
     row instead. */
  .jd__act{flex-direction:column}
  .jd__act .btn{width:100%}
}

/* ── the account menu ──────────────────────────────────────────── */
/* Three roles, one browser: the same person is often the admin and the one
   building, and checking what a client sees should not mean signing out. */
/* Pushed right explicitly. The nav's `margin-inline:auto` used to do this as
   a side effect, but on a phone the nav is `position:fixed` and out of flow,
   so the end block sat next to the logo — and the account menu, anchored to
   it, opened off the left edge of the screen. */
.appbar__end{position:relative;margin-inline-start:auto}
.acct{position:absolute;top:calc(100% + 10px);inset-inline-end:0;z-index:200;
  width:min(310px,calc(100vw - 24px));background:var(--card);border-radius:22px;
  box-shadow:0 30px 64px -22px rgba(var(--s-tint),.55);border:1px solid var(--line);
  padding:8px;color:var(--ink);
  opacity:0;transform:translateY(-8px) scale(.97);transform-origin:top right;
  transition:opacity .22s,transform .3s cubic-bezier(.16,1,.3,1)}
.acct.is-in{opacity:1;transform:none}
/* The panel sets dark text for its own content, and the avatars inherited it
   — white initials on a dark disc became dark initials on a dark disc, i.e.
   invisible. They are always white. */
.acct .avatar{color:#fff}
.acct__me{display:flex;align-items:center;gap:12px;padding:12px 12px 14px}
.avatar--lg{width:44px;height:44px;font-size:17px;flex-shrink:0}
.acct__me div{min-width:0}
.acct__me b{display:block;font-weight:800;font-size:15.5px;letter-spacing:-.02em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* `div span`, not bare `span`. The avatar is itself a <span> inside these
   blocks, so a bare selector captured it too and replaced its `display:flex`
   with `display:block` — which is why the initial sat outside its disc
   instead of centred in it, and at the wrong size. */
.acct__me div span{display:block;font-size:12.5px;color:var(--ink-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acct__me i{display:inline-block;margin-top:5px;font-style:normal;
  font-family:"Mono",ui-monospace,monospace;font-size:9px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--brand-2);
  background:var(--lav);border-radius:999px;padding:3px 9px}
.acct__lab{margin:0;padding:6px 12px;font-family:"Mono",ui-monospace,monospace;
  font-size:9px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-3);border-top:1px solid var(--line)}
.acct__row{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:14px;
  transition:background .2s}
.acct__row:hover{background:var(--card-2)}
.acct__row div{flex:1;min-width:0}
.acct__row b{display:block;font-weight:700;font-size:14.5px;letter-spacing:-.015em}
.acct__row div span{display:block;font-size:12px;color:var(--ink-3)}
.acct__row svg{width:16px;height:16px;color:var(--ink-3)}
.acct__foot{border-top:1px solid var(--line);margin-top:6px;padding-top:6px}
.acct__act{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:14px;
  font-size:14.5px;font-weight:700;transition:background .2s}
.acct__act:hover{background:var(--card-2)}
.acct__act svg{width:17px;height:17px;color:var(--ink-3)}
.acct__act--out{color:var(--s-bad-ink)}
.acct__act--out svg{color:var(--s-bad-ink)}
.acct__row:focus-visible,.acct__act:focus-visible{outline:3px solid var(--brand);
  outline-offset:-3px}

/* No upward flip on a phone: only the *nav* moves to the bottom, the bar
   holding this button stays at the top. What the phone does need is to be
   pinned to the viewport rather than to the button, so the panel cannot be
   pushed off an edge by whatever the bar's layout happens to be. */
@media (max-width:820px){
  /* Fixed to the viewport, just under the bar. The bar is sticky at the top
     and 62px tall on a phone. */
  .acct{position:fixed;top:64px;inset-inline-end:12px;
    width:min(310px,calc(100vw - 24px))}
}

/* ═══════════════════════════════════════════ project detail ══ */
/* One screen, no page scroll — the same discipline as login and apply, for
   the same reason: this is a screen you work in, not a document you read.
   Everything is sized to fit rather than to breathe. */
body.app.is-fixed{height:100svh;overflow:hidden;padding:0}
.is-fixed .appshell{height:100svh;display:flex;flex-direction:column;overflow:hidden;
  border-radius:0}
.is-fixed .appbar{flex:0 0 auto}

/* The back link sits on its own line above the title. Inline beside the
   project name it read as part of the name — Elad: "the back button is
   unrelated [to the title]". */
.phead{flex:0 0 auto;display:grid;grid-template-columns:1fr auto;gap:4px 16px;
  align-items:center;padding:10px clamp(14px,2.2vw,26px) 0}
.phead .backlink{grid-column:1/-1;justify-self:start}
.backlink{display:inline-flex;align-items:center;gap:7px;font-size:13.5px;font-weight:700;
  color:var(--ink-3);transition:color .2s}
.backlink:hover{color:var(--ink)}
.backlink svg{width:15px;height:15px}
.phead__id{display:flex;align-items:center;gap:12px;min-width:0;flex:1}

.phead__sw{width:34px;height:34px;border-radius:11px;flex-shrink:0;display:flex;
  align-items:center;justify-content:center;color:#fff;font-weight:900;font-size:16px}
.phead__id h1{margin:0;font-weight:900;font-size:clamp(19px,2.1vw,25px);letter-spacing:-.035em}
.phead__id p{margin:1px 0 0;font-size:13px;color:var(--ink-3)}
.phead__act{display:flex;gap:9px;flex-wrap:wrap}
.phead__act .btn{padding:10px 17px;font-size:14px;border-radius:14px}
.btn--danger{border-color:var(--s-bad-line);color:var(--s-bad-ink)}
.btn--danger:hover{background:var(--s-bad-ink);border-color:var(--s-bad-ink);color:#fff}

/* the meta strip */
/* Smaller. These are reference figures you glance at, not the subject of the
   screen — the workspace is. Elad: "the boxes above the project are too big". */
.pstrip{flex:0 0 auto;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:8px;padding:8px clamp(14px,2.2vw,26px)}
.ps{display:flex;align-items:center;gap:10px;background:var(--card);border-radius:13px;
  padding:8px 12px;box-shadow:var(--sh-sm);min-width:0}
.ps > div{min-width:0;flex:1}
.ps__l{display:block;font-family:"Mono",ui-monospace,monospace;font-size:8px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
/* `> div b`, not `.ps b`. The progress ring's own <b> lives directly in the
   strip item, so a loose selector clipped "72%" down to "/2%" — the third
   time a bare tag selector has eaten a component in this file. Style the
   text by its container. */
.ps > div b{display:block;font-weight:800;font-size:14.5px;letter-spacing:-.025em;margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ps__s{display:flex;align-items:center;gap:5px;margin-top:1px;font-size:11px;color:var(--ink-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ps__s svg{width:12px;height:12px;color:var(--brand);flex-shrink:0}
.ps .ring{width:34px;height:34px;flex-shrink:0}
.ps .ring b{width:25px;height:25px;font-size:9px;margin:0}
.ps--link{transition:transform .25s,box-shadow .25s}
.ps--link:hover{transform:translateY(-2px);box-shadow:var(--sh)}
.ps--link > svg{width:15px;height:15px;color:var(--ink-3);flex-shrink:0}
.ps--n{gap:18px}
.ps--n > div{flex:0 0 auto}

/* the working area */
.pwork{flex:1;min-height:0;display:grid;
  grid-template-columns:minmax(0,1fr) clamp(290px,23vw,350px);
  gap:12px;padding:0 clamp(14px,2.2vw,26px) 14px;overflow:hidden;
  transition:grid-template-columns .42s cubic-bezier(.16,1,.3,1)}
/* Expanded: the chat collapses to nothing and the frame takes the screen. */
.is-wide .pwork{grid-template-columns:minmax(0,1fr) 0px}
.is-wide .pchat{opacity:0;pointer-events:none}
/* `min-width:0` all the way down. A grid track of `1fr` is `minmax(auto,1fr)`
   and auto means min-content — so the frame bar's row of page buttons, the
   url and the action icons set a floor the column could not go below, and on
   a 390px phone the whole workspace hung 155px off the side of the screen.
   Every box between the track and the scrolling row has to opt out. */
.pmain{min-height:0;min-width:0;display:flex;flex-direction:column}

.frame{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column;background:var(--card);
  border-radius:18px;overflow:hidden;box-shadow:var(--sh-sm)}
.frame__bar{flex:0 0 auto;min-width:0;display:flex;align-items:center;gap:12px;padding:9px 12px;
  background:var(--card-2);border-bottom:1px solid var(--line)}
.frame__dots{display:flex;gap:5px;flex-shrink:0}
.frame__dots i{width:9px;height:9px;border-radius:99px;background:var(--line)}
.frame__pages{display:flex;gap:3px;min-width:0;flex-shrink:1;overflow-x:auto;scrollbar-width:none}
.frame__pages::-webkit-scrollbar{display:none}
.frame__pages button{flex:0 0 auto;border:0;cursor:pointer;font:inherit;font-size:12.5px;
  font-weight:700;color:var(--ink-3);background:none;border-radius:9px;padding:5px 11px;
  transition:background .2s,color .2s}
.frame__pages button:hover{background:var(--card);color:var(--ink)}
.frame__pages button.on{background:var(--card);color:var(--ink);box-shadow:var(--sh-sm)}
.frame__url{flex:1;text-align:center;font-family:"Mono",ui-monospace,monospace;font-size:11px;
  color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.frame__act{display:flex;gap:4px;flex-shrink:0}
.fbtn{width:30px;height:30px;border-radius:9px;border:0;cursor:pointer;background:none;
  color:var(--ink-3);display:flex;align-items:center;justify-content:center;
  transition:background .2s,color .2s}
.fbtn:hover{background:var(--card);color:var(--ink)}
.fbtn svg{width:15px;height:15px}
.frame__body{flex:1;min-height:0}
.shot{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:8px;color:#fff}
.shot b{font-weight:900;font-size:clamp(26px,3.4vw,44px);letter-spacing:-.04em}
.shot span{font-size:14px;opacity:.7}

/* the docked conversation */
.pchat{min-height:0;min-width:0;display:flex;flex-direction:column;background:var(--card);
  border-radius:18px;box-shadow:var(--sh-sm);overflow:hidden;transition:opacity .3s}
.pchat__h{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;
  padding:12px 14px;border-bottom:1px solid var(--line)}
.pchat__h h2{margin:0;font-weight:900;font-size:15.5px;letter-spacing:-.025em}
.chat__log{flex:1;min-height:0;overflow-y:auto;padding:14px;display:flex;
  flex-direction:column;gap:11px}
.bub{max-width:92%;border-radius:16px;padding:10px 13px}
.bub b{display:block;font-family:"Mono",ui-monospace,monospace;font-size:8.5px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;opacity:.62;margin-bottom:4px}
.bub p{margin:0;font-size:14px;line-height:1.45}
.bub span{display:block;margin-top:4px;font-size:10.5px;opacity:.55}
.bub--them{background:var(--card-2);align-self:flex-start;border-bottom-left-radius:6px}
.bub--us{background:var(--brand);color:#fff;align-self:flex-end;border-bottom-right-radius:6px}
.chat__new{flex:0 0 auto;display:flex;gap:8px;padding:11px;border-top:1px solid var(--line)}
.chat__new input{flex:1;min-width:0;font:inherit;font-size:16px;font-weight:500;color:var(--ink);
  background:var(--card-2);border:2px solid var(--line);border-radius:13px;padding:10px 13px}
.chat__new input:focus{outline:none;border-color:var(--brand);background:var(--card)}
.chat__new .btn{padding:10px 13px;border-radius:13px}

/* copy confirmation */
/* Elad, 28 Aug: "lots of hidden text" — this is the biggest single instance
   of it. `--ink` is the site's dark-navy text colour in light theme, which
   is why a toast reusing it as a *background* (white text on dark navy)
   worked at all — but `--ink` is exactly what G2b flips to near-white for
   *text* in the dark studio, and this chip inherits that flip too. White
   text on `#ECEEFA` is every toast in the app, invisible, in dark mode.
   Same fix as `.ap__bar`: this chip is meant to read as dark regardless of
   theme, so it gets a literal colour instead of the token that theme owns. */
.toast{position:fixed;left:50%;bottom:26px;transform:translate(-50%,14px);z-index:300;
  background:#141A3C;color:#fff;border-radius:999px;padding:11px 20px;font-size:14px;
  font-weight:700;box-shadow:0 20px 44px -16px rgba(var(--s-tint),.6);
  opacity:0;transition:opacity .25s,transform .32s cubic-bezier(.16,1,.3,1)}
.toast.is-in{opacity:1;transform:translate(-50%,0)}

@media (max-width:1180px){
  .pstrip{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:1000px){
  /* A three-pane fixed screen does not exist on a phone. The page scrolls
     here and the conversation goes under the workspace. */
  body.app.is-fixed{height:auto;overflow:visible;padding:0}
  .is-fixed .appshell{height:auto;overflow:visible}
  .pwork{grid-template-columns:minmax(0,1fr);overflow:visible;height:auto}
  .is-wide .pwork{grid-template-columns:minmax(0,1fr)}
  .is-wide .pchat{opacity:1;pointer-events:auto}
  .frame{height:min(58vh,460px)}
  .pchat{height:min(64vh,520px)}
  [data-expand],[data-chattoggle]{display:none}
}
@media (max-width:640px){
  .pstrip{grid-template-columns:1fr}
  .phead{gap:10px}
  .phead__act{width:100%}
  .phead__act .btn{flex:1;justify-content:center}
}

/* ── dialogs ───────────────────────────────────────────────────── */
/* Log time, Set price, Unlock and Delete all open one of these. They were
   labels with no behaviour until Elad pointed out that none of them worked. */
.mdl{position:fixed;inset:0;z-index:400;display:flex;align-items:center;justify-content:center;
  padding:18px;background:rgba(var(--s-tint),.5);-webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);opacity:0;transition:opacity .26s}
.mdl.is-in{opacity:1}
/* A dialog is a light panel, and on the studio screens the body's own colour
   is near-white — so every value inside a receipt, a share sheet or a payment
   sheet was white text on white paper and simply did not exist. The panel
   states its own ink rather than inheriting whatever page opened it. */
.mdl__panel{color:var(--ink);width:min(430px,100%);background:var(--card);border-radius:24px;
  box-shadow:0 40px 90px -30px rgba(var(--s-tint),.7);overflow:hidden;
  transform:translateY(14px) scale(.97);transition:transform .34s cubic-bezier(.16,1,.3,1)}
.mdl.is-in .mdl__panel{transform:none}
.mdl__h{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:16px 18px;border-bottom:1px solid var(--line)}
.mdl__h h2{margin:0;font-weight:900;font-size:18px;letter-spacing:-.03em}
.mdl__h .fbtn{font-size:20px;line-height:1}
.mdl__b{padding:18px}
.mdl__b p{margin:0 0 12px;font-size:14.5px;line-height:1.55;color:var(--ink-2)}
.mdl__b p:last-child{margin-bottom:0}
.mdl__l{display:flex;flex-direction:column;gap:6px;margin-bottom:14px;
  font-size:12.5px;font-weight:700;color:var(--ink-2)}
.mdl__l input,.mdl__l textarea{font:inherit;font-size:16px;font-weight:600;color:var(--ink);
  background:var(--card-2);border:2px solid var(--line);border-radius:13px;padding:11px 14px;
  resize:vertical}
.mdl__l input:focus,.mdl__l textarea:focus{outline:none;border-color:var(--brand);
  background:var(--card)}
.mdl__note{font-size:12.5px!important;color:var(--ink-3)!important}
.mdl__total{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  background:var(--card-2);border-radius:14px;padding:13px 16px;margin-bottom:14px}
.mdl__total span{font-size:14px;font-weight:700}
.mdl__total b{font-weight:900;font-size:26px;letter-spacing:-.035em}
.mdl__ul{list-style:none;margin:0 0 12px;padding:0;display:flex;flex-direction:column;gap:8px}
.mdl__ul li{display:flex;gap:9px;align-items:flex-start;font-size:14px;color:var(--ink-2)}
.mdl__ul li::before{content:"";width:16px;height:16px;border-radius:99px;background:var(--sage);
  flex-shrink:0;margin-top:2px}
.mdl__f{display:flex;gap:9px;padding:14px 18px;border-top:1px solid var(--line);
  justify-content:flex-end}
.mdl__f .btn{padding:11px 19px;font-size:14.5px;border-radius:14px}
@media (max-width:520px){
  .mdl__f{flex-direction:column-reverse}
  .mdl__f .btn{width:100%;justify-content:center}
}

/* ── the PayPal step ───────────────────────────────────────────── */
/* Shaped like the real one: gold, pill, 48 tall, vertical — the style object
   in components/payments/paypal-checkout.tsx. The SDK cannot load here, so
   this is the same button and the same three states without the network. */
.pp{margin-top:4px}
.pp__btn{width:100%;height:48px;border:0;border-radius:999px;cursor:pointer;
  background:#FFC439;color:#0d1a3a;font:inherit;font-weight:800;font-size:16px;
  display:flex;align-items:center;justify-content:center;gap:8px;
  transition:filter .2s,transform .2s}
.pp__btn:hover{filter:brightness(1.05);transform:translateY(-1px)}
.pp__btn.is-busy{background:#F0E0B4;cursor:default}
.pp__btn.is-done{background:var(--sage);color:var(--mint,#03363D);cursor:default}
.pp__mark{font-size:19px;letter-spacing:-.03em}
.pp__mark b{color:#003087;font-weight:900}
.pp__mark i{color:#009cde;font-style:italic;font-weight:900}
.pp__spin{width:16px;height:16px;border-radius:99px;border:2.5px solid rgba(0,0,0,.2);
  border-top-color:#0d1a3a;animation:ppspin .7s linear infinite}
@keyframes ppspin{to{transform:rotate(360deg)}}
.pp__note{margin:10px 0 0;font-size:12px;color:var(--ink-3);text-align:center}

.mdl__hero{display:flex;align-items:center;gap:14px;background:var(--card-2);
  border-radius:16px;padding:14px 16px;margin-bottom:14px}
.mdl__lock{width:40px;height:40px;border-radius:13px;background:var(--lav);color:var(--brand);
  display:flex;align-items:center;justify-content:center;flex-shrink:0}
.mdl__lock svg{width:19px;height:19px}
.mdl__hero > div{flex:1;display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.mdl__hero span{font-size:13px;font-weight:700;color:var(--ink-3)}
.mdl__hero b{font-weight:900;font-size:30px;letter-spacing:-.04em}
.mdl__empty{background:var(--card-2);border-radius:14px;padding:14px 16px;
  text-align:center;font-size:14px!important}
/* a dollar field that only takes a number */
.mdl__money{display:flex;align-items:center;background:var(--card-2);border:2px solid var(--line);
  border-radius:13px;padding-inline-start:13px;transition:border-color .2s}
.mdl__money:focus-within{border-color:var(--brand);background:var(--card)}
.mdl__money i{font-style:normal;font-weight:800;font-size:16px;color:var(--ink-3)}
.mdl__money input{flex:1;min-width:0;border:0;background:none;padding:11px 13px}
.mdl__money input:focus{outline:none}
.mdl__money input::-webkit-outer-spin-button,
.mdl__money input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* the share-link row a file's own dialog opens with */
.sharelink{display:flex;align-items:center;gap:6px;background:var(--card-2);
  border:2px solid var(--line);border-radius:13px;padding:4px 4px 4px 14px}
.sharelink input{flex:1;min-width:0;border:0;background:none;font:inherit;
  font-size:13px;color:var(--ink-2);padding:9px 0}
.sharelink input:focus{outline:none}

/* ── typing, notifications, floating chat ──────────────────────── */
.bub--typing{display:flex;gap:4px;align-items:center;padding:13px 15px}
.bub--typing i{width:6px;height:6px;border-radius:99px;background:var(--ink-3);
  animation:typing 1.1s infinite}
.bub--typing i:nth-child(2){animation-delay:.15s}
.bub--typing i:nth-child(3){animation-delay:.3s}
@keyframes typing{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}

.notes{position:absolute;top:calc(100% + 10px);inset-inline-end:0;z-index:200;
  /* 320 was right for a two-line row; the rows carry an icon, a time and a
     body now, and at that width every second title wrapped to three lines. */
  width:min(392px,calc(100vw - 24px));background:var(--card);border-radius:20px;
  border:1px solid var(--line);box-shadow:0 30px 64px -22px rgba(var(--s-tint),.55);
  color:var(--ink);overflow:hidden;
  opacity:0;transform:translateY(-8px) scale(.97);transform-origin:top right;
  transition:opacity .22s,transform .3s cubic-bezier(.16,1,.3,1)}
.notes.is-in{opacity:1;transform:none}
.notes__h{padding:13px 16px;border-bottom:1px solid var(--line)}
.notes__h h2{margin:0;font-weight:900;font-size:15.5px;letter-spacing:-.025em}
.notes__b{max-height:min(60vh,380px);overflow-y:auto;padding:6px}
.note__row{display:block;padding:11px 12px;border-radius:14px;transition:background .2s}
.note__row:hover{background:var(--card-2)}
.note__row b{display:block;font-size:14px;font-weight:800;letter-spacing:-.015em}
.note__row span{display:block;font-size:13px;color:var(--ink-2);margin-top:2px}
.note__row i{display:block;font-style:normal;font-size:10.5px;color:var(--ink-3);margin-top:4px}
.note__none{margin:0;padding:22px;text-align:center;font-size:13.5px;color:var(--ink-3)}

/* the on-screen toast for an arriving message */
/* Same bug as .toast, same fix: this is the "a message just arrived" pop-up
   inside the studio, meant to always read dark, not the toast's own theme
   token flipped near-white in dark mode. */
.note{position:fixed;top:74px;inset-inline-end:16px;z-index:320;width:min(300px,calc(100vw - 32px));
  background:#141A3C;color:#fff;border-radius:16px;padding:12px 15px;
  box-shadow:0 22px 48px -18px rgba(var(--s-tint),.7);
  opacity:0;transform:translateX(16px);transition:opacity .26s,transform .34s cubic-bezier(.16,1,.3,1)}
.note.is-in{opacity:1;transform:none}
.note b{display:block;font-family:"Mono",ui-monospace,monospace;font-size:9px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;opacity:.66}
.note p{margin:4px 0 0;font-size:14px;line-height:1.4}

.fab{position:fixed;inset-inline-end:20px;bottom:20px;z-index:300;width:54px;height:54px;
  border-radius:999px;border:0;cursor:pointer;background:var(--ink);color:#fff;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 18px 40px -14px rgba(var(--s-tint),.7);transition:transform .28s}
.fab:hover{transform:translateY(-3px) scale(1.04)}
.fab svg{width:23px;height:23px}
.fab__dot{position:absolute;top:11px;right:12px;width:10px;height:10px;border-radius:99px;
  background:var(--hot);border:2px solid var(--ink)}
.fchat{position:fixed;inset-inline-end:20px;bottom:86px;z-index:300;
  width:min(340px,calc(100vw - 32px));height:min(460px,70vh);background:var(--card);
  border-radius:22px;box-shadow:0 34px 70px -24px rgba(var(--s-tint),.6);
  display:flex;flex-direction:column;overflow:hidden;
  opacity:0;transform:translateY(12px) scale(.97);transform-origin:bottom right;
  transition:opacity .24s,transform .32s cubic-bezier(.16,1,.3,1)}
.fchat.is-in{opacity:1;transform:none}
.fchat__h{display:flex;align-items:center;gap:11px;padding:13px 14px;border-bottom:1px solid var(--line)}
.fchat__h > div{flex:1;min-width:0}
.fchat__h b{display:block;font-weight:800;font-size:15px;letter-spacing:-.02em}
.fchat__h span{display:block;font-size:11.5px;color:var(--ink-3)}
.fchat__log{flex:1;min-height:0;overflow-y:auto;padding:13px;display:flex;
  flex-direction:column;gap:10px}
@media (max-width:820px){
  /* clear of the bottom tab bar on the dashboards */
  .fab{bottom:84px}
  .fchat{bottom:148px}
}

/* ═══════════════════════════════════════════════ admin · team ══ */
/* Rebuilt from app/dashboard/admin/employees/page.tsx. The list is a table
   rather than the real page's CSS-grid rows because seven fields per person
   is a table, and this site already has one that behaves — the worker's queue
   on the dashboard. Everything below either widens that table for seven
   columns or belongs to the sheet behind a row. */
.mono{font-family:"Mono",ui-monospace,monospace;font-size:12.5px;letter-spacing:-.01em}
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}

/* The amber banner is the one thing on this screen that reports the server
   rather than the database, so it does not look like the other panels. */
.warn{display:flex;gap:13px;align-items:flex-start;background:var(--s-warn-bg-2);
  border:1.5px solid #F3D6B0;border-radius:20px;padding:15px 18px;
  margin-bottom:clamp(12px,1.6vw,18px)}
.warn svg{width:19px;height:19px;color:var(--s-warn-ink);flex-shrink:0;margin-top:1px}
/* Child, not descendant. `.warn b` also matched the <b>not</b> inside the
   offboard warning's sentence and put it on a line of its own — the same
   mistake as `.em__hero span`, and worth only making once. */
.warn > div > b{display:block;font-weight:800;font-size:14.5px;letter-spacing:-.02em}
.warn p{margin:5px 0 0;font-size:13px;line-height:1.55;color:var(--ink-2)}
.warn--flat{margin:0 0 14px;border-radius:16px;padding:12px 14px}
.warn--flat p{margin:0;font-size:12.5px}

/* A row action has to be quieter than the page's own buttons, or five rows
   of them read as five calls to action. */
.tiny{font:inherit;font-size:12px;font-weight:700;letter-spacing:-.01em;cursor:pointer;
  padding:5px 11px;border-radius:999px;border:1.5px solid var(--line);
  background:var(--card);color:var(--ink-2);white-space:nowrap;
  transition:background .2s,border-color .2s,color .2s}
.tiny:hover{background:var(--lav);border-color:var(--lav);color:var(--brand-2)}
.tiny--warn:hover{background:var(--s-bad-bg);border-color:var(--s-bad-line);color:var(--s-bad-ink)}
.tbl tbody tr.on .tiny{background:rgba(255,255,255,.16);border-color:transparent;color:#fff}

/* Fixed columns only while it is still a table. Below 820px every row is a
   block and these widths would be applied to stacked cells — which is the
   whole reason the shared rule sets width:100% down there. */
@media (min-width:821px){
  .tbl--team{table-layout:fixed}
  .tbl--team th:nth-child(1),.tbl--team td:nth-child(1){width:22%}
  .tbl--team th:nth-child(2),.tbl--team td:nth-child(2){width:18%}
  .tbl--team th:nth-child(3),.tbl--team td:nth-child(3){width:14%}
  .tbl--team th:nth-child(4),.tbl--team td:nth-child(4){width:11%}
  .tbl--team th:nth-child(5),.tbl--team td:nth-child(5){width:12%}
  .tbl--team th:nth-child(6),.tbl--team td:nth-child(6){width:7%;text-align:center}
  /* Named rather than left to the remainder: two buttons is 150px and the
     leftover after six columns was not that. */
  .tbl--team th:nth-child(7),.tbl--team td:nth-child(7){width:16%}
  .tbl--team td{overflow:hidden;text-overflow:ellipsis}
}
.tbl--team .t__sub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.em__n{font-variant-numeric:tabular-nums;font-weight:700}
/* This has to stay a table cell. Making it display:flex took it out of the
   row's column layout and the two buttons painted past the end of the row —
   which looked like a width problem and was not. The cell stays a cell and
   the buttons are inline inside it. */
.em__act{text-align:end;white-space:nowrap}
.em__act .tiny + .tiny{margin-inline-start:6px}
.em__closed{font-size:12px;color:var(--ink-3)}
/* The marker for "this person is on the about page", same meaning as the eye
   on the real row. */
.em__eye{display:inline-flex;margin-inline-start:6px;color:var(--brand);vertical-align:-2px}
.em__eye svg{width:13px;height:13px}
.tbl tbody tr.on .em__eye{color:#fff}
.row--ghost{opacity:.62}
.row--ghost b{font-weight:700}

/* ── the sheet behind a row ─────────────────────────────────────── */
.mdl--wide .mdl__panel{width:min(660px,100%)}
.mdl--wide .mdl__b{max-height:min(72vh,720px);overflow-y:auto}
.mdl__two{display:grid;grid-template-columns:1fr 1fr;gap:0 12px}
.mdl__l select{font:inherit;font-size:16px;font-weight:600;color:var(--ink);
  background:var(--card-2);border:2px solid var(--line);border-radius:13px;padding:11px 14px;
  -webkit-appearance:none;appearance:none;cursor:pointer}
.mdl__l select:focus{outline:none;border-color:var(--brand);background:var(--card)}
/* A select with appearance:none is a text input as far as the eye is
   concerned. The site's answer to that is .selwrap's ::after chevron; this is
   the same chevron on the label, since these selects sit in one. The class is
   on the markup rather than behind :has() — iOS Safari 15 does not have it. */
.mdl__l select{padding-inline-end:40px}
.mdl__l--sel{position:relative}
.mdl__l--sel::after{content:"";position:absolute;inset-inline-end:16px;bottom:19px;
  width:8px;height:8px;border:solid var(--ink-2);border-width:0 2.5px 2.5px 0;
  transform:rotate(45deg);pointer-events:none}
.mdl__note.is-bad{color:var(--s-bad-ink)!important;font-weight:700}

.em__hero{display:flex;align-items:center;gap:14px;background:var(--card-2);
  border-radius:18px;padding:14px 16px;margin-bottom:14px}
.em__hero > div{flex:1;min-width:0}
/* Scoped to the text column on purpose. Unscoped, `.em__hero span` also
   matched the avatar beside it — which is a span — and turned the initial
   inside it into 13px grey text laid out as a block. */
.em__hero > div b{display:block;font-weight:900;font-size:19px;letter-spacing:-.035em}
.em__hero > div span{display:block;font-size:13px;color:var(--ink-3)}
.em__av{width:46px!important;height:46px!important;font-size:19px}

.em__facts{display:grid;grid-template-columns:1fr 1fr;gap:11px 18px;margin:0 0 15px}
.em__facts div{min-width:0}
.em__facts dt{font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3)}
.em__facts dd{margin:3px 0 0;font-size:14px;font-weight:600;word-break:break-word}
.em__ok,.em__bad{display:block;font-size:11.5px;font-weight:700;margin-top:2px}
.em__ok{color:#2F7A5B} .em__bad{color:var(--s-warn-ink)}

.em__card{background:var(--card-2);border-radius:18px;padding:14px 16px;margin-bottom:14px}
.em__card > b{font-weight:800;font-size:14px;letter-spacing:-.02em}
.em__cardh{display:flex;align-items:center;justify-content:space-between;gap:10px}
.em__cardh b{font-weight:800;font-size:14px;letter-spacing:-.02em}
.em__tag{margin:9px 0 0;font-weight:700;font-size:15px;letter-spacing:-.02em}
.em__bio{margin:6px 0 0;font-size:13.5px;line-height:1.55;color:var(--ink-2)}
.em__bio a{color:var(--brand)}
.em__chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.em__chips .chip{background:var(--card);color:var(--ink-2);font-size:12px;font-weight:700;padding:4px 11px}
.em__meta{margin:10px 0 0;font-size:12px;color:var(--ink-3)}
.em__meta a{color:var(--brand)}
.em__folders{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.em__folders li{background:var(--card);border-radius:9px;padding:4px 10px}
.em__off{display:flex;align-items:center;gap:9px;margin:0;background:var(--card-2);
  border-radius:14px;padding:12px 14px;font-size:13px;color:var(--ink-2)}
.em__off svg{width:16px;height:16px;flex-shrink:0;color:var(--ink-3)}
.em__acts{display:flex;flex-wrap:wrap;gap:8px}
.em__acts .btn{padding:10px 16px;font-size:14px;border-radius:13px}
.em__acts .btn--danger{margin-inline-start:auto}

/* Two answers, both spelled out, neither pre-chosen for you — the API refuses
   to default this and the dialog should not either. */
.emopt{border:2px solid var(--line);border-radius:16px;padding:13px 15px;margin-bottom:10px;
  cursor:pointer;transition:border-color .2s,background .2s}
.emopt:hover{border-color:var(--ink-3)}
.emopt.on{border-color:var(--brand);background:var(--lav)}
.emopt > b{display:block;font-weight:800;font-size:14.5px;letter-spacing:-.02em}
.emopt > span{display:block;margin-top:4px;font-size:12.5px;line-height:1.55;color:var(--ink-2)}

.em__link{display:grid;grid-template-columns:1fr 1.4fr auto;gap:8px;margin-bottom:8px}
.em__link .fbtn{align-self:center}
/* .mdl__l is a column flex box, so a pill button in one stretches to the
   full width and stops reading as a button at all. */
.mdl__l > .tiny{align-self:flex-start}
.em__link.is-bad input{border-color:var(--s-bad-line)}
.em__creds{margin:0 0 14px;background:var(--card-2);border-radius:16px;padding:13px 15px;
  display:flex;flex-direction:column;gap:10px}
.em__creds div{display:flex;align-items:center;justify-content:space-between;gap:12px}
.em__creds dt{font-size:13px;color:var(--ink-2);font-weight:700}
.em__creds dd{margin:0;display:flex;align-items:center;gap:9px}
.em__cmd{position:relative;margin-top:9px}
.em__cmd .tiny{position:absolute;top:8px;inset-inline-end:8px;z-index:1}
.em__cmd pre{margin:0;background:var(--ink);color:#EDEDF7;border-radius:14px;
  /* room for the Copy button sitting on top of the first line */
  padding:13px 15px;padding-inline-end:78px;overflow-x:auto;font-size:11.5px;line-height:1.7;
  white-space:pre-wrap;word-break:break-all}

@media (max-width:820px){
  /* The table is a stack of cards at this width, so the actions cell stops
     pretending to be a right-aligned column. */
  .em__act{text-align:start;margin-top:4px}
}
/* Keyed to the panel, not the phone: the sheet is 660px wide and its two-up
   rows run out of room before the viewport does. */
@media (max-width:640px){
  .em__facts,.mdl__two{grid-template-columns:1fr}
  .em__link{grid-template-columns:1fr auto}
  .em__link [data-lu]{grid-column:1 / -1}
  .em__acts .btn{flex:1;justify-content:center}
  .em__acts .btn--danger{margin-inline-start:0}
}

/* ═══════════════════════════════════════════ admin · revenue ══ */
/* Rebuilt from app/dashboard/admin/revenue/page.tsx. Four data tables on one
   screen, so the shared `.tbl` does the work and only the column widths, the
   money column and the totals row are new. */
.kpis--2{grid-template-columns:repeat(2,1fr)}
.pnl__sub{margin:6px 0 14px;font-size:13.5px;line-height:1.55;color:var(--ink-2)}
.pnl__note{font-family:"Mono",ui-monospace,monospace;font-size:10px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}

/* Money reads down the column or it does not read at all. */
.tbl .num{text-align:end;font-variant-numeric:tabular-nums}
.tbl .num b{font-weight:800}
.rev__none{color:var(--ink-3)}
.rev__owed{color:var(--s-warn-ink)}
.rev__cpn{margin-inline-start:5px}
.rev__rcpt{display:inline-flex;align-items:center;gap:5px;font-size:13px;font-weight:700;
  color:var(--brand);white-space:nowrap}
.rev__rcpt svg{width:13px;height:13px}
/* None of these four tables navigates anywhere, so none of them offers the
   hand cursor the selectable queue on the dashboard earns. */
.tbl--rev tbody tr,.tbl--tx tbody tr,.tbl--lab tbody tr{cursor:default}
.tbl--rev tbody tr:hover td,.tbl--tx tbody tr:hover td,.tbl--lab tbody tr:hover td{
  background:var(--lav)}
.tbl tfoot td{background:var(--ink);color:#fff;font-weight:800}
.tbl tfoot .rev__owed{color:#FFC58A}
.tbl tfoot .num{font-variant-numeric:tabular-nums}

/* The three streams, before any of the tables. One bar so the shares can be
   compared at a glance, and the amount under each name so the bar does not
   have to be read as a measurement. */
.streams__bar{display:flex;height:14px;border-radius:99px;overflow:hidden;gap:3px;background:var(--card-2)}
.streams__bar i{display:block}
.streams__key{list-style:none;margin:16px 0 0;padding:0;display:grid;
  grid-template-columns:repeat(3,1fr);gap:14px}
.streams__key li{display:grid;grid-template-columns:auto 1fr;gap:0 9px;align-items:center}
.streams__key span{width:11px;height:11px;border-radius:4px;grid-row:1}
.streams__key b{font-weight:800;font-size:14.5px;letter-spacing:-.02em}
.streams__key em{grid-column:2;font-style:normal;font-weight:900;font-size:26px;
  letter-spacing:-.04em;line-height:1.15}
.streams__key small{grid-column:2;font-size:12px;color:var(--ink-3)}

@media (min-width:821px){
  .tbl--tpl{table-layout:fixed}
  .tbl--tpl th:nth-child(1),.tbl--tpl td:nth-child(1){width:36%}
  .tbl--tpl th:nth-child(2),.tbl--tpl td:nth-child(2){width:34%}
  .tbl--tpl th:nth-child(3),.tbl--tpl td:nth-child(3){width:18%;text-align:end}
  .tbl--tpl th:nth-child(4),.tbl--tpl td:nth-child(4){width:12%;text-align:end}
  .tbl--prod{table-layout:fixed}
  .tbl--prod th:nth-child(1),.tbl--prod td:nth-child(1){width:32%}
  .tbl--prod th:nth-child(2),.tbl--prod td:nth-child(2){width:18%}
  .tbl--prod th:nth-child(n+3),.tbl--prod td:nth-child(n+3){width:16.66%}
  .tbl--prod th:nth-child(n+3){text-align:end}
  .tbl--tpl td,.tbl--prod td{overflow:hidden;text-overflow:ellipsis}
  .tbl--rev{table-layout:fixed}
  .tbl--rev th:nth-child(1),.tbl--rev td:nth-child(1){width:34%}
  .tbl--rev th:nth-child(2),.tbl--rev td:nth-child(2){width:14%}
  .tbl--rev th:nth-child(n+3),.tbl--rev td:nth-child(n+3){width:17.33%}
  .tbl--rev th:nth-child(n+3){text-align:end}
  .tbl--tx{table-layout:fixed}
  .tbl--tx th:nth-child(1),.tbl--tx td:nth-child(1){width:28%}
  .tbl--tx th:nth-child(2),.tbl--tx td:nth-child(2){width:17%}
  .tbl--tx th:nth-child(3),.tbl--tx td:nth-child(3){width:27%}
  .tbl--tx th:nth-child(4),.tbl--tx td:nth-child(4){width:16%;text-align:end}
  .tbl--tx th:nth-child(5),.tbl--tx td:nth-child(5){width:12%;text-align:end}
  .tbl--tx td,.tbl--rev td{overflow:hidden;text-overflow:ellipsis}
  .tbl--lab th:nth-child(1),.tbl--lab td:nth-child(1){width:46%}
  .tbl--lab th:nth-child(n+2){text-align:end}
}
@media (max-width:820px){
  /* Stacked, the amount and its label sit on one line like every other pair,
     so the end-alignment that made a column read stops applying. */
  .tbl .num{text-align:start}
  .kpis--2{grid-template-columns:1fr}
  .streams__key{grid-template-columns:1fr;gap:12px}
  /* The shared rule that turns rows into cards lists tbody and misses tfoot,
     so the totals row stayed a table-footer-group and sized itself to its
     own content — a half-width dark card floating beside the list. */
  .tbl tfoot{display:block;width:100%}
  .tbl tfoot tr{display:block;width:100%;background:var(--ink);color:#fff;
    border-radius:16px;padding:13px 14px}
  .tbl tfoot td{background:none;border-radius:0}
  .tbl tfoot td + td{border-top-color:rgba(255,255,255,.16)}
  .tbl tfoot td::before{color:rgba(255,255,255,.62)}
  /* A cell that is empty only exists to keep the columns lined up. Stacked,
     it is a labelled row with nothing in it. */
  .tbl td.is-blank{display:none}
  /* Left over from the desktop row: the first and last cells still carried
     the row's end radii, and a border-top follows a radius — which is the
     stray curve at the end of every separator line in a stacked card. The
     selector has to match the shape of the rule it is undoing; a shorter one
     loses on specificity and changes nothing. */
  .tbl tr td:first-child,.tbl tr td:last-child{border-radius:0}
}

/* A product whose model has not been decided is not a product earning zero,
   and this row is a sentence rather than a set of empty money columns. */
.rev__pending td{background:transparent!important;border:1.5px dashed var(--line);
  border-radius:14px!important}
.rev__pending b{display:block;font-weight:800;font-size:14.5px;letter-spacing:-.02em}
.rev__pending span{display:block;margin-top:3px;font-size:12.5px;line-height:1.5;color:var(--ink-3)}
@media (max-width:820px){
  .rev__pending td{border-radius:16px!important}
}

/* ═══════════════════════════════════════════ admin · settings ══ */
/* Rebuilt from app/dashboard/admin/settings/page.tsx. Two columns because the
   instructions box is a fourteen-row textarea and the other three cards are
   short — stacked, the page was mostly scrolling past settings to reach it. */
.setgrid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(12px,1.6vw,18px);align-items:start}
.setcol{display:flex;flex-direction:column;gap:clamp(12px,1.6vw,18px);min-width:0}

/* A card whose header carries an icon and a sentence, not just a title. */
.pnl__id{display:flex;gap:12px;align-items:flex-start;min-width:0}
.pnl__id h2{margin:0;font-weight:900;font-size:17px;letter-spacing:-.03em}
.pnl__id h2 em{font-style:normal;font-family:"Mono",ui-monospace,monospace;font-size:9.5px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);
  margin-inline-start:7px;vertical-align:2px}
.pnl__id p{margin:3px 0 0;font-size:12.5px;line-height:1.5;color:var(--ink-3)}
.pnl__ic{width:34px;height:34px;border-radius:11px;flex-shrink:0;background:var(--lav);
  color:var(--brand);display:flex;align-items:center;justify-content:center}
.pnl__ic svg{width:17px;height:17px}

/* The switch. aria-checked is the state; the class is only how it looks. */
.sw{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  padding:14px 0;border-top:1px solid var(--line);cursor:pointer}
.sw b{display:block;font-weight:700;font-size:14.5px;letter-spacing:-.02em}
.sw > span > span{display:block;margin-top:3px;font-size:12.5px;line-height:1.5;color:var(--ink-3)}
.sw__t{position:relative;flex-shrink:0;width:44px;height:25px;border:0;padding:0;cursor:pointer;
  border-radius:999px;background:var(--line);transition:background .24s}
.sw__t.on{background:var(--brand)}
.sw__t i{position:absolute;top:3px;inset-inline-start:3px;width:19px;height:19px;border-radius:99px;
  background:#fff;box-shadow:0 2px 6px rgba(var(--s-tint),.28);transition:transform .24s cubic-bezier(.16,1,.3,1)}
.sw__t.on i{transform:translateX(19px)}
.sw__t:focus-visible{outline:3px solid var(--brand);outline-offset:3px}

.field{padding:15px 0;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:8px}
.field--sep{margin-top:4px}
.field > label{font-size:12.5px;font-weight:700;color:var(--ink-2)}
.field__top{display:flex;align-items:center;justify-content:space-between;gap:12px}
.field__top label{font-size:12.5px;font-weight:700;color:var(--ink-2)}
.field input,.field textarea,.field select{font:inherit;font-size:15px;font-weight:600;color:var(--ink);
  width:100%;max-width:100%;background:var(--card-2);border:2px solid var(--line);border-radius:13px;
  padding:11px 14px;transition:border-color .2s,background .2s}
.field textarea{resize:vertical;line-height:1.6;font-size:14px}
.field select{-webkit-appearance:none;appearance:none;cursor:pointer;padding-inline-end:42px}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:var(--brand);
  background:var(--card)}
.field .selwrap{position:relative;display:block}
.field__h{margin:0;font-size:12px;line-height:1.5;color:var(--ink-3)}
.field__h a{color:var(--brand)}
.field__h.is-bad{color:var(--s-bad-ink);font-weight:700}
.field__act{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding-top:4px}
.field__act .btn{padding:10px 18px;font-size:14.5px;border-radius:13px}
/* The key sits on its own line with the clear beside it: it is a value you
   read, not one you type over. */
.field__key{display:flex;align-items:center;gap:10px;background:var(--card-2);
  border-radius:13px;padding:11px 12px 11px 14px}
.field__key .mono{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acctrow{display:flex;align-items:center;gap:12px;background:var(--card-2);
  border-radius:14px;padding:12px 14px}
.acctrow b{display:block;font-weight:800;font-size:15px;letter-spacing:-.02em}
.acctrow .mono{display:block;font-size:11.5px;color:var(--ink-3)}

@media (max-width:1040px){
  .setgrid{grid-template-columns:1fr}
}

/* ═══════════════════════════════════════ admin · notifications ══ */
/* One row component, two sizes: six of them in the bell's panel, all of them
   on the page. Same markup so the two can never drift apart. */
.nrow{display:flex;align-items:flex-start;gap:12px;padding:13px 14px;border-radius:15px;
  background:var(--card-2);color:inherit;text-decoration:none;position:relative;
  transition:background .2s,transform .3s cubic-bezier(.16,1,.3,1)}
a.nrow:hover{background:var(--lav);transform:translateX(2px)}
.nrow__ic{width:34px;height:34px;border-radius:11px;flex-shrink:0;display:flex;
  align-items:center;justify-content:center;background:var(--lav);color:var(--brand)}
.nrow__ic svg{width:16px;height:16px}
.nrow__ic.message{background:#E4E4FF;color:var(--brand-2)}
.nrow__ic.success{background:var(--sage);color:#03363D}
.nrow__ic.error,.nrow__ic.alert{background:var(--s-warn-bg);color:var(--s-warn-ink)}
.nrow__b{flex:1;min-width:0}
.nrow__b b{display:block;font-weight:800;font-size:14.5px;letter-spacing:-.02em}
.nrow__b p{margin:3px 0 0;font-size:13px;line-height:1.5;color:var(--ink-2)}
.nrow__tag{display:inline-block;margin-top:8px;font-family:"Mono",ui-monospace,monospace;
  font-size:9.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);background:var(--card);border-radius:999px;padding:4px 10px}
.nrow__end{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex-shrink:0}
.nrow__t{font-size:11.5px;color:var(--ink-3);white-space:nowrap}
.nrow__go{color:var(--brand);display:flex}
.nrow__go svg{width:15px;height:15px}
/* A row with nowhere to go says so. It is not a disabled link — there is no
   screen behind it yet, and that is worth reading rather than hiding. */
.nrow__todo{font-family:"Mono",ui-monospace,monospace;font-size:9px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);
  border:1.5px dashed var(--line);border-radius:999px;padding:3px 8px;white-space:nowrap}
.nrow__x{border:0;background:none;padding:2px;cursor:pointer;color:var(--ink-3);
  display:flex;opacity:0;transition:opacity .2s,color .2s}
.nrow__x svg{width:15px;height:15px}
.nrow:hover .nrow__x,.nrow__x:focus-visible{opacity:1}
.nrow__x:hover{color:var(--s-bad-ink)}
/* Unread is a state you should be able to see without reading. */
.nrow.is-new{background:var(--card)}
.nrow.is-new::before{content:"";position:absolute;inset-inline-start:0;top:16px;bottom:16px;
  width:3px;border-radius:0 3px 3px 0;background:var(--brand)}
.nrow.is-new .nrow__b b{color:var(--ink)}
.nrow.is-sys{background:var(--s-warn-bg-2)}
.nrow.is-sys.is-new::before{background:var(--hot)}
a.nrow.is-sys:hover{background:var(--s-warn-bg-3)}

.nlist{display:flex;flex-direction:column;gap:8px}
.nday{margin:14px 0 2px;font-family:"Mono",ui-monospace,monospace;font-size:10px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.nday:first-child{margin-top:0}
.nrow--lg{padding:15px 16px}

/* the bell's panel */
/* Which screen a row is waiting on is worth saying on the page and is only
   noise in a 392px panel, where it competes with the title for the same line. */
.notes__b .nrow__todo{display:none}
.notes__h{display:flex;align-items:center;justify-content:space-between;gap:12px}
.notes__b{display:flex;flex-direction:column;gap:7px}
.notes__f{display:flex;align-items:center;justify-content:center;gap:7px;
  margin-top:10px;padding-top:11px;border-top:1px solid var(--line);
  font-size:13.5px;font-weight:700;color:var(--brand)}
.notes__f svg{width:14px;height:14px}
/* The dot became a count. It has to hold two characters now. */
.iconbtn .dot{min-width:17px;width:auto;height:17px;padding:0 4px;border-radius:99px;
  display:flex;align-items:center;justify-content:center;top:5px;right:5px;
  font-family:"Mono",ui-monospace,monospace;font-size:9.5px;font-weight:700;color:#fff}
.mdl__opt{font-weight:600;color:var(--ink-3);text-transform:none;letter-spacing:0}

@media (max-width:640px){
  .nrow__x{opacity:1}
  .nrow__b p{font-size:12.5px}
}

/* ═══════════════════════════════════════════ admin · messages ══ */
/* The list beside the thread, from components/dashboard/admin-messages.tsx.
   Both panes scroll inside themselves so the page itself does not — a
   conversation you have to scroll the whole document to read is not one. */
.msgs{display:grid;grid-template-columns:320px minmax(0,1fr);gap:clamp(12px,1.6vw,18px);
  height:min(62vh,560px);min-height:380px}
.msgs--solo{grid-template-columns:minmax(0,1fr)}
.msgs--solo .msgs__list{display:none}
.msgs__list{background:var(--card);border-radius:22px;box-shadow:var(--sh-sm);
  padding:8px;overflow-y:auto;display:flex;flex-direction:column;gap:4px}
.msgs__thread{background:var(--card);border-radius:22px;box-shadow:var(--sh-sm);
  display:flex;flex-direction:column;min-height:0;overflow:hidden}

.mrow{display:flex;align-items:center;gap:11px;width:100%;text-align:start;cursor:pointer;
  border:0;background:none;font:inherit;padding:11px 12px;border-radius:15px;
  transition:background .2s}
.mrow:hover{background:var(--card-2)}
.mrow.on{background:var(--lav)}
.mrow__av{position:relative;width:36px;height:36px;border-radius:999px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;color:#fff;
  font-size:11.5px;font-weight:800;letter-spacing:.02em}
/* The unanswered mark sits on the face, not at the end of the row — it is
   about the person, and at the end it competed with the status pill. */
.mrow__av[data-dot]::after{content:"";position:absolute;top:-1px;inset-inline-end:-1px;
  width:11px;height:11px;border-radius:99px;background:var(--brand);border:2.5px solid var(--card)}
.mrow.on .mrow__av[data-dot]::after{border-color:var(--lav)}
.mrow__b{flex:1;min-width:0}
.mrow__b b{display:block;font-weight:800;font-size:14px;letter-spacing:-.02em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mrow__b span{display:block;font-size:11.5px;color:var(--ink-3);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}

/* 92% of a 1030px pane is a 90-character line. A bubble is a sentence, not a
   paragraph column. */
.msgs__thread .bub{max-width:min(560px,78%)}
.mhead{display:flex;align-items:center;gap:12px;padding:13px 16px;
  border-bottom:1px solid var(--line);flex:0 0 auto}
.mhead > div{flex:1;min-width:0}
.mhead b{display:block;font-weight:800;font-size:15.5px;letter-spacing:-.025em}
.mhead span{display:block;font-size:12px;color:var(--ink-3)}
.tiny--ok{border-color:var(--sage);color:#03363D;background:var(--sage)}
.tiny--ok:hover{background:#A8CCC9;border-color:#A8CCC9;color:#03363D}

/* Why the other half of the brief is not on this screen. */
.msgs__note{display:flex;gap:11px;align-items:flex-start;margin:clamp(12px,1.6vw,18px) 0 0;
  padding:14px 16px;border:1.5px dashed var(--line);border-radius:18px;
  font-size:13px;line-height:1.55;color:var(--ink-2)}
.msgs__note svg{width:17px;height:17px;flex-shrink:0;margin-top:1px;color:var(--ink-3)}

@media (max-width:900px){
  /* Stacked, the list becomes a strip you scroll sideways: on a phone you are
     picking a person, not scanning a directory. */
  .msgs{grid-template-columns:1fr;height:auto}
  .msgs__list{flex-direction:row;overflow-x:auto;overflow-y:hidden;gap:6px}
  .mrow{width:auto;flex:0 0 auto;padding:9px 12px 9px 9px}
  .mrow__b span,.mrow .pill{display:none}
  .msgs__thread{height:min(64vh,480px)}
}

/* ═══════════════════════════════════════════════ worker · files ══ */
/* `.pnl` is a column flex box, and setting only `display:flex` here left its
   flex-direction in place — the row stacked and centred itself. */
.newfold{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;gap:14px;
  /* one row of controls does not need a panel's full section padding */
  padding:15px 18px}
.newfold__ic{width:38px;height:38px;border-radius:13px;flex-shrink:0;background:var(--lav);
  color:var(--brand);display:flex;align-items:center;justify-content:center}
.newfold__ic svg{width:18px;height:18px}
.newfold__b{flex:1;min-width:180px}
.newfold__b b{display:block;font-weight:800;font-size:15px;letter-spacing:-.02em}
.newfold__b span{display:block;font-size:12.5px;color:var(--ink-3)}
.newfold input{font:inherit;font-size:15px;font-weight:600;color:var(--ink);min-width:190px;
  background:var(--card-2);border:2px solid var(--line);border-radius:13px;padding:10px 14px}
.newfold input:focus{outline:none;border-color:var(--brand);background:var(--card)}
.wfcount{margin:12px 2px 14px;font-family:"Mono",ui-monospace,monospace;font-size:10px;
  font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3)}

/* One folder open at a time. Three folders of six files each, all expanded, is
   a page you scroll past to reach the one you came for. */
.folds{display:flex;flex-direction:column;gap:10px}
.fold{background:var(--card);border-radius:22px;box-shadow:var(--sh-sm);overflow:hidden}
.fold__h{display:flex;align-items:center;gap:13px;width:100%;text-align:start;border:0;
  background:none;font:inherit;cursor:pointer;color:var(--ink);padding:15px 18px;
  transition:background .3s cubic-bezier(.32,.72,0,1)}
.fold__h:hover{background:var(--card-2)}
.fold.on .fold__h{background:var(--lav)}
.fold__ic{width:34px;height:34px;border-radius:11px;flex-shrink:0;background:var(--card-2);
  color:var(--ink-2);display:flex;align-items:center;justify-content:center}
.fold.on .fold__ic{background:var(--card);color:var(--brand)}
.fold__ic svg{width:16px;height:16px}
.fold__id{flex:1;min-width:0}
.fold__id b{display:block;font-family:"Mono",ui-monospace,monospace;font-size:14px;
  font-weight:700;letter-spacing:-.01em}
.fold__id span{display:block;font-size:12px;color:var(--ink-3)}
.fold__x{position:relative;width:24px;height:24px;flex-shrink:0}
.fold__x i{position:absolute;top:50%;left:50%;width:11px;height:2px;border-radius:2px;
  background:var(--ink-3);transform:translate(-50%,-50%);
  transition:transform .45s cubic-bezier(.32,.72,0,1)}
.fold__x i:last-child{transform:translate(-50%,-50%) rotate(90deg)}
.fold.on .fold__x i:last-child{transform:translate(-50%,-50%) rotate(0deg)}
.fold__b{height:0;overflow:hidden;transition:height .5s cubic-bezier(.32,.72,0,1)}
.fold__in{padding:4px 12px 12px}

.frow{display:grid;grid-template-columns:1fr auto auto auto;align-items:center;gap:14px;
  padding:9px 12px;border-radius:12px;transition:background .25s}
.frow:hover{background:var(--card-2)}
.frow__n{font-family:"Mono",ui-monospace,monospace;font-size:13px;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.frow__s{font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.frow__t{font-size:12px;color:var(--ink-3);white-space:nowrap}
.frow .tiny{opacity:0}
.frow:hover .tiny,.frow .tiny:focus-visible{opacity:1}

.fdrop{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:8px;
  padding:18px;border:1.5px dashed var(--line);border-radius:16px;font-size:13px;
  color:var(--ink-3);transition:border-color .3s,background .3s}
.fdrop:hover{border-color:var(--brand);background:var(--lav)}
.fdrop b{color:var(--brand);font-weight:700}
.fdrop svg{width:16px;height:16px}
.fold__act{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.fold__act .tiny{text-decoration:none}

@media (max-width:640px){
  .frow{grid-template-columns:1fr auto;gap:6px 12px}
  .frow__t{grid-column:1/-1;order:3}
  .frow .tiny{opacity:1;order:4}
}

/* ── Inbox, wired to the real routes (13 Sep) ─────────────────────────
   A row that nobody has opened yet, the studio's reply under the message,
   and the quoted original inside the reply dialog. */
.prow.is-new{box-shadow:inset 3px 0 0 var(--brand)}
.pill.ok{background:var(--sage);color:var(--mint,#03363D)}
.pill.hot{background:var(--brand);color:#fff}
.prow__reply{display:block;margin-top:6px;padding:8px 12px;border-radius:10px;
  background:var(--card-2);color:var(--ink-2);font-size:13px;line-height:1.5;
  white-space:pre-wrap;overflow-wrap:anywhere}
.mdl__quote{margin:0 0 14px;padding:10px 14px;border-inline-start:3px solid var(--lav);
  border-radius:0 10px 10px 0;background:var(--card-2);color:var(--ink-2);
  font-size:13.5px;line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere}
.field__err{margin:10px 0 0;font-size:13px;color:var(--s-bad-ink)}
.mdl__b textarea[data-reply-text]{width:100%;min-height:120px;resize:vertical}
/* `.prow__b span` is display:block for the second line; a pill inside the
   name line is not a line of its own. (This is why "PRICING PAGE" used to
   stretch across the whole row.) */
.prow__b b .pill{display:inline-block;vertical-align:middle;margin-inline-start:6px}
