/* ── the three brand faces, self-hosted, nothing else ────────────────
     Montserrat         → everything structural (H1/H2/H3/body/UI)
     Editorial Today    → the highlighted words, Thin Italic
     Paperink           → the handwritten asides
     Only these three. No webfont service, no system fallback in the design. */

  /* One variable file for the whole 100–900 range, not nine static cuts:
     216 KB and a single request, against 349 KB over nine. Every weight the
     design asks for — 300 for body, 500 for UI, 700/900 for headings — is an
     instance of this one file. */
  @font-face{font-family:'Montserrat';font-weight:100 900;font-style:normal;font-display:swap;
    src:url('montserrat-font/Montserrat-Variable.woff2') format('woff2')}


  @font-face{font-family:'Editorial Today';font-weight:100;font-style:normal;font-display:swap;
    src:url('editorial-font/EditorialToday-Thin.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:100;font-style:italic;font-display:swap;
    src:url('editorial-font/EditorialToday-ThinItalic.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:400;font-style:normal;font-display:swap;
    src:url('editorial-font/EditorialToday-Regular.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:400;font-style:italic;font-display:swap;
    src:url('editorial-font/EditorialToday-Italic.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:600;font-style:normal;font-display:swap;
    src:url('editorial-font/EditorialToday-SemiBold.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:700;font-style:normal;font-display:swap;
    src:url('editorial-font/EditorialToday-Bold.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:800;font-style:normal;font-display:swap;
    src:url('editorial-font/EditorialToday-ExtraBold.ttf') format('truetype')}
  @font-face{font-family:'Editorial Today';font-weight:800;font-style:italic;font-display:swap;
    src:url('editorial-font/EditorialToday-ExtraBoldItalic.ttf') format('truetype')}

  /* Regular only. The Blue-SVG and Black-SVG cuts are colour-layer fonts —
     32 MB and 61 MB — far too heavy to ship to a browser. */
  @font-face{font-family:'Paperink';font-weight:400;font-style:normal;font-display:swap;
    src:url('paperink-font/paperink-regular.otf') format('opentype')}

  /* This is a set of plain HTML documents, so every link is a real page
     load — and a hard swap of the whole screen is what makes clicking
     around feel like the site restarting. The browser cross-fades between
     the two documents instead. No script, and browsers without it simply
     navigate the way they always did. */
  @view-transition{navigation:auto}
  @media (prefers-reduced-motion:reduce){
    @view-transition{navigation:none}
  }

  html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
/* a tap answers with the design's own states, not a grey flash */
a,button{-webkit-tap-highlight-color:transparent}

:root{
    --white:#FFFFFF;
    --sky:#C7E1FD;
    --blue-light:#83C8F0;
    --blue:#1A4E98;
    --ink:#000000;

    --font:'Montserrat',system-ui,sans-serif;
    --font-display:'Editorial Today',Georgia,serif;
    --font-note:'Paperink',cursive;               /* the chatty asides */

    /* One design pixel. The whole frame is drawn at 1440 and shrinks with
       the viewport, so every number below is the raw Figma number. */
    --u:calc(min(100vw,1440px) / 1440);

    /* How wide the frame is allowed to get before it stops. 1440 is the
       Figma width, so at the default the hero renders 1:1 and simply stops
       growing; see the .hdr/.hero-body shell below. */
    --shell:1440px;

    /* How far a shell child has to reach to get back out to the screen
       edge. Zero until the viewport passes --shell, so it is inert on
       every size the design was actually drawn for. */
    --bleed:min(0px,calc((var(--shell) - 100vw) / 2));

    /* The overshoot every macOS surface settles on. The dock and its
       labels ride it; older components keep their own ease-out curve. */
    --spring:cubic-bezier(.34,1.42,.64,1);

    /* CTA — locked to the Figma component */
    --cta-radius:12px;
    --cta-border:3px;
  }

  *{box-sizing:border-box}

  /* How far you scroll before the header contracts. The sentinel is just a
     tall invisible strip at the top of the document — the pill engages the
     moment its bottom edge clears the viewport, so its height IS the
     threshold. Absolutely positioned, so it costs the layout nothing. */
  #top{position:absolute;top:0;width:1px;height:calc(280 * var(--u))}

  /* form controls do not inherit the page font on their own */
  button,input,textarea,select{font-family:inherit;letter-spacing:inherit}

  html,body{margin:0}
  body{
    background:var(--sky);          /* full-bleed, no frame, no gaps */
    font-family:var(--font);
    font-weight:300;
    letter-spacing:-0.03em;
    color:var(--ink);
    overflow-x:hidden;
    -webkit-font-smoothing:antialiased;
  }

  /* ── the hero block, ending in a scalloped edge ───────────────────────
     Arc geometry measured off the Figma frame: 77 pitch, 24 deep, which
     puts the circle centre 18.88 above the bottom with r = 42.88.        */
  .hero{
    position:relative;
    z-index:2;                             /* the bumps hang over section 2 */
    min-height:100vh;
    background:var(--sky);
    overflow:hidden;
    -webkit-mask:
      linear-gradient(#000,#000) top/100% calc(100% - 24 * var(--u)) no-repeat,
      radial-gradient(circle calc(42.88 * var(--u)) at 50% calc(-18.88 * var(--u)),#000 100%,transparent 0)
        bottom left/calc(77 * var(--u)) calc(24 * var(--u)) repeat-x;
            mask:
      linear-gradient(#000,#000) top/100% calc(100% - 24 * var(--u)) no-repeat,
      radial-gradient(circle calc(42.88 * var(--u)) at 50% calc(-18.88 * var(--u)),#000 100%,transparent 0)
        bottom left/calc(77 * var(--u)) calc(24 * var(--u)) repeat-x;
  }

  /* ── the shell ────────────────────────────────────────────────────────
     Past 1440 the design pixel is already locked, but the rows themselves
     kept growing, so the only thing that actually stretched was the air
     inside them: on a 2560 monitor the brand and the CTA end up a metre
     apart, the three steps drift into separate corners and the folder
     sails off after the headline. Capping the rows parks that spread and
     centres them.

     Deliberately left out, because they are meant to reach the edge: the
     sky and white grounds, both scalloped bands, the drifting ribbon, the
     work strips, and the mock-up board (see .board below).               */
  .hero-body,
  .believe,
  .steps,
  .services,
  .foot-end,.foot-bar{
    max-width:var(--shell);
    margin-inline:auto;
  }

  /* The hero carries its own --u on top of that, so lowering --shell scales
     it down as one piece instead of pulling the copy and the folder into
     each other — they clear by 26px at 1440, so there is no slack to give
     away. The sections below have no such collision and stay on the root
     unit, which keeps them in step with the full-bleed rows they sit
     between. */
  .hdr,.hero-body{--u:calc(min(100vw,var(--shell)) / 1440)}

  /* ── header ───────────────────────────────────────────────────────────
     One element, two shapes. At the top of the page it is a full-width bar
     with nothing behind it; once you scroll it contracts into a floating
     pill and the frosted ground fades up under it. Everything between the
     two states is a plain animatable property — max-width, height, padding,
     gap, font-size, colour — so it is one continuous move, not a hand-off
     between two separate elements.

     It has to live outside .hero: the hero is masked, which makes it a
     containing block, and a fixed child inside would be clipped by it.   */
  .hdr{
    position:fixed;top:0;left:0;right:0;z-index:55;
    display:flex;justify-content:center;
    padding:0;                             /* the bar reaches both edges */
    pointer-events:none;                   /* the bar itself takes the clicks */
    transition:padding 1s cubic-bezier(.34,1.2,.5,1);
  }
  .hdr-in{
    pointer-events:auto;
    width:100%;
    /* Full-bleed ground, but the contents still line up with the 1440
       column every other row on the page is measured against.

       100vw rather than none: a transition needs a length at both ends, and
       max-width:none is not one — it snaps straight to the pill width. */
    max-width:100vw;
    height:calc(90 * var(--u));
    padding-inline:max(calc(115 * var(--u)),
                       calc((100% - var(--shell)) / 2 + 115 * var(--u)));
    padding-block:0;
    /* Three tracks, not space-between. Space-between shares the slack out
       equally, so the nav only lands on the centre line when the logo and
       the button happen to weigh the same — and they never do. It sat 22u
       right of centre in the bar and 35u left of it in the pill, which is
       what read as crooked. Equal side tracks put it on the centre line in
       both, and it stays there whatever the logo does next. */
    display:grid;
    /* minmax(min-content,…), not minmax(0,…): the pill closes down to the
       width where these tracks are exactly as wide as the logo and the
       button, and a track that may collapse to nothing would let the
       button slide under the nav on the way there. */
    grid-template-columns:minmax(min-content,1fr) auto minmax(min-content,1fr);
    align-items:center;
    gap:calc(32 * var(--u));

    /* One ground for both shapes: the frosted white the pill always had.
       Nothing about the colour animates — only the shape does. */
    background:rgba(255,255,255,.8);
    -webkit-backdrop-filter:blur(16px) saturate(1.3);
            backdrop-filter:blur(16px) saturate(1.3);
    border:1px solid transparent;          /* the hairline is a pill detail */
    border-radius:0;
    box-shadow:0 calc(14 * var(--u)) calc(34 * var(--u)) rgba(26,78,152,.13);
    transition:
      max-width     1.15s cubic-bezier(.34,1.2,.5,1),
      height        1s    cubic-bezier(.34,1.2,.5,1),
      padding       1s    cubic-bezier(.34,1.2,.5,1),
      gap           1s    cubic-bezier(.34,1.2,.5,1),
      border-radius .8s   ease,
      background-color .8s ease,
      border-color  .8s   ease,
      box-shadow    .8s   ease;
  }

  /* ── the pill ─────────────────────────────────────────────────────── */
  .hdr.pill{padding:calc(14 * var(--u)) calc(20 * var(--u)) 0}
  .hdr.pill .hdr-in{
    /* Same three tracks as the bar — swapping the template here is what made
       the contraction look broken: the layout snapped to its end state on
       the first frame while the white ground crawled in behind it for the
       next second. So the pill changes nothing but its size, and shrinks to
       the exact width at which the side tracks have run down to the logo and
       the button. Nothing is left over to sit as a hole, and every position
       in between is a real step on the way there. */
    max-width:calc(504 * var(--u));
    height:calc(58 * var(--u));
    padding:calc(7 * var(--u)) calc(20 * var(--u));
    gap:calc(26 * var(--u));
    border-color:rgba(26,78,152,.18);
    border-radius:999px;
    box-shadow:0 calc(14 * var(--u)) calc(34 * var(--u)) rgba(26,78,152,.15);
  }

  /* the three children shrink with it */
  .hdr.pill .brand{height:calc(38 * var(--u));margin-left:0}
  .hdr.pill .brand-full{display:none}
  .hdr.pill .brand-mark{display:block}
  .hdr.pill .nav{gap:calc(30 * var(--u))}
  .hdr.pill .nav a{font-size:calc(17 * var(--u))}
  .hdr.pill .cta{
    height:calc(44 * var(--u));
    padding:calc(8 * var(--u)) calc(26 * var(--u));
    font-size:calc(17 * var(--u));
    border-width:calc(2 * var(--u));
    border-radius:calc(999 * var(--u));
  }
  .hdr.pill .cta .ink{border-radius:999px}

  /* the hero used to hold the header in flow; keep its top air */
  .hero{padding-top:calc(90 * var(--u))}

  @media (prefers-reduced-motion:reduce){
    .hdr,.hdr-in{transition:none}
  }

  /* The full lockup at rest, the mark alone once the bar is a pill.

     Not a stylistic choice so much as arithmetic: the pill is 540u wide
     and, after the nav and the button, has about 60u to spare — while the
     lockup is 5.3:1, so at the pill's own 38u height it would want 200u.
     The wordmark simply cannot come along, and the icon is what the pill
     was always shaped around.                                          */
  .brand{
    justify-self:start;
    display:flex;align-items:center;
    height:calc(46 * var(--u));
    text-decoration:none;
    flex:none;
    transition:height 1s cubic-bezier(.34,1.2,.5,1);
  }
  /* no display here: it would outrank the .brand-mark rule below and
     put both marks in the bar at once. A flex child is blockified
     anyway, so there was nothing for it to do. */
  .brand img{height:100%;width:auto}
  .brand .brand-mark{display:none}

  /* header links — Montserrat Light 20 / 120% / -3% */
  .nav{justify-self:center;display:flex;align-items:center;gap:calc(52 * var(--u));
    transition:gap 1s cubic-bezier(.34,1.2,.5,1)}
  .nav a{
    font-weight:300;
    font-size:calc(20 * var(--u));
    line-height:1.2;
    letter-spacing:-0.03em;
    color:var(--ink);
    text-decoration:none;
    position:relative;
    padding:calc(4 * var(--u)) 0;
    transition:font-size 1s cubic-bezier(.34,1.2,.5,1);
  }
  .nav a::after{
    content:'';position:absolute;left:0;right:0;bottom:0;
    height:2px;background:var(--blue);
    transform:scaleX(0);transform-origin:left;
    transition:transform .34s cubic-bezier(.22,1,.36,1);
  }
  .nav a:hover::after,.nav a:focus-visible::after,
  .nav a[aria-current="page"]::after{transform:scaleX(1)}

  /* the third track is as wide as the first, so the button has to be told
     to sit at its end rather than stretch across it */
  .hdr .cta{justify-self:end;white-space:nowrap}

  /* ══ loading screen ═══════════════════════════════════════════════════
     The folder is the progress bar: it fills from the bottom as the page
     arrives. Then the whole panel lifts away on the brand's scalloped
     edge — the site's own signature, used as the way in.               */
  .loader{
    position:fixed;left:0;right:0;top:0;z-index:200;
    height:calc(100vh + 60px);           /* the scallop waits below the fold */
    background:var(--blue);
    display:grid;place-items:center;
    align-content:center;
    transform:translateY(0);
    transition:transform 1s cubic-bezier(.76,0,.24,1);
    -webkit-mask:
      linear-gradient(#000,#000) top/100% calc(100% - 26px) no-repeat,
      radial-gradient(circle 46px at 50% -20px,#000 100%,transparent 0)
        bottom left/84px 26px repeat-x;
            mask:
      linear-gradient(#000,#000) top/100% calc(100% - 26px) no-repeat,
      radial-gradient(circle 46px at 50% -20px,#000 100%,transparent 0)
        bottom left/84px 26px repeat-x;
  }
  .loader.done{transform:translateY(-100%)}
  .loader.gone{pointer-events:none;visibility:hidden}
  /* Second and later pages this session: the curtain has already been shown,
     and the head script says so before anything paints. */
  .no-curtain .loader{display:none}

  .loader-in{
    transition:opacity .4s ease .1s,transform .55s cubic-bezier(.22,1,.36,1) .1s;
  }
  .loader.done .loader-in{opacity:0;transform:scale(.9)}

  /* The seal turns while it waits. The turn is drawn frame by frame rather
     than rotated in CSS — only the ring of type goes round, the globe and
     the pencil stay upright, which no single transform can do. The disc is
     filled at the brand blue, so on this ground it melts away and the
     line-art is all that shows, exactly as the flat [white] cut did. */
  .ld-logo{
    display:block;
    width:calc(150 * var(--u));height:auto;
  }

  .ld-pct{
    position:absolute;left:0;right:0;
    bottom:calc(56 * var(--u));
    text-align:center;
    color:var(--white);
    font-weight:300;
    font-size:calc(52 * var(--u));
    line-height:1;letter-spacing:-0.03em;
    font-variant-numeric:tabular-nums;   /* the digits must not jitter */
    transition:opacity .35s ease;
  }
  .loader.done .ld-pct{opacity:0}


  /* ── hamburger + slide-down menu (mobile only) ────────────────────── */
  .burger{
    display:none;
    position:fixed;
    top:15px;right:20px;
    width:44px;height:44px;
    border:0;padding:0;cursor:pointer;
    z-index:70;                          /* above the menu overlay, always */
    -webkit-tap-highlight-color:transparent;
    /* On a phone this is the only chrome left, and it can be sitting on a
       full-bleed photograph, so it carries its own frosted ground. */
    border-radius:50%;
    background:rgba(255,255,255,.82);
    -webkit-backdrop-filter:blur(14px) saturate(1.3);
            backdrop-filter:blur(14px) saturate(1.3);
    box-shadow:0 6px 18px rgba(26,78,152,.18);
    transition:background .3s ease,box-shadow .3s ease;
  }
  /* once the panel is out, the ground would only fight with it */
  .burger[aria-expanded="true"]{
    background:none;box-shadow:none;
    -webkit-backdrop-filter:none;backdrop-filter:none;
  }
  .burger span{
    position:absolute;left:9px;right:9px;height:2px;
    background:var(--ink);border-radius:2px;
    transition:transform .42s cubic-bezier(.22,1,.36,1),opacity .2s ease;
  }
  .burger span:nth-child(1){top:16px}
  .burger span:nth-child(2){top:26px}
  .burger[aria-expanded="true"] span:nth-child(1){transform:translateY(5px) rotate(45deg)}
  .burger[aria-expanded="true"] span:nth-child(2){transform:translateY(-5px) rotate(-45deg)}
  .burger:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:6px}

  /* Three brand colours bloom out of the burger one after another, the last
     one being the panel that carries the links. Closing runs the same stack
     in reverse, so everything collapses back into the button. */
  .menu{
    position:fixed;inset:0;z-index:60;
    --ox:calc(100% - 44px);              /* the burger's centre */
    --oy:37px;
    visibility:hidden;
    transition:visibility 0s 1.1s;
  }
  .menu.open{visibility:visible;transition-delay:0s}

  .sweep,.menu-inner{
    position:absolute;inset:0;
    clip-path:circle(0px at var(--ox) var(--oy));
    transition:clip-path .8s cubic-bezier(.22,1,.36,1);
  }
  .menu.open .sweep,.menu.open .menu-inner{
    clip-path:circle(170% at var(--ox) var(--oy));
  }
  .sweep-1{background:var(--blue)}
  .sweep-2{background:var(--blue-light)}
  .menu-inner{
    background:var(--sky);
    display:flex;flex-direction:column;
    align-items:flex-start;justify-content:center;
    gap:14px;padding:0 30px;
  }

  /* opening order: deep blue first, panel last */
  .menu.open .sweep-1  {transition-delay:0s}
  .menu.open .sweep-2  {transition-delay:.15s}
  .menu.open .menu-inner{transition-delay:.3s}
  /* closing order: panel collapses first, deep blue last */
  .menu .menu-inner{transition-delay:0s}
  .menu .sweep-2{transition-delay:.15s}
  .menu .sweep-1{transition-delay:.3s}

  .menu a{
    color:var(--ink);text-decoration:none;
    font-weight:300;font-size:clamp(30px,9vw,46px);
    line-height:1.25;letter-spacing:-0.03em;
    opacity:0;transform:translateY(18px);
    transition:opacity .45s ease,transform .55s cubic-bezier(.22,1,.36,1);
  }
  .menu.open a{opacity:1;transform:none;transition-delay:var(--d,0s)}
  .menu.open a:nth-of-type(1){--d:.80s}
  .menu.open a:nth-of-type(2){--d:.88s}
  .menu.open a:nth-of-type(3){--d:.96s}
  .menu.open a:nth-of-type(4){--d:1.04s}
  .menu.open .cta{--d:1.14s}
  .menu .cta{margin-top:26px;font-size:20px;height:50px;padding:10px 40px;
    border-width:3px;border-radius:999px}
  .menu .cta .ink{border-radius:999px}

  /* ── CTA: variant A — magnetic + directional ink ──────────────────── */
  .cta{
    position:relative;
    display:inline-flex;align-items:center;justify-content:center;
    height:calc(50 * var(--u));
    padding:calc(10 * var(--u)) calc(50 * var(--u));
    border:calc(3 * var(--u)) solid var(--blue);
    border-radius:calc(999 * var(--u));    /* a stadium at every size */
    background:transparent;
    font-family:inherit;font-weight:300;
    font-size:calc(20 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
    color:var(--ink);text-decoration:none;
    cursor:pointer;overflow:hidden;flex:none;
    will-change:transform;
    -webkit-tap-highlight-color:transparent;
  }
  .cta .label{position:relative;z-index:2;white-space:nowrap;transition:color .3s ease;will-change:transform}
  .cta .ink{
    position:absolute;inset:0;z-index:1;
    background:var(--blue);
    border-radius:calc(999 * var(--u));
    transform:translate(0,101%);
    transition:transform .5s cubic-bezier(.22,1,.36,1);
  }
  .cta:hover .ink,.cta:focus-visible .ink{transform:translate(0,0)}
  .cta:hover .label,.cta:focus-visible .label{color:var(--white)}
  .cta:focus-visible{outline:none;box-shadow:0 0 0 calc(4 * var(--u)) rgba(26,78,152,.28)}

  /* ── hero body ────────────────────────────────────────────────────── */
  .hero-body{
    position:relative;
    padding:calc(120 * var(--u)) calc(115 * var(--u)) calc(60 * var(--u));
  }
  .hero-copy{width:calc(659 * var(--u))}

  /* H1 — 48, the same as a section heading like "How it works?". It was 64,
     which made every page open on a shout; at the section size the title
     sits in the same scale as the rest of the page instead of above it.
     The nowrap line "Brand systems that last." shrinks with it, so the box
     goes back to the 659 column the paragraph was drawn on. */
  h1{
    margin:0;
    width:calc(659 * var(--u));
    font-size:calc(48 * var(--u));
    line-height:1.2;
    letter-spacing:-0.03em;
    font-weight:700;                       /* "Beyond visuals." */
  }
  h1 .l2{display:block;white-space:nowrap}
  /* A lead can be told where to break too: two blocks on a wide screen,
     so the line ends where the sentence pauses rather than where the box
     happens to run out. */
  .lead .l1,.lead .l2{display:block}
  h1 .tail{font-weight:300}                /* "that last." — measured Light */

  /* ── highlight + bracket, used at 64 / 48 / 40px ──────────────────────
     Everything is in em (derived from the 64px hero: 4/64, 28/64, 17/64…)
     so one component serves every size. Variants: --white / --sky / --sans */
  .hl{
    position:relative;display:inline-block;
    margin-right:.39em;                    /* clears the right bracket */
  }
  .hl mark{
    display:inline-block;
    background:var(--white);
    color:var(--ink);
    font-family:var(--font-display);
    font-style:italic;
    font-weight:100;                       /* Editorial Today Thin Italic */
    letter-spacing:-0.02em;
    line-height:1;
    padding:.03em .25em .07em;
  }
  /* Only where the box starts a line: it hangs left so the glyphs inside stay
     aligned with the line above. Mid-sentence this would collide with the
     preceding word, so it is opt-in. */
  .hl--hang{margin-left:-.36em}
  /* The negative margin and this padding cancel out, so the glyphs inside
     land exactly under the line above while the box bleeds left. The right
     side has to match it, or the word sits off-centre in its own box. */
  .hl--hang mark{padding-left:.36em;padding-right:.36em}

  .hl--sky mark{background:var(--sky)}
  .hl--sans{margin-right:0}                /* alone in a centred heading */
  .hl--sans mark{
    font-family:var(--font);font-style:normal;font-weight:700;
    letter-spacing:-0.03em;padding:.16em .5em .2em;
  }

  /* The two brackets are one shape used twice, so every number below is
     mirrored exactly: same width, same offset from the box, and the top
     overhang of one is the bottom overhang of the other. That makes both
     bars identical in length and sets the word the same distance from each
     of them. The bar lives in ::before so it can grow on its own while the
     dot pops, instead of the dot squashing along with a scaled parent. */
  .hl .rule{position:absolute;width:.0625em}
  .hl .rule::before{
    content:'';position:absolute;inset:0;
    background:var(--blue);
    transform-origin:50% 0;
  }
  .hl .rule-r::before{transform-origin:50% 100%}
  /* offset == the bar's own width, so the bar sits flush against the box
     with no seam of page showing between them */
  .hl .rule-l{left:-.0625em;top:-.4375em;bottom:-.03em}
  .hl .rule-r{right:-.0625em;top:-.03em;bottom:-.4375em}
  .hl .rule::after{                        /* dot capping the end of the rule */
    content:'';position:absolute;left:50%;
    width:.266em;height:.266em;
    border-radius:50%;background:var(--blue);
    transform:translateX(-50%);
  }
  .hl .rule-l::after{top:0}
  .hl .rule-r::after{bottom:0}

  /* paragraph — 645 wide · Montserrat Light 32 / 120% / -3% */
  .hero-cta{margin-top:calc(40 * var(--u))}

  /* An ordinary paragraph, at the body size the rest of the page uses. At 32
     it was a second headline and the two competed; the title should be the
     only thing at the top asking to be read first. */
  .lead{
    margin:calc(28 * var(--u)) 0 0;
    width:calc(645 * var(--u));
    font-weight:300;
    font-size:calc(20 * var(--u));
    line-height:1.45;
    letter-spacing:-0.03em;
  }

  /* ── the folder stage ─────────────────────────────────────────────── */
  .stage-fit{
    position:absolute;
    top:calc(30 * var(--u));
    right:calc(80 * var(--u));
    width:calc(560 * var(--u));
    aspect-ratio:780/660;
  }
  .stage{
    position:absolute;left:0;top:0;
    width:780px;height:660px;
    transform-origin:0 0;
    perspective:1400px;perspective-origin:50% 45%;
    touch-action:none;
  }

  .item{
    position:absolute;left:0;top:0;
    display:grid;place-items:center;
    cursor:grab;touch-action:none;
    will-change:transform,opacity;
    z-index:2;
  }
  .item.dragging{cursor:grabbing;z-index:20}
  .item img{width:100%;height:100%;display:block;pointer-events:none;-webkit-user-drag:none}
  .mb-outer,.mb-mid,.mb-inner{width:100%;height:100%;display:grid;place-items:center}
  .aa{font-weight:700;font-size:64px;line-height:1;color:var(--ink);letter-spacing:-0.03em;pointer-events:none}

  .folder{position:absolute;left:0;top:0;width:345px;height:265px;rotate:-9deg;transform-style:preserve-3d;will-change:transform}
  .folder svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
  .folder-back{filter:drop-shadow(0 16px 24px rgba(26,78,152,.34)) drop-shadow(0 3px 6px rgba(26,78,152,.22))}
  .folder-front{
    z-index:5;transform-origin:50% 100%;will-change:transform;
    filter:drop-shadow(0 -6px 14px rgba(26,78,152,.30)) drop-shadow(0 10px 20px rgba(26,78,152,.26));
  }
  .folder-glow{position:absolute;inset:0;z-index:4;border-radius:22px;box-shadow:0 0 0 0 rgba(255,255,255,0);transition:box-shadow .25s ease;pointer-events:none}
  .armed .folder-glow{box-shadow:0 0 0 6px rgba(255,255,255,.55)}
  .shadow{position:absolute;left:0;top:0;width:310px;height:40px;border-radius:50%;background:rgba(26,78,152,.30);filter:blur(19px);z-index:1;will-change:transform}

  /* ══ section 2 — "I believe your brand already has something to say" ══ */
  /* everything below the hero sits on one sheet, so the grid runs all the
     way down instead of stopping at the end of section 2 */
  .sheet{
    position:relative;
    z-index:1;                             /* the blue bumps hang over it */
    margin-top:calc(-24 * var(--u));       /* starts level with the cusps */
    background:var(--white);
    /* how far the ribbon rides up into section 2 */
    --ribbon-lift:calc(150 * var(--u));
    /* the grid runs one 100px block past that before it stops */
    --grid-end:calc(var(--ribbon-lift) - 100 * var(--u));
  }

  .believe{
    position:relative;
    display:grid;
    grid-template-columns:calc(716 * var(--u)) 1fr;
    /* stretch, so the board takes the height of the row rather than a fixed
       one: when the accordion opens the column grows and the picture grows
       with it, and the two still end level */
    align-items:stretch;
    /* must clear the ribbon's ride-up, otherwise the opened accordion grows
       straight into it — the section keeps that gap as the panel expands */
    padding-bottom:calc(var(--ribbon-lift) + 50 * var(--u));
  }
  /* the faint 100px grid — --sky, dialled down */
  .believe::before{
    content:'';
    position:absolute;
    inset:0 0 var(--grid-end) 0;
    margin-inline:var(--bleed);            /* the paper runs past the shell */
    background-image:
      linear-gradient(to right,rgba(199,225,253,.65) 1px,transparent 1px),
      linear-gradient(to bottom,rgba(199,225,253,.65) 1px,transparent 1px);
    background-size:calc(100 * var(--u)) calc(100 * var(--u));
    pointer-events:none;
  }
  .believe > *{position:relative}          /* content sits above the grid */

  /* left: the pinned mock-up board.
     The one thing inside the shell that still wants the screen edge — it is
     a cropped photograph, and stopping it short would leave a white gutter
     exactly where the crop is supposed to run out of frame. The negative
     margin reaches back out; the grid column is unchanged, so the box just
     grows leftward and object-fit:cover shows more picture. */
  .board{
    /* the drawn height when nothing is open; past that it follows the row */
    min-height:calc(811 * var(--u));
    margin-left:var(--bleed);
    overflow:hidden;
    background:#DBDBD4;
  }
  .board img{
    width:100%;height:100%;
    /* the source is landscape, the column is portrait — centre keeps all
       four pinned cards inside the crop */
    object-fit:cover;object-position:center;
    display:block;
    transform:scale(1.04);
    transition:transform 1.6s cubic-bezier(.22,1,.36,1);
  }
  .board.in img{transform:scale(1)}

  .believe-copy{
    padding:calc(198 * var(--u)) calc(115 * var(--u)) 0 calc(124 * var(--u));
  }

  /* Montserrat Light 32 / 120% / -3%, with Editorial Today 40 inside */
  .say{
    margin:0;
    font-weight:300;
    font-size:calc(32 * var(--u));
    line-height:1.2;
    letter-spacing:-0.03em;
  }
  /* 40px box inside a 32px line: negative vertical margins keep it from
     stretching the line box, so the two lines stay evenly spaced */
  .say .hl{
    font-size:calc(40 * var(--u));
    margin-top:calc(-5 * var(--u));
    margin-bottom:calc(-5 * var(--u));
  }

  /* Montserrat Regular 20 / 120% / -3% */
  .body-copy{
    margin:calc(34 * var(--u)) 0 0;
    max-width:calc(470 * var(--u));
    font-weight:400;
    font-size:calc(20 * var(--u));
    line-height:1.2;
    letter-spacing:-0.03em;
  }

  /* ── the "Sound familiar?" accordion ──────────────────────────────── */
  .acc{
    margin-top:calc(48 * var(--u));
    width:calc(485 * var(--u));
    background:var(--white);
    border:calc(2 * var(--u)) solid var(--sky);
    border-radius:calc(14 * var(--u));
    transition:border-color .35s ease,box-shadow .35s ease;
  }
  .acc[data-open]{
    border-color:var(--blue);
    box-shadow:0 0 0 calc(1 * var(--u)) var(--blue) inset;   /* reads as 3px, no reflow */
  }
  .acc:hover{border-color:var(--blue)}

  .acc-head{
    width:100%;
    display:flex;align-items:center;justify-content:space-between;
    gap:calc(20 * var(--u));
    padding:calc(14 * var(--u)) calc(26 * var(--u));
    background:none;border:0;
    font-family:var(--font-display);
    font-style:italic;font-weight:100;
    font-size:calc(40 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
    color:var(--ink);
    text-align:left;cursor:pointer;
  }
  .acc-head:focus-visible{outline:calc(3 * var(--u)) solid var(--blue);outline-offset:calc(2 * var(--u))}

  /* the + that rotates into an × */
  .sign{position:relative;flex:none;width:calc(26 * var(--u));height:calc(26 * var(--u));
    transition:transform .45s cubic-bezier(.22,1,.36,1)}
  .sign::before,.sign::after{
    content:'';position:absolute;left:50%;top:50%;
    width:calc(26 * var(--u));height:calc(2.4 * var(--u));
    background:var(--ink);border-radius:2px;
    transform:translate(-50%,-50%);
  }
  .sign::after{transform:translate(-50%,-50%) rotate(90deg)}
  .acc[data-open] .sign{transform:rotate(135deg)}

  /* 0fr → 1fr animates to the content's own height, no magic max-height */
  .acc-panel{
    display:grid;grid-template-rows:0fr;
    transition:grid-template-rows .5s cubic-bezier(.22,1,.36,1);
  }
  .acc[data-open] .acc-panel{grid-template-rows:1fr}
  .acc-panel > div{overflow:hidden}
  .acc-inner{
    padding:0 calc(26 * var(--u)) calc(26 * var(--u));
    opacity:0;transform:translateY(calc(-8 * var(--u)));
    transition:opacity .35s ease .08s,transform .45s cubic-bezier(.22,1,.36,1) .08s;
  }
  .acc[data-open] .acc-inner{opacity:1;transform:none}

  .acc-inner ul{margin:0;padding:0 0 0 calc(22 * var(--u));list-style:none}
  .acc-inner li{
    position:relative;
    font-weight:300;font-size:calc(20 * var(--u));line-height:1.2;letter-spacing:-0.03em;
    margin-bottom:calc(24 * var(--u));
  }
  .acc-inner li::before{
    content:'';position:absolute;left:calc(-16 * var(--u));top:calc(9 * var(--u));
    width:calc(4 * var(--u));height:calc(4 * var(--u));
    border-radius:50%;background:var(--ink);
  }
  .acc-inner p{
    margin:calc(26 * var(--u)) 0 0;
    font-weight:300;font-size:calc(20 * var(--u));line-height:1.2;letter-spacing:-0.03em;
  }

  /* ── the services ribbon: text riding a wave, drifting left ───────── */
  .ribbon{
    position:relative;z-index:4;
    margin:calc(0px - var(--ribbon-lift)) 0 0;
    overflow:hidden;
    pointer-events:none;
  }
  .ribbon svg{display:block;width:100%}
  .ribbon text{
    font-family:var(--font-display);
    font-style:italic;font-weight:100;
    font-size:38px;                       /* user units — scales with the viewBox */
    letter-spacing:-0.02em;
    fill:var(--ink);
  }

  /* ── "How it works?" ──────────────────────────────────────────────── */
  .how{
    padding:calc(120 * var(--u)) 0 calc(150 * var(--u));
    text-align:center;
    /* the stamp hangs past its card, and before it lands it waits big and
       invisible — on a phone that widened the whole page by 35px, which
       zoomed everything out. clip, not hidden: nothing here scrolls. */
    overflow-x:clip;
  }
  .how h2{
    margin:0;
    font-size:calc(48 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
  }

  /* ── the three steps ──────────────────────────────────────────────── */
  .steps{
    position:relative;
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:calc(52 * var(--u));
    align-items:start;
    margin-top:calc(150 * var(--u));       /* not the shorthand — it would
                                              reset the shell's auto sides */
    padding:0 calc(79 * var(--u));
    text-align:left;
  }

  .step{
    position:relative;
    background:var(--white);
    border:calc(2 * var(--u)) solid var(--sky);
    border-radius:calc(14 * var(--u));
    cursor:pointer;
    transition:border-color .3s ease,box-shadow .3s ease;
  }
  .step:hover,.step[data-open]{
    border-color:var(--blue);
    box-shadow:0 0 0 calc(1 * var(--u)) var(--blue) inset;
  }

  .step-head{
    display:flex;align-items:center;
    gap:calc(12 * var(--u));
    min-height:calc(80 * var(--u));
    padding:0 calc(16 * var(--u)) 0 calc(22 * var(--u));
    background:none;border:0;width:100%;
    font:inherit;color:inherit;text-align:left;cursor:pointer;
  }
  .step-head:focus-visible{outline:calc(3 * var(--u)) solid var(--blue);outline-offset:calc(3 * var(--u))}

  /* The folder rides above the card's top edge. On hover it lifts and tips,
     and its pattern floods up from the bottom — the same ink move as the CTA,
     rather than a flat cross-fade. */
  .step-fold{
    position:relative;flex:none;
    width:calc(82 * var(--u));height:calc(68 * var(--u));
    margin-top:calc(-11 * var(--u));
  }
  .step-fold img,.dsk-fold img{position:absolute;inset:0;width:100%;height:100%;display:block;object-fit:contain}
  /* The pattern blooms in as a handful of soft blobs that spread and merge,
     so it arrives shaped rather than as a straight edge sweeping up. Each
     blob ends at a different size, so they land at different moments. */
  .step-fold .fold-patt,
  .dsk-fold .fold-patt{
    --blob:radial-gradient(circle,#000 42%,rgba(0,0,0,0) 72%);
    -webkit-mask-image:var(--blob),var(--blob),var(--blob),var(--blob),var(--blob);
            mask-image:var(--blob),var(--blob),var(--blob),var(--blob),var(--blob);
    -webkit-mask-repeat:no-repeat;  mask-repeat:no-repeat;
    -webkit-mask-position:26% 72%, 70% 34%, 44% 16%, 84% 82%, 12% 34%;
            mask-position:26% 72%, 70% 34%, 44% 16%, 84% 82%, 12% 34%;
    -webkit-mask-size:0% 0%,0% 0%,0% 0%,0% 0%,0% 0%;
            mask-size:0% 0%,0% 0%,0% 0%,0% 0%,0% 0%;
    transition:-webkit-mask-size 1s cubic-bezier(.33,1,.42,1),
                       mask-size 1s cubic-bezier(.33,1,.42,1);
  }
  .step:hover .fold-patt,.step[data-open] .fold-patt,
  .dsk-folder:hover .fold-patt,.dsk-folder:focus-visible .fold-patt{
    -webkit-mask-size:170% 170%,150% 150%,135% 135%,160% 160%,145% 145%;
            mask-size:170% 170%,150% 150%,135% 135%,160% 160%,145% 145%;
  }

  /* The step's number, sitting astride the card's top edge as the design
     sheet has it: filled at rest, and turning to sky the moment the card
     wakes, so it moves with the border and the folder rather than after
     them. Written in the house hand — it is an aside, not a label. */
  .step-n{
    position:absolute;top:0;right:calc(20 * var(--u));
    translate:0 -50%;
    width:calc(53 * var(--u));height:calc(53 * var(--u));
    display:grid;place-items:center;
    border-radius:50%;
    background:var(--blue);color:var(--white);
    font-family:var(--font-note);
    font-size:calc(30 * var(--u));line-height:1;
    pointer-events:none;
    transition:background-color .3s ease,color .3s ease;
  }
  .step:hover .step-n,.step[data-open] .step-n{
    background:var(--sky);color:var(--blue);
  }

  /* Editorial Today Thin Italic 32 / 120% / -3% */
  .step-title{
    font-family:var(--font-display);
    font-style:italic;font-weight:100;
    font-size:calc(32 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
    /* one line, as the design sheet has it. "We find the system." needs
       253u and used to get 247, so it broke in two on every screen; the
       head now leaves it 257. nowrap is only the guard — a phone, where
       the card is narrow, lets it break again below. */
    white-space:nowrap;
  }


  .step-panel{
    display:grid;grid-template-rows:0fr;
    transition:grid-template-rows .5s cubic-bezier(.22,1,.36,1);
  }
  .step[data-open] .step-panel{grid-template-rows:1fr}
  .step-panel > div{overflow:hidden}

  /* Montserrat Light 20 / 120% / -3% */
  .step-body{
    padding:calc(4 * var(--u)) calc(26 * var(--u)) calc(26 * var(--u));
    font-weight:300;
    font-size:calc(20 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
    opacity:0;transform:translateY(calc(-6 * var(--u)));
    transition:opacity .35s ease .08s,transform .45s cubic-bezier(.22,1,.36,1) .08s;
  }
  .step[data-open] .step-body{opacity:1;transform:none}

  .steps .arrow{
    position:absolute;top:calc(-74 * var(--u));
    width:calc(131 * var(--u));
    pointer-events:none;
  }
  .steps .arrow-1{left:calc(33.33% - 66 * var(--u))}
  .steps .arrow-2{left:calc(66.66% - 66 * var(--u))}

  /* "You get a stamp." — so the card gets stamped. The mark waits above the
     paper, big and tilted, and comes down as the card opens: quick, with a
     little rebound, the way a rubber stamp bites and settles. It lands on
     the card's bottom line, hooked over the corner the way the design
     sheet has it — a third inside, the rest hanging below and a little
     past the edge. It leaves again the moment the card closes. */
  .step .seal{
    position:absolute;
    right:calc(-16 * var(--u));bottom:calc(-64 * var(--u));
    width:calc(96 * var(--u));
    pointer-events:none;
    opacity:0;
    transform:rotate(-17deg) scale(1.9);
    transition:opacity .16s ease,
               transform .3s cubic-bezier(.3,1.5,.5,1);
  }
  .step[data-open] .seal{
    opacity:1;
    transform:rotate(-7deg) scale(1);
    transition-delay:.26s;               /* the panel is on its way open */
  }
  /* The stamp hangs off the bottom line now, so the card no longer keeps a
     124u band for it inside — only enough that its upper third never sits
     on the last line of the copy. */
  .step:has(.seal) .step-body{padding-bottom:calc(40 * var(--u))}

  /* Every note stands on the same floor: app.js measures the tallest and
     hands it over as --step-body, so whichever cards are open end level,
     and each still opens with its own motion rather than snapping to a
     taller neighbour's height. */
  .step-body{box-sizing:border-box;min-height:var(--step-body,0)}

  /* ══ section 4 — the work strips ══════════════════════════════════════
     Two full-bleed rows of stills drifting in opposite directions. Each
     still is a link into that project's page, so the rows stop on hover —
     otherwise you would be chasing a moving target.                      */
  .work{
    padding:calc(40 * var(--u)) 0 calc(130 * var(--u));
    display:grid;
    gap:calc(20 * var(--u));
  }
  .strip{overflow:hidden}
  .track{
    display:flex;
    width:max-content;
    will-change:transform;
    animation:drift-left var(--dur,58s) linear infinite;
  }
  .strip--right .track{animation-name:drift-right}
  .strip:hover .track,.track:focus-within{animation-play-state:paused}

  /* the run is cloned once, so half a lap is exactly one full set */
  @keyframes drift-left {from{transform:translate3d(0,0,0)}      to{transform:translate3d(-50%,0,0)}}
  @keyframes drift-right{from{transform:translate3d(-50%,0,0)}   to{transform:translate3d(0,0,0)}}

  .tile{
    position:relative;
    flex:none;
    display:block;
    width:calc(var(--w,314) * var(--u));
    height:calc(372 * var(--u));
    background:var(--c,#DEDEDE) center/cover no-repeat;
    overflow:hidden;
    text-decoration:none;
  }
  .tile img{width:100%;height:100%;object-fit:cover;display:block;
    transition:transform .8s cubic-bezier(.22,1,.36,1)}
  .tile:hover img{transform:scale(1.05)}

  /* the caption rises out of the bottom edge on hover */
  .tile .cap{
    position:absolute;left:0;right:0;bottom:0;
    padding:calc(46 * var(--u)) calc(22 * var(--u)) calc(18 * var(--u));
    background:linear-gradient(transparent,rgba(26,78,152,.86));
    color:var(--white);
    font-weight:300;font-size:calc(20 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
    opacity:0;transform:translateY(calc(14 * var(--u)));
    transition:opacity .4s ease,transform .5s cubic-bezier(.22,1,.36,1);
  }
  .tile .cap b{display:block;font-weight:700;font-size:calc(26 * var(--u));margin-bottom:calc(6 * var(--u))}
  .tile:hover .cap,.tile:focus-visible .cap{opacity:1;transform:none}
  .tile:focus-visible{outline:calc(4 * var(--u)) solid var(--blue);outline-offset:calc(-4 * var(--u))}

  /* the sixth slot is an invitation, not a case study — so it reads
     as an empty frame waiting to be filled rather than a project. */
  .tile--open{
    background:transparent;
    border:calc(3 * var(--u)) dashed var(--blue);
    display:grid;align-content:center;
    padding:calc(30 * var(--u));
  }
  .tile--open .open-in{
    color:var(--ink);font-weight:300;
    font-size:calc(20 * var(--u));line-height:1.25;letter-spacing:-0.03em;
  }
  .tile--open .open-in b{
    display:block;margin-top:calc(14 * var(--u));
    font-family:var(--font-display);font-style:italic;font-weight:100;
    font-size:calc(34 * var(--u));letter-spacing:-0.02em;
  }
  .tile--open:hover{background:var(--white)}

  @media (prefers-reduced-motion:reduce){
    .track{animation:none}
    .strip{overflow-x:auto}
  }

  /* ══ section 5 — services ═════════════════════════════════════════════
     The scalloped edge is Group 17.png driven as a 9-slice border-image.
     Its bumps repeat on a 12px pitch, so `round` tiles them at a constant
     size whatever the card grows to — no stretching, no distortion.      */
  .services{padding:calc(40 * var(--u)) calc(115 * var(--u)) calc(150 * var(--u));text-align:center}
  .services h2{
    margin:0;
    font-size:calc(48 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
  }
  .svc-grid{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:calc(60 * var(--u));
    margin-top:calc(120 * var(--u));
    text-align:left;
  }

  /* A still and its name, the way a menu card is set: the picture is the
     whole card, upright, with its corners taken off, and the name sits on
     it as a soft tab along the foot. Nothing framing it and nothing behind
     it — the photograph is the card. It shares the portfolio tile's 4:5,
     so the two kinds of card belong to the same set. */
  .svc{display:block;color:var(--ink);text-decoration:none}
  .svc-card{
    position:relative;display:block;overflow:hidden;
    aspect-ratio:4 / 5;
    border-radius:calc(20 * var(--u));
    background:#EAF1F9;                    /* the empty plate */
    box-shadow:0 calc(10 * var(--u)) calc(26 * var(--u)) rgba(26,78,152,.10);
    transition:transform .5s var(--spring),box-shadow .4s ease;
    will-change:transform;
  }
  .svc:hover .svc-card,.svc:focus-visible .svc-card{
    transform:translateY(calc(-9 * var(--u)));
    box-shadow:0 calc(26 * var(--u)) calc(48 * var(--u)) rgba(26,78,152,.22);
  }
  .svc:focus-visible{outline:none}
  .svc:focus-visible .svc-card{
    outline:calc(3 * var(--u)) solid var(--blue);outline-offset:calc(4 * var(--u));
  }

  /* Empty, it is a plain plate with the file it is waiting for written on
     it; swap the text for <img> and nothing else has to change. */
  .svc-shot{
    position:absolute;inset:0;
    display:grid;place-items:center;
    padding:calc(18 * var(--u));
    color:rgba(26,78,152,.45);
    font-size:calc(15 * var(--u));letter-spacing:-0.03em;text-align:center;
  }
  .svc-shot img{width:100%;height:100%;object-fit:cover;display:block}

  /* the tab across the foot — it sits on the picture, not beside it */
  .svc-title{
    position:absolute;left:calc(18 * var(--u));right:calc(18 * var(--u));
    bottom:calc(18 * var(--u));
    background:var(--sky);
    border-radius:calc(999 * var(--u));
    padding:calc(15 * var(--u)) calc(26 * var(--u)) calc(17 * var(--u));
    font-weight:300;
    font-size:calc(24 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
  }

  /* on the services page the grid is the contents, so it sits in tighter */
  .svc-grid--page{margin-top:calc(10 * var(--u));margin-bottom:calc(80 * var(--u))}

  /* ══ footer ═══════════════════════════════════════════════════════════
     Same scallop as the hero, mirrored: the circle now sits below the band
     so the bumps push up into the white instead of hanging down.         */
  .foot{
    position:relative;
    background:var(--blue);
    color:var(--white);
    padding:calc(150 * var(--u)) calc(115 * var(--u)) calc(40 * var(--u));
    -webkit-mask:
      linear-gradient(#000,#000) bottom/100% calc(100% - 24 * var(--u)) no-repeat,
      radial-gradient(circle calc(42.88 * var(--u)) at 50% calc(42.88 * var(--u)),#000 100%,transparent 0)
        top left/calc(77 * var(--u)) calc(24 * var(--u)) repeat-x;
            mask:
      linear-gradient(#000,#000) bottom/100% calc(100% - 24 * var(--u)) no-repeat,
      radial-gradient(circle calc(42.88 * var(--u)) at 50% calc(42.88 * var(--u)),#000 100%,transparent 0)
        top left/calc(77 * var(--u)) calc(24 * var(--u)) repeat-x;
  }

  /* Montserrat 48 / 131% / -3% / centred. "Structure" is the only Bold run —
     measured 6.6px stems against 2px on the rest of the line. */
  .foot-h{
    margin:0 auto;
    max-width:calc(1150 * var(--u));
    text-align:center;
    font-weight:300;
    font-size:calc(48 * var(--u));
    line-height:1.31;
    letter-spacing:-0.03em;
  }
  .foot-h b{font-weight:700}
  .foot-h .l1,.foot-h .l2{display:block;white-space:nowrap}

  /* White box, blue type — and here the display face is upright Bold, not
     the thin italic used elsewhere. Brackets are --sky, because white ones
     would dissolve into the white box behind them. */
  .hl--invert mark{
    background:var(--white);
    color:var(--blue);
    font-style:normal;
    font-weight:700;
    letter-spacing:-0.01em;
  }
  .hl--invert .rule::before,.hl--invert .rule::after{background:var(--sky)}

  /* It ends a centred line, so the trailing bracket margin would throw the
     whole line off-centre. */
  .foot-h .hl{margin-right:0;margin-left:.1em}
  /* Here the bracket sits directly under the line above, not out in the
     margin like the hero, so its reach is pulled back inside the leading —
     131% simply has no room for the full 0.44em overhang. */
  .foot-h .hl mark{padding-top:.09em;padding-bottom:.13em}
  /* shorter here, and mirrored the same way as the base pair */
  .foot-h .hl .rule-l{top:-.19em}
  .foot-h .hl .rule-r{bottom:-.19em}
  .foot-h .hl .rule::after{width:.2em;height:.2em}

  /* ── testimonials ─────────────────────────────────────────────────── */
  .tstm{
    display:grid;
    grid-template-columns:calc(340 * var(--u)) 1fr;
    gap:calc(56 * var(--u));
    align-items:center;
    max-width:calc(1056 * var(--u));
    min-height:calc(465 * var(--u));
    margin:calc(120 * var(--u)) auto 0;
    padding:calc(46 * var(--u));
    border:1px solid rgba(255,255,255,.55);
  }

  .tstm-photo{
    aspect-ratio:4/5;
    background:rgba(255,255,255,.12);
    border:1px solid rgba(255,255,255,.4);
    display:grid;place-items:center;
    font-size:calc(14 * var(--u));letter-spacing:0;
    color:rgba(255,255,255,.62);text-align:center;padding:calc(16 * var(--u));
  }
  .tstm-photo img{width:100%;height:100%;object-fit:cover;display:block}
  .foot-side p a{color:inherit;text-decoration:none;border-bottom:1px solid rgba(255,255,255,.4)}
  .foot-side p a:hover{border-bottom-color:var(--white)}

  .tstm-contact{margin-top:calc(22 * var(--u));display:grid;gap:calc(7 * var(--u))}
  .tstm-contact a{
    color:var(--white);text-decoration:none;
    font-weight:300;font-size:calc(18 * var(--u));letter-spacing:-0.03em;
    position:relative;width:fit-content;
  }
  .tstm-contact a::after{
    content:'';position:absolute;left:0;right:0;bottom:calc(-2 * var(--u));
    height:1px;background:currentColor;
    transform:scaleX(0);transform-origin:left;
    transition:transform .34s cubic-bezier(.22,1,.36,1);
  }
  .tstm-contact a:hover::after,.tstm-contact a:focus-visible::after{transform:scaleX(1)}

  /* the quotes roll through one after another */
  .tstm-stage{position:relative;display:grid;align-content:center;min-height:calc(300 * var(--u))}
  .quote{
    grid-area:1/1;
    /* a <figure> carries 16px/40px of its own by default, which pushed the
       quote 40px clear of the dots that belong under it */
    margin:0;
    opacity:0;visibility:hidden;
    transform:translateY(calc(26 * var(--u)));
    transition:opacity .55s ease,transform .7s cubic-bezier(.22,1,.36,1),visibility 0s .7s;
  }
  .quote.on{opacity:1;visibility:visible;transform:none;transition-delay:0s,0s,0s}
  .quote.out{transform:translateY(calc(-26 * var(--u)))}
  .quote blockquote{
    margin:0;
    font-family:var(--font-display);font-style:italic;font-weight:100;
    font-size:calc(32 * var(--u));line-height:1.28;letter-spacing:-0.02em;
  }
  .quote figcaption{
    margin-top:calc(26 * var(--u));
    font-weight:300;font-size:calc(18 * var(--u));letter-spacing:-0.03em;
    opacity:.78;
  }

  /* ── moving between the quotes ──────────────────────────────────────
     The bars used to be the whole control: 3 tall, and nothing about them
     said they could be pressed. They stay, because they are the only thing
     that shows how long is left — but the arrows are now the obvious
     handle, and each bar carries transparent padding so a finger has
     something to land on without the bar itself getting fatter. */
  .tstm-nav{
    display:flex;align-items:center;gap:calc(16 * var(--u));
    margin-top:calc(30 * var(--u));
  }
  .tstm-arrow{
    flex:none;
    width:calc(44 * var(--u));height:calc(44 * var(--u));
    display:grid;place-items:center;
    padding:0;border-radius:50%;cursor:pointer;
    border:calc(1.5 * var(--u)) solid rgba(255,255,255,.55);
    background:transparent;color:var(--white);
    transition:background .28s ease,border-color .28s ease,transform .28s var(--spring);
  }
  .tstm-arrow svg{width:calc(17 * var(--u));height:calc(17 * var(--u));display:block}
  .tstm-arrow:hover{background:rgba(255,255,255,.16);border-color:var(--white)}
  .tstm-arrow:active{transform:scale(.93)}
  .tstm-arrow:focus-visible{outline:calc(2 * var(--u)) solid var(--white);outline-offset:calc(3 * var(--u))}

  .tstm-count{
    margin-left:auto;
    font-weight:300;font-size:calc(15 * var(--u));letter-spacing:-0.02em;
    color:rgba(255,255,255,.7);font-variant-numeric:tabular-nums;
  }

  .tstm-dots{display:flex;gap:calc(2 * var(--u))}
  /* The button is only the target: transparent padding a finger can land
     on. The line is its own element inside, so the line's shape never
     depends on the button's box — a radius on the padded button used to
     come out as pointed, lens-shaped ends with a square fill in them. */
  .tstm-dots button{
    display:block;
    padding:calc(14 * var(--u)) calc(4 * var(--u));
    border:0;background:none;cursor:pointer;
  }
  .tstm-line{
    display:block;
    width:calc(46 * var(--u));height:calc(3 * var(--u));
    border-radius:99px;overflow:hidden;
    background:rgba(255,255,255,.32);
    transition:background-color .25s ease;
  }
  .tstm-dots button:hover .tstm-line{background-color:rgba(255,255,255,.6)}
  .tstm-dots button:focus-visible{
    outline:calc(2 * var(--u)) solid var(--white);outline-offset:0;
    border-radius:calc(6 * var(--u));
  }
  .tstm-fill{
    display:block;height:100%;width:100%;background:var(--white);
    transform:scaleX(0);transform-origin:left;
  }
  .tstm-dots button[aria-current="true"] .tstm-fill{
    animation:tick var(--hold,7s) linear forwards;
  }
  .tstm:hover .tstm-dots button[aria-current="true"] .tstm-fill{animation-play-state:paused}
  @keyframes tick{from{transform:scaleX(0)}to{transform:scaleX(1)}}

  /* ── sign-off ─────────────────────────────────────────────────────── */
  .foot-end{
    display:grid;
    grid-template-columns:1fr auto;
    align-items:end;
    gap:calc(40 * var(--u));
    margin-top:calc(130 * var(--u));
  }
  /* The full stamp, wordmark and all, drawn into the artwork. Big enough
     that the ring of type is actually readable — it is the wordmark now. */
  /* Shrink to the stamp. As a plain grid item it stretched the full column
     — 725px wide against a 196px stamp — which put its label out over empty
     space and made half the footer a hit area for "back to top". */
  .foot-mark{
    display:inline-flex;align-items:center;text-decoration:none;
    width:max-content;justify-self:start;
  }
  /* the same drawn turn as the curtain's seal — see .ld-logo */
  .foot-mark img{
    height:calc(196 * var(--u));width:auto;display:block;
  }

  .foot-side{text-align:right;display:grid;gap:calc(22 * var(--u));justify-items:end}
  .foot-side p{
    margin:0;max-width:calc(430 * var(--u));
    font-weight:300;font-size:calc(24 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
  }
  .foot .cta{border-color:var(--white);color:var(--white)}
  .foot .cta .ink{background:var(--white)}
  .foot .cta:hover .label,.foot .cta:focus-visible .label{color:var(--blue)}

  .foot-bar{
    display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
    gap:calc(16 * var(--u));
    margin-top:calc(70 * var(--u));
    padding-top:calc(22 * var(--u));
    border-top:1px solid rgba(255,255,255,.28);
    font-size:calc(16 * var(--u));letter-spacing:-0.03em;
    color:rgba(255,255,255,.8);
  }
  .foot-bar nav{display:flex;gap:calc(26 * var(--u))}
  .foot-bar a{color:inherit;text-decoration:none}
  .foot-bar a:hover,.foot-bar a:focus-visible{color:var(--white)}

  /* ══ the dock ═════════════════════════════════════════════════════════
     The macOS Dock, borrowed for "elsewhere": a frosted pill of app tiles
     that swell under the pointer and name themselves in a floating label.

     Two transforms, deliberately split. The anchor carries the sideways
     shove that makes room for whichever tile is growing; the tile inside
     carries the scale. Keeping them apart leaves the label — a pseudo of
     the anchor — unscaled and readable, while still sliding along with
     the icon it belongs to. The numbers come from app.js ("the dock").  */
  .dock{
    position:relative;                  /* the tiles measure their x off it */
    display:flex;align-items:flex-end;
    gap:calc(12 * var(--u));
    /* Wide enough that the spread tiles never reach the glass edge: the
       whole row grows by ~44u at most, half of it to each side. */
    padding:calc(10 * var(--u)) calc(32 * var(--u));
    border-radius:calc(26 * var(--u));
    background:rgba(255,255,255,.15);
    border:1px solid rgba(255,255,255,.3);
    box-shadow:0 calc(12 * var(--u)) calc(34 * var(--u)) rgba(0,0,0,.22),
               inset 0 1px 0 rgba(255,255,255,.35);
    -webkit-backdrop-filter:blur(calc(16 * var(--u))) saturate(150%);
            backdrop-filter:blur(calc(16 * var(--u))) saturate(150%);
    --tip-gap:calc(36 * var(--u));      /* labels clear the tallest tile */
  }
  /* The label stands 36u clear of a tile that has already grown 28u, so the
     dock asks for more room above it than the footer's own 22u rhythm.

     And it hangs: the glass keeps its padding so a magnified tile never
     touches the edge, but that padding is not part of the reading edge.
     Pulling it out by exactly that inset puts the last icon on the same
     line as the address above it and the button below it — the glass
     bleeds into the margin instead, the way hung punctuation does. */
  .foot-side .dock{
    margin-top:calc(52 * var(--u));
    margin-right:calc(-32 * var(--u) - 1px);   /* glass padding + its border */
  }

  .dock-app{
    /* an <a> for the links, a <button> for Notes — same shape either way */
    appearance:none;-webkit-appearance:none;
    border:0;margin:0;padding:0;background:none;color:inherit;font:inherit;
    display:block;line-height:0;text-decoration:none;cursor:pointer;
    -webkit-tap-highlight-color:transparent;
    transition:transform .16s cubic-bezier(.22,1,.36,1);
  }
  /* Every tile is a finished app icon — its own ground, its own corners,
     artwork edge to edge — so the tile itself is only what casts the
     shadow and what the pointer magnifies. The clip rides on the artwork
     rather than here: the tile has to stay open for the unread badge,
     which hangs over its corner. */
  .dock-tile{
    position:relative;                   /* the unread badge hangs off it */
    display:block;
    width:calc(56 * var(--u));height:calc(56 * var(--u));
    border-radius:calc(13 * var(--u));   /* 22.4% — the Big Sur icon radius */
    box-shadow:0 calc(3 * var(--u)) calc(9 * var(--u)) rgba(0,0,0,.26);
    transform-origin:50% 100%;           /* grows up off the dock floor */
    transition:transform .16s cubic-bezier(.22,1,.36,1);
    will-change:transform;
  }
  .dock-tile img{
    display:block;width:100%;height:100%;
    border-radius:inherit;
  }

  /* the divider before the last group, as the Dock keeps before the bin */
  .dock-sep{
    align-self:stretch;width:max(1px,calc(1.5 * var(--u)));
    margin:calc(4 * var(--u)) calc(6 * var(--u));
    border-radius:1px;
    background:rgba(255,255,255,.6);
  }

  .dock-app:focus-visible{outline:none}
  .dock-app:focus-visible .dock-tile{
    box-shadow:0 0 0 calc(3 * var(--u)) var(--white),
               0 calc(3 * var(--u)) calc(9 * var(--u)) rgba(0,0,0,.26);
  }

  /* The launch bounce. It rides the `translate` property so it can play on
     top of the scale that JS is writing into `transform`. */
  .dock-tile.jump{animation:dock-jump .62s cubic-bezier(.3,.9,.4,1)}
  @keyframes dock-jump{
    0%,100%{translate:0 0}
    30%    {translate:0 calc(-20 * var(--u))}
    58%    {translate:0 0}
    76%    {translate:0 calc(-7 * var(--u))}
  }

  /* ── the floating label ────────────────────────────────────────────
     A general component: put data-tip on anything. It sits --tip-gap above
     the element, so inside the dock every label lines up at one height
     instead of riding up with whichever tile just grew.                 */
  [data-tip]{position:relative}
  [data-tip]::before,[data-tip]::after{
    position:absolute;left:50%;
    pointer-events:none;opacity:0;
    transition:opacity .16s ease,transform .3s var(--spring);
  }
  [data-tip]::after{
    content:attr(data-tip);
    bottom:calc(100% + var(--tip-gap,calc(12 * var(--u))));
    transform:translate(-50%,calc(6 * var(--u))) scale(.94);
    transform-origin:50% 130%;
    white-space:nowrap;
    padding:calc(5 * var(--u)) calc(14 * var(--u));
    border-radius:calc(8 * var(--u));
    background:#F3F3F3;
    border:1px solid rgba(0,0,0,.14);
    box-shadow:0 calc(6 * var(--u)) calc(18 * var(--u)) rgba(0,0,0,.3);
    color:#1D1D1F;
    font:500 calc(17 * var(--u))/1.3 var(--font);letter-spacing:-.02em;
  }
  /* The tail is a square on its corner. Its top half sits behind the
     bubble, which is opaque, so only the clean point shows below. */
  [data-tip]::before{
    content:'';
    bottom:calc(100% + var(--tip-gap,calc(12 * var(--u))) - 6 * var(--u));
    width:calc(12 * var(--u));height:calc(12 * var(--u));
    transform:translate(-50%,calc(6 * var(--u))) rotate(45deg) scale(.94);
    border-radius:calc(2 * var(--u));
    background:#F3F3F3;
    border:1px solid rgba(0,0,0,.14);
  }
  /* a beat before it shows, none at all before it goes — the Dock's timing */
  [data-tip]:hover::after,[data-tip]:focus-visible::after{
    opacity:1;transform:translate(-50%,0) scale(1);transition-delay:.14s;
  }
  [data-tip]:hover::before,[data-tip]:focus-visible::before{
    opacity:1;transform:translate(-50%,0) rotate(45deg) scale(1);transition-delay:.14s;
  }

  /* ── the unread badge ──────────────────────────────────────────────
     Notes counts what is waiting the way an app in the Dock does, so the
     note is noticed without having to catch the bounce. It lives inside
     whatever the nudge animates, so the two never come apart, and it goes
     for good on the same signal — see "Notes" in app.js.               */
  .sv-badge{
    position:absolute;top:calc(-6 * var(--u));right:calc(-6 * var(--u));
    min-width:calc(21 * var(--u));height:calc(21 * var(--u));
    padding:0 calc(5 * var(--u));
    display:grid;place-items:center;
    border-radius:999px;
    background:#FF3B30;color:#FFFFFF;
    border:max(1px,calc(2 * var(--u))) solid var(--white);
    box-shadow:0 calc(2 * var(--u)) calc(6 * var(--u)) rgba(0,0,0,.32);
    font:700 calc(13 * var(--u))/1 var(--font);letter-spacing:-.02em;
    pointer-events:none;
  }
  .seen .sv-badge{display:none}

  /* It nudges the way an app bounces in the Dock when it wants you, and
     stops for good once it has been opened — see "Notes" in app.js. */
  .dock-app[data-notes] .dock-tile{animation:dock-nudge 5s ease-in-out 2.4s infinite}
  .dock-app[data-notes].seen .dock-tile:not(.jump){animation:none}
  @keyframes dock-nudge{
    0%,66%,100%{translate:0 0}
    72%{translate:0 calc(-16 * var(--u))}
    79%{translate:0 0}
    85%{translate:0 calc(-6 * var(--u))}
    91%{translate:0 0}
  }

  /* ══ Notes ════════════════════════════════════════════════════════════
     One window, built by app.js and parked on the body so no page carries
     a copy of it. Same chrome as any other window on this desktop.       */
  .nw[hidden]{display:none}
  .nw{
    --u:calc(min(100vw,var(--shell)) / 1440);
    position:fixed;inset:0;z-index:95;
    display:grid;place-items:center;padding:calc(30 * var(--u));
  }
  .nw-back{
    position:absolute;inset:0;background:rgba(6,18,38,.42);
    -webkit-backdrop-filter:blur(calc(14 * var(--u)));
            backdrop-filter:blur(calc(14 * var(--u)));
    opacity:0;transition:opacity .34s ease;
  }
  .nw-win{
    position:relative;
    width:min(calc(620 * var(--u)),100%);
    max-height:100%;
    display:flex;flex-direction:column;overflow:hidden;
    border-radius:calc(13 * var(--u));
    background:var(--white);
    box-shadow:0 calc(34 * var(--u)) calc(90 * var(--u)) rgba(0,0,0,.45);
    opacity:0;transform:scale(.93) translateY(calc(14 * var(--u)));
    transition:opacity .28s ease,transform .48s var(--spring);
  }
  .nw.in .nw-back{opacity:1}
  .nw.in .nw-win{opacity:1;transform:none}

  /* same toolbar as the project's Notes window on the work pages */
  .nw-bar{
    flex:none;display:flex;align-items:center;gap:calc(16 * var(--u));
    height:calc(50 * var(--u));padding:0 calc(15 * var(--u));
    background:#F4F4F4;
    border-bottom:1px solid rgba(0,0,0,.1);
    cursor:grab;user-select:none;-webkit-user-select:none;
  }
  .nw-bar:active{cursor:grabbing}
  .nw-lights{display:flex;align-items:center;gap:calc(8 * var(--u))}
  .nw-light{
    display:block;padding:0;border:0;
    width:calc(13 * var(--u));height:calc(13 * var(--u));border-radius:50%;
    box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
  }
  .nw-light--red{background:#FF5F57;cursor:pointer}
  .nw-light--red:focus-visible{outline:calc(2 * var(--u)) solid var(--blue);outline-offset:calc(2 * var(--u))}
  .nw-light--yellow{background:#FEBC2E}
  .nw-light--green{background:#28C840}
  .nw-name{display:grid;line-height:1.15;pointer-events:none}
  .nw-name b{font-weight:700;font-size:calc(16 * var(--u));letter-spacing:-0.02em;color:#1D1D1F}
  .nw-name i{
    font-style:normal;font-weight:300;font-size:calc(12 * var(--u));
    letter-spacing:-0.02em;color:#8A8A8E;
  }

  .nw-body{
    flex:1;min-height:0;overflow:auto;
    padding:calc(30 * var(--u)) calc(34 * var(--u)) calc(36 * var(--u));
  }
  .nw-body h2{
    margin:0;font-weight:700;font-size:calc(26 * var(--u));
    line-height:1.2;letter-spacing:-0.03em;
  }
  .nw-body p{
    margin:calc(18 * var(--u)) 0 0;
    font-weight:300;font-size:calc(18 * var(--u));
    line-height:1.55;letter-spacing:-0.03em;
  }
  /* Paperink is a tall, loose face with no em dash in it — it needs its own
     leading, and the signature has to stay dash-free */
  .nw-body .sign{
    margin-top:calc(30 * var(--u));margin-bottom:calc(6 * var(--u));
    font-family:var(--font-note);font-size:calc(30 * var(--u));
    line-height:1.35;letter-spacing:-0.02em;color:var(--blue);
  }
  .nw-body a{color:var(--blue)}

  /* ══ reveal on scroll ═════════════════════════════════════════════════
     Guarded behind .js so nothing is ever hidden if the script fails.     */
  .js [data-reveal]{
    opacity:0;
    transform:translateY(calc(24 * var(--u)));
    transition:opacity .75s ease var(--d,0s),
               transform .9s cubic-bezier(.22,1,.36,1) var(--d,0s);
  }
  .js [data-reveal].in{opacity:1;transform:none}
  /* the first screen of a page still fetching its pictures — see "reveal
     on scroll" in app.js: a small ring in the house colours, centred where
     the work will be, and removed the moment it has arrived */
  .sv-ring{
    position:fixed;left:50%;top:50%;z-index:40;
    width:calc(44 * var(--u));height:calc(44 * var(--u));
    translate:-50% -50%;
    border-radius:50%;
    border:calc(3 * var(--u)) solid var(--sky);border-top-color:var(--blue);
    animation:sv-ring .8s linear infinite;
    pointer-events:none;
  }
  @keyframes sv-ring{to{rotate:360deg}}
  /* Already on screen when the page arrived. Arriving is a performance;
     moving around the site is not, so on every page after the first this
     session it is simply there. app.js decides which elements those are,
     before the first paint — see "reveal on scroll". */
  .js [data-reveal].now{transition:none}
  .js .hl.now mark,
  .js .hl.now .rule::before,
  .js .hl.now .rule::after{transition:none}

  /* the ink arrows swing in rather than slide */
  .js .arrow[data-reveal]{transform:translateY(calc(10 * var(--u))) rotate(-14deg) scale(.82);transform-origin:0% 100%}
  .js .arrow[data-reveal].in{transform:none}
  /* the highlight wipes open, then the dot pops and its bar draws out of it */
  .js .hl mark{
    clip-path:inset(0 100% 0 0);
    transition:clip-path .8s cubic-bezier(.22,1,.36,1) var(--d,0s);
  }
  .js .hl.in mark{clip-path:inset(0 0 0 0)}
  .js .hl .rule::after{
    transform:translateX(-50%) scale(0);
    transition:transform .5s cubic-bezier(.34,1.56,.64,1) calc(var(--d,0s) + .34s);
  }
  .js .hl.in .rule::after{transform:translateX(-50%) scale(1)}
  .js .hl .rule::before{
    transform:scaleY(0);
    transition:transform .6s cubic-bezier(.22,1,.36,1) calc(var(--d,0s) + .46s);
  }
  .js .hl.in .rule::before{transform:none}

  .hero .hl{--d:.45s}                       /* above the fold — let it settle */

  .believe-copy .say{--d:.05s}
  .believe-copy .body-copy{--d:.16s}
  .believe-copy .acc{--d:.27s}
  .steps .step:nth-of-type(1){--d:.06s}
  .steps .step:nth-of-type(2){--d:.18s}
  .steps .step:nth-of-type(3){--d:.30s}
  .steps .arrow-1{--d:.44s}
  .steps .arrow-2{--d:.56s}

  @media (prefers-reduced-motion:reduce){
    .dock-app,.dock-tile{transition:none}
    .dock-app[data-notes] .dock-tile{animation:none}
    .nw-win,.nw-back{transition:none}
    .dock-tile.jump{animation:none}
    [data-tip]::before,[data-tip]::after{transition:opacity .01s linear}
    .js [data-reveal],.js [data-reveal].in,
    .js .hl mark,.js .hl .rule::before,.js .hl .rule::after{
      opacity:1;transform:none;clip-path:none;transition:none;
    }
    .step-fold,.step-fold .fold-patt,.step,.dsk-fold .fold-patt{transition:none}
    .step .seal{transition:none}
  }

  /* ── below 900 the proportional shrink stops and it stacks ────────── */
  @media (max-width:900px){
    :root{--u:1px}
    .hdr,.hdr-in,.hero-body{--u:1px}          /* the shell's own --u must fall back too */
    /* The logo stays on a phone, but not as a bar across the top: a
       frosted capsule in the left corner, on the same ground and at the
       same 44px as the burger it faces. The nav and the call button are
       both in the panel, so there is one thing in it — which also means
       there is nothing to contract, and the pill state is held off. */
    .hdr,.hdr.pill{
      display:flex;justify-content:flex-start;
      padding:15px 20px;
    }
    .hdr .hdr-in,.hdr.pill .hdr-in{
      width:auto;max-width:none;height:44px;
      padding:0 16px;
      display:flex;                  /* one child — no tracks to line up */
      gap:0;
      border-radius:999px;border-color:transparent;
      background:rgba(255,255,255,.82);
      -webkit-backdrop-filter:blur(14px) saturate(1.3);
              backdrop-filter:blur(14px) saturate(1.3);
      box-shadow:0 6px 18px rgba(26,78,152,.18);
      transition:none;
    }
    .nav{display:none}
    .burger{display:block}
    .hero{padding-top:74px}
    .hdr .brand,.hdr.pill .brand{height:26px;margin-left:0}
    .hdr.pill .brand-full{display:block}
    .hdr.pill .brand-mark{display:none}
    /* the phone never gets the contracted pill, so the wordmark stays */
    .hdr .cta{display:none}          /* it lives in the menu on a phone */

    /* the folder leads on a phone — the visual first, then the words */
    .hero-body{display:flex;flex-direction:column;padding:16px 22px 44px}
    .stage-fit{order:-1;position:relative;top:0;right:0;
      width:100%;max-width:440px;
      margin:0 auto 10px;align-self:center}
    .hero-copy,h1,.lead{width:auto;max-width:100%}
    h1{font-size:clamp(24px,5.7vw,38px)}
    h1 .l2{white-space:normal}
    /* too narrow to hold a chosen break; let it wrap where it fits */
    .lead .l1,.lead .l2{display:inline}
    .hl .rule{display:none}
    .lead{font-size:clamp(16px,4.2vw,19px);line-height:1.5;margin-top:18px}

    .sheet{margin-top:-24px;--ribbon-lift:40px;--grid-end:0px}
    .believe{grid-template-columns:1fr}
    .board{height:min(70vw,420px);min-height:0}   /* the desktop floor must go */
    .believe-copy{padding:44px 24px 0}
    .say{font-size:clamp(22px,5.6vw,30px)}
    .say .hl{font-size:clamp(27px,7vw,38px)}
    .body-copy,.acc{max-width:none;width:auto}
    .acc-head{font-size:clamp(26px,6.6vw,36px);padding:12px 18px}
    .acc-inner{padding:0 18px 20px}
    .ribbon text{font-size:26px}
    .how{padding:70px 16px 90px}
    .how h2{font-size:clamp(26px,6.4vw,42px)}
    .steps{grid-template-columns:1fr;gap:28px;margin-top:56px;padding:0}
    .steps .arrow{display:none}
    .step .seal{width:64px;right:-8px;bottom:-40px}
    .step:has(.seal) .step-body{padding-bottom:30px}
    .step-body{min-height:0}
    .step-title{font-size:clamp(22px,5.4vw,30px);white-space:normal}
    .step-fold{width:70px;height:58px}
    .step-n{width:40px;height:40px;right:16px;font-size:23px}
    .foot{padding:70px 22px 26px}
    /* the dock: no pointer to magnify against, so it just gets smaller */
    .dock{gap:10px;padding:9px 14px;border-radius:22px}
    .dock-tile{width:48px;height:48px;border-radius:11px}
    .dock-sep{margin:4px 2px}
    /* no hover here, so no label to clear — and the column reads from the
       left, so the glass hangs off that edge instead */
    .foot-side .dock{margin-top:10px;margin-right:0;margin-left:-15px}
    .nw{--u:1px;padding:16px}
    .nw-win{width:100%}
    .nw-body{padding:22px 20px 28px}

    .foot-h{font-size:clamp(26px,6.4vw,42px)}
    .foot-h .l1,.foot-h .l2{white-space:normal}
    .tstm{grid-template-columns:1fr;gap:30px;min-height:0;padding:24px;margin-top:56px}
    .tstm-stage{min-height:0}
    /* the arrows are the whole control here — no hover to lean on */
    .tstm-nav{gap:12px;margin-top:22px}
    .tstm-arrow{width:42px;height:42px}
    .tstm-arrow svg{width:16px;height:16px}
    .tstm-dots button{padding:21px 7px}          /* a 45px-tall target for a 3px line */
    .tstm-line{width:18px}
    /* two arrows, five bars and the counter on one 390 line — without this
       the counter breaks after every character */
    .tstm-count{font-size:14px;white-space:nowrap}
    .quote blockquote{font-size:clamp(21px,5.2vw,28px)}
    .foot-end{grid-template-columns:1fr;gap:34px;margin-top:64px}
    .foot-side{text-align:left;justify-items:start}
    .foot-mark img{height:118px}
    .foot-bar{margin-top:44px;font-size:14px;gap:12px}
    .foot-bar nav{gap:18px;flex-wrap:wrap}
    /* footer links get a thumb-sized target without looking any bigger */
    .foot-bar a,.foot-side p a{display:inline-block;padding-block:12px}
    .services{padding:24px 20px 90px}
    .services h2{font-size:clamp(26px,6.4vw,42px)}
    .svc-grid{grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:30px;margin-top:56px}
    /* There is no hover to turn it over, so the card unfolds: one frame,
       both faces stacked inside it, everything readable at once. */
    .svc-card{border-radius:16px}
    .svc-shot{font-size:14px;padding:14px}
    .svc-title{font-size:21px;left:14px;right:14px;bottom:14px;padding:12px 22px 14px}
    .work{padding:24px 0 80px;gap:12px}
    .tile{height:230px;width:calc(var(--w,314) * .62px)}
    .tile .cap{font-size:15px;padding:34px 14px 12px;opacity:1;transform:none}
    .step-body{font-size:17px}
  }
