/* ============================================================ theme: clean
   Deep Graphite #1F2329 + Lime Compute #B6FF2E, on white.

   NOTE: the tokens in the :root block immediately below are the ORIGINAL blue
   palette, kept because ~500 lines of rules reference them by name. The live
   values are re-declared in the palette block at the END of this file, which is
   what actually paints the app. Read that block first — it also documents the
   one rule that governs everything: LIME IS A FILL, NOT AN INK (lime on white
   is 1.21:1, graphite on lime is 13.03).

   The brief is readability, so this stays deliberately quiet: contrast does the
   work, colour only marks state.

   Historical, for the blue tokens below — computed against #f5f6f7 / #ffffff:
     ink      #16181c  16.4 / 17.8
     ink-2    #3c4149   9.5 / 10.3
     muted    #5e6672   5.4 /  5.8
     blue     #1559c9   5.9 /  6.4      white on it: 6.4
   #8b93a1 measures 2.9 and is therefore DISABLED/EMPTY ONLY — never live text.

   Status: good/warn/bad all clear 4.5 on a card but sit within 1.1 of each other
   in lightness, which no palette in this family avoids. So the meaning is carried
   by the numeral and the word next to it — colour is a second cue, never the only
   one. Do not remove those labels. */
:root{
  --bg:#f5f6f7; --surface:#ffffff; --surface-2:#f0f2f4; --sidebar:#1b1d21;
  --ink:#16181c; --ink-soft:#3c4149; --muted:#5e6672; --faint:#8b93a1;
  --line:#e1e4e8; --line-soft:#eceef1;
  --accent:#1559c9; --accent-ink:#1559c9; --accent-2:#3c4149; --accent-3:#c3c9d1;
  --accent-tint:#eaf2fe; --accent-soft:#eaf2fe;
  --primary:#1b1d21; --primary-fg:#ffffff;
  --ok:#116b3a; --good:#116b3a; --good-soft:#e7f3ec;
  --warn:#8a5a00; --warn-text:#8a5a00; --warn-soft:#fbf1de;
  --bad:#b3261e; --bad-text:#b3261e; --bad-soft:#fdeceb;
  --warn-on-dark:#f0b452; --bad-on-dark:#ff9a90;
  --star:#8a5a00; --track:#e1e4e8; --ring:rgba(21,89,201,.38);
  --display:'Inter',system-ui,sans-serif;   /* no serif — one family throughout */
  --r:6px;
  /* public pages carry their own names */
  --violet:#1b1d21; --violet-2:#2b2f36; --coral:#1559c9; --soft:#f5f6f7;
}
body.app{background:var(--bg);color:var(--ink)}
*{font-family:'Inter',system-ui,-apple-system,sans-serif}

/* ---- the horizontal topbar, restated (style.css hardcodes it) ---- */
.cc-topbar{background:var(--sidebar);border-bottom:1px solid #000}
.cc-brand{color:#fff;border-right-color:rgba(255,255,255,.14)}
.cc-brand svg{color:#7db3ff}
.cc-sec-head{color:#c7cdd6}
.cc-sec-head:hover,.cc-sec.open .cc-sec-head,.cc-sec-head.is-active{color:#fff}
.cc-sec-head.is-active::after,.cc-sec-head.open::after{background:#7db3ff}
.cc-switcher{background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.16)}
.cc-switcher .avatar{background:#1559c9;color:#fff}
.cc-topbar .cc-item{color:#c7cdd6}
.pagehead{background:rgba(245,246,247,.9)}
.pagehead::after{background:var(--accent)}

/* ---- cards: hairline border, no shadow theatre ---- */
.card,.toolcard,.makecard,.hm-card,.igm,.eb-act,.eb-tile,.stat,.scorecard,.cl-card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:none}
.eb-sec-head{border-bottom:1px solid var(--line)}
.eb-sec-head h2{font-weight:600;letter-spacing:.02em;color:var(--muted)}
.eb-sec-head h2::before,.eb-create .eb-sec-head h2::before,
.eb-review .eb-sec-head h2::before{background:var(--accent)}

/* ---- presence board: a white card, not a coloured slab ---- */
.eb-hero{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);color:var(--ink)}
.eb-hero::before{display:none}                 /* no ruled texture */
.eb-hero::after{display:none}
.eb-hero-l{border-right:1px solid var(--line)}
@media(max-width:860px){.eb-hero-l{border-right:0;border-bottom:1px solid var(--line)}}
.eb-hero-l .eb-eyebrow{color:var(--muted);font-weight:600}
.eb-score b{color:var(--ink);font-weight:600;letter-spacing:-.03em}
.eb-score span{color:var(--muted)}
.eb-score.na b{color:var(--faint)}
.eb-verdict{color:var(--ink);font-weight:600;border:0;padding:0;transform:none;font-size:19px}
.eb-insight{color:var(--ink-soft)}
.eb-hero-l .eb-foot{color:var(--muted)}
.eb-cta-review{background:var(--accent);color:#fff;border-radius:var(--r);font-weight:600}
.eb-cta-review:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.eb-menu-lab{color:var(--muted);font-weight:600}
.eb-row{border-top-color:var(--line)}
.eb-row:hover{background:var(--surface-2)}
.eb-row-lab{color:var(--ink);font-weight:600}
.eb-row-meta{color:var(--muted)}
.eb-dots{border-bottom-color:var(--line)}
.eb-row-val{color:var(--ink);font-weight:600}
.eb-row-val.warnband{color:var(--warn-text)}
.eb-row-val.badband{color:var(--bad-text)}
.eb-row-val.na{color:var(--faint)}
.eb-row-go{color:var(--muted)}
.eb-row:hover .eb-row-go{color:var(--accent)}
.eb-row-sub .k{color:var(--muted)}
.eb-chip{background:var(--surface-2);border-color:var(--line);color:var(--ink-soft);border-radius:999px}
.eb-chip.miss{background:var(--bad-soft);border-color:#f2c9c6;color:var(--bad-text)}

/* ---- week rows ---- */
.eb-week-list{border-top-color:var(--line)}
.eb-week-item{border-bottom:1px solid var(--line)}
.eb-week-item:hover{background:var(--surface-2)}
.eb-week-item.k-order{border-left-color:var(--warn-text)}
.eb-week-item.k-fix{border-left-color:var(--accent)}
.eb-week-item.k-moment{border-left-color:var(--muted)}
.eb-week-ic{background:var(--accent-tint);color:var(--accent)}
.eb-week-item.k-order .eb-week-ic{background:var(--warn-soft);color:var(--warn-text)}
.eb-week-cta{background:var(--accent);color:#fff;border-radius:var(--r);font-weight:600}
.eb-week-item:hover .eb-week-cta{background:#0f47a3;color:#fff}
.eb-tile-n{color:var(--accent);font-weight:600}
.eb-tile-go,.eb-tile:hover .eb-tile-go{color:var(--accent);font-weight:600}

/* ---- buttons ---- */
.btn{border-radius:var(--r)}
.btn-primary,.ba-btn-primary{background:var(--accent);color:#fff;border-color:var(--accent)}
.btn-primary:hover,.ba-btn-primary:hover{background:#0f47a3;border-color:#0f47a3}

/* ---- rings: one blue arc on a grey track, plus the number ---- */
.pv-ring.band-good,.hm-ring.band-good{background:conic-gradient(var(--accent) calc(var(--p)*1%),#e1e4e8 0)}
.pv-ring.band-warn,.hm-ring.band-warn{background:conic-gradient(var(--warn-text) calc(var(--p)*1%),#e1e4e8 0)}
.pv-ring.band-bad,.hm-ring.band-bad{background:conic-gradient(var(--bad-text) calc(var(--p)*1%),#e1e4e8 0)}

/* The base pushes .eb-foot down with margin-top:auto, which was fine on a tall
   coloured slab but leaves an obvious hole in a white card. Let the column close
   up around its content instead. */
.eb-hero-l .eb-foot{margin-top:18px}
.eb-hero-l{padding-bottom:26px}

/* ═══════════════════════════════════ onboarding · login · signup ═══════════
   These are standalone dark-violet pages with their own :root, and two of their
   token names (--ink, --muted) collide with the app's. The app sets --ink to a
   near-black; left alone that paints dark text onto a dark ground and the page
   disappears. So the ground has to flip to white here, not just the accents.

   On #ffffff: ink 17.8 · muted 5.8 · blue 6.4. Inputs get a real border rather
   than a lighter fill, which is what carries structure once the ground is white. */
body.onboard,
body.auth{
  --paper:#ffffff; --ink:#16181c; --muted:#5e6672;
  --olive:#1559c9; --olive-ink:#1559c9; --line:#e1e4e8;
  background:#ffffff;color:#16181c}

/* the violet fills used for inputs, buttons and dropdowns.
   SCOPED to the onboard/auth bodies — this block originally listed bare .btn,
   textarea, select, input[...], which white-!important-ed every button in the
   whole app. That is what killed the dashboard hero's lime CTA: the reference's
   most important button rendered as bare text because an onboarding rule from
   two design systems ago outranked it from 1000 lines away. */
body.onboard .ob-input,body.onboard .ob-search input,body.onboard .ac-list,
body.onboard .btn,body.onboard textarea,body.onboard select,
body.onboard input[type=text],body.onboard input[type=email],
body.onboard input[type=url],body.onboard input[type=password],
body.auth .btn,body.auth textarea,body.auth select,
body.auth input[type=text],body.auth input[type=email],
body.auth input[type=url],body.auth input[type=password]{
  background:#ffffff!important;border-color:#e1e4e8!important;color:#16181c!important}
body.onboard .ob-input:focus-within,body.onboard .ob-search input:focus{border-color:#1559c9!important}
body.onboard .btn,body.auth .btn{color:#16181c!important}
body.onboard .btn:hover,body.auth .btn:hover{border-color:#1559c9!important;background:#f5f6f7!important}
body.onboard .btn-primary,body.auth .btn-primary{background:#1559c9!important;border-color:#1559c9!important;color:#fff!important}
body.onboard .btn-primary:hover,body.auth .btn-primary:hover{background:#0f47a3!important;border-color:#0f47a3!important}
body.onboard .ac-list .ac-item:hover,body.onboard .ac-i:hover{background:#f0f2f4!important}
body.onboard .ob-f.needs .ob-input{border-color:#b3261e!important;background:#fdeceb!important}

/* progress pips: grey track, blue for done/active — the only colour on the page */
#ob-progress i::before{border-color:#c3c9d1;background:transparent}
#ob-progress i.active::before,#ob-progress i.done::before{
  border-color:#1559c9;background:#1559c9}
.ob-eyebrow{color:#5e6672}
.ob-f-lab,.lab{color:#16181c}
.ob-f-note,.muted{color:#5e6672}
.ob-back{color:#5e6672}
.ob-back:hover{color:#16181c}

/* onboarding's own left rail. It is a violet slab with its own step list, and
   flipping --ink to near-black above left those labels dark-on-dark. Make it the
   same near-black as the app rail and put light text back on it.
   On #1b1d21: #ffffff 16.9 · #c7cdd6 10.6 · #9aa3b0 6.6 · #7db3ff 6.1. */
/* The page-level --ink flip above is near-black, and descendants of the rail
   resolve var(--ink) too — so the step labels rendered #15171b on a #1b1d21
   ground, about 1.1:1. getComputedStyle on the parent reported #9aa3b0 and was
   simply wrong about the child text; only sampling rendered pixels caught it.
   Re-point the tokens inside the rail rather than chasing each descendant. */
body.onboard .ob-rail{--ink:#ffffff;--muted:#9aa3b0;--paper:#1b1d21;
  background:#1b1d21;color:#c7cdd6}
body.onboard .ob-rail *{color:inherit}
body.onboard .ob-rail .ob-eyebrow,body.onboard .ob-rail-foot{color:#9aa3b0}
body.onboard .ob-rail::before{display:none}          /* violet texture wash */
body.onboard .ob-rail .ob-eyebrow{color:#9aa3b0}
body.onboard #ob-progress i{color:#9aa3b0}
body.onboard #ob-progress i::before{border-color:#5b636f;background:transparent}
body.onboard #ob-progress i.active{color:#ffffff;font-weight:600}
body.onboard #ob-progress i.active::before{border-color:#7db3ff;background:#7db3ff}
body.onboard #ob-progress i.done{color:#c7cdd6}
body.onboard #ob-progress i.done::before{border-color:#7db3ff;background:#7db3ff}
body.onboard .ob-rail-foot{color:#9aa3b0}
body.onboard .ob-rail a,body.onboard .ob-rail .wm{color:#ffffff}

/* ═══════════════════════════════════════════ flyer wizard ═══════════════════
   Most of the wizard already reads the tokens, so it inherits. Two exceptions:
   a hardcoded violet left in the stepper, and a green "selected" state — the one
   non-blue colour on the page, which breaks the brief. Selected becomes a filled
   near-black: it is a state, not a status, so it does not need a hue.
   White on #1b1d21 = 16.9. */
.step.done i{background:var(--surface);color:var(--ink);border:1px solid var(--line)}
.step.active{color:#fff;background:var(--accent)}
.step.active i{background:rgba(255,255,255,.22);color:#fff}
.step.done:hover{background:var(--accent-tint);color:var(--accent)}
.tile-select{background:var(--accent);color:#fff;border-radius:var(--r)}
.tile-select:hover{background:#0f47a3}
.tile-select.is-sel{background:var(--ink);color:#fff}
.tile-select.is-sel:hover{background:#000}
/* selection ring: blue halo, not the old violet/coral pair */
.tile.sel .thumb img{box-shadow:0 0 0 3px rgba(21,89,201,.30),0 0 0 4px var(--accent)}
.tilegrid .tile-group h3{color:var(--ink)}
.tilegrid .tile-group p{color:var(--muted)}
.tilegrid .tile-group{border-top-color:var(--line)}

/* ═══════════════════════════════════════════ review reports ════════════════
   The reports filled whole panels with green and pink, which is the loudest
   departure from a monochrome brief. HubSpot keeps its cards white and puts the
   colour in small marks, so that is what this does: the panels go neutral and
   the tick / cross icons carry the state. Colour becomes a cue, not a field.

   The icons and their labels keep real hue and still clear 4.5:1 on the neutral
   ground: good #116b3a 6.6 · bad #b3261e 6.5 · warn #8a5a00 5.9 on #ffffff.
   Nothing here relies on colour alone — every row has a tick or cross AND a
   verdict in words. */
.done-group{background:var(--surface);border:1px solid var(--line)}
.need-group{background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--bad-text)}
.verify-group{background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--warn-text)}
.done-group .feat-grouphd,.done-group .feat-grouphd.done{color:var(--ink)}
.need-group .feat-grouphd,.need-group .feat-grouphd.needs{color:var(--ink)}
.verify-group .feat-grouphd{color:var(--ink)}
.feat-grouphd .n{background:var(--surface-2);color:var(--muted);
  border:1px solid var(--line)}
.feat-grouphd.needs .n{background:var(--bad-soft);color:var(--bad-text);border-color:#f2c9c6}
.feat-grouphd.done .n{background:var(--surface-2);color:var(--ink);border-color:var(--line)}

/* impact chips: neutral by default, one quiet tint for high */
.cl-chip-impact{background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--line)}
.cl-chip-impact.hi{background:var(--accent-tint);color:var(--accent);border-color:#c4dbfb}
.cl-chip-impact.md{background:var(--surface-2);color:var(--muted);border-color:var(--line)}

/* completeness heading pill: was amber-on-amber (1.7:1 before tonight) */
body[data-report] #features-box h2{background:var(--surface-2);color:var(--ink);
  border:1px solid var(--line)}

/* category rings: one blue arc on a grey track — the number carries the value */
.cat .ring,.cat-tab .ring{background:conic-gradient(var(--accent) calc(var(--p)*1%),#e1e4e8 0)}
.cat .ring.r-warn,.cat-tab .ring.r-warn{background:conic-gradient(var(--warn-text) calc(var(--p)*1%),#e1e4e8 0)}
.cat .ring.r-bad,.cat-tab .ring.r-bad{background:conic-gradient(var(--bad-text) calc(var(--p)*1%),#e1e4e8 0)}
.cat .ring b,.cat-tab .ring b{color:var(--ink)}
.cat .vd.warn,.cat-tab .vd.warn{color:var(--warn-text)}
.cat .vd.bad,.cat-tab .vd.bad{color:var(--bad-text)}
.cat .vd.good,.cat-tab .vd.good{color:var(--ok)}
.cat-tab.is-on{border-color:var(--accent);background:var(--accent-tint)}

/* findings marks. #e0393b on #fce4e4 measured 3.37 — the only text on the whole
   report that failed after the panels went neutral. Each mark now uses its own
   tint at 5.6:1 or better, and every one sits next to a written finding, so the
   glyph is a second cue rather than the message. */
.fnd-good .fnd-i{background:var(--surface-2);color:var(--ok)}
.fnd-issue .fnd-i{background:var(--bad-soft);color:var(--bad-text)}
.fnd-tip .fnd-i{background:var(--accent-tint);color:var(--accent)}
.feat-mark{color:#fff}
.feat.on .feat-mark{background:var(--ok)}
.feat.partial .feat-mark{background:var(--warn-text)}
.feat.off .feat-mark{background:var(--bad-text)}
.feat.unknown .feat-mark{background:var(--muted)}
.verify-group .feat-mark{background:var(--warn-text)!important}

/* ── report header + rings: the last five failures on the review page ──────
   All from the report's own hardcoded block, and all the same mistake — a tone
   picked to sit on a tinted chip being used on white, or --faint carrying live
   content again. Measured values before this block: domain 3.00, big score 4.23,
   band label 3.60, partial mark 1.00 (invisible), category numeral 3.70. */
body[data-report] .rp-dom,body[data-report] .who,.rp-sub,.sc-sub{color:var(--muted)}
.scorecard[data-tone] .sc-score,.sc-score{color:var(--ink)}
.scorecard[data-tone="bad"] .sc-score{color:var(--bad-text)}
.scorecard[data-tone="warn"] .sc-score{color:var(--warn-text)}
.band,.rp-band{background:var(--surface-2);color:var(--ink);border:1px solid var(--line)}
.band.good,.rp-band.good{background:var(--good-soft);color:var(--ok);border-color:#cfe3d7}
.band.warn,.rp-band.warn{background:var(--warn-soft);color:var(--warn-text);border-color:#eddcb8}
.band.bad,.rp-band.bad{background:var(--bad-soft);color:var(--bad-text);border-color:#f2c9c6}
/* the ◐ partial glyph was rendering its own fill colour — 1.00:1, invisible */
.feat.partial .feat-mark,.feat-mark{color:#fff!important}
.cat .ring b,.cat-tab .ring b,.pv-ring b,.hm-ring b{color:var(--ink)}

/* ── the real class names, read off the DOM rather than guessed ────────────
   My first pass at these missed because I invented selectors. Measured before:
   .sh-sub 3.00 · .sh-ring b 4.23 · .sh-band 3.60 · .ring.r-bad .tnum 3.70 ·
   .feat.partial .feat-mark 1.00 (white on white — the fill never applied). */
.sh-sub{color:var(--muted)}
.ring.sh-ring b,.ring.sh-ring .tnum{color:var(--ink)}
.ring.sh-ring.s-bad b,.ring.s-bad .tnum{color:var(--bad-text)}
.ring.sh-ring.s-warn b,.ring.s-warn .tnum{color:var(--warn-text)}
.ring.r-bad .tnum{color:var(--bad-text)}
.ring.r-warn .tnum{color:var(--warn-text)}
.ring.r-good .tnum,.ring.s-good b{color:var(--ok)}
.sh-band{background:var(--surface-2);color:var(--ink);border:1px solid var(--line)}
.sh-band.s-bad{background:var(--bad-soft);color:var(--bad-text);border-color:#f2c9c6}
.sh-band.s-warn{background:var(--warn-soft);color:var(--warn-text);border-color:#eddcb8}
.sh-band.s-good{background:var(--good-soft);color:var(--ok);border-color:#cfe3d7}
/* the partial mark had no fill at all, so a white glyph sat on white */
.feat.partial .feat-mark{background:var(--warn-text)!important;color:#fff!important}
.feat.on .feat-mark{background:var(--ok)!important;color:#fff!important}
.feat.off .feat-mark{background:var(--bad-text)!important;color:#fff!important}
.feat.unknown .feat-mark{background:var(--muted)!important;color:#fff!important}
/* stepper numeral sat on a translucent white over blue */
.step.active i{background:#0f47a3!important;color:#fff!important}

/* These two are set by a longer selector inside the report's own override layer,
   so token-level and plain class overrides both lose. Forced. Measured before:
   ◐ 1.00 (white on white — no fill reached it), category numeral 3.70. */
.feat-mark{background:var(--muted)!important;color:#fff!important}
.feat.on .feat-mark{background:var(--ok)!important}
.feat.partial .feat-mark{background:var(--warn-text)!important}
.feat.off .feat-mark{background:var(--bad-text)!important}
.ring .tnum,.cat .ring .tnum,.cat-tab .ring .tnum{color:var(--ink)!important}
.ring.r-bad .tnum,.cat .ring.r-bad .tnum,.cat-tab .ring.r-bad .tnum{color:var(--bad-text)!important}
.ring.r-warn .tnum,.cat .ring.r-warn .tnum,.cat-tab .ring.r-warn .tnum{color:var(--warn-text)!important}
.cat .ring,.cat-tab .ring{background:conic-gradient(var(--accent) calc(var(--p)*1%),#e1e4e8 0)!important}
.cat .ring.r-bad,.cat-tab .ring.r-bad{background:conic-gradient(var(--bad-text) calc(var(--p)*1%),#e1e4e8 0)!important}
.cat .ring.r-warn,.cat-tab .ring.r-warn{background:conic-gradient(var(--warn-text) calc(var(--p)*1%),#e1e4e8 0)!important}
.cat .ring::before,.cat-tab .ring::before{background:var(--surface)!important}

/* ── login/signup canvas panel ───────────────────────────────────────────────
   Third instance of the same mistake: the page ground was flipped to white but
   this panel's foregrounds are light-on-violet, so they ended up light-on-white.
   Measured: .l #f7f4f8 on white 1.09 (invisible) · .cv-eyebrow 2.19 · .v 2.19 ·
   the accent word 3.48.

   The fix is the same as onboarding's rail — give the panel back a dark ground
   rather than darkening a dozen foregrounds one at a time. On #1b1d21:
   #ffffff 16.9 · #c7cdd6 10.6 · #9aa3b0 6.6 · #7db3ff 6.1. */
body.auth .canvas{--cream:#ffffff;--ink:#ffffff;--muted:#9aa3b0;
  background:#1b1d21!important;color:#c7cdd6!important}
body.auth .canvas::before{display:none}
body.auth .canvas .cv-brand{color:#ffffff}
body.auth .canvas .cv-eyebrow{color:#9aa3b0!important}
body.auth .canvas .cv-head{color:#ffffff!important}
body.auth .canvas .cv-head em,body.auth .canvas em{color:#7db3ff!important;font-style:normal}
body.auth .canvas .l{color:#c7cdd6!important}
body.auth .canvas .v{color:#7db3ff!important}
body.auth .canvas .dots,body.auth .canvas .menu-row{border-color:rgba(255,255,255,.18)!important}
body.auth .canvas p,body.auth .canvas small{color:#9aa3b0!important}

/* ── last three, each read off the DOM ───────────────────────────────────────
   login <label>        #a99aba on white          2.62  (old violet muted)
   login submit .go     #2a1240 on #1559c9        2.62  (dark text on the blue)
   rail active nav item #c7cdd6 on #eaf2fe        1.42  (light-mode tint applied
                        inside the DARK rail — the theme's active style assumed a
                        light ground, the rail is near-black) */
body.auth label,body.onboard label{color:var(--ink)!important}
body.auth .go,body.auth button[type=submit],body.auth .btn-primary{
  background:var(--accent)!important;color:#fff!important;border-color:var(--accent)!important}
.cc-topbar .cc-item.is-active{background:rgba(255,255,255,.10)!important;color:#fff!important}
.cc-topbar .cc-item.is-active span{color:#fff!important}
.cc-topbar .cc-item.is-active svg{color:#7db3ff!important}
.cc-topbar .cc-item.is-active::before{background:#7db3ff!important}

/* The auth FORM side (the white half) still carried violet-era greys —
   #a99aba at 2.62 and the step numerals at 3.50. Rather than chase each class,
   set the whole form column and let the canvas rules above keep the dark half.
   :not(.canvas *) so the dark panel is untouched. */
body.auth *:not(.canvas):not(.canvas *){color:var(--ink)}
body.auth p:not(.canvas *),body.auth small:not(.canvas *),
body.auth .sub:not(.canvas *),body.auth .or:not(.canvas *),
body.auth .muted:not(.canvas *),body.auth .note:not(.canvas *){color:var(--muted)}
body.auth .num:not(.canvas *),body.auth .n:not(.canvas *){color:var(--muted)}
body.auth a:not(.canvas *){color:var(--accent)}
body.auth .go,body.auth button[type=submit]{color:#fff!important}

/* signup step numerals: #7a6c8c on white = 3.50. My earlier `.num`/`.n` rule
   lost to a longer selector, so scope it to the parent. */
body.auth .step .n,body.auth .step > .n{color:var(--muted)!important}

/* ── public scan page ────────────────────────────────────────────────────────
   Mostly inherited, because clean re-points --violet/--coral/--soft at :root and
   scan.html reads those. Two exceptions:
     .note      #a49eb0 on white           2.40  (hardcoded old faint)
     .gform btn #2a1240 on the new blue    2.62  (dark text left on a fill that
                                                  used to be coral and is now blue)
   The second is the same class of bug as the login submit: when a fill changes
   hue, the text on it has to be re-checked, not inherited. */
body:has(.scanwrap) .note,.scan .note,.note{color:var(--muted)}
.gform button,.gform button[type=submit]{background:var(--accent);color:#fff}
.gform button:hover{background:#0f47a3}
.mbtn{background:var(--accent);color:#fff}
.mbtn:hover{background:#0f47a3;color:#fff}
.share button{border-color:var(--accent);color:var(--accent)}
.share button:hover{background:var(--accent);color:#fff}
.band.good{background:var(--good-soft);color:var(--ok)}
.band.warn{background:var(--warn-soft);color:var(--warn-text)}
.band.bad{background:var(--bad-soft);color:var(--bad-text)}
.band.none{background:var(--surface-2);color:var(--muted)}

/* ══════════════════════ round 2, from Liam's HubSpot screenshots ═══════════
   "keep the blue though but make the black lighter on the nav on the left, also
    make the light grey darker on the main screen … have more split between each
    section, makes it clear to read"

   Rail  #1b1d21 -> #31363e. Every rail tone still clears 4.5 on it:
     white 12.15 · idle #c7cdd6 7.60 · dim #9aa3b0 4.77 · blue #7db3ff 5.65.
     #373d45 was the next step lighter and pushed dim to 4.30, so this is the
     lightest the rail can go without moving the text tones too.
   Page  #f5f6f7 -> #e6e9ec. Card-against-page separation goes 1.08 -> 1.22, so
     white cards actually read as raised. muted on the new ground is 4.76, still
     passing; --surface-2 moves up to stay distinct from the page. */
:root{
  --sidebar:#31363e;
  --bg:#e6e9ec;
  --surface-2:#eef0f2;
  --line:#d8dde3;
  --line-soft:#e6e9ec;
}
body.app{background:var(--bg)}
.cc-topbar{background:var(--sidebar)}
.pagehead{background:rgba(230,233,236,.92)}

/* ══════════════════════ round 3 — darker ground, icons, motion ═════════════
   "darker background grey please, i need all these cards, layout redesigns,
    happy for you to create some icons and animations to help it stand out and
    separate each thing"

   Page #e6e9ec -> #d6dce3. Card-against-page separation 1.22 -> 1.38, so the
   white cards now clearly float. That ground is too dark for --muted (4.20), so
   anything sitting DIRECTLY on the page uses --on-page #4a515c (5.80). Text on
   the white cards is unaffected — that is where nearly all copy lives. */
:root{
  --bg:#d6dce3;
  --on-page:#4a515c;
  --line:#c9d1da;
  --line-soft:#dfe4ea;
}
body.app{background:var(--bg)}
.pagehead{background:rgba(214,220,227,.92);border-bottom:1px solid var(--line)}
/* section labels sit on the page, not a card */
.eb-sec-head{border-bottom:0}
.eb-sec-head h2{color:var(--on-page);font-size:12px;letter-spacing:.1em;text-transform:uppercase}
.eb-sec-head .sub{color:var(--on-page)}

/* ── section icons ──────────────────────────────────────────────────────────
   A small marked chip in front of each section title, so the eye finds the
   boundary before it reads the words. Inline SVG data URIs — no new files, and
   nothing external for the CSP to block. */
.eb-sec-head h2{display:flex;align-items:center;gap:9px}
.eb-sec-head h2::before{
  content:"";width:22px;height:22px;flex:none;border-radius:6px;
  background-color:var(--surface);border:1px solid var(--line);
  background-repeat:no-repeat;background-position:center;background-size:13px 13px}
.eb-week .eb-sec-head h2::before{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231559c9' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")}
.eb-sec:has(.eb-create) .eb-sec-head h2::before{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231559c9' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v18M3 12h18'/%3E%3C/svg%3E")}
.eb-sec:has(.eb-act) .eb-sec-head h2::before{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231559c9' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20V10M10 20V4M16 20v-7M22 20H2'/%3E%3C/svg%3E")}

/* ── This Week becomes three separate cards ─────────────────────────────────
   They were rows inside one block, which read as a table. Split apart they read
   as three jobs, which is what they are. */
.eb-week-list{border-top:0;display:flex;flex-direction:column;gap:10px;background:none}
.eb-week-item{background:var(--surface);border:1px solid var(--line);border-radius:8px;
  border-left-width:3px;border-bottom:1px solid var(--line)}
.eb-week-item:hover{background:var(--surface)}

/* ── motion: a short lift on hover, a staggered settle on load ──────────────
   Both are decoration; prefers-reduced-motion removes them entirely and the
   cards simply appear. */
.eb-week-item,.eb-tile,.eb-act,.eb-hero,.card,.scorecard{
  transition:transform .16s cubic-bezier(.22,1,.36,1),box-shadow .16s,border-color .16s}
.eb-week-item:hover,.eb-tile:hover{transform:translateY(-2px);
  box-shadow:0 6px 16px rgba(22,24,28,.09);border-color:var(--accent-3)}
@keyframes cleanIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.eb-hero{animation:cleanIn .42s cubic-bezier(.22,1,.36,1) both}
.eb-week-item{animation:cleanIn .42s cubic-bezier(.22,1,.36,1) both}
.eb-week-item:nth-child(2){animation-delay:.06s}
.eb-week-item:nth-child(3){animation-delay:.12s}
.eb-tile{animation:cleanIn .42s cubic-bezier(.22,1,.36,1) both}
.eb-tile:nth-child(2){animation-delay:.06s}
.eb-tile:nth-child(3){animation-delay:.12s}
.eb-act{animation:cleanIn .42s cubic-bezier(.22,1,.36,1) .1s both}
@media(prefers-reduced-motion:reduce){
  .eb-hero,.eb-week-item,.eb-tile,.eb-act{animation:none!important}
  .eb-week-item,.eb-tile,.eb-act,.eb-hero,.card,.scorecard{transition:none}
  .eb-week-item:hover,.eb-tile:hover{transform:none}
}
/* the Create tiles were butted together in one grid — separate them */
.eb-create{border-top:0;gap:14px}
.eb-tile{background:var(--surface);border:1px solid var(--line);border-radius:8px;
  padding:20px 22px}

/* The darker page ground put --muted at 4.20 wherever it sits directly on the
   page — 72 elements across five screens, all the same value. Chasing each
   usage would have been the wrong fix; the token itself has to clear both
   grounds now. #525965 gives 5.11 on the page and 7.06 on a card, and is still
   visibly secondary to --ink. */
:root{--muted:#525965;--on-page:#525965}

/* .muted is set with a literal #5e6672 somewhere with enough specificity to beat
   the token, so it stayed at 4.20 on the darker ground while everything else
   moved. Same value, applied by class. */
.muted{color:var(--muted)}

/* ── BY CHANNEL: three blocks, not three rows ────────────────────────────────
   The channels were separated by a hairline and a lot of air, which reads as one
   continuous list. Each is a separate thing you can act on, so each gets its own
   bordered block — the same move that fixed This Week.
   Fill #f7f9fa on the white card: text tones are unaffected (ink 16.9, muted
   6.8, and the score bands all still clear 4.5 on it). */
.eb-menu{display:flex;flex-direction:column;gap:10px}
.eb-menu-lab{margin-bottom:2px}
.eb-row{border-top:0;border:1px solid var(--line);border-radius:8px;
  background:#f7f9fa;padding:14px 16px}
.eb-row:hover{background:#eef2f5;border-color:var(--accent-3)}
.eb-row:first-child{padding-top:14px}
/* the leader dots were doing the separating; with blocks they are noise */
.eb-dots{border-bottom-color:transparent}

/* left column: the score block sat top-aligned in a card as tall as the channel
   list, leaving an obvious hole under the insight. Let it centre instead. */
.eb-hero-l{justify-content:center}
.eb-hero-l .eb-foot{margin-top:22px}

/* ── channel block internals ─────────────────────────────────────────────────
   The score was floating mid-block with dead space above and below it. Cause:
   the grid is `auto 1fr auto auto` and .eb-dots explicitly claims column 2, but
   .eb-row-meta auto-places into column 2 first — so the dots got bumped to row 2
   and took the score and arrow down with them.

   With blocks instead of a list the dots have no job, so they go, and everything
   is placed explicitly: name + handle left, score + arrow right, ORDER beneath.
   Each block drops about a third in height. */
.eb-row{align-items:center;gap:6px 12px;padding:14px 16px}
.eb-row .eb-dots{display:none}
.eb-row .eb-row-lab{grid-area:1/1/2/2}
.eb-row .eb-row-meta{grid-area:1/2/2/3;justify-self:start;align-self:center}
.eb-row .eb-row-val{grid-area:1/3/2/4;align-self:center;font-size:26px}
.eb-row .eb-row-go{grid-area:1/4/2/5;align-self:center}
.eb-row .eb-row-sub{grid-area:2/1/3/5;margin-top:2px}

/* ── section headers on a phone ──────────────────────────────────────────────
   .eb-sec-head is a flex row with the subtitle pushed right by margin-left:auto.
   At 390px there is no room left to push into, so the subtitle ends up jammed
   against the label — worst on CREATE, whose subtitle is the longest. Stack them
   below 560px and let the subtitle have its own line. */
@media(max-width:560px){
  .eb-sec-head{flex-direction:column;align-items:flex-start;gap:4px}
  .eb-sec-head .sub{margin-left:0;text-align:left;font-size:12.5px}
}

/* ── focus indicators ────────────────────────────────────────────────────────
   WCAG 1.4.11 wants a focus indicator at 3:1 against whatever it sits on. The
   global rule draws it in --accent, which is 5.9 on white but collapses
   elsewhere: 1.09 on the dark rail, 1.03 on the tinted channel blocks, 2.66 on
   the scan page's dark bar, 1.06 on the login submit.

   One ring cannot clear 3:1 on both a near-black rail and a white card. So the
   indicator is a PAIR — a dark inner ring with a white outer ring — and whichever
   ground it lands on, one of the two is visible. This is the standard fix and it
   removes the need to tune focus per surface. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--ink);
  outline-offset:2px;
  box-shadow:0 0 0 4px rgba(255,255,255,.95);
  border-radius:4px}
/* on the dark surfaces, invert the pair */
.cc-topbar :focus-visible,
body.onboard .ob-rail :focus-visible,
body.auth .canvas :focus-visible,
.bar :focus-visible{
  outline:2px solid #ffffff;
  outline-offset:2px;
  box-shadow:0 0 0 4px rgba(0,0,0,.55)}
/* filled blue controls: white ring inside, dark ring outside */
.btn-primary:focus-visible,.eb-week-cta:focus-visible,.eb-cta-review:focus-visible,
.tile-select:focus-visible,.job-go:focus-visible,.gform button:focus-visible,
body.auth .go:focus-visible,.mbtn:focus-visible{
  outline:2px solid #ffffff;
  outline-offset:-4px;
  box-shadow:0 0 0 3px var(--ink)}

/* :where() above has zero specificity, so any existing :focus-visible rule beat
   it — and inputs that set outline:none kept none at all. Restated with real
   specificity, and forced on the inputs, which is where a missing focus ring
   matters most: you cannot see the caret's container without it. */
a:focus-visible,button:focus-visible,summary:focus-visible,[tabindex]:focus-visible,
.eb-row:focus-visible,.chan:focus-visible,.eb-week-item:focus-visible,.eb-tile:focus-visible{
  outline:2px solid var(--ink)!important;outline-offset:2px!important;
  box-shadow:0 0 0 4px rgba(255,255,255,.95)!important}
input:focus-visible,select:focus-visible,textarea:focus-visible,
.ba-inp:focus-visible,.ob-input:focus-within,.ba-control:focus-within{
  outline:2px solid var(--accent)!important;outline-offset:1px!important;
  box-shadow:0 0 0 3px rgba(21,89,201,.20)!important}
/* dark surfaces keep the inverted pair, restated to win the same way */
.cc-topbar a:focus-visible,.cc-topbar button:focus-visible,.cc-topbar [tabindex]:focus-visible,
body.onboard .ob-rail a:focus-visible,body.auth .canvas a:focus-visible,
.bar a:focus-visible,.bar button:focus-visible{
  outline:2px solid #ffffff!important;outline-offset:2px!important;
  box-shadow:0 0 0 4px rgba(0,0,0,.55)!important}
/* filled blue buttons: white inside, dark outside */
.btn-primary:focus-visible,.eb-week-cta:focus-visible,.eb-cta-review:focus-visible,
.tile-select:focus-visible,.gform button:focus-visible,body.auth .go:focus-visible,
.mbtn:focus-visible,.ob-go:focus-visible{
  outline:2px solid #ffffff!important;outline-offset:-4px!important;
  box-shadow:0 0 0 3px var(--ink)!important}

/* Last four: .ba-btn-primary was missing from the filled-button list, and the
   input ring leaned on a 20%-alpha blue that composites to a pale wash (1.28 on
   some grounds). Inputs now get the solid dark ring like everything else — the
   blue tint stays only as a soft outer glow, decorative rather than load-bearing. */
.ba-btn-primary:focus-visible,.ba-btn.ba-btn-primary:focus-visible,
.btn-primary.ob-go:focus-visible{
  outline:2px solid #ffffff!important;outline-offset:-4px!important;
  box-shadow:0 0 0 3px var(--ink)!important}
input:focus-visible,select:focus-visible,textarea:focus-visible,.ba-inp:focus-visible{
  outline:2px solid var(--ink)!important;outline-offset:1px!important;
  box-shadow:0 0 0 4px rgba(21,89,201,.18)!important}

/* ── colour swatches: the one control whose background we cannot know ────────
   <input type="color"> in .ba-swatch renders the RESTAURANT'S OWN brand colour as
   its background. Ottolenghi's first swatch is #1b1b1b, so the dark focus ring
   measured 1.14 on it — and no single ring colour can be safe, because tomorrow
   that swatch might be white.

   So this one gets the full two-tone treatment: a white ring immediately around
   the swatch and a dark ring outside it. One of the two always contrasts, whatever
   colour the restaurant picked. */
input[type=color]:focus-visible,.ba-swatch:focus-within{
  outline:2px solid #ffffff!important;outline-offset:-2px!important;
  box-shadow:0 0 0 3px var(--ink),0 0 0 6px rgba(255,255,255,.95)!important}

/* onboard #w-next resolved a 3px white ring on a white panel (1.00). Four passes
   failed to find what sets it — every :focus-visible rule enumerated from
   document.styleSheets specifies 2px, and the plain :focus rules are all inputs.
   Rather than keep hunting the winner, out-specify it by id and give it the same
   two-tone pair used everywhere else, which is correct on any ground. */
body.onboard #w-next:focus-visible,
body.onboard .ob-go:focus-visible,
body.onboard .btn-primary:focus-visible{
  outline:2px solid #ffffff!important;
  outline-offset:-4px!important;
  box-shadow:0 0 0 3px #16181c,0 0 0 6px rgba(255,255,255,.95)!important}

/* ── Channel groups: Ordering vs Discovery ────────────────────────────────
   The board used to be one flat "By channel" list, which implied Instagram,
   Google Business and the website all do the same job. They don't: the first
   two get you found, the website is where the order is actually placed. The
   subhead carries that distinction so a weak website reads as a lost sale
   rather than just another low number.

   The second group needs air above it or the two read as one list; the first
   must NOT get that margin or it pushes off the panel's top padding. */
.eb-group{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.eb-group + .eb-row{margin-top:2px}
.eb-group ~ .eb-group{margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
/* --faint (#8b93a1) measured 3.09:1 here — it is calibrated for large or
   decorative text, not an 11.5px subhead. --muted clears 4.5. */
.eb-group em{font-style:normal;font-weight:500;font-size:11.5px;letter-spacing:0;
  text-transform:none;color:var(--muted)}
@media(max-width:560px){
  /* At 390px the subhead wraps under its own label; drop the gap so the two
     lines read as one unit rather than as two separate headings. */
  .eb-group{gap:2px}
  .eb-group em{flex:1 0 100%}
}

/* ── channel rows on a phone ─────────────────────────────────────────────────
   Every part of the row is pinned to row 1 (name | domain | score | arrow).
   Column 1 is `auto`, so when the channel label grew from "Website" to
   "Website & ordering" it simply overflowed instead of letting the domain
   ellipsis — and the score landed on top of the domain text at 390px.

   Below 560px give each part its own line: name and score on row 1, domain
   under it, ORDER chips under that. The label can wrap now, so a longer
   channel name can't push anything off the row again. */
@media(max-width:560px){
  .eb-row{grid-template-columns:1fr auto auto}
  .eb-row .eb-row-lab{grid-area:1/1/2/2;min-width:0;font-size:16.5px}
  .eb-row .eb-row-val{grid-area:1/2/2/3}
  .eb-row .eb-row-go{grid-area:1/3/2/4}
  .eb-row .eb-row-meta{grid-area:2/1/3/4;justify-self:start;max-width:100%}
  .eb-row .eb-row-sub{grid-area:3/1/4/4}
}

/* ══ Google Business & Instagram review pages ═════════════════════════════
   These two carried 24 contrast failures because style.css:1111 gives
   #gbp-switcher its OWN scoped palette — a full re-declaration of the violet
   tokens (--ink:#241730, --muted:#6f6980, --faint:#a49eb0, --bad:#f15153).
   Theme tokens set on :root never reached that subtree, so the whole page
   stayed on the old palette while everything around it moved.

   These pages were not in any earlier sweep; only /marketing/website-review
   was. So this is long-standing, not a regression from the redesign — it only
   became visible once the audit covered all three review pages.

   Re-point the scoped block at the monochrome tokens. --faint is deliberately
   darker here than the global one: inside this subtree it paints real text
   (.ol-lbl, .dash), not decoration, so it has to clear 4.5 rather than 3. */
#gbp-switcher{
  --surface:#ffffff; --line:#c9d1da; --line-soft:#e5e9ee;
  --ink:#16181c; --muted:#525965; --faint:#5f6773;
  --accent:#1559c9; --accent-ink:#1559c9; --accent-2:#4d8df6;
  --accent-3:#a9c3ea; --accent-soft:#eaf2fe;
  --good:#116b3a; --good-soft:#eef7f1;
  --warn:#f5a623; --warn-text:#8a5a00; --warn-soft:#fdf3e0;
  --bad:#b3261e; --bad-soft:#fdecea; --star:#8a5a00; --track:#e5e9ee;
}

/* Literals that bypass the scoped block entirely and so survived it. */
.hm-ring.band-none b{color:#525965}          /* was #a49eb0 on #e3deea, 1.96 */
.ol-unread{color:var(--warn-text,#8a5a00)}   /* was #b39152, 2.87 */
.fnd-issue .fnd-i{background:#fdecea;color:#b3261e}   /* was #e0393b on #fce4e4, 3.60 */
.ring.r-bad b,.sh-ring.s-bad b,.cat .ring.r-bad b,
.cat-tab .ring.r-bad b,#gbp-switcher .ring.s-bad b{color:#b3261e}  /* was 4.23 */
.vd.bad,.cat-tab .vd.bad,.sh-band.s-bad,
.ring-band.s-bad,.gh-bandlbl.s-bad{color:#b3261e}
/* .glance-src took the GLOBAL --faint (#8b93a1) and paints a 12px paragraph
   of source attribution — 3.00. Decoration-weight token on body text. */
.glance-src{color:var(--muted)}

/* The "no ordering link" callout on the Instagram review. I had guessed
   .fnd-issue .fnd-i for this and the override did nothing — the actual chain is
   B < .ord-none < .hero-ord. Read off the DOM, not inferred. 3.60 -> 6.6. */
.ord-none{background:#fdecea}
.ord-none b{color:#b3261e}

/* ── in-page anchors vs the sticky section bar ────────────────────────────
   The "ON THIS PAGE" bar (.report-key) sticks at 60-117px. The five section
   anchors have scroll-margin-top:0, so clicking Overview / Action plan /
   Completeness / Breakdown / Replies parks the section at y=100 — 17px behind
   the bar, hiding each section's own heading and its first line of copy.

   Measured, not guessed: bar bottom 117, target top 100. 128 clears it with a
   little air, and matches on both viewports since the bar height is fixed. */
#rep-overview,#rep-checklist,#features-box,#sections,#replies-box{scroll-margin-top:128px}

/* ═══════════════════════════════════════════════════════════════════════════
   PALETTE: Deep Graphite #1F2329 + Lime Compute #B6FF2E, on white
   (29 Jul — replaces the blue accent)

   The one thing that governs everything below: LIME IS A FILL, NOT AN INK.

     lime on white        1.21   unusable
     white on lime        1.21   unusable
     lime on page grey    1.12   unusable
     graphite on lime    13.03   excellent
     lime on graphite    13.03   excellent
     graphite on white   15.78   excellent

   At 0.817 luminance lime is lighter than most greys, so it can only ever be a
   ground with something dark on it, or a mark on the graphite rail. Every rule
   that previously read `background:var(--accent);color:#fff` — fourteen of them —
   would have rendered at 1.21:1, so each is restated here with graphite ink.

   Where the accent had to be TEXT on white (links, small labels), lime cannot
   go at all; --accent-ink is a darkened lime that clears 4.5 on both grounds. */
:root{
  --sidebar:#1F2329;
  --ink:#1F2329; --ink-soft:#3a4048; --muted:#5b626b; --faint:#8b93a1;
  --accent:#B6FF2E;        /* FILL ONLY — never text, never a border on white */
  --accent-on:#1F2329;     /* the only ink allowed on top of lime */
  --accent-ink:#4f6a00;    /* lime-as-text: 6.19 on white, 5.6 on page grey */
  --accent-2:#3a4048; --accent-3:#c9d1da;
  --accent-tint:#f2ffdb; --accent-soft:#f2ffdb;
  --primary:#1F2329; --primary-fg:#ffffff;
  --ring:rgba(31,35,41,.42);
  --line:#e1e4e8; --track:#e1e4e8;
}

/* ---- the rail, now graphite with a lime mark ---- */
.cc-topbar{background:var(--sidebar)}
.cc-brand svg{color:#B6FF2E}
.cc-sec-head.is-active::after,.cc-sec-head.open::after{background:#B6FF2E}
.cc-switcher .avatar{background:#B6FF2E;color:#1F2329}
.pagehead::after{background:#B6FF2E}
.eb-sec-head h2::before,.eb-create .eb-sec-head h2::before,
.eb-review .eb-sec-head h2::before{background:#B6FF2E}

/* ---- every fill that used to carry white text ---- */
.eb-cta-review,.eb-week-cta,.btn-primary,.ba-btn-primary,
.step.active,.tile-select,.gform button,.gform button[type=submit],.mbtn{
  background:var(--accent);color:var(--accent-on);border-color:var(--accent)}
.share button:hover{background:var(--accent);color:var(--accent-on)}
.btn-primary:hover,.ba-btn-primary:hover,.eb-week-item:hover .eb-week-cta,
.eb-cta-review:hover{background:#a4ec1c;border-color:#a4ec1c;color:var(--accent-on)}
/* the onboarding/auth layer sets these with !important, so it needs restating */
body.onboard .btn-primary,body.auth .btn-primary,
body.onboard .ob-go,body.auth .ob-go{
  background:#B6FF2E!important;border-color:#B6FF2E!important;color:#1F2329!important}
body.onboard,body.auth{--olive:#4f6a00;--olive-ink:#4f6a00}

/* ---- accent-as-text: never lime ---- */
a,.eb-row:hover .eb-row-go,.eb-tile-n,.eb-tile-go,.eb-tile:hover .eb-tile-go{
  color:var(--accent-ink)}
.eb-week-ic{background:var(--accent-soft);color:var(--accent-ink)}
.pv-ring.band-good,.hm-ring.band-good{
  background:conic-gradient(#4f6a00 calc(var(--p)*1%),#e1e4e8 0)}

/* ---- focus: graphite ring, which reads on white AND on lime ---- */
:root{--focus:#1F2329}
.btn-primary:focus-visible,.eb-cta-review:focus-visible,.mbtn:focus-visible{
  outline:2px solid #1F2329!important;outline-offset:2px!important;
  box-shadow:0 0 0 4px rgba(182,255,46,.55)!important}

/* ---- the GBP scoped palette, re-pointed again ---- */
#gbp-switcher{
  --accent:#B6FF2E; --accent-ink:#4f6a00; --accent-2:#3a4048;
  --accent-3:#c9d1da; --accent-soft:#f2ffdb; --good:#4f6a00;
  --ink:#1F2329; --track:#e1e4e8;
}

/* --muted at #5b626b measured 4.47 on the page grey — I picked it by eye and it
   landed just under 4.5, failing in 100+ places at once. #545b64 is 6.87 on
   white and 6.35 on the page ground. */
:root{--muted:#545b64}

/* The last three elements sitting ON lime with light text, found by querying the
   DOM for computed background === rgb(182,255,46) rather than grepping the
   stylesheet — .ig-rec and .go are declared in style.css, so a grep of this file
   would have missed them (and did). All three were 1.21:1. */
.go,.ig-rec,.lib-count{color:#1F2329!important}

/* ── the last of the lime-as-text ────────────────────────────────────────────
   Six selectors took var(--accent) as a COLOUR rather than a background, so
   pointing --accent at lime made them 1.16-1.21 on white. Found by querying the
   DOM for computed color === rgb(182,255,46) across every page, which is the
   only reliable way to catch the ones with no class of their own (the scan
   share button and the wizard's custom-offer summary are styled by tag). */
.cl-num,.cl-chip-impact.hi,.cl-chip.cl-chip-impact.hi,.fnd-i,.num.tnum,
.share button,.custom>summary{color:var(--accent-ink)}
.cl-startpill{color:#1F2329}

/* .go stayed white because an EARLIER rule in this same file — body.auth .go —
   out-specifies a bare .go, and both carry !important. Specificity decides when
   importance ties. Restated at matching specificity. */
body.auth .go,body.auth button[type="submit"],
body.onboard .go,body.onboard button[type="submit"]{color:#1F2329!important}

/* Two descendant selectors out-specified the bare ones above: .cl-prio .cl-num
   in style.css, and .fnd-tip .fnd-i earlier in THIS file (which I had pointed at
   --accent back when accent was blue and safe as text). Matched specificity. */
.cl-prio .cl-num{color:var(--accent-ink)}
.fnd-tip .fnd-i{color:var(--accent-ink)}

/* The empty-ring dash: #525965 landed at 4.48 against the ring's track — under
   by 0.02, which is still a fail. --ink-soft clears it comfortably. */
.hm-ring.band-none b,.pv-ring.band-none b{color:var(--ink-soft)}

/* #gbp-switcher .ring.s-none b takes the scoped --faint, and #5f6773 measured
   4.48 against the ring's #e1e4e8 track — the token was calibrated against white,
   not against the track it actually sits on. */
#gbp-switcher{--faint:#4e555e}

/* ══════════════════════════════════════════════════════════════════════════
   DASHBOARD GRID (29 Jul)

   Two problems, one cause. rail.css set `.content{max-width:none}` when the
   sidebar arrived, so at 1728px the cards ran to 1664px — every section a
   single full-bleed column, which is what read as "stretched". Meanwhile
   .pagehead kept its 1180px cap, so the brand name and the Brand & assets
   button sat in a box 484px narrower than the cards under them. They looked
   badly placed because they were, by 484px.

   Fixed by capping both at the same width and laying the sections out on a
   12-column grid: 4+8, then 7+5, then 12. One column, two columns, three
   inside Create.
   ══════════════════════════════════════════════════════════════════════════ */
.content,.pagehead{max-width:1440px;margin-left:auto;margin-right:auto}
.content.nohead{padding-top:26px}
.pagehead:empty,.content.nohead ~ .pagehead{display:none}

.dg{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:16px;align-items:start}
.sp-4{grid-column:span 4}
.sp-5{grid-column:span 5}
.sp-7{grid-column:span 7}
.sp-8{grid-column:span 8}
.sp-12{grid-column:span 12}
@media(max-width:1180px){
  .sp-4,.sp-5,.sp-7,.sp-8{grid-column:span 12}
}

.dg-card{background:var(--surface);border:1px solid var(--line);border-radius:10px;
  padding:20px 22px}
.dg-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding-bottom:12px;margin-bottom:14px;border-bottom:1px solid var(--line)}
.dg-head h2{font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);margin:0}
.dg-head .sub{font-size:12.5px;color:var(--muted);margin-left:auto}
.dg-k{display:block;font-size:11px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);margin-bottom:16px}

/* ── the score, as one piece ──────────────────────────────────────────────
   It used to be a bare numeral floating in the corner of a wide slab. Now it
   is a lime arc with the number inside it, which is the only place on the
   dashboard lime carries meaning rather than decoration: the sweep IS the
   score. Graphite numeral on white inside the hole, so nothing sits on lime. */
.dg-score{display:flex;flex-direction:column;align-items:center;text-align:center}
.sc-ring{--p:0;width:172px;height:172px;border-radius:50%;display:grid;place-items:center;
  background:conic-gradient(#B6FF2E calc(var(--p)*1%),#e8ebee 0);position:relative}
.sc-ring.band-none{background:conic-gradient(#e8ebee 100%,#e8ebee 0)}
.sc-hole{width:136px;height:136px;border-radius:50%;background:var(--surface);
  display:flex;align-items:baseline;justify-content:center;gap:1px}
.sc-hole b{font-size:52px;font-weight:700;letter-spacing:-.04em;color:var(--ink);
  line-height:1;font-variant-numeric:tabular-nums}
.sc-hole b.na{color:var(--faint)}
.sc-hole span{font-size:15px;font-weight:500;color:var(--muted)}
.sc-verdict{margin-top:16px;font-size:19px;font-weight:600;color:var(--ink)}
.sc-insight{margin:10px 0 0;font-size:13.5px;line-height:1.55;color:var(--ink-soft);
  max-width:34ch}
.sc-foot{margin-top:14px;padding-top:13px;border-top:1px solid var(--line);
  font-size:12px;color:var(--muted);width:100%}
.dg-score .eb-cta-review{margin-top:14px}

/* ── channel groups, each in its own bordered block ───────────────────────
   Liam asked for the two groups to be separated and for the border to carry
   the lime. Ordering gets the lime edge because it is the one that costs
   money; Discovery gets a quiet grey so the two don't compete. */
.cg{border:1px solid var(--line);border-radius:9px;padding:12px 14px 6px;
  background:#fbfcfc}
.cg + .cg{margin-top:14px}
.cg-ordering{border-left:3px solid #B6FF2E}
.cg-discovery{border-left:3px solid var(--line)}
.cg-lab{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;
  font-size:10.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);padding-bottom:8px}
.cg-lab em{font-style:normal;font-weight:500;font-size:11.5px;letter-spacing:0;
  text-transform:none;color:var(--muted)}
.cg .eb-row{background:transparent;border:0;border-top:1px solid var(--line);
  border-radius:0;padding:12px 2px}
.cg .eb-row:first-of-type{border-top:0}
.cg .eb-row:hover{background:transparent}
.cg .eb-row:hover .eb-row-lab{color:var(--accent-ink)}

/* Create: three across, dropping to two then one. */
.dg-create .eb-create{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
@media(max-width:980px){.dg-create .eb-create{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:640px){.dg-create .eb-create{grid-template-columns:minmax(0,1fr)}}

@media(max-width:560px){
  .dg{gap:12px}
  .dg-card{padding:16px}
  .sc-ring{width:148px;height:148px}
  .sc-hole{width:116px;height:116px}
  .sc-hole b{font-size:44px}
}

/* ══════════════════════════════════════════════════════════════════════════
   REVIEW REPORTS — out of one column

   The report was .report-main as a single 940px stack, 3915px tall: eight cards
   one under another, several of them short. That is the "1 column, too
   stretched" Liam flagged. Now a 12-column grid — 12 / 6+6 / 7+5 / 12 — so the
   short blocks pair up and the tall ones keep the full measure.

   .content.narrow carries max-width:none and out-specifies the 1440 cap in
   rail.css, so the cap is restated here at matching specificity.

   One ordering note: .strengths-d sits last in the DOM but is placed beside the
   action plan, so its visual position is one step ahead of its tab position.
   It is a read-only summary block, so nothing is reachable out of order.
   ══════════════════════════════════════════════════════════════════════════ */
@media(min-width:901px){
  .content.narrow{max-width:1440px;margin-left:auto;margin-right:auto}
  .report-cols{max-width:none}
  .report-main{max-width:none;width:100%;
    display:grid;grid-template-columns:repeat(12,minmax(0,1fr));
    gap:16px;align-items:start}
  .report-main > *{min-width:0}

  #rep-overview  {order:1;grid-column:span 12}
  #comp-box      {order:2;grid-column:span 6}
  #ig-box        {order:3;grid-column:span 6}
  #rep-checklist {order:4;grid-column:span 7}
  .report-main .fset.strengths-d{order:5;grid-column:span 5;margin:0}
  #features-box  {order:6;grid-column:span 12}
  #sections      {order:7;grid-column:span 12}
  #replies-box   {order:8;grid-column:span 12}
  /* The outcome strip has no span of its own, so it rode the catch-all below and
     got span 1 - a 105px column that wrapped its headline to four lines and shot
     "N days tracked" out of the flex row. Given an explicit span, and order:1 to
     tie with #rep-overview so DOM order keeps it under the hero rather than
     above it (an unset order is 0, which sorts before everything). */
  #out-strip     {order:1;grid-column:span 12}

  /* anything the report grows later still gets a sane default.
     NB: keep this on ONE line. A line break between the :not()s is whitespace,
     i.e. a descendant combinator - which is what silently broke #out-strip. */
  .report-main > :not(#rep-overview):not(#comp-box):not(#ig-box):not(#rep-checklist):not(.strengths-d):not(#features-box):not(#sections):not(#replies-box):not(#out-strip){grid-column:span 12}

  /* the two tall blocks read better split than as one long list */
  #features-box .fset-grid,#replies-box #replies{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
}
@media(min-width:1500px){
  /* three across once there is genuinely room for it */
  #replies-box #replies{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* The report pages scope their layout under body[data-report], which
   out-specifies a bare .content or #rep-checklist — that is why the width cap
   and the checklist's grid order above did nothing. Restated at that
   specificity. (style.css sets order:20 on the checklist to push it last in the
   old single column; in the grid it belongs beside the strengths block.) */
@media(min-width:901px){
  body[data-report] .content{max-width:1440px;margin-left:auto;margin-right:auto}
  body[data-report] .report-cols{max-width:none;width:100%}
  body[data-report] .report-main{max-width:none;width:100%}
  body[data-report] .report-main > #rep-checklist{order:4}
}

/* The report renders inside .setup, which is capped at 940px — that cap is what
   held the whole grid to one narrow column regardless of everything above.
   Found by walking the ancestor chain rather than guessing at the next selector. */
@media(min-width:901px){
  body[data-report] .setup{max-width:none}
}

/* .setup:has(> #result:not(.hidden)) sets 940px, and :has() takes the
   specificity of its argument — the #result inside it makes that rule (1,2,0),
   which outranks body[data-report] .setup at (0,2,1). Matched by wearing the
   same :has(), which is the only way to beat it without !important. */
@media(min-width:901px){
  body[data-report] .setup:has(> #result:not(.hidden)){max-width:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   NO CONTAINERS INSIDE CONTAINERS (29 Jul)

   Every section was a white card wrapping a heading plus more white cards —
   two borders and two backgrounds to say one thing. The heading now sits on
   the page ground and only the items are cards. Applies to the dashboard and
   to the report pages, so the rule holds everywhere rather than page by page.

   .dg-score keeps its card because it IS one item, not a group of them.
   ══════════════════════════════════════════════════════════════════════════ */
.dg-chan,.dg-week,.dg-act,.dg-create{
  background:transparent;border:0;border-radius:0;padding:0}
.dg-chan .dg-head,.dg-week .dg-head,.dg-act .dg-head,.dg-create .dg-head{
  border-bottom:0;padding:0 2px 10px;margin-bottom:10px}
.dg-head h2{font-size:12px;letter-spacing:.14em;color:var(--muted)}

/* The report pages had the same doubling: a .card wrapping .fset blocks that
   were themselves bordered. Strip the outer one, keep the inner. */
body[data-report] #features-box,body[data-report] #replies-box,
body[data-report] #sections{background:transparent;border:0;padding:0}
body[data-report] #features-box > .fset,body[data-report] #replies-box .reply-card,
body[data-report] #sections .cat{background:var(--surface);border:1px solid var(--line);
  border-radius:9px}

/* ── by channel: the weak one ─────────────────────────────────────────────
   Name, number, and a lot of air. Two changes: the groups become the cards
   (there is no outer box now), and every row carries a bar so the three
   scores are comparable without holding numbers in your head. Lime fills it,
   which is the one thing lime is actually good at. */
.cg{background:var(--surface);border:1px solid var(--line);border-left-width:3px;
  border-radius:10px;padding:14px 18px 8px}
.cg-ordering{border-left-color:#B6FF2E}
.cg-discovery{border-left-color:var(--line)}
.cg + .cg{margin-top:14px}

.cg .eb-row{grid-template-columns:auto 1fr auto auto;row-gap:10px;padding:14px 0}
.eb-row-bar{grid-area:3/1/4/5;height:6px;border-radius:99px;background:#eceef1;
  overflow:hidden;display:block;width:100%}
.eb-row-bar i{display:block;height:100%;width:calc(var(--p,0)*1%);border-radius:99px;
  background:#B6FF2E;transition:width .5s cubic-bezier(.4,0,.2,1)}
/* Warn and bad keep their own colour so the bar agrees with the numeral rather
   than telling a cheerier story than the score does. */
.eb-row:has(.warnband) .eb-row-bar i{background:#e0a92b}
.eb-row:has(.badband) .eb-row-bar i{background:#e06a5e}
.eb-row-sub{grid-area:2/1/3/5}
@media(prefers-reduced-motion:reduce){.eb-row-bar i{transition:none}}

/* ── the grey gap under Activity ──────────────────────────────────────────
   This week (span 7) is much taller than Activity (span 5), so the grid cell
   left a block of bare page below the shorter one. Stretch the activity card
   to the row height so the column ends where its neighbour does. */
.dg{align-items:stretch}
.dg-score,.dg-chan,.dg-week,.dg-act,.dg-create{display:flex;flex-direction:column}
.dg-act .eb-act{flex:1}
.dg-score{justify-content:flex-start}

/* Stretching the Activity card to match This week only traded a grey void for a
   white one, which reads worse — an empty card looks broken, empty page ground
   just looks like page ground. Natural heights, and the two columns simply end
   where their content ends. */
.dg{align-items:start}
.dg-act .eb-act{flex:0 0 auto}

/* The bars are graphical objects and need 3:1 against their own track. Measured
   against #eceef1: lime 1.04, amber 1.83, red 2.83 — all three fail, and the
   lime one is effectively invisible. Same trap as lime text, in a new place:
   a light mark on a light track cannot work no matter how saturated it is.
   The dark variants land at 5.3 / 5.1 / 5.6. Lime stays where it belongs, on
   the fills and the score ring, where it has a dark ground under it. */
.eb-row-bar i{background:#4f6a00}
.eb-row:has(.warnband) .eb-row-bar i{background:#8a5a00}
.eb-row:has(.badband) .eb-row-bar i{background:#b3261e}

/* ═══════════════════════════════════════════════════════════════════════════
   PRESENCE DASHBOARD — presence-final.html port (30 Jul)

   Reference tokens, with two amendments the measurements force:
   - ink-3 #7a828d measures 3.9 on white and 3.5 on the #dfe3e8 page — under
     4.5 for the 11px labels it is used for. All ink-3 roles take var(--muted)
     (#545b64: 6.9 white / 5.8 page) instead.
   - the semantic greens/ambers are darkened a step so numerals clear 3:1 as
     large text AND meters clear 3:1 against their track. Lime itself remains
     fill-only, as everywhere.
   ═══════════════════════════════════════════════════════════════════════════ */
.content.presence{
  --lime:#c3f53c;--lime-ink:#1a2400;--lime-soft:#eef9cf;
  --pf-line:#e7eaee;--card:#ffffff;
  --poor:#c23b2f;--fair:#96690c;--good:#42811f;--good-deep:#38701a;
  --poor-soft:#f7e3e0;--fair-soft:#f6ecd4;--good-soft:#e6f2dd;
  --pf-radius:18px;--pf-shadow:0 1px 2px rgba(20,22,26,.04),0 8px 24px rgba(20,22,26,.06);
  max-width:1160px;padding-top:30px}
body.app{background:#dfe3e8}

.content.presence .eyebrow{font-size:11px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
.pf-topbar{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:22px}
.pf-topbar h1{font-size:15px;font-weight:700;letter-spacing:-.01em;color:var(--ink)}
.pf-topbar .crumbs{font-size:13px;color:var(--muted)}
.pf-topbar .crumbs b{color:var(--ink);font-weight:600}
.content.presence .section-head{display:flex;align-items:baseline;justify-content:space-between;
  margin:30px 2px 14px}
.content.presence .section-head .sub{font-size:12px;color:var(--muted)}

.content.presence .btn{border:0;cursor:pointer;font-weight:700;font-size:13.5px;
  border-radius:11px;padding:11px 18px;display:inline-flex;align-items:center;gap:8px;
  transition:.15s;text-decoration:none}
.content.presence .btn.primary{background:var(--lime);color:var(--lime-ink)}
.content.presence .btn.primary:hover{filter:brightness(.96)}
.content.presence .btn.ghost{background:#fff;color:var(--ink);border:1px solid var(--pf-line)}
.content.presence .btn.ghost:hover{border-color:#cfd4da}
.content.presence .btn .arw{transition:.15s}
.content.presence .btn:hover .arw{transform:translateX(3px)}
.content.presence .btn:focus-visible{outline:2px solid var(--ink)!important;outline-offset:2px!important}

/* ── glow (pointer-follow conic border), lime-forward gradient ── */
.glow-card{position:relative;border-radius:var(--pf-radius)}
.glow{position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:0}
.glow::after{content:"";position:absolute;inset:-3px;border-radius:inherit;
  border:3px solid transparent;
  background:
    radial-gradient(circle,#c3f53c 10%,#c3f53c00 20%),
    radial-gradient(circle at 40% 40%,#8fd400 5%,#8fd40000 15%),
    radial-gradient(circle at 60% 60%,#5a922c 10%,#5a922c00 20%),
    repeating-conic-gradient(from 236deg at 50% 50%,#c3f53c 0%,#8fd400 12%,#5a922c 25%,#c3f53c 37%);
  background-attachment:fixed;opacity:var(--active,0);transition:opacity .3s;
  -webkit-mask-clip:padding-box,border-box;mask-clip:padding-box,border-box;
  -webkit-mask-composite:source-in;mask-composite:intersect;
  -webkit-mask-image:linear-gradient(#0000,#0000),conic-gradient(from calc((var(--start,0) - var(--spread,40))*1deg),#00000000 0deg,#fff,#00000000 calc(var(--spread,40)*2deg));
  mask-image:linear-gradient(#0000,#0000),conic-gradient(from calc((var(--start,0) - var(--spread,40))*1deg),#00000000 0deg,#fff,#00000000 calc(var(--spread,40)*2deg))}
.glow-inner{position:relative;z-index:1;background:var(--card);border-radius:inherit;
  height:100%;display:block;text-decoration:none;color:inherit}
@media(prefers-reduced-motion:reduce){.glow::after{transition:none;opacity:0!important}}

/* ── hero: setup progress ── */
.hero .glow-inner{padding:30px 34px;box-shadow:var(--pf-shadow)}
.hero .pf-top{display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap}
.hero .eyebrow{display:block;margin-bottom:10px}
.hero .headline{font-size:28px;font-weight:800;letter-spacing:-.025em;line-height:1.1;color:var(--ink)}
.hero .headline b{color:var(--good)}
.hero .subline{font-size:14px;color:var(--ink-soft);margin-top:8px;max-width:52ch;line-height:1.5}
.hero .ring{position:relative;width:116px;height:116px;flex-shrink:0}
.hero .ring .c{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center}
.hero .ring .c .f{font-size:27px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.hero .ring .c .l{font-size:10px;color:var(--muted);font-weight:700;
  text-transform:uppercase;letter-spacing:.09em}
.checks{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:24px}
.chk{display:flex;align-items:center;gap:10px;padding:12px 14px;border:1px solid var(--pf-line);
  border-radius:12px;font-size:13px;font-weight:600;text-decoration:none;color:var(--ink);
  transition:border-color .15s}
.chk:hover{border-color:#b8bfc7}
.chk:focus-visible{outline:2px solid var(--ink)!important;outline-offset:2px!important}
.chk .box{width:20px;height:20px;border-radius:6px;display:grid;place-items:center;
  font-size:12px;flex-shrink:0}
.chk.done .box{background:var(--good);color:#fff}
.chk.todo .box{border:1.5px solid #cfd4da;color:transparent}
.chk.todo{color:var(--muted);border-style:dashed}
.chk.next .box{background:var(--lime);color:var(--lime-ink)}
.chk.next{border-color:#9fd41c;color:var(--ink)}
.hero .cta{margin-top:22px;display:flex;gap:10px;flex-wrap:wrap}

/* ── channels ── */
.chan-grid{display:grid;gap:14px}
.chan{background:var(--card);border-radius:var(--pf-radius);box-shadow:var(--pf-shadow);
  padding:20px 22px;display:grid;grid-template-columns:230px 1fr 96px;align-items:center;
  gap:24px;text-decoration:none;color:inherit;transition:transform .15s}
.chan:hover{transform:translateY(-2px)}
.chan:focus-visible{outline:2px solid var(--ink)!important;outline-offset:2px!important}
.chan.accent{border-left:4px solid var(--lime)}
.chan .tag{font-size:10.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted)}
.chan .name{font-size:17px;font-weight:700;letter-spacing:-.01em;margin-top:5px;color:var(--ink);
  display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.chan .name .handle{font-size:13px;color:var(--muted);font-weight:500}
.chan .name .star{font-size:13px;color:var(--fair);font-weight:600}
.chan .lbl{font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);display:block;margin-bottom:8px}
.content.presence .chips{display:flex;gap:6px;flex-wrap:wrap}
.content.presence .chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;
  font-weight:600;padding:5px 10px;border-radius:8px;border:1px solid var(--pf-line);
  background:#fff;color:var(--ink)}
.content.presence .chip .ic{width:15px;height:15px;border-radius:4px;display:grid;
  place-items:center;font-size:10px;font-weight:800;color:#fff;overflow:hidden}
.content.presence .chip .ic img{width:100%;height:100%;object-fit:cover}
.content.presence .chip.warn{color:#9c2a20;border-color:#eecfc9;background:var(--poor-soft)}
.scorecol{text-align:right}
.scorecol .val{font-size:30px;font-weight:800;letter-spacing:-.02em;line-height:1;
  font-variant-numeric:tabular-nums}
.scorecol .val.poor{color:var(--poor)}
.scorecol .val.fair{color:var(--fair)}
.scorecol .val.good{color:var(--good)}
.scorecol .val.na{color:var(--faint);font-weight:600}
.scorecol .meter{height:5px;border-radius:999px;background:var(--pf-line);margin-top:9px;overflow:hidden}
.scorecol .meter i{display:block;height:100%;border-radius:999px}
.scorecol .meter i.poor{background:var(--poor)}
.scorecol .meter i.fair{background:var(--fair)}
.scorecol .meter i.good{background:var(--good)}

/* ── create tiles ── */
.create-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:14px}
.make .glow-inner{padding:22px;box-shadow:var(--pf-shadow);transition:transform .18s}
.make:hover .glow-inner{transform:translateY(-3px)}
.make .glow-inner:focus-visible{outline:2px solid var(--ink)!important;outline-offset:2px!important}
.make .idx{font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--good-deep)}
.make h3{font-size:21px;font-weight:750;letter-spacing:-.02em;margin:10px 0 8px;color:var(--ink)}
.make p{font-size:13px;color:var(--ink-soft);line-height:1.5;min-height:56px;margin:0}
.make .go{display:inline-flex;align-items:center;gap:7px;margin-top:6px;font-weight:700;
  font-size:13px;color:var(--lime-ink);background:var(--lime);padding:8px 14px;border-radius:9px}
.make .go .arw{transition:.15s}
.make:hover .go .arw{transform:translateX(3px)}

@media(max-width:880px){
  .chan{grid-template-columns:1fr;gap:14px}
  .scorecol{text-align:left}
  .create-grid{grid-template-columns:1fr}
  .checks{grid-template-columns:1fr}
}
@media(prefers-reduced-motion:reduce){
  .chan,.make .glow-inner,.content.presence .btn .arw,.make .go .arw{transition:none}
  .chan:hover,.make:hover .glow-inner{transform:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   OVERNIGHT ITERATION 1 (30 Jul) — product-designer review findings.
   The CTA fix is above, at the source (the onboarding block was unscoped).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── (1) one design system: hoist the presence tokens app-wide ──
   Inner pages still carried 6-9px radii, hairline borders and no shadow —
   visibly a different product from the dashboard. Cards everywhere now take
   the reference shape. Selectors verified against style.css/templates, not
   taken on trust from the review. */
body.app{
  --pf-radius:18px;--pf-line:#e7eaee;
  --pf-shadow:0 1px 2px rgba(20,22,26,.04),0 8px 24px rgba(20,22,26,.06);
  --lime:#c3f53c;--lime-ink:#1a2400;
  --poor:#c23b2f;--fair:#96690c;--good:#42811f;--good-deep:#38701a;
  --r:11px}
.card,.toolcard,.makecard,.hm-card,.igm,.eb-act,.eb-tile,.stat,.scorecard,
.cl-card,.dg-card,.cg,.ba-panel,
body[data-report] #features-box > .fset,body[data-report] #replies-box .reply-card,
body[data-report] #sections .cat{
  border:0;border-radius:var(--pf-radius);box-shadow:var(--pf-shadow)}

/* ── (2) pagehead: same voice as the presence topbar, and no lime dash ──
   32px display h1 on a mismatched wash band, with a thin lime ::after on a
   light ground (~1.1:1 — the banned mark). Now the pf-topbar pattern. */
.pagehead{background:transparent;border-bottom:0;backdrop-filter:none;position:static}
.pagehead::after{display:none}
.ph-title h1{font-size:15px;font-weight:700;letter-spacing:-.01em}
.ph-title p{font-size:13px;color:var(--muted);margin-top:2px}

/* ── (3) glow at rest ──
   The conic border painted a dark crescent with no pointer anywhere near —
   permanently, on touch. And background-attachment:fixed shears under scroll. */
.glow::after{background-attachment:scroll}
@media(hover:none){.glow{display:none}}
.hero .glow-inner,.make .glow-inner{border:1px solid var(--pf-line)}

/* ── (5) wizard: the last blue-era pixels ──
   A royal-blue numeral chip inside the lime step pill, and a blue selection
   halo on chosen tiles. Both graphite now. !important matches the rule it
   replaces at :312. */
.step.active i{background:#1F2329!important;color:#fff!important}
.tile.sel .thumb img{box-shadow:0 0 0 3px rgba(31,35,41,.30)}

/* ── (6) disabled buttons must look intentional, not broken ──
   style.css fades any disabled .btn to 55% opacity; on a lime fill that reads
   as a rendering bug on the page's main action. Disabled controls are exempt
   from contrast minimums, but they still have to look designed. */
.btn:disabled,.btn[disabled]{opacity:1;background:var(--surface-2);
  color:var(--faint);border-color:var(--line);cursor:default}

/* Unmasked by scoping the onboarding block: .btn.accent (Re-run review, Add
   payment method) was white-on-accent from the blue era — 1.17 now the accent
   is lime. The old unscoped !important had been hiding it, which is why no
   sweep ever saw it. Lime fill, lime-ink, like every other primary action. */
.btn.accent{background:var(--lime);color:var(--lime-ink);border-color:var(--lime)}
.btn.accent:hover{background:#b2e332;border-color:#b2e332;color:var(--lime-ink)}

/* ═══ ITERATION 2 — the four queued findings, selectors read off the DOM ═══ */

/* (7) GBP overview: unscored rows say so in words, the unread state is a
   chip-shaped action rather than bare amber text, and the sort control gets
   room at phone width. .loc/.sort/.ol-unread confirmed live; the review's
   .done-group family does not exist and was ignored. */
#gbp-switcher .notscored{font-size:12.5px;font-weight:600;color:var(--muted)}
#gbp-switcher .runhint{display:inline-flex;align-items:center;font-size:12px;
  font-weight:700;color:var(--ink);border:1px solid var(--line);border-radius:8px;
  padding:5px 10px;background:var(--surface)}
#gbp-switcher .row:hover .runhint{border-color:#b8bfc7}
#gbp-switcher .ol-unread{display:inline-flex;align-items:center;gap:5px;
  border:1px solid #e8d5ab;border-radius:8px;padding:4px 9px;
  background:var(--warn-soft);color:var(--warn-text)}
@media(max-width:560px){
  #gbp-switcher .sort{display:flex;width:100%;gap:0}
  #gbp-switcher .sort > *{flex:1;white-space:nowrap;padding:8px 4px;font-size:12px}
}

/* (5b) wizard progress line: the counter and its dot were breaking mid-number
   at 390px. The whole line may wrap between words; the figures may not. */
.tile-prog{flex-wrap:wrap;line-height:1.45}
.tile-prog b,.tile-prog .n{white-space:nowrap}

/* gradient-dots background lived here for about an hour on 30 Jul — Liam saw
   it and asked for it gone. Plain #dfe3e8 ground; the block is in git if the
   idea ever comes back. */
body.app{background:#dfe3e8}

/* ── wizard stepper at phone width (queued designer finding) ────────────────
   Seven labelled pills wrapped to three rows: 121px of stepper, first content
   at y=434 — half the viewport spent before "Confirm your colours". Inactive
   steps drop to their numbered chip (the label is a bare text node after the
   <i>, so font-size:0 on the button hides it and the chip restores its own);
   the ACTIVE step keeps its label, so the row still says where you are.
   Chip stays 30px inside a padded button, keeping the tap target ~44px. */
@media(max-width:560px){
  #stepper .step:not(.active){font-size:0;gap:0;padding:7px}
  #stepper .step:not(.active) i{font-size:12.5px;width:30px;height:30px}
}

/* One row needs ALL seven as chips: 7 x 44px targets + gaps = 332px, which
   fits 390 only if the active pill gives up its label too. The stage title
   right below ("Confirm your colours") already names the step, so the label
   was duplicated anyway. Active chip keeps its highlight. */
@media(max-width:560px){
  #stepper{gap:4px;flex-wrap:nowrap}
  #stepper .step{font-size:0;gap:0;padding:7px}
  #stepper .step i{font-size:12.5px;width:30px;height:30px}
}

/* Collapsing the stepper exposed the active chip as white-on-lime (1.21) —
   the same law, found by the same measurement, for at least the fourth time:
   anything on lime wears graphite. */
#stepper .step.active i{color:#1a2400;background:transparent}

/* The chip rule above lost to iteration 1's `.step.active i{color:#fff!important}`
   (written when the pill was still its old shape). Importance ties break on
   specificity, so the id-scoped rule wins once it carries !important too. */
#stepper .step.active i{color:#1a2400!important;background:transparent!important}

/* review round 3, finding 2 — the report pages alone kept a 24px title on a
   white band: body[data-report] rules in style.css out-specify the bare
   pagehead condensation. The one visible seam across the four pages. */
body[data-report] .ph-title h1{font-size:15px;font-weight:700}
body[data-report] .pagehead{background:transparent;border-bottom:0}

/* ═══════════════════════════════════════════════════════════════════════════
   MONO DASHBOARD (30 Jul evening) — the activity-chart-card language.
   Black is the data colour. Big friendly titles, huge tight numerals, chunky
   rounded bars, tiny quiet labels. Lime keeps its two jobs: actions and the
   dock. The green trend arrow uses --good (#42811f, 4.0+ large / decorative).
   ═══════════════════════════════════════════════════════════════════════════ */
.content.mndash{max-width:1160px;padding-top:34px}
.mn-top{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:20px}
.mn-top h1{font-size:22px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.mn-crumb{font-size:13px;color:var(--muted)}
.mn-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:18px;align-items:start}
.mn-grid .sp-5{grid-column:span 5}
.mn-grid .sp-7{grid-column:span 7}
.mn-grid .sp-12{grid-column:span 12}
@media(max-width:1080px){.mn-grid .sp-5,.mn-grid .sp-7{grid-column:span 12}}

.mn-card{background:#fff;border:1px solid #ececf0;border-radius:18px;
  padding:26px 28px;box-shadow:0 1px 2px rgba(20,22,26,.03),0 10px 30px rgba(20,22,26,.05)}
.mn-head{display:flex;align-items:center;justify-content:space-between;
  gap:14px;margin-bottom:18px}
.mn-head h2{font-size:24px;font-weight:800;letter-spacing:-.02em;color:var(--ink);margin:0}
.mn-range{font-size:13.5px;font-weight:600;color:var(--muted)}
.mn-next{font-size:13px;font-weight:700;color:var(--lime-ink);background:var(--lime);
  border-radius:9px;padding:8px 13px;text-decoration:none;white-space:nowrap}
.mn-next b{display:inline-block;transition:transform .15s}
.mn-next:hover b{transform:translateX(3px)}

.mn-stat-row{display:flex;align-items:flex-end;gap:26px;flex-wrap:wrap}
.mn-stat{flex:0 0 auto}
.mn-big{font-size:54px;font-weight:800;letter-spacing:-.045em;line-height:1;
  color:var(--ink);margin:0;font-variant-numeric:tabular-nums}
.mn-of{font-size:22px;font-weight:600;color:var(--muted);letter-spacing:-.01em}
.mn-trend{display:flex;align-items:center;gap:6px;font-size:13.5px;color:var(--muted);
  margin:8px 0 0;max-width:22ch;line-height:1.4}
.mn-trend .up{width:16px;height:16px;color:var(--good);flex:0 0 auto}

/* the chart: bars scale up with a small stagger, exactly the reference */
.mn-chart{display:flex;align-items:flex-end;gap:10px;height:112px;flex:1;min-width:200px}
.mn-col{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  gap:8px;flex:1;height:100%}
.mn-bar{width:100%;border-radius:9px;background:var(--ink);
  height:max(6px, calc(var(--h,0) * 1% - 22px));
  transform-origin:bottom;animation:mnbar .5s cubic-bezier(.4,0,.2,1) both;
  animation-delay:calc(var(--i,0) * 70ms)}
.mn-day{font-size:11.5px;color:var(--muted)}
@keyframes mnbar{from{transform:scaleY(0);opacity:0}to{transform:scaleY(1);opacity:1}}
@media(prefers-reduced-motion:reduce){.mn-bar{animation:none}}

/* checklist, compact 2-col */
.mn-checks{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;flex:1;min-width:280px}
.mn-chk{display:flex;align-items:center;gap:9px;padding:9px 11px;border:1px solid #ececf0;
  border-radius:11px;font-size:13px;font-weight:600;text-decoration:none;color:var(--ink)}
.mn-chk:hover{border-color:#c9cdd4}
.mn-chk .box{width:19px;height:19px;border-radius:6px;display:grid;place-items:center;
  font-size:11.5px;flex:0 0 auto}
.mn-chk.done .box{background:var(--ink);color:#fff}
.mn-chk.todo{color:var(--muted);border-style:dashed}
.mn-chk.todo .box{border:1.5px solid #c9cdd4;color:transparent}
.mn-chk.next{border-color:#9fd41c}
.mn-chk.next .box{background:var(--lime);color:var(--lime-ink)}

/* channels: one row each — name, chunky black bar, big numeral */
.mn-chans{display:flex;flex-direction:column}
.mn-chan{display:grid;grid-template-columns:250px 1fr auto;align-items:center;gap:24px;
  padding:16px 2px;border-top:1px solid #ececf0;text-decoration:none;color:inherit}
.mn-chan:first-child{border-top:0;padding-top:2px}
.mn-chan-name{font-size:16.5px;font-weight:700;letter-spacing:-.01em;color:var(--ink);display:block}
.mn-chan-name em{font-style:normal;font-weight:500;font-size:13px;color:var(--muted);margin-left:6px}
.mn-chan-sub{font-size:12.5px;color:var(--muted);display:block;margin-top:3px}
.mn-chan-sub .miss{font-weight:700;color:var(--bad-text)}
.mn-chan-bar{height:10px;border-radius:99px;background:#eef0f3;overflow:hidden}
.mn-chan-bar i{display:block;height:100%;border-radius:99px;background:var(--ink);
  width:calc(var(--w,0) * 1%);transition:width .5s cubic-bezier(.4,0,.2,1)}
.mn-chan-n{font-size:30px;font-weight:800;letter-spacing:-.03em;color:var(--ink);
  text-align:right;font-variant-numeric:tabular-nums;min-width:64px}
.mn-chan-n em{display:block;font-style:normal;font-size:11px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase}
.mn-chan-n .w-poor{color:var(--bad-text)}
.mn-chan-n .w-fair{color:var(--warn-text)}
.mn-chan-n .w-good{color:var(--good)}
.mn-chan-n.na{color:var(--faint);font-weight:600}
.mn-chan:hover .mn-chan-name{text-decoration:underline;text-underline-offset:3px}
@media(prefers-reduced-motion:reduce){.mn-chan-bar i{transition:none}}

/* create: three quiet cards, no glow */
.mn-create{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
@media(max-width:900px){.mn-create{grid-template-columns:minmax(0,1fr)}}
.mn-make{display:flex;flex-direction:column;gap:8px;text-decoration:none;color:inherit;
  transition:transform .16s}
.mn-make:hover{transform:translateY(-3px)}
.mn-make h3{font-size:20px;font-weight:800;letter-spacing:-.02em;color:var(--ink);margin:0}
.mn-make p{font-size:13.5px;color:var(--muted);line-height:1.5;margin:0;flex:1}
.mn-make .go{align-self:flex-start;margin-top:8px;font-size:13px;font-weight:700;
  color:var(--lime-ink);background:var(--lime);border-radius:9px;padding:8px 14px}
.mn-make .go b{display:inline-block;transition:transform .15s}
.mn-make:hover .go b{transform:translateX(3px)}
@media(prefers-reduced-motion:reduce){.mn-make,.mn-make .go b,.mn-next b{transition:none}}
@media(max-width:640px){
  .mn-chan{grid-template-columns:1fr auto;gap:10px 16px}
  .mn-chan-bar{grid-column:1/3;grid-row:2}
  .mn-big{font-size:44px}
  .mn-card{padding:20px}
  .mn-checks{grid-template-columns:minmax(0,1fr)}
}

/* 390px: the checklist's 280px min-width and the nowrap next-chip stretched
   their grid column 3px past the viewport (with the chip itself 96px past).
   Min-widths yield on phones; the chip wraps its label. */
@media(max-width:640px){
  .mn-checks{min-width:0}
  .mn-chart{min-width:0}
  .mn-next{white-space:normal;text-align:left}
  .mn-head{flex-wrap:wrap}
}

/* ═══════════════════════════════════════════════════════════════════════════
   MONO · review pages (Liam: "update all the review products to the same
   styling — instagram, website and google"). All three share
   marketing_audit.html, so this lands once. Pattern = the mndash dashboard:
   big friendly titles, black data, huge tight numerals, quiet labels.
   ═══════════════════════════════════════════════════════════════════════════ */
/* section titles: 11px uppercase eyebrows become real titles */
body[data-report] #result h2,
body[data-report] #gbp-switcher h2{
  font-size:21px;font-weight:800;letter-spacing:-.02em;text-transform:none;
  color:var(--ink);background:none;border:0;padding:0}
/* card chrome: mono hairline + softer shadow on the existing 18px radius */
body[data-report] .card,body[data-report] .fset,body[data-report] .cat,
body[data-report] .reply-card,body[data-report] .cat-panel,
body[data-report] #gbp-switcher .card{
  border:1px solid #ececf0;
  box-shadow:0 1px 2px rgba(20,22,26,.03),0 10px 30px rgba(20,22,26,.05)}
/* score rings: black is the data colour — the arc goes ink, the numeral goes
   huge; semantic meaning stays on the band WORDS (gh-bandlbl, verdict chips),
   which is exactly how the dashboard's channel rows carry it */
body[data-report] :is(.ring.s-bad,.ring.s-warn,.ring.s-good){
  background:conic-gradient(var(--ink) calc(var(--p)*1%),#eef0f3 0)}
body[data-report] :is(.ring.s-bad,.ring.s-warn,.ring.s-good) b{
  color:var(--ink);font-weight:800;letter-spacing:-.03em}
/* big metric numerals (rating / reviews / photos) get the mono weight */
body[data-report] .num.tnum,body[data-report] .igm .num{
  font-weight:800;letter-spacing:-.03em;color:var(--ink)}
/* small labels stay small and quiet, but consistent */
body[data-report] .igm-k,body[data-report] .ord-k{
  font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--muted)}

/* mono reviews, pass 2 — measured, not assumed:
   - the ring rule lost to #gbp-switcher .ring.s-* (id beats the :is chain);
     restated above the id.
   - .reply-date was --faint on white (3.09) — only visible with a branch
     OPEN, which is why no earlier sweep ever caught it. The sweeps now open
     a branch; the date takes --muted.
   - .igm-tag chips measured 4.35 — same story. Deep variants. */
body[data-report] #gbp-switcher :is(.ring.s-bad,.ring.s-warn,.ring.s-good),
#gbp-switcher :is(.gh-ring.s-bad,.gh-ring.s-warn,.gh-ring.s-good){
  background:conic-gradient(var(--ink) calc(var(--p)*1%),#eef0f3 0)}
body[data-report] #gbp-switcher :is(.ring.s-bad,.ring.s-warn,.ring.s-good) b{
  color:var(--ink);font-weight:800;letter-spacing:-.03em}
body[data-report] .reply-date{color:var(--muted)}
body[data-report] .igm-tag{color:var(--good-deep)}
body[data-report] .igm-tag.low,body[data-report] .igm-tag.warn{color:var(--warn-text)}

/* pass 3 — the tag variants live on the PARENT (.igm-good/-warn/-bad), which
   my blanket .igm-tag colour ignored: green-deep text landed on the old
   violet and amber chip fills. Soft mono chips, deep text, literals because
   the -soft tokens are scoped to the presence page. */
body[data-report] .igm-good .igm-tag{background:#e6f2dd;color:#38701a}
body[data-report] .igm-warn .igm-tag{background:#f6ecd4;color:#8a5a00}
body[data-report] .igm-bad .igm-tag{background:#f7e3e0;color:#b3261e}

/* icon chips (Liam) — the dock's own glyphs, as quiet ink-on-grey squares */
.mn-ic{width:42px;height:42px;border-radius:12px;background:#eef0f3;
  display:grid;place-items:center;color:var(--ink);flex:0 0 auto}
.mn-ic svg{width:20px;height:20px}
.mn-chan{grid-template-columns:auto 250px 1fr auto}
@media(max-width:640px){
  .mn-chan{grid-template-columns:auto 1fr auto}
  .mn-chan-bar{grid-column:1/4;grid-row:2}
}
.mn-make .mn-ic{margin-bottom:4px}

/* ═══════════════════════════════════════════════════════════════════════════
   PAGE GROUND (2 Aug, Liam) — matched to the marketing site's --paper so the
   two surfaces are the same colour. Was #43474e, a lighter grey that made the
   dashboard read as a different product to the website sitting next to it.
   On #1e2126: ground-ink #f2f4f6 ≈ 14.8 · ground-muted #b6bdc6 ≈ 8.4, both
   comfortably past AA — the cards at #31343c now sit lighter than the ground
   rather than darker, which is the same relationship the website uses. */
body.app{background:#1e2126;
  --ground-ink:#f2f4f6;--ground-muted:#b6bdc6}

/* dashboard furniture on the ground */
.mn-top h1{color:var(--ground-ink)}
.mn-crumb{color:var(--ground-muted)}

/* inner-page furniture on the ground */
.ph-title h1{color:var(--ground-ink)}
.ph-title p{color:var(--ground-muted)}
body[data-report] .ph-title h1{color:var(--ground-ink)}
body[data-report] .ph-title p{color:var(--ground-muted)}
body[data-report] .pagehead{background:transparent;border-bottom:0}
.ph-actions .btn,.ph-actions .btn.ghost,.ph-actions a.btn,
body[data-report] .ph-actions .btn,body[data-report] #rerun{
  background:rgba(255,255,255,.10)!important;color:#f2f4f6!important;
  border:1px solid rgba(255,255,255,.25)!important}
#gbp-back,.content > a,#result > a{color:#c3f53c}
.report-key{background:rgba(52,56,63,.92);border-color:rgba(255,255,255,.14)}
.report-key a{color:#d3d8de}
.report-key a.on,.report-key a:hover{color:#14161a;background:#c3f53c}
body[data-report] #features-box > .cl-help,.cl-help{color:var(--ground-muted)}
#gbp-switcher .tbl-controls-l,.tbl-controls-l{color:var(--ground-ink)}

/* The wizard used to be a card on the ground — surface fill, border, shadow,
   24px of padding. Every step then put its own cards inside that card, so the
   choices read as objects in a box rather than as the page. The Social page
   never had the box and reads better for it, so the box goes: the steps sit
   straight on the ground and the option cards are the only containers left. */
#wizard-body{background:transparent;border:0;border-radius:0;padding:0;box-shadow:none}

/* shadows tuned for a dark ground */
body.app{--pf-shadow:0 1px 2px rgba(0,0,0,.3),0 10px 30px rgba(0,0,0,.28)}

/* dark-grey pass 2 — chains, not guesses:
   - .cat-panel lost its card surface when the charcoal commit was reverted;
     the finding rows were dark-on-dark (1.12). Card restored.
   - the checklist/replies headings sit on the ground between cards (their
     wrappers were stripped to transparent long ago) — ground ink.
   - .muted.cl-help: the .muted pairing was outranking the earlier fix. */
body[data-report] .cat-panel{background:var(--surface);border:1px solid #ececf0;
  border-radius:14px;padding:14px 16px}
body[data-report] .checklist-head h2,
body[data-report] #features-box > h2,body[data-report] #sections > h2,
body[data-report] #replies-box > h2{color:var(--ground-ink)}
body[data-report] #replies-count{color:var(--ground-muted)}
body[data-report] .muted.cl-help{color:var(--ground-muted)}

/* pass 3 — my own mono rule (body[data-report] #features-box h2 -> ink) wins
   on its id, and pass 2 used a > child combinator where the h2 is a
   grandchild. Same ids, deeper path, later in file. */
body[data-report] #features-box .checklist-head h2,
body[data-report] #replies-box .checklist-head h2,
body[data-report] #sections .checklist-head h2{color:var(--ground-ink)}

/* ═══════════════════════════ DIRECTORY HOME (31 Jul, Liam) ═════════════════
   "Doesn't need to be insightful — just a directory to the 6 tools, remove
   rounded corners." The scores/activity dashboard is gone from the template;
   the home page is two labelled rows of three cards, Create and Review.
   Square corners throughout this page — cards, icon chips, the go button. */
.content.mndir{max-width:1160px;padding-top:34px}
.dir-lab{font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ground-muted,#6a7078);margin:26px 0 12px}
.dir-lab:first-of-type{margin-top:6px}
.dir-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
@media(max-width:900px){.dir-grid{grid-template-columns:minmax(0,1fr)}}
.dir-card{display:flex;flex-direction:column;gap:8px;padding:24px;
  background:#fff;border:1px solid #ececf0;border-radius:0;
  text-decoration:none;color:inherit;transition:transform .16s;
  box-shadow:0 1px 2px rgba(0,0,0,.3),0 10px 30px rgba(0,0,0,.25)}
.dir-card:hover{transform:translateY(-3px)}
/* Liam's own icon tiles (31 Jul) — self-contained 200×200 SVGs with their own
   dark ground, served from /static/icons/. They replace the mn-ic glyph chips. */
.dir-ic{width:56px;height:56px;margin-bottom:6px}
.dir-card h3{font-size:20px;font-weight:800;letter-spacing:-.02em;color:#f2f4f6;margin:0}
.dir-card p{font-size:13.5px;color:#b6bdc6;line-height:1.5;margin:0;flex:1}
.dir-card .go{align-self:flex-start;margin-top:8px;font-size:13px;font-weight:700;
  color:var(--lime-ink);background:var(--lime);border-radius:0;padding:8px 14px}
.dir-card .go b{display:inline-block;transition:transform .15s}
.dir-card:hover .go b{transform:translateX(3px)}
.dir-card:focus-visible{outline:2px solid var(--lime);outline-offset:3px}
@media(prefers-reduced-motion:reduce){.dir-card,.dir-card .go b{transition:none}}

/* ═══════════════ DIRECTORY HOME, DEPTH PASS (31 Jul, Liam: "do everything") ═
   The flat-fix critique applied in one go: masthead, ground glow, card light,
   filled card layout (text left / art right), quiet buttons that go lime on
   card hover. The icon SVGs lost their baked-in dark tiles — art sits straight
   on the card now. */

/* masthead: centred under the rail so nav → greeting → cards read as one
   column (it hung off the left edge before, orphaned between two centred
   systems) */
.dir-mast{display:block;text-align:center;margin:4px 0 34px}
.dir-mast h1{font-size:38px;font-weight:800;letter-spacing:-.03em;
  color:var(--ground-ink,#f2f4f6)}
.dir-mast p{margin:6px 0 0;font-size:15.5px;color:var(--ground-muted,#b6bdc6)}
/* section labels join the centred column */
.content.mndir .dir-lab{text-align:center}

/* atmosphere: soft light pooling top-centre, edges falling darker */
body:has(.content.mndir){
  background:radial-gradient(1100px 600px at 50% -80px,#262a31 0%,#1e2126 55%,#1e2126 100%)}

/* cards: top-lit surface, real two-layer shadow for a dark ground, hover lifts
   and the shadow grows with it */
.dir-card{grid-template-columns:minmax(0,1fr) auto;grid-template-rows:auto auto 1fr;
  display:grid;grid-template-areas:"title ic" "desc ic" "go ic";
  column-gap:18px;padding:26px 28px;
  /* dock styling (Liam): same dark surface, hairline and shadow as the rail */
  background:rgba(43,46,53,.92);
  border:1px solid rgba(255,255,255,.22);
  box-shadow:0 18px 50px rgba(0,0,0,.28);
  transition:transform .18s ease,box-shadow .18s ease}
.dir-card:hover{transform:translateY(-4px);
  box-shadow:0 24px 60px rgba(0,0,0,.4)}
.dir-card h3{grid-area:title;align-self:start}
.dir-card p{grid-area:desc;flex:none;margin-top:6px}
.dir-card .go{grid-area:go;align-self:end;margin-top:18px}
/* art: big, right-hand column, no box around it */
.dir-ic{grid-area:ic;width:86px;height:86px;margin:0;align-self:start;
  justify-self:end;filter:drop-shadow(0 3px 6px rgba(20,24,10,.18));
  transition:transform .18s ease}
.dir-card:hover .dir-ic{transform:translateY(-2px) rotate(-2deg) scale(1.04)}

/* buttons: lime by default (Liam), brightening slightly when the card is
   engaged so hover still answers back */
.dir-card .go{background:var(--lime);color:var(--lime-ink);
  border:1px solid var(--lime);padding:8px 14px;
  transition:background .15s,border-color .15s}
.dir-card:hover .go,.dir-card:focus-visible .go{
  background:#b2e332;border-color:#b2e332}
@media(prefers-reduced-motion:reduce){.dir-card,.dir-ic{transition:none}
  .dir-card:hover{transform:none}
  .dir-card:hover .dir-ic{transform:none}}
/* Liam: slight rounding, nudged up from 4px */
.dir-card{border-radius:10px}
.dir-card .go{border-radius:7px}
@media(max-width:640px){.dir-mast h1{font-size:30px}.dir-ic{width:68px;height:68px}}

/* ═══════════════ DARK REPORT PAGES (31 Jul, Liam) ══════════════════════════
   The review pages join the home page's system: cards take the rail's dark
   surface, hairline and 10px radius; text flips white/muted-grey; lime stays
   on actions and links. body[data-report] covers all three channels. */
body[data-report] .card,body[data-report] .fset,body[data-report] .cat,
body[data-report] .reply-card,body[data-report] .cat-panel,
body[data-report] #gbp-switcher .card,
body[data-report] #gbp-switcher .summary,body[data-report] #gbp-switcher .gbp-hero,
body[data-report] #gbp-switcher .table,body[data-report] .setup .fset{
  background:rgba(43,46,53,.92);
  border:1px solid rgba(255,255,255,.22);border-radius:10px;
  box-shadow:0 18px 50px rgba(0,0,0,.28);
  color:#dfe3e8}

/* type on the dark cards */
body[data-report] #result h2,body[data-report] #gbp-switcher h2,
body[data-report] .fset h2,body[data-report] .card h2,
body[data-report] .fset h3,body[data-report] .card h3,
body[data-report] .fset b,body[data-report] .card b,
body[data-report] .num.tnum,body[data-report] .igm .num{color:#f2f4f6}
body[data-report] .muted,body[data-report] .cl-help,
body[data-report] .igm-k,body[data-report] .ord-k,
body[data-report] .secard-label{color:#b6bdc6}
body[data-report] .bullets li{color:#dfe3e8}
body[data-report] .fset a,body[data-report] .card a{color:#c3f53c}

/* score rings on dark: white numeral, lime arc over a faint track */
body[data-report] :is(.ring.s-bad,.ring.s-warn,.ring.s-good){
  background:conic-gradient(#c3f53c calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] :is(.ring.s-bad,.ring.s-warn,.ring.s-good) b,
body[data-report] .ring.s-none b{color:#f2f4f6}
body[data-report] .ring.s-none{
  background:conic-gradient(rgba(255,255,255,.15) 100%,rgba(255,255,255,.15) 0)}
body[data-report] .ring::after,body[data-report] .score-ring::after{
  background:#2f323b}
body[data-report] .score-ring span{color:#f2f4f6}

/* inputs and quiet buttons on the dark cards */
body[data-report] input,body[data-report] select,body[data-report] textarea{
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.22);
  color:#f2f4f6;border-radius:7px}
body[data-report] input::placeholder{color:#8a919b}
body[data-report] .btn:not(.accent):not(.btn-primary){
  background:rgba(255,255,255,.08);color:#f2f4f6;
  border:1px solid rgba(255,255,255,.25)}

/* tables and separators */
body[data-report] td,body[data-report] th{border-color:rgba(255,255,255,.12)}
body[data-report] hr{border-color:rgba(255,255,255,.12)}

/* ═══════════ DARK REPORT, TOKEN FLIP (31 Jul, Liam: "everything") ══════════
   The per-component pass above missed most of the audit page — the right move
   is to flip the design tokens themselves, so every component that reads
   --surface/--ink/--line inherits the dark system without being named. */
body[data-report]{
  --surface:#31343c;--surface-2:#3a3e46;--sidebar:#2b2e35;
  --ink:#f2f4f6;--ink-soft:#d7dbe0;--muted:#b6bdc6;--faint:#7d838d;
  --line:rgba(255,255,255,.16);--line-soft:rgba(255,255,255,.10);
  --rule:#c3f53c;
  --accent:#c3f53c;--accent-ink:#c3f53c;--accent-tint:rgba(195,245,60,.14);
  --ok:#9ad462;--warn-text:#ffc250;--bad-text:#ff8a80;
  --good-soft:rgba(154,212,98,.16);--warn-soft:rgba(255,194,80,.14);
  --ring:rgba(195,245,60,.45);
  --r-lg:10px;--r:8px;--r-sm:6px;
  --sh-sm:0 1px 2px rgba(0,0,0,.35);
  --sh:0 2px 4px rgba(0,0,0,.3),0 12px 30px rgba(0,0,0,.3);
  --sh-lg:0 18px 50px rgba(0,0,0,.4)}
/* the earlier explicit-white card chrome yields to the tokens */
body[data-report] .card,body[data-report] .fset,body[data-report] .cat,
body[data-report] .reply-card,body[data-report] .cat-panel,
body[data-report] #gbp-switcher .card{
  background:var(--surface);border:1px solid rgba(255,255,255,.22);
  border-radius:10px}
/* the "on this page" section nav joins the system */
body[data-report] .report-nav,body[data-report] .report-key{
  background:#2b2e35;border:1px solid rgba(255,255,255,.16);border-radius:10px}
/* black-on-white chips invert (e.g. DIRECT · COMMISSION-FREE) */
body[data-report] .ord-flag{background:#f2f4f6;color:#1a1c21}

/* ── GBP switcher: the scoped light palette re-pointed dark ─────────────────
   #gbp-switcher carries its own token block (id specificity), so the
   body[data-report] flip above never reached this subtree — which is why the
   locations table stayed white. Same dark values, restated at id+attribute
   specificity so they win. */
body[data-report] #gbp-switcher{
  --surface:#31343c;--line:rgba(255,255,255,.16);--line-soft:rgba(255,255,255,.10);
  --ink:#f2f4f6;--muted:#b6bdc6;--faint:#8a919b;
  --accent:#c3f53c;--accent-ink:#c3f53c;--accent-2:#d7dbe0;
  --accent-3:rgba(255,255,255,.25);--accent-soft:rgba(195,245,60,.14);
  --good:#9ad462;--good-soft:rgba(154,212,98,.16);
  --warn:#ffc250;--warn-text:#ffc250;--warn-soft:rgba(255,194,80,.14);
  --bad:#ff8a80;--bad-soft:rgba(255,138,128,.16);
  --star:#ffd75e;--track:rgba(255,255,255,.15)}
/* literals in the subtree that bypass tokens */
body[data-report] #gbp-switcher .runhint{background:var(--surface);
  border-color:rgba(255,255,255,.25);color:var(--ink)}
body[data-report] #gbp-switcher .row:hover .runhint{border-color:rgba(255,255,255,.45)}
body[data-report] #gbp-switcher .ol-unread{border-color:rgba(255,194,80,.4)}
body[data-report] #gbp-switcher .notscored{color:var(--muted)}
/* provider logo tiles keep their white chip so the logos stay legible */

/* ── GBP: the literal #fcfbfd whites that dodge the tokens ──────────────────
   Table shell, column-head strip, sort pills and the ring inner discs were
   painted with hardcoded near-white, not var(--surface) — the token flip
   could not reach them. Restated dark, same specificity+later so they win. */
body[data-report] #gbp-switcher .tbl-controls,
body[data-report] #gbp-switcher .table{background:var(--surface)}
body[data-report] #gbp-switcher .colhead{background:#2b2e35;
  border-bottom:1px solid rgba(255,255,255,.14)}
body[data-report] #gbp-switcher .sort{background:rgba(255,255,255,.08)}
body[data-report] #gbp-switcher .sort button{color:var(--muted)}
body[data-report] #gbp-switcher .sort button.on{background:#c3f53c;color:#1a2400;
  box-shadow:none}
/* ring inner disc + white numeral circle */
body[data-report] #gbp-switcher .ring::before{background:var(--surface)}
body[data-report] #gbp-switcher .ring b{color:var(--ink)}
/* provider mini-pills: keep a light chip behind the brand logos, but calm the
   glow so it reads as a badge, not a hole */
body[data-report] .miniprov img{box-shadow:0 0 0 1px rgba(0,0,0,.2)}
body[data-report] #gbp-switcher .avg-inline{background:var(--surface);
  box-shadow:none}

/* ── report cards proper: the "Airbnb white card" chrome flipped dark ───────
   style.css paints the report's top-level cards with literal #fcfbfd at
   child-combinator specificity, which beat the generic dark card rule — the
   whole "Your website" card stayed white while its text went white. Same
   selectors, dark values. */
body[data-report] .report-main > .fset,
body[data-report] .report-main > .hero,
body[data-report] .report-main > .breakdown-card,
body[data-report] .report-main > #ordering > .fset,
body[data-report] .report-main > #changes > .fset{
  background:var(--surface);border:1px solid rgba(255,255,255,.22);
  box-shadow:0 18px 50px rgba(0,0,0,.28)}
/* the section-header pills keep their tint idea, dark-compatible */
body[data-report] .report-main h2,
body[data-report] .report-main .cl-head .t,
body[data-report] .report-main .shead .t{background:var(--surface-2);color:var(--ink)}
body[data-report] #rep-checklist .cl-head .t,
body[data-report] #sections .shead .t{background:rgba(195,245,60,.14);color:#c3f53c}
body[data-report] #features-box h2{background:rgba(255,194,80,.14);color:#ffc250}
body[data-report] #changes h2,body[data-report] #replies-box h2{
  background:var(--surface-2);color:var(--ink)}
/* order-link tiles and grouped blocks inside the cards */
body[data-report] .ord-block,body[data-report] .eb-row,body[data-report] .cg{
  background:var(--surface-2);border-color:rgba(255,255,255,.14)}
body[data-report] .eb-row:hover{background:#454952;border-color:rgba(255,255,255,.25)}
body[data-report] .ord-none{background:rgba(255,138,128,.14)}
body[data-report] .fnd-issue .fnd-i{background:rgba(255,138,128,.16);color:#ff8a80}
body[data-report] .igm-warn .igm-tag{background:rgba(255,194,80,.14);color:#ffc250}
body[data-report] .igm-bad .igm-tag{background:rgba(255,138,128,.16);color:#ff8a80}
body[data-report] .igm-good .igm-tag{background:rgba(154,212,98,.16);color:#9ad462}
/* NEEDS WORK band chip + page ground (style.css sets both to light literals) */
body[data-report]{background:#1e2126}
body[data-report] .pagehead{background:transparent;border-bottom:0}
body[data-report] .band,body[data-report] .rp-band{border-color:rgba(255,255,255,.2)}

/* ── last light stragglers on the reports (from the headless screenshot) ────
   Score-ring inner disc, brand-tinted order-link tiles (color-mix against
   literal #fcfbfd), and the category tabs' active fill. */
body[data-report] .hm-ring::before,body[data-report] .pv-ring::before,
body[data-report] .score-ring::before,
body[data-report] .cat-tab .ring::before{background:var(--surface)}
body[data-report] .score-ring{background-color:var(--surface)}
body[data-report] .ord-prov{
  background:color-mix(in srgb,var(--brand,#6f6980) 14%,#31343c);
  border-color:color-mix(in srgb,var(--brand,#6f6980) 35%,#31343c)}
body[data-report] a.ord-prov:hover{
  border-color:color-mix(in srgb,var(--brand) 55%,#31343c)}
body[data-report] .ord-prov-logo{background:#f2f4f6;border-color:rgba(0,0,0,.2)}
body[data-report] .cat-tab.active{background:var(--surface-2)}


/* the summary-hero ring: inner disc and numeral were literal near-white */
body[data-report] .sh-ring::before{background:var(--surface)}
body[data-report] .sh-ring b{color:var(--ink)}
body[data-report] .sh-ring.s-good{background:conic-gradient(#9ad462 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] .sh-ring.s-warn{background:conic-gradient(#ffc250 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] .sh-ring.s-bad{background:conic-gradient(#ff8a80 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] .sh-band.s-good{color:#9ad462}
body[data-report] .sh-band.s-warn{color:#ffc250}
body[data-report] .sh-band.s-bad{color:#ff8a80}

/* review pages match the home page's 1160px measure (they ran at 1440) */
body[data-report] .content,body[data-report] .content.narrow,
body[data-report] .pagehead{max-width:1160px;margin-left:auto;margin-right:auto}

/* ═══════════════ HONEY BASIL (31 Jul, Liam) ════════════════════════════════
   Display face from Liam's font bundle, served locally. It goes on the
   dashboard's display moments — masthead, card titles, section labels, page
   titles — while Inter keeps the body text and controls readable. */
@font-face{
  font-family:'Honey Basil';
  src:url('/static/fonts/HoneyBasil-Regular.otf') format('opentype'),
      url('/static/fonts/HoneyBasil-Regular.ttf') format('truetype');
  font-weight:normal;font-style:normal;font-display:swap}
.dir-mast h1{font-family:'Honey Basil',var(--display);font-weight:400;
  font-size:52px;letter-spacing:.01em}
.dir-mast p{font-size:16px}
.dir-card h3{font-family:'Honey Basil',var(--display);font-weight:400;
  font-size:26px;letter-spacing:.01em}
.ph-title h1{font-family:'Honey Basil',var(--display);font-weight:400;
  letter-spacing:.01em}

/* ═══════════ REVIEW PAGES, HOME-PAGE LANGUAGE (31 Jul, Liam) ═══════════════
   "Redesign the review pages to look like the home page." The moves that make
   the home page: Honey Basil display titles, a centred masthead, quiet dark
   cards, lime actions. Applied here. */

/* page head becomes a centred masthead like Ottolenghi's */
body[data-report] .pagehead{display:block;text-align:center;padding-top:6px}
body[data-report] .ph-title h1{font-size:40px}
body[data-report] .ph-title p{font-size:15.5px;margin-top:6px}
body[data-report] .ph-actions{margin-top:14px;display:flex;justify-content:center}
body[data-report] .ph-actions .btn,body[data-report] #rerun{
  background:var(--lime,#c3f53c)!important;color:#1a2400!important;
  border:1px solid var(--lime,#c3f53c)!important;border-radius:7px;
  font-weight:700}
body[data-report] .ph-actions .btn:hover,body[data-report] #rerun:hover{
  background:#b2e332!important;border-color:#b2e332!important}

/* card titles: the ClickUp pills give way to Honey Basil display type,
   exactly like the six home cards */
body[data-report] .report-main h2,
body[data-report] .report-main .cl-head .t,
body[data-report] .report-main .shead .t,
body[data-report] #result h2,body[data-report] #gbp-switcher h2,
body[data-report] .sh-title{
  font-family:'Honey Basil',var(--display);font-weight:400;
  font-size:22px;letter-spacing:.02em;line-height:1.15;
  background:none;padding:0;border-radius:0;color:#f2f4f6;
  text-transform:none;display:block}
body[data-report] #rep-checklist .cl-head .t,
body[data-report] #sections .shead .t,
body[data-report] #features-box h2,
body[data-report] #changes h2,body[data-report] #replies-box h2{
  background:none;color:#f2f4f6}
/* small uppercase labels inside cards become the home page's quiet eyebrows */
body[data-report] .ord-k,body[data-report] .igm-k{
  letter-spacing:.09em;text-transform:uppercase;font-size:11.5px}

/* the "on this page" bar matches the rail panel's rounding */
body[data-report] .report-key{border-radius:14px}

/* the "on this page" bar no longer follows the scroll (Liam) */
body[data-report] .report-key{position:static;top:auto}

/* ── report head spacing + the quick-jump bar as a button row (Liam) ────────
   More air under the nav; Re-run sits INSIDE the "on this page" bar, right-
   aligned; the jump links dress like quiet buttons (the lime one is Re-run). */
body[data-report] .pagehead{padding-top:44px}
body[data-report] .report-key{padding:10px 12px;gap:8px}
body[data-report] .report-key a{
  border:1px solid rgba(255,255,255,.22);border-radius:7px;
  padding:8px 14px;font-weight:700;color:#dfe3e8;background:transparent}
body[data-report] .report-key a:hover{border-color:#c3f53c;color:#c3f53c;
  background:rgba(195,245,60,.10)}
body[data-report] .report-key a.active{background:#c3f53c;border-color:#c3f53c;
  color:#1a2400}
body[data-report] .report-key #rerun{margin-left:auto}
@media(max-width:700px){body[data-report] .report-key #rerun{margin-left:0}}

/* subtitle joins the centred masthead (it was hugging the left edge — the
   pagehead's flex layout survived the text-align) */
body[data-report] .pagehead,body[data-report] .ph-title{display:block;text-align:center}
body[data-report] .ph-title p{margin-left:auto;margin-right:auto;max-width:60ch}

/* ── summary hero, layout + design pass (Liam) ──────────────────────────────
   The ord-block wrapper had inherited a filled background from the dark
   sweep, painting a stray band behind the order links — it goes transparent;
   only the provider tiles themselves are surfaces. Band chips move to the
   translucent on-dark family; the summary reads bigger with a tighter
   measure; the ordering strip loses its hard top border for a quiet one. */
body[data-report] .ord-block{background:transparent;border:0;padding:0}
body[data-report] .sh-body{gap:44px;padding-top:26px}
body[data-report] .sh-side{width:170px}
body[data-report] .sh-sum{font-size:16px;line-height:1.7;max-width:62ch;color:#dfe3e8}
body[data-report] .sh-band{padding:5px 14px;border-radius:7px}
body[data-report] .sh-band.s-bad{background:rgba(255,138,128,.16);color:#ff8a80}
body[data-report] .sh-band.s-warn{background:rgba(255,194,80,.16);color:#ffc250}
body[data-report] .sh-band.s-good{background:rgba(154,212,98,.16);color:#9ad462}
body[data-report] .sh-ordering:not(:empty){margin-top:24px;padding-top:22px;
  border-top:1px solid rgba(255,255,255,.10)}
body[data-report] .ord-k{margin-bottom:10px}
body[data-report] .ord-provs{gap:12px}
body[data-report] .ord-prov{padding:14px 16px;border-radius:8px}
/* the service chips (delivery / pick-up) in the on-dark accent language */
body[data-report] .ord-svc{background:rgba(195,245,60,.12);color:#c3f53c;
  border-color:rgba(195,245,60,.3)}
body[data-report] .ord-svc::before{background:#c3f53c}
/* "First review" sits closer to its chip */
body[data-report] .sh-delta{margin-top:4px!important}

/* hero, round 2 (Liam: "does it look fixed?") — no. (1) the score numeral had
   escaped the ring: pin it dead-centre over the disc regardless of what the
   cascade does to the ring's layout mode. (2) the summary measure widens so
   the card's right side stops reading as dead space. */
body[data-report] .sh-ring{position:relative;display:grid;place-items:center}
body[data-report] .sh-ring b{position:absolute;inset:0;display:grid;
  place-items:center;margin:0;padding:0;line-height:1}
body[data-report] .sh-sum{max-width:74ch}

/* action plan runs full width (Liam) — the "what's already working" card
   that shared its row drops below it, also full width */
@media(min-width:901px){
  body[data-report] #rep-checklist{grid-column:span 12}
  body[data-report] .report-main .fset.strengths-d{grid-column:span 12}
}

/* ── completeness in two columns; strengths card retired (Liam) ─────────────
   The done/needs lists ran as one long single column. Each group's items now
   flow in a 2-col grid (single col again under 900px). "What's already
   working" is gone — the action plan already carries the story. */
body[data-report] .report-main .fset.strengths-d{display:none}
body[data-report] .feat-group{display:block}
body[data-report] .feat-group .feat-grouphd{margin-bottom:10px}
@media(min-width:901px){
  body[data-report] .feat-group{display:grid;
    grid-template-columns:1fr 1fr;column-gap:36px;row-gap:2px}
  body[data-report] .feat-group .feat-grouphd{grid-column:1/-1}
}
/* the done items live in an inner .feat-on-list wrapper — grid THAT */
@media(min-width:901px){
  body[data-report] .feat-on-list{display:grid;
    grid-template-columns:1fr 1fr;column-gap:36px;row-gap:6px}
}

/* ═══════════ HOME: CREATE vs REVIEW differentiated (31 Jul, Liam) ══════════
   Review cards are mini scorecards: the nav's ring, bigger, with the number
   inside and the band word beneath, where the icon used to float. Their
   buttons go quiet (lime only on hover / label flips to "Fix it" when red).
   Create keeps the loud lime CTAs and grows its illustrations ~20%. The
   section eyebrows take Honey Basil so they stop reading as form labels. */
.dir-lab{font-family:'Honey Basil',var(--display);font-weight:400;
  font-size:16px;letter-spacing:.08em;color:#d7dbe0}
.dir-ic{width:104px;height:104px}
.dir-review .dir-side{grid-area:ic;justify-self:end;align-self:start;
  display:flex;flex-direction:column;align-items:center;gap:7px}
.dir-score{position:relative;width:92px;height:92px;display:block}
.dir-score svg{position:absolute;inset:0;width:100%;height:100%}
.dir-score b{position:absolute;inset:0;display:grid;place-items:center;
  font-size:27px;font-weight:800;letter-spacing:-.02em;color:#f2f4f6}
.dir-band{font-size:11.5px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:#8a919b}
.dir-band.b-bad{color:#e25555}
.dir-band.b-warn{color:#e8963c}
.dir-band.b-good{color:#c3f53c}
/* review buttons back to lime like Create's (Liam) */
.dir-review:hover .go,.dir-review:focus-visible .go{
  background:var(--lime,#c3f53c);border-color:var(--lime,#c3f53c);color:#1a2400}

/* ═══════════ HOME: INSIGHTS ROW (31 Jul, Liam) ═════════════════════════════
   Third section: the week's activity (real event counts, tiny bar chart) and
   up to two prioritised actions from this_week_actions — an ordering gap, the
   weakest channel's top fix, or the next UK calendar moment. */
.ins-kind{font-size:11.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:#c3f53c;margin-bottom:2px}
.dir-insight h3{font-size:22px}
.ins-bars{display:flex;align-items:flex-end;gap:10px;height:84px;
  grid-area:ic;justify-self:end;align-self:end;margin-top:10px}
.ins-col{display:flex;flex-direction:column;align-items:center;gap:5px;
  height:100%;justify-content:flex-end}
.ins-col i{display:block;width:14px;border-radius:3px 3px 0 0;
  background:#c3f53c;min-height:3px}
.ins-col em{font-style:normal;font-size:10px;font-weight:600;color:#8a919b}
.dir-insight{grid-template-areas:"kind kind" "title ic" "desc ic" "go ic";
  grid-template-rows:auto auto auto 1fr}
.dir-insight .ins-kind{grid-area:kind;margin-bottom:8px}

/* ── insights v2 (Liam's spec): links per channel · gap · channel numbers ── */
.ol-rows,.ov-rows{grid-column:1/-1;display:flex;flex-direction:column;
  gap:12px;margin-top:12px}
.ol-row,.ov-row{display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;border-top:1px solid rgba(255,255,255,.10);padding-top:12px}
.ol-ch,.ov-ch{font-size:13px;font-weight:700;color:#dfe3e8;flex:none}
.ol-provs{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}
.ol-prov{font-size:12px;font-weight:700;padding:4px 10px;border-radius:6px;
  background:rgba(255,255,255,.08);color:#dfe3e8;
  border:1px solid rgba(255,255,255,.18)}
.ol-prov.direct{background:rgba(195,245,60,.14);color:#c3f53c;
  border-color:rgba(195,245,60,.35)}
.ol-nope{font-size:12px;font-weight:700;color:#ff8a80}
.ov-stats{display:flex;gap:22px}
.ov-stat{display:flex;flex-direction:column;align-items:flex-end;gap:2px}
.ov-stat b{font-size:20px;font-weight:800;letter-spacing:-.02em;color:#f2f4f6}
.ov-stat em{font-style:normal;font-size:11px;font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;color:#8a919b}

/* ── insights first + lime section separators + two-row layout (Liam) ───────
   Row 1: "where people can order" full width, channels side by side.
   Row 2: ordering gap + channel numbers. Lime hairlines between sections. */
.dir-sep{border:0;height:2px;background:#c3f53c;opacity:.55;
  border-radius:2px;margin:34px auto 8px;max-width:1160px}
.dir-grid-1{grid-template-columns:1fr}
.dir-grid-2{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:18px}
@media(max-width:900px){.dir-grid-2{grid-template-columns:minmax(0,1fr)}}
/* full-width card: the three channels sit side by side as columns */
/* Was flex-direction:row - three channels as side-by-side columns. The rows are
   now full-width (channel · identifier · order links · review), so they stack. */
.dir-grid-1 .ol-provs{justify-content:flex-start}

/* channel glyphs + branded provider chips in Insights (Liam) */
.ol-ch,.ov-ch{display:inline-flex;align-items:center;gap:8px}
.ol-ic{width:17px;height:17px;color:#b6bdc6;flex:none}
.ol-prov{display:inline-flex;align-items:center;gap:7px}
/* No plate. The white disc behind each mark read as a card stuck on the chip,
   which is worse than a logo that sits slightly quiet. The chip already carries
   the provider's brand tint, so the name and colour identify it either way. */
.ol-prov img{width:16px;height:16px;border-radius:3px;background:none;
  padding:0;box-shadow:none;object-fit:contain}
/* brand tint: the provider's own colour mixed into the dark chip */
.ol-prov[style]{background:color-mix(in srgb,var(--brand) 16%,#31343c);
  border-color:color-mix(in srgb,var(--brand) 45%,#31343c);color:#f2f4f6}
.ol-prov.direct[style]{background:color-mix(in srgb,var(--brand) 16%,#31343c);
  border-color:color-mix(in srgb,var(--brand) 55%,#31343c)}

/* the gap card's CTA hugs its label instead of spanning the card */
.dir-insight .go{justify-self:start;align-self:end}

/* ═══════════ REVIEW PAGES ADOPT THE HOME INSIGHTS STYLING (31 Jul) ═════════
   The home page is the reference now: lime uppercase eyebrows, Honey Basil
   card titles (already in place), compact brand-tinted provider chips with
   favicons, and big-numeral stats over quiet uppercase labels. */

/* eyebrow labels go lime, like ORDER LINKS FOUND / CHANNEL OVERVIEW */
body[data-report] .ord-k,body[data-report] .igm-k,
body[data-report] .feat-grouphd,body[data-report] .cl-progtxt{
  color:#c3f53c;font-weight:700;letter-spacing:.09em;text-transform:uppercase}
body[data-report] .glance-src{color:#b6bdc6;text-transform:none;
  letter-spacing:0;font-weight:400}
body[data-report] .feat-grouphd.needs{color:#ff8a80}
body[data-report] .feat-grouphd .n{background:rgba(255,255,255,.08);
  color:#dfe3e8;border-color:rgba(255,255,255,.18)}

/* provider tiles become the home page's compact branded chips */
body[data-report] .ord-prov{display:inline-flex;flex-direction:row;
  align-items:center;gap:8px;padding:7px 13px;border-radius:7px;width:auto}
body[data-report] .ord-provs{display:flex;flex-wrap:wrap;gap:8px}
body[data-report] .ord-prov-top{flex-direction:row;align-items:center;gap:8px}
body[data-report] .ord-prov-id{gap:8px}
body[data-report] .ord-prov-logo{width:17px;height:17px;border-radius:4px;
  padding:1px;background:#fff;box-shadow:0 0 0 1px rgba(0,0,0,.25);border:0}
body[data-report] .ord-prov-name{font-size:13px;font-weight:700}
body[data-report] .ord-prov-url{display:none}
body[data-report] .ord-prov-role{font-size:10px}

/* stats take the home page's numeral-over-label form */
body[data-report] .sh-stat b,body[data-report] .gh-stat b,
body[data-report] .igm .num{font-size:21px;font-weight:800;
  letter-spacing:-.02em;color:#f2f4f6}
body[data-report] .sh-stat span,body[data-report] .gh-stat span{
  font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:#8a919b}

/* the "None — no order link in bio" warning: on-dark red tint, readable text
   (it was old-palette purple body text on a light red wash) */
body[data-report] .ord-none{background:rgba(255,138,128,.12);
  border:1px solid rgba(255,138,128,.35);border-radius:8px;
  color:#dfe3e8;padding:14px 16px}
body[data-report] .ord-none b{color:#ff8a80}
body[data-report] .ord-note,body[data-report] .ord-note a{color:#b6bdc6}
body[data-report] .ord-note a{text-decoration-color:rgba(255,255,255,.3)}

/* ═══ COMPLETENESS, DEFINITIVE (Liam: "too thin, hard to read") ═════════════
   Final word over every earlier layer. Two columns of items; on-dark colours
   (the labels were #4a7a2e forest green on the dark card — near-invisible). */
body[data-report] .features,body[data-report] .feat-group{display:block!important}
body[data-report] .feat-on-list{display:flex!important;flex-wrap:wrap;
  column-gap:44px;margin-top:8px}
body[data-report] .feat-on-list .feat-on{flex:0 0 calc(50% - 22px);
  box-sizing:border-box}
@media(max-width:800px){
  body[data-report] .feat-on-list .feat-on{flex-basis:100%}
}
body[data-report] .feat-on{border-bottom:1px solid rgba(255,255,255,.08);
  padding:12px 0}
body[data-report] .feat-on i{background:#9ad462!important;color:#14210a}
body[data-report] .feat-on-l{color:#9ad462!important;font-size:14px}
body[data-report] .feat-on-d{color:#b6bdc6;font-size:12.5px}
/* needs-attention rows: same two-column flow, readable text */
body[data-report] .need-group{display:flex!important;flex-wrap:wrap;
  column-gap:44px}
body[data-report] .need-group .feat-grouphd{flex:1 1 100%}
body[data-report] .need-group .feat{flex:0 0 calc(50% - 22px);
  box-sizing:border-box}
@media(max-width:800px){
  body[data-report] .need-group .feat{flex-basis:100%}
}
body[data-report] .feat-label{color:#f2f4f6}
body[data-report] .feat-detail{color:#b6bdc6}
body[data-report] .feat.off .feat-mark{color:#ff8a80}
body[data-report] .feat.partial .feat-mark{color:#ffc250}

/* ── done + needs attention side by side (Liam) ─────────────────────────────
   The two groups become columns of one list each; the earlier two-column
   flow inside each group stands down. */
@media(min-width:901px){
  body[data-report] .features{display:flex!important;
    flex-direction:row!important;flex-wrap:nowrap;gap:36px;
    align-items:flex-start}
  body[data-report] .feat-group{flex:1 1 0;min-width:0}
  body[data-report] .feat-on-list{display:block!important}
  body[data-report] .feat-on-list .feat-on{width:100%}
  body[data-report] .need-group{display:block!important}
  body[data-report] .need-group .feat{width:100%}
  /* the needs column keeps its red spine */
  body[data-report] .need-group{border-left:3px solid rgba(255,138,128,.5);
    padding-left:18px}
}

/* the two completeness columns take the card rounding */
body[data-report] .feat-group{border-radius:10px;overflow:hidden}
body[data-report] .need-group{border-radius:10px}

/* ═══════════ CATEGORY BREAKDOWN → home-card language + 2×2 (Liam) ══════════
   The tab buttons become dark rounded cards in a 2-across grid: ring + name
   left, band word under; active card wears the lime edge. Panels join the
   dark system. */
body[data-report] .cat-tabs{grid-template-columns:repeat(2,minmax(0,1fr));
  gap:14px}
@media(max-width:640px){body[data-report] .cat-tabs{grid-template-columns:1fr}}
body[data-report] .cat-tab{background:var(--surface-2);
  border:1px solid rgba(255,255,255,.14);border-radius:10px;
  padding:16px 18px;cursor:pointer;transition:border-color .15s}
body[data-report] .cat-tab:hover{border-color:rgba(255,255,255,.35)}
body[data-report] .cat-tab.active{border-color:#c3f53c;background:var(--surface-2)}
body[data-report] .cat-tab.active::after{display:none}
body[data-report] .cat-tab .nm{font-size:15px;font-weight:700;color:#f2f4f6;
  text-transform:capitalize}
/* The verdict was uppercase, bold and amber on all four cards at once, which
   made every category look like a warning and shouted over the score. It is a
   description, so it now reads as one: sentence case, normal weight, muted.
   The band colour lives in the ring and the number, where one glance finds it. */
body[data-report] .cat-tab .vd{font-size:12px;font-weight:400;
  letter-spacing:0;text-transform:none;color:#b6bdc6;line-height:1.35}
body[data-report] .cat-tab .vd.good,
body[data-report] .cat-tab .vd.warn,
body[data-report] .cat-tab .vd.bad{color:#b6bdc6}
body[data-report] .cat-tab .ring b{color:#f2f4f6}
body[data-report] .cat-panel{color:#dfe3e8}
body[data-report] .cat-panel li{border-color:rgba(255,255,255,.08)}

/* ═══════════ SECTION EYEBROWS on the review cards (Liam) ═══════════════════
   Every big section opens like a home card: lime uppercase eyebrow above the
   Honey Basil title. */
body[data-report] .sh-head,body[data-report] .cl-head,
body[data-report] .checklist-head,body[data-report] #sections .shead{
  flex-wrap:wrap}
body[data-report] #rep-overview .sh-head::before,
body[data-report] #rep-checklist .cl-head::before,
body[data-report] #features-box .checklist-head::before,
body[data-report] #sections .shead::before,
body[data-report] #replies-box .checklist-head::before{
  display:block;flex:1 1 100%;margin-bottom:6px;
  font-family:var(--font);font-size:11.5px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:#c3f53c}
body[data-report] #rep-overview .sh-head::before{content:"Overview"}
body[data-report] #rep-checklist .cl-head::before{content:"Action plan"}
body[data-report] #features-box .checklist-head::before{content:"Completeness"}
body[data-report] #sections .shead::before{content:"Breakdown"}
body[data-report] #replies-box .checklist-head::before{content:"Reviews"}
/* grid here suffers the same phantom-track override as the checklists — flex it */
body[data-report] .cat-tabs{display:flex!important;flex-wrap:wrap;gap:14px}
body[data-report] .cat-tab{flex:0 0 calc(50% - 7px);box-sizing:border-box}
@media(max-width:640px){body[data-report] .cat-tab{flex-basis:100%}}

/* ═══════════ "AT A GLANCE" METRIC TILES, home language (Liam) ══════════════
   The 4-up grid was escaping its card (same phantom-track disease — flexed),
   and the icons wore pastel chips from the light era. Now: 2×2 tiles inside
   the card, bare outline glyphs in muted ink, big white numeral, lime label,
   band tags in the on-dark tints. */
body[data-report] .ig-metrics-grid{display:flex!important;flex-wrap:wrap;gap:12px}
body[data-report] .igm{flex:1 1 calc(50% - 6px);min-width:240px;
  box-sizing:border-box;background:var(--surface-2);
  border:1px solid rgba(255,255,255,.14);border-radius:10px;
  box-shadow:none;padding:16px 18px}
body[data-report] .igm-ic{background:none!important;width:auto;height:auto;
  color:#b6bdc6!important;border-radius:0}
body[data-report] .igm-ic svg{width:19px;height:19px}
body[data-report] .igm-v{color:#f2f4f6}
body[data-report] .igm-k{color:#c3f53c}
body[data-report] .igm-d{color:#b6bdc6}
body[data-report] .igm-tag{border-radius:6px}
/* the glance card runs full width; tiles sit four across (2×2 below 1100px) */
@media(min-width:901px){
  body[data-report] #ig-box,body[data-report] #comp-box{grid-column:span 12}
  body[data-report] .igm{flex:1 1 calc(25% - 9px);min-width:220px}
}

/* glance tiles: label first (eyebrow pattern) so all four align; values never
   wrap ("11.7 /mo" was two-lining and sinking its label) */
body[data-report] .igm{display:flex;flex-direction:column}
body[data-report] .igm-k{order:-1;margin-bottom:10px}
body[data-report] .igm-v{white-space:nowrap}
body[data-report] .igm-top{align-items:center}

/* ── completeness: "can't verify" stacks under "needs attention" (Liam) ─────
   Grid with explicit placement: done owns the left column full-height. */
@media(min-width:901px){
  body[data-report] .features{display:grid!important;
    grid-template-columns:1fr 1fr;grid-template-rows:auto 1fr;
    gap:24px 36px;align-items:start}
  body[data-report] .done-group{grid-column:1;grid-row:1 / span 2}
  body[data-report] .need-group{grid-column:2;grid-row:1}
  body[data-report] .verify-group{grid-column:2;grid-row:2}
}

/* ── ordering chips: one consistent size (Liam) ─────────────────────────────
   Full row width, fixed min-height, and the role badge stops changing the
   chip's geometry between providers. */
body[data-report] .ord-provs{flex-direction:row;flex-wrap:wrap;gap:10px}
body[data-report] .ord-prov{flex:0 0 calc(50% - 5px);width:auto;
  box-sizing:border-box;min-height:48px;padding:10px 14px}
@media(max-width:700px){body[data-report] .ord-prov{flex-basis:100%}}
body[data-report] .ord-prov-role{font-size:10px;line-height:1;
  padding:4px 8px;flex:none;white-space:nowrap}
body[data-report] .ord-prov-name{white-space:nowrap}

/* role badges can't ride the brand colour (black-on-black for Slerp):
   DIRECT wears the lime system badge, MARKETPLACE a neutral one */
body[data-report] .ord-prov-role.direct{background:#c3f53c!important;
  color:#1a2400!important}
body[data-report] .ord-prov-role.marketplace{
  background:rgba(255,255,255,.14)!important;color:#f2f4f6!important}

/* home "where people can order": chips take the review pages' sizing */
.dir-grid-1 .ol-prov{min-height:48px;padding:10px 14px;border-radius:8px;
  font-size:13px;background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.3);gap:9px}
.dir-grid-1 .ol-prov img{width:18px;height:18px}
.dir-grid-1 .ol-prov.direct{background:rgba(255,255,255,.07);
  border-color:rgba(255,255,255,.3);color:#f2f4f6}
.dir-grid-1 .ol-prov.direct::after{content:"";display:none}

/* ── home chips: brand colours back (sizing stays) ── */
.dir-grid-1 .ol-prov[style]{
  background:color-mix(in srgb,var(--brand) 18%,#31343c);
  border-color:color-mix(in srgb,var(--brand) 40%,#8a919b);color:#f2f4f6}

/* #features-box/#sections/#replies-box are transparent wrappers (titles sit
   on the ground) — but they inherited the dark card's drop shadow, which
   rendered as a ghost card floating behind them. No card, no shadow. */
body[data-report] #features-box,body[data-report] #sections,
body[data-report] #replies-box{box-shadow:none!important;
  background:transparent!important;border:0!important}

/* ── uniform section rhythm on the reports (Liam) ───────────────────────────
   One 28px gap between every section, owned by the grid alone; stray
   per-section margins that made some gaps read bigger are zeroed, and the
   ground-sitting section titles get one consistent inset. */
body[data-report] .report-main{row-gap:28px!important}
body[data-report] .report-main > *{margin-top:0!important;margin-bottom:0!important}
body[data-report] #features-box .checklist-head,
body[data-report] #replies-box .checklist-head,
body[data-report] #sections .shead{margin:4px 0 12px!important}
body[data-report] .report-main .cl-help{margin:0 0 16px}

/* stars read brighter on the dark ground (Liam) */
body[data-report]{--star:#ffd75e}
body[data-report] .reply-stars,body[data-report] .rate .star,
body[data-report] .c-rating .star,body[data-report] .gh-stat .star{
  color:#ffd75e!important}

/* ── category cards: squarer, one row (Liam) ────────────────────────────────
   Ring on top, name and verdict beneath, centred; flex 1 each so 3 categories
   fill a row of 3 and 4 fill a row of 4. */
body[data-report] .cat-tab{flex:1 1 0;min-width:0;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;gap:12px;
  padding:26px 18px;min-height:190px}
body[data-report] .cat-tab-meta{display:flex;flex-direction:column;
  align-items:center;gap:6px}
body[data-report] .cat-tab .nm{white-space:normal}
@media(max-width:900px){
  body[data-report] .cat-tab{flex:1 1 calc(50% - 7px);min-height:150px}
}

/* ── action plan: flat rows, not card-per-step (Liam) ───────────────────────
   Two old layers dressed every .cl-card as its own card; back to quiet rows
   separated by hairlines inside the one Action Plan card. */
body[data-report] .cl-card{background:none!important;border:0!important;
  border-bottom:1px solid rgba(255,255,255,.08)!important;border-radius:0!important;
  box-shadow:none!important;padding:15px 6px}
body[data-report] .cl-item:last-child .cl-card{border-bottom:0!important}
body[data-report] .cl-card:hover{background:rgba(255,255,255,.04)!important}

/* the findings panel's drop shadow painted a ghost of the TALLEST panel's
   height under shorter ones (the slider container reserves that room) —
   the panel keeps its surface and border, the shadow goes */
body[data-report] .cat-panel{box-shadow:none!important}

/* action plan: detail sits UNDER the title, not beside it (Liam) */
body[data-report] .cl-body{flex-direction:column;align-items:flex-start;gap:3px}
body[data-report] .cl-detail{flex:none;width:100%}

/* action rows: text column left, chips centred on the right (Liam) */
body[data-report] .cl-body{display:grid!important;
  grid-template-columns:minmax(0,1fr) auto;
  grid-template-areas:"pill chips" "title chips" "detail chips";
  align-items:center;column-gap:20px;row-gap:3px}
body[data-report] .cl-startpill{grid-area:pill;justify-self:start}
body[data-report] .cl-action{grid-area:title}
body[data-report] .cl-detail{grid-area:detail;width:auto}
body[data-report] .cl-chips{grid-area:chips;align-self:center;
  display:flex;gap:8px;margin:0}

/* ── GBP list header polish (Liam) ──────────────────────────────────────────
   1. Re-run all sits in the All-locations row (adopted by JS).
   2. The average-score ring takes its band colour like every other ring.
   3. "All locations" goes Honey Basil, and the controls row loses the card
      background that welded it to the sort pills. */
body[data-report] #gbp-switcher .tbl-controls{background:transparent;
  border:0;box-shadow:none;padding:6px 2px}
body[data-report] #gbp-switcher .tbl-controls-l{
  font-family:'Honey Basil',var(--display);font-weight:400;font-size:22px;
  letter-spacing:.02em;color:#f2f4f6}
body[data-report] .tbl-rerun-slot{margin-left:auto;margin-right:12px}
body[data-report] .tbl-rerun-slot #rerun{margin:0}
/* band-coloured hero ring */
body[data-report] #gbp-switcher .gh-ring.s-good{
  background:conic-gradient(#9ad462 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] #gbp-switcher .gh-ring.s-warn{
  background:conic-gradient(#ffc250 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] #gbp-switcher .gh-ring.s-bad{
  background:conic-gradient(#ff8a80 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}

/* "None found" on the home order-links card dresses as a chip like the
   platforms, in the red state */
.dir-grid-1 .ol-nope{display:inline-flex;align-items:center;gap:9px;
  min-height:48px;padding:10px 14px;border-radius:8px;font-size:13px;
  background:rgba(255,138,128,.10);border:1px solid rgba(255,138,128,.4);
  color:#ff8a80}
.dir-grid-1 .ol-nope::before{content:"✕";font-size:13px;font-weight:700}

/* Not connected — same chip shape, but lime and clickable rather than red.
   A channel we cannot read has not failed; it is waiting on a connection, and
   dressing it as a failure blames the restaurant for our missing plumbing. */
.ol-connect{display:inline-flex;align-items:center;gap:8px;min-height:48px;
  padding:10px 14px;border-radius:8px;font-size:13px;font-weight:700;
  text-decoration:none;background:rgba(195,245,60,.10);
  border:1px solid rgba(195,245,60,.45);color:var(--lime,#c3f53c);
  transition:background .15s,border-color .15s,transform .12s}
.ol-connect:hover{background:rgba(195,245,60,.18);
  border-color:var(--lime,#c3f53c);transform:translateY(-1px)}
.ol-connect::before{content:"+";font-size:15px;font-weight:700;line-height:1}

/* Waiting on us, not on them. Deliberately inert: no link, no red, no plus -
   there is nothing here for the restaurant to do. */
.ol-soon{display:inline-flex;align-items:center;gap:8px;min-height:48px;
  padding:10px 14px;border-radius:8px;font-size:13px;font-weight:600;
  background:rgba(255,255,255,.05);border:1px dashed rgba(255,255,255,.22);
  color:var(--muted,#b6bdc6);cursor:default}
.ol-soon::before{content:"…";font-size:15px;font-weight:700;line-height:1}

/* re-run all lives in the GBP hero card now (Liam) */
body[data-report] #gbp-switcher .gbp-hero{grid-template-columns:auto 1fr auto auto;
  gap:22px}
body[data-report] .gbp-hero .tbl-rerun-slot{margin:0;align-self:center}

/* ═══════════ GBP HERO v2 (31 Jul, Liam's mock) ═════════════════════════════
   Ring left; title with coverage; stacked band bar + legend; worst/best
   callout chips; inner stats bar with Re-run all. */
body[data-report] #gbp-switcher .gbp-hero.gh2{display:flex;align-items:flex-start;
  gap:30px;grid-template-columns:none}
body[data-report] .gh2 .gh-main{flex:1;min-width:0;display:flex;
  flex-direction:column;gap:12px}
body[data-report] .gh2 .gh-title{font-size:19px}
body[data-report] .gh2 .gh-title span{color:#8a919b;font-weight:500}
body[data-report] .gh-seg{display:flex;height:9px;border-radius:6px;
  overflow:hidden;background:rgba(255,255,255,.10)}
body[data-report] .gh-seg i{display:block;height:100%}
body[data-report] .gh-seg i.g{background:#9ad462}
body[data-report] .gh-seg i.w{background:#ffc250}
body[data-report] .gh-seg i.b{background:#ff8a80}
body[data-report] .gh-seg i.p{background:rgba(255,255,255,.16)}
body[data-report] .gh-legend{display:flex;gap:20px;flex-wrap:wrap;
  font-size:13px;color:#dfe3e8}
body[data-report] .gh-leg{display:inline-flex;align-items:center;gap:7px}
body[data-report] .gh-leg.zero{color:#8a919b}
body[data-report] .gh-leg i{width:8px;height:8px;border-radius:50%;display:block}
body[data-report] .gh-leg i.g{background:#9ad462}
body[data-report] .gh-leg i.w{background:#ffc250}
body[data-report] .gh-leg i.b{background:#ff8a80}
body[data-report] .gh-leg i.p{background:rgba(255,255,255,.3)}
body[data-report] .gh-callouts{display:flex;gap:12px;flex-wrap:wrap}
body[data-report] .gh-callout{display:inline-flex;align-items:baseline;gap:8px;
  padding:9px 14px;border-radius:9px;font-size:13.5px;color:#b6bdc6}
body[data-report] .gh-callout b{font-weight:700}
body[data-report] .gh-callout em{font-style:normal;font-weight:800}
body[data-report] .gh-callout.bad{background:rgba(255,138,128,.10);
  border:1px solid rgba(255,138,128,.3)}
body[data-report] .gh-callout.bad b,body[data-report] .gh-callout.bad em{color:#ff8a80}
body[data-report] .gh-callout.good{background:rgba(154,212,98,.10);
  border:1px solid rgba(154,212,98,.3)}
body[data-report] .gh-callout.good b,body[data-report] .gh-callout.good em{color:#9ad462}
body[data-report] .gh-statsbar{display:flex;align-items:center;gap:34px;
  margin-top:4px;padding:16px 20px;border-radius:12px;
  background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.10)}
body[data-report] .gh-statsbar .gh-stat b{font-size:22px;color:#f2f4f6}
body[data-report] .gh-statsbar .gh-stat b.att{color:#ff8a80}
body[data-report] .gh-statsbar .gh-stat span{display:block;font-size:10.5px;
  font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#8a919b}
body[data-report] .gh-statsbar .tbl-rerun-slot{margin-left:auto}
@media(max-width:800px){
  body[data-report] #gbp-switcher .gbp-hero.gh2{flex-direction:column}
  body[data-report] .gh-statsbar{flex-wrap:wrap;gap:18px}
}

/* stats move to the hero's right side, stacked with the button (Liam) */
body[data-report] .gh2 .gh-statsbar{flex-direction:column;align-items:stretch;
  gap:16px;margin-top:0;padding:18px 22px;min-width:190px;flex:none;
  align-self:stretch;justify-content:center}
body[data-report] .gh2 .gh-statsbar .gh-stat{display:flex;align-items:baseline;
  justify-content:space-between;gap:14px}
body[data-report] .gh2 .gh-statsbar .gh-stat b{font-size:20px}
body[data-report] .gh2 .gh-statsbar .gh-stat span{display:inline}
body[data-report] .gh2 .gh-statsbar .tbl-rerun-slot{margin:4px 0 0}
body[data-report] .gh2 .gh-statsbar #rerun{width:100%}


/* location completeness bars: capped width (they ran edge to edge) */
body[data-report] #gbp-switcher .comp .bar{flex:0 1 150px;max-width:150px}

/* bigger score + re-run beneath it (Liam) */
body[data-report] .gh2 .gh-ring{width:112px;height:112px}
body[data-report] .gh2 .gh-ring::before{inset:8px}
body[data-report] .gh2 .gh-ring b{font-size:34px}
body[data-report] .gh2 .gh-bandlbl{font-size:12.5px}
body[data-report] .gh2 .gh-score{gap:10px}
body[data-report] .gh2 .gh-score .tbl-rerun-slot{margin:6px 0 0}
body[data-report] .gh2 .gh-score #rerun{white-space:nowrap}
body[data-report] #gbp-switcher .gh2 .gh-ring{width:112px;height:112px}
body[data-report] #gbp-switcher .gh2 .gh-ring::before{inset:8px}
body[data-report] #gbp-switcher .gh2 .gh-ring b{font-size:34px}

/* stats panel rows align on two clean columns: numerals right-aligned in a
   fixed column, labels left-aligned beside them */
body[data-report] .gh2 .gh-statsbar .gh-stat{display:grid;
  grid-template-columns:86px 1fr;align-items:baseline;column-gap:14px;
  justify-content:start}
body[data-report] .gh2 .gh-statsbar .gh-stat b{text-align:right;
  font-variant-numeric:tabular-nums}
body[data-report] .gh2 .gh-statsbar .gh-stat span{text-align:left}

/* stats panel retired — the re-run button holds the hero's right edge */
body[data-report] .gh2 .gh-rerun-right{align-self:center;flex:none}

/* locations table joins the home card language: dark hover, soft hairlines */
body[data-report] #gbp-switcher .row:hover,
body[data-report] #gbp-switcher .row:focus-visible{
  background:rgba(255,255,255,.05)!important}
body[data-report] #gbp-switcher .row{
  border-bottom:1px solid rgba(255,255,255,.08)!important}
body[data-report] #gbp-switcher .row:last-child{border-bottom:0!important}
body[data-report] #gbp-switcher .tbl{border:1px solid rgba(255,255,255,.22);
  border-radius:10px}

/* ── locations table reads like the action plan (Liam) ──────────────────────
   Band words under the rings go — the ring colour carries the band now.
   Header band flattens to lime eyebrow labels on the ground; rows stay flat
   hairline rows. */
body[data-report] #gbp-switcher .ring-band{display:none}
body[data-report] #gbp-switcher .row .ring.s-good{
  background:conic-gradient(#9ad462 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] #gbp-switcher .row .ring.s-warn{
  background:conic-gradient(#ffc250 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] #gbp-switcher .row .ring.s-bad{
  background:conic-gradient(#ff8a80 calc(var(--p)*1%),rgba(255,255,255,.15) 0)}
body[data-report] #gbp-switcher .colhead{background:transparent!important;
  border-bottom:1px solid rgba(255,255,255,.10)}
body[data-report] #gbp-switcher .colhead div{color:#c3f53c;font-weight:700;
  letter-spacing:.09em}

/* score rings align on one axis whether scored or pending */
body[data-report] #gbp-switcher .row .scorecell{display:flex;
  justify-content:center;align-items:center;padding:0;margin:0}
body[data-report] #gbp-switcher .row > .ring,
body[data-report] #gbp-switcher .scorecell .ring{margin:0 auto}

/* "Couldn't read — re-run": the muddy brown chip becomes the clean on-dark
   amber tint used everywhere else */
body[data-report] #gbp-switcher .ol-unread{
  background:rgba(255,194,80,.12)!important;
  border:1px solid rgba(255,194,80,.45)!important;
  color:#ffc250!important;border-radius:8px}
/* completeness fill was #50505f — indistinguishable from the dark track */
body[data-report] #gbp-switcher .comp .bar i{background:#c3f53c!important}

/* table polish round 3 (Liam): lime hover like the dock had, bigger column
   headings, and the couldn't-read chip goes neutral like Open to scan */
body[data-report] #gbp-switcher .row:hover,
body[data-report] #gbp-switcher .row:focus-visible{
  background:rgba(195,245,60,.10)!important}
body[data-report] #gbp-switcher .colhead div{font-size:13px}
body[data-report] #gbp-switcher .colhead{height:42px}
body[data-report] #gbp-switcher .ol-unread{
  background:rgba(255,255,255,.06)!important;
  border:1px solid rgba(255,255,255,.3)!important;
  color:#dfe3e8!important}
/* legacy light-theme rule turned the ring disc white on hover, erasing the
   numeral — the disc holds its dark surface whatever the row state */
body[data-report] #gbp-switcher .row:hover .ring::before{
  background:var(--surface)!important}

/* ═══════════ ACCOUNT PAGES, dark-system cleanup (1 Aug) ════════════════════
   settings/preferences/billing joined the report system via data-report; the
   light literals that dodge the tokens follow here. */
/* sticky save bar: white glass band → dark glass */
body[data-report] .ba-actionbar{background:rgba(43,46,53,.9);
  border:1px solid rgba(255,255,255,.22);
  box-shadow:0 18px 50px rgba(0,0,0,.35)}
/* photo dropzone */
body[data-report] .ba-drop{background:rgba(255,255,255,.04);
  border-color:rgba(255,255,255,.25);color:#b6bdc6}
body[data-report] .ba-drop:hover{background:rgba(195,245,60,.08);
  border-color:#c3f53c;color:#c3f53c}
/* segmented toggles: active pill goes lime like the table sort */
body[data-report] .seg button.on{background:#c3f53c;color:#1a2400;box-shadow:none}
/* danger zone: on-dark red instead of the pale pink wash */
body[data-report] .fset.danger{border-color:rgba(255,138,128,.4)}
body[data-report] .btn.danger-btn{border-color:rgba(255,138,128,.5)!important;
  color:#ff8a80!important;background:rgba(255,138,128,.08)!important}
body[data-report] .btn.danger-btn:hover{background:rgba(255,138,128,.16)!important;
  border-color:#ff8a80!important}
/* card titles pick up Honey Basil like every other card */
body[data-report] .fset > h2,body[data-report] .ba h2,
body[data-report] .ba-grid h2{
  font-family:'Honey Basil',var(--display);font-weight:400;font-size:21px;
  letter-spacing:.02em;color:#f2f4f6}
/* the preferences saverow strip was the last white band */
body[data-report] .saverow{background:transparent!important;border:0!important;
  box-shadow:none!important;backdrop-filter:none!important;
  -webkit-backdrop-filter:none!important}

/* ── ba-btn family on dark (1 Aug): Save was lime-on-lime with WHITE text and
   Start over was white-on-white — the buttons worked, you just couldn't see
   them doing it. ── */
body[data-report] .ba-btn{background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.3);color:#f2f4f6}
body[data-report] .ba-btn:hover{border-color:rgba(255,255,255,.5)}
body[data-report] .ba-btn-primary{background:#c3f53c!important;
  border-color:#c3f53c!important;color:#1a2400!important}
body[data-report] .ba-btn-primary:hover{background:#b2e332!important;
  border-color:#b2e332!important}
/* disabled reads unmistakably dead */
body[data-report] .ba-btn:disabled,body[data-report] .ba-btn-primary:disabled{
  background:rgba(255,255,255,.06)!important;border-color:rgba(255,255,255,.15)!important;
  color:#7d838d!important;opacity:1;cursor:not-allowed}

/* ── colour swatches: obviously clickable (Liam) ── */
body[data-report] .ba-swatch{position:relative;cursor:pointer;
  border-radius:9px;box-shadow:0 0 0 1px rgba(255,255,255,.25);
  transition:transform .12s,box-shadow .12s}
body[data-report] .ba-swatch::after{display:none}
body[data-report] .ba-swatch:hover{transform:scale(1.06);
  box-shadow:0 0 0 2px #c3f53c}

/* ── account pages: eyebrows + Channel-Overview-style colour rows (1 Aug) ── */
.acct-eyebrow{display:block;font-size:11.5px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:#c3f53c;margin-bottom:4px}
/* brand-colour rows read like the Numbers card: swatch + name left, hex
   right, hairlines between — the boxy inputs go quiet */
body[data-report] .ba-col-row{gap:14px;padding:14px 10px;margin:0 -10px;
  border-bottom:1px solid rgba(255,255,255,.10);border-radius:8px;
  transition:background .12s}
body[data-report] .ba-col-row:hover{background:#e9fbb0}
body[data-report] .ba-col-row:hover input[type="text"],
body[data-report] .ba-col-row:hover .ba-col-role{color:#1a2400}
body[data-report] .ba-col-row:hover .ba-col-del{color:#1a2400}
body[data-report] .ba-col-del:hover{background:rgba(0,0,0,.12);color:#1a2400}
/* the dashed add/upload affordances go quiet on the dark ground, lime on hover */
body[data-report] .ba-add-col,body[data-report] .ba-drop{
  background:transparent;border-color:rgba(255,255,255,.18);color:#b6bdc6}
body[data-report] .ba-add-col:hover,body[data-report] .ba-drop:hover{
  border-color:#c3f53c;color:#c3f53c;background:rgba(195,245,60,.07)}
body[data-report] .ba-drop:hover strong{color:#c3f53c}
/* logo preview fills its card and answers hover like the swatches */
body[data-report] .ba-logo-prev{max-width:100%;height:150px;padding:18px;
  border:1px solid rgba(255,255,255,.12);border-radius:10px;
  transition:box-shadow .12s}
body[data-report] .ba-logo-prev:hover{box-shadow:0 0 0 2px #c3f53c}
body[data-report] .ba-stack>.ba-panel+.ba-panel::before{background:#c3f53c}
/* text inputs light up on hover, matching the row/dock hover language */
body[data-report] .ba-inp:hover:not(:focus){border-color:#c3f53c;
  background:rgba(195,245,60,.06)}
body[data-report] .ba-col-row input[type="text"]{background:transparent;
  border:0;border-radius:0;font-weight:600;color:#f2f4f6;padding:4px 2px}
body[data-report] .ba-col-row input[type="text"]:focus{outline:0;
  box-shadow:0 1px 0 #c3f53c}
/* the hex value right-aligns like the stat numerals */
body[data-report] .ba-col-row input[data-k="hex"],
body[data-report] .ba-col-row input[type="text"]:last-of-type{
  text-align:right;color:#b6bdc6;font-weight:700;letter-spacing:.03em;
  text-transform:uppercase;max-width:110px;margin-left:auto}
/* the colour-row inputs are bare <input>s — flatten those too */
body[data-report] .ba-col-row input:not([type="color"]){background:transparent!important;
  border:0!important;border-radius:0;font-weight:600;color:#f2f4f6;padding:4px 2px}
body[data-report] .ba-col-row input:not([type="color"]):focus{outline:0!important;
  box-shadow:0 1px 0 #c3f53c}
body[data-report] .ba-col-row input[data-k="hex"]{text-align:right;color:#b6bdc6;
  font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  max-width:110px;margin-left:auto}

/* drag-reorder colour rows (1 Aug) */
body[data-report] .ba-col-row{cursor:grab}
body[data-report] .ba-col-row.dragging{opacity:.45}
body[data-report] .ba-col-row.drop-hint{box-shadow:0 -2px 0 #c3f53c}
body[data-report] .ba-drag{color:#7d838d;flex:none;display:grid;place-items:center}
body[data-report] .ba-col-role{font-weight:700;color:#f2f4f6;flex:1;min-width:0}

/* settings page in two columns (Liam) — the cards were half-empty at full
   width. Dashboard view keeps the full row for its toggle rows. */
@media(min-width:901px){
  .prefs2{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:stretch}
  .prefs2 > .fset{margin:0;display:flex;flex-direction:column}
  .prefs2 > .fset > :last-child{margin-top:auto;padding-top:14px}
  .prefs2 > .fset > a.btn{align-self:flex-start}
  .prefs2 > .fset:nth-of-type(3),.prefs2 > .fset.gbp{grid-column:1/-1}
}

/* stepper as dock items: number in a dark circle, label written underneath.
   Hover warms the circle pale-lime like the dock; the current step gets the
   dock's is-here thin lime outline + lime label. */
body[data-report] #stepper{gap:26px}
body[data-report] .step{display:flex;flex-direction:column;align-items:center;gap:8px;
  background:none;border:0;padding:0;border-radius:8px;box-shadow:none;
  color:#eceef0;font-size:12.5px;font-weight:600;letter-spacing:.01em}
body[data-report] .step i{display:grid;place-items:center;width:44px;height:44px;
  border-radius:50%;background:#23252b!important;border:1px solid rgba(255,255,255,.14);
  color:#eceef0!important;font-size:14px;font-weight:700;font-style:normal}
body[data-report] .step:hover{background:none}
body[data-report] .step:hover i{background:#e9fbb0!important;color:#1a2400!important;
  border-color:#e9fbb0}
body[data-report] .step.done{color:var(--muted)}
body[data-report] .step.done i{color:#c3f53c!important}
body[data-report] .step.active{color:#c3f53c;background:none!important;border:0}
body[data-report] .step.active i,
body[data-report] #stepper .step.active i{background:#23252b!important;color:#c3f53c!important;
  box-shadow:0 0 0 2px #c3f53c;border-color:transparent}

/* create pages read as one centred column, like onboarding: stage headings,
   notes and the wizard's colour stage centre; form internals stay left-aligned */
body[data-report] #stagehead,body[data-report] .nb-h{text-align:center}
body[data-report] #stagehead .muted{margin-left:auto;margin-right:auto;max-width:64ch}
/* ══════════ wizard: the brand-colour editor ═══════════════════════════════
   The swatch opens an in-app picker. It used to be <input type="color">, which
   hands you the OS panel — white, off-brand, and RGB spinners for a job that is
   really "nudge this red a bit warmer". */
body[data-report] .cw-colours{margin:0 auto;max-width:none}
body[data-report] .cw-swatches{flex-direction:row;justify-content:center;gap:18px;margin-bottom:18px}
body[data-report] .cw-sw{flex:none;flex-direction:column;align-items:center;gap:9px;
  padding:0;margin:0;border:0;width:auto}
body[data-report] .cw-chip{width:72px;height:72px;border-radius:16px;cursor:pointer;
  border:0;padding:0;box-shadow:0 0 0 1px rgba(255,255,255,.18);
  transition:transform .12s,box-shadow .12s}
body[data-report] .cw-chip:hover{transform:scale(1.05);box-shadow:0 0 0 2px #c3f53c}
body[data-report] .cw-chip.open{box-shadow:0 0 0 2px #c3f53c}
body[data-report] .cw-sw b{font-size:11.5px;font-weight:700;color:#b6bdc6;
  letter-spacing:.06em;text-transform:uppercase}
body[data-report] .cw-hexwrap{display:flex;align-items:center;gap:2px;
  background:#2a2d33;border:1px solid rgba(255,255,255,.16);border-radius:8px;
  padding:5px 9px;transition:border-color .14s}
body[data-report] .cw-hexwrap:hover{border-color:#c3f53c}
body[data-report] .cw-hexwrap:focus-within{border-color:#c3f53c;box-shadow:0 0 0 3px rgba(195,245,60,.3)}
body[data-report] .cw-hexwrap span{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:#7d838d}
body[data-report] .cw-edit .cw-hex{display:block;width:7ch;border:0;background:none;padding:0;
  font-family:ui-monospace,Menlo,monospace;font-size:12px;font-weight:700;
  letter-spacing:.05em;color:#f2f4f6;text-transform:uppercase;text-align:left}
body[data-report] .cw-edit .cw-hex:focus{outline:0}
body[data-report] .cw-cnote{text-align:center;margin:0 0 6px}
body[data-report] .cw-saved{display:inline-block;margin-left:8px;color:#c3f53c;font-weight:700}

/* ── the picker popover ── */
.cp{position:absolute;z-index:80;width:236px;padding:12px;border-radius:14px;
  background:#2b2e35;border:1px solid rgba(255,255,255,.16);
  box-shadow:0 20px 50px rgba(0,0,0,.5)}
.cp-sv{position:relative;height:132px;border-radius:9px;cursor:crosshair;
  background:linear-gradient(to top,#000,transparent),linear-gradient(to right,#fff,var(--hue));}
.cp-dot{position:absolute;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;
  border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.5);pointer-events:none}
.cp-hue{position:relative;height:14px;margin-top:11px;border-radius:7px;cursor:pointer;
  background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)}
.cp-hue .cp-dot{top:7px}
.cp-row{display:flex;align-items:center;gap:8px;margin-top:11px}
.cp-prev{width:30px;height:30px;border-radius:8px;flex:none;box-shadow:0 0 0 1px rgba(255,255,255,.2)}
.cp-hex{flex:1;min-width:0;background:#23252b;border:1px solid rgba(255,255,255,.16);
  border-radius:8px;padding:7px 9px;font-family:ui-monospace,Menlo,monospace;
  font-size:12.5px;font-weight:700;color:#f2f4f6;text-transform:uppercase}
.cp-hex:focus{outline:0;border-color:#c3f53c}
.cp-done{border:0;border-radius:8px;background:#c3f53c;color:#1a2400;font-weight:700;
  font-size:12.5px;padding:8px 12px;cursor:pointer;font-family:inherit}
.cp-done:hover{background:#e9fbb0}
body[data-report] .cw-cnote{text-align:center}
body[data-report] .cw-colours .actions,body[data-report] .discount-panel .actions{justify-content:center}
body[data-report] .discount-panel{margin-left:auto;margin-right:auto}
body[data-report] .tile-prog{text-align:center}
body[data-report] #cstatus{text-align:center}
/* carousel confirm stage: picker + headline + actions in one centred card */
body[data-report] .car-card{background:var(--surface);border:1px solid rgba(255,255,255,.22);
  border-radius:12px;padding:24px;max-width:720px;margin:0 auto 24px}
body[data-report] .car-card .acct-eyebrow{text-align:center;margin-bottom:12px}
body[data-report] .car-photos-head{justify-content:center}
body[data-report] .car-photos{justify-content:center}
body[data-report] .car-note,body[data-report] .car-headline{text-align:center}
/* remove-photo is always visible, and reads clearly as destructive on hover */
body[data-report] .car-rm{opacity:1;width:24px;height:24px;font-size:17px;
  background:#c3f53c;color:#1a2400;box-shadow:none}
body[data-report] .car-rm:hover{background:#e9fbb0;color:#1a2400}
body[data-report] #cstage-review .actions{justify-content:center}

/* ═══════════ CREATE PAGES join the dark system (1 Aug) ═════════════════════
   wizard / carousel / setup carry data-report now. The token flip covers all
   the var()-driven chrome; this section is only the light literals in
   style.css that dodge it. Flyer/slide/photo PREVIEWS keep their true
   colours — only the chrome around them goes dark. */
/* stage + section titles take the display face like every other card title */
body[data-report] #stagehead h1,body[data-report] .lib-head h1,
body[data-report] .nb-h,body[data-report] .downloads h2,
body[data-report] .slides-head h2{
  font-family:'Honey Basil',var(--display);font-weight:400;
  letter-spacing:.02em;color:var(--ink)}
/* the wizard's white card border was a light literal (#ececf0) */
/* thumb backings + render shimmer: light lilac → dark surface. The <img>s on
   top are the rendered artwork and are never filtered. */
body[data-report] .tile .thumb img,body[data-report] .lib-thumb,
body[data-report] .car-photo,body[data-report] .tile.rendering .thumb{
  background:var(--surface-2)}
body[data-report] .tile.rendering .thumb::after,
body[data-report] .slide-skel{
  background:linear-gradient(100deg,#3a3e46 30%,#454952 50%,#3a3e46 70%);
  background-size:220% 100%}
body[data-report] .slide-skel{border-color:rgba(255,255,255,.14)}
/* offer rows answer hover in the dock's pale-lime language */
body[data-report] .offer:hover{background:#e9fbb0;border-color:#e9fbb0}
body[data-report] .offer:hover .amt,
body[data-report] .offer:hover .meta{color:#1a2400}
/* the "5 / 5" photo counter's full state: violet-on-white → lime tint */
body[data-report] .car-count.full{background:rgba(195,245,60,.14);
  color:#c3f53c;border-color:rgba(195,245,60,.4)}
/* agency card grid: hover hairline, initial chip and Built pill */
body[data-report] .card:hover{border-color:rgba(255,255,255,.35)}
body[data-report] .mono{border-color:rgba(195,245,60,.35)}
body[data-report] .pill.ok{background:rgba(195,245,60,.14);color:#c3f53c}
/* setup boxes painted with light gradients (find / AI copy / import) */
body[data-report] .lookupbox,body[data-report] .aibox,
body[data-report] .importbox{
  background:linear-gradient(180deg,rgba(195,245,60,.07),var(--surface) 60%);
  border-color:rgba(255,255,255,.22)}
/* photo-thumb remove ×: it fills with --ink, which flips near-white here */
body[data-report] .thumb button{background:#1a1c21;color:#f2f4f6}
/* text controls answer hover in lime like the account pages (focus already
   goes lime through the flipped --accent/--ring) */
body[data-report] :is(input,select,textarea):not([type=color]):not([type=radio]):not([type=checkbox]):not([type=file]):hover:not(:focus):not(:disabled){
  border-color:#c3f53c;background:rgba(195,245,60,.06)}

/* the badge standing in for the old star + wordmark */
body[data-report] .wm-badge,.wm-badge{display:block;height:26px;width:auto}


/* ── print-quality warning at export (2 Aug) ──────────────────────────────
   The flyer still downloads; this says what it will look like on paper. */
body[data-report] .dpi-warn{display:block;width:100%;margin:0 0 14px;padding:14px 16px;
  border-radius:10px;text-align:left;font-size:13.5px;line-height:1.5}
body[data-report] .dpi-warn b{display:block;margin-bottom:4px;font-size:14px}
body[data-report] .dpi-warn span{display:block;color:inherit;opacity:.92}
body[data-report] .dpi-warn .dpi-warn-note{margin-top:8px;opacity:.75;font-size:12.5px}
body[data-report] .dpi-warn.q-soft{background:rgba(255,194,80,.12);
  border:1px solid rgba(255,194,80,.4);color:#ffc250}
body[data-report] .dpi-warn.q-low{background:rgba(255,138,128,.12);
  border:1px solid rgba(255,138,128,.45);color:#ff8a80}


/* ── funnel page (2 Aug) ─────────────────────────────────────────────────── */
body[data-report] .fn-wrap{display:flex;flex-direction:column;gap:16px}
body[data-report] .fn-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:12px;margin-top:16px}
body[data-report] .fn-step{background:#2a2d33;border:1px solid rgba(255,255,255,.12);
  border-radius:10px;padding:16px 14px}
body[data-report] .fn-n{font-family:'Honey Basil',var(--display);font-weight:400;
  font-size:32px;line-height:1;color:#c3f53c}
body[data-report] .fn-l{margin-top:6px;font-size:13.5px;font-weight:600;color:#f2f4f6}
body[data-report] .fn-p{margin-top:3px;font-size:11.5px;color:#7d838d}
body[data-report] .fn-pages{list-style:none;margin:14px 0 0;padding:0}
body[data-report] .fn-pages li{display:flex;align-items:baseline;gap:10px;padding:9px 0;
  font-size:13.5px;color:#f2f4f6;border-bottom:1px solid rgba(255,255,255,.08)}
body[data-report] .fn-pages li:last-child{border-bottom:0}
body[data-report] .fn-pages .dots{flex:1;border-bottom:1.5px dotted rgba(255,255,255,.22);
  transform:translateY(-4px)}
body[data-report] .fn-pages b{font-family:ui-monospace,Menlo,monospace;color:#c3f53c}


/* ── the consistency card on Home (2 Aug) ────────────────────────────────── */
.cons-card.is-loading h3,
.cons-card.is-loading p{opacity:.55}
.cons-card.cons-ok .ins-kind{color:#9ad462}
.cons-card.cons-warn{border-color:rgba(255,194,80,.45)}
.cons-card.cons-warn .ins-kind{color:#ffc250}
.cons-card.cons-bad{border-color:rgba(255,138,128,.5)}
.cons-card.cons-bad .ins-kind{color:#ff8a80}

/* .dir-insight lays its children into named grid areas (kind/title/desc/go +
   an icon column). An extra child lands in whatever cell is free, which is how
   the two numbers ended up stacked in the icon column. Give this card its own
   area map with a row for them. */
.dir-card.dir-insight.cons-card{
  grid-template-areas:"kind kind" "title title" "rows rows" "desc desc" "go go";
  grid-template-columns:minmax(0,1fr) auto}
.cons-card .ins-kind{grid-area:kind}
.cons-card h3{grid-area:title}
.cons-card .cons-rows{grid-area:rows}
.cons-card p{grid-area:desc}
.cons-card .go{grid-area:go}
.cons-rows{display:block;width:100%;margin:12px 0 14px}
.cons-row{display:flex;align-items:baseline;justify-content:space-between;
  gap:14px;padding:7px 0;border-bottom:1px solid rgba(255,255,255,.09);font-size:13.5px}
.cons-row:last-child{border-bottom:0}
.cons-row span{color:#7d838d;flex:none}
.cons-row b{color:#f2f4f6;font-family:ui-monospace,Menlo,monospace;
  font-size:13px;text-align:right;overflow-wrap:anywhere}


/* ---- Google locations editor (Settings) ---------------------------------- */
body[data-report] .loc-list{display:flex;flex-direction:column;gap:2px;margin-top:6px}
body[data-report] .loc-row{display:flex;align-items:center;gap:14px;padding:12px 14px;
  border-radius:10px;background:var(--surface-2,#3a3e46);
  border:1px solid rgba(255,255,255,.10)}
body[data-report] .loc-txt{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px}
body[data-report] .loc-txt b{font-size:14.5px;color:var(--ink,#f2f4f6)}
body[data-report] .loc-txt span{font-size:12.5px;color:var(--muted,#b6bdc6);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body[data-report] .loc-del{flex:none}
body[data-report] .loc-ac{position:relative;margin-top:6px;border-radius:10px;
  background:var(--surface,#31343c);border:1px solid var(--lime,#c3f53c);overflow:hidden}
body[data-report] .loc-ac.hidden{display:none}
body[data-report] .loc-ac-item{display:flex;align-items:center;gap:11px;
  padding:9px 14px;font-size:14px;cursor:pointer;
  border-top:1px solid rgba(255,255,255,.08)}
body[data-report] .loc-ac-item:first-child{border-top:0}
body[data-report] .loc-ac-item:hover{background:var(--lime,#c3f53c);color:var(--lime-ink,#1a2400)}
body[data-report] .loc-ac-item:hover .loc-btn.add{background:var(--lime-ink,#1a2400);
  border-color:var(--lime-ink,#1a2400);color:var(--lime,#c3f53c)}


/* ---- empty / blocked states: one CTA, the rest quiet --------------------- */
/* The failure mode here is a wall of explanation with three equal-weight
   buttons. Keep one primary action; demote the correction to a link and hide
   the reasoning behind a disclosure, so the page reads in about two seconds. */
body[data-report] .emptystate .es-sub{max-width:52ch;margin-left:auto;margin-right:auto}
body[data-report] .es-quiet{display:inline-block;margin-top:14px;font-size:13px;
  color:var(--muted,#b6bdc6);text-decoration:underline;text-underline-offset:3px}
body[data-report] .es-quiet:hover{color:var(--ink,#f2f4f6)}
body[data-report] .es-why{margin-top:16px;font-size:13px;color:var(--faint,#7d838d)}
body[data-report] .es-why summary{cursor:pointer;list-style:none;
  text-decoration:underline;text-underline-offset:3px}
body[data-report] .es-why summary::-webkit-details-marker{display:none}
body[data-report] .es-why p{max-width:48ch;margin:10px auto 0;line-height:1.55}

body[data-report] .es-acts{display:flex;align-items:center;justify-content:center;
  gap:16px;flex-wrap:wrap;margin-top:12px}


/* ---- review failure: same shape as the empty state, in red -------------- */
/* A failed review has to read as failed at a glance, then say what to do. The
   old version buried the message under a generic "Try again", which resends
   the same input and fails the same way. */
body[data-report] .wiz-error{border:1.5px solid rgba(255,138,128,.55);
  border-radius:16px;background:rgba(255,138,128,.07);padding:38px 24px;text-align:center}
body[data-report] .wiz-error .es-icon.err{width:46px;height:46px;margin:0 auto 12px;
  border-radius:50%;display:grid;place-items:center;font-size:24px;font-weight:800;
  opacity:1;color:#ff8a80;background:rgba(255,138,128,.14);
  border:2px solid rgba(255,138,128,.55)}
body[data-report] .wiz-error .es-title{font-size:22px;color:#ff8a80}
body[data-report] .wiz-error .es-sub{font-size:14.5px;color:var(--muted);
  max-width:50ch;margin:8px auto 0}
/* the value we actually used - the thing most likely to be wrong */
body[data-report] .err-check{display:inline-flex;align-items:center;gap:12px;
  flex-wrap:wrap;justify-content:center;
  margin:18px auto 4px;padding:9px 10px 9px 15px;border-radius:11px;
  background:rgba(0,0,0,.25);border:1px solid rgba(255,255,255,.12)}
body[data-report] .err-check-cta{flex:none;padding:9px 16px;font-size:13.5px}
body[data-report] .err-check-lab{font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--faint)}
body[data-report] .err-check-val{font:600 15px/1 ui-monospace,SFMono-Regular,Menlo,monospace;
  color:var(--ink);margin-right:2px}
body[data-report] .btn-bad{background:#ff8a80;border-color:#ff8a80;color:#2a0f0c;
  font-weight:700}
body[data-report] .btn-bad:hover{background:#ffa79f;border-color:#ffa79f}
body[data-report] .es-quiet.as-btn{background:none;border:0;cursor:pointer;
  font:inherit;font-size:13px;color:var(--muted);text-decoration:underline;
  text-underline-offset:3px;padding:0}
body[data-report] .es-quiet.as-btn:hover{color:var(--ink)}

body[data-report] .loc-manage{display:flex;align-items:center;justify-content:flex-end;
  gap:9px;margin:0}
body[data-report] .loc-manage-lab{font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--faint);margin-right:2px}
body[data-report] .loc-manage .loc-btn{text-decoration:none}
body[data-report] .loc-row.just-landed{animation:ba-land 1.6s ease}

/* review-in-progress banner on the dashboard home */
body[data-report] .rev-running{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin:0 0 16px;padding:12px 16px;border-radius:12px;
  background:rgba(195,245,60,.08);border:1px solid rgba(195,245,60,.35);
  font-size:14px;font-weight:600;color:var(--ink)}
body[data-report] .rev-running.hidden{display:none}
body[data-report] .rev-running em{font-style:normal;font-weight:400;font-size:13px;
  color:var(--muted)}

/* landing flash so an anchored jump does not dump you at an ambiguous spot */
@keyframes ba-land{0%{box-shadow:0 0 0 0 rgba(195,245,60,.55)}
  30%{box-shadow:0 0 0 4px rgba(195,245,60,.35)}
  100%{box-shadow:0 0 0 0 rgba(195,245,60,0)}}
body[data-report] .ba-panel.just-landed{animation:ba-land 1.6s ease}

/* round +/- controls for branches */
body[data-report] .loc-btn{width:34px;height:34px;flex:none;border-radius:50%;
  display:grid;place-items:center;padding:0;font-size:20px;font-weight:700;
  line-height:1;cursor:pointer;
  /* was a thin grey ring on a grey row - technically present, practically
     invisible. Brighter ring, filled ground, brighter glyph. */
  border:1.5px solid rgba(255,255,255,.45);
  background:rgba(255,255,255,.08);color:var(--ink,#f2f4f6);transition:.14s}
body[data-report] .loc-btn:hover{transform:scale(1.08)}
body[data-report] .loc-btn.rm:hover{border-color:#ff8a80;color:#ff8a80;
  background:rgba(255,138,128,.12)}
body[data-report] .loc-btn.add{border-color:var(--lime,#c3f53c);color:var(--lime,#c3f53c);
  background:rgba(195,245,60,.10)}
body[data-report] .loc-btn.add:hover{background:var(--lime,#c3f53c);color:var(--lime-ink,#1a2400)}

body[data-report] .loc-add-row{display:flex;align-items:center;gap:10px;margin-top:8px}

/* branch controls share the filters row with the sort group */
body[data-report] .tbl-controls{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
body[data-report] .tbl-controls .loc-manage{margin-left:auto}
body[data-report] .tbl-controls .loc-btn{width:30px;height:30px;font-size:18px}

/* ---- inline branch editing in the locations table ----------------------- */
/* The minus sits OUTSIDE the row, in its own gutter, and is always visible.
   Inside-on-hover meant you had to already know it was there. */
/* The control belongs OUTSIDE the table card, not inside its padding. The card
   is inset by the gutter and allowed to overflow, so the minus can sit clear of
   its right edge instead of floating over the last column. */
/* Table keeps its full width - shrinking it to make room made every column
   narrower for the sake of a control that is only there on hover. The minus
   hangs outside instead, so ancestors must not clip it. */
body[data-report] #gbp-switcher .tbl{overflow:visible}
body[data-report] #gbp-switcher{overflow:visible}
body[data-report] #gbp-rows{--rm-gutter:46px}
body[data-report] #gbp-rows .row{position:relative}
body[data-report] .row-rm{position:absolute;right:-40px;
  top:50%;transform:translateY(-50%);
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  font-size:16px;font-weight:700;line-height:1;cursor:pointer;
  border:1.5px solid rgba(255,255,255,.45);background:rgba(255,255,255,.08);
  color:var(--ink,#f2f4f6);opacity:0;pointer-events:none;transition:.14s}
body[data-report] #gbp-rows .row:hover .row-rm,
body[data-report] .brow-wrap:hover .row-rm,
body[data-report] .row-rm:focus-visible{opacity:1;pointer-events:auto}
body[data-report] .row-rm:hover{transform:translateY(-50%) scale(1.08)}
/* The control sits in a gutter outside the row, leaving a dead strip between
   the two. Crossing it, neither was hovered, so the button vanished mid-reach.
   An invisible pad bridges the gap - and because it is a descendant of the row,
   hovering it keeps :hover alive on the row itself. */
body[data-report] .row-rm::before{content:"";position:absolute;
  top:-8px;bottom:-8px;left:-16px;right:-10px}
/* plus a short grace period, so a fast diagonal never outruns the bridge */
body[data-report] .row-rm{transition:opacity .14s .12s,transform .14s,
  border-color .14s,background .14s,color .14s}
body[data-report] #gbp-rows .row:hover .row-rm{transition-delay:0s}
body[data-report] .row-rm:hover{border-color:#ff8a80;color:#ff8a80;
  background:rgba(255,138,128,.14)}
/* closing row: dashed, so it reads as "space for another" not as data */
body[data-report] .row-add{display:flex;align-items:center;gap:11px;
  padding:14px 16px;border:1px dashed rgba(255,255,255,.22);border-radius:10px;
  margin-top:6px;color:var(--muted,#b6bdc6);font-size:14px;font-weight:600;
  text-decoration:none;transition:.14s}
body[data-report] .row-add:hover{border-color:var(--lime,#c3f53c);
  color:var(--lime,#c3f53c);background:rgba(195,245,60,.06)}
body[data-report] .row-add-ic{width:28px;height:28px;flex:none;border-radius:50%;
  display:grid;place-items:center;font-size:17px;font-weight:700;line-height:1;
  border:1.5px solid currentColor}

/* ---- branches before any scores exist ----------------------------------- */
/* One line per branch instead of a table of empty columns. The table comes
   back the moment there is something to put in it. */
body[data-report] .brow{position:relative;display:flex;align-items:center;gap:16px;
  padding:14px 16px;border-radius:10px;background:var(--surface-2,#3a3e46);
  border:1px solid rgba(255,255,255,.10);margin-bottom:6px;cursor:pointer;
  transition:border-color .14s,background .14s}
body[data-report] .brow:hover{border-color:rgba(195,245,60,.45);
  background:rgba(195,245,60,.05)}
body[data-report] .brow-scan{flex:none;margin-right:26px}
body[data-report] .brow-txt{flex:1 1 auto;min-width:0}
body[data-report] .brow-name{font-size:15px;font-weight:600;color:var(--ink,#f2f4f6)}
body[data-report] .brow-addr{font-size:12.5px;color:var(--muted,#b6bdc6);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body[data-report] .brow-state{flex:none;font-size:12.5px;color:var(--faint,#7d838d);
  display:inline-flex;align-items:center;gap:8px;margin-right:26px}
body[data-report] .brow-state.running{color:var(--lime,#c3f53c)}
body[data-report] .brow .row-rm{opacity:0;right:8px}
body[data-report] .brow:hover .row-rm{opacity:1;pointer-events:auto;
  transform:translateY(-50%) scale(1)}

body[data-report] .row-add-hint{font-style:normal;font-size:12px;color:var(--faint,#7d838d);
  margin-left:auto}

/* ---- branch list: control outside the card ------------------------------ */
/* The minus lived inside the card, only on hover - invisible until you found
   it. Outside and always on: it reads as "act on this row", and the card stays
   a clean block of information. */
body[data-report] .brow-wrap{display:flex;align-items:center;gap:12px;margin-bottom:8px}
body[data-report] .brow-wrap .brow{flex:1 1 auto;margin-bottom:0}
body[data-report] .brow-wrap .row-rm{position:static;transform:none;opacity:0;
  pointer-events:none;flex:none;width:26px;height:26px;font-size:16px}
body[data-report] .brow-wrap:hover .row-rm,
body[data-report] .brow-wrap .row-rm:focus-visible{opacity:1;pointer-events:auto}
body[data-report] .brow-wrap .row-rm:hover{transform:scale(1.08)}

/* ---- add a branch: dotted lime box, plus centred ------------------------ */
/* Detached from the list and full width: it is not another branch, it is the
   way to get one, so it sits apart rather than continuing the stack. One slim
   row instead of a tall block. */
body[data-report] .row-add{display:flex;flex-direction:row;align-items:center;
  justify-content:center;gap:11px;padding:13px 16px;margin:22px 0 0;width:100%;
  border:1.5px dashed rgba(195,245,60,.45);border-radius:10px;
  background:rgba(195,245,60,.05);color:var(--lime,#c3f53c);
  font-size:14px;font-weight:700;text-decoration:none;transition:.15s}
body[data-report] .row-add:hover{border-color:var(--lime,#c3f53c);
  background:rgba(195,245,60,.12)}
body[data-report] .row-add-ic{width:24px;height:24px;flex:none;border-radius:50%;
  display:grid;place-items:center;font-size:16px;font-weight:700;line-height:1;
  border:1.5px solid currentColor;color:var(--lime,#c3f53c)}
body[data-report] .row-add-t{letter-spacing:.01em}

/* it is a button now, so it must look pressable */
body[data-report] button.ol-unread{cursor:pointer;font:inherit;
  border:1px solid rgba(255,255,255,.25);background:rgba(255,255,255,.06);
  border-radius:7px;padding:5px 10px;color:var(--muted,#b6bdc6);transition:.14s}
body[data-report] button.ol-unread:hover{border-color:var(--lime,#c3f53c);
  color:var(--lime,#c3f53c);background:rgba(195,245,60,.10)}

/* ---- Add a location card (Brand & assets) ------------------------------- */
/* Matches the dotted add row on the Google review so the same job looks the
   same in both places. */
body[data-report] .loc-add-card{display:flex;align-items:flex-start;gap:14px;
  margin-top:14px;padding:16px;max-width:560px;cursor:text;
  border:1.5px dashed rgba(195,245,60,.45);border-radius:12px;
  background:rgba(195,245,60,.05);transition:.15s}
body[data-report] .loc-add-card:hover,
body[data-report] .loc-add-card:focus-within{border-color:var(--lime,#c3f53c);
  background:rgba(195,245,60,.10)}
body[data-report] .loc-add-ic{width:28px;height:28px;flex:none;border-radius:50%;
  display:grid;place-items:center;font-size:18px;font-weight:700;line-height:1;
  border:1.5px solid var(--lime,#c3f53c);color:var(--lime,#c3f53c);margin-top:2px}
body[data-report] .loc-add-body{flex:1 1 auto;min-width:0}
body[data-report] .loc-add-t{font-size:14px;font-weight:700;
  color:var(--lime,#c3f53c);margin-bottom:9px}
body[data-report] .loc-add-card .loc-ac{margin-top:8px}

/* ---- scanning indicator: left gutter, mirroring the minus on the right --- */
body[data-report] #gbp-rows .row.is-running,
body[data-report] .brow-wrap.is-running{position:relative}
/* The control that started the scan IS the progress indicator - a separate
   spinner in the gutter split one action across two places. */
body[data-report] .btn.is-loading,
body[data-report] .ol-unread.is-loading{display:inline-flex;align-items:center;
  justify-content:center;gap:8px;cursor:default;opacity:.9}
body[data-report] .btn.is-loading .spin,
body[data-report] .ol-unread.is-loading .spin{width:13px;height:13px;
  border-width:2px;flex:none;margin:0;display:block}
/* the toast is gone for good */
body[data-report] #rerun-toast{display:none !important}

/* route to the locations list from the Google review, including the
   single-branch case where no table (and so no add row) is drawn at all */
body[data-report] .gbp-manage{display:inline-flex;align-items:center;gap:9px;
  margin:0 0 16px;padding:9px 14px;border-radius:10px;text-decoration:none;
  border:1.5px dashed rgba(195,245,60,.45);background:rgba(195,245,60,.05);
  color:var(--lime,#c3f53c);font-size:13.5px;font-weight:700;transition:.15s}
body[data-report] .gbp-manage:hover{border-color:var(--lime,#c3f53c);
  background:rgba(195,245,60,.12)}
body[data-report] .gbp-manage-ic{width:22px;height:22px;border-radius:50%;
  display:grid;place-items:center;font-size:15px;line-height:1;
  border:1.5px solid currentColor}

/* "show all" toggle under a folded location list */
body[data-report] .rows-fold{display:block;width:100%;margin:10px 0 0;padding:11px 14px;
  border-radius:10px;cursor:pointer;font:600 13.5px/1 Inter,system-ui,sans-serif;
  color:var(--muted,#b6bdc6);background:transparent;
  border:1px solid rgba(255,255,255,.18);transition:.14s}
body[data-report] .rows-fold:hover{border-color:var(--lime,#c3f53c);
  color:var(--lime,#c3f53c);background:rgba(195,245,60,.06)}

/* the photo requirement, stated as a range and hard to skim past */
body[data-report] .ba-req{display:inline-block;font-size:15.5px;font-weight:700;
  color:var(--lime,#c3f53c);margin-right:4px}


/* ---- home: where people can order --------------------------------------- */
/* One row per channel: who, what we have on file, the order links, and a way
   in. Colours are literal - single_home.html carries no data-report, so the
   dark token block never applies there and var(--surface-2) resolves to the
   LIGHT theme (that is what turned the previous tiles near-white). */
.dir-grid-1 .ol-row:last-child{border-bottom:0}
.dir-grid-1 .ol-ident{font-size:13px;color:#b6bdc6;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dir-grid-1 .ol-provs{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.ol-more{font-size:12px;font-weight:700;color:#7d838d}
.ol-go{font-size:13px;font-weight:700;color:#b6bdc6;text-decoration:none;
  white-space:nowrap;padding:6px 12px;border-radius:8px;
  border:1px solid rgba(255,255,255,.18);transition:.14s}
.ol-go:hover{color:#c3f53c;border-color:#c3f53c;background:rgba(195,245,60,.08)}
@media(max-width:900px){
    .ol-go{justify-self:start}
}

/* Slimmer chips so the full set fits, wrapping onto a second line rather than
   collapsing into "+N" - the providers ARE the content of this card. */
/* min-height:48px above is what kept these chunky - it survived the padding
   change because it is a floor, not padding. */
.dir-grid-1 .ol-prov{min-height:34px;padding:6px 11px;font-size:12.5px;gap:6px;
  border-radius:8px}
.dir-grid-1 .ol-prov img{width:14px;height:14px}
.dir-grid-1 .ol-provs{row-gap:6px;max-height:none}

/* Each channel in its own container, edged in lime. Dividers made the three
   read as one list; separate blocks make them three distinct places a customer
   can arrive - which is what the card is actually about. */
.dir-grid-1 .ol-rows{gap:10px}
.dir-grid-1 .ol-row:hover{border-color:rgba(195,245,60,.65);
  background:linear-gradient(180deg,rgba(195,245,60,.10),rgba(195,245,60,.03))}
.dir-grid-1 .ol-row:last-child{border-bottom:1px solid rgba(195,245,60,.35)}

/* ---- website review: crawl coverage, evidence, per-branch ordering ------- */
body[data-report] .scan-coverage{margin:10px 0 0;font-size:12.5px;color:var(--faint,#7d838d)}
body[data-report] .scan-coverage b{color:var(--muted,#b6bdc6)}
body[data-report] .feat-where{display:block;margin-top:3px;font-size:11.5px;
  color:var(--faint,#7d838d)}
body[data-report] .feat-where code{font-size:11px;color:var(--muted,#b6bdc6)}
/* "found, but not where anyone lands" is the point of the whole crawl */
body[data-report] .feat-where em{font-style:normal;color:var(--warn,#e8c15a)}
body[data-report] .branch-ordering{margin-top:16px;padding:14px 16px;border-radius:12px;
  background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.10)}
body[data-report] .branch-ordering.hidden{display:none}
body[data-report] .bo-head{font-size:13px;font-weight:700;color:var(--ink,#f2f4f6);
  margin-bottom:10px}
body[data-report] .bo-head em{font-style:normal;font-weight:400;font-size:12px;
  color:var(--faint,#7d838d);margin-left:8px}
body[data-report] .bo-row{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:10px;
  align-items:center;padding:8px 0;border-top:1px solid rgba(255,255,255,.07)}
body[data-report] .bo-row.bo-hd{border-top:0;font-size:11px;letter-spacing:.07em;
  text-transform:uppercase;color:var(--faint,#7d838d)}
body[data-report] .bo-name{font-size:13.5px;font-weight:600;color:var(--ink,#f2f4f6)}
body[data-report] .bo-prov{display:inline-block;margin:0 5px 0 0;padding:3px 9px;
  border-radius:999px;font-size:11.5px;font-weight:700;
  background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.18);
  color:var(--muted,#b6bdc6)}
body[data-report] .bo-prov.direct{color:var(--lime,#c3f53c);
  border-color:rgba(195,245,60,.5);background:rgba(195,245,60,.10)}
body[data-report] .bo-prov.marketplace{color:#f2836f;border-color:rgba(242,131,111,.5);
  background:rgba(242,131,111,.10)}
body[data-report] .bo-none{color:var(--faint,#7d838d);font-size:12px}
@media(max-width:760px){body[data-report] .bo-row{grid-template-columns:1fr 1fr}}

/* pages we were refused - amber, because it is neither a pass nor a failure */
/* Amber was the wrong signal here. Everything else amber on this page is a
   thing the restaurant should go and fix; a refusal is not theirs to fix and
   the copy says so. Neutral surface, no alarm colour - it reads as a note about
   our coverage, which is what it is. */
body[data-report] .scan-blocked{margin-top:10px;padding:11px 14px;border-radius:10px;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.16);
  display:flex;flex-direction:column;gap:4px}
body[data-report] .scan-blocked.hidden{display:none}
body[data-report] .scan-blocked b{font-size:13.5px;color:var(--ink,#f2f4f6)}
body[data-report] .scan-blocked span{font-size:12.5px;color:var(--muted,#b6bdc6);line-height:1.5}
body[data-report] .scan-blocked code{font-size:11.5px;color:var(--faint,#7d838d);
  background:rgba(0,0,0,.22);border:1px solid rgba(255,255,255,.08)}

/* score chip beside the identifier */
.dir-grid-1 .ol-score{justify-self:end;align-self:center;
  font:700 15px/1 Inter,system-ui,sans-serif;padding:5px 10px;border-radius:8px;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.18)}
.dir-grid-1 .ol-score.s-good{color:#c3f53c;border-color:rgba(195,245,60,.5);background:rgba(195,245,60,.10)}
.dir-grid-1 .ol-score.s-warn{color:#e8c15a;border-color:rgba(232,193,90,.5);background:rgba(232,193,90,.10)}
.dir-grid-1 .ol-score.s-bad{color:#f2836f;border-color:rgba(242,131,111,.5);background:rgba(242,131,111,.10)}
.dir-grid-1 .ol-score.s-none{color:#7d838d}
/* identifier and score share one line */
.dir-grid-1 .ol-ch{grid-column:1/-1}
.dir-grid-1 .ol-provs{grid-column:1/-1;align-content:flex-start}
.dir-grid-1 .ol-go{grid-column:1/-1;justify-self:start}
@media(max-width:900px){.dir-grid-1 .ol-rows{flex-direction:column}}

/* ---- home: one card per channel ----------------------------------------- */
/* Colours are literal: single_home.html sets no data-report, so every var()
   here would resolve against the LIGHT theme and paint these cards near-white. */
.dir-grid-ch{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
@media(max-width:1000px){.dir-grid-ch{grid-template-columns:1fr}}
/* Same skin as every other .dir-card on this page - the channel cards are not a
   special class of thing and dressing them differently made the page busier
   without saying anything extra. Only the layout differs. */
/* Flex column, not grid rows. With grid the five children landed in different
   rows per card - Google's wrapped provider chips collapsed two rows to zero -
   so the CTAs sat 32px apart. A column with the providers taking the slack and
   the CTA pushed to the bottom cannot drift. */
.ch-card{display:flex;flex-direction:column;gap:11px}
.ch-card .ch-provs{flex:1 1 auto;align-content:flex-start}
.ch-card .ch-cta{margin-top:auto}
.ch-top{display:flex;align-items:center;gap:12px}
.ch-ic{width:38px;height:38px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.16);color:#b6bdc6}
.ch-ic svg{width:19px;height:19px}
.ch-id{flex:1 1 auto;min-width:0}
.ch-id h3{margin:0;font-size:16px;line-height:1.2;color:#f2f4f6}
.ch-sub{display:block;margin-top:2px;font-size:12.5px;color:#b6bdc6;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* the score ring, same component as the review cards at the foot of the page -
   sized down to sit in a card header. .dir-score carries the look; .ch-ring
   only changes the scale, so the two stay in step if the ring is restyled. */
.ch-ring{flex:none;width:58px;height:58px}
.ch-ring b{font-size:20px}

/* the two numbers, in the row under the header */
.ch-stats{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.ch-stat{display:flex;flex-direction:column;gap:2px;min-width:0}
.ch-stat b{font:700 19px/1 Inter,system-ui,sans-serif;letter-spacing:-.01em;color:#f2f4f6;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ch-stat em{font-style:normal;font-size:11px;color:#7d838d;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ch-lab{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:#7d838d}
/* Every ordering system gets an identical tile - two per row, fixed height, so
   "Slerp" and "Deliveroo" carry the same weight instead of being sized by the
   length of their name. Neutral surface, brand colour only in the logo tile:
   four vendor tints plus a lime CTA was five colours arguing on one card, and
   the tint carried no information the logo did not already give. Tinting is
   also what made Slerp (#111111) invisible on the #31343c card. */
.ch-card .ol-prov,.ch-card .ol-prov[style],.ch-card .ol-prov.direct[style]{
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.16);color:#f2f4f6}
.ch-card .ol-prov:hover,.ch-card .ol-prov[style]:hover{border-color:rgba(255,255,255,.30)}
/* the logo sits on its own white tile so every brand mark reads at 20px */
.ch-card .ol-prov img{width:20px;height:20px;border-radius:4px;background:#fff;
  padding:2px;object-fit:contain;flex:none}
/* no logo file: a dot in the brand colour keeps the vendor identifiable */
.ch-card .ol-prov .ol-dot{background:var(--brand,#b6bdc6)}
.ch-provs{display:grid;grid-template-columns:1fr 1fr;gap:8px;align-content:flex-start}
.ch-card .ol-prov{min-width:0;height:38px;padding:0 10px;border-radius:8px;
  font-size:11.5px;line-height:1.15;overflow:hidden}
.ch-card .ol-nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ch-card .ol-connect,.ch-card .ol-soon,.ch-card .ol-nope{grid-column:1 / -1}
.ch-cta{justify-self:stretch;text-align:center;font-size:13.5px;font-weight:700;
  padding:10px 14px;border-radius:9px;text-decoration:none;
  background:#c3f53c;border:1px solid #c3f53c;color:#1a2400}
.ch-cta:hover{background:#d3ff5c;border-color:#d3ff5c;color:#1a2400}

.ch-card .ins-kind{color:#c3f53c}

/* superseded by the neutral-chip rules above - the logo now sits on a white
   tile, which is the only place a brand colour appears on this card */


/* ── completeness tally + branch empty state (12 Aug) ──────────────────────
   The tally repeats the home-page card's number next to the section that
   defines it. The empty state replaces a section that used to vanish. */
body[data-report] .feat-tally{display:inline-flex;align-items:baseline;gap:8px;
  font-size:14px;font-weight:600;letter-spacing:.01em;
  padding:9px 17px;border-radius:999px;white-space:nowrap;
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.18);color:#b6bdc6}
body[data-report] .feat-tally b{color:#c3f53c;font-weight:700;font-size:24px;
  line-height:1;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
body[data-report] .feat-tallybox{display:flex;flex-direction:column;align-items:flex-end;gap:5px}
body[data-report] .feat-tally-note{font-size:11.5px;line-height:1.3;color:#7d838d;text-align:right}
body[data-report] .cl-help b{color:#f2f4f6;font-weight:700}
@media(max-width:640px){
  body[data-report] .feat-tally{font-size:13px;padding:7px 14px}
  body[data-report] .feat-tally b{font-size:20px}
  body[data-report] .feat-tallybox{align-items:flex-start}
  body[data-report] .feat-tally-note{text-align:left}}

body[data-report] .checklist-head{display:flex;align-items:center;gap:12px;
  justify-content:space-between;flex-wrap:wrap}
body[data-report] .bo-empty{margin:8px 0 0;font-size:13px;line-height:1.5;color:#b6bdc6}


/* ── the active card points at its findings (12 Aug) ───────────────────────
   Four cards above, one list below, and nothing joining them. */
body[data-report] .cat-tab{position:relative}
body[data-report] .cat-tab.active::after{content:"";display:block;position:absolute;
  left:50%;bottom:-8px;width:14px;height:14px;margin-left:-7px;transform:rotate(45deg);
  background:var(--surface-2);border-right:1px solid #c3f53c;border-bottom:1px solid #c3f53c;
  border-radius:0 0 3px 0}
body[data-report] .cat-lead{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  margin:22px 0 -4px}
body[data-report] .cat-lead-nm{font-size:13px;font-weight:700;letter-spacing:.02em;
  text-transform:capitalize;color:#c3f53c}
body[data-report] .cat-lead-vd{font-size:12.5px;color:#b6bdc6}
body[data-report] .cat-panels{border-top:1px solid rgba(195,245,60,.28);padding-top:4px}


/* ── re-run: a visible running state (12 Aug) ──────────────────────────────
   A re-run keeps the old report on screen, so the only feedback was a disabled
   button - indistinguishable from a dead click. */
body[data-report] .btn-spin{display:inline-block;width:13px;height:13px;flex:none;
  margin-right:8px;vertical-align:-2px;border-radius:50%;
  border:2px solid rgba(26,36,0,.28);border-top-color:#1a2400;
  animation:btnspin .7s linear infinite}
body[data-report] #rerun.is-running{opacity:1}
body[data-report] .rerun-banner{display:flex;align-items:center;gap:2px;flex-wrap:wrap;
  margin:12px 0 0;padding:10px 13px;border-radius:9px;font-size:12.5px;line-height:1.5;
  background:rgba(195,245,60,.08);border:1px solid rgba(195,245,60,.32);color:#dfe3e8}
body[data-report] .rerun-banner.hidden{display:none}
body[data-report] .rerun-banner .btn-spin{border-color:rgba(195,245,60,.30);
  border-top-color:#c3f53c;margin-right:9px}
@keyframes btnspin{to{transform:rotate(360deg)}}


/* ── ordering cards: one neutral card for every provider (12 Aug) ──────────
   Same move as the home page. The card was tinted with the provider's brand,
   so four providers meant four different card colours in one row - teal, green,
   brown, near-black - none of which said anything the logo had not. Colour on
   this row now only ever means direct vs marketplace, which is the distinction
   the section exists to draw. */
body[data-report] .ord-prov,
body[data-report] .ord-prov[style],
body[data-report] a.ord-prov[style]{
  background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.16)}
body[data-report] a.ord-prov:hover,
body[data-report] a.ord-prov[style]:hover{
  background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.32)}
/* the logo tile is the only brand colour left on the card */
body[data-report] .ord-prov-logo{background:#fff;border:0;
  box-shadow:0 0 0 1px rgba(0,0,0,.25)}

body[data-report] .rerun-banner.is-done{background:rgba(195,245,60,.10);
  border-color:rgba(195,245,60,.45);color:#f2f4f6}
body[data-report] .rerun-banner.is-done b{color:#c3f53c;margin-right:2px}


/* ── reply cards: buttons on one line (12 Aug) ─────────────────────────────
   The card was a plain block, so "Draft reply" sat wherever the review text
   happened to stop. A one-line review put it four rows above a long one in the
   same row. Same fix as the channel cards: column, text takes the slack. */
body[data-report] #replies-box #replies{align-items:stretch}
body[data-report] .reply-card{display:flex;flex-direction:column}
body[data-report] .reply-card .reply-text{flex:1 1 auto;margin-bottom:12px}
body[data-report] .reply-card .reply-draft{align-self:flex-start;margin-top:auto}
/* a drafted reply appears under the button and must not fight it for the floor */
body[data-report] .reply-card .reply-out{flex:0 0 auto;margin-top:10px}


/* ── "couldn't confirm an order link" (12 Aug) ─────────────────────────────
   Was a red box asserting the listing HAS no order button, off the back of an
   empty scrape. Neutral now, because the claim is about our reading, not their
   listing. The instructions stay - they are useful either way. */
body[data-report] .ord-unconfirmed{display:flex;flex-direction:column;gap:7px;
  margin:12px 0 0;padding:13px 15px;border-radius:9px;font-size:13px;line-height:1.55;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.16);color:#b6bdc6}
body[data-report] .ord-unconfirmed b{color:#f2f4f6;font-size:13.5px}
body[data-report] .ord-unconfirmed a{color:#c3f53c;text-decoration:none;
  border-bottom:1px solid rgba(195,245,60,.4)}
body[data-report] .ord-unconfirmed a:hover{border-bottom-color:#c3f53c}


/* ── selected tile button (14 Aug) ─────────────────────────────────────────
   .tile-select.is-sel used var(--ink) for its background with white text. In
   the light theme --ink is near-black, so that read fine; under data-report it
   flips to #f2f4f6 and you get white on white — 1.07:1. The selected state also
   should not shout like the unselected one: "Select" is the action and wears
   solid lime, "Selected" is a state and wears the outline. */
body[data-report] .tile-select.is-sel,
body[data-report] .tile-select.is-sel:hover{
  background:rgba(195,245,60,.12);color:#c3f53c;
  box-shadow:0 0 0 1px #c3f53c inset}


/* The Select hover was #0f47a3 - a blue from the light theme, which has no
   business in a dark shell whose only accent is lime. */
body[data-report] .tile-select{background:#c3f53c;color:#1a2400;font-weight:700}
body[data-report] .tile-select:hover{background:#d3ff5c;color:#1a2400}

/* ── channel cards: room to breathe (16 Aug) ────────────────────────────────
   Everything was packed into ~11px gaps with the provider tiles taking up the
   slack, so the header, the two numbers and the order chips all ran together
   and the card read as one dense block. A minimum height plus real space
   between the four parts lets each one be its own thing. The gaps grow rather
   than the padding, so the extra height goes where the content is. */
.ch-card{gap:18px;padding:28px 26px 26px;min-height:342px}
.ch-top{gap:14px;padding-bottom:2px}
.ch-ic{width:44px;height:44px}
.ch-ic svg{width:22px;height:22px}
.ch-id h3{font-size:17px}
.ch-ring{width:64px;height:64px}
.ch-ring b{font-size:22px}
/* the two numbers get their own band, separated from the header above */
.ch-stats{gap:14px;padding:4px 0 2px;border-top:1px solid rgba(255,255,255,.07);
  padding-top:16px}
.ch-stat b{font-size:22px}
.ch-stat em{font-size:11.5px}
/* the label sits closer to the chips it introduces than to the numbers above */
.ch-lab{margin-top:2px;margin-bottom:-6px}
.ch-card .ol-prov{height:42px}
.ch-cta{padding:12px 14px;font-size:14px}
@media(max-width:900px){.ch-card{min-height:0}}

/* ── channel card header, second pass (16 Aug) ──────────────────────────────
   The score was a 58px ring tucked in the top-right corner, competing with the
   name for the same row and reading as a badge rather than the number the card
   exists to report. It leads now: centred, 92px, with the channel underneath
   it. The eyebrow sits tight to it so "CHANNEL" labels the block it belongs to
   instead of floating a card-width away. */
.ch-card .ins-kind{margin-bottom:-4px;text-align:center;display:block}
.ch-top{display:grid;grid-template-columns:auto auto;
  grid-template-areas:"ring ring" "ic id";
  justify-content:center;align-items:center;gap:10px 10px;padding-bottom:4px}
.ch-card .ch-ring{grid-area:ring;justify-self:center;width:92px;height:92px}
.ch-card .ch-ring b{font-size:31px;letter-spacing:-.02em}
.ch-card .ch-ring svg circle{stroke-width:5}
.ch-card .ch-ic{grid-area:ic;width:30px;height:30px}
.ch-card .ch-ic svg{width:16px;height:16px}
.ch-card .ch-id{grid-area:id;flex:none;text-align:left;max-width:15ch}
.ch-card .ch-id h3{font-size:18px;letter-spacing:-.01em}
.ch-card .ch-sub{font-size:12px}
/* the numbers centre with the header above them — a centred score over a
   left-ranged pair of stats reads as two cards stuck together */
.ch-card .ch-stats{text-align:center;padding-top:18px}
.ch-card .ch-stat{align-items:center}
.ch-card .ch-lab{text-align:center}

/* ── channel name: centred, and the icon off the baseline (16 Aug) ──────────
   The icon sat beside the name, so the pair was centred but the NAME wasn't —
   it read as offset, and the longer the name the worse it looked. The icon
   becomes a badge on the foot of the ring, the way a platform mark sits on an
   avatar. That frees the name to centre on the card's true axis and gives it
   room to go up to 22px. */
.ch-top{position:relative;display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:4px;padding-bottom:2px}
.ch-card .ch-ring{order:-1;margin-bottom:16px}
.ch-card .ch-ic{position:absolute;left:50%;top:74px;transform:translateX(-50%);
  width:30px;height:30px;background:#31343c;border:1px solid rgba(255,255,255,.26);
  box-shadow:0 0 0 3px #2b2e35}
.ch-card .ch-id{max-width:none;text-align:center}
.ch-card .ch-id h3{font-size:22px;line-height:1.15}
.ch-card .ch-sub{font-size:12.5px;margin-top:3px}

/* one more step up: the score is the headline of the card, so it carries the
   weight, and the channel name matches it rather than trailing behind */
.ch-card .ch-ring{width:106px;height:106px;margin-bottom:18px}
.ch-card .ch-ring b{font-size:37px}
/* the badge follows the ring's foot — it is positioned, not laid out, so it
   does not move on its own when the ring grows */
.ch-card .ch-ic{top:86px;width:32px;height:32px}
.ch-card .ch-ic svg{width:17px;height:17px}
.ch-card .ch-id h3{font-size:25px}
.ch-card .ch-sub{font-size:13px}

/* no artwork yet: the icon sits in the same frame rather than filling it */
.dir-rows .dir-art .dir-ic{width:74px;height:74px;grid-area:auto}
.dir-rows h3{grid-area:head;margin:0;font-size:23px;line-height:1.15;align-self:end}
.dir-rows p{grid-area:body;margin:0;max-width:52ch;font-size:14px;line-height:1.55}
.dir-rows .go{grid-area:go;align-self:end;justify-self:start;margin-top:6px}
/* the review ring is the visual on its side of the page — same frame, so the
   two sections scan as one rhythm down the page */
.dir-rows .dir-side{display:flex;flex-direction:column;align-items:center;gap:10px;
  width:210px;height:172px;justify-content:center}
.dir-rows .dir-score{width:112px;height:112px}
.dir-rows .dir-score b{font-size:38px}
@media(max-width:820px){
  .dir-rows .dir-card{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"art" "head" "body" "go";row-gap:12px}
  .dir-rows .dir-art,.dir-rows .dir-side{width:100%;height:150px}
}

/* scope and count sit with the title, not in the button label — "21 saved
   Open →" read as one broken sentence */
.dir-scope,.dir-badge{font-style:normal;font:700 11px/1 Inter,system-ui,sans-serif;
  letter-spacing:.08em;text-transform:uppercase;padding:5px 9px;border-radius:999px}
.dir-scope{color:#b6bdc6;background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.14)}
.dir-badge{color:#1a2400;background:#c3f53c}
.dir-stat{grid-area:stat;font-size:12.5px;color:#7d838d;line-height:1.5}
/* the library shows four, so it reads as a shelf rather than repeating the
   single thumbnail of the row above it */
.dir-rows .dir-art-4{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;
  gap:6px;padding:8px;place-items:stretch}
.dir-rows .dir-art-4 img{width:100%;height:100%;object-fit:cover;border-radius:6px}

/* the newest of each kind, fanned — one picture made of your actual work */
.dir-showcase img{position:absolute;border-radius:8px;box-shadow:0 18px 40px rgba(0,0,0,.55);
  object-fit:cover;background:#1e2126}
.dir-showcase img:nth-child(1){width:44%;left:9%;top:12%;transform:rotate(-7deg);z-index:1}
.dir-showcase img:nth-child(2){width:46%;left:33%;top:22%;transform:rotate(4deg);z-index:3}
.dir-showcase img:nth-child(3){width:38%;left:60%;top:9%;transform:rotate(11deg);z-index:2}
.dir-showcase .dir-ic{position:static;width:84px;margin:auto;display:block;padding-top:120px}
.dir-cards{display:flex;flex-direction:column;gap:12px}
/* compact: title row, one line of copy, the stat, the action */
.dir-cards .dir-mini{flex:1 1 0;display:flex;flex-direction:column;gap:6px;
  padding:18px 20px;justify-content:center}
.dir-cards .dir-mini h3{margin:0;font-size:19px}
.dir-cards .dir-mini p{margin:0;font-size:13.5px;line-height:1.5;max-width:46ch}
.dir-cards .dir-mini .dir-stat{font-size:12px}
.dir-cards .dir-mini .go{margin-top:4px;align-self:flex-start}
@media(max-width:900px){
  .dir-create{grid-template-columns:minmax(0,1fr)}
  .dir-showcase{min-height:220px}
}

/* Review gets the same half-and-half shape as Create */
.dir-create-rev .dir-cards .dir-card{flex:1 1 0}
.dir-create-rev .dir-rows{display:contents}
/* Review rows keep their ring, but sized for a compact card, not a hero slot */
.dir-create-rev .dir-side{display:flex;align-items:center;gap:12px;width:auto;height:auto}
.dir-create-rev .dir-score{width:54px;height:54px}
.dir-create-rev .dir-score b{font-size:19px}
.dir-create-rev .dir-card{display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-areas:"art head" "art body" "art go";column-gap:16px;row-gap:5px;
  align-items:center;padding:18px 20px}
.dir-create-rev .dir-card h3{grid-area:head;margin:0;font-size:18px}
.dir-create-rev .dir-card p{grid-area:body;margin:0;font-size:13px;line-height:1.5}
.dir-create-rev .dir-card .go{grid-area:go;justify-self:start;margin-top:4px}

/* the section headings were a 11px eyebrow — too quiet to divide a page this
   long into parts you can find by scrolling */
.dir-lab{font:800 26px/1.1 'Honey Basil',var(--display),system-ui,sans-serif;
  letter-spacing:.01em;text-transform:none;color:var(--ink);margin:34px 0 16px}

/* ── three across, with the chips and stat line kept (16 Aug) ───────────────
   Back to a 3x1 row after trying full-width rows and a half-and-half with one
   shared visual. What survives from those: the scope/count chip beside the
   title, and the stat line — both earn their place in a narrow column too. */
.dir-head{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.dir-head h3{margin:0}
.dir-scope,.dir-badge{font-style:normal;font:700 10.5px/1 Inter,system-ui,sans-serif;
  letter-spacing:.07em;text-transform:uppercase;padding:4px 8px;border-radius:999px}
.dir-scope{color:#b6bdc6;background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.14)}
.dir-badge{color:#1a2400;background:#c3f53c}
.dir-stat{font-size:12px;color:#7d838d;line-height:1.5;margin-top:2px}

/* The card is a named grid — "title ic" / "desc ic" / "go ic" — so it only
   places children it knows. Wrapping the h3 in .dir-head and adding .dir-stat
   left both unplaced: they were auto-flowed into new implicit tracks, which
   squeezed the text column to one word wide and dropped the icon over the
   title. Give the new children their own areas. */
.dir-card{grid-template-areas:"title ic" "desc ic" "stat ic" "go ic";
  grid-template-rows:auto auto auto 1fr}
.dir-card .dir-head{grid-area:title;align-self:start}
.dir-card .dir-stat{grid-area:stat;align-self:start;margin-top:8px}
/* the chip sits beside the title; the title itself no longer holds the area */
.dir-card .dir-head h3{grid-area:auto;align-self:baseline}

/* The phone treatment above collapses all seven steps to 44px chips and sets
   `#stepper{gap:4px}` so the row fits: 7x44 + 6x4 = 332px inside 390. But
   `body[data-report] #stepper{gap:26px}` further down carries an attribute AND
   an id, so it out-specified the media rule and the gap stayed 26px — the row
   measured 464px and the last chip sat 37px past the right edge. Same
   specificity, stated later, only on phones. */
@media(max-width:560px){
  body[data-report] #stepper{gap:4px}
}

/* ── phone: one page header, not two ──────────────────────────────────────
   Every data-report page renders .pagehead from base.html AND its own
   #stagehead. Two <h1>s and two subtitles saying the same thing, ~530px of a
   ~745px viewport spent before the first control. #stagehead is the one worth
   keeping: it changes per stage, .pagehead never does. */
@media (max-width:700px){
  body[data-report] .pagehead{display:none}
}

/* ── --faint was carrying live content ───────────────────────────────────
   This file's own token comment says faint is the DISABLED/EMPTY tone and
   never live text. Measured: #7d838d is 3.26:1 on the card and 4.23:1 on the
   ground — both under 4.5. --muted (#b6bdc6) is 6.57:1 and 8.52:1. Same
   palette, no brand change; these selectors were just reaching for the wrong
   one. Reads fine at a desk, gone in a kitchen at half brightness. */
.wp-card span,          /* what each paper size and QR option actually means */
.pc-claim,              /* the flyer's own headline, previewed on every purpose card */
.fp-cw-lab,             /* the colour names under all 16 swatches */
.fp-fld > span,         /* "Dish name" */
.sv-when,               /* Today / Yesterday — the whole navigation of /saved */
.soc-back,              /* the only way back out of the food builder */
.pw-fine,               /* "Cancel any time. Card handled by Stripe." */
.dir-stat, .wp-lab, .fe-lab, .dl-size, .bl-row em, .lw-f > span,
.fp-sizenote{color:var(--muted)}
.fp-fld input::placeholder{color:var(--muted);opacity:.8}

/* ── phone: stop iOS zooming the page on every input ──────────────────────
   Safari auto-zooms any field under 16px, and the viewport meta correctly has
   no maximum-scale. Type six characters into the brand hex box and the page
   sits at 150% until you fix it by hand. */
@media (max-width:560px){
  /* !important on purpose: a bare `input` loses to every `.thing input` in the
     codebase, and this isn't a style preference — under 16px, Safari zooms and
     the user has to pinch back out. One platform rule, stated once. */
  input,select,textarea{font-size:16px !important}
}

/* ── phone: two tiles across, not one ─────────────────────────────────────
   17 designs at one-per-screen is ~8,000px of scroll, and comparing options is
   the entire job of a board — you end up remembering tile 3 while looking at
   tile 11. At 2-up, six fit a screen. The "Bigger" pill is already there for
   reading detail. */
@media (max-width:480px){
  #tiles.tilegrid,.tilegrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .tilegrid .cap{flex-direction:column;align-items:stretch;gap:6px}
  .tilegrid .cap-txt span{display:-webkit-box;-webkit-line-clamp:2;
    -webkit-box-orient:vertical;overflow:hidden}
  .tilegrid .tile-select,.tilegrid .cap .btn{width:100%;min-height:44px;
    justify-content:center}
  .tile-group > h3{position:sticky;top:104px;z-index:3;
    background:var(--ground);padding:8px 0 6px;margin:0}
}

/* ── phone: things you tap should be tappable ─────────────────────────────
   Apple and Google both put the floor at 44px. Measured before this: .btn.sm
   was 30px, the per-size PNG/PDF links about 27x18, the paywall close 28x33 in
   the top-right — the hardest point on a 390x844 screen to reach one-handed.
   #sv-groups .soc-tab was already 44px; that's the pattern, applied outward. */
@media (max-width:560px){
  .btn.sm{min-height:44px;padding:10px 14px}

  /* one full-width row per paper size, PNG and PDF as tappable ends */
  .lib-papers{flex-direction:column;gap:5px}
  .lib-paper{padding:0 0 0 11px;gap:0;justify-content:space-between;width:100%;
    min-height:44px;align-items:center}
  .lib-paper a,.lib-paper .lnk{min-height:44px;display:inline-flex;align-items:center;
    padding:0 13px}

  /* the close X, and a Not now where the thumb actually is */
  .pw-x button{width:44px;height:44px;font-size:26px;color:var(--muted)}
  .pw-lead .lw-f input{min-height:44px}

  /* "Print-ready (3mm bleed + CMYK .tif)" was a 22px row */
  .downloads .opt{min-height:44px;margin:4px 0}

  /* the food page's format switcher missed the 44px the /saved pills got */
  .soc-tab{min-height:44px;display:inline-flex;align-items:center}
}

/* ── phone: the stepper says nothing, so replace it ───────────────────────
   All seven chips render label-less (the font-size:0 rule catches the active
   one too), so the row is seven identical circles 44px tall. The stage title
   below already names where you are; what's missing is where Back goes. */
@media (max-width:560px){
  #stepper{display:none}
  .wiz-top{justify-content:space-between;gap:10px}
  .wiz-top #back{min-height:44px}
  .wiz-count{font-size:12.5px;color:var(--muted);letter-spacing:.03em;
    font-variant-numeric:tabular-nums;white-space:nowrap}
}
@media (min-width:561px){ .wiz-count{display:none} }

/* ── phone: the same three scores were rendered twice ─────────────────────
   Channel cards at the top, then the same website/instagram/google trio again
   ~1,600px down as review cards. On desktop they sit as summary and action; in
   a single column they read as two different features. ~750px back. */
@media (max-width:560px){
  .dir-review-row,.dir-review-sep{display:none}
}

/* ── phone: the step rail gives its gutter back ───────────────────────────
   30px number + 16px gap = 46px of a 346px column, the full length of the
   page, for a numeral. The number moves inline with the heading; the connector
   line goes (it draws nothing useful in a single column); a locked step
   collapses from a ~90px dashed box to one quiet line — arriving at the food
   page put ~500px of "…lands here" boxes below the fold. */
@media (max-width:560px){
  body[data-report] .p-step{grid-template-columns:minmax(0,1fr);gap:0}
  body[data-report] .p-step:not(:last-child)::before{display:none}
  body[data-report] .p-num{width:24px;height:24px;font-size:12px;
    float:left;margin:1px 9px 0 0}
  body[data-report] .p-rail{gap:24px}
  body[data-report] .p-step.off .p-wait{padding:10px 0;border:0;background:none;
    text-align:left;min-height:44px;display:flex;align-items:center}
}

