
/* ── Vibrant-Mesh native home (mounts ONLY inside the Capacitor app; unused on web) ── */
.mh-root{position:relative;min-height:100vh;min-height:100dvh;background:#F7F5FB;color:#181530;font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',Roboto,sans-serif}
/* .mh-root deliberately has NO overflow-x. CSS forces overflow-y to auto whenever
   overflow-x is hidden, which turns this into a scroll container the page never scrolls —
   and position:sticky inside it silently stops working. The horizontal overflow it used to
   mask is fixed properly at source (.mh-grid uses minmax(0,1fr); .mh-gc has min-width:0). */
.mh-fx{position:absolute;top:0;left:0;right:0;height:440px;z-index:0;pointer-events:none;background:radial-gradient(400px 280px at 8% -4%,rgba(231,177,6,.4),transparent 60%),radial-gradient(420px 320px at 102% 3%,rgba(35,209,126,.22),transparent 62%),radial-gradient(500px 360px at 60% 17%,rgba(37,211,102,.22),transparent 64%)}
.mh-in{position:relative;z-index:1;padding:0 0 100px}
.mh-sbpad{height:env(safe-area-inset-top)}
/* Belt and braces for the Dynamic Island. The app calls setOverlaysWebView({overlay:true})
   so the webview draws UNDER the status bar, and this spacer is what pushes content clear.
   But capacitor.config.js also sets ios.contentInset:'always', and with both in play
   env(safe-area-inset-top) can report 0 inside the webview — the spacer then collapses and
   the wordmark lands under the Island (observed on a real iPhone 17 Pro). max() keeps the
   true inset where it is reported and falls back to a floor where it is not. Scoped to
   .cap-ios, a class the app already sets, so browsers are untouched. */
html.cap-ios .mh-sbpad{height:max(env(safe-area-inset-top),52px)}
/* Search and the chips stay reachable while the grid scrolls under them. Translucent so the
   mesh still reads through, which is what stops it looking like a pasted-on bar. The block
   carries .mh-sbpad, so it keeps clearing the Dynamic Island when pinned. */
.mh-stick{position:sticky;top:0;z-index:40;background:rgba(250,252,251,.78);
  -webkit-backdrop-filter:blur(20px) saturate(150%);backdrop-filter:blur(20px) saturate(150%);
  border-bottom:1px solid rgba(24,21,48,.06)}
.mh-cnt{font-size:12px;font-weight:700;color:#129E52;white-space:nowrap}
/* Rotating + swipeable hero. A scroll-snap track rather than a JS slider, so iOS gives us
   momentum, rubber-band and snapping for nothing; the timer only nudges it and stands down
   for 8s whenever a finger touches it. One accent per section, all on the same ink base —
   six unrelated backgrounds would read as six different components. */
/* The bar that replaces the live input — same shell, so nothing shifts when it opens. */
.mh-fakein{flex:1;min-width:0;border:0;background:transparent;font:inherit;font-size:14px;
  color:#9c98b0;text-align:left;padding:0;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Full-screen search. Sits above the sticky header and the tab bar. */
.mh-srch{position:fixed;inset:0;z-index:120;background:#F7F5FB;display:flex;flex-direction:column;
  overflow-y:auto;-webkit-overflow-scrolling:touch;animation:mhSrchIn .22s cubic-bezier(.32,.72,0,1) both}
@keyframes mhSrchIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.mh-field-live{box-shadow:0 0 0 2px #23D17E,0 10px 26px -12px rgba(90,60,180,.4)}
.mh-cancel{border:0;background:none;font:inherit;font-size:13px;font-weight:800;color:#0E7C5A;
  padding:0 2px;min-height:44px;cursor:pointer;flex:none}
.mh-paste{display:flex;align-items:center;gap:11px;margin:12px 16px 4px;padding:12px 14px;min-height:44px;
  background:#fff;border:1px dashed #23D17E;border-radius:14px;font:inherit;text-align:left;cursor:pointer}
.mh-pi{font-size:19px;flex:none}
.mh-paste b{display:block;font-size:13px;color:#181530}
.mh-paste em{display:block;font-style:normal;font-size:11px;color:#7a7690;margin-top:2px}
.mh-srh{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:#9c98b0;font-weight:800;padding:16px 18px 4px}
.mh-srr{display:block;width:100%;text-align:left;min-height:44px;border:0;border-bottom:1px solid rgba(24,21,48,.07);
  background:none;font:inherit;font-size:14px;color:#181530;padding:0 18px;cursor:pointer}
.mh-schips{padding:4px 16px 2px;flex-wrap:wrap;overflow:visible}
.mh-scanbig{margin:20px 16px 40px;min-height:48px;border:0;border-radius:15px;background:#181530;color:#fff;
  font:inherit;font-weight:800;font-size:14px;cursor:pointer}
.mh-hero{position:relative;padding:14px 16px 0}
.mh-htrack{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;border-radius:17px}
.mh-htrack::-webkit-scrollbar{display:none}
.mh-hslide{flex:0 0 100%;scroll-snap-align:center;display:flex;align-items:center;gap:11px;min-width:0;
  border:0;font:inherit;text-align:left;color:#fff;border-radius:17px;padding:13px 15px;min-height:74px;
  cursor:pointer;box-shadow:0 12px 26px -14px rgba(24,21,48,.75)}
.hs-rarest  {background:linear-gradient(135deg,#101B2E,#12402F)}
.hs-verified{background:linear-gradient(135deg,#101B2E,#0E3A44)}
.hs-drop    {background:linear-gradient(135deg,#101B2E,#4A2A0B)}
.hs-deep    {background:linear-gradient(135deg,#101B2E,#132A55)}
.hs-rarest   .mh-htag,.hs-rarest   .mh-ht b,.hs-rarest   .mh-hgo{color:#4BE89B}
.hs-verified .mh-htag,.hs-verified .mh-ht b,.hs-verified .mh-hgo{color:#46D9E0}
.hs-drop     .mh-htag,.hs-drop     .mh-ht b,.hs-drop     .mh-hgo{color:#FFB03A}
.hs-deep     .mh-htag,.hs-deep     .mh-ht b,.hs-deep     .mh-hgo{color:#7FA8FF}
.mh-hl{flex:1;min-width:0}
.mh-htag{display:block;font-size:9px;font-weight:800;letter-spacing:.13em;margin-bottom:4px}
.mh-ht{display:block;font-size:13.5px;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mh-hs{display:block;font-size:10.5px;color:#93A6BE;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mh-hgo{font-size:23px;font-weight:800;flex:none}
.mh-hdots{position:absolute;left:0;right:0;bottom:-11px;display:flex;justify-content:center;gap:6px}
/* 4px dot in a 44pt-friendly hit slug */
.mh-hdots i{width:5px;height:5px;border-radius:50%;background:rgba(24,21,48,.22);cursor:pointer;
  box-shadow:0 0 0 6px transparent;transition:background .2s,transform .2s}
.mh-hdots i.on{background:#129E52;transform:scale(1.35)}
@media (prefers-reduced-motion: reduce){ .mh-htrack{scroll-behavior:auto} }
.mh-bar{display:flex;justify-content:center;align-items:center;padding:7px 16px 5px}
.mh-brand{display:flex;align-items:center;gap:9px}
.mh-amk{width:40px;height:40px;flex:none;display:block}
.mh-amk svg{transform-origin:center;animation:mhIn .6s cubic-bezier(.2,.8,.2,1) both}
.mh-amk ellipse{animation:mhGlow 3.2s ease-in-out infinite}
.mh-amk .mh-ck{stroke-dasharray:44;stroke-dashoffset:44;animation:mhDraw .7s .35s ease forwards}
.mh-wm{font-size:21px;font-weight:800;letter-spacing:-.015em;color:#181530}.mh-wm .g{color:#129E52}
.mh-srow{padding:5px 16px 2px}
.mh-field{display:flex;align-items:center;gap:11px;background:rgba(255,255,255,.8);border:1px solid rgba(24,21,48,.07);border-radius:16px;padding:13px 13px;box-shadow:0 10px 26px -12px rgba(90,60,180,.4);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);animation:mhFieldGlow 3.2s ease-in-out infinite}
.mh-field input{flex:1;border:none;background:transparent;outline:none;font-size:14px;color:#181530;min-width:0}
.mh-field input::placeholder{color:#9c98b0}
.mh-mag{opacity:.45;flex:none}
.mh-scan{width:38px;height:38px;border-radius:11px;background:linear-gradient(160deg,#F7CF20,#E7B106);display:flex;align-items:center;justify-content:center;color:#0A0E17;flex:none;box-shadow:0 5px 14px rgba(231,177,6,.42);border:none;position:relative;overflow:hidden;animation:mhScanPulse 2.2s ease-in-out infinite}
.mh-scan svg{width:19px;height:19px}
.mh-scan::after{content:'';position:absolute;left:7px;right:7px;height:2px;border-radius:2px;background:rgba(255,255,255,.92);box-shadow:0 0 7px rgba(255,255,255,.85);animation:mhScanline 1.9s ease-in-out infinite}
.mh-sub{text-align:center;font-size:11.5px;color:#9c98b0;margin:10px 0 0}.mh-sub b{color:#0E7C5A;font-weight:700}
.mh-chips{display:flex;gap:8px;padding:9px 16px 9px;overflow-x:auto;-webkit-overflow-scrolling:touch}
.mh-chips::-webkit-scrollbar{display:none}
.mh-chip{white-space:nowrap;font-size:12px;font-weight:700;padding:8px 13px;border-radius:20px;background:rgba(255,255,255,.8);border:1px solid rgba(24,21,48,.07);color:#5b5776;cursor:pointer}
.mh-chip.on{background:linear-gradient(150deg,#3AE08F,#12b76a);color:#053a2c;border:1px solid transparent}
.mh-sec{display:flex;align-items:baseline;justify-content:space-between;padding:18px 18px 12px}
.mh-sec h3{font-size:16px;margin:0;color:#181530;font-weight:800;letter-spacing:-.01em}
.mh-sec a{font-size:12px;color:#0E7C5A;font-weight:700;text-decoration:none;cursor:pointer}
.mh-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:11px;padding:0 16px}
.mh-gc{min-width:0}
.mh-gc{position:relative;background:rgba(255,255,255,.8);border:1px solid rgba(24,21,48,.07);border-radius:20px;padding:10px;box-shadow:0 12px 30px -16px rgba(90,60,180,.4);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);text-align:left;cursor:pointer;font:inherit;color:inherit}
.mh-gc .im{width:100%;height:86px;border-radius:14px;background:#fff;display:flex;align-items:center;justify-content:center;margin-bottom:9px;overflow:hidden}
.mh-gc .im img{max-width:82%;max-height:82%;object-fit:contain}
.mh-gc .bdg{position:absolute;top:16px;right:16px;font-size:9.5px;font-weight:800;padding:4px 9px;border-radius:20px;transform:rotate(-4deg)}
.mh-gc .chk{position:absolute;top:16px;right:15px;font-size:9px;font-weight:800;color:#0E7C5A;background:rgba(18,158,82,.12);padding:4px 8px;border-radius:20px}
.mh-buy{color:#fff;background:linear-gradient(150deg,#2fd06f,#129E52);box-shadow:0 5px 14px rgba(18,158,82,.4)}
.mh-skip{color:#E23D6B;background:rgba(226,61,107,.14);border:1px solid rgba(226,61,107,.3)}
.mh-wait{color:#B8860B;background:rgba(231,177,6,.16);border:1px solid rgba(231,177,6,.35)}
.mh-fair{color:#5b6b86;background:rgba(91,107,134,.14);border:1px solid rgba(91,107,134,.28)}
.mh-nm{font-size:12px;font-weight:600;color:#181530;line-height:1.25;margin-bottom:5px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:30px}
.mh-prow{display:flex;align-items:baseline;gap:6px}
.mh-now{font-size:15px;font-weight:800;color:#181530;font-variant-numeric:tabular-nums}
.mh-was{font-size:11px;color:#8a849c;font-weight:600}.mh-was s{text-decoration:line-through;font-weight:500;color:#9c98b0}
.mh-empty{padding:34px 20px;text-align:center;color:#9c98b0;font-size:13px}
.mh-tabbar{position:fixed;bottom:0;left:0;right:0;background:#fff;border-top:1px solid rgba(14,26,43,.08);display:flex;align-items:flex-start;padding:6px 6px calc(6px + env(safe-area-inset-bottom));z-index:45;box-shadow:0 -1px 0 rgba(14,26,43,.04)}
.mh-tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;font-size:9px;font-weight:600;color:#8a919c;background:none;border:none;cursor:pointer;position:relative;font-family:inherit}
.mh-tab.on{color:#0E7C5A}.mh-tab svg{width:22px;height:22px}
.mh-tab.center{margin-top:-14px;color:#0E7C5A}
.mh-tab.center .fab{width:50px;height:50px;border-radius:50%;background:linear-gradient(180deg,#3AE08F,#12b76a);display:flex;align-items:center;justify-content:center;box-shadow:0 8px 18px -8px rgba(18,158,82,.5);margin-bottom:2px;border:3px solid #fff}
.mh-tab.center .fab svg{width:23px;height:23px;stroke:#053a2c}
.mh-tab .wn{position:absolute;top:-1px;right:calc(50% - 22px);background:#12b76a;color:#fff;font-size:8px;font-weight:800;min-width:15px;height:15px;border-radius:8px;display:flex;align-items:center;justify-content:center;padding:0 3px}
@keyframes mhIn{0%{transform:scale(.5) rotate(-10deg);opacity:0}100%{transform:scale(1) rotate(0);opacity:1}}
@keyframes mhGlow{0%,100%{opacity:.16}50%{opacity:.44}}
@keyframes mhDraw{to{stroke-dashoffset:0}}
@keyframes mhFieldGlow{0%,100%{box-shadow:0 10px 26px -13px rgba(90,60,180,.4)}50%{box-shadow:0 12px 32px -8px rgba(35,209,126,.42)}}
@keyframes mhScanPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
@keyframes mhScanline{0%{transform:translateY(-12px);opacity:0}15%,85%{opacity:.95}100%{transform:translateY(12px);opacity:0}}
@media (prefers-reduced-motion:reduce){.mh-amk svg,.mh-amk ellipse,.mh-amk .mh-ck,.mh-field,.mh-scan,.mh-scan::after{animation:none}.mh-amk .mh-ck{stroke-dashoffset:0}}
/* ══════════════════════════════════════════════════════════════════════════════════════════
   REDESIGN — CHROME  (claude/redesign-2026-08, owner-directed 14 Aug 2026)

   Trailing override layer, not surgery: every rule targets an existing class, nothing above is
   deleted, and reverting is one block.

   TARGET NOTE: the pinned header on the storefront is `.rd-topwrap` (a sticky gradient), NOT
   `.sf-stick`. I patched `.sf-stick` first and the page did not change — the class exists in the
   stylesheet but this route does not use it. Verified with elementFromPoint after scrolling.

   WHAT CHANGED
   · Chrome goes from the navy gradient to a light-yellow wash. Measured L*96 / C 0.047 against
     WAIT amber's L*77 / C 0.156 — same warm family, a third the saturation, far lighter, so it
     reads as tinted paper and cannot be taken for a verdict badge (product invariants §1). An orange
     chrome was tested and rejected: it lands at L*52 with chroma close to amber's.
   · Light ground means dark type. Pairs re-measured: wordmark 15.76:1, nav 6.69:1, accent 5.25:1,
     placeholder 5.66:1. None below AA.
   · `.com` dropped from the lockup — widest and faintest thing in the bar, and the lockup is a
     name, not a URL.
   · Wordmark moves to `ui-rounded` (SF Pro Rounded on Apple platforms) so it shares a voice with
     the Nunito Black mark instead of being a second typeface.
     CAVEAT: falls back to system-ui on Windows/Android; shipping properly means self-hosting
     Nunito, which the App Icon already uses.

   NOT DONE — the monogram is a raster
   `/wi-mark.png` is a PNG, so its ground cannot be recoloured in CSS. The ink-chip + gold-"?"
   treatment needs `scripts/gen-icons.mjs` re-run from a new master. Left alone deliberately.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

:root{
  /* WHITE, apple.com-style (owner, 15 Aug 2026). Measured off apple.com's .globalnav rather than
     guessed: it paints rgba(255,255,255,.8) behind `saturate(180%) blur(20px)` and carries NO
     bottom border — the separation comes from the page ground showing through the blur.
     This supersedes the mock's light yellow. The yellow existed to sit far from WAIT amber
     (L*96 C.047 vs L*77 C.156); white is C 0 and cannot collide with the verdict palette at all,
     so the argument that justified the yellow is satisfied more strongly, not weakened. */
  /* LANDING CHROME (owner, 25 Aug 2026) — #0B1220 continuous with BrandMoment.
     Supersedes Space Black #2D2D2F: a grey header over a navy hero card was the measured bug
     (header rgb(45,45,47) → seam → hero card #0B1220). Header + hero are ONE near-black band.
     Fully opaque — no color-mix with white (that reproduced #2D2D2F and the split). */
  --rd-chrome:11,18,32;
  --rd-chrome-a:1;
  /* Flat alias kept for older rules / @supports branch — same value as rgb(var(--rd-chrome)). */
  --rd-chrome-flat:#0B1220;
  --rd-ink:#F5F5F7; --rd-ink2:#A1A1A6; --rd-acc:#2997FF;
  /* The LOCKUP's accent, separate from --rd-acc on purpose (owner picked option C, 15 Aug).
     --rd-acc is Apple accent blue and stays that for the rest of the chrome — strip links, focus.
     The mark and the wordmark are brand, not chrome: product invariants has always specified "white Wi +
     deep teal ?" and "foryou is teal as ONE unit (site + WiApp)". The Space Black pass pointed
     both at --rd-acc, which quietly turned the header lockup blue while the base sheet, the
     scrolled sticky wordmark and the iOS app all stayed teal — so the site stopped matching its
     own app icon. This token is what makes the drift impossible to repeat by accident.
     #14B8A6 rather than the App Icon's own #0D9488: measured 5.52:1 here against 3.67:1, and the
     deeper teal only clears AA on the icon's indigo ground, which the header does not have. */
  --rd-lockup:#14B8A6;
  --logo-bar:#2C2C2E;
  --logo-sticker:#FFC21A;
  --logo-sticker-ink:#1D1D1F;
  --logo-foryou:#FFFFFF;
  /* The full Apple cool ramp on the logotype (owner picked option 4, 15 Aug). Indigo -> blue ->
     cyan, all three from Apple's DARK-mode system set. Stops are ordered so the darkest sits at
     the start of a 120deg sweep, which on both glyph runs puts it in the least-read corner.
     Of Apple's ten system colours only cyan and teal are usable bare on this chrome: five fail
     contrast and four sit within 26 degrees of a verdict hue (orange is 1 degree off WAIT amber,
     red 3 off SKIP). The two used here that fail as TEXT are legitimate only because a logotype is
     exempt from the contrast minimum — see the note at .rd-mg and scripts/check-contrast.mjs. */
  --rd-lockup-ramp:linear-gradient(120deg,#5E5CE6 0%,#0A84FF 42%,#64D2FF 100%);
  /* Secondary text on the CHROME can be --rd-ink2 (5.42:1). Secondary text inside the search WELL
     cannot: the well is rgba(255,255,255,.10) over the bar = rgb(66,66,68), and --rd-ink2 measures
     only 3.90 there. One token for everything sitting on the well, at 5.07:1.
     This is not a nicety — check:contrast caught "All ▾" at 1.32:1 on the first build, and it
     CANNOT catch ::placeholder, which is a pseudo-element the DOM walker never visits. */
  --rd-well-ink:#B8B8BD;
  /* SF Pro Display FIRST (owner 16 Aug) — same face as WiApp wordmark. Raster App Icon
     remains Nunito Black in mobile/assets/icon.png; this stack is for live type lockups. */
  --rd-brandfont:-apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text",system-ui,sans-serif;
}

/* FLAT #0B1220 — same surface as BrandMoment on home (owner, 25 Aug). No Space Black grey bar. */
.rd-topwrap{
  background:rgb(var(--rd-chrome)) !important;
  border-bottom:1px solid rgba(255,255,255,.08) !important;
  box-shadow:0 8px 22px -20px rgba(0,0,0,.75) !important;
}
/* @supports color-mix branch retired for chrome fill: landing chrome is opaque #0B1220.
   Older engines and modern ones both get rgb(var(--rd-chrome)). */
.rd-topwrap.scrolled{box-shadow:0 12px 30px -18px rgba(0,0,0,.85) !important}

/* ── MONOGRAM AS TYPE ────────────────────────────────────────────────────────────────────
   Closes the "NOT DONE — the monogram is a raster" note above. /wi-mark.png bakes its own
   #141a21 tile in, so on any chrome but the old navy it sat as a dark chip in a bar of a
   different colour, and no CSS could recolour it. Set in --rd-brandfont it is the SAME face
   as the wordmark, so the lockup is one piece of type: it recolours with the tokens, stays
   sharp at any size, and drops a 256x256 request from the header.
   1.34x is the optical correction — caps beside lowercase measure level but never read level.
   Only the DESKTOP header is converted here; the boot screen and the mobile lockup still use
   the PNG, so gen-icons.mjs is still the source of truth for the app icon and favicon. */
/* ── LOCKUP ALIGNMENT ────────────────────────────────────────────────────────────────────
   Two bugs here, neither visible without measuring, both fixed 15 Aug on the owner's
   "make sure it is aligned well in the header".

   1. SIZE. The mark was `1.34em` — 1.34x .rd-brand, which is a FIXED var(--wm-md) = 20px, giving
      26.8px in every state. The thing it optically corrects against is the WORDMARK, and that
      moves: --wm-lg 26px at rest, --wm-md 20px scrolled, --wm-sm 16px on a scrolled phone. The
      mark never moved with it, so it was right at rest (26.8 against 26) and up to a third
      oversized once the wordmark condensed.
      Note what 1.34 actually was: the ratio to the CONTAINER, not the correction. Against the
      wordmark it worked out at 26.8/26 = 1.03, and 1.03 is the number that reproduces the resting
      lockup — so that is the ratio, now expressed against --rd-wm which tracks the wordmark state
      for state. Reading 1.34 as "1.34x the wordmark" was my first attempt and it blew the mark up
      to 34.84px at rest, visibly larger than it has ever been. Measured, seen, corrected.

   2. BASELINE. .rd-brand is flex with align-items:center, so two runs of DIFFERENT size were
      centred on each other rather than seated on one baseline. Measured spread: 0.61px at rest,
      2.61px scrolled and on phone. A logotype whose halves are centre-aligned reads subtly wrong
      without ever looking broken, which is why this survived so long. .dk-wm already had
      align-items:baseline internally; the outer row did not.

   Keep the two together: fixing the size without the baseline still leaves a spread, because
   1.34x means the two runs can never be the same height. */
.rd-topwrap .rd-brand{align-items:baseline}
.rd-topwrap .rd-brand{--rd-wm:var(--wm-lg)}
.rd-topwrap.scrolled .rd-brand{--rd-wm:var(--wm-md)}
.sf.m-page .rd-brand{--rd-wm:var(--wm-md)}
.sf.m-page .rd-topwrap.scrolled .rd-brand{--rd-wm:var(--wm-sm)}
.rd-brand .rd-mg{
  font-family:var(--rd-brandfont);font-weight:800;line-height:1;
  font-size:calc(var(--rd-wm, var(--wm-lg)) * 1.03);
  letter-spacing:-.04em;color:var(--rd-ink);flex:0 0 auto;
}
/* THE "?" WAS BEING CLIPPED ON ITS RIGHT EDGE (2026-08-16). Measured, not guessed, in Nunito Black
   at the header's 26.78px:
       glyph advance   12.80px
       letter-spacing  -1.07px   (-.04em, inherited from .rd-mg)
       <i> layout box  11.73px   (advance + the negative tracking)
       glyph ink ends  12.67px
       => 0.94px of the "?" sits OUTSIDE its own background box
   That only shows up because the "?" is painted with `background-clip:text`: the gradient is drawn
   into the element's BACKGROUND BOX and clipped to the glyph, so any ink beyond the box simply
   receives no paint and disappears. With a plain `color` the same glyph overflows harmlessly and
   looks fine — which is why this survived the ramp being added and was never visible before it.
   Letter-spacing exists to tighten the gap BETWEEN letters and there is no letter after "?", so the
   trailing tracking is pure loss. Removing it on the <i> restores the full 12.80px advance without
   touching the gap between "i" and "?", which comes from the tracking on the parent's own "i". */
.rd-mg i,.nh-mg i{letter-spacing:normal}
.rd-brand .rd-mg i{font-style:normal;color:var(--rd-lockup)}
/* Backdrop 01 "Midnight Well" — a radial of the brand's own ink, DARKER than the chrome, held to
   the brand zone. It has to darken: the accent clears AA by only 0.12 on this bar, so any glow
   that lightens the ground fails the "?" immediately (an accent wash at a .06 alpha drops it to
   4.28). Darkening pays contrast back instead — measured #1f242d, ink 14.30, accent 5.16. */
/* The plate BLEEDS via the pseudo-element's inset — it must not change the brand's layout box.
   Padding + negative margin did: it added 28px of width and pulled .rd-brand 14px into .rd-nav,
   which the grid then resolved as an 83px overlap. */
.rd-topwrap .rd-brand{position:relative;isolation:isolate}
.rd-topwrap .rd-brand::before{content:"";position:absolute;inset:-6px -12px;z-index:0;
  border-radius:14px;
  background:radial-gradient(120% 150% at 22% 50%,rgba(14,26,43,.72),rgba(14,26,43,0) 72%);
  pointer-events:none}
.rd-topwrap .rd-brand > *{position:relative;z-index:1}

/* ── HEADER LAYOUT — rebuilt to design/mock/ `.bar` (owner, 15 Aug 2026) ──────────────────
   Mock: `grid-template-columns:auto minmax(0,1fr) auto`, height 58, brand left, nav centred,
   search right. We carry a FOURTH column for the account button: the mock is silent on it
   rather than removing it, and it is the only route to menu/account on desktop.
   The mock's 340px pill also assumes no store filter and no Check button. Owner kept both, so
   the field is sized to what it actually contains instead of to the mock's number — matching
   340 while holding three more controls would just crush them. */
/* Two columns now — brand and search. The pages moved out to their own strip below, which is
   what frees the bar and lets the search be the only thing competing with the wordmark. */
.rd-topwrap .rd-topbar{
  display:grid !important;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:18px;min-height:64px;
}
/* ── SEARCH GROWS ON SCROLL ────────────────────────────────────────────────────────────────
   At the top the hero owns the search, so the bar carries a compact pill. As the hero leaves,
   the pill widens to take over — by the time the big field is gone the bar holds a full-size one,
   frozen at the top of the screen, so you never scroll back up to check something.
   Driven by the native scroll() timeline: no listener, no rAF, nothing to leak — the same
   mechanism as the shelf reveal. Guarded twice, and the DEFAULT IS THE COMPACT PILL, so a
   browser without scroll-driven animation simply keeps the small search rather than breaking. */
/* Owner landing 2026-08-25: paste is always in the header (center), never only after scroll. */
.rd-search{justify-self:center;min-width:0;width:100%;max-width:min(560px,100%)}
/* The search element ships as a full search BAR (.sf-top wrapper + 52px .sf-sbox) because it is
   also the hero's field on other surfaces. In the header it has to collapse to the mock's 40px
   pill, so the wrapper's own padding goes and the box is pinned. Measured before and after rather
   than nudged: .rd-search was 68px, which alone put the bar at 86 against the mock's 58. */
.rd-topwrap .rd-search .sf-top{padding:0 !important;margin:0 !important;border:0 !important;
  background:none !important;box-shadow:none !important}
.rd-topwrap .rd-search .sf-search{margin:0 !important;max-width:none !important}
.rd-topwrap .rd-search .sf-sbox{min-height:42px !important;height:42px !important;
  border-radius:999px !important;overflow:hidden}
/* The mock's bar is 58px and its scan affordance is an icon INSIDE the field. Ours is a separate
   92x52 stacked button with a "Scan" caption, which alone forced the bar to 92px. In the bar it
   becomes a 40px icon button so the row can hold the mock's height; the stacked version stays for
   every other surface. The caption is hidden, so the button carries an explicit aria-label —
   without it the accessible name would fall back to `title`, which is not a reliable substitute. */
.rd-topwrap .rd-topbar{min-height:64px;padding-top:11px;padding-bottom:11px}
.rd-topwrap .rd-topbar .sf-scanbtn{
  flex-direction:row;gap:0;width:42px;min-width:42px;height:42px;min-height:42px;
  border-radius:999px;padding:0;box-shadow:none;animation:none}
/* font-size:0 hides the caption WITHOUT hiding the icon. `display:none` on span did both — the
   icon is wrapped in one — and shipped a blank green circle. */
.rd-topwrap .rd-topbar .sf-scanbtn{font-size:0 !important}
.rd-topwrap .sf-scan-t{color:#99F6E4}   /* dark chrome — the button's own light teal */
/* The mobile-home top bar is the OTHER dark ground this button sits on, and it is not inside
   .rd-topwrap — the visible instance at 402px is .sf-scanbtn < .sf-search < .sf-top < .srow <
   .mtop < .mhome. Found by walking the ancestors of the element the sweep flagged; my first guess
   at the container was wrong and measured as still-failing. */
.mhome .sf-scan-t{color:#99F6E4}
.rd-topwrap .rd-topbar .sf-scanbtn .sf-scan-t{display:none !important}
.rd-topwrap .rd-topbar .sf-scanbtn svg{width:19px !important;height:19px !important;display:block}
.rd-topwrap .rd-topbar .sf-sgo{padding:0 16px}
.rd-topwrap .rd-topbar .rd-you{width:38px;height:38px}
/* ── OFF-HOME BAR: same ground and accent as home ─────────────────────────────────────────────
   These two have to sit HERE, not beside the `body:has(.hcwrap)` pair they extend. That pair is
   declared ~8,500 lines above `.rd-topwrap{background:rgb(var(--rd-chrome)) !important}`, and
   against an equally-specific `!important` the LATER rule wins — so the copy written up there
   applied to nothing and the bar stayed on the fallback gradient. Measured, not assumed: the
   matched-rule list for .nh-topwrap ended on --rd-chrome with the #2B2631 rule sitting above it.
   The ground: matching the Snipcart hero was the original reason for #2B2631; matching HOME is
   the reason now, and a flat near-black holds on its own with no band under it.
   The accent: "one accent means one thing everywhere" is the note on the home rule, and an accent
   that means one thing everywhere cannot be switched off on three routes. 8.9:1 on #2B2631. */
/* Both selectors double up `.nh-topwrap.rd-topwrap` so they win on SPECIFICITY rather than on
   source order. Order alone is not enough here: the one-colour-wordmark rule
   `.rd-topwrap .rd-brand .dk-wm .f{color:var(--rd-ink) !important}` is (0,4,0) and declared after
   this block, so a matching (0,4,0) of mine lost and "foryou" stayed #F5F5F7. Home wins the same
   fight with `body:has(.hcwrap) …` at (0,5,0); this is that trick without the home-only gate. */
.nh-topwrap.rd-topwrap{background:#2B2631 !important;border-bottom:none !important}
.nh-topwrap.rd-topwrap .rd-brand .dk-wm .f{color:#FFCC00 !important}

/* ── OFF-HOME BAR: this route's own actions on the shared dark ground ─────────────────────────
   The verdict/product/browse/you routes render the SAME .rd-topwrap as the storefront, but keep
   their own three controls (saved · you · menu). Those were authored for the old light .nh-nav —
   white fill, --line border, --ink2 glyph — which on this ground reads as three white chips. */
.rd-topwrap .nh-links{display:flex;align-items:center;gap:10px;margin-left:0;flex:0 0 auto}
.rd-topwrap .nh-scan,.rd-topwrap .nh-burger{
  width:38px;height:38px;min-width:38px;border-radius:999px;padding:0;
  background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.16);color:#EEF2F8}
.rd-topwrap .nh-scan:hover,.rd-topwrap .nh-burger:hover{
  background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.28);color:#fff}
/* The bar's own light teal, the same one .sf-scan-t uses on this ground. */
.rd-topwrap .nh-scan.nh-on{
  background:rgba(20,184,166,.22);border-color:rgba(20,184,166,.5);color:#99F6E4}
.rd-topwrap .nh-scan svg,.rd-topwrap .nh-burger svg{width:19px;height:19px}
/* Phone: the 3-column grid puts brand + search + three buttons on one 390pt row and crushes the
   field. Search drops to its own row instead — the shape .nh-nav-in used before this merge. */
@media(max-width:720px){
  .nh-topwrap .rd-topbar{grid-template-columns:auto 1fr !important;row-gap:10px;
    padding:10px 16px !important}
  .nh-topwrap .rd-brand{grid-area:1/1}
  .nh-topwrap .nh-links{grid-area:1/2;justify-self:end}
  .nh-topwrap .rd-search{grid-area:2/1/3/3;max-width:none}
}
/* WIDTH BUDGET, measured not guessed. The mock's bar fits at 1280 because it carries three things
   we do not: no account button, no "All ▾" store filter, no Check button. Owner kept all three
   (15 Aug), which costs ~175px, so the inline nav needs ~1400px to sit without colliding:
       1440  brand 227 + nav 658 + search 426 + you 38 + gaps/pad 106  = fits
       1280  same content, overlaps by 69px and 70px
   Below the budget the nav returns to the strip under the hero — the same place phones keep it —
   instead of being crushed or having its labels rewritten. One rule, no JS, no width listener. */
/* ── PAGES STRIP — full bleed under the bar, frozen with it (design/mock/ `.tabs`) ─────────
   Not its own sticky layer. Nested sticky + a shrinking header is what made the strip bounce
   on iOS. Light on purpose: a second dark band under the bar was the TALLY look, removed 14 Aug. */
.sf-tabbar{position:relative;top:auto;z-index:1;
  background:rgba(255,255,255,.92);
  -webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid #E1E4E9;padding:0;overflow:visible}
.sf-tabbar::-webkit-scrollbar{display:none}
.sf-tabbar .sf-tabs{display:flex;align-items:stretch;gap:2px;background:none;border:0;
  box-shadow:none;padding:0}
.sf-tabbar .sf-tab{position:relative;display:inline-flex;align-items:center;gap:7px;
  padding:12px 14px 13px;font:600 13px/1 system-ui;letter-spacing:-.012em;color:#3D4654;
  white-space:nowrap;border:0;background:none;border-radius:9px 9px 0 0;min-height:0;
  transition:color .16s,background .16s;cursor:pointer}
.sf-tabbar .sf-tab svg{width:15px;height:15px;opacity:.85}
.sf-tabbar .sf-tab:hover{color:#141A21;background:rgba(20,26,33,.04)}
/* #0E7C74 measured 4.40:1 against its OWN tinted chip — 0.1 under AA, which only became visible
   once the tabs stopped being overridden by the dark chrome's ink and the contrast sweep could
   resolve them. Two notches darker clears it at 4.99:1 on the chip and 6.35:1 on the bare strip,
   at the same hue. The chip is measured as the backdrop here, not the strip: the active tab paints
   its own background, so that is what its label actually sits on. */
.sf-tabbar .sf-tab.on,.sf-tabbar .sf-tab[aria-selected="true"]{color:#0A524C;
  background:rgba(20,184,166,.10);font-weight:700}
/* Owner landing: All Deals tab uses brand teal wash — mint reserved for BUY stamps only. */
.sf-tabbar .sf-tab.t-all.on,.sf-tabbar .sf-tab.t-all[aria-selected="true"]{
  color:#0A524C;background:rgba(20,184,166,.10)}
.sf-tabbar .sf-tab.on svg{opacity:1}
.sf-tabbar .sf-tab.on::after{content:"";position:absolute;left:12px;right:12px;bottom:0;
  height:2.5px;border-radius:2px 2px 0 0;background:#0E7C74}

/* lockup — the spans are .w / .f / .d, read off the live DOM after guessing wrong twice.
   SPECIFICITY, not !important, is what decides here: `.rd-brand .dk-wm .w` already carries
   `color:#EEF2F8 !important` at (0,3,0), so my first attempt at `.rd-topwrap .w` (0,2,0) lost
   despite also being !important. Two !important declarations are ranked by specificity. */
.rd-topwrap .rd-brand .dk-wm .w,.rd-topwrap .dk-wm .w{
  font-family:var(--rd-brandfont) !important;font-weight:800 !important;
  letter-spacing:-.03em !important;color:var(--rd-ink) !important;
}
.rd-topwrap .rd-brand .dk-wm .f,.rd-topwrap .dk-wm .f{
  font-family:var(--rd-brandfont) !important;font-weight:800 !important;
  letter-spacing:-.03em !important;color:var(--rd-ink) !important;
}
.rd-topwrap .rd-brand .dk-wm .d,.rd-topwrap .dk-wm .d{display:none !important}

/* MOBILE HEADER — shipped broken, fixing forward.
   `.sf.m-page .rd-brand .dk-wm .w{color:#EEF2F8 !important}` is (0,5,0); my (0,4,0) override lost
   to it, so on phones the wordmark stayed near-white and the light-yellow chrome put it at roughly
   1.1:1 — effectively invisible. Measured on production, not spotted by eye. Same specificity trap
   as the desktop wordmark earlier: !important does not beat !important. */
.sf.m-page .rd-brand .dk-wm .w,.sf .rd-topbar .rd-brand .dk-wm .w{
  color:var(--rd-ink) !important;font-family:var(--rd-brandfont) !important;font-weight:800 !important;
}
.sf.m-page .rd-brand .dk-wm .f,.sf .rd-topbar .rd-brand .dk-wm .f{
  color:var(--rd-ink) !important;font-family:var(--rd-brandfont) !important;font-weight:800 !important;
}
.sf.m-page .rd-brand .dk-wm .d,.sf .rd-topbar .rd-brand .dk-wm .d{display:none !important}

/* ── LOGOTYPE RAMP ───────────────────────────────────────────────────────────────────────
   The "?" and "foryou" carry --rd-lockup-ramp instead of a flat colour. Four separate rules
   colour this lockup (base, .rd-topwrap, .sf-stick-wm, .sf.m-page), so ONE grouped rule placed
   after all of them paints every state — desktop and phone, top and scrolled. Adding the ramp to
   three of the four is the exact mistake that let the header drift blue in the first place.

   Guarded by @supports, and this guard is load-bearing rather than decorative: the technique is
   `color:transparent` + background-clip:text, so in an engine without background-clip the brand
   name renders as NOTHING. --rd-lockup stays the declared colour outside the guard, so the
   fallback is the flat teal rather than an invisible wordmark.

   CONTRAST: the indigo stop measures 2.72:1 on this chrome and the blue 3.77:1, both under AA.
   That is permitted — WCAG 1.4.3 exempts "text that is part of a logo or brand name" — and it is
   a deliberate, recorded decision, not an oversight. check-contrast.mjs knows about this exemption
   by name and still resolves the ramp's darkest stop, so the gate reports the real number instead
   of silently passing on a computed colour of `transparent`. Do not widen the exemption past the
   logotype; every other pixel of chrome still owes 4.5:1. */
/* ONE-COLOUR WORDMARK (owner 2026-09-04, design_handoff_header_rail §5.1). `foryou` was brand teal
   and is now the same colour as `worthit` on every surface the lockup appears on. It moved because
   the app header gained the four-verdict rail directly beneath it, and teal sits 32.2 dE from BUY
   green — CLOSER than any two verdict colours are to each other (the tightest pair, WAIT/SKIP, is
   39.0). A fifth saturated colour inside the set's own spacing, in the same visual unit as a rail
   whose whole job is to teach that four colours mean four verdicts, reads as a sixth verdict.
   Changed on the SITE too, not just the app: a lockup that is teal on one surface and ink on
   another is a worse problem than the one being fixed.
   The monogram's `?` KEEPS the teal — it clears the same test at 38.4, and it is one glyph in a
   30px disc rather than 22px of text, so it stays the brand's accent up there. That is why it is
   split out of the rule below instead of riding along with the wordmark. */
.rd-topwrap .rd-brand .rd-mg i{
  background-image:none !important;
  -webkit-background-clip:border-box !important; background-clip:border-box !important;
  color:var(--rd-lockup) !important; -webkit-text-fill-color:var(--rd-lockup) !important;
}
/* The header ramp is retired with the teal: a gradient across `foryou` is the same competing-colour
   problem in motion. --rd-lockup-ramp stays DEFINED for the non-header surfaces that still use it. */
/* .sf-stick-wm is deliberately NOT in this list. Its `worthit` is #EEF2F8, not --rd-ink (#F5F5F7),
   so folding it in here would leave the two halves a few units apart — invisible, but it is exactly
   the by-construction match this pass exists to guarantee. It gets its colour from its own rule
   beside its own .w, and it no longer needs the ramp reset because the ramp rule is gone. */
.rd-topwrap .rd-brand .dk-wm .f, .rd-topwrap .dk-wm .f,
.sf.m-page .rd-brand .dk-wm .f, .sf .rd-topbar .rd-brand .dk-wm .f{
  background-image:none !important;
  -webkit-background-clip:border-box !important; background-clip:border-box !important;
  color:var(--rd-ink) !important; -webkit-text-fill-color:currentColor !important;
}

/* Tabs INSIDE THE DARK BAR only. The comment used to read "tabs on a light ground", which is the
   opposite of what these do: --rd-ink2 is #A1A1A6 and --rd-ink is #F5F5F7, the dark chrome's inks.
   The tabs moved OUT of the bar into a light strip under the hero on 11 Aug and these two rules
   came with them, at (0,2,0) with !important, so they beat the strip's own colours. Measured on the
   light strip: inactive 2.57:1, and the ACTIVE tab #F5F5F7 on near-white at 1.09:1 — the label was
   very nearly invisible, which is what "increase the font brightness" was pointing at.
   Scoped to a descendant of the BAR itself, so if an inline nav ever returns to the dark chrome it
   is still styled, and the light strip keeps its own ink. */
.rd-topbar .sf-tab{color:var(--rd-ink2) !important}
.rd-topbar .sf-tab.on,.rd-topbar .sf-tab[aria-selected="true"]{color:var(--rd-ink) !important}

/* search: on the dark bar a white box is a glaring hole, so it becomes a recessed well — a light
   film on the chrome rather than an object on top of it. This is Apple's own treatment of fields
   in dark nav, and it keeps the bar reading as one surface. */
.rd-topwrap .sf-sbox{
  background:rgba(255,255,255,.10) !important;border:1.5px solid color-mix(in srgb, var(--rd-lockup) 55%, rgba(255,255,255,.22)) !important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 8px 22px rgba(0,0,0,.22) !important;
}
.rd-topwrap .sf-sbox:focus-within{
  border-color:var(--rd-lockup) !important;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--rd-lockup) 28%, transparent), inset 0 1px 0 rgba(255,255,255,.22) !important;
}
.rd-topwrap .sf-sic{color:#E8EAED}
.rd-topwrap .sf-sbox .wi-phanim{color:rgba(232,234,237,.78)}
.rd-topwrap .sf-sbox input{background:transparent !important;color:var(--rd-ink) !important}
.rd-topwrap .sf-sbox input::placeholder{color:var(--rd-well-ink) !important;opacity:1 !important}
.rd-topwrap .sf-seg,.rd-topwrap .sf-seg *{color:var(--rd-well-ink) !important}
/* the store selector lives in the well too and is NOT .sf-seg — it was missed on the first pass
   and check:contrast failed it at 1.32:1 */

/* Scan stays a filled control — on the dark bar it was an outline with white text, which on a
   light ground became white-on-pale and effectively disappeared. */
.rd-topwrap .sf-scanbtn{background:#14B8A6 !important;border-color:#14B8A6 !important;color:var(--teal-ink) !important}
.rd-topwrap .sf-scanbtn svg{stroke:var(--teal-ink) !important}
.rd-topwrap .sf-scanbtn .sf-scan-t,.rd-topwrap .sf-scanbtn span{color:var(--teal-ink) !important}

/* The account button was #EEF2F8 ink AND a #EEF2F8 SVG stroke — invisible on the wash. Found by
   sweeping the header for anything still painting above luminance 190, rather than by eye. */
.rd-topwrap .rd-actions{display:inline-flex;align-items:center;gap:10px;justify-self:end;min-width:0}
.rd-topwrap .rd-chrome{
  display:inline-flex;align-items:center;gap:8px;flex:0 0 auto;
  min-height:38px;padding:0 14px;border-radius:999px;text-decoration:none;
  background:#14B8A6 !important;color:var(--teal-ink) !important;border:1px solid #14B8A6 !important;
  font:700 13px/1 system-ui,-apple-system,sans-serif;white-space:nowrap;
  box-shadow:0 8px 18px -12px color-mix(in srgb, #14B8A6 65%, transparent);
}
.rd-topwrap .rd-chrome:hover{filter:brightness(1.05);color:var(--teal-ink) !important}
.rd-topwrap .rd-chrome:focus-visible{outline:3px solid #99F6E4;outline-offset:2px}
.rd-topwrap .rd-chrome .wi-promo-g{width:14px;height:14px;flex:0 0 auto;color:var(--teal-ink) !important}
.rd-topwrap .rd-chrome span{color:var(--teal-ink) !important;-webkit-text-fill-color:var(--teal-ink) !important}
@media (max-width:720px){
  .rd-topwrap .rd-chrome span{display:none}
  .rd-topwrap .rd-chrome{padding:0;width:38px;justify-content:center}
}
/* ── Mobile web brightness / contrast lift (2026-09-28) — phone storefront only.
   Does not touch desktop, dark chrome inks, or any JS/feature path. */
@media (max-width:720px){
  :root{
    --bg:#FAFAFB; --mist:#F7F7F9; --paper:#FFFFFF; --paper2:#F4F4F6;
    --ink2:#3A3A3C; --ink3:#55555A; --mute:#55555A; --line:#E5E5EA;
  }
  body{background:var(--bg)}
  .mhome{background:#FAFAFB;--mute:#55555A;--dim:#4A4A4F;--slate:#55555A}
  .mhome .mdc,.mhome .card{--mdc-mute:#55555A}
  .mdc.mdc-studio .mdc-store,.mdc.mdc-studio .mdc-was{color:#55555A}
}

/* Profile: grey empty circle (owner mock) — no silhouette, no teal outline. */
.rd-topwrap .rd-you,
.rd-topwrap .rd-you.rd-you-empty{
  width:38px;height:38px;border-radius:50%;padding:0;
  color:transparent !important;border:0 !important;
  background:#4A4A4F !important;box-shadow:none !important;
  display:inline-grid;place-items:center;
}
.rd-topwrap .rd-you svg{display:none !important}
.rd-topwrap .rd-you.rd-you-empty::before{content:none}

/* Logo 2a — yellow “worthit” sticker + “foryou” (design/handoff/app-logo).
   Same lockup as Cap wait-state: 8px gap (not a space character), foryou in its own span.
   Sticker yellow is --logo-sticker (logo only). On light grounds wrap in .logo2a-pill.
   On dark website chrome the pill must stay visible (hairline) — otherwise the 8px gap
   reads as a space in the name (header #2B2631 ≈ pill #2C2C2E). */
.logo2a{
  display:inline-flex;align-items:center;gap:8px;
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text",system-ui,sans-serif;
  font-size:20px;font-weight:800;letter-spacing:-.04em;line-height:1.2;white-space:nowrap;
  color:#1D1D1F;
}
.logo2a-sticker{
  display:inline-block;padding:3px 10px;border-radius:8px;
  background:var(--logo-sticker);color:var(--logo-sticker-ink);transform:rotate(-3deg);
}
.logo2a-fy{display:inline-block}
.logo2a-on-dark{color:var(--logo-foryou)}
.logo2a-on-dark .logo2a-fy{color:var(--logo-foryou)}
.logo2a-pill{
  display:inline-flex;align-items:center;justify-content:center;
  padding:5px 14px 5px 8px;border-radius:999px;background:var(--logo-bar);
  line-height:1;flex:0 0 auto;
}
.logo2a-pill .logo2a{font-size:inherit;flex:0 0 auto}
/* Dark chrome ≈ pill colour — hairline keeps the gap inside the capsule (mobile look). */
.rd-topwrap .logo2a-pill,
.sf-stick-wm .logo2a-pill,
.mhome .mwm2 .logo2a-pill,
.hc-brand .logo2a-pill,
.dg-brand .logo2a-pill,
.nh-brand .logo2a-pill,
.nh-foot-brand .logo2a-pill,
.mkh-lock .logo2a-pill{
  box-shadow:0 0 0 1px rgba(255,255,255,.14);
}
.rd-topwrap .rd-brand .logo2a,
.sf-stick-wm .logo2a,
.mhome .mwm2 .logo2a,
.rd-topwrap .rd-brand .logo2a-pill .logo2a,
.sf-stick-wm .logo2a-pill .logo2a,
.mhome .mwm2 .logo2a-pill .logo2a{font-size:18px} /* Cap wait-state header */
.rd-topwrap.scrolled .rd-brand .logo2a,
.sf-stick.scrolled .sf-stick-wm .logo2a,
.rd-topwrap.scrolled .rd-brand .logo2a-pill .logo2a,
.sf-stick.scrolled .sf-stick-wm .logo2a-pill .logo2a{font-size:16px}
.rd-topwrap.scrolled .rd-brand .logo2a-sticker,
.sf-stick.scrolled .sf-stick-wm .logo2a-sticker{padding:2px 8px;border-radius:7px}
.rd-topwrap.scrolled .rd-brand .logo2a-pill,
.sf-stick.scrolled .sf-stick-wm .logo2a-pill{padding:4px 12px 4px 7px}
/* WiApp / Today / Scan — same Logo 2a; pill on light grounds */
.wi-app .wi-head .logo2a-pill .logo2a,
.wi-app .wi-head .logo2a{font-size:18px}
.wi-app .wi-phead .logo2a-pill .logo2a,
.wi-app .wi-phead .logo2a{font-size:16px}
.wi-app .wi-lkmd .logo2a-pill .logo2a,
.wi-app .wi-lkmd .logo2a{font-size:16px}
.wi-app .wi-lksm .logo2a-pill .logo2a,
.wi-app .wi-lksm .logo2a{font-size:13px}
.wi-app .wi-scanbrand .logo2a{font-size:20px}
.wi-onb-sheet-brand .logo2a-pill .logo2a,
.wi-onb-sheet-brand .logo2a{font-size:15px}
.tdv2-lock .logo2a-pill .logo2a,
.tdv2-lock .logo2a{font-size:22px}
.dg-brand .logo2a{font-size:20px}
.hc-brand .logo2a{font-size:16px}
.mkh-lock .logo2a{font-size:15px}
.mkh-lock .logo2a-sticker{padding:2px 8px;border-radius:7px}
.nm2 .wordmark .logo2a{font-size:20px}
#boot .boot-logo.logo2a,#wi-interim .boot-logo.logo2a{font-size:clamp(1.85rem,2.15rem,2.35rem);position:relative;z-index:1}
#boot .boot-logo .logo2a-sticker{padding:5px 16px;border-radius:14px}
.wi-app .wi-offgate .boot-logo.logo2a{font-size:clamp(1.65rem,1.85rem,2rem)}
/* Owner mock lockup: Logo 2a replaces circular /wi-mark.png — no .com. */
.rd-topwrap .rd-brand{align-items:center !important;gap:10px}
.rd-topwrap .rd-brand::before{display:none !important} /* no midnight plate behind circular mark */
.rd-topwrap .rd-brand .rd-mark,
.rd-topwrap .rd-brand .amark.wi-mark{
  width:calc(var(--rd-wm, var(--wm-lg)) * 1.38);
  height:calc(var(--rd-wm, var(--wm-lg)) * 1.38);
  border-radius:50%;object-fit:cover;display:block;flex:none;
  box-shadow:0 0 0 1px rgba(255,255,255,.06);
}
.rd-topwrap .rd-brand .dk-wm .d,
.sf-stick-wm .dk-wm .d{display:none !important}
/* Header search: small TEAL check icon inside the field (mock) — not a filled Check pill. */
.rd-topwrap .rd-topbar .sf-scanbtn{display:none !important}
.rd-topwrap .rd-topbar .sf-sgo{
  width:28px;min-width:28px;height:28px;padding:0 !important;margin-right:6px;border-radius:0;
  background:transparent !important;color:#14B8A6 !important;gap:0;box-shadow:none !important;
}
.rd-topwrap .rd-topbar .sf-sgo .sgt{display:none !important}
.rd-topwrap .rd-topbar .sf-sgo svg{stroke:#14B8A6 !important;width:18px;height:18px}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   REDESIGN — CARD LANGUAGE  (claude/card-language)

   Trailing override layer, same discipline as the chrome: every rule targets an existing class,
   nothing above is deleted, reverting is one block. No DOM changes — the verified card already
   has .pstamp, .hd-seller, .hd-off and .hd-rare in the right order, so this is restyling only.

   1. THE SAVING STOPS BEING GREEN. .hd-off was #12B26A on a green wash — the same family as the
      BUY verdict directly above it. Two different claims in one colour: the discount borrowed the
      authority of a verdict, and the verdict lost its exclusivity on green. The saving moves to the
      accent (#0061CE, white on it 5.83:1) so green means "we checked this" and blue means "this is
      what you save". Cut as a tag flag with an eyelet rather than a pill, so it cannot be mistaken
      for a control either.

   2. THE VERDICT BECOMES A STAMP. .pstamp is already absolutely positioned and rotated -7deg, so
      it is most of the way there; it just had a 9px pill radius and a single hairline. Squared off
      to 3px with a double rule, which is what an inked stamp looks like and what nothing else on
      the page looks like.

   3. THE CARD BECOMES A TAG. Punched hole at the top (psq2 had no pseudo-elements, so ::before was
      free), and .hd-rare — which already sat behind a 10px gap at the foot of the card — becomes a
      perforated stub carrying the rarity line. That is the one fact no competitor can print, and it
      now sits on the part of the card that looks torn off.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

.psq2{
  border-radius:18px !important;
  padding-top:26px !important;                       /* room for the punched hole */
  border-color:#E4E7EC !important;
  box-shadow:0 2px 0 rgba(20,26,33,.06),0 12px 24px -16px rgba(20,26,33,.4) !important;
  transition:transform .2s cubic-bezier(.2,.7,.3,1),box-shadow .2s !important;
}
.psq2:hover{
  transform:translateY(-3px) rotate(-.35deg) !important;
  box-shadow:0 3px 0 rgba(20,26,33,.08),0 20px 34px -18px rgba(20,26,33,.45) !important;
}
.psq2::before{                                       /* the punched hole */
  content:"";position:absolute;top:11px;left:50%;transform:translateX(-50%);
  width:32px;height:10px;border-radius:999px;background:#E4E6EB;
  box-shadow:inset 0 1.5px 2px rgba(20,26,33,.32);z-index:3;pointer-events:none;
}

/* ── the verdict, as a stamp ───────────────────────────────────────────────────────────── */
.psq2 .pstamp{
  border-radius:3px !important;
  border-width:2px !important;
  background:transparent !important;
  padding:5px 9px !important;
  box-shadow:none !important;
}
.psq2 .pstamp::after{                                /* inked double rule */
  content:"";position:absolute;inset:2px;border:1px solid currentColor;border-radius:1px;
  opacity:.4;pointer-events:none;
}

/* ── the saving, as a tag flag in the accent ───────────────────────────────────────────── */
.psq2 .hd-off{
  color:#fff !important;
  background:#0061CE !important;
  border-radius:0 6px 6px 0 !important;
  padding:5px 10px 5px 15px !important;
  clip-path:polygon(8px 0,100% 0,100% 100%,8px 100%,0 50%);
  position:relative;
}
.psq2 .hd-off::before{                               /* the eyelet */
  content:"";position:absolute;left:9px;top:50%;transform:translateY(-50%);
  width:3.5px;height:3.5px;border-radius:50%;background:rgba(255,255,255,.85);
}
.psq2 .hd-off-lead,.psq2 .hd-off-sep,.psq2 .hd-off *{color:#fff !important}

/* ── the stub ──────────────────────────────────────────────────────────────────────────── */
.psq2 .hd-rare{
  position:relative;
  border-top:2px dashed #DCE0E5 !important;
  margin-top:14px !important;
  padding-top:14px !important;
}
/* NO punched notches here, deliberately. A notch is a hole you see the board through, and these
   cards sit directly on #FFF — measured, the painted ancestor is .sf at rgb(255,255,255), while
   --bg is #f2f4f8 and never applies. Cutting circles in that colour produced grey blobs floating
   in the gutters. The dashed line alone reads as the tear; the notches come back if and when the
   shelf gets a board behind it, which is a larger change than this one. */

/* The "we read that as" row on the Amazon-results page. It reuses .sq-chip, which is styled for
   the DARK smart-search panel — white text on a translucent white fill. Dropped onto this LIGHT
   page unchanged it would be invisible, the same trap as the verdict-page wordmark, so the colours
   are restated for this ground rather than inherited. */
/* .sq-read is the DARK smart-search panel — a 22px navy card with a glow. Reusing the class for
   its layout dragged that whole treatment onto the light results page: a black band wedged between
   a white heading and white cards. Restated as a quiet light strip that belongs to this page. */
.srq-read{margin:16px 0 10px;background:#F7F9FC;border:1px solid #E3E9F1;border-radius:14px;
  padding:13px 15px 14px;box-shadow:none;overflow:visible}
.srq-read::before{display:none}
.srq-read .sq-us{font:700 11px/1 system-ui;letter-spacing:.09em;text-transform:uppercase;color:#5A6472;margin-bottom:9px}
.srq-read .sq-chips{display:flex;flex-wrap:wrap;gap:8px}
.srq-read .sq-chip{color:#0E1A2B;background:#F2F5F9;border:1px solid #DCE3EC;font-size:13px;
  padding:7px 13px;-webkit-backdrop-filter:none;backdrop-filter:none;opacity:1;transform:none;animation:none}
.srq-read .sq-chip svg{width:14px;height:14px}
.srq-read .sq-chip-ai{color:#3F3DB0;background:#EEEEFC;border-color:#CFCEF6}

/* ══ MOBILE BROWSER — LAST WORD ══════════════════════════════════════════════════════════════
   Deliberately at the END of the sheet. The earlier attempt at these same rules sat at ~3030 and
   lost silently: `.bm` is re-declared at 3276 with width + !important, and `.sf-tabbar` again at
   6568. Same specificity plus !important on both sides means LAST ONE WINS, so a correct rule in
   the wrong place is simply dead. It measured as unchanged, which is the only reason I caught it.
   Anything here is a phone-width override of a desktop rule; keep it small and keep it last. */
/* 1080, not 900 (owner, 15 Aug: "fix the 1024 view too"). The panel is a 496px column, so the copy
   column is whatever is left. Measured on the built page: 1440 -> input 619px, 1280 -> 459px,
   1024 -> 203px with the placeholder clipped mid-word. The mock's grid now lets the panel shrink
   first (clamp), which fixes the range down to about 1100 — but at 1024 even a floored panel
   leaves too little, and the hero reads better stacked there than as two cramped columns.
   So the stacking point moves up to 1080: 1024 gets the same clean, full-width hero as a phone. */
@media (max-width:1080px){
  /* .bm-proof is the hero's RIGHT-HAND column. Once the hero stacks it is beside nothing:
     measured at 402 it was a 380px block above the headline holding a 112px panel, so ~250px of
     empty grey, with the USUAL / YEAR LOW / YEAR HIGH tiles overlapping each other and their
     figures clipped to "$2," and "$1". It pushed the headline, sub and search below the fold.
     Removed where the layout changes rather than patched at each width — it is not a broken
     phone component, it is a column with nothing to sit beside. The proof it carried is still on
     the page: the verified shelf below is the same real banked BUYs. */
  .bm-proof{display:none !important}
  .bm{grid-template-columns:1fr !important}
}
@media (max-width:640px){
  /* 80px of gutter is a fifth of a 402px screen, and it squeezed the search input to 77px — the
     placeholder rendered as "Search a p". */
  .bm{width:calc(100% - 24px) !important;max-width:none !important;margin:14px auto 0 !important}
  .bm-field-go{padding:8px 12px !important;font-size:13px !important}
  /* Last word at phone width: the BUY CTA fill must still win if an earlier mobile
     `background` shorthand landed on .pp-cta-pri or a. Same colour as desktop; no !important. */
  a.pp-cta-pri.buy,.pp-cta-pri.buy{background-color:var(--buy-deep);background-image:none;color:#fff}
}
/* ── OFF-HOME LOCKUP (verdict / product / browse / you) ─────────────────────────────────────
   Owner, 15 Aug: "Verdict page monogram icon & logo not matching with home screen." Measured —
   four differences, none of them deliberate:
       landing  .rd-brand   Nunito type "Wi?"      Nunito 900 wordmark   Apple ramp    no suffix
       verdict  .nh-brand   /wi-mark.png raster    DM Sans wordmark      GREEN #16B24A  ".com"
   The green is also a drift from the documented invariant ("foryou is teal as ONE unit"), the same
   way the header was until this afternoon.

   The mark and the face now match exactly. The COLOUR cannot, and that is worth stating rather than
   fudging: .nh-nav is a near-white bar (rules scoped to .nh-nav .nh-brand, NOT .nh-brand — the FOOTER
   shares that class on a DARK ground, and the unscoped version put #0E1A2B on rgb(21,33,52) at
   1.08:1, which check-contrast caught before it shipped) (rgba(252,253,255,.92)) and the landing's ramp ends in cyan
   #64D2FF, which measures 1.6:1 on white — invisible. So this uses the DARK half of the same ramp,
   indigo -> blue, which is the landing's ramp with the washed-out end cut off: #5E5CE6 is 5.6:1 on
   white and #0A84FF is 3.3:1. Under AA as text, permitted as a logotype (WCAG 1.4.3) exactly as the
   landing's is — and check-contrast.mjs now recognises .nh-brand alongside .rd-brand, so the number
   is still printed rather than hidden.
   The remaining difference is the BAR itself: dark on the landing, light here. Flagged to the owner
   rather than changed, because making this chrome dark is a redesign of the whole layer. */
/* The `.nh-*` bar below is NO LONGER RENDERED (owner 2026-09-16): the off-home routes now emit
   `.rd-topwrap` markup so they share the storefront's bar outright. Its rules are kept, unused,
   only because `.nh-foot` borrows some of them for the footer lockup — anything scoped `.nh-nav`
   is dead and safe to delete in a cleanup pass. The amber question this block used to answer is
   answered by the merge instead: `foryou` is amber again because the ground is dark again. */
.nh-nav .nh-brand.rd-brand .rd-mg,.nh-nav .nh-brand.rd-brand .nh-mg{
  font-family:var(--rd-brandfont);font-weight:800;font-size:calc(22px * 1.03);line-height:1;
  letter-spacing:-.04em;color:var(--ink);flex:0 0 auto}
.nh-nav .nh-brand.rd-brand .rd-mg i,.nh-nav .nh-brand.rd-brand .nh-mg i{font-style:normal;color:var(--rd-lockup)}
.nh-nav .nh-brand.rd-brand .dk-wm{font-size:clamp(20px,2.2vw,26px)}
.nh-nav .nh-brand.rd-brand .dk-wm .w{color:var(--ink) !important}
.nh-nav .nh-brand.rd-brand .dk-wm .f{color:var(--ink) !important}
/* .d BELONGS TO THIS SET (2026-08-19). The light-ground pass gave .w and .f their values and
   stopped there, so ".com" kept the DARK-chrome rgba(238,242,248,.55) from .rd-brand .dk-wm .d
   -- an offwhite at 55% alpha, which on this near-white nav measures 1.05:1 and is simply not
   visible. .rd-brand used to mean the dark bar; it is now also the off-home nav, so every rule
   that assumed a dark ground under it needs a sibling here. Exactly the trap product invariants records:
   four rules colour the lockup and changing three proves nothing about the fourth. */
.nh-nav .nh-brand.rd-brand .dk-wm .d{color:var(--ink2) !important}
/* --ink2, NOT --slate: --slate is declared on .mhome only, so off this nav it is unresolved and
   the whole declaration falls back to INHERIT -- which handed ".com" the parent's ink and made it
   the same colour as "worthit". An undefined custom property does not fail loudly; it silently
   inherits. Verified --ink2 resolves here (7.50:1) before using it. */
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  .nh-nav .nh-brand.rd-brand .rd-mg i,.nh-nav .nh-brand.rd-brand .nh-mg i{
    background-image:var(--rd-lockup-ramp);
    -webkit-background-clip:text;background-clip:text;
    color:transparent !important;-webkit-text-fill-color:transparent;
  }
}

/* FOOTER LOCKUP (2026-08-16). Every rule of the Apple-ramp lockup above is scoped `.nh-nav`, and the
   footer brand lives in `.nh-foot` — so it never received the 15 Aug update and quietly kept the OLD
   brand-kit wordmark: DM Sans 800 instead of Nunito 900, flat teal instead of the ramp, a 31px
   wordmark against the header's 26px, the PNG app-icon tile instead of the monogram, and a GREEN
   `.com` from `.wm.dark .dc{color:#22C55E}`. Measured on production across home, verdict and
   product — identical on all three, so it was the footer that was wrong, not one page.

   GROUNDS ARE THE WHOLE PROBLEM HERE, again. The nav is a LIGHT bar, so its monogram takes dark ink
   and its wordmark gets its own navy chip. The footer is `--navy` (#152134) throughout — one dark
   ground, no chip — so both halves must be LIGHT, and the chip must be actively switched off or the
   wordmark sits in a navy box on a navy footer. Applying the nav's colours here verbatim is exactly
   the 1:1 invisible-wordmark bug from 15 Aug in a new place. */
/* 1.03x the wordmark, the same optical ratio the header uses (--rd-wm * 1.03). Matching the
   wordmark's own 26px leaves the mark reading a touch small beside it. */
.nh-foot-brand .nh-mg{font-family:var(--rd-brandfont);font-weight:800;font-size:calc(26px * 1.03);line-height:1;
  letter-spacing:-.04em;color:#F5F5F7;flex:0 0 auto}
.nh-foot-brand .wm,.nh-foot-brand .wm.dark{font-family:var(--rd-brandfont) !important;font-weight:800 !important;
  font-size:26px !important;letter-spacing:-.03em !important;color:#F5F5F7 !important;
  background:none !important;padding:0 !important;border-radius:0 !important}
.nh-foot-brand .wm .fy,.nh-foot-brand .wm.dark .fy{color:#5EEAD4 !important;font-weight:800 !important}
/* was #22C55E — a green ".com" that appears nowhere else in the lockup. Slate matches the header. */
.nh-foot-brand .wm .dc,.nh-foot-brand .wm.dark .dc{color:#94A3B8 !important;font-weight:800 !important}
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  /* On navy BOTH halves carry the landing's full ramp — unlike the nav, where the monogram sits on
     the light bar and has to use the ramp's dark half instead. */
  .nh-foot-brand .nh-mg i,.nh-foot-brand .wm .fy,.nh-foot-brand .wm.dark .fy{
    background-image:var(--rd-lockup-ramp);
    -webkit-background-clip:text; background-clip:text;
    color:transparent !important; -webkit-text-fill-color:transparent;
  }
}

/* The account button belongs at the RIGHT edge, always (owner, 15 Aug).
   .rd-topbar is `grid-template-columns:auto minmax(0,1fr) auto` and relied on AUTO PLACEMENT: with
   brand, search and account it filled 1-2-3 and the button landed in column 3. Withholding the
   bar's search on the landing left two children, so the account button became the SECOND and
   auto-placed into the wide middle column — sitting immediately beside the wordmark. Measured:

       scrollY 0    columns 226.86 / 1125.14 / 0px    brand 26..253   you  271..309
       scrollY 700  columns 176.83 / 1149.17 / 38px   brand 26..203   you 1376..1414

   A knock-on from the one-search-box change rather than a new layout bug — auto placement was
   doing the positioning, so removing a sibling moved it. Pinned explicitly now, which is true
   whatever else the bar does or does not render. */
.rd-topwrap .rd-topbar .rd-actions{grid-column:3;justify-self:end}

/* Deal-pages strip lives INSIDE sticky chrome (.rd-topwrap / .mhome .mtop). A second
   position:sticky + overflow-x:clip on .sf-tabbar made iOS pan the strip up/down (nested
   sticky vs shrinking header) and left/right (scroll chaining into the page). */
.sf-tabbar{overflow:visible !important}
.sf-tabbar-row{display:flex;align-items:center;max-width:1720px;margin:0 auto;
  width:100%;min-width:0;box-sizing:border-box;padding:0 12px}
.sf-tabbar-row .sf-tabs{flex:1 1 auto;min-width:0;max-width:none;margin:0;
  overflow-x:auto !important;overflow-y:hidden !important;
  overscroll-behavior-x:contain;overscroll-behavior-y:none;touch-action:pan-x;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none}
.sf-tabbar-row .sf-tabs::-webkit-scrollbar{display:none}

/* ══════════════════════════════════════════════════════════════════════════════
   Marketing hero (design_handoff_marketing_hero/README.md, 2026-09-01).
   Desktop only — the handoff is explicit that a mobile layout is NOT designed and
   must not be improvised from this one, so .mkh is never mounted under isMobile.
   Values are transcribed from the spec, not eyeballed; every colour pair in it was
   measured against its composited background for AA and several are the second
   attempt, so do NOT lighten the greys (--mkh-mut on --mkh-ground is 6.51:1).
   ═══════════════════════════════════════════════════════════════════════════ */
.mkh{
  --mkh-ground:#f6f6f4; --mkh-surface:#ffffff; --mkh-ink:#0d0f12; --mkh-ink-p:#111214;
  --mkh-mut:#55595f; --mkh-mut-p:#6e6e73; --mkh-hair:#d8d8d3; --mkh-hair-p:#eef1f5;
  --mkh-grn:#0b7a45; --mkh-grn-h:#0e9857; --mkh-grn-a:#096638; --mkh-chart:#2bb46a;
  --mkh-buy:#0e7f40; --mkh-wait:#a35f0b; --mkh-skip:#b3262b; --mkh-fair:#0059b3;
  --mkh-buy-t:#e6f4ec; --mkh-wait-t:#fdf1e2; --mkh-skip-t:#fbe9ea; --mkh-fair-t:#e8f0fb;
  --mkh-buy-x:#0b3d22; --mkh-wait-x:#4a2c04; --mkh-skip-x:#4d1113; --mkh-fair-x:#0a2d52;
  --mkh-amber2:#7d4a08; --mkh-red2:#8d1e22; --mkh-blue2:#0a4a8c;
  --mkh-ease:cubic-bezier(0.2,0.8,0.2,1);
  --mkh-font:-apple-system,BlinkMacSystemFont,'SF Pro Display','SF Pro Text','Helvetica Neue',Helvetica,Arial,sans-serif;
  position:relative; min-width:1280px; overflow:hidden;
  background:var(--mkh-ground); color:var(--mkh-ink);
  font-family:var(--mkh-font); -webkit-font-smoothing:antialiased;
}
/* Background price graphic — behind everything, never interactive. */
.mkh-bg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
/* The 0.05 opacity lives on the PATH; the fade animation goes on the wrapping <g>.
   An opacity animation ending at 1 on the path itself overrides the attribute and
   the band renders solid — that is the trap the handoff calls out by name. */
.mkh-bg-area{animation:mkhFade 1s .2s var(--mkh-ease) both}
.mkh-bg-line{animation:mkhDraw 1.6s .35s cubic-bezier(.3,.7,.2,1) both;stroke-dasharray:2400;stroke-dashoffset:2400}
.mkh-bg-dots{animation:mkhFade .8s 1.7s var(--mkh-ease) both}
.mkh-leg{position:absolute;left:max(64px,calc((100% - 1320px)/2 + 64px));bottom:22px;display:flex;align-items:center;gap:10px;
  animation:mkhFade .8s 1.9s var(--mkh-ease) both}
.mkh-leg i{display:block;width:26px;height:1px;background:var(--mkh-grn);opacity:.45}
.mkh-leg span{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--mkh-mut)}

/* The right column is PINNED to the device + shop rail. Device bounding box notes above still
   apply; the shop rail sits beside the phone (not under the copy). */
.mkh-grid{position:relative;z-index:2;display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:28px;align-items:center;padding:40px 48px 52px;max-width:1480px;margin:0 auto;box-sizing:border-box}
.mkh-right{display:flex;align-items:center;gap:18px;justify-self:end;
  animation:mkhRise .8s .86s var(--mkh-ease) both}
/* 52px bottom: the chart legend is absolutely positioned at bottom:22px, so the grid needs to clear
   it. Without this the proof row's labels print straight through TWELVE MONTHS OF REAL PRICES. */

.mkh-h1{margin:0;font-size:clamp(38px,5.2vw,76px);line-height:1;font-weight:600;letter-spacing:-.038em;white-space:nowrap}
/* Each line wipes up from behind its own baseline, so the mask CLIPS — it does not wrap.
   Rendered width per font-pixel is 6.253 (line 1) and 8.949 (line 2); re-measure if the
   copy or the font changes or an oversized line truncates silently. */
.mkh-h1 .mkh-mask{display:block;overflow:hidden}
.mkh-h1 .mkh-mask>span{display:block}
.mkh-h1 .mkh-mask:nth-child(1)>span{animation:mkhLine .85s .18s cubic-bezier(.16,.9,.2,1) both}
.mkh-h1 .mkh-mask:nth-child(2)>span{animation:mkhLine .85s .30s cubic-bezier(.16,.9,.2,1) both}
.mkh-h1 .mkh-hon{color:var(--mkh-fair)}
.mkh-h1 .mkh-ver{color:var(--mkh-grn)}

.mkh-vocab{margin-top:26px;animation:mkhRise .7s .48s var(--mkh-ease) both}
.mkh-vocab-l{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--mkh-mut)}
.mkh-pills{display:flex;gap:10px;margin-top:12px}
.mkh-pill{padding:9px 22px;border-radius:980px;font-size:17px;font-weight:600;letter-spacing:-.022em;color:#fff}
.mkh-pill.b{background:var(--mkh-buy)} .mkh-pill.w{background:var(--mkh-wait)}
.mkh-pill.s{background:var(--mkh-skip)} .mkh-pill.f{background:var(--mkh-fair)}

.mkh-intro{margin:26px 0 0;max-width:520px;font-size:21px;font-weight:400;line-height:1.381;
  letter-spacing:.011em;color:var(--mkh-mut);animation:mkhRise .8s .55s var(--mkh-ease) both}

/* 680px aligns the field with the headline's own right edge (line 2 = 8.949 x 76px), rather than
   the spec's 540 which left it visibly short of the copy above it. Still a cap, so it collapses
   with the column at the 1100px floor. */
.mkh-field{display:flex;align-items:center;gap:8px;margin-top:30px;max-width:680px;
  padding:6px 6px 6px 22px;border-radius:980px;background:var(--mkh-surface);border:1px solid var(--mkh-hair);
  box-shadow:0 14px 34px -20px rgba(13,15,18,.28);animation:mkhRise .8s .68s var(--mkh-ease) both}
.mkh-field input{flex:1;min-width:0;border:0;outline:0;background:transparent;font-family:inherit;
  font-size:17px;letter-spacing:-.022em;padding:13px 0;color:var(--mkh-ink)}
.mkh-field input::placeholder{color:var(--mkh-mut)}
.mkh-go{padding:13px 26px;border:0;border-radius:980px;background:var(--mkh-grn);color:#fff;
  font-family:inherit;font-size:17px;font-weight:600;letter-spacing:-.022em;white-space:nowrap;cursor:pointer}
.mkh-go:hover{background:var(--mkh-grn-h)} .mkh-go:active{background:var(--mkh-grn-a)}
.mkh-go[disabled]{opacity:.62;cursor:default}
.mkh-err{margin:10px 0 0;font-size:13px;color:var(--mkh-skip);max-width:540px}
.mkh-fine{margin:16px 0 0;font-size:12px;font-weight:400;line-height:1.33;letter-spacing:-.01em;
  color:var(--mkh-mut);animation:mkhRise .8s .78s var(--mkh-ease) both}
.mkh-fine a{color:var(--mkh-grn);text-decoration:none}
.mkh-fine a:hover{color:var(--mkh-grn-h)}
/* The handoff notes the prototype defines no focus rings and says to add them. */
.mkh :focus-visible{outline:2px solid var(--mkh-grn);outline-offset:2px;border-radius:4px}

/* Install paths + proof row. Pill spec from the handoff's header: 8px 16px, 980px radius, hairline
   border, 13px/600/-0.01em, green on hover. */
.mkh-plat{display:flex;gap:10px;margin-top:22px;flex-wrap:wrap;animation:mkhRise .8s .86s var(--mkh-ease) both}
.mkh-pl{display:inline-flex;align-items:center;gap:8px;padding:8px 16px;border-radius:980px;
  border:1px solid var(--mkh-hair);background:var(--mkh-surface);font-size:13px;font-weight:600;
  letter-spacing:-.01em;color:var(--mkh-ink);text-decoration:none;white-space:nowrap}
.mkh-pl:hover{border-color:var(--mkh-grn);color:var(--mkh-grn)}
.mkh-pl svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}

/* ── device ── */
.mkh-devwrap{position:relative;height:620px;display:flex;align-items:center;justify-content:center}
.mkh-dev{width:402px;height:874px;flex:none;border-radius:56px;background:#0d0f12;padding:12px;
  box-sizing:border-box;
  transform:rotate(-7deg) scale(.66);animation:mkhPhone 1s .35s var(--mkh-ease) both}
.mkh-scr{position:relative;width:100%;height:100%;border-radius:44px;overflow:hidden;
  background:var(--mkh-surface);color:var(--mkh-ink-p);padding:60px 20px 20px;box-sizing:border-box;
  display:flex;flex-direction:column}
.mkh-island{position:absolute;top:14px;left:50%;transform:translateX(-50%);width:112px;height:32px;
  border-radius:980px;background:#0d0f12}
.mkh-appbar{display:flex;align-items:center;justify-content:space-between}
.mkh-lock{display:inline-flex;align-items:center;gap:8px}
/* Rebuild of wi-mark.png from a 102px screenshot per the handoff — swap for the vector original.
   Navy comes from the brand token (it is a brand hex, so check:brand forbids typing it here). */
/* The real /wi-mark.png, not the handoff's type-and-CSS rebuild — that was explicitly a placeholder
   ("a rebuild of the client's existing wi-mark.png from a low-resolution screenshot"), and at 22px
   the two glyphs wrapped onto separate lines inside the disc. */
.mkh-disc{width:22px;height:22px;border-radius:50%;flex:none;object-fit:contain;display:block}
.mkh-wm{font-size:15px;font-weight:600;letter-spacing:-.022em}
.mkh-chip{padding:4px 11px;border-radius:980px;background:var(--mkh-fair-t);color:var(--mkh-blue2);
  font-size:11px;font-weight:600}
.mkh-prod{display:flex;gap:13px;margin-top:20px}
.mkh-thumb{width:56px;height:56px;border-radius:14px;background:#eaf1fb;overflow:hidden;flex:none;
  display:grid;place-items:center}
.mkh-thumb img{width:100%;height:100%;object-fit:contain}
.mkh-seller{font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--mkh-mut-p)}
.mkh-pname{margin-top:3px;font-size:17px;font-weight:600;line-height:1.26;letter-spacing:-.022em}
.mkh-price{margin-top:18px;font-size:42px;font-weight:600;letter-spacing:-.03em;line-height:1}
.mkh-price small{font-size:16px;font-weight:500;letter-spacing:normal;color:var(--mkh-mut-p);margin-left:8px}
.mkh-cap{display:flex;justify-content:space-between;margin-top:18px;font-size:11px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--mkh-mut-p)}
.mkh-chart{display:block;width:100%;height:116px;margin-top:8px}
/* Entrance timings are absolute and were authored for page load. The flip remounts this block,
   so scoping them to .mkh-entry (first card only) stops the 2.45s verdict-card delay replaying on
   every swap — which left the card invisible for half of each 4.6s cycle. */
.mkh-chart .ln{stroke-dasharray:520;stroke-dashoffset:0}
.mkh-entry .mkh-chart .ln{animation:mkhDraw 1.5s 1.05s cubic-bezier(.3,.7,.2,1) both;stroke-dashoffset:520}
.mkh-chart .mk{transform-origin:322px 92px}
.mkh-entry .mkh-chart .mk{animation:mkhPop .5s 2.3s cubic-bezier(.2,.9,.2,1) both}
.mkh-vcard{margin-top:14px;border-radius:20px;background:var(--mkh-grn);color:#fff;padding:18px 20px}
.mkh-entry .mkh-vcard{animation:mkhPop .6s 2.45s cubic-bezier(.2,.9,.2,1) both}
.mkh-vcard.w{background:var(--mkh-wait)} .mkh-vcard.s{background:var(--mkh-skip)} .mkh-vcard.f{background:var(--mkh-fair)}
.mkh-vtop{display:flex;align-items:baseline;justify-content:space-between}
.mkh-vtop b{font-size:40px;font-weight:600;letter-spacing:-.03em;line-height:1}
.mkh-vtop span{font-size:15px;font-weight:600;letter-spacing:-.022em}
.mkh-vnote{margin-top:6px;font-size:14px;letter-spacing:-.022em;opacity:.92}
.mkh-cmpl{margin-top:22px;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--mkh-mut-p)}
.mkh-row{display:flex;align-items:center;gap:10px;padding:12px 14px;border-radius:16px;margin-top:8px}
.mkh-row:first-of-type{margin-top:12px}
.mkh-rlogo{width:22px;height:22px;border-radius:6px;background:var(--mkh-surface);flex:none;display:grid;
  place-items:center;font-size:9px;font-weight:700;position:relative;overflow:hidden}
.mkh-rlogo img{position:absolute;inset:2px;width:calc(100% - 4px);height:calc(100% - 4px);object-fit:contain}
.mkh-seller{display:flex;align-items:center;gap:6px}
.mkh-sfav{width:14px;height:14px;object-fit:contain;border-radius:3px;flex:none}
.mkh-rname{flex:1;min-width:0;font-size:15px;font-weight:600;letter-spacing:-.022em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mkh-rdelta{font-size:12px;font-weight:600}
.mkh-lowest{padding:4px 11px;border-radius:980px;background:var(--mkh-grn);color:#fff;font-size:11px;font-weight:600}
.mkh-rprice{font-size:17px;font-weight:600;letter-spacing:-.022em}
.mkh-row.t-buy{background:var(--mkh-buy-t);color:var(--mkh-buy-x)}
.mkh-row.t-fair{background:var(--mkh-fair-t);color:var(--mkh-fair-x)}
.mkh-row.t-fair .mkh-rdelta{color:var(--mkh-blue2)}
.mkh-row.t-skip{background:var(--mkh-skip-t);color:var(--mkh-skip-x)}
.mkh-row.t-skip .mkh-rdelta{color:var(--mkh-red2)}
.mkh-row.t-wait{background:var(--mkh-wait-t);color:var(--mkh-wait-x)}
.mkh-row.t-wait .mkh-rdelta{color:var(--mkh-amber2)}
.mkh-receipt{margin-top:auto;padding-top:16px;font-size:15px;font-weight:600;letter-spacing:-.022em;color:var(--mkh-grn)}
.mkh-vleg{margin-top:20px;padding-top:16px;border-top:1px solid var(--mkh-hair-p)}
.mkh-vleg-l{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--mkh-mut-p)}
.mkh-vleg-r{display:flex;gap:6px;margin-top:10px}
.mkh-vleg-r span{flex:1;text-align:center;padding:7px 0;border-radius:980px;font-size:11px;font-weight:600;color:#fff}

/* ── flip: the panel cycles real verdicts, so the swapping block cross-fades and the legend is
      pinned to the bottom rather than leaving a void under a short card. ── */
.mkh-swap{animation:mkhSwap .5s var(--mkh-ease) both}
@keyframes mkhSwap{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
.mkh-prodt{display:flex;flex-direction:column;min-width:0}
.mkh-pname{display:block}
.mkh-vleg{margin-top:auto}
/* Active marks use transform + shadow, never opacity — these are white-on-colour at 11-17px and
   fading them would drop them under AA. */
.mkh-pill,.mkh-vleg-r span{transition:transform .3s var(--mkh-ease),box-shadow .3s var(--mkh-ease)}
.mkh-pill.on{transform:translateY(-2px);box-shadow:0 8px 18px -8px rgba(13,15,18,.5)}
.mkh-vleg-r span.on{transform:scale(1.07);box-shadow:0 5px 12px -5px rgba(13,15,18,.55)}
.mkh-vl-b{background:var(--mkh-buy)} .mkh-vl-w{background:var(--mkh-wait)}
.mkh-vl-s{background:var(--mkh-skip)} .mkh-vl-f{background:var(--mkh-fair)}
@media (prefers-reduced-motion:reduce){.mkh-swap{animation:none}}

@keyframes mkhRise{from{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}
@keyframes mkhLine{from{transform:translateY(112%)}to{transform:translateY(0)}}
@keyframes mkhPhone{from{opacity:0;transform:translateY(80px) rotate(0deg) scale(.64)}
                    to{opacity:1;transform:translateY(0) rotate(-7deg) scale(.66)}}
@keyframes mkhFade{from{opacity:0}to{opacity:1}}
@keyframes mkhPop{0%{opacity:0;transform:scale(.7)}68%{transform:scale(1.06)}100%{opacity:1;transform:scale(1)}}
@keyframes mkhDraw{to{stroke-dashoffset:0}}
/* Settled state, no motion. */
@media (prefers-reduced-motion:reduce){
  .mkh *,.mkh *::before,.mkh *::after{animation:none!important}
  .mkh-bg-line,.mkh-chart .ln{stroke-dashoffset:0}
  .mkh-dev{transform:rotate(-7deg) scale(.66);opacity:1}
}


/* Verdict SEO facts (VerdictSeoFacts) — quiet reading block under the verdict. */
.vseo{max-width:880px;margin:8px auto 40px;padding:0 20px;font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text",system-ui,sans-serif;color:#1D1D1F}
.vseo-blk{background:#fff;border-radius:18px;box-shadow:0 0 0 1px #E8E8ED;padding:20px 22px;margin-top:14px}
.vseo h2{margin:0 0 10px;font-size:18px;font-weight:700;letter-spacing:-.015em}
.vseo ul{margin:0;padding-left:20px;font-size:15px;line-height:1.6;color:#424245}
.vseo-q{padding:12px 0;border-top:1px solid #EDEDF0}
.vseo-q:first-of-type{border-top:0;padding-top:0}
.vseo h3{margin:0 0 4px;font-size:15px;font-weight:600}
.vseo-q p{margin:0;font-size:14px;line-height:1.55;color:#6E6E73}
.vseo-rel{list-style:none;padding:0}
.vseo-rel li{padding:6px 0}
.vseo a{color:#0071E3;text-decoration:none;font-weight:600}
.vseo-guide{margin:16px 2px 0;font-size:15px}
/* Verified grid 28a — list mode + embed under storefront (not in handoff deal-card.css) */
/* List view = one full-width ROW per deal (owner 2026-09-29), in the home feed-row idiom:
   thumb · title + seller · price + usual · verdict pill · checked/save/share. It was a single
   420px column of the grid card, which read as a broken grid. The low/high bar stays a
   grid-card detail: most rows carry no band, and an empty column is what made rows look off. */
.wi-grid.wi-grid-list{grid-template-columns:minmax(0,1fr);gap:10px}
.wi-grid.wi-grid-list .wi-grid-skel{height:96px}
.wi-card.wi-card-list{flex-direction:row;align-items:center;gap:20px;padding:10px 14px 10px 10px;border-radius:18px}
.wi-card.wi-card-list:hover{transform:none}
.wi-card-list .wi-photo{margin:0;width:76px;flex:0 0 76px;border-radius:12px}
.wi-card-list .wi-title a::after{border-radius:18px}
.wi-card-list .wi-body{flex:1;min-width:0;padding:0;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,320px);
  grid-template-rows:auto auto;column-gap:32px;row-gap:6px;align-items:center}
.wi-card-list .wi-title{grid-column:1;grid-row:1;height:auto;-webkit-line-clamp:1}
.wi-card-list .wi-store{grid-column:1;grid-row:2}
.wi-card-list .wi-range{display:none}
.wi-card-list .wi-price-block{grid-column:2;grid-row:1 / span 2;align-items:flex-end;text-align:right;min-width:0}
.wi-card-list .wi-price-row{height:auto}
.wi-card-list .wi-price{font-size:22px}
.wi-card-list .wi-usual{max-width:100%}
.wi-lstamp{flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;min-width:76px;justify-content:center;
  padding:8px 14px;border-radius:999px;background:var(--v);color:#fff;font-size:13px;font-weight:800;letter-spacing:.05em}
.wi-card-list .wi-foot{margin:0;height:auto;flex:0 0 auto;box-shadow:none;padding-left:18px;border-left:1px solid var(--wi-line-2)}
@media (max-width:1279px){
  .wi-card-list .wi-body{grid-template-columns:minmax(0,1fr) minmax(0,240px)}
  .wi-card-list .wi-foot time,.wi-card-list .wi-foot>svg{display:none}
}
.rd-herowrap .wi-grid-page{padding-left:0;padding-right:0}
.wi-grid-page .wi-grid-skel{height:420px;border-radius:22px;background:#EDEDF0}
/* All Deals 28a feed — sits under page-nav; no second H1 pad. */
.all-deals .wi-grid-page{padding:0 0 40px;background:transparent}
.all-deals .wi-all-tools{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;margin:8px 0 12px}
.all-deals .wi-all-tools .ad-filter{margin:0}
.all-deals .wi-all-tools .wi-sort{margin-left:auto}
