/* =============================================================================
   ALPHA VITAL ELITE IV — THE INFUSION MENU
   -----------------------------------------------------------------------------
   This page does not share a look with any other on the site, and it should
   not. The about page has its thread; this one has FLOW. Everything here is
   built from the behaviour of an infusion — something that arrives slowly,
   one drop at a time, and is given to one person at a time.

     · the hero is a field of colour, not an image: ten blooms, one per
       formulation, drifting under the type at ten different speeds
     · the headline finishes itself, letter by letter
     · the ten are not a list. They take the screen one at a time, and the
       scroll is what moves you between them

   Type is set for reading first: 62ch measures, 1.8 leading, and a display
   face only ever used at sizes where its detail actually shows.
============================================================================= */

.page-infusions {
    --bone:       #FDFCF8;
    --paper:      #F5F0E5;
    --ink:        #121E16;
    --ink-mid:    #2E3F2C;
    --ink-soft:   #55614F;
    --mist:       #8D9487;
    --brass:      #A8813C;
    --brass-lite: #D9BE83;
    --rule:       rgba(18, 30, 22, .1);
    --rule-brass: rgba(168, 129, 60, .28);

    --fx-display: 'Fraunces', Georgia, serif;
    --fx-body:    'Figtree', system-ui, sans-serif;
    --fx-mono:    'IBM Plex Mono', ui-monospace, monospace;

    --gut:   clamp(1.15rem, 4vw, 3.5rem);
    --maxw:  1320px;
    --pad-y: clamp(5rem, 12vw, 10rem);
    --stack: clamp(2rem, 5vw, 3.75rem);
    --ease:  cubic-bezier(.16, 1, .3, 1);

    background: var(--bone);
    color: var(--ink-soft);
    font-family: var(--fx-body);
    -webkit-tap-highlight-color: transparent;
}
.page-infusions section[id] { scroll-margin-top: calc(var(--head-h, 76px) + 1.25rem); }
.page-infusions :is(h1, h2, h3) { text-wrap: balance; }
.page-infusions :is(p, li, dd)  { text-wrap: pretty; }
.page-infusions ::selection { background: var(--brass-lite); color: var(--ink); }

/* ── the shared entrance, disarmed ────────────────────────────────────────
   /styles.css runs its own [data-rise] entrance and re-enables it with a CSS
   transition the moment script.js adds body.is-ready. This page drives those
   same elements with GSAP, and two writers on one property is the flicker you
   see at load. Take the inherited transition off and hold the start state;
   GSAP owns these from here. Both selectors carry body.page-infusions so they
   outrank the shared body.is-ready rule rather than relying on file order. */
body.page-infusions [data-rise],
body.page-infusions.is-ready [data-rise] { transition: none; }

html.ivx-on body.page-infusions.is-ready [data-rise] {
    opacity: 0; transform: translate3d(0, 30px, 0);
}

/* ── start states, set before first paint so nothing flashes ─────────────── */
html.ivx-on [data-rise]  { opacity: 0; transform: translate3d(0, 30px, 0); }
html.ivx-on [data-split] { opacity: 0; }
html.ivx-on .ivx-ch      { opacity: 0; }
.ivx-word { display: inline-block; }
/* No standing will-change here. It used to promote all 48 letters to their own
   compositor layers for the life of the page, not just for the ~1s they move.
   GSAP sets and clears it around the tween instead. The perspective went with
   the rotateX it existed for. */
.ivx-ch   { display: inline-block; }

.ivx-eyebrow {
    display: inline-flex; align-items: center; gap: .55rem;
    font-family: var(--fx-mono); font-size: .58rem; font-weight: 500;
    letter-spacing: .26em; text-transform: uppercase; color: var(--brass);
    margin-bottom: 1.5rem;
}
.ivx-eyebrow i { font-size: 1rem; }

.ivx-btn {
    display: inline-flex; align-items: center; gap: .6rem;
    padding: 1rem 1.7rem; border-radius: 999px;
    border: 1px solid var(--rule-brass); color: var(--ink); background: transparent;
    font-family: var(--fx-mono); font-size: .66rem; font-weight: 500;
    letter-spacing: .16em; text-transform: uppercase;
    transition: background .5s var(--ease), color .5s var(--ease),
                border-color .5s var(--ease), transform .5s var(--ease);
}
.ivx-btn:hover { background: rgba(255,255,255,.7); transform: translateY(-2px); }
.ivx-btn--solid { background: var(--ink); border-color: var(--ink); color: var(--bone); }
.ivx-btn--solid:hover { background: var(--ink-mid); border-color: var(--ink-mid); }
.ivx-btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }


/* =============================================================================
   01 · HERO — the field
   -----------------------------------------------------------------------------
   No photograph. Ten soft blooms, one carrying each formulation's tone, drift
   on their own cycles behind a bone veil and a grain layer. The result reads
   as light through fluid rather than as a gradient background.
============================================================================= */
.ivx-hero {
    position: relative; isolation: isolate; overflow: clip;
    min-height: min(100svh, 900px);
    display: grid; align-items: center;
    padding: calc(var(--head-h, 76px) + clamp(3rem, 8vw, 6rem)) var(--gut) clamp(5rem, 10vw, 7rem);
    background: var(--bone);
}
.hr__field { position: absolute; inset: -20%; z-index: -2; }
/* A blurred element is rasterised at its layout size and the blur is applied to
   that raster. A TRANSLATE of the result is handed to the compositor and costs
   nothing per frame; a SCALE changes the size of the thing being blurred, so the
   raster and the 46px blur are both redone every frame. Ten of those was the
   stutter. The drift is translate-only now, and the gradient stop is pushed out
   to 72% to give back the spread the scale used to add.

   `will-change: transform` is gone with it: it was promoting ten 620px layers to
   the GPU for the life of the page, and the grain layer above had to read them
   all back anyway. */
.hr__bloom {
    position: absolute; left: var(--bx); top: var(--by);
    width: clamp(320px, 42vw, 620px); aspect-ratio: 1; border-radius: 50%;
    background: radial-gradient(circle at 50% 50%, var(--c), transparent 72%);
    opacity: .34; filter: blur(46px);
    transform: translate(-50%, -50%);
    animation: hrDrift var(--bd, 24s) var(--bi, 0s) ease-in-out infinite alternate;
}
@keyframes hrDrift {
    from { transform: translate(-50%, -50%) translate(0, 0); }
    to   { transform: translate(-50%, -50%) translate(7%, -9%); }
}
.hr__veil {
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(253,252,248,.62), rgba(253,252,248,.86) 58%, var(--bone));
}
/* a fine tooth, so the colour reads as printed rather than as a CSS gradient */
/* mix-blend-mode was the other half of the stutter. A blend has to flatten and
   read back everything painted beneath it in the stacking context — all the
   blooms — on every frame that any of them moves, and they never stop moving.
   On a bone background multiply at .5 and normal at .22 are the same tooth. */
.hr__grain {
    position: absolute; inset: 0; opacity: .22;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.34'/%3E%3C/svg%3E");
}

.hr__wrap { position: relative; z-index: 1; max-width: var(--maxw); margin: 0 auto; width: 100%; }

.hr__folio {
    display: flex; align-items: center; flex-wrap: wrap; gap: .75rem;
    font-family: var(--fx-mono); font-size: .55rem; font-weight: 500;
    letter-spacing: .24em; text-transform: uppercase; color: var(--mist);
    margin-bottom: clamp(2rem, 5vw, 3.5rem);
}
.hr__dot { width: 3px; height: 3px; border-radius: 50%; background: var(--brass); }

.hr__title {
    font-family: var(--fx-display); font-optical-sizing: auto; font-weight: 300;
    /* two fixed lines instead of one, so the display size steps down to keep
       the headline, the rotating line, the dek and the buttons on one screen */
    font-size: clamp(1.9rem, 5.5vw, 4.4rem);
    line-height: 1.04; letter-spacing: -.04em; color: var(--ink);
    margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem);
}
.hr__line { display: block; }
/* the rotating line runs much longer than the fixed ones — set it smaller so
   the longest phrase still reads as one line of type, not a paragraph */

/* THE JUMP.
   min-height:1.24em reserved ONE line, but the third phrase wraps to two on
   nearly every width. So the box grew by a full line the moment the typewriter
   crossed the wrap point and shrank again as it erased — and the dek, the two
   buttons and the whole lower half of the hero rode up and down with it, twice
   a cycle, forever. That was the struggling.

   Fixed by stacking a hidden copy of the LONGEST phrase in the same grid cell
   as the live text. The box is always exactly as tall as the tallest thing it
   will ever hold, at whatever width the reader is at, so nothing below it ever
   moves — and no space is wasted, because the spacer wraps by the same rules
   the real text does. */
.hr__line--type {
    display: grid; margin-top: .35em;
    font-size: .5em; line-height: 1.24; letter-spacing: -.02em;
    color: var(--brass); font-style: italic;
}
.hr__line--type::before {
    content: "Under one physician\2019 s care \2014  from review through administration.";
    visibility: hidden;
}
.hr__line--type::before,
.hr__typebox { grid-area: 1 / 1; align-self: start; }
.hr__typebox { display: block; }
.hr__typed { font-style: italic; }
/* the caret only exists once there is something to type — before the headline
   has landed it was blinking on its own over an empty line */
.hr__caret {
    display: inline-block; width: .045em; height: .78em; margin-left: .06em;
    background: var(--brass); vertical-align: baseline;
    opacity: 0;
}
.hr__line--type.is-typing .hr__caret { animation: hrBlink 1.05s steps(1) infinite; }
html:not(.ivx-on) .hr__caret { display: none; }
@keyframes hrBlink { 0%, 48% { opacity: 1; } 49%, 100% { opacity: 0; } }
.hr__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

.hr__dek {
    max-width: 54ch; font-size: clamp(1.02rem, 1.15vw, 1.16rem);
    line-height: 1.8; color: var(--ink-soft);
    padding-left: 1.4rem; border-left: 1px solid var(--rule-brass);
    margin-bottom: clamp(2rem, 4vw, 2.75rem);
}
.hr__acts { display: flex; flex-wrap: wrap; gap: .75rem; }

/* the drop that falls down the left margin */
/* .hr__drip / .hr__stem / .hr__drop — the falling bead, removed: it ran a
   GSAP tween on a permanent loop for the life of the page. */


/* =============================================================================
   02 · THE STAGE — the ten, one at a time
   -----------------------------------------------------------------------------
   The section pins and the deck cross-fades: one formulation holds the screen
   until the scroll hands it to the next. The numerals down the left are both a
   position indicator and a jump control.

   Pinning is a desktop behaviour only. Mobile browsers recalculate viewport
   height when the address bar hides, which drifts a pin badly — so below
   900px the panels simply stack and reveal normally.
============================================================================= */
.ivx-stage { position: relative; background: var(--bone); padding-top: var(--pad-y); }

.st__intro { max-width: var(--maxw); margin: 0 auto clamp(2.5rem, 6vw, 4.5rem); padding-inline: var(--gut); }
.st__head {
    font-family: var(--fx-display); font-weight: 300;
    font-size: clamp(2.1rem, 5.6vw, 4.4rem);
    line-height: 1.02; letter-spacing: -.04em; color: var(--ink); margin-bottom: 1.3rem;
}
.st__lede {
    max-width: 58ch; font-size: clamp(.98rem, 1.08vw, 1.1rem);
    line-height: 1.8; color: var(--ink-soft);
    padding-left: 1.3rem; border-left: 1px solid var(--rule-brass);
}

.st__pin { position: relative; }
.st__inner {
    position: relative; max-width: var(--maxw); margin: 0 auto;
    padding: clamp(1.5rem, 4vw, 3rem) var(--gut) clamp(3rem, 6vw, 5rem);
    min-height: min(84svh, 780px);
    display: grid; grid-template-columns: auto minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
}

/* ---------- the numerals ---------- */
.st__rail { list-style: none; display: flex; flex-direction: column; gap: .1rem; }
.st__mark {
    display: grid; place-items: center;
    width: 2.5rem; height: 2.5rem; border-radius: 50%;
    background: none; border: 1px solid transparent; cursor: pointer;
    font-family: var(--fx-display); font-style: italic; font-size: .92rem;
    color: var(--mist);
    transition: color .45s var(--ease), border-color .45s var(--ease),
                background .45s var(--ease), transform .45s var(--ease);
}
.st__mark:hover { color: var(--ink); border-color: var(--rule-brass); }
.st__mark.is-on {
    color: var(--bone); background: var(--tone); border-color: var(--tone);
    transform: scale(1.1);
}
.st__mark:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* ---------- the deck ---------- */
.st__deck { position: relative; min-height: min(66svh, 620px); }
.st__panel {
    position: absolute; inset: 0;
    display: grid; grid-template-columns: minmax(0, 1fr) clamp(150px, 22vw, 290px);
    gap: clamp(1.5rem, 4vw, 4rem); align-items: center;
    opacity: 0; visibility: hidden; pointer-events: none;
}
.st__panel.is-live { opacity: 1; visibility: visible; pointer-events: auto; }

.st__no {
    display: flex; align-items: center; gap: .7rem;
    font-family: var(--fx-mono); font-size: .58rem; font-weight: 500;
    letter-spacing: .2em; text-transform: uppercase; color: var(--mist);
    margin-bottom: 1.1rem;
}
.st__no i {
    font-family: var(--fx-display); font-style: italic; font-size: 1.5rem;
    color: var(--tone); line-height: 1;
}
.st__no s { flex: 0 0 2.5rem; height: 1px; background: var(--rule-brass); }

.st__name {
    font-family: var(--fx-display); font-optical-sizing: auto; font-weight: 400;
    font-size: clamp(1.9rem, 4.4vw, 3.5rem);
    line-height: 1.04; letter-spacing: -.035em; color: var(--ink);
    margin-bottom: 1.1rem; min-height: 1.04em;
}
.st__note {
    max-width: 52ch; font-size: clamp(1rem, 1.12vw, 1.14rem);
    line-height: 1.8; color: var(--ink-soft); margin-bottom: 1.4rem;
}
.st__tags { display: flex; flex-wrap: wrap; gap: .35rem; list-style: none; margin-bottom: 1.75rem; }
.st__tags li {
    padding: .3rem .7rem; border: 1px solid var(--rule); border-radius: 3px;
    font-family: var(--fx-mono); font-size: .55rem; font-weight: 500;
    letter-spacing: .13em; text-transform: uppercase; color: var(--mist);
}
.st__meta { display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 4vw, 3rem); margin-bottom: 1.9rem; }
.st__meta dt {
    font-family: var(--fx-mono); font-size: .53rem; font-weight: 500;
    letter-spacing: .2em; text-transform: uppercase; color: var(--mist);
    margin-bottom: .35rem;
}
.st__meta dd {
    font-family: var(--fx-display); font-weight: 400; font-size: clamp(1.3rem, 2vw, 1.8rem);
    letter-spacing: -.02em; color: var(--ink);
}
.st__rate em { font-style: italic; font-weight: 300; color: var(--brass); }
.st__open {
    display: inline-flex; align-items: center; gap: .6rem;
    padding-bottom: .4rem; border-bottom: 1px solid var(--rule-brass); color: var(--ink);
    font-family: var(--fx-mono); font-size: .64rem; font-weight: 500;
    letter-spacing: .16em; text-transform: uppercase;
    transition: gap .45s var(--ease), border-color .45s var(--ease), color .45s var(--ease);
}
.st__open:hover { gap: 1rem; color: var(--tone); border-color: var(--tone); }
.st__open:focus-visible { outline: 2px solid var(--brass); outline-offset: 4px; }

.st__shot { position: relative; display: grid; place-items: center; }
.st__halo {
    position: absolute; width: 118%; aspect-ratio: 1; border-radius: 50%;
    background: radial-gradient(circle, var(--tone), transparent 62%);
    opacity: .2; filter: blur(34px);
}
.st__shot img {
    position: relative; width: 100%; height: auto; display: block;
    filter: drop-shadow(0 34px 42px rgba(18, 30, 22, .26));
}

.st__prog {
    position: absolute; left: var(--gut); right: var(--gut); bottom: clamp(1.5rem, 3vw, 2.5rem);
    height: 1px; background: var(--rule);
}
.st__prog span {
    display: block; height: 100%; width: 0%;
    background: linear-gradient(90deg, var(--brass-lite), var(--brass));
}

/* ---------- stage · controls (phones only) ---------- */
.st__ctrl { display: none; }

/* =============================================================================
   STAGE · PHONES — the deck
   -----------------------------------------------------------------------------
   No pin below 900px (the address bar drags it out of register). Instead the
   nine sit side by side as cards and the reader swipes between them, one at a
   time — the same idea as the desktop pin, carried by the thumb instead of the
   scroll. Each card snaps into place, the next one peeks in at the edge so it
   is obvious there is more, and the numerals above track and jump.
============================================================================= */
@media (max-width: 900px) {
    .ivx-stage { padding-top: clamp(4rem, 14vw, 6rem); padding-bottom: clamp(3.5rem, 12vw, 5rem); }
    .st__intro { margin-bottom: 1.75rem; }

    .st__inner {
        display: block; min-height: 0; max-width: none;
        padding: 0;
    }

    /* numerals: all nine across one row, shared evenly */
    .st__rail {
        display: grid; grid-template-columns: repeat(9, minmax(0, 1fr));
        gap: .25rem; padding: .2rem var(--gut) 1.1rem;
    }
    .st__rail li { display: grid; place-items: center; min-width: 0; }
    .st__mark {
        width: 100%; max-width: 2.6rem; height: auto; aspect-ratio: 1;
        border-color: var(--rule); background: var(--bone);
        font-size: .9rem; color: var(--ink-soft);
    }
    .st__mark.is-on { transform: none; }

    /* the deck */
    .st__deck {
        min-height: 0;
        display: grid; grid-auto-flow: column;
        grid-auto-columns: min(84%, 400px);
        gap: .85rem;
        overflow-x: auto; overflow-y: hidden;
        overscroll-behavior-x: contain;
        scroll-snap-type: x mandatory;
        scroll-padding-inline: var(--gut);
        padding: .25rem var(--gut) 1.25rem;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
    .st__deck::-webkit-scrollbar { display: none; }

    .st__panel {
        position: relative; inset: auto;
        opacity: 1; visibility: visible; pointer-events: auto;
        display: flex; flex-direction: column; gap: 0;
        scroll-snap-align: start; scroll-snap-stop: always;
        border-radius: 20px; overflow: hidden;
        background: var(--bone);
        background: color-mix(in srgb, var(--tone) 7%, var(--bone));
        border: 1px solid var(--rule);
        border: 1px solid color-mix(in srgb, var(--tone) 24%, transparent);
        box-shadow: 0 24px 44px -34px rgba(18, 30, 22, .45);
    }

    /* the bag sits on its own lit stage at the top of the card */
    .st__shot {
        order: -1; max-width: none; margin: 0;
        height: clamp(200px, 58vw, 250px);
        display: grid; place-items: center; overflow: hidden;
        background:
            radial-gradient(75% 90% at 50% 100%, color-mix(in srgb, var(--tone) 30%, transparent), transparent 70%),
            color-mix(in srgb, var(--tone) 12%, var(--bone));
    }
    .st__halo { width: 70%; opacity: .32; filter: blur(26px); }
    .st__shot img {
        width: auto; height: clamp(168px, 49vw, 212px); max-width: 60%;
        object-fit: contain;
        filter: drop-shadow(0 18px 22px rgba(18, 30, 22, .28));
    }

    .st__text {
        flex: 1; display: flex; flex-direction: column;
        padding: 1.25rem 1.25rem 1.35rem;
    }
    .st__no { margin-bottom: .7rem; }
    .st__no i { font-size: 1.2rem; }
    .st__no s { flex-basis: 1.6rem; }
    .st__name {
        font-size: clamp(1.55rem, 6.6vw, 1.95rem); line-height: 1.08;
        margin-bottom: .7rem;
    }
    /* four lines at most, so one long description does not stretch all
       nine cards — the full protocol is one tap away */
    .st__note {
        font-size: .95rem; line-height: 1.62; margin-bottom: 1rem;
        display: -webkit-box; -webkit-box-orient: vertical;
        -webkit-line-clamp: 4; line-clamp: 4; overflow: hidden;
    }
    .st__tags { margin-bottom: 1.1rem; }
    .st__tags li { background: rgba(255, 255, 255, .55); font-size: .6rem; padding: .32rem .62rem; }
    .st__no, .st__meta dt { font-size: .58rem; }

    /* price and chair time sit on a shared baseline, pinned to the card foot
       so every card's button lands in the same place */
    .st__meta {
        margin-top: auto; margin-bottom: 1.1rem; padding-top: 1rem;
        border-top: 1px solid var(--rule);
        display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;
    }
    .st__meta dd { font-size: 1.45rem; }

    .st__open {
        justify-content: center; gap: .55rem;
        padding: 1rem 1.2rem; border: 0; border-radius: 999px;
        background: var(--ink); color: var(--bone);
        font-size: .62rem;
    }
    .st__open:hover { gap: .55rem; color: var(--bone); }
    .st__open i { font-size: .9rem; }

    /* prev · counter + progress · next */
    .st__ctrl {
        display: flex; align-items: center; gap: .9rem;
        padding: 0 var(--gut);
    }
    .st__step {
        flex: 0 0 auto; width: 2.9rem; height: 2.9rem; border-radius: 50%;
        display: grid; place-items: center;
        border: 1px solid var(--rule-brass); background: var(--bone); color: var(--ink);
        font-size: 1.05rem; cursor: pointer;
        transition: opacity .3s var(--ease), background .3s var(--ease);
    }
    .st__step:disabled { opacity: .35; cursor: default; }
    .st__step:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
    .st__count {
        flex: 1; display: flex; align-items: center; gap: .75rem;
        font-family: var(--fx-mono); font-size: .6rem; font-weight: 500;
        letter-spacing: .16em; color: var(--mist); white-space: nowrap;
    }
    .st__count b {
        font-family: var(--fx-display); font-style: italic; font-weight: 400;
        font-size: 1.05rem; letter-spacing: 0; color: var(--ink);
    }
    .st__count span {
        flex: 1; height: 2px; border-radius: 2px; background: var(--rule); overflow: hidden;
    }
    .st__count span i {
        display: block; height: 100%; width: 11.11%;
        background: var(--brass);
        transition: width .35s var(--ease);
    }

    .st__prog { display: none; }
}

@media (max-width: 380px) {
    .st__deck { grid-auto-columns: 86%; }
    .st__mark { font-size: .78rem; }
    .st__text { padding: 1.1rem 1.05rem 1.2rem; }
    .st__meta dd { font-size: 1.3rem; }
}

/* =============================================================================
   03 · THE WALL — pick a component, the bags answer
============================================================================= */
.ivx-idx { position: relative; padding: var(--pad-y) var(--gut); background: var(--paper); }
.ivx-idx__wrap { max-width: var(--maxw); margin: 0 auto; }
.ivx-idx__head { margin-bottom: clamp(2rem, 4.5vw, 3.25rem); }
.ivx-idx__title {
    font-family: var(--fx-display); font-optical-sizing: auto; font-weight: 300;
    font-size: clamp(2rem, 5.4vw, 4.25rem);
    line-height: 1; letter-spacing: -.04em; color: var(--ink); margin-bottom: 1.3rem;
}
.ivx-idx__title span { display: block; overflow: hidden; }
.ivx-idx__title span > i { display: block; font-style: normal; will-change: transform; }
.ivx-idx__title em { font-style: italic; font-weight: 300; color: var(--brass); }
.ivx-idx__lede {
    max-width: 58ch; font-size: clamp(.95rem, 1.05vw, 1.05rem);
    line-height: 1.8; color: var(--ink-soft);
    padding-left: 1.2rem; border-left: 1px solid var(--rule-brass);
}

.ivx-wall {
    display: grid; grid-template-columns: minmax(0, .58fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 3.5vw, 3.25rem); align-items: start;
}
.wl__raillab {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    font-family: var(--fx-mono); font-size: .54rem; font-weight: 500;
    letter-spacing: .2em; text-transform: uppercase; color: var(--mist);
    padding-bottom: .7rem; border-bottom: 1px solid var(--ink);
}
.wl__keys { display: flex; flex-direction: column; list-style: none; }
.wl__key {
    position: relative; width: 100%;
    display: grid; grid-template-columns: minmax(0, 1fr) clamp(40px, 6vw, 76px) auto;
    align-items: center; gap: clamp(.5rem, 1.3vw, .9rem);
    padding: .95rem .35rem; min-height: 58px;
    background: none; border: 0; border-bottom: 1px solid var(--rule);
    text-align: left; color: var(--ink-soft); cursor: pointer;
    transition: color .4s var(--ease), padding-left .45s var(--ease);
}
.wl__key::before {
    content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
    background: var(--brass); transform: scaleY(0);
    transition: transform .45s var(--ease);
}
.wl__name {
    font-family: var(--fx-display); font-weight: 400; font-size: 1.05rem;
    letter-spacing: -.015em; line-height: 1.2;
}
.wl__meter {
    position: relative; height: 2px; border-radius: 999px;
    background: var(--rule); overflow: hidden;
}
.wl__meter i {
    position: absolute; left: 0; top: 0; bottom: 0; width: var(--w, 0%);
    border-radius: inherit; transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--brass-pale), var(--brass));
}
.wl__n {
    min-width: 2rem; text-align: center;
    font-family: var(--fx-mono); font-weight: 500; font-size: .6rem;
    letter-spacing: .1em; color: var(--mist);
    padding: .2rem .48rem; border: 1px solid var(--rule); border-radius: 999px;
    transition: color .4s var(--ease), border-color .4s var(--ease), background .4s var(--ease);
}
.wl__key:hover { color: var(--ink); padding-left: .8rem; }
.wl__key:hover .wl__n { border-color: var(--rule-brass); color: var(--brass); }
.wl__key:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }
.wl__key.is-on { color: var(--ink); padding-left: .9rem; }
.wl__key.is-on::before { transform: scaleY(1); }
.wl__key.is-on .wl__n { background: var(--brass); border-color: var(--brass); color: var(--bone); }

.wl__bags {
    list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: clamp(.4rem, 1.2vw, .9rem); margin-bottom: clamp(1.35rem, 3vw, 2.25rem);
}
.wl__bag { min-width: 0; }
.wl__bag a {
    display: block; text-align: center; color: inherit;
    padding: .6rem .3rem .75rem; border-radius: 6px; border: 1px solid transparent;
    transition: border-color .5s var(--ease), background .5s var(--ease),
                transform .55s var(--ease), opacity .5s var(--ease);
}
.wl__bag img {
    display: block; width: 100%; height: auto;
    filter: drop-shadow(0 14px 18px rgba(22, 36, 26, .15));
    transition: filter .5s var(--ease);
}
.wl__no {
    display: block; margin-top: .45rem;
    font-family: var(--fx-display); font-style: italic; font-size: .8rem; color: var(--tone);
}
.wl__ttl {
    display: block; margin-top: .08rem;
    font-family: var(--fx-mono); font-size: .5rem; font-weight: 500;
    letter-spacing: .12em; text-transform: uppercase; color: var(--mist);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wl__bag.is-in a {
    border-color: var(--tone); background: var(--bone); transform: translateY(-7px);
}
.wl__bag.is-in img { filter: drop-shadow(0 28px 32px rgba(22, 36, 26, .26)); }
.wl__bag.is-in .wl__ttl { color: var(--ink); }
.wl__bag.is-past a { opacity: .26; }
.wl__bag.is-past img { filter: grayscale(1) drop-shadow(0 8px 10px rgba(22, 36, 26, .1)); }
.wl__bag a:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

.wl__panel {
    position: relative; overflow: hidden;
    padding: clamp(1.4rem, 2.6vw, 2.1rem);
    border: 1px solid var(--rule-brass); border-radius: 4px;
    background: var(--bone);
    box-shadow: 0 30px 64px -50px rgba(22, 36, 26, .5);
}
.wl__panel::after {
    content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
    background: radial-gradient(70% 60% at 96% 0%, var(--tone, var(--brass)), transparent 70%);
    opacity: .12; transition: opacity .5s var(--ease);
}
.wl__lab {
    position: relative; z-index: 1;
    font-family: var(--fx-mono); font-size: .55rem; font-weight: 500;
    letter-spacing: .2em; text-transform: uppercase; color: var(--mist);
    margin-bottom: .6rem;
}
.wl__lab b { font-weight: 700; color: var(--brass); }
.wl__title {
    position: relative; z-index: 1;
    font-family: var(--fx-display); font-weight: 400;
    font-size: clamp(1.7rem, 3.2vw, 2.5rem);
    line-height: 1.05; letter-spacing: -.03em; color: var(--ink); margin-bottom: .9rem;
}
.wl__what {
    position: relative; z-index: 1; max-width: 56ch;
    font-size: clamp(.94rem, 1.05vw, 1.02rem); line-height: 1.75; color: var(--ink-soft);
}
.ivx-idx__legal {
    max-width: 80ch; margin-top: var(--stack);
    font-size: .74rem; line-height: 1.7; color: var(--mist);
}


/* =============================================================================
   04 · IN EVERY RATE
============================================================================= */
.ivx-inc { padding: var(--pad-y) var(--gut); background: var(--bone); }
.ivx-inc__wrap { max-width: var(--maxw); margin: 0 auto; }
.ivx-inc__head { margin-bottom: var(--stack); }
.ivx-inc__title {
    font-family: var(--fx-display); font-weight: 300;
    font-size: clamp(1.9rem, 4.6vw, 3.4rem);
    line-height: 1.05; letter-spacing: -.035em; color: var(--ink);
}
.ivx-inc__title em { font-style: italic; color: var(--brass); }
.ivx-inc__grid {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1rem, 2.5vw, 2rem); list-style: none;
}
.ivx-inc__item {
    position: relative; padding: clamp(1.5rem, 2.6vw, 2.1rem);
    border-top: 1px solid var(--ink);
    transition: background .5s var(--ease);
}
.ivx-inc__item:hover { background: var(--paper); }
.ivx-inc__no {
    font-family: var(--fx-mono); font-size: .55rem; font-weight: 500;
    letter-spacing: .2em; color: var(--brass);
}
.ivx-inc__item i { display: block; margin: 1.4rem 0 1rem; font-size: 1.9rem; color: var(--brass); }
.ivx-inc__item h3 {
    font-family: var(--fx-display); font-weight: 400; font-size: 1.3rem;
    letter-spacing: -.02em; color: var(--ink); margin-bottom: .6rem;
}
.ivx-inc__item p { font-size: .93rem; line-height: 1.7; color: var(--ink-soft); }


/* =============================================================================
   05 · BEGIN
============================================================================= */
.ivx-begin { padding: var(--pad-y) var(--gut); background: var(--paper); }
.ivx-begin__wrap {
    max-width: var(--maxw); margin: 0 auto;
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .85fr);
    gap: clamp(1.75rem, 4vw, 3.5rem); align-items: center;
}
.ivx-begin__title {
    font-family: var(--fx-display); font-weight: 300;
    font-size: clamp(1.9rem, 4.4vw, 3.25rem);
    line-height: 1.06; letter-spacing: -.035em; color: var(--ink); margin-bottom: 1.2rem;
}
.ivx-begin__title em { font-style: italic; color: var(--brass); }
.ivx-begin__lede {
    max-width: 46ch; font-size: 1rem; line-height: 1.8; color: var(--ink-soft);
    margin-bottom: 1.9rem;
}
.ivx-begin__acts { display: flex; flex-wrap: wrap; gap: .7rem; }
.ivx-begin__shot { position: relative; }
.ivx-begin__shot img {
    display: block; width: 100%; height: auto; border-radius: 4px;
    box-shadow: 0 44px 80px -52px rgba(22, 36, 26, .6);
}
.ivx-begin__shot figcaption {
    margin-top: .9rem;
    font-family: var(--fx-mono); font-size: .55rem; font-weight: 500;
    letter-spacing: .2em; text-transform: uppercase; color: var(--mist);
}
.ivx-begin__legal {
    max-width: var(--maxw); margin: var(--stack) auto 0;
    font-size: .72rem; line-height: 1.7; color: var(--mist);
}


/* =============================================================================
   RESPONSIVE
============================================================================= */
@media (max-width: 1080px) {
    .ivx-wall { grid-template-columns: minmax(0, .72fr) minmax(0, 1fr); }
}

@media (max-width: 900px) {
    /* the rack becomes one swipeable shelf */

    /* a menu row stacks: the bag moves beside the numeral */

    .ivx-wall { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
    .wl__rail, .wl__stage { min-width: 0; }
    .wl__raillab { display: none; }
    .wl__keys {
        flex-direction: row; flex-wrap: nowrap; gap: .4rem;
        overflow-x: auto; overscroll-behavior-x: contain;
        scroll-snap-type: x proximity; scrollbar-width: none; padding-bottom: .4rem;
        margin-inline: calc(var(--gut) * -1); padding-inline: var(--gut);
        -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 92%, transparent);
                mask-image: linear-gradient(90deg, transparent, #000 4%, #000 92%, transparent);
    }
    .wl__keys::-webkit-scrollbar { display: none; }
    .wl__keys li { flex: 0 0 auto; scroll-snap-align: center; }
    .wl__key {
        width: auto; min-height: 46px;
        grid-template-columns: auto auto;
        grid-template-areas: 'name n' 'meter meter';
        gap: .25rem .5rem; padding: .55rem .9rem;
        border: 1px solid var(--rule); border-radius: 14px; white-space: nowrap;
    }
    .wl__name  { grid-area: name; font-size: .95rem; }
    .wl__n     { grid-area: n; font-size: .54rem; min-width: 1.7rem; }
    .wl__meter { grid-area: meter; }
    .wl__key::before { display: none; }
    .wl__key:hover, .wl__key.is-on { padding-left: .9rem; }
    .wl__key.is-on { background: var(--ink); border-color: var(--ink); color: var(--bone); }
    .wl__key.is-on .wl__meter { background: rgba(253, 251, 246, .22); }

    .ivx-inc__grid { grid-template-columns: 1fr; }
    .ivx-begin__wrap { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
    /* nine bags as five over four, centred, short enough that the answer
       panel is still on screen when a component is tapped */
    .wl__bags {
        display: flex; flex-wrap: wrap; justify-content: center;
        gap: .5rem .25rem; margin-bottom: 1.1rem;
    }
    .wl__bag { flex: 0 0 calc(20% - .2rem); }
    .wl__bag a { padding: .45rem .15rem .5rem; border-radius: 10px; }
    .wl__glass { display: block; height: clamp(84px, 24vw, 110px); }
    .wl__bag img { width: auto; height: 100%; max-width: 100%; margin: 0 auto; object-fit: contain; }
    .wl__bag.is-in a { transform: translateY(-4px); }
    .wl__no { margin-top: .3rem; font-size: .75rem; }
    .wl__ttl { display: none; }
    .wl__panel { padding: 1.25rem 1.2rem 1.35rem; border-radius: 14px; }
    .wl__title { font-size: 1.6rem; }

    /* hero + closing buttons: full width, easy thumbs */
    .hr__acts, .ivx-begin__acts { flex-direction: column; }
    .hr__acts .ivx-btn, .ivx-begin__acts .ivx-btn { justify-content: center; width: 100%; }
    .ivx-hero { min-height: 0; padding-bottom: 4rem; }
    .hr__folio {
        flex-direction: column; align-items: flex-start;
        gap: .4rem; font-size: .52rem; letter-spacing: .2em;
    }
    .hr__folio .hr__dot { display: none; }
    .hr__dek { padding-left: 1rem; font-size: 1rem; line-height: 1.7; }
    .st__lede, .ivx-idx__lede { padding-left: 1rem; }
    .ivx-inc__item { padding: 1.4rem .25rem; }
    .ivx-inc__item i { margin: 1rem 0 .75rem; }
}

/* =============================================================================
   HERO FIELD · PHONES
   -----------------------------------------------------------------------------
   The expensive part of this field is the BLUR RADIUS, not the number of
   layers or the drift. A 46px blur on a 620px circle is a large raster for a
   phone GPU to hold; the translate that moves it afterwards is free, and the
   grain is a static tile that paints once.

   So the field keeps all six blooms, keeps drifting, and keeps its tooth —
   it just works at a radius a phone can afford. Visually this is the same
   hero; the compositor simply has less to carry per frame.
============================================================================= */
@media (max-width: 900px) {
    .hr__bloom {
        width: clamp(260px, 56vw, 420px);
        filter: blur(22px);
        opacity: .32;
    }
}

@media (prefers-reduced-motion: reduce) {
    .page-infusions *,
    .page-infusions *::before,
    .page-infusions *::after {
        animation-duration: .01ms !important; animation-iteration-count: 1 !important;
        transition-duration: .01ms !important; scroll-behavior: auto !important;
    }
    .hr__bloom, .hr__caret { animation: none; }
    .hr__drop { display: none; }
}
