:root{
    --asphalt-900:#121c33;
    --asphalt-800:#212c47;
    --asphalt-700:#33405c;
    --asphalt-600:#4a5670;
    --asphalt-500:#747f99;
    --asphalt-400:#b8c1d6;
    --asphalt-300:#d5dceb;
    --asphalt-200:#f5f8ff;
    --white:#ffffff;
    --yellow:#ffb511;
    --blue:#00aacc;
    --purple:#b26eff;
    --red:#f46677;
    --font-body:'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-mono:'DM Mono','Courier New', monospace;
  }
  *{ box-sizing:border-box; }
  .site-content{
    /* intentionally unstyled — the hero/page renders normally the whole
       time; the loading screen reveals it via a growing circular mask
       cut into itself, not by scaling this content */
  }
  .loading-screen{
    position:fixed;
    inset:0;
    z-index:100000;
    background:var(--asphalt-900);
    display:flex;
    align-items:center;
    justify-content:center;
    /* no mask here: a degenerate `circle 0px` gradient resolves to fully
       transparent in WebKit, which hid the loading screen in Safari */
    opacity:1;
    will-change:opacity, transform;
  }
  .loading-screen.is-hidden{
    opacity:0;
    pointer-events:none;
  }
  .loading-pill{
    border:1px solid #ffffff;
    border-radius:10px;
    padding:12px 24px;
    background:linear-gradient(90deg, rgba(255,255,255,0.25) 0%, rgba(255,255,255,0.25) 100%), linear-gradient(90deg, rgb(45,54,72) 0%, rgb(45,54,72) 100%);
    transition:opacity 0.5s ease;
  }
  .loading-pill p{
    font-family:var(--font-mono);
    font-weight:500;
    font-size:18px;
    color:#ffffff;
    white-space:nowrap;
    margin:0;
  }
  .loading-logo{
    position:absolute;
    opacity:0;
    transition:opacity 0.6s ease;
  }
  .loading-logo img{
    height:52px;
    width:auto;
  }

  html{ scroll-behavior:auto; scroll-padding-top:117px; }
  html,body{ margin:0; padding:0; background:var(--asphalt-900); }
  body{
    font-family:var(--font-body);
    color:var(--asphalt-900);
    line-height:1.4;
    overflow-x:hidden;
  }
  .skip-link{
    position:fixed;
    top:12px;
    left:12px;
    z-index:100001;
    padding:10px 14px;
    border-radius:8px;
    background:var(--yellow);
    color:var(--asphalt-900);
    font-weight:700;
    transform:translateY(-160%);
  }
  .skip-link:focus{ transform:none; }
  img{ max-width:100%; display:block; }
  a{ color:inherit; text-decoration:none; }
  button{ font-family:inherit; cursor:pointer; }
  a:focus-visible,
  button:focus-visible,
  [role="button"]:focus-visible,
  input:focus-visible,
  textarea:focus-visible{
    outline:3px solid var(--yellow);
    outline-offset:4px;
  }
  .accent{ color:var(--yellow); }
  /* Every section shares ONE measure and gutter, and the nav shares it too,
     so the logo's left edge and the nav box's right edge are the alignment
     line for the whole page at any width. */
  :root{ --measure:1680px; --gutter:120px; }
  .wrap{ max-width:var(--measure); margin:0 auto; padding:0 var(--gutter); }
  /* the page edge in absolute terms — what an absolutely positioned block
     needs in order to sit on the same line as the nav's content */
  :root{ --edge:max(var(--gutter), calc((100vw - var(--measure)) / 2 + var(--gutter))); }

  /* ============================================================
     NAV — node 49:2986
     ============================================================ */
  header.nav{
    padding:24px var(--gutter);
    position:fixed;
    top:0;
    left:0;
    right:0;
    z-index:200;
  }
  .top-fade{
    position:fixed;
    top:0;
    left:0;
    right:0;
    height:320px;
    z-index:150;
    pointer-events:none;
    background:linear-gradient(to bottom,
      rgba(18,28,51,0.92) 0%,
      rgba(18,28,51,0.86) 14%,
      rgba(18,28,51,0.72) 28%,
      rgba(18,28,51,0.55) 42%,
      rgba(18,28,51,0.38) 56%,
      rgba(18,28,51,0.23) 68%,
      rgba(18,28,51,0.12) 79%,
      rgba(18,28,51,0.05) 89%,
      rgba(18,28,51,0.01) 96%,
      transparent 100%);
  }
  .nav-inner{
    max-width:calc(var(--measure) - var(--gutter) * 2);
    margin:0 auto;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:24px;
    flex-wrap:wrap;
  }
  .logo-lockup{ display:flex; align-items:center; }
  .logo-lockup img{ height:34px; width:auto; }
  .nav-group{
    display:flex;
    align-items:center;
    gap:32px;
    flex-wrap:wrap;
    background:rgba(255,255,255,0.08);
    border-radius:10px;
    padding:15px 30px;
  }
  .nav-links{ display:contents; }
  .nav-links a{ color:var(--white); font-size:16px; white-space:nowrap; transition:color 0.15s ease; }
  .nav-links a:hover{ color:var(--yellow); }
  .btn{
    display:inline-flex; align-items:center; justify-content:center;
    background:var(--yellow); color:var(--asphalt-900); font-weight:600;
    font-size:16px; padding:10px 24px; border-radius:10px; border:none;
    cursor:pointer;
    transition:background 0.15s ease;
  }
  .btn:hover{ background:var(--yellow); filter:brightness(0.92); }
  .btn:active{ background:var(--yellow); filter:brightness(0.84); transform:translateY(1px); }

  /* ============================================================
     HERO — node 49:3090 — pinned scrollytelling section
     ============================================================ */
  .hero-scroll{
    position:relative;
    background:var(--asphalt-900);
  }
  /* the content that scrolls over the sticky background */
  .hero-flow{ position:relative; z-index:2; }
  .hero-panel{ position:relative; height:100vh; height:100dvh; }
  /* the water + school fill the WHOLE hero block and scroll with it, so the
     page travels along the pond from the copy down to the carousel */
  .hero-pin{
    position:absolute;
    inset:0;
    z-index:0;
    /* both axes clip: with overflow-y hidden, an overflow-x of visible
       computes to auto and produces a sideways scrollbar, so the flanking
       carousel cards are simply cut at the viewport edge instead */
    overflow:hidden;
    display:flex;
    align-items:center;
    justify-content:center;
    background:var(--asphalt-900);
  }
  #hero-bg-canvas{
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    z-index:0;
    /* the caustics used to stop dead at the section's edge; they now
       dissolve into the navy so there is no visible line */
    -webkit-mask-image:linear-gradient(to bottom, #000 0, #000 88%, transparent 100%);
    mask-image:linear-gradient(to bottom, #000 0, #000 88%, transparent 100%);
  }
  /* the school swims between the water sim and the vignette */
  #hero-fish-top{
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    z-index:1;
    pointer-events:none;
    -webkit-mask-image:linear-gradient(to bottom, #000 0, #000 86%, transparent 99%);
    mask-image:linear-gradient(to bottom, #000 0, #000 86%, transparent 99%);
  }
  .hero-bg-vignette{
    position:absolute;
    inset:0;
    z-index:2;
    pointer-events:none;
    background:linear-gradient(to bottom,
      var(--asphalt-900) 0%,
      transparent 12%,
      transparent 78%,
      var(--asphalt-900) 100%);
  }
  .hero-content{
    position:relative;
    z-index:2;
    width:100%;
    height:100%;
    box-sizing:border-box;
    color:var(--white);
    text-align:left;
  }
  /* All the hero copy is one block now — heading, lede and CTA
     together in a single frame rather than revealed in stages. JS
     only fades the whole block in once, then out as the benefits
     deck rises. */
  /* centred in the area BELOW the fixed nav, not in the whole pin —
     the block is tall enough now that dead-centring pushed the first
     headline line up behind the nav pill */
  .hero-copy{
    position:absolute;
    left:var(--edge);
    right:122px;
    top:0;
    bottom:0;
    max-width:1180px;
    box-sizing:border-box;
    padding-top:clamp(94px, 14vh, 150px);
    padding-bottom:clamp(16px, 3vh, 40px);
    display:flex;
    flex-direction:column;
    justify-content:center;
    align-items:flex-start;
    gap:clamp(18px, 4.1vh, 44px);
    will-change:opacity, transform;
  }
  .hero-copy h1{
    margin:0;
    font-size:clamp(32px, 4.9vw, 90px);
    font-weight:600;
    line-height:1.14;
    letter-spacing:-0.02em;
  }
  /* Each line is two stacked copies of the same text: a soft, quarter-opacity
     base and a sharp copy on top revealed by a feathered gradient mask that
     travels left to right. That makes the focus a genuinely linear wipe rather
     than a sequence of per-word steps. */
  .hero-copy h1 .hl{ display:block; position:relative; }
  .hero-copy h1 .ln{ display:block; }
  .hero-copy h1 .soft{ opacity:0.25; filter:blur(2.5px); }
  .hero-copy h1 .sharp{
    position:absolute;
    top:0; left:0; right:0;
    pointer-events:none;
    /* a mask crops to its own box, so the box is padded out (with matching
       negative margins, which keeps the text exactly where it was) — without
       this, descenders and the final full stop get clipped */
    padding:0.22em 0.32em;
    margin:-0.22em -0.32em;
    /* clip-path rather than an animated mask: WebKit does not animate
       mask-position, which left the sharp copy permanently hidden in Safari
       and the whole headline stuck blurred. */
    -webkit-clip-path:inset(0 100% 0 0);
    clip-path:inset(0 100% 0 0);
  }
  .hero-ready .hero-copy h1 .sharp{
    -webkit-animation:heroWipe 1.05s cubic-bezier(.4,0,.25,1) forwards;
    animation:heroWipe 1.05s cubic-bezier(.4,0,.25,1) forwards;
  }
  @-webkit-keyframes heroWipe{
    from{ -webkit-clip-path:inset(0 100% 0 0); }
    to{ -webkit-clip-path:inset(0 0 0 0); }
  }
  @keyframes heroWipe{
    from{ -webkit-clip-path:inset(0 100% 0 0); clip-path:inset(0 100% 0 0); }
    to{ -webkit-clip-path:inset(0 0 0 0); clip-path:inset(0 0 0 0); }
  }
  /* "Goldfish Agent" is on the page from the start as an outline, and fills
     to solid yellow before the rest of the line wipes in. */
  .hero-lede{ opacity:0; transition:opacity 0.9s ease 1.75s; }
  .hero-ready .hero-lede{ opacity:1; }
  /* Reveal the hero action with the body copy it follows. */
  .hero-cta{
    align-self:flex-start;
    margin-top:clamp(6px, 2.4vh, 26px);
    padding:14px 30px;
    font-size:17px;
    text-decoration:none;
    opacity:0;
    transition:opacity 0.9s ease 1.95s;
  }
  .hero-ready .hero-cta{ opacity:1; }
  /* Every line is authored explicitly and set to nowrap, so the breaks are
     identical in every browser — Safari sets Poppins a shade wider than
     Chrome, which was re-wrapping lines that only just fitted. */
  .hero-lede .lp{ display:block; }
  .hero-lede .lp + .lp{ margin-top:0.8em; }
  .hero-lede .ln{ display:block; white-space:nowrap; }
  @media (max-width:900px){
    /* narrow screens need to wrap rather than overflow */
    .hero-lede .ln,
    .hq-headline{ white-space:normal; }
  }
  .hero-lede{
    margin:0;
    /* 720px as designed, but never into the gutter the digest notification
       occupies on the right — below ~1280px it would sit over the text */
    max-width:min(880px, calc(100vw - 560px));
    font-size:clamp(17px, 1.35vw, 22px);
    font-weight:400;
    line-height:1.38;
    color:var(--asphalt-200);
    text-wrap:pretty;
  }
  .scroll-cue{
    position:absolute;
    bottom:32px;
    left:50%;
    transform:translateX(-50%);
    color:var(--asphalt-400);
    font-size:13px;
    letter-spacing:0.08em;
    text-transform:uppercase;
    opacity:0;
    transition:opacity .6s ease;
    z-index:2;
  }
  .scroll-cue.show{ opacity:1; }
  @media (max-width:1200px){
    /* clear of both the taller copy block and the digest card above it */
    .scroll-cue{ bottom:18px; }
  }
  .scroll-cue::after{
    content:"";
    display:block;
    width:1px; height:28px;
    background:var(--asphalt-400);
    margin:8px auto 0;
    animation:cue-move 1.6s ease-in-out infinite;
  }
  @keyframes cue-move{
    0%,100%{ transform:scaleY(0.4); opacity:.4; }
    50%{ transform:scaleY(1); opacity:1; }
  }

  /* ============================================================
     SECTION 1 — Goldfish Benefits carousel — node 49:3221/3224
     Lives inside .hero-pin as a transparent overlay: the WebGL
     background keeps running underneath/around it exactly as it
     was during the hero, and this rises up from below to sit on
     top of it (a parallax hand-off rather than a hard cut between
     two separately-backed sections).
     ============================================================ */
  /* A scroll buffer: the panel is taller than the screen and the cards hold
     centred inside it, so the carousel comes to rest for a stretch of scroll
     instead of sliding straight past. The pond still scrolls behind it. */
  .benefits-overlay{
    position:relative;
    height:170vh;
    background:transparent;
    /* clip, not hidden — hidden would make this a scroll container and kill
       the sticky hold inside it (and the pond's own layer) */
    overflow-x:clip;
  }
  .benefits-inner{
    position:sticky;
    top:0;
    height:100vh;
    height:100dvh;
    box-sizing:border-box;
    padding-top:clamp(118px, 17vh, 168px);
    padding-bottom:clamp(28px, 6vh, 84px);
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:clamp(14px, 3.6vh, 35px);
    width:100%;
  }
  .benefits-inner h2{
    font-size:clamp(30px, 3.1vw, 46px);
    font-weight:600;
    margin:0;
    text-align:center;
    color:var(--white);
    padding:0 40px;
  }
  /* Card deck: the 3 cards sit stacked on top of each other; clicking the
     front card sends it to the back. No horizontal track, no scroll capture,
     so the page keeps scrolling normally over this area. */
  /* landscape deck (option 10b): the cards are wide and short — fish on the
     left, copy beside it — so the water background reads above and below.
     The stacking/click behaviour is unchanged. */
  /* the neighbouring cards sit out to the left and right of the front one,
     so overflow has to stay visible here */
  .benefits-deck{
    position:relative;
    width:min(660px, 58vw);
    height:clamp(178px, 34vh, 300px);
    overflow:visible;
  }
  /* arrows sit under the deck with the dots between them, so cycling is a
     button press rather than a guess at where to click */
  .carousel-nav{
    display:flex;
    align-items:center;
    justify-content:center;
    gap:26px;
    margin-top:clamp(10px, 3vh, 30px);
  }
  .carousel-arrow{
    flex:none;
    width:50px;
    height:50px;
    padding:0;
    border:none;
    background:none;
    border-radius:50%;
    cursor:pointer;
    display:flex;
    align-items:center;
    justify-content:center;
    transition:opacity 0.15s ease, transform 0.15s ease;
  }
  .carousel-arrow svg{ width:50px; height:50px; display:block; }
  .carousel-arrow.is-prev svg{ transform:scaleX(-1); }
  .carousel-arrow:hover{ opacity:0.78; }
  .carousel-arrow:active{ transform:translateY(1px); }
  .carousel-nav .carousel-dots{ margin-top:0; }
  .carousel-dots{
    display:flex;
    justify-content:center;
    gap:16px;
    /* the deck's rearmost card sits ~48px below the front one, so the dots
       are pushed clear of that tail rather than sitting on top of it */
    margin-top:34px;
  }
  .carousel-dot{
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius:50%;
    background:rgba(255,255,255,0.2);
    transition:background 0.35s ease, transform 0.35s ease;
  }
  .carousel-dot.active{
    background:var(--yellow);
    transform:scale(1.15);
  }
  .benefit-card{
    position:absolute;
    inset:0;
    box-sizing:border-box;
    border:1px solid rgba(255,181,17,0.5);
    border-radius:15px;
    background:linear-gradient(180deg, rgba(255,181,17,0) 17%, rgba(255,181,17,0.25) 178%), #121C33;
    box-shadow:8px 8px 32px rgba(18,37,60,0.35);
    cursor:pointer;
    will-change:transform;
    transition:transform 0.55s cubic-bezier(.22,.61,.36,1), opacity 0.55s ease;
    display:flex;
    align-items:center;
    gap:clamp(28px, 3.4vw, 48px);
    padding:clamp(28px, 4vh, 44px) clamp(32px, 3.8vw, 56px);
    -webkit-user-select:none;
    user-select:none;
  }
  .benefit-card{ transition:transform 0.52s cubic-bezier(.22,.61,.36,1), opacity 0.52s ease, filter 0.52s ease; }
  .benefit-card.aside{ filter:blur(1.6px); }
  .benefit-card.aside:hover{ filter:blur(0.7px); }
  .benefit-card.aside::after{
    content:'';
    position:absolute;
    inset:0;
    border-radius:15px;
    background:rgba(0,170,204,0.22);
    pointer-events:none;
  }
  .benefit-card img{ flex:none; width:auto; height:clamp(120px, 21vh, 190px); pointer-events:none; }
  .benefit-card .benefit-copy{ min-width:0; display:flex; flex-direction:column; gap:14px; }
  .benefit-card h3{ font-size:clamp(26px, 2.4vw, 35px); font-weight:600; line-height:1.1; color:var(--white); margin:0; text-align:left; }
  .benefit-card p{ font-size:17px; line-height:1.55; color:var(--asphalt-200); margin:0; text-align:left; text-wrap:pretty; }
  /* ============================================================
     SECTION 2 — Goldfish HQ. A single, bounded service advert rather
     than another run of Goldfish Agent editorial content.
     ============================================================ */
  .hq-section{
    position:relative;
    background:#0d162a;
    padding:160px var(--gutter) 180px;
    overflow:hidden;
  }
  .hq-glow{
    position:absolute;
    inset:0;
    background:
      radial-gradient(60% 75% at 8% 10%, rgba(0,170,204,0.14), transparent 66%),
      radial-gradient(55% 70% at 96% 82%, rgba(178,110,255,0.11), transparent 68%);
    pointer-events:none;
  }
  .hq-inner{
    position:relative;
    max-width:calc(var(--measure) - var(--gutter) * 2);
    margin:0 auto;
    display:flex;
    flex-direction:column;
    gap:42px;
    overflow:hidden;
    padding:48px 50px 0;
    border:1px solid rgba(0,170,204,0.68);
    border-radius:32px;
    background:
      linear-gradient(145deg, rgba(23,54,80,0.96), rgba(18,28,51,0.98) 58%),
      var(--asphalt-900);
    box-shadow:0 36px 90px rgba(0,0,0,0.34), inset 0 1px rgba(255,255,255,0.06);
  }
  .hq-headline-row{ display:flex; align-items:flex-end; justify-content:space-between; gap:56px; }
  .hq-copy{ max-width:850px; }
  .hq-headline{
    margin:0;
    font-size:clamp(38px, 4.15vw, 68px);
    font-weight:600;
    line-height:1.04;
    letter-spacing:-0.035em;
    color:var(--white);
  }
  .hq-headline .accent{ color:var(--yellow); }
  .hq-copy > p{
    max-width:720px;
    margin:22px 0 0;
    color:var(--asphalt-300);
    font-size:20px;
    line-height:1.5;
    text-wrap:pretty;
  }
  .hq-fish{
    width:clamp(150px, 15vw, 230px);
    height:auto;
    flex:none;
    margin-left:auto;
    filter:drop-shadow(0 20px 30px rgba(0,0,0,0.34));
  }
  .hq-award{
    display:flex;
    width:fit-content;
    align-items:center;
    gap:18px;
    color:var(--white);
  }
  .hq-award-mark{
    display:block;
    width:152px;
    padding:7px 9px;
    border-radius:8px;
    background:var(--white);
    transition:opacity .15s ease;
  }
  .hq-award-mark img{ width:100%; height:auto; }
  .hq-award strong{
    display:block;
    font-size:20px;
    text-decoration:underline;
    text-decoration-color:transparent;
    text-underline-offset:5px;
    transition:text-decoration-color .15s ease;
  }
  .hq-award-copy > span{
    display:block;
    margin-top:5px;
    color:var(--asphalt-200);
    font-family:var(--font-mono);
    font-size:13px;
    letter-spacing:.02em;
  }
  .hq-award:hover .hq-award-mark{ opacity:.84; }
  .hq-award:hover strong{ text-decoration-color:var(--yellow); }
  .hq-grid{
    display:grid;
    grid-template-columns:repeat(2, 1fr);
    gap:0;
    overflow:hidden;
    border:1px solid rgba(0,170,204,0.28);
    border-radius:20px;
    background:rgba(8,18,38,0.34);
  }
  /* The grid reveals as one unit; no card is given priority by arriving first. */
  .hq-card{
    opacity:0;
    transform:translateY(64px) scale(0.97);
    transition:opacity 0.85s ease, transform 0.85s cubic-bezier(.16,.84,.28,1);
  }
  .hq-card.in{
    opacity:1;
    transform:none;
  }
  @media (prefers-reduced-motion:reduce){
    .hq-card{ transition:none; opacity:1; transform:none; }
  }
  .hq-card{
    background:transparent;
    padding:28px 34px 30px;
    display:flex;
    flex-direction:column;
    gap:8px;
  }
  .hq-card:nth-child(odd){ border-right:1px solid rgba(0,170,204,0.22); }
  .hq-card:nth-child(-n+2){ border-bottom:1px solid rgba(0,170,204,0.22); }
  .hq-card .hq-num{
    font-family:var(--font-mono);
    font-size:14px;
    letter-spacing:0.1em;
    color:var(--yellow);
  }
  .hq-card h3{
    margin:0;
    font-size:30px;
    font-weight:600;
    letter-spacing:-0.01em;
    color:var(--white);
  }
  .hq-card p{
    margin:0;
    font-size:18px;
    line-height:1.45;
    color:var(--asphalt-200);
    text-wrap:pretty;
  }
  .hq-action-row{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:28px;
    margin:0 -50px;
    padding:26px 50px 30px;
    border-top:1px solid rgba(0,170,204,0.42);
    background:rgba(0,170,204,0.08);
  }
  .hq-cta{ flex:none; }
  @media (max-width:1100px){
    .hq-section{ padding-top:120px; padding-bottom:140px; }
    .hq-inner{ gap:38px; padding:40px 40px 0; }
    .hq-headline-row{ gap:24px; }
    .hq-fish{ width:clamp(130px, 18vw, 170px); }
    .hq-grid{ grid-template-columns:1fr; }
    .hq-card:nth-child(odd){ border-right:0; }
    .hq-card:nth-child(-n+3){ border-bottom:1px solid rgba(0,170,204,0.22); }
    .hq-card{ padding:22px 36px 24px; }
    .hq-card h3{ font-size:26px; }
    .hq-card p{ font-size:17px; }
    .hq-action-row{ margin-inline:-40px; padding-inline:40px; }
  }
  @media (max-width:760px){
    .hq-section{ padding:90px 20px 110px; }
    .hq-inner{ gap:30px; padding:24px 20px 0; border-radius:24px; }
    .hq-headline-row{ align-items:center; gap:14px; }
    .hq-headline{ font-size:clamp(34px, 10vw, 44px); }
    .hq-copy > p{ margin-top:16px; font-size:16px; }
    .hq-fish{ width:92px; }
    .hq-action-row{ flex-direction:column; align-items:stretch; }
    .hq-award{ align-self:flex-start; }
    .hq-cta{ justify-content:center; width:100%; text-align:center; }
    .hq-action-row{ margin-inline:-20px; padding:24px 20px 26px; }
  }

  /* ============================================================
     SECTION 3 — Timeline — node 49:3289
     ============================================================ */
  .timeline-scroll{
    position:relative;
    z-index:3;              /* above .hero-flow, so the pin can dissolve over it */
    margin-top:-20vh;
    height:430vh;
    background:transparent;
  }
  .timeline-pin{
    position:sticky;
    top:0;
    height:100vh;
    height:100dvh;
    overflow:hidden;
    z-index:10;
    display:flex;
    flex-direction:column;
    align-items:center;
    /* anchored to the top, not centred: the pill needs to sit high without
       a negative margin pushing it into the clipped region above */
    justify-content:flex-start;
    padding-top:clamp(142px, 17.5vh, 212px);
    box-sizing:border-box;
    background:transparent;
  }
  /* bubble-field parallax background, after the reference video: small
     glassy bubbles continuously rising, with bubbles closer to the
     "camera" (bigger) drifting more with scroll than distant ones —
     the same depth-parallax idea as before, just bubbles instead of
     blurred colour orbs. Each bubble is two nested elements: an outer
     wrapper JS moves for scroll-parallax, an inner one that has its own
     independent, endless CSS rise animation — nesting them means the
     two motions layer on top of each other instead of fighting over
     the same transform. */
  .timeline-glow-bg{
    position:absolute;
    inset:0;
    overflow:hidden;
    z-index:0;
    pointer-events:none;
  }
  .timeline-bubble-wrap{
    position:absolute;
    top:0;
    bottom:0;
    will-change:transform;
  }
  .timeline-bubble{
    position:absolute;
    bottom:-60px;
    border-radius:50%;
    background:
      radial-gradient(circle at 30% 24%, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0.95) 9%, rgba(255,255,255,0) 16%),
      radial-gradient(circle at 67% 70%, rgba(255,255,255,0.45) 0%, rgba(255,255,255,0.45) 5%, rgba(255,255,255,0) 10%),
      radial-gradient(circle at 50% 50%, rgba(0,170,204,0.04) 0%, rgba(0,170,204,0.08) 55%, rgba(0,170,204,0.42) 88%, rgba(0,140,168,0.68) 100%);
    box-shadow:
      inset 0 0 2px rgba(255,255,255,0.5),
      inset -2px -2px 4px rgba(0,90,110,0.35);
    animation-name:timelineBubbleRise;
    animation-timing-function:linear;
    animation-iteration-count:infinite;
  }
  @keyframes timelineBubbleRise{
    0%{ transform:translate(0, 0); opacity:0; }
    8%{ opacity:0.65; }
    92%{ opacity:0.65; }
    100%{ transform:translate(var(--bx, 14px), -820px); opacity:0; }
  }
  .timeline-head{
    position:relative;
    z-index:120;
    display:flex;
    justify-content:center;
    flex:none;
    margin-bottom:clamp(40px, 9vh, 110px);
    opacity:0;
    will-change:opacity;
  }
  .timeline-pill{
    border:1px solid var(--purple);
    border-radius:16px;
    padding:12px 24px;
    background:linear-gradient(90deg, rgba(178,110,255,0.25) 0%, rgba(178,110,255,0.25) 100%), linear-gradient(90deg, rgb(45,54,72) 0%, rgb(45,54,72) 100%);
  }
  .timeline-pill p{ font-family:var(--font-mono); font-size:18px; color:var(--white); margin:0; }
  .timeline-line{
    position:absolute;
    left:50%;
    top:126px;
    bottom:60px;
    width:3px;
    background:var(--asphalt-700);
    transform:translateX(-50%);
    z-index:1;
    overflow:hidden;
    opacity:0;
    will-change:opacity;
    -webkit-mask-image:linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
    mask-image:linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
  }
  .timeline-line-fill{
    position:absolute;
    inset:0;
    background:var(--asphalt-300);
    transform:scaleY(0);
    transform-origin:top;
    will-change:transform;
  }
  .timeline-stage{
    --tl-stage-h:min(440px, 52vh);
    --tl-floor:clamp(320px, 30vh, 400px);   /* below the pill, always */
    position:absolute;
    left:50%;
    /* centred in the section, but pushed down if centring would put it
       over the pill — the stage is out of flow, so nothing else can */
    top:min(
      max(var(--tl-floor), calc(50% - var(--tl-stage-h) / 2)),
      calc(100vh - var(--tl-stage-h) - 40px)
    );
    transform:translateX(-50%);
    z-index:2;
    width:1223px;
    max-width:calc(100vw - var(--gutter) * 2);
    height:var(--tl-stage-h);
  }
  /* No clip of its own: the pin already clips at the viewport and the pill
     sits above the cards, so a departing card is cut there. Avoiding three
     extra clip layers keeps the scroll cheap. */
  .timeline-item{
    position:absolute;
    inset:0;
    display:flex;
    align-items:center;
    justify-content:center;
    filter:blur(10px);
    opacity:0;
  }
  /* the dot lives out here so the panel's crop cannot clip it */
  .t-panel-wrap{
    position:relative;
    width:min(1140px, 100%);
    height:100%;
  }
  .t-panel{
    position:relative;
    box-sizing:border-box;
    width:100%;
    height:100%;
    overflow:hidden;
    border-radius:28px;
    /* a lit top-left edge and a faint yellow bloom behind the phone give the
       panel some depth against the flat water behind it */
    background:
      radial-gradient(120% 130% at 84% 4%, rgba(255,181,17,0.10), transparent 58%),
      radial-gradient(90% 120% at 4% 0%, rgba(0,170,204,0.12), transparent 62%),
      linear-gradient(150deg, #27334f 0%, var(--asphalt-800) 44%, #1a2440 100%);
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,0.09),
      inset 0 0 0 1px rgba(255,255,255,0.05),
      0 26px 60px rgba(6,12,24,0.45);
    display:flex;
    align-items:center;
    gap:48px;
    padding:0 56px;
  }
  /* the spine reads as passing behind the panel rather than stopping at it */
  /* no spine in this version — the numbered marker carries the sequence */
  .t-panel > *{ position:relative; z-index:1; }
  /* Title and copy now sit together in ONE left-aligned block on the left of
     the spine, with the step's own visual opposite it. */
  .timeline-item .t-copy{
    flex:1 1 0;
    min-width:0;
    max-width:694px;
    display:flex;
    flex-direction:column;
    gap:12px;
  }
  .timeline-item .t-title{
    margin:0;
    font-size:34px;
    font-weight:600;
    line-height:1.2;
    text-align:left;
    color:var(--white);
  }
  /* the example callout under the copy on step one */
  .timeline-item .t-example{
    margin:8px 0 0;
    align-self:flex-start;
    box-sizing:border-box;
    width:min(calc(34ch + 58px), 100%);
    border:1px solid var(--yellow);
    border-radius:14px;
    background:linear-gradient(160deg, rgba(255,181,17,0.17), rgba(255,181,17,0.10));
    padding:20px 26px;
    font-family:var(--font-mono);
    font-size:clamp(14px, 1.15vw, 17px);
    font-weight:700;
    line-height:1.55;
    color:var(--white);
  }
  /* one block per authored line; they run together as normal prose once the
     card is too narrow for the breaks */
  .timeline-item .t-example span,
  .timeline-item .t-body span{ display:block; }
  .timeline-item .t-body{
    margin:0;
    font-size:24px;
    font-weight:600;
    line-height:1.35;
    text-align:left;
    color:var(--white);
  }
  /* the step counter lives inside the card, above the title */
  .timeline-item .t-dot{
    align-self:flex-start;
    display:inline-flex;
    align-items:center;
    gap:10px;
    padding:6px 14px;
    border-radius:999px;
    background:var(--yellow);
    font-family:var(--font-mono);
    font-size:14px;
    letter-spacing:0.12em;
    color:var(--asphalt-900);
  }
  .timeline-item .t-dot i{ font-style:normal; opacity:0.55; }
  /* the phone drops in from the panel's top and is cropped by its bottom */
  .timeline-item .t-visual{
    flex:none;
    align-self:flex-start;
    margin-top:24px;
    height:calc(100% + 96px);
    display:flex;
  }
  /* the digest alert is not cropped — it sits centred in the panel */
  .timeline-item .t-visual.is-alert{
    align-self:center;
    margin-top:0;
    height:auto;
    align-items:center;
  }

  /* flat renders rather than a built screen — one image per step */
  .t-phone{
    flex:none;
    height:100%;
    aspect-ratio:453 / 914;
    background:center top / 100% auto no-repeat;
    filter:drop-shadow(0 22px 34px rgba(6,12,24,0.55)) drop-shadow(0 4px 10px rgba(6,12,24,0.35));
  }
  @media (max-width:1100px){
    /* the image keeps its own aspect but the box is capped, so the bottom of
       the phone is cut by the card exactly as it is on desktop */
    .t-phone{ aspect-ratio:auto; background-size:100% auto; }
  }
  .t-phone.is-steering{ background-image:url("/static/homepage/steering-email.png"); }


  /* ------------------------------------------------------------
     Step one's phone is animated rather than static: the report is
     tapped at the top of the inbox and the message opens out of that
     row. Both renders include the bezel, so the inbox is a fixed base
     layer (the handset never moves) and the opened message is masked
     to the glass, so only the screen changes.
     ------------------------------------------------------------ */
  .t-phone.is-live{
    position:relative;
    background:none;
    filter:none;
  }
  .tpa{
    position:absolute;
    left:0;
    top:0;
    width:100%;
    aspect-ratio:453 / 915;
    --glass-x:5.52%;
    --glass-y:2.2%;
    filter:drop-shadow(0 22px 34px rgba(6,12,24,0.55)) drop-shadow(0 4px 10px rgba(6,12,24,0.35));
  }
  .tpa-base{ position:absolute; inset:0; width:100%; height:100%; display:block; }
  .tpa-tap, .tpa-open{
    position:absolute;
    left:var(--glass-x);
    right:var(--glass-x);
    top:var(--glass-y);
    bottom:var(--glass-y);
    border-radius:11% / 5.5%;
    overflow:hidden;
    pointer-events:none;
  }
  .tpa-row{
    position:absolute;
    left:1.5%; right:1.5%;
    top:21%;
    height:11%;
    border-radius:10px;
    background:rgba(255,181,17,0.34);
    box-shadow:inset 0 0 0 2px rgba(255,181,17,0.9), 0 2px 10px rgba(255,181,17,0.28);
    opacity:0;
    animation:tpaRow 11s cubic-bezier(.3,0,.2,1) infinite;
  }
  .tpa-open{ opacity:0; animation:tpaOpen 11s steps(1, end) infinite; }
  .tpa-open img{
    position:absolute;
    max-width:none;
    left:-6.21%;
    top:-2.3%;
    width:112.41%;
    height:104.6%;
    display:block;
    filter:drop-shadow(-9px 0 16px rgba(4,9,18,0.55));
    animation:tpaShot 11s cubic-bezier(.32,.72,0,1) infinite;
  }
  /* 11s cycle: ~1.1s on the inbox, the tap, then the message open for a
     little over 8s before it closes and the loop restarts */
  @keyframes tpaRow{
    0%,   8.6% { opacity:0; transform:scale(1.03); }
    9.8%, 14.2% { opacity:1; transform:scale(1); }
    17.5%, 100% { opacity:0; transform:scale(1); }
  }
  /* opacity is a hard switch — the slide does all the work, so there is no
     ghosting of one screen over the other */
  @keyframes tpaOpen{
    0%,  13.5% { opacity:0; }
    13.6%, 99.4% { opacity:1; }
    99.5%, 100% { opacity:0; }
  }
  @keyframes tpaShot{
    0%,  13.5% { transform:translateX(89%); }
    20.5%, 99.4% { transform:translateX(0); }
    99.5%, 100% { transform:translateX(89%); }
  }
  @media (prefers-reduced-motion:reduce){
    .tpa-row, .tpa-open, .tpa-open img{ animation:none; }
    .tpa-open{ opacity:1; }
  }

  /* the digest alert, as it appears against step three */
  /* A phone notification banner, after the iOS/Gmail alert: a light frosted
     panel with the app tile, sender, subject and preview line. It drops in
     when the card takes focus, so it reads as arriving. */
  .t-notif{
    flex:none;
    box-sizing:border-box;
    width:392px;
    max-width:100%;
    display:flex;
    align-items:flex-start;
    gap:14px;
    padding:16px 18px;
    border-radius:24px;
    background:linear-gradient(180deg, rgba(247,250,255,0.97), rgba(228,238,252,0.95));
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,0.9),
      0 20px 44px rgba(4,10,22,0.55),
      0 4px 12px rgba(4,10,22,0.35);
    opacity:0;
    transform:translateY(-72px) scale(0.9);
    transition:opacity 0.34s ease 0.34s, transform 0.72s cubic-bezier(.16,1.3,.3,1) 0.34s;
  }
  /* .focus is set by the timeline once the card is essentially opaque */
  .timeline-item.focus .t-notif{ opacity:1; transform:translateY(0) scale(1); }
  .t-notif-tile{
    position:relative;
    flex:none;
    width:44px;
    height:44px;
    border-radius:12px;
    background:#fff;
    box-shadow:0 1px 3px rgba(4,10,22,0.22);
    display:flex;
    align-items:center;
    justify-content:center;
    font-family:var(--font-body);
    font-size:16px;
    font-weight:700;
    letter-spacing:-0.02em;
    color:#f2820d;
  }
  /* unread badge, sitting on the app tile as it would on a home screen */
  .t-notif-dot{
    position:absolute;
    top:-5px;
    right:-5px;
    width:14px;
    height:14px;
    border-radius:50%;
    background:var(--red);
    box-shadow:0 0 0 2.5px rgba(247,250,255,0.97), 0 1px 3px rgba(4,10,22,0.35);
  }
  .t-notif-main{ min-width:0; flex:1 1 auto; }
  .t-notif-head{
    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:10px;
  }
  .t-notif-from{
    margin:0;
    font-size:16px;
    font-weight:700;
    color:#0d1526;
    letter-spacing:-0.01em;
  }
  .t-notif-when{ margin:0; flex:none; font-size:14px; color:#5b708f; }
  .t-notif-subject{
    margin:1px 0 0;
    font-size:16px;
    font-weight:700;
    color:#0d1526;
    letter-spacing:-0.01em;
  }
  .t-notif-line{
    margin:2px 0 0;
    font-size:15px;
    line-height:1.35;
    color:#2c3a52;
    text-wrap:pretty;
  }
  .t-alert{
    flex:none;
    box-sizing:border-box;
    width:340px;
    max-width:100%;
    filter:drop-shadow(0 18px 30px rgba(6,12,24,0.5));
    padding:21px 21px 29px;
    border-radius:17px;
    background:var(--asphalt-900);
    box-shadow:inset 0 0 0 1.7px rgb(51,64,92), 7px 7px 27px rgba(18,37,60,0.25);
    display:flex; flex-direction:column; gap:5px;
  }
  @keyframes unreadFlash{
    0%, 100%{ opacity:1; }
    50%{ opacity:0.4; }
  }
  .t-alert .t-alert-badge{
    animation:unreadFlash 1.1s ease-in-out infinite;
    align-self:flex-start;
    display:inline-flex; align-items:center; gap:7px;
    padding:4px 11px;
    border-radius:999px;
    background:rgba(244,102,119,0.16);
    border:1px solid rgba(244,102,119,0.55);
    font-family:var(--font-mono);
    font-size:11px; letter-spacing:0.12em;
    color:#ffd3d9;
  }
  .t-alert .t-alert-badge i{
    display:block; width:7px; height:7px; border-radius:50%;
    background:var(--red);
  }
  .t-alert h4{ margin:9px 0 0; font-size:22px; font-weight:600; color:var(--white); }
  .t-alert .t-alert-date{ margin:0; font-size:13px; color:var(--yellow); }
  .t-alert .t-alert-line{
    margin:2px 0 0;
    font-size:13px; letter-spacing:0.08em; text-transform:uppercase;
    color:var(--white);
  }

  /* ============================================================
     SECTION 5 — Contact form — node 50:3539
     ============================================================ */
  section.contact-form{
    background:var(--asphalt-900);
    padding:180px 0 180px;
  }
  #contact-form, #goldfishHQ{ scroll-margin-top:112px; }
  /* The hold: sticky was inert because .form-wrap exactly filled its
     containing block, so it had nowhere to travel. A sibling spacer gives it
     room. Only engaged on viewports tall enough to show the whole form, so
     the Submit button can never be stranded below the fold while stuck. */
  .form-hold-spacer{ height:0; }
  @media (min-height:900px){
    section.contact-form .form-wrap{
      position:sticky;
      top:clamp(168px, 21vh, 240px);
    }
    .form-hold-spacer{ height:46vh; }
  }
  .form-wrap{ max-width:var(--measure); margin:0 auto; padding:0 var(--gutter); }
  /* two columns: the ask sits on the left, the fields on the right.
     Fields carry no box — a hairline underline that lights yellow on
     focus, with mono uppercase labels above. */
  .form-layout{
    display:grid;
    grid-template-columns:minmax(0,0.8fr) minmax(0,1.2fr);
    gap:110px;
    align-items:start;
  }
  .form-intro{ display:flex; flex-direction:column; gap:22px; }
  .form-wrap h3{
    color:var(--yellow);
    font-size:clamp(30px, 3.1vw, 46px);
    font-weight:600;
    line-height:1.15;
    letter-spacing:-0.015em;
    margin:0;
    text-wrap:pretty;
  }
  .form-intro p{
    margin:0;
    max-width:380px;
    font-size:17px;
    line-height:1.6;
    color:var(--asphalt-400);
  }
  /* The fields sit in their own panel, on a lighter ground than the section,
     so the form reads as something to fill in rather than as more copy. */
  form{
    box-sizing:border-box;
    display:flex;
    flex-direction:column;
    gap:30px;
    background:var(--asphalt-800);
    border:1px solid var(--asphalt-700);
    border-radius:24px;
    padding:40px;
    box-shadow:0 18px 48px rgba(0,0,0,0.28);
  }
  .form-row{ display:grid; grid-template-columns:1fr 1fr; gap:24px; }
  .form-row.trio{ grid-template-columns:repeat(3, minmax(0,1fr)); }
  .field{ display:flex; flex-direction:column; gap:10px; min-width:0; }
  .field label{
    font-family:var(--font-mono);
    font-size:13px;
    letter-spacing:0.1em;
    text-transform:uppercase;
    color:var(--asphalt-200);
  }
  .field label .req{ color:var(--red); }
  .field input, .field textarea{
    box-sizing:border-box;
    width:100%;
    background:var(--asphalt-900);
    border:1.5px solid var(--asphalt-700);
    border-radius:8px;
    padding:13px 15px;
    font-family:var(--font-body);
    font-size:17px;
    line-height:1.5;
    color:var(--white);
    outline:none;
    transition:border-color .15s ease, box-shadow .15s ease;
  }
  .field input:focus, .field textarea:focus{
    border-color:var(--yellow);
    box-shadow:0 0 0 3px rgba(255,181,17,0.16);
  }
  .field textarea{ min-height:110px; resize:vertical; }
  .field textarea::placeholder{ color:var(--asphalt-400); }
  .form-foot{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:32px;
    flex-wrap:wrap;
    padding-top:6px;
  }
  .checkbox-row{ display:flex; align-items:center; gap:12px; font-size:15px; color:var(--asphalt-200); }
  .checkbox-row input{ width:18px; height:18px; accent-color:var(--yellow); }
  .checkbox-row a{ text-decoration:underline; }
  form .btn{ padding:16px 42px; font-size:16px; }

  /* ============================================================
     FOOTER
     ============================================================ */
  footer{ background:var(--asphalt-900); border-top:1px solid var(--asphalt-700); color:var(--white); padding:80px 0 32px; }
  .footer-top{ display:flex; gap:64px; justify-content:space-between; align-items:flex-end; flex-wrap:wrap; margin-bottom:32px; }
  .footer-contact p{ margin:4px 0; font-size:16px; }
  .footer-nav{ display:flex; gap:32px; flex-wrap:wrap; justify-content:flex-end; }
  .footer-nav a{ font-size:16px; white-space:nowrap; transition:color 0.15s ease; }
  .footer-nav a:hover{ color:var(--yellow); }
  .footer-contact a{ transition:color 0.15s ease; }
  .footer-contact a:hover{ color:var(--yellow); }
  .footer-credits a{ transition:color 0.15s ease; }
  .footer-credits a:hover{ color:var(--yellow); }
  .footer-divider{ height:1px; background:var(--yellow); margin:0 0 24px; }
  .footer-credits{ display:flex; justify-content:space-between; flex-wrap:wrap; gap:8px; font-size:14px; color:var(--asphalt-300); }

  @media (max-width:1200px){
    :root{ --gutter:40px; }
    .hero-copy{ right:40px; }
    .t-panel{ padding:0 40px 0 32px; gap:28px; }
    .timeline-item .t-title{ font-size:22px; }
    .timeline-item .t-body{ font-size:16px; }
    .form-layout{ grid-template-columns:1fr; gap:56px; }
    .form-row.trio{ grid-template-columns:1fr 1fr; }
  }
  @media (max-width:760px){
    .timeline-stage{ height:min(460px, 62vh); }
    .timeline-item .t-copy{ max-width:none; }
    .timeline-line{ display:none; }
    .hero-copy{ gap:clamp(16px, 3.4vh, 30px); padding-top:clamp(94px, 14vh, 150px); }
    .hero-lede{ max-width:100%; }
  }
  /* between 760 and 1200 the copy starts at 40px, so it can use more width
     before running into the digest notification's gutter */
  /* ------------------------------------------------------------
     Mid widths: the side-by-side arrangements survive longer if the
     type steps down with the space rather than the columns holding
     a fixed size until they are too narrow to read.
     ------------------------------------------------------------ */
  @media (max-width:1400px){
    .timeline-item .t-title{ font-size:clamp(20px, 2.3vw, 30px); }
    .timeline-item .t-body{ font-size:clamp(15px, 1.7vw, 22px); }
    .timeline-item .t-copy{ max-width:clamp(280px, 40vw, 694px); }
    .t-panel-wrap{ width:min(980px, 100%); }
    /* A phone notification banner, after the iOS/Gmail alert: a light frosted
     panel with the app tile, sender, subject and preview line. It drops in
     when the card takes focus, so it reads as arriving. */
  .t-notif{
    flex:none;
    box-sizing:border-box;
    width:392px;
    max-width:100%;
    display:flex;
    align-items:flex-start;
    gap:14px;
    padding:16px 18px;
    border-radius:24px;
    background:linear-gradient(180deg, rgba(247,250,255,0.97), rgba(228,238,252,0.95));
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,0.9),
      0 20px 44px rgba(4,10,22,0.55),
      0 4px 12px rgba(4,10,22,0.35);
    opacity:0;
    transform:translateY(-72px) scale(0.9);
    transition:opacity 0.34s ease 0.34s, transform 0.72s cubic-bezier(.16,1.3,.3,1) 0.34s;
  }
  /* .focus is set by the timeline once the card is essentially opaque */
  .timeline-item.focus .t-notif{ opacity:1; transform:translateY(0) scale(1); }
  .t-notif-tile{
    position:relative;
    flex:none;
    width:44px;
    height:44px;
    border-radius:12px;
    background:#fff;
    box-shadow:0 1px 3px rgba(4,10,22,0.22);
    display:flex;
    align-items:center;
    justify-content:center;
    font-family:var(--font-body);
    font-size:16px;
    font-weight:700;
    letter-spacing:-0.02em;
    color:#f2820d;
  }
  /* unread badge, sitting on the app tile as it would on a home screen */
  .t-notif-dot{
    position:absolute;
    top:-5px;
    right:-5px;
    width:14px;
    height:14px;
    border-radius:50%;
    background:var(--red);
    box-shadow:0 0 0 2.5px rgba(247,250,255,0.97), 0 1px 3px rgba(4,10,22,0.35);
  }
  .t-notif-main{ min-width:0; flex:1 1 auto; }
  .t-notif-head{
    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:10px;
  }
  .t-notif-from{
    margin:0;
    font-size:16px;
    font-weight:700;
    color:#0d1526;
    letter-spacing:-0.01em;
  }
  .t-notif-when{ margin:0; flex:none; font-size:14px; color:#5b708f; }
  .t-notif-subject{
    margin:1px 0 0;
    font-size:16px;
    font-weight:700;
    color:#0d1526;
    letter-spacing:-0.01em;
  }
  .t-notif-line{
    margin:2px 0 0;
    font-size:15px;
    line-height:1.35;
    color:#2c3a52;
    text-wrap:pretty;
  }
  .t-alert{ width:clamp(240px, 24vw, 340px); }
  }
  @media (max-width:1250px){
    /* stays alongside the headline as at full width — the fish scales with
       the space instead of dropping below and leaving a hole */
    .hq-headline-row{ gap:32px; }
    .hq-fish{ width:clamp(150px, 22vw, 250px); }
    .hq-headline{ font-size:clamp(26px, 3.4vw, 40px); }
  }
  @media (max-width:1100px){
    /* Portrait card: the two columns no longer leave a readable measure, so
       the copy sits on top and the artefact beneath it — still cropped by the
       card's bottom edge, so the crop reads the same as on desktop. */
    .timeline-stage{ --tl-stage-h:min(640px, 76vh); }
    .timeline-item .t-title{ font-size:clamp(22px, 3.2vw, 28px); }
    .timeline-item .t-body{ font-size:clamp(15px, 2.2vw, 20px); }
    .timeline-item .t-body span{ display:inline; }
    .timeline-item .t-example{ padding:14px 18px; border-radius:12px; }
    .timeline-item .t-example span{ display:inline; }
    .t-panel{
      flex-direction:column;
      align-items:stretch;
      justify-content:flex-start;
      gap:24px;
      padding:36px 36px 0;
    }
    .timeline-item .t-copy{ max-width:none; flex:none; }
    .timeline-item .t-visual{
      flex:1 1 auto;
      min-height:0;
      align-self:center;
      margin-top:0;
      height:auto;
      justify-content:center;
      /* the tapped row sits 157px down the phone: never crop above it, even
         on a short landscape viewport where the stage cannot grow */
      min-height:210px;
    }
    .t-phone{ height:auto; width:min(240px, 62vw); }
    /* the alert has nothing to crop, so it just centres in the space */
    .timeline-item .t-visual.is-alert{ flex:0 0 auto; height:auto; padding-bottom:36px; }
    .timeline-line{ display:none; }
  }
  @media (max-width:1100px) and (max-height:820px){
    .timeline-pin{ padding-top:clamp(88px, 13vh, 140px); }
    .timeline-stage{
      --tl-stage-h:min(640px, calc(100vh - 190px));
      --tl-floor:clamp(160px, 22vh, 230px);
    }
    /* the handset scales with the height it has, rather than disappearing */
    .t-phone{ width:min(240px, 62vw, 34vh); }
    .timeline-item .t-visual{ min-height:min(210px, 26vh); }
    .t-panel{ padding:28px 28px 0; }
  }
  @media (max-width:1100px) and (max-height:560px){
    /* below this the row the tap plays on cannot stay inside the crop */
    .timeline-item .t-visual{ display:none; }
    /* the alert is a fraction of the handset's height, so it stays */
    .timeline-item .t-visual.is-alert{ display:flex; }
    .t-panel{ padding:28px; justify-content:center; }
    .timeline-item .t-copy{ align-self:center; }
  }

  /* ============================================================
     SMALL SCREENS — the wide, side-by-side arrangements all stack
     ============================================================ */
  @media (max-width:900px){
    /* the landscape benefit card has no room for image-beside-copy here */
    .benefits-deck{
      width:min(520px, calc(100vw - var(--gutter) * 2));
      height:auto;
      min-height:430px;
    }
    .benefit-card{
      flex-direction:column;
      justify-content:center;
      gap:18px;
      padding:30px 26px;
    }
    .benefit-card img{ height:clamp(96px, 16vh, 150px); }
    .benefit-card .benefit-copy{ align-items:center; }
    .benefit-card h3, .benefit-card p{ text-align:center; }
    /* the authored break would leave a two-word line in a narrow card */
    .benefit-card h3{ font-size:clamp(22px, 4.4vw, 30px); }
    .benefit-card h3 br{ display:none; }
    .benefit-card p{ font-size:clamp(14px, 3.4vw, 17px); }
    /* the flanking cards would sit on top of the copy at this width */
    .benefit-card.aside{ opacity:0; }
    .benefits-inner h2{ font-size:clamp(26px, 6vw, 40px); }
  }
  @media (max-width:760px){
    header.nav{ padding:14px var(--gutter); }
    .nav-inner{ flex-wrap:wrap; gap:14px; }
    /* the links move to their own full-width row under the logo */
    .nav-group{ width:100%; justify-content:space-between; gap:16px; padding:12px 18px; }
    .nav-links a{ font-size:14px; }
    .logo-lockup img{ height:28px; }
    .hero-copy{ padding-top:200px; }
    .footer-top{ align-items:flex-start; gap:32px; }
    .footer-nav{ justify-content:flex-start; }
    .form-wrap h2{ font-size:clamp(26px, 6vw, 38px); }
    form{ padding:26px; border-radius:16px; }
    .form-row, .form-row.trio{ grid-template-columns:1fr; }
    .hq-award{ gap:14px; }
    .hq-award-mark{ width:132px; }
    .hq-award strong{ font-size:18px; }
    .hq-award-copy > span{ font-size:12px; }
    #contact-form, #goldfishHQ{ scroll-margin-top:176px; }
  }
  @media (max-width:560px){
    :root{ --gutter:20px; }
    /* three links plus the button no longer fit one row */
    .nav-links{ display:flex; flex-wrap:wrap; gap:14px; }
    .nav-group{ flex-direction:column; align-items:flex-start; gap:14px; }
    .nav-group .btn{ width:100%; }
    .hq-fish{ width:136px; }
    .hq-card{ padding:20px 24px 22px; }
    .benefit-card p{ font-size:15px; }
    .timeline-item .t-body{ font-size:15px; }
    .scroll-cue{ display:none; }
  }
  @media (min-width:761px) and (max-width:1200px){
    .hero-lede{ max-width:min(880px, calc(100vw - 500px)); }
    /* the authored lines are wider than this band allows, so the paragraph
       sets its own — the forced breaks would only add orphans */
    .hero-lede .ln{ white-space:normal; display:inline; }
    .hero-lede .ln br{ display:none; }
  }

  @media (prefers-reduced-motion:reduce){
    html{ scroll-behavior:auto; }
    .loading-screen,
    #hero-bg-canvas,
    #hero-fish-top{ display:none; }
    .hero-copy h1 .sharp{
      clip-path:inset(0 0 0 0) !important;
      -webkit-clip-path:inset(0 0 0 0) !important;
    }
    .hero-lede .lp,
    .hero-cta,
    .benefit-card,
    .carousel-arrow,
    .carousel-dot,
    .scroll-cue,
    .timeline-item,
    .hq-card{
      animation:none !important;
      transition:none !important;
    }
  }
