/* Acme Company Performance Dashboard — public example site, built by scripts/build-sample-assets.ts. Single dark theme, values from the Apex PDP treatment (spec section 7). */
:root{
  color-scheme:dark;
  --plane:#0b0c0f; --surface:#12141a; --surface-2:#171a21;
  --line:#242832; --line-2:#2e3340;
  --ink:#f4f5f7; --ink-2:#d5d9e0; --muted:#a4abb7; --muted2:#7c8391;
  --brand:#7dc23b; --brand2:#8fd94a; --blue:#57b8ff;
  --f1:#c8e8a0; --f2:#a6d873; --f3:#7dc23b; --f4:#5da42b; --f5:#41871f;
  --bar:#7dc23b; --accent:#7dc23b; --accent-soft:rgba(125,194,59,.13);
  --prior:#3a4152; --neutral:#2e3340;
  --ver:#7dc23b; --lik:#41871f; --untraced:#2e3340;
  --good:#8fd94a; --warn:#e0a52a; --crit:#ff8a8a;
  --good-bg:rgba(125,194,59,.14); --crit-bg:rgba(255,138,138,.13); --warn-bg:rgba(224,165,42,.13);
  --band:#0b0c0f; --band-ink:#ffffff; --band-2:#1b1e26;
  --r:14px; --r2:8px;
  /* One hue per section. Green stays the brand and the hero; the rest are saturated and
     electric, never pastel. A frame re-scopes --surface/--line from its own hue, so every
     panel, table and bar inside it picks up the tint without a second set of rules. */
  --c-ov:#7dc23b; --c-ad:#3d8bff; --c-pr:#ff9f1c; --c-bk:#e040fb; --c-on:#19d3e6; --c-ch:#9aa3b2;
}

*{box-sizing:border-box}
html,body{margin:0}
body{
  background:var(--plane); color:var(--ink);
  font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:14px; line-height:1.45; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
[hidden]{display:none!important}
.wrap{max-width:1180px; margin:0 auto; padding-inline:16px; padding-block:0 56px}
.mono{font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace}
.eyebrow{font-family:"IBM Plex Mono",ui-monospace,monospace; font-size:10.5px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted)}
.num{font-variant-numeric:tabular-nums}
.sr-only{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
.empty{color:var(--muted); font-size:12.5px; padding:6px 0}

/* ---------- header ---------- */
header.top{position:sticky; top:0; z-index:30; background:var(--band); border-bottom:1px solid var(--line)}
.top-inner{max-width:1180px; margin:0 auto; padding:14px 16px 12px; display:flex; flex-wrap:wrap; gap:14px 20px; align-items:center}
.brand{display:flex; align-items:center; gap:12px; margin-right:auto; min-width:0}
.brand .mark{height:30px; width:auto; flex:none; display:block}
.brandname{display:flex; align-items:baseline; gap:10px; min-width:0}
.brand b{font-weight:900; letter-spacing:-.01em; text-transform:uppercase; font-size:16px; color:var(--band-ink); white-space:nowrap}
.brand .sub{font-weight:600; color:var(--muted2); font-size:12px; text-transform:uppercase; letter-spacing:.14em; white-space:nowrap}
/* Seven ranges will not fit on a phone, so the row scrolls sideways inside its own wrapper
   rather than pushing the page wide. */
.segwrap{max-width:100%; overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch}
.segwrap::-webkit-scrollbar{display:none}
.seg{display:inline-flex; background:var(--band-2); padding:3px; gap:2px; border-radius:var(--r2); border:1px solid var(--line)}
.seg button{font:inherit; font-size:11.5px; font-weight:700; color:var(--muted); letter-spacing:.07em;
  text-transform:uppercase; background:none; border:0; padding:6px 14px; cursor:pointer; border-radius:5px; white-space:nowrap}
.seg button:hover{color:var(--ink)}
.seg button[aria-pressed="true"]{background:var(--brand); color:#0b0c0f}
.seg button:focus-visible{outline:2px solid var(--brand); outline-offset:2px}
@media (max-width:760px){
  /* The mark carries the brand on a phone; the two lines of type would push the range row
     off the header, so the wordmark stacks and the subtitle drops below it. */
  .brandname{flex-direction:column; align-items:flex-start; gap:1px}
  .brand .sub{font-size:10px; letter-spacing:.1em}
}
@media (max-width:620px){
  .brand .mark{height:26px}
  .brand b{font-size:14px}
  .brand .sub{display:none}
  .top-inner{gap:10px 14px}
}
/* Seven presets needed an abbreviated form on a phone; four do not, so the labels stay spelled
   out and only the padding tightens. */
@media (max-width:480px){
  .seg button{padding:6px 9px; letter-spacing:.04em}
}
@media (max-width:380px){
  .seg button{padding:6px 6px; font-size:11px; letter-spacing:.02em}
  .wrap{padding-inline:12px}
}
.stampwrap{display:flex; flex-direction:column; align-items:flex-end; gap:2px; line-height:1.3}
.stamp{font-size:11.5px; color:var(--muted2); white-space:nowrap}
.refreshbtn{font:inherit; font-size:11px; font-weight:600; color:var(--brand); background:none; border:0;
  padding:0; cursor:pointer; white-space:nowrap; text-decoration:underline; text-underline-offset:2px;
  text-decoration-color:color-mix(in srgb, var(--brand) 45%, transparent)}
.refreshbtn:hover:not(:disabled){text-decoration-color:var(--brand)}
.refreshbtn:disabled{color:var(--muted2); cursor:default; text-decoration:none}
.refreshbtn:focus-visible{outline:2px solid var(--brand); outline-offset:2px; border-radius:3px}
@media (max-width:620px){.stampwrap{align-items:flex-start}}
.mockflag{font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:600; letter-spacing:.1em;
  text-transform:uppercase; color:var(--warn); border:1px solid rgba(224,165,42,.4); padding:3px 8px; border-radius:5px; background:var(--warn-bg)}

/* ---------- panels ---------- */
.panel{background:var(--surface); border:1px solid var(--line); border-radius:var(--r); min-width:0}
.panel-head{display:flex; flex-wrap:wrap; gap:6px 16px; align-items:baseline; padding:14px 18px 0}
.panel-head h3{margin:0; font-size:13.5px; font-weight:900; letter-spacing:-.02em; text-transform:uppercase; display:inline-flex; align-items:center; gap:9px}
.ico{width:15px; height:15px; flex:none; color:var(--brand); opacity:.92}
.panel-head .hint{font-size:12px; color:var(--muted); margin-left:auto}
.panel-body{padding:14px 18px 18px}
/* Applied when a load fails and the figures on screen belong to the previous view. The banner
   says so in words; this stops the numbers reading as current at a glance. */
.wrap.stale .frame{opacity:.45; filter:saturate(.5)}

/* ---------- framed sections ----------
   Each section is one large rounded object on the black plane: a thick coloured rail, a tinted
   header strip with a numbered chapter marker, and a body washed in the same hue. Black gaps
   separate them, so the frame is the shape the eye reads rather than thirteen separate panels. */
.frame{position:relative; margin-top:36px; border-radius:20px; overflow:hidden; scroll-margin-top:72px;
  --surface:color-mix(in srgb, var(--c) 7%, #12141a);
  --surface-2:color-mix(in srgb, var(--c) 10%, #171a21);
  --line:color-mix(in srgb, var(--c) 24%, #12141a);
  --line-2:color-mix(in srgb, var(--c) 34%, #12141a);
  /* Bars, minibars and badges inside a frame take its hue too, so the colour runs through the
     content and not only the chrome. Up and down chips keep their own green and red: those
     carry meaning and must not change from section to section. */
  --brand:var(--c); --brand2:var(--c); --accent:var(--c); --bar:var(--c);
  --accent-soft:color-mix(in srgb, var(--c) 14%, transparent);
  --ver:var(--c); --lik:color-mix(in srgb, var(--c) 55%, #0b0c0f);
  background:var(--surface);
  border:1px solid color-mix(in srgb, var(--c) 34%, transparent); border-left:7px solid var(--c);
  box-shadow:0 0 0 1px rgba(0,0,0,.4), 0 34px 80px -46px color-mix(in srgb, var(--c) 55%, transparent)}
/* #buildNote is the last thing before the first frame; the old selectors named #loadError
   and .wrap's first child, neither of which is ever the frame. */
#buildNote + .frame{margin-top:20px}
.frame.ov{--c:var(--c-ov)} .frame.ad{--c:var(--c-ad)} .frame.pr{--c:var(--c-pr)}
.frame.bk{--c:var(--c-bk)} .frame.on{--c:var(--c-on)} .frame.ch{--c:var(--c-ch)}
.fhead{display:flex; align-items:center; gap:18px; padding:16px 24px 15px;
  background:linear-gradient(90deg, color-mix(in srgb, var(--c) 26%, transparent), color-mix(in srgb, var(--c) 12%, transparent) 45%, color-mix(in srgb, var(--c) 6%, transparent));
  border-bottom:1px solid color-mix(in srgb, var(--c) 45%, transparent)}
.chap{font-family:"IBM Plex Mono",monospace; font-size:13px; font-weight:600; letter-spacing:.06em;
  background:var(--c); color:#0b0c0f; padding:8px 10px; border-radius:7px; line-height:1; flex:none}
.fhead .ttl{display:flex; flex-direction:column; gap:4px; min-width:0}
.fhead .eyebrow{color:var(--c); white-space:nowrap}
.sectitle{margin:0; font-size:26px; font-weight:900; letter-spacing:-.025em; text-transform:uppercase; line-height:1; color:#fff}
.frame.ov .sectitle{font-size:32px}
.fhead .meta{margin-left:auto; text-align:right; font-family:"IBM Plex Mono",monospace; font-size:10.5px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink-2); line-height:1.6}
.fhead .meta .st{display:inline-block; margin-left:10px; padding:2px 8px; border-radius:4px;
  background:color-mix(in srgb, var(--c) 18%, transparent); color:#fff; letter-spacing:.06em}

/* Inside a frame the panels lose their own borders and are split by hairlines, so the frame
   stays the dominant shape. */
.fbody{display:flex; flex-direction:column; gap:1px; background:var(--line)}
.frame .panel{background:var(--surface); border:0; border-radius:0}
.frame .panel-head{padding:18px 24px 0}
.frame .panel-body{padding:13px 24px 22px}
.frame .notewrap{padding:16px 24px}
.split{display:grid; gap:1px; background:var(--line)}
.split > *{background:var(--surface); min-width:0}
.split.s-15{grid-template-columns:1.55fr 1fr}
.split.s-11{grid-template-columns:1fr 1fr}

/* ---------- kpi grids ----------
   Store overview leads with one oversized tile: at a glance the owner reads net revenue, then
   the six supporting figures. The advertising strip is always four equal tiles. */
.kgrid{display:grid; grid-template-columns:1.75fr 1fr 1fr 1fr; grid-auto-rows:minmax(126px,auto); gap:1px; background:var(--line)}
.kgrid.ad{grid-template-columns:repeat(4,1fr); grid-auto-rows:auto}
.kgrid:empty{display:none}
.kgrid > .kpi{display:flex; flex-direction:column; justify-content:center}
.kgrid > .kpi.hero{grid-row:1/3; padding:30px 30px 28px;
  background:linear-gradient(158deg, color-mix(in srgb, var(--c) 18%, transparent), transparent 60%), var(--surface);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--c) 28%, transparent)}
.kpi.hero .kpihead{font-size:12px; letter-spacing:.1em; color:var(--c)}
/* The hero number has to survive both a narrower tile and a bigger figure: a year-long range
   reaches six digits, and at a fixed 84px that clips. */
.kpi.hero .v{font-size:clamp(46px, 5.4vw, 84px); letter-spacing:-.045em; line-height:.95; margin:14px 0 14px}
.kpi.hero .v small{font-size:.4em}
.kpi.hero .chip{font-size:14px; padding:4px 9px}
.kpi.hero .cmp{font-size:13px; margin-left:8px}
.kpi.hero .ctx{font-size:12.5px; color:var(--muted); margin-top:13px}
.kpi{background:var(--surface); padding:16px 20px 17px; min-height:96px; min-width:0}
.kpi .v{font-size:32px; font-weight:900; letter-spacing:-.03em; margin:8px 0 6px; line-height:1.05}
.kpi .v small{font-size:18px; font-weight:600; color:var(--ink-2)}
.chip{display:inline-flex; align-items:center; gap:4px; font-size:11.5px; font-weight:600; padding:2px 6px; border-radius:4px; font-variant-numeric:tabular-nums}
.chip.up{color:var(--good); background:var(--good-bg)}
.chip.down{color:var(--crit); background:var(--crit-bg)}
.chip.flat{color:var(--ink-2); background:var(--surface-2)}
.kpi .cmp{font-size:11.5px; color:var(--muted); margin-left:5px}
.kpi .cmp.solo{margin-left:0}
.kpihead{display:flex; align-items:center; gap:6px}
.kpi .ctx{font-size:11.5px; color:var(--muted2); margin-top:6px}

/* ---------- custom range button and picker ---------- */
.custombtn{display:inline-flex; align-items:center; gap:7px; font:inherit; font-size:11.5px; font-weight:700;
  letter-spacing:.07em; text-transform:uppercase; color:var(--muted); background:var(--band-2);
  border:1px solid var(--line); border-radius:var(--r2); padding:7px 12px; cursor:pointer; white-space:nowrap}
.custombtn svg{width:13px; height:13px; flex:none}
.custombtn:hover{color:var(--ink)}
.custombtn.on{background:var(--brand); border-color:var(--brand); color:#0b0c0f}
.custombtn:focus-visible{outline:2px solid var(--brand); outline-offset:2px}
/* Declared after the base rule on purpose: the same override placed with the other header
   breakpoints sat earlier in the file and silently lost the cascade. */
@media (max-width:620px){.custombtn{padding:6px 9px; letter-spacing:.04em}}
.picker{position:fixed; z-index:60; width:min(330px, calc(100vw - 24px)); background:var(--surface-2);
  border:1px solid var(--line-2); border-radius:12px; padding:14px; box-shadow:0 16px 44px rgba(0,0,0,.6)}
.pfields{display:grid; grid-template-columns:1fr 1fr; gap:10px}
.pfields label{display:flex; flex-direction:column; gap:5px; font-family:"IBM Plex Mono",monospace;
  font-size:10px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--muted)}
.pfields input{font:inherit; font-size:13px; font-variant-numeric:tabular-nums; color:var(--ink);
  background:var(--surface); border:1px solid var(--line-2); border-radius:7px; padding:7px 9px; width:100%}
.pfields input:focus-visible{outline:2px solid var(--brand); outline-offset:1px}
.ppresets{display:flex; flex-wrap:wrap; gap:6px; margin-top:11px}
.ppresets button{font:inherit; font-size:11.5px; font-weight:600; color:var(--ink-2); background:var(--surface);
  border:1px solid var(--line-2); border-radius:6px; padding:5px 9px; cursor:pointer}
.ppresets button:hover{border-color:var(--brand); color:var(--ink)}
.pnote{margin:11px 0 0; font-size:11.5px; line-height:1.45; color:var(--muted2)}
.perr{margin:9px 0 0; font-size:12px; line-height:1.45; color:var(--crit)}
.pactions{display:flex; justify-content:flex-end; gap:8px; margin-top:13px}
.pactions button{font:inherit; font-size:12px; font-weight:700; border-radius:7px; padding:7px 13px; cursor:pointer}
.pactions .ghost{color:var(--muted); background:none; border:1px solid var(--line-2)}
.pactions .ghost:hover{color:var(--ink)}
.pactions .primary{color:#0b0c0f; background:var(--brand); border:1px solid var(--brand)}
.pactions .primary:hover{background:var(--brand2)}
.pactions button:focus-visible{outline:2px solid var(--brand); outline-offset:2px}

/* ---------- provenance: the small "?" and its popover ---------- */
.qm{
  flex:none; margin-left:auto; width:15px; height:15px; padding:0; line-height:13px;
  font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:600;
  color:var(--muted2); background:none; border:1px solid var(--line-2); border-radius:50%;
  cursor:pointer; opacity:.7; transition:opacity .12s, color .12s, border-color .12s;
}
.panel-head h3 .qm{margin-left:2px}
.qm:hover,.qm[aria-expanded="true"]{opacity:1; color:var(--ink-2); border-color:var(--muted2)}
.qm:focus-visible{outline:2px solid var(--brand); outline-offset:2px; opacity:1}
.pop{
  position:fixed; z-index:60; background:var(--surface-2); border:1px solid var(--line-2);
  border-radius:10px; padding:12px 13px; box-shadow:0 10px 30px rgba(0,0,0,.5);
  font-size:12.5px; line-height:1.5; color:var(--ink-2); text-transform:none; letter-spacing:normal; font-weight:400;
}
.pop p{margin:0}
.pop a{display:inline-block; margin-top:9px; color:var(--brand); font-weight:600; font-size:12px; text-decoration:none}
.pop a:hover{text-decoration:underline}

/* Links out of a tile or a table row, kept quiet until hovered. */
a.kpilink{color:inherit; text-decoration:none; display:inline-flex; align-items:center; gap:3px}
a.kpilink:hover{color:var(--ink-2)}
a.kpilink .ext{font-size:9px; opacity:.55}
a.kpilink:hover .ext{opacity:1; color:var(--brand)}
a.rowlink{color:inherit; text-decoration:none; border-bottom:1px dotted var(--line-2)}
a.rowlink:hover{color:var(--brand); border-bottom-color:var(--brand)}
a.kpilink:focus-visible,a.rowlink:focus-visible{outline:2px solid var(--brand); outline-offset:2px}

/* ---------- grids ---------- */
.two{display:grid; grid-template-columns:1.55fr 1fr; gap:14px}
.two>*{min-width:0}
.two.even{grid-template-columns:1fr 1fr}
/* Both variants stack on narrow screens; .two.even is listed explicitly because its two-class
   selector would otherwise outrank this rule and keep the platform cards side by side at 158px. */
@media (max-width:860px){.two, .two.even{grid-template-columns:1fr}}

/* ---------- charts ---------- */
.chartbox{position:relative}
svg.chart{display:block; width:100%; height:auto; overflow:visible}
.chartblk .chartbox{margin-top:2px}
.legend:empty{display:none}
.legend{display:flex; gap:16px; flex-wrap:wrap; font-size:12px; color:var(--ink-2); margin:2px 0 8px}
.legend i{display:inline-block; width:16px; height:3px; border-radius:2px; margin-right:6px; vertical-align:middle}
.tip{position:absolute; pointer-events:none; opacity:0; transition:opacity .09s; background:var(--surface); border:1px solid var(--line-2);
  border-radius:10px; box-shadow:0 6px 20px rgba(0,0,0,.35); padding:8px 10px; font-size:12px; min-width:128px; z-index:10}
.tip b{display:block; font-size:11px; font-weight:600; color:var(--muted); margin-bottom:4px; font-family:"IBM Plex Mono",monospace; letter-spacing:.04em}
.tip .row{display:flex; justify-content:space-between; gap:14px; font-variant-numeric:tabular-nums}
.tip .row span:last-child{font-weight:600}

/* ---------- funnel ---------- */
.funnel{display:flex; flex-direction:column; gap:2px}
.fstage{display:grid; grid-template-columns:minmax(112px,auto) 1fr auto; gap:12px; align-items:center}
.ftrack{background:var(--surface-2); border-radius:5px; height:26px; position:relative; overflow:hidden}
.ffill{height:100%; border-radius:5px}
.fstage .lbl{font-size:12.5px; color:var(--ink-2)}
.fstage .val{font-size:13px; font-weight:600; font-variant-numeric:tabular-nums; min-width:74px; text-align:right}
.fdrop{font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--muted); padding-left:124px; height:15px; display:flex; align-items:center}
.fdrop.bad{color:var(--crit)}
.funnelsum{font-size:12px; color:var(--ink-2); border-top:1px solid var(--line); margin-top:12px; padding-top:11px}
@media (max-width:480px){.fstage{grid-template-columns:minmax(88px,auto) 1fr auto}.fdrop{padding-left:100px}}

/* ---------- ranked bars ---------- */
.ranked{display:flex; flex-direction:column; gap:11px}
.rrow{display:grid; grid-template-columns:1fr auto; gap:4px 12px; align-items:baseline}
.rrow .name{font-size:13px; font-weight:500; min-width:0; overflow-wrap:anywhere}
.rrow .figs{font-size:12.5px; color:var(--ink-2); font-variant-numeric:tabular-nums; white-space:nowrap}
.rrow .figs b{color:var(--ink); font-weight:600}
.rtrack{grid-column:1/-1; height:9px; background:var(--surface-2); border-radius:4px; overflow:hidden}
.rfill{height:100%; background:var(--bar); border-radius:4px}
.rfill.other{background:var(--line-2)}
.flag{font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; padding:1px 6px; border-radius:4px; margin-left:7px; white-space:nowrap}
.flag.low{color:var(--crit); background:var(--crit-bg)}
.flag.sub{color:var(--accent); background:var(--accent-soft)}
.flag.merge{color:var(--muted); background:var(--surface-2); border:1px solid var(--line-2); cursor:help}

/* The headline share of product revenue, so the products frame leads with a number rather
   than a sentence. */
.callout{display:flex; align-items:center; gap:16px; margin-top:20px; padding:4px 0 4px 16px; border-left:3px solid var(--c)}
.callout b{font-size:38px; font-weight:900; letter-spacing:-.035em; line-height:1; color:var(--c); flex:none; font-variant-numeric:tabular-nums}
.callout span{font-size:13px; line-height:1.45; color:var(--ink-2)}
.callout span strong{color:var(--ink); font-weight:700}
@media (max-width:700px){.callout{gap:12px; margin-top:16px}.callout b{font-size:32px}}

/* ---------- tables ---------- */
.tblwrap{overflow-x:auto; -webkit-overflow-scrolling:touch}
table{border-collapse:collapse; width:100%; font-size:12.5px; min-width:460px}
th,td{padding:8px 10px; text-align:right; border-bottom:1px solid var(--line); white-space:nowrap}
th:first-child,td:first-child{text-align:left; white-space:normal}
thead th{font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:var(--muted); border-bottom:1px solid var(--line-2)}
tbody td{font-variant-numeric:tabular-nums; color:var(--ink-2)}
tbody td:first-child{color:var(--ink); font-weight:500}
tbody tr:last-child td{border-bottom:0}
td .minibar{display:block; height:4px; min-width:2px; border-radius:2px; background:var(--bar); margin-top:4px}
td.best{color:var(--brand); font-weight:600}
td.zero{color:var(--muted2)}

/* ---------- AOV levers ---------- */
.levers{display:grid; grid-template-columns:repeat(auto-fit,minmax(196px,1fr)); gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r2); overflow:hidden}
.lever{background:var(--surface); padding:14px 15px 16px; display:flex; flex-direction:column; gap:5px}
.lever .v{font-size:23px; font-weight:900; letter-spacing:-.025em; font-variant-numeric:tabular-nums; line-height:1.1}
.lever .sub{font-size:12px; color:var(--muted); font-variant-numeric:tabular-nums}
.lever .st{margin-top:2px}
.lever .cmp{font-size:11px; color:var(--muted); margin-left:5px}
.livebadge{font-family:"IBM Plex Mono",monospace; font-size:9.5px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--brand); background:var(--accent-soft); border:1px solid color-mix(in srgb, var(--brand) 40%, transparent); padding:2px 7px; border-radius:4px}
.leverfoot{display:flex; flex-wrap:wrap; gap:6px 22px; font-size:12.5px; color:var(--muted); border-top:1px solid var(--line); margin-top:14px; padding-top:13px; font-variant-numeric:tabular-nums}
.leverfoot:empty{display:none}
.leverfoot b{color:var(--ink-2); font-weight:600}

/* ---------- paid buckets ---------- */
.buckets{display:flex; flex-direction:column; gap:18px}
/* align-content:start matters more than it looks. The two cards share a row, so the grid makes
   them equal height, and a grid's default align-content stretches its auto rows to fill any
   slack. The shorter card was inflating its own header and ROAS line by several pixels each,
   which pushed its bar down and left the two bars visibly out of line. Slack now collects at the
   bottom of the card instead, so the rows match across both. */
/* Platform cards. The frame system paints everything inside a section in that section's one hue,
   which is what made Meta and Google indistinguishable. --pf is each platform's own accent and is
   the only colour in here that does NOT come from the section, so the two cards separate at a
   glance while the bar segments still mean the same thing on both. */
.pf{display:grid; grid-template-columns:1fr; gap:9px; align-content:start;
  background:var(--surface-2); border:1px solid var(--line);
  border-left:4px solid var(--pf,var(--line-2)); border-radius:var(--r2); padding-bottom:13px}
.pf-meta{--pf:#0866ff}
/* Google's own blue is a near-match for this section's blue, so the card takes the amber from the
   same brand palette instead. Against Meta's blue it is unmistakable, which is the whole job. */
.pf-google{--pf:#f9ab00}
.pf > :not(.hdr){margin-left:14px; margin-right:14px}
.pf .hdr{display:flex; flex-wrap:wrap; gap:6px 11px; align-items:center; padding:10px 14px;
  background:linear-gradient(90deg, color-mix(in srgb, var(--pf,var(--c)) 24%, transparent), transparent 72%);
  border-bottom:1px solid var(--line)}
.pf .hdr .logo{flex:none; display:block}
/* nowrap on both: "GOOGLE ADS" is longer than "META", so at in-between widths its header wrapped
   to a second line while Meta's did not, and every row below it sat lower than its neighbour. The
   two cards sit side by side and must stay in step. */
.pf .hdr{flex-wrap:nowrap}
.pf .hdr h4{margin:0; font-size:13.5px; font-weight:900; text-transform:uppercase; letter-spacing:-.02em; color:#fff;
  white-space:nowrap; min-width:0; overflow:hidden; text-overflow:ellipsis}
/* The spend is what the reader came to this card for, so it is set as a figure rather than as a
   caption. At 12.5px muted it was quieter than the ROAS line below it and read as a footnote. */
.pf .hdr .spend{margin-left:auto; display:flex; align-items:baseline; gap:7px; font-variant-numeric:tabular-nums}
.pf .hdr .spend .amt{font-size:21px; font-weight:800; color:#fff; letter-spacing:-.025em; line-height:1}
.pf .hdr .spend .u{font-family:"IBM Plex Mono",monospace; font-size:9.5px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted)}
/* The same two keys on the strip at the top of the section, so it reads as the same two things. */
.pdot{display:inline-block; width:8px; height:8px; border-radius:2px; margin-right:6px}
/* The per-platform amounts in the strip are the point of that line; the names are the label. */
#adStrip .ctx b{color:var(--ink); font-weight:700}
.pdot.meta{background:#0866ff}
.pdot.google{background:#f9ab00}
.pf .hdr .range{margin-left:auto; font-size:12.5px; font-variant-numeric:tabular-nums; color:var(--ink-2)}
.pf .hdr .range b{color:var(--ink); font-weight:700}
.pf .roas{font-size:12.5px; color:var(--ink-2)}
.pf .roas b{color:var(--ink); font-weight:700}
.mutedtxt{color:var(--muted)}
.pfsum{margin:2px 0 0; font-size:12.5px; line-height:1.5; color:var(--ink-2)}
.stack{display:flex; height:32px; background:var(--surface-2); overflow:hidden; border-radius:6px}
.stack div{height:100%; display:flex; align-items:center; justify-content:center; font-size:11.5px; font-weight:700; font-variant-numeric:tabular-nums; box-shadow:0 0 0 2px var(--surface) inset;
  /* min-width:0 so a segment narrower than its own label still keeps its proportional share. */
  min-width:0; overflow:hidden}
.stack .sv{background:var(--ver); color:#0b0c0f}
.stack .sl{background:var(--lik); color:#e9f5dd}
.stack .su{background:var(--untraced); color:var(--muted)}
/* 132px needed 528px for four across; the cards are 507px inside their new padding, so the fourth
   fact wrapped onto a row of its own beside a 340px hole. These four belong on one line. */
.pfacts{display:grid; grid-template-columns:repeat(auto-fit,minmax(104px,1fr)); gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r2); overflow:hidden}
.pfacts div{background:var(--surface); padding:8px 10px}
.pfacts .k{font-family:"IBM Plex Mono",monospace; font-size:9.5px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--muted)}
.pfacts .n{font-size:14px; font-weight:700; font-variant-numeric:tabular-nums; margin-top:2px}
.bkey{display:flex; flex-wrap:wrap; gap:8px 20px; font-size:12px; color:var(--ink-2); margin-bottom:4px}
.bkey span i{display:inline-block; width:11px; height:11px; border-radius:3px; margin-right:6px; vertical-align:-1px}
.merbar{display:flex; flex-wrap:wrap; gap:6px 14px; align-items:baseline; border-top:1px solid var(--line); padding-top:13px; font-size:12.5px; color:var(--muted); margin-top:16px}
.merbar b{font-size:16px; font-weight:900; color:var(--ink); font-variant-numeric:tabular-nums}

/* ---------- callouts ---------- */
.note{display:flex; gap:10px; align-items:flex-start; font-size:12.5px; line-height:1.5; border-radius:10px; padding:11px 13px; color:var(--ink-2)}
.note.warn{background:var(--warn-bg); border:1px solid rgba(224,165,42,.26)}
.note.plain{background:var(--surface-2); border:1px solid var(--line)}
.note strong{color:var(--ink)}
.note .mk{font-weight:700; color:var(--warn); font-family:"IBM Plex Mono",monospace; flex:none}

/* ---------- device ---------- */
.dev{display:flex; flex-direction:column; gap:14px}
.devrow .top{display:flex; justify-content:space-between; align-items:baseline; font-size:13px; gap:8px; flex-wrap:wrap}
.devrow .top b{font-weight:600}
.devrow .cr{font-variant-numeric:tabular-nums; font-weight:600}
.devtrack{height:22px; background:var(--surface-2); border-radius:5px; margin-top:6px; overflow:hidden}
.devfill{height:100%; border-radius:5px}
.devnote{font-size:12px; color:var(--ink-2); border-top:1px solid var(--line); padding-top:11px}

/* ---------- order feed ---------- */
.feed{display:flex; flex-direction:column}
.fitem{display:grid; grid-template-columns:auto 1fr auto; gap:4px 12px; align-items:baseline; padding:9px 0; border-bottom:1px solid var(--line)}
.fitem:last-child{border-bottom:0}
.fitem .t{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--muted)}
.fitem .d{font-size:12.5px; color:var(--ink-2); min-width:0; overflow-wrap:anywhere}
.fitem .a{font-size:13px; font-weight:600; font-variant-numeric:tabular-nums}
.fitem .src{grid-column:2/-1; font-size:11.5px; color:var(--muted)}

/* ---------- changelog / basket rows ---------- */
.log{display:flex; flex-direction:column; gap:0}
.logitem{display:grid; grid-template-columns:76px 1fr; gap:12px; padding:9px 0; border-bottom:1px solid var(--line); font-size:12.5px}
.logitem:last-child{border-bottom:0}
.logitem .when{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--muted)}
.logitem .who{display:block; margin-top:2px; font-family:Inter,system-ui,sans-serif; font-size:11px; color:var(--muted2)}
/* Entries run to a paragraph each and are meant to be read, so nothing is clipped or scrolled
   inside a box. The panel is as tall as the window's changes require; it is the last thing on the
   page, so the length costs the reader nothing they did not ask for. */
.logitem .what b{font-weight:600}
/* The "searched, nothing found" list reuses .logitem, whose 76px first column is meant for a
   date. A search term needs the room and the count belongs on the right. */
.basketrow{grid-template-columns:1fr auto; align-items:baseline}
.basketrow .val{text-align:right; color:var(--ink-2); font-variant-numeric:tabular-nums; white-space:nowrap}
.logitem .area{font-family:"IBM Plex Mono",monospace; font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted2); margin-left:8px}
/* Status is on every row, quiet when it is Live because that is the norm, loud when it is not:
   a change still in testing is not on the site and must not be read as one that is. */
.logstatus{font-family:"IBM Plex Mono",monospace; font-size:9.5px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; padding:1px 6px; border-radius:4px; margin-left:8px; white-space:nowrap; vertical-align:1px}
.st-live{color:var(--brand); background:var(--accent-soft)}
.st-testing{color:var(--warn); background:var(--warn-bg)}
.st-reverted{color:var(--crit); background:var(--crit-bg)}
.logstatus:not(.st-live):not(.st-testing):not(.st-reverted){color:var(--muted2); background:var(--surface-2)}
/* On a phone a 76px date column leaves the text about 279px wide, which turns a paragraph into
   fifteen lines. The date and the name go above it instead, so the entry reads across the full
   width of the panel. */
@media (max-width:620px){
  .logitem{grid-template-columns:1fr; gap:4px}
  .logitem .when{display:flex; align-items:baseline; gap:8px}
  .logitem .who{display:inline; margin-top:0}
}
/* Basket reads as five tiles across rather than a stack of rows, so the figures carry the
   same weight as the levers below them. */
.btiles{display:grid; grid-template-columns:repeat(5,1fr); gap:12px}
.btile{background:var(--surface-2); border:1px solid var(--line); border-radius:10px; padding:14px 15px;
  display:flex; flex-direction:column; gap:6px; min-width:0}
.btile .k{font-size:12.5px; font-weight:600; color:var(--ink)}
.btile .v{font-size:26px; font-weight:900; letter-spacing:-.03em; line-height:1.1; font-variant-numeric:tabular-nums; color:var(--ink)}
.btile .v.txt{font-size:15.5px; line-height:1.3; letter-spacing:-.01em}
.btile .n{font-size:11.5px; color:var(--muted); line-height:1.4}
.btile .chipline{margin-top:auto; padding-top:4px}

footer{margin-top:26px; padding-top:16px; border-top:1px solid var(--line); font-size:12px; color:var(--muted); line-height:1.6}
footer b{color:var(--ink-2); font-weight:600}
footer .warnlist{margin:8px 0 0; padding-left:18px; color:var(--warn)}

@media (max-width:700px){
  .wrap{padding-inline:12px}
  .frame{margin-top:26px; border-radius:16px; border-left-width:6px; scroll-margin-top:92px}
  /* On a phone the chapter block sits inline beside the title and the dates drop to their own line. */
  .fhead{display:grid; grid-template-columns:auto 1fr; gap:8px 12px; padding:13px 16px 12px; align-items:center}
  .chap{width:32px; height:32px; padding:0; display:inline-flex; align-items:center; justify-content:center; font-size:11.5px}
  .fhead .ttl{gap:2px}
  .sectitle, .frame.ov .sectitle{font-size:21px; line-height:1.05}
  .fhead .meta{grid-column:1/-1; margin:0; text-align:left; line-height:1.5}
  .fhead .meta .st{margin:4px 0 0}
  .frame .panel-head{padding:16px 16px 0}
  .frame .panel-body{padding:12px 16px 18px}
  .frame .notewrap{padding:14px 16px}
  .split, .split.s-15, .split.s-11{grid-template-columns:1fr}
}

@media (max-width:1000px) and (min-width:661px){
  .kgrid{grid-template-columns:1.6fr 1fr 1fr}
  .btiles{grid-template-columns:repeat(3,1fr)}
  /* Five tiles over three columns leaves one alone with a 200-300px hole beside it. */
  .btiles .btile:last-child{grid-column:span 2}
  /* Three columns with a two-row hero leaves the last tile alone in the bottom row with a hole
     beside it, so it takes the space instead. */
  .kgrid:not(.ad) > .kpi:last-child:nth-child(odd){grid-column:span 2}
}
@media (max-width:660px){
  .kgrid, .kgrid.ad{grid-template-columns:repeat(2,1fr)}
  .kgrid > .kpi.hero{grid-row:auto; grid-column:1/-1; padding:22px 18px 20px}
  .kpi.hero .v{font-size:58px; margin:10px 0 11px}
  .kpi.hero .v small{font-size:26px}
  .kgrid > .kpi{padding:14px 16px}
  .kpi .v{font-size:26px}
  .kpi .v small{font-size:15px}
  .kgrid:not(.ad) > .kpi:last-child:nth-child(even){grid-column:1/-1}
  .kgrid.ad > .kpi:last-child:nth-child(odd){grid-column:1/-1}
  .btiles{grid-template-columns:1fr 1fr; gap:10px}
  .btiles .btile:last-child{grid-column:1/-1}
  .btile .v{font-size:23px}
}


/* ---------- demo banner (sample site only, appended by scripts/build-sample-assets.ts) ----------
   Inside header.top rather than above it: the header is sticky at top:0, so a second sticky strip
   would have to keep the header's offset in step with its own wrapped height at every breakpoint.
   Nested, it simply travels with it. */
.demobar{margin:0; padding:9px 16px; text-align:center; background:var(--c-ov); color:#0b0c0f;
  font-size:13px; line-height:1.4; border-bottom:1px solid rgba(0,0,0,.28)}
.demobar strong{font-weight:800}
.demobar span{font-weight:500; opacity:.74}
@media (max-width:620px){
  .demobar{font-size:11.5px; padding:7px 12px}
  /* The qualifier is the first thing to go; the sentence that matters still fits. */
  .demobar span{display:none}
}
