/* ===========================================================================
   Answermend — app.answermend.com — the authenticated dashboard.

   ⚠️ THIS DIRECTORY IS NOT PUBLISHED BY tools/publish-wp.mjs, EVER.
   08-website.md §8.2: the app lives on a subdomain — separate cookie scope,
   separate deploy target, no marketing-site cache in front of it — and its
   pages are not trying to rank. Every page here carries noindex,nofollow and
   canonicalises to https://app.answermend.com/. publish-wp takes an explicit
   file argument, so nothing here is picked up by accident; the danger is
   somebody typing one of these paths at it. Don't.

   WHY THIS IS A SHARED STYLESHEET AND THE MARKETING PAGES INLINE THEIRS.
   build/*.html inline their <style> because WordPress DISCARDS the built
   <head> at publish, so a <link> there would vanish (see the header comment in
   build/pricing.html). That constraint does not exist on a static subdomain
   served as files. Six pages sharing 900 lines of duplicated CSS would drift
   within a week, so the app takes the one file. The tokens below are COPIED
   from build/pricing.html — the production shell, Direction B,
   design/directions/B_BUILD_SPEC.md, owner-approved 2026-08-31 — including the
   contrast corrections that file records. This is not a second design system:
   if a token changes there, it changes here, and the two are meant to be
   diff-able. Nothing below invents a colour, a size or a family.

   THE ONE RULE THIS FILE EXISTS TO ENFORCE VISUALLY
   ------------------------------------------------------------------
   "Not measured" must never be able to be mistaken for zero, for a loss, or
   for a low score. So the four states are carried by THREE signals each —
   colour, border style, and the presence or absence of a numeral:

     cited        solid  green tint   real numerals   "2 of 3 runs"
     mentioned    solid  grey  tint   real numerals   "3 of 3 runs"
     missing      solid  red   tint   real numerals   "0 of 3 runs"   <- a real zero
     not measured DASHED, NO FILL, grey, and an EM DASH where the numeral goes,
                  plus the reason it did not run.

   A measured zero is a solid red chip carrying the digit 0. An unmeasured cell
   is a dashed outline carrying no digit at all. Screenshot the two side by side
   and they are different objects, not different shades of one.
   =========================================================================== */

:root{
  /* ground */
  --bg:#FBFBFC;
  --pap:#F7F7F9;
  --card:#FFFFFF;
  --ink:#0A0E12;

  /* text */
  --tx2:#59646E;
  --tx3:#646E78;       /* muted / mono labels — #8A95A0 failed at 2.79–3.05:1 */
  --on-ink:#9BA6AF;

  /* line */
  --line:#E7E9EC;
  --line2:#F0F1F3;

  /* accent */
  --acc:#F07800;
  --accD:#AD5500;
  --accS:#FFF3E4;
  --accB:#FADFBE;
  --accTx:#8A5200;

  /* the four states — never invent a fifth */
  --grn:#12784A; --grnS:#E9F6EF; --grnB:#CDE7D6;   /* cited */
  --red:#C42B1C; --redS:#FDEDEB; --redB:#F3D3CF;   /* missing */
  /* mentioned is --tx2 on #F3F4F6 with #E5E7EA — deliberately NOT a success colour */
  --dash:#848D96;      /* the not-measured carrier. Load-bearing and corrected
                          twice upstream; clears --bg 3.26 · --pap 3.15 ·
                          --card 3.37 · --accS 3.08. Do not lighten it. */
  --dash-fill:#FCFCFD;

  --inkCard:#131A20;
  --inkLine:#5C6A75;
  --inkRing:#FFD79A;

  --f-disp:"Space Grotesk",Inter,sans-serif;
  --f-sans:"Inter","Helvetica Neue",Arial,sans-serif;
  --f-mono:"IBM Plex Mono",monospace;
}

*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--f-sans);font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
p{margin:0;line-height:1.6;}
h1,h2,h3,h4{margin:0;}
ul,ol{margin:0;padding:0;list-style:none;}
a{color:inherit;}

:focus-visible{outline:2px solid var(--accD);outline-offset:2px;border-radius:4px;}

.skip{
  position:absolute;left:0;top:-64px;z-index:99;
  background:var(--ink);color:#fff;padding:12px 18px;
  font-family:var(--f-mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  text-decoration:none;
}
.skip:focus{top:0;}
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* ---------- layout ---------- */
.wrap{max-width:1280px;margin:0 auto;padding:0 40px;position:relative;}
.sec{padding:40px 0;}
.sec-pap{background:var(--pap);}

/* ---------- type ---------- */
.kick{
  font-family:var(--f-mono);font-weight:500;font-size:11px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--tx3);display:block;
}
h1{font-family:var(--f-disp);font-weight:700;font-size:40px;line-height:1.05;letter-spacing:-.035em;margin:10px 0 0;}
h2{font-family:var(--f-disp);font-weight:700;font-size:24px;line-height:1.14;letter-spacing:-.03em;}
h3{font-family:var(--f-disp);font-weight:500;font-size:17px;letter-spacing:-.02em;line-height:1.3;}
h4{font-family:var(--f-mono);font-weight:500;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--tx3);}
/* .lbl is the same eyebrow, as a <p>. Most of the small uppercase labels in
   this app are captions on a card, not sections of the document — marking
   them up as <h4> under an <h2> skipped a heading level on every page and
   handed a screen-reader user an outline the page does not have. Same
   pixels, no heading. */
.lbl{font-family:var(--f-mono);font-weight:500;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--tx3);}
.lede{font-size:16px;color:var(--tx2);max-width:720px;margin-top:10px;}
.mono{font-family:var(--f-mono);}
.fine{font-family:var(--f-mono);font-size:11.5px;color:var(--tx3);letter-spacing:.02em;}
.muted{color:var(--tx3);}
.dom{font-family:var(--f-mono);font-size:11.5px;color:var(--tx3);}

/* ---------- buttons ---------- */
.btn{
  display:inline-block;font-family:var(--f-sans);font-weight:600;font-size:15px;
  line-height:1.2;text-decoration:none;border-radius:10px;border:1px solid transparent;
  padding:13px 22px;cursor:pointer;
}
.btn-primary{background:var(--acc);color:var(--ink);box-shadow:0 12px 30px -12px rgba(240,120,0,.85);}
.btn-primary:focus-visible{outline-color:var(--ink);}
.btn-secondary{border-color:var(--line);background:#fff;color:var(--ink);font-weight:550;padding:12px 18px;}
.btn-dark{background:var(--ink);color:#fff;font-weight:600;font-size:13px;padding:9px 15px;border-radius:8px;}
.btn-sm{font-size:13px;padding:9px 14px;}
.btn-block{display:block;width:100%;text-align:center;}
.btn[aria-disabled="true"],.btn:disabled{
  background:#EEEFF1;color:var(--tx3);border-color:var(--line);box-shadow:none;cursor:not-allowed;
}

/* ---------- chips (the four states, verbatim from the shell) ---------- */
.p{
  font-family:var(--f-mono);font-weight:500;font-size:11px;
  padding:3px 8px;border-radius:5px;display:inline-block;line-height:1.4;
  border:1px solid transparent;white-space:nowrap;
}
.pc{color:var(--grn);background:var(--grnS);border-color:var(--grnB);}
.pm{color:var(--tx2);background:#F3F4F6;border-color:#E5E7EA;}
.pr{color:var(--red);background:var(--redS);border-color:var(--redB);}
.pu{color:var(--tx3);background:transparent;border:1px dashed var(--dash);}
.pa{color:var(--accTx);background:var(--accS);border-color:var(--accB);}

/* The k/n line that sits under a chip. It is NEVER omitted on a measured cell
   and NEVER present on an unmeasured one — see .kn-none below. */
.kn{font-family:var(--f-mono);font-size:10.5px;color:var(--tx3);display:block;margin-top:4px;letter-spacing:.02em;}
/* The em dash that stands where a numeral would be. Same size and same slot as
   .kn so the layout does not shift, but it is not a number and cannot be read
   as one. */
.kn-none{font-family:var(--f-mono);font-size:10.5px;color:var(--dash);display:block;margin-top:4px;}

/* ---------- the EXAMPLE DATA chip (same object as build/pricing.html .ex) ---------- */
.ex{
  font-family:var(--f-mono);font-weight:500;font-size:11px;letter-spacing:.12em;
  color:var(--accTx);background:var(--accS);border:1px solid var(--accB);
  padding:3px 9px;border-radius:5px;display:inline-block;
}

/* ---------- app bar ---------- */
.appbar{background:var(--card);border-bottom:1px solid var(--line);position:relative;z-index:5;}
.appbar-inner{display:flex;align-items:center;gap:22px;padding-block:14px;}
.wm{font-family:var(--f-disp);font-weight:700;font-size:18px;letter-spacing:-.02em;text-decoration:none;color:var(--ink);}
.wm span{border-bottom:3px dashed var(--acc);padding-bottom:1px;}
.appnav{display:flex;gap:22px;align-items:center;font-size:14px;color:var(--tx2);}
.appnav a{text-decoration:none;color:var(--tx2);padding:4px 0;}
.appnav a:hover{color:var(--ink);}
.appnav a[aria-current="page"]{color:var(--ink);font-weight:600;box-shadow:inset 0 -2px 0 var(--acc);}
.appbar-right{margin-left:auto;display:flex;align-items:center;gap:14px;}
.orgpill{
  font-family:var(--f-mono);font-size:11px;color:var(--tx2);
  border:1px solid var(--line);border-radius:99px;padding:5px 11px;background:var(--pap);
}
.nav-toggle{display:none;}

/* ---------- page head ---------- */
.phead{padding:26px 0 6px;}
.crumb{font-family:var(--f-mono);font-size:11px;color:var(--tx3);letter-spacing:.06em;}
.crumb a{text-decoration:none;color:var(--tx3);}
.crumb a:hover{color:var(--ink);}
.head-row{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-top:8px;}
.head-row .ex{margin-bottom:6px;}

/* ---------- the example-data banner ---------- */
/* Every page in this directory renders fabricated data. DEFINITION_OF_DONE
   Type B7: mock output labels itself as fabricated. It is a banner and not a
   footnote because a screenshot of this page will end up in a deck. */
.exbanner{
  display:flex;gap:12px;align-items:flex-start;
  background:var(--accS);border:1px solid var(--accB);border-radius:11px;
  padding:13px 16px;margin-top:18px;font-size:13.5px;color:var(--accTx);
}
.exbanner b{color:var(--ink);}

/* ---------- cards / grid ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:20px;}
.card + .card{margin-top:14px;}
.card > h2,.card > h3{margin-bottom:4px;}
.grid{display:grid;gap:14px;}
/* A grid item's default is min-width:auto, which means it REFUSES to get
   narrower than its own min-content — and the min-content of a card holding
   the prompt matrix is that table's 660px min-width. The result was the card
   sitting 704px wide inside a 458px track and the whole PAGE scrolling
   sideways on a phone, while .tbl-wrap's overflow-x:auto sat there doing
   nothing because the box it was meant to clip had already been widened.
   min-width:0 hands the constraint back to the track, and the table then
   scrolls inside its own container the way it was always meant to. */
.grid > *,.stack > *{min-width:0;}
.g2{grid-template-columns:1fr 1fr;align-items:start;}
.g3{grid-template-columns:repeat(3,1fr);}
.g4{grid-template-columns:repeat(4,1fr);}
.g-side{grid-template-columns:minmax(0,1fr) 340px;align-items:start;}
.stack{display:grid;gap:14px;}

/* ---------- KPI tiles ---------- */
/* Used sparingly and never as the top of a brand page — see the Admodifier
   note carried in brand.html: a stale tile is worse than no tile. Every tile
   carries the date it was measured, in the tile. */
.k{border:1px solid var(--line);border-radius:11px;padding:14px 15px;background:var(--card);}
.k.dash{border-style:dashed;border-color:var(--dash);background:var(--dash-fill);}
.kfig{font-family:var(--f-disp);font-weight:700;font-size:28px;letter-spacing:-.03em;line-height:1;}
.kfig .of{font-size:15px;color:var(--tx3);font-weight:500;}
.kfig.g{color:var(--grn);}
.kfig.u{color:var(--tx3);}
/* The unmeasured tile's figure is a COUNT OF CHECKS THAT DID NOT RUN. It is
   deliberately typeset smaller and in mono so it does not read as a score in
   the same units as the tiles beside it. */
.kfig.count{font-family:var(--f-mono);font-size:22px;font-weight:500;letter-spacing:0;}
.klabel{font-size:12.5px;color:var(--tx2);margin-top:6px;}
.kdesc{font-family:var(--f-mono);font-size:9.5px;color:var(--tx3);margin-top:3px;line-height:1.5;}
.kstamp{font-family:var(--f-mono);font-size:9.5px;color:var(--tx3);margin-top:8px;padding-top:7px;border-top:1px solid var(--line2);}

/* ---------- tables ---------- */
.tbl-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:13px;background:var(--card);}
table.t{width:100%;border-collapse:collapse;min-width:720px;}
table.t caption{
  caption-side:top;text-align:left;padding:16px 18px 0;
  font-family:var(--f-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--tx3);
}
table.t thead th{
  font-family:var(--f-mono);font-weight:500;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--tx3);text-align:left;padding:14px 16px;border-bottom:1px solid var(--line);vertical-align:bottom;
}
table.t tbody th{
  text-align:left;font-weight:550;font-size:13.5px;color:var(--ink);
  padding:13px 16px;border-bottom:1px solid var(--line2);vertical-align:top;
}
table.t td{font-size:13px;color:var(--tx2);padding:13px 16px;border-bottom:1px solid var(--line2);vertical-align:top;}
table.t tbody tr:last-child th,table.t tbody tr:last-child td{border-bottom:none;}
table.t td.num{font-family:var(--f-mono);font-size:12.5px;color:var(--ink);}
/* A whole ROW that could not be measured gets the dashed treatment too, so the
   state survives being skimmed rather than read cell by cell. */
tr.row-unmeasured td,tr.row-unmeasured th{background:var(--dash-fill);}
tr.row-unmeasured th{box-shadow:inset 3px 0 0 var(--dash);}

/* ---------- the not-measured block ---------- */
/* The first-class UI state. Dashed, unfilled, grey, and it always says WHY —
   lib/store/schema.mjs refuses to store an unmeasured cell without a reason,
   so there is always one to print, and printing it is the whole point. */
.nm{
  border:1px dashed var(--dash);border-radius:10px;background:var(--dash-fill);
  padding:13px 15px;color:var(--tx2);font-size:13px;
}
.nm h4,.nm .lbl{margin-bottom:5px;}
.nm .why{font-family:var(--f-mono);font-size:11.5px;color:var(--tx3);display:block;margin-top:5px;}
.nm-inline{
  font-family:var(--f-mono);font-size:11px;color:var(--tx3);
  border:1px dashed var(--dash);border-radius:5px;padding:2px 7px;display:inline-block;
}

/* ---------- the state legend ---------- */
.legend{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;}
.legend .li{border:1px solid var(--line);border-radius:11px;padding:14px 15px;background:var(--card);}
.legend .li.u{border-style:dashed;border-color:var(--dash);background:var(--dash-fill);}
.legend p{font-size:12.5px;color:var(--tx2);margin-top:9px;}

/* ---------- append-only change log ---------- */
/* The Admodifier client portal ships a change log instead of metric tiles, on
   purpose: a tile that has not been recomputed since March is worse than no
   tile, because it is confidently wrong and nothing on it says so. A log entry
   is stamped with the moment it was true and stays true forever. Entries are
   appended; nothing here edits or removes one. */
.log{border-left:2px solid var(--line);margin-left:6px;padding-left:0;}
.log li{position:relative;padding:0 0 20px 24px;}
.log li::before{
  content:"";position:absolute;left:-5px;top:6px;width:8px;height:8px;border-radius:99px;
  background:var(--tx3);border:2px solid var(--card);
}
.log li.up::before{background:var(--grn);}
.log li.down::before{background:var(--red);}
/* An unmeasured entry's dot is hollow and dashed — it marks a hole in the
   record, not a movement in it. */
.log li.unm::before{background:var(--dash-fill);border:1.5px dashed var(--dash);width:9px;height:9px;left:-5.5px;}
.log .when{font-family:var(--f-mono);font-size:10.5px;color:var(--tx3);letter-spacing:.06em;}
.log .what{font-size:14px;color:var(--ink);margin-top:3px;font-weight:550;}
.log .detail{font-size:13px;color:var(--tx2);margin-top:4px;}
.log li:last-child{padding-bottom:0;}

/* ---------- trend chart ---------- */
.trend{border:1px solid var(--line);border-radius:13px;background:var(--card);padding:18px 18px 10px;}
.trend svg{display:block;width:100%;height:auto;}
.trend-legend{display:flex;gap:18px;flex-wrap:wrap;margin-top:6px;font-size:12.5px;color:var(--tx2);}
.trend-legend i{display:inline-block;width:14px;height:0;border-top:2px solid var(--grn);vertical-align:middle;margin-right:7px;}
.trend-legend i.men{border-top-color:var(--tx3);border-top-style:solid;}
.trend-legend i.gap{border-top:2px dashed var(--dash);}
.trend-note{margin-top:10px;font-size:12.5px;color:var(--tx2);border-top:1px solid var(--line2);padding-top:10px;}

/* ---------- share of voice bars ---------- */
.sov-row{padding:16px 0;border-top:1px solid var(--line2);}
.sov-row:first-of-type{border-top:none;}
.sov-prompt{font-size:14px;color:var(--ink);font-weight:550;}
.sov-meta{font-family:var(--f-mono);font-size:10.5px;color:var(--tx3);margin-top:3px;letter-spacing:.04em;}
.sov-bars{margin-top:11px;display:grid;gap:7px;}
.sov-bar{display:grid;grid-template-columns:190px minmax(0,1fr) 74px;gap:12px;align-items:center;}
.sov-name{font-size:12.5px;color:var(--tx2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sov-name.you{color:var(--ink);font-weight:600;}
.sov-track{background:var(--line2);border-radius:5px;height:16px;position:relative;overflow:hidden;}
.sov-fill{position:absolute;left:0;top:0;bottom:0;background:var(--tx3);border-radius:5px;}
.sov-fill.you{background:var(--acc);}
.sov-kn{font-family:var(--f-mono);font-size:11px;color:var(--tx3);text-align:right;}
/* A MEASURED ZERO still gets a mark. A bar of width 0 is invisible, and an
   invisible bar in a solid track is one glance away from looking like the
   dashed unmeasured track below it. So k=0 draws a red tick at the origin and
   the k/n line still prints the digit: "0 of 6". Something we measured is
   always drawn. */
.sov-fill.zero{width:4px!important;background:var(--red);border-radius:2px;}
.sov-kn.zero{color:var(--red);}

/* A prompt whose runs did not come back has NO bar and NO track fill — an
   empty DASHED track with nothing in it at all, which cannot be read as
   "0% share" because there is no bar, no tick and no numeral. */
.sov-track.unm{background:transparent;border:1px dashed var(--dash);}
.sov-kn.unm{color:var(--dash);}

/* ---------- the "not switched on" block ---------- */
/* Same register as build/tools/*.html's !API_LIVE branch: say what is off,
   name the flag, and never leave a control that looks like it would work. */
.offblock{
  border:1px dashed var(--dash);border-radius:12px;background:var(--dash-fill);
  padding:18px 20px;
}
.offblock h2,.offblock h3{margin-bottom:6px;font-family:var(--f-disp);font-weight:500;font-size:17px;letter-spacing:-.02em;line-height:1.3;}
.offblock p{font-size:13.5px;color:var(--tx2);margin-top:8px;}
.offblock code{font-family:var(--f-mono);font-size:12px;color:var(--ink);}
.offblock ul{margin-top:10px;display:grid;gap:7px;}
.offblock ul li{font-size:13px;color:var(--tx2);padding-left:15px;position:relative;}
.offblock ul li::before{content:"";position:absolute;left:0;top:8px;width:5px;height:5px;border-radius:99px;background:var(--dash);}

/* ---------- forms ---------- */
.field{
  width:100%;font-family:var(--f-sans);font-size:15px;color:var(--ink);
  background:#fff;border:1px solid var(--line);border-radius:10px;padding:13px 14px;
}
.field::placeholder{color:var(--tx3);}
.field[aria-invalid="true"]{border-color:var(--red);}
.field:disabled{background:var(--pap);color:var(--tx3);cursor:not-allowed;}
.label{display:block;font-size:13.5px;color:var(--tx2);margin-bottom:7px;}
/* Rendered but empty at parse, never display:none — a role="alert" region that
   is hidden at load is not registered by every screen reader and the first
   message it is given is silently dropped. Copied from build/pricing.html. */
.err{margin-top:10px;font-size:13.5px;color:var(--red);}
.err:empty{margin-top:0;}
.ok{margin-top:10px;font-size:13.5px;color:var(--grn);}
.ok:empty{margin-top:0;}

/* ---------- definition rows ---------- */
.drow{display:grid;grid-template-columns:190px minmax(0,1fr);gap:14px;padding:10px 0;border-top:1px solid var(--line2);font-size:13.5px;}
/* In the 340px sidebar the two-column drow squeezes the value into ~120px and
   every line wraps mid-word. There it stacks. */
.side .drow{grid-template-columns:1fr;gap:2px;}
.side .drow .dk{padding-top:0;}
.drow:first-of-type{border-top:none;}
.drow .dk{font-family:var(--f-mono);font-size:11.5px;color:var(--tx3);letter-spacing:.02em;padding-top:2px;}
.drow .dv{color:var(--ink);}
.drow .dv .sub{display:block;color:var(--tx2);font-size:12.5px;margin-top:3px;}

/* ---------- footer ---------- */
.appfoot{border-top:1px solid var(--line);margin-top:34px;}
.appfoot .wrap{display:flex;gap:18px;flex-wrap:wrap;padding-block:22px 40px;align-items:center;}
.appfoot p,.appfoot a{font-size:12.5px;color:var(--tx3);}
.appfoot a{text-decoration:none;}
.appfoot a:hover{color:var(--ink);}
.appfoot .right{margin-left:auto;display:flex;gap:16px;}

/* ---------- motion ---------- */
.appnav a,.btn{transition:color .15s ease,background-color .15s ease;}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ---------- responsive ---------- */
@media (max-width:1040px){
  .g-side{grid-template-columns:1fr;}
  .g4{grid-template-columns:1fr 1fr;}
  .legend{grid-template-columns:1fr 1fr;}
}
@media (max-width:860px){
  .g3{grid-template-columns:1fr;}
  .g2{grid-template-columns:1fr;}
}
@media (max-width:767px){
  .wrap{padding:0 18px;}
  h1{font-size:29px;}
  h2{font-size:20px;}
  .sec{padding:26px 0;}
  .g4{grid-template-columns:1fr;}
  .legend{grid-template-columns:1fr;}
  .appnav{
    display:none;
  }
  .appnav.open{
    display:flex;flex-direction:column;align-items:flex-start;gap:12px;
    position:absolute;left:18px;right:18px;top:56px;background:var(--card);
    border:1px solid var(--line);border-radius:12px;padding:14px 16px;z-index:20;
  }
  .nav-toggle{
    display:inline-flex;flex-direction:column;gap:4px;background:none;border:0;padding:6px;cursor:pointer;
    order:-1;
  }
  .nav-toggle i{width:18px;height:1.5px;background:var(--ink);display:block;border-radius:2px;}
  .appbar-inner{gap:12px;}
  .orgpill{display:none;}
  .drow{grid-template-columns:1fr;gap:2px;}
  .sov-bar{grid-template-columns:1fr;gap:4px;}
  .sov-kn{text-align:left;}
  .sov-name{white-space:normal;}
  /* The matrix cannot fit 375px as a grid. It stays a real table and scrolls,
     rather than being reflowed into cards — a prompt x engine cell means
     nothing without its column header, and a reflow drops the header. */
  table.t{min-width:660px;}
}

/* ---------- small utilities ----------
   These exist so that NO HTML file in this directory writes var(--token) in an
   inline style attribute. tools/qa-sweep.mjs reads each .html in isolation and
   cannot see this stylesheet, so an inline var() there is reported as an
   undefined token on every page — and it is right to, for the marketing pages
   it was written for, where the <style> block IS the file. Keeping the tokens
   on this side of the line keeps the sweep meaningful instead of noisy. */
.p-note{font-size:13px;color:var(--tx2);margin-top:9px;}
.p-body{font-size:13.5px;color:var(--tx2);margin-top:8px;}
.kfig.r{color:var(--red);}
.fine.red{color:var(--red);}
.sov-row.unm-row{background:var(--dash-fill);border-radius:10px;padding:16px 14px;}
.linkbtn{
  margin-left:auto;background:none;border:0;padding:0;cursor:pointer;
  text-decoration:underline;color:var(--tx3);
  font-family:var(--f-mono);font-size:11.5px;letter-spacing:.02em;
}
.linkbtn:hover{color:var(--ink);}

/* ---------- CSP-DRIVEN UTILITIES ----------------------------------------
   services/deploy/app/nginx-app.conf serves this subdomain under
   `default-src 'none'; script-src 'self'; style-src 'self'` — with NO
   'unsafe-inline'. Under CSP Level 2+ that blocks a style="" ATTRIBUTE in
   markup, not merely a <style> block. Every one of the 134 inline styles
   these six pages used to carry would have been dropped by the browser on
   the real host, while a local `python3 -m http.server` — which sends no CSP
   at all — rendered them perfectly. The layout looked correct everywhere
   except production.

   So the spacing and layout below are classes, and the one inline <script>
   moved to signin.js. Nothing here is a new design decision: each rule is
   the exact declaration that used to sit in the attribute it replaces.

   The share-of-voice bar widths could not become classes — they are DATA,
   and real data is not drawn from a fixed set of percentages. They are
   carried as data-w="83.3" and applied by app.js through the CSSOM, which
   CSP permits from an allowed script (style-src governs markup attributes
   and <style>, not element.style set by same-origin JavaScript). A bar whose
   width never arrives is still correct: the k/n numeral beside it is the
   number that matters, and it is in the HTML.
   ------------------------------------------------------------------------ */
.mt-6{margin-top:6px;}
.mt-7{margin-top:7px;}
.mt-8{margin-top:8px;}
.mt-9{margin-top:9px;}
.mt-10{margin-top:10px;}
.mt-12{margin-top:12px;}
.mt-14{margin-top:14px;}
.mt-16{margin-top:16px;}
.mt-18{margin-top:18px;}
.mt-20{margin-top:20px;}
.mt-22{margin-top:22px;}
.mt-26{margin-top:26px;}
.mb-9{margin-bottom:9px;}
.ml-auto{margin-left:auto;}
.ml-10{margin-left:10px;}
.d-block{display:block;}
.ta-left{text-align:left;}
.fw-400{font-weight:400;}
.fs-12{font-size:12px;}
.maxw-640{max-width:640px;}
/* the card header row: title left, a fine-print stamp pushed right */
.cardhead{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;}
/* a row of secondary buttons under a card */
.btnrow{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px;}
/* the prompt column in the scan matrix */
.col-prompt{width:32%;}
/* a share-of-voice bar with no name column — the sidebar's whole-scan totals */
.sov-solo{grid-template-columns:1fr;gap:4px;}
/* <summary> defaults to the text cursor in some engines; it is a control */
.nm-why > summary{cursor:pointer;}
