@font-face { font-family: 'Bodoni Moda'; font-style: normal; font-weight: 400 700; font-display: swap; src: url(/fonts/bodoni-moda.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
    @font-face { font-family: 'Bodoni Moda'; font-style: italic; font-weight: 400 700; font-display: swap; src: url(/fonts/bodoni-moda-italic.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
    @font-face { font-family: 'Hanken Grotesk'; font-style: normal; font-weight: 300 700; font-display: swap; src: url(/fonts/hanken-grotesk.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
    html, body { margin: 0; background: #050d11; }
    html { overflow-x: hidden; scrollbar-width: none; }
    html::-webkit-scrollbar { display: none; }
    body { overflow-x: hidden; }
    /* touch: holding the clock must never open the image menu, select text, or
       flash the tap highlight; the hold gesture must not scroll or zoom the page */
    body { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
    #stage img, #teaser img, #gate img { pointer-events: none; -webkit-user-drag: none; user-drag: none; }
    #clockzone { touch-action: none; }
    a { color: #e8c391; text-decoration: none; }
    a:hover { color: #f0d3a6; }
    * { box-sizing: border-box; }

    @keyframes mistDriftA { 0% { transform: translate3d(-6%, 0, 0) scale(1); } 50% { transform: translate3d(5%, -3%, 0) scale(1.12); } 100% { transform: translate3d(-6%, 0, 0) scale(1); } }
    @keyframes mistDriftB { 0% { transform: translate3d(4%, 2%, 0) scale(1.05); } 50% { transform: translate3d(-5%, -2%, 0) scale(1); } 100% { transform: translate3d(4%, 2%, 0) scale(1.05); } }
    @keyframes smokeDriftA {
      0% { transform: translate3d(-4%, 2%, 0) rotate(0deg) scale(1); opacity: .15; }
      50% { transform: translate3d(4%, -3%, 0) rotate(3deg) scale(1.12); opacity: .22; }
      100% { transform: translate3d(-4%, 2%, 0) rotate(0deg) scale(1); opacity: .15; }
    }
    @keyframes smokeDriftB {
      0% { transform: translate3d(5%, -2%, 0) rotate(-2deg) scale(1.08); opacity: .11; }
      50% { transform: translate3d(-5%, 2%, 0) rotate(1deg) scale(1); opacity: .17; }
      100% { transform: translate3d(5%, -2%, 0) rotate(-2deg) scale(1.08); opacity: .11; }
    }
    @keyframes gearCW { to { transform: rotate(360deg); } }
    @keyframes gearCCW { to { transform: rotate(-360deg); } }
    @keyframes balanceSwing { from { transform: rotate(-14deg); } to { transform: rotate(14deg); } }
    @keyframes subdialTurn { from { transform: translate(-25%, -72.17%) rotate(0deg); } to { transform: translate(-25%, -72.17%) rotate(360deg); } }
    @keyframes soonPulse { 0%, 100% { opacity: .92; letter-spacing: .52em; } 50% { opacity: 1; letter-spacing: .58em; } }
    @keyframes grainJit {
      0% { background-position: 0 0; } 12% { background-position: -34px 22px; }
      25% { background-position: 18px -40px; } 37% { background-position: -52px -14px; }
      50% { background-position: 40px 30px; } 62% { background-position: -20px 48px; }
      75% { background-position: 52px -26px; } 87% { background-position: -44px -46px; }
      100% { background-position: 0 0; }
    }

    @media (prefers-reduced-motion: reduce) {
      .gear-spin, .mist, .fogband, .soon, #grain, .smoke { animation: none !important; }
    }

    /* GPU smoke canvas: above the stage AND the teaser video, so the "ténèbres"
       can cover both; the two smoke <img> in #stage are the no-WebGL fallback only */
    /* the smoke lives BEHIND the scene (between the backdrop and the stage) while
       ambient; it comes to the front only to engulf the screen and to lift again */
    #fluid { position: fixed; inset: 0; z-index: 1; width: 100%; height: 100%; pointer-events: none; }
    body.smoke-front #fluid { z-index: 6; }
    #stage { contain: paint; will-change: transform; }
    /* the clock moves every scroll frame (translate + scale) and tilts every frame:
       composited layers, or each move repaints the stage tiles around it, and a
       phone that cannot keep up shows the missing tiles as dark squares */
    #clockzone, #clock3d { will-change: transform; }
    /* the hands turn every frame and the ring redraws every frame while held:
       their own layers, or the whole clock face is repainted each time (at DPR 3
       on an iPhone, that alone halves the frame rate) */
    #ring-svg, #hand-hour, #hand-minute, #hand-second { will-change: transform; }
    @supports (height: 100lvh) { #fluid, #stage, #bg { height: 100lvh; bottom: auto; } }
    body.no-fluid #fluid { display: none; }
    body:not(.no-fluid) .smoke { display: none; }

    @keyframes ctaBreath { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
    #cta { animation: ctaBreath 4.5s ease-in-out infinite; transition: opacity .4s ease; }
    .winding #cta, .revealed #cta, .revealing #cta { animation: none; opacity: 0; }
    .winding .gear-spin { animation-duration: 2.4s !important; }
    .winding .gear-balance { animation-duration: .35s !important; }

    .lang-fr { display: none; }
    .fr .lang-fr { display: block; }
    .fr .lang-en { display: none; }
    span.lang-fr { display: none; }
    .fr span.lang-fr { display: inline; }
    .fr span.lang-en { display: none; }

    .langbtn { cursor: pointer; background: none; border: none; padding: 4px 6px; font: 500 11px/1 "Hanken Grotesk", "Segoe UI", sans-serif; letter-spacing: .18em; color: #8fa3b1; }
    .langbtn.active { color: #e8c391; }
    .mutebtn { padding: 3px 4px; display: inline-flex; color: #8fa3b1; transition: color .25s; }
    .mutebtn:hover { color: #e8c391; }
    .mutebtn .cross { display: none; }
    .mutebtn.muted .wave { display: none; }
    .mutebtn.muted .cross { display: block; }
    #langswitch, #soundswitch { z-index: 8; } /* above the teaser and the smoke: the mute stays reachable while the film plays */

    .navlink { font: 500 11px/1 "Hanken Grotesk", "Segoe UI", sans-serif; letter-spacing: .3em; color: #A9C0CA; text-transform: uppercase; transition: color .25s; }
    .navlink:hover { color: #e8c391; }
    .social { display: inline-flex; align-items: center; gap: 8px; padding: 6px 2px; color: #A9C0CA; font: 500 12.5px/1 'Hanken Grotesk', 'Segoe UI', sans-serif; letter-spacing: .06em; transition: color .25s ease, transform .18s ease; }
    .social svg { width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; transition: transform .25s ease; }
    .social.gold { color: #e8c391; }
    .social:hover { color: #f0d3a6; }
    .social:hover svg { transform: translateY(-1px); }
    .social:active { transform: scale(.96); color: #fff4dc; }
    .social:focus-visible { outline: 1px solid rgba(240,211,166,.6); outline-offset: 3px; }
    .social-sep { width: 1px; height: 12px; background: rgba(232,195,145,.3); }

    #glitchfx { visibility: hidden; }
    .glitching #glitchfx { visibility: visible; }
    .glitching #clock3d { animation: glJitter .14s steps(2) infinite; }
    @keyframes glJitter {
      0% { translate: 0 0; } 50% { translate: 3px -2px; } 100% { translate: -3px 2px; }
    }
    .gl-slice { position: absolute; inset: 0; width: 100%; height: 100%; mix-blend-mode: screen; }
    .gl-slice.r { filter: sepia(1) saturate(3) hue-rotate(-48deg) brightness(.92) contrast(1.1); opacity: .55; animation: glSliceR .19s steps(2) infinite; }
    .gl-slice.g { filter: sepia(1) saturate(2.6) hue-rotate(4deg) brightness(1.08) contrast(1.08); opacity: .55; animation: glSliceG .23s steps(2) infinite; }
    @keyframes glSliceR {
      0% { transform: translateX(-9px); clip-path: polygon(0 8%, 100% 8%, 100% 22%, 0 22%, 0 46%, 100% 46%, 100% 52%, 0 52%); opacity: .5; }
      50% { transform: translateX(6px); clip-path: polygon(0 30%, 100% 30%, 100% 41%, 0 41%, 0 70%, 100% 70%, 100% 79%, 0 79%); opacity: .32; }
      100% { transform: translateX(-5px); clip-path: polygon(0 55%, 100% 55%, 100% 66%, 0 66%, 0 12%, 100% 12%, 100% 18%, 0 18%); opacity: .5; }
    }
    @keyframes glSliceG {
      0% { transform: translateX(8px); clip-path: polygon(0 24%, 100% 24%, 100% 33%, 0 33%, 0 60%, 100% 60%, 100% 68%, 0 68%); opacity: .48; }
      50% { transform: translateX(-7px); clip-path: polygon(0 44%, 100% 44%, 100% 50%, 0 50%, 0 84%, 100% 84%, 100% 90%, 0 90%); opacity: .3; }
      100% { transform: translateX(5px); clip-path: polygon(0 16%, 100% 16%, 100% 25%, 0 25%, 0 73%, 100% 73%, 100% 80%, 0 80%); opacity: .48; }
    }
    .gl-bar { position: absolute; left: -2%; right: -2%; height: 1.7%; mix-blend-mode: screen; filter: blur(1px); background: linear-gradient(90deg, rgba(255,64,48,0) 0%, rgba(255,64,48,.55) 22%, rgba(232,195,145,.6) 55%, rgba(255,64,48,.28) 78%, rgba(232,195,145,0) 100%); }
    .gl-bar.b1 { animation: glBar1 .27s steps(1) infinite; }
    .gl-bar.b2 { animation: glBar2 .21s steps(1) infinite; }
    .gl-bar.b3 { animation: glBar3 .33s steps(1) infinite; }
    @keyframes glBar1 { 0% { top: 18%; } 33% { top: 61%; } 66% { top: 37%; } 100% { top: 18%; } }
    @keyframes glBar2 { 0% { top: 72%; } 50% { top: 26%; } 100% { top: 72%; } }
    @keyframes glBar3 { 0% { top: 47%; } 25% { top: 12%; } 60% { top: 83%; } 100% { top: 47%; } }
    .gl-ring { position: absolute; inset: -1.2%; border-radius: 50%; }
    .gl-ring.r { border: 1.5px solid rgba(255,64,48,.9); box-shadow: 0 0 20px rgba(255,64,48,.5), inset 0 0 24px rgba(255,64,48,.22); animation: glRingR .17s steps(2) infinite; }
    .gl-ring.g { border: 1.5px solid rgba(232,195,145,.9); box-shadow: 0 0 20px rgba(232,195,145,.5), inset 0 0 24px rgba(232,195,145,.2); animation: glRingG .21s steps(2) infinite; }
    @keyframes glRingR { 0% { translate: -5px 2px; opacity: .9; } 50% { translate: 4px -2px; opacity: .5; } 100% { translate: -3px -3px; opacity: .9; } }
    @keyframes glRingG { 0% { translate: 5px -2px; opacity: .9; } 50% { translate: -4px 3px; opacity: .3; } 100% { translate: 3px 2px; opacity: .9; } }
    @media (prefers-reduced-motion: reduce) { .glitching #clock3d, .gl-slice, .gl-bar, .gl-ring { animation: none !important; } }
    /* frozen beat between the two bursts: a clean, cold 10:10 with everything stopped */
    .frozen #clock3d { filter: grayscale(.35) contrast(1.08) hue-rotate(-8deg); }
    .frozen .gear-spin, .frozen #subdial-needle { animation-play-state: paused !important; }
    #scan { position: absolute; inset: 0; border-radius: 50%; overflow: hidden; pointer-events: none; opacity: 0; mix-blend-mode: screen; background: repeating-linear-gradient(0deg, rgba(255,255,255,.04) 0 1px, transparent 1px 3px); }
    #scan::after { content: ''; position: absolute; left: 0; right: 0; top: -14%; height: 12%; background: linear-gradient(180deg, rgba(232,195,145,0) 0%, rgba(232,195,145,.14) 50%, rgba(232,195,145,0) 100%); }
    .frozen #scan { opacity: 1; }
    .frozen #scan::after { animation: scanSweep 1.8s linear forwards; }
    @keyframes scanSweep { to { top: 102%; } }
    /* ---------- fullscreen teaser (outside #stage, under the smoke canvas) ---------- */
    /* the film is never cropped: it fits inside the screen, on the page's own
       backdrop (not black bars), lifted by a soft shadow when bars appear */
    #teaser { position: fixed; inset: 0; z-index: 5; background: radial-gradient(120% 95% at 32% 18%, #0b151b 0%, #071013 50%, #03080b 100%); display: none; overflow: hidden; align-items: center; justify-content: center; }
    #teaser.open { display: flex; }
    /* the zoom carries through the smoke: the video starts closer and settles,
       and pushes in again while the ténèbres take it back */
    /* the film also fades in and out under the smoke, so a thin patch of smoke
       (slow phone) never lets it pop or vanish in one frame */
    /* No transform on the video element: scaling a playing video makes Chrome
       re-place its surface every frame and the picture visibly vibrates (badly on
       Android). The film only fades; the zoom is carried by the stage diving in. */
    /* full width always: on a screen wider than 16:9 the film overflows top and
       bottom and is cropped there; on a narrower one it is letterboxed, never cropped sideways */
    #teaser-video { display: block; width: auto; height: auto; max-width: 100%; max-height: 100%; flex: none; background: #000; box-shadow: 0 28px 90px rgba(0,0,0,.65), 0 6px 24px rgba(0,0,0,.5), 0 0 0 1px rgba(232,195,145,.07); opacity: 0; transition: opacity 1.4s ease; }
    #teaser.settled #teaser-video { opacity: 1; }
    #teaser.leaving #teaser-video { opacity: 0; transition: opacity 1.1s ease .3s; }
    .tbtn { position: absolute; left: 50%; transform: translateX(-50%); cursor: pointer; background: rgba(2,6,9,.55); border: 1px solid rgba(232,195,145,.4); padding: 10px 26px; font: 500 11px/1 'Hanken Grotesk', sans-serif; letter-spacing: .3em; text-indent: .3em; color: #e8c391; text-transform: uppercase; opacity: 0; pointer-events: none; transition: opacity .35s ease; }
    #btn-close { bottom: 34px; }
    .tbtn { z-index: 3; }
    /* rotate prompt: a 70% black veil over the paused film, the pictogram turns
       to landscape and back on a loop; no pointer: Close stays reachable through it */
    #rotate { position: absolute; inset: 0; z-index: 2; display: none; flex-direction: column; align-items: center; justify-content: center; gap: 22px; background: rgba(0,0,0,.7); pointer-events: none; opacity: 0; transition: opacity .5s ease; }
    #teaser.rotate #rotate { display: flex; }
    #teaser.rotate.rotate-in #rotate { opacity: 1; }
    #teaser.leaving #rotate { opacity: 0; }
    #rotate svg { width: 72px; height: 72px; overflow: visible; }
    #rotate .rp-phone { transform-origin: 32px 32px; animation: rotatePhone 2.6s cubic-bezier(.65,0,.35,1) infinite; }
    #rotate .rp-arrow { animation: rotateArrow 2.6s ease-in-out infinite; }
    @keyframes rotatePhone { 0%, 18% { transform: rotate(0deg); } 48%, 72% { transform: rotate(-90deg); } 100% { transform: rotate(0deg); } }
    @keyframes rotateArrow { 0%, 18% { opacity: .7; } 48%, 72% { opacity: 0; } 100% { opacity: .7; } }
    #rotate p { margin: 0; font: 500 11px/1 'Hanken Grotesk', sans-serif; letter-spacing: .3em; text-transform: uppercase; color: #e8c391; }
    @media (prefers-reduced-motion: reduce) { #rotate .rp-phone, #rotate .rp-arrow { animation: none; } #rotate .rp-phone { transform: rotate(-90deg); } }
    #teaser.ui #btn-close { opacity: 1; pointer-events: auto; }
    /* No flash of the fallback font: text waits for the webfonts (main.js adds
       fonts-ready when they are in, or after 2 s at most) */
    .gate-sub, #copy, #footerlinks, #langswitch, #soundswitch { opacity: 0; transition: opacity 1.1s ease; }
    body.fonts-ready .gate-sub, body.fonts-ready #copy, body.fonts-ready #footerlinks, body.fonts-ready #langswitch, body.fonts-ready #soundswitch { opacity: 1; }
    /* these two already breathe with an opacity animation: fade them in through a filter instead */
    .gate-cta, #cta { filter: opacity(0); transition: filter 1.1s ease .15s; }
    body.fonts-ready #cta { filter: opacity(1); }
    /* the gate: a light line fills while the scene loads (before the script
       runs, a glint travels along it); the invitation replaces it once ready */
    .gate-load { position: relative; width: 150px; height: 1px; margin: 4px 0 6px; background: rgba(232,195,145,.14); transition: opacity .6s ease .5s; }
    .gate-load::after { content: ''; position: absolute; top: -1px; left: 0; width: 34px; height: 3px; background: linear-gradient(90deg, rgba(240,211,166,0), rgba(240,211,166,.9), rgba(240,211,166,0)); filter: blur(.6px); animation: gateGlint 1.8s ease-in-out infinite; }
    .gate-load i { position: absolute; left: 0; top: 0; height: 100%; width: 100%; transform: scaleX(0); transform-origin: 0 50%; background: #f0d3a6; box-shadow: 0 0 5px rgba(232,195,145,.9), 0 0 14px rgba(232,195,145,.45); transition: transform .45s ease; }
    @keyframes gateGlint { 0% { left: -34px; opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { left: 150px; opacity: 0; } }
    #gate.ready .gate-load { opacity: 0; }
    #gate.ready .gate-load::after { animation: none; }
    #gate:not(.ready) { cursor: default; }
    #gate:not(.ready) .gate-sub { opacity: 0; }
    #gate.ready .gate-cta { filter: opacity(1); }
    @media (prefers-reduced-motion: reduce) { .gate-load::after { animation: none; } }

    /* ---------- scroll hint ---------- */
    #scrollhint { position: absolute; left: 20px; bottom: 26px; width: 20px; height: min(300px, 38vh); pointer-events: none; z-index: -1; opacity: .62; } /* z -1: under the copy and the links, never over a word */
    @media (max-width: 1000px) { #scrollhint { display: none; } } /* the link rows wrap and reach the left edge here */
    #scrollhint svg { display: block; overflow: visible; }
    @media (prefers-reduced-motion: reduce) { #scrollhint { display: none; } }

    /* ---------- the one-pager ---------- */
    #page { position: relative; z-index: 7; pointer-events: none; } /* the scene behind stays clickable; only section content takes the pointer */
    .section { min-height: 100vh; min-height: 100svh; display: flex; align-items: center; justify-content: center; padding: 96px 24px; pointer-events: none; }
    .section > * { pointer-events: auto; }
    .section.hero { padding: 0; min-height: 135vh; min-height: 135svh; } /* room for the clock to leave the screen before the next section */
    /* the hero copy, links and call to action leave with the scroll; the lockup and the switches stay as a header */
    #copy, #footerlinks { will-change: transform, opacity; }
    body.scrolled #cta { animation: none; opacity: 0; }
    body.scrolled #clockzone { cursor: default; }
    #epic { position: fixed; left: 0; right: 0; bottom: 10px; z-index: 8; padding: 0 16px; text-align: center; font: 300 9px/1.4 'Hanken Grotesk', sans-serif; letter-spacing: .08em; color: rgba(143,163,177,.55); pointer-events: none; }
    /* while the film is up the document cannot scroll (position: fixed is what
       iOS actually honours, overflow alone is not) and the scrolling page, which
       sits above the player, is hidden: nothing can slide over the film. Only
       Close (or the end of the film) leaves; the page comes back on close. */
    body.teaser-open { overflow: hidden; position: fixed; inset: 0; width: 100%; touch-action: none; }
    body.teaser-open #page { visibility: hidden; }

    /* ---------- follow section ---------- */
    .follow-card { width: min(520px, 100%); text-align: center; padding: 40px 32px 40px; border: 1px solid rgba(232,195,145,.22); background: rgba(4,10,14,.86); opacity: 0; transform: translateY(72px) scale(.965); transition: opacity .9s ease, transform 1.5s cubic-bezier(.18, .85, .22, 1.04); }
    .follow-card.in { opacity: 1; transform: translateY(0) scale(1); }
    .follow-eyebrow { font: 500 11px/1 'Hanken Grotesk', sans-serif; letter-spacing: .42em; text-indent: .42em; color: #8fa3b1; text-transform: uppercase; margin-bottom: 18px; }
    .follow-title { margin: 0 0 16px; font: 400 clamp(26px, 4.4vh, 40px)/1.15 'Bodoni Moda', 'Didot', serif; font-weight: 475; color: #F4F8FA; }
    .follow-title em { font-style: italic; letter-spacing: .1em; color: #e8c391; }
    .follow-text { margin: 0 auto 26px; max-width: 420px; font: 300 15px/1.55 'Hanken Grotesk', sans-serif; color: #c3d2dc; }
    .follow-text b { font-weight: 600; color: #fff; }
    .follow-btn { display: inline-block; padding: 14px 30px; border: 1px solid #e8c391; font: 500 12px/1 'Hanken Grotesk', sans-serif; letter-spacing: .32em; text-indent: .32em; color: #e8c391; text-transform: uppercase; transition: background .3s ease, color .3s ease; }
    .follow-btn:hover { background: #e8c391; color: #06101a; }
    .follow-social { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 14px; margin: 30px 0 0; }
    .follow-social.follow-poppy { margin-top: 18px; }
    .follow-social a { font: 500 11px/1 'Hanken Grotesk', sans-serif; letter-spacing: .3em; color: #A9C0CA; text-transform: uppercase; transition: color .25s; }
    .follow-social a:hover { color: #e8c391; }
    .follow-label { width: 100%; font: 300 10px/1 'Hanken Grotesk', sans-serif; letter-spacing: .3em; text-indent: .3em; color: rgba(143,163,177,.7); text-transform: uppercase; margin-bottom: 2px; }
    .follow-social .dot { width: 3px; height: 3px; border-radius: 50%; background: linear-gradient(135deg, #f0d3a6, #c99a5e); }
    #page .lang-fr { display: none; } body.fr #page .lang-fr { display: inline; } body.fr #page .lang-en { display: none; }
    @media (max-width: 700px) { .follow-card { padding: 30px 20px 22px; } .follow-text { font-size: 14px; } }

    /* ---------- entry gate ---------- */
    #gate { position: fixed; inset: 0; z-index: 9; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; cursor: pointer; background: radial-gradient(120% 95% at 50% 40%, #07131a 0%, #04090c 55%, #02050a 100%); transition: opacity 1.4s ease; }
    #gate.leaving { opacity: 0; pointer-events: none; }
    #gate.gone { display: none; }
    .gate-lockup { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; }
    .gate-lockup img:first-child { height: 30px; filter: brightness(1.05); }
    .gate-lockup img:last-child { height: 18px; opacity: .96; }
    .gate-lockup span { font: italic 400 19px/1 'Bodoni Moda', 'Didot', serif; color: #e8c391; }
    .gate-cta { font: 500 12px/1 'Hanken Grotesk', sans-serif; letter-spacing: .42em; text-indent: .42em; color: #e8c391; text-transform: uppercase; animation: ctaBreath 4.5s ease-in-out infinite; }
    .gate-sub { font: 300 12px/1 'Hanken Grotesk', sans-serif; letter-spacing: .2em; text-indent: .2em; color: #8fa3b1; text-transform: uppercase; }
    #gate .lang-fr { display: none; } body.fr #gate .lang-fr { display: inline; } body.fr #gate .lang-en { display: none; }
    @media (prefers-reduced-motion: reduce) { .gate-cta { animation: none; } }

    /* no-WebGL / reduced-motion transition: a plain fade to black instead of the smoke */
    #blackout { position: fixed; inset: 0; z-index: 7; background: #02050a; opacity: 0; pointer-events: none; transition: opacity .8s ease; }
    #blackout.on { opacity: 1; }

    /* ---------- portrait / narrow windows ----------
       the clock is sized by the smaller of width and height, so it never grows
       into the copy below it or the lockup above it */
    /* Spacing model, every format: lockup (34px) + call to action + 56px of air
       above the clock; at least 72px of air between the clock and the copy;
       copy 78px above the footer band. The clock takes what is left, capped. */
    @media (orientation: portrait) {
      #clockzone { width: min(84vw, 46vh, calc(100vh - 440px)) !important; top: calc(50vh - 60px) !important; }
    }
    @media (max-height: 640px) {
      #clockzone { width: min(84vw, 42vh, calc(100vh - 330px)) !important; top: calc(50vh - 50px) !important; }
      #cta { top: 66px !important; }
      #copy { bottom: 60px !important; }
      #footerlinks { bottom: 24px !important; }
    }

    /* ---------- mobile ---------- */
    @media (max-width: 700px) {
      #lockup { top: 26px !important; }
      #lockup img.lk-poppy { height: 20px !important; }
      #lockup img.lk-sw { height: 13px !important; }
      #langswitch { left: 16px !important; right: auto !important; top: 26px !important; }
      #soundswitch { right: 16px !important; top: 26px !important; }
      /* Mobile rhythm, from the SMALL viewport (the one with the address bar
         shown): lockup 26, call to action 58, then the clock centred in the band
         left between the call to action and the copy, copy 150 above the
         footer band, footer, Epic line. Nothing may touch its neighbour. */
      #cta { top: 58px !important; }
      #clockzone { width: min(80vw, 40svh, calc(100svh - 400px)) !important; top: calc(50svh - 92px) !important; }
      /* centre = midpoint of (call to action bottom 79, copy top 100svh - 264):
         no lvh term here, the stage top is the visible top; the diameter leaves
         at least 28px on each side */
      #copy h1 { font-size: 24px !important; margin-bottom: 8px !important; }
      #copy .sub { font-size: 13px !important; padding: 0 9vw; margin-bottom: 12px !important; }
      #copy .soon { font-size: 11px !important; }
      /* mobile perf: no CPU-rasterised SVG filter on the moving clock, one static
         grain layer instead of three animated blended ones, fewer blurred mist layers */
      #clock3d { filter: none !important; }
      #grain2, #grain3 { display: none; }
      #grain { animation: none !important; mix-blend-mode: normal; opacity: .07 !important; }
      .mist:nth-of-type(3), .mist:nth-of-type(4) { display: none; }
      #beam { display: none; }
      #footerlinks { gap: 0 14px !important; padding: 0 12px; }
      .social { padding: 4px 2px; font-size: 11px; gap: 6px; }
      .social svg { width: 15px; height: 15px; }
      .social-sep { width: 100%; height: 0; background: none; }
      /* the stage is 100lvh tall (so the smoke never resizes when the address
         bar collapses); the bottom blocks anchor to the small viewport instead,
         so they stay above the bar, and the Epic line sits under them */
      #copy { bottom: calc(100lvh - 100svh + 152px) !important; }
      #footerlinks { bottom: calc(100lvh - 100svh + 38px) !important; }
      #epic { bottom: 6px !important; font-size: 7.5px !important; letter-spacing: .03em !important; line-height: 1.3 !important; }
      #scrollhint { display: none; } /* a finger scrolls by instinct; the hint only crowds the footer here */
    }

    /* ---------- a phone held sideways ----------
       A short, wide, touch screen (a phone in landscape; a laptop with a short
       window is not one). The stacked composition cannot fit in 360px of
       height, so it becomes two columns: the clock on the left, the copy on the
       right, the lockup and the call to action along the top, the links along
       the bottom. Same perf rules as portrait: it is the same phone. */
    @media (max-height: 520px) and (orientation: landscape) and (pointer: coarse) {
      #lockup { top: 12px !important; }
      #lockup img.lk-poppy { height: 18px !important; }
      #lockup img.lk-sw { height: 12px !important; }
      #langswitch { left: 16px !important; right: auto !important; top: 12px !important; }
      #soundswitch { right: 16px !important; top: 12px !important; }
      #cta { top: 40px !important; }
      #cta span { font-size: 10px !important; letter-spacing: .28em !important; }
      #clockzone { left: 26% !important; width: min(58svh, 28vw) !important; top: 50svh !important; }
      #copy { left: 50% !important; right: 0 !important; bottom: auto !important; top: calc(50svh - 50px) !important; padding: 0 24px 0 8px; }
      #copy h1 { font-size: 22px !important; margin-bottom: 6px !important; }
      #copy .sub { font-size: 12px !important; padding: 0; margin-bottom: 8px !important; }
      #copy .soon { font-size: 10px !important; margin-bottom: 0 !important; }
      #footerlinks { bottom: calc(100lvh - 100svh + 20px) !important; gap: 0 12px !important; padding: 0 16px; }
      .social { padding: 3px 2px; font-size: 10px; gap: 5px; }
      .social svg { width: 13px; height: 13px; }
      .social-sep { width: 100%; height: 0; background: none; }
      #epic { bottom: 3px !important; font-size: 7px !important; letter-spacing: .03em !important; line-height: 1.3 !important; }
      #scrollhint, #beam { display: none; }
      #clock3d { filter: none !important; }
      #grain2, #grain3 { display: none; }
      #grain { animation: none !important; mix-blend-mode: normal; opacity: .07 !important; }
      .mist:nth-of-type(3), .mist:nth-of-type(4) { display: none; }
      /* the Follow card, compact enough to sit whole inside the short screen */
      .section { padding: 36px 24px 40px; }
      .follow-card { width: min(600px, 100%); padding: 20px 26px 18px; }
      .follow-eyebrow { font-size: 10px; margin-bottom: 10px; }
      .follow-title { font-size: 22px; margin-bottom: 8px; }
      .follow-text { font-size: 13px; line-height: 1.45; margin-bottom: 14px; max-width: 480px; }
      .follow-btn { padding: 11px 22px; font-size: 11px; }
    }