/* Commerce Growth OS — dashboard styles. Light + dark, no external assets. */
:root {
  --bg: #f6f7f9; --panel: #ffffff; --ink: #1b2430; --muted: #636d79; --line: #e3e7ec;
  --brand: #2f5bea; --brand-ink: #ffffff; --ok: #197c49; --warn: #9b620a; --bad: #c0392b;
  --ok-bg: #e7f5ee; --warn-bg: #fdf3e2; --bad-bg: #fbe9e7; --muted-bg: #eef1f4;
  /* Ink for text sitting ON a filled brand/danger surface, and a border dark enough to
     mark the edge of a control (WCAG 1.4.11 wants 3:1; --line manages 1.24:1). */
  --bad-ink: #ffffff; --field-line: #7f91a8;
  --radius: 10px; --shadow: 0 1px 2px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.04);
  /* The navigation rail is dark in BOTH themes (Redesign Cut A: "persistent dark left navigation, clean
     light workspace"). A navy biased toward --brand, not a neutral grey. Contrast on --nav-bg:
     --nav-ink 10.6:1, --nav-muted 5.2:1, --nav-ink-strong 16:1. */
  --nav-bg: #111a2c; --nav-bg-hover: #1a2640; --nav-active: #22365f; --nav-line: #23304a;
  --nav-ink: #c3cddc; --nav-ink-strong: #f3f6fb; --nav-muted: #8190a6; --nav-accent: #8aa6ff;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f141a; --panel: #161c24; --ink: #e7ecf2; --muted: #9aa6b2; --line: #263140;
    --brand: #5b82ff; --ok: #4ec98a; --warn: #e0a94a; --bad: #f07567;
    --ok-bg: #12271d; --warn-bg: #2a2113; --bad-bg: #2c1815; --muted-bg: #1c242e;
    --brand-ink: #0f141a; --bad-ink: #0f141a; --field-line: #516888;
    /* One step darker than the dark workspace, so the rail still reads as its own surface. */
    --nav-bg: #0a0f1b; --nav-bg-hover: #151e33; --nav-active: #1d2d50; --nav-line: #1b253b;
  }
}
* { box-sizing: border-box; }
body { margin: 0; font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; color: var(--ink); background: var(--bg); }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; background: var(--muted-bg); padding: 1px 5px; border-radius: 5px; }
h1, h2 { margin: 0 0 .5rem; }
h2 { font-size: 1.05rem; }

.mock-strip { background: repeating-linear-gradient(45deg, #a5680b, #a5680b 12px, #8f5a09 12px, #8f5a09 24px); color: #fff; text-align: center; font-weight: 600; font-size: .8rem; padding: 5px; letter-spacing: .02em; }
.mock-strip-live { background: #1a7f4b; }

.app { display: grid; grid-template-columns: 256px minmax(0, 1fr); min-height: 100vh; }
/* Persistent: the rail stays in view while the page scrolls, and scrolls on its own when it is taller
   than the screen. `color-scheme: dark` gives it native dark scrollbars instead of a white track. */
.sidebar { background: var(--nav-bg); color: var(--nav-ink); padding: 16px 12px 24px; position: sticky; top: 0;
  height: 100vh; overflow-y: auto; overscroll-behavior: contain; color-scheme: dark; }
.brand { font-weight: 700; font-size: 1.02rem; margin-bottom: 16px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Brand wordmark on a white chip so the black "virtuad Media" logo stays legible in both light and dark themes. */
.brand-logo { display: inline-block; width: 100%; background: #fff; border-radius: 9px; padding: 8px 11px; box-sizing: border-box; box-shadow: 0 1px 2px rgba(16,24,40,.06); }
.brand-logo img { display: block; width: 100%; height: auto; }
.login-logo { background: #fff; border-radius: 12px; padding: 16px 20px; margin: 0 auto 18px; box-shadow: 0 1px 3px rgba(16,24,40,.10); }
.login-logo img { display: block; width: 100%; max-width: 260px; height: auto; margin: 0 auto; }
.login-product { text-align: center; text-transform: uppercase; letter-spacing: .2em; font-size: .82rem; font-weight: 600; color: var(--brand); margin: -10px 0 14px; }
.advisor-hd { display: flex; align-items: center; gap: 8px; margin: 0 0 .5rem; }
.advisor-hd-icon { flex: none; border-radius: 6px; }
/* Inactivity warning modal (session timeout) */
.idle-modal-backdrop { position: fixed; inset: 0; background: rgba(10,15,22,.55); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 20px; }
.idle-modal-backdrop[hidden] { display: none; }
.idle-modal { background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 14px; padding: 24px; width: 100%; max-width: 380px; box-shadow: 0 16px 48px rgba(0,0,0,.4); }
.idle-modal h2 { margin: 0 0 8px; }
.idle-countdown { font-variant-numeric: tabular-nums; }
.idle-modal-actions { display: flex; gap: 10px; margin-top: 18px; }
.nav { display: flex; flex-direction: column; gap: 1px; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 7px; color: var(--nav-ink); font-size: .88rem; line-height: 1.35; }
.nav-item:hover { background: var(--nav-bg-hover); color: var(--nav-ink-strong); text-decoration: none; }
/* Current page: a lighter fill, heavier weight and an accent icon. Colour is never the only signal:
   the link also carries aria-current="page". */
.nav-item.active { background: var(--nav-active); color: #fff; font-weight: 600; }
.nav-item.active .nav-ico { color: var(--nav-accent); }
.nav-item.danger { color: #ff9d92; }
.nav-item.active.danger { background: #4a1c19; color: #ffd9d4; }
.pill { background: var(--bad); color: var(--bad-ink); border-radius: 999px; font-size: .72rem; padding: 0 7px; min-width: 18px; text-align: center; }
/* The count badge keeps the app's danger pair (--bad on --bad-ink), which clears AA in both themes. */
.sidebar .pill { margin-left: auto; font-weight: 600; }
.nav-item.active .pill { background: var(--nav-ink-strong); color: var(--nav-active); }

.main { display: flex; flex-direction: column; min-width: 0; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 10px 24px; min-height: 60px; border-bottom: 1px solid var(--line); background: var(--panel); }
.topbar-id { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.topbar-title { font-size: 1.15rem; font-weight: 700; margin: 0; letter-spacing: -.01em; }
/* WHERE AM I: section, subsection, and a link back when the page sits under a list. */
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 2px 6px; font-size: .76rem; color: var(--muted); }
.crumbs li { white-space: nowrap; }
.crumbs li + li::before { content: "\203A"; margin-right: 6px; color: var(--muted); }
.crumbs a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.crumbs a:hover { color: var(--brand); }
/* COMPANY, THEN BRAND, as one object: a page scoped to one brand must not read as the whole company. */
.topbar-context { display: inline-flex; align-items: center; gap: 8px; padding: 3px 3px 3px 10px; border: 1px solid var(--line); border-radius: 9px; background: var(--bg); min-width: 0; }
.topbar-tenant { font-weight: 600; font-size: .8rem; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 16ch; }
.topbar-user { display: flex; align-items: center; gap: 12px; }
.topbar-advisor { white-space: nowrap; font-weight: 600; }
.topbar-advisor.active { box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--brand); }
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.topbar-title, .topbar-tenant { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-toggle { display: none; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; font-size: 1.15rem; line-height: 1; padding: 6px 11px; cursor: pointer; color: var(--ink); }
.nav-toggle:hover { border-color: var(--brand); }

/* ── Accordion sidebar ─────────────────────────────────────────────────────────────────────────── */
/* The gutter is sized for the IMAGE, not the emoji, and both rows share it so an icon row and an
   emoji row line up down the same edge. */
.nav-ico { flex: none; width: 1.25rem; display: inline-flex; align-items: center; justify-content: center; color: var(--nav-muted); }
/* In-page channel buttons still use the 128px PNG icons (`navIcon`); the rail itself draws line icons. */
.nav-img { width: 1.5rem; height: 1.5rem; object-fit: contain; }
.nav-svg { display: block; width: 18px; height: 18px; }
.nav-txt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item:hover .nav-ico { color: var(--nav-ink-strong); }
/* The daily block at the top: Home, What needs you, Approvals, Notifications. Never nested. */
.nav-home { display: flex; flex-direction: column; gap: 1px; padding-bottom: 10px; margin-bottom: 8px; border-bottom: 1px solid var(--nav-line); }
.nav-group > summary, .nav-sub > summary { display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none; user-select: none; border-radius: 7px; }
.nav-group > summary { padding: 8px 10px; font-size: .88rem; font-weight: 600; color: var(--nav-ink-strong); }
/* A section name is the product's own wording and is never cut: "Customers & Sales Growth" wraps to a
   second line rather than reading "Customers & Sales G…". */
.nav-group > summary > .nav-txt { white-space: normal; overflow: visible; line-height: 1.3; }
.nav-sub > summary { padding: 6px 10px; font-size: .84rem; font-weight: 500; color: var(--nav-ink); }
.nav-group > summary::-webkit-details-marker, .nav-sub > summary::-webkit-details-marker { display: none; }
.nav-group > summary::marker, .nav-sub > summary::marker { content: ''; }
.nav-group > summary:hover, .nav-sub > summary:hover { background: var(--nav-bg-hover); color: var(--nav-ink-strong); }
.nav-group[open] > summary .nav-ico { color: var(--nav-accent); }
.nav-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* One focus ring on the dark rail, bright enough to read against navy. */
.sidebar a:focus-visible, .sidebar summary:focus-visible, .sidebar select:focus-visible, .sidebar button:focus-visible { outline: 2px solid var(--nav-accent); outline-offset: 1px; }
/* One way into a separate workspace, marked as such. */
.nav-workspace { margin-top: 4px; font-weight: 600; color: var(--nav-ink-strong); }
.nav-out { flex: none; color: var(--nav-muted); display: inline-flex; }
.nav-out .nav-svg { width: 14px; height: 14px; }
.nav-sep { border: 0; border-top: 1px solid var(--nav-line); margin: 10px 4px; }
/* Connection state, said in words: Connect, Reconnect, Demo, Connector pending. It sits on its OWN line
   under the channel's name: side by side, "Connector pending" left "TikTok Ads" as "Ti…" at this rail
   width. The empty ::after is a full-width break, so the name keeps line one (with its chevron) and the
   state reads in full on line two, whatever either says. */
.nav-note { flex: none; font-size: .68rem; font-weight: 600; line-height: 1.5; padding: 0 7px; border-radius: 999px; white-space: nowrap; }
.nav-note-warn { background: #3a2c10; color: #f2c46b; }
.nav-note-bad { background: #3d1a17; color: #ff9d92; }
.nav-sub > summary:has(> .nav-note), .nav-item:has(> .nav-note) { flex-wrap: wrap; row-gap: 0; }
.nav-sub > summary:has(> .nav-note)::after, .nav-item:has(> .nav-note)::after { content: ''; flex-basis: 100%; height: 0; order: 5; }
.nav-sub > summary > .nav-note, .nav-item > .nav-note { order: 6; margin: 3px 0 2px; }

/* The sidebar puts ~92 focusable elements ahead of the page content. Without this, reaching the
   first control on any page took that many Tab presses — every single navigation. */
.skip-link { position: absolute; left: 8px; top: -60px; z-index: 60; background: var(--panel); color: var(--brand); border: 1px solid var(--brand); border-radius: 8px; padding: 9px 14px; font-weight: 600; font-size: .9rem; transition: top .12s ease; }
.skip-link:focus { top: 8px; text-decoration: none; }

/* One focus ring everywhere, so it does not depend on each browser's default landing legibly on
   a filled brand button. :focus-visible keeps it off mouse clicks. */
.content a:focus-visible, .content button:focus-visible, .content input:focus-visible,
.content select:focus-visible, .content textarea:focus-visible, .content summary:focus-visible,
.topbar a:focus-visible, .topbar button:focus-visible, .topbar select:focus-visible,
.skip-link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { .skip-link { transition: none; } }
.nav-chevron { flex: none; margin-left: auto; color: var(--nav-muted); display: inline-flex; transition: transform .15s ease; }
.nav-chevron .nav-svg { width: 14px; height: 14px; }
.nav-group-pill + .nav-chevron { margin-left: 6px; }
.nav-group[open] > summary > .nav-chevron, .nav-sub[open] > summary > .nav-chevron { transform: rotate(90deg); }
/* The aggregate badge shows only while the group is closed; open, each link carries its own. */
.nav-group[open] > summary .nav-group-pill, .nav-sub[open] > summary .nav-group-pill { display: none; }
.nav-group-pill { margin-left: auto; }
.nav-group-items { display: flex; flex-direction: column; gap: 1px; margin: 2px 0 6px 19px; padding-left: 8px; border-left: 1px solid var(--nav-line); }
.nav-sub-items { display: flex; flex-direction: column; gap: 1px; margin: 1px 0 4px 10px; padding-left: 8px; border-left: 1px solid var(--nav-line); }
.nav-group-items .nav-item, .nav-sub-items .nav-item { font-size: .85rem; padding: 6px 10px; }
@media (prefers-reduced-motion: reduce) { .nav-chevron { transition: none; } }

/* ── Mobile drawer ─────────────────────────────────────────────────────────────────────────────── */
.nav-backdrop { display: none; }
/* WIDE SCREENS (Redesign Cut B, Luis: up to 1600px). Dense pages (tables, dashboards) use the room; running
   text and form fields are held to readable widths in the Cut B block at the end of this file. */
.content { padding: 22px 24px; flex: 1; max-width: 1600px; width: 100%; }
.foot { padding: 14px 24px; border-top: 1px solid var(--line); font-size: .8rem; }

.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; margin-bottom: 18px; box-shadow: var(--shadow); }
.card-foot { margin-top: 10px; font-size: .88rem; }

.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 18px; }
.kpi { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); color: var(--ink); }
.kpi:hover { text-decoration: none; border-color: var(--brand); }
.kpi-n { font-size: 1.7rem; font-weight: 700; }
.kpi-l { color: var(--muted); font-size: .82rem; }
.kpi-bad .kpi-n { color: var(--bad); } .kpi-warn .kpi-n { color: var(--warn); }
/* THE COMMAND CENTER'S STRIP: the same tiles, one compact row, so the decisions below still fit the
   first screen. Tabular figures so the numbers line up tile to tile. */
.kpi-strip { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 16px; }
.kpi-strip .kpi { padding: 11px 14px; box-shadow: none; }
.kpi-strip .kpi-n { font-size: 1.3rem; font-variant-numeric: tabular-nums; line-height: 1.25; }
.kpi-strip .kpi-l { font-size: .76rem; line-height: 1.35; }

.table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.table th { text-align: left; color: var(--muted); font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.table td { padding: 9px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.table tr.unread td { background: var(--warn-bg); }

.badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .74rem; font-weight: 600; }
.badge-ok { background: var(--ok-bg); color: var(--ok); }
.badge-warn { background: var(--warn-bg); color: var(--warn); }
.badge-bad { background: var(--bad-bg); color: var(--bad); }
.badge-muted { background: var(--muted-bg); color: var(--muted); }
/* badge-alert was used by nine route files and defined by none, so every "hot" prospect, failed
   message and missing-evidence marker rendered as bare bold text with no pill — the loudest state in
   each of those tables was the only one without a shape. Same tokens as badge-bad; a separate name
   because callers mean "needs you now", not "this failed". */
.badge-alert { background: var(--bad-bg); color: var(--bad); }

.banner { padding: 10px 14px; border-radius: 8px; margin-bottom: 14px; font-size: .9rem; }
.banner-ok { background: var(--ok-bg); color: var(--ok); }
.banner-warn { background: var(--warn-bg); color: var(--warn); }
.banner-alert { background: var(--bad-bg); color: var(--bad); }

.btn { display: inline-block; border: 1px solid var(--line); background: var(--panel); color: var(--ink); padding: 8px 14px; border-radius: 8px; font: inherit; cursor: pointer; }
.btn:hover { border-color: var(--brand); text-decoration: none; }
.btn-primary { background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
.btn-danger { background: var(--bad); color: var(--bad-ink); border-color: var(--bad); }
.btn-small { padding: 4px 10px; font-size: .82rem; }
.inline { display: inline; } .row { display: flex; gap: 10px; } .stack { display: flex; flex-direction: column; gap: 10px; max-width: 460px; }

label { display: flex; flex-direction: column; gap: 4px; font-size: .86rem; color: var(--muted); }
input, select, textarea { font: inherit; color: var(--ink); background: var(--panel); border: 1px solid var(--field-line); border-radius: 8px; padding: 8px 10px; }
.grid-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; align-items: end; }
.grid-form button { grid-column: 1 / -1; justify-self: start; }
.w-90 { width: 90px; } .checks { grid-column: 1/-1; display: flex; flex-wrap: wrap; gap: 12px; }
.check { flex-direction: row; align-items: center; gap: 6px; color: var(--ink); }

.tabs { display: flex; gap: 6px; margin-bottom: 14px; }
.tab { padding: 5px 12px; border-radius: 999px; background: var(--muted-bg); color: var(--muted); font-size: .85rem; text-transform: capitalize; }
.tab.active { background: var(--brand); color: var(--brand-ink); }

.kv { display: grid; grid-template-columns: 150px 1fr; gap: 6px 12px; margin: 0 0 12px; }
.kv dt { color: var(--muted); } .kv dd { margin: 0; }
.code { background: var(--muted-bg); padding: 12px; border-radius: 8px; overflow: auto; font-size: .82rem; max-height: 300px; }
.bar { height: 7px; background: var(--muted-bg); border-radius: 999px; margin-top: 5px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--brand); }
.bar-full { background: var(--bad); }
.warn-list { margin: 0; padding-left: 18px; } .warn-list li { color: var(--warn); }

.thumb { width: 40px; height: 40px; object-fit: contain; border-radius: 6px; background: #fff; border: 1px solid var(--line); vertical-align: middle; margin-right: 9px; }
.prodname { font-weight: 600; }
.muted { color: var(--muted); } .small { font-size: .82rem; }
.row-closed { opacity: .58; }
.row-closed td:nth-child(2) { text-decoration: line-through; text-decoration-color: var(--bad); }
/* A link that lands on one row (#kw-<id> from "Open existing keyword") marks it; no script. */
tr:target td { background: color-mix(in srgb, var(--brand) 12%, transparent); }
tr:target td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
details summary { cursor: pointer; color: var(--brand); margin-bottom: 8px; }

.login-body { display: grid; place-items: center; min-height: 100vh; }
.login-card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 30px; width: 340px; box-shadow: var(--shadow); }
.login-card form { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }

/* BELOW A LAPTOP, THE RAIL BECOMES A DRAWER. At 768px a fixed 256px rail left the page 512px, which
   is a phone's width with a desktop's chrome. Tablets get the whole width and the same menu behind the
   button; the drawer is a deliberate collapse, never a sideways-scrolling rail. */
@media (max-width: 1023px) {
  .app { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: fixed; top: 0; left: 0; bottom: 0; height: auto; width: min(300px, 86vw); z-index: 60;
    transform: translateX(-100%); visibility: hidden; transition: transform .2s ease, visibility 0s linear .2s; }
  .app.nav-open .sidebar { transform: translateX(0); visibility: visible; transition: transform .2s ease, visibility 0s; box-shadow: 0 0 40px rgba(0,0,0,.35); }
  .nav-backdrop { display: block; position: fixed; inset: 0; z-index: 55; background: rgba(0,0,0,.45);
    opacity: 0; pointer-events: none; transition: opacity .2s ease; }
  .app.nav-open .nav-backdrop { opacity: 1; pointer-events: auto; }
  .nav-toggle { display: inline-block; }
  /* Bigger tap targets on touch. */
  .nav-item, .nav-group > summary, .nav-sub > summary { padding-top: 10px; padding-bottom: 10px; }
  /* The page title keeps its row: at 768px the email squeezed "Command Center" to "Co…" and broke
     "Log out" in two. The email goes, and the rest wraps to a second row rather than squeezing. */
  .topbar { flex-wrap: wrap; row-gap: 8px; }
  .topbar-left { flex: 1 1 auto; }
  .topbar-email { display: none; }
  .topbar .btn { white-space: nowrap; }
}
@media (max-width: 1023px) and (prefers-reduced-motion: reduce) {
  .sidebar, .app.nav-open .sidebar, .nav-backdrop { transition: none; }
}

@media (max-width: 760px) {
  .topbar-email { display: none; } /* save room for the AI Advisor button + menu on small screens */
  .topbar-tenant { max-width: 12ch; }

  /* ── THE REASON THE APP WAS UNUSABLE ON A PHONE ───────────────────────────────────────────────
     161 tables across the route files; 14 of them were wrapped in `.table-scroll`. The other 147
     were wider than the screen, and a table wider than its card pushes the PAGE wider than the
     viewport — so every one of those screens panned sideways, and the columns rendered outside the
     card on the bare page background. Measured on the prospect list at 375px: a 522px table inside a
     325px card, document width 565px.
     Containing it at the card edge fixes all 147 without touching 147 call sites, and leaves the
     desktop layout alone. `.table-scroll` still works where it is used; this is the floor under it. */
  .card { overflow-x: auto; }

  /* `.card { overflow-x: auto }` above gives the table somewhere to scroll, but `.table` is
     `width: 100%`, so it shrank to fit the card instead of overflowing it — and the columns took
     the squeeze out on the words. At 390px a status pill read "Contacte / d" with the last letter
     outside the pill, a header read "SCOR / E", and a link read "Ope / n". A min-width makes the
     table overflow and the card scroll, which is what the rule above was for. Data tables are
     exempt from WCAG 1.4.10 reflow; text sliced mid-word is not exempt from anything.

     `min-content`, NOT a pixel value. A fixed 460px widened Chrome's layout viewport from 390 to
     435 — measured — so the whole page panned sideways again, which is the thing the rule above
     exists to prevent. `min-content` is "as narrow as the words allow and no narrower": it stops
     the squeeze without ever forcing the table wider than its own content. */
  .table { min-width: min-content; }
  .table th { white-space: nowrap; }
  /* Action links ("Open", "Edit", "Review") sit in the narrowest column, and Chrome squeezed that
     column below the width of the word — "Open" rendered as "Op / en". Measured alternative:
     `width: max-content` also fixes it but pushes the layout viewport past the screen at 320px,
     which is the page-panning bug all over again. */
  .table td a { white-space: nowrap; }

  /* Same defect in the buttons: "Cancel" wrapped to "Canc / el" once the row got tight. These are
     short labels — they should push the row to wrap, never break inside a word. */
  .btn, .badge, .tab, .chip, .pill { white-space: nowrap; }
  /* …and once they stopped breaking, a three-button row ran off the card edge instead, leaving
     "Delete prospect" cut in half with no hint it was there. `.row` is a flex line with no wrap. */
  .row { flex-wrap: wrap; }

  /* Four KPI tiles stacked one per row pushed the actual content 1,600px down, so the first screen
     of a list page showed no list. Two across fits a phone and keeps the numbers readable. */
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr)); gap: 10px; }

  /* A <select> is as wide as its longest option, which flex-wrap cannot help with — one option
     longer than the screen overflows the form on its own. */
  select, input, textarea { max-width: 100%; }
  label { min-width: 0; }

  /* THE TOP BAR WAS THE FIRST THING TOO WIDE, ON EVERY PAGE. It is one non-wrapping flex row holding
     the business name, the brand selector, the AI Advisor button, the email and Log out. At 375px that
     row cannot fit, so it pushed the document wider than the screen and every page panned sideways
     before a single table was reached. */
  .topbar { flex-wrap: wrap; gap: 8px; padding: 10px 14px; }
  .topbar-user { flex-wrap: wrap; gap: 8px; row-gap: 6px; }
  .topbar-left { flex: 1 1 auto; }

  /* 48px of horizontal padding out of 375 is an eighth of the screen spent on margin. */
  .content { padding: 16px 14px; }

  /* Long single words (a URL, a SKU) are the other thing that widens a page on a narrow screen. */
  .card, .content { overflow-wrap: anywhere; }
}

/* ===================== Sales Dashboard ===================== */
.sales-head { margin-bottom: 6px; }
.sales-controls { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin: 10px 0 6px; }
.sales-controls select, .sales-controls input { font: inherit; padding: 6px 8px; border: 1px solid var(--field-line); border-radius: 8px; background: var(--panel); color: var(--ink); }
.chips { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 6px 0; }
.chip { display: inline-block; padding: 4px 11px; border-radius: 999px; background: var(--muted-bg); color: var(--muted); font-size: .84rem; border: 1px solid transparent; }
.chip:hover { text-decoration: none; border-color: var(--brand); }
.chip-on { background: var(--brand); color: var(--brand-ink); }
.chip-clear { background: transparent; color: var(--bad); }
.applied { margin: 6px 0 2px; font-size: .84rem; color: var(--muted); }
.tag { display: inline-block; background: var(--muted-bg); border-radius: 6px; padding: 2px 8px; margin: 0 4px 4px 0; font-size: .8rem; }

.skpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; }
.skpi { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 13px 14px; box-shadow: var(--shadow); }
.skpi:focus { outline: 2px solid var(--brand); outline-offset: 1px; }
.skpi-l { color: var(--muted); font-size: .78rem; display: flex; justify-content: space-between; gap: 6px; }
.skpi-i { opacity: .5; cursor: help; }
.skpi-v { font-size: 1.45rem; font-weight: 700; margin: 3px 0; letter-spacing: -.01em; }
.skpi-foot { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-height: 24px; }
.delta { font-size: .78rem; font-weight: 700; white-space: nowrap; }
.delta-up { color: var(--ok); } .delta-down { color: var(--bad); } .delta-flat { color: var(--muted); }
.spark { display: block; }
.spark-line { fill: none; stroke: var(--brand); stroke-width: 1.4; opacity: .85; }

.num { text-align: right; } .table th.num, .table td.num { text-align: right; white-space: nowrap; }
.tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.tab-on { background: var(--brand); color: var(--brand-ink); }
.sub { font-size: .8rem; color: var(--muted); margin: 12px 0 6px; text-transform: uppercase; letter-spacing: .03em; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.chart { width: 100%; height: auto; overflow: visible; }
.ax-grid { stroke: var(--line); stroke-width: 1; }
.ax-lbl, .ax-title { fill: var(--muted); font-size: 10px; }
.ax-be { stroke: var(--ok); stroke-width: 1; stroke-dasharray: 4 3; opacity: .7; }
.ln { fill: none; stroke-width: 2; } .ln-cur { stroke: var(--brand); } .ln-cmp { stroke: var(--muted); stroke-dasharray: 4 3; opacity: .7; }
.ln-dot { fill: var(--brand); } .lg-cur { fill: var(--brand); } .lg-cmp { fill: var(--muted); }
.chart-empty { padding: 26px; text-align: center; color: var(--muted); background: var(--muted-bg); border-radius: 8px; font-size: .88rem; }

.hbars { display: flex; flex-direction: column; gap: 7px; margin: 8px 0; }
.hbar-row { display: grid; grid-template-columns: minmax(110px, 34%) 1fr auto; gap: 10px; align-items: center; font-size: .88rem; }
.hbar-lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar-track { background: var(--muted-bg); border-radius: 999px; height: 12px; overflow: hidden; }
.hbar-fill { background: var(--brand); height: 100%; border-radius: 999px; }
.hbar-val { font-variant-numeric: tabular-nums; color: var(--muted); }

.bub { opacity: .55; stroke: var(--panel); stroke-width: 1; }
.bub-strong { fill: var(--ok); } .bub-monitor { fill: var(--warn); } .bub-underperforming { fill: var(--bad); }
.verdict { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .74rem; font-weight: 600; text-transform: capitalize; }
.verdict-strong { background: var(--ok-bg); color: var(--ok); }
.verdict-monitor { background: var(--warn-bg); color: var(--warn); }
.verdict-underperforming { background: var(--bad-bg); color: var(--bad); }

.insights { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.insight { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }
.insight-t { font-weight: 700; font-size: .92rem; margin-bottom: 3px; }
.insight p { margin: 3px 0; }
/* Redesign Cut C: an insight's severity is its badge (word + colour), not a coloured left edge. */
.insight-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.insight-head .insight-t { margin-bottom: 0; }

.empty-state { padding: 20px; background: var(--muted-bg); border-radius: 8px; }
.empty-title { font-weight: 700; margin-bottom: 4px; }
.pager { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.table-scroll { overflow-x: auto; }
.w-220 { width: 220px; max-width: 60vw; }

@media (max-width: 760px) {
  .two-col { grid-template-columns: 1fr; }
  .skpi-v { font-size: 1.25rem; }
  .hbar-row { grid-template-columns: minmax(90px, 40%) 1fr auto; }
}

/* schedule-a-post: multi-channel checkboxes + compliance results */
.chkset { border: 1px solid var(--line); border-radius: 8px; padding: 6px 12px 10px; margin: 8px 0; }
.chkset legend { color: var(--muted); font-size: .82rem; padding: 0 4px; }
.chk { flex-direction: row; align-items: center; gap: 6px; display: inline-flex; margin: 6px 16px 2px 0; color: var(--ink); font-size: .92rem; }
.chk input { width: auto; }
.comp-results { border-top: 1px solid var(--line); padding: 8px 0 0; margin: 8px 0; display: flex; flex-direction: column; gap: 4px; }
.comp-row { font-size: .88rem; }
.chan-row { display: flex; align-items: center; gap: 10px; margin: 5px 0; }
.chan-row .chk { min-width: 150px; margin: 0; }
.fmt-sel { font: inherit; padding: 3px 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel); color: var(--ink); }

/* Schedule-a-post: two-column compose + live post preview (src/web/static/preview.js) */
.compose-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem; align-items: start; }
@media (min-width: 900px) { .compose-grid { grid-template-columns: minmax(0, 1fr) 340px; } }
.post-preview { align-self: start; }
@media (min-width: 900px) { .post-preview { position: sticky; top: 1rem; } }
.pv-head { font-weight: 600; margin-bottom: .5rem; }
.pv-note { margin-top: .5rem; }
.pv-empty { padding: 1.5rem; border: 1px dashed var(--line); border-radius: var(--radius); text-align: center; }
.pv-card { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--panel); box-shadow: var(--shadow); margin-bottom: 1rem; }
.pv-top { display: flex; align-items: center; gap: .5rem; padding: .55rem .7rem; }
/* The post-preview avatar. Two contrast bugs lived here and neither shows up in a rule-by-rule
   scan: the fill is a gradient (so there is no single background colour to measure), and the
   Facebook variant overrides only the background in a separate rule while inheriting this rule's
   colour. White on the gradient's orange stop was 2.54:1; white on the dark theme's --brand was
   3.45:1. The stops are darkened enough to clear AA while still reading orange → pink → purple,
   and the Facebook variant now takes the same per-theme ink as every other brand fill. */
.pv-av { width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(135deg, #bb5909, #dc2477, #8134af); color: #fff; display: flex; align-items: center; justify-content: center; font-size: .72rem; font-weight: 700; flex: 0 0 auto; }
.pv-fb .pv-av { background: var(--brand); color: var(--brand-ink); }
.pv-name { font-weight: 600; font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-fmt { margin-left: auto; font-size: .68rem; text-transform: capitalize; background: var(--muted-bg); color: var(--muted); padding: 1px 8px; border-radius: 999px; flex: 0 0 auto; }
.pv-media { background: var(--muted-bg); aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.pv-media img, .pv-media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.pv-media-empty { color: var(--muted); font-size: .8rem; }
.pv-fb .pv-media { aspect-ratio: auto; max-height: 260px; }
.pv-below { padding: .5rem .7rem; }
.pv-cap { font-size: .86rem; line-height: 1.42; white-space: pre-wrap; word-break: break-word; }
.pv-link { display: inline-block; margin-top: .25rem; color: var(--brand); font-size: .84rem; word-break: break-all; }
.pv-link-text { color: var(--muted); }
.pv-actions { display: flex; gap: 1rem; padding: .45rem .7rem; font-size: 1.05rem; color: var(--ink); }
.pv-actions-fb { font-size: .8rem; color: var(--muted); border-top: 1px solid var(--line); gap: 1.1rem; }

/* Video generation controls (content studio): model / proportions / length selects + button */
.vid-form { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }

/* Content Studio: media gallery tiles + consolidated generate forms + preview grid */
.gen-gallery { display: flex; gap: 12px; flex-wrap: wrap; margin: .4rem 0 .8rem; }
.gen-fig { margin: 0; display: flex; flex-direction: column; gap: 4px; max-width: 280px; }
.gen-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.gen-forms { display: flex; gap: 14px; flex-wrap: wrap; margin: .4rem 0; }
.gen-form { flex: 1 1 320px; min-width: 280px; border: 1px solid var(--line); border-radius: var(--radius); padding: .7rem .8rem; background: var(--panel); display: flex; flex-direction: column; gap: .5rem; }
.gen-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.gen-lbl { display: block; font-size: .9rem; }
.gen-form textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: .85rem; padding: 6px 8px; border: 1px solid var(--field-line); border-radius: 7px; background: var(--bg); color: var(--ink); resize: vertical; }
.gen-form .btn { align-self: flex-start; }
.pv-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; max-width: 720px; }
@media (min-width: 720px) { .pv-grid { grid-template-columns: 1fr 1fr; } }
.pv-media video, .pv-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── AI Advisor ─────────────────────────────────────────────────────────────────────────────── */
.advisor-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; }
.advisor-card { display: flex; align-items: center; gap: 10px; text-align: left; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius, 10px); background: var(--panel); color: var(--ink); font: inherit; cursor: pointer; transition: border-color .12s, transform .12s; }
.advisor-card:hover { border-color: var(--brand); transform: translateY(-1px); }
.advisor-card-icon { font-size: 1.35rem; line-height: 1; }
.advisor-recs { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.advisor-rec { border: 1px solid var(--line); border-radius: var(--radius, 10px); padding: 10px 12px; background: var(--panel); }
.advisor-recents { list-style: none; margin: 0; padding: 0; }
.advisor-recents li { padding: 6px 0; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; gap: 10px; }
.advisor-recents li:last-child { border-bottom: 0; }
.advisor-ctxbar select[multiple] { min-height: 34px; }
.advisor-thread { display: flex; flex-direction: column; gap: 14px; max-height: 62vh; overflow-y: auto; padding: 4px 2px 8px; }
.advisor-msg { display: flex; flex-direction: column; gap: 3px; max-width: 88%; }
.advisor-user { align-self: flex-end; align-items: flex-end; }
.advisor-assistant { align-self: flex-start; }
.advisor-role { font-size: .72rem; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.advisor-bubble { border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; background: var(--panel); }
.advisor-user .advisor-bubble { background: var(--brand); color: var(--brand-ink, #fff); border-color: var(--brand); }
.advisor-user .advisor-bubble a { color: var(--brand-ink, #fff); text-decoration: underline; }
.advisor-bubble p:first-child { margin-top: 0; }
.advisor-bubble p:last-child { margin-bottom: 0; }
.advisor-bubble code { background: var(--muted-bg); padding: 1px 5px; border-radius: 4px; font-size: .9em; }
.advisor-pinned { background: var(--muted-bg); border-radius: 8px; padding: 6px 10px; }

/* ── Pipeline board ──────────────────────────────────────────────────────────────────────────── */
/* Horizontal scroll lives on the board, never the page body — a Kanban with nine stages must not
   make the whole layout slide sideways on a laptop. */
.pipe-board {
  display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; align-items: flex-start;
}
.pipe-col {
  flex: 0 0 260px; display: flex; flex-direction: column; gap: 8px;
  background: var(--muted-bg); border: 1px solid var(--line); border-radius: 8px; padding: 10px;
}
.pipe-head { display: flex; flex-direction: column; gap: 2px; }
.pipe-drop { display: flex; flex-direction: column; gap: 8px; min-height: 70px; border-radius: 6px; transition: background .12s ease; }
.pipe-drop.is-over { background: rgba(127, 127, 127, .14); outline: 2px dashed var(--line); outline-offset: 2px; }

.deal-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 10px;
  display: flex; flex-direction: column; gap: 4px; cursor: grab;
}
.deal-card:active { cursor: grabbing; }
.deal-card.is-dragging { opacity: .45; }
/* A rejected move has to be visible, or an optimistic UI quietly lies about what was saved. */
.deal-card.move-failed { outline: 2px solid var(--bad); outline-offset: 1px; }
.deal-name { font-weight: 600; }
.deal-value { font-variant-numeric: tabular-nums; font-weight: 600; }
.deal-actions { display: flex; gap: 4px; flex-wrap: wrap; }
.deal-move { display: flex; gap: 4px; align-items: center; }
.deal-move select { flex: 1; min-width: 0; font-size: .82rem; }

@media (prefers-reduced-motion: reduce) { .pipe-drop { transition: none; } }

/* Brand selector — sits in the topbar beside the AI Advisor button. Compact by design: it is a
   persistent control on every page, so it must not compete with the page's own content. */
.brand-switch { display: inline-flex; align-items: center; gap: .35rem; margin: 0; }
.brand-select {
  font-size: .82rem; padding: .28rem 1.6rem .28rem .5rem; max-width: 13rem;
  border: 1px solid var(--field-line); border-radius: 4px;
  background: var(--panel); color: var(--ink); line-height: 1.3;
}
.brand-select:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@media (max-width: 700px) { .brand-select { max-width: 8.5rem; } }

/* Channel category label. The channel groups below it are generated from the registry, so this is a
   heading for a run of them rather than a clickable thing — hence aria-hidden in the markup: a screen
   reader gets the channel names, which are the actual destinations. */
.nav-cat {
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 10px 12px 4px;
  margin-top: 4px;
}
.nav-cat:first-child { margin-top: 0; }

/* ── Media picker ─────────────────────────────────────────────────────────────────────────────────
   Choosing an image used to mean choosing a filename from a dropdown, and the library holds seven
   files called "Triple Magnesium" — so the only way to learn what you had picked was to attach it
   and look. These are ordinary radio inputs wearing thumbnails: no JavaScript (the CSP forbids
   inline script), full keyboard support, and the selected tile is visible at a glance. */
.media-pick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  max-height: 268px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--line, #ddd);
  border-radius: 10px;
  background: var(--panel, #fafafa);
}
.media-pick-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
  cursor: pointer;
  border-radius: 9px;
  padding: 5px;
  border: 2px solid transparent;
  /* The selected state must survive a theme change, so it is drawn from the accent token rather
     than a literal that only reads correctly on one background. */
  transition: border-color .12s ease, background-color .12s ease;
}
.media-pick-item:hover { background: var(--muted-bg); }
/* Visually hidden, NOT display:none — a hidden-by-display radio is unreachable by keyboard, and the
   whole control would then be unusable without a mouse. */
.media-pick-item input[type="radio"] {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.media-pick-thumb {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 7px;
  border: 1px solid var(--line, #ddd);
  background: var(--panel, #eee);
  display: block;
}
.media-pick-cap {
  font-size: .72rem;
  line-height: 1.25;
  word-break: break-word;
}
/* Adjacent-sibling selection works in every browser; :has() then adds the surrounding frame for the
   ones that support it. Either way the choice is visible. */
.media-pick-item input[type="radio"]:checked ~ .media-pick-thumb {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 30%, transparent);
}
.media-pick-item:has(input[type="radio"]:checked) {
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
/* Keyboard focus has to be visible, since the input itself is not. */
.media-pick-item:has(input[type="radio"]:focus-visible) {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* ── Numbered steps in a long builder form ────────────────────────────────────────────────────
   The Meta ad builder asks six things in order, and the operator scrolls back to change one of
   them constantly. A bare <h3> for each gave no edge to find, so every section looked like the
   middle of the previous one. The rule down the left is what separates them; the number is what
   you actually aim at.

   `.step-n` paints text on a filled surface, so it is one of the pairs the contrast test checks:
   --brand-ink on --brand is 5.52:1 light and 5.36:1 dark. The left rule uses --field-line, not
   --line: --line is the 1.24:1 hairline used between table rows and is invisible as an edge. */
.step { margin: 0 0 1.35rem; }
.step:last-of-type { margin-bottom: .6rem; }
.step-h { display: flex; align-items: baseline; gap: .55rem; margin: 0 0 .55rem; font-size: 1rem; font-weight: 650; }
.step-n {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.5rem; height: 1.5rem; border-radius: 999px;
  background: var(--brand); color: var(--brand-ink);
  font-size: .8rem; font-weight: 700; line-height: 1;
}
.step-sub { color: var(--muted); font-weight: 400; font-size: .85rem; }
/* The assistant sits INSIDE step 4, above the fields it writes into, so it reads as part of
   writing the ad rather than as a separate tool you have to go and find. */
.step-ai { background: var(--muted-bg); border: 1px solid var(--line); border-radius: var(--radius); padding: .7rem .8rem; margin: 0 0 .8rem; }

/* ── The Google copy step ──────────────────────────────────────────────────────────────────────
   Up to fifteen headlines, five long headlines and five descriptions, so the lines sit in a grid
   that gives one column on a phone and two or three on a desk. Short assets (30 characters) take
   the narrow track, long ones (90) the wide. A line with a problem keeps its field where it was
   and says why underneath, in the warning colour, so the grid never reflows around a message.
   `.gcopy-kind` is a fieldset: the legend names the asset and its limit, which a screen reader
   then announces for every field inside it. */
.gcopy-kind { border: 0; padding: 0; margin: 0 0 .9rem; }
.gcopy-kind > legend { font-weight: 600; color: var(--ink); font-size: .92rem; padding: 0; margin-bottom: .35rem; }
.gcopy-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px 12px; }
.gcopy-grid.gcopy-wide { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }
.gcopy-slot { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.gcopy-slot > label { flex-direction: row; gap: 6px; align-items: baseline; }
.gcopy-line { display: flex; align-items: center; gap: 8px; }
.gcopy-line input:not([type="checkbox"]) { flex: 1 1 auto; min-width: 0; }
.gcopy-keep { margin: 0; white-space: nowrap; }
.gcopy-slot.has-issue input:not([type="checkbox"]) { border-color: var(--warn); }
.gcopy-issue { color: var(--warn); margin: 0; }
.gcopy-alt { display: flex; flex-direction: row; align-items: baseline; margin: 2px 0; }
.gcopy-alt > span:first-of-type { overflow-wrap: anywhere; }

/* ── Ad-type / campaign-type cards ─────────────────────────────────────────────────────────────
   The builder now asks what KIND of ad this is, and the answer is 6–12 options depending on the
   platform. Built on the same bones as `.media-pick-item` — a visually hidden radio inside a label,
   never `display:none`, because a radio hidden that way cannot be reached by keyboard and the whole
   step becomes mouse-only.

   `auto-fill` with a 210px floor rather than a fixed column count: twelve Meta types and six Google
   ones have to look deliberate in the same grid, and the phone gets one column without a query. */
.adtype-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 8px;
  margin: .35rem 0 0;
}
.adtype-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  cursor: pointer;
  border: 2px solid var(--line, #ddd);
  border-radius: 9px;
  padding: 9px 10px;
  background: var(--panel);
  transition: border-color .12s ease, background-color .12s ease;
}
.adtype-card:hover { background: var(--muted-bg); }
.adtype-card input[type="radio"] {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.adtype-card:has(input[type="radio"]:checked) {
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
/* The input is invisible, so the focus ring has to be drawn on the card or keyboard users lose
   their place entirely. */
.adtype-card:has(input[type="radio"]:focus-visible) {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.adtype-name { font-weight: 600; font-size: .86rem; line-height: 1.25; }
.adtype-desc { font-size: .76rem; line-height: 1.3; color: var(--muted); }
.adtype-meta { font-size: .7rem; color: var(--muted); }
/* Prerequisites this app does not have — Merchant Center, an app listing. Said out loud on the card
   rather than discovered after a failed launch. */
.adtype-req { font-size: .7rem; line-height: 1.3; color: var(--warn); }

@media (max-width: 560px) {
  .adtype-grid { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------------------------
   STUDIO — the scene workspace.

   Everything here is built from the tokens above, so it follows the theme like the rest of the app.
   Two rules are load-bearing rather than decorative: state on a timeline block is carried by a LABEL
   as well as a fill, because a band of coloured rectangles is unreadable to anyone who cannot
   separate the hues; and the segmented Film/Generate control uses --field-line, which is the border
   token dark enough for WCAG 1.4.11 (3:1 for a control edge) — --line is not.
   --------------------------------------------------------------------------------------------- */
.st-eyebrow { text-transform: uppercase; letter-spacing: .08em; font-size: .7rem; font-weight: 700; color: var(--muted); margin: 0 0 .2rem; }
.st-sub { margin: 0 0 1rem; font-size: .9rem; }

.st-band { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 14px 16px; margin-bottom: 1rem; }
.st-band-top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: .5rem; }
.st-state { font-size: .88rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.st-state b { color: var(--ink); }

.st-track { display: flex; gap: 3px; height: 46px; }
.st-blk { flex: 1; min-width: 34px; border-radius: 6px; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 1px; overflow: hidden; padding: 0 2px; }
.st-blk-n { font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.st-blk-s { font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; }
.st-b-unplanned { background: var(--muted-bg); color: var(--muted); }
.st-b-generate { background: var(--muted-bg); color: var(--ink); border: 1px dashed var(--field-line); }
.st-b-film { background: var(--warn-bg); color: var(--warn); }
.st-b-ready { background: var(--ok-bg); color: var(--ok); }

.st-band-act { margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.st-band-act p { margin: 0; }

/* The confirmation opens where the eye already is rather than in a modal, and it is also where one
   press becomes one, some or all. `summary` is styled as the button it replaces. */
.st-confirm > summary { display: inline-block; list-style: none; cursor: pointer; }
.st-confirm > summary::-webkit-details-marker { display: none; }
.st-confirm[open] > summary { margin-bottom: .7rem; }
.st-confirm-hd { font-weight: 600; margin: 0 0 .4rem; font-size: .92rem; }
/* `flex-direction: row` AND `color`, both of which look redundant and are not.
   `app.css` line 153 sets `label { display: flex; flex-direction: column; color: var(--muted) }` for
   the ordinary "caption above the input" case. A class on a <label> that sets `display:flex` but not
   the direction therefore inherits COLUMN, and `align-items: center` in a column axis centres
   horizontally: every row rendered as a four-item vertical stack, ~103px tall instead of ~35px. Not
   setting `color` left the row's own name in the grey meant for small print, the same colour and
   nearly the same size as its footnote. The house already has `.check` for exactly this. */
.st-pick { display: flex; flex-direction: row; align-items: center; color: var(--ink); gap: .6rem; padding: .35rem 0; border-bottom: 1px solid var(--line); font-size: .9rem; }
.st-pick-n { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--muted); min-width: 1.2rem; }
.st-pick-t { flex: 1; }
.st-pick-c { font-variant-numeric: tabular-nums; color: var(--muted); font-size: .84rem; }

.st-section { font-size: .95rem; margin: 1.2rem 0 .5rem; }
.st-scene { padding: 12px 14px; margin-bottom: .6rem; }
.st-top { display: flex; gap: 14px; align-items: flex-start; }
.st-slot { min-width: 4.2rem; text-align: center; font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.st-slot b { display: block; font-size: 1.1rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.st-body { flex: 1; min-width: 0; }
.st-shot-line { margin: 0 0 .25rem; }
.st-why { margin: 0; font-size: .85rem; color: var(--muted); }
.st-meta { margin-top: .35rem; }
.st-chip { display: inline-block; font-size: .76rem; background: var(--muted-bg); color: var(--muted); border-radius: 999px; padding: 2px 9px; }
.st-time { text-align: right; font-size: .78rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.st-time b { display: block; color: var(--ink); font-size: .95rem; }
.st-note { font-size: .85rem; margin: .5rem 0 0; }
.st-note.warn { color: var(--warn); }

.st-seg { display: flex; border: 1px solid var(--field-line); border-radius: 8px; overflow: hidden; align-self: center; }
.st-seg button { border: 0; background: var(--panel); color: var(--muted); font: inherit; font-size: .82rem; padding: .3rem .7rem; cursor: pointer; }
.st-seg button + button { border-left: 1px solid var(--field-line); }
.st-seg button[aria-pressed="true"] { background: var(--brand); color: var(--brand-ink); }

.st-film { display: flex; gap: .6rem; align-items: flex-end; flex-wrap: wrap; margin-top: .6rem; }
.st-film label { margin: 0; font-size: .82rem; }

/* One platform inside a shape group. Same direction/colour rule as `.st-pick` above. The row is the
   hit target, not the 13px box: a checkbox alone is half the 24px WCAG minimum. */
.st-out { display: flex; flex-direction: row; align-items: center; color: var(--ink); gap: .55rem; padding: .15rem .3rem; min-height: 34px; border-radius: 6px; font-size: .9rem; cursor: pointer; }
.st-out:hover { background: var(--muted-bg); }
.st-out input { width: 17px; height: 17px; margin: 0; accent-color: var(--brand); }
.st-out-n { flex: 1; }
.st-out-s { font-size: .82rem; color: var(--muted); }
.st-out-s.cost { color: var(--warn); }
/* THE SHAPE IS THE DECISION, so it is a group with the price on its legend rather than eight rows
   that each have to be read and compared. Five of the eight platforms are the same tall frame. */
.st-frameset { border: 1px solid var(--field-line); border-radius: var(--radius); padding: .45rem .7rem .55rem; margin: 0 0 .7rem; }
.st-frameset:has(input:checked) { border-color: var(--brand); }
/* A real <legend> now, so the shape and its price are announced with the group. */
.st-frameset-lg { display: flex; align-items: center; gap: .5rem; width: 100%; font-weight: 600; font-size: .92rem; color: var(--ink); padding: 0 0 .3rem; }
.st-frameset-c { margin-left: auto; font-weight: 400; font-size: .82rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.st-frameset-c.cost { color: var(--warn); font-weight: 600; }
/* The platforms are INDENTED under their shape. Without this the group's shape swatch sat 5px from
   the checkbox column below it and read as one more unticked box, in a list of unticked boxes. */
.st-frameset .st-out { padding-left: 1.7rem; }
.st-main { font-size: .66rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; background: var(--muted-bg); color: var(--muted); border-radius: 999px; padding: 1px 7px; }
/* Once the choice is made it collapses to one line, so the scenes move up to where the work is. */
.st-shapes > summary { cursor: pointer; font-size: .9rem; color: var(--ink); }
.st-shapes > summary::-webkit-details-marker { display: none; }
.st-shapes > summary .st-change { color: var(--brand); margin-left: .4rem; }
.st-shapes[open] > summary { margin-bottom: .7rem; }
/* ── Storyboard (Phase II S1) ─────────────────────────────────────────────────────────────────
   A board is read as a SEQUENCE, so the panels are a grid of equal cells in reading order and the
   number is drawn on the artwork rather than left to the list marker — an operator types those
   numbers into the reorder box, so they have to be legible against the picture. */
.st-panels { list-style: none; margin: .8rem 0 0; padding: 0; display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.st-panel { position: relative; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: 8px; display: flex; flex-direction: column; gap: 6px; }
/* The artwork sets the cell's height, and a tall panel is letterboxed rather than allowed to
   stretch the row it sits in. */
.st-panel img { width: 100%; height: 150px; object-fit: contain; background: var(--muted-bg);
  border-radius: 2px; display: block; }
.st-panel-no { position: absolute; top: 12px; left: 12px; min-width: 1.4rem; text-align: center;
  background: var(--ink); color: var(--panel); border-radius: 3px; font-size: .75rem;
  font-weight: 700; padding: 1px 5px; }
/* `display:flex` on a form that contains a label — so the direction is set explicitly, because
   `label { flex-direction: column }` would otherwise win and stack the row into a tower. */
.st-panel-note { display: flex; flex-direction: row; gap: 6px; align-items: center; }
.st-panel-note input { flex: 1 1 auto; min-width: 0; font-size: .8rem; }
.st-reorder { display: flex; flex-direction: row; gap: 10px; align-items: flex-end;
  flex-wrap: wrap; margin-top: .8rem; }
.st-reorder input { min-width: 220px; }
/* The confirmation for an irreversible delete. A disclosure rather than confirm(), which the CSP blocks. */
.st-panel-del > summary { cursor: pointer; font-size: .8rem; color: var(--bad-ink); }
.st-panel-del[open] > summary { margin-bottom: .3rem; }
/* A scene's storyboard panels, beside the words that describe it. Small, because the scene row is the
   place to read and decide, and the board card is the place to look closely. */
.st-scene-panels { display: flex; flex-direction: row; gap: 6px; flex-wrap: wrap; margin: 0 0 .4rem; }
.st-scene-panels figure { margin: 0; display: flex; flex-direction: column; gap: 2px; }
.st-scene-panels img { width: 72px; height: 48px; object-fit: contain; background: var(--muted-bg);
  border: 1px solid var(--line); border-radius: 2px; display: block; }
.st-scene-panels figcaption { font-size: .7rem; color: var(--muted); }

/* A drawn frame, so the shape is visible rather than only named. */
.st-ar { display: inline-block; border: 1.5px solid var(--field-line); border-radius: 2px; }
.st-ar-916 { width: 11px; height: 20px; }
.st-ar-45 { width: 16px; height: 20px; }
.st-ar-11 { width: 18px; height: 18px; }
.st-ar-169 { width: 26px; height: 15px; }

.st-fine { font-size: .84rem; color: var(--muted); margin-top: 1rem; }
.st-fine p { margin: 0 0 .5rem; }

@media (max-width: 720px) {
  .st-top { flex-wrap: wrap; }
  .st-time { text-align: left; }
  .st-blk-s { display: none; }
}
.st-again { display: flex; gap: .6rem; align-items: center; margin-top: .6rem; font-size: .82rem; }
/* One tab per frame that has to be shot. Only rendered when a brief needs more than one. */
.st-frames { display: flex; gap: .4rem; margin-bottom: .6rem; }
.st-frame { font-size: .8rem; padding: .25rem .7rem; border: 1px solid var(--field-line); border-radius: 999px; color: var(--muted); font-variant-numeric: tabular-nums; }
.st-frame span { opacity: .75; }
.st-frame.on { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); }
.st-frame.on span { opacity: .9; }
.st-frame:hover { text-decoration: none; }
/* The prompt, where the owner can read and change it. Collapsed by default: on a six-scene brief six
   open textareas is a wall, and the ordinary case is not editing but generating. */
.st-prompt { margin-top: .6rem; }
.st-prompt > summary { cursor: pointer; font-size: .84rem; color: var(--ink); }
.st-prompt > summary::-webkit-details-marker { display: none; }
.st-prompt textarea { width: 100%; margin-top: .4rem; font: inherit; font-size: .86rem; line-height: 1.45; color: var(--ink); background: var(--panel); border: 1px solid var(--field-line); border-radius: 8px; padding: 8px 10px; resize: vertical; }
.st-prompt-acts { display: flex; gap: .5rem; margin-top: .4rem; flex-wrap: wrap; }

/* One finished cut per shape: the row this whole page exists to produce. `.st-cut-s.cost` and not a
   bare `.cost` — the warn colour in this file is always qualified by the element it sits on. */
.st-cut { display: flex; flex-direction: row; align-items: center; gap: .6rem; padding: .45rem 0; border-bottom: 1px solid var(--line); font-size: .9rem; color: var(--ink); }
.st-cut-n { flex: 1; }
.st-cut-s { font-size: .82rem; color: var(--muted); }
.st-cut-s.cost { color: var(--warn); }
.st-cut form { margin: 0; }
/* THE CUT, WATCHABLE IN PLACE. A bare <video> takes its intrinsic size, and these are 1080x1920:
   without a cap it renders a metre tall and pushes the page sideways on a phone. Capped by HEIGHT
   because the tall shape is the common one, and `width:auto` then keeps every shape's own aspect. */
.st-cut-v { display: block; height: 220px; width: auto; max-width: 100%; margin: .1rem 0 .7rem; border-radius: 6px; background: var(--line); }
/* Storyboard S3: the shots inside a scene, their references by role, and their takes. */
.st-shots { margin-top: .5rem; border-top: 1px solid var(--line); padding-top: .4rem; }
.st-shots > summary { cursor: pointer; font-weight: 600; }
.st-shotlist { list-style: none; margin: .4rem 0; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.st-shot { border: 1px solid var(--line); border-radius: var(--radius); padding: .5rem .6rem; background: var(--panel); }
.st-shot-hd { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem; margin-bottom: .3rem; }
.st-refs, .st-takes { list-style: none; margin: .3rem 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; font-size: .88rem; }
.st-refs li, .st-takes li { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.st-takes li.on { font-weight: 600; }
.st-ref-thumb { width: 48px; height: 48px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
.st-inline { display: inline-flex; margin: 0; }
.st-ask { margin: .2rem 0 .4rem; padding: .4rem .5rem; background: var(--muted-bg); border-radius: 6px; font-size: .9rem; }
.st-shot-more { margin-top: .4rem; }
.st-shot-more > summary { cursor: pointer; font-size: .84rem; color: var(--ink); }
.st-shot-more textarea, .st-shot-more input[type="text"], .st-shot-more input:not([type]) { width: 100%; margin-top: .3rem; font: inherit; font-size: .86rem; color: var(--ink); background: var(--panel); border: 1px solid var(--field-line); border-radius: 8px; padding: 6px 8px; }
/* Phase 1.6 D: the project's sound. */
.st-sound-card h3 { font-size: .95rem; margin: .8rem 0 .3rem; }
.st-write-lock { border: 0; margin: 0; padding: 0; min-width: 0; }
.st-write-lock-note { font-size: .85rem; margin: .5rem 0; padding: .35rem .6rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--muted-bg); color: var(--muted); }
.st-sound { border: 1px solid var(--line); border-radius: var(--radius); padding: .45rem .6rem; background: var(--panel); display: flex; flex-direction: column; gap: .3rem; }
.st-sound-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .45rem; font-size: .85rem; }
.st-sound-form label { display: flex; flex-direction: column; gap: 2px; }
.st-sound-form input[type="number"] { width: 5.5rem; }
.st-sound-form .st-check { flex-direction: row; align-items: center; gap: 4px; }
.st-sound audio, .st-sound-card .st-takes audio { display: block; max-width: 100%; margin-top: .25rem; }

/* ── REDESIGN CUT B: Command Center, channel tabs, wide-screen reading widths ──────────────────────── */

/* Readable measure on a wide page (Luis: about 72 characters): a paragraph in a card stops at 72ch, and a form field
   is never wider than it was when the workspace stopped at 1100px (1100 less the page and card padding).
   Tables and dashboards are left to use the width. */
.card p, .card li { max-width: 72ch; }
.content :is(textarea, select, input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"])) { max-width: min(100%, 1014px); }
.grid-form { max-width: 1052px; }

/* THE COMMAND CENTER: on a wide screen the decisions keep the wider column and the standing of the business
   sits beside them, in the same reading order as the single column below 1400px (where the side column
   would be too narrow for its four-column tables). */
.home-cols { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: 20px; align-items: start; }
@media (min-width: 1400px) { .home-cols { grid-template-columns: minmax(0, 5fr) minmax(0, 4fr); } }
.card-sub { font-size: .76rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: .3rem 0 .25rem; }
.card-sub:not(:first-child) { margin-top: 1rem; }
.table-compact th, .table-compact td { padding: 6px 8px; }
.table-compact td.num, .table-compact th.num { font-variant-numeric: tabular-nums; }
.table-compact .badge, .nowrap { white-space: nowrap; }
/* A row header reads as the row's name, not as another column heading. */
.table tbody th[scope="row"] { text-align: left; text-transform: none; letter-spacing: 0; font-size: .92rem; font-weight: 600; color: var(--ink); padding: 9px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.table-compact tbody th[scope="row"] { padding: 6px 8px; }
.health-list { list-style: none; margin: 0; padding: 0; }
.health-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 7px 0; border-top: 1px solid var(--line); }
.health-row:first-child { border-top: 0; }
.health-name { font-weight: 600; min-width: 9rem; }
.health-note { flex-basis: 100%; }

/* THE CHANNEL TABS: the existing pill tabs, wrapping instead of widening the page, in the words the pages
   use (no forced capitals), with a hover and a touch-sized target below a laptop. */
.channel-tabs { flex-wrap: wrap; margin: 0 0 16px; }
.channel-tabs .tab { text-transform: none; }
.channel-tabs .tab:hover { text-decoration: none; color: var(--ink); background: var(--line); }
.channel-tabs .tab.active:hover { color: var(--brand-ink); background: var(--brand); }
@media (max-width: 1023px) { .channel-tabs .tab { display: inline-flex; align-items: center; min-height: 40px; padding: 8px 14px; } }

/* The sync page's run notes are long unbroken strings: they wrap inside their own cell. */
.sync-detail { overflow-wrap: anywhere; min-width: 16ch; }

/* ── REDESIGN CUT C: the shared primitives and the table/responsive contract ─────────────────────── */

/* THE TABLE SHELL. A card contains whatever it holds at every width: a table wider than its card scrolls
   inside the card and never widens the page (1024px, where the rail returns and content is 720px wide,
   overflowed on four pages before this). Scroll boxes are POSITIONED so an absolutely positioned child,
   such as a screen-reader-only label in a table header, is clipped by them instead of stretching the
   page from outside: that one property was the whole of the phone-width overflow on seven pages. */
.card { overflow-x: auto; position: relative; }
.table-scroll { position: relative; }
@media (max-width: 1023px) { .table { min-width: min-content; } }
/* A figure is never cut in two. Below 761px a card lets long words break anywhere (for a URL or SKU in
   prose), and a table's narrowest width is measured from those breaks, so a squeezed table printed
   "$105. / 50" on Meta's Ads health. Inside a table a word too long for its column widens the table
   instead, and the table scrolls inside its card. The sync page's run notes keep their own rule. */
.table td, .table th { overflow-wrap: normal; }
.table .sync-detail { overflow-wrap: anywhere; }

/* THE FORM CONTRACT. A <select> is as wide as its longest option and a fieldset is as wide as its
   content by default; neither may be wider than the form it sits in. A label is a flex item that may
   shrink. */
label { min-width: 0; }
select { max-width: 100%; }
fieldset { min-width: 0; }

/* THE ACTION ROW. A row of buttons wraps rather than running off its card. */
.row { flex-wrap: wrap; }

/* BANNER TONES used across the app and never defined (they rendered as bare text). */
.banner-info { background: var(--muted-bg); color: var(--ink); }
.banner-muted { background: var(--muted-bg); color: var(--muted); }
.banner-bad { background: var(--bad-bg); color: var(--bad); }

/* THE ITEM ROW: one finding, task or decision inside a card, separated from the next by a hairline.
   Severity is the badge in its head (a word and a colour), never a coloured edge on one side. */
.item { padding: .6rem 0; border-top: 1px solid var(--line); }
.item-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px 10px; flex-wrap: wrap; }
.item-head.lead { justify-content: flex-start; }
.item-body { margin-top: .3rem; }
.item-actions { margin-top: .5rem; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

/* THE EMPTY STATE: what a panel says when it has nothing, in one voice. */
.empty { color: var(--muted); margin: 0; }


/* ── THE GOAL BUILDER (2026-09-24): the New Goal page's "Describe your goal" card ─────────────────── */
/* A field the builder could not settle, under the control it belongs to: a badge and the reason, never a coloured edge. */
.field-review { display: block; margin-top: .3rem; font-size: .82rem; line-height: 1.4; color: var(--ink); }
.field-review .badge { margin-right: .35rem; }
/* The form grid lines its controls up along the bottom; a row that carries a review note lines them up along the top instead,
   so a control with a note under it stays level with its neighbours. */
.grid-form:has(.field-review) { align-items: start; }
/* The one follow-up question: a row per choice, each a full-width touch target. */
.builder-question fieldset { border: 0; padding: 0; margin: 0 0 .6rem; }
.builder-question legend { font-weight: 600; color: var(--ink); margin-bottom: .3rem; }
.choice { flex-direction: row; align-items: center; gap: .55rem; min-height: 44px; font-size: .92rem; color: var(--ink); border-top: 1px solid var(--line); }
.choice input[type="radio"] { width: 1.05rem; height: 1.05rem; padding: 0; margin: 0; flex: none; accent-color: var(--brand); }
.builder-h { font-size: .8rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: .9rem 0 .3rem; }
.builder-list { list-style: none; padding: 0; margin: 0; }
.builder-list li { padding: .4rem 0; border-top: 1px solid var(--line); }
textarea[name="intent"] { width: 100%; box-sizing: border-box; resize: vertical; line-height: 1.5; }

/* V2-G: Reference Strength on a Shot's reference, the same segmented look as the Film / Generate switch. */
.st-strength { display: grid; gap: .25rem; margin: .4rem 0 0; }
.st-strength-title { font-size: .78rem; color: var(--muted); }
.st-strength-set { display: inline-flex; border: 1px solid var(--field-line); border-radius: 8px; overflow: hidden; justify-self: start; }
.st-strength-set button { border: 0; background: var(--panel); color: var(--muted); font: inherit; font-size: .82rem; padding: .3rem .7rem; cursor: pointer; }
.st-strength-set button + button { border-left: 1px solid var(--field-line); }
.st-strength-set button[aria-pressed="true"] { background: var(--brand); color: var(--brand-ink); }
.st-strength-set button[disabled] { cursor: not-allowed; opacity: .55; }
.st-strength-help { font-size: .8rem; }
.st-strength-note, .st-strength-locked { font-size: .76rem; color: var(--muted); margin: .3rem 0 0; }
