/* ============================================================
   VOID© — /fragrance · NÉANT, Extrait de Parfum
   A layered 2.5D product stage: the bottle, its specular glass
   lighting, rim light, amber core, contact shadow and floor
   reflection are all separate layers so each can respond to the
   pointer with its own weight (see PARALLAX in the JS below).
   Everything animates on transform/opacity only.

   All tunable values live in the :root block — nothing below
   hard-codes a tilt, damping or opacity figure.
   ============================================================ */

:root {
    /* ── Palette (matches the house tokens in index.html) ── */
    --fr-black: #030302;
    --fr-black-2: #050403;
    --fr-gold: #c7a96c;
    --fr-gold-soft: #d9bd81;
    --fr-gold-bright: #f0dca8;
    --fr-amber: 212, 175, 55;
    --fr-text: rgba(245, 242, 236, 0.72);
    --fr-text-muted: rgba(245, 242, 236, 0.4);
    --fr-ease: cubic-bezier(0.16, 1, 0.3, 1);

    /* ── TUNABLES ──────────────────────────────────────────
       Rotation (deg). Kept under 6° — heavy glass, not a card. */
    --fr-max-tilt-x: 3;
    --fr-max-tilt-y: 4;
    /* Bottle translation (px) */
    --fr-translate-x: 7;
    --fr-translate-y: 4;
    /* Inertia: 0→1, lower = heavier/slower catch-up */
    --fr-damping: 0.055;
    /* Return-to-rest damping when the pointer leaves */
    --fr-release-damping: 0.035;

    /* The bottle artwork. Its own alpha is reused as the mask for the
       lighting layers and the reflection, so every highlight is clipped
       exactly to the glass silhouette. One line to swap the asset. */
    --fr-bottle: url('/assets/fragrance/neant-bottle-transparent.webp');

    /* Lighting */
    --fr-glare-intensity: 0.3;
    --fr-glare-size: 42%;
    --fr-edge-intensity: 0.26;
    --fr-amber-intensity: 0.58;

    /* Shadow */
    --fr-shadow-opacity: 0.66;
    --fr-shadow-blur: 26px;
    --fr-shadow-move: 12;

    /* Reflection */
    --fr-reflection-opacity: 0.26;
    --fr-reflection-blur: 5px;
    --fr-reflection-squash: 0.58;
    --fr-reflection-fade: 38%;

    /* Where the bottle's base actually sits in the artwork, as a fraction of
       image height — measured from the asset's alpha channel (opaque pixels
       end at 96.55%, so there is 3.4% of empty padding beneath the glass).
       Re-measure this if the artwork is ever re-exported. */
    --fr-bottle-base: 0.9655;
    /* Bottle box height as a share of the stage. The floor line — where the
       glass meets the stone — is base × this, and the shadow, floor pool and
       reflection all key off it so they can never drift apart. */
    --fr-bottle-height: 78%;
    --fr-floor-line: calc(var(--fr-bottle-base) * var(--fr-bottle-height));
    /* The reflection mirrors about the box's bottom edge, so that padding is
       doubled into a visible gap under the bottle. Lift it by exactly the gap:
       (1 + squash·(1−base)) − base. Derived rather than eyeballed, so it stays
       correct if --fr-reflection-squash is retuned. */
    --fr-reflection-offset: calc(
        (1 + var(--fr-reflection-squash) * (1 - var(--fr-bottle-base)) - var(--fr-bottle-base)) * -100%);

    /* Layer parallax weights (fraction of the bottle's own movement) */
    --fr-w-glare: 0.8;
    --fr-w-shadow: 0.3;
    --fr-w-reflection: 0.28;
    --fr-w-backglow: 0.15;
    --fr-w-bg: 0.05;

    /* Live pointer state, written by JS (-1 … 1) */
    --fr-px: 0;
    --fr-py: 0;
    --fr-active: 0;
    /* Manifesto section: ambient light position + crest specular strength */
    --fr-mx: 0;
    --fr-my: 0;
    --fr-crest-lit: 0;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
    background: var(--fr-black);
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    min-height: 100dvh;
    background: var(--fr-black);
    color: var(--fr-text);
    font-family: 'Jost', system-ui, -apple-system, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
}

::selection { background: rgba(var(--fr-amber), 0.26); color: #fff7e8; }

:focus-visible {
    outline: 1px solid rgba(var(--fr-amber), 0.8);
    outline-offset: 3px;
}

/* ── Atmosphere ─────────────────────────────────────────────
   Three still gradient layers. No blur filter, no tiled noise —
   both were measured problems elsewhere on this site. */
.fr-atmos {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(80% 46% at 50% 34%, rgba(var(--fr-amber), 0.05), transparent 64%),
        radial-gradient(120% 60% at 50% 108%, rgba(var(--fr-amber), 0.028), transparent 62%),
        linear-gradient(180deg, #060605 0%, var(--fr-black) 42%, var(--fr-black-2) 100%);
    transform: translate3d(calc(var(--fr-px) * var(--fr-w-bg) * 10px), calc(var(--fr-py) * var(--fr-w-bg) * 10px), 0);
}

.fr-atmos::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(130% 100% at 50% 45%, transparent 40%, rgba(0, 0, 0, 0.8) 100%);
}

/* ── Minimal nav ── */
.fr-nav {
    position: relative;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    padding: clamp(1.3rem, 3vw, 2rem) clamp(1.2rem, 5vw, 3rem);
}

.fr-nav a {
    color: var(--fr-text-muted);
    font-size: 0.58rem;
    font-weight: 500;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    text-decoration: none;
    transition: color 0.45s var(--fr-ease);
}

.fr-nav a:hover, .fr-nav a:focus-visible { color: var(--fr-gold-soft); }

.fr-nav-mark {
    width: 20px;
    height: 20px;
    background: var(--fr-gold);
    opacity: 0.5;
    -webkit-mask: url('/assets/ev-emblem.png') center / contain no-repeat;
    mask: url('/assets/ev-emblem.png') center / contain no-repeat;
}

/* ── Hero ── */
.fr-hero {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Light on top so the glass sits high in frame, generous below so the
       identity has room to breathe before the chamber begins. */
    padding: clamp(0.5rem, 2vh, 1.4rem) clamp(1.1rem, 5vw, 2rem) clamp(5rem, 14vh, 9rem);
}

/* ── Identity, set directly beneath the glass ───────────────
   Tight to the bottle (negative top margin pulls it up into the space the
   reflection vacates) so the two read as one object. Centred, because the
   bottle itself is the axis — asymmetry belongs to the chamber below. */
.fr-identity {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: clamp(-3.5rem, -5vh, -2rem);
    text-align: center;
}

.fr-name {
    font-family: 'Cormorant Garamond', serif;
    font-size: clamp(2.9rem, 9.5vw, 5.2rem);
    font-weight: 500;
    line-height: 1;
    letter-spacing: 0.26em;
    text-indent: 0.26em;
    text-transform: uppercase;
    background: linear-gradient(176deg, #fbf3e2 0%, #ecd9ad 26%, #cdb076 60%, #8a6c34 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--fr-gold-soft);
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 1s var(--fr-ease) 0.5s, transform 1s var(--fr-ease) 0.5s;
}

.is-ready .fr-name { opacity: 1; transform: translateY(0); }

.fr-kind {
    margin-top: clamp(0.6rem, 1.6vw, 0.95rem);
    font-family: 'Cormorant Garamond', serif;
    font-style: italic;
    font-weight: 400;
    font-size: clamp(1rem, 2.5vw, 1.22rem);
    letter-spacing: 0.14em;
    color: rgba(245, 242, 236, 0.6);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 1s var(--fr-ease) 0.62s, transform 1s var(--fr-ease) 0.62s;
}

.is-ready .fr-kind { opacity: 1; transform: translateY(0); }

.fr-id-rule {
    display: block;
    width: 0;
    height: 1px;
    margin: clamp(1.3rem, 3.4vw, 2rem) 0 clamp(1.1rem, 3vw, 1.6rem);
    background: linear-gradient(90deg, transparent, rgba(var(--fr-amber), 0.55), transparent);
    transition: width 1.1s var(--fr-ease) 0.76s;
}

.is-ready .fr-id-rule { width: clamp(90px, 16vw, 150px); }

.fr-maison {
    font-family: 'Cormorant SC', 'Cormorant Garamond', serif;
    font-size: clamp(0.6rem, 1.5vw, 0.7rem);
    letter-spacing: 0.46em;
    text-indent: 0.46em;
    color: rgba(var(--fr-amber), 0.55);
    opacity: 0;
    transition: opacity 1.1s var(--fr-ease) 0.88s;
}

.is-ready .fr-maison { opacity: 1; }

/* ── Product stage ──────────────────────────────────────────
   Fixed aspect box so nothing reflows while the bottle moves. */
.fr-stage {
    position: relative;
    width: min(560px, 92vw);
    /* Sized so the glass itself lands around 55vh — the stage is taller than
       the bottle because the reflection needs room beneath the floor line. */
    height: clamp(400px, 71vh, 720px);
    perspective: 1400px;
    perspective-origin: 50% 45%;
    touch-action: pan-y;
}

/* Warm pool sitting behind the glass, separating it from the dark. */
.fr-backglow {
    position: absolute;
    left: 50%;
    top: 52%;
    width: 78%;
    height: 62%;
    border-radius: 50%;
    background: radial-gradient(circle,
        rgba(var(--fr-amber), calc(0.16 * var(--fr-amber-intensity))) 0%,
        rgba(var(--fr-amber), calc(0.06 * var(--fr-amber-intensity))) 42%,
        transparent 72%);
    transform: translate3d(
        calc(-50% + var(--fr-px) * var(--fr-w-backglow) * var(--fr-translate-x) * 1px),
        calc(-50% + var(--fr-py) * var(--fr-w-backglow) * var(--fr-translate-y) * 1px), 0);
    opacity: 0;
    transition: opacity 1.4s var(--fr-ease) 0.5s;
    pointer-events: none;
}

.is-ready .fr-backglow { opacity: 1; }

/* Floor light — the only hint that a surface exists at all. */
.fr-floor {
    position: absolute;
    left: 50%;
    top: var(--fr-floor-line);
    width: 84%;
    height: 17%;
    border-radius: 50%;
    background: radial-gradient(ellipse,
        rgba(var(--fr-amber), 0.09) 0%,
        rgba(var(--fr-amber), 0.03) 42%,
        transparent 72%);
    transform: translate3d(-50%, -46%, 0);
    opacity: 0;
    transition: opacity 1.4s var(--fr-ease) 0.6s;
    pointer-events: none;
}

.is-ready .fr-floor { opacity: 1; }

/* Contact shadow — independent of the bottle, drifts opposite. */
/* Sits on the floor line, drifting opposite the bottle so the light source
   stays believable. Narrower than the glass so contact reads as a footprint
   rather than a halo. */
.fr-shadow {
    position: absolute;
    left: 50%;
    top: var(--fr-floor-line);
    width: 42%;
    height: 4.6%;
    border-radius: 50%;
    background: radial-gradient(ellipse, rgba(0, 0, 0, 0.95) 0%, rgba(0, 0, 0, 0.55) 46%, transparent 74%);
    filter: blur(var(--fr-shadow-blur));
    opacity: 0;
    transform: translate3d(
        calc(-50% - var(--fr-px) * var(--fr-w-shadow) * var(--fr-shadow-move) * 1px), -34%, 0);
    transition: opacity 1.2s var(--fr-ease) 0.45s;
    pointer-events: none;
}

.is-ready .fr-shadow { opacity: var(--fr-shadow-opacity); }

/* ── Bottle ── */
/* Locked to the artwork's own aspect ratio so `contain` fits exactly with no
   letterbox — that makes every percentage in the lighting gradients and the
   reflection line up with the bottle instead of with empty space. */
.fr-bottle-wrap {
    position: absolute;
    left: 50%;
    top: 0;
    height: var(--fr-bottle-height);
    aspect-ratio: 1024 / 1536;
    transform-style: preserve-3d;
    transform: translate3d(-50%, 0, 0);
    pointer-events: none;
}

.fr-bottle {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    will-change: transform;
    transform:
        translate3d(
            calc(var(--fr-px) * var(--fr-translate-x) * 1px),
            calc(var(--fr-py) * var(--fr-translate-y) * 1px), 0)
        rotateX(calc(var(--fr-py) * var(--fr-max-tilt-x) * -1deg))
        rotateY(calc(var(--fr-px) * var(--fr-max-tilt-y) * 1deg));
    opacity: 0;
    transition: opacity 1.6s var(--fr-ease) 0.35s;
}

.is-ready .fr-bottle { opacity: 1; }

/* The supplied render carries its own dark backdrop, so the edges are
   masked away radially — the artwork's own glow then blends into the
   page instead of ending at a visible rectangle. Swapping in a true
   cut-out asset only means dropping this mask. */
/* The asset is a true cut-out, so it needs no mask of its own — the glass
   edge is the artwork's own alpha, untouched. */
.fr-bottle-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Specular travelling highlight, clipped to the bottle silhouette. */
.fr-glare {
    position: absolute;
    inset: 0;
    pointer-events: none;
    mix-blend-mode: screen;
    opacity: calc(var(--fr-glare-intensity) * var(--fr-active));
    /* `ellipse <pct> <pct>` rather than `circle <pct>` — a circle's radius
       must be a length, so a percentage there invalidates the gradient. */
    background: radial-gradient(
        ellipse var(--fr-glare-size) var(--fr-glare-size) at
            calc(50% + var(--fr-px) * 34%)
            calc(42% + var(--fr-py) * 22%),
        rgba(255, 246, 226, 0.3) 0%,
        rgba(var(--fr-amber), 0.12) 34%,
        transparent 68%);
    /* Clipped to the glass by the artwork's own alpha, so light never
       spills past the silhouette onto the background. */
    -webkit-mask: var(--fr-bottle) center / contain no-repeat;
    mask: var(--fr-bottle) center / contain no-repeat;
    transition: opacity 0.7s var(--fr-ease);
}

/* Rim light on the leading edge; the opposite side dims. */
.fr-edge {
    position: absolute;
    inset: 0;
    pointer-events: none;
    mix-blend-mode: screen;
    opacity: calc(var(--fr-edge-intensity) * var(--fr-active));
    /* Two narrow bands riding the outer contours of the glass. The layer box
       is locked to the artwork's aspect ratio (below), so 0%/100% really are
       the bottle's own edges rather than empty letterbox. */
    background: linear-gradient(
        calc(90deg + var(--fr-px) * -34deg),
        rgba(255, 244, 214, 0.26) 0%,
        rgba(255, 244, 214, 0.1) 12%,
        transparent 30%,
        transparent 70%,
        rgba(var(--fr-amber), 0.12) 88%,
        rgba(var(--fr-amber), 0.24) 100%);
    -webkit-mask: var(--fr-bottle) center / contain no-repeat;
    mask: var(--fr-bottle) center / contain no-repeat;
    transition: opacity 0.7s var(--fr-ease);
}

/* ── Floor reflection ───────────────────────────────────────
   The same asset, flipped, squashed, blurred, faded downward
   and moving at a fraction of the bottle's own travel. */
/* Occupies the same box as the bottle and mirrors about that box's BASE
   line, so the reflection grows downward from the bottle's foot. (Flipping
   about the top edge instead would throw it upward over the bottle.) */
.fr-reflection {
    position: absolute;
    left: 50%;
    top: 0;
    height: var(--fr-bottle-height);
    aspect-ratio: 1024 / 1536;
    transform-origin: 50% 100%;
    transform:
        translate3d(
            calc(-50% + var(--fr-px) * var(--fr-w-reflection) * var(--fr-translate-x) * 1px),
            var(--fr-reflection-offset), 0)
        scaleY(calc(var(--fr-reflection-squash) * -1));
    opacity: 0;
    pointer-events: none;
    transition: opacity 1.6s var(--fr-ease) 0.7s;
}

.is-ready .fr-reflection { opacity: var(--fr-reflection-opacity); }

.fr-reflection img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: blur(var(--fr-reflection-blur)) brightness(0.42) saturate(1.1);
    /* Two masks intersected: the bottle's own alpha (so the reflection has
       the exact glass silhouette), and a vertical fade. Masks apply in the
       element's own space, before the flip — the box's BOTTOM edge is the
       pivot at the floor, so that edge stays opaque and the fade runs
       toward the box top, which lands furthest from the floor on screen. */
    -webkit-mask:
        var(--fr-bottle) center / contain no-repeat,
        linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0.5) 14%, transparent var(--fr-reflection-fade));
    mask:
        var(--fr-bottle) center / contain no-repeat,
        linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0.5) 14%, transparent var(--fr-reflection-fade));
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
}

/* ── The manifesto chamber ──────────────────────────────────
   A 12-column editorial grid, deliberately off-axis: the statement sits
   left of centre, the house marks and the atelier annotation sit right,
   and hairlines run between them. No card, no box, no centred stack. */
.fr-manifesto {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    align-items: start;
    row-gap: clamp(3rem, 9vh, 6rem);
    max-width: 1180px;
    margin: 0 auto;
    padding: clamp(5rem, 16vh, 10rem) clamp(1.4rem, 6vw, 4rem) clamp(4rem, 12vh, 8rem);
    /* The ghost wordmark is wider than the page on purpose. */
    overflow: hidden;
}

/* Large, dim warm pool that drifts with the cursor. Fades to nothing well
   inside its own box, so there is never a visible gradient edge. */
.fr-ambient {
    position: absolute;
    inset: -25%;
    pointer-events: none;
    background: radial-gradient(46% 38% at
        calc(50% + var(--fr-mx, 0) * 9%)
        calc(46% + var(--fr-my, 0) * 8%),
        rgba(var(--fr-amber), 0.05) 0%,
        rgba(var(--fr-amber), 0.018) 42%,
        transparent 68%);
}

/* Black-on-black NÉANT sitting behind everything, readable only once the
   eye adjusts. Width is a share of the CONTAINER, not of the viewport —
   the container is max-width capped, so a vw-based size overflowed it and
   the section clipped the N and the T clean off. The SVG's textLength
   guarantees the wordmark is exactly this wide whatever the font metrics,
   leaving a consistent margin on both sides at every width. */
.fr-ghost {
    position: absolute;
    left: 50%;
    top: 47%;
    z-index: 0;
    width: min(84%, 1000px);
    height: auto;
    overflow: visible;
    fill: #ffffff;
    opacity: 0.028;
    transform: translate3d(
        calc(-50% + var(--fr-mx, 0) * 8px),
        calc(-50% + var(--fr-my, 0) * 5px), 0);
    pointer-events: none;
    user-select: none;
}

.fr-ghost text {
    font-family: 'Cormorant Garamond', serif;
    font-weight: 500;
    /* Chosen so lengthAdjust distributes roughly the 0.16em tracking the
       wordmark had before, rather than stretching or crowding the glyphs. */
    font-size: 238px;
}

/* ── The statement ──
   Two voices: an engraved capital line, then an italic answer set lower
   and further right, so the phrase reads across the space rather than
   sitting on one axis. */
.fr-say {
    grid-column: 2 / 8;
    grid-row: 2;
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    font-weight: 500;
}

.fr-say-lead {
    display: block;
    font-family: 'Cormorant SC', 'Cormorant Garamond', serif;
    font-size: clamp(2.4rem, 7.2vw, 4.6rem);
    line-height: 0.98;
    letter-spacing: 0.1em;
    background: linear-gradient(176deg, #f7ecd2 0%, #e3cd9e 38%, #c7a96c 72%, #96793d 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--fr-gold-soft);
}

.fr-say-tail {
    display: block;
    margin-top: clamp(0.4rem, 1.4vw, 0.9rem);
    margin-left: clamp(1.6rem, 9vw, 6.5rem);
    font-family: 'Cormorant Garamond', serif;
    font-style: italic;
    font-weight: 400;
    font-size: clamp(1.35rem, 3.6vw, 2.3rem);
    line-height: 1.1;
    letter-spacing: 0.03em;
    color: rgba(245, 242, 236, 0.62);
}

/* The serpent crest, used once, as a maison hallmark. */
.fr-crest {
    position: relative;
    display: block;
    width: clamp(46px, 5.4vw, 64px);
    aspect-ratio: 1;
    background-image: url('/assets/fragrance/neant-crest.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    opacity: 0.9;
}

/* Specular pass over the metal — masked to the crest's own alpha so the
   light only ever touches the gold, never the space around it. */
.fr-crest-sweep {
    position: absolute;
    inset: 0;
    pointer-events: none;
    mix-blend-mode: screen;
    opacity: calc(var(--fr-crest-lit, 0) * 0.55);
    background: linear-gradient(
        calc(102deg + var(--fr-mx, 0) * -26deg),
        transparent 34%,
        rgba(255, 248, 232, 0.34) 50%,
        transparent 66%);
    -webkit-mask: url('/assets/fragrance/neant-crest.png') center / contain no-repeat;
    mask: url('/assets/fragrance/neant-crest.png') center / contain no-repeat;
}

/* ── The seal ───────────────────────────────────────────────
   One mark, one line of status. Everything the hero already stated is
   deliberately absent here — no second name, no second house label. */
.fr-seal {
    grid-column: 8 / 12;
    grid-row: 2;
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: clamp(1rem, 2.6vw, 1.5rem);
    padding-top: clamp(1rem, 4vw, 2.4rem);
}

.fr-seal-rule {
    display: block;
    width: clamp(2.6rem, 6vw, 4rem);
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(var(--fr-amber), 0.5));
}

.fr-seal-status {
    font-family: 'Cormorant SC', 'Cormorant Garamond', serif;
    font-size: clamp(0.6rem, 1.5vw, 0.68rem);
    letter-spacing: 0.42em;
    text-indent: 0.42em;
    color: rgba(var(--fr-amber), 0.6);
    white-space: nowrap;
}


.fr-footer {
    position: relative;
    z-index: 1;
    padding: clamp(2rem, 6vh, 3rem) 1.2rem calc(clamp(1.6rem, 4vh, 2.4rem) + env(safe-area-inset-bottom, 0px));
    text-align: center;
}

.fr-footer p {
    font-family: 'Cormorant SC', 'Cormorant Garamond', serif;
    font-size: 0.6rem;
    letter-spacing: 0.34em;
    color: rgba(245, 242, 236, 0.22);
    line-height: 2.2;
}

/* ── Scroll reveal ──────────────────────────────────────────
   Ceremonial rather than staggered: the hairline draws first, the capital
   line rises, the italic answer follows, then the house marks and the
   annotation settle last. Small offsets, nothing flies. */
.fr-reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 1s var(--fr-ease), transform 1s var(--fr-ease);
}

.fr-reveal.is-in { opacity: 1; transform: translateY(0); }

.fr-say-lead.is-in { transition-delay: 0.1s; }
.fr-say-tail.is-in { transition-delay: 0.28s; }
.fr-seal.is-in { transition-delay: 0.44s; }

/* ── Small screens ──────────────────────────────────────────
   Bottle scales down rather than cropping. The chamber collapses to one
   column; the seal moves under the statement but stays right-aligned so
   the section never becomes a plain centred stack. */
@media (max-width: 860px) {
    .fr-manifesto {
        grid-template-columns: 1fr;
        row-gap: clamp(2.4rem, 7vh, 3.6rem);
        padding-top: clamp(4rem, 12vh, 7rem);
    }

    .fr-say,
    .fr-seal {
        grid-column: 1;
        grid-row: auto;
    }

    /* Slightly wider share on narrow screens so the wordmark keeps presence,
       still short of the edges. */
    .fr-ghost { width: 90%; opacity: 0.034; }
}

@media (max-width: 620px) {
    .fr-stage {
        width: min(400px, 94vw);
        height: clamp(340px, 54vh, 470px);
    }
    .fr-name { letter-spacing: 0.2em; text-indent: 0.2em; }
    .fr-say-tail { margin-left: clamp(1.2rem, 12vw, 3rem); }
    .fr-identity { margin-top: clamp(-2.4rem, -4vh, -1.2rem); }
}

/* ── Reduced motion ─────────────────────────────────────────
   Per the house convention (see index.html), the OS signal is not
   treated as a kill switch — html.reduce-motion is. Under it the
   composition stays fully intact: bottle, shadow, reflection and
   amber all remain, only the movement stops. */
/* Neutral pose: the composition stays whole — bottle, shadow, reflection and
   amber all remain — only the pointer-driven movement is removed. */
html.reduce-motion .fr-shadow,
html.reduce-motion .fr-backglow {
    transform: translate3d(-50%, -50%, 0);
}

html.reduce-motion .fr-shadow { transform: translate3d(-50%, 0, 0); }
html.reduce-motion .fr-bottle { transform: none; }
html.reduce-motion .fr-atmos { transform: none; }

html.reduce-motion .fr-reflection {
    transform:
        translate3d(-50%, var(--fr-reflection-offset), 0)
        scaleY(calc(var(--fr-reflection-squash) * -1));
}

html.reduce-motion .fr-glare,
html.reduce-motion .fr-edge { opacity: 0; }

/* The manifesto keeps its full composition — ghost wordmark, hairlines,
   crest and annotation all stay; only the drift and the specular pass go. */
html.reduce-motion .fr-ambient,
html.reduce-motion .fr-ghost {
    transform: translate3d(-50%, -50%, 0);
}

html.reduce-motion .fr-ambient { transform: none; }
html.reduce-motion .fr-crest-sweep { opacity: 0; }

html.reduce-motion .fr-name,
html.reduce-motion .fr-kind,
html.reduce-motion .fr-id-rule,
html.reduce-motion .fr-maison,
html.reduce-motion .fr-bottle,
html.reduce-motion .fr-reflection,
html.reduce-motion .fr-reveal {
    transition-duration: 0.01ms;
    transition-delay: 0s;
}
