@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:500 800;font-display:swap;src:url(/assets/fonts/bricolage-grotesque-500_800-latin.woff2) format('woff2');}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/hanken-grotesk-400-latin.woff2) format('woff2');}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/hanken-grotesk-500-latin.woff2) format('woff2');}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/hanken-grotesk-600-latin.woff2) format('woff2');}
  @font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/hanken-grotesk-700-latin.woff2) format('woff2');}
  @font-face{font-family:'Space Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/space-mono-400-latin.woff2) format('woff2');}
  @font-face{font-family:'Space Mono';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/space-mono-700-latin.woff2) format('woff2');}

  :root{
    --ink:#171513; --ink-soft:#403a35; --paper:#fff;
    --coral:#f0543c; --coral-deep:#d23b26; --coral-ink:#7c1d0f;
    --coral-wash:#fff0ec; --coral-line:#ffd7cd;
    --line:#eae6e1; --blue:#1f4dff;
    /* NEW TOKEN from the Replit palette: a warmer, slightly lifted dark, distinct from
       --ink. Used for the two dark bands and the footer. Decide whether to keep it or
       fold back to --ink before this ships. */
    --ink-warm:#211e1b;
    --dark-soft:#c9c4be;
    /* the live site's error/attention yellow. Only used for :user-invalid on the demo form,
       where a red error state would vanish against the coral band. */
    --sun:#ffcf3a;
    --display:'Bricolage Grotesque',system-ui,sans-serif;
    --body:'Hanken Grotesk',system-ui,sans-serif;
    --mono:'Space Mono',ui-monospace,monospace;
    --ease:cubic-bezier(.2,.7,.2,1);
  }
  .skip-link{position:absolute;left:14px;top:-60px;z-index:200;background:var(--ink);color:#fff;
             padding:12px 18px;border-radius:10px;text-decoration:none;font-weight:700;
             font-family:var(--display);transition:top .12s var(--ease);}
  .skip-link:focus{top:14px;outline:3px solid var(--blue);outline-offset:2px;}
  /* The header is sticky at 81px, so an anchor jump lands the target UNDER it: every
     nav link put its section heading behind the bar. scroll-padding-top on the scroll
     container fixes all of them at once, including #main from the skip link, and works
     for keyboard focus scrolling too. */
  html{scroll-padding-top:96px;}
  /* The features page stacks a SECOND sticky bar (the category filter) under the
     header, 144px in total, so the homepage value left every anchor 48px underneath
     it. The footer links straight to #certs, which landed behind the filter.
     :has() scopes this to the page that actually has the filter, so the value cannot
     drift from the markup the way a hardcoded body class would. */
  html:has(.fp-filter){scroll-padding-top:164px;}
  *{box-sizing:border-box;}
  body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden;}
  /* ONE container width for the whole page. There used to be a second 960px tier for
     pricing, FAQ and the demo band, which meant the page ran 1152 x6, narrowed to 912 x3,
     then sprang back to 1152 for the footer. Sections here are distinguished by BACKGROUND
     (bone / coral-wash / dark / red / coral band), and a width change stacked on top of a
     colour change reads as a mistake rather than an intention.
     Line length is capped LOCALLY on the text that needs it (--measure below), never by
     narrowing the container: a paragraph's comfort is not a reason to drag the card, the
     band and the section edges in with it. */
  .wrap{max-width:1200px;margin:0 auto;padding:0 24px;}
  /* ~66 characters of Hanken at 17px. Safe as a ch unit ONLY because it is applied to the
     text element itself; ch on a CONTAINER resolves against the container's font, which is
     what broke four headlines earlier in this build. */
  :root{--measure:66ch;}
  h1,h2,h3,h4{font-family:var(--display);margin:0;letter-spacing:-0.03em;text-wrap:balance;}
  /* Max 74px, not 92px. At 92px "Your tickets." is ~660px wide and the hero's left column is
     ~470px, so every line wrapped in two, the headline grew to 433px tall and pushed the CTAs
     below the fold. Size the display type to the column it lives in. */
  h1{font-weight:800;font-size:clamp(44px,5.6vw,74px);line-height:.96;}
  h2{font-weight:800;font-size:clamp(34px,5vw,62px);line-height:1.0;}
  h3{font-weight:700;font-size:clamp(21px,2.2vw,26px);line-height:1.15;}
  img{display:block;max-width:100%;}
  a{color:inherit;}
  section{padding:clamp(72px,9vw,132px) 0;}
  .kick{display:block;font-family:var(--mono);font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;margin-bottom:18px;}
  .lede{font-size:clamp(18px,2vw,22px);color:var(--ink-soft);line-height:1.55;}

  .btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;font-family:var(--body);font-weight:600;
       font-size:17px;text-decoration:none;padding:17px 30px;border-radius:14px;border:1.5px solid transparent;cursor:pointer;min-height:56px;
       transition:transform .14s var(--ease),background .16s;}
  .btn:focus-visible{outline:3px solid var(--blue);outline-offset:3px;}
  .btn-coral{background:var(--coral-deep);color:#fff;box-shadow:0 10px 24px -12px rgba(210,59,38,.7);}
  .btn-coral:hover{background:#b02f1d;transform:translateY(-2px);}
  .btn-out{background:var(--paper);color:var(--ink);border-color:var(--coral-line);}
  .btn-out:hover{border-color:var(--coral-deep);color:var(--coral-ink);}
  .btn-white{background:#fff;color:var(--ink);}
  .btn-white:focus-visible{outline-color:#fff;}
  .btn-sm{padding:12px 20px;font-size:15px;min-height:46px;border-radius:12px;}

  /* ---------- 1 header ---------- */
  .hdr{position:sticky;top:0;z-index:60;background:rgba(255,255,255,.92);backdrop-filter:blur(12px);border-bottom:1px solid var(--coral-wash);}
  .hdr-in{max-width:1200px;margin:0 auto;padding:0 24px;height:80px;display:flex;align-items:center;gap:20px;position:relative;}
  /* The real arch mark + the wordmark as LIVE TEXT, rather than the flat hatch-logo-nav.png.
     Three reasons: the PNG's wordmark is a softer charcoal where this is true --ink; it was
     rendering at 47% scale so it softened on standard-DPI screens; and a baked-in dark
     wordmark cannot go white for the footer, where the same lockup has to sit on --ink-warm.
     Bricolage Grotesque 800 is the same face the logo is drawn in. */
  /* width:fit-content matters in the footer: flex:0 0 auto does nothing for a GRID item,
     so the link stretched the full 525px cell and swallowed clicks across the whole row. */
  .logo{display:flex;align-items:center;gap:9px;text-decoration:none;flex:0 0 auto;width:fit-content;}
  .logo img{width:30px;height:auto;}
  .logo-word{font-family:var(--display);font-weight:800;font-size:27px;letter-spacing:-0.045em;color:var(--ink);line-height:1;}
  /* margin:0 auto centres the nav between the logo and the right-hand group. margin-left:auto
     shoved it up against the CTA, which is what made the bar feel crowded. */
  .hdr-nav{display:flex;gap:32px;font-weight:500;font-size:15.5px;margin:0 auto;align-items:center;}
  .hdr-nav a{text-decoration:none;}
  .hdr-nav a:hover{color:var(--coral-ink);}
  /* the in-nav Log in exists ONLY for the mobile menu; without this it renders twice */
  .login-m{display:none;}
  .hdr-right{display:flex;align-items:center;gap:18px;flex:0 0 auto;}
  /* quiet, deliberately not a button: existing customers need it, prospects don't */
  .login{font-size:15.5px;font-weight:600;text-decoration:none;color:var(--ink-soft);white-space:nowrap;}
  .login:hover{color:var(--coral-ink);}
  .login:focus-visible{outline:3px solid var(--blue);outline-offset:3px;border-radius:6px;}
  /* the logo and the four nav links were the only interactive elements on the page falling
     back to the browser's default ring. Not a 2.4.7 failure (the default IS visible), but
     it was the one inconsistent indicator on an otherwise deliberate set. */
  .logo:focus-visible,.hdr-nav a:focus-visible{outline:3px solid var(--blue);outline-offset:4px;border-radius:6px;}
  /* mobile: burger + a persistent CTA, matching the live site. The live burger handler
     already lives in /js/site.js; the script at the foot of this file is concept-only and
     must NOT be inlined when this ports (CSP is script-src 'self'). */
  .burger{display:none;width:46px;height:46px;border:1.5px solid var(--line);border-radius:12px;background:#fff;
          align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;}
  .burger:focus-visible{outline:3px solid var(--blue);outline-offset:2px;}

  /* ---------- 2 hero ---------- */
  .hero{background:var(--coral-wash);position:relative;overflow:hidden;padding-top:clamp(48px,6vw,84px);padding-bottom:clamp(56px,7vw,104px);}
  .hero-glow{position:absolute;top:-30%;right:-14%;width:820px;height:820px;border-radius:50%;
             background:var(--coral-line);filter:blur(120px);opacity:.45;pointer-events:none;}
  .hero-grid{display:grid;grid-template-columns:.95fr 1.05fr;gap:clamp(36px,4.5vw,64px);align-items:center;position:relative;z-index:1;}
  /* category pill: the headline is a benefit claim, not a category, so this tells a cold
     visitor what Hatch actually is before they read anything else */
  .pill{display:inline-block;font-family:var(--body);font-weight:600;font-size:11.5px;letter-spacing:.14em;
        text-transform:uppercase;color:var(--ink-soft);background:#fff;border:1px solid var(--coral-line);
        border-radius:999px;padding:9px 16px;margin-bottom:26px;}
  .hero h1 .hl{color:var(--coral-deep);}
  .hero .lede{margin:26px 0 0;max-width:38ch;color:var(--ink-soft);}
  .hero-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:32px;}
  .hero-mail{display:flex;align-items:center;gap:9px;font-size:14.5px;color:var(--ink-soft);margin:20px 0 0;}
  .hero-mail .d{width:8px;height:8px;border-radius:50%;background:var(--coral-deep);flex:0 0 auto;}
  .hero-mail a{color:var(--coral-ink);font-weight:600;}

  /* layered product shot: the real booking page, with a live order panel overlapping it */
  .stage{position:relative;}
  .stage-card{border-radius:22px;overflow:hidden;border:1px solid rgba(23,21,19,.09);background:#fff;
              box-shadow:0 60px 100px -60px rgba(23,21,19,.55);width:82%;}
  .stage-card img{width:100%;height:auto;}
  /* real Hatch Park figures: Adult skater £10.50, Junior £8.50, 2% booking fee, Pay £30.09 */
  .order{position:absolute;right:0;top:16%;width:56%;max-width:300px;background:#fff;border-radius:18px;
         padding:20px;box-shadow:0 40px 70px -40px rgba(23,21,19,.5);border:1px solid rgba(23,21,19,.07);}
  .order .ord-h{font-family:var(--display);font-weight:700;font-size:16px;letter-spacing:-0.02em;margin:0 0 14px;}
  .o-row{display:flex;justify-content:space-between;gap:14px;font-size:14px;color:var(--ink-soft);margin-bottom:9px;}
  .o-row b{font-family:var(--mono);font-weight:400;color:var(--ink);font-size:13.5px;}
  .o-tot{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--line);
         margin-top:13px;padding-top:13px;font-weight:700;font-size:16px;}
  .o-tot b{font-family:var(--mono);font-size:16px;}
  .o-pay{margin-top:15px;width:100%;background:var(--ink);color:#fff;border:0;border-radius:12px;padding:13px;
         font-family:var(--body);font-weight:600;font-size:15px;display:flex;align-items:center;justify-content:center;gap:7px;}
  .o-alt{text-align:center;font-size:12.5px;color:var(--ink-soft);margin:10px 0 0;}
  .o-trust{display:flex;flex-direction:column;gap:7px;margin-top:13px;padding-top:13px;border-top:1px solid var(--line);}
  .o-trust span{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--ink-soft);}

  /* decoration: coral brush swash + ink sparks, echoing the mockup */
  .swash{position:absolute;right:-4%;bottom:4%;width:210px;height:96px;pointer-events:none;z-index:-1;}
  .sparks{position:absolute;right:8%;top:-2%;pointer-events:none;color:var(--ink);}
  .pw{position:absolute;right:2%;bottom:-3%;background:#fff;border:1px solid var(--coral-line);border-radius:999px;
      padding:9px 15px;display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink-soft);
      box-shadow:0 14px 30px -18px rgba(23,21,19,.4);}
  .pw img{width:17px;height:auto;}
  .pw b{font-family:var(--display);font-weight:800;font-size:14px;color:var(--ink);letter-spacing:-0.03em;}

  /* ---------- 3 trust bar ---------- */
  /* Self-identification, NOT social proof. This replaced the mockup's logo wall but does a
     different job: "is this for a venue like mine?". Deliberately plain text — the mockup
     set these in mixed fonts so they would read as customer logos at a glance. */
  .bar{background:var(--paper);border-top:1px solid var(--coral-wash);border-bottom:1px solid var(--coral-wash);padding:clamp(44px,5vw,64px) 0;}
  /* no ch cap: the line needs ~765px at 34px and .wrap gives 1152px, so it sits on one
     line at desktop and wraps naturally on narrow screens */
  .bar h2{text-align:center;font-size:clamp(24px,2.9vw,34px);letter-spacing:-0.03em;margin:0 auto 26px;}
  .bar h2 .hl{color:var(--coral-deep);}
  /* no max-width: the eight chips need 1067px and .wrap gives 1152px, so they sit on one
     row at desktop. A 900px cap was forcing a second row for no reason. */
  .bar-row{display:flex;flex-wrap:wrap;justify-content:center;gap:12px 14px;}
  .bar-row span{font-size:15.5px;font-weight:500;color:var(--ink);background:var(--coral-wash);
                border:1px solid var(--coral-line);border-radius:999px;padding:9px 17px;}

  /* ---------- 4 dark: differentiators ---------- */
  .dark{background:var(--ink-warm);color:#fff;}
  .dark h2,.dark h3{color:#fff;}
  .dark .kick{color:var(--coral-line);}
  /* 820px, not 46ch. 46ch resolves against the DIV's 17px body font, giving a 438px box that
     forced the 62px headline onto three lines. "Everything else is handled." needs 720px. */
  .dark-head{max-width:820px;margin:0 auto;text-align:center;}
  .dark-head p{color:var(--dark-soft);font-size:clamp(17px,1.8vw,20px);margin:22px 0 0;max-width:46ch;margin-inline:auto;}
  /* four across, centred head above: deliberately a different shape from the red section's
     split layout, so the two feature blocks do not read as the same slide twice */
  .cols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(24px,2.8vw,40px);margin-top:clamp(44px,5vw,72px);}
  .cols h3{font-size:clamp(18px,1.9vw,21px);}
  .col-ic{width:54px;height:54px;border-radius:15px;background:rgba(210,59,38,.16);border:1px solid rgba(210,59,38,.4);
          display:grid;place-items:center;color:var(--coral);margin-bottom:20px;}
  .cols p{color:var(--dark-soft);margin:11px 0 0;font-size:15.5px;line-height:1.55;}

  /* ---------- 5 full red ---------- */
  .red{background:var(--coral-deep);color:#fff;}
  .red h2,.red h3{color:#fff;}
  /* white, not --coral-line: coral-line on coral-deep is 3.61:1 and fails at 12.5px */
  .red .kick{color:#fff;}
  .red-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(40px,5vw,76px);align-items:center;}
  .red-list{margin-top:clamp(34px,4vw,52px);display:flex;flex-direction:column;gap:30px;}
  .red-item{display:flex;gap:18px;}
  .red-item svg{flex:0 0 auto;margin-top:3px;}
  .red-item h3{font-family:var(--display);font-weight:700;font-size:21px;letter-spacing:-0.02em;margin:0 0 7px;}
  /* solid white, not white/80: at 80% this is ~3.4:1 on coral and fails AA */
  .red-item p{margin:0;color:#fff;font-size:16px;line-height:1.55;}
  /* 2/3 matches the source photo exactly, so nothing is cropped */
  .red-photo{position:relative;border-radius:24px;overflow:hidden;aspect-ratio:2/3;box-shadow:0 40px 80px -50px rgba(0,0,0,.7);}
  .red-photo img{width:100%;height:100%;object-fit:cover;}
  .red-photo::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 40%,rgba(0,0,0,.78) 100%);}
  /* DARK glass, not white glass. A white veil over an unknown photo gives unpredictable
     contrast: measured 3.0-4.0:1 here. A dark scrim guarantees white text passes whatever
     image is behind it, which matters because venues will swap this photo. */
  .red-card{position:absolute;left:22px;right:22px;bottom:22px;z-index:1;background:rgba(18,16,15,.62);
            backdrop-filter:blur(14px);border:1px solid rgba(255,255,255,.28);border-radius:18px;padding:22px;}
  /* white, not coral-line: on the glass card over a photo, coral-line measures ~3.6:1 and
     the true backdrop varies with whatever image a venue puts behind it */
  .red-card .rc-k{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:#fff;margin:0 0 8px;}
  .red-card h3{font-size:23px;margin:0 0 5px;}
  .red-card p{margin:0 0 16px;font-size:14.5px;color:#fff;}
  /* .track / .rc-pc removed with the invented "76% sold" progress bar */

  /* ---------- 6 how it works ---------- */
  .steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:26px;margin-top:clamp(44px,5vw,72px);position:relative;}
  .step{text-align:center;position:relative;}
  .step-n{width:86px;height:86px;margin:0 auto 22px;border-radius:50%;background:var(--coral-wash);border:4px solid #fff;
          display:grid;place-items:center;font-family:var(--mono);font-weight:700;font-size:26px;
          /* coral-ink not coral-deep: coral-deep on coral-wash is 4.31:1 */
          color:var(--coral-ink);box-shadow:0 2px 10px -4px rgba(23,21,19,.18);position:relative;z-index:1;}
  .step:last-child .step-n{background:var(--coral-deep);color:#fff;}
  .step p{color:var(--ink-soft);margin:12px 0 0;font-size:15.5px;}
  .step:not(:last-child)::before{content:"";position:absolute;top:43px;left:calc(50% + 52px);right:calc(-50% + 52px);height:2px;background:var(--coral-wash);}
  /* asterisk + footnote, same pattern the live site uses for "included in your 3%*" */
  .ast{color:var(--coral-deep);font-weight:700;}
  .ast-note{max-width:62ch;margin:clamp(34px,4vw,52px) auto 0;text-align:center;font-size:14px;
            color:var(--ink-soft);line-height:1.6;}

  /* ---------- 7 pricing ---------- */
  .pricing{background:var(--coral-wash);position:relative;}
  .dots{position:absolute;inset:0;pointer-events:none;opacity:.5;
        background-image:radial-gradient(var(--coral-line) 1.6px,transparent 1.6px);background-size:24px 24px;}
  .price-card{background:#fff;border:1px solid var(--coral-line);border-radius:32px;padding:clamp(32px,4.4vw,64px);
              box-shadow:0 40px 80px -60px rgba(23,21,19,.4);position:relative;z-index:1;
              display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,4vw,60px);align-items:center;}
  .big-n{display:flex;align-items:baseline;gap:6px;}
  .big-n b{font-family:var(--display);font-weight:800;font-size:clamp(96px,13vw,160px);line-height:.82;letter-spacing:-0.06em;color:var(--coral-deep);}
  .big-n i{font-family:var(--mono);font-weight:700;font-size:clamp(34px,5vw,60px);color:var(--coral-deep);font-style:normal;}
  .price-ticks{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:14px;}
  .price-ticks li{display:flex;gap:13px;align-items:flex-start;font-size:16.5px;font-weight:500;line-height:1.4;}
  .price-ticks svg{flex:0 0 auto;color:var(--coral-deep);margin-top:2px;}

  /* Compact competitor comparison, folded into the card rather than given its own column.
     The 7% + 59p rate is a published figure, which is why this claim is safe where an
     unsourced "most platforms" one would not be. */
  .cmp{grid-column:1/-1;border-top:1.5px solid var(--coral-line);margin-top:clamp(8px,1.4vw,18px);padding-top:clamp(24px,2.6vw,32px);}
  .cmp-h{font-family:var(--mono);font-size:11.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-soft);margin:0 0 18px;}
  /* calc and comparison side by side: both describe the SAME £40 booking, so they share a
     heading and cost horizontal space rather than vertical */
  .cmp-split{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(24px,3vw,48px);align-items:start;}
  .calc-row{display:flex;justify-content:space-between;gap:16px;font-size:15.5px;padding:7px 0;color:var(--ink-soft);}
  .calc-row b{font-family:var(--mono);font-weight:400;color:var(--ink);font-size:14.5px;}
  .calc-keep{display:flex;justify-content:space-between;gap:16px;border-top:1.5px solid var(--coral-line);
             margin-top:8px;padding-top:12px;font-weight:700;font-size:16.5px;}
  .calc-keep b{font-family:var(--mono);font-size:16.5px;color:var(--coral-ink);}
  .cmp-row{display:grid;grid-template-columns:minmax(0,1fr) 96px;gap:16px;align-items:center;margin-bottom:12px;}
  .cmp-row .lbl{font-size:15.5px;font-weight:500;}
  .cmp-bar{height:12px;border-radius:99px;background:var(--coral-wash);overflow:hidden;}
  .cmp-bar i{display:block;height:100%;border-radius:99px;background:var(--coral-deep);}
  .cmp-row.them .cmp-bar i{background:#cbc3ba;}
  .cmp-val{font-family:var(--mono);font-weight:700;font-size:15px;text-align:right;}
  .cmp-note{font-size:13px;color:var(--ink-soft);margin:14px 0 0;line-height:1.55;max-width:64ch;}

  /* ---------- 8 faq (dark) ---------- */
  .faq{border-top:1px solid rgba(255,255,255,.12);}
  .qa{border-bottom:1px solid rgba(255,255,255,.12);}
  .qa summary{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;list-style:none;cursor:pointer;
              padding:26px 0;font-family:var(--display);font-weight:700;font-size:clamp(19px,2.1vw,24px);letter-spacing:-0.02em;}
  .qa summary::-webkit-details-marker{display:none;}
  .qa summary:hover{color:var(--coral-line);}
  .qa summary:focus-visible{outline:3px solid #fff;outline-offset:-3px;border-radius:8px;}
  .qa-pm{flex:0 0 auto;width:34px;height:34px;border-radius:50%;background:rgba(255,255,255,.12);display:grid;place-items:center;margin-top:3px;transition:background .2s var(--ease);}
  .qa summary:hover .qa-pm{background:var(--coral-deep);}
  .qa[open] .qa-pm .v{display:none;}
  .qa .qa-pm .h{display:none;}
  .qa[open] .qa-pm .h{display:block;}
  /* the container is now 1152 wide, so the answer needs its own cap or it runs to ~110
     characters. This is the local fix that replaces the old 960px wrap-mid tier. */
  .qa p{margin:0;padding:0 60px 26px 0;color:var(--dark-soft);font-size:17px;line-height:1.65;max-width:var(--measure);}
  /* the support answer runs to two paragraphs; without this each one carries the 26px
     bottom padding and the gap between them doubles. */
  .qa p:not(:last-child){padding-bottom:0;}
  .qa p+p{margin-top:15px;}

  /* ---------- 9 closing cta ----------
     A contained coral BAND, not a full-bleed coral section. Section 5 is already a full
     stretch of --coral-deep, so a second one would read as a repeat; a rounded object on
     bone reads as an arrival instead, and gives the dark FAQ above it something to end
     against. Kept deliberately compact: 2x2 field grid, labels inside nothing, no
     textarea (see the markup note), so the form is four inputs in two rows. */
  .close{padding-top:clamp(56px,7vw,96px);padding-bottom:clamp(56px,7vw,96px);}
  .band{position:relative;background:var(--coral-deep);color:#fff;border-radius:28px;overflow:hidden;
        padding:clamp(34px,4vw,54px) clamp(24px,3.5vw,52px);text-align:center;}
  .band-arch{position:absolute;left:50%;bottom:-40%;width:120%;aspect-ratio:2/1;transform:translateX(-50%);
             background:radial-gradient(100% 100% at 50% 100%,rgba(255,255,255,.12) 0 70%,transparent 71%);pointer-events:none;}
  .band-in{position:relative;z-index:1;}
  .band h2{color:#fff;font-size:clamp(32px,4.6vw,56px);margin:0;line-height:1.02;}
  .band-lede{font-size:clamp(16px,1.6vw,18.5px);color:#fff;margin:14px auto 26px;max-width:46ch;font-weight:500;}

  /* widened from 620 when the band went to the full 1152: at 620 there were 266px of empty
     coral either side of the form, which made the band read as padding rather than as a card. */
  .demo-form{max-width:740px;margin:0 auto;text-align:left;}
  /* 2x2 rather than the live site's four stacked fields. Same four questions, half the height. */
  .df-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px 14px;}
  .df-field{display:flex;flex-direction:column;min-width:0;}
  .df-field label{font-family:var(--display);font-weight:700;font-size:14px;color:#fff;margin-bottom:5px;}
  /* NO opacity here. opacity:.85 composited white to rgb(248,226,222) over the coral
     band, which is 3.85:1 against it and fails AA for 13px/400 text. The label is
     already distinguished from its bold heading by weight and typeface, so it does not
     need dimming as well. Solid white is 4.78:1.
     This is the exact mistake this file's own notes warn about for the Replit design:
     never set text down with opacity on a coloured surface. */
  .df-opt{font-family:var(--body);font-weight:400;}
  .demo-form input{font-family:var(--body);font-size:16px;color:var(--ink);background:#fff;border:1.5px solid #fff;
                   border-radius:11px;padding:12px 13px;width:100%;box-sizing:border-box;min-height:46px;
                   transition:box-shadow .15s var(--ease),border-color .15s var(--ease);}
  .demo-form ::placeholder{color:#6b645d;opacity:1;}
  /* :user-invalid, NOT :invalid — :invalid flags every required field on page load. */
  .demo-form input:user-invalid{border-color:var(--sun);border-width:2.5px;box-shadow:0 0 0 3px rgba(255,207,58,.45);}
  /* the blue focus ring is 1.23:1 on coral. White is the only ring that passes 1.4.11 here. */
  .band a:focus-visible,.band .btn:focus-visible,.demo-form input:focus-visible{outline:3px solid #fff;outline-offset:2px;}
  .df-submit{width:100%;margin-top:14px;justify-content:center;}
  .df-fine{font-size:13px;color:#fff;margin:12px auto 0;max-width:52ch;text-align:center;}
  .df-fine a{color:#fff;font-weight:700;}
  .hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}

  /* ---------- 10 footer ---------- */
  .ft{background:var(--ink-warm);color:#fff;padding:clamp(56px,7vw,88px) 0 44px;border-top:1px solid rgba(255,255,255,.1);}
  .ft-grid{display:grid;grid-template-columns:2fr 1fr 1fr;gap:clamp(30px,4vw,56px);}
  .ft .logo-word{color:#fff;}
  .ft-blurb{color:var(--dark-soft);max-width:38ch;margin:20px 0 0;font-size:17px;}
  .ft h3{font-family:var(--mono);font-weight:700;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:#a8a29b;margin:0 0 20px;}
  .ft ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:13px;}
  .ft ul a{color:var(--dark-soft);text-decoration:none;font-size:16px;}
  .ft ul a:hover{color:#fff;}
  .ft-base{margin-top:clamp(40px,5vw,68px);padding-top:26px;border-top:1px solid rgba(255,255,255,.1);
           display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;color:var(--dark-soft);font-size:14px;}
  .ft-base a{color:var(--dark-soft);}
  .ft-base a:hover{color:#fff;}
  /* the email addresses are the longest items in a 1fr column and would otherwise decide
     how wide the whole grid track is. */
  .ft ul a{overflow-wrap:anywhere;}
  .ft a:focus-visible{outline:3px solid #fff;outline-offset:3px;border-radius:5px;}


  @media(max-width:980px){
    /* the overlapping order panel needs room; below this it sits under the card instead */
    .stage-card{width:100%;}
    /* margin-top was -52px, tucking the panel over the card the way it does on desktop.
       Two problems on a phone. (1) Both boxes are position:static, and CSS paints ALL
       block backgrounds before ANY inline text - so the panel's white background covered
       the card, but the card's session-row TEXT still painted on top of the panel, which
       read as the two overlapping. (2) Even painted correctly it would hide 52px of a
       real screenshot, which is a whole session row. So on mobile the panel simply sits
       below the card. position:relative + z-index also make the stacking explicit, so
       this cannot resurface if the margin ever comes back. */
    .order{position:relative;inset:auto;z-index:1;width:100%;max-width:none;margin-top:14px;
           margin-left:auto;margin-right:auto;}
    .swash,.sparks{display:none;}
    .pw{position:static;width:fit-content;margin:18px auto 0;}
    /* .hdr-nav carries margin:0 auto, and on desktop that auto margin is the only thing
       pushing .hdr-right over to the edge. Hiding the nav on mobile removed it, so logo,
       CTA and burger packed to the left and all the slack fell on the right - a 40px gap
       at 390 and ~77px on a 430-wide phone. Put the push back explicitly. */
    .hdr-nav{display:none;}
    .hdr-right{margin-left:auto;}
    .burger{display:flex;}
    .login{display:none;}                 /* moves into the open menu instead */
    .hdr-nav.open{display:flex;position:absolute;top:80px;left:0;right:0;flex-direction:column;align-items:stretch;
                  gap:4px;background:#fff;border-bottom:1px solid var(--line);padding:14px 24px 20px;
                  box-shadow:0 24px 40px -30px rgba(23,21,19,.4);}
    .hdr-nav.open a{padding:13px 4px;font-size:17px;}
    .hdr-nav.open .login-m{display:block;border-top:1px solid var(--line);margin-top:8px;padding-top:16px;color:var(--ink-soft);}
    .hero-grid,.red-grid,.price-card,.ft-grid,.cmp-split,.df-grid{grid-template-columns:minmax(0,1fr);}
    .cols{grid-template-columns:1fr 1fr;gap:36px 28px;}
    .steps{grid-template-columns:1fr 1fr;gap:38px 26px;}
    .step:not(:last-child)::before{display:none;}
    .red-photo{aspect-ratio:4/3;}
  }

  /* 1.4.10 Reflow. At 320px the header ran to 350px and scrolled the whole document
     sideways: logo (114) + gap + CTA + burger (195) + 48px of padding does not fit.
     The live site failed this exact check, so it is worth catching here.
     The CTA stays: the bar is sticky, so it is the only always-visible way to convert.
     Breakpoint measured, not guessed: the full-size bar needs 366px, so it holds at 375
     and 390 and only shrinks on the genuinely narrow phones below that. */
  @media (max-width:365px){
    /* .wrap comes too, or the header sits 8px left of every other section and the page
       loses the single content edge it was just given. */
    .wrap,.hdr-in{padding-left:16px;padding-right:16px;}
    .hdr-in{gap:10px;}
    .logo img{width:26px;}
    .logo-word{font-size:22px;}
    .hdr-right{gap:10px;}
    .btn-sm{padding:9px 13px;font-size:14px;}
    .burger{width:42px;height:42px;}
  }
  @media(max-width:600px){
    .cols{grid-template-columns:1fr;}
    .steps{grid-template-columns:1fr;}
    .bar-row{gap:14px 26px;}
    .qa p{padding-right:0;}
  }


  /* ---------- externalised inline style="" attributes ----------
     style-src 'self' drops every inline style attribute in production, so these
     cannot live on the element. .w-hatch/.w-them are the load-bearing pair: as
     inline widths they were silently stripped and both comparison bars collapsed
     to zero. site.css carries an identical section for the same reason. */
  .bar-head{text-align:center;max-width:700px;margin:0 auto;}
  .above-dots{position:relative;z-index:1;}
  .sect-head{text-align:center;margin-bottom:clamp(34px,4vw,56px);}
  .kick-ink{color:var(--coral-ink);}
  .sect-lede{margin:18px auto 0;max-width:46ch;}
  .price-of{font-size:19px;font-weight:600;margin:18px 0 0;}
  .price-fine{color:var(--ink-soft);margin:6px 0 0;}
  .cmp-bar i.w-hatch{width:39%;}
  .cmp-bar i.w-them{width:99%;}
  .df-alt{margin-top:16px;font-family:var(--mono);font-size:12.5px;}


  /* ---------- cookie banner ----------
     Copied from site.css. index.html deliberately does NOT load site.css: that sheet
     defines .band/.btn/.hero/.wrap/.dark for the other pages and those names collide
     with the v4 definitions above. The other four pages keep site.css untouched. */
  #cookie-banner{position:fixed;left:16px;right:16px;bottom:16px;z-index:9999;max-width:560px;margin:0 auto;
    background:var(--ink);color:#fff;border-radius:14px;padding:16px 18px;
    box-shadow:0 12px 44px rgba(0,0,0,.28);font-family:'Hanken Grotesk',system-ui,sans-serif;font-size:14px;line-height:1.55;}
  #cookie-banner p{margin:0 0 12px;}
  #cookie-banner a{color:#fff;text-underline-offset:2px;}
  #cookie-banner .cb-row{display:flex;gap:10px;flex-wrap:wrap;}
  #cookie-banner button{font:inherit;font-weight:700;border:0;border-radius:10px;padding:10px 20px;cursor:pointer;}
  #cookie-accept{background:var(--coral-deep);color:#fff;}
  #cookie-decline{background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.4);}

  /* Respect a reduced-motion preference. The four transitions here are short hover and
     focus micro-interactions, so this is 2.3.3 Animation from Interactions, which is AAA
     rather than AA. Cheap to honour, so honoured. site.js already switches its FAQ
     deep-link scrolling from smooth to auto under the same query. */
  @media (prefers-reduced-motion: reduce){
    *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important;
                         animation-iteration-count:1 !important;scroll-behavior:auto !important;}
  }

  /* ============================================================================
     FEATURES PAGE
     Layout adapted from a Replit concept: a sticky category filter, numbered
     section headers and a three-column card grid. Shares this stylesheet with the
     homepage so the header, footer, buttons and tokens are literally the same
     rules rather than a copy that drifts.
     The concept's content was NOT used: about a third of its 81 claims described
     features that do not exist. Every card below comes from the audited list.
     ============================================================================ */

  /* --- hero --- */
  .fp-hero{background:var(--coral-wash);position:relative;overflow:hidden;
           padding:clamp(44px,6vw,84px) 0 clamp(40px,5vw,72px);}
  .fp-hero h1{font-size:clamp(38px,6.4vw,74px);line-height:.96;margin:14px 0 0;max-width:16ch;}
  .fp-hero .lede{margin:20px 0 28px;max-width:56ch;}
  .fp-hero .row{display:flex;gap:14px;flex-wrap:wrap;}

  /* --- sticky category filter ---
     top:81px, NOT 80: .hdr-in is 80px tall and .hdr adds a 1px bottom border, so the
     header occupies 81px. At 80 the filter rode up over that border on scroll. Both
     bars are sticky, so the offset has to match the header exactly. --- */
  .fp-filter{position:sticky;top:81px;z-index:50;background:#fff;
             border-bottom:1px solid var(--coral-wash);}
  /* WRAPS on desktop, SCROLLS on narrow. At 1440 the eleven chips needed 1298px in a
     1152px track, so two were clipped with nothing to show the bar scrolled sideways.
     flex-wrap only breaks when it has to, so wide screens still get one line and the
     second line appears where it is genuinely needed. Below 980 it goes back to a
     scroller: wrapping there would be four lines of sticky furniture. */
  .fp-filter-in{display:flex;flex-wrap:wrap;gap:8px;padding:12px 24px;
                max-width:1200px;margin:0 auto;scrollbar-width:none;}
  .fp-filter-in::-webkit-scrollbar{display:none;}
  .fp-chip{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;border:0;cursor:pointer;
           background:var(--coral-wash);color:var(--ink);font-family:var(--body);
           font-size:14.5px;font-weight:600;padding:9px 13px;border-radius:999px;
           min-height:38px;transition:background .15s var(--ease),color .15s var(--ease);}
  .fp-chip:hover{background:var(--coral-line);}
  .fp-chip[aria-pressed="true"]{background:var(--coral-deep);color:#fff;}
  .fp-chip:focus-visible{outline:3px solid var(--blue);outline-offset:2px;}
  .fp-chip svg{flex:0 0 auto;}

  /* --- category sections --- */
  .fcat{padding:clamp(56px,7vw,104px) 0;}
  .fcat.alt{background:var(--bone);}
  .fcat[hidden]{display:none;}
  .fcat-head{margin-bottom:clamp(30px,4vw,52px);}
  .fcat-meta{display:flex;align-items:center;gap:12px;margin-bottom:16px;}
  .fcat-num{font-family:var(--mono);font-size:12.5px;letter-spacing:.14em;color:var(--ink-soft);}
  .fcat-rule{width:1px;height:15px;background:var(--line);}
  .fcat-kicker{font-family:var(--mono);font-size:12.5px;letter-spacing:.14em;
               text-transform:uppercase;color:var(--coral-ink);}
  .fcat h2{font-size:clamp(28px,4vw,52px);line-height:.98;max-width:22ch;}
  .fcat-lede{color:var(--ink-soft);font-size:clamp(16px,1.7vw,19px);margin:16px 0 0;max-width:58ch;}

  /* --- feature cards --- */
  .fgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;}
  .fitem{display:flex;gap:12px;align-items:flex-start;background:#fff;
         border:1px solid var(--coral-wash);border-radius:16px;padding:20px 20px 22px;
         transition:border-color .15s var(--ease),box-shadow .15s var(--ease);}
  .fcat.alt .fitem{border-color:var(--line);}
  .fitem:hover{border-color:var(--coral-line);box-shadow:0 8px 24px -10px rgba(210,59,38,.16);}
  .fitem svg{flex:0 0 auto;color:var(--coral-deep);margin-top:2px;}
  .fitem h3{font-size:16.5px;line-height:1.22;margin:0 0 6px;letter-spacing:-0.02em;}
  .fitem p{margin:0;font-size:14.5px;line-height:1.55;color:var(--ink-soft);}

  /* --- empty state for the filter --- */
  .fp-none{padding:clamp(56px,7vw,96px) 0;text-align:center;color:var(--ink-soft);}

  @media(max-width:980px){
    .fgrid{grid-template-columns:repeat(2,minmax(0,1fr));}
    .fp-filter{top:81px;}
    /* back to a single scrolling row: eleven wrapped chips would be four lines */
    .fp-filter-in{flex-wrap:nowrap;overflow-x:auto;}
  }
  @media(max-width:640px){
    .fgrid{grid-template-columns:minmax(0,1fr);}
  }

  /* .hl was scoped to .hero h1 and .bar h2 only, so the features headline lost its
     accent. Scope it to the features hero too rather than making it global, which
     would leak the colour into any heading that happens to use the class. */
  .fp-hero h1 .hl{color:var(--coral-deep);}
  /* outline button ON a coral surface: the standard .btn-out border is --line, which
     is invisible against coral. White at 40% is 2.4:1 against --coral-deep, so this
     uses a solid white border to clear 1.4.11's 3:1 for a control boundary. */
  .btn-out-w{background:transparent;color:#fff;border:1.6px solid #fff;}
  .btn-out-w:hover{background:rgba(255,255,255,.14);}

  /* --- thanks page ---------------------------------------------------------
     The post-submit destination. Ported onto v4 so the header and nav match the
     rest of the site (3.2.3 Consistent Navigation is an AA criterion), which also
     retires css/site.css: this was its last consumer. --- */
  .thanks{padding:clamp(52px,7vw,96px) 0;}
  .thanks .band{text-align:center;}
  .thanks-next{max-width:56ch;margin:clamp(30px,4vw,48px) auto 0;text-align:center;}
  .thanks-next h2{font-size:clamp(22px,2.6vw,30px);margin:0 0 12px;}
  .thanks-next p{color:var(--ink-soft);margin:0 0 12px;}
  .thanks-next a{color:var(--coral-ink);font-weight:600;}
  .thanks-back{font-family:var(--mono);font-size:13.5px;margin-top:20px;}
  /* the quiet contact pill inside the coral band */
  .band-note{display:flex;width:fit-content;max-width:100%;align-items:center;justify-content:center;
             gap:9px;font-family:var(--mono);font-size:13px;color:#fff;margin:24px auto 0;
             background:rgba(0,0,0,.22);border:1px solid rgba(255,255,255,.26);
             padding:9px 18px;border-radius:999px;text-wrap:balance;overflow-wrap:anywhere;}
  .band-note>span{min-width:0;}
  .band-note a{color:#fff;font-weight:700;}
  .band-dot{width:7px;height:7px;border-radius:50%;background:#fff;
            box-shadow:0 0 0 4px rgba(255,255,255,.24);flex:0 0 auto;}

  /* Visually hidden but available to assistive tech. Not display:none, which would
     remove it from the accessibility tree and defeat the point. */
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
           clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;}
