/* Both palettes are declared outright and never flip; the themed
     tokens just point at one set or the other. That way the switch
     can read the colours it is about to become, which is the whole
     trick behind the transition. */
  :root{
    --paper-l:#FBFAF8; --ink-l:#0B0B0A; --mono-l:#8A8781;
    --mono2-l:#AEABA5; --rule-l:#C9C7C2; --marka-l:#1B3BFF; --markb-l:#E8391A;
    --paper-d:#0C0C0C; --ink-d:#F4F2EE; --mono-d:#6E6C67;
    --mono2-d:#454340; --rule-d:#2B2A28; --marka-d:#2FC8FF; --markb-d:#FF5A2B;

    --paper:var(--paper-l); --ink:var(--ink-l); --mono:var(--mono-l);
    --mono-2:var(--mono2-l); --rule:var(--rule-l);
    --mark-a:var(--marka-l); --mark-b:var(--markb-l);

    /* The header is fixed, so its height is the one number the rest of
       the page has to know: the section tags clear it, and the hero's
       top rule is now the header's own bottom edge. */
    --bar-h:38px;

    /* Which way the wipe runs. Set per switch; the value here is the
       light-to-dark direction, so a page that somehow loses the
       script still wipes rather than doing nothing. */
    --wipe:wipe-left;
  }
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]){
      --paper:var(--paper-d); --ink:var(--ink-d); --mono:var(--mono-d);
      --mono-2:var(--mono2-d); --rule:var(--rule-d);
      --mark-a:var(--marka-d); --mark-b:var(--markb-d);
    }
  }
  :root[data-theme="dark"]{
    --paper:var(--paper-d); --ink:var(--ink-d); --mono:var(--mono-d);
    --mono-2:var(--mono2-d); --rule:var(--rule-d);
    --mark-a:var(--marka-d); --mark-b:var(--markb-d);
  }
  *{margin:0;padding:0;box-sizing:border-box}
  body{background:var(--paper);color:var(--ink);
       font-family:Archivo,system-ui,sans-serif}

  .hero{position:relative;width:100%;height:100svh;min-height:560px;overflow:hidden;
        border:1px solid var(--rule);background:var(--paper)}

  /* Nothing on the page cross-fades its colours any more. Every
     section used to carry `transition:background-color .9s ease`,
     which is the right instinct when a theme flips in place and
     exactly the wrong one now: the reveal below shows the new
     palette through a moving edge, and a section still fading
     underneath it would put a half-mixed grey inside the circle
     instead of the finished theme. The palette lands instantly; the
     circle is the only thing that takes time. Hover transitions are
     a separate matter and are all still here. */

  /* ── the wall ─────────────────────────────────────────── */
  .wall{position:absolute;inset:0;z-index:1;
        display:grid;grid-template-columns:repeat(4,1fr);
        gap:0 26px;padding:48px 22px 46px;
        font-family:'IBM Plex Mono',monospace;
        font-size:12.5px;line-height:1.52;color:var(--mono);
        white-space:pre;overflow:hidden}
  .col{overflow:hidden;position:relative}
  /* A mark repaints one word on top of the wall: its own ground,
     its own colour. Cheaper than a span per word, and it can carry
     the mutating buffer text rather than the original. */
  .mark{position:absolute;white-space:pre;font:inherit;pointer-events:none}
  .ln{white-space:pre;height:1.52em}
  .ln.dim{color:var(--mono-2)}



  /* ── chrome ───────────────────────────────────────────── */
  .bar{position:absolute;z-index:4;left:0;right:0;display:flex;
       font-family:'IBM Plex Mono',monospace;font-size:12px;
       letter-spacing:.04em;color:var(--ink)}

  /* The header used to sit inside the hero, under the display words —
     which render through `difference`, so every letter that crossed
     the nav inverted it and the labels came apart. It lives outside
     the hero now: fixed to the viewport, on its own ground, above the
     hero's stacking context rather than inside it. That fixes the
     legibility and makes it sticky in the same move — the hero has a
     transform on it, which would otherwise have anchored a fixed
     child to the hero instead of to the window.

     Its bottom edge is the rule that used to be a separate element in
     the hero, so the frame still closes at the same pixel. */
  .bar--top{position:fixed;top:0;left:0;right:0;z-index:60;
            height:var(--bar-h);padding:0 22px;
            justify-content:space-between;align-items:center;
            background:var(--paper);
            border-bottom:1px solid var(--rule)}
  .bar--top nav{display:flex;gap:56px}
  .bar--top nav a{color:inherit;text-decoration:none;
                  border-bottom:1px solid transparent;padding-bottom:2px;
                  transition:border-color .2s ease}
  .bar--top nav a:hover,.bar--top nav a:focus-visible{border-color:currentColor}
  .bar--top .end{display:flex;gap:34px;align-items:center}
  /* Fixed to the wider of the two labels so the box never changes
     size. DARK and LIGHT are different lengths, and letting the
     button resize would nudge the whole right-hand group on every
     click — and, once it is captured as its own transition layer
     below, stretch the label while it swaps. */
  .theme{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;
         letter-spacing:.04em;white-space:pre;
         display:inline-flex;align-items:center;justify-content:center;min-width:9ch}
  .theme::before{content:"[ "}
  .theme::after{content:" ]"}

  /* ── the theme reveal ─────────────────────────────────────
     The new palette is not drawn on top of the old one; it is
     underneath the whole time, and the circle is a window onto it.
     `data-theme` flips, the page re-renders once in the new colours,
     and the View Transition API holds the previous frame still while
     the new render is clipped to a growing circle centred on the
     toggle. Layout, scroll and every running rAF loop are untouched,
     because none of them were ever part of the change.

     The default crossfade has to go. Fading two snapshots through
     each other puts both palettes on screen at half strength for the
     whole transition, which on a monochrome page is not a transition
     between black and white — it is a long look at grey. The UA also
     composites the pair with `plus-lighter`, which is built for that
     crossfade and would blow the overlap out to white here, so the
     blend mode is reset alongside it. */
  ::view-transition-image-pair(root){isolation:auto}
  ::view-transition-old(root),
  ::view-transition-new(root){animation:none;mix-blend-mode:normal}

  /* the frame we are leaving, held perfectly still */
  ::view-transition-old(root){z-index:0}

  /* and the one we are going to, arriving behind a vertical edge.
     Dark comes in from the right, light comes back from the left, so
     the two directions are a pair rather than a repeat. Both are the
     same keyframe shape — an inset collapsing to nothing — and the
     script picks between them through --wipe rather than through a
     selector, because a custom property inherits into this pseudo
     tree and is one less thing to be wrong about. */
  ::view-transition-new(root){
    z-index:1;
    animation:1100ms cubic-bezier(.76,0,.24,1) both var(--wipe)}

  @keyframes wipe-left {from{clip-path:inset(0 0 0 100%)}
                        to  {clip-path:inset(0 0 0 0)}}
  @keyframes wipe-right{from{clip-path:inset(0 100% 0 0)}
                        to  {clip-path:inset(0 0 0 0)}}

  /* ── the ascii band ───────────────────────────────────────
     The clip above is a hard vertical line, and on its own it reads
     as a wipe over a screenshot. The band is what makes it read as
     the page being retyped instead: a dense, ragged column of the
     site's own words standing on the seam, thickest along it and
     thinning into the two themes on either side.

     It has to be a named transition layer. Ordinary DOM does not
     paint above the root snapshots during a transition, and neither
     does a popover — both end up behind them. A named group is the
     one thing that goes over the top, and its `new` side is live
     rather than a still, so what is drawn into it keeps updating.

     A canvas, not elements. At this density the band is several
     hundred glyphs at any instant, and that many nodes is the wrong
     shape of cost — style and layout for all of them, every frame,
     to move one edge. The About lettering is already drawn this way,
     so the technique is the page's own rather than imported. */
  .wipe{position:fixed;inset:0;pointer-events:none;
        view-transition-name:ascii-wipe;
        /* One ink for both sides. The band is the only thing on the
           page standing on the light theme and the dark one at the
           same instant, so any fixed colour is invisible on one side
           of the seam. White through `difference` comes out
           near-black on paper and near-white on ink, and inverts
           again over the marks in the wall. Not an effect — it is
           the only way to stay legible across a boundary that is by
           definition both, and the display type already answers the
           same problem the same way. It blends against the root
           snapshots rather than against an isolated group, which is
           not obvious and is easy to break. */
        mix-blend-mode:difference}

  ::view-transition-group(ascii-wipe){z-index:10;animation:none}
  ::view-transition-new(ascii-wipe){animation:none;opacity:1}

  /* The toggle is lifted out of the root snapshot so it swaps on its
     own clock rather than waiting for an edge that reaches it either
     first or last depending on which way the wipe is running. Short
     enough to read as punctuation to the wipe, not a second event. */
  .theme{view-transition-name:theme-toggle}
  ::view-transition-group(theme-toggle){z-index:12}
  ::view-transition-old(theme-toggle){
    animation:toggle-out 180ms cubic-bezier(.4,.1,.6,.9) forwards}
  ::view-transition-new(theme-toggle){
    animation:toggle-in 180ms cubic-bezier(.4,.1,.6,.9) 60ms backwards}
  @keyframes toggle-out{to{opacity:0;transform:scale(.88)}}
  @keyframes toggle-in{from{opacity:0;transform:scale(1.08)}}

  /* Asked for less motion: the palette changes and that is all. The
     script never starts a transition in that case, so these rules
     are the belt to its braces. */
  @media (prefers-reduced-motion:reduce){
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*){animation:none!important}
  }
  .bar--bot{bottom:0;padding:12px 22px;justify-content:space-between;
            letter-spacing:.16em}
  .rule-b{position:absolute;z-index:4;left:0;right:0;bottom:38px;height:1px;background:var(--rule)}

  /* ── the display type ─────────────────────────────────── */
  /* White through `difference` renders as a true negative of whatever
     is behind: near-black on the paper, and inverted again wherever a
     mark passes under a letter — so the phrase never sinks into a bar. */
  .say{position:absolute;z-index:6;pointer-events:none;
       color:#fff;mix-blend-mode:difference;
       font-variation-settings:'wdth' 100,'wght' 400;
       letter-spacing:-.035em;line-height:.86;white-space:nowrap}
  /* The big words cannot scramble convincingly at this size, so they
     take a hard signal-drop instead, timed to the swap. */
  .say.flick{animation:flick .2s steps(1,end) 1}
  @keyframes flick{
    0%{opacity:1} 20%{opacity:.12} 40%{opacity:1}
    60%{opacity:.3} 80%{opacity:1} 100%{opacity:1}}
  @media (prefers-reduced-motion:reduce){ .say.flick{animation:none} }
  .s1{left:1.5%;  top:33%;  font-size:12.6vw}
  .s2{left:26.5%; top:6.5%; font-size:9.4vw}
  .s3{left:56.5%; top:16%;  font-size:12.2vw}
  .s4{left:41%;   top:54%;  font-size:12.4vw}
  .s5{left:3%;    top:70%;  font-size:12.8vw}
  .s6{left:56%;   top:75%;  font-size:12.8vw}


  /* Anchor jumps ease rather than teleport. The script at the foot of
     the page takes this over and paces the travel by distance; this
     rule is the fallback when it cannot run. No scroll snapping: with
     full-height sections it grabs the wheel at every boundary, which
     reads as the page sticking rather than as anything smooth. */
  html{scroll-behavior:smooth}

  @media (prefers-reduced-motion:reduce){
    html{scroll-behavior:auto}
  }

  /* ── the handover between sections ────────────────────────
     Scroll-linked, not scroll-triggered. The two numbers below are
     read off each section's position in the viewport every frame, so
     the page moves exactly as far as the wheel says and no further.
     Nothing latches, nothing waits on a threshold, and there is no
     scroll snapping — snapping is what made this feel like it was
     sticking the last time.

     The declared values are the resting state, so a section is
     correct before the first frame and stays correct if the script
     never runs. */
  .hero,.about,.loc,.work,.meet,.foot-in{
    --sy:0px; --so:1;
    transform:translate3d(0,var(--sy),0);
    opacity:var(--so);
  }

  /* The footer is the one section whose ground is not the page colour,
     so fading the element itself would wash its ink panel out to paper
     on the way in. Its content rides in over a background that stays
     solid instead. */
  /* The column flex lives here rather than on .foot: the word's `auto`
     top margin only pushes against its own flex parent, and with a
     plain block in between all the slack was landing under the fine
     print instead of over the word. */
  .foot-in{position:relative;flex:1;display:flex;flex-direction:column}

  /* Opacity below 1 turns the hero into an isolated group, which would
     otherwise move the goalposts for the difference blend on the
     display words halfway through a scroll. Isolating it permanently
     keeps that backdrop the same at every opacity. */
  .hero{isolation:isolate}

  @media (prefers-reduced-motion:reduce){
    .hero,.about,.loc,.work,.meet,.foot-in{transform:none;opacity:1}
  }



  /* ── the header on a phone ────────────────────────────────
     Four columns of monospace do not survive 390px — each ends up
     narrower than the words inside it. The wall drops to two columns
     (the script builds only as many as the grid asks for), the chrome
     loses the clock, and the display words are re-placed rather than
     merely scaled: at this width they would otherwise collide with
     each other and run off the right edge. */
  @media (max-width:720px){
    .wall{grid-template-columns:repeat(2,1fr);gap:0 16px;
          padding:44px 16px 42px;font-size:11px}

    .bar{font-size:10px;letter-spacing:.02em}
    :root{--bar-h:34px}
    .bar--top{padding:0 16px}
    .bar--top nav{gap:18px}
    .bar--top .end{gap:14px}
    .bar--top .end > span{display:none}       /* the clock goes */
    .bar--bot{padding:11px 16px;letter-spacing:.06em}
    .bar--bot span:nth-child(3),
    .bar--bot span:nth-child(4),
    .bar--bot span:nth-child(6){display:none} /* AS · A · OF */
    .rule-b{bottom:34px}

    .say{letter-spacing:-.03em}
    .s1{left:3%;   top:18%;  font-size:21vw}   /* Product  */
    .s2{left:30%;  top:7%;   font-size:13vw}   /* Delivery */
    .s3{left:8%;   top:30%;  font-size:21vw}   /* Manager  */
    .s4{left:6%;   top:44%;  font-size:18vw}   /* Between  */
    .s5{left:4%;   top:62%;  font-size:22vw}   /* Plan     */
    .s6{left:30%;  top:74%;  font-size:22vw}   /* & Ship   */
  }

  /* ── 02 about ─────────────────────────────────────────── */
    /* `clip` on one axis only: the canvas overhangs by PAD so magnified
     glyphs are not sliced, and that overhang must not widen the page —
     but the vertical overhang has to stay visible. */
  .about{overflow-x:clip;position:relative;min-height:100vh;padding:0 22px;
         border:1px solid var(--rule);border-top:0;
         display:flex;flex-direction:column;justify-content:center;
         background:var(--paper)}
  .about .tag{position:absolute;top:calc(var(--bar-h) + 22px);left:22px;right:22px;
              display:flex;justify-content:space-between;
              font-family:'IBM Plex Mono',monospace;font-size:12px;
              letter-spacing:.16em;color:var(--ink)}
  /* The letterforms are drawn out of their own name: one <pre>, a
     character grid sampled from the phrase rendered on a canvas. */
  .ascii-wrap{position:relative;width:max-content;margin:0 auto;cursor:crosshair}
  .ascii-cv{display:block}
  /* A spec row rather than a paragraph: the same mono chrome the rest
     of the page uses for facts, so it reads as data under the mark. */
  .facts{display:flex;justify-content:space-between;align-items:flex-start;
         gap:22px 30px;flex-wrap:wrap;
         /* full measure, so the row sits on the same margins the
            letterforms above it are justified to */
         width:100%;margin:44px auto 0;padding:0 22px;
         font-family:'IBM Plex Mono',monospace}
  .facts > div{display:flex;flex-direction:column;gap:6px}
  .facts dt{font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
            color:var(--mono)}
  .facts dd{margin:0;font-size:13.5px;letter-spacing:.02em;color:var(--ink)}
  .facts a{color:inherit;text-decoration:none;
           border-bottom:1px solid var(--rule);padding-bottom:1px;
           transition:border-color .2s ease}
  .facts a:hover{border-color:var(--ink)}



  /* ── 03 location ──────────────────────────────────────────
     A dot map of the Americas under a slow noise field. Every dot's
     radius and alpha ride the same fractal noise, sampled with time
     added to y so features drift upward — about three quarters of the
     map holds still and the rest breathes. Drawn in --ink on --paper,
     so the panel inverts with the theme like everything else. */
  .loc{overflow-x:clip;position:relative;min-height:100vh;padding:0 22px;
       display:flex;flex-direction:column;justify-content:center;
       background:var(--paper)}
  .loc .tag{position:absolute;top:calc(var(--bar-h) + 22px);left:22px;right:22px;
            display:flex;justify-content:space-between;
            font-family:'IBM Plex Mono',monospace;font-size:12px;
            letter-spacing:.16em;color:var(--ink)}

  .loc-in{display:flex;align-items:center;justify-content:space-between;
          gap:40px 64px;width:100%;max-width:1240px;margin:0 auto;padding:0 22px;
          /* the map is measured off this line, so it has to be the full
             height of the section for the panel to bleed top to bottom */
          min-height:100vh}
  .loc-copy{flex:1 1 360px;min-width:270px}

  /* The station lockup, on the same scale as the other display type.
     The second line is (AR) rather than the reference's 01, which would
     have read as a section number against the 03 in the tag row. */
  .loc-code{margin:0;font-size:clamp(56px,10.5vw,166px);line-height:.82;
            letter-spacing:-.045em;
            font-variation-settings:'wdth' 100,'wght' 400}

  .loc-now{display:flex;align-items:center;gap:10px;margin:32px 0 0;
           font-family:'IBM Plex Mono',monospace;font-size:11px;
           letter-spacing:.18em;text-transform:uppercase;color:var(--mono)}
  .loc-now i{width:6px;height:6px;border-radius:50%;background:var(--ink);
             flex:none}

  .loc-city,.loc-country{margin:0;font-size:clamp(26px,3.1vw,46px);
                         line-height:1.06;letter-spacing:-.02em;
                         font-variation-settings:'wdth' 100,'wght' 400}
  .loc-city{margin-top:14px}
  .loc-country{color:var(--mono)}

  /* The readout, ruled top and bottom as in the reference */
  .loc-coords{margin:26px 0 0;padding:10px 0;max-width:330px;
              border-top:1px solid var(--rule);
              border-bottom:1px solid var(--rule);
              font-family:'IBM Plex Mono',monospace}
  .loc-coords > div{display:flex;gap:18px;align-items:baseline;padding:6px 0}
  .loc-coords dt{width:30px;flex:none;font-size:10.5px;letter-spacing:.18em;
                 text-transform:uppercase;color:var(--mono)}
  .loc-coords dd{margin:0;font-size:13.5px;letter-spacing:.02em;color:var(--ink)}

  .loc-note{margin:18px 0 0;max-width:330px;font-size:15px;line-height:1.5;
            color:var(--mono)}

  /* The panel runs the full height of the section and takes its width
     from what is left. 75vh is the width that holds the design's
     675x900 exactly, and it wins on every ordinary 16:9 or 16:10
     window; 52vw is the backstop that keeps the map from crowding the
     copy out of an unusually tall one. When the backstop wins the
     field just draws a little narrower — the engine scales each axis
     on its own, as the reference does. The pin is placed in per cent,
     so it tracks Buenos Aires whatever the panel ends up. */
  .loc-map{position:relative;flex:0 0 auto;align-self:stretch;
           width:min(52vw,75vh)}
  .loc-map canvas{display:block;width:100%;height:100%}

  .loc-pin{position:absolute;left:70.815%;top:58.444%;
           pointer-events:none;color:var(--ink)}
  .loc-pin .ring{position:absolute;left:-7px;top:-7px;width:14px;height:14px;
                 border:1px solid var(--ink);border-radius:50%}
  .loc-pin .dot{position:absolute;left:-2.5px;top:-2.5px;width:5px;height:5px;
                border-radius:50%;background:var(--ink)}
  .loc-pin .hline{position:absolute;left:11px;top:0;width:42px;height:1px;
                  background:var(--ink);opacity:.75}
  .loc-pin span{position:absolute;left:62px;top:-7px;
                font-family:'IBM Plex Mono',monospace;font-size:12px;
                letter-spacing:.1em;white-space:nowrap}

  @media (max-width:720px){
    /* On a phone the map stops being a panel beside the copy and becomes
       the ground underneath it. Its proportions are left alone — .75 is
       the design's own ratio — so rather than being squeezed to fit a
       narrow screen it simply runs off both edges, the way a photograph
       used as a background would. */
    .loc{overflow:hidden}
    .loc-in{display:flex;flex-direction:column;justify-content:center;
            align-items:stretch;position:static;gap:0;padding:0}

    .loc-map{
      --gutter:92px;                 /* room for the pin's line and label */
      /* 78vh is how tall the field wants to stand. The second term is
         the height at which it still reaches the left edge once the
         gutter has pushed it right — its left edge sits at
         100vw - gutter - .708w, so w must be at least
         (100vw - gutter) / .708, and h is that over .75. Without the
         floor a bare strip opens up the side of a short screen. */
      --h:max(78vh, calc(1.884 * (100vw - var(--gutter))));
      --w:calc(var(--h) * .75);      /* the design's ratio, untouched */
      position:absolute;align-self:auto;z-index:0;
      top:50%;transform:translateY(-50%);
      height:var(--h);width:var(--w);
      /* Anchored by the marker rather than by an edge. Buenos Aires sits
         70.8% across the field, so this leaves exactly --gutter to its
         right whatever the screen: the pin and its label can never fall
         off, and the overhang lands on empty ocean instead. */
      right:calc(var(--gutter) - var(--w) * .292);
    }
    /* The canvas fades out under the copy so the type stays crisp. The
       pin is a sibling of the canvas, not a child, so it keeps its full
       weight out on the right. */
    .loc-map canvas{
      -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,.12) 0,
        rgba(0,0,0,.38) 38%,rgba(0,0,0,.82) 62%,#000 78%);
      mask-image:linear-gradient(90deg,rgba(0,0,0,.12) 0,
        rgba(0,0,0,.38) 38%,rgba(0,0,0,.82) 62%,#000 78%);
    }

    .loc-copy{position:relative;z-index:1;
              flex:0 0 auto;min-width:0;width:100%}

    .loc .tag{font-size:10px;letter-spacing:.1em}
    .loc-code{font-size:20vw}
    .loc-now{margin-top:24px}
    /* The readout has to stop clear of the marker: the pin ring sits at
       x = 100% - 92px, and these rules would otherwise run right up
       against it. */
    .loc-coords{margin-top:20px;max-width:190px}
    .loc-note{max-width:240px}
    .loc-pin .hline{width:34px}
    .loc-pin span{left:52px;font-size:10px}
  }

  /* ── 04 work experience ───────────────────────────────── */
  .work{overflow-x:clip;position:relative;min-height:100vh;padding:0 22px;
        display:flex;flex-direction:column;justify-content:center;
        background:var(--paper)}
  .work .tag{position:absolute;top:calc(var(--bar-h) + 22px);left:22px;right:22px;
             display:flex;justify-content:space-between;
             font-family:'IBM Plex Mono',monospace;font-size:12px;
             letter-spacing:.16em;color:var(--ink)}

  /* The stage carries the perspective; every glyph is its own element
     so it can leave and return in three dimensions without touching
     layout — the lines stay exactly where the grid put them. */
  .sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
           border:0;clip-path:inset(50%);overflow:hidden;white-space:nowrap}
  .work-stage{position:relative;width:100%;
              height:min(74vh,700px);margin:0 auto}
  @media (max-width:720px){
    .work-stage{height:min(66vh,560px)}
    .work .tag{font-size:10px;letter-spacing:.1em}
    .tick{width:5px;height:5px}
  }
  .work-stage canvas{display:block;width:100%;height:100%}

  /* registration ticks, as on the poster */
  .tick{position:absolute;width:7px;height:7px;background:var(--ink)}
  .tick.tl{left:22px;top:26%}   .tick.tr{right:22px;top:26%}
  .tick.bl{left:22px;bottom:26%} .tick.br{right:22px;bottom:26%}


  @media (max-width:720px){
    .facts{gap:18px 26px;margin-top:30px;
           display:grid;grid-template-columns:repeat(2,1fr)}
    .facts > div:last-child{grid-column:1 / -1}   /* the email needs a full row */
    .facts dd{font-size:12.5px;word-break:break-word}
  }

  /* ── 04 let's meet ────────────────────────────────────── */
  .meet{position:relative;min-height:100vh;padding:0 22px;
        display:flex;flex-direction:column;justify-content:center;
        background:var(--paper)}
  .meet .tag{position:absolute;top:calc(var(--bar-h) + 22px);left:22px;right:22px;
             display:flex;justify-content:space-between;
             font-family:'IBM Plex Mono',monospace;font-size:12px;
             letter-spacing:.16em;color:var(--ink)}
  /* pulled in off the section margins, so the pair sits as a block
     rather than being pinned to both edges of the page */
  .meet-in{display:flex;align-items:center;justify-content:space-between;
           gap:clamp(28px,5vw,80px);width:100%;flex-wrap:wrap;
           max-width:1280px;margin:0 auto;padding:0 clamp(0px,4vw,80px)}
  .meet-copy{flex:1 1 420px;min-width:290px}
  .meet h2{font-size:clamp(46px,9vw,152px);line-height:.92;
           letter-spacing:-.038em;font-variation-settings:'wdth' 100,'wght' 400;
           margin:0}
  .meet .sub{margin:28px 0 0;max-width:440px;font-size:15px;line-height:1.5;
             color:var(--mono)}
  .meet .cta{display:inline-flex;align-items:center;gap:14px;margin-top:30px;
             padding:13px 20px 13px 24px;border-radius:999px;
             border:1px solid var(--rule);color:var(--ink);text-decoration:none;
             font-family:'IBM Plex Mono',monospace;font-size:12px;
             letter-spacing:.14em;text-transform:uppercase;
             transition:background-color .2s ease,color .2s ease,border-color .2s ease}
  .meet .cta:hover{background:var(--ink);color:var(--paper);border-color:var(--ink)}

  /* The portrait is a mosaic until you ask for it. Hovering raises the
     resolution rather than cross-fading, so it resolves the way the
     reference poster's star does. */
  .shot{flex:0 0 auto;width:clamp(260px,33vw,440px);aspect-ratio:1;
        position:relative;cursor:crosshair}
  .shot canvas{display:block;width:100%;height:100%}
  .shot figcaption{position:absolute;left:0;bottom:-26px;
                   font-family:'IBM Plex Mono',monospace;font-size:11px;
                   letter-spacing:.16em;text-transform:uppercase;color:var(--mono)}

  /* ── 05 footer ────────────────────────────────────────── */
  /* The slab always runs inverse to the page: black on paper,
     paper on black. It closes the page either way, and it flips
     with the theme for free. */
  .foot{position:relative;background:var(--ink);color:var(--paper);
        padding:44px 22px 14px;overflow:hidden;
        /* One viewport, like every section above it. The slab is the
           last full screen of the page, not a strip stuck on the end.
           Column flex so the slack lands in one place: the top block
           stays at the top, the word and the fine print sit on the
           bottom edge together. */
        min-height:100vh;display:flex;flex-direction:column}
  .foot-top{display:flex;justify-content:space-between;align-items:flex-start;
            flex-wrap:wrap;gap:32px 40px;margin-bottom:48px}
  .foot h2{font-size:clamp(34px,4.6vw,68px);line-height:1.02;
           font-variation-settings:'wdth' 100,'wght' 400;
           letter-spacing:-.03em;margin:0 0 26px}
  .pills{display:flex;gap:12px;flex-wrap:wrap}
  .pill{display:inline-flex;align-items:center;gap:14px;
        padding:13px 20px;border:1px solid rgba(128,128,128,.55);
        border-radius:999px;color:inherit;text-decoration:none;
        font-family:'IBM Plex Mono',monospace;font-size:12px;
        letter-spacing:.14em;text-transform:uppercase;
        transition:background-color .2s ease,color .2s ease}
  .pill:hover{background:var(--paper);color:var(--ink)}
  .socials{display:flex;flex-direction:column;gap:2px;text-align:left;
           font-size:clamp(17px,1.5vw,23px);line-height:1.34}
  .socials a{color:inherit;text-decoration:none;opacity:.92}
  .socials a:hover{text-decoration:underline;text-underline-offset:4px}

  /* Sized in script rather than in vw: the word has to touch both
     margins exactly, whatever the word turns out to be. */
  .foot-word{display:inline-block;white-space:nowrap;line-height:.82;
             font-variation-settings:'wdth' 100,'wght' 800;
             letter-spacing:-.045em;
             /* `auto` on top drops the word to the bottom of the slab.
                `flex-start` keeps the box hugging its text — stretched
                to the full column it would measure as the footer's
                width and the fitter would size against itself. */
             margin:auto 0 6px;align-self:flex-start;
             /* the line box is tighter than the face, so the descender
                hangs out of it — reserve it in em so it scales with the
                fitted size */
             padding-bottom:.15em;
             font-size:120px}
  .foot-fine{display:flex;justify-content:space-between;align-items:center;
             gap:24px;padding-top:12px;
             font-family:'IBM Plex Mono',monospace;font-size:12px;
             letter-spacing:.04em;opacity:.72}
  .chip{border:1px solid rgba(128,128,128,.55);border-radius:4px;
        padding:3px 7px;letter-spacing:.12em}

  /* ── the footer on a phone ────────────────────────────────
     Four monospace items strung across 375px each end up narrower
     than the words inside them, so the fine print becomes four ragged
     stacks. It goes to two ruled rows of two instead, and the word
     above it breaks in half so it can be set to the width of the slab
     rather than to the width of the longest line that fits on one. */
  @media (max-width:720px){
    .foot{padding:34px 18px 16px}

    /* nowrap keeps the link in the corner. Wrapped it reads as a third
       item stacked under the pill rather than as the opposite corner. */
    .foot-top{flex-wrap:nowrap;gap:0 18px;margin-bottom:30px}
    .foot-top > div{min-width:0}
    .foot h2{font-size:clamp(29px,8vw,38px);margin-bottom:20px}
    .socials{flex:0 0 auto;font-size:16px}
    .pill{padding:12px 17px;letter-spacing:.12em}

    .foot-word{white-space:normal;margin-bottom:16px}
    .foot-word .fw-b{display:block;text-transform:capitalize}

    .foot-fine{display:grid;grid-template-columns:auto auto;
               justify-content:space-between;align-items:center;
               gap:10px 16px;font-size:11px;
               border-top:1px solid rgba(128,128,128,.3);padding-top:15px}
    /* place, then note; ownership, then language — the two pairs that
       actually belong together, rather than source order */
    .foot-fine > :nth-child(2){order:1}
    .foot-fine > :nth-child(3){order:2;text-align:right}
    .foot-fine > :nth-child(1){order:3}
    .foot-fine > .chip{order:4;justify-self:end}
  }


  /* The page cannot scroll behind the opening. Keyed off a class so a
     failure to remove it is at least visible, rather than the page
     being silently stuck. */
  html.is-opening, html.is-opening body{overflow:hidden}

  /* ── the opening ─────────────────────────────────────────────
     Everything below is scoped to `.opening`. The source file styled
     html and body directly — applied here that would set the whole
     page black and stop it scrolling even after the opening had gone. */
  .opening{
    --bg:#0a0a0a; --fg:#eceae5; --dim:#5d5b57; --line:#272725;
    position:fixed;inset:0;z-index:999;
    background:var(--bg);color:var(--fg);
    font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;
    display:none;transition:opacity 250ms cubic-bezier(0.23,1,0.32,1)}
  html.is-opening .opening{display:block}
  .opening.gone{display:block}
  .opening.gone{opacity:0;pointer-events:none}

  .opening .screen{position:absolute;inset:0}

  .opening .frame{position:absolute;inset:0;display:grid;padding:24px 28px}

  /* Matched to the page's own top bar — same family, size and tracking,
     same 12px/22px inset — so the opening hands over to a masthead that
     is already in the right place. */
  .opening .lbar{position:absolute;top:0;left:0;right:0;z-index:6;
                display:flex;justify-content:space-between;align-items:baseline;
                padding:12px 22px;
                font-family:'IBM Plex Mono',monospace;font-size:12px;
                letter-spacing:.04em;color:var(--fg)}
  .opening .lrule{position:absolute;z-index:6;left:0;right:0;top:38px;
                 height:1px;background:#2a2a28}
  @media (max-width:720px){
    .opening .lbar{padding:11px 16px;font-size:10px;letter-spacing:.02em}
    .opening .lrule{top:34px}
  }

  .opening .stage{position:relative;display:flex;align-items:center;
    justify-content:center;perspective:900px;overflow:hidden}


  .opening .core{width:200px;height:200px;position:relative;
    transform-style:preserve-3d;animation:spin 8s linear infinite}
  @keyframes spin{
    0%{transform:rotateX(-18deg) rotateY(0deg) rotateZ(4deg)}
    50%{transform:rotateX(14deg) rotateY(180deg) rotateZ(-4deg)}
    100%{transform:rotateX(-18deg) rotateY(360deg) rotateZ(4deg)}}

  .opening .face{position:absolute;inset:0;border:1px solid #4b4945;
    background:rgba(10,10,10,.78);display:flex;align-items:center;
    justify-content:center;overflow:hidden;backface-visibility:visible}
  .opening .face pre{margin:0;font-size:12.5px;line-height:1.05;
    letter-spacing:.05em;white-space:pre;text-align:center;
    color:var(--fg);opacity:.95;text-shadow:0 0 10px rgba(255,255,255,.03)}

  .opening .front  {transform:translateZ(100px)}
  .opening .back   {transform:rotateY(180deg) translateZ(100px)}
  .opening .rightf {transform:rotateY(90deg) translateZ(100px)}
  .opening .leftf  {transform:rotateY(-90deg) translateZ(100px)}
  .opening .topf   {transform:rotateX(90deg) translateZ(100px)}
  .opening .bottomf{transform:rotateX(-90deg) translateZ(100px)}

  .opening .scan{position:absolute;width:280px;height:1px;background:var(--fg);
    box-shadow:0 0 10px rgba(255,255,255,.35);
    animation:scan 2.8s ease-in-out infinite;opacity:.75}
  @keyframes scan{
    0%,100%{transform:translateY(-140px);opacity:.1}
    50%{transform:translateY(140px);opacity:.95}}


  .opening .meta{position:absolute;left:3vw;bottom:11vh;font-size:10px;
    line-height:1.55;letter-spacing:.09em;color:#77746e}
  .opening .meta b{color:var(--fg);font-weight:400}


  @media (max-width:700px){
    .opening .frame{padding:18px 16px}
    .opening .core{width:150px;height:150px}
    .opening .front  {transform:translateZ(75px)}
    .opening .back   {transform:rotateY(180deg) translateZ(75px)}
    .opening .rightf {transform:rotateY(90deg) translateZ(75px)}
    .opening .leftf  {transform:rotateY(-90deg) translateZ(75px)}
    .opening .topf   {transform:rotateX(90deg) translateZ(75px)}
    .opening .bottomf{transform:rotateX(-90deg) translateZ(75px)}
    .opening .face pre{font-size:9px}
    .opening .scan{width:210px}
    .opening .meta{display:none}
  }

  @media (prefers-reduced-motion:reduce){
    .opening .core{animation:none}
    .opening .scan{animation:none;opacity:.3}
  }

  /* Quiet boundaries let the type, map and portrait have their own moments. */
  .portrait-toggle{display:block;width:100%;height:100%;padding:0;border:0;background:none;cursor:crosshair}
  :where(a,button):focus-visible{outline:2px solid currentColor;outline-offset:5px}
  .portrait-toggle:focus-visible{outline-offset:8px}
  .bar--top .theme{min-height:32px}
  [data-bue-clock]{font-variant-numeric:tabular-nums}
  @media (max-width:720px){
    .hero{min-height:520px}
    .bar--top nav{gap:12px}
    .bar--top nav a{display:inline-flex;align-items:center;min-height:32px}
    .meet-copy{min-width:0}
    .shot{max-width:100%}
    .foot-fine > :nth-child(3){max-width:19ch}
  }
