/* Axis shell in style C (M-045, M-049, M-057, M-107): values measured from the approved C draft live in
   tokens.css. Tonal pills and fields, panels without wires, one ink focus ring. Existing hooks and state
   mappings retained; composition is CSS over unchanged DOM. */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html{height:100%;background: var(--ground);scrollbar-color:var(--line-2) transparent;}
body{
margin:0;min-height:100%;
font:var(--t-body);color:var(--ink);background:var(--ground);
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
text-rendering:optimizeLegibility;
}
h1, h2, h3, p, ul, ol, pre{margin:0;}
ul, ol{padding:0;list-style:none;}
a{color:inherit;text-decoration:none;}
button, input, select, textarea{font:inherit;color:inherit;}
input, textarea{caret-color:var(--ink);}
button{cursor:pointer;}
img{display:block;max-width:100%;}
svg.i{width:var(--icon);height:var(--icon);flex:none;fill:none;stroke:currentColor;stroke-width: 1.75;stroke-linecap:round;stroke-linejoin:round;}
svg.i.i-sm{width:20px;height:20px;}
svg.i.i-meta{color:var(--meta);}/* Meta's own blue, only on its glyph */
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.muted{color:var(--ink-3);}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
[hidden]{display:none !important;}
::selection{background:var(--selection);color:var(--ink);}
/* Focus: one ring everywhere, only from the keyboard. */
:focus{outline:none;}
:focus-visible { outline: 2px solid var(--focus-ring);outline-offset:2px;box-shadow: var(--sh-focus);border-radius:var(--r-sm);}
/* Pills keep their shape under the ring, 3px clear of the fill. */
.btn:focus-visible, .nav-item:focus-visible, .seg-item:focus-visible, .icon-btn:focus-visible, .pick-btn:focus-visible, .avatar:focus-visible{outline-offset:3px;border-radius:var(--r-tab);}
/* A field keeps its fill, edge and corners; the ring sits 2px outside the edge. */
.input:focus-visible, .select:focus-visible, .textarea:focus-visible{background:var(--field);border-color:var(--line-2);box-shadow: none;}
/* ---------- Shell ---------- */
/* The single navigation is the 72px icon rail on the left; panels sit inset on the ground. */
.app, .app.is-collapsed{display:grid;grid-template-columns:var(--sidebar) minmax(0, 1fr);grid-template-rows:var(--topbar) 1fr;min-height:100vh;}
.main{min-width:0;grid-column:2;}
/* The topbar stops where the panel stops (seat, 2026-09-28): the same cap as .views, so on a wide screen the
   top-right controls sit over the panel's right edge, not the window's. Below the cap nothing changes. */
.top{
position:relative;z-index:30;grid-column:2;min-height:var(--topbar);height:var(--topbar);max-width:calc(var(--intake-canvas) + 2 * var(--gap));
display:flex;align-items:center;gap:var(--s-12);padding:0 var(--s-16) 0 var(--s-20);
color:var(--ink);background:var(--chrome);
}
.top-left, .top-right{display:flex;align-items:center;gap:var(--s-8);min-width:0;}
.top-left{flex:1;}
.top-right{flex:none;}
.workspace{font:var(--t-small);color:var(--ink-2);white-space:nowrap;}
.mark{display:inline-flex;align-items:center;gap:var(--s-8);font:var(--t-mark);letter-spacing:var(--track-mark);color:inherit;border-radius:var(--r-sm);}
.top > .mark{position:fixed;left:calc((var(--sidebar) - 32px) / 2);top:calc((var(--topbar) - 32px) / 2);}
.senditor-mark{width:32px;height:32px;flex:none;}
.mark--auth .senditor-mark{width:40px;height:40px;}
.side-panel{position:fixed;inset:0 auto 0 0;z-index:20;width:var(--sidebar);}
.side, .app.is-collapsed .side{
height:100%;display:flex;flex-direction:column;gap:var(--s-8);padding:calc(var(--topbar) + var(--s-8)) var(--s-12) calc(var(--ctl) + var(--s-24));
background:var(--chrome);color:var(--ink);overflow-y:auto;overscroll-behavior:contain;
}
.side-top, .side-collapse, .icon-btn.side-expand, .app.is-collapsed .icon-btn.side-expand{display:none;}
.nav{display:flex;flex-direction:column;gap:var(--s-4);}
.nav-item{position:relative;display:flex;width:100%;border:0;background:transparent;text-align:left;align-items:center;gap:var(--s-8);min-height:var(--ctl);padding:var(--s-8) var(--s-12);color:var(--ink-2);font:var(--t-strong);white-space:nowrap;border-radius:var(--r-tab);}
/* The chosen state is an ink fill. */
.nav-item[aria-current="page"]{color: var(--on-chosen);background: var(--chosen);box-shadow: inset 0 0 0 1.5px var(--chosen-edge);}
.nav-item .i{color:inherit;}
.nav-item.is-soon, .soon{color:var(--ink-3);}
.soon { margin-left: auto; font: var(--t-small); }
.nav--bottom{margin-top:auto;}
.side .nav-item[href]:active{background:var(--press);}
.side .nav-item[href][aria-current="page"]:active{background:var(--chosen);color:var(--on-chosen);}
.pick-btn{display:inline-flex;align-items:center;gap:var(--s-8);min-height:var(--ctl);padding:var(--s-8) var(--s-12);max-width:240px;border:0;border-radius:var(--r-tab);background: var(--ctl-fill);font:var(--t-strong);}
.pick-btn span:not(.brand-dot){overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
[data-brand-name]:not(:empty) + [data-brand-empty] { display: none; }
.pick-chev { color: var(--chrome-secondary); flex: none; }
.brand-dot{width:24px;height:24px;border-radius:var(--r-thumb);display:inline-grid;place-items:center;flex:none;font:var(--t-small);font-weight:500;color:var(--ink-2);background: var(--sunk);}
.brand-image{width:24px;height:24px;object-fit:cover;border-radius:var(--r-thumb);flex:none;}
.brand-image:not([hidden]) ~ .brand-dot, .brand-image:not([hidden]) ~ .brand-fallback,
[data-brand-dot]:empty, [data-brand-dot]:not(:empty) + .brand-fallback,
[data-session-initials]:empty, [data-session-initials]:not(:empty) + [data-session-glyph] { display: none; }
[data-session-name] { overflow-wrap: anywhere; }
[data-session-org]:empty { display: none; }
.menu-wrap:has([data-act="account-menu"]) .menu { max-width: min(320px, calc(100vw - 32px)); }
/* REVIEW-ONLY (DV2-D): retained API hook, pinned to Geist. */
.font-pick{width:112px;}
.top .font-pick{display:none;}
.avatar{display:inline-grid;place-items:center;width:var(--ctl);height:var(--ctl);border-radius:var(--r-pill);border:0;background:var(--ctl-fill);color:var(--chrome-ink);font:var(--t-strong);}
.bell-dot{position:absolute;top:6px;right:6px;width:6px;height:6px;border-radius:var(--r-pill);background:var(--chrome-ink);}
.top .icon-btn{color:var(--chrome-ink);}
.top .menu{color:var(--ink);}
.top [data-brand-empty]{color:var(--chrome-secondary);}
.top :focus-visible, .side :focus-visible{outline-color:var(--focus-chrome);}
/* Text on the ground: the muted grey steps up to ink-2 (4.66:1 on the ground). */
.top, .side{--ink-3: var(--ink-2);}
.i-moon{display:none;}
:root[data-theme="dark"] .i-sun { display: none; }
:root[data-theme="dark"] .i-moon{display:block;}
@media (prefers-color-scheme: dark) {
 :root:not([data-theme="light"]) .i-sun { display: none; }
 :root:not([data-theme="light"]) .i-moon { display: block; }
}

/* Menus float: a raised layer with a hairline and the pop shadow. */
.menu-wrap{position:relative;}
.menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 40; min-width: 232px; padding: var(--s-4);
  background: var(--elevated); border: 0; border-radius: var(--r-layer); box-shadow: var(--sh-pop);
  transform-origin: top left; animation: fade var(--dur-1) var(--ease);
}
.menu--right{left:auto;right:0;transform-origin:top right;}
.menu-item{
display:flex;align-items:center;gap:var(--s-8);width:100%;height:var(--ctl);padding:0 var(--s-8);
border:0;border-radius:var(--r);background:transparent;text-align:left;font:var(--t-body);
transition:background var(--dur-1) var(--ease);
}
.menu-item:focus-visible{background: var(--hover);box-shadow:none;}
@media (hover: hover) and (pointer: fine) {
.menu-item:hover { background: var(--hover); box-shadow: none; }
}
.menu-item[aria-checked="true"]{font-weight:600;}
.menu-item[aria-checked="true"]::after{content:"";width:6px;height:6px;border-radius:var(--r-pill);background:var(--chosen-edge);margin-left:auto;}
.menu-item .i{color:var(--ink-3);}
.menu-meta{font:var(--t-small);color:var(--ink-3);}
.menu-head{padding:var(--s-8);display:flex;flex-direction:column;gap:0;}
.menu-rule{height:1px;background:var(--line);margin:var(--s-4) 0;}
/* ---------- Views ---------- */
/* One workspace inset for every view (founder D3, 2026-09-28): the panel sits --gap from the rail at every width
   and stops at the canvas width (--intake-canvas); beyond it the spare width goes to the right, never between
   the rail and the panel. Add ads uses the same box. */
.views { width: 100%; max-width: calc(var(--intake-canvas) + 2 * var(--gap)); margin-inline: 0 auto; padding: var(--gap);flex:1;}
/* A view is one inset panel on the ground; Add ads composes two (see Create layout). */
.view{background:var(--page);border:0;border-radius:var(--r-panel);padding:var(--workspace-gutter);}
.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s-16);margin-bottom:var(--s-20);}
.page-title{font:var(--t-display);letter-spacing:var(--track-display);}
.page-sub{font:var(--t-body);color:var(--ink-2);margin-top:var(--s-4);}
.page-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-8);flex:none;}
.section{margin-top:var(--s-24);}
.section-head{display:flex;align-items:center;justify-content:space-between;height:28px;padding-bottom:var(--s-8);margin-bottom:var(--s-8);border-bottom:1px solid var(--line);}
.label{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);}
.label-row{display:flex;align-items:center;justify-content:space-between;gap:var(--s-12);}
/* Links are ink, as on the approval page, where blue means Yes and nothing else. */
.link{font:var(--t-small);font-weight:600;color:var(--act-ink);border-radius:4px;transition:color var(--dur-1) var(--ease);}
@media (hover: hover) and (pointer: fine) {
.link:hover{text-decoration:underline;text-underline-offset:3px;}
}
.two-col{display:grid;grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);gap:var(--s-16);}
/* ---------- Controls ---------- */
/* One button component (UI-HOME round 2, #93): the v3 .aa-btn, --ctl-dense high, sentence case */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--step-tight); height: var(--ctl-dense); padding: 0 var(--s-12);
  border: 0; border-radius: var(--r-tab); background: var(--ctl-fill); color: var(--act-ink);
  font: var(--t-action); white-space: nowrap;user-select:none;
}
@media (hover: hover) and (pointer: fine) {
.btn:hover{background:var(--ctl-hover);}
}
.btn:not(:disabled):active { transform: scale(var(--press-scale));background:var(--ctl-hover);}
.btn:disabled, .modal[data-deliver-state="working"] [data-act="deliver-confirm"], [data-auth-form][data-auth-state="working"] [type="submit"], [data-brand-form][data-brand-form-state="working"] [type="submit"] { opacity: .4; pointer-events: none; }
.btn .i{color:var(--act-ink);width:var(--s-16);height:var(--s-16);}
/* #93: one size; large is Sign in's Continue under its 48 px fields */
.btn--sm, .btn--mini{height:var(--ctl-dense);padding:0 var(--s-12);border-radius:var(--r-tab);}
.btn--lg{height:var(--ctl-lg);padding:0 var(--s-20);border-radius:var(--r-tab);}
.btn--block{width:100%;}
/* Step 1's primary is the Meta dialog's own Connect button, weighted only while the first run borrows it: the
   product binds that hook and the page script never names it (one writer), so the weight lives here. */
.btn--primary, [data-first-run-slot="meta"] [data-meta-connect] {
background: var(--primary-top);border-color:var(--primary-border);
color: var(--primary-text);box-shadow:var(--sh-primary);
}
.btn--primary .i{color:inherit;}
@media (hover: hover) and (pointer: fine) {
.btn--primary:hover, [data-first-run-slot="meta"] [data-meta-connect]:hover{background:var(--primary-hover);border-color:var(--primary-border);}
}
.btn--primary:not(:disabled):active, [data-first-run-slot="meta"] [data-meta-connect]:not(:disabled):active{background:var(--primary-press);}/* :not(:disabled) matches the .btn press rule above, else its --press wins and the white label vanishes */
.btn--ghost{background:transparent;}
@media (hover: hover) and (pointer: fine) {
.btn--ghost:hover{background:var(--hover);border-color:transparent;}
}
.btn--approve .i{color:var(--ok);}
@media (hover: hover) and (pointer: fine) {
.btn--approve:hover{background:var(--ok-tint);border-color:var(--ok);color:var(--ok);}
}
.btn.is-done{background:var(--ok-tint);border-color:var(--ok);color:var(--ok);}
.btn.is-done .i{color:var(--ok);}
.icon-btn{
position:relative;display:inline-grid;place-items:center;width:var(--ctl-sm);height:var(--ctl-sm);
border:0;border-radius:var(--r-tab);background:transparent;color:var(--ink-2);
transition:background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
.icon-btn:hover{background:var(--hover);color:var(--ink);}
}
.icon-btn:not(:disabled):active{transform:scale(var(--press-scale));background:var(--press);}
.icon-btn:disabled { opacity: .4; pointer-events: none; } /* the same hold as .btn:disabled (DV2-I) */
@media (hover: hover) and (pointer: fine) {
.icon-btn--danger:hover{color:var(--bad);background:var(--bad-tint);}
}
.link-btn{
border:0;background: none;padding:0;font:var(--t-small);font-weight:600;color:var(--act-ink);border-radius:4px;
transition:color var(--dur-1) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
.link-btn:hover{text-decoration:underline;text-underline-offset:3px;}
}
/* Segmented control: a field-tone track, the chosen item an ink pill. */
.seg{display:inline-flex;align-items:center;height:var(--ctl);padding:var(--s-4);gap:var(--s-4);border-radius:var(--r-tab);background:var(--field);}
.seg-item{
height:24px;padding:0 var(--s-12);border:0;border-radius:var(--r-tab);background:transparent;color:var(--ink-2);
font:var(--t-strong);display:inline-flex;align-items:center;gap:var(--s-8);
transition:background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
.seg-item:hover{color:var(--ink);}
}
.seg-item:not(:disabled):active{transform:scale(var(--press-scale));}
.seg-item[aria-checked="true"]{background:var(--chosen);color:var(--on-chosen);box-shadow:inset 0 0 0 1.5px var(--chosen-edge);}
.seg-item:disabled{opacity:.5;cursor:default;}
/* LAUNCH: the same segmented control with exactly one option. There is no
   second state to offer — Senditor never creates a live ad. */
.seg--fixed{align-self:flex-start;}
.seg--fixed .seg-item{cursor:default;}
.seg--icons .seg-item{padding:0 var(--s-8);}
.chip{
display:inline-block;box-sizing:border-box;vertical-align:middle;max-width:100%;min-height: var(--label-h);
padding:calc((var(--label-h) - 1lh) / 2) var(--s-8);border:0;border-radius: var(--label-r);box-shadow:none;outline:none;
  font: var(--label-font); color: var(--label-ink); background: var(--label-neutral); white-space: normal; overflow-wrap: anywhere;
}
/* DV2-E: one served status attribute keys colour; never infer success from truthiness.
   Absent data-tone uses the named status mappings; present data-tone alone decides.
   Empty/unknown tone fails closed to neutral even beside ok; recheck means Needs recheck. */
[data-review-tone="success"]{background:var(--label-success)}
[data-review-tone="failure"]{background:var(--label-failure)}
[data-review-tone="neutral"],[data-review-tone="warning"]{background:var(--label-neutral)}
.chip[data-tone="success"],
.chip[data-status="approved"]:not([data-tone]),
.chip[data-state="ok"]:not([data-tone]), .chip[data-state="created"]:not([data-tone]), .chip[data-state="approved"]:not([data-tone]), .chip[data-state="delivered"]:not([data-tone]),
.chip[data-state="added"]:not([data-tone]) { background: var(--label-success); }
.chip[data-tone="failure"],
.chip[data-status="changes"]:not([data-tone]), .chip[data-state="bad"]:not([data-tone]), .chip[data-state="refused"]:not([data-tone]),
.chip[data-state="not_added"]:not([data-tone]) { background: var(--label-failure); }
.chip[data-tone="recheck"] { background: var(--label-recheck); }
.chip[data-status="review"]:not([data-tone]),
.chip[data-status="sent"]:not([data-tone]), .chip[data-status="viewed"]:not([data-tone]),
.chip[data-status="paused"]:not([data-tone]), .chip[data-status="expired"]:not([data-tone]),
.chip[data-state="warn"]:not([data-tone]), .chip[data-state="sent"]:not([data-tone]),
.chip[data-state="over_limit"]:not([data-tone]){background:var(--label-neutral);}
/* Current is local planning, not a status (brand RULES). W7 Ink (the founder: "borderless"): where you are is the ink
   fill with no ring; Incomplete stays the neutral label, a different fill in both schemes (review P3-10). */
.chip[data-status="current"]:not([data-tone]) { background: var(--chosen); color: var(--on-chosen); }
.chip:empty { display: none; }
/* A status the product serves is an icon, not a label (M-138, M-140, which supersede M-053's solid chip for these words
   only): status-icons.js draws it into the chip it replaces. The served word stays inside as the accessible name and is
   the tooltip; it shows beside the icon only where showWord says so (data-show-word). No label fill, no label ink. */
/* The word keys above are (0,3,0) (.chip[data-status="approved"]:not([data-tone])); the attribute pairs here match that
   and come later, so an icon never inherits a word's label fill. */
.chip[data-icon], .chip[data-icon][data-status], .chip[data-icon][data-state], .chip[data-icon][data-tone] { display: inline-flex; align-items: center; gap: var(--s-8); min-height: var(--label-h); padding: 0; border-radius: 0; background: none; font: var(--t-small); color: var(--ink-2); white-space: nowrap; }
.chip[data-icon]:not([data-show-word]) > .st-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* A card is a container: the white bar on the panel, radius 14, no wire and no shadow. */
.card { background: var(--raised); border: 0; border-radius: var(--r-lg); padding: var(--s-24); }
/* A block sits on the page with no edge: the checklist, a form. */
.block-title{font:var(--t-title);}
/* Connection copy comes from the product; empty slots carry no verdict. */
.meta-heading{font:var(--t-strong);}
.meta-card .help, .meta-heading{max-width:70ch;overflow-wrap:anywhere;}
.meta-card .row-actions{margin:0;}
.meta-card .row-actions:not(:has(> :not([hidden]))){display:none;}/* no shown button, no row and no gap */
.meta-selection{width:100%;max-width:680px;min-width:0;}
.meta-selection .field, .meta-selection .select-wrap{min-width:0;}
.meta-selection > .row-actions{margin-top:var(--s-16);}
[data-meta-error]:not(:empty) { color: var(--bad); }
[data-meta-error]:focus{outline:2px solid var(--bad);outline-offset:2px;}
.meta-card [aria-busy="true"]{cursor:progress;}
.meta-disconnect{display:grid;gap:var(--s-8);width:100%;}
[data-meta-disconnect-status]:empty, .approval-reach:empty { display: none; }
.approval-reach { overflow-wrap: anywhere; }
.meta-card .row-actions { flex-wrap: wrap; }
/* A list: rows on the page, separated by hairlines. */
.list { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; gap: var(--s-12); height: 40px; }
.row + .row { border-top: 1px solid var(--line); }
.row-title { font: var(--t-body); color: var(--ink-2); flex: 1; min-width: 0; overflow: hidden;text-overflow:ellipsis;white-space:nowrap;}
.row-title strong{font-weight:600;color:var(--ink);}
.row-time{font:var(--t-small);color:var(--ink-3);flex:none;}
/* The empty panel: their PERFORMANCE plate, on the page. One sentence, one grey
   line under it, nothing else — an honest statement, not a prompt. */
.panel{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--s-8);text-align:center;padding:var(--s-48) var(--s-24);}
/* The same plate inside a list or a column, where 56px of air would push the next row away. */
.panel--tight{padding:var(--s-16) var(--s-24);}
.empty-line{font:var(--t-body);color:var(--ink);max-width:44ch;}
.empty-note{font:var(--t-small);color:var(--ink-3);max-width:44ch;}
/* Checklist: rows on the page, hairlines between, the button under them. The step's state
   is data-step-state="done|next|todo" on the row (DV2-E), the one key the product sets. */
.checklist{display:flex;flex-direction:column;margin:var(--s-8) 0 var(--s-20);}
.checklist:empty{display:none;}
.check{display:flex;align-items:center;gap:var(--s-12);height:36px;}
.check + .check{border-top:1px solid var(--line);}
.check-mark{
width:16px;height:16px;border-radius:var(--r-pill);border: 1.5px solid var(--line-2);display:inline-grid;place-items:center;
font:600 9px/1 var(--font-mono);color:var(--ink-3);background:transparent;flex:none;
}
.check-mark .i{display:none;width:9px;height:9px;stroke-width:2.4;}
.check[data-step-state="done"] .check-mark{border-color:var(--ok);color:var(--ok);}
.check[data-step-state="done"] .check-mark .i{display:block;}
.check[data-step-state="done"] .check-n{display:none;}
.check[data-step-state="done"] .check-text{color:var(--ink-3);text-decoration:line-through;text-decoration-color:var(--ink-3);}
.check[data-step-state="next"] .check-mark{border-color:var(--ink);color:var(--ink);}
.check[data-step-state="next"] .check-text{font-weight:600;}
.check-text{color:var(--ink-2);}
.check[data-step-state="next"] .check-text{color:var(--ink);}
/* ---------- Forms ---------- */
.field{display:flex;flex-direction:column;gap:var(--s-8);}
.field + .field, .field-row + .field, .field + .field-row, .field-row + .field-row, .checkbox + .field, .subsection + .field, .field + .help { margin-top: var(--s-16); }
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-16);}
.field-row > .field + .field{margin-top:0;}
.help{font:var(--t-small);color:var(--ink-3);}
/* Error copy and focus are product-owned; keep an empty slot out of the layout. */
/* UI-HOME round 2 (#92): every field's own message slot takes the same box, under its field */
:is([data-auth-error], [data-auth-error-for]):empty, :is([data-auth-error], [data-auth-error-for])[hidden] { display: none; }
:is([data-auth-error], [data-auth-error-for]):not(:empty):not([hidden]){
padding:var(--s-12);border:1px solid var(--bad);border-radius:var(--r);
color:var(--bad);background:var(--bad-tint);font:var(--t-field);
min-width:0;overflow-wrap:anywhere;
}
/* The later binding may focus this message after either pointer or keyboard submit. */
:is([data-auth-error], [data-auth-error-for]):focus{outline:2px solid var(--bad);outline-offset:2px;box-shadow:none;}
/* A held input or select takes the .btn:disabled declarations (DV2-N): no new value. */
.input:disabled, .select:disabled, .textarea:disabled { opacity: .4; pointer-events: none; }
/* Inputs and selects rest on the field tone with a visible edge (3:1 and up); hover darkens the edge,
   focus draws the ink ring outside it. */
.input, .select, .textarea{
height:var(--ctl);padding:var(--s-8) var(--s-12);border:1px solid var(--line-2);border-radius:var(--r);background:var(--field);
font:var(--t-body);box-shadow:var(--sh-input);width:100%;
transition:border-color var(--dur-1) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
.input:hover, .select:hover, .textarea:hover{border-color:var(--ink-2);}
}
.input::placeholder, .textarea::placeholder{color:var(--ink-3);}
.input--lg{height:var(--ctl-lg);font-size:16px;}
.textarea{height:auto;resize:vertical;line-height:18px;padding:var(--s-8) var(--s-12);}
.select{appearance:none;padding-right:var(--s-32);cursor:pointer;text-overflow:ellipsis;}
.select-wrap{position:relative;}
.select-chev{position:absolute;right:var(--s-8);top:50%;transform:translateY(-50%);color:var(--ink-3);pointer-events:none;}
.select-dot{position:absolute;left:var(--s-8);top:50%;transform:translateY(-50%);pointer-events:none;z-index:1;}
.select--dot{padding-left:var(--s-32);}
.select--sm{height:var(--ctl-sm);padding:var(--s-4) var(--s-32) var(--s-4) var(--s-12);border-radius:var(--r-tab);}
.input-wrap{position:relative;display:flex;align-items:center;}
.input-wrap .input-icon{position:absolute;left:var(--s-12);color:var(--ink-2);pointer-events:none;}
.input-wrap .input-icon + .input{padding-left:calc(var(--s-12) + var(--icon) + var(--s-12));}/* the icon's inset, the icon, a gap */
.input-wrap--action{gap:var(--s-8);}
.input-wrap--action .btn{flex:none;}
.checkbox{display:flex;align-items:flex-start;gap:var(--s-12);cursor:pointer;user-select:none;}
.checkbox input{position:absolute;opacity:0;width:1px;height:1px;}
.checkbox-box{
width:var(--box);height:var(--box);margin-top:calc((1lh - var(--box)) / 2);font:var(--t-body);border:1.5px solid var(--line-2);border-radius:5px;background:var(--raised);
display:inline-grid;place-items:center;flex:none;
transition:background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.checkbox-box .i{width:11px;height:11px;stroke-width:2.2;color:var(--on-chosen);opacity:0;transition:opacity var(--dur-1) var(--ease);}
.checkbox input:checked + .checkbox-box{background:var(--chosen);border-color:var(--chosen-edge);}
.checkbox input:checked + .checkbox-box .i{opacity:1;}
.checkbox:active .checkbox-box { transform: scale(var(--press-scale)); }
/* A locked checkbox — its input disabled, the deliver modal while working (DV2-I) — reads as held:
   the .btn:disabled opacity, the default cursor, no press. */
label.checkbox:has(> input:disabled) { cursor: default; opacity: .4; }
label.checkbox:has(> input:disabled):active .checkbox-box { transform: none; }
.checkbox input:focus-visible + .checkbox-box{outline:2px solid var(--focus-ring);outline-offset:2px;box-shadow:var(--sh-focus);}
.checkbox-text{display:flex;flex-direction:column;gap:var(--s-4);font:var(--t-body);}
/* The deliver confirm: one sentence on the field tone, the box on its first line, the ad set in weight.
   Inline text, so the served ad set flows on after "in" instead of breaking to its own line. */
.checkbox--confirm{align-items:flex-start;padding:var(--s-12) var(--s-16);border-radius:var(--r-sm);background:var(--field);box-shadow:inset 0 0 0 1px var(--line);}
.checkbox--confirm .checkbox-text{display:block;text-wrap:pretty;}
.checkbox--confirm [data-deliver-adset] { font-weight: 600; }
.checkbox--sm .checkbox-text{font:var(--t-small);}
.checkbox--sm{align-items:center;}
.checkbox--sm .checkbox-box{margin-top:0;}
/* Form sections sit on the page, a hairline between each. */
.fsection{padding:var(--s-32) 0;border-top:1px solid var(--line);}
.page-head + .fsection, .fsection--first{border-top:0;padding-top:0;}
.subsection{margin-top:var(--s-24);}
.fsection-title{font:var(--t-title);margin-bottom:var(--s-16);}
/* A drop area is a tonal place, no wire: white on the panel, the sunk tone inside a raised container
   so it still reads as a place. Hover and a file held over it step one tone darker. */
.dropzone {
  display: flex; flex-direction: column; gap: var(--s-4); padding: var(--s-20) var(--s-24) var(--s-24);
  border: 0; border-radius: var(--r-lg); background: var(--raised); cursor: pointer;
  transition: background-color var(--dur-1) var(--ease);
}
.dropzone.is-over{background:var(--sunk);}
.first-run-card .dropzone, .card .dropzone, .modal .dropzone, .auth-card .dropzone, .centered-chooser .dropzone{background:var(--sunk);}
.first-run-card .dropzone.is-over, .card .dropzone.is-over, .modal .dropzone.is-over, .auth-card .dropzone.is-over, .centered-chooser .dropzone.is-over{background:var(--ctl-hover);}
@media (hover: hover) and (pointer: fine) {
.dropzone:hover{background:var(--sunk);}
.first-run-card .dropzone:hover, .card .dropzone:hover, .modal .dropzone:hover, .auth-card .dropzone:hover, .centered-chooser .dropzone:hover{background:var(--ctl-hover);}
}
.drop-title{font:var(--t-strong);}
.drop-sub{font:var(--t-small);color:var(--ink-3);}
/* Founder change 1: photo is a dashed field beside Name/Website. Served photo replaces
   the mark/title; Replace stays the action. Edge-only hover preserves contrast; drag uses
   solid ink, disabled uses .btn:disabled; phone pill stacks. Product dragover clears
   .is-over (reported to seat); demo retains it. */
.brand-form .dropzone--photo {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--s-12) var(--s-16);
  padding: var(--s-16); border: 1.5px dashed var(--line-2); background: var(--field);
transition:border-color var(--dur-1) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
.brand-form .dropzone--photo:hover{background:var(--field);border-color:var(--ink-2);}
}
.brand-form .dropzone--photo.is-over{background:var(--field);border-style:solid;border-color:var(--ink);}
.brand-form .dropzone--photo[aria-disabled="true"]{opacity:.4;pointer-events:none;}
[data-brand-form][aria-busy="true"]{cursor:progress;}
.drop-icon{display:grid;place-items:center;width:48px;height:48px;border-radius:var(--r-pill);background:var(--raised);color:var(--ink-2);}
.dropzone--photo .thumb{width:48px;height:60px;}
.drop-text{display:flex;flex-direction:column;gap:var(--s-4);min-width:0;}
.drop-text [data-brand-photo-name] { color: var(--ink); overflow-wrap: anywhere; }
.drop-pill{
display:inline-flex;align-items:center;min-height:var(--ctl-dense);padding:0 var(--s-12);border-radius:var(--r-tab);
background:var(--raised);font:var(--t-action);white-space:nowrap;transition:transform var(--dur-press) var(--e-out);
}
.dropzone--photo:not([aria-disabled="true"]):active .drop-pill{transform:scale(var(--press-scale));}
.drop-text [data-brand-photo-name]:empty, .pill-chosen,
.dropzone--photo:has(img[data-brand-photo-preview][src]) :is(.drop-icon, .drop-title, .pill-empty) { display: none; }
.dropzone--photo:has(img[data-brand-photo-preview][src]) .pill-chosen{display:inline;}
@media (max-width:600px){
.brand-form .dropzone--photo{grid-template-columns:auto minmax(0, 1fr);}
.drop-pill{grid-column:2;justify-self:start;}
}
/* Product folders (M-038/M-039): the Library folder row, then the Library
   creative card at asset size, then their PRIMARY TEXT / HEADLINE / DESCRIPTION.
   A folder holds images, so it is a container: hairline, radius 12. */
.products{display:flex;flex-direction:column;gap:var(--s-12);margin-top:var(--s-16);}
.products:empty{display:none;}
.product { border: 0; border-radius: var(--r-lg); background: var(--raised); overflow: hidden; }
.product-head{display:flex;align-items:center;gap:var(--s-8);height:48px;padding:0 var(--s-16);width:100%;border:0;background:transparent;text-align:left;transition:background var(--dur-1) var(--ease);}
@media (hover: hover) and (pointer: fine) {
.product-head:hover{background:var(--hover);}
}
.product-head .i{color:var(--ink-3);}
.product-head .i-chev{transition:transform var(--dur-2) var(--ease);}
.product[data-open="true"] .product-head .i-chev{transform:rotate(90deg);}
.product-name{font:var(--t-strong);}
.product-meta{margin-left:auto;font:var(--t-small);color:var(--ink-3);}
.product-body{border-top:1px solid var(--line);padding:var(--s-20) var(--s-16) var(--s-16);display:none;flex-direction:column;gap:var(--s-20);}
.product[data-open="true"] .product-body{display:flex;}
/* The body's own gap spaces its grouped fields (DV2-N); a product with no images draws no empty strip. */
.product-body > .field { margin-top: 0; }
.assets{display:flex;gap:var(--s-12);flex-wrap:wrap;}
.assets:empty { display: none; }
.asset{position:relative;display:flex;flex-direction:column;gap:var(--s-8);width:108px;border:0;background:none;padding:0;text-align:left;transition:transform var(--dur-1) var(--ease);}
.asset-media{border-radius:var(--r-sm);overflow:hidden;background:var(--sunk);border:0;transition:box-shadow var(--dur-1) var(--ease);}
.asset-img{width:100%;height:96px;object-fit:cover;}
@media (hover: hover) and (pointer: fine) {
.asset:hover .asset-media{box-shadow: 0 0 0 1px var(--ink);}
}
/* The picked picture wears no ring (M-152, F-101): the Library's ink check sits on its top-left corner (the check's look
   is the .creative rule's, one rule for both). */
.asset:not(:disabled):active{transform:scale(var(--press-scale));}
.asset-name{font:var(--t-small);color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.variants{display:flex;flex-direction:column;gap:var(--s-16);}
.variant{display:flex;flex-direction:column;gap:var(--s-8);}
.variant + .variant{border-top:1px solid var(--line);padding-top:var(--s-16);}
.variant-head{display:flex;align-items:center;justify-content:space-between;}
.variant-head .label{color:var(--ink-2);}
.variant .field + .field{margin-top:0;}
.variant-src{font:var(--t-mono);color:var(--ink-3);}
.variant .textarea{min-height:54px;}
.add-variant{align-self:flex-start;}
/* Create layout */
.sticky-foot{
position:static;bottom:0;z-index:5;display:flex;align-items:center;gap:var(--s-8);flex-wrap:wrap;
padding:var(--s-16) 0 max(var(--s-24), env(safe-area-inset-bottom));border-top:1px solid var(--line);background:var(--page);
}
.foot-note{font:var(--t-small);color:var(--ink-3);flex-basis:100%;}
@media (min-width:1100px){.foot-note{flex-basis:auto;margin-left:var(--s-4);}}
.preview-sticky{display:flex;flex-direction:column;gap:var(--s-8);max-width:400px;}
.preview-head{display:flex;align-items:center;justify-content:space-between;height:var(--ctl-sm);}
.pager{display:inline-flex;align-items:center;gap:var(--s-4);}
.pager-count{font:var(--t-small);color:var(--ink-3);}
/* The exact ad count sits one gap from its label; the head's space-between would send it right. */
.section-count{margin-right:auto;font:var(--t-small);color:var(--ink-3);font-variant-numeric:tabular-nums;}
/* The feed preview is a container: it is someone else's surface drawn inside ours. It is the approval
   page's C post at Facebook's own desktop sizes: light in both themes, a 40px avatar, 15px text, the art
   whole on the matte up to 4:5 of the post's width, a white link bar and a grey square-cornered CTA. */
.feed { container-type: inline-size; background: var(--post); color: var(--post-ink); border: 0; border-radius: var(--r-post); box-shadow: 0 0 0 1px var(--card-edge), var(--post-lift); overflow: hidden; }
.feed-top{display:flex;align-items:center;gap:var(--s-8);padding:var(--s-12) var(--s-16) 0;}
.feed-avatar{flex:none;width:40px;height:40px;border-radius:var(--r-pill);background:var(--post-ink);display:grid;place-items:center;font:600 15px/1 var(--font-sans);color:var(--post);}
.feed-page{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;font:600 15px/20px var(--font-sans);}
.feed-page strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.feed-sponsored{font:400 13px/16px var(--font-sans);color:var(--post-grey);display:inline-flex;align-items:center;gap:var(--s-4);}
.feed-top > .i{color:var(--post-grey);}
.feed-text{margin:0;padding:var(--s-12) var(--s-16);font:400 15px/20px var(--font-sans);min-height:44px;white-space:pre-wrap;overflow-wrap:anywhere;}
.feed-media{position:relative;display:grid;place-items:center;background:var(--matte);overflow:hidden;}
/* Art taller than 4:5 is shown whole on the matte, never cut: the box stops at 4:5 of the post's width. */
.feed-img{display:block;width:100%;height:auto;max-height:125cqw;object-fit:contain;}
.feed-media:has(> .feed-empty:not([hidden])){aspect-ratio:4 / 5;}
.feed-empty{position:absolute;inset:0;display:grid;place-items:center;color:var(--post-grey);font:var(--t-small);}
.feed-foot{display:flex;align-items:center;gap:var(--s-12);padding:var(--s-12) var(--s-16);background:var(--post);}
.feed-foot-text{display:flex;flex-direction:column;gap:0;min-width:0;flex:1;}
.feed-domain{font:400 13px/16px var(--font-sans);color:var(--post-grey);text-transform:uppercase;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.feed-headline{font:600 17px/22px var(--font-sans);overflow-wrap:anywhere;}
.feed-desc{font:400 15px/20px var(--font-sans);color:var(--post-grey);overflow-wrap:anywhere;}
.feed-desc:empty{display:none;}
.feed-cta{flex:none;height:36px;padding:0 var(--s-16);display:inline-flex;align-items:center;border-radius:2px;background:var(--post-cta);border:0;font:600 15px/1 var(--font-sans);color:var(--post-ink);white-space:nowrap;}
/* an empty CTA slot (product mode, before the product writes one) draws no pill, as .chip:empty (DV2-H) */
.feed-cta:empty { display: none; }
.feed-actions{display:flex;justify-content:space-around;margin:0 var(--s-16);padding:var(--s-4) 0;min-height:44px;align-items:center;border-top:1px solid var(--post-line);font:600 15px/20px var(--font-sans);color:var(--post-grey);}
.feed-actions span{display:inline-flex;align-items:center;gap:var(--s-8);}
/* ---------- Library ---------- */
.toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--s-8);height:44px;padding:0 0 var(--s-16);}
.toolbar-left, .toolbar-right{display:flex;align-items:center;gap:var(--s-8);}
.search{position:relative;display:flex;align-items:center;height:var(--ctl-sm);border:1px solid var(--line-2);border-radius:var(--r-tab);background:var(--field);box-shadow:var(--sh-input);padding:0 var(--s-8) 0 var(--s-12);gap:var(--s-8);width:220px;transition:border-color var(--dur-1) var(--ease);}
@media (hover: hover) and (pointer: fine) {
.search:hover{border-color:var(--ink-2);}
}
.search:focus-within{outline:2px solid var(--focus-ring);outline-offset:2px;}
.search .i{color:var(--ink-3);}
.search-input{border:0;background:transparent;flex:1;min-width:0;font:var(--t-body);padding:0;}
.search-input:focus-visible{box-shadow:none;}
.search-input::-webkit-search-cancel-button{display:none;}
.kbd{font:600 10px/1 var(--font-sans);color:var(--ink-3);border:1px solid var(--line);border-radius:4px;padding:var(--s-4);background:var(--raised);}
/* Selecting swaps the toolbar for this bar, in place — it is not a popover. */
.selbar-count{font:var(--t-strong);padding:0 var(--s-4);}
.selbar-rule{width:1px;height:18px;background:var(--line);margin:0 var(--s-4);}
/* The canvas is a sunk fill with their dotted grid; no edge, it blends. */
.canvas{
position:relative;min-height:480px;padding:var(--s-24);border-radius:var(--r-lg);
background-color:var(--sunk);
background-image:radial-gradient(var(--dot) 1px, transparent 1.2px);
background-size:var(--grid) var(--grid);background-position:12px 12px;
}
.grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(var(--card-w), var(--card-w)));gap:var(--s-16);justify-content:start;}
/* A creative card is a container: raised, hairline, no shadow; hover darkens the
   hairline. Selection draws no ring (W7 Ink, the founder: "very elegant and borderless"): an ink check sits on the
   picture's top-left corner, the way photo pickers mark a pick, on a halo of the card's own ground so it reads on any picture. */
.creative{
width:var(--card-w);border-radius:var(--r-lg);background:var(--raised);border:1px solid var(--line);padding:var(--s-8);text-align:left;cursor:pointer;position:relative;
transition:box-shadow var(--dur-1) var(--ease), transform var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
.creative:hover{border-color:var(--line-2);}
}
.creative:not(:disabled):active{transform:scale(var(--press-scale));}
.creative[aria-pressed="true"] { box-shadow: none; }
.creative[aria-pressed="true"]::before, .creative[aria-pressed="true"]::after, .asset.is-current::before, .asset.is-current::after { content: ""; position: absolute; z-index: 1; pointer-events: none; }
.creative[aria-pressed="true"]::before, .asset.is-current::before { top: var(--s-16); left: var(--s-16); width: 24px; height: 24px; border-radius: var(--r-pill);
  background: var(--chosen); box-shadow: 0 0 0 2px var(--raised); }
/* The check is drawn in CSS only, because the vendor step refuses any fetched picture in served CSS (tests/css-no-fetch-ui.mjs): an L
   of two 2px borders, 6 by 11, turned 45 degrees. Turned, its ink sits about 2px below the box's middle, so the box sits
   1.5px above the circle's centre (28px, 28px from the card's corner), and the check's ink centres on the circle. */
.creative[aria-pressed="true"]::after, .asset.is-current::after { top: calc(var(--s-16) + 5px); left: calc(var(--s-16) + 9px); width: 6px; height: 11px;
  border: solid var(--on-chosen); border-width: 0 2px 2px 0; transform: rotate(45deg); }
/* a product's picture has no card padding round it: its check sits the same 8px in from the picture's corner */
.asset.is-current::before { top: var(--s-8); left: var(--s-8); }
.asset.is-current::after { top: calc(var(--s-8) + 5px); left: calc(var(--s-8) + 9px); }
.creative:focus-visible{box-shadow:var(--sh-focus);border-radius:var(--r-lg);}
.creative-media{border-radius:var(--r);overflow:hidden;background:var(--sunk);}
.creative-img{width:100%;height:216px;object-fit:cover;}
.creative-foot{display:flex;align-items:center;gap:var(--s-8);padding:var(--s-8) var(--s-4) 0;}
.creative-name{font:var(--t-small);color:var(--ink-2);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.canvas[data-density="list"] .grid{grid-template-columns:1fr;gap:var(--s-4);}
.canvas[data-density="list"] .creative{width:100%;display:grid;grid-template-columns:56px 1fr;gap:var(--s-12);align-items:center;padding:var(--s-8);}
.canvas[data-density="list"] .creative-img{height:56px;}
.canvas[data-density="list"] .creative-foot{padding:0;}
/* ---------- Tables: rows on the page, hairlines between, no box ---------- */
.table{width:100%;border-collapse:collapse;}
.table th{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);text-align:left;padding:0 var(--s-16) var(--s-8);border-bottom:1px solid var(--line);height:28px;}
.table th.th-num{text-align:right;}
.table td{padding:var(--s-8) var(--s-16);border-bottom:1px solid var(--line);vertical-align:middle;height:60px;}
.table th:first-child, .table td:first-child{padding-left:0;}
.table th:last-child, .table td:last-child{padding-right:0;}
.table tbody tr:last-child td{border-bottom:0;}
.table .td-actions{text-align:right;white-space:nowrap;}
.cell-label{display:none;}/* a column's caption inside its cell, shown only where the header row is hidden */
.table .td-actions .icon-btn, .table .td-actions .btn{vertical-align:middle;}
/* Row actions arrive on hover, as theirs do; keyboard focus reveals them too. */
.table .td-actions > *{opacity:0;transition:opacity var(--dur-1) var(--ease);}
.table .td-actions > *:focus-visible{opacity:1;}
/* Create paused is an approved row's next step, so it shows at rest, not only on hover (review P3-8). */
.table tr[data-status="approved"] .td-actions > [data-act="deliver"] { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
.table tbody tr:hover .td-actions > * { opacity: 1;}
}
.cell-main { display: flex; flex-direction: column; gap: var(--s-4); align-items: flex-start; }
/* M-137: a status icon whose word is for the screen reader sits beside the cell's words, on their centre, never above
   them like a label: "✓ 2 PAUSED in Meta". A chip that shows its word keeps the stacked label. */
.cell-main:has(> .chip[data-icon]:not([data-show-word])){flex-direction:row;align-items:center;gap:var(--s-8);}
.cell-main strong{font-weight:600;}
.cell-meta{font:var(--t-small);color:var(--ink-3);}
.cell-num{font:var(--t-mono);font-variant-numeric:tabular-nums;text-align:right;color:var(--ink-2);}
/* ---------- Results: the KPI strip, cells split by hairlines, no box ---------- */
.kpis{display:grid;grid-template-columns:repeat(6, 1fr);border-bottom:1px solid var(--line);}
.kpi{display:flex;flex-direction:column;gap:var(--s-8);padding:var(--s-4) var(--s-24) var(--s-24);border-left:1px solid var(--line);}
.kpi:first-child{border-left:0;padding-left:0;}
.kpi-value{font:var(--t-num);color:var(--ink-3);}
/* ---------- Brands ---------- */
.brand-new{max-width:640px;}
.brand-form{display:flex;flex-direction:column;}
/* The chosen photo (DV2-N) draws inside the photo target, only once the product writes a src. */
img[data-brand-photo-preview]:not([src]) { display: none; }
/* The product's two lines take room only when they say something. Empty, they keep the .sr-only box, not
   display none, so a polite or alert region exists before its words arrive and is announced. A result
   reads in ink, a refusal as one tinted line. */
.brand-form .help:empty{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
.brand-form .help:not(:empty){margin-top:var(--s-12);}
.brand-form [data-brand-form-status]:not(:empty) { color: var(--ink); overflow-wrap: anywhere; }
.brand-form [data-brand-form-error]:not(:empty) { padding: var(--s-8) var(--s-12); color: var(--bad); background: var(--bad-tint); border-radius: var(--r-sm); overflow-wrap: anywhere; }
.form-foot{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--s-8);margin-top:var(--s-24);}
/* ---------- Auth: the one centred card ---------- */
.view--auth{min-height:calc(100vh - var(--topbar) - var(--s-48));display:grid;place-items:center;padding:0;background:transparent;border:0;border-radius:0;}
.auth-card{width:100%;max-width:380px;border-radius:var(--r-panel);padding:var(--s-32) var(--s-24) var(--s-24);display:flex;flex-direction:column;gap:var(--s-8);text-align:center;align-items:center;}
.mark--auth{margin-bottom:var(--s-8);font-size:24px;line-height:28px;}
.auth-title{font:var(--t-display);letter-spacing:var(--track-display);}
.auth-form{width:100%;display:flex;flex-direction:column;gap:var(--s-16);margin-top:var(--s-16);text-align:left;}
/* One rhythm in the form: the flex gap alone spaces the fields (the generic .field + .field margin
   doubled it), and Continue sits a step further from the last field than the fields sit from each other. */
.auth-form .field + .field{margin-top:0;}
.auth-form [type="submit"]{margin-top:var(--s-8);}
/* Both sign-in fields lead with their icon in the same place. The passcode ends in a show/hide eye
   inside its edge; typed bullets get air, a shown code reads in even figures. */
.auth-form .input-wrap .input-icon{left:var(--s-16);}
.auth-form .input-wrap .input-icon + .input{padding-left:calc(var(--s-16) + var(--icon) + var(--s-12));}
.input-wrap--reveal .input{padding-right:calc(var(--ctl) + var(--s-8));}/* the eye's slot (its inset and button), a gap */
.input-reveal{position:absolute;right:var(--s-4);width:calc(var(--ctl) - var(--s-4));height:calc(var(--ctl) - var(--s-4));}
.input-reveal .i-hide, .input-reveal[aria-pressed="true"] .i-show{display:none;}
.input-reveal[aria-pressed="true"] .i-hide{display:block;}
.input--code{font-variant-numeric:tabular-nums;letter-spacing:.04em;}
.input--code[type="password"]:not(:placeholder-shown) { letter-spacing: .2em; }
:root[data-signed-out] .side-panel, :root[data-signed-out] .top{display:none;}
:root[data-signed-out] .app{display:block;}
/* Signed out there is no shell: the view is the whole viewport less one even gap round it, so the card sits at its
   centre, across and down (founder, 2026-10-03: "login is not in the middle"). The signed-in workspace's capped,
   left-aligned column and its deeper bottom padding (.views) put it 32 px left and 12 px high. dvh: a phone's
   browser bars never push it off centre (vh first, for a browser without dvh). */
:root[data-signed-out] .views{max-width:none;margin-inline:0;padding:var(--gap);}
:root[data-signed-out] .view--auth{min-height:calc(100vh - 2 * var(--gap));min-height:calc(100dvh - 2 * var(--gap));}
/* ---------- Lightbox ---------- */
.app.is-blurred{filter:blur(6px);pointer-events:none;user-select:none;}
.lightbox{position:fixed;inset:0;z-index:60;display:flex;flex-direction:column;background:var(--scrim-2);animation:fade var(--dur-2) var(--ease);}
.lb-top{display:flex;align-items:center;justify-content:space-between;gap:var(--s-12);height:var(--topbar);padding:0 var(--s-16) 0 var(--s-24);border-bottom:1px solid var(--line);background:var(--page);}
.lb-top-left, .lb-top-mid, .lb-top-right{display:flex;align-items:center;gap:var(--s-8);min-width:0;}
.lb-file{font:var(--t-strong);color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.lb-body{flex:1;display:grid;grid-template-columns:64px minmax(0, 1fr) 64px 320px;min-height:0;}
.lightbox.panel-closed .lb-body{grid-template-columns:64px minmax(0, 1fr) 64px;}
.lightbox.panel-closed .lb-panel{display:none;}
/* The arrows float over the scrim, so they carry the small float shadow. */
.lb-arrow{align-self:center;justify-self:center;width:36px;height:36px;border-radius:var(--r-pill);border:1px solid var(--line);background:var(--raised);color:var(--ink);box-shadow:var(--sh-float);display:grid;place-items:center;transition:transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease);}
@media (hover: hover) and (pointer: fine) {
.lb-arrow:hover{background:var(--sunk);}
}
.lb-arrow:not(:disabled):active{transform:scale(var(--press-scale));}
.lb-arrow:focus-visible{border-radius:var(--r-pill);}
.lb-stage{display:grid;place-items:center;padding:var(--s-24);min-height:0;}
.lb-img{max-height:calc(100vh - var(--topbar) - var(--s-48));width:auto;max-width:100%;border-radius:var(--r-lg);box-shadow:var(--sh-pop);animation:fade var(--dur-2) var(--ease);}
.lb-panel{display:flex;flex-direction:column;background:var(--page);border-left:1px solid var(--line);min-height:0;}
.lb-panel-head{display:flex;flex-direction:column;gap:var(--s-4);padding:var(--s-16) var(--s-16) var(--s-12);border-bottom:1px solid var(--line);}
.lb-panel-file{font:var(--t-small);color:var(--ink-3);}
.lb-comments{flex:1;overflow-y:auto;padding:var(--s-12) var(--s-16);display:flex;flex-direction:column;gap:var(--s-12);}
.lb-comments:empty{display:none;}
.lb-comment-empty{flex:1;}
.comment{display:flex;flex-direction:column;gap:var(--s-4);}
.comment-head{display:flex;align-items:baseline;gap:var(--s-8);font:var(--t-strong);}
.comment-head .row-time{margin-left:auto;}
.comment-body{font:var(--t-body);color:var(--ink-2);}
.comment[data-kind="verdict"] .comment-body{color:var(--ink);}
.lb-checks{border-top:1px solid var(--line);padding:var(--s-12) var(--s-16);}
.lb-panel-foot{display:flex;flex-direction:column;gap:var(--s-8);padding:var(--s-12) var(--s-16) var(--s-16);border-top:1px solid var(--line);}
.lb-panel-foot .textarea{min-height:64px;}
/* ---------- Modal: a floating container ---------- */
.scrim{position:fixed;inset:0;z-index:50;background:var(--scrim);animation:fade var(--dur-2) var(--ease);}
.modal {
  position: fixed; z-index: 55; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(520px, calc(100vw - 32px));
  background: var(--elevated); border: 0; border-radius: var(--r-layer); box-shadow: var(--sh-pop);
  animation: fade var(--dur-1) var(--ease);
}
/* The close ×: its 44px button sits 16px outside the drawn glyph, so the head's right padding is the body's less 16 and the
   drawn × ends where the body's content ends (W6-UI-2, the dialog rows check). */
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:var(--s-16) var(--s-8) var(--s-12) var(--s-24);}
.modal-title{font:var(--t-title);}
.modal-body{padding:var(--s-8) var(--s-24) var(--s-24);display:flex;flex-direction:column;gap:0;}
.modal-body .checkbox{margin-top:var(--s-16);}
.modal-foot{display:flex;align-items:center;justify-content:flex-end;gap:var(--s-8);padding:var(--s-16) var(--s-24);border-top:1px solid var(--line);flex-wrap:wrap;}
.modal-foot .foot-note{flex:1 1 0;min-width:160px;margin-left:0;}
/* ---------- DV2-E: functional hooks. Layout of the new containers from existing tokens;
   every element is one already on the page (ELEMENT-MAP.md §9). No new paint. ---------- */
.label-count{margin-left:var(--s-4);text-transform:none;letter-spacing:0;font:var(--t-small);color:var(--ink-3);}
.checks{margin-top:var(--s-16);}
.row .cell-main{min-width:0;max-width:100%;}
.row .creative-name{flex:none;max-width:100%;}
.mono.cell-meta, .mono.row-title{font-family:var(--font-mono);}
/* The CAS conflict notice: a list row between two hairlines, one sentence and the reload. */
.notice{display:flex;align-items:center;gap:var(--s-12);padding:var(--s-12) 0;margin-bottom:var(--s-24);border-top:1px solid var(--line);border-bottom:1px solid var(--line);}
/* An ad row: the asset tile's thumbnail, the file and its copy, then the per-ad controls. */
.row--ad, .row--deliver, .row--receipt{height:auto;min-height:40px;padding:var(--s-8) 0;}
.row--ad{display:grid;grid-template-columns:32px minmax(0, 1fr) 118px 118px minmax(0, 1fr) auto;gap:var(--s-8);}
/* A deliver row: the thumbnail, then the file over its labelled facts. Headline, Button and Placement
   share a line and wrap; the link takes its own line and truncates. The two columns hold on a phone. */
.row--deliver{display:grid;grid-template-columns:40px minmax(0, 1fr);align-items:center;gap:var(--s-12);padding:var(--s-12) 0;}/* M-137: the thumbnail sits on its facts' centre */
.row--deliver > .thumb{width:40px;height:50px;}
.row--deliver > .cell-main{display:flex;flex-direction:column;gap:var(--s-4);}
.ad-facts{display:flex;flex-wrap:wrap;gap:var(--s-4) var(--s-16);margin:0;}
.ad-facts > div{display:flex;align-items:baseline;gap:var(--s-8);min-width:0;max-width:100%;}
.ad-facts > div:has(> dd:empty){display:none;}
.ad-facts dt{flex:none;font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);}
.ad-facts dd{margin:0;min-width:0;font:var(--t-small);color:var(--ink-2);}
.ad-facts > div:first-child{flex:1 1 100%;}
.ad-facts > .ad-fact--link{flex:1 1 140px;}
.ad-fact--link dd{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Receipt identity can wrap; reserve the canonical status word's full width. */
.row--receipt{display:grid;grid-template-columns:minmax(0, 1fr) minmax(0, 1fr) max-content;}
.row--receipt > .cell-main, .row--receipt > [data-slot="meta_id"] { min-width: 0; overflow-wrap: anywhere; }
.row--receipt .creative-name{white-space:normal;}
@media (max-width:600px){
/* Keep the filename together above the full ID and status on narrow receipts. */
.row--receipt{grid-template-columns:minmax(0, 1fr) max-content;row-gap:var(--s-4);}
.row--receipt > .cell-main{grid-column:1 / -1;}
}
.thumb{width:32px;height:40px;object-fit:cover;border-radius:var(--r-thumb);background:var(--sunk);border:0;}
.input--sm{height:var(--ctl-sm);padding:var(--s-4) var(--s-12);border-radius:var(--r);}
.cell-url{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Every button row keeps one 8px gap across and down, so a wrapped row never has pills touching. */
.row-actions{display:inline-flex;flex-wrap:wrap;align-items:center;gap:var(--s-8);}
/* Row actions that depend on the row's own state: one key, read from the row. */
.table tr:not([data-status="approved"]) [data-act="deliver"] { display: none; }
.table tr[data-status="current"] [data-act="switch-brand"] { display: none; }
/* The deliver modal shows the parts of its current state and nothing else. */
/* A tall dialog keeps its title and its buttons in view: only the body scrolls between them. */
.modal--wide{width:min(560px, calc(100vw - 32px));max-height:calc(100dvh - 32px);display:flex;flex-direction:column;overflow:hidden;}
.modal--wide > .modal-head, .modal--wide > .modal-foot{flex:none;}
.modal--wide > .modal-body{flex:0 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;}
/* Add a brand (prod-brands-d, C5): the form's home is the dialog's scrolling body, and the form's own foot
   is the dialog's foot, held at the bottom while the body scrolls. Moved into the first run, the form
   leaves these rules behind, and its Cancel, which only closes the dialog, is hidden there. */
.modal--brand > .brand-new{flex:0 1 auto;min-height:0;max-width:none;overflow-y:auto;overscroll-behavior:contain;}
.modal--brand .brand-form{padding:var(--s-8) var(--s-24) 0;}
.modal--brand .brand-form > .form-foot{position:sticky;bottom:0;margin:var(--s-24) calc(-1 * var(--s-24)) 0;padding:var(--s-16) var(--s-24);border-top:1px solid var(--line);background:var(--elevated);}
[data-first-run-slot] [data-brand-cancel] { display: none; }
@media (max-width:600px){
.modal--brand .brand-form{padding:var(--s-16) var(--s-16) 0;}
.modal--brand .brand-form > .form-foot{margin:var(--s-16) calc(-1 * var(--s-16)) 0;padding:var(--s-16);}
.modal--brand .brand-form > .form-foot > .btn{flex:1;}
}
.modal[data-deliver-state="confirm"] [data-deliver-only="receipt"],
.modal[data-deliver-state="working"] [data-deliver-only="receipt"],
.modal[data-deliver-state="receipt"] [data-deliver-only="confirm"] { display: none; }
/* ---------- Toast: floats ----------
   An elevated surface, as the menus are (W6-UI-1): its done mark is a status icon, whose tones keep 3:1 on the
   theme's surfaces, not on an inverted ink fill. */
.toast{
position:fixed;left:50%;bottom:var(--s-24);z-index:70;transform:translateX(-50%);padding:var(--s-8) var(--s-12);display:inline-flex;align-items:center;gap:var(--s-8);
background:var(--elevated);color:var(--ink);border-radius:var(--r);font:var(--t-strong);box-shadow:0 0 0 1px var(--line), var(--sh-float);animation:fade var(--dur-2) var(--ease);
}
/* ---------- Scroll fade ----------
   A list that scrolls fades out at its bottom edge while more is below, and the fade lifts at the end so
   the last row reads whole (founder, handoff C). app.js marks the list data-more-below from its own
   scroll position in both modes; a list that does not overflow never carries it. */
:is(.ad-choices, .saved-batches [data-batches], .lb-comments, .feedview-stage, .modal--wide > .modal-body)[data-more-below]{
mask-image:var(--fade-mask);
}
/* ---------- Full-screen feed preview ----------
   The preview post at Facebook's desktop feed width or a phone's full width, on the lightbox scrim.
   The stage scrolls, so a tall post shows whole; the arrows step the same index as the pager. */
.create-preview [data-feed]{cursor:zoom-in;}
.feedview{position:fixed;inset:0;z-index:60;display:flex;flex-direction:column;background:var(--scrim-2);animation:fade var(--dur-2) var(--ease);}
.feedview-top{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s-8) var(--s-12);min-height:var(--topbar);padding:var(--s-8) var(--s-16) var(--s-8) var(--s-24);border-bottom:1px solid var(--line);background:var(--page);}
.feedview-title{margin:0;font:var(--t-strong);color:var(--ink);}
.feedview-right{display:flex;align-items:center;gap:var(--s-8);}
.feedview-body{flex:1;display:grid;grid-template-columns:64px minmax(0, 1fr) 64px;min-height:0;}
.feedview-stage{display:flex;flex-direction:column;align-items:center;overflow-y:auto;padding:var(--s-24) var(--s-16);min-height:0;}
.feedview-stage > .feed{flex:none;width:min(500px, 100%);cursor:auto;animation:fade var(--dur-2) var(--ease);}
.feedview-stage[data-size="phone"] > .feed{width:min(390px, 100%);border-radius:0;}
.feedview-note{margin:0;padding:var(--s-8) var(--s-16) var(--s-12);text-align:center;}
/* ---------- Motion ---------- */
@keyframes fade{from{opacity:0;}to{opacity:1;}}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .btn:active, .icon-btn:active, .seg-item:active, .creative:active, .asset:active, .lb-arrow:active, .mark:active, .pick-btn:active, .avatar:active, .ad-choice:active, .nav-item:active, .checkbox:active .checkbox-box { transform: none; }
  .table .td-actions > * { opacity: 1; }
  .app.is-blurred { filter: none; }
}
/* The left column consumes workspace width before the phone navigation breakpoint. */
@media (max-width:1200px){
.lb-body{grid-template-columns:48px minmax(0, 1fr) 48px 280px;}
}
@media (max-width:900px){
.top{gap:var(--s-8);padding-inline:var(--s-16);}
  .top .mark-word, .workspace, .font-pick, .top [data-act="bell"], .top [data-go="add"] { display: none; }
.top .mark .senditor-mark{width:24px;height:24px;}
.top-left{flex:1;}
.pick-btn{max-width:100%;}
.app, .app.is-collapsed{display:block;}
.top > .mark{position:static;flex:none;}
.workspace{display:none;}
.top-left > .menu-wrap{min-width:0;}
.pick-btn .brand-dot{display:none;}
.side-panel{z-index:60;visibility:hidden;width:min(280px, calc(100vw - 64px));}
.side, .app.is-collapsed .side{padding:var(--s-8) var(--s-12) var(--s-16);}
.side-top{display:flex;min-height:var(--ctl);justify-content:space-between;align-items:center;margin-bottom:var(--s-16);}
.side-top .mark{font-size:22px;}
.side-top .senditor-mark{width:24px;height:24px;}
.side-collapse, .icon-btn.side-expand, .app.is-collapsed .icon-btn.side-expand{display:inline-flex;}
.app.is-nav-open .side-panel{visibility:visible;}
.nav-backdrop{position:fixed;inset:0;z-index:50;background:var(--scrim);}
.nav-backdrop:not([hidden]){display:block;}
.views{padding:var(--gap);}
.view{padding:var(--s-16);}
.page-head{flex-direction:column;gap:var(--s-12);}
.two-col{grid-template-columns:minmax(0, 1fr);}
.field-row{grid-template-columns:minmax(0, 1fr);}
.fsection{padding:var(--s-24) 0;}
.input, .select, .textarea, .search-input{font:var(--t-field);}
.kpis{grid-template-columns:repeat(3, 1fr);}
.kpi{padding:var(--s-16) var(--s-16);}
.kpi:nth-child(3n+1){border-left:0;padding-left:0;}
.kpi:nth-child(n+4){border-top:1px solid var(--line);}
.toolbar{height:auto;flex-wrap:wrap;}
.toolbar-left{flex-wrap:wrap;}
.search{width:100%;}
.canvas{padding:var(--s-12);min-height:0;}
.grid{grid-template-columns:repeat(2, minmax(0, 1fr));gap:var(--s-8);}
.creative{width:auto;}
.creative-img{height:160px;}
.table thead{display:none;}
.table, .table tbody, .table tr, .table td{display:block;}
.table tr{padding:var(--s-12) 0;border-bottom:1px solid var(--line);display:grid;grid-template-columns:1fr auto;gap:var(--s-8) var(--s-12);}
.table tr:last-child{border-bottom:0;}
.table td{padding:0;border:0;height:auto;}
.table td:nth-child(1){grid-column:1;}
.table td:nth-child(2){grid-column:1;}
.table td.cell-num{text-align:left;font:var(--t-small);color:var(--ink-3);}
.table td.td-actions{grid-column:2;grid-row:1 / span 2;align-self:start;text-align:right;}
.table .td-actions > *{opacity:1;}
/* An approval on a narrow screen: the client and its controls on top, then Status, Ads, Sent and
     Expires side by side, each value under its own caption, since the table's header row is gone. */
  [data-approvals-table] tr { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); gap: var(--s-12); }
[data-approvals-table] td:nth-child(1){grid-column:1 / 3;grid-row:1;}
[data-approvals-table] td.td-actions{grid-column:3 / -1;grid-row:1;}
[data-approvals-table] td:nth-child(2){grid-column:1;grid-row:2;}
[data-approvals-table] td.cell-num{grid-row:2;font:var(--t-body);color:var(--ink);}
[data-approvals-table] .cell-label{display:block;margin-bottom:var(--s-4);font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);}
.modal-foot .foot-note{flex-basis:100%;}
.sticky-foot{padding-bottom:var(--s-16);}
.row--ad{grid-template-columns:32px minmax(0, 1fr);}
.row--ad > .select-wrap, .row--ad > .input, .row--ad > .checkbox{grid-column:2;}
.row--batch{flex-wrap:wrap;height:auto;padding:var(--s-8) 0;}
.auth-card{max-width:none;}
.lb-top{flex-wrap:wrap;height:auto;padding:var(--s-8) var(--s-12);gap:var(--s-8);}
.lb-top-mid{order:3;flex-basis:100%;}
.lb-top-left{flex:1;}
.lb-body{grid-template-columns:40px minmax(0, 1fr) 40px;grid-template-rows:auto auto;}
.lb-panel{grid-column:1 / -1;border-left:0;border-top:1px solid var(--line);max-height:40vh;}
.lb-stage{padding:var(--s-12);}
.lb-img{max-height:46vh;}
.lb-arrow{width:30px;height:30px;}
}
/* Guidance has no completion state. */
.workflow-guide{margin:0 0 var(--s-16);color:var(--ink-2);font:var(--t-body);}
/* Saved batches (M-057): full content width, the page scrolls (UI-HOME round 2, #87) */
.page-title [data-batches-total] { color: var(--ink-2); font: var(--t-body); letter-spacing: 0; margin-left: var(--s-8); }
.batches-tools{padding-bottom:var(--s-16);display:grid;gap:var(--s-12);}
.batches-tools > .field{max-width:400px;}
.batches-pager{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--s-8);}
.saved-batches [data-batches]{padding-block:var(--s-4);}
.batch-id{overflow-wrap:anywhere;}
.batch-label-field{margin-top:var(--s-24);}
[data-batch-label-error]:empty { display: none; }
[data-batch-label-error]{color:var(--bad);overflow-wrap:anywhere;}
/* Compact row: name, brand and ID on one wrapping line; updated and ad count under it. */
.row--batch { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--s-4) var(--s-16); height: auto; min-height: 72px; flex-shrink: 0;padding:var(--s-12);}
.row--batch .row-title{grid-column:1;grid-row:1;display:block;min-width:0;white-space:normal;overflow:visible;overflow-wrap:anywhere;}
.row--batch .batch-id{margin-left:var(--s-8);}
.row--batch > .cell-meta{grid-column:1;grid-row:2;}
.row--batch > .cell-num{grid-column:2;grid-row:2;text-align:left;font:var(--t-small);}
.row--batch > .chip{grid-column:2;grid-row:1;align-self:center;}
.row--batch > .row-actions{grid-column:3;grid-row:1 / span 2;align-self:center;}
.row--batch .row-title strong, .product-name, .creative-name{font:var(--t-row);}
.row--batch:focus-within{background:var(--selected);}
.row--batch .chip{justify-self:start;}
.section-head{min-height:var(--ctl);height:auto;gap:var(--s-8);flex-wrap:wrap;}
.field{min-width:0;}
.input, .select, .textarea{min-height:var(--ctl);}
.icon-btn, .seg-item, .menu-item, .link-btn, .checkbox, .radio, .product-head, .lb-arrow{min-height:var(--ctl);}
.icon-btn, .lb-arrow{min-width:var(--ctl);}
.btn{height:auto;min-height:var(--ctl-dense);padding-block:var(--s-4);}
.btn--lg{min-height:var(--ctl-lg);}
/* Press (Emil): scale .97 over 160ms on the C ease-out, enabled controls only. Keyboard activation is not
   animated (no focus transition); reduced motion sets the scale to 1 and the time to 0ms in tokens. */
.btn:not(:disabled), .icon-btn:not(:disabled), .pick-btn, .avatar, .seg-item, .nav-item, .ad-choice{transition:transform var(--dur-press) var(--e-out), background-color var(--dur-press) var(--e-out), color var(--dur-press) var(--e-out);}
.btn:not(:disabled):active, .icon-btn:not(:disabled):active, .pick-btn:not(:disabled):active, .avatar:not(:disabled):active, .ad-choice:active, .side .nav-item[href]:active{transform:scale(var(--press-scale));}
button:disabled:active{transform:none;}
.pick-btn:active, .avatar:active{background:var(--ctl-hover);}
.product { overflow: visible; }
.product-head{border-radius:var(--r);height:auto;padding-block:var(--s-12);flex-wrap:wrap;}
.product-meta{white-space:normal;}
.row, .notice, .modal-body, .modal-foot, .toast, .cell-meta, .foot-note{overflow-wrap:anywhere;min-width:0;}
.seg{border-radius:var(--r-layer);flex-wrap:wrap;height:auto;}
.grid{gap:var(--s-16);}
.canvas{background-image:none;}
@media (hover: hover) and (pointer: fine) {
.side .nav-item[href]:hover{color:var(--ink);background:var(--hover);}
.side .nav-item[aria-current="page"]:hover{color:var(--on-chosen);background:var(--chosen);}
.top .icon-btn:hover{color:var(--chrome-ink);background:var(--hover);}
.row--batch:hover{background:var(--selected);}
}
@media (max-width:900px){
.row--batch{grid-template-columns:minmax(0, 1fr) auto;padding:var(--s-12) 0;}
.row--batch > .cell-num{grid-column:1;grid-row:3;}
.row--batch > .chip{grid-column:1;grid-row:4;justify-self:start;}
.row--batch > .row-actions{grid-column:2;grid-row:1 / span 4;flex-direction:column;}
}
@media (max-width:600px){
.page-title{font-size:24px;line-height:30px;}
.grid{grid-template-columns:minmax(0, 1fr);}
.field-row, .row--ad{grid-template-columns:minmax(0, 1fr);}
.row--ad > *{grid-column:1 !important;}
.row-actions, .page-actions{flex-wrap:wrap;}
/* Contextual and approved-row actions need a full phone row to keep the status readable. */
.table tr:has([data-approval-next-action]:not([hidden])) td.td-actions,.table tr[data-status="approved"] td.td-actions{grid-column:1 / -1;grid-row:auto;text-align:left;}
.modal-head, .modal-body, .modal-foot{padding:var(--s-16);}
.modal-head{padding-right:0;}
.modal-foot .btn{flex:1;}
.notice{flex-wrap:wrap;}
.sticky-foot{position:static;}
.top .menu{min-width:min(264px, calc(100vw - 32px));}
.top-left .menu{left:0;right:auto;min-width:min(232px, calc(100vw - 112px));}
/* On a phone the post runs edge to edge, as in the Facebook app, and the arrows move under it. */
.feedview-top{padding-left:var(--s-16);}
.feedview-size{display:none;}
.feedview-body{grid-template-columns:1fr 1fr;grid-template-rows:minmax(0, 1fr) auto;}
.feedview-stage{grid-column:1 / -1;grid-row:1;padding:var(--s-12) 0;}
.feedview-stage > .feed, .feedview-stage[data-size="phone"] > .feed{width:100%;border-radius:0;}
.feedview-body > .lb-arrow{grid-row:2;width:44px;height:44px;margin:var(--s-8) var(--s-12) 0;}
.feedview-body > .lb-arrow:first-child{grid-column:1;justify-self:end;}
.feedview-body > .lb-arrow:last-child{grid-column:2;justify-self:start;}
}
@media (prefers-reduced-motion:reduce){
*, *::before, *::after{animation:none !important;transition:none !important;}
button:active, a:active{transform:none !important;}
}
/* Audit correction: keep recovery sentences and loose filenames fully readable. */
.notice .row-title, [data-row="unassigned-file"] .row-title { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
.side .is-soon{display:none;}/* Unsupported nodes retain their hooks; no speculative controls. */
@media (max-width:600px){
[data-row="unassigned-file"]{flex-direction:column;align-items:stretch;height:auto;gap:var(--s-8);padding-block:var(--s-8);}
.notice .row-title{flex-basis:100%;}
}
/* ---------- Axis shell (M-057) ---------- */
/* Topbar breadcrumb: brand picker, then the view title go() writes. */
.crumb-sep{color:var(--ink-3);}
.crumb{font:var(--t-strong);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.top-saved{padding:0 var(--s-8);white-space:nowrap;}
/* #90: no view hides a top bar control */
.nav-phone{display:none;}
@media (hover: hover) and (pointer: fine) {
.pick-btn:hover{background:var(--ctl-hover);}
}
/* Desktop rail: 44px icon targets, labels kept for assistive technology and the phone drawer. */
@media (min-width:901px){
.side, .app.is-collapsed .side{padding-inline:0;align-items:center;overflow-x:hidden;}
.top .mark-word{display:none;}
.side .nav-item{width:var(--ctl);height:var(--ctl);padding:0;justify-content:center;}
.side .nav-item > span:not(.nav-glyph){position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
/* The account button is one node in the header; on the rail it sits under the social trigger. */
.account{position:fixed;left:calc((var(--sidebar) - var(--ctl)) / 2);bottom:var(--s-12);}
.account .menu--right{top:auto;bottom:0;right:auto;left:calc(100% + var(--s-12));transform-origin:bottom left;}
}
@media (max-width:900px){
 .crumb-sep, .crumb, .top .top-saved { display: none; }
.nav-phone{display:block;}
.side, .app.is-collapsed .side{padding-bottom:var(--s-16);}
}
@media (hover: hover) and (pointer: fine) {
.side button.nav-item:hover{color:var(--ink);background:var(--hover);}
}
.side button.nav-item:active{background:var(--press);}
/* The rail's Social accounts trigger (UI-HOME, 2026-10-03; supersedes M-057's filled circle and M-053's mark under it, the
   founder: "make it differently … more elegant … it should remind us of social networks"). The sprite's line glyph,
   drawn like every rail icon, and the canon's --dot-size status dot on the glyph's top-right node, (12, 3.5) on its 16
   grid. One fact: the product-served data-meta-state on the dialog's hook node, read with :has(); the page never copies
   or infers it. Green (--icon-success) while connected; red (--icon-failure) when the sign-in expired or the read
   failed; no dot otherwise. No motion of its own. */
.nav-glyph{position:relative;display:grid;flex:none;}
.nav-dot{display:none;position:absolute;left:calc(var(--icon) * 12 / 16 - var(--dot-size) / 2);top:calc(var(--icon) * 3.5 / 16 - var(--dot-size) / 2);
width: var(--dot-size); height: var(--dot-size);border-radius:var(--r-pill);}
:root:has([data-overview-meta][data-meta-state="connected"]) .nav-dot { display: block; background: var(--icon-success); }
:root:has([data-overview-meta]:is([data-meta-state="expired"], [data-meta-state="error"])) .nav-dot{display:block;background:var(--icon-failure);}
/* UI-HOME, 2026-10-03: one network element across Overview, rail, dialog and first run.
   Mark on --chip tile, name and served state below; no check under the logo. Connectable
   Meta uses --meta; Coming soon is grey --line-2/--ink-2. The one served data-meta-state
   drives the dot: success connected, failure expired/error, hollow otherwise. List wraps. */
.net-list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-12) var(--s-32);min-width:0;margin:0;padding:0;list-style:none;}
.net{display:flex;align-items:center;gap:var(--s-16);min-width:0;}
.net-tile{display:grid;place-items:center;flex:none;width:var(--chip);height:var(--chip);border-radius:var(--r-sm);background:var(--raised);box-shadow:inset 0 0 0 1px var(--card-edge);color:var(--line-2);}
.net-tile > .i{width:var(--net-mark);height:var(--net-mark);}
.net-text{display:flex;flex-direction:column;align-items:flex-start;min-width:0;}
.net-name{font:var(--t-row);color:var(--ink);overflow-wrap:anywhere;}
.net--soon .net-name{color:var(--ink-2);}
.meta-word, .net-state{display:inline-flex;align-items:center;gap:var(--s-8);font:var(--t-small);color:var(--ink-2);white-space:nowrap;}
.meta-word::before, .net-state::before{content:"";flex:none;width:var(--dot-size);height:var(--dot-size);border-radius:var(--r-pill);box-shadow:inset 0 0 0 1.5px var(--icon-neutral);}
:root:has([data-overview-meta][data-meta-state="connected"]) .meta-word::before{background:var(--icon-success);box-shadow:none;}
:root:has([data-overview-meta]:is([data-meta-state="expired"], [data-meta-state="error"])) .meta-word::before{background:var(--icon-failure);box-shadow:none;}
.ready-row--nets > .net-list{flex:1;}
@media (max-width:600px){
.ready-row--nets > .net-list{flex-direction:column;align-items:flex-start;}
.ready-row--nets .net--soon{display:none;}/* a phone: Meta alone; the dialog lists the rest (round 3) */
}
/* UI-HOME rail peek: app.js owns aria-expanded and measured --peek-x/--peek-y.
   Desktop layer grows beside the trigger in --dur-2 (--e-out), leaves in --dur-1;
   networks stagger 30ms. Phone opens beneath the item with full touch targets.
   Meta alone is interactive: hover, --press-scale, focus ring. Reduced motion removes
   all transitions/animations. Founder reference: small, elegant, slight motion. */
.nav-social[aria-expanded="true"]{color:var(--ink);background:var(--hover);}
.nav-social:active{transform:scale(var(--press-scale));}
.net-peek .net{width:100%;padding:var(--s-8) var(--s-12) var(--s-8) var(--s-8);border-radius:var(--r);}
.net-peek button.net{border:0;background:transparent;color:inherit;text-align:left;cursor:pointer;
transition:transform var(--dur-press) var(--e-out), background-color var(--dur-1) var(--ease);}
.net-peek button.net:active{transform:scale(var(--press-scale));background:var(--press);}
@media (hover: hover) and (pointer: fine) {
.net-peek button.net:hover{background:var(--hover);}
}
@media (min-width:901px){
.net-peek{position:fixed;z-index:40;left:calc(var(--peek-x) + var(--s-12));top:var(--peek-y);padding:var(--s-4);
background:var(--elevated);border-radius:var(--r-layer);box-shadow:var(--sh-pop);color:var(--ink);
visibility:hidden;opacity:0;pointer-events:none;transform:translate(calc(var(--s-8) * -1), -50%) scale(.96);transform-origin:0 50%;
transition:opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--e-out), visibility 0s var(--dur-1);}
.nav-social[aria-expanded="true"] + .net-peek{visibility:visible;opacity:1;pointer-events:auto;transform:translate(0, -50%);
transition:opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--e-out), visibility 0s;}
.net-peek .net-list{flex-wrap:nowrap;gap:var(--s-4);}
.net-peek .net-list > li{opacity:0;transform:translateX(calc(var(--s-4) * -1));
transition-property:opacity, transform;transition-duration:var(--dur-1);transition-timing-function:var(--e-out);transition-delay:0s;}
.nav-social[aria-expanded="true"] + .net-peek .net-list > li{opacity:1;transform:none;transition-duration:var(--dur-2);}
.nav-social[aria-expanded="true"] + .net-peek .net-list > li:nth-child(2){transition-delay:calc(var(--dur-1) / 4);}
.nav-social[aria-expanded="true"] + .net-peek .net-list > li:nth-child(3){transition-delay:calc(var(--dur-1) / 2);}
}
@media (max-width:900px){
.net-peek{display:none;padding:0 0 var(--s-8) var(--s-32);}
.nav-social[aria-expanded="true"] + .net-peek{display:block;}
.net-peek .net-list{flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:var(--s-4);}
.net-peek .net{padding:var(--s-4) var(--s-8);}
.net-peek .net-list > li{animation:net-in var(--dur-2) var(--e-out) both;}
.net-peek .net-list > li:nth-child(2){animation-delay:calc(var(--dur-1) / 4);}
.net-peek .net-list > li:nth-child(3){animation-delay:calc(var(--dur-1) / 2);}
}
@keyframes net-in{from{opacity:0;transform:translateX(calc(var(--s-4) * -1));}}
/* Overview panes: an inset card inside the view panel. The demo sections stay direct children
   (the product cuts them there) and take the same card. */
.pane, [data-view="overview"] > .section, [data-view="overview"] > .two-col > .section { border: 0; border-radius: var(--r-lg); background: var(--raised); padding: var(--s-16); }
[data-view="overview"] > .section, [data-view="overview"] > .two-col{margin-top:var(--s-16);}
[data-view="overview"] > .two-col > .section{margin-top:0;}
.ready{padding-block:var(--s-4);}
.ready-row, .social-row{display:flex;align-items:center;gap:var(--s-12);padding:var(--s-12) 0;min-width:0;}
.ready-row + .ready-row, .social-row + .social-row{border-top:1px solid var(--line);}
.ready-text{display:flex;flex-direction:column;gap:var(--s-4);flex:1;min-width:0;overflow-wrap:anywhere;}
.ready-text strong{font:var(--t-row);}
.social-row--meta{padding:0;}/* the row holds the Meta card alone, and the card is its own padded ground (W6-UI-2, s1b) */
.social-row--meta .meta-card{flex:1;min-width:0;}
.modal--social .field-row{grid-template-columns:minmax(0, 1fr);}
:root[data-mode="product"] [data-demo-only] { display: none; }
@media (max-width:600px){
.ready-row{flex-wrap:wrap;}
.ready-row > .btn, .ready-row > .row-actions{flex-basis:100%;}
}
/* Getting started (M-075): glue only, incumbent tokens and components. The product shows the card
   and the rows and serves each row's state; only the served next row shows its one action. */
[data-getting-started] { padding-block: var(--s-12); }
.ready-row:not([hidden]) ~ [data-getting-started]{border-top:1px solid var(--line);}
.ready-row[hidden] + .ready-row{border-top:0;}
[data-getting-started] > * + *{margin-top:var(--s-12);}
[data-getting-started] .checklist{margin-bottom:0;}
.check:not([data-step-state="next"]) [data-act="start-step"] { display: none; }
.check > [data-act="start-step"]{margin-left:auto;flex:none;}
.check[data-step-state="next"]{height:auto;min-height:36px;padding-block:var(--s-4);}
.gs-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s-12);margin-block:calc(-1 * var(--s-8));}
.gs-head > .icon-btn{margin-right:calc(-1 * var(--s-8));}/* -8, not -12: the 2 px ring clears the card border */
[data-act="getting-started-toggle"] .i { transition: transform var(--dur-2) var(--ease); }
[data-act="getting-started-toggle"][aria-expanded="false"] .i{transform:rotate(-90deg);}
/* A runtime focus fallback heading (tabindex -1): the ring hugs the words, not the row. */
.page-title[tabindex="-1"]{width:fit-content;}
/* First run (first run v2; UI-HOME round 2: three steps, centred as Sign in, item 104): a state of Overview on the auth
   card's composition. As signed out there is no shell. The step bar: three pills, filled through the current step. */
:root[data-first-run-open] .side-panel, :root[data-first-run-open] .top{display:none;}
:root[data-first-run-open] .app{display:block;}
:root[data-first-run-open] .views{max-width:none;margin-inline:0;padding:var(--gap);}
:root[data-first-run-open] section[data-view="overview"]{display:grid;justify-items:center;align-content:center;min-height:calc(100vh - 2 * var(--gap));min-height:calc(100dvh - 2 * var(--gap));padding:0;background:transparent;border:0;border-radius:0;}
:root[data-first-run-open] section[data-view="overview"] > :not([data-first-run]) { display: none; }
.first-run{width:100%;max-width:560px;}
.first-run-card{display:flex;flex-direction:column;gap:var(--s-20);border-radius:var(--r-panel);}
.first-run-head{display:grid;grid-template-columns:minmax(0, 1fr) auto minmax(0, 1fr);align-items:center;margin-block:calc(-1 * var(--s-8));}
.first-run-head [data-first-run-act="back"] { grid-column: 1; justify-self: start; margin-left: calc(-1 * var(--s-12)); }
.mark--first-run{grid-column:2;font-size:22px;line-height:28px;}
.mark--first-run .senditor-mark{width:24px;height:24px;}
.first-run-head [data-first-run-act="skip"] { grid-column: 3; justify-self: end; margin-right: calc(-1 * var(--s-12)); }
.first-run-bar{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:var(--s-4);}
.first-run-bar > span { height: 4px; border-radius: var(--r-tab); background-color: var(--line); transition: background-color var(--dur-2) var(--ease);}
[data-first-run-step="meta"] .first-run-bar > span:nth-child(-n+1),
[data-first-run-step="brand"] .first-run-bar > span:nth-child(-n+2),
[data-first-run-step="ready"] .first-run-bar > span{background-color:var(--ink);}
.first-run-step{display:flex;flex-direction:column;animation: first-run-in var(--dur-2) var(--ease);}
@keyframes first-run-in { from { opacity: 0; transform: translateY(8px); } }
.first-run-title{font:var(--t-display);letter-spacing:var(--track-display);width:fit-content;margin-bottom:var(--s-4);}/* the 2+2 px focus ring clears the line below */
.first-run .page-sub{text-wrap:pretty;}/* a step's line never ends on one word */
.first-run-count{display:block;margin-bottom:var(--s-4);font:var(--t-small);letter-spacing:0;color:var(--ink-3);}
.first-run-slot, .first-run-step > .social-row--meta, .first-run-facts{margin-top:var(--s-24);}
.first-run-slot .form-foot{margin-top:var(--s-20);}
[data-first-run-slot="meta"] .field-row{grid-template-columns:minmax(0, 1fr);}
.first-run-facts > div{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-12);padding:var(--s-12) 0;border-bottom:1px solid var(--line);}
.first-run-facts:has(dd:not(:empty)){border-top:1px solid var(--line);}
.first-run-facts > div:has(> dd:empty){display:none;}
.first-run-facts dt{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);}
.first-run-facts dd{min-width:0;font:var(--t-row);text-align:right;overflow-wrap:anywhere;}
.first-run-foot{display:flex;justify-content:flex-end;gap:var(--s-8);margin-top:var(--s-24);}
/* The same caption-and-value rows in a dialog, tighter: 8px rows, the value in control weight. */
.facts{margin:0 0 var(--s-16);}
.facts > div{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-12);padding:var(--s-8) 0;border-bottom:1px solid var(--line);}
.facts:has(dd:not(:empty)){border-top:1px solid var(--line);}
.facts > div:has(> dd:empty){display:none;}
.facts dt{flex:none;font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);}
.facts dd{margin:0;min-width:0;font:var(--t-strong);text-align:right;overflow-wrap:anywhere;}
@media (max-width:900px){
:root[data-first-run-open] section[data-view="overview"]{align-content:start;padding-top:var(--s-16);min-height:0;}
.first-run{max-width:none;}
.first-run-card{padding:var(--s-16);}
}
@media (max-width:600px){
.first-run-foot > .btn, .first-run-slot .form-foot > .btn{flex:1;}
}
/* Polish pass (one bounded Impeccable gate): pill actions keep their own width inside a stacked
   field, helpers clear the row above them, and check rows wrap inside the 300px context panel. */
.field > .btn{align-self:flex-start;}
.field-row + .help{margin-top:var(--s-8);}
.row-actions + .row-actions{display:flex;margin-top:var(--s-8);}
/* Add ads v3 (V3-UI release): with the mount's switch on, today's add flow is never painted, not even before the v3
   stylesheet arrives, except on a visit that opens existing work (data-add-today, app.js). M-160 deletes it. */
.view[data-view="add"]:has(> [data-add-v3="on"]:not([data-add-today])) > :not([data-add-v3]) { display: none; }
/* Compact intake (2026-09-22): upload.ad supplies density; Axis owns identity.
   A bounded form on the LEFT and its preview on the RIGHT. No product state is derived here. */
.view--create .create{display:contents;}
.view--create .fsection{padding:var(--s-16) 0;}
.view--create .fsection-title{margin-bottom:var(--s-12);font:var(--t-row);}
.view--create .page-sub, .view--create .create-form > .fsection:first-child > .fsection-title,
.view--create .label-row > .label{display:none;}
.view--create .label-row{justify-content:flex-end;}
.view--create .dropzone > .i{color:var(--ink-2);}
.view--create .help:empty{display:none;}
.view--create [data-empty-state="add"] { display: none; } /* Main intake supplies the empty instruction. */
/* The main intake already offers Add folder. Preserve the hook without a duplicate empty CTA. */
.view--create [data-empty-state="add"] > [data-act="browse"] { display: none; }
.view--create [data-empty-state="ads"] { display: none; } /* Ads 0 and the intake already describe the state. */
.view--create [data-empty-state="ads"] .empty-line{display:none;}
.view--create .subsection{margin-top:var(--s-12);}
.view--create .product-body{gap:var(--s-12);padding:var(--s-12);}
.view--create .variant{gap:var(--s-8);padding:var(--s-12);}
.view--create .variant .copy-scope{margin:0;}
.view--create .assets{gap:var(--s-8);}
.view--create .asset{width:80px;}
.view--create .asset-media{height:80px;}
.view--create .asset-img{width:100%;height:100%;object-fit:contain;}
.view--create .row--ad{display:grid;grid-template-columns:48px minmax(0, 1fr) minmax(0, 1fr);gap:var(--s-8);padding:var(--s-12) 0;}
.view--create .foot-note{flex-basis:100%;margin:0;}
.intake-options, .delivery-options{margin-top:var(--s-12);padding:var(--s-8) 0;border-block:1px solid var(--line);}
.delivery-options{margin-top:0;border-bottom:0;}
.intake-options summary, .delivery-options summary{width:fit-content;min-height:var(--ctl);display:list-item;align-content:center;cursor:pointer;font:var(--t-strong);color:var(--ink-2);border-radius:var(--r-sm);}
.intake-options summary:focus-visible, .delivery-options summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;}
.intake-options summary:active, .delivery-options summary:active{color:var(--ink);}
.preview-placeholder{display:none;}
.view--create:not(:has([data-ads] [data-ad-id])) .feed,
.view--create:not(:has([data-ads] [data-ad-id])) .checks,
.view--create:not(:has([data-ads] [data-ad-id])) .preview-placeholder + .help{display:none;}
.view--create:not(:has([data-ads] [data-ad-id])) .preview-placeholder{display:block;padding-block:var(--s-16);}
.intake-options[open] > .field{margin-top:var(--s-12);}
.intake-options[open]{padding-bottom:var(--s-16);}
.view--create [data-intake-error]:not(:empty) { padding: var(--s-8) var(--s-12); color: var(--bad); background: var(--bad-tint); border-radius: var(--r-sm); overflow-wrap: anywhere; }
.view--create [data-intake-status]:not(:empty) { color: var(--ink); overflow-wrap: anywhere; }
.dropstage{display:none;position:fixed;inset:var(--s-16);z-index:45;background:var(--scrim-2);border:2px dashed var(--ink);border-radius:var(--r-panel);pointer-events:none;place-items:center;}
[data-view="add"][data-drop-active] > .dropstage{display:grid;}
.dropstage-in{display:flex;align-items:center;gap:var(--s-12);padding:var(--s-24);background:var(--page);color:var(--ink);border-radius:var(--r);font:var(--t-title);}
@media (hover: hover) and (pointer: fine) {.intake-options summary:hover, .delivery-options summary:hover{color:var(--ink);background:var(--hover);}}
@media (min-width:901px) and (pointer:fine){
 .view--create { --ctl: var(--intake-control); --ctl-sm: var(--intake-control); }
.view--create .btn{padding-block:var(--s-4);}
.view--create .input, .view--create .select{min-height:var(--intake-control);height:var(--intake-control);}
.view--create .textarea{height:auto;min-height:72px;}
.view--create .product-head{padding-block:var(--s-8);}
}
@media (max-width:600px){
.view--create .label-row{flex-wrap:wrap;gap:var(--s-8);}
.dropstage{inset:var(--s-8);}
}
/* Targets: inline links and the mark keep their look but take the 44px minimum. */
.link{display:inline-flex;align-items:center;min-height:var(--ctl);}
.top > .mark{min-width:var(--ctl);min-height:var(--ctl);justify-content:center;}
@media (min-width:901px){.top > .mark{left:calc((var(--sidebar) - var(--ctl)) / 2);top:calc((var(--topbar) - var(--ctl)) / 2);}}
/* W6-UI-2 (2B/r3-add, 2A strip): Ads left, sunk sticky preview centre, editor right.
   display:contents keeps hooks and identity ancestry intact; five editor items share
   one raised card. Tall panes span the flexible last row, never stretch editor rows.
   Selected B syncEditor() owns [data-editor-*] copy/ad selection marks. */
.view--create{display:grid;grid-template-columns:var(--add-list) minmax(0, 1fr) var(--add-form);grid-template-rows:repeat(8, auto) 1fr;gap:0 var(--s-16);align-items:start;padding:var(--s-20);border:0;border-radius:var(--r-panel);background:var(--page);}
.view--create > .page-head{grid-row:1;grid-column:1 / -1;margin:0;padding:0;}
.view--create > .workflow-guide{grid-row:2;grid-column:1 / -1;margin:0 0 var(--s-16);padding:0;color:var(--ink-2);}
.view--create > .notice{grid-row:3;grid-column:1 / -1;margin:0 0 var(--s-16);flex-wrap:wrap;}
.view--create .create-form, .view--create .centered-work-form{display:contents;}
/* The Ads pane */
.centered-chooser{grid-column:1;grid-row:4 / -1;align-self:start;min-width:0;display:flex;flex-direction:column;gap:var(--s-12);padding:var(--s-16);border-radius:var(--r-panel);background:var(--raised);box-shadow:inset 0 0 0 1px var(--line);}
.centered-chooser > .section-head{justify-content:flex-start;gap:var(--s-8);min-height:0;height:auto;margin:0;padding:0;border:0;}
.centered-chooser > .section-head > .label{font:var(--t-row);letter-spacing:0;text-transform:none;color:var(--ink);}
.centered-chooser > .section-head > .section-count:not(:empty){margin:0;padding:0 var(--s-8);border-radius:var(--r-tab);background:var(--sunk);color:var(--ink-2);}
.view--create .centered-intake{display:flex;flex-direction:column;gap:var(--s-8);margin:0;}
.view--create .centered-intake > .dropzone{order:-1;min-height:0;align-items:center;padding:var(--s-16) var(--s-12);gap:var(--s-4);text-align:center;}
.view--create .centered-intake > .label-row{justify-content:stretch;}
.view--create .centered-intake .row-actions{display:grid;grid-template-columns:repeat(auto-fit, minmax(128px, 1fr));gap:var(--s-8);width:100%;}/* side by side, stacked when a pane is narrower than two whole labels */
.view--create .centered-intake .row-actions > .btn{justify-content:center;min-width:0;padding-inline:var(--s-8);}
.ad-choices{display:flex;flex-direction:column;gap:var(--s-4);margin:0;padding:0;}
.ad-choice{display:flex;align-items:center;gap:var(--s-12);width:100%;min-height:76px;padding:var(--s-8);border:0;border-radius:var(--r);background:transparent;color:var(--ink);text-align:left;cursor:pointer;}
.ad-choice-pic{position:relative;flex:none;display:block;width:48px;height:60px;border-radius:var(--r-pic);background:var(--sunk);overflow:hidden;}
.ad-choice-pic > .thumb{display:block;width:100%;height:100%;object-fit:cover;border-radius:0;}
.ad-choice-n{position:absolute;left:var(--s-4);bottom:var(--s-4);display:grid;place-items:center;min-width:20px;height:20px;padding:0 var(--s-4);border-radius:var(--r-tab);background:var(--ink);color:var(--raised);font:var(--t-label);font-variant-numeric:tabular-nums;
/* picking: the badge turns violet with the row's fill, on the same press timing (F-101; reduced motion: none, as all) */
transition:background-color var(--dur-press) var(--e-out), color var(--dur-press) var(--e-out);}
.ad-choice-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--s-4);}
/* P2-8: a file name keeps whole lines, at most two, and breaks inside a word only when one word fills a line */
.ad-choice-name{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:break-word;font:var(--t-strong);}
.ad-choice-meta{display:flex;align-items:center;gap:var(--s-4);min-width:0;font:var(--t-small);color:var(--ink-2);}
.ad-choice-meta > .i{flex:none;color:var(--ink-3);}
.ad-choice-off{color:var(--ink-3);}
/* The chosen ad: a soft neutral fill and no ring (W7 Ink, 2026-10-02; the founder: "very elegant and borderless"). Its
   number badge takes the primary violet, which an ad under the pointer never wears: in dark the hover fill and this fill
   are about 1.01:1 apart, so the fill alone made a hovered ad look picked (F-101). */
.ad-choice[aria-pressed="true"] { background: var(--ctl-fill); box-shadow: none; }
.ad-choice[aria-pressed="true"] .ad-choice-n { background: var(--primary-top); color: var(--primary-text); }
.ad-choice:focus-visible, [data-manage-creatives]:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.ad-choice:active{background:var(--hover);}
@media (hover: hover) and (pointer: fine) {.ad-choice:hover{background:var(--hover);}.ad-choice[aria-pressed="true"]:hover{background:var(--ctl-fill);}}
.centered-chooser > [data-manage-creatives]{align-self:flex-start;}
.view--create .centered-chooser > .intake-options{margin:0;}
.view--create .centered-chooser .batch-label-field{margin:0;gap:var(--s-4);}
.view--create .centered-chooser [data-unassigned-section] { margin: 0; }
.view--create .centered-chooser [data-unassigned-section] .section-head{margin-bottom:0;}
.view--create .centered-chooser [data-unassigned-section] .select{width:100%;}
.centered-chooser [data-unassigned] .row{display:flex;flex-direction:column;align-items:stretch;height:auto;min-height:44px;padding:var(--s-8) 0;gap:var(--s-8);}
.centered-chooser [data-unassigned] .row-title{white-space:normal;overflow-wrap:anywhere;}
/* The folder sort: one row per dropped file, its box, its name and the served reason; an unsure row wears
   the waiting tint, so the operator's call is the one to look at. */
.intake-sort{display:flex;flex-direction:column;gap:var(--s-8);padding:var(--s-12);border-radius:var(--r);background:var(--sunk);}
.intake-sort[hidden]{display:none;}
.intake-sort-title{margin:0;font:var(--t-strong);color:var(--ink);}
.intake-sort > .help{margin:0;}
.intake-sort-refusal{padding:var(--s-8) var(--s-12);border-radius:var(--r-sm);background:var(--raised);color:var(--ink);}
.intake-sort-rows{display:flex;flex-direction:column;gap:var(--s-4);}
.sort-row{position:relative;display:flex;align-items:center;gap:var(--s-12);min-height:var(--ctl);padding:var(--s-8);border-radius:var(--r-sm);background:var(--raised);cursor:pointer;}
.sort-row > input{position:absolute;opacity:0;width:1px;height:1px;}
.sort-row > .checkbox-box{flex:none;}
.sort-row > input:checked + .checkbox-box{background:var(--chosen);border-color:var(--chosen-edge);}
.sort-row > input:checked + .checkbox-box .i{opacity:1;}
.sort-row > input:focus-visible + .checkbox-box{outline:2px solid var(--focus-ring);outline-offset:2px;box-shadow:var(--sh-focus);}
.sort-row:active > .checkbox-box{transform:scale(var(--press-scale));}
.sort-row[data-verdict="unsure"]{background:var(--wait-tint);}
.sort-text{flex:1;min-width:0;display:flex;flex-direction:column;}
.sort-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--t-strong);color:var(--ink);}
.sort-reason{font:var(--t-small);color:var(--ink-2);text-wrap:pretty;}
.intake-sort > [data-act="sort-add"] { align-self: stretch; }
@media (hover: hover) and (pointer: fine) {.sort-row:hover{background:var(--hover);}}
.ad-choices{scrollbar-width:thin;}
/* The post: big, centred on the sunk ground, staying in view while the editor scrolls past. */
.view--create .create-preview { grid-column: 2; grid-row: 4 / -1;align-self:start;position:sticky;top:calc(var(--topbar) + var(--s-16));min-width:0;width:auto;max-width:none;margin:0;padding:var(--s-8) var(--s-24) var(--s-24);border-radius:var(--r-panel);background:var(--sunk);}
.view--create .preview-sticky{max-width:none;}
.view--create .preview-sticky > :not(.preview-head){width:100%;max-width:var(--intake-preview);margin-inline:auto;}
/* The editor's card: five items, one surface. */
.view--create :is(.centered-editor, .create > .checks, .delivery-options, .client-note, .sticky-foot) { grid-column: 3;min-width:0;margin:0;padding-inline:var(--s-16);background:var(--raised);box-shadow:inset 1px 0 var(--line), inset -1px 0 var(--line);}
.centered-editor{grid-row:4;padding-top:var(--s-16);border-radius:var(--r-panel) var(--r-panel) 0 0;}
.view--create .centered-editor{box-shadow:inset 1px 0 var(--line), inset -1px 0 var(--line), inset 0 1px var(--line);}
.view--create > .create > .checks { grid-row: 5; padding-top: var(--s-16); }
.view--create .delivery-options{grid-row:6;padding-block:0;border-bottom:0;}
.view--create .client-note { grid-row: 7; padding-top: var(--s-12); }
.view--create .sticky-foot { grid-row: 8; padding-top:var(--s-16);padding-bottom:var(--s-16);border-top:0;border-radius:0 0 var(--r-panel) var(--r-panel);box-shadow:inset 1px 0 var(--line), inset -1px 0 var(--line), inset 0 -1px var(--line);}
.view--create .centered-editor .fsection-title{margin-bottom:var(--s-4);}
.view--create .centered-editor .products, .view--create .centered-editor .product, .view--create .centered-editor .product-body, .view--create .centered-editor .variants{margin:0;padding:0;border:0;background:transparent;}
.view--create:not([data-manage-open]):not(:has([data-products] [role="alert"]:not(:empty)))[data-editor-mapped] .product:not([data-editor-product]),
.view--create:not([data-manage-open]):not(:has([data-products] [role="alert"]:not(:empty)))[data-editor-mapped] .variant:not([data-editor-copy]),
.view--create:not([data-manage-open]):not(:has([data-products] [role="alert"]:not(:empty)))[data-editor-mapped] .product-head,
.view--create:not([data-manage-open]):not(:has([data-products] [role="alert"]:not(:empty)))[data-editor-mapped] .product-body > :not(.variants),
.view--create:not([data-manage-open]):not(:has([data-products] [role="alert"]:not(:empty)))[data-editor-mapped] .add-variant{display:none;}
.view--create:not([data-manage-open]) [data-editor-product] > .product-body{display:flex;}
.view--create .centered-editor .variant{gap:var(--s-8);border:0;padding:0;background:transparent;}
.view--create:not([data-manage-open]):not(:has([data-products] [role="alert"]:not(:empty)))[data-editor-mapped] .centered-editor .variant-head{display:none;}
.view--create .centered-editor .field{gap:var(--s-4);}
.view--create .centered-editor .textarea{field-sizing:content;min-height:96px;max-height:240px;}/* the whole primary text, up to ten lines */
.view--create .centered-editor .subsection{margin-top:var(--s-8);}
.view--create .centered-editor .row--ad{grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);padding:0;border:0;}
.view--create .centered-editor .row--ad:not([data-editor-ad]){display:none;}
.view--create .centered-editor .row--ad > .thumb, .view--create .centered-editor .row--ad > .cell-main{display:none;}
.view--create .centered-editor .row--ad > .select-wrap{grid-column:auto;}
.view--create .centered-editor .row--ad > [data-ad-url], .view--create .centered-editor .row--ad > .checkbox{grid-column:1 / -1;}
/* Wider than a phone, a copy field's name sits beside its answer, as the r3 editor reads. */
@media (min-width:901px){
.view--create .centered-editor .variant > .field{display:grid;grid-template-columns:96px minmax(0, 1fr);align-items:start;gap:var(--s-12);}
.view--create .centered-editor .variant > .field > .label{padding-top:var(--s-8);font:var(--t-small);letter-spacing:0;text-transform:none;color:var(--ink-2);}
}
/* Send leads the foot in the narrow pane: its own full row, the two quiet actions share the next. */
.view--create .sticky-foot{gap:var(--s-8);}
.view--create .sticky-foot > .foot-act:has(> [data-act="send-approval"]) { order: -2; flex: 1 0 100%; display: flex; flex-direction: column; gap: var(--s-4); }
.view--create .sticky-foot [data-act="send-approval"]{width:100%;justify-content:center;}
.view--create .sticky-foot > .foot-act:has(> [data-act="send-approval"]) > .foot-reason{order:1;}/* under Send at every width */
/* Three panes: the foot rides the window's bottom edge while the card scrolls under it (r3-add's pane foot), so Send is
   in view at every scroll; a hairline on top separates it from what passes under. */
@media (min-width:1241px){.view--create .sticky-foot{position:sticky;bottom:0;z-index:5;box-shadow:inset 1px 0 var(--line), inset -1px 0 var(--line), inset 0 -1px var(--line), 0 -1px 0 var(--line);}}
.view--create > .create > .checks .row--check{height:auto;min-height:44px;flex-wrap:wrap;padding:var(--s-8) 0;}
.view--create > .create > .checks .row-title{white-space:normal;overflow:visible;}
/* the check's name line (its name, its ad's name) on its own weight, the detail on its own quieter line under it, as
   r3's checks read; run on, "Best of 2024 3 supplied text fields" read as one phrase (the binder's review). The ad's
   name moves to a line of its own whole, never split, and starts on the name's edge. */
.view--create > .create > .checks .row-title{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:var(--s-8);}
.view--create > .create > .checks .check-ad-name{margin-left:0;}
.view--create > .create > .checks .row-title > [data-slot="detail"] { flex: 1 0 100%; font: var(--t-small); color: var(--ink-2); }
.view--create[data-manage-open] .product + .product{margin-top:var(--s-16);}
.view--create[data-manage-open] .product-body{padding:var(--s-8) 0;}
.view--create:has([data-products] [role="alert"]:not(:empty)) .product > .product-body{display:flex;}
@media (prefers-reduced-motion:reduce){.ad-choice{transition:none;animation:none;}}
/* Between a phone and a wide screen: the list and one column, the post above the editor's card. */
@media (max-width:1240px) and (min-width:901px){
.view--create{grid-template-columns:var(--add-list) minmax(0, 1fr);grid-template-rows:repeat(9, auto) 1fr;}
.view--create .create-preview{grid-column:2;grid-row:4;position:static;margin-bottom:var(--s-16);}
.view--create :is(.centered-editor, .create > .checks, .delivery-options, .client-note, .sticky-foot){grid-column:2;}
.centered-editor{grid-row:5;}
.view--create > .create > .checks{grid-row:6;}
.view--create .delivery-options{grid-row:7;}
.view--create .client-note{grid-row:8;}
.view--create .sticky-foot{grid-row:9;}
}
/* A phone: one column, the Ads pane, the post, then the editor's card; the ads are a strip that scrolls sideways
   (2A), each row the same card at a fixed width with the next one peeking in. */
@media (max-width:900px){
.view--create{display:flex;flex-direction:column;gap:0;padding:var(--s-16);}
.view--create > .workflow-guide, .view--create > .notice{margin-bottom:var(--s-16);}
.centered-chooser{order:1;width:100%;margin-bottom:var(--s-16);}
.view--create .create-preview{order:2;position:static;margin-bottom:var(--s-16);padding:var(--s-8) var(--s-16) var(--s-16);}
.centered-editor{order:3;width:100%;}
.view--create > .create > .checks{order:4;}
/* the card's parts share its width: the view's grid `align-items: start` let the empty Checks shrink to its words */
.view--create :is(.centered-editor, .create > .checks, .delivery-options, .client-note, .sticky-foot){align-self:stretch;}
.view--create .delivery-options{order:5;}
.view--create .client-note{order:6;}
.view--create .sticky-foot{order:7;}
.ad-choices{flex-direction:row;overflow-x:auto;scrollbar-width:none;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;margin-inline:calc(-1 * var(--s-16));padding:var(--s-4) var(--s-16);scroll-padding-inline:var(--s-16);}
.ad-choice{flex:none;width:min(232px, calc(100% - var(--s-48)));scroll-snap-align:start;box-shadow:inset 0 0 0 1px var(--line);}
.view--create .input, .view--create .select, .view--create .textarea{font:var(--t-field);min-height:44px;}
.view--create .textarea{min-height:120px;}
.view--create button, .view--create summary, .view--create .checkbox{min-height:44px;}
.view--create .centered-editor .row--ad > .select-wrap{grid-column:auto !important;}
 .view--create .sticky-foot :is([data-act="recheck"], [data-act="save-draft"]) { flex: 1 1 auto; justify-content: center; }
/* the link and the switch keep the full row against the phone's `.row--ad > * { grid-column: 1 !important }` */
.view--create .centered-editor .row--ad > [data-ad-url], .view--create .centered-editor .row--ad > .checkbox{grid-column:1 / -1 !important;}
}
/* Approval view (brief C, change 5): one link opened from its row. The row's client name is the
   one real control, so keyboard and screen readers get a named button; a pointer click anywhere on
   the row forwards to it. The view reuses the dialog, facts and chip parts; nothing here is new paint. */
.row-open{overflow-wrap:anywhere;max-width:100%;display:inline;padding:0;margin:0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;border-radius:var(--r-thumb);}
.row-open:active strong{color:var(--ink-2);}
[data-approvals-body] > tr { cursor: pointer; }
@media (hover: hover) and (pointer: fine) {
[data-approvals-body] > tr:hover .row-open strong{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;}
}
.approval-who{display:flex;flex-direction:column;gap:var(--s-8);margin-bottom:var(--s-16);}
.approval-person{display:grid;grid-template-columns:var(--chip) minmax(0, 1fr) auto;align-items:center;gap:var(--s-12);}
.approval-avatar { width: var(--chip); height: var(--chip);display:grid;place-items:center;border-radius:var(--r-pill);background:var(--ctl-fill);color:var(--ink);font:var(--t-strong);text-transform:uppercase;}
.approval-person .cell-main{min-width:0;}
.approval-person .cell-main strong{overflow-wrap:anywhere;}
.approval-verdict{display:flex;flex-direction:column;align-items:flex-end;gap:var(--s-4);text-align:right;}
.approval-ads{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill, minmax(96px, 1fr));gap:var(--s-12) var(--s-8);}
.approval-ads:empty{display:none;}
.approval-ad{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-8);min-width:0;}
.approval-ad .thumb{width:100%;height:auto;aspect-ratio:4 / 5;}
.approval-ad-name{font:var(--t-small);color:var(--ink-2);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere;}
/* Told before: the notice sits under the link it would replace, with both ways out side by side. */
.field + .edit-notice{margin-top:var(--s-16);}
.edit-notice{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s-12) var(--s-16);padding:var(--s-12) var(--s-16);border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--field);transition:opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);}
@starting-style{.edit-notice:not([hidden]){opacity:0;transform:translateY(-4px);}}
.edit-notice-text{flex:1 1 220px;display:flex;flex-direction:column;gap:var(--s-4);}
.edit-notice-actions{display:flex;flex-wrap:wrap;gap:var(--s-8);margin-left:auto;}
/* The editor says what Send does. */
.foot-note--editing:empty{display:none;}
.foot-note--editing{color:var(--ink);font-weight:600;}
@media (prefers-reduced-motion:reduce){.edit-notice{transition:none;}}
@media (max-width:600px){
.approval-person{grid-template-columns:var(--chip) minmax(0, 1fr);row-gap:var(--s-8);}
.approval-verdict{grid-column:2;flex-direction:row;flex-wrap:wrap;align-items:center;gap:var(--s-8);text-align:left;}
.approval-ads{grid-template-columns:repeat(auto-fill, minmax(84px, 1fr));}
.edit-notice-actions{flex:1 1 100%;}
.edit-notice-actions > .btn{flex:1;}
}
/* Brand cards (founder, 2026-09-25), option D (prod-brands-d, C5): a card per brand that selects it, with
   its served batch counts, its served empty line and its one next step. The name button is the card's
   select control; its ::after stretches over the card so the whole card takes the click, and focus rings
   the card. The next step sits above that stretch as its own control. The current brand is marked by its
   "Current" tag, with no ring (W7 Ink). The press is a third of the button's, so a large card barely moves. */
.brand-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(min(100%, 320px), 1fr));gap:var(--s-12);}
.brand-card{position:relative;display:flex;flex-direction:column;gap:var(--s-16);padding:var(--s-16);border-radius:var(--r-lg);background:var(--raised);transition:transform var(--dur-press) var(--ease);}
/* The picked brand card wears no ring (W7 Ink, 2026-10-02, "borderless"): its "Current" tag marks it. */
.brand-card:has(.brand-card-pick:focus-visible){outline:2px solid var(--focus-ring);outline-offset:2px;}
.brand-card:has(.brand-card-pick:active){transform:scale(calc(1 - (1 - var(--press-scale)) / 3));}
/* Reduced motion: the card does not move at all (the token gives scale(1); this says none, like the buttons). */
@media (prefers-reduced-motion:reduce){.brand-card:has(.brand-card-pick:active){transform:none;}}
.brand-card-head{display:flex;align-items:center;gap:var(--s-12);}
.brand-card-head > .cell-main{flex:1 1 auto;min-width:0;}
.brand-card-head > .chip{flex:none;}
/* The brand card's picture is the chip size; its look is the 5B picture square (.pic, at the end of this file). */
.brand-mark { flex: none; width: var(--chip); height: var(--chip);}
.brand-card-pick{padding:0;margin:0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;overflow-wrap:anywhere;}
.brand-card-pick::after{content:"";position:absolute;inset:0;border-radius:inherit;}
.brand-card-pick:focus-visible{outline:none;}
.brand-card-pick strong{font:var(--t-row);font-weight:600;}
/* M-116 brand-count: served state text (600/ink), ads_text (400/ink-2), one space;
   empty ads_text removes the space. Unknown states keep the hollow waiting ring.
   F-082: --dot-size owns size (--dot is canvas grain); inset shadow preserves 1.5px,
   unlike a border that snaps to 1px. */
.brand-counts{display:flex;flex-wrap:wrap;gap:var(--s-8) var(--s-16);margin:0;padding:0;list-style:none;}
.brand-counts:empty { display: none; }
.brand-counts > li { position: relative; min-width: 0; padding-left: calc(var(--dot-size) + var(--s-8)); font: var(--t-body); font-variant-numeric: tabular-nums; color: var(--ink); overflow-wrap: anywhere; }
.brand-counts [data-slot="text"] { font-weight: 600; color: var(--ink); }
.brand-counts [data-slot="ads_text"] { color: var(--ink-2); }
.brand-counts .dot { position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: var(--dot-size); height: var(--dot-size); border-radius: var(--r-pill); box-shadow: inset 0 0 0 1.5px var(--ink-2); }
.brand-counts > [data-state="approved"] .dot { background: var(--ok); box-shadow: none; }
.brand-counts > [data-state="changes"] .dot { background: var(--bad); box-shadow: none; }
/* A served count draws its status icon in the dot's place (M-140): the icon's size, none of the dot's ring or fill.
   A state the product does not serve keeps the hollow dot above. */
.brand-counts .dot[data-icon]{width:var(--st);height:var(--st);border-radius:0;background:none;box-shadow:none;}
.brand-counts .dot[data-icon] > .st{display:block;}
.brand-counts > li:has(> .dot[data-icon]){padding-left:calc(var(--st) + var(--s-8));}
.brand-card-empty{margin:0;font:var(--t-small);color:var(--ink-2);}
/* Brands' one pill starts level with the title's line box, as the reference sets it (y 84-127 at 1440); the
   shared 2px nudge set it 2px low (review R0-F6). Other pages keep the shared rule. */
.view[data-view="brands"] .page-actions { padding-top: 0; }
/* No brands: the empty plate carries the page's own opener (C5), set a step apart from the statement above it. */
[data-empty-state="brands-table"] > .btn { margin-top: var(--s-8); }
/* One Add brand on screen at a time (review F2): while the empty plate shows, its opener is the page's one
   action and the page head's twin steps aside; it returns when the first card replaces the plate. The
   plate's own hidden attribute is the one fact read, so nothing here can disagree with the list. */
.view[data-view="brands"]:has([data-empty-state="brands-table"]:not([hidden])) .page-actions [data-act="open-brand-modal"] { display: none; }
.brand-card-empty:empty { display: none; }
/* The next step: a full-width tonal pill at the foot of the card, above the card's stretched select. */
.brand-next{position:relative;z-index:1;width:100%;justify-content:space-between;gap:var(--s-8);margin-top:auto;text-align:left;white-space:normal;}
/* The step names an operator's batch, so it can run long: it wraps with the small copy's 18px leading (the
   label's own is 1, and two lines would touch). One line still sits inside the control height. */
.brand-next > [data-slot="next_text"] { min-width: 0; line-height: 18px; overflow-wrap: anywhere; }
/* The chevron is part of the step's label, so it takes the label's ink, not a button icon's grey (review R0-F3). */
.brand-next .i{color:var(--act-ink);}
/* One owner hides the next step: the product serves an empty act when there is nothing to do. */
[data-act="brand-next"][data-next-act=""] { display: none; }
@media (hover: hover) and (pointer: fine) {
 .brand-card:hover:not(:has(.brand-card-pick[aria-current="true"])):not(:has(.brand-next:hover)) { background: var(--hover); } /* W7 Ink: a soft fill, no ring */
.brand-card:hover:not(:has(.brand-next:hover)) .brand-card-pick strong{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;}
}
/* M-112 · The operator's note to the client, above Send for approval. The count is visual only; the
   live region speaks only near the limit. The link dialog shows the note the link was sent with. */
.view--create .client-note .label-row{justify-content:space-between;align-items:baseline;}
.view--create .client-note .label-row > .label{display:block;}/* the create view hides row labels; this one names the field */
.client-note .textarea{min-height:72px;max-height:240px;field-sizing:content;}/* grows with the note, then scrolls */
.client-note-count{flex:none;font:var(--t-small);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.client-note-count[data-full]{color:var(--ink);}
.modal-note-field:has(> .modal-note:empty) { display: none; }
.modal-note{margin:0;max-height:132px;overflow-y:auto;padding:var(--s-8) var(--s-12);border-radius:var(--r);background:var(--ctl-fill);font:var(--t-body);color:var(--ink);white-space:pre-line;overflow-wrap:anywhere;}
@media (max-width:900px){
.view--create .client-note, .view--create .delivery-options{align-self:stretch;}/* full column, like Send below it */
.view--create .client-note .textarea{min-height:96px;}
}
/* ---------- Wave 5: Add brand tabs, From Meta, Upgrade, Finish setup, link text (prod-w5a-ui) ----------
   Style C tokens only (M-107). The tab track is the segmented control's (.seg): the field track, the ink
   pill for the selected tab, the same height, radius and press. */
.brand-tabs{display:flex;gap:0;padding:var(--s-4);margin:0 var(--s-24) var(--s-8);align-self:flex-start;background:var(--field);border-radius:var(--r-tab);}
.brand-tab { position: relative;height:calc(var(--ctl) - 2 * var(--s-4));padding:0 var(--s-16);border:0;border-radius:var(--r-tab);background:transparent;color:var(--ink-2);font:var(--t-strong);cursor:pointer;transition:background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);}
/* The pill stays 36px inside the 4px track; the pointer gets the track's 4px above and below: 44px. */
.brand-tab::after { content: ""; position: absolute; inset: calc(-1 * var(--s-4)) 0; }
@media (hover: hover) and (pointer: fine) {
.brand-tab:hover{color:var(--ink);}
}
.brand-tab[aria-selected="true"]{background:var(--chosen);color:var(--on-chosen);box-shadow:inset 0 0 0 1.5px var(--chosen-edge);}
.brand-tab:active { transform: scale(var(--press-scale)); }
.brand-tab:focus-visible {outline-offset:3px;border-radius:var(--r-tab);}
.modal--brand:has([data-from-meta-state="result"]) .brand-tabs,
.modal--brand:has([data-from-meta-state="adding"]) .brand-tab[aria-selected="false"]{display:none;}
/* From Meta: the panel is the dialog's scrolling body, its own foot the dialog's foot (as By hand's form). */
.from-meta{display:flex;flex-direction:column;min-height:0;flex:1 1 auto;}
.from-meta[hidden]{display:none;}
.from-meta-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--s-8) var(--s-24) var(--s-24);}
.from-meta-body > *{display:none;}
.from-meta[data-from-meta-state="connect"] .fm-connect,
.from-meta[data-from-meta-state="refused"][data-from-meta-reason="not_connected"] .fm-connect,
.from-meta[data-from-meta-state="loading"] .fm-loading,
.from-meta[data-from-meta-state="list"] .fm-list,
.from-meta[data-from-meta-state="adding"] .fm-list,
.from-meta[data-from-meta-state="empty"] .fm-empty,
.from-meta[data-from-meta-state="result"] .fm-outcome,
.from-meta[data-from-meta-state="unknown"] .fm-error,
.from-meta[data-from-meta-state="refused"] .fm-error{display:block;}
.from-meta[data-from-meta-state="empty"] .fm-reload,
.from-meta[data-from-meta-state="unknown"] .fm-reload,
.from-meta[data-from-meta-state="refused"]:not([data-from-meta-reason="not_connected"]) .fm-reload{display:inline-flex;}
.from-meta[data-from-meta-state="refused"] .fm-error{margin-bottom:var(--s-16);}
.fm-connect{text-align:center;padding:var(--s-32) 0 var(--s-16);}
.from-meta .fm-connect{display:none;}
.from-meta[data-from-meta-state="connect"] .fm-connect,
.from-meta[data-from-meta-state="refused"][data-from-meta-reason="not_connected"] .fm-connect{display:flex;flex-direction:column;align-items:center;gap:var(--s-16);}
.fm-lead{font:var(--t-body);color:var(--ink);margin:0;}
.fm-loading{font:var(--t-body);color:var(--ink-2);padding:var(--s-16) 0;}
.fm-intro{font:var(--t-body);color:var(--ink-2);margin:0 0 var(--s-16);}
.fm-group + .fm-group{margin-top:var(--s-24);}
.fm-group-head{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--s-8);border-bottom:1px solid var(--line);}
.fm-count{margin-left:var(--s-4);color:var(--ink-3);}
.fm-group-head .link-btn{display:none;}
.fm-list:has([data-from-meta-tick]:checked) .fm-group-head [data-from-meta-clear] { display: inline-flex; align-items: center; }
.fm-note{margin:var(--s-8) 0 0;}
.fm-group:not(:has(.fm-row)){display:none;}
.fm-row{display:grid;grid-template-columns:1fr auto;align-items:center;column-gap:var(--s-16);padding:var(--s-12) 0;border-bottom:1px solid var(--line);}
.fm-limit{font:var(--t-small);color:var(--ink-3);}
.fm-limit:empty{display:none;}
.fm-row[data-limit="true"] .fm-pick{opacity:.4;pointer-events:none;}
.fm-detail{display:none;grid-column:1 / -1;grid-template-columns:1fr 1fr;gap:var(--s-16);margin:var(--s-12) 0 0 calc(var(--box) + var(--s-12));}/* under the words: the box and its gap */
.fm-row:has([data-from-meta-tick]:checked) .fm-detail{display:grid;}
.fm-detail .field + .field{margin-top:0;}
.fm-name-error{color:var(--bad);}
.fm-name-error:empty, .fm-detail .help:empty{display:none;}
.fm-row:has(.fm-name-error:not(:empty)) [data-from-meta-name] { border-color: var(--bad); }
.fm-empty .help{margin:var(--s-8) 0 var(--s-16);}
.fm-error{font:var(--t-body);color:var(--ink);margin:0 0 var(--s-16);}
.fm-error:empty{display:none !important;}
.fm-heading{font:var(--t-title);color:var(--ink);margin:0;}
.fm-result-sub{margin:var(--s-4) 0 0;}
.fm-result-sub:empty{display:none;}
.fm-results{margin-top:var(--s-16);border-top:1px solid var(--line);}
.fm-result{padding:var(--s-12) 0;border-bottom:1px solid var(--line);}
.fm-result-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s-12);}
.fm-reason, .fm-next{margin:var(--s-4) 0 0;}
.fm-next{font:var(--t-strong);color:var(--ink);}
.fm-reason:empty, .fm-next:empty{display:none;}
/* The actions line shows only when it holds a shown control: Rename, or Upgrade on an over-limit row. */
.fm-result-actions{display:none;align-items:center;gap:var(--s-12);margin-top:var(--s-8);}
.fm-result:has(.fm-rename[data-rename="true"]) .fm-result-actions,
:root[data-brand-limit="upgrade"] .fm-result[data-reason="over_limit"] .fm-result-actions{display:flex;}
.fm-rename{display:none;}
.fm-rename[data-rename="true"]{display:inline-flex;}
/* The foot: the words, Cancel and Add in the list; Done alone on a result; Cancel alone elsewhere. */
.from-meta-foot [data-from-meta-done], .from-meta-foot [data-from-meta-add] { display: none; }
.from-meta[data-from-meta-state="list"] [data-from-meta-add],
.from-meta[data-from-meta-state="adding"] [data-from-meta-add]{display:inline-flex;}
.from-meta[data-from-meta-state="result"] [data-from-meta-done]{display:inline-flex;}
.from-meta[data-from-meta-state="result"] [data-from-meta-cancel] { display: none; }
.from-meta-foot .foot-note:empty{visibility:hidden;}
/* Upgrade entry points (C11.2): hidden unless the binder writes data-brand-limit="upgrade" on <html>. */
.upgrade-link { display: none;}
:root[data-brand-limit="upgrade"] .from-meta[data-from-meta-state="list"] .from-meta-foot .upgrade-link,
:root[data-brand-limit="upgrade"] .fm-result[data-reason="over_limit"] .upgrade-link{display:inline-flex;}
/* Upgrade (C11.2): the mail link stays dim and inert until the binder writes its address. The dialog's look is the
   W6-UI-2 3B block at the end of this file. */
a.btn[data-upgrade-mailto]:not([href]) { opacity: .4; pointer-events: none; }
/* Finish setup (C11.3): one step at a time; the page shows the step the form's data-step names. */
.modal--finish .finish-form{display:flex;flex-direction:column;min-height:0;flex:1 1 auto;}
.finish-body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--s-8) var(--s-24) var(--s-24);}
.finish-count{font:var(--t-label);text-transform:uppercase;color:var(--ink-3);margin:0 0 var(--s-12);}
.finish-step{border:0;margin:0;padding:0;min-width:0;}
.finish-legend{font:var(--t-strong);color:var(--ink);padding:0;margin-bottom:var(--s-16);}
.finish-choice, .finish-numbers{border:0;margin:0;padding:0;min-width:0;}
.finish-choice legend, .finish-numbers legend{padding:0;margin-bottom:var(--s-8);}
.finish-radios{display:flex;gap:var(--s-24);}
.finish-number{display:flex;align-items:center;gap:var(--s-16);margin-top:var(--s-8);}
.finish-number-name{min-width:88px;font:var(--t-strong);}
.field-reason{color:var(--bad);}
.field-reason:empty, [data-finish-status]:empty, [data-finish-error]:empty, [data-finish-numbers-tokens]:empty { display: none; }
[data-finish-error]{color:var(--bad);}
.finish-foot [data-finish-save] { display: none; }
.finish-form[data-step="5"] [data-finish-save]{display:inline-flex;}
.finish-form[data-step="5"] [data-finish-next] { display: none; }
.finish-form[data-step="1"] [data-finish-back] { visibility: hidden; }
.finish-form[data-finish-state="working"] .finish-foot .btn{opacity:.4;pointer-events:none;}
/* The one radio (a round checkbox): the same box, focus and press as .checkbox. */
.radio{position:relative;display:inline-flex;align-items:center;gap:var(--s-8);cursor:pointer;user-select:none;font:var(--t-body);}
.radio input{position:absolute;opacity:0;width:1px;height:1px;}
.radio-dot { flex: none; width: 18px; height: 18px; border-radius: var(--r-tab);border:1px solid var(--line-2);background:var(--field);display:inline-grid;place-items:center;transition:background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);}
.radio-dot::after { content: ""; width: 8px; height: 8px; border-radius: var(--r-tab);background:var(--on-chosen);opacity:0;transition:opacity var(--dur-1) var(--ease);}
.radio input:checked + .radio-dot{background:var(--chosen);border-color:var(--chosen-edge);}
.radio input:checked + .radio-dot::after{opacity:1;}
@media (hover: hover) and (pointer: fine) {
.radio:hover .radio-dot{border-color:var(--ink-2);}
}
.radio:active .radio-dot { transform: scale(var(--press-scale)); }
.radio input:focus-visible + .radio-dot {outline:2px solid var(--focus-ring);outline-offset:2px;box-shadow:var(--sh-focus);}
/* Finish setup on an incomplete card (C11.3): page-owned, keyed on data-complete="false" only. */
.brand-finish { display: none;}
.brand-card[data-complete="false"] .brand-finish { display: inline-flex;position:relative;z-index:1;align-self:flex-start;}/* above the card's stretched pick */
/* Brands left (C12, D4): served words; an empty slot draws nothing. */
.brands-left:empty { display: none; }
/* The approval link as text (C11.4, C12): the whole URL, wrapping, selectable in one go. */
.link-line{display:flex;align-items:flex-start;gap:var(--s-8);}
/* The whole link shows, wrapped (C12), and the field is the Copy button's height (W6-UI-2, the dialog rows check): two
   lines of the small size fit the 44px row, and one line sits on its centre. */
.link-text{flex:1 1 auto;min-width:0;margin:0;min-height:var(--ctl-dense);display:flex;align-items:center;padding:var(--s-4) var(--s-12);border-radius:var(--r);background:var(--field);font:var(--t-small);color:var(--ink);overflow-wrap:anywhere;user-select:all;}
.link-text:empty{display:none;}
.link-line .btn{flex:none;}
.approval-resend:empty{display:none;}
/* Copied (C12): the binder sets data-approval-copy-state="copied" for two seconds. The check fades in. */
[data-approval-copy] .i-copied{display:none;}
[data-approval-copy][data-approval-copy-state="copied"] .i-copied{display:block;animation:copied-in var(--dur-2) var(--ease);}
[data-approval-copy][data-approval-copy-state="copied"] .i-copy-idle{display:none;}
@keyframes copied-in{from{opacity:0;transform:scale(.8);}to{opacity:1;transform:none;}}
@media (max-width:600px){
.brand-tabs{margin-left:var(--s-16);margin-right:var(--s-16);}
.from-meta-body, .finish-body{padding-left:var(--s-16);padding-right:var(--s-16);}
.fm-detail{grid-template-columns:minmax(0, 1fr);margin-left:0;}
.from-meta-foot, .finish-foot{flex-wrap:wrap;}
.from-meta-foot .foot-note{flex:1 0 100%;}
.from-meta-foot .btn, .finish-foot .btn{flex:1 1 0;}
.finish-form[data-step="1"] [data-finish-back]{display:none;}
.link-line{flex-wrap:wrap;}
.link-line .link-text, .link-line .btn{flex:1 1 100%;}
}
@media (prefers-reduced-motion: reduce) {
  /* Reduced motion: the check swaps in at once, no scale and no fade; the page-wide rule above removes every animation. */
  [data-approval-copy][data-approval-copy-state="copied"] .i-copied { animation: none; }
  .brand-tab, .radio-dot { transition: none; }
  .brand-tab:active, .radio:active .radio-dot { transform: none; }
}

/* ---------- Wave 5b: the link dialog and the richer pass (prod-w5b-ui) ----------
   PLAN-prod-wave5-2026-09-29 C11.4/C12/§2.3; M-107/R9: Style C tokens,
   no new colours or --meta/--label-* / --mark-* on chips/icons.
   W7a owns data-approval-link-state: busy/ready draw URL; none/creating/stale use
   prose selection and ink-2. Error offers Try again; local lifts the reach sentence. */
.link-line[data-approval-link-state="none"] .link-text,
.link-line[data-approval-link-state="creating"] .link-text,
.link-line[data-approval-link-state="stale"] .link-text { color: var(--ink-2); user-select: text; }
[data-approval-copy] .i-retry { display: none; }
.link-line[data-approval-link-state="error"] [data-approval-copy] .i-retry { display: block; }
.link-line[data-approval-link-state="error"] [data-approval-copy] .i-copy-idle { display: none; }
[data-approval-copy][data-approval-copy-state="copied"] .i-copied { color: var(--ok);}
/* The reach sentence and the resend words, each beside one mark; an empty slot draws neither. */
.link-notice{display:flex;align-items:flex-start;gap:var(--s-8);color:var(--ink-3);font:var(--t-small);}
.link-notice > .i{margin-top:calc((1lh - var(--icon)) / 2);}/* the mark on the first line's centre */
.link-notice > p{margin:0;min-width:0;}
.link-notice:has(> p:empty) { display: none; }
.field + .link-notice, .link-notice + .link-notice{margin-top:var(--s-12);}
.modal:has(.link-line[data-approval-link-state="local"]) .link-notice:has(> .approval-reach), .modal:has(.link-line[data-approval-link-state="local"]) .link-notice > .approval-reach{color:var(--ink);}
/* Tinted icon chips (§2.3): a 40px ctl-fill circle holding one sprite mark in ink-2. Empty states wear one above
   their sentence; the brand mark and the approval avatar are the same size (--chip). */
.icon-chip { width: var(--chip); height: var(--chip); flex: none; display: grid; place-items: center; border-radius: var(--r-pill); background: var(--ctl-fill); color: var(--ink-2); }
.panel > .icon-chip{margin-bottom:var(--s-4);}
/* The first link's empty state ("no approval links yet") is the one welcome moment: its disc takes the theme's rare warm
   accent (W6-UI-1, palette round 3). A period with no results, a search with no match and a Meta login with nothing
   shared are not welcomes: quiet chip (reviewer, 2026-10-02: the warm disc was the loudest thing on Overview). */
.panel[data-empty-state="approvals"] > .icon-chip { background: var(--spirit); color: var(--on-spirit); }
.fm-empty > .icon-chip{margin-bottom:var(--s-12);}
/* Finish setup's step meter: a line track under "Step N of 5" that fills a fifth per step, in ink. */
.finish-count{position:relative;padding-bottom:var(--s-12);}
.finish-count::before, .finish-count::after{content:"";position:absolute;left:0;bottom:0;height:4px;border-radius:var(--r-tab);}
.finish-count::before{width:100%;background:var(--line);}
.finish-count::after{width:0;background:var(--ink);transition:width var(--dur-2) var(--ease);}
.finish-form[data-step="1"] .finish-count::after{width:20%;}
.finish-form[data-step="2"] .finish-count::after{width:40%;}
.finish-form[data-step="3"] .finish-count::after{width:60%;}
.finish-form[data-step="4"] .finish-count::after{width:80%;}
.finish-form[data-step="5"] .finish-count::after{width:100%;}
/* Approvals: the row's name button stretches over its whole cell, so the first cell is one 44px target that
   presses and focuses as the name. The status and number cells still forward a click (app.js); the actions
   cell is its own. The name dims on press (above) and does not move. */
[data-approvals-body] > tr > td:first-child{position:relative;min-height:var(--ctl);}/* phone rows stack their cells; a table cell ignores it */
[data-approvals-body] .row-open::after{content:"";position:absolute;inset:0;}
/* Page headers: Saved batches' count as a tonal pill (served in product; the sample fills it); subs never
   leave one word alone on a line. */
.page-title [data-batches-total]{display:inline-block;padding:0 var(--s-8);border-radius:var(--r-tab);background:var(--ctl-fill);vertical-align:middle;font-variant-numeric:tabular-nums;}
.page-sub{text-wrap:pretty;}
@media (prefers-reduced-motion:reduce){
/* The meter jumps to its step (--dur-2 is 0 here); the copy button and row name keep the page-wide rule: no scale. */
.finish-count::after{transition:none;}
}
/* Wave 5c: seven small fixes so no control lies (prod-w5c-ui). Plan §9 U1-U7, controls inventory 1.3-1.21 (M-125).
   No new motion: the changed buttons keep the page's .97 press and 2px ring, and reduced motion keeps the page-wide
   rule (no scale, no transition). W7a and W7b bind the hooks; an unbound slot takes no room. */
/* U1: on a phone, each step's primary takes its own full row above the step's other buttons. */
@media (max-width:600px){
.first-run-foot{flex-wrap:wrap;}
.first-run-foot > .btn--primary{order:-1;flex-basis:100%;}
}
/* U2: the Add ads head keeps no actions slot while nothing in it is shown (product mode, until W7b shows New batch). */
.view--create > .page-head > .page-actions:not(:has(> :not([hidden]))) { display: none; }
/* U5: All brands is navigation, pressed in place with the press fill and no scale: a menu row is reached often. */
[data-menu="brand"] > .menu-item[data-go="brands"]:active { background: var(--press); }
/* U7: why Send for approval or Re-run checks is off, one served sentence each (1.4, 1.14). An empty reason takes no
   room. It reads in ink-2, a step above the PAUSED note, under its own button (W5d, below). On a phone Send's reason
   sits right under Send, above the two quiet actions, and Re-run checks' under their row, before the notes. */
.foot-reason:empty { display: none; }
.foot-reason { color: var(--ink-2);}
.view--create .sticky-foot .foot-reason{order:1;}
.view--create .sticky-foot > .foot-note:not(.foot-reason){order:2;}
@media (max-width:900px){
 .view--create .sticky-foot [data-send-approval-reason] { order: -1; }
}
/* W5d §9 U7: .foot-act keeps each reason under its own button. width:0/min-width:100%
   prevents text from moving buttons sideways; row top-alignment preserves Save draft.
   Wrapped desktop rows grow beneath reasons; at <=900px pairs dissolve into the stacked
   phone row. Empty reasons leave layout unchanged. */
.foot-act{display:grid;justify-items:start;row-gap:var(--s-4);}
.foot-act > .foot-reason{width:0;min-width:100%;}
@media (min-width:901px){.view--create .sticky-foot{align-items:flex-start;}}
@media (max-width:900px){.view--create .foot-act{display:contents;}}
/* U7 (1.8): one hook decides the sentence: shown, the no-batch line replaces "No approval links yet." */
[data-empty-state="approvals"]:has(> [data-approvals-no-batch]:not([hidden])) > .empty-line:not([data-approvals-no-batch]) { display: none; }
/* W6-UI-2: the served lines for the binder (names fixed by the seat; W6-FIX serves their words). Each ships hidden and
   empty and takes no room; the binder, or fill() for a template slot, writes it and shows it. They read as plain small
   text in ink-2, the reason lines' step, and an error in the bad tone. Nothing here derives a word. */
.served-line{margin:0;min-width:0;font:var(--t-small);color:var(--ink-2);overflow-wrap:anywhere;}
.served-line--error{color:var(--bad);}
/* send-warning and draft-error sit in the foot above every button, on every width (the phone order puts Send first at -1). */
.view--create .sticky-foot > .served-line{flex:1 0 100%;order:-3;}
.deliver-meta-state{padding-bottom:var(--s-12);}
/* held-back: the approved ads the server holds back, under the ads it will create, each its file and served reason. */
.held-back{margin-top:var(--s-16);}
.held-back-list{border-top:1px solid var(--line);}
.row--held{height:auto;min-height:var(--ctl);padding:var(--s-8) 0;border-bottom:1px solid var(--line);}
.row--held > .cell-main{display:flex;flex-direction:column;min-width:0;overflow-wrap:anywhere;}
.row--held .cell-meta{color:var(--ink-2);}
/* decision-note: the client's words on one ad in the approval detail, under its chip. */
.approval-ad-note{font:var(--t-small);color:var(--ink-2);overflow-wrap:anywhere;min-width:0;}
/* ad-name: the file beside "Ad N" in the check results. */
.check-ad-name{margin-left:var(--s-8);font:var(--t-small);color:var(--ink-3);overflow-wrap:anywhere;}
/* meta-word: one served word beside Meta, on the Overview and in the dialog; drawn with the network rows above. */
/* client-verdict and client-note: what the client said on this ad, one line under the ad's settings; the line hides
   while both are hidden. */
.client-said{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:var(--s-4) var(--s-8);margin:0;min-width:0;font:var(--t-small);color:var(--ink-2);overflow-wrap:anywhere;}
.client-said:not(:has(> :not([hidden]))){display:none;}
.client-said-verdict{color:var(--ink);font-weight:600;}
/* draft-error on a Saved batches row: its own line under the name, in the bad tone. */
.row--batch .draft-error:not([hidden]){display:block;margin-top:var(--s-4);color:var(--bad);}
/* review-note and unchecked-note (W6UI3, M-150): under an ad's name in Create paused, in the row's meta size and colour
   (.served-line). Each served line keeps its own line and wraps; nothing clips. Static text: no press, focus or motion. */
.deliver-note{white-space:pre-line;}
/* W6-UI-2 (5B): a brand's picture. One rounded square holds the Page's own picture, served into the photo slot; while
   there is none it shows the served letter on the one neutral fill, the same for every brand (never a colour derived
   from a name, AGENTS §5). A hairline edge keeps a white or dark picture off the surface. Sizes: the brand card 40
   (.brand-mark, the chip size), the From Meta list 32, the brand menu 28; the topbar's product-owned image is 24 with
   the thumbnail corner. A picture that fails to load drops its src (app.js), so the letter shows; neither, no square. */
.pic { position: relative; flex: none; display: inline-grid; place-items: center; overflow: hidden; width: 40px; height: 40px; border-radius: var(--r-sm); background: var(--sunk); color: var(--ink-2);font:var(--t-strong);text-transform:uppercase;}
.pic::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 0 0 1px var(--card-edge);pointer-events:none;}
.pic--32{width:32px;height:32px;border-radius:var(--r-pic);font:var(--t-small);font-weight:600;}
.pic--28{width:28px;height:28px;border-radius:var(--r-pic);font:var(--t-small);font-weight:600;}
.pic-img{grid-area:1 / 1;width:100%;height:100%;object-fit:cover;display:block;}
.pic-img:not([src]){display:none;}
.pic-letter{grid-area:1 / 1;}
.pic:has(> .pic-img[src]) > .pic-letter{display:none;}
.pic:not(:has(> .pic-img[src])):has(> .pic-letter:empty){display:none;}
/* From Meta: the box, the picture and the two lines sit on one centre line. */
.fm-pick:has(> .pic){align-items:center;}
/* end 5B */
/* W6-UI-2 (3B, with 3A's hero): Upgrade. The head is a centred column: the plan's brands as 48px picture squares and one
   free slot, the served title, one line. The Now line is a quiet sunk bar. The hero is the plan: a soft sunk panel with
   no ring (W7 Ink), the spirit chip, the big words and the four benefits, each on a raised icon plate in the
   action ink. Colour from the theme file only; the close x keeps every dialog's place. */
.modal--upgrade > .upgrade-top{position:relative;flex-direction:column;align-items:center;gap:var(--s-8);padding:var(--s-32) var(--s-48) var(--s-20);text-align:center;}
.upgrade-top > .icon-btn{position:absolute;top:var(--s-16);right:var(--s-8);}
.upgrade-top > .modal-title{text-wrap:balance;}
.upgrade-top > .modal-title:empty{display:none;}
.upgrade-sub{margin:0;font:var(--t-body);color:var(--ink-2);}
.upgrade-slots{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--s-8);margin-bottom:var(--s-8);}
.pic--48{width:48px;height:48px;border-radius:var(--r-lg);font:var(--t-title);}
.upgrade-free{background:transparent;color:var(--ink-2);box-shadow:inset 0 0 0 1px var(--line-2);}
.upgrade-free::after{content:none;}
.upgrade-now{display:flex;align-items:center;gap:var(--s-12);margin:0 0 var(--s-12);padding:var(--s-12) var(--s-16);border-radius:var(--r);background:var(--sunk);font:var(--t-body);color:var(--ink-2);}
.upgrade-now:has(> [data-brands-left]:empty) { display: none; }
.upgrade-hero { display: grid; justify-items: start; gap: var(--s-12); padding: var(--s-20); border-radius: var(--r-lg); background: var(--sunk);}/* W7 Ink: a soft panel, no ring */
.upgrade-chip { padding: var(--s-4) var(--s-12); border-radius: var(--r-tab); background: var(--spirit);color:var(--on-spirit);font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;}
.upgrade-big{margin:0;font:var(--t-display);letter-spacing:var(--track-display);color:var(--ink);}
.upgrade-benefits{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-12);justify-self:stretch;}
.upgrade-benefits li{display:flex;align-items:center;gap:var(--s-12);font:var(--t-body);color:var(--ink);}
.upgrade-benefits li > span:last-child{min-width:0;text-wrap:pretty;}
.upgrade-fi, .finish-fi{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:var(--r-sm);background:var(--raised);color:var(--act-ink);box-shadow:inset 0 0 0 1px var(--line);}
@media (max-width:600px){
.modal--upgrade > .upgrade-top{padding:var(--s-32) var(--s-16) var(--s-16);}
.upgrade-hero{padding:var(--s-16);}
.upgrade-slots > .pic--48{width:40px;height:40px;border-radius:var(--r-sm);}/* six squares keep one row on a phone */
}
/* end 3B */
/* W6-UI-2 (4B): Finish setup, a list you confirm. A row: the name and one small line (where a filled value came from,
   served, or "Optional"), the answer beside it (above on a phone). A served line makes the answer a quiet value until
   focus, with Change, and shows the banner. The meter is five parts. Motion: the input edge's own --dur-1. */
.finish-count{container-type:inline-size;}
.finish-count::before, .finish-count::after{mask:var(--seg-mask);}
.finish-legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}/* the count line says it */
.finish-step{border-bottom:1px solid var(--line);}
.finish-step > :is(.finish-row, .finish-block){margin:0;padding:var(--s-12) 0;box-shadow:inset 0 1px 0 var(--line);}/* not a border: a legend sits on a fieldset's border */
.finish-block > legend{float:left;width:100%;margin:0 0 var(--s-4);font:var(--t-strong);letter-spacing:0;text-transform:none;color:var(--ink);}/* floated: an ordinary box under the row's padding */
.finish-row{display:grid;grid-template-columns:144px minmax(0, 1fr);align-items:center;gap:var(--s-4) var(--s-12);min-height:64px;}
.finish-row > .help{grid-column:2 / -1;}
.finish-key{display:grid;gap:var(--s-4);min-width:0;}
.finish-key > .label{font:var(--t-strong);letter-spacing:0;text-transform:none;color:var(--ink);}
.finish-from, .finish-opt{font:var(--t-small);color:var(--ink-3);}
.finish-key:has(> .finish-from:not([hidden])) > .finish-opt, .finish-change{display:none;}
.finish-row .textarea{field-sizing:content;}
.finish-row:has(.finish-from:not([hidden])){grid-template-columns:144px minmax(0, 1fr) auto;}
.finish-row:has(.finish-from:not([hidden])) > .finish-change{display:inline-flex;}
.finish-row:has(.finish-from:not([hidden])) > :is(.input, .textarea):not(:focus){border-color:transparent;background:transparent;box-shadow:none;resize:none;}
@media (hover:hover) and (pointer:fine) and (min-width:601px){.finish-row:has(.finish-from:not([hidden])) > :is(.input, .textarea):hover:not(:focus){border-color:var(--line-2);}}
.finish-filled{display:none;align-items:center;gap:var(--s-12);margin:0 0 var(--s-16);padding:var(--s-12);border-radius:var(--r);background:var(--sunk);font:var(--t-small);color:var(--ink-2);}
.finish-filled p{margin:0;}
.finish-filled b{display:block;font:var(--t-strong);color:var(--ink);}
.finish-form:has(.finish-step:not([hidden]) .finish-from:not([hidden])) .finish-filled{display:flex;}
.finish-note{margin:var(--s-16) 0 0;padding:var(--s-12);border-radius:var(--r);box-shadow:inset 0 0 0 1px var(--line);font:var(--t-small);color:var(--ink-2);}
@media (max-width:600px){
.finish-row, .finish-row:has(.finish-from:not([hidden])){grid-template-columns:minmax(0, 1fr);}
.finish-row:has(.finish-from:not([hidden])){grid-template-columns:minmax(0, 1fr) auto;}
.finish-key, .finish-row > .help{grid-column:1 / -1;}
/* stacked, a filled answer's words start on its name's edge; Change opens the field with its padding and edge */
.finish-row:has(.finish-from:not([hidden])) > :is(.input, .textarea):not(:focus){padding-inline:0;}
}
/* end 4B */
/* W6-UI-2 (1B), founder pick s1b: raised Meta card, sunk interior, centred tile/name.
   Served Connect shares the desktop line and stacks on phone. Scope lines span from
   tile edge with centred icons (M-137); no added motion. UI-HOME uses the shared
   network element and places Coming soon networks after the card. */
.meta-card{display:grid;grid-template-columns:auto minmax(0, 1fr);align-items:center;gap:var(--s-8) var(--s-16);
padding:var(--s-20);border-radius:var(--r-lg);background:var(--sunk);}
.meta-card > *{grid-column:1 / -1;}
.meta-card > .net-tile{grid-column:1;}
.meta-card > .meta-id{grid-column:2;}
/* the head and the actions stand 16px clear of what follows (the 8px row gap and 8 more), 20px from the lines' hairline */
.meta-card > :is(.net-tile, .meta-id, .row-actions){margin-bottom:var(--s-8);}
.meta-perms{display:none;list-style:none;margin:var(--s-4) 0 0;padding:var(--s-20) 0 0;border-top:1px solid var(--line);grid-template-columns:1fr 1fr;align-items:start;gap:var(--s-16) var(--s-24);}/* side by side, two lines start level; each icon still sits on its own text */
/* Public setup is founder-assisted. Keep connection facts and read-only reload;
   hide the self-service form/instructions, using the incumbent help component. */
.meta-card[data-meta-setup="false"] > :is(.meta-selection, .meta-perms, [data-meta-guidance], [data-meta-disconnect-status], [data-meta-status]),
.from-meta[data-meta-setup="false"] .fm-connect > :is(h3, p:not([data-from-meta-capability-guidance])),
:root:has([data-overview-meta][data-meta-setup="false"]) [data-first-run-panel="meta"] > .page-sub { display:none; }
.meta-card[data-meta-setup="false"]:has(> .row-actions > [data-meta-connect]:not([hidden])) > .meta-perms { display:none; }
.meta-card:has(> .row-actions > [data-meta-connect]:not([hidden])) > .meta-perms{display:grid;}
.meta-perms li{display:grid;grid-template-columns:var(--icon) minmax(0, 1fr);align-items:center;gap:var(--s-12);font:var(--t-small);color:var(--ink-2);}
.meta-perms li > .i{color:var(--ink-2);}
.meta-perms li > span{min-width:0;text-wrap:pretty;}
.meta-perms b{display:block;font:var(--t-strong);color:var(--ink);}
/* UI-HOME (2026-10-03): the later platforms in the one network element under the card, the first tile on the card's tile
   column (its 20px inset), side by side. Not controls: no hover, press or focus state. */
.meta-soon{margin:var(--s-16) 0 0;padding:0 0 0 var(--s-20);}
@media (min-width:601px){
.meta-card{grid-template-columns:auto minmax(0, 1fr) auto;}
.meta-card > .row-actions{grid-column:3;grid-row:1;}
}
@media (max-width:600px){
.meta-perms{grid-template-columns:minmax(0, 1fr);}
.meta-card > .row-actions > [data-meta-connect]{flex:1;}
}
/* end 1B */
/* ---------- UI-HOME round 2 (2026-10-03): option A, the 3-step first run, review10 shell fixes (#n) ---------- */
/* #96: a view reaches the window's foot; Add ads keeps add-ads.css's 32 px foot */
.view{min-height:calc(100vh - var(--topbar) - 2 * var(--gap));min-height:calc(100dvh - var(--topbar) - 2 * var(--gap));}
:root[data-view="add"] .views{padding-bottom:var(--s-32);}
:root[data-view="add"] .view{min-height:0;}
/* Option A: one equal card per brand; an unserved count keeps its empty cell, so cards stay level */
.client-cards{display:grid;grid-template-columns:minmax(0, 1fr);gap:var(--s-12);margin:var(--s-16) 0 0;padding:0;list-style:none;}
.client-cards:empty{display:none;}
@media (min-width: 1100px) { .client-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; } }
.client-card{display:flex;flex-direction:column;gap:var(--s-16);min-width:0;padding:var(--s-16);border-radius:var(--r-lg);background:var(--raised);}
.client-head{display:flex;align-items:center;gap:var(--s-12);min-width:0;}
.client-id{min-width:0;}
.client-name{font:var(--t-row);color:var(--ink);overflow-wrap:anywhere;}
.client-setup{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-4) var(--s-8);font:var(--t-small);color:var(--ink-2);}
.client-setup > .i-meta{width:var(--s-16);height:var(--s-16);flex:none;}
.client-setup:not(:has([data-slot]:not([hidden]))){display:none;}
.client-page:has(> [data-slot="page_name"][hidden]) { display: none; }
.client-account:not([hidden]):has(+ .client-page > [data-slot="page_name"]:not([hidden]))::after{content:"·";margin-left:var(--s-8);color:var(--ink-3);}
.client-cap{color:var(--ink-3);}
.client-tally{display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));margin:0;border-block:1px solid var(--line);}
.client-cell{min-width:0;padding:var(--s-12) var(--s-8) var(--s-12) var(--s-12);}
.client-cell:first-child{padding-left:0;}
.client-cell + .client-cell{border-left:1px solid var(--line);}
.client-cell > dt{display:flex;align-items:center;gap:var(--s-8);font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.client-cell > dd{margin:0;min-height:var(--s-32);font:var(--t-num);font-variant-numeric:tabular-nums;color:var(--ink);}
.client-cell > dd.client-last{min-height:0;font:var(--t-small);color:var(--ink-2);}
.client-cell:not([data-cell="created"]):has(> dd:not(:empty)) > dt::before { content: ""; flex: none; width: var(--dot-size); height: var(--dot-size); border-radius: var(--r-pill); box-shadow: inset 0 0 0 1.5px var(--icon-neutral); }
.client-cell[data-cell="approved"] > dt::before { background: var(--icon-success); box-shadow: none !important; }
.client-cell[data-cell="changes"] > dt::before { background: var(--icon-failure); box-shadow: none !important; }
.client-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--s-8) var(--s-12);margin-top:auto;}
.client-empty{margin:0 auto 0 0;font:var(--t-small);color:var(--ink-2);}
.client-next{max-width:100%;white-space:normal;text-align:left;}
.client-next > [data-slot="next_text"]{min-width:0;overflow-wrap:anywhere;}
.client-next .i{color:inherit;}
.client-next[data-next-act="create"]{background:var(--primary-top);color:var(--primary-text);box-shadow:var(--sh-primary);}
@media (hover: hover) and (pointer: fine) {.client-next[data-next-act="create"]:hover{background:var(--primary-hover);}}
.client-next[data-next-act="create"]:not(:disabled):active{background:var(--primary-press);}
.client-card:not([data-complete="false"]) .client-finish{display:none;}
/* a caption wraps, never cut; the numbers keep one line (subgrid, round 3) */
@media (min-width:601px){
.client-tally{grid-template-rows:repeat(3, auto);}
.client-cell{display:grid;grid-row:span 3;grid-template-rows:subgrid;}
.client-cell > dt{align-items:baseline;white-space:normal;}
}
/* unfinished: Finish setup only (round 3) */
.client-card[data-complete="false"] .client-tally{display:none;}
@media (max-width:600px){
.client-tally{grid-template-columns:minmax(0, 1fr);border-bottom:0;}
.client-cell, .client-cell:first-child{display:grid;grid-template-columns:minmax(0, 1fr) auto;align-items:center;column-gap:var(--s-12);padding:var(--s-8) 0;border-bottom:1px solid var(--line);}
.client-cell + .client-cell{border-left:0;}
.client-cell > dd{grid-column:2;grid-row:1;min-height:var(--s-20);font:var(--t-row);text-align:right;}
.client-cell > dd.client-last{grid-column:1;grid-row:2;text-align:left;}
:is(.client-next, .client-finish){flex:1 1 100%;justify-content:space-between;}
}
/* C1 (M-164): "connected" once, the word under the mark, the days beside it */
.meta-id{flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:var(--s-8);}
.meta-id > .net-name{flex-basis:100%;}
.meta-days{font:var(--t-small);color:var(--ink-2);white-space:nowrap;}
.meta-word:not([hidden]) + .meta-days::before{content:"·";margin-right:var(--s-8);color:var(--ink-3);}
.meta-card[data-meta-state="connected"] > [data-meta-heading] { display: none; }
.meta-card:has([data-meta-days]:not([hidden])) > [data-meta-status] { display: none; }
.meta-card:not([data-meta-state=""]) > [data-demo-only] { display: none; }
/* #82: step 1, once connected: Continue, no guidance, no "come back and confirm"; a sign-in needing attention keeps both */
:root:has([data-overview-meta][data-meta-state="connected"]) [data-first-run-slot="meta"] [data-meta-guidance] { display: none; }
[data-first-run-panel="meta"] [data-first-run-act="next"] { display: none; }
:root:has([data-overview-meta][data-meta-state="connected"]:not([data-meta-attention="true"])) [data-first-run-panel="meta"] [data-first-run-act="next"] { display: inline-flex; }
:root:has([data-overview-meta][data-meta-state="connected"]:not([data-meta-attention="true"])) [data-first-run-panel="meta"] :is([data-first-run-act="later"], .fr-confirm) { display: none; }
/* item 104: a focused heading is no control: no ring */
:is(h1, h2)[tabindex="-1"]:focus{outline:none;box-shadow:none;}
/* #81: the served needs_attention (data-meta-attention) turns every status dot to the warning hue */
:root:has([data-overview-meta][data-meta-attention="true"]) .nav-dot{display:block;background:var(--icon-failure);}
:root:has([data-overview-meta][data-meta-attention="true"]) .meta-word::before{background:var(--icon-failure);box-shadow:none;}
.meta-card[data-meta-attention="true"] [data-meta-connect]{background:var(--primary-top);color:var(--primary-text);box-shadow:var(--sh-primary);}
/* #86: a deleted batch row leaves (none under reduced motion) */
.row--batch.is-leaving { pointer-events: none; animation:row-leave var(--dur-2) var(--e-out) forwards;}
@keyframes row-leave{to{opacity:0;transform:translateY(calc(-1 * var(--s-4)));}}
.modal--confirm [data-delete-batch-confirm] { color: var(--bad); }
/* #88: one row height, no raw ID */
.row--batch:first-child{border-top:1px solid transparent;}
.row--batch .batch-id{display:none;}
.row--batch .row-title strong{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.row--batch .row-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.row--batch:has(.draft-error:not([hidden])) .row-title{white-space:normal;}
/* #99: no pager for one page */
.batches-pager:not(:has(button:not(:disabled))){display:none;}
/* #91: the chip names the brand over its ad account; at 900 px the theme moves into the account menu */
.pick-btn{padding-block:var(--s-4);}
.pick-text{display:flex;flex-direction:column;align-items:flex-start;min-width:0;text-align:left;}
.pick-name{display:flex;min-width:0;max-width:100%;}
.brand-account{display:inline-flex;align-items:center;gap:var(--s-4);min-width:0;max-width:100%;font:var(--t-small);color:var(--chrome-secondary);}
.brand-account > .i{width:var(--s-16);height:var(--s-16);flex:none;}
.brand-account:has(> [data-brand-account]:empty) { display: none; }
.account [data-act="theme"] { display: none; }
@media (max-width:900px){
.top-right > [data-act="theme"]{display:none;}
.account [data-act="theme"]{display:flex;}
.top-left > .menu-wrap{flex:1 1 auto;}
}
/* item 102: a hidden rail item's li goes too */
.nav > li:has(> .nav-item[hidden]), .nav > li:has(> .nav-item.is-soon){display:none;}
/* item 103: the skip link shows on focus; in the drawer the account menu opens upward */
.skip-link{position:fixed;top:var(--s-8);left:var(--s-8);z-index:100;display:inline-flex;align-items:center;height:var(--ctl-dense);padding:0 var(--s-12);
border-radius:var(--r-tab);background:var(--chosen);color:var(--on-chosen);font:var(--t-action);transform:translateY(calc(-100% - var(--s-16)));}
.skip-link:focus{transform:none;}
@media (max-width:900px){
.side .account{position:static;margin-top:var(--s-8);}
.side .account .menu{top:auto;bottom:calc(100% + var(--s-8));left:0;right:auto;transform-origin:bottom left;}
}
/* item 105: the icon takes the 28 px picture's box */
[data-menu="brand"] .menu-item > svg.i{box-sizing:content-box;padding-inline:var(--s-4);}
/* #92: aria-invalid turns the field's edge; while a message shows, the card keeps its idle top (app.js) */
.input[aria-invalid="true"], .input[aria-invalid="true"]:focus-visible{border-color:var(--icon-failure);}
.view--auth[data-auth-anchored]{align-items:start;}
/* item 106 */
.auth-lost{margin-top:var(--s-8);text-align:center;text-wrap:pretty;}
.top-right > [data-first-run-entry] { flex: none; }
/* First run step 2: the borrowed brand parts take the card's inset; Back and Skip are its ways out */
[data-first-run-slot="brand"] > .brand-tabs { margin: 0 0 var(--s-16); }
[data-first-run-slot="brand"] .from-meta-body{padding:0;overflow:visible;}
[data-first-run-slot="brand"] .from-meta-foot{margin-top:var(--s-20);padding:var(--s-16) 0 0;}
[data-first-run-slot="brand"] .brand-form{padding:0;}
[data-first-run-slot="brand"] [data-from-meta-cancel], [data-first-run-slot="brand"] [data-from-meta-done]{display:none;}
@media (max-width:900px){
[data-first-run-slot="brand"] > .brand-tabs{margin-inline:0;}
[data-first-run-slot="brand"] .from-meta-body{padding-inline:0;}
}

/* The served connection state owns Overview visibility; Social accounts remains in the rail. */
body:has([data-meta-state="connected"]) :is([data-ready-row="meta"],.ready:has([data-getting-started][hidden])) { display:none;}

/* Review words are independent of legacy delivery eligibility. Empty new slots keep old bindings usable. */
[data-review-tone]:empty,[data-approval-review-summary]:empty,[data-approval-next-actor]:empty,[data-approval-next-reason]:empty,.approval-answers:empty{display:none}
[data-review-tone]:not(:empty)+[data-approval-status],[data-slot="review_status_text"]:not(:empty)+[data-slot="status_text"]{display:none}
.approval-avatar{overflow:hidden;position:relative}
.approval-avatar img{width:100%;height:100%;object-fit:cover}
.approval-avatar:has(img:not([hidden])) [data-approval-initial]{display:none}
.approval-answers{list-style:none;margin:var(--s-16) 0;padding:0;display:grid;gap:var(--s-16)}
.approval-answer{display:flex;flex-direction:column;gap:var(--s-4);min-width:0;font:var(--t-small);overflow-wrap:anywhere;white-space:pre-wrap}
.approval-answer>:empty{display:none}
[data-approval-review-summary]{margin:var(--s-8) 0;font:var(--t-body)}
[data-approval-next-reason]{overflow-wrap:anywhere}

.table .td-actions > [data-approval-next-action]{opacity:1}

[data-modal="approval-link"] fieldset{border:0;padding:0;margin:0}
[data-modal="approval-link"] legend{padding:0;margin-bottom:var(--s-8)}
[data-approval-respondent-answers] .approval-answer-name{display:none}
