/* ═══ WESTLYN CRO — THE DESIGN SYSTEM ══════════════════════════════════════════════════
   One stylesheet, five screens.

   The card on the Overview screen is the object every other screen is built from. Its parts —
   a headline number with a soft unit beside it, a segmented funnel strip, a joints line where
   the number and the word sit together, and a hairline-separated row of small figures — are
   not card decoration. They are the board's vocabulary, and every screen speaks it:

     .headline   the one number this thing earns          — card, teardown, test verdict
     .fstrip     a funnel, drawn                          — card, per-page rows, journey
     .joints     rate + word on one line, leak in red     — everywhere a funnel appears
     .stat/.quad a labelled figure with its movement      — card footer, teardown strip, verdict
     .mcard      one metric, both arms, a bar each        — compare, test
     .ladder     absolute counts and what was lost        — overview, teardown
     .vprob      how much to believe it                   — test

   Warm paper, one deep green, red reserved exclusively for "people are leaving here". Nothing
   else is allowed to be red — the moment a second thing uses it, the leak stops being findable.
   Light mode only, by request. */
:root{
  /* ink */
  --ink:#17181A; --ink-2:#43464C; --mute:#71757E; --faint:#A0A4AD;
  /* surface */
  --line:#E8E5DF; --line-2:#D8D4CB; --paper:#FFFDFB; --wash:#F6F3EE; --sunk:#FCFAF7;
  /* accent */
  --acc:#0C5C46; --acc-2:#14876A; --acc-l:#E7F2EE; --acc-br:#C4DED5;
  /* the leak, and nothing else */
  --bad:#A83A2A; --bad-l:#FAEDE9; --bad-br:#EDCEC6;
  /* caution — used for "not enough data" and staleness, never for a metric */
  --warn:#9A6212; --warn-l:#FBF3E4; --warn-br:#EFDCB4;
  /* THE TWO SIDES OF A COMPARISON ARE THE SAME COLOUR.
     They used to be sage and deep green. Equal-sized things drawn at unequal weight read as
     "this one matters less" before a single number is parsed — side A looked like a weaker page
     on every screen it appeared on, and a lower-is-better bar drawn at half opacity looked
     switched off. Which side is which comes from the A/B badge, the row name, and which side of
     the axis the bar sits on. None of those can be mistaken for a value. */
  --a:#0C5C46; --b:#0C5C46; --c:#0C5C46;

  /* MULTI-SERIES LINES ARE THE ONE EXCEPTION, and it is not a reversal of the rule above.
     That rule is about BARS: two bars of equal length in unequal weight read as "this one matters
     less", and which arm a bar belongs to is already given by which side of the axis it sits on.
     A LINE CHART HAS NO SUCH CUE — same-coloured lines are simply unreadable, and letters in the
     legend are not an answer either ("A and B means nothing to me", Arthur, 30 Jul).
     So: two hues of the SAME depth and saturation, so neither reads as the stronger. Not a dark
     line and a pale one — that would be the bar mistake in a new place. */
  --ln1:#0C5C46; --ln2:#5B4B8A;

  --r:10px; --r-lg:16px; --r-pill:99px; --r-bar:99px;
  --sh:0 1px 2px rgba(23,24,26,.04),0 8px 24px -8px rgba(23,24,26,.08);
  --sh-h:0 2px 4px rgba(23,24,26,.05),0 18px 40px -12px rgba(23,24,26,.16);
  --rail:200px;
  --ease:cubic-bezier(.22,1,.36,1);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--wash);color:var(--ink);
  font:400 14px/1.55 ui-sans-serif,-apple-system,"Inter","Segoe UI",system-ui,sans-serif;
  font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased}
h1,h2,h3{margin:0;letter-spacing:-.028em}
a{color:inherit}

/* ── the rail ──────────────────────────────────────────────────────────────────────────
   Down the left. These screens are wide tables and a very tall page capture, so vertical space
   is the scarce resource — a narrow rail costs width the layout has to spare and hands a full
   header's height back to the content. */
.rail{position:fixed;inset:0 auto 0 0;width:var(--rail);background:var(--paper);
  border-right:1px solid var(--line);padding:22px 14px 18px;display:flex;flex-direction:column;z-index:20}
/* The wordmark and "CRO" are STACKED, not set side by side. The logo is a long lockup with its
   own internal baseline; sitting a second word beside it made the pair read as two competing
   marks and left the letterforms out of alignment at every rail width. */
.brand{display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  text-decoration:none;padding:4px 10px 20px;color:var(--ink)}
.brand img{width:92px;height:auto;display:block}
.brand i{font:700 10px/1 inherit;letter-spacing:.19em;text-transform:uppercase;
  color:var(--acc);font-style:normal;padding-left:2px}
.railnav{display:flex;flex-direction:column;gap:2px}
.railnav a{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:var(--r);
  text-decoration:none;color:var(--mute);font-size:13.5px;font-weight:520;
  transition:background .16s,color .16s}
.railnav a:hover{background:var(--wash);color:var(--ink-2)}
.railnav a.on{background:var(--acc);color:#fff;font-weight:600}
.railnav svg{width:15px;height:15px;flex:none;opacity:.85}
.railfoot{margin-top:auto;padding:0 10px}
.railfoot .st{font-size:11.5px;color:var(--faint);line-height:1.5}
.railfoot .st b{display:block;color:var(--ink-2);font-weight:600;font-size:12px;margin-bottom:2px}

main{margin-left:var(--rail)}
.wrap{max-width:1360px;margin:0 auto;padding:26px 30px 90px}

/* ── page head ── */
.phead{display:flex;align-items:flex-end;gap:18px;margin-bottom:24px}
.phead h1{font-size:27px;letter-spacing:-.038em}
.phead .sub{color:var(--mute);font-size:13.5px;margin-top:5px}
.grow{flex:1;min-width:0}
.crumb{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:560;
  color:var(--mute);text-decoration:none;margin-bottom:9px;transition:color .16s}
.crumb:hover{color:var(--acc)}

/* ── controls ── */
.btn{height:34px;padding:0 15px;border:1px solid var(--line-2);background:var(--paper);
  border-radius:var(--r-pill);font:520 13px/1 inherit;color:var(--ink-2);cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;transition:.16s;text-decoration:none;white-space:nowrap}
.btn:hover{background:var(--wash)}
.btn.pri{background:var(--acc);border-color:var(--acc);color:#fff}
.btn.pri:hover{background:var(--acc-2)}
.btn.sm{height:29px;font-size:12.5px;padding:0 12px}
select.pick{height:44px;padding:0 38px 0 15px;border:1px solid var(--line-2);
  border-radius:var(--r);background-color:var(--paper);font:600 14.5px/1 inherit;color:var(--ink);
  letter-spacing:-.022em;appearance:none;cursor:pointer;box-shadow:var(--sh);width:100%;transition:.16s;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 5l3 3 3-3' stroke='%2371757E' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center;background-size:13px}
select.pick:hover{border-color:var(--line-2);background-color:var(--sunk)}
select.pick:focus{outline:0;border-color:var(--acc);box-shadow:0 0 0 3px rgba(12,92,70,.1)}
/* ── the dropdown ──────────────────────────────────────────────────────────────────────
   A native <select> opens an OS menu that no stylesheet can reach: system font, square
   corners, blue highlight — the one moment the board stops looking like the board. So the
   closed control keeps the same box as before and the OPEN list is ours: paper, the card
   radius, the card shadow, and the accent for the current choice.
   Each option can carry a second line — a page's URL — because picking the wrong page is
   the mistake a name alone cannot prevent. */
.sel{position:relative;width:100%}
.selbtn{height:44px;width:100%;padding:0 38px 0 15px;border:1px solid var(--line-2);
  border-radius:var(--r);background:var(--paper);font:600 14.5px/1 inherit;color:var(--ink);
  letter-spacing:-.022em;cursor:pointer;box-shadow:var(--sh);text-align:left;transition:.16s;
  display:flex;align-items:center;gap:8px;white-space:nowrap;overflow:hidden}
.selbtn:hover{background:var(--sunk)}
.sel.open .selbtn{border-color:var(--acc);box-shadow:0 0 0 3px rgba(12,92,70,.1)}
.selbtn .selv{overflow:hidden;text-overflow:ellipsis}
.selbtn .cv{position:absolute;right:14px;width:13px;height:13px;flex:none;
  background:no-repeat center/13px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 5l3 3 3-3' stroke='%2371757E' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  transition:transform .18s var(--ease)}
.sel.open .selbtn .cv{transform:rotate(180deg)}
.selmenu{position:absolute;z-index:40;top:calc(100% + 6px);left:0;right:0;padding:5px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-h);max-height:298px;overflow:auto;display:none}
.sel.open .selmenu{display:block;animation:in .16s var(--ease) both}
.selopt{display:block;width:100%;text-align:left;border:0;background:none;cursor:pointer;
  padding:8px 11px;border-radius:var(--r);font:560 13.5px/1.35 inherit;color:var(--ink);
  transition:background .12s}
.selopt:hover{background:var(--sunk)}
.selopt s{display:block;text-decoration:none;font-size:11.5px;font-weight:400;color:var(--faint);
  margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.selopt.on{background:var(--acc-l);color:var(--acc)}
.selopt.on s{color:var(--acc-2)}

/* ── the page picker ───────────────────────────────────────────────────────────────────
   A page is chosen by what it LOOKS like and where it LIVES, not by a name someone typed
   into the CMS — so every tile carries a preview and its full path, and the checkbox is the
   whole tile rather than a 15px square beside it. */
.ppick{display:grid;grid-template-columns:repeat(auto-fill,minmax(214px,1fr));gap:12px}
.ppick label{position:relative;display:block;cursor:pointer;background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;transition:.16s}
.ppick label:hover{border-color:var(--line-2);box-shadow:var(--sh)}
.ppick input{position:absolute;opacity:0;pointer-events:none}
.ppick label:has(input:checked){border-color:var(--acc);box-shadow:0 0 0 1px var(--acc)}
.ppick .shot{height:96px;background:linear-gradient(165deg,#EFEBE4,#E2DDD3);position:relative;
  overflow:hidden;border-bottom:1px solid var(--line)}
.ppick .shot .fake{inset:9px 12px auto 12px}
.ppick .shot .fake .h{height:7px;margin-bottom:6px}
.ppick .shot .fake .p{height:4px;margin-bottom:4px}
.ppick .shot::after{content:"";position:absolute;inset:auto 0 0 0;height:26px;
  background:linear-gradient(to bottom,rgba(255,253,251,0),var(--paper))}
.ppick .tick{position:absolute;top:9px;right:9px;width:20px;height:20px;border-radius:50%;
  border:1px solid var(--line-2);background:var(--paper);z-index:2;transition:.16s}
.ppick label:has(input:checked) .tick{background:var(--acc);border-color:var(--acc);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 7.4l2.6 2.6L11 4.5' stroke='%23fff' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:center;background-size:14px}
.ppick .pmeta{padding:10px 12px 11px}
.ppick .pn{font-size:13px;font-weight:600;letter-spacing:-.02em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.ppick .pp{font-size:11.5px;color:var(--faint);margin-top:3px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.ppick .pfoot{display:flex;align-items:center;gap:7px;margin-top:9px}
.ppick .pfoot .s{margin-left:auto;font-size:11.5px;color:var(--mute)}

input.fld{height:42px;padding:0 14px;border:1px solid var(--line-2);border-radius:var(--r);
  background:var(--paper);font:400 14px/1 inherit;color:var(--ink);width:100%;transition:.16s}
input.fld::placeholder{color:var(--faint)}
input.fld:focus{outline:0;border-color:var(--acc);box-shadow:0 0 0 3px rgba(12,92,70,.1)}

.chip{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:var(--r-pill);
  background:var(--wash);border:1px solid var(--line);font-size:11px;font-weight:640;color:var(--mute)}
.chip.g{background:var(--acc-l);border-color:var(--acc-br);color:var(--acc)}
.chip.r{background:var(--bad-l);border-color:var(--bad-br);color:var(--bad)}
.chip.w{background:var(--warn-l);border-color:var(--warn-br);color:var(--warn)}
.chip.solid{background:var(--acc);border-color:var(--acc);color:#fff}

.lbl,.k{font-size:10px;font-weight:640;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
.up{color:var(--acc-2)} .dn{color:var(--bad)} .mut{color:var(--mute)} .pend{color:var(--faint)}

/* ── structure ── */
.sect{display:flex;align-items:baseline;gap:11px;margin:34px 0 15px}
.sect:first-child{margin-top:0}
.sect h2{font-size:15.5px;font-weight:620}
.sect span{font-size:13px;color:var(--mute)}
.card{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh)}
.ch{display:flex;align-items:center;gap:10px;padding:15px 20px;border-bottom:1px solid var(--line)}
.ch h3{font-size:14px;font-weight:620}
.ch .n{font-size:12.5px;color:var(--mute)}
.cb{padding:18px 20px 20px}
.note{padding:14px 18px;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-lg);font-size:13px;line-height:1.65;color:var(--ink-2)}
.note b{color:var(--ink)}
.note.warn{background:var(--warn-l);border-color:var(--warn-br);color:#6B4409}
.note.warn b{color:#4E3106}
.note.flat{border:0;border-top:1px solid var(--line);border-radius:0;margin:0;font-size:12.5px}
/* Footnote. The board explains itself as little as possible — a screen that has to be read
   before it can be looked at is a screen you stop opening. This is for the two or three places
   where leaving the caveat out would let a number be read as something it is not, and it is
   deliberately the quietest type on the page. */
.fine{font-size:11.5px;color:var(--faint);line-height:1.55;padding:12px 20px;border-top:1px solid var(--line)}
.fine b{color:var(--mute);font-weight:640}
/* a group heading INSIDE a card — keeps three related tables in one object instead of
   scattering twelve little cards across the screen */
.gsub{display:flex;align-items:baseline;gap:10px;padding:14px 20px 8px;background:var(--sunk);
  border-bottom:1px solid var(--line);border-top:1px solid var(--line)}
.gsub:first-child{border-top:0}
.gsub b{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-2)}

/* ── THE PAGE CARD ─────────────────────────────────────────────────────────────────────
   The primary object of the whole board. Preview large, one headline number, the funnel, then
   four supporting figures. Nothing else earns a place on it. */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:22px}
.grid.two{grid-template-columns:repeat(auto-fill,minmax(430px,1fr))}
a.pcard{text-decoration:none;color:inherit;display:block}
.vgrid>.pcard>.inner{height:100%}
.pcard>.inner{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh);overflow:hidden;
  transition:box-shadow .22s var(--ease),transform .22s var(--ease);
  animation:in .6s var(--ease) both}
a.pcard:hover>.inner{box-shadow:var(--sh-h);transform:translateY(-3px)}
.grid>*:nth-child(2) .inner{animation-delay:.07s}
.grid>*:nth-child(3) .inner{animation-delay:.14s}
.grid>*:nth-child(4) .inner{animation-delay:.21s}
.pcard.win>.inner{border-color:var(--acc-br);box-shadow:0 0 0 1px var(--acc-br),var(--sh)}

.shot{position:relative;height:242px;background:linear-gradient(165deg,#EFEBE4,#E2DDD3);overflow:hidden}
.shot.sm{height:200px}
.fake{position:absolute;inset:16px 22px auto 22px}
.fake .h{height:11px;border-radius:3px;background:#C6BFB2;margin-bottom:9px;width:88%}
.fake .h.s{width:62%}
.fake .p{height:5px;border-radius:2px;background:#D6D0C5;margin-bottom:5px}
.fake .p.a{width:96%}.fake .p.b{width:88%}.fake .p.c{width:73%}
.fake .img{height:88px;border-radius:6px;background:linear-gradient(135deg,#CFC7B8,#BDB4A3);margin:12px 0}
.fake .cta{height:26px;border-radius:6px;background:var(--acc);width:72%;margin-top:12px}
.rank{position:absolute;top:12px;left:12px;width:23px;height:23px;border-radius:7px;
  background:rgba(23,24,26,.72);color:#fff;font-size:11.5px;font-weight:700;
  display:flex;align-items:center;justify-content:center}
.fold{position:absolute;left:0;right:0;bottom:54px;border-top:1.5px dashed rgba(23,24,26,.38)}
.fold span{position:absolute;right:8px;top:-9px;background:rgba(23,24,26,.78);color:#fff;
  font-size:9px;font-weight:650;padding:2px 6px;border-radius:4px;letter-spacing:.03em}
.shot::after{content:"";position:absolute;inset:auto 0 0 0;height:54px;
  background:linear-gradient(to bottom,rgba(255,253,251,0),var(--paper))}

.cbody{padding:16px 18px 18px}
.ctitle{font-size:16.5px;font-weight:620;letter-spacing:-.03em}
.cmeta{font-size:12px;color:var(--faint);margin-top:3px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.headline{display:flex;align-items:flex-end;gap:12px;margin:16px 0 2px}
.headline .n{font-size:33px;font-weight:620;letter-spacing:-.048em;line-height:1}
.headline .u{font-size:12px;color:var(--mute);padding-bottom:5px}
.headline svg{margin-left:auto;padding-bottom:3px}
.headline.lg .n{font-size:44px}
.headline.lg .u{font-size:13px;padding-bottom:7px}

/* THE FUNNEL.
   Four segments — landed, clicked, PDP, bought — and that is the whole funnel, everywhere.
   There is no checkout step: this store's express wallets (Shop Pay, Apple Pay) let a buyer go
   from the product page to a paid order without ever landing on a checkout page, so a
   "reached checkout" rate measures which payment method someone used, not intent. Purchases
   are server-side and complete either way, which is why the last hop is PDP → bought.
   Rates sit on the JOINTS, one line each, number and word together. */
.fstrip{display:flex;gap:3px;height:7px;margin-top:16px;position:relative}
.fstrip .tip{top:0;transform:translate(-50%,-135%)}
/* The FIRST segment is full-strength — it is the longest bar on the screen and it has to be the
   same green as every other long bar on the board. The steps after it keep stepping down: that
   is the funnel decaying, and it is the one place a lighter green means something. */
.fstrip i{border-radius:var(--r-bar);background:var(--seg,var(--acc));min-width:9px;
  transform-origin:left;animation:grow .8s var(--ease) both}
.fstrip i:nth-child(2){opacity:.58}
.fstrip i:nth-child(3){opacity:.36}
.fstrip i:nth-child(4){opacity:.18}
.fstrip.lg{height:11px;gap:4px;margin-top:0}
.joints{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:10px}
.joints .j{font-size:11.5px;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.joints .j b{font-size:12.5px;font-weight:650;letter-spacing:-.02em;color:var(--ink);margin-right:4px}
.joints .j:nth-child(2){text-align:center}
.joints .j:nth-child(3){text-align:right}
.joints .j.hot,.joints .j.hot b{color:var(--bad)}
/* Journey rows carry Landed as its own column ahead of the three hops, so the row states its
   own denominator instead of making you find it in the label beside it. */
.joints.four{grid-template-columns:repeat(4,1fr)}
.joints.four .j:nth-child(2){text-align:left}
.joints.four .j:nth-child(3){text-align:center}
.joints.four .j:nth-child(4){text-align:right}

.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:16px;
  padding-top:15px;border-top:1px solid var(--line)}
.stats.five{grid-template-columns:repeat(5,1fr)}
.stats.six{grid-template-columns:repeat(6,1fr)}
.stat .k{font-size:10px;font-weight:640;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
.stat .v{font-size:15.5px;font-weight:620;letter-spacing:-.026em;margin-top:4px}
.stat .d{font-size:10.5px;font-weight:650;margin-top:2px}

/* ── QUAD — a row of labelled figures ──────────────────────────────────────────────────
   The card's footer, promoted to a standalone strip. It replaced four near-identical
   implementations of "a row of numbers with small labels", which is exactly the drift this
   stylesheet exists to prevent. */
.quad{display:grid;grid-template-columns:repeat(auto-fit,minmax(104px,1fr));background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh);overflow:hidden}
.quad>div{padding:13px 16px;border-left:1px solid var(--line)}
.quad>div:first-child{border-left:0}
.quad .v{font-size:19px;font-weight:620;letter-spacing:-.035em;margin-top:5px;line-height:1}
.quad .d{font-size:10.5px;font-weight:650;margin-top:4px}
.quad .s{font-size:11.5px;color:var(--faint);margin-top:4px}
/* inside a card, the strip loses its own frame and borrows the card's */
.quad.flat{border:0;border-radius:0;box-shadow:none;background:transparent;
  border-top:1px solid var(--line)}
.quad.big .v{font-size:23px;letter-spacing:-.042em}
/* a fixed six-across strip that wraps to a second row — auto-fit would leave the first cell of
   row two carrying a left border and no top one */
.quad.g6{grid-template-columns:repeat(6,1fr)}
.quad.g6>div:nth-child(6n+1){border-left:0}
.quad.g6>div:nth-child(n+7){border-top:1px solid var(--line)}
.quad.g5{grid-template-columns:repeat(5,1fr)}
.quad.g5>div:nth-child(5n+1){border-left:0}
.quad.g5>div:nth-child(n+6){border-top:1px solid var(--line)}

/* ── chart hover ───────────────────────────────────────────────────────────────────────
   A line with no readout is a shape. Every chart carries its points as data and shows the
   value under the cursor, snapped to the nearest one — no interpolation, because a number
   between two measurements is a number nobody measured. */
.hasdots{position:relative}
.vline{position:absolute;top:0;bottom:16px;width:1px;background:var(--line-2);
  pointer-events:none;opacity:0;transition:opacity .12s}
.cursor{position:absolute;width:10px;height:10px;border-radius:50%;background:var(--acc);
  box-shadow:0 0 0 3px var(--paper);pointer-events:none;opacity:0;
  transform:translate(-50%,-50%);transition:opacity .12s}
.tip{position:absolute;pointer-events:none;background:var(--ink);color:#fff;font-size:11px;
  font-weight:650;padding:5px 9px;border-radius:6px;white-space:nowrap;z-index:5;
  transform:translate(-50%,-165%);opacity:0;transition:opacity .12s}
.tip s{text-decoration:none;color:rgba(255,255,255,.6);font-weight:500;margin-left:5px}
.vline.on,.cursor.on,.tip.on{opacity:1}

/* ── bars, used everywhere a rate is drawn ── */
.track{height:11px;border-radius:var(--r-bar);background:var(--wash);overflow:hidden}
.track i{display:block;height:100%;border-radius:var(--r-bar);background:var(--acc);
  transform-origin:left;animation:grow .8s var(--ease) both}
.track.hot{background:#F3DDD7}
.track.hot i{background:var(--bad)}
.track.a i{background:var(--a)}
.track.b i{background:var(--b)}

/* progress toward a threshold — how close a test is to being callable */
.prog{position:relative;height:11px;border-radius:var(--r-bar);background:var(--wash)}
/* the reading sits above where the fill ENDS. Parked at the right-hand end it sat directly
   over the 95% tick and read as a label for the bar it has to clear, not for the bar it is. */
.prog .pval{position:absolute;bottom:100%;margin-bottom:6px;transform:translateX(-50%);
  font-size:13.5px;font-weight:700;white-space:nowrap;line-height:1}
.prog .pval[data-c="warn"]{color:var(--warn)}
.prog>i{display:block;height:100%;border-radius:var(--r-bar);background:var(--warn);
  transform-origin:left;animation:grow .8s var(--ease) both}
.prog.ok>i{background:var(--acc)}
.prog .mark{position:absolute;left:95%;top:-4px;bottom:-4px;width:1.5px;
  background:var(--ink-2);border-radius:1px}

/* ── LADDER — absolute counts, and what was lost between them ─────────────────────────
   Rates say how well each hop performs; this says how many people it costs. Both matter and
   they are not interchangeable: 86% sounds healthy until it is 402 people. */
.ladder .lrow{display:grid;grid-template-columns:118px 1fr 52px 46px;gap:11px;align-items:center;
  padding:11px 0;border-top:1px solid var(--line)}
.ladder .lrow:first-of-type{border-top:0}
.ladder .lk{font-size:12.5px;color:var(--ink-2)}
.ladder .lv{text-align:right;font-weight:620;font-size:13px}
.ladder .lp{text-align:right;font-size:11.5px;color:var(--faint)}
.ladder .lost{margin:2px 0 2px 129px;padding:3px 0}
.ladder .lost span{font-size:11px;font-weight:650;color:var(--mute);background:var(--wash);
  border:1px solid var(--line);padding:2px 9px;border-radius:var(--r-pill)}
.ladder .lost.hot span{color:var(--bad);background:var(--bad-l);border-color:var(--bad-br)}

/* ── BROW — the board's list primitive: label, bar, value ─────────────────────────────
   Anything that is "a list of things with one number each" is this row: biggest losses, engaged
   time bands, CTA slots, the ad sets feeding a page. The bar and the value are always the SAME
   metric — the bar is the value drawn — and anything else about the item rides in the sub-label
   under its name. Before this there were four shapes doing this job: a vertical histogram, a
   two-line name-plus-joints block, a four-column table with a 3px dot-marker rail, and this. */
.browhead{display:flex;align-items:baseline;justify-content:space-between;padding-bottom:9px;
  border-bottom:1px solid var(--line);margin-bottom:4px}
.brow{display:grid;grid-template-columns:1fr 84px 48px;gap:10px;align-items:center;padding:10px 0}
.brow+.brow{border-top:1px solid var(--line)}
.brow .lk{font-size:12.5px;color:var(--ink-2);min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brow .lk s{display:block;text-decoration:none;font-size:10.5px;color:var(--faint);margin-top:2px}
.brow .lv{text-align:right;font-size:13.5px;font-weight:650;letter-spacing:-.022em}
.brow .lv.pend{font-weight:400;color:var(--faint)}
.brownote{margin-top:14px;padding-top:13px;border-top:1px solid var(--line)}

/* ── JOURNEY — the funnel strip, one row per page or arm ───────────────────────────────
   Same component as the card, at reading size. Stacking the arms means the four hop rates
   land in the same four columns on every row, so the difference row underneath aligns to the
   step it describes rather than to a legend somewhere else. Vertical bar charts could not do
   this: at a 1.8% final step the bar is a pixel and the number has to be read from a caption. */
.jrn{padding:4px 20px 6px}
.jrow{display:grid;grid-template-columns:158px 1fr;gap:18px;align-items:center;
  padding:15px 0;border-bottom:1px solid var(--line)}
.jrow:last-child{border-bottom:0}
/* a row that names a page opens that page, same as its card does */
a.jrow{text-decoration:none;color:inherit;transition:background .16s}
a.jrow:hover{background:var(--sunk);box-shadow:0 0 0 12px var(--sunk)}
.jname{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;
  letter-spacing:-.015em;min-width:0}
.jname span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jname s{display:block;text-decoration:none;font-size:11px;color:var(--faint);font-weight:400;margin-top:2px}
.jhead{display:grid;grid-template-columns:158px 1fr;gap:18px;padding:11px 20px;
  background:var(--sunk);border-bottom:1px solid var(--line)}
/* the header columns mirror `.joints.four` exactly — same count, same alignment — or the step
   names sit somewhere other than the numbers they name */
.jhead .steps4{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.jhead .steps4 div{font:640 9.5px/1 inherit;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
.jhead .steps4 div:nth-child(3){text-align:center}
.jhead .steps4 div:nth-child(4){text-align:right}
.jdiff{background:var(--sunk);margin:0 -20px;padding:13px 20px}
.jdiff .jname{color:var(--mute);font-weight:640;font-size:11.5px;letter-spacing:.05em;text-transform:uppercase}
.jdiff .joints .j b{font-weight:700}
.jbest b{color:var(--acc-2)!important}

/* ── DBROW — one metric, two sides, diverging from a shared axis ───────────────────────
   Replaced a two-column table of bars AND twelve little comparison cards that between them
   printed every metric three times. Length reads as size and side reads as winner, so the
   answer arrives before any number is parsed. */
/* ONE METRIC PER CARD, ONE ARM PER LINE, A BAR UNDER EACH.
   The diverging table this replaced put both values and both bars on one row. It fitted more on a
   screen and read as a spreadsheet — the eye ran down the labels instead of comparing the pair.
   Stacked, the comparison is a vertical step between two bars of the same scale, which is the
   thing being asked. Bars are FULLY ROUNDED, like every other bar on the board. */
.mgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:13px;
  padding:14px 20px 18px}
.mcard{border:1px solid var(--line);border-radius:var(--r);padding:13px 14px 14px;
  background:var(--paper)}
.mrow{display:flex;align-items:baseline;gap:7px;font-size:13px}
.mrow .dot{width:8px;height:8px;border-radius:50%;flex:none;align-self:center}
.mrow .mname{color:var(--mute);font-weight:520;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;min-width:0}
.mrow .mval{margin-left:auto;font-size:14.5px;font-weight:640;letter-spacing:-.025em;
  white-space:nowrap}
.mrow .mdelta{font-size:12px;font-weight:650;letter-spacing:-.01em;white-space:nowrap}
.mbar{height:9px;margin:6px 0 12px;background:var(--wash);border-radius:var(--r-bar);
  overflow:hidden}
.mbar:last-child{margin-bottom:0}
.mbar i{display:block;height:9px;border-radius:var(--r-bar);transform-origin:left;
  animation:grow .8s var(--ease) both}
/* Lower-is-better rows are NOT drawn faded. Fading them made the bar harder to read while
   still leaving it the longest one, which is the worst of both — the green delta beside it is
   what names the winner, and one encoding is enough. */

/* ── RESULT BLOCK — who is ahead, by how much, and whether you can act on it ───────────
   Lives on Tests and on Compare. The confidence bar carries a tick at 95% because "52%" means
   nothing without the bar it has to clear, and a leading arm quoted on its own is an invitation
   to stop a test early. */
/* Fills its container. On Tests that is the test card; on Compare it is a fixed column beside
   the table. The container does the sizing — the block itself never needs a cap, and a cap is
   what left it short of the card edge on Tests. */
.res{padding:14px 18px 14px}
.rtop{display:flex;align-items:flex-end;gap:14px;margin-bottom:13px}
.rv{font-size:16px;font-weight:640;letter-spacing:-.03em;margin-top:5px}
.rgap{margin-left:auto;text-align:right}
.rgap .rv{font-size:22px;letter-spacing:-.04em}
.clab{display:flex;align-items:baseline;margin-bottom:19px}
.clab span{font-size:11px;font-weight:640;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}

/* what is still owed before the test can be read — a count and a countdown, nothing else */
.cneed{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:12px;
  padding-top:11px;border-top:1px solid var(--line)}
.cneed .v{font-size:17px;font-weight:640;letter-spacing:-.03em;margin-top:3px}
.cnote{font-size:12px;color:var(--mute);margin-top:10px;line-height:1.5}
.cnote b{color:var(--ink-2)}
.mk{font-size:9.5px;color:var(--faint);text-align:right;margin-top:5px}

/* ── RING — how much to believe it ── */

/* ── tables ── */
.thead,.trow{display:grid;gap:14px;align-items:center;padding:0 20px}
.thead{padding-top:11px;padding-bottom:11px;background:var(--sunk);border-bottom:1px solid var(--line)}
.thead div{font:640 9.5px/1 inherit;letter-spacing:.085em;text-transform:uppercase;color:var(--faint)}
/* DENSE TABLES TIGHTEN THE HEADER TYPE.
   Uppercase at .085em tracking makes "Sessions" 77px wide — wider than the column the numbers
   underneath need. Rather than widen every column to fit a LABEL, the label gets out of the way:
   same colour and weight, less tracking, a touch smaller. Verified by measuring scrollWidth
   against clientWidth on every header cell, which is the only way to catch this. */
.thead.dense div{font-size:9px;letter-spacing:.03em}
.trow{padding-top:13px;padding-bottom:13px;border-bottom:1px solid var(--line);transition:background .16s}
.trow:last-child{border-bottom:0}
.trow:hover{background:var(--sunk)}
.tname{font-weight:600;font-size:13.5px;letter-spacing:-.015em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tmeta{font-size:11.5px;color:var(--faint);margin-top:2px}
.tv{font-size:14px;font-weight:620;letter-spacing:-.022em}
.tsub{font-size:11px;color:var(--faint);margin-top:1px}
.dot{display:inline-block;width:9px;height:9px;border-radius:var(--r-bar);flex:none}

/* ── motion ────────────────────────────────────────────────────────────────────────────
   Load-in only. Bars grow from their origin, cards lift in, lines draw. Nothing loops and
   nothing moves once it has settled — an animation that repeats is a thing you have to wait
   for every time you glance at the screen. */
@keyframes in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes rise{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes pop{from{transform:scale(.4);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes draw{from{stroke-dashoffset:300}to{stroke-dashoffset:0}}
/* Line charts do NOT draw themselves with a dash offset. These paths carry
   vector-effect:non-scaling-stroke so the line keeps its weight when the chart is stretched —
   and that makes the browser resolve stroke-dasharray in SCREEN pixels, not path units. A
   dasharray of 1 becomes a 1px-on/1px-off dotted line that reads as a broken chart, and
   pathLength does not rescue it. The whole chart wipes in from the left instead. */
@keyframes wipe{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
.wipein{animation:wipe 1.1s var(--ease) both}
.spark path{stroke-dasharray:300;animation:draw 1.1s var(--ease) both}
.fadein{animation:in .6s var(--ease) both}
.d1{animation-delay:.07s}.d2{animation-delay:.14s}.d3{animation-delay:.21s}.d4{animation-delay:.28s}

@media (max-width:900px){
  .rail{position:static;width:auto;flex-direction:row;align-items:center;gap:16px;
    border-right:0;border-bottom:1px solid var(--line);padding:10px 16px}
  .brand{padding:0;gap:1px}
  .brand img{width:82px}
  .railnav{flex-direction:row}
  .railfoot{margin-top:0;margin-left:auto}
  main{margin-left:0}
  .wrap{padding:20px 16px 60px}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}


/* ══ OVERVIEW ══════════════════════════════════════════════════════════ */
/* ═══ OVERVIEW ═════════════════════════════════════════════════════════════════════════
   The cards are the screen. Everything below them is the same funnel the cards already draw,
   said once at store level and then once per page — same strip, same joints, same colours, so
   a row and a card are recognisably the same object rather than two designs of one idea. */
.leakwrap{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh);overflow:hidden}
/* store-level steps */
.steps{display:grid;grid-template-columns:repeat(4,1fr);border-bottom:1px solid var(--line)}
.stp{padding:17px 20px 19px;border-left:1px solid var(--line);position:relative}
.stp:first-child{border-left:0}
.stp .hop{font-size:12px;color:var(--ink-2);display:flex;align-items:center;gap:6px}
.stp .hop i{font-style:normal;color:var(--faint)}
.stp .pc{font-size:27px;font-weight:620;letter-spacing:-.045em;margin-top:11px;line-height:1}
.stp .of{font-size:11.5px;color:var(--faint);margin-top:7px}
.stp .of b{font-size:12.5px;font-weight:650;color:var(--ink);margin-right:4px;letter-spacing:-.02em}
.stp .track{margin-top:12px}
.stp .lost{font-size:11.5px;color:var(--mute);margin-top:9px}
.stp.hot{background:var(--bad-l)}
.stp.hot .pc{color:var(--bad)}
.stp.hot .lost{color:var(--bad);font-weight:600}
.stp .chip{position:absolute;top:14px;right:15px;background:var(--paper)}
/* end-to-end column on the per-page journey */
.jend{text-align:right;flex:none;width:74px}
.jend b{display:block;font-size:15px;font-weight:620;letter-spacing:-.028em}
.jend s{display:block;text-decoration:none;font-size:11px;color:var(--faint);margin-top:2px}
/* the header has to carry the SAME columns as the rows or the step labels sit a column-width
   away from the numbers they name — the end-to-end column is 74px + an 18px gap of drift */
.jrow,.jhead{grid-template-columns:158px 1fr 74px}
.detail{display:grid;grid-template-columns:1.05fr 1fr;border-top:1px solid var(--line)}
.dl{padding:20px 22px 22px;border-right:1px solid var(--line)}
.dl h3{font-size:13.5px;font-weight:640;margin-bottom:3px}
.dl .s{font-size:12px;color:var(--mute);margin-bottom:15px}
.dr{padding:20px 22px 22px;background:var(--sunk)}
.dr h3{font-size:13.5px;font-weight:640;margin-bottom:3px}
.dr .s{font-size:12px;color:var(--mute);margin-bottom:15px}
@media (max-width:1040px){.detail{grid-template-columns:1fr}
  .dl{border-right:0;border-bottom:1px solid var(--line)}
  .steps{grid-template-columns:1fr 1fr}.stp:nth-child(3){border-left:0}}


/* ══ THE TEARDOWN ══════════════════════════════════════════════════════════ */
/* ═══ ONE PAGE, LOOKED AT CLOSELY ══════════════════════════════════════════════════════
   A bridge page is judged on four things — how many click through, how many get past the fold,
   how long they stay, and how far they read — so all four sit in the strip at the top beside
   the money, not folded into a chip on a card halfway down the screen.

   The engaged-time band table is gone. Six rows of "share of sessions in this bucket" had to be
   worked out before they said anything, and what they were really being asked was "do people
   stay long enough to read this", which is one number. */
/* THREE CHARTS, NOT TWO — CVR joins CTR and revenue per visitor, 30 Jul. They are the three rates
   the funnel multiplies out to, so they belong on one row at one width. */
.hcard{display:grid;grid-template-columns:1fr 1fr 1fr;margin-bottom:20px;overflow:hidden}
/* Centred, and the strip below is six across so 50% is one of its column rules. The divider
   has to land on a rule — one that misses by 80px reads as a mistake, not a boundary. */
.hl{padding:20px 20px 22px;min-width:0;display:flex;flex-direction:column}
.hr{padding:20px 20px 22px;border-left:1px solid var(--line);min-width:0;display:flex;flex-direction:column}
.hcard .quad{grid-column:1/-1}
/* the funnel spans both halves: it keeps the two charts the same height, and a four-segment
   strip reads better across the full card than squeezed under one of them */
.chartwrap{flex:1;min-height:150px;margin:14px 0 4px}
.chartwrap svg{display:block;width:100%;height:100%}
.chartx{display:flex;justify-content:space-between;font-size:10px;color:var(--faint)}
.layout{display:grid;grid-template-columns:352px 1fr;gap:20px;align-items:start}
.rightcol{display:grid;gap:20px}
.two{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start}
/* the heat stack */
.pageview{position:relative;max-height:860px;overflow-y:auto;overscroll-behavior:contain}
.pvrow{display:flex;align-items:stretch}
.canvas{position:relative;flex:1;min-width:0}
.pagefake{background:linear-gradient(178deg,#F0ECE5,#E6E1D7);padding:20px 18px}
.pagefake div{border-radius:3px;background:#CFC8BA;margin-bottom:8px}
.veil{position:absolute;inset:0;z-index:2;pointer-events:none}
.heat{position:absolute;inset:0;z-index:2;pointer-events:none;mix-blend-mode:multiply;opacity:.4}
.hotdot{position:absolute;z-index:3;width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;
  pointer-events:none;animation:pop .6s var(--ease) both;
  background:radial-gradient(circle,rgba(168,58,42,.6) 0%,rgba(214,120,60,.3) 45%,rgba(214,120,60,0) 70%)}
.marker{position:absolute;left:0;right:0;height:0;z-index:4}
.marker .ln{border-top:2px dashed var(--ink)}
.marker .lb{position:absolute;right:7px;top:-10px;background:var(--ink);color:#fff;font-size:9.5px;
  font-weight:650;padding:3px 7px;border-radius:5px;white-space:nowrap}
.marker.faint .ln{border-top-color:var(--faint)}
.marker.faint .lb{background:var(--mute)}
/* retention — a curve, because retention is continuous and a handful of bars pretend it isn't */
.curve svg{display:block;width:100%;height:170px}
.xax{display:flex;justify-content:space-between;margin-top:6px}
.xax span{font-size:10px;color:var(--faint)}
.bandrow{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:16px;
  padding-top:15px;border-top:1px solid var(--line)}
.bandrow .k{margin-bottom:5px}
.bandrow .v{font-size:17px;font-weight:620;letter-spacing:-.03em}
.bandrow .s{font-size:11px;color:var(--faint);margin-top:3px}
@media (max-width:1320px){.hcard{grid-template-columns:1fr}
  .hr{border-left:0;border-top:1px solid var(--line)}
  .layout{grid-template-columns:1fr}}


/* ══ COMPARE ══════════════════════════════════════════════════════════ */
/* ═══ COMPARE ══════════════════════════════════════════════════════════════════════════
   Two cards, the difference, and how much to believe it. No commentary: the reader is looking
   at the same numbers this file would be describing, and describing them just puts a paragraph
   between them and the screen. */
.picks{display:grid;grid-template-columns:1fr 54px 1fr;gap:16px;align-items:end;margin-bottom:22px}
.pf label{display:flex;align-items:center;gap:7px;margin-bottom:8px}
.pf label i{width:11px;height:11px;border-radius:3px;display:inline-block}
.vs{height:44px;display:flex;align-items:center;justify-content:center;
  font:700 11px/1 inherit;letter-spacing:.14em;color:var(--faint)}
.vgrid{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:22px}
.ctop{display:flex;align-items:flex-start;gap:10px}
.vtag{width:22px;height:22px;border-radius:6px;display:flex;align-items:center;justify-content:center;
  font-size:11.5px;font-weight:700;color:#fff;flex:none;margin-top:1px}
.pills{margin-left:auto;display:flex;gap:6px;flex:none}
.pills .amt{font-size:11.5px;font-weight:700;padding:4px 10px;border-radius:var(--r-pill);
  background:var(--acc-l);border:1px solid var(--acc-br);color:var(--acc);white-space:nowrap}
.pills .cf{font-size:11px;font-weight:650;padding:4px 9px;border-radius:var(--r-pill);
  border:1px solid var(--warn-br);background:var(--warn-l);color:var(--warn);white-space:nowrap}
/* the block sits in its own 400px column so it is the same object it is on Tests — stretched
   across a full-width card it was unrecognisable as the same thing */
.split{display:grid;grid-template-columns:400px 1fr;align-items:stretch}
.split>.res{border-right:1px solid var(--line)}
.sig{grid-template-columns:1fr 68px 58px 84px 96px 92px;gap:12px}
.sig>div:nth-child(n+2){text-align:right;white-space:nowrap}
/* below this the arm-name column in the table beside it drops under 160px and the row wraps to
   two lines — the block gives up the width because the table is the thing that needs it */
@media (max-width:1340px){.split{grid-template-columns:352px 1fr}}
/* below this the table needs the whole card, so the block stacks above it — its own max-width
   keeps it the same size it is on Tests rather than letting it stretch */
@media (max-width:1240px){.split{grid-template-columns:1fr}
  .split>.res{border-right:0;border-bottom:1px solid var(--line)}}
@media (max-width:1060px){.vgrid{grid-template-columns:1fr}
  .picks{grid-template-columns:1fr}.vs{height:auto;padding:4px 0}}


/* ══ TESTS ══════════════════════════════════════════════════════════ */
/* ═══ TESTS ════════════════════════════════════════════════════════════════════════════
   A test is two pages, so a test is a card with two pages in it — the same objects, the same
   funnel strip, the same colours as everywhere else.

   The question this screen answers is not "what is winning" but "can I call it yet", so the
   confidence bar with the 95% tick on it is the largest thing in the result block, and the
   estimate of how much longer it needs sits directly underneath. A leading arm quoted without
   that is an invitation to stop a test early, which is how noise gets promoted to strategy.

   The start form is folded away: on a screen whose job is READING tests, an open nine-field
   form is the loudest thing on it and the least often used. */
.tgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(540px,1fr));gap:22px;align-items:start}
.tcard{display:flex;flex-direction:column;overflow:hidden;animation:in .6s var(--ease) both;
  cursor:pointer;transition:box-shadow .22s var(--ease),transform .22s var(--ease)}
.tcard:hover{box-shadow:var(--sh-h);transform:translateY(-3px)}
.tcard.live:hover{box-shadow:0 0 0 1px var(--acc-br),var(--sh-h)}
.tcard:nth-child(2){animation-delay:.07s}
.tcard:nth-child(3){animation-delay:.14s}
.tcard.live{border-color:var(--acc-br);box-shadow:0 0 0 1px var(--acc-br),var(--sh)}
.tcard.demo{border-style:dashed}
.demopill{display:inline-flex;align-items:center;padding:3px 9px;border-radius:var(--r-pill);
  font-size:11px;font-weight:700;background:var(--warn-l);border:1px solid var(--warn-br);color:var(--warn)}
.arms{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;border-bottom:1px solid var(--line)}
.arm{position:relative;display:block;text-decoration:none;color:inherit;
  border-right:1px solid var(--line);min-width:0;padding-bottom:12px;transition:background .16s}
.arm:hover{background:var(--sunk)}
.arm:last-child{border-right:0}
.armshot{height:124px;background:linear-gradient(165deg,#EFEBE4,#E2DDD3);position:relative;overflow:hidden}
.armshot .fake{inset:12px 16px auto 16px}
.armshot::after{content:"";position:absolute;inset:auto 0 0 0;height:36px;
  background:linear-gradient(to bottom,rgba(255,253,251,0),var(--paper))}
.armlab{display:flex;align-items:center;gap:7px;padding:11px 14px 0;
  font-size:12.5px;font-weight:560;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.armlab b{flex:none;width:19px;height:19px;border-radius:6px;color:#fff;
  font-size:10.5px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}
.arm .fstrip{margin:11px 14px 0}
/* three metrics, the same three on every arm, in the shared 3-up joints grid */
.arm .joints{margin:8px 11px 0;gap:6px;grid-template-columns:repeat(4,auto);
  justify-content:space-between}
.arm .joints .j{font-size:10.5px;text-align:left}
.arm .joints .j b{font-size:12px;margin-right:3px}
.tfoot{display:flex;gap:8px;padding:11px 16px 13px;margin-top:auto}


/* ══ ONE TEST ══════════════════════════════════════════════════════════ */
/* ═══ READING A TEST ═══════════════════════════════════════════════════════════════════
   Conclusion, the two pages, where the gap opens, then the working.

   The arms are drawn as the same card as everywhere else and open the same teardown. A test
   screen that never shows you the pages makes you hold "which one was the variant again" in
   your head while reading a table.

   The monthly projection is blank below 95%: it is the number people act on, so it is the one
   most worth refusing to print. */
.vprob{flex:none;text-align:right;padding-left:14px}
.vprob .pv{font-size:33px;font-weight:620;letter-spacing:-.042em;line-height:1;color:var(--good)}
.vprob .pv.warn{color:var(--warn)}
.vprob .pk{font-size:10.5px;font-weight:600;color:var(--mute);margin-top:6px;white-space:nowrap}
.verdict{background:var(--paper);border:1px solid var(--acc-br);border-radius:var(--r-lg);
  box-shadow:0 0 0 1px var(--acc-br),var(--sh);overflow:hidden;margin-bottom:20px}
.vhead{display:flex;align-items:center;gap:16px;padding:18px 24px 15px}
.vclaim{min-width:0}
/* the four figures live IN the banner rather than in a strip under it — the claim is short
   and left a hand-span of empty card beside it */
.vfigs{border-top:1px solid var(--line);padding:13px 10px 16px}
.vfigs .v{font-size:20px;letter-spacing:-.038em}
.vfigs>div{padding:6px 14px}
.vmark{width:34px;height:34px;border-radius:11px;flex:none;display:flex;align-items:center;
  justify-content:center;font-size:16px;font-weight:700;background:var(--acc-l);color:var(--acc)}
.vhead h2{font-size:20px;font-weight:620;letter-spacing:-.034em}
.vhead .vsub{font-size:13px;color:var(--mute);margin-top:6px}
.vhead .vsub b{color:var(--ink);font-weight:640}
/* the monthly estimates are the widest figures on the board; below these widths the banner
   gives them their own full-width row rather than squeezing them into a quarter of one */
@media (max-width:820px){.vhead{flex-wrap:wrap}
  .vprob{padding-left:0;text-align:left}}
@media (max-width:1060px){.vgrid{grid-template-columns:1fr}}


/* ══ START A TEST ══════════════════════════════════════════════════════════ */
/* ═══ START A TEST ═════════════════════════════════════════════════════════════════════
   Its own screen, because it is a decision rather than a control. Folded into the Tests page
   it was the loudest object there and the least often used; on its own it can give the page
   picker the room it needs to show what each page actually looks like.

   Nothing here is reversible in the way a filter is: pressing the button starts the clock,
   and every figure the test ever reports is measured from that instant forward. */
.form{max-width:940px;display:grid;gap:26px}
.fsect{display:grid;gap:11px}
.fsect>.lbl{margin:0}
.fbar{display:flex;align-items:center;gap:12px;padding-top:4px;
  border-top:1px solid var(--line);margin-top:2px}
.fbar .btn{height:40px;padding:0 20px;font-size:13.5px}
.picked{font-size:12.5px;color:var(--mute);margin-left:auto}
.picked b{color:var(--ink);font-weight:640}

/* ══ LIVE-ONLY ═══════════════════════════════════════════════════════════════════════════
   Everything above is the design as it was drawn in mockups/v2/next. What follows exists only
   because the live board has things a static mockup does not: a timeframe control, a COGS
   freshness chip, loading and error states, and real page captures where the mockup drew a
   grey skeleton. */

.loading,.empty{padding:80px 20px;text-align:center;color:var(--faint);font-size:14px}
.errbox{max-width:640px;margin:60px auto;padding:18px 20px;background:var(--bad-l);
  border:1px solid var(--bad-br);border-radius:var(--r-lg);color:#7F1D1D;
  font-size:13.5px;line-height:1.6}

/* ── real captures ──
   The mockup drew `.fake`; here the box holds a JPEG of the live storefront. `height:auto` is
   load-bearing: the img carries width/height attributes from the capture manifest so its box is
   reserved before decode, and without `height:auto` that HEIGHT ATTRIBUTE wins over the aspect
   ratio — a 440×8155 capture rendered 44% too tall and put every heat band at the wrong depth. */
/* A card preview is the first DESKTOP screen — 1440×900. The card box is wider than 1.6:1 and
   grows with the grid, so `cover` fills the width and trims the bottom by an amount that changes
   with the viewport. That is fine for a thumbnail and is exactly why the pill states the page's
   LENGTH rather than naming a fold it cannot point at. */
.shot img,.armshot img,.ppick .shot img{width:100%;height:100%;object-fit:cover;
  object-position:top;display:block}
/* The teardown's capture is the exception and MUST keep its natural aspect ratio: the heat bands
   and the fold marker are positioned as a percentage of the document. */
.canvas img{width:100%;height:auto;display:block}
/* THE FOLD MARKER IS THE DESIGN'S, UNTOUCHED. It was overridden to sit at the very bottom with
   no rule — which dropped the pill into the card's fade-to-white gradient and left it barely
   legible, and removed a line that was doing visual work beyond marking a depth. The design's
   rule stays; nothing here overrides it. */
.shot.blank,.armshot.blank{display:flex;align-items:center;justify-content:center;
  color:var(--faint);font-size:11.5px}
.shot.blank .fold,.armshot.blank .fold{display:none}

/* ── the test edit form (LIVE-ONLY) ──
   A <details> so the screen it sits on stays a reading surface by default. Editing a running test
   is a deliberate act, not something to fall into while scanning a result. */
.editbox{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden}
.editbox summary{padding:13px 20px;font-size:13px;font-weight:620;cursor:pointer;
  list-style:none;color:var(--ink-2);transition:.16s}
.editbox summary::-webkit-details-marker{display:none}
.editbox summary::before{content:"＋";margin-right:9px;font-weight:500;color:var(--faint)}
.editbox[open] summary::before{content:"－"}
.editbox summary:hover{background:var(--sunk)}
.editbox .ebody{padding:6px 20px 18px;border-top:1px solid var(--line);
  display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;align-items:start}
.efield{min-width:0}
.efield label{display:block;font-size:11px;font-weight:650;letter-spacing:.05em;
  text-transform:uppercase;color:var(--mute);margin:10px 0 6px}
.einput{width:100%;height:40px;padding:0 13px;border:1px solid var(--line-2);
  border-radius:var(--r);background:var(--paper);font:520 14px/1 inherit;color:var(--ink);
  transition:.16s}
.einput:focus{outline:0;border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-l)}
.efield s{display:block;text-decoration:none;font-size:11.5px;color:var(--faint);margin-top:6px;
  line-height:1.45}
.erow{grid-column:1/-1;display:flex;align-items:center;gap:14px;margin-top:14px}
.emsg{font-size:12.5px;font-weight:600;color:var(--mute)}
.emsg.ok{color:var(--good)}
.emsg.bad{color:var(--bad)}

/* ── the working, inside the verdict banner ──
   Moved up from a card at the foot of the page: it is the evidence for the claim above it, not an
   appendix. Borderless and on the banner's own surface so it reads as part of the verdict rather
   than a table that happens to sit nearby. */
.vwork{border-top:1px solid var(--line)}
.vwork .thead{background:0;border-top:0}
.vwork .trow:last-child{border-bottom:0}

/* .mtitle, NOT .mk — `.mk` is already taken by the "95% ↑" marker on a test card, which sets
   text-align:right. Reusing the name silently right-aligned every metric card title on two
   screens, and nothing in the markup hinted at why. */
.mcard .mtitle{font-size:11.5px;font-weight:650;letter-spacing:.04em;text-transform:uppercase;
  color:var(--mute);text-align:left;margin:0 0 11px;padding:0 0 7px;
  border-bottom:1px dotted var(--line-2)}

/* The traffic chart is a supporting read, not a hero — the hero charts are 150px tall and this one
   was rendering at 317. */
.chartwrap.sm{min-height:0;height:104px;margin:10px 0 2px}


/* A metric grid sitting directly on the page rather than inside a card. Wrapped, every metric had
   two borders — the card's and its own — and the group names became bands in a table. On the page
   each card is its own object and the group name is a heading, the shape Overview already uses. */
.mgrid.bare{padding:0 0 4px}

/* The line-chart legend: names, because letters mean nothing to a reader who did not label them.
   Sits BELOW the plot: above it, the tooltip covered it — `.tip` translates -165% from the
   chart box, so it always lands over whatever is directly above the plot area. */
.lgnd{display:flex;flex-wrap:wrap;gap:16px;padding:8px 0 0;font-size:12px;color:var(--mute)}
.lgnd span{display:inline-flex;align-items:center;gap:7px;min-width:0}
.lgnd i{width:11px;height:3px;border-radius:99px;flex:none}
