:root{
    --bg:#141414; --panel:#292929; --line:#525252;
    --white:#fff; --soft:#e5e5e5; --dim:#a3a3a3;
    --brand:#8b5cf6; --brand-deep:#6d3ae0;
    --teal:#22d3ee;
    /* Neon green, and used for exactly one idea: your data stays yours.
       13.2:1 on the page ground, 10.2:1 on a panel — it is loud because it
       has to be found by someone scanning, not because it is decoration.
       Nothing else on the page is this colour, which is what makes it read
       as a signal rather than a third brand hue beside the purple. */
    --neon:#3ff5a5;
    /* 90vw up to a 2000px ceiling. On a 1440 desktop that is ~90% of the
       width; on a 3440 ultrawide it settles at 2000px, about 58% — wide
       enough not to look like a small site marooned in the middle, narrow
       enough that a line of text is still readable. The old 82rem cap was
       1312px, which on that same ultrawide used 38%. */
    --shell:min(90vw,2000px); --narrow:min(88vw,52rem);
  }
  *{box-sizing:border-box}
  html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
  body{
    margin:0;background:var(--bg);color:var(--soft);
    font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
    font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
    /* clip, not hidden: hidden makes the body a scroll container, which
       breaks position:sticky and lets a stray element scroll the page. */
    overflow-x:clip;
  }
  .si{font-family:'Noto Sans Sinhala','Plus Jakarta Sans',sans-serif;font-weight:800}
  .shell{width:var(--shell);margin:0 auto}
  @media(max-width:768px){:root{--shell:min(92vw,2000px)}}
  a{color:inherit}

  h1,h2,h3{color:var(--white);margin:0;letter-spacing:-.025em}
  h1{font-size:clamp(2.4rem,4.6vw,5rem);font-weight:600;line-height:1.12}
  h2{font-size:clamp(1.85rem,3vw,3.5rem);font-weight:600;line-height:1.15}
  h3{font-size:clamp(1.05rem,1.15vw,1.4rem);font-weight:600;line-height:1.35}
  .kicker{
    font-size:.8125rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
    color:var(--brand);margin:0 0 1rem
  }
  .lede{font-size:clamp(1rem,1.15vw,1.35rem);color:var(--dim);margin:1.25rem 0 0;line-height:1.55;max-width:46ch}
  .intro .lede{max-width:none}
  .intro{max-width:var(--narrow);margin:0 auto;text-align:center}
  /* Capped in rem rather than left to grow with vw: at 9vw an ultrawide
     put roughly 300px of emptiness between every section. */
  section{padding:clamp(3.5rem,5vw,6.5rem) 0}

  /* ── buttons ───────────────────────────────────────────── */
  .btn{
    display:inline-flex;align-items:center;justify-content:center;gap:.55rem;
    padding:.85rem 1.5rem;border-radius:.5rem;font-size:.9375rem;font-weight:600;
    text-decoration:none;border:1px solid var(--line);background:var(--panel);
    color:var(--white);transition:background .4s ease,color .4s ease,border-color .4s ease;
    white-space:nowrap
  }
  .btn:hover{background:var(--white);color:#141414;border-color:var(--white)}
  .btn-brand{background:var(--brand-deep);border-color:var(--brand-deep)}
  .btn-brand:hover{background:var(--white);color:#141414;border-color:var(--white)}
  .btn-sm{padding:.6rem 1.1rem;font-size:.875rem}
  .btn svg{width:1.05rem;height:1.05rem;flex:none}

  .arrowlink{
    display:inline-flex;align-items:center;gap:.5rem;margin-top:1.15rem;
    font-size:.875rem;font-weight:600;color:var(--white);text-decoration:none;
    transition:gap .3s ease
  }
  .arrowlink:hover{gap:.75rem}
  .arrowlink svg{width:.9rem;height:.9rem}

  /* ── nav ───────────────────────────────────────────────── */
  nav{position:relative;z-index:60}
  .home nav{position:absolute;top:0;left:0;right:0}
  nav .shell{display:flex;align-items:center;gap:1.25rem;height:5rem}
  .navlinks{display:flex;align-items:center;gap:clamp(1rem,1.7vw,2rem);margin-left:auto}
  .navlinks a{color:var(--soft);text-decoration:none;font-size:.9rem;font-weight:500;white-space:nowrap}
  .navlinks a:hover,.navlinks a[aria-current="page"]{color:var(--white)}
  /*
   * On the home page the nav floats over the hero, and the card fan spreads
   * up and to the left until a bright cyan card is directly behind the
   * links. They were grey on cyan and effectively unreadable.
   *
   * A scrim rather than a solid bar: the floating nav is the design, so the
   * fix darkens whatever passes underneath instead of boxing the nav in. It
   * fades out well below the links so there is no visible edge against the
   * hero.
   */
  .home nav::before{
    content:"";position:absolute;inset:0 0 -3.5rem;pointer-events:none;
    background:linear-gradient(180deg,
      rgba(20,20,20,.96) 0%,
      rgba(20,20,20,.88) 45%,
      rgba(20,20,20,.55) 72%,
      rgba(20,20,20,0) 100%)
  }
  nav .shell{position:relative;z-index:1}
  nav .btn{margin-left:1.25rem}
  .navlinks + .btn{margin-left:0}
  /*
   * No hamburger. A menu that half works is worse than none on a site this
   * size, so below the fold the links become a scrollable row — but only on
   * pages where the nav sits in the flow. On the home page it floats over
   * the hero, where a second row would land on the headline, and there the
   * footer carries every link instead.
   */
  @media(max-width:768px){
    nav .shell{flex-wrap:wrap;height:auto;padding-top:1rem;padding-bottom:.5rem}
    .navlinks{
      order:3;width:100%;margin:.25rem -1rem 0;padding:.35rem 1rem .6rem;
      overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none
    }
    .navlinks::-webkit-scrollbar{display:none}
    nav .btn{margin-left:auto}
    .home .navlinks{display:none}
  }
  .brand{display:flex;align-items:center;gap:.7rem;text-decoration:none}
  .brandmark{
    width:2.15rem;height:2.15rem;border-radius:.6rem;background:var(--brand-deep);
    display:grid;place-items:center;flex:none
  }
  .brandmark span{font-family:'Noto Sans Sinhala',sans-serif;font-weight:800;font-size:.95rem;color:#fff;line-height:1}
  .brand b{color:var(--white);font-size:1.15rem;font-weight:700;letter-spacing:-.02em}

  /* ── hero ──────────────────────────────────────────────── */
  /* clip rather than hidden, so the fan can spill past the edge without
     turning the hero into a horizontal scroll container. */
  .hero{padding-top:clamp(7rem,10vw,10rem);padding-bottom:clamp(2.5rem,4vw,4.5rem);position:relative;overflow-x:clip}
  .hero-grid{display:grid;gap:3rem;align-items:center}
  /* Slightly more room to the words than the picture: the headline has to
     hold three lines without breaking awkwardly at any width. */
  @media(min-width:992px){.hero-grid{grid-template-columns:1.05fr 1fr;gap:clamp(2rem,3vw,4rem)}}
  .tagpill{
    display:inline-flex;align-items:center;gap:.55rem;padding:.4rem .9rem .4rem .45rem;
    border:1px solid var(--line);border-radius:99px;background:var(--panel);
    font-size:.8125rem;font-weight:600;color:var(--soft);margin-bottom:1.5rem
  }
  .tagpill i{
    width:1.35rem;height:1.35rem;border-radius:99px;background:var(--brand-deep);
    display:grid;place-items:center;font-style:normal;font-size:.72rem;color:#fff;
    font-family:'Noto Sans Sinhala',sans-serif;font-weight:800
  }
  /* The words win. Cards travel left into this column as they spread, and
     a headline you cannot finish reading is a worse trade than a card
     partly hidden behind it. */
  .hero-grid > div:first-child{position:relative;z-index:20}
  .hero-cta{display:flex;gap:.75rem;flex-wrap:wrap;margin-top:2rem}
  .hero-note{
    font-size:.8125rem;color:var(--dim);margin-top:1rem;
    display:flex;align-items:center;gap:.5rem;flex-wrap:wrap
  }
  .hero-note b{color:var(--neon);font-weight:600;display:inline-flex;align-items:center;gap:.4rem}
  .hero-note svg{width:.95rem;height:.95rem;flex:none}

  /* ── the card fan ──────────────────────────────────────── */
  /*
   * Reading the reference frame by frame, three things happen at once, and
   * the third is the one that makes it work:
   *
   *   1. Each card rotates.
   *   2. Each card travels outward, in its own direction — up-left, up-right,
   *      down-left, down-right — so the group radiates rather than hinging.
   *   3. THE WHOLE GROUP GROWS. Frame one is a single card at rest; by the
   *      last frame the arrangement has outgrown the hero and is cropped by
   *      the top, the sides and the bottom.
   *
   * Two earlier attempts missed the third and looked tidy and small as a
   * result. The scale lives on the container so it multiplies every card's
   * travel, which is what turns a neat arrangement into one that spills off
   * the page.
   */
  .fan-area{
    position:relative;
    height:clamp(22rem,28vw,38rem);
    display:grid;place-items:center;
    overflow:visible;
    /* Pushed off its own centre, so the leftward cards clear the text
       and the group leans into the page edge as the reference does. */
    margin-left:clamp(0rem,3vw,5rem);
  }
  /* The card sizes itself from the viewport, so the fan keeps its presence
     on a 34-inch screen instead of becoming a stamp in the corner. The
     ratio is a real card's, near enough. */
  .fan{
    position:relative;
    width:clamp(19rem,22vw,32rem);
    aspect-ratio:1.6/1;
    transform:scale(.78);
    animation:fanGrow 2.4s cubic-bezier(.16,.84,.34,1) .1s forwards;
  }
  @keyframes fanGrow{ to{ transform:scale(1.18) } }

  .pc{
    position:absolute;inset:0;border-radius:clamp(.9rem,1.1vw,1.6rem);
    padding:clamp(1.05rem,1.4vw,2rem);
    container-type:inline-size;
    display:flex;flex-direction:column;justify-content:space-between;
    box-shadow:0 2rem 4rem -1rem rgba(0,0,0,.85);
    border:1px solid rgba(255,255,255,.1);
    transform-origin:50% 50%;
    /* At rest every card sits exactly behind the first one. */
    transform:translate(0,0) rotate(0deg);
    opacity:0;
    animation:cardOut 2.1s cubic-bezier(.16,.84,.34,1) forwards;
  }

  .pc .top{display:flex;align-items:flex-start;justify-content:space-between}
  .pc .bank{font-size:clamp(.72rem,4.2cqw,1.1rem);font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:rgba(255,255,255,.96)}
  .pc .chip{width:12cqw;height:9cqw;border-radius:.34rem;background:linear-gradient(135deg,#f0dda0,#c9a24a 55%,#efd68e)}
  .pc .num{font-family:ui-monospace,'SF Mono',Consolas,monospace;font-size:clamp(.8rem,5cqw,1.35rem);letter-spacing:.2em;color:#fff}
  .pc .foot{display:flex;align-items:flex-end;justify-content:space-between}
  .pc .who{font-size:clamp(.66rem,3.6cqw,.95rem);letter-spacing:.07em;color:rgba(255,255,255,.78)}
  .pc .net{font-size:clamp(.68rem,3.8cqw,1rem);font-weight:800;letter-spacing:.04em;color:rgba(255,255,255,.94)}

  /* Real Sri Lankan issuer colours, the same ones the app uses. */
  .is-one  {background:linear-gradient(135deg,#0033A0 0%,#001f61 100%)}
  .is-two  {background:linear-gradient(135deg,#F58220 0%,#8f4a10 100%)}
  .is-three{background:linear-gradient(135deg,#00A9E0 0%,#00607f 100%)}
  .is-four {background:linear-gradient(135deg,#D6001C 0%,#7a0011 100%)}
  .is-five {background:linear-gradient(135deg,#6d3ae0 0%,#3b1f7d 100%)}

  /*
   * Where each card ends up. Directions radiate from the centre; the first
   * card barely moves, because it is the one already on screen at rest and
   * the others appear to come out from behind it.
   *
   * Later cards sit UNDER earlier ones, so the front of the stack never
   * changes and the reveal reads as emergence rather than reshuffling.
   */
  /* Travel is a proportion of the card, so the spread grows with it. */
  .is-one  {--x:0;    --y:0;    --r:-16deg; z-index:9; animation-delay:.15s}
  .is-two  {--x:-36%; --y:-44%; --r:-34deg; z-index:8; animation-delay:.45s}
  .is-three{--x:40%;  --y:-54%; --r:26deg;  z-index:7; animation-delay:.75s}
  .is-four {--x:-30%; --y:50%;  --r:-6deg;  z-index:6; animation-delay:1.05s}
  .is-five {--x:34%;  --y:60%;  --r:20deg;  z-index:5; animation-delay:1.35s}

  @keyframes cardOut{
    from{opacity:0;transform:translate(0,0) rotate(0deg)}
    /* Visible early, so the travel is watched rather than arrived at. */
    18% {opacity:1}
    to  {opacity:1;transform:translate(var(--x),var(--y)) rotate(var(--r))}
  }

  /*
   * Below the desktop breakpoint the hero stacks: words and buttons first,
   * the fan under them. It is NOT rotated — an earlier version turned the
   * whole group ninety degrees, which put every card number on its side.
   * It simply stays wide and is allowed to run off both edges, which is
   * what gives a narrow screen the same impact as a broad one.
   */
  /*
   * .98, not 991. Under display scaling the viewport lands on fractional
   * pixels, and with a plain 991 there is a sliver where neither this nor
   * the min-width:992 block matches — the hero stacks but the fan keeps its
   * desktop size, and the top two cards land on the reassurance line.
   */
  @media(max-width:991.98px){
    .fan-area{
      height:clamp(17rem,52vw,26rem);
      margin-left:0;
      /* Wider than its column on purpose, and centred on the page. */
      width:118vw;justify-self:center;margin-inline:calc(50% - 59vw);
      /* The spread reaches well above the box that reserves space for it —
         a rotated card's corner is far higher than the card. Stacked, the
         thing directly above is the "Windows and macOS" line, and the top
         two cards landed on top of it. This clears the overhang. */
      margin-top:clamp(2.5rem,7vw,4.5rem);
    }
    .fan{width:clamp(17rem,46vw,24rem)}
    /*
     * The spread flattens as the screen narrows. A phone has width to give
     * and none at all to spare vertically, so the cards travel further
     * sideways — off both edges, which is the point — and much less up and
     * down. Same fan, laid out for the shape of the screen it is on.
     */
    .is-two  {--x:-46%;--y:-19%}
    .is-three{--x:50%; --y:-23%}
    .is-four {--x:-40%;--y:23%}
    .is-five {--x:44%; --y:27%}
  }
  @media(max-width:480px){
    .fan-area{height:clamp(14rem,58vw,19rem)}
    .fan{width:clamp(14.5rem,58vw,18rem)}
  }

  @media(prefers-reduced-motion:reduce){
    .vault-kicker i{animation:none}
    .fan{animation:none;transform:scale(1.05)}
    .pc{animation:none;opacity:1;transform:translate(var(--x),var(--y)) rotate(var(--r))}
    .reveal{opacity:1!important;transform:none!important}
  }


  /* ── the privacy band ──────────────────────────────────── */
  /*
   * The objection, answered where it is raised.
   *
   * Someone is being asked to hand over every credit card statement they
   * own. They want one question answered before they will read a word about
   * features, and it used to be answered in 13px of grey under the download
   * button, then again in section five in a panel that looked like every
   * other panel. Now it sits immediately under the hero, in the one colour
   * used nowhere else.
   *
   * The caveat is inside the band on purpose. A privacy promise with its
   * exception printed next to it is believed; one without it is marketing,
   * and this app really does send some statement text to Gemini. Settings
   * once claimed nothing was uploaded anywhere and that was wrong — do not
   * make the same claim out here in green.
   */
  .vault{
    position:relative;display:grid;gap:clamp(1.75rem,3vw,3.5rem);
    border:1px solid rgba(63,245,165,.3);border-radius:1rem;
    padding:clamp(1.75rem,3.2vw,3.25rem);
    background:
      radial-gradient(120% 140% at 0% 0%,rgba(63,245,165,.10) 0%,rgba(63,245,165,0) 55%),
      var(--panel);
    box-shadow:0 1.5rem 4rem -2.25rem rgba(63,245,165,.55)
  }
  @media(min-width:992px){
    .vault{grid-template-columns:1.35fr .8fr;align-items:start}
    .vault-caveat{grid-column:1/-1}
  }
  .vault h2{margin-bottom:.85rem}
  /* The shared 46ch measure is right for a centred intro, but here it left a
     band of nothing between the paragraph and the list on a wide screen.
     58ch still reads comfortably and closes the gap. */
  .vault .lede{margin:0;max-width:58ch}
  .vault-kicker{
    display:flex;align-items:center;gap:.6rem;margin:0 0 1rem;
    font-size:.8125rem;font-weight:700;letter-spacing:.12em;
    text-transform:uppercase;color:var(--neon)
  }
  .vault-kicker i{
    width:.5rem;height:.5rem;border-radius:99px;background:var(--neon);
    box-shadow:0 0 0 0 rgba(63,245,165,.65);animation:pulse 2.8s ease-out infinite
  }
  @keyframes pulse{to{box-shadow:0 0 0 .8rem rgba(63,245,165,0)}}
  .vault-caveat{
    margin:0;padding-top:1.35rem;border-top:1px solid var(--line);
    font-size:.875rem;color:var(--dim);max-width:70ch
  }
  .vault-caveat strong{color:var(--soft);font-weight:600}
  .vault-caveat a{color:var(--neon);font-weight:600;text-decoration:none;white-space:nowrap}
  .vault-caveat a:hover{text-decoration:underline}
  .vault-list{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
  /* A surface per claim, so five rows spread down the column read as a
     panel of proof rather than five sentences drifting apart. */
  .vault-list li{
    position:relative;padding:.8rem 1rem .8rem 2.9rem;font-size:.9375rem;
    color:var(--soft);font-weight:500;line-height:1.4;
    background:rgba(20,20,20,.55);border:1px solid var(--line);border-radius:.625rem
  }
  .vault-list li::before{
    content:"";position:absolute;left:.95rem;top:.88rem;width:1.2rem;height:1.2rem;
    border-radius:99px;border:1px solid rgba(63,245,165,.45);background:rgba(63,245,165,.12)
  }
  /* The band's "what that means" link lands here, so the panel it lands on
     carries the same green — otherwise the jump looks like it missed. */
  #honest .panel:last-child{border-color:rgba(63,245,165,.32)}
  #honest .panel:last-child h3{color:var(--neon)}
  #honest .panel:last-child .checks li svg{color:var(--neon)}
  .vault-list li::after{
    content:"";position:absolute;left:1.37rem;top:1.13rem;width:.26rem;height:.55rem;
    border:solid var(--neon);border-width:0 2px 2px 0;transform:rotate(45deg)
  }

  /* ── scroll reveals ────────────────────────────────────── */
  /* Hidden ONLY once the script has confirmed it can reveal them again.
     Starting at opacity:0 unconditionally means any failure — no JS, no
     IntersectionObserver, a script error — leaves the entire page below
     the fold as a blank void, with nothing on screen to suggest why. */
  .js .reveal{opacity:0;transform:translateY(1.25rem);transition:opacity 1s cubic-bezier(.165,.84,.44,1) .2s,transform 1s cubic-bezier(.165,.84,.44,1) .2s}
  .js .reveal.in{opacity:1;transform:none}

  /* ── panels ────────────────────────────────────────────── */
  .cards{display:grid;gap:clamp(1rem,1.5vw,2rem);margin-top:clamp(2.5rem,3.5vw,4rem)}
  .c4{grid-template-columns:repeat(4,1fr)}
  .c3{grid-template-columns:repeat(3,1fr)}
  .c2{grid-template-columns:repeat(2,1fr)}
  @media(max-width:1179px){.c4,.c3{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:768px){.c4,.c3,.c2{grid-template-columns:1fr}}
  .panel{
    background:var(--panel);border:1px solid var(--line);border-radius:.625rem;
    padding:clamp(1.25rem,1.6vw,2rem)
  }
  .panel p{margin:.6rem 0 0;font-size:.9375rem;color:var(--dim);line-height:1.6}
  .sq{
    width:clamp(2.4rem,2.6vw,3.25rem);aspect-ratio:1;border-radius:.625rem;
    display:grid;place-items:center;margin-bottom:clamp(1.75rem,2.5vw,3rem)
  }
  .sq svg{width:1.35rem;height:1.35rem;color:#fff}
  .sq.v{background:linear-gradient(135deg,#8b5cf6,#6d3ae0)}
  .sq.t{background:linear-gradient(135deg,#22d3ee,#0e7490)}
  .sq.c{background:linear-gradient(135deg,#fb7185,#be123c)}
  .sq.p{background:linear-gradient(135deg,#fdba74,#c2410c)}

  /* ── steps ─────────────────────────────────────────────── */
  .step{display:grid;gap:clamp(1.5rem,2.5vw,2.5rem);align-items:center;margin-top:clamp(3rem,5vw,5.5rem)}
  @media(min-width:992px){.step{grid-template-columns:1fr 1.1fr;gap:clamp(2.5rem,4vw,5rem)}}
  .step:first-of-type{margin-top:clamp(2.5rem,3.5vw,3.5rem)}
  /*
   * The number anchors the row, so it is white, large and light. It was grey
   * at 700 weight, which read as a disabled label rather than a numeral —
   * heavy enough to compete with the heading and faint enough to be ignored,
   * the worst of both. Light and white, it sits above the heading the way a
   * chapter number sits above a chapter.
   */
  .stepno{
    font-size:clamp(3.25rem,5.2vw,5.75rem);font-weight:400;
    line-height:.95;color:var(--white);letter-spacing:-.03em
  }
  /* The step heading is the line people actually read, so it outranks the
     shared h3 scale used inside panels. */
  .step h3{
    margin-top:clamp(.9rem,1.4vw,1.5rem);
    font-size:clamp(1.5rem,2.1vw,2.35rem);line-height:1.2
  }
  /* Scoped to .step on purpose — the same .checks list is used inside the
     honest panels, where this size would be far too loud. */
  .step .checks{
    margin-top:clamp(1.5rem,2.4vw,2.5rem);
    display:grid;gap:clamp(1.1rem,2vw,1.75rem)
  }
  .step .checks li{
    padding-left:2.7rem;margin-bottom:0;
    font-size:clamp(1rem,1.35vw,1.25rem);
    color:var(--soft);line-height:1.45
  }
  .step .checks li svg{width:1.45rem;height:1.45rem;top:.05rem;color:var(--soft)}
  .checks{list-style:none;padding:0;margin:1.25rem 0 0}
  .checks li{position:relative;padding-left:1.75rem;margin-bottom:.75rem;font-size:.9375rem;color:var(--dim)}
  .checks li svg{position:absolute;left:0;top:.3rem;width:1.05rem;height:1.05rem;color:var(--brand)}

  /*
   * The artwork slot for each step. Fixed at 3:2 — the shape of the
   * 1152x768 screenshots that go here — so dropping the real images in
   * later changes what is inside the box and not the page around it.
   *
   *   <div class="shot"><img src="step-01.png" alt="..." width="1152" height="768"></div>
   *
   * Until then it holds the built mock, which fills the same box.
   */
  /* The three <img> in this section point at img/placeholder-step.webp,
     which is NOT committed (see .gitignore) and is NOT ours — it is
     Fintria's marketing artwork, standing in only to prove the slot. Swap
     in real 1152x768 CardGoda screenshots before this site is deployed. */
  .shot{aspect-ratio:3/2;min-width:0}
  .shot > img{
    width:100%;height:100%;object-fit:cover;display:block;
    border:1px solid var(--line);border-radius:.75rem;
    box-shadow:0 1.5rem 3.5rem -1.5rem rgba(0,0,0,.8)
  }
  .shot > .mock{height:100%;display:flex;flex-direction:column}
  .shot > .mock .mock-in{flex:1}

  /* ── product mock ──────────────────────────────────────── */
  .mock{background:#fbfcfd;border:1px solid var(--line);border-radius:.75rem;overflow:hidden;box-shadow:0 1.5rem 3.5rem -1.5rem rgba(0,0,0,.8)}
  .mock-bar{display:flex;align-items:center;gap:.4rem;padding:.7rem .9rem;background:#f1f4f7;border-bottom:1px solid #e2e8ee}
  .mock-bar i{width:.55rem;height:.55rem;border-radius:99px;background:#d3dae3}
  .mock-bar b{margin-left:.5rem;font-size:.7rem;font-weight:600;color:#596779}
  .mock-in{padding:1.15rem}
  .mrow{display:flex;align-items:center;gap:.7rem;padding:.55rem 0;border-bottom:1px solid #e2e8ee;font-size:.78rem}
  .mrow:last-child{border-bottom:0}
  .mrow .sw{width:.5rem;height:.5rem;border-radius:99px;flex:none}
  .mrow .nm{flex:1;color:#2b3440;font-weight:500}
  .mrow .am{font-weight:700;color:#121821;font-variant-numeric:tabular-nums}
  .mtiles{display:grid;grid-template-columns:repeat(3,1fr);gap:.55rem;margin-bottom:1rem}
  .mtile{border:1px solid #e2e8ee;border-radius:.5rem;padding:.6rem}
  .mtile .k{font-size:.55rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#596779}
  .mtile .v{font-size:.9rem;font-weight:800;color:#121821;margin-top:.2rem;font-variant-numeric:tabular-nums}
  .mtile.hi{background:#f2edfd;border-color:#ddd0fb}
  .mtile.hi .v{color:#5b2fc4}

  /* ── price ─────────────────────────────────────────────── */
  .price .panel{display:flex;flex-direction:column}
  .price .amt{font-size:2.25rem;font-weight:700;color:var(--white);letter-spacing:-.03em;margin:.9rem 0 .15rem}
  .price .per{font-size:.8125rem;color:var(--dim)}
  .price .panel.now{border-color:var(--brand)}
  .badge{
    display:inline-block;font-size:.6875rem;font-weight:700;letter-spacing:.08em;
    text-transform:uppercase;color:var(--brand);margin-bottom:.4rem
  }

  .strip{
    border:1px solid var(--line);background:var(--panel);border-radius:.625rem;
    padding:1.5rem 1.75rem;margin-top:2.5rem
  }
  .strip p{margin:0;font-size:.9375rem;color:var(--dim)}
  .strip strong{color:var(--white);font-weight:600}

  /* ── cta ───────────────────────────────────────────────── */
  .cta-panel{
    border:1px solid var(--line);background:var(--panel);border-radius:.625rem;
    padding:clamp(2.5rem,5vw,4rem);display:grid;gap:2.5rem;align-items:center;overflow:hidden
  }
  @media(min-width:992px){.cta-panel{grid-template-columns:1.1fr .9fr}}

  /* ── footer ────────────────────────────────────────────── */
  footer{border-top:1px solid var(--line);padding:clamp(2.5rem,5vw,4.5rem) 0 2.5rem;margin-top:clamp(3rem,6vw,7rem)}
  .fnav{display:grid;gap:clamp(1.75rem,3vw,2.5rem) clamp(1.25rem,3vw,3rem);grid-template-columns:repeat(2,1fr)}
  @media(min-width:640px){.fnav{grid-template-columns:repeat(3,1fr)}}
  @media(min-width:992px){.fnav{grid-template-columns:repeat(5,1fr)}}
  .fcol h4{
    font-size:.8125rem;font-weight:500;color:var(--dim);margin:0 0 1.1rem;
    letter-spacing:.01em
  }
  .fcol a{
    display:block;color:var(--soft);font-size:.9375rem;text-decoration:none;
    margin:0 0 .75rem
  }
  .fcol a:hover{color:var(--white)}
  .fbottom{
    display:flex;align-items:center;justify-content:space-between;gap:1rem;
    flex-wrap:wrap;margin-top:clamp(2.5rem,4vw,4rem);padding-top:1.75rem;
    border-top:1px solid var(--line)
  }
  .fbottom small{color:var(--dim);font-size:.8125rem}
  .fbrand{display:flex;align-items:center;gap:.6rem;color:var(--white);font-weight:700;text-decoration:none}

  /* ── subpage header ────────────────────────────────────── */
  .page-head{padding:clamp(2.5rem,5vw,5rem) 0 clamp(1.25rem,2.5vw,2.25rem)}
  .page-head h1{font-size:clamp(2rem,3.6vw,3.75rem);font-weight:600;line-height:1.12}
  .page-head .lede{max-width:60ch;margin-top:1rem}
  .page-head .updated{font-size:.8125rem;color:var(--dim);margin:1.25rem 0 0}

  /* ── long-form document ────────────────────────────────── */
  /* Legal and help text is read, not scanned, so it gets a measure of about
     72 characters rather than the full shell. */
  .doc{max-width:72ch}
  .doc h2{font-size:clamp(1.25rem,1.7vw,1.6rem);margin:clamp(2.25rem,3.5vw,3.25rem) 0 .85rem}
  .doc h3{font-size:1.0625rem;margin:2rem 0 .6rem;color:var(--soft)}
  .doc p{margin:0 0 1rem;color:var(--dim)}
  .doc ul,.doc ol{margin:0 0 1.25rem;padding-left:1.35rem;color:var(--dim)}
  .doc li{margin-bottom:.6rem}
  .doc strong{color:var(--soft);font-weight:600}
  .doc a{color:var(--brand);text-decoration:none}
  .doc a:hover{text-decoration:underline}
  .doc code{
    font-family:ui-monospace,'SF Mono',Consolas,monospace;font-size:.875em;
    background:var(--panel);border:1px solid var(--line);border-radius:.3rem;padding:.1rem .35rem
  }
  .doc table{width:100%;border-collapse:collapse;margin:0 0 1.5rem;font-size:.9375rem}
  .doc th,.doc td{text-align:left;padding:.7rem .8rem;border-bottom:1px solid var(--line);vertical-align:top}
  .doc th{color:var(--soft);font-weight:600}
  .doc td{color:var(--dim)}
  .doc-wrap{overflow-x:auto}

  /* ── callout ───────────────────────────────────────────── */
  .note{
    border:1px solid var(--line);border-left:3px solid var(--brand);
    background:var(--panel);border-radius:.5rem;padding:1.1rem 1.35rem;margin:0 0 1.5rem
  }
  .note :last-child{margin-bottom:0}
  .note.warn{border-left-color:#fb923c}
  .note.good{border-left-color:var(--neon)}
  .note h3{margin-top:0;color:var(--white)}

  /* ── numbered instructions ─────────────────────────────── */
  .howto{list-style:none;counter-reset:hw;padding:0;margin:0 0 1.5rem;display:grid;gap:1rem}
  .howto li{
    counter-increment:hw;position:relative;padding:1.05rem 1.25rem 1.05rem 3.5rem;
    border:1px solid var(--line);border-radius:.625rem;background:var(--panel);
    color:var(--dim);margin:0
  }
  .howto li::before{
    content:counter(hw);position:absolute;left:1.1rem;top:1.05rem;
    width:1.6rem;height:1.6rem;border-radius:99px;background:var(--brand-deep);color:#fff;
    display:grid;place-items:center;font-size:.8125rem;font-weight:700
  }
  .howto li strong{display:block;color:var(--white);font-weight:600;margin-bottom:.2rem}
  .howto li :last-child{margin-bottom:0}

  /* ── FAQ ───────────────────────────────────────────────── */
  .faq{display:grid;gap:.7rem}
  .faq details{border:1px solid var(--line);border-radius:.625rem;background:var(--panel);overflow:hidden}
  .faq summary{
    cursor:pointer;list-style:none;padding:1.05rem 3rem 1.05rem 1.25rem;
    color:var(--white);font-weight:600;font-size:.9875rem;position:relative
  }
  .faq summary::-webkit-details-marker{display:none}
  .faq summary::after{
    content:"";position:absolute;right:1.3rem;top:1.35rem;width:.55rem;height:.55rem;
    border-right:2px solid var(--dim);border-bottom:2px solid var(--dim);
    transform:rotate(45deg);transition:transform .2s
  }
  .faq details[open] summary::after{transform:rotate(-135deg);border-color:var(--brand)}
  .faq .a{padding:0 1.25rem 1.25rem;color:var(--dim);font-size:.9375rem}
  .faq .a :first-child{margin-top:0}
  .faq .a :last-child{margin-bottom:0}

  /* ── video ─────────────────────────────────────────────── */
  .vid{
    aspect-ratio:16/9;border:1px solid var(--line);border-radius:.75rem;
    overflow:hidden;background:#000;display:block;position:relative
  }
  .vid iframe{width:100%;height:100%;border:0;display:block}
  /* Placeholder state, used until a tutorial has actually been filmed. It is
     visibly a gap rather than a broken embed. */
  .vid.soon{
    display:grid;place-items:center;background:var(--panel);
    border-style:dashed;color:var(--dim);font-size:.9375rem;text-align:center;padding:1.5rem
  }
  .vidcard h3{margin:1rem 0 .35rem}
  .vidcard p{color:var(--dim);font-size:.9375rem;margin:0}

  /* Footer entries for accounts that do not exist yet. Plain text, not a
     dead link — a footer full of links going nowhere is worse than one that
     admits the account is not up. */
  .fsoon{display:block;color:var(--line);font-size:.9375rem;margin:0 0 .75rem}

  /*
   * The video facade.
   *
   * A YouTube <iframe> contacts Google the moment the page loads, and so does
   * a YouTube thumbnail. The cookies page says nothing is requested from
   * YouTube until you press play, so this is a locally drawn poster and the
   * iframe is built only on click. Keep it that way, or that claim becomes
   * false.
   */
  button.vid{
    width:100%;cursor:pointer;padding:0;
    background:linear-gradient(150deg,#1d1d1d,#2c2c2c 60%,#241d3a);
    display:grid;place-items:center
  }
  button.vid:hover .vid-play{transform:scale(1.08);background:var(--brand)}
  button.vid:focus-visible{outline:2px solid var(--brand);outline-offset:3px}
  .vid-play{
    width:3.75rem;height:3.75rem;border-radius:99px;background:rgba(255,255,255,.14);
    border:1px solid rgba(255,255,255,.25);display:grid;place-items:center;
    transition:transform .18s,background .18s
  }
  .vid-play::after{
    content:"";border-style:solid;border-width:.55rem 0 .55rem .95rem;
    border-color:transparent transparent transparent #fff;margin-left:.2rem
  }
  @media(prefers-reduced-motion:reduce){
    button.vid:hover .vid-play{transform:none}
  }

  /* ── visual components ─────────────────────────────────── */
  /*
   * These exist because the help and legal pages were walls of prose. The
   * claims they carry — what leaves your machine, what a warning dialog
   * looks like, how many banks are covered — are all things a reader takes
   * in faster as a picture than as a sentence, and every one is drawn in
   * CSS rather than shipped as an image so it stays sharp and themeable.
   */

  /* Big scannable numbers. */
  .stats{display:grid;gap:clamp(.75rem,1.2vw,1.15rem);grid-template-columns:repeat(2,1fr);margin:0 0 clamp(1.5rem,2.5vw,2.5rem)}
  @media(min-width:768px){.stats{grid-template-columns:repeat(4,1fr)}}
  .stat{border:1px solid var(--line);background:var(--panel);border-radius:.75rem;padding:clamp(1rem,1.5vw,1.5rem)}
  .stat b{display:block;font-size:clamp(1.75rem,3.2vw,2.75rem);font-weight:700;color:var(--white);line-height:1;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
  .stat span{display:block;margin-top:.5rem;font-size:.8125rem;color:var(--dim);line-height:1.35}
  .stat.on b{color:var(--neon)}
  .stat.off b{color:var(--dim)}

  /* The data-flow picture: one box that holds everything, and the few
     arrows that leave it. */
  .flow{margin:0 0 clamp(1.5rem,2.5vw,2.5rem)}
  .flow-box{
    border:1px solid rgba(63,245,165,.35);border-radius:1rem;
    background:radial-gradient(120% 140% at 50% 0%,rgba(63,245,165,.09),rgba(63,245,165,0) 60%),var(--panel);
    padding:clamp(1.25rem,2vw,1.75rem)
  }
  .flow-box h4{margin:0 0 .9rem;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--neon);font-weight:700}
  .flow-items{display:grid;gap:.5rem;grid-template-columns:repeat(2,1fr);margin:0;padding:0;list-style:none}
  @media(min-width:640px){.flow-items{grid-template-columns:repeat(3,1fr)}}
  .flow-items li{
    background:var(--bg);border:1px solid var(--line);border-radius:.5rem;
    padding:.6rem .75rem;font-size:.8125rem;color:var(--soft);margin:0
  }
  .flow-arrows{
    display:grid;gap:clamp(.75rem,1.2vw,1.15rem);grid-template-columns:1fr;
    margin-top:clamp(1.5rem,2.5vw,2.25rem);position:relative
  }
  @media(min-width:768px){.flow-arrows{grid-template-columns:repeat(3,1fr)}}
  .flow-out{
    border:1px dashed var(--line);border-radius:.75rem;padding:1rem 1.15rem;
    background:var(--panel);position:relative
  }
  .flow-out::before{
    content:"";position:absolute;left:1.15rem;top:-1.05rem;width:1px;height:.8rem;background:var(--line)
  }
  .flow-out .tag{
    display:inline-block;font-size:.6875rem;font-weight:700;letter-spacing:.08em;
    text-transform:uppercase;color:#fb923c;margin-bottom:.4rem
  }
  .flow-out h5{margin:0 0 .3rem;font-size:.9375rem;color:var(--white);font-weight:600}
  .flow-out p{margin:0;font-size:.8125rem;color:var(--dim);line-height:1.45}
  .flow-never{
    margin-top:clamp(1rem,1.6vw,1.5rem);border:1px solid var(--line);border-radius:.75rem;
    padding:1rem 1.15rem;background:var(--bg);display:flex;gap:.85rem;align-items:flex-start
  }
  .flow-never .x{
    flex:none;width:1.5rem;height:1.5rem;border-radius:99px;border:1px solid #7f1d1d;
    background:rgba(220,38,38,.14);display:grid;place-items:center;color:#f87171;
    font-size:.9rem;font-weight:700;line-height:1
  }
  .flow-never p{margin:0;font-size:.875rem;color:var(--dim)}
  .flow-never strong{color:var(--soft)}

  /* Drawn operating-system dialogs, so the warning is recognised on sight. */
  .osdlg{border-radius:.6rem;overflow:hidden;border:1px solid var(--line);margin:0 0 1rem;font-size:.8125rem}
  .osdlg.win{background:#f3f3f3;color:#1a1a1a}
  .osdlg.win .bar{background:#0067b8;color:#fff;padding:.9rem 1.1rem;font-weight:600;font-size:.9375rem}
  .osdlg.win .body{padding:1.1rem}
  .osdlg.win .body p{margin:0 0 .9rem;color:#3a3a3a}
  .osdlg.win .link{color:#0067b8;font-weight:600;text-decoration:underline;display:inline-block;margin-bottom:.9rem}
  .osdlg .btns{display:flex;gap:.5rem;justify-content:flex-end}
  .osdlg.win .btns span{border:1px solid #adadad;background:#e1e1e1;padding:.4rem .95rem;border-radius:.15rem}
  .osdlg.win .btns .go{background:#0067b8;border-color:#0067b8;color:#fff;font-weight:600}
  .osdlg.mac{background:#ecebeb;color:#1a1a1a;text-align:center;border-radius:.9rem}
  .osdlg.mac .body{padding:1.4rem 1.5rem 1.1rem}
  .osdlg.mac .icon{
    width:2.75rem;height:2.75rem;border-radius:.6rem;margin:0 auto .8rem;
    background:linear-gradient(135deg,#8b5cf6,#6d3ae0);display:grid;place-items:center;
    color:#fff;font-weight:800;font-size:1.1rem
  }
  .osdlg.mac b{display:block;font-size:.875rem;margin-bottom:.35rem}
  .osdlg.mac p{margin:0 0 1rem;color:#4a4a4a;font-size:.78rem;line-height:1.45}
  .osdlg.mac .btns{justify-content:center}
  .osdlg.mac .btns span{background:#fff;border:1px solid #c8c8c8;border-radius:.3rem;padding:.35rem 1.1rem;font-size:.78rem}
  .osdlg.mac .btns .go{background:#0a84ff;border-color:#0a84ff;color:#fff;font-weight:600}
  .dlgnote{font-size:.8125rem;color:var(--dim);margin:0 0 1.75rem}

  /* Side-by-side before and after. */
  .vs{display:grid;gap:clamp(.85rem,1.5vw,1.35rem);grid-template-columns:1fr;margin:0 0 1.5rem}
  @media(min-width:768px){.vs{grid-template-columns:1fr 1fr}}
  .vs > div{border:1px solid var(--line);border-radius:.75rem;padding:clamp(1.1rem,1.7vw,1.6rem);background:var(--panel)}
  .vs .then{border-style:dashed;opacity:.85}
  .vs h4{margin:0 0 .9rem;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;font-weight:700}
  .vs .then h4{color:var(--dim)}
  .vs .now h4{color:var(--neon)}
  .vs ul{margin:0;padding:0;list-style:none}
  .vs li{position:relative;padding-left:1.5rem;margin-bottom:.65rem;font-size:.9375rem;color:var(--dim);line-height:1.45}
  .vs li::before{position:absolute;left:0;top:-.05rem;font-weight:700}
  .vs .then li::before{content:"\00d7";color:#f87171}
  .vs .now li::before{content:"\2713";color:var(--neon)}
  .vs li:last-child{margin-bottom:0}

  /* Icon heading for a card. */
  .iconbox{
    width:2.5rem;height:2.5rem;border-radius:.65rem;display:grid;place-items:center;
    margin-bottom:.9rem;background:var(--brand-deep)
  }
  .iconbox svg{width:1.25rem;height:1.25rem;color:#fff}
  .iconbox.g{background:linear-gradient(135deg,#3ff5a5,#0e9f6e)}
  .iconbox.g svg{color:#06281a}
  .iconbox.t{background:linear-gradient(135deg,#22d3ee,#0e7490)}
  .iconbox.o{background:linear-gradient(135deg,#fb923c,#c2410c)}

  /* Screenshot slots on the setup pages, waiting for real captures. */
  .figures{display:grid;gap:clamp(1rem,2vw,1.75rem);grid-template-columns:1fr;margin:0 0 1.75rem}
  @media(min-width:768px){.figures{grid-template-columns:repeat(3,1fr)}}
  .figure{margin:0}
  .figure figcaption{margin-top:.7rem;font-size:.8125rem;color:var(--dim);line-height:1.45}
  .shot-soon{
    display:grid;place-items:center;width:100%;height:100%;
    border:1px dashed var(--line);border-radius:.75rem;background:var(--panel);
    color:var(--dim);font-size:.875rem;text-align:center;line-height:1.5
  }
  .shot-soon small{color:var(--line);font-size:.75rem}

  /* ── illustrated cards ─────────────────────────────────── */
  /*
   * The problem and feature cards were a heading plus a paragraph, which read
   * as a wall of prose: three, then four, identical grey rectangles. Each now
   * carries a small drawing of the thing it describes, because "the totals
   * never meet" lands in a second when you can see three amounts and no total,
   * and takes a sentence otherwise.
   *
   * All of it is CSS. No image files, so it stays sharp at any size, costs
   * nothing to load, and cannot rot into a broken img later.
   */
  .pcard{
    background:var(--panel);border:1px solid var(--line);border-radius:.75rem;
    padding:clamp(1.05rem,1.5vw,1.5rem);display:flex;flex-direction:column;
    gap:clamp(.9rem,1.2vw,1.15rem);min-width:0
  }
  .pc-head{display:flex;gap:.8rem;align-items:flex-start}
  .pc-ico{
    width:2.4rem;height:2.4rem;border-radius:.6rem;flex:none;display:grid;place-items:center;
    background:rgba(255,255,255,.06);border:1px solid var(--line)
  }
  .pc-ico svg{width:1.15rem;height:1.15rem;color:var(--soft)}
  .pc-head h3{font-size:1.0625rem;margin:0 0 .25rem;line-height:1.25}
  .pc-head p{margin:0;font-size:.8125rem;color:var(--dim);line-height:1.45}
  .mini{background:var(--bg);border:1px solid var(--line);border-radius:.6rem;padding:.8rem}
  /* Two of the drawings are a single block, so they sat at the top of a box
     sized by the tallest card and left the rest of it empty. These stretch. */
  .mini:has(> .sheet),.mini:has(> .subs){display:flex;flex-direction:column}
  .mini > .sheet,.mini > .subs{flex:1;min-height:0}
  /* And the row-based ones spread their rows, so whichever card happens to
     set the height, none of the three is left with a gap under its drawing. */
  .mini:has(> .srow),.mini:has(> .crow),.mini:has(> .prow){
    display:flex;flex-direction:column;justify-content:space-between
  }
  /* The drop zone grows into its space; the donut simply centres in it. */
  .mini:has(> .drop){display:flex;flex-direction:column;justify-content:space-between}
  .mini > .drop{flex:1;display:flex;flex-direction:column;justify-content:center}
  .mini:has(> .donutwrap){display:flex}
  .mini > .donutwrap{flex:1}

  /*
   * Aligning the illustrations by their bottoms was the wrong end. margin-top
   * auto did that, and because the drawings are different heights it opened a
   * gap between a card's description and its picture — on two of three cards
   * a hole big enough to read as a rendering fault.
   *
   * subgrid aligns them by the top instead, which is what the eye actually
   * tracks. Each card spans two rows of the parent grid and inherits them, so
   * every header row is as tall as the tallest header and every drawing starts
   * on the same line. Slack now falls at the bottom of the shorter cards,
   * where trailing space in a panel looks like padding rather than a mistake.
   *
   * Scoped with :has so the plain .panel grids elsewhere are untouched, and it
   * degrades quietly: without subgrid the cards simply align as they did.
   */
  @media(min-width:769px){
    .cards:has(.pcard){grid-template-rows:auto auto}
    .pcard{display:grid;grid-row:span 2;grid-template-rows:subgrid;gap:clamp(.9rem,1.2vw,1.15rem)}
  }

  /* Statement rows, and the total that never appears. */
  .srow{display:flex;align-items:center;gap:.6rem;padding:.5rem;border-radius:.45rem;
    background:rgba(255,255,255,.03);border:1px solid var(--line)}
  .srow + .srow{margin-top:.4rem}
  .srow .lg{width:1.8rem;height:1.8rem;border-radius:.35rem;flex:none;display:grid;
    place-items:center;font-size:.55rem;font-weight:800;color:#fff}
  .srow .nm{flex:1;min-width:0}
  .srow .nm b{display:block;font-size:.775rem;color:var(--soft);font-weight:600;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .srow .nm i{font-style:normal;font-size:.65rem;color:var(--dim)}
  .srow .amt{font-size:.775rem;font-weight:700;color:var(--white);
    font-variant-numeric:tabular-nums;white-space:nowrap}
  .srow.void{border-style:dashed;background:none}
  .srow.void .nm b,.srow.void .amt{color:var(--dim)}

  /* The spreadsheet that went stale. */
  .sheet{border:1px solid var(--line);border-radius:.45rem;overflow:hidden;
    background:rgba(255,255,255,.03);display:flex;flex-direction:column;position:relative}
  .sheet-top{display:flex;align-items:center;gap:.5rem;padding:.5rem .55rem;border-bottom:1px solid var(--line)}
  .sheet-top .xl{width:1.5rem;height:1.5rem;border-radius:.25rem;background:#1d6f42;
    display:grid;place-items:center;color:#fff;font-size:.55rem;font-weight:800;flex:none}
  .sheet-top b{font-size:.725rem;color:var(--soft);display:block;font-weight:600}
  .sheet-top i{font-style:normal;font-size:.625rem;color:var(--dim)}
  .sheet-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.28rem;
    padding:.55rem .55rem 1.75rem;flex:1;align-content:space-between}
  .sheet-grid span{height:.45rem;border-radius:.12rem;background:rgba(255,255,255,.09)}
  .stale{position:absolute;right:.55rem;bottom:.5rem;background:rgba(185,28,28,.92);color:#fee2e2;
    font-size:.575rem;font-weight:700;padding:.12rem .4rem;border-radius:.25rem;border:1px solid #b91c1c}

  /* Recurring charges, quietly running. */
  .subs{display:grid;gap:.4rem;margin-top:.5rem;align-content:space-between}
  .subtile{display:flex;align-items:center;gap:.5rem;padding:.45rem .5rem;border-radius:.4rem;
    background:rgba(255,255,255,.03);border:1px solid var(--line)}
  .subtile .ic{width:1.5rem;height:1.5rem;border-radius:.3rem;flex:none;display:grid;
    place-items:center;font-size:.6rem;font-weight:800;color:#fff}
  .subtile b{font-size:.725rem;color:var(--soft);display:block;font-weight:600}
  .subtile i{font-style:normal;font-size:.625rem;color:var(--dim)}
  .subtile .v{margin-left:auto;font-size:.725rem;font-weight:700;color:var(--white);
    font-variant-numeric:tabular-nums;white-space:nowrap}

  /* Drop your statements here. */
  .drop{border:1px dashed var(--line);border-radius:.45rem;padding:1.1rem .7rem;text-align:center}
  .drop .di{width:1.9rem;height:1.9rem;margin:0 auto .45rem;border-radius:.35rem;
    background:rgba(255,255,255,.06);display:grid;place-items:center}
  .drop .di svg{width:.95rem;height:.95rem;color:var(--dim)}
  .drop p{margin:0;font-size:.725rem;color:var(--dim);line-height:1.4}
  .drop u{color:var(--brand);text-decoration:none}
  .files{display:flex;gap:.3rem;flex-wrap:wrap;margin-top:.55rem}
  .fchip{display:flex;align-items:center;gap:.3rem;font-size:.625rem;color:var(--dim);
    background:rgba(255,255,255,.04);border:1px solid var(--line);border-radius:.3rem;padding:.28rem .4rem}
  .fchip em{font-style:normal;background:#b91c1c;color:#fff;font-size:.45rem;font-weight:800;
    padding:.08rem .18rem;border-radius:.12rem}

  /* The reconciliation result. */
  .crow{display:flex;align-items:center;gap:.5rem;padding:.45rem .55rem;border-radius:.4rem;
    background:rgba(255,255,255,.03);border:1px solid var(--line);font-size:.75rem;color:var(--soft)}
  .crow + .crow{margin-top:.35rem}
  .crow .tick{width:1.05rem;height:1.05rem;border-radius:99px;background:rgba(63,245,165,.15);
    border:1px solid rgba(63,245,165,.5);display:grid;place-items:center;flex:none}
  .crow .tick::after{content:"";width:.2rem;height:.42rem;border:solid var(--neon);
    border-width:0 2px 2px 0;transform:rotate(45deg);margin-top:-.1rem}
  .crow .v{margin-left:auto;font-weight:700;color:var(--white);font-variant-numeric:tabular-nums}
  .allgood{margin-top:.5rem;display:flex;align-items:center;gap:.45rem;padding:.55rem .65rem;
    border-radius:.4rem;background:rgba(63,245,165,.1);border:1px solid rgba(63,245,165,.4);
    font-size:.75rem;font-weight:600;color:var(--neon)}

  /* A month, planned. */
  .mhead{display:flex;align-items:center;justify-content:space-between;padding:0 .1rem .5rem;
    font-size:.775rem;font-weight:700;color:var(--soft)}
  .mhead em{font-style:normal;color:var(--line);letter-spacing:.2em;font-weight:400}
  .prow{display:flex;align-items:center;gap:.5rem;font-size:.725rem;padding:.4rem .1rem;
    border-top:1px solid var(--line)}
  .prow .dot{width:.42rem;height:.42rem;border-radius:99px;flex:none}
  .prow .nm{color:var(--soft);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .prow .v{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
  .prow .v.in{color:var(--neon)}
  .prow .d{color:var(--dim);font-size:.65rem;width:2.9rem;text-align:right;flex:none}
  .addline{margin-top:.45rem;font-size:.7rem;color:var(--brand);font-weight:600}

  /* Where it went. */
  .donutwrap{display:flex;align-items:center;gap:.85rem}
  .donut{width:5.75rem;height:5.75rem;border-radius:99px;flex:none;position:relative;
    background:conic-gradient(#f472b6 0 38%,#a78bfa 38% 62%,#fb923c 62% 76%,#22d3ee 76% 88%,#3ff5a5 88% 96%,#64748b 96% 100%)}
  .donut::after{content:"";position:absolute;inset:24%;border-radius:99px;background:var(--bg)}
  .donut b{position:absolute;inset:0;display:grid;place-items:center;font-size:.7rem;
    font-weight:800;color:var(--white);z-index:1;line-height:1.15;text-align:center}
  .legend{flex:1;min-width:0;display:grid;gap:.28rem}
  .legend div{display:flex;align-items:center;gap:.4rem;font-size:.675rem;color:var(--dim)}
  .legend i{width:.42rem;height:.42rem;border-radius:99px;flex:none}
  .legend b{margin-left:auto;color:var(--soft);font-weight:700;font-variant-numeric:tabular-nums}

  /* ── sequenced entrance ────────────────────────────────── */
  /*
   * The two story sections play themselves in when they are reached: label,
   * heading, description, then the cards, then the data inside each card.
   *
   * Nothing here is keyed on JavaScript having run correctly — it is keyed on
   * the `js` class, which an inline script in <head> sets before the body
   * paints. No script, no class, no hiding: the page renders complete and
   * static. That ordering matters. An earlier version of the scroll reveals
   * on this site started at opacity:0 unconditionally, which meant any JS
   * failure left everything below the fold blank.
   */
  @property --sweep{syntax:'<angle>';inherits:false;initial-value:0deg}

  .js [data-anim]{
    opacity:0;
    transition:opacity .62s cubic-bezier(.22,.61,.36,1) var(--d,0ms),
               transform .62s cubic-bezier(.22,.61,.36,1) var(--d,0ms)
  }
  .js [data-anim].in{opacity:1;transform:none}

  /* Outer elements: the brief's 20px and 0.98, ease-out, no overshoot. */
  .js [data-anim="up"]{transform:translateY(20px) scale(.98)}
  /* Data inside a card moves less — it is a smaller object in a smaller box. */
  .js [data-anim="row"]{transform:translateY(12px);transition-duration:.5s}
  /* Spreadsheet cells draw out from the left, row by row. */
  .js [data-anim="cell"]{transform:scaleX(0);transform-origin:left center;transition-duration:.42s}
  /* File chips drop into the upload area. */
  .js [data-anim="chip"]{transform:translateY(-10px) scale(.92);transition-duration:.44s}
  .js [data-anim="fade"]{transition-duration:.55s}

  /* The stale badge arrives last, with one pulse and then stillness. */
  .js [data-anim="pulse"]{transform:scale(.9)}
  .js [data-anim="pulse"].in{animation:stalePulse .9s ease-out .1s 1}
  @keyframes stalePulse{
    0%{box-shadow:0 0 0 0 rgba(185,28,28,.55)}
    100%{box-shadow:0 0 0 .6rem rgba(185,28,28,0)}
  }

  /*
   * The donut sweeps clockwise. The conic lives on ::before so the mask that
   * does the sweeping cannot also erase the label sitting in the middle.
   * --sweep is a registered property, which is what lets an angle be
   * transitioned at all; without @property it jumps straight to full, and a
   * donut that simply appears is a fine thing to fall back to.
   */
  .donut{--sweep:360deg;transition:--sweep 1s cubic-bezier(.22,.61,.36,1)}
  .donut::before{
    content:"";position:absolute;inset:0;border-radius:99px;
    background:conic-gradient(#f472b6 0 38%,#a78bfa 38% 62%,#fb923c 62% 76%,
      #22d3ee 76% 88%,#3ff5a5 88% 96%,#64748b 96% 100%);
    -webkit-mask:conic-gradient(#000 var(--sweep),transparent 0);
    mask:conic-gradient(#000 var(--sweep),transparent 0)
  }

  /* Everything arrives at once, and stays, for anyone who asked for less. */
  @media(prefers-reduced-motion:reduce){
    .js [data-anim]{opacity:1!important;transform:none!important;transition:none!important;animation:none!important}
    .donut{--sweep:360deg;transition:none}
  }
