/* ============================================================================
   MentionBeat — "Graphite" design system
   Dark graphite hero + cool-white canvas + lively coral accent.
   Shared by the landing (/), auth (/login), free checker (/checker) and the
   authenticated console (/app). Colours are exposed as CSS variables so the
   hand-built SVG charts and the measurement renderers re-theme automatically.
   ============================================================================ */

:root {
  /* Brand + accents */
  --accent: #EC6B4C;         /* primary actions, active nav, key bars, links */
  --accent-text: #C24E2E;    /* accent text on light */
  --accent-soft: #FBEAE3;    /* active nav bg, accent pills, avatar bg */
  --accent-grad: linear-gradient(180deg, #F17A5A, #DE5A38);

  /* Neutrals */
  --ink: #141821;            /* headings, dark cards, strong text */
  --body: #2A2F3A;           /* primary body text */
  --muted: #5D6472;          /* secondary text (darkened for WCAG AA at small sizes) */
  --faint: #7E8694;          /* captions, eyebrows, sub-labels (darkened for contrast) */
  --canvas: #F6F7F9;         /* app background */
  --sidebar: #FBFCFD;        /* sidebar + table header rows */
  --surface: #FFFFFF;        /* cards */
  --line: #E6E9EE;           /* card & control borders */
  --line-light: #EDEFF3;     /* inner dividers, bar tracks */
  --line-hover: #D5DAE1;     /* control hover border */
  --neutral-bar: #D5DAE1;    /* competitor / neutral bars */

  /* Dark hero */
  --hero: radial-gradient(125% 125% at 82% -12%, #2C2E33 0%, #1A1C20 55%, #111316 100%);
  --hero-spark: #F5895F;
  --hero-sub: #A6ACB5;
  --hero-foot: #8A9099;

  /* Semantic */
  --ok: #0E7A5F;        --ok-bg: #E6F5EE;   --ok-border: #BFE3D5;
  --warn: #A86512;      --warn-bg: #FBF2E0;
  --danger: #B23A2E;    --danger-bg: #FBEAE7;
  --pos: #1F9D6B;       /* up deltas / trends */
  --neg: #C0392B;       /* down trends */

  /* Legacy aliases used by inline var() styles in checker.html + charts */
  --brand: var(--accent);
  --brand-dark: var(--accent-text);
  --bg: var(--canvas);
  --soft: var(--sidebar);
  --radius: 14px;

  --display: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --sans: "Instrument Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, Menlo, "SFMono-Regular", monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--sans);
  color: var(--body);
  background: var(--canvas);
  line-height: 1.55;
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}
::selection { background: #FBD9CD; }
a { color: var(--accent-text); text-decoration: none; }
a:hover { color: var(--accent); }
h1, h2, h3 { color: var(--ink); line-height: 1.2; margin: 0; }
.display { font-family: var(--display); letter-spacing: -0.02em; }
code, pre, .mono { font-family: var(--mono); }

/* Smooth, cheap transitions for interactive things */
a, button, input, select, .clickable, .nav a, .tool, .vcard.click, tr[data-click] {
  transition: background .2s ease, border-color .2s ease, color .18s ease,
              box-shadow .24s ease, transform .22s cubic-bezier(.2,.7,.2,1), filter .18s ease;
}

/* Scrollbar */
.scroll::-webkit-scrollbar { width: 9px; height: 9px; }
.scroll::-webkit-scrollbar-thumb { background: #d3d7dd; border-radius: 8px; border: 2px solid var(--canvas); }

/* Motion */
@keyframes vUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes vFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes vDraw { to { stroke-dashoffset: 0; } }
@keyframes vGlow { 0%,100% { opacity: .55; transform: scale(1); } 50% { opacity: .9; transform: scale(1.08); } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 16px; border-radius: 10px; font-weight: 600; font-size: 13px;
  border: 1px solid transparent; cursor: pointer; font-family: inherit; line-height: 1;
}
.btn-primary { background: var(--accent-grad); color: #fff; box-shadow: 0 8px 18px -8px rgba(236,107,76,.5); }
.btn-primary:hover { filter: brightness(1.04); color: #fff; }
.btn-ghost { background: var(--surface); border-color: var(--line); color: var(--ink); font-weight: 600; }
.btn-ghost:hover { border-color: var(--line-hover); color: var(--ink); }
.btn-dark { background: var(--ink); color: #fff; }
.btn-dark:hover { filter: brightness(1.15); color: #fff; }
.btn-sm { padding: 7px 12px; font-size: 12.5px; border-radius: 9px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn svg { display: block; }

/* ==========================================================================
   Pills / badges (also used by measurement renderers)
   ========================================================================== */
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700; line-height: 1.3; }
.pill.published, .pill.ok    { background: var(--ok-bg); color: var(--ok); }
.pill.draft, .pill.neutral   { background: #F1F3F6; color: var(--muted); }
.pill.review, .pill.warn     { background: var(--warn-bg); color: var(--warn); }
.pill.archived, .pill.danger { background: var(--danger-bg); color: var(--danger); }
.pill.accent { background: var(--accent-soft); color: var(--accent-text); }

/* ==========================================================================
   Forms
   ========================================================================== */
label { display: block; font-weight: 700; font-size: 11px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 6px; }
input, select, textarea {
  width: 100%; padding: 9px 12px; border: 1px solid var(--line); border-radius: 9px;
  font-size: 13.5px; font-family: inherit; color: var(--ink); background: var(--surface);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(236,107,76,.12); }
.field-soft input, .field-soft select, input.soft, select.soft { background: var(--canvas); }
.msg { margin-top: 12px; padding: 10px 12px; border-radius: 9px; font-size: 13px; display: none; }
.msg.error { background: var(--danger-bg); color: var(--danger); display: block; }
.msg.ok { background: var(--ok-bg); color: var(--ok); display: block; }
.auth-link { font-size: 13px; color: var(--accent); text-decoration: none; }
.auth-link:hover { text-decoration: underline; }

/* ==========================================================================
   Utilities
   ========================================================================== */
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.muted { color: var(--muted); }
.faint { color: var(--faint); }
.hidden { display: none !important; }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
/* Label only — no leading glyph. The uppercase accent-coloured, letter-spaced
   text carries the eyebrow on its own; a decorative square just added noise. */
.eyebrow-row { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 700;
  letter-spacing: .11em; text-transform: uppercase; color: var(--accent-text); }

/* ==========================================================================
   LANDING / MARKETING (index.html) + shared top bar (checker.html)
   ========================================================================== */
.topbar { background: var(--surface); border-bottom: 1px solid var(--line); }
.topbar .wrap { display: flex; align-items: center; justify-content: space-between; height: 62px; }
.brand { font-family: var(--display); font-weight: 700; font-size: 18px; letter-spacing: -0.01em;
  color: var(--ink); display: inline-flex; align-items: center; gap: 9px; }
.brand .logo { width: 28px; height: 28px; border-radius: 8px; background: var(--accent);
  display: inline-flex; align-items: center; justify-content: center; }
.topbar .nav { display: flex; flex-direction: row; flex-wrap: wrap; gap: 22px; align-items: center; }
.topbar .nav a { color: var(--body); font-weight: 500; }
.topbar .nav a:hover { color: var(--ink); }
.topbar .nav a.btn { color: #fff; }

.hero { background: var(--canvas); padding: 84px 0 56px; }
.hero h1 { font-family: var(--display); font-size: 2.9rem; letter-spacing: -0.03em; margin: 0 0 16px; color: var(--ink); }
.hero p.lead { font-size: 1.2rem; color: var(--muted); max-width: 60ch; margin: 0 0 26px; line-height: 1.5; }
.loop { display: flex; gap: 10px; flex-wrap: wrap; margin: 26px 0; }
.loop .step { background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 16px; font-weight: 700; color: var(--ink); font-size: .95rem; }
.loop .step span { display: block; font-weight: 400; color: var(--faint); font-size: .8rem; margin-top: 3px; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; margin: 30px 0; }
.card { border: 1px solid var(--line); border-radius: 14px; padding: 22px; background: var(--surface); }
.card h3 { margin: 0 0 8px; font-family: var(--display); font-size: 1.05rem; }
.card .eyebrow { color: var(--accent-text); font-weight: 700; font-size: .72rem; text-transform: uppercase; letter-spacing: .09em; }
section.band { padding: 52px 0; }
section.band.alt { background: var(--sidebar); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
section.band h2 { font-family: var(--display); font-size: 1.9rem; letter-spacing: -0.02em; margin: 0 0 22px; }

.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }
.plan { border: 1px solid var(--line); border-radius: 16px; padding: 26px; background: var(--surface); }
.plan h3 { font-family: var(--display); font-size: 1.2rem; }
.plan.featured { border-color: var(--accent); box-shadow: 0 12px 34px -12px rgba(236,107,76,.35); }
.plan .price { font-family: var(--display); font-size: 2rem; font-weight: 700; color: var(--ink); margin: 8px 0; }
.plan ul { padding-left: 18px; color: var(--muted); font-size: .95rem; }
.plan ul li { margin: 4px 0; }
.plan .btn { width: 100%; margin-top: 8px; }

footer { border-top: 1px solid var(--line); padding: 28px 0; color: var(--muted); font-size: .9rem; margin-top: 20px; background: var(--surface); }
footer a { color: var(--muted); }
footer a:hover { color: var(--ink); }

/* ==========================================================================
   AUTH (login.html)
   ========================================================================== */
/* Split layout: graphite brand half + light form half. The dark side is the
   same --hero used by the console's Overview band, so signing in and landing
   in the app feel like one product rather than two. */
.auth { min-height: 100vh; display: grid; grid-template-columns: 1.05fr .95fr; background: var(--canvas); }
.auth-brand { background: var(--hero); color: #fff; position: relative; overflow: hidden;
  padding: 52px 56px; display: flex; flex-direction: column; }
.auth-brand::after { content: ""; position: absolute; right: -14%; top: -18%; width: 62%; height: 78%;
  background: radial-gradient(closest-side, rgba(245,137,95,.32), transparent 72%);
  pointer-events: none; animation: vGlow 7s ease-in-out infinite; }
.auth-brand > * { position: relative; z-index: 1; }
.auth-brand .brand { color: #fff; margin-bottom: auto; }
.auth-brand h1 { font-family: var(--display); font-size: 2.3rem; line-height: 1.15; letter-spacing: -.03em;
  color: #fff; margin: 40px 0 16px; }
.auth-brand > p { color: var(--hero-sub); font-size: 14.5px; line-height: 1.65; max-width: 46ch; margin: 0 0 32px; }

/* Proof, not adjectives: one answer shaped like the ones we capture. */
.auth-proof { background: rgba(255,255,255,.055); border: 1px solid rgba(255,255,255,.1);
  border-radius: 14px; padding: 16px 18px; max-width: 480px; }
.ap-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.ap-q { flex: 1; font-size: 12.5px; color: #fff; font-weight: 600; }
.ap-tag { flex: none; font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--hero-foot); border: 1px solid rgba(255,255,255,.18); border-radius: 999px; padding: 2px 7px; }
.ap-a { font-size: 12.5px; line-height: 1.65; color: var(--hero-sub); margin: 0 0 14px;
  padding-top: 12px; border-top: 1px solid rgba(255,255,255,.09); }
.ap-a mark { background: rgba(245,137,95,.22); color: #FFB79B; border-radius: 3px; padding: 0 3px; font-weight: 600; }
.ap-bars { display: flex; flex-direction: column; gap: 7px; }
.ap-bar { display: flex; align-items: center; gap: 10px; font-size: 11px; }
.ap-bar .l { flex: none; width: 34px; color: var(--hero-sub); }
.ap-bar i { flex: 1; height: 7px; border-radius: 999px; background: rgba(255,255,255,.1); position: relative; }
.ap-bar i::after { content: ""; position: absolute; inset: 0 auto 0 0; width: var(--w);
  border-radius: 999px; background: var(--hero-spark); }
.ap-bar.dim i::after { background: rgba(255,255,255,.28); }
.ap-bar b { flex: none; width: 30px; text-align: right; color: #fff; font-variant-numeric: tabular-nums; }

.auth-engines { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 28px; }
.auth-engines .e { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--hero-foot); }
.auth-engines .e i { width: 7px; height: 7px; border-radius: 50%; }

.auth-form { display: grid; place-items: center; padding: 40px 24px; }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: 34px;
  width: 100%; max-width: 400px; box-shadow: 0 20px 60px -34px rgba(20,24,33,.25); }
.panel .brand { justify-content: flex-start; margin-bottom: 6px; }
.tabs { display: flex; gap: 6px; margin: 0 0 16px; background: #F1F3F6; padding: 3px; border-radius: 11px; }
.tabs button { flex: 1; padding: 9px; border: none; background: transparent; border-radius: 8px;
  cursor: pointer; font-weight: 600; font-family: inherit; color: var(--muted); font-size: 13px; }
.tabs button.active { background: var(--surface); color: var(--accent-text); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.panel label { margin-top: 14px; }
.auth-lede { font-size: 13px; color: var(--muted); line-height: 1.55; margin: 0 0 4px; }
.auth-fine { font-size: 11.5px; color: var(--faint); line-height: 1.5; margin: 14px 0 0; }
.auth-or { display: flex; align-items: center; gap: 10px; margin: 18px 0 12px;
  font-size: 11px; color: var(--faint); text-transform: uppercase; letter-spacing: .08em; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

@media (max-width: 900px) {
  /* Stack, and drop the proof block — on a phone the form is the whole job. */
  .auth { grid-template-columns: 1fr; }
  .auth-brand { padding: 30px 22px 26px; }
  .auth-brand h1 { font-size: 1.7rem; margin: 22px 0 12px; }
  .auth-brand > p { margin-bottom: 0; }
  .auth-proof, .auth-engines { display: none; }
  .auth-form { padding: 26px 20px 40px; }
}
@media (prefers-reduced-motion: reduce) { .auth-brand::after { animation: none; opacity: .7; } }

/* ==========================================================================
   APP SHELL  (app.html)
   ========================================================================== */
.app { display: flex; min-height: 100vh; width: 100%; background: var(--canvas);
  color: var(--body); animation: vFade .5s ease both; }

/* --- Sidebar --- */
.side { width: 236px; flex: none; background: var(--sidebar); border-right: 1px solid #EAEDF1;
  display: flex; flex-direction: column; padding: 22px 16px; position: sticky; top: 0; height: 100vh; }
.brandlock { display: flex; align-items: center; gap: 10px; padding: 2px 8px 22px; }
.brandlock .logo { width: 30px; height: 30px; border-radius: 9px; background: var(--accent);
  display: flex; align-items: center; justify-content: center; }
.brandlock .word { font-family: var(--display); font-weight: 600; font-size: 17px; color: var(--ink); letter-spacing: -.01em; }

.wsswitch { position: relative; margin-bottom: 20px; }
.wsswitch > button { display: flex; align-items: center; gap: 9px; width: 100%; background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; cursor: pointer; font-family: inherit; text-align: left; }
.wsswitch > button:hover { border-color: var(--line-hover); }
.wsswitch .chip { width: 22px; height: 22px; border-radius: 6px; background: #111; color: #fff;
  font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex: none; }
.wsswitch .name { flex: 1; min-width: 0; }
.wsswitch .name b { display: block; font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wsswitch .name span { font-size: 11px; color: var(--faint); }
.wsmenu { position: absolute; top: calc(100% + 6px); left: 0; right: 0; background: var(--surface);
  border: 1px solid var(--line); border-radius: 11px; box-shadow: 0 16px 40px -16px rgba(20,24,33,.28);
  padding: 6px; z-index: 40; }
.wsmenu button { display: flex; align-items: center; gap: 8px; width: 100%; background: none; border: none;
  padding: 9px 10px; border-radius: 8px; font-family: inherit; font-size: 13px; color: var(--body); cursor: pointer; text-align: left; }
.wsmenu button:hover { background: #F1F3F6; }
.wsmenu .divide { height: 1px; background: var(--line-light); margin: 5px 4px; }
.wsmenu .who { padding: 8px 10px 4px; font-size: 11px; color: var(--faint); }

/* Product scope — subordinate to the workspace switcher above it, so the
   hierarchy reads workspace › product. Sits flush under it (hence the pulled-up
   margin) because the two together answer one question: whose numbers am I
   looking at. Hidden entirely at one product. */
.pscope { margin: -12px 0 20px; }
.pscope label { display: block; font-size: 10px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--faint); padding: 0 3px 5px; }
/* The global input rule adds 9px of vertical padding; against a 32px fixed
   height that left a 12px content box for 12.5px text, so the glyphs were
   clipped top and bottom. Let the height carry the text instead of fighting
   the padding, and keep room on the right for the native arrow. */
.pscope select { width: 100%; height: 34px; padding: 0 28px 0 11px; font-size: 12.5px;
  text-overflow: ellipsis; }

.navgroup { font-size: 10.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--faint); padding: 16px 8px 8px; }
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 9px;
  font-size: 13.5px; font-weight: 500; color: var(--body); cursor: pointer; }
.nav a svg { width: 17px; height: 17px; flex: none; stroke: var(--muted); fill: none; }
.nav a:hover { background: #F1F3F6; }
.nav a.active { font-weight: 600; color: var(--ink); background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }
.nav a.active svg { stroke: var(--accent); }
.nav a .badge { margin-left: auto; font-size: 10.5px; font-weight: 700; color: var(--accent-text);
  background: var(--accent-soft); padding: 1px 7px; border-radius: 999px; }
.nav a .badge.new { color: var(--ok); background: var(--ok-bg); font-size: 9.5px; }

/* ---- Collapsible sidebar ----------------------------------------------------
   Reclaims 172px for the wide surfaces (Sources rows, the Prompts workbench,
   Portfolio). Labels become title tooltips when collapsed, so nothing is lost —
   only the width. Text is hidden with font-size:0 on the row and restored on
   the icon, because these labels are bare text nodes with no element to target. */
.side-toggle { margin-left: auto; flex: none; width: 26px; height: 26px; border-radius: 7px;
  border: 1px solid transparent; background: none; color: var(--faint); cursor: pointer;
  display: flex; align-items: center; justify-content: center; }
.side-toggle:hover { border-color: var(--line); color: var(--ink); background: var(--surface); }
.side-toggle svg { width: 15px; height: 15px; transition: transform .25s var(--ease-out); }
.side { transition: width .24s var(--ease-out); }

.app.side-collapsed .side { width: 66px; padding-left: 11px; padding-right: 11px; }
.app.side-collapsed .side-toggle svg { transform: rotate(180deg); }
.app.side-collapsed .brandlock { flex-direction: column; gap: 10px; padding: 2px 0 16px; }
.app.side-collapsed .brandlock .word,
.app.side-collapsed .wsswitch .name,
.app.side-collapsed .wsswitch > button > svg:last-child,
.app.side-collapsed .pscope,
.app.side-collapsed .navgroup,
.app.side-collapsed .nav a .badge,
.app.side-collapsed .plancard { display: none; }
.app.side-collapsed .side-toggle { margin: 0; }
.app.side-collapsed .wsswitch > button { justify-content: center; padding: 8px 0; }
.app.side-collapsed .nav { gap: 4px; }
.app.side-collapsed .nav a { justify-content: center; padding: 10px 0; gap: 0; font-size: 0; }
.app.side-collapsed .nav a svg { width: 18px; height: 18px; }
.app.side-collapsed .nav a.active::before { border-radius: 0 3px 3px 0; }
/* Groups collapse to a hairline so the sections still read as sections. */
.app.side-collapsed .navgroup + .nav { border-top: 1px solid var(--line); padding-top: 10px; margin-top: 6px; }
.app.side-collapsed .side-bottom { gap: 8px; }
.app.side-collapsed .side-bottom .btn { font-size: 0; padding: 10px 0; justify-content: center; gap: 0; }
.app.side-collapsed .side-bottom .btn > span { font-size: 16px !important; }
.app.side-collapsed .side-bottom .btn > svg { width: 15px; height: 15px; }

.side-bottom { margin-top: auto; display: flex; flex-direction: column; gap: 10px; padding-top: 12px; }
.side-bottom .btn { width: 100%; }
.plancard { background: var(--ink); border-radius: 13px; padding: 14px 15px; color: #fff; }
.plancard b { font-size: 12.5px; font-weight: 600; }
.plancard span { display: block; font-size: 11px; color: rgba(255,255,255,.6); margin-top: 3px; line-height: 1.4; }
.plancard .track { height: 5px; border-radius: 999px; background: rgba(255,255,255,.16); margin-top: 10px; overflow: hidden; }
.plancard .track > i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.plancard[data-nav] { cursor: pointer; transition: box-shadow .15s, transform .05s; }
.plancard[data-nav]:hover { box-shadow: 0 0 0 1.5px var(--accent); }
.plancard[data-nav]:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent); }
.plancard[data-nav]:active { transform: translateY(1px); }

/* --- Main column --- */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; height: 100vh; }
.hdr { flex: none; height: 60px; border-bottom: 1px solid #EAEDF1; display: flex; align-items: center;
  gap: 16px; padding: 0 26px; background: var(--canvas); }
.hdr .search { flex: 1; max-width: 400px; display: flex; align-items: center; gap: 9px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; }
.hdr .search svg { stroke: var(--faint); fill: none; flex: none; }
.hdr .search input { border: none; background: transparent; padding: 0; font-size: 13px; }
.hdr .search input:focus { box-shadow: none; }
.hdr .search .kbd { margin-left: auto; font-size: 10.5px; color: #B4BAC3; border: 1px solid var(--line); border-radius: 5px; padding: 1px 6px; }
.hdr .right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.modelpill { display: flex; align-items: center; gap: 8px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; padding: 8px 12px; font-family: inherit; cursor: pointer; }
.modelpill:hover { border-color: var(--line-hover); }
.modelpill .k { font-size: 11px; color: var(--faint); }
.modelpill .v { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.iconbtn { width: 34px; height: 34px; border-radius: 9px; background: var(--surface); border: 1px solid var(--line);
  color: var(--muted); font-size: 15px; font-weight: 700; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.iconbtn:hover { border-color: var(--line-hover); }
.avatar { width: 33px; height: 33px; border-radius: 50%; background: var(--accent-soft); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 700; cursor: pointer; border: none; font-family: inherit; }

.appmain { flex: 1; overflow-y: auto; padding: 28px 34px 60px; }
.view { max-width: 1180px; margin: 0 auto; }
.view.narrow { max-width: 840px; }
.view:not(.active) { display: none; }
.view.active { animation: vUp .5s cubic-bezier(.22,.61,.36,1) both; }

/* --- Page header pattern --- */
.pagehead h1 { font-family: var(--display); font-size: 26px; font-weight: 600; color: var(--ink);
  letter-spacing: -.02em; margin: 8px 0 4px; }
.pagehead p { margin: 0; color: var(--muted); font-size: 14px; max-width: 96ch; }
.greeting { font-size: 13px; color: var(--muted); font-weight: 500; }

/* ==========================================================================
   APP COMPONENTS
   ========================================================================== */
.vcard { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 20px 22px; }
.vcard.pad-sm { padding: 15px 17px; }
.vcard.r16 { border-radius: 16px; }
.vcard.accent-top { border-top: 3px solid var(--accent); }
.vcard.click { cursor: pointer; }
.vcard.click:hover { border-color: var(--line-hover); transform: translateY(-2px); box-shadow: 0 8px 22px rgba(20,24,33,.07); }
.vcard h3 { font-family: var(--display); font-size: 15px; font-weight: 600; color: var(--ink); }
.card-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.card-sub { font-size: 11.5px; color: var(--faint); margin: 3px 0 0; }
.sec-head { display: flex; align-items: center; justify-content: space-between; margin: 26px 0 13px; }
.sec-head h3 { font-family: var(--display); font-size: 16px; font-weight: 600; color: var(--ink); }

/* Dark visibility-index hero */
.dark-hero { background: var(--hero); border-radius: 16px; padding: 22px 24px; color: #fff; overflow: hidden; position: relative; }
.dark-hero .glow { position: absolute; top: -45%; right: -8%; width: 58%; height: 135%;
  background: radial-gradient(circle, rgba(245,137,95,.42), transparent 70%); filter: blur(30px);
  animation: vGlow 6s ease-in-out infinite; pointer-events: none; }
.dark-hero .eyebrow { position: relative; font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--hero-sub); }
.dark-hero .big { font-family: var(--display); font-size: 62px; font-weight: 600; line-height: .9; letter-spacing: -.03em; }
.dark-hero .sub { font-size: 12px; color: var(--hero-sub); }
.dark-hero .foot { display: flex; justify-content: space-between; font-size: 11px; color: var(--hero-foot); margin-top: 6px; }

/* KPI cards */
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 15px 17px; }
.kpi .label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--faint); }
.kpi .val { font-family: var(--display); font-size: 28px; font-weight: 600; color: var(--ink); line-height: 1; }
.kpi .delta { font-size: 12px; font-weight: 700; }
.kpi .delta.up { color: var(--pos); } .kpi .delta.down { color: var(--neg); }
.kpi .valrow { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; }
.kpi .sub { font-size: 10.5px; color: var(--faint); margin-top: 6px; }
.kpi svg { width: 100%; height: 22px; margin-top: 9px; display: block; }

/* Stat cards (competitors / sources / portfolio) */
.statcard { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 18px 20px; }
.statcard.dark { background: var(--hero); color: #fff; border: none; }
.statcard .label { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }
.statcard.dark .label { color: var(--hero-sub); }
.statcard .num { font-family: var(--display); font-size: 34px; font-weight: 600; color: var(--ink); margin-top: 6px; line-height: 1; }
.statcard.dark .num { color: #fff; }
.statcard .num.lg { font-size: 40px; }
.statcard .note { font-size: 12px; color: var(--muted); margin-top: 4px; }

/* Horizontal bars */
.bars { display: flex; flex-direction: column; gap: 11px; }
.bar { display: flex; align-items: center; gap: 12px; }
/* Brand names are user data and vary in length; a fixed-width label with no
   guard lets a long one ("ClauseMinds" at 70px) spill over the track beside it.
   Truncate instead — the full name is on the row's title attribute. */
.bar .lbl { flex: none; font-size: 12.5px; text-align: right; color: var(--muted); font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar .lbl.me { color: var(--ink); font-weight: 700; }
.bar .track { flex: 1; height: 16px; background: var(--line-light); border-radius: 6px; overflow: hidden; }
.bar .track.round { border-radius: 999px; }
.bar .track > i { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
.bar .val { flex: none; width: 40px; text-align: right; font-size: 12.5px; font-weight: 700; color: var(--ink); }
/* Some rows put a sentence where the number goes ("8 answers — too few to
   read"). The 40px numeric slot can't hold that, so it needs its own sizing —
   and the track must be allowed to give up space rather than force an overflow. */
.bar .val.note { flex: 0 1 auto; width: auto; max-width: 60%; text-align: right;
  font-size: 11.5px; font-weight: 500; color: var(--faint); }
.bar.thin { opacity: .62; }
.bar.thin .track { min-width: 24px; }

/* Interactive rows announce themselves on hover. Scoped to .drillable on
   purpose: plenty of bar lists (the drawer's dbars, GEO sub-scores, crawler
   counts) are read-only, and giving those a hover state would promise a click
   that does nothing. The row gains a tinted lane, its label firms up, and a
   chevron slides in from the right edge.
   The chevron is absolutely positioned into reserved padding, so nothing
   reflows on hover — a bar list that nudges sideways under the cursor feels
   broken, not responsive. */
/* The lane spans the row's own box — no negative margin. An earlier version bled
   10px each side, which made every row 20px wider than .bars and showed up as
   real horizontal overflow. box-sizing is border-box, so this padding is inside
   the row and costs nothing. */
.bars .bar.drillable { position: relative; cursor: pointer; border-radius: 9px;
  padding-inline: 0 26px;
  transition: background .18s ease; }
.bars .bar.drillable::after { content: "›"; position: absolute; right: 9px; top: 50%;
  transform: translateY(-50%) translateX(-4px); opacity: 0;
  font-size: 16px; line-height: 1; font-weight: 700; color: var(--accent-text);
  transition: opacity .18s ease, transform .22s var(--ease-out); pointer-events: none; }
.bars .bar.drillable:hover { background: var(--canvas); }
.bars .bar.drillable:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }
.bars .bar.drillable:hover .lbl { color: var(--ink); }
.bars .bar.drillable:hover .track { background: #E4E7EC; }
.bars .bar.drillable:hover .track > i { filter: saturate(1.12) brightness(1.03); }
.bars .bar.drillable:focus-visible { background: var(--canvas); }
/* A row that can't be read (too thin a sample) is not a click target. */
.bars .bar.drillable[aria-disabled="true"] { cursor: default; }
.bars .bar.drillable[aria-disabled="true"]:hover { background: none; }
.bars .bar.drillable[aria-disabled="true"]:hover::after { opacity: 0; }

/* Engine mini cards */
.engine-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.engine-card { border: 1px solid var(--line); border-radius: 12px; padding: 14px; }
.engine-card .name { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; color: var(--body); }
.engine-card .dot { width: 8px; height: 8px; border-radius: 50%; }
.engine-card .val { font-family: var(--display); font-size: 24px; font-weight: 600; color: var(--ink); margin-top: 8px; }
.engine-card .track { height: 6px; background: var(--line-light); border-radius: 999px; margin-top: 8px; overflow: hidden; }
.engine-card .track > i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }

/* Tables */
.vtable-wrap { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.vtable-wrap.r16 { border-radius: 16px; }
.vtable-wrap .thead { padding: 16px 22px; border-bottom: 1px solid var(--line-light); }
.vtable-wrap .thead.pf-head { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; }
.pf-head-t { min-width: 0; }
.pf-head-a { display: flex; gap: 8px; flex: none; }
.vtable { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.vtable th { text-align: left; padding: 12px 14px; font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line); background: var(--sidebar); font-weight: 700; }
.vtable th:first-child, .vtable td:first-child { padding-left: 20px; }
.vtable th:last-child, .vtable td:last-child { padding-right: 20px; }
.vtable th.r, .vtable td.r { text-align: right; }
.vtable td { padding: 13px 14px; border-bottom: 1px solid var(--line-light); color: var(--body); }
.vtable tr[data-click] { cursor: pointer; }
.vtable tbody tr:hover { background: var(--sidebar); }
.vtable tr.me { background: #FFF7F3; }
.vtable tr.me:hover { background: #FFF1EA; }
.vtable .pname { font-weight: 700; color: var(--ink); }
.vtable .psub { font-size: 11.5px; color: var(--faint); }
/* Compact in-card table (Brand profile → What we'll measure). Flush to the card
   edge, left-aligned uppercase headers, first column absorbs the slack so Stage
   and source stay tight next to it instead of drifting apart. */
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th { text-align: left; padding: 7px 32px 8px 0; font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint); font-weight: 600; white-space: nowrap;
  border-bottom: 1px solid var(--line); }
.table td { padding: 11px 32px 11px 0; border-bottom: 1px solid var(--line-light);
  color: var(--body); vertical-align: middle; }
.table th:first-child { width: 100%; }
.table th:last-child, .table td:last-child { padding-right: 0; }
.table tbody tr:last-child td { border-bottom: none; }
.dotname { display: flex; align-items: center; gap: 9px; }
.dotname .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.geocell { display: inline-flex; align-items: center; gap: 8px; justify-content: flex-end; }
.geocell .track { width: 42px; height: 6px; border-radius: 999px; background: var(--line-light); overflow: hidden; }
.geocell .track > i { display: block; height: 100%; border-radius: 999px; }
.geocell b { width: 24px; text-align: right; color: var(--ink); }

/* Legacy metric grid (measurement renderers) */
.metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.metric-card { border: 1px solid var(--line); border-radius: 14px; padding: 16px 17px; background: var(--surface); }
.metric-card .muted:first-child { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.metric-val { font-family: var(--display); font-size: 28px; font-weight: 600; color: var(--ink); line-height: 1; margin-top: 8px; }
.metric-ci { font-size: 10.5px; margin-top: 6px; color: var(--faint); }

/* Charts */
.chart svg { width: 100%; height: auto; display: block; }
.chart text { font-family: var(--sans); }
.chart .axis { font-size: 11px; fill: var(--faint); }
/* Trend-chart hover: the dot grows with a soft accent halo, a vertical guide drops
   to the axis, and a floating card (positioned in JS) shows the run detail. */
.trenddot { cursor: pointer; }
.trenddot .dotv { transition: r .12s ease, stroke-width .12s ease; }
.trenddot:hover .dotv { r: 7; stroke-width: 2; filter: drop-shadow(0 0 3.5px var(--accent)); }
.trend-guide { pointer-events: none; transition: opacity .12s ease; }
.chart-tip { position: absolute; z-index: 30; pointer-events: none; white-space: nowrap;
  background: var(--ink); color: #fff; border-radius: 9px; padding: 8px 11px; line-height: 1.35;
  box-shadow: 0 8px 22px rgba(20,24,33,.28); transform: translate(-50%, calc(-100% - 12px));
  opacity: 0; visibility: hidden; transition: opacity .12s ease; }
.chart-tip.show { opacity: 1; visibility: visible; }
.chart-tip::after { content: ""; position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--ink); }

/* ============================================================================
   Inviting onboarding / profile surfaces  (Get started · Brand profile)
   A warm gradient hero header with an icon badge, softly-elevated cards, and a
   more prominent stepper — so the first-run surfaces feel crafted, not clerical.
   ============================================================================ */
.pagehead.invite { display: flex; gap: 18px; align-items: flex-start; position: relative; overflow: hidden;
  background: radial-gradient(130% 150% at 100% -30%, rgba(236,107,76,.13), transparent 55%), linear-gradient(180deg, #fff, var(--sidebar));
  border: 1px solid var(--line); border-radius: 18px; padding: 24px 26px; margin-bottom: 22px; }
.pagehead.invite::after { content: ""; position: absolute; right: -60px; bottom: -76px; width: 210px; height: 210px;
  background: radial-gradient(circle, rgba(236,107,76,.10), transparent 68%); pointer-events: none; }
.pagehead.invite .head-badge { flex: none; width: 48px; height: 48px; border-radius: 14px;
  background: var(--accent-grad); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 18px -4px rgba(222,90,56,.45); }
.pagehead.invite .head-badge svg { width: 24px; height: 24px; stroke: #fff; fill: none; }
.pagehead.invite > div { position: relative; z-index: 1; }
.pagehead.invite h1 { font-size: 29px; margin: 5px 0 0; }
.pagehead.invite p { max-width: 74ch; margin-top: 8px; }

/* Compact page header — icon badge + title, no prose; the stepper docks right */
.pagehead.compact { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; margin-bottom: 20px; }
.pagehead.compact .head-badge { flex: none; width: 40px; height: 40px; border-radius: 12px;
  background: var(--accent-grad); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 14px -4px rgba(222,90,56,.4); }
.pagehead.compact .head-badge svg { width: 20px; height: 20px; stroke: #fff; fill: none; }
.pagehead.compact h1 { font-family: var(--display); font-size: 22px; font-weight: 600;
  letter-spacing: -.02em; margin: 0; }

/* Softly-crafted cards on these two views */
.view[data-view="getstarted"] .vcard,
.view[data-view="brand"] .vcard { border-radius: 16px;
  box-shadow: 0 1px 2px rgba(20,24,33,.03), 0 14px 30px -24px rgba(20,24,33,.28); }

/* Section mini-badge (Brand-profile card headers) */
.mini-badge { width: 30px; height: 30px; border-radius: 9px; background: var(--accent-soft);
  display: inline-flex; align-items: center; justify-content: center; flex: none; }
.mini-badge svg { width: 16px; height: 16px; stroke: var(--accent-text); fill: none; }

/* Card-title info tooltip — explanations in a styled bubble on hover/focus/click */
.info-tip { position: relative; display: inline-flex; color: var(--faint); cursor: pointer; outline: none; }
.info-tip svg { width: 15px; height: 15px; stroke: currentColor; fill: none; }
.info-tip:hover, .info-tip.open, .info-tip:focus-visible { color: var(--muted); }
.info-tip .tipbox {
  position: absolute; left: -10px; top: calc(100% + 9px); z-index: 60;
  width: max-content; max-width: 300px; white-space: normal;
  background: var(--ink); color: #fff; font-size: 12px; font-weight: 400; line-height: 1.55;
  padding: 10px 13px; border-radius: 10px; box-shadow: 0 10px 28px rgba(20,24,33,.3);
  display: none; pointer-events: none; text-transform: none; letter-spacing: normal;
}
.info-tip .tipbox::before {
  content: ""; position: absolute; left: 11px; top: -11px;
  border: 6px solid transparent; border-bottom-color: var(--ink);
}
.info-tip:hover .tipbox, .info-tip:focus-visible .tipbox, .info-tip.open .tipbox { display: block; }
/* Anchor the bubble to the right when the ⓘ sits near the right edge of a pane
   that clips — the default left-aligned box would be cut off by the overflow. */
.info-tip.tip-right .tipbox { left: auto; right: -10px; }
.info-tip.tip-right .tipbox::before { left: auto; right: 11px; }
/* Legend bubble: a definition list, not a paragraph. The four verdicts are the
   thing being explained, so each gets its own line and its own colour. */
.tipbox.tip-legend { width: 302px; }
.tipbox.tip-legend b { display: block; font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: rgba(255,255,255,.5); margin: 10px 0 3px; }
.tipbox.tip-legend b:first-child { margin-top: 0; }
.tipbox.tip-legend p { margin: 0 0 3px; color: rgba(255,255,255,.86); }
.tipbox.tip-legend .lg { display: flex; gap: 8px; padding: 2px 0; color: rgba(255,255,255,.7); }
.tipbox.tip-legend .lg i { flex: none; width: 76px; font-style: normal; font-weight: 700; }

/* Derived-setup row icons (Get started) */
.gs-ic { flex: none; width: 26px; height: 26px; border-radius: 8px; background: var(--accent-soft);
  display: inline-flex; align-items: center; justify-content: center; }
.gs-ic svg { width: 14px; height: 14px; stroke: var(--accent-text); fill: none; }
.gs-ic.dim { background: #F1F3F6; }
.gs-ic.dim svg { stroke: var(--faint); }

/* Identity-grid label icons (Brand profile) */
.bp-lbl { display: inline-flex; align-items: center; gap: 7px; }
.bp-lbl svg { width: 14px; height: 14px; stroke: var(--faint); fill: none; flex: none; }

/* Brand profile — wide two-column top row; equal-height cards whose content
   stretches (the truth description absorbs the slack). The row fills the
   viewport height (minus header, page head and the suite-summary card below),
   so the freed vertical space goes to the description instead of dead canvas. */
.bp-cols { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 16px; align-items: start; margin-bottom: 16px;
  min-height: max(430px, calc(100vh - 420px)); }
.bp-cols .vcard { display: flex; flex-direction: column; }
/* Buttons sit directly under the card's content. They used to be pushed to the
   bottom (margin-top:auto) to line the two cards' actions up, but the Identity
   card is much shorter than the tall Source-of-truth textarea, so that left a
   big dead gap above its buttons. */
.bp-cols .vcard > .row:last-child { padding-top: 14px; }
/* Aliases + competitors are comma lists that overflowed a single-line input;
   these grow to show the whole list instead of clipping it. */
textarea.bp-grow { resize: none; overflow: hidden; min-height: 38px; line-height: 1.5; }
/* The description keeps a comfortable floor so an empty box still reads as a
   writing surface; JS grows it from there up to the viewport bottom. */
#bp-desc { min-height: 170px; }

/* Plain-language "why this matters" callout — for foundational concepts a new
   user shouldn't have to hover a tooltip to understand. */
.explain-callout { display: flex; gap: 12px; align-items: flex-start; max-width: 780px;
  background: var(--accent-soft); border: 1px solid #F3D3C6; border-radius: 12px;
  padding: 14px 16px; font-size: 13px; line-height: 1.6; color: var(--body); }
.explain-callout b { color: var(--accent-text); }
.explain-callout .ec-icon { flex: none; width: 22px; height: 22px; color: var(--accent-text); }
.explain-callout .ec-icon svg { width: 22px; height: 22px; stroke: currentColor; fill: none; }

/* Get started: introduce the product brief in-context. The note frames the
   page-derived facts AS the brief (the thing pages + prompts are built from);
   the suite note reinforces the same link at the prompt-selection step. */
.gs-brief-note { display: flex; gap: 8px; align-items: flex-start; margin: 2px 0 4px; padding: 9px 12px;
  background: var(--accent-soft); border-radius: 10px; font-size: 12.5px; line-height: 1.55; color: var(--body); }
.gs-brief-note b { color: var(--accent-text); font-weight: 650; }
.gs-brief-note a { color: var(--accent-text); font-weight: 600; white-space: nowrap; }
.gs-brief-note .gs-ic { flex: none; margin-top: 1px; }
.gs-suite-note { margin: 0; font-size: 12px; line-height: 1.5; color: var(--faint); }
.gs-suite-note b { color: var(--body); font-weight: 600; }
.gs-suite-note a { color: var(--accent-text); font-weight: 600; white-space: nowrap; }
/* Brief source card: the URL path is the fastest seed; a labelled "or" divider
   separates it from the file/manual paths below. */
.s-faint { font-size: 11.5px; line-height: 1.5; color: var(--faint); }
.ss-or { display: flex; align-items: center; gap: 12px; margin: 16px 0; color: var(--faint);
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.ss-or::before, .ss-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
/* ===== Product brief — document + sticky sidebar =====
   The brief document owns ~65% of the width; a clean sticky sidebar holds the
   publish action, the "start from" sources, and the "why". */
.brief-layout { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(300px, 1fr);
  gap: 22px; align-items: start; margin-top: 14px; }
.brief-main { min-width: 0; }
.brief-main .brief-head { margin-bottom: 16px; }
.brief-main .brief-doc { margin-top: 0; }
.brief-side { position: sticky; top: 12px; display: flex; flex-direction: column; gap: 14px; }
.brief-side-card { border: 1px solid var(--line); border-radius: 14px; background: var(--surface); padding: 16px; }
.bsc-h { font-size: 12.5px; font-weight: 650; color: var(--ink); margin: 0 0 12px;
  display: flex; align-items: center; gap: 8px; }
.bsc-pub { margin-bottom: 12px; }
.bsc-hint { margin: 10px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--faint); }
.brief-side-card .soft { width: 100%; }
.brief-side-card input.soft { margin-bottom: 8px; }
.brief-side-card > .btn { width: 100%; }
.brief-side-card label { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faint); margin: 6px 0 4px; }
.why-card { background: var(--accent-soft); border-color: #F3D3C6; }
.why-card .bsc-h { color: var(--accent-text); }
.why-card .ec-icon { width: 16px; height: 16px; color: var(--accent-text); flex: none; }
.why-card .ec-icon svg { width: 16px; height: 16px; stroke: currentColor; fill: none; }
.why-card p { margin: 0; font-size: 12px; line-height: 1.55; color: var(--body); }
/* Sidebar "other ways to build" disclosure. */
.brief-more > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 600; color: var(--muted); padding: 8px 0 2px; user-select: none; }
.brief-more > summary::-webkit-details-marker { display: none; }
.brief-more > summary svg { transition: transform .2s ease; stroke: currentColor; }
.brief-more[open] > summary svg { transform: rotate(180deg); }
.brief-more[open] > summary { color: var(--body); }
.bm-body { padding-top: 8px; }
.bm-body .dropzone { padding: 16px; }
.bm-body > .btn { width: 100%; margin-top: 10px; }
@media (max-width: 900px) {
  .brief-layout { grid-template-columns: 1fr; }
  .brief-side { position: static; }
}

/* The document — the hero. Each fact type is its own titled section. */
.brief-doc { margin-top: 18px; display: flex; flex-direction: column; gap: 14px; }
.brief-sec { border: 1px solid var(--line); border-radius: 14px; background: var(--surface); padding: 16px 20px 6px; }
.brief-sec-h { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.brief-sec-h h4 { margin: 0; font-size: 14.5px; font-weight: 650; color: var(--ink); }
.bs-ico { flex: none; width: 28px; height: 28px; border-radius: 8px; background: var(--accent-soft);
  display: inline-flex; align-items: center; justify-content: center; }
.bs-ico svg { width: 16px; height: 16px; stroke: var(--accent-text); }
.bs-count { font-size: 11px; font-weight: 700; color: var(--faint); background: var(--bg);
  border-radius: 20px; padding: 1px 8px; }
.bs-spacer { flex: 1; }
.brief-add { color: var(--muted); }
/* Description rows: labelled key, prose value. */
.brief-field { display: grid; grid-template-columns: 96px 1fr; gap: 6px 16px; align-items: start;
  padding: 11px 0; border-bottom: 1px solid var(--line); }
.brief-field:last-child { border-bottom: 0; }
.bf-k { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--faint); padding-top: 2px; }
.bf-v { font-size: 13.5px; line-height: 1.55; color: var(--body); max-width: 70ch; }
/* Use cases & FAQs: a bold head line + a prose body line. */
.brief-item { padding: 12px 0; border-bottom: 1px solid var(--line); }
.brief-item:last-child { border-bottom: 0; }
.bi-head { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--ink); }
.bi-body { margin-top: 3px; font-size: 13px; line-height: 1.55; color: var(--muted); max-width: 70ch; }
/* Specs: a tidy definition grid — key left, value right. */
.brief-specs { display: flex; flex-direction: column; }
.spec-row { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 0; border-bottom: 1px solid var(--line); }
.spec-row:last-child { border-bottom: 0; }
.spec-k { font-size: 12.5px; color: var(--faint); }
.spec-v { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--ink); text-align: right; }
/* Not-designed-for: honest-scope chips. */
.brief-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 6px 0 10px; }
.ndf-chip { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--body);
  background: var(--bg); border: 1px solid var(--line); border-radius: 9px; padding: 6px 10px; }
/* Inline delete: quiet until hovered. */
.brief-del { border: none; background: none; cursor: pointer; color: var(--faint); padding: 2px;
  display: inline-flex; align-items: center; border-radius: 6px; line-height: 1; }
.brief-del:hover { color: var(--danger, #D64545); background: rgba(214,69,69,.08); }
.brief-empty { font-size: 12.5px; color: var(--faint); padding: 8px 0; }
@media (max-width: 760px) {
  .brief-head { flex-direction: column; gap: 12px; }
  .brief-head-side { align-items: flex-start; }
  .brief-sources { grid-template-columns: 1fr; }
}
/* "Where these come from" note under the Generate button — points at the brief
   as the source, keeping the Prompts workflow dedicated. */
.pl-brief-note { margin: 14px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--faint); }
.pl-brief-note b { color: var(--body); font-weight: 600; }
.pl-brief-note a { color: var(--accent-text); font-weight: 600; white-space: nowrap; }
/* Brand profile's facts card is a reflection of the brief, not an editor. The
   note names the brief as the source; the description renders as read-only prose
   (not a writing surface) so it doesn't invite edits that belong in the brief. */
.reflect-note { display: flex; gap: 8px; align-items: flex-start; margin: 2px 0 14px;
  font-size: 12px; line-height: 1.55; color: var(--faint); }
.reflect-note svg { flex: none; width: 15px; height: 15px; margin-top: 1px; stroke: var(--muted); }
.reflect-note b { color: var(--body); font-weight: 600; }
.reflect-desc { font-size: 13.5px; line-height: 1.6; color: var(--body); white-space: pre-wrap;
  padding: 10px 12px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 10px; }
/* Caption over the read-only fact inventory — marks the chips as "what we
   detected", so they don't read as buttons the user can act on. */
.bp-facts-cap { margin-top: 14px; font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; display: inline-flex; align-items: center; gap: 6px; }
.bp-facts-cap .info-tip svg { width: 13px; height: 13px; }
/* Page lead — states Brand profile's job (detection & measurement) so it reads
   as distinct from the product brief, and points facts back to the brief. */
.bp-lead { font-size: 13px; line-height: 1.6; color: var(--muted); max-width: 82ch; margin: 0 0 16px; }
.bp-lead b { color: var(--body); font-weight: 650; }
.bp-lead a { color: var(--accent-text); font-weight: 600; white-space: nowrap; }
/* The facts card is now a slim measurement pointer, not a second facts surface. */
.bp-side-stack { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.bp-reflect-lead { font-size: 12.5px; line-height: 1.55; color: var(--muted); margin: 6px 0 0; }
.bp-reflect-lead b { color: var(--body); font-weight: 600; }
.bp-reflect-stats { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
@media (max-width: 980px) { .bp-cols { grid-template-columns: 1fr; } }

/* Detected-rival chip: the chip is the track action */
.chip.track { cursor: pointer; background: var(--warn-bg); color: var(--warn); border-color: #EFDDBC; font-family: inherit; }
.chip.track b { font-weight: 700; }
.chip.track:hover { border-color: var(--warn); }
#bp-detected .chip { font-size: 11px; }
#bp-disc-more { cursor: pointer; font-family: inherit; }

/* Icon-only retire button (prompt suite rows) */
.iconx { width: 24px; height: 24px; border-radius: 7px; border: 1px solid var(--line); background: var(--surface);
  color: var(--faint); cursor: pointer; font-size: 14px; line-height: 1; padding: 0; }
.iconx:hover { color: var(--danger); border-color: var(--danger); }

/* Suggested prompts — fill the width in columns */
.bp-sugs { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 10px; }

/* Prompts view — the promptlab drill entered from the main nav: no Content
   Studio backlink (it wasn't the path in), and the width cap lifts so the
   tracked list + filters use the screen like the other work-queue views. */
.view[data-view="studio"].as-prompts [data-drill="promptlab"] .backlink { display: none; }
.view[data-view="studio"].as-prompts { max-width: 1500px; }

/* Ask-likelihood pill — MODELED styling (dashed, transparent): visually distinct
   from every measured/solid pill so an estimate can never read as a measurement */
.pill.ask { background: transparent; border: 1px dashed var(--line-hover); color: var(--muted);
  font-weight: 600; font-size: 10px; cursor: help; }
.pill.ask.unlikely { color: var(--warn); border-color: #E0C08A; }

/* Portfolio — watch-pages expander chip + sub-row */
.chip.pf-pages { cursor: pointer; font-family: inherit; margin-top: 5px; font-size: 11px; padding: 3px 9px; }
.chip.pf-pages:hover { border-color: var(--line-hover); color: var(--body); }
tr.pf-sub td { border-bottom: 1px solid var(--line-light); }

/* Get started — prominent stepper, docked right in the compact header */
.view[data-view="getstarted"] .steps { gap: 12px; margin: 0 0 0 auto; }
.view[data-view="getstarted"] .steps .step .n { width: 26px; height: 26px; font-size: 12.5px; transition: box-shadow .15s ease, background .15s ease; }
.view[data-view="getstarted"] .steps .step.active .n { box-shadow: 0 4px 10px -2px rgba(222,90,56,.5); }
.view[data-view="getstarted"] .steps .bar { width: 44px; height: 2px; border-radius: 2px; background: var(--line-hover); }

/* Get started — the URL card is the primary action, so it reads as one */
.gs-hero-card { background: radial-gradient(120% 130% at 0% 0%, var(--accent-soft), #fff 60%); border-color: #F3D3C6 !important; }
.gs-hero-card input.soft { padding: 12px 14px; font-size: 14px; background: #fff; }

/* Get started — derived-setup rows get rhythm */
#gs-preview > .row { padding: 10px 2px !important; border-top: 1px solid var(--line-light); }
#gs-preview > .row:first-child { border-top: none; }
.chart .lbl { font-size: 12px; fill: var(--ink); }
.chart .val { font-size: 12px; fill: var(--body); font-weight: 600; }

/* Tab bar */
.tabbar { display: flex; gap: 2px; margin-top: 26px; border-bottom: 1px solid var(--line); overflow-x: auto; }
.tabbar button { background: none; border: none; border-bottom: 2.5px solid transparent; color: var(--muted);
  font-weight: 600; font-size: 13px; padding: 11px 4px; margin-right: 20px; cursor: pointer; font-family: inherit; white-space: nowrap; }
.tabbar button.active { border-bottom-color: var(--accent); color: var(--ink); font-weight: 700; }
.tabpanel:not(.active) { display: none; }

/* Tracking strip / drift banner */
.strip { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 13px 16px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.strip.drift { border-left: 3px solid var(--accent); background: var(--accent-soft); }
/* Stale-data warning. It sat flush against the stat cluster below, so the
   warning and the numbers it discredits read as one block — the separation IS
   the message. Extra bottom margin keeps the numbers clearly "underneath the
   warning" rather than part of it. */
.strip.stale { margin: 16px 0 26px; gap: 12px; border-left: 3px solid var(--warn);
  background: rgba(201,138,30,.08); border-color: #EBDCC0; }
.strip.stale .t { font-size: 13px; font-weight: 700; color: var(--ink); }
.strip.stale .btn-primary { margin-left: auto; }
.strip-x { flex: none; width: 26px; height: 26px; border-radius: 7px; border: 1px solid transparent;
  background: none; color: var(--faint); font-size: 13px; cursor: pointer; line-height: 1;
  display: flex; align-items: center; justify-content: center; }
.strip-x:hover { border-color: var(--line-hover); color: var(--ink); background: var(--surface); }
.strip { flex-wrap: wrap; }
.pulse { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700; color: var(--ok); }
.pulse .d { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px rgba(14,122,95,.15); }
.seg { display: flex; background: #F1F3F6; border-radius: 8px; padding: 2px; }
.seg button { background: none; border: none; padding: 6px 11px; border-radius: 6px; font-family: inherit;
  font-size: 12px; font-weight: 600; color: var(--muted); cursor: pointer; }
.seg button.active { background: var(--surface); color: var(--accent-text); font-weight: 700; box-shadow: 0 1px 2px rgba(0,0,0,.08); }

/* Headline KPI (answers) with sparkline */
.headline-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
.usage-bar { height: 8px; background: var(--line-light); border-radius: 999px; overflow: hidden; margin-top: 6px; }
.usage-bar > div { height: 100%; background: var(--accent); border-radius: 999px; }

/* Score donut */
.donut text.big { font-family: var(--display); font-weight: 700; fill: var(--ink); }
.donut text.sub { fill: var(--faint); }

/* Findings / facts / evidence */
.finding-row { display: flex; align-items: flex-start; gap: 11px; padding: 11px 0; border-top: 1px solid var(--line-light); }
.finding-row .glyph { flex: none; width: 22px; height: 22px; border-radius: 7px; display: flex; align-items: center;
  justify-content: center; font-size: 12px; font-weight: 800; }
.finding-row .glyph.pass { background: var(--ok-bg); color: var(--ok); }
.finding-row .glyph.warn { background: var(--warn-bg); color: var(--warn); }
.finding-row .glyph.fail { background: var(--danger-bg); color: var(--danger); }
.finding-row .t { font-size: 13.5px; font-weight: 700; color: var(--body); }
.finding-row .d { font-size: 12px; color: var(--muted); margin-top: 2px; }
.finding-row .cta { flex: none; font-size: 12px; font-weight: 700; color: var(--accent-text); white-space: nowrap; }
.kv { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 0; border-top: 1px solid var(--line-light); }
.kv .k { font-size: 12px; color: var(--faint); }
.kv .v { font-size: 12.5px; font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 7px; }
.chiprow { display: flex; flex-wrap: wrap; gap: 7px; }
.chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); background: var(--surface); }
.chip.on { background: var(--ok-bg); color: var(--ok); border-color: var(--ok-border); }
.chip.off { background: #F1F3F6; color: var(--faint); }
.chip.dark { background: var(--ink); color: #fff; border-color: var(--ink); }
.details > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 9px; padding: 9px 0; font-size: 12.5px; color: var(--muted); border-top: 1px solid var(--line-light); }
.details > summary::-webkit-details-marker { display: none; }
.details p { margin: 2px 0 12px; font-size: 13px; color: var(--body); line-height: 1.6; background: var(--canvas); border-radius: 9px; padding: 12px 14px; }
.details p mark { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; border-radius: 3px; padding: 0 2px; }

/* Studio */
.studio-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: 16px; margin-top: 22px; }
.tool { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 22px; cursor: pointer; display: flex; flex-direction: column; }
.tool:hover { border-color: var(--line-hover); transform: translateY(-2px); box-shadow: 0 8px 22px rgba(20,24,33,.07); text-decoration: none; }
.tool .tile { width: 38px; height: 38px; border-radius: 10px; background: var(--accent-soft); display: flex; align-items: center; justify-content: center; margin-bottom: 13px; }
.tool .tile svg { stroke: var(--accent); fill: none; }
.tool h3 { margin: 0 0 6px; font-family: var(--display); font-size: 15.5px; font-weight: 600; }
.tool p { margin: 0 0 14px; font-size: 13px; color: var(--muted); line-height: 1.55; }
.tool .cta { margin-top: auto; font-size: 12.5px; font-weight: 700; color: var(--accent-text); }
.backlink { display: inline-flex; align-items: center; gap: 7px; background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 700; color: var(--muted); padding: 0; margin-bottom: 14px; }
.backlink:hover { color: var(--ink); }
.backlink svg { stroke: currentColor; fill: none; }

/* iOS toggle */
.toggle { position: relative; width: 40px; height: 23px; border-radius: 999px; background: var(--neutral-bar); flex: none; transition: background .15s; border: none; cursor: pointer; padding: 0; }
.toggle > i { position: absolute; top: 2.5px; left: 2.5px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: left .15s; }
.toggle.on { background: var(--accent); }
.toggle.on > i { left: 19px; }

/* ICP Discovery — file dropzone */
.icp-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; text-align: center; padding: 24px 18px;
  border: 1.5px dashed var(--line); border-radius: 12px;
  background: var(--canvas); color: var(--muted); cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.icp-drop:hover, .icp-drop:focus-visible { border-color: var(--accent); color: var(--body); outline: none; }
.icp-drop.dragover { border-color: var(--accent); background: var(--accent-soft); color: var(--ink); }
.icp-drop-ic { color: var(--accent); margin-bottom: 2px; }
.icp-drop-main { font-size: 13px; color: var(--body); }
.icp-drop-main strong { font-weight: 600; }
.icp-drop-browse { color: var(--accent); font-weight: 600; text-decoration: underline; }
.icp-drop-hint { font-size: 11px; color: var(--muted); max-width: 54ch; line-height: 1.45; }
.icp-files { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.icp-file-row {
  display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--body);
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px;
}
.icp-file-row .ic { color: var(--accent); flex: none; display: flex; }
.icp-file-row .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.icp-file-row .sz { color: var(--muted); font-size: 11px; flex: none; }
.icp-file-row .rm {
  flex: none; cursor: pointer; color: var(--muted); background: none; border: none;
  padding: 3px; line-height: 0; border-radius: 5px; display: flex;
}
.icp-file-row .rm:hover { color: var(--danger); background: var(--danger-bg); }

/* Dropzone */
.dropzone { border: 1.5px dashed #CBD1D9; border-radius: 12px; padding: 34px 20px; text-align: center; background: var(--sidebar); }
.dropzone svg { stroke: var(--faint); fill: none; margin-bottom: 8px; }
.dropzone .t { font-size: 14px; font-weight: 600; color: var(--ink); }
.dropzone .t a { text-decoration: underline; }
.dropzone .s { font-size: 11.5px; color: var(--faint); margin-top: 5px; }

/* Dark JSON card */
.json-card { background: var(--ink); border-radius: 14px; padding: 20px 22px; color: #C7D6DC; }
.json-card h3 { color: #fff; font-size: 14px; }
.json-card pre { margin: 0; font-family: var(--mono); font-size: 11.5px; line-height: 1.65; color: #9FB6C4; white-space: pre-wrap; }

/* Step indicator */
.steps { display: flex; align-items: center; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.steps .step { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--faint); }
.steps .step.active { font-weight: 700; color: var(--ink); }
.steps .step .n { width: 22px; height: 22px; border-radius: 50%; background: var(--line-light); color: var(--muted);
  display: flex; align-items: center; justify-content: center; font-size: 12px; }
.steps .step.active .n { background: var(--accent); color: #fff; }
.steps .bar { width: 26px; height: 1px; background: var(--line-hover); }

/* Grids */
.g2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.g3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.mt16 { margin-top: 16px; } .mt18 { margin-top: 18px; } .mt12 { margin-top: 12px; }

/* Loading + spinner */
.spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid var(--line);
  border-top-color: var(--accent); border-radius: 50%; animation: spin .8s linear infinite; vertical-align: -3px; margin-right: 8px; }

/* ============================================================================
   SOURCES — type filter dropdown on the table header
   ============================================================================ */
.src-type-h { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 5px; }
.src-filtericon { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  border-radius: 5px; border: 1px solid transparent; background: none; color: var(--faint); cursor: pointer; padding: 0; }
.src-filtericon:hover { color: var(--ink); border-color: var(--line); background: var(--surface); }
/* Filtered ⇒ the funnel carries the accent, so an active filter is legible without opening the menu. */
.src-filtericon.on { color: var(--accent-text); }
.srcmenu { position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%); z-index: 40;
  min-width: 154px; background: var(--surface); border: 1px solid var(--line); border-radius: 11px;
  box-shadow: 0 16px 40px -16px rgba(20,24,33,.28); padding: 5px;
  text-transform: none; letter-spacing: normal; font-weight: 400; }
.srcmenu[hidden] { display: none; }
.srcmenu button { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: none;
  cursor: pointer; padding: 7px 9px; border-radius: 7px; font-family: inherit; font-size: 12.5px;
  color: var(--body); text-align: left; }
.srcmenu button .l { flex: 1; }
.srcmenu button .n { color: var(--faint); font-variant-numeric: tabular-nums; }
.srcmenu button:hover { background: var(--canvas); }
.srcmenu button.on { color: var(--accent-text); font-weight: 600; }
.srcmenu button.on .n { color: var(--accent-text); }

/* ============================================================================
   MODAL SURFACES — the console's one overlay treatment
   Every overlay is a CENTRED dialog, not a side drawer: the content here is
   wide (tables, bar rows, quoted answers, candidate lists) and a 760px rail
   forced it all to wrap. Centring also puts the thing you asked about in the
   middle of your attention instead of at the edge.

   Shared rules, so a new overlay inherits them by adding .modal-scrim/.modal:
     · closed is transform + visibility, never display:none — a display flip
       can't transition, and the rAF workaround silently fails in a throttled
       tab, leaving the panel invisible while it thinks it is open.
     · scale-in from .975 rather than a slide, so nothing travels far.
     · size is per-modal; everything else is common.
   ============================================================================ */
.drawer-overlay, .pl-scrim, .modal-scrim {
  position: fixed; inset: 0; background: rgba(20,24,33,.4);
  opacity: 0; pointer-events: none; transition: opacity .22s ease; z-index: 90; }
.drawer-overlay.open, .pl-scrim.open, .modal-scrim.open { opacity: 1; pointer-events: auto; }
.drawer, .pl-over, .modal {
  position: fixed; top: 50%; left: 50%; z-index: 91;
  background: var(--surface); border: 1px solid var(--line); border-radius: 18px;
  box-shadow: 0 40px 110px rgba(20,24,33,.34), 0 8px 24px rgba(20,24,33,.14);
  display: flex; flex-direction: column; overflow: hidden;
  transform: translate(-50%, -50%) scale(.975); opacity: 0; visibility: hidden;
  transition: transform .28s var(--ease-out), opacity .2s ease, visibility 0s linear .28s; }
.drawer.open, .pl-over.open, .modal.open {
  transform: translate(-50%, -50%) scale(1); opacity: 1; visibility: visible;
  transition: transform .28s var(--ease-out), opacity .18s ease, visibility 0s; }
/* Per-modal size only. */
.drawer { width: min(920px, 94vw); height: min(824px, 88vh); }
.modal { width: min(720px, 94vw); max-height: 88vh; }

@media (prefers-reduced-motion: reduce) {
  .drawer, .pl-over, .modal { transition: opacity .12s ease, visibility 0s; transform: translate(-50%, -50%); }
  .drawer.open, .pl-over.open, .modal.open { transform: translate(-50%, -50%); }
}

.drawer-head { flex: none; display: flex; align-items: flex-start; gap: 12px; padding: 20px 28px; border-bottom: 1px solid var(--line-light); }
.drawer-head .eyebrow { font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-text); }
.drawer-head h2 { font-family: var(--display); font-size: 20px; font-weight: 600; color: var(--ink); margin: 4px 0 0; letter-spacing: -.01em; }
.drawer-close { margin-left: auto; flex: none; width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); cursor: pointer; color: var(--muted); font-size: 15px; display: flex; align-items: center; justify-content: center; }
.drawer-close:hover { border-color: var(--line-hover); color: var(--ink); }
.drawer-body { flex: 1; overflow-y: auto; padding: 20px 28px 44px; }
.dsec { margin-bottom: 22px; }
.dsec-label { font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); margin-bottom: 9px; }
.dbig { font-family: var(--display); font-size: 42px; font-weight: 600; color: var(--ink); line-height: 1; }
.dformula { background: var(--canvas); border: 1px solid var(--line-light); border-radius: 10px; padding: 12px 14px; font-size: 13px; color: var(--body); line-height: 1.6; }
.dformula b, .dformula code { color: var(--ink); }
.dcalc { display: flex; flex-direction: column; gap: 7px; }
.dcalc-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.dcalc-row .k { flex: 1; color: var(--muted); }
.dcalc-row .v { font-weight: 700; color: var(--ink); font-family: var(--mono); font-size: 12.5px; }
.dcalc-row.total { border-top: 1px solid var(--line-light); padding-top: 9px; margin-top: 2px; }
.dcalc-row.total .k { color: var(--ink); font-weight: 700; }
.dnote { font-size: 13px; color: var(--muted); line-height: 1.65; margin: 0; }
.daction { background: var(--accent-soft); border: 1px solid #F3D3C6; border-radius: 12px; padding: 14px 16px; }
/* Sections concatenate several of these, and with no margin they butt together
   into one undifferentiated slab — the cards stop reading as separate choices
   and their buttons look cramped. */
.daction + .daction { margin-top: 10px; }
.daction .t { font-size: 13px; font-weight: 700; color: var(--accent-text); }
.daction .d { font-size: 12.5px; color: var(--body); margin: 5px 0 11px; line-height: 1.55; }
/* Replaces a CTA that would have navigated to the current view. */
.dhere { font-size: 12px; font-weight: 600; color: var(--accent-text); opacity: .75; }
.drillable { cursor: pointer; }
/* Headline stat cards that dive deeper — lift + accent border on hover so they read as clickable. */
.statcard.drillable { transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease; }
.statcard.drillable:hover { border-color: var(--accent); box-shadow: 0 4px 14px rgba(0,0,0,.06); transform: translateY(-1px); }
.statcard.dark.drillable:hover { box-shadow: 0 6px 18px rgba(0,0,0,.22); transform: translateY(-1px); }

/* ============================================================================
   OVERVIEW — instrument band, cluster, bento
   Three moves away from "grid of identical cards": one full-bleed dark band
   that owns the headline reading, a borderless stat cluster, and a bento where
   a block's SIZE is what says how important it is.
   ============================================================================ */
/* Negative margins cancel .appmain's padding so the band runs to the edges of
   the scroll container. The view stays max-width'd, so on very wide screens the
   band is inset rather than edge-to-edge — deliberate: a 2000px-wide dark slab
   reads as a banner, not an instrument. */
.ov-band { background: var(--hero); color: #fff; position: relative; overflow: hidden;
  margin: -28px -34px 22px; padding: 26px 34px 24px; }
.ov-band::after { content: ""; position: absolute; right: -6%; top: -60%; width: 46%; height: 210%;
  background: radial-gradient(closest-side, rgba(245,137,95,.30), transparent 72%);
  pointer-events: none; animation: vGlow 7s ease-in-out infinite; }
.ov-band-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  flex-wrap: wrap; margin-bottom: 16px; position: relative; z-index: 1; }
.ov-band .greeting { color: var(--hero-sub); }
.ov-band h1 { color: #fff; font-size: 27px; margin: 5px 0 0; }
.ov-band #ov-stage-filter { position: relative; z-index: 1; margin-bottom: 18px; }
.ov-band .btn-ghost { background: rgba(255,255,255,.09); border-color: rgba(255,255,255,.2); color: #fff; }
.ov-band .btn-ghost:hover { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.34); color: #fff; }
.ov-band .pill.neutral { background: rgba(255,255,255,.1); color: var(--hero-sub); }
.ov-band .pill.neutral:hover { background: rgba(255,255,255,.18); color: #fff; }

/* The hero stops being a card and becomes the band's content: number on the
   left, the index trend stretched across the right and bleeding off the edge. */
.ov-band .dark-hero { background: none; border-radius: 0; padding: 0; overflow: visible;
  display: grid; grid-template-columns: minmax(0, auto) minmax(200px, 1fr);
  column-gap: 40px; align-items: center; position: relative; z-index: 1; }
.ov-band .dark-hero .glow { display: none; }        /* the band owns the glow now */
.ov-band .dark-hero .eyebrow { grid-column: 1; grid-row: 1; }
.ov-band .dark-hero .ov-num { grid-column: 1; grid-row: 2; margin-top: 4px !important; }
.ov-band .dark-hero .big { font-size: 76px; }
.ov-band .dark-hero > svg { grid-column: 2; grid-row: 1 / span 2; height: 104px !important;
  margin: 0 !important; align-self: center;
  /* bleed past the band's right padding, then fade out instead of stopping dead */
  width: calc(100% + 34px) !important; margin-right: -34px !important;
  -webkit-mask-image: linear-gradient(90deg, #000 62%, transparent 99%);
  mask-image: linear-gradient(90deg, #000 62%, transparent 99%); }
.ov-band .dark-hero .foot { grid-column: 1 / -1; grid-row: 3; margin-top: 14px;
  padding-top: 13px; border-top: 1px solid rgba(255,255,255,.1); }

/* --- borderless stat cluster --- */
.ov-cluster { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: 20px; }
.ov-cluster .kpi { background: none; border: none; border-radius: 0; padding: 2px 22px;
  border-left: 1px solid var(--line); }
.ov-cluster .kpi:first-child { border-left: none; padding-left: 0; }
.ov-cluster .kpi .val, .ov-cluster .kpi .valrow > span:first-child { font-size: 32px !important; }
.ov-cluster .kpi.drillable:hover { transform: none; box-shadow: none; }
/* No card to lift, so the hover affordance is the reading itself brightening. */
.ov-cluster .kpi.drillable .label { transition: color .18s ease; }
.ov-cluster .kpi.drillable:hover .label { color: var(--accent-text); }

/* --- bento --- */
.ov-bento { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 16px; }
.ov-bento .b-field { grid-column: span 7; }
.ov-bento .b-act   { grid-column: span 5; grid-row: span 2; }
.ov-bento .b-eng   { grid-column: span 7; }
.ov-bento .b-act .card-sub { margin-bottom: 2px; }

@media (max-width: 1080px) {
  .ov-cluster { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 16px; }
  .ov-cluster .kpi:nth-child(odd) { border-left: none; padding-left: 0; }
  .ov-cluster .kpi:nth-child(n+3) { border-top: 1px solid var(--line); padding-top: 14px; }
  .ov-bento .b-field, .ov-bento .b-eng { grid-column: span 12; }
  .ov-bento .b-act { grid-column: span 12; grid-row: auto; }
}
@media (max-width: 620px) {
  .ov-band { margin: -18px -16px 18px; padding: 20px 16px; }
  .ov-band .dark-hero { grid-template-columns: minmax(0, 1fr); }
  .ov-band .dark-hero > svg { grid-column: 1; grid-row: 3; height: 62px !important;
    width: calc(100% + 16px) !important; margin-right: -16px !important; }
  .ov-band .dark-hero .foot { grid-row: 4; }
  .ov-band .dark-hero .big { font-size: 58px; }
  .ov-cluster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================================
   PROMPTS WORKBENCH
   A fixed-height, three-zone operations surface: queue rail · suite table ·
   inspector, over a persistent cost/run footer. Nothing but the three panes
   scrolls, so the page never moves under you while you triage.
   ============================================================================ */
.view[data-view="studio"].as-prompts { max-width: none; }
/* 60px header + .appmain's 28/60 padding = the height the grid can claim. */
.as-prompts [data-drill="promptlab"] { height: calc(100vh - 148px); display: flex; flex-direction: column; min-height: 460px; }
.pl-wb {
  flex: 1; min-height: 0; display: grid;
  grid-template-columns: 214px minmax(0, 1fr) var(--pl-insp-w, 0px);
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas: "head head head" "rail main insp" "foot foot foot";
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  overflow: hidden; position: relative;
  transition: grid-template-columns .3s var(--ease-out);
}
.pl-wb.insp-open { --pl-insp-w: 352px; }

/* --- head --- */
.pl-head { grid-area: head; display: flex; align-items: center; gap: 12px;
  padding: 13px 16px; border-bottom: 1px solid var(--line); background: var(--sidebar); }
.pl-head h1 { font-size: 19px; font-weight: 600; letter-spacing: -.01em; }
/* Whose suite this is. Reads as part of the title, not as a control — the
   control is the sidebar switcher. */
.pl-scope { font-size: 12.5px; font-weight: 600; color: var(--muted); background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 11px; max-width: 260px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-scope.all { border-style: dashed; color: var(--faint); font-weight: 500; }
.pl-search { flex: 1; max-width: 340px; margin-left: auto; display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 0 10px; height: 33px; }
.pl-search svg { stroke: var(--faint); fill: none; flex: none; }
.pl-search input { border: none; background: transparent; padding: 0; font-size: 13px; height: 100%; }
.pl-search input:focus { box-shadow: none; }
.pl-search .kbd { font-size: 10.5px; color: #B4BAC3; border: 1px solid var(--line); border-radius: 5px; padding: 0 5px; }
.pl-search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(236,107,76,.12); }

/* --- rail: the work queue --- */
.pl-rail { grid-area: rail; border-right: 1px solid var(--line); background: var(--sidebar);
  overflow-y: auto; padding: 10px 8px; }
.pl-rail .grp { font-size: 10px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
  color: var(--faint); padding: 12px 8px 5px; }
.pl-rail .grp:first-child { padding-top: 2px; }
.pl-q { display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 9px; border: none;
  border-radius: 8px; background: none; cursor: pointer; font-family: inherit; font-size: 13px;
  color: var(--body); text-align: left; transition: background .16s ease; }
.pl-q:hover { background: #EDEFF3; }
.pl-q .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--neutral-bar); }
/* One line per queue — the rail is navigation, kept quiet. What a jargon label
   ("Rival wins", "Unlikely phrasing") means lives in its hover tooltip and its
   group heading, not in a description printed under every item. */
.pl-q .lb { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Counts form a right-aligned column. Every count carries the SAME horizontal
   padding (not just the toned pills), so a plain number and a badged one share
   the exact right edge — otherwise the pill's padding insets its digit and the
   column zig-zags. tabular-nums + text-align:right keeps 1- and 2-digit counts
   lined up on their ones place. */
.pl-q .n { flex: none; min-width: 25px; padding: 1px 6px; text-align: right; box-sizing: border-box;
  font-size: 11.5px; font-weight: 700; color: var(--faint); font-variant-numeric: tabular-nums; }
.pl-q.on { background: var(--accent-soft); color: var(--ink); font-weight: 600; }
.pl-q.on .n { color: var(--accent-text); }
/* A queue with work in it earns the accent count; an empty one stays quiet.
   Background + colour only — the padding that shapes the pill already lives on
   .pl-q .n above, so toned and plain counts never fall out of alignment. */
.pl-q.hot .n { color: var(--danger); background: var(--danger-bg); border-radius: 999px; }
.pl-q.warm .n { color: var(--warn); background: var(--warn-bg); border-radius: 999px; }

/* --- main: the suite table --- */
/* overflow:hidden is the hard guarantee that nothing in the middle column can
   ever paint over the inspector column beside it, whatever the width. The list
   inside keeps its own vertical scroll. */
.pl-main { grid-area: main; display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
/* Wraps rather than overflows: when the middle column is squeezed (inspector
   open on a narrow window) the sort seg drops to a second line instead of
   spilling sideways over the inspector. */
.pl-bar { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  row-gap: 7px; padding: 9px 14px; border-bottom: 1px solid var(--line-light); }
.pl-bar input[type=checkbox] { width: 14px; height: 14px; accent-color: var(--accent); cursor: pointer; flex: none; }
.pl-view-t { font-size: 13px; font-weight: 700; color: var(--ink); }
.pl-bar .muted { font-size: 11.5px; }
/* Active filters, named and removable. The list bar's job is to answer "why am I
   seeing 4 of 20" without making you read the rail — and every chip is also the
   way back out. */
.pl-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pl-chip { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; font-family: inherit;
  font-size: 11px; color: var(--accent-text); background: var(--accent-soft);
  border: 1px solid #F0D2CD; border-radius: 999px; padding: 2px 8px; }
.pl-chip .k { font-weight: 400; opacity: .72; }
.pl-chip .v { font-weight: 700; max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-chip .x { font-size: 9.5px; opacity: .55; }
.pl-chip:hover { border-color: var(--accent); }
.pl-chip:hover .x { opacity: 1; }
.pl-chip.clr { background: none; border-color: var(--line); color: var(--muted); font-weight: 600; }
.pl-chip.clr:hover { color: var(--ink); border-color: var(--line-hover); }
.pl-sort { margin-left: auto; flex: none; }
.pl-sort button { padding: 4px 9px; font-size: 11.5px; }
/* The list takes only the height it needs, so the composer below rides up under
   the last row instead of being pinned to the pane floor with a field of white
   between them. A long list still shrinks to fit and scrolls.
   The min-height is load-bearing: with a content-sized flex-basis the list is the
   only thing here that CAN shrink, so in a short window it would otherwise be
   squeezed to nothing and the prompts would vanish entirely. This floors it at
   about two rows and lets it scroll from there. */
.pl-list { flex: 0 1 auto; min-height: 96px; overflow-y: auto; }
.pl-add { flex: none; display: flex; gap: 8px; padding: 11px 14px;
  border-top: 1px solid var(--line-light); background: var(--surface); }
.pl-add select { width: auto; flex: none; }
.pl-add input { flex: 1; min-width: 0; }
.pl-add .btn { flex: none; }
.pl-fill { flex: 1 1 auto; min-height: 0; }

.pl-row { display: flex; align-items: center; gap: 10px; padding: 9px 14px;
  border-bottom: 1px solid var(--line-light); cursor: pointer; }
.pl-row:hover { background: var(--sidebar); }
.pl-row.sel { background: #FFF7F3; }
.pl-row.cur { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.pl-row input[type=checkbox] { width: 14px; height: 14px; accent-color: var(--accent); cursor: pointer; flex: none; }
.pl-row .st { flex: none; width: 52px; text-align: center; font-size: 9.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .04em; border-radius: 999px; padding: 3px 0; }
.pl-row .tx { flex: 1; min-width: 0; font-size: 13px; color: var(--body);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-row.cur .tx, .pl-row:hover .tx { color: var(--ink); }
/* Per-engine outcome for the loaded run — filled = named you, hollow = didn't. */
.pl-eng { flex: none; display: flex; gap: 3px; }
.pl-eng i { width: 7px; height: 7px; border-radius: 50%; display: block; border: 1.5px solid var(--neutral-bar); }
.pl-eng i.hit { border-color: transparent; }
.pl-vd { flex: none; width: 74px; text-align: right; font-size: 10.5px; font-weight: 700; }
.pl-vd.visible { color: var(--ok); } .pl-vd.rival { color: var(--danger); }
.pl-vd.invisible { color: var(--warn); } .pl-vd.nodata { color: var(--faint); font-weight: 500; }
/* What a row can DO, on hover. The slot holds its width when hidden so hovering
   never reflows the row under the cursor. */
.pl-acts { flex: none; display: flex; align-items: center; justify-content: flex-end; gap: 2px;
  width: 74px; opacity: 0; pointer-events: none; transition: opacity .13s ease; }
.pl-row:hover .pl-acts, .pl-row.cur .pl-acts, .pl-acts:focus-within { opacity: 1; pointer-events: auto; }
.pl-acts button { width: 23px; height: 23px; flex: none; display: inline-flex; align-items: center;
  justify-content: center; padding: 0; border: none; border-radius: 6px; background: none;
  cursor: pointer; color: var(--faint); }
.pl-acts button svg { width: 14px; height: 14px; stroke: currentColor; fill: none; }
.pl-acts button:hover { background: var(--surface); color: var(--ink); box-shadow: 0 0 0 1px var(--line); }
.pl-acts button[data-row-act="retire"]:hover { background: var(--danger-bg); color: var(--danger); box-shadow: none; }
/* Reading key in the list bar for the dots + verdict columns. Mirrors .pl-eng i
   so the sample dots are the exact glyphs a row uses; the ⓘ beside it spells out
   all four verdicts, since a colour on its own has never taught anyone what
   "rival wins" means. */
.pl-key { flex: none; display: flex; align-items: center; gap: 5px; font-size: 10.5px;
  font-weight: 600; color: var(--faint); }
.pl-key i.d { width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid var(--neutral-bar); }
.pl-key i.d.on { background: var(--faint); border-color: transparent; }
.pl-key .info-tip { margin-left: 3px; }
/* Stage header shown only when the list is sorted by journey — turns a flat
   stage-ordered list into visible Learn / Decide / Act sections. */
.pl-grp { display: flex; align-items: center; gap: 9px; padding: 11px 14px 5px;
  position: sticky; top: 0; background: var(--surface); z-index: 1; }
.pl-grp .st { flex: none; width: 52px; text-align: center; font-size: 9.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .04em; border-radius: 999px; padding: 3px 0; }
.pl-grp-b { font-size: 11px; color: var(--faint); }
.pl-grp-n { margin-left: auto; font-size: 11px; font-weight: 700; color: var(--muted);
  font-variant-numeric: tabular-nums; }
/* A losing prompt earns a coloured edge so wins and losses don't scan alike.
   Kept off the selected/current rows, whose own inset accent takes priority. */
.pl-row.loss-rival:not(.sel):not(.cur) { box-shadow: inset 3px 0 0 var(--danger); }
.pl-row.loss-invisible:not(.sel):not(.cur) { box-shadow: inset 3px 0 0 var(--warn); }
.pl-empty { padding: 34px 20px; text-align: center; color: var(--muted); font-size: 13px; }
.pl-empty b { display: block; color: var(--ink); font-size: 14px; margin-bottom: 5px; }
/* Why a candidate is being offered — the engine that issued it, or the server's
   rationale. Truncates rather than pushing the action button off the row. */
.pl-why { flex: none; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11px; color: var(--faint); }
.pl-row .pl-rowbtn { flex: none; padding: 4px 10px; font-size: 11.5px; }
.pl-row .pl-rowbtn[data-act="track"] { color: var(--accent-text); border-color: #F0D2CD; }
.pl-row .pl-rowbtn[data-act="track"]:hover { background: var(--accent-soft); border-color: var(--accent); }
/* Which product's suite a row belongs to. ONLY rendered in the all-products
   roll-up: inside a single product's suite every row would carry the same chip,
   which is noise, not information. */
.pl-row .pl-prod { flex: none; max-width: 176px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 10.5px; font-weight: 700; color: var(--muted); background: var(--canvas);
  border: 1px solid var(--line-light); border-radius: 999px; padding: 2px 8px; }
/* The same question tracked under two products: two prompts, two runs, two bills. */
.pl-row .pl-dupe { flex: none; font-size: 10px; font-weight: 700; color: var(--warn);
  background: var(--warn-bg); border-radius: 999px; padding: 2px 7px; }
.pl-row .pl-go { flex: none; font-size: 11px; color: var(--faint); }
.pl-row:hover .pl-go { color: var(--accent-text); }
/* Per-product cost breakdown in the roll-up footer — each entry switches scope. */
.pl-brk { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.pl-brk button { display: inline-flex; align-items: center; gap: 6px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px 10px; cursor: pointer;
  font-family: inherit; font-size: 11.5px; color: var(--muted); }
.pl-brk button:hover { border-color: var(--accent); color: var(--ink); }
.pl-brk button.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-text); font-weight: 600; }
.pl-brk button b { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.pl-brk button.on b { color: var(--accent-text); }
/* Where generated candidates will land. Sits under the subject picker in the
   generation dialog, because the picker no longer silently disagrees with it. */
.pl-dest { font-size: 11.5px; line-height: 1.5; color: var(--muted); margin: 7px 0 0; }
.pl-dest b { color: var(--ink); font-weight: 600; }
/* The rail's "Generate prompts…" row is gone: it was the third button on this
   screen doing exactly what the header's "Generate prompts" does, and the
   "Grow the suite" heading already frames what that group is for. */

/* Prompts carries its own Run button in the footer, beside the suite size, the
   engine count and what the run will cost. One primary run action per screen —
   the global header one steps aside here rather than competing with it. */
body.on-promptlab #btn-run-measurement { display: none; }

/* --- inspector --- */
.pl-insp { grid-area: insp; border-left: 1px solid var(--line); overflow-y: auto;
  background: var(--surface); min-width: 0; }
.pl-wb:not(.insp-open) .pl-insp { border-left: none; }
.pl-insp-in { padding: 16px 18px 28px; width: 352px; }
.pl-insp textarea { min-height: 78px; resize: vertical; font-size: 13.5px; line-height: 1.5; }
/* Verdict headline: the first thing the inspector says, coloured by outcome so a
   glance confirms the row's status. The prompt text drops to a quieter line
   beneath it — it's the subject, but no longer the loudest thing here. */
.pl-i-head { font-size: 15.5px; font-weight: 700; line-height: 1.35; margin: 0 0 4px; }
.pl-i-head.ok { color: var(--ok); } .pl-i-head.danger { color: var(--danger); }
.pl-i-head.warn { color: var(--warn); } .pl-i-head.faint { color: var(--faint); }
.pl-i-q { font-size: 13px; line-height: 1.5; color: var(--body); margin: 0; }
/* Destructive action, demoted: a quiet text link at the very bottom of the
   action stack, so it can't out-shout the emphasized "Open full breakdown". */
.pl-linkbtn { align-self: flex-start; background: none; border: none; padding: 3px 0; margin-top: 1px;
  font-size: 12px; font-weight: 600; color: var(--danger); cursor: pointer; opacity: .8; }
.pl-linkbtn:hover { opacity: 1; text-decoration: underline; }
.pl-insp .sec { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--faint); margin: 20px 0 8px; }
.pl-erow { display: flex; align-items: center; gap: 9px; padding: 7px 0; border-top: 1px solid var(--line-light); font-size: 12.5px; }
.pl-erow .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.pl-erow .vd { margin-left: auto; font-weight: 700; font-size: 11px; }
.pl-quote { background: var(--canvas); border-radius: 9px; padding: 11px 13px; font-size: 12.5px;
  line-height: 1.65; color: var(--body); max-height: 190px; overflow: auto; }
.pl-quote mark { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; border-radius: 3px; padding: 0 2px; }

/* --- footer + selection bar --- */
.pl-foot { grid-area: foot; display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 10px 16px; border-top: 1px solid var(--line); background: var(--sidebar); font-size: 12.5px; }
.pl-foot .m { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
.pl-foot .m b { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.pl-foot .sp { width: 1px; height: 15px; background: var(--line-hover); }
.pl-foot .btn { margin-left: auto; }
/* Hidden by transform, never by display: a display:none → block flip can't
   transition, and the rAF dance that works around it silently fails in a
   throttled background tab, leaving the bar off-screen while rows are ticked. */
.pl-selbar { position: absolute; left: 214px; right: 0; bottom: 0; z-index: 12;
  display: flex; align-items: center; gap: 10px; padding: 11px 16px;
  background: var(--ink); color: #fff; font-size: 12.5px;
  transform: translateY(100%); pointer-events: none;
  transition: transform .26s var(--ease-out); }
.pl-selbar.up { transform: none; pointer-events: auto; }
.pl-selbar b { font-variant-numeric: tabular-nums; }
.pl-selbar .btn { flex: none; }
.pl-selbar .btn-ghost { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.22); color: #fff; }
.pl-selbar .btn-ghost:hover { background: rgba(255,255,255,.18); color: #fff; }
.pl-selbar .x { margin-left: auto; background: none; border: none; color: rgba(255,255,255,.6);
  font-size: 17px; cursor: pointer; line-height: 1; padding: 2px 6px; }
.pl-selbar .x:hover { color: #fff; }

/* --- generation dialog --- */
/* Geometry only — the dialog treatment itself comes from MODAL SURFACES. */
.pl-over { width: min(1080px, 94vw); height: min(840px, 88vh); }
.pl-over-head { flex: none; display: flex; align-items: flex-start; gap: 12px; padding: 18px 24px;
  border-bottom: 1px solid var(--line-light); }
.pl-over-head h2 { font-size: 20px; font-weight: 600; margin: 4px 0 0; }
.pl-over-head .drawer-close { margin-left: auto; }
.pl-over-body { flex: 1; min-height: 0; display: grid;
  grid-template-columns: 336px minmax(0, 1fr); overflow: hidden; }
.pl-gen-side { overflow-y: auto; padding: 20px 22px 26px;
  border-right: 1px solid var(--line); background: var(--sidebar); }
.pl-gen-side select, .pl-gen-side .btn { width: 100%; }
.pl-gen-main { overflow-y: auto; padding: 20px 24px 26px; }
/* The shared .bp-sugs min is tuned for a full-width card; in this column it
   leaves a whole empty track. Narrow it so the dialog runs two-up. */
.pl-gen-main .bp-sugs { grid-template-columns: repeat(auto-fill, minmax(296px, 1fr)); }
.pl-gen-empty { padding: 60px 24px; text-align: center; color: var(--muted); font-size: 13px;
  line-height: 1.6; max-width: 46ch; margin: 0 auto; }
.pl-gen-empty b { display: block; color: var(--ink); font-size: 15px; margin-bottom: 6px;
  font-family: var(--display); font-weight: 600; }
.pl-seed { display: flex; align-items: flex-start; gap: 10px; background: var(--accent-soft);
  border: 1px solid #F3D3C6; border-radius: 11px; padding: 10px 12px; margin-bottom: 16px; }
.pl-seed .k { flex: none; font-size: 10px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--accent-text); padding-top: 2px; }
.pl-seed .t { flex: 1; min-width: 0; font-size: 12.5px; color: var(--ink); line-height: 1.45; }
.pl-seed .x { flex: none; background: none; border: none; color: var(--accent-text);
  font-size: 14px; cursor: pointer; line-height: 1; padding: 2px 4px; }
/* One engine-issued query inside the inspector's fan-out section. */
.pl-fanq { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.pl-fanq code { flex: 1; min-width: 0; font-size: 11.5px; color: var(--body);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-over-foot { flex: none; display: flex; gap: 10px; padding: 14px 22px; border-top: 1px solid var(--line);
  background: var(--sidebar); }
.pl-over-foot .btn { flex: 1; }

/* --- shortcut sheet --- */
.pl-keys { position: absolute; right: 14px; bottom: 56px; z-index: 20; width: 268px;
  background: var(--ink); color: #fff; border-radius: 12px; padding: 14px 16px;
  box-shadow: 0 20px 44px rgba(20,24,33,.3); font-size: 12.5px; }
.pl-keys[hidden] { display: none; }
.pl-keys .r { display: flex; align-items: center; gap: 10px; padding: 4px 0; color: rgba(255,255,255,.72); }
.pl-keys .r kbd { flex: none; min-width: 22px; text-align: center; background: rgba(255,255,255,.14);
  border-radius: 5px; padding: 2px 6px; font-family: var(--mono); font-size: 11px; color: #fff; }

@media (max-width: 1180px) {
  .pl-wb.insp-open { --pl-insp-w: 300px; }
  .pl-insp-in { width: 300px; }
}
/* Below ~1180 with the inspector open there is no honest room for three columns
   (the middle one collapses to ~160px and its controls get clipped). Rather than
   crush it, drop the inspector UNDER the list: rail stays a column on the left,
   the list and the inspector share the right, stacked. The full ≤980 stack below
   takes over when even that is too tight. */
@media (min-width: 981px) and (max-width: 1180px) {
  .pl-wb.insp-open {
    grid-template-columns: 214px minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "head head" "rail main" "rail insp" "foot foot";
  }
  .pl-wb.insp-open .pl-insp { border-left: none; border-top: 1px solid var(--line); max-height: 42vh; }
  .pl-wb.insp-open .pl-insp-in { width: auto; }
}
/* With the inspector open the middle column is narrow enough that the reading
   key would push the sort onto a second line, so it's the first thing to yield
   space — the row it explains is right below it, and the verdict words carry
   their own meaning. It returns once the column is wide enough to keep the bar
   on one line (wide window, or inspector closed — this only targets insp-open).
   Below 980 the layout stacks full-width, so the key comes back there too. */
@media (min-width: 981px) and (max-width: 1400px) {
  .pl-wb.insp-open .pl-key { display: none; }
}
@media (max-width: 860px) {
  /* Not enough width for two columns — stack, and let the dialog fill the screen. */
  .pl-over { width: 96vw; height: 92vh; }
  .pl-over-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .pl-gen-side { border-right: none; border-bottom: 1px solid var(--line); }
  .pl-gen-empty { padding: 30px 16px; }
}
@media (max-width: 980px) {
  .as-prompts [data-drill="promptlab"] { height: auto; }
  .pl-wb { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto auto auto;
    grid-template-areas: "head" "rail" "main" "insp" "foot"; }
  .pl-wb.insp-open { --pl-insp-w: auto; }
  .pl-rail { border-right: none; border-bottom: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 6px; }
  .pl-rail .grp { display: none; }
  .pl-q { width: auto; border: 1px solid var(--line); background: var(--surface); }
  /* No hover on touch, so the row's verbs can't hide behind one. */
  .pl-acts { opacity: 1; pointer-events: auto; }
  .pl-list { max-height: 58vh; }
  .pl-insp-in { width: auto; }
  .pl-selbar { left: 0; }
}

/* ============================================================================
   MOTION SYSTEM
   Everything below is presentation-only: the DOM always ends in its final,
   correct state, so a failed animation degrades to "it was already there".
   Charts and counters are driven from app.html's motionScan() via an
   IntersectionObserver, so they play when scrolled into view — not all at
   once on load. The whole layer is switched off under prefers-reduced-motion
   at the bottom of this section.
   ============================================================================ */
:root {
  --ease-out: cubic-bezier(.22,.61,.36,1);   /* decelerate — entrances */
  --ease-spring: cubic-bezier(.34,1.36,.64,1); /* slight overshoot — pops, lifts */
}

@keyframes vRise { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: none; } }
@keyframes dotIn { from { opacity: 0; transform: scale(.3); } to { opacity: 1; transform: none; } }
@keyframes barGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes shimmer { to { background-position: 200% 0; } }
@keyframes ringPulse { 0% { box-shadow: 0 0 0 0 rgba(236,107,76,.4); } 70%, 100% { box-shadow: 0 0 0 7px rgba(236,107,76,0); } }

/* --- Staggered view entry ---------------------------------------------------
   The section itself only fades (a transform on the section would drag its
   children's transforms with it); each top-level block rises on its own beat.
   nth-child covers the deepest view; anything past it just fades with the
   parent, which is correct — it's below the fold anyway. */
.view.active { animation: vFade .3s ease both; }
.view.active > * { animation: vRise .5s var(--ease-out) both; }
.view.active > *:nth-child(1)  { animation-delay: 0ms; }
.view.active > *:nth-child(2)  { animation-delay: 45ms; }
.view.active > *:nth-child(3)  { animation-delay: 85ms; }
.view.active > *:nth-child(4)  { animation-delay: 120ms; }
.view.active > *:nth-child(5)  { animation-delay: 150ms; }
.view.active > *:nth-child(6)  { animation-delay: 175ms; }
.view.active > *:nth-child(7)  { animation-delay: 195ms; }
.view.active > *:nth-child(8)  { animation-delay: 212ms; }
.view.active > *:nth-child(n+9) { animation-delay: 225ms; }
/* Hidden blocks must not reserve their animated opacity when revealed later. */
.view.active > .hidden, .view.active > [hidden] { animation: none; }

/* Prompts workbench entrance.
   Every other view is a stack of cards, so `.view.active > *` staggers each one
   in. The workbench is a SINGLE full-height child, so that rule slid the whole
   card up as one flat block — present, but lifeless next to the card cascade.
   So the container just fades (no translate, or it would double up with the
   zones), and its four zones rise in sequence — head, rail, main, footer — the
   same reveal, adapted to a fixed grid. Inside, the rail queues and the first
   rows fade up in a light second wave so the content reads as arriving, not the
   panels alone. Opacity-only there, so nothing compounds with a rising parent.
   One-shot: JS adds `.pl-in` on entry and drops it once it plays, so re-rendering
   the list on a filter click never re-cascades. */
.view.active > [data-drill="promptlab"] { animation: vFade .35s ease both; }
.pl-wb.pl-in > .pl-head { animation: vRise .5s var(--ease-out) both; }
.pl-wb.pl-in > .pl-rail { animation: vRise .5s var(--ease-out) 55ms both; }
.pl-wb.pl-in > .pl-main { animation: vRise .5s var(--ease-out) 90ms both; }
.pl-wb.pl-in > .pl-foot { animation: vRise .5s var(--ease-out) 135ms both; }
.pl-wb.pl-in .pl-rail .pl-q { animation: vFade .44s ease 130ms both; }
/* Cascade every direct child of the list — rows AND the sticky stage headers
   that sit between them when grouped — so the sequence stays even in every sort
   mode (targeting .pl-row alone let a header steal the first slot). */
.pl-wb.pl-in .pl-list > * { animation: vFade .42s ease both; }
.pl-wb.pl-in .pl-list > *:nth-child(1) { animation-delay: 150ms; }
.pl-wb.pl-in .pl-list > *:nth-child(2) { animation-delay: 176ms; }
.pl-wb.pl-in .pl-list > *:nth-child(3) { animation-delay: 200ms; }
.pl-wb.pl-in .pl-list > *:nth-child(4) { animation-delay: 222ms; }
.pl-wb.pl-in .pl-list > *:nth-child(5) { animation-delay: 242ms; }
.pl-wb.pl-in .pl-list > *:nth-child(6) { animation-delay: 260ms; }
.pl-wb.pl-in .pl-list > *:nth-child(n+7) { animation-delay: 276ms; }

/* --- Charts ---------------------------------------------------------------- */
/* Line draw-on. The dash length is measured in JS (getTotalLength) and set
   inline; vDraw only has to run the offset to zero. Unscoped on purpose — every
   line in the app draws, including KPI sparklines and table-cell trends. */
polyline.ln-draw { animation: vDraw .85s var(--ease-out) both; }
/* A 104px sparkline taking as long as a 700px trend chart reads as sluggish;
   match the duration roughly to the distance the eye has to travel. */
.kpi polyline.ln-draw, .vtable polyline.ln-draw, .statcard polyline.ln-draw,
.metric-card polyline.ln-draw, .headline-grid polyline.ln-draw { animation-duration: .5s; }
/* CI band waits for the line it belongs to, then settles in behind it. */
/* The 95% CI ribbon. Its opacity is defined ONCE, here — the fade-in animates
   to that same value rather than to 1, so playing the animation can never
   change how heavy the band reads. */
.ci-band { opacity: .12; }
@keyframes bandIn { from { opacity: 0; } to { opacity: .12; } }
.ci-band.band-in { animation: bandIn .5s ease .42s both; }
.trenddot.dot-in { animation: dotIn .34s var(--ease-spring) both; }
.barfill.bar-in { animation: barGrow .62s var(--ease-out) both; }
.whisker-in { animation: vFade .3s ease both; }

/* HTML bar rows (.bars, .engine-card, .usage-bar, .plancard) grow from the
   left rather than appearing at full length. */
.bars.anim .bar .track > i,
.engine-grid.anim .engine-card .track > i,
.src-rows.anim .bar .track > i,
.anim > .usage-bar > div { transform-origin: left center; animation: barGrow .6s var(--ease-out) both; }
.bars.anim .bar:nth-child(1) .track > i, .engine-grid.anim .engine-card:nth-child(1) .track > i, .src-rows.anim .bar:nth-child(1) .track > i { animation-delay: 40ms; }
.bars.anim .bar:nth-child(2) .track > i, .engine-grid.anim .engine-card:nth-child(2) .track > i, .src-rows.anim .bar:nth-child(2) .track > i { animation-delay: 95ms; }
.bars.anim .bar:nth-child(3) .track > i, .engine-grid.anim .engine-card:nth-child(3) .track > i, .src-rows.anim .bar:nth-child(3) .track > i { animation-delay: 150ms; }
.bars.anim .bar:nth-child(4) .track > i, .engine-grid.anim .engine-card:nth-child(4) .track > i, .src-rows.anim .bar:nth-child(4) .track > i { animation-delay: 205ms; }
.bars.anim .bar:nth-child(5) .track > i, .src-rows.anim .bar:nth-child(5) .track > i { animation-delay: 260ms; }
.bars.anim .bar:nth-child(6) .track > i, .src-rows.anim .bar:nth-child(6) .track > i { animation-delay: 315ms; }
.bars.anim .bar:nth-child(n+7) .track > i, .src-rows.anim .bar:nth-child(n+7) .track > i { animation-delay: 360ms; }

/* --- Details that make it feel settled -------------------------------------
   Small things, but they're the difference between "it animated" and "it feels
   built". Each one fixes a specific irritation rather than adding decoration. */

/* Proportional digits change width as a counter ticks, so an animating number
   visibly jitters and shoves its delta pill around. Tabular figures lock every
   digit to one advance width — the count-up we added is the reason this matters. */
[data-count], .kpi .val, .kpi .valrow > span:first-child, .statcard .num,
.metric-val, .dark-hero .big, .engine-card .val, .bar .val, .pl-vd,
.vtable td.r, .ap-bar b { font-variant-numeric: tabular-nums; }

/* A delta only means something once you've read the number it belongs to, so it
   arrives just after the counter lands rather than competing with it. */
.kpi .delta, .kpi .valrow > span:nth-child(2) { animation: vFade .34s ease .46s both; }

/* Scroll affordance: a hairline shadow appears at a pane's edge only when there
   is genuinely more content past it. Pure CSS — background-attachment does the
   detection, so there is no scroll listener anywhere. */
.pl-list, .pl-insp, .pl-rail, .drawer-body, .pl-over-body > .scroll {
  background:
    linear-gradient(var(--surface) 30%, rgba(255,255,255,0)) top / 100% 26px no-repeat,
    linear-gradient(rgba(255,255,255,0), var(--surface) 70%) bottom / 100% 26px no-repeat,
    radial-gradient(farthest-side at 50% 0, rgba(20,24,33,.09), rgba(0,0,0,0)) top / 100% 9px no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(20,24,33,.09), rgba(0,0,0,0)) bottom / 100% 9px no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.pl-rail { background-color: var(--sidebar); }

/* Selection should feel like a click landed, not like a checkbox changed. */
input[type=checkbox] { transition: transform .16s var(--ease-spring); }
input[type=checkbox]:active { transform: scale(.86); }
input[type=checkbox]:checked { animation: tickPop .24s var(--ease-spring); }
@keyframes tickPop { 0% { transform: scale(.8); } 60% { transform: scale(1.14); } 100% { transform: scale(1); } }

/* Keyboard users get the same quality of feedback as mouse users. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.pl-row:focus-visible, .nav a:focus-visible { outline-offset: -2px; }

/* A row leaving the list collapses instead of the list snapping shut under the
   cursor — you see WHICH row went, which is what makes an undo offer legible. */
@keyframes rowExit { to { opacity: 0; transform: translateX(-14px); max-height: 0;
  padding-top: 0; padding-bottom: 0; border-bottom-width: 0; } }
.pl-row.exit { animation: rowExit .3s var(--ease-out) forwards; overflow: hidden; pointer-events: none; }

/* --- Skeletons -------------------------------------------------------------
   Placeholder geometry that matches what lands, so nothing jumps on arrival. */
.skel { background: linear-gradient(90deg, var(--line-light) 25%, #F4F6F8 50%, var(--line-light) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s ease-in-out infinite; border-radius: 7px; }
.skel-row { height: 13px; margin: 11px 0; }
.skel-row.w40 { width: 40%; } .skel-row.w60 { width: 60%; } .skel-row.w80 { width: 80%; }
.skel-bar { display: flex; align-items: center; gap: 12px; margin: 11px 0; }
.skel-bar .k { flex: none; width: 78px; height: 11px; }
.skel-bar .t { flex: 1; height: 16px; border-radius: 6px; }
.skel-card { height: 92px; border-radius: 12px; }

/* --- Interaction physics ---------------------------------------------------
   Lift + an accent-tinted shadow rather than a flat grey one: the surface
   looks like it is picking up the brand light above it. */
.vcard.click, .tool, .kpi, .statcard, .engine-card {
  transition: transform .26s var(--ease-spring), box-shadow .26s var(--ease-out), border-color .2s ease;
}
.vcard.click:hover, .tool:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px -14px rgba(20,24,33,.22), 0 3px 10px -6px rgba(236,107,76,.22);
}
.kpi.drillable { cursor: pointer; }
.kpi.drillable:hover, .statcard.drillable:hover, .engine-card.drillable:hover {
  transform: translateY(-2px); border-color: var(--line-hover);
  box-shadow: 0 10px 24px -12px rgba(20,24,33,.2), 0 2px 8px -5px rgba(236,107,76,.2);
}
.statcard.dark.drillable:hover { box-shadow: 0 14px 30px -12px rgba(20,24,33,.45); }
.btn:active:not([disabled]), .iconbtn:active, .chip:active { transform: scale(.97); }
.btn-primary { transition: filter .18s ease, transform .2s var(--ease-spring), box-shadow .24s ease; }
.btn-primary:hover { box-shadow: 0 12px 24px -10px rgba(236,107,76,.62); transform: translateY(-1px); }
/* Active nav gets a live accent rail rather than a static inset border. */
.nav a.active { position: relative; }
.nav a.active::before { content: ""; position: absolute; left: 0; top: 7px; bottom: 7px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--accent); }
.nav a.active { box-shadow: none; }
.nav a svg { transition: transform .24s var(--ease-spring); }
.nav a:hover svg { transform: translateX(1px) scale(1.06); }
/* A run in flight is the one thing worth a pulse. */
.pulse .d { animation: ringPulse 2.4s ease-out infinite; }

/* --- Reduced motion --------------------------------------------------------
   Kills every entrance and the shimmer. Hover transitions stay: they're a
   response to direct input, not ambient movement. */
@media (prefers-reduced-motion: reduce) {
  .view.active, .view.active > *,
  /* NB: .ci-band is deliberately absent — this block forces opacity:1, which
     would flatten the CI ribbon into a solid block. Its own rule already ends
     at .12, so killing the animation needs no help here. */
  polyline.ln-draw, .trenddot.dot-in, .barfill.bar-in, .whisker-in,
  .bars.anim .bar .track > i, .engine-grid.anim .engine-card .track > i,
  .src-rows.anim .bar .track > i,
  .pl-wb.pl-in > .pl-head, .pl-wb.pl-in > .pl-rail, .pl-wb.pl-in > .pl-main,
  .pl-wb.pl-in > .pl-foot, .pl-wb.pl-in .pl-q, .pl-wb.pl-in .pl-list > *,
  .anim > .usage-bar > div, .skel, .pulse .d, .pl-row.exit {
    animation: none !important;
    stroke-dashoffset: 0 !important;
    opacity: 1 !important;
    transform: none !important;
  }
  /* Ambient loops are the clearest case for this setting. Held at the midpoint
     of their pulse rather than opacity:1, which would leave them brighter than
     they ever get while animating. */
  .ov-band::after, .dark-hero .glow { animation: none !important; opacity: .7 !important; }
  .vcard.click:hover, .tool:hover, .kpi.drillable:hover,
  .statcard.drillable:hover, .engine-card.drillable:hover, .btn-primary:hover { transform: none; }
}

/* ==========================================================================
   Embed mode — chromeless single-feature view for the unified shell iframe
   ========================================================================== */
html.embed .side, html.embed .hdr { display: none; }
html.embed .main { height: auto; }
html.embed .appmain { padding: 10px 18px 30px; }
html.embed .view:not(.active) { display: none; }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1080px) {
  .headline-grid { grid-template-columns: repeat(3, 1fr); }
  .engine-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  .side { position: fixed; left: 0; top: 0; z-index: 60; transform: translateX(-100%); transition: transform .25s; box-shadow: 0 0 40px rgba(0,0,0,.2); }
  .app.nav-open .side { transform: none; }
  /* !important is deliberate: eight of these carry an inline
     style="display:grid;grid-template-columns:1.7fr 1fr", and an inline
     declaration outranks a plain rule — so the two-column layouts never
     collapsed on narrow screens and overflowed by ~290px instead. */
  .g2, .g3 { grid-template-columns: 1fr !important; }
  /* Bar rows carry fixed inline label widths; let them give way rather than
     push the value out of the card. */
  .bar .lbl { width: auto !important; max-width: 42%; }
  .bar .val.note { max-width: 52%; }
  .headline-grid, .engine-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
  .appmain { padding: 18px 16px 40px; }
  .headline-grid, .engine-grid { grid-template-columns: 1fr 1fr; }
  .hero h1 { font-size: 2.1rem; }
}

/* ===== Product tour (coach marks) =====
   A light guided walkthrough for first-time users: a spotlight ring dims the app
   around one target, a small popover explains it, Next/Back/Skip to move. */
.tour-block { position: fixed; inset: 0; z-index: 99998; }
.tour-ring { position: fixed; z-index: 99999; border-radius: 10px; pointer-events: none;
  box-shadow: 0 0 0 3px var(--accent), 0 0 0 9999px rgba(16, 20, 28, .55); transition: all .22s ease; }
.tour-pop { position: fixed; z-index: 100000; width: 300px; max-width: calc(100vw - 24px);
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 16px 44px rgba(16, 20, 28, .24); padding: 16px 16px 14px;
  transition: left .22s ease, top .22s ease; }
.tour-t { font-size: 14.5px; font-weight: 700; color: var(--ink); margin-bottom: 5px; }
.tour-b { font-size: 12.8px; line-height: 1.55; color: var(--muted); }
.tour-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 14px; }
.tour-dots { display: flex; gap: 5px; }
.tour-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line); }
.tour-dot.on { background: var(--accent); }
.tour-btns { display: flex; align-items: center; gap: 6px; }
.tour-btns button { font: inherit; cursor: pointer; border-radius: 8px; font-size: 12.5px; font-weight: 600;
  padding: 6px 12px; border: 1px solid transparent; }
.tour-skip { background: none; color: var(--faint); }
.tour-skip:hover { color: var(--muted); }
.tour-back { background: none; color: var(--muted); border-color: var(--line); }
.tour-next { background: var(--ink); color: #fff; }
.tour-next:hover { opacity: .92; }
