:root {
    --navy: #1F2348;
    --navy-bg: radial-gradient(100% 100% at bottom right, #260133, #1F2348);
    --blue-bg: radial-gradient(100% 100% at bottom right, #265DD7, #0582CA);
    --green: #21BCA5;
    /* Status tokens, lifted from nimiq.blog so the two sites agree on what
       proven vs qualified looks like. */
    --ok: #21BCA5;   --ok-bg: rgba(33,188,165,.13);
    --warn: #FC8702; --warn-bg: rgba(252,135,2,.13);
    --ease: cubic-bezier(0.25, 0, 0, 1);
  }

  * { box-sizing: border-box; }
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  }

  body {
    margin: 0;
    background: #F8F8F8;
    color: var(--navy);
    font-family: 'Mulish', 'Muli', system-ui, sans-serif !important;
    font-size: 17px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
  }

  h1, h2 { text-wrap: balance; margin: 0; letter-spacing: 0; font-weight: 700; }
  h1 { font-size: clamp(34px, 6.5vw, 56px); line-height: 1.1; }
  h2 { font-size: clamp(24px, 3.6vw, 32px); line-height: 1.2; }
  p { margin: 0; text-wrap: pretty; }

  .wrap { max-width: 800px; margin: 0 auto; padding: 0 24px; }

  /* header, the nimiq.blog lockup pattern */
  .site-head { padding: 0 0 40px; text-align: center; }
  .lockup { display: inline-flex; align-items: center; gap: 16px; }
  .lockup svg { width: 72px; height: auto; display: block; }
  .lockup .word { font-size: 40px; font-weight: 700; letter-spacing: .08em; color: var(--navy); }

  /* hero, the nimiq.com centred pattern */
  /* One centred group: logo, nav, headline, CTA. The nav sits above the headline, it is
     not pinned to the viewport's top edge. Pinning it was the mistake, because it forced
     the leftover height to open as a gap between the nav and the headline. */
  .hero {
    background: #fff; color: var(--navy);
    /* 100dvh. svh fits on load then lets the next section show through once the toolbars
       retract; vh covers but extends BEHIND the browser's bottom bar, so on a phone about
       280px of the box is not visible and centring lands lopsided, wide at the top and
       tight at the bottom. dvh tracks the height actually on screen, so the content centres
       in what you can see and the hero still covers when the toolbars move.
       vh is the fallback for anything without dvh. */
    min-height: 100vh;
    min-height: 100dvh;
    padding: 48px 0;
    display: flex; flex-direction: column; justify-content: center;
  }
  .hero .inner {
    text-align: center; padding: 0;
    display: flex; flex-direction: column; align-items: center;
  }
  .hero h1 { margin: 0 auto 20px; max-width: 19ch; }
  .hero .lede {
    font-size: clamp(17px, 2.1vw, 20px); color: rgba(31,35,72,.6);
    max-width: 46ch; margin: 0 auto 32px;
  }
  .cta {
    display: inline-flex; align-items: center; gap: 8px; justify-content: center;
    background-image: var(--blue-bg); color: #fff;
    font-weight: 700; font-size: 17px; text-decoration: none;
    padding: 16px 40px; border-radius: 999px;
    box-shadow: 0 8px 24px rgba(0,0,0,.15);
    transition: transform .25s var(--ease), box-shadow .25s var(--ease);
  }
  .cta:hover { transform: translateY(-2px); box-shadow: 0 16px 40px rgba(0,0,0,.2); }
  .cta:active { transform: translateY(1px); box-shadow: 0 3px 5px rgba(0,0,0,.2); }
  .cta:focus-visible { outline: 2px solid #0CA6FE; outline-offset: 3px; }
  /* Constrained and balanced: unbroken it runs the full column at 390px and
     breaks wherever it lands, which reads as edge-to-edge. */
  .cta-note {
    margin: 16px auto 0; max-width: 34ch; text-wrap: balance;
    font-size: 14px; color: rgba(31,35,72,.5);
  }

  /* screens */
  .screens { padding: 80px 0; background: #FAFAFA; }
  .shots { display: flex; gap: 32px; justify-content: center; flex-wrap: wrap; margin-top: 48px; }
  .shot { width: 264px; margin: 0; }
  .shot img {
    width: 100%; height: auto; display: block;
    border-radius: 12px; box-shadow: 0 8px 56px rgba(0,0,0,.111);
  }
  .shot figcaption { margin-top: 16px; font-size: 15px; color: rgba(31,35,72,.5); text-align: center; }
  .shot .frame {
    aspect-ratio: 390 / 844; border-radius: 12px; background: #EDEDED;
    display: flex; align-items: center; justify-content: center;
    color: rgba(31,35,72,.4); font-size: 14px; text-align: center; padding: 24px;
  }

  /* proof */
  .proof { background-image: var(--navy-bg); color: #fff; padding: 80px 0; text-align: center; }
  .proof h2 { margin-bottom: 16px; }
  .proof > .wrap > p { color: rgba(255,255,255,.6); max-width: 52ch; margin: 0 auto; }

  .ledger { list-style: none; margin: 40px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
  .ledger li {
    background: #fff; border-radius: 8px; padding: 24px;
    display: grid; gap: 8px 24px; text-align: left;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: 'amt when blk' 'route route route' 'note note note';
    align-items: baseline;
  }
  @media (max-width: 620px) {
    .ledger li { grid-template-columns: 1fr auto; grid-template-areas: 'amt when' 'route route' 'blk blk' 'note note'; }
  }
  .ledger .amt { grid-area: amt; font-size: 20px; font-weight: 700; color: var(--navy); text-decoration: none; }
  .ledger .when { grid-area: when; font-size: 14px; color: rgba(31,35,72,.45); }
  .ledger .blk { grid-area: blk; font-family: 'Fira Mono', monospace; font-size: 13px; color: #0071C3; text-decoration: none; white-space: nowrap; }
  .ledger .route { grid-area: route; display: flex; align-items: flex-start; gap: 8px; font-family: 'Fira Mono', monospace; font-size: 11.5px; color: rgba(31,35,72,.6); }
  .ledger .who { display: inline-flex; flex-direction: column; align-items: center; gap: 4px; color: #0071C3; text-decoration: none; font-weight: 700; white-space: nowrap; }
  .ledger .note { grid-area: note; font-size: 15px; color: rgba(31,35,72,.6); }
  .ledger a:hover { color: var(--navy); }
  .ledger a:focus-visible { outline: 2px solid #0CA6FE; outline-offset: 3px; }
  .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

  /* The ledger in motion (mockup: NIMmesh in Motion, round 2). The Iqons are the Rive rig at
     /assets/rive/iqon.riv, mounted by /ledger.js; the host clips them to the hexagon the wallet
     uses. Money in motion is the Nimiq hexagon, never a circle (nimiq-ui rule 22). */
  .ledger .iqon { display: block; width: 48px; height: 48px; background: rgba(31,35,72,.06);
    clip-path: polygon(0 50%, 30% 5%, 70% 5%, 100% 50%, 70% 95%, 30% 95%); }
  .ledger .iqon canvas { display: block; width: 100%; height: 100%; }
  .ledger .track { position: relative; flex: 1 1 40px; height: 48px; }
  .ledger .track::before, .ledger .track::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; margin-top: -1px; border-top: 2px dashed rgba(31,35,72,.2); }
  .ledger .track::before { right: auto; width: 0; border-top-color: var(--navy); z-index: 1; }
  .ledger .pkt { position: absolute; top: 50%; left: 0; width: 20px; height: 18px; margin: -9px 0 0 -10px; z-index: 2; overflow: visible;
    color: var(--navy); fill: currentColor; stroke: #fff; stroke-width: 2.5; paint-order: stroke; opacity: 0; }
  .ledger .bhx { width: 14px; height: 13px; margin-right: 6px; vertical-align: -1px; color: rgba(31,35,72,.22); fill: currentColor; }
  .ledger .blk { position: relative; }
  .ledger .num { display: inline-block; vertical-align: bottom; overflow: hidden; white-space: nowrap; }

  /* Wait state, set by /ledger.js unless the reader asked for reduced motion: the receiver is
     dim, the block is a bar, the note is hidden. Without JS the page reads as it always did. */
  .ledger.motion .who.to { opacity: .4; transition: opacity .3s var(--ease); }
  .ledger.motion .blk { color: transparent; transition: color 0s; }
  .ledger.motion .blk::before { content: ""; position: absolute; left: 0; top: 50%; margin-top: -5px; width: 132px; height: 10px; border-radius: 5px; background: rgba(31,35,72,.08); transition: opacity .2s; }
  .ledger.motion .blk::after { content: ""; display: inline-block; width: 2px; height: 13px; margin-left: 2px; vertical-align: -2px; background: #0071C3; opacity: 0; }
  .ledger.motion .bhx { opacity: 0; transition: opacity 0s, color 0s; }
  .ledger.motion .num { width: 0; }
  .ledger.motion .note { opacity: 0; }

  /* Go: the timing score. t0 is the row reaching mid viewport, the packet lands at 1.6s. */
  .ledger li.go .pkt { opacity: 1; animation: fly 1.6s var(--ease) both, land 1.2s linear 1.6s forwards; }
  .ledger li.go .pkt.g1 { opacity: .3; animation: fly 1.6s var(--ease) .12s both, gone .2s linear 1.6s forwards; }
  .ledger li.go .pkt.g2 { opacity: .14; animation: fly 1.6s var(--ease) .24s both, gone .2s linear 1.6s forwards; }
  .ledger li.go .track::before { animation: lit 1.5s var(--ease) .1s forwards; }
  .ledger li.go .who.to { opacity: 1; transition-delay: 1.6s; }
  .ledger li.go .blk { color: #0071C3; transition-delay: 1.6s; }
  .ledger li.go .blk::before { opacity: 0; transition-delay: 1.6s; }
  .ledger li.go .blk::after { animation: caret .7s step-end 1.6s; }
  .ledger li.go .bhx { opacity: 1; color: var(--green); transition-delay: 1.6s; }
  .ledger li.go .num { animation: type .7s steps(8, end) 1.6s forwards; }
  .ledger li.go .note { animation: fadein .5s var(--ease) 2.3s forwards; }
  @keyframes fly { from { left: 0; } to { left: 100%; } }
  @keyframes land { 0%, 66% { color: var(--green); opacity: 1; } 100% { color: var(--green); opacity: 0; } }
  @keyframes gone { to { opacity: 0; } }
  @keyframes lit { to { width: 100%; } }
  @keyframes type { to { width: 8ch; } }
  @keyframes caret { from, to { opacity: 1; } }
  @keyframes fadein { to { opacity: 1; } }

  footer { background-image: var(--navy-bg); color: rgba(255,255,255,.6); padding: 48px 0; font-size: 14px; text-align: center; }

  /* ---------- shared page chrome added for how/ and test/ ---------- */
  /* White strip. It used to be #1a1d3d on the navy hero, which on a phone read as a
     slightly-off rectangle rather than a notice. */
  /* "Public alpha" as a grey section label, the shape nimiq.com uses for THE APPS
     and TRUSTED BY. It lives INSIDE the header group rather than as a strip above
     it: as a sibling it sat on the body's #F8F8F8 while everything below it is
     white, which drew a seam across the top of the page, and its gap stacked on
     top of the hero's own centring slack. Inside the group it just spaces off the
     lockup. Grey keeps the page's one saturated element the CTA. */
  .alpha {
    margin: 0 0 24px; padding: 0;
    color: #6E707E; text-align: center;
    font-size: 13px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  }

  .nav { display: flex; gap: 24px; justify-content: center; margin-top: 24px; font-size: 15px; }

  .nav a { color: rgba(31,35,72,.6); text-decoration: none; font-weight: 700; }
  .nav a:hover { color: var(--navy); }
  .nav a[aria-current] { color: var(--navy); }
  .nav a:focus-visible { outline: 2px solid #0CA6FE; outline-offset: 3px; }

  /* article pages */
  .page-head { background: #fff; color: var(--navy); padding: 32px 0 48px; text-align: center; }
  .page-head h1 { font-size: clamp(30px, 5vw, 44px); margin: 32px auto 16px; max-width: 20ch; }
  .page-head .sub { color: rgba(31,35,72,.6); max-width: 52ch; margin: 0 auto; }

  article { padding: 48px 0 96px; background: #FAFAFA; }
  article h2 { margin: 48px 0 16px; }
  article h2:first-child { margin-top: 0; }
  article h3 { font-size: 19px; font-weight: 700; margin: 32px 0 8px; }
  article p { max-width: 640px; margin-bottom: 16px; color: rgba(31,35,72,.75); }
  article ol, article ul { max-width: 640px; margin: 0 0 16px; padding-left: 24px; color: rgba(31,35,72,.75); }
  article li { margin-bottom: 8px; }
  article strong { color: var(--navy); }
  article a { color: var(--navy); font-weight: 700; text-decoration: none; }
  article a:hover { color: #0582CA; }
  article a:focus-visible { outline: 2px solid #0CA6FE; outline-offset: 3px; }

  .callout { background: #fff; border-radius: 8px; padding: 32px 24px; margin: 32px 0; max-width: 640px; }
  .callout p:last-child { margin-bottom: 0; }

  /* Roadmap on a light band with white cards, the nimiq.kids pattern. It was navy
     before, which put three dark sections in a row. */
  .band { background: #FAFAFA; padding: 80px 0; }
  .band-white { background: #fff; padding: 80px 0; }
  .eyebrow {
    font-size: 12px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
    color: #6E707E; margin: 0 0 12px;
  }
  .roadmap { list-style: none; padding: 0; margin: 32px 0 0; display: flex; flex-direction: column; gap: 24px; }
  .roadmap li { background: #fff; border: 1px solid rgba(31,35,72,.12); border-radius: 8px; padding: 24px; text-align: left; }
  /* Status chips, the pattern nimiq.blog ships (chip ok / chip warn). The
     background is a ~12% tint and the TEXT stays navy; only the icon takes the
     colour. That is what keeps this a status alert, the one pill nimiq-ui
     allows, rather than the coloured eyebrow rule 17 bans. A row with no
     modifier is the neutral "not built yet" state. */
  .chip {
    display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
    color: var(--navy); font-size: 13px; font-weight: 700; line-height: 1.3;
    padding: 5px 12px; border-radius: 500px;
    background: rgba(31,35,72,.06);
  }
  .chip svg { width: 12px; height: 12px; flex: 0 0 auto; }
  .chip.ok { background: var(--ok-bg); }
  .chip.ok svg { color: var(--ok); }
  .chip.warn { background: var(--warn-bg); }
  .chip.warn svg { color: var(--warn); }
  .roadmap .chip { margin-bottom: 12px; }
  .roadmap h3 { font-size: 19px; font-weight: 700; margin: 0 0 8px; color: var(--navy); }
  .roadmap p { color: rgba(31,35,72,.6); font-size: 16px; margin: 0; max-width: 62ch; }

  /* Steps, the condensed version of /test/ that lives on the home page */
  .steps-list { list-style: none; counter-reset: st; padding: 0; margin: 32px 0 0;
    display: flex; flex-direction: column; gap: 20px; text-align: left; }
  .steps-list li { counter-increment: st; display: grid; grid-template-columns: 32px 1fr; gap: 16px; align-items: start; }
  .steps-list li::before {
    content: counter(st); font-family: 'Fira Mono', monospace; font-size: 13px; font-weight: 600;
    color: var(--navy); border: 1px solid rgba(31,35,72,.12); border-radius: 6px;
    height: 32px; display: flex; align-items: center; justify-content: center; background: #fff;
  }
  .steps-list b { display: block; color: var(--navy); }
  .steps-list span { color: rgba(31,35,72,.6); font-size: 16px; }


  /* every link on the page gets a brand colour; an unstyled one renders browser blue */
  footer a { color: #fff; font-weight: 700; text-decoration: none; }
  footer a:hover { color: var(--green); }
  footer a:focus-visible { outline: 2px solid #0CA6FE; outline-offset: 3px; }
  .alpha a { color: inherit; font-weight: 700; text-decoration: none; }
  .hero .nav a { color: rgba(31,35,72,.6); }
  .hero .nav a:hover { color: var(--navy); }
  .page-head a { color: inherit; }

  /* ---- Added for nimiq.tech: the download page and the ledger footnote ---- */

  /* Provenance line under the on-chain ledger. The four transfers were sent
     between iPhones; the Android build has not reproduced them yet, and the page
     must not let a reader assume otherwise. */

  /* The download block. A white 1px-bordered card, the same card shape the
     roadmap uses, so the page has one card idiom rather than two. */
  .dl {
    background: #fff; border: 1px solid rgba(31,35,72,.12); border-radius: 8px;
    padding: 32px 24px; margin: 0 0 48px; text-align: center;
  }
  .dl-plat {
    font-size: 12px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
    color: #6E707E; margin: 0 0 24px;
  }
  .dl-meta { margin-top: 16px; font-size: 14px; color: rgba(31,35,72,.5); }

  /* Secondary CTA: same shape, no brand gradient, so the Android button stays the
     one obvious action on the page. */
  .cta-quiet {
    background-image: none; background-color: #fff; color: var(--navy);
    border: 1px solid rgba(31,35,72,.2); box-shadow: none;
  }
  .cta-quiet:hover { box-shadow: 0 8px 24px rgba(0,0,0,.1); }

  /* Hashes. Fira Mono per the brand rule that every number is monospaced, and
     wrapping is forced because a 64-char digest must stay readable at 390px. */
  .hash {
    background: var(--navy); color: #fff; border-radius: 6px;
    padding: 12px 16px; margin: 0 0 8px; max-width: 640px;
    overflow-x: auto; font-size: 13px;
  }
  /* pre-wrap, not pre: at 390px the apksigner line is wider than the box, and a
     clipped command reads as broken. Wrapping inserts no characters, so copying
     still yields the original single line. */
  .hash code { font-family: 'Fira Mono', ui-monospace, monospace; white-space: pre-wrap; }
  .hash-val {
    font-family: 'Fira Mono', ui-monospace, monospace;
    font-size: 13px; line-height: 1.7; word-break: break-all;
    color: rgba(31,35,72,.75); max-width: 640px; margin-bottom: 24px;
  }
  .hash-val code { font-family: inherit; }

  /* Permission table. Scrolls inside itself rather than pushing the page wide. */
  .perms {
    width: 100%; max-width: 640px; border-collapse: collapse;
    margin: 24px 0 16px; font-size: 15px; text-align: left;
  }
  .perms th, .perms td {
    border-bottom: 1px solid rgba(31,35,72,.12);
    padding: 12px 12px 12px 0; vertical-align: top;
  }
  .perms th { font-weight: 700; color: var(--navy); font-size: 13px;
    letter-spacing: 1px; text-transform: uppercase; }
  .perms td { color: rgba(31,35,72,.75); }
  .perms td:first-child { width: 42%; }
  .perms code {
    font-family: 'Fira Mono', ui-monospace, monospace; font-size: 12.5px;
    color: var(--navy); word-break: break-word;
  }
  .perms-note { font-size: 15px; color: rgba(31,35,72,.6); max-width: 640px; }

  @media (max-width: 560px) {
    .perms, .perms tbody, .perms tr, .perms td { display: block; width: 100%; }
    .perms thead { display: none; }
    .perms tr { border-bottom: 1px solid rgba(31,35,72,.12); padding: 12px 0; }
    .perms td { border: 0; padding: 2px 0; }
    .perms td:first-child { width: 100%; }
  }

  /* The before/after pair earns more width than the generic .shot: the whole
     point of it is a small grey status line ("mesh offline / mesh meshed"), and
     at 264px that line is unreadable, which loses the comparison entirely. */
  .shots--pair .shot { width: 330px; max-width: 100%; }
  @media (max-width: 760px) {
    .shots--pair .shot { width: 100%; max-width: 340px; }
  }

  /* Two download buttons side by side. They wrap to a column on narrow screens
     rather than shrinking, because a pill CTA that loses its padding stops
     reading as a button. */
  .cta-row {
    display: flex; gap: 16px; justify-content: center;
    flex-wrap: wrap; align-items: center;
  }
  @media (max-width: 460px) {
    .cta-row { flex-direction: column; }
    .cta-row .cta { width: 100%; max-width: 320px; }
  }

  /* Android and iPhone as two equal cards. iPhone is the constrained one, so it
     gets the quiet button rather than a smaller card: the limitation belongs in
     the copy, not in the layout. */
  .dl-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
    margin: 0 0 48px; max-width: 640px;
  }
  .dl-grid .dl { margin: 0; }
  .dl-grid .cta { padding: 16px 24px; font-size: 16px; }
  @media (max-width: 620px) {
    .dl-grid { grid-template-columns: 1fr; }
  }

  /* The hero's "Install on iPhone" jumps here. Without a scroll margin the card
     lands flush against the viewport's top edge, which reads as a broken jump
     rather than a deliberate one. */
  .dl-grid .dl[id] { scroll-margin-top: 24px; }

  /* ---- Support dialog ---------------------------------------------------- */
  /* A real <dialog>, so Escape, focus trapping and inertness come from the
     platform instead of being reimplemented badly. */
  .sup {
    border: 0; border-radius: 12px; padding: 32px 28px 28px;
    width: min(440px, calc(100vw - 32px)); max-width: none;
    background: #fff; color: var(--navy);
    box-shadow: 0 8px 56px rgba(0,0,0,.18);
  }
  .sup::backdrop { background: rgba(31,35,72,.6); }   /* navy, never black: rule 11 */
  .sup:focus { outline: 0; }
  .sup h2 { font-size: 24px; margin: 0 0 16px; }
  .sup p { margin: 0 0 12px; color: rgba(31,35,72,.75); font-size: 16px; }
  .sup-x {
    position: absolute; top: 14px; right: 14px;
    border: 0; background: none; padding: 6px; cursor: pointer;
    color: rgba(31,35,72,.4); line-height: 0;
  }
  .sup-x:hover { color: var(--navy); }

  /* One row, matching the blog's .lb-form. The field and the button sit side by
     side at every width; stacking them turned the pair into two large ovals. */
  .sup-form { display: flex; align-items: center; gap: 8px; margin-top: 24px; }
  .sup-amt-wrap { position: relative; display: block; flex: 1 1 auto; }
  .sup-amt {
    width: 100%; font: inherit; font-size: 15px; font-weight: 700; color: var(--navy);
    background: var(--page, #f8f8f8); border: 0; border-radius: 500px;
    box-shadow: inset 0 0 0 2px rgba(31,35,72,.1);
    padding: 8px 48px 8px 16px;
  }
  /* ⚠ An input's focus is the inset ring DEEPENING, nothing more. A :focus-visible
     outline here stacks a second ring outside the first and renders as concentric
     ovals. The blog hit this exact bug and its CSS carries the same warning; do
     not "restore the focus ring" on this field. Navy, not light blue, so the
     machinery stays two-colour. */
  .sup-amt:focus { outline: 0; box-shadow: inset 0 0 0 2px var(--navy); }
  .sup-amt.bad { box-shadow: inset 0 0 0 2px #D94432; }
  .sup-unit {
    position: absolute; top: 50%; right: 16px; transform: translateY(-50%);
    font-size: 13px; font-weight: 700; color: #6E707E; pointer-events: none;
  }
  .sup-usd {
    font-size: 13px; font-weight: 700; color: #6E707E;
    white-space: nowrap; align-self: center;
  }
  .sup-usd:empty { display: none; }
  .sup-send {
    flex: none; font: inherit; font-size: 14px; font-weight: 700;
    border: 0; border-radius: 500px; cursor: pointer; white-space: nowrap;
    padding: 9px 18px;
    background-image: var(--blue-bg); color: #fff;
    transition: transform .25s var(--ease), box-shadow .25s var(--ease);
  }
  .sup-send:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,.15); }
  .sup-send:active:not(:disabled) { transform: translateY(1px); }
  .sup-send:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
  .sup-send:disabled { opacity: .55; cursor: default; }
  .sup-note { margin: 16px 0 0; font-size: 14px; color: rgba(31,35,72,.5); min-height: 20px; }
  .sup-note:empty { min-height: 0; }

  /* Closing ask at the end of a long read. A plain bold link, not a third pill:
     the page already has one filled CTA and this must not compete with it. */
  .sup-tail {
    margin-top: 48px; padding-top: 24px;
    border-top: 1px solid rgba(31,35,72,.12);
    max-width: 640px;
  }

  /* ⚠ THE hidden ATTRIBUTE LOSES TO A DISPLAY RULE. .sup-amt-wrap carries
     display:block, so [hidden] alone leaves it on screen. The blog's CSS records
     this same bug biting three times. */
  .sup-form [hidden] { display: none !important; }
  /* Step one is a single button and nothing else, so it gets the full width. */
  .sup-form:not(.is-connected) .sup-send { flex: 1 1 auto; padding: 13px 28px; font-size: 16px; }

  /* Scorecard. Four columns, three of them a single number, so the criterion
     column takes everything left over. Scrolls inside itself rather than
     pushing the page wide. */
  .scorewrap { overflow-x: auto; margin: 32px 0 8px; -webkit-overflow-scrolling: touch; }
  .score {
    width: 100%; min-width: 560px; border-collapse: collapse;
    font-size: 15px; text-align: left;
  }
  .score th, .score td {
    border-bottom: 1px solid rgba(31,35,72,.12);
    padding: 14px 10px 14px 0; vertical-align: top;
  }
  .score thead th {
    font-weight: 700; color: var(--navy); font-size: 12px;
    letter-spacing: 1px; text-transform: uppercase; white-space: nowrap;
  }
  .score .num { width: 78px; text-align: center; padding-right: 0;
    font-variant-numeric: tabular-nums; font-weight: 700; color: var(--navy); }
  .score thead .num { text-align: center; }
  .score .crit { font-weight: 700; color: var(--navy); display: block; }
  .score .ask { display: block; margin-top: 3px; color: rgba(31,35,72,.5); font-size: 13.5px; font-style: italic; }
  .score .why { display: block; margin-top: 8px; color: rgba(31,35,72,.72); font-size: 14.5px; max-width: 62ch; }
  .score tr.cat td { padding-top: 30px; border-bottom: 0; }
  .score tr.cat h3 { margin: 0; font-size: 13px; letter-spacing: 1px;
    text-transform: uppercase; color: rgba(31,35,72,.55); font-weight: 700; }
  .score tr.sub td { background: rgba(31,35,72,.035); font-weight: 700; color: var(--navy);
    border-bottom: 1px solid rgba(31,35,72,.12); }
  .score tr.total td { border-bottom: 0; border-top: 2px solid var(--navy);
    font-size: 19px; font-weight: 700; color: var(--navy); padding-top: 18px; }
  .score tr.zero .crit { color: var(--warn, #C0451D); }

  /* On a phone the three columns cannot all be on screen at once, and a table
     that scrolls sideways hides two thirds of the comparison, which IS the page.
     So the row stops being a row: the criterion stacks, and the three scores sit
     under it as one labelled line that reads without any scrolling. */
  @media (max-width: 620px) {
    .scorewrap { overflow-x: visible; }
    .score { min-width: 0; display: block; }
    .score thead { display: none; }
    .score tbody, .score tr, .score td { display: block; width: 100%; }
    .score tr { border-bottom: 1px solid rgba(31,35,72,.12); padding: 14px 0; }
    .score td { border: 0; padding: 0; }
    .score .why { font-size: 14px; margin-bottom: 10px; }
    .score .num {
      display: inline-block; width: auto; text-align: left;
      margin: 0 22px 0 0; font-size: 15px;
    }
    .score .num::before {
      content: attr(data-label) " ";
      font-weight: 700; font-size: 11px; letter-spacing: 1px;
      text-transform: uppercase; color: rgba(31,35,72,.5);
      margin-right: 5px;
    }
    .score tr.cat { border-bottom: 0; padding-bottom: 0; }
    .score tr.cat td { padding-top: 18px; }
    .score tr.sub { background: rgba(31,35,72,.035); padding: 12px 10px; }
    .score tr.sub td:first-child { font-weight: 700; margin-bottom: 6px; }
    .score tr.total { border-bottom: 0; border-top: 2px solid var(--navy); padding-top: 16px; }
    .score tr.total td:first-child { font-size: 17px; margin-bottom: 8px; }
    .score tr.total .num { font-size: 19px; }
  }

  /* ---- Score chart ------------------------------------------------------- */
  /* Bars are divs, so the chart reflows and the type never scales. An SVG scaled
     as one unit put 12px labels at 7px on a phone, and a min-width to stop that
     pushed the chart off screen sideways. --f is a bar as a fraction of the axis,
     --m a category's own max, --g a gridline. Each subtracts the label gutter so
     the number at the end of a full bar still has somewhere to sit. */
  .chart { background: #fff; border-radius: 8px; padding: 24px; margin: 24px 0 0;
    box-shadow: 0 8px 56px rgba(0,0,0,.055); }
  .chart .legend { display: flex; gap: 24px; flex-wrap: wrap; margin: 0 0 16px; padding: 0;
    list-style: none; font-size: 13px; font-weight: 600; color: rgba(31,35,72,.72); }
  .chart .legend li { display: flex; align-items: center; gap: 8px; }
  .chart .sw { width: 15px; height: 15px; border-radius: 3px; background: var(--navy); flex: 0 0 auto; }
  .bars { position: relative; margin: 20px 0 0; overflow: hidden; background: #fff; }
  .axis { position: relative; height: 18px; margin-bottom: 2px; }
  .axis span { position: absolute; top: 18px; height: 9999px; z-index: 0;
    left: calc(var(--g) * (100% - 38px)); border-left: 1px solid rgba(31,35,72,.09); }
  .axis i { position: absolute; top: -18px; left: 0; transform: translateX(-50%); font-style: normal;
    font-size: 12px; font-weight: 600; color: rgba(31,35,72,.5); }
  .axis span:first-child i { transform: none; }
  .grp { position: relative; padding: 14px 0 4px; background: #fff; z-index: 1; }
  .glab { margin: 0 0 8px; font-size: 14px; font-weight: 700; color: var(--navy); }
  .glab span { font-weight: 400; font-size: 12.5px; color: rgba(31,35,72,.5); }
  .track { position: relative; border-radius: 4px; padding: 5px 0;
    background: linear-gradient(to right, rgba(31,35,72,.05) 0 calc(var(--m) * (100% - 38px)),
      transparent calc(var(--m) * (100% - 38px))); }
  .bars .row { display: flex; align-items: center; gap: 8px; height: 19px; background: transparent; }
  .bars .fill { height: 15px; border-radius: 4px; background: var(--navy); opacity: var(--o);
    flex: 0 0 auto; width: calc(var(--f) * (100% - 38px)); min-width: 2px; }
  .bars .row b { font-size: 13px; font-weight: 700; color: rgba(31,35,72,.72);
    font-variant-numeric: tabular-nums; background: #fff; }
  /* Three columns: name, plot, value. The value sat right after the bar once, and at
     360px the total rode into the hatched zone it is supposed to stop short of. */
  .totals-card { padding-bottom: 76px; }
  .totals { padding-top: 6px; overflow: visible; background: #fff; }
  .totals .row { height: 38px; gap: 10px; display: grid; grid-template-columns: 52px 1fr 34px;
    align-items: center; }
  .totals em { font-style: normal; text-align: right; font-size: 13px; font-weight: 700;
    color: rgba(31,35,72,.5); }
  .totals .fill { height: 30px; width: calc(var(--f) * 100%); }
  .totals b { font-size: 15px; color: var(--navy); text-align: right; }
  .unreach { position: absolute; top: 0; bottom: 0;
    left: calc(62px + var(--a) * (100% - 62px - 44px)); right: 44px;
    border-left: 1.5px dashed rgba(31,35,72,.5);
    background: repeating-linear-gradient(45deg, transparent 0 5px, rgba(31,35,72,.16) 5px 6.5px); }
  .unreach i, .unreach u { position: absolute; font-style: normal; text-decoration: none;
    font-size: 12px; color: rgba(31,35,72,.5); text-align: center; white-space: nowrap;
    background: #fff; padding: 0 4px; }
  .unreach i { bottom: -20px; left: 0; transform: translateX(-50%); font-weight: 700; }
  .unreach u { bottom: -56px; left: 50%; transform: translateX(-50%); line-height: 1.35; }

  /* ---- Folds, strips, roles, stats --------------------------------------- */
  /* Progressive disclosure. The summary carries the answer, the body the why,
     so a reader who never opens one is still served. */
  .fold { border-top: 1px solid rgba(31,35,72,.12); }
  .fold:last-of-type { border-bottom: 1px solid rgba(31,35,72,.12); }
  .fold summary { cursor: pointer; list-style: none; padding: 14px 0; font-weight: 700;
    color: var(--navy); display: grid; grid-template-columns: 16px 1fr; column-gap: 8px;
    align-items: baseline; font-size: 16px; }
  .fold summary::-webkit-details-marker { display: none; }
  .fold summary::before { content: ""; width: 8px; height: 8px; flex: 0 0 auto;
    border-right: 2px solid var(--navy); border-bottom: 2px solid var(--navy);
    transform: rotate(-45deg); transition: transform .16s var(--ease); }
  .fold[open] summary::before { transform: rotate(45deg); }
  .fold summary span { font-weight: 400; color: rgba(31,35,72,.6); grid-column: 2; display: block; }
  .fold p { margin: 0 0 16px; color: rgba(31,35,72,.72); }
  /* A sequence: glyph per step, one line under it. Numbering only where order is real. */
  .strip { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 12px; counter-reset: s; }
  .strip li { display: grid; grid-template-columns: 44px 1fr; gap: 16px; align-items: start; }
  .strip .g { width: 44px; height: 44px; border-radius: 12px; background: rgba(31,35,72,.05);
    display: grid; place-items: center; color: var(--navy); font-weight: 700; font-size: 16px;
    counter-increment: s; }
  .strip .g::before { content: counter(s); }
  .strip b { display: block; color: var(--navy); padding-top: 10px; }
  .strip span { display: block; color: rgba(31,35,72,.6); font-size: 14.5px; }
  .roles { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 12px;
    grid-template-columns: repeat(3, 1fr); }
  .roles li { background: #fff; border: 1px solid rgba(31,35,72,.12); border-radius: 8px; padding: 20px; }
  .roles h3 { margin: 0 0 6px; font-size: 16px; }
  .roles p { margin: 0; font-size: 14.5px; color: rgba(31,35,72,.72); }
  .hops { display: flex; align-items: center; gap: 8px; margin: 24px 0 0; flex-wrap: wrap;
    font-weight: 700; color: var(--navy); font-size: 14.5px; }
  .hops .node { display: inline-flex; align-items: center; padding: 10px 16px; border-radius: 500px;
    background: rgba(31,35,72,.05); }
  .hops .node.on { background: rgba(33,188,165,.13); }
  .hops .node.off { background: rgba(31,35,72,.05); text-decoration: line-through; color: rgba(31,35,72,.5); }
  .hops .arrow { color: rgba(31,35,72,.4); }
  .stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 24px 0 0; }
  .stats div { background: rgba(31,35,72,.035); border-radius: 8px; padding: 16px; }
  .stats b { display: block; font-size: 22px; color: var(--navy); font-variant-numeric: tabular-nums; }
  .stats span { font-size: 14.5px; color: rgba(31,35,72,.6); }
  .chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; }
  @media (max-width: 620px) { .roles, .stats { grid-template-columns: 1fr; } }
  /* The scorecard's reasons fold per row: numbers always visible, the why on a tap. */
  .score .fold { border: 0; margin-top: 4px; }
  .score .fold summary { padding: 6px 0; font-size: 13.5px; }
  .score .fold .ask { margin-top: 6px; }
  .score .fold .why { margin-bottom: 8px; }
