@import url("fonts/fonts.css");

/* ==========================================================================
   TIRI HUB — DESIGN SYSTEM
   Type: Bricolage Grotesque (brand wordmark face) + Instrument Sans, self-hosted.
   Colour: OKLCH throughout; neutrals carry warm chroma, never pure grey.
   ========================================================================== */

:root {
    /* --- Brand --- */
    --terracotta:        oklch(0.615 0.158 44);
    --terracotta-bright: oklch(0.665 0.163 47);
    --terracotta-deep:   oklch(0.545 0.148 40);   /* white on this = 5.26:1 */
    --terracotta-darker: oklch(0.492 0.134 38);   /* white on this = 6.4:1  */
    --ember:             oklch(0.735 0.155 65);
    --cream:             oklch(0.958 0.042 85);

    /* --- Warm neutral ramp (chroma > 0 by design) --- */
    --sand-50:  oklch(0.977 0.011 78);
    --sand-100: oklch(0.958 0.017 76);
    --sand-200: oklch(0.918 0.021 74);
    --sand-300: oklch(0.842 0.024 70);
    --sand-600: oklch(0.545 0.026 58);
    --sand-800: oklch(0.348 0.024 52);
    --sand-950: oklch(0.216 0.019 48);
    --umber:    oklch(0.166 0.016 46);

    /* --- Text on LIGHT surfaces (ink) --- */
    --ink-1: var(--sand-950);
    --ink-2: var(--sand-800);
    --ink-3: var(--sand-600);

    /* --- Text on DARK surfaces (paper) --- */
    --paper-1: oklch(1 0 0);
    --paper-2: oklch(0.958 0.042 85 / 0.84);
    --paper-3: oklch(0.958 0.042 85 / 0.62);

    /* --- Surfaces --- */
    --surface-page:  var(--sand-50);
    --surface-glass: oklch(0.988 0.012 80 / 0.76);
    --surface-dark:  oklch(0.216 0.024 46 / 0.62);
    --surface-night: var(--umber);

    --hairline-light: oklch(1 0 0 / 0.92);
    --hairline-ink:   oklch(0.216 0.019 48 / 0.12);
    --hairline-paper: oklch(1 0 0 / 0.17);

    /* --- Geometry --- */
    --r-sm: 10px;
    --r-md: 16px;
    --r-lg: 26px;
    --r-xl: 34px;
    --r-full: 9999px;

    --shadow-card: 0 24px 60px oklch(0.545 0.09 55 / 0.12), 0 2px 8px oklch(0.216 0.019 48 / 0.04);
    --shadow-lift: 0 34px 80px oklch(0.545 0.09 55 / 0.20);
    --shadow-deep: 0 30px 70px oklch(0.166 0.016 46 / 0.46);

    --blur-glass: blur(26px) saturate(150%);

    /* --- Motion: custom easings only, never a bare ease-in-out ---
       Four curves with different jobs, four duration tiers. `--t-micro` is the
       120-180ms tier: press, hover, focus — anything that has to feel like a
       response rather than an animation. One duration everywhere is what makes
       a bold layout still feel templated. */
    --ease-out:   cubic-bezier(0.22, 1, 0.36, 1);     /* snappy reveal */
    --ease-io:    cubic-bezier(0.66, 0, 0.24, 1);     /* symmetric, ambient loops */
    --ease-entry: cubic-bezier(0.32, 0.72, 0, 1);     /* fast out, long settle */
    --ease-exit:  cubic-bezier(0.55, 0, 1, 0.45);     /* accelerates away */
    --t-micro:  0.15s var(--ease-entry);
    --t-fast:   0.22s var(--ease-out);
    --t-mid:    0.42s var(--ease-out);
    --t-slow:   0.72s var(--ease-out);

    --header-h: 84px;

    /* --- Breakpoints: four values, and nothing else in the sheet ---
       Custom properties cannot be used inside a media query, so these are
       documentation for the literals below rather than something the queries
       read. They were eleven ad-hoc numbers; anything not on this list is a
       patch, not a decision.
         sm  560px   one column, controls stack
         md  760px   two-column content, side metadata appears
         lg  900px   the asymmetric editorial layouts turn on; nav replaces burger
         xl 1180px   full-width footer
    */

    --font-display: "Bricolage Grotesque", "Helvetica Neue", sans-serif;
    --font-body: "Instrument Sans", system-ui, -apple-system, sans-serif;
}

/* ==========================================================================
   RESET & BASE
   ========================================================================== */

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

@media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
}

html {
    font-size: 100%;
    -webkit-text-size-adjust: 100%;
}

body {
    /* Flat warm cream. Direction A is an editorial ground for ink type — a
       photographic wash underneath muddies every hairline rule on it. The
       ambient blobs carry the warmth instead. */
    /* Grain as a tiled background on the ground itself. A fixed, blended
       overlay looked the same and cost a full-viewport composite on every
       scrolled frame — p95 went 20ms -> 50ms. This is free. */
    background-color: var(--surface-page);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
    color: var(--ink-1);
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: clip;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
ul { list-style: none; }
a { color: inherit; }

/* Visible focus everywhere — never remove without replacing */
:focus-visible {
    outline: 2px solid var(--terracotta-bright);
    outline-offset: 3px;
    border-radius: 4px;
}
.on-dark :focus-visible,
.scene :focus-visible,
.modal-panel :focus-visible,
.drawer :focus-visible {
    outline-color: var(--ember);
}

.visually-hidden {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
    position: absolute; top: 0; left: 50%;
    transform: translate(-50%, -120%);
    z-index: 5000;
    padding: 0.75rem 1.5rem;
    background: var(--surface-night);
    color: var(--cream);
    border-radius: 0 0 var(--r-md) var(--r-md);
    text-decoration: none;
    font-weight: 600;
    transition: transform var(--t-fast);
}
.skip-link:focus-visible { transform: translate(-50%, 0); }

/* ==========================================================================
   TYPOGRAPHY
   ========================================================================== */

.display {
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 78%;
    line-height: 0.92;
    letter-spacing: -0.005em;
    text-transform: uppercase;
    text-wrap: balance;
}

.editorial {
    font-family: var(--font-display);
    font-weight: 600;
    font-stretch: 100%;
    line-height: 1.08;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

.eyebrow {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--terracotta-deep);   /* 4.85:1 on cream */
}
.on-dark .eyebrow { color: var(--ember); }

.container {
    width: 100%;
    max-width: 1280px;
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}

.section { padding-block: clamp(4.5rem, 9vw, 7.5rem); position: relative; z-index: 2; }

.section-head { margin-bottom: clamp(2.5rem, 5vw, 3.5rem); max-width: 62ch; }
.section-head.is-centred { margin-inline: auto; text-align: center; }
.section-title {
    font-size: clamp(2rem, 4.4vw, 3.1rem);
    margin-block: 0.6rem 0.9rem;
    color: var(--ink-1);
}
.section-intro { color: var(--ink-2); font-size: 1.05rem; }

/* ==========================================================================
   ICONS
   ========================================================================== */

.icon {
    width: 1em; height: 1em;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.8rem 1.5rem;
    border-radius: var(--r-full);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    text-decoration: none;
    white-space: nowrap;
    transition: transform var(--t-fast), background-color var(--t-fast),
                border-color var(--t-fast), box-shadow var(--t-fast), color var(--t-fast);
}
.btn .icon { font-size: 1.05em; }
@media (hover: hover) {
    .btn:hover { transform: translateY(-2px); }
}
.btn:focus-visible { transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(0.985); }

.btn--primary {
    background: linear-gradient(140deg, var(--terracotta-deep), var(--terracotta-darker));
    color: oklch(1 0 0);
    box-shadow: 0 8px 22px oklch(0.615 0.158 44 / 0.34);
}
@media (hover: hover) {
    .btn--primary:hover { box-shadow: 0 14px 30px oklch(0.615 0.158 44 / 0.42); }
}
.btn--primary:focus-visible { box-shadow: 0 14px 30px oklch(0.615 0.158 44 / 0.42); }
.btn--primary:active { box-shadow: 0 4px 12px oklch(0.615 0.158 44 / 0.38); }

.btn--outline {
    background: transparent;
    border: 1px solid oklch(0.615 0.158 44 / 0.34);
    color: var(--terracotta-deep);
}
@media (hover: hover) {
    .btn--outline:hover { background: var(--terracotta-deep); border-color: var(--terracotta-deep); color: oklch(1 0 0); }
}
.btn--outline:focus-visible { background: var(--terracotta-deep); border-color: var(--terracotta-deep); color: oklch(1 0 0); }
.btn--outline:active { background: var(--terracotta-darker); border-color: var(--terracotta-darker); color: oklch(1 0 0); }

.btn--block { width: 100%; }
.btn--lg { padding: 1rem 1.9rem; font-size: 1rem; }

.btn--icon {
    width: 46px; height: 46px;
    padding: 0;
    border-radius: 50%;
    font-size: 1.05rem;
}

/* ==========================================================================
   HEADER
   ========================================================================== */

.header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 100;
    /* Constant height: `--header-h` is what anchors, scroll-margin and the
       film's own padding are all measured against, and a header that changed
       height on scroll made every one of them briefly wrong. Only colour and
       shadow transition — padding in a transition is a layout pass per frame. */
    padding-block: 1.35rem;
    transition: background-color var(--t-mid), box-shadow var(--t-mid),
                border-color var(--t-mid);
    border-bottom: 1px solid transparent;
}

/* Over the film the header has no ground of its own. The reel ends on a
   sunlit white wall, so without a scrim the nav loses contrast at exactly the
   moment the frame matters most. */
.header::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 210%;
    z-index: -1;
    background: linear-gradient(to bottom,
        oklch(0.166 0.016 46 / 0.66) 0%,
        oklch(0.166 0.016 46 / 0.36) 44%,
        oklch(0.166 0.016 46 / 0) 100%);
    transition: opacity var(--t-mid);
    pointer-events: none;
}
.header.is-solid::before { opacity: 0; }

.header.is-solid {
    background: oklch(0.977 0.011 78 / 0.86);
    backdrop-filter: var(--blur-glass);
    -webkit-backdrop-filter: var(--blur-glass);
    border-bottom-color: var(--hairline-ink);
    box-shadow: 0 8px 30px oklch(0.216 0.019 48 / 0.06);
}

.header-inner {
    max-width: 1400px;
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}

.brand { display: flex; align-items: center; gap: 0.8rem; text-decoration: none; flex: none; }
.brand-mark { height: 34px; width: auto; }
.brand-word { height: 22px; width: auto; }
.brand-word--ink { display: none; }
.header.is-solid .brand-word--cream { display: none; }
.header.is-solid .brand-word--ink { display: block; }

.nav { display: flex; align-items: center; gap: clamp(1.25rem, 2.6vw, 2.5rem); }
.nav-link {
    position: relative;
    color: var(--paper-2);
    text-decoration: none;
    font-size: 0.9375rem;
    font-weight: 500;
    padding-block: 0.35rem;
    transition: color var(--t-fast);
}
.nav-link::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 1.5px;
    background: var(--terracotta-bright);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--t-mid);
}
@media (hover: hover) {
    .nav-link:hover { color: var(--paper-1); }
    .nav-link:hover::after { transform: scaleX(1); }
    .header.is-solid .nav-link:hover { color: var(--terracotta-deep); }
}
.nav-link:focus-visible { color: var(--paper-1); }
.nav-link:focus-visible::after,
.nav-link[aria-current="true"]::after { transform: scaleX(1); }
.nav-link:active { color: var(--ember); }
.header.is-solid .nav-link { color: var(--ink-2); }
.header.is-solid .nav-link:focus-visible,
.header.is-solid .nav-link:active,
.header.is-solid .nav-link[aria-current="true"] { color: var(--terracotta-deep); }

.header-actions { display: flex; align-items: center; gap: 0.75rem; }

.burger {
    display: none;
    width: 44px; height: 44px;
    align-items: center; justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--hairline-paper);
    color: var(--paper-1);
    font-size: 1.25rem;
    transition: background-color var(--t-fast), border-color var(--t-fast);
}
@media (hover: hover) {
    .burger:hover { background: oklch(1 0 0 / 0.12); }
}
.burger:focus-visible { background: oklch(1 0 0 / 0.12); }
.burger:active { background: oklch(1 0 0 / 0.2); transform: scale(0.94); }
.header.is-solid .burger { color: var(--ink-1); border-color: var(--hairline-ink); }

/* ==========================================================================
   MOBILE DRAWER
   ========================================================================== */

.drawer-scrim {
    position: fixed; inset: 0;
    background: oklch(0.166 0.016 46 / 0.55);
    backdrop-filter: blur(4px);
    z-index: 900;
    opacity: 0; visibility: hidden;
    transition: opacity 0.42s var(--ease-out), visibility 0s linear 0.42s;
}
.drawer-scrim.is-open { opacity: 1; visibility: visible; transition: opacity 0.42s var(--ease-out), visibility 0s linear 0s; }

.drawer {
    position: fixed;
    top: 0; right: 0;
    width: min(340px, 86vw);
    height: 100dvh;
    z-index: 1000;
    background: var(--surface-night);
    color: var(--paper-1);
    border-left: 1px solid var(--hairline-paper);
    padding: 1.6rem 1.6rem calc(1.6rem + env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    transform: translateX(102%);
    visibility: hidden;
    transition: transform 0.42s var(--ease-out), visibility 0s linear 0.42s;
}
.drawer.is-open { transform: translateX(0); visibility: visible; transition: transform 0.42s var(--ease-out), visibility 0s linear 0s; }

.drawer-top { display: flex; align-items: center; justify-content: space-between; }
.drawer-close {
    width: 42px; height: 42px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--hairline-paper);
    color: var(--paper-1);
    font-size: 1.15rem;
    transition: background-color var(--t-fast);
}
@media (hover: hover) {
    .drawer-close:hover { background: oklch(1 0 0 / 0.12); }
}
.drawer-close:focus-visible { background: oklch(1 0 0 / 0.12); }
.drawer-close:active { background: oklch(1 0 0 / 0.2); transform: scale(0.94); }

.drawer-nav {
    display: flex; flex-direction: column;
    gap: 0.35rem;
    margin-block: 2.5rem auto;
}
.drawer-nav a {
    font-family: var(--font-display);
    font-stretch: 88%;
    font-weight: 700;
    font-size: 1.5rem;
    text-transform: uppercase;
    letter-spacing: -0.01em;
    text-decoration: none;
    color: var(--paper-1);
    padding-block: 0.6rem;
    border-bottom: 1px solid var(--hairline-paper);
    transition: color var(--t-fast), transform var(--t-fast);
}
@media (hover: hover) {
    .drawer-nav a:hover { color: var(--ember); transform: translateX(0.5rem); }
}
.drawer-nav a:focus-visible { color: var(--ember); transform: translateX(0.5rem); }
.drawer-nav a:active { color: var(--terracotta-bright); transform: translateX(0.25rem); }

/* ==========================================================================
   SCENE — scroll-driven film
   ========================================================================== */

.scene {
    position: relative;
    z-index: 10;
    height: 360vh;
    background: var(--surface-night);
}

/* Anchor targets so nav links land at the right point in the scene */
.scene-anchor {
    position: absolute;
    left: 0;
    width: 1px; height: 1px;
    scroll-margin-top: 0;
    pointer-events: none;
}

.scene-viewport {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
    overflow: hidden;
    isolation: isolate;
}

.scene-media { position: absolute; inset: 0; z-index: 1; }

.scene-media img,
.scene-media video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.scene-poster { z-index: 1; }
.video-hero { z-index: 2; opacity: var(--hero-video-o, 1); }
.video-scrub { z-index: 3; opacity: var(--scrub-video-o, 0); }

.scene-vignette {
    position: absolute; inset: 0;
    z-index: 4;
    pointer-events: none;
    background:
        radial-gradient(120% 90% at 50% 40%, transparent 38%, oklch(0.166 0.016 46 / 0.42) 100%),
        linear-gradient(to bottom, oklch(0.166 0.016 46 / 0.42) 0%, transparent 26%);
}

/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
   THE FILM RAIL

   A vertical hairline down the right-hand gutter, on the same inset as the
   editorial container below. It is the one thing present for the whole film:
   it carries the progress fill, the four beat marks and the section numeral,
   and it never crosses the frame — the earlier horizontal rule sat across the
   middle of the footage, which is the one thing section 01 exists to show.
   -------------------------------------------------------------------------- */

.filmrail {
    position: absolute;
    top: calc(var(--header-h) + clamp(1rem, 3vh, 2rem));
    bottom: clamp(1.5rem, 5vh, 3.25rem);
    right: clamp(1.25rem, 4vw, 2.5rem);
    width: 1px;
    z-index: 20;
    pointer-events: none;
}

.filmrail-line {
    position: absolute;
    inset: 0;
    background: oklch(1 0 0 / 0.34);
    box-shadow: 0 0 3px oklch(0.166 0.016 46 / 0.5);
}

.filmrail-fill {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, var(--terracotta-bright), var(--ember));
    transform: scaleY(var(--p, 0));
    transform-origin: top;
}

/* The four beats, marked down the rail. A mark flips to terracotta the moment
   the fill passes it — the multiplier turns the difference into a step. */
.filmrail-mark {
    position: absolute;
    top: calc(var(--at) * 100%);
    right: 0;
    width: 11px;
    height: 1px;
    margin-top: -0.5px;
    background: oklch(1 0 0 / 0.5);
    box-shadow: 0 0 3px oklch(0.166 0.016 46 / 0.5);
}
.filmrail-mark::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--ember);
    opacity: clamp(0, calc((var(--p, 0) - var(--at)) * 400), 1);
}

.filmrail-num {
    position: absolute;
    top: -1.75rem;
    right: -0.1rem;
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 78%;
    font-size: 1.375rem;
    line-height: 1;
    letter-spacing: 0.06em;
    color: var(--ember);
    text-shadow: 0 1px 2px oklch(0.166 0.016 46 / 0.7), 0 0 12px oklch(0.166 0.016 46 / 0.6);
}

/* --------------------------------------------------------------------------
   THE BEATS

   All four sit in the same place — bottom-left, on the container gutter — so
   the film has one reading position and the frame above it stays clear. The
   type metrics are `.ed-title` / `.ed-lede` / `.ed-marker` exactly, resolved
   to the paper scale, so section 01 and sections 02+ are one system.
   -------------------------------------------------------------------------- */

.stage { position: absolute; inset: 0; z-index: 10; }

.panel {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    opacity: var(--o, 0);
    pointer-events: none;
    transform: translate3d(0, var(--y, 0px), 0);
}
.panel > * { pointer-events: auto; }
.panel[data-active="false"] { visibility: hidden; }

.beat {
    position: relative;
    width: 100%;
    max-width: 1280px;
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 2.5rem);
    padding-bottom: clamp(1.75rem, 6vh, 4rem);
    padding-right: clamp(2.75rem, 7vw, 4.5rem);   /* clear of the rail */
}

/* A lower-third scrim: the type sits on it and the sky stays untouched. Soft
   at both ends so it never reads as a panel edge. */
.beat::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: -6svh;
    bottom: -12svh;
    left: 50%;
    width: 100vw;
    margin-left: -50vw;
    background: linear-gradient(to top,
        oklch(0.166 0.016 46 / 0.60) 0%,
        oklch(0.166 0.016 46 / 0.42) 46%,
        oklch(0.166 0.016 46 / 0) 100%);
    pointer-events: none;
}

/* .ed-marker, on the paper scale */
.beat-marker {
    display: flex;
    align-items: baseline;
    gap: clamp(0.75rem, 2vw, 1.1rem);
    margin: 0 0 clamp(0.7rem, 1.6svh, 1.1rem);
}
.beat-num {
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 78%;
    font-size: 1.375rem;
    line-height: 1;
    letter-spacing: 0.06em;
    color: var(--ember);
}
.beat-kicker {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--paper-2);
    white-space: nowrap;
}

/* .ed-title, on the paper scale. The arrival is the largest thing in the film;
   the two middle beats are deliberately the smallest, because build-up set
   larger than the payoff competes with it. */
.beat-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-stretch: 100%;
    font-size: clamp(1.75rem, 3.4vw, 2.75rem);
    line-height: 0.95;
    letter-spacing: -0.03em;
    color: var(--paper-1);
    text-wrap: balance;
    max-width: 15ch;
    margin: 0;
}
.beat-title--lead { font-size: clamp(2rem, 4.4vw, 3.5rem); }

.beat-title,
.beat-lede,
.beat-kicker,
.beat-num,
.beat-onward {
    text-shadow:
        0 1px 1px oklch(0.166 0.016 46 / 0.72),
        0 0 6px  oklch(0.166 0.016 46 / 0.88),
        0 0 18px oklch(0.166 0.016 46 / 0.72),
        0 0 42px oklch(0.166 0.016 46 / 0.55);
}
/* Small type needs the halo tighter and denser, not bigger. */
.beat-lede,
.beat-kicker {
    text-shadow:
        0 1px 1px oklch(0.166 0.016 46 / 0.88),
        0 0 3px  oklch(0.166 0.016 46 / 0.96),
        0 0 8px  oklch(0.166 0.016 46 / 0.90),
        0 0 20px oklch(0.166 0.016 46 / 0.68);
}

/* .ed-lede, on the paper scale */
.beat-lede {
    font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
    line-height: 1.62;
    color: oklch(0.958 0.042 85 / 0.94);
    text-wrap: pretty;
    max-width: 42ch;
    margin: clamp(0.8rem, 1.8svh, 1.3rem) 0 0;
}

.beat-actions { margin: clamp(1.1rem, 2.6svh, 1.9rem) 0 0; }

.beat-title--arrival {
    font-size: clamp(2rem, 4.6vw, 3.75rem);
    max-width: 20ch;
}

/* Quiet enough not to compete with the frame it sits on. */
.beat-onward {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: clamp(0.9rem, 2svh, 1.4rem) 0 0;
    padding-bottom: 0.3rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--paper-1);
    text-decoration: none;
    border-bottom: 1px solid oklch(1 0 0 / 0.38);
    transition: color var(--t-micro), border-color var(--t-micro), transform var(--t-micro);
}
.beat-onward .icon { font-size: 0.875rem; }
@media (hover: hover) {
    .beat-onward:hover { color: var(--ember); border-bottom-color: var(--ember); }
}
.beat-onward:focus-visible { color: var(--ember); border-bottom-color: var(--ember); }
.beat-onward:active { transform: translateY(1px); color: var(--terracotta-bright); }


/* Scroll cue */
.scroll-cue {
    position: absolute;
    left: 50%;
    bottom: 1.75rem;
    transform: translateX(-50%);
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--paper-3);
    opacity: var(--cue-o, 1);
    pointer-events: none;
}
.scroll-cue .icon { font-size: 1rem; animation: cueDrift 2.4s var(--ease-io) infinite; }
@keyframes cueDrift {
    0%, 100% { transform: translateY(-2px); opacity: 0.5; }
    50%      { transform: translateY(3px);  opacity: 1; }
}

/* ==========================================================================
   AMBIENT BLOBS
   ========================================================================== */

.ambient {
    position: fixed; inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.8s var(--ease-out);
}
.ambient.is-visible { opacity: 1; }

.blob {
    position: absolute;
    filter: blur(90px);
    opacity: 0.55;
}
/* Promote only while the layer is actually on screen and drifting.
   `will-change` is a hint for an imminent change, not a decoration — three
   permanently-promoted 90px-blur layers is a GPU cost the page paid all the
   time, including through the whole film. */
.ambient.is-visible .blob { will-change: transform; }
.blob-1 {
    top: 12%; right: 4%; width: 34vw; height: 30vw; min-width: 340px; min-height: 300px;
    background: radial-gradient(circle, oklch(0.615 0.158 44 / 0.22), oklch(0.8 0.14 80 / 0.12) 60%, transparent 74%);
    border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
    animation: drift1 26s var(--ease-io) infinite alternate;
}
.blob-2 {
    bottom: 8%; left: -4%; width: 38vw; height: 34vw; min-width: 360px; min-height: 320px;
    background: radial-gradient(circle, oklch(0.82 0.14 82 / 0.24), oklch(0.615 0.158 44 / 0.12) 60%, transparent 74%);
    border-radius: 40% 60% 70% 30% / 50% 60% 30% 60%;
    animation: drift2 32s var(--ease-io) -6s infinite alternate;
}
.blob-3 {
    top: 46%; right: 26%; width: 26vw; height: 26vw; min-width: 280px; min-height: 280px;
    background: radial-gradient(circle, oklch(0.7 0.15 55 / 0.2), oklch(0.8 0.14 78 / 0.1) 60%, transparent 74%);
    border-radius: 50% 50% 40% 60% / 40% 60% 50% 50%;
    animation: drift3 22s var(--ease-io) -11s infinite alternate;
}
@keyframes drift1 {
    from { transform: translate3d(0,0,0) rotate(0deg); }
    to   { transform: translate3d(-46px, 44px, 0) rotate(210deg); }
}
@keyframes drift2 {
    from { transform: translate3d(0,0,0) rotate(0deg); }
    to   { transform: translate3d(54px, -38px, 0) rotate(-160deg); }
}
@keyframes drift3 {
    from { transform: translate3d(0,0,0) scale(1); }
    to   { transform: translate3d(-40px, -52px, 0) scale(1.14); }
}

/* ==========================================================================
   REVEAL ON SCROLL (sections below the scene)
   ========================================================================== */

/* Base: up from below. 0.8s for a 26px move reads as a slow fade with no
   direction, so this is shorter and lands on a curve that settles. */
.reveal {
    opacity: 0;
    transform: translate3d(0, 30px, 0);
    transition: opacity 0.62s var(--ease-entry), transform 0.62s var(--ease-entry);
    transition-delay: var(--d, 0ms);
}
.reveal.is-in { opacity: 1; transform: none; }

/* --- three entry choreographies -------------------------------------------
   Assigned in the markup so that no two consecutive sections share one. They
   differ in direction, distance, duration AND stagger step, because a page
   where every section enters the same way is the definition of flat. */

/* photography lands: barely moves, but settles out of a slight scale */
.ed--settle .reveal {
    transform: translate3d(0, 16px, 0) scale(0.982);
    transition-duration: 0.78s, 0.78s;
    transition-timing-function: var(--ease-out), var(--ease-out);
}
/* rows and rules arrive from the margin. The distance is clamped to the
   viewport so it never starts wider than the gutter on a phone — a fixed
   -30px puts the element off-canvas at 390px. */
.ed--drift .reveal {
    transform: translate3d(clamp(-30px, -4vw, -14px), 0, 0);
    transition-duration: 0.68s, 0.68s;
}
/* the plain one, a touch longer travel than the base */
.ed--rise .reveal {
    transform: translate3d(0, 38px, 0);
    transition-duration: 0.60s, 0.60s;
}

/* --- stagger --------------------------------------------------------------
   The top-level blocks of a section sequence instead of arriving at once.
   Done with nth-child so the stylesheet owns it — JS never writes a style
   attribute here. The step differs per choreography, which is the difference
   between "the same animation again" and a section with its own rhythm. */
.stagger > *:nth-child(1) { --d: 0ms; }
.stagger > *:nth-child(2) { --d: 55ms; }
.stagger > *:nth-child(3) { --d: 110ms; }
.stagger > *:nth-child(4) { --d: 165ms; }
.stagger > *:nth-child(5) { --d: 220ms; }
.stagger > *:nth-child(6) { --d: 275ms; }
.stagger > *:nth-child(n+7) { --d: 330ms; }

.ed--settle .stagger > *:nth-child(2) { --d: 75ms; }
.ed--settle .stagger > *:nth-child(3) { --d: 150ms; }
.ed--settle .stagger > *:nth-child(4) { --d: 225ms; }
.ed--settle .stagger > *:nth-child(5) { --d: 300ms; }
.ed--settle .stagger > *:nth-child(n+6) { --d: 375ms; }

.ed--drift .stagger > *:nth-child(2) { --d: 34ms; }
.ed--drift .stagger > *:nth-child(3) { --d: 68ms; }
.ed--drift .stagger > *:nth-child(4) { --d: 102ms; }
.ed--drift .stagger > *:nth-child(5) { --d: 136ms; }
.ed--drift .stagger > *:nth-child(n+6) { --d: 170ms; }

/* the three plates carry their own sequence inside the section */
.plates .reveal:nth-of-type(2) { --d: 130ms; }
.plates .reveal:nth-of-type(3) { --d: 240ms; }

/* ==========================================================================
   CARDS — STAYS & SPACES
   ========================================================================== */

.card-grid { display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); }
.card-grid--stays  { grid-template-columns: repeat(auto-fit, minmax(min(100%, 330px), 1fr)); }
.card-grid--spaces { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }

.card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--surface-glass);
    backdrop-filter: var(--blur-glass);
    -webkit-backdrop-filter: var(--blur-glass);
    border: 1.5px solid var(--hairline-light);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-card);
    transition: transform var(--t-mid), box-shadow var(--t-mid);
}
@media (hover: hover) {
    .card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
}
.card:focus-within { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
.card:active { transform: translateY(-1px); box-shadow: var(--shadow-card); }

.card-media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; }
.card-media img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform 0.9s var(--ease-out);
}
@media (hover: hover) {
    .card:hover .card-media img { transform: scale(1.045); }
}
.card:focus-within .card-media img { transform: scale(1.045); }

.card-chip {
    position: absolute;
    bottom: 0.9rem; left: 0.9rem;
    padding: 0.42rem 0.95rem;
    background: oklch(0.988 0.012 80 / 0.92);
    backdrop-filter: blur(10px);
    border: 1px solid oklch(0.615 0.158 44 / 0.28);
    border-radius: var(--r-full);
    font-size: 0.8125rem; font-weight: 700;
    color: var(--terracotta-deep);
}
.card-chip--tr { top: 0.9rem; right: 0.9rem; bottom: auto; left: auto; font-size: 0.75rem; }

.card-body { padding: 1.6rem; display: flex; flex-direction: column; flex: 1; }
.card-title { font-size: 1.3rem; font-weight: 700; color: var(--ink-1); margin-bottom: 0.5rem; letter-spacing: -0.01em; }
.card-text { color: var(--ink-2); font-size: 0.9375rem; margin-bottom: 1.25rem; flex: 1; }

.amenities {
    display: flex; flex-wrap: wrap;
    gap: 0.45rem;
    margin-bottom: 1.4rem;
}
.amenities li {
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-size: 0.8125rem;
    color: var(--ink-2);
    background: oklch(0.918 0.021 74 / 0.5);
    border-radius: var(--r-full);
    padding: 0.32rem 0.72rem;
}
.amenities .icon { color: var(--terracotta-deep); font-size: 0.95rem; }

/* ==========================================================================
   FOOTER — light surface, therefore INK text (this is the bug that was here)
   ========================================================================== */

.footer {
    position: relative;
    z-index: 2;
    background: oklch(0.977 0.011 78 / 0.93);
    backdrop-filter: var(--blur-glass);
    -webkit-backdrop-filter: var(--blur-glass);
    border-top: 1px solid var(--hairline-ink);
    color: var(--ink-1);
    padding-block: clamp(3.5rem, 7vw, 5rem) 2rem;
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1.5fr;
    gap: clamp(2rem, 4vw, 3.5rem);
    margin-bottom: 3rem;
}

.footer-bio { color: var(--ink-2); font-size: 0.9375rem; margin-block: 1.1rem 1.5rem; max-width: 34ch; }

.socials { display: flex; gap: 0.6rem; }
.socials a {
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: oklch(1 0 0 / 0.6);
    border: 1px solid var(--hairline-ink);
    color: var(--ink-1);
    font-size: 1.05rem;
    transition: background-color var(--t-fast), color var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
@media (hover: hover) {
    .socials a:hover {
        background: var(--terracotta-deep);
        color: oklch(1 0 0);
        border-color: var(--terracotta-deep);
        transform: translateY(-2px);
    }
}
.socials a:focus-visible {
    background: var(--terracotta-deep);
    color: oklch(1 0 0);
    border-color: var(--terracotta-deep);
    transform: translateY(-2px);
}
.socials a:active {
    background: var(--terracotta-darker);
    border-color: var(--terracotta-darker);
    transform: translateY(0) scale(0.94);
}

.footer-col h2 {
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-bottom: 1.1rem;
}
.footer-col ul { display: flex; flex-direction: column; gap: 0.7rem; }
.footer-col a {
    color: var(--ink-2);
    text-decoration: none;
    font-size: 0.9375rem;
    transition: color var(--t-fast);
}
@media (hover: hover) {
    .footer-col a:hover { color: var(--terracotta-deep); text-decoration: underline; text-underline-offset: 3px; }
}
.footer-col a:focus-visible { color: var(--terracotta-deep); text-decoration: underline; text-underline-offset: 3px; }
.footer-col a:active { color: var(--terracotta-darker); }

.footer-note { color: var(--ink-2); font-size: 0.875rem; margin-bottom: 0.9rem; }

.field-inline { display: flex; gap: 0.5rem; }
.field-inline input {
    flex: 1;
    min-width: 0;
    padding: 0.75rem 1.1rem;
    background: oklch(1 0 0 / 0.7);
    border: 1px solid var(--hairline-ink);
    border-radius: var(--r-full);
    color: var(--ink-1);
    font-size: 0.9375rem;
}
.field-inline input::placeholder { color: var(--ink-3); }
.field-inline input:focus-visible { border-color: var(--terracotta); }

.form-msg { font-size: 0.8125rem; margin-top: 0.6rem; min-height: 1.2em; color: var(--terracotta-deep); font-weight: 600; }

.footer-bottom {
    display: flex; flex-wrap: wrap;
    align-items: center; justify-content: space-between;
    gap: 1rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--hairline-ink);
    color: var(--ink-3);
    font-size: 0.8438rem;
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: 1.25rem; }
.footer-bottom a { color: var(--ink-3); text-decoration: none; }
@media (hover: hover) {
    .footer-bottom a:hover { color: var(--terracotta-deep); text-decoration: underline; text-underline-offset: 3px; }
}
.footer-bottom a:focus-visible { color: var(--terracotta-deep); text-decoration: underline; text-underline-offset: 3px; }
.footer-bottom a:active { color: var(--terracotta-darker); }

/* ==========================================================================
   MODAL
   ========================================================================== */

.modal {
    position: fixed; inset: 0;
    z-index: 2000;
    display: grid;
    place-items: center;
    padding: 1.25rem;
    background: oklch(0.166 0.016 46 / 0.72);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.42s var(--ease-out), visibility 0s linear 0.42s;
    overflow-y: auto;
}
.modal.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.42s var(--ease-out), visibility 0s linear 0s;
}

.modal-panel {
    position: relative;
    width: 100%;
    max-width: 560px;
    padding: clamp(1.6rem, 4vw, 2.4rem);
    background: var(--surface-night);
    border: 1px solid var(--hairline-paper);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-deep);
    color: var(--paper-1);
    transform: translateY(22px) scale(0.985);
    transition: transform var(--t-mid);
}
.modal.is-open .modal-panel { transform: none; }

.modal-close {
    position: absolute;
    top: 1.1rem; right: 1.1rem;
    width: 38px; height: 38px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: oklch(1 0 0 / 0.09);
    border: 1px solid var(--hairline-paper);
    color: var(--paper-1);
    font-size: 1.1rem;
    transition: background-color var(--t-fast), color var(--t-fast);
}
@media (hover: hover) {
    .modal-close:hover { background: var(--terracotta-deep); }
}
.modal-close:focus-visible { background: var(--terracotta-deep); }
.modal-close:active { background: var(--terracotta-darker); transform: scale(0.94); }

.modal-head { margin-bottom: 1.6rem; padding-right: 3rem; }
.modal-head h2 { font-size: 1.6rem; color: var(--paper-1); margin-block: 0.4rem 0.4rem; }
.modal-head p { color: var(--paper-3); font-size: 0.9375rem; }

.form { display: flex; flex-direction: column; gap: 1.1rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.field label {
    display: flex; align-items: center; gap: 0.45rem;
    font-size: 0.8125rem; font-weight: 600;
    color: var(--paper-2);
    margin-bottom: 0.4rem;
}
.field label .icon { color: var(--ember); }
.control {
    width: 100%;
    padding: 0.8rem 1rem;
    background: oklch(1 0 0 / 0.06);
    border: 1px solid var(--hairline-paper);
    border-radius: var(--r-sm);
    color: var(--paper-1);
    font-size: 0.9375rem;
    color-scheme: dark;
}
.control:focus-visible { border-color: var(--terracotta-bright); }

.summary {
    background: oklch(1 0 0 / 0.045);
    border: 1px dashed var(--hairline-paper);
    border-radius: var(--r-sm);
    padding: 0.95rem 1.15rem;
    display: flex; flex-direction: column; gap: 0.45rem;
}
.summary-row {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 0.9375rem;
    color: var(--paper-2);
}
.summary-row strong { color: var(--paper-1); }
.summary-row .accent { color: var(--ember); font-size: 1.05rem; }

/* ==========================================================================
   TOASTS
   ========================================================================== */

.toasts {
    position: fixed;
    bottom: 1.5rem; right: 1.5rem;
    z-index: 3000;
    display: flex; flex-direction: column;
    gap: 0.6rem;
    max-width: min(360px, calc(100vw - 3rem));
    pointer-events: none;
}
.toast {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.9rem 1.2rem;
    background: var(--surface-night);
    border: 1px solid oklch(0.615 0.158 44 / 0.5);
    border-radius: var(--r-md);
    color: var(--paper-1);
    font-size: 0.9063rem;
    box-shadow: var(--shadow-deep);
    animation: toastIn 0.36s var(--ease-out);
    pointer-events: auto;
}
.toast .icon { color: var(--ember); font-size: 1.15rem; }
.toast.is-leaving { animation: toastOut 0.3s var(--ease-io) forwards; }
@keyframes toastIn  { from { transform: translateX(110%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes toastOut { to { transform: translateX(110%); opacity: 0; } }

/* ==========================================================================
   LEGAL / PROSE PAGES
   ========================================================================== */

.prose-page { padding-top: calc(var(--header-h) + 3rem); }
.prose { max-width: 68ch; color: var(--ink-2); }
.prose h1 { font-size: clamp(2rem, 4vw, 2.8rem); color: var(--ink-1); margin-bottom: 0.75rem; }
.prose h2 { font-size: 1.25rem; color: var(--ink-1); margin-block: 2.25rem 0.6rem; letter-spacing: -0.01em; }
.prose p, .prose li { margin-bottom: 0.75rem; }
.prose ul { list-style: disc; padding-left: 1.25rem; }
.prose a { color: var(--terracotta-deep); text-underline-offset: 3px; }
.prose .lede { font-size: 1.1rem; color: var(--ink-2); margin-bottom: 2rem; }
.prose .todo {
    background: oklch(0.82 0.14 82 / 0.16);
    border-left: 3px solid var(--ember);
    padding: 0.2rem 0.5rem;
    border-radius: 3px;
    font-weight: 600;
    color: var(--ink-1);
}

/* ==========================================================================
   SECTION COMPONENTS
   Classes for what used to be 30 inline `style` attributes across 02-09.
   Inline styles win over every stylesheet rule, so none of this could be
   overridden at a breakpoint — the sections were being patched, not designed.
   ========================================================================== */

/* an aside with no rule or inset — used where it closes a block rather than
   sitting beside one */
.ed-aside--plain {
    border: 0;
    padding: 0;
    margin-top: 1.25rem;
}

/* side panel body copy */
.panel-body {
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--ink-2);
    margin: 0.6rem 0 0;
}
.panel-note {
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--ink-3);
    margin: 0.6rem 0 0;
}
.sidepanel-kicker--after-figure { margin-top: 1rem; }

/* --- 07 · voices --- */
.quote-figure { margin: 0; }
.quote-byline { flex-grow: 1; }

.score {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-top: 0.75rem;
}
.score-value { margin: 0; }
.score-outof { font-size: 0.875rem; color: var(--ink-3); }

/* --- 08 · the four standing facts, as a row of figures rather than a list --- */
.factgrid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 1.5rem;
    margin-top: clamp(1.75rem, 4vw, 2.5rem);
    padding-bottom: 2rem;
    border-bottom: 2px solid var(--ink-1);
}
.factgrid > div { display: block; }
.factgrid dt {
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-3);
}
.factgrid dd {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.3125rem;
    margin: 0.5rem 0 0;
    text-align: left;
    color: var(--ink-1);
}

/* the FAQ list follows the fact grid's rule, so it does not draw its own */
.acc--faq { border-top: 0; margin-top: 0.5rem; }
.acc--faq .acc-btn { grid-template-columns: 1fr auto; }

/* --- 09 · calendar legend --- */
.cal-swatch--picked  { background: var(--terracotta-deep); }
.cal-swatch--between { background: oklch(0.735 0.155 65 / 0.22); }
.cal-swatch--taken   { background: oklch(0.545 0.026 58); }

.score-n { color: var(--ink-3); font-weight: 400; font-size: 0.78rem; }

.ctl-label--flush { margin: 0; }
.summary-panel .btn--block { margin-top: 1rem; }

/* ==========================================================================
   GROUND TEXTURE + SCROLL LIFE

   The cream was a flat fill across the whole page. Grain gives it tooth, and a
   pair of arch outlines drift behind the content so the ground is never dead
   between sections. Both sit behind everything, cost one composited layer each
   and never move the layout.
   ========================================================================== */

/* `overflow-x: clip` (not hidden) contains the drifting arches without making
   a scroll container — so the sticky index in 03 keeps working and `view()`
   still resolves against the page. */
.ed { position: relative; z-index: 2; overflow-x: clip; }

/* ==========================================================================
   NIGHT SECTIONS
   Two sections on the dark ground, with the gallery between them, so the page
   is no longer one unbroken field of cream. Everything inside switches to the
   `--paper-*` scale; mixing the two ramps is what made the footer invisible
   once, so nothing here reads an `--ink-*` token.
   ========================================================================== */

.ed--night {
    background: var(--surface-night);
    color: var(--paper-2);
}
.ed--night .ed-kicker,
.ed--night .ed-meta { color: var(--paper-3); }
.ed--night .ed-rule { background: oklch(1 0 0 / 0.22); }
.ed--night .ed-title,
.ed--night .daycard-name,
.ed--night .daycard-price,
.ed--night .quote,
.ed--night .quote-who,
.ed--night .sidepanel-title { color: var(--paper-1); }
.ed--night .ed-lede,
.ed--night .daycard-copy { color: var(--paper-2); }
.ed--night .daycard-when,
.ed--night .quote-meta,
.ed--night .quote-count,
.ed--night .panel-note,
.ed--night .score-outof,
.ed--night .score-n,
.ed--night .sidepanel-kicker { color: var(--paper-3); }
.ed--night .idx-arch { color: var(--ember); }
.ed--night .daycard { border-top-color: oklch(1 0 0 / 0.32); }
.ed--night .daycard-foot,
.ed--night .quote-foot { border-color: oklch(1 0 0 / 0.18); }
.ed--night .daycard-media { background: oklch(1 0 0 / 0.05); }
.ed--night .taglist li { color: var(--paper-2); border-color: oklch(1 0 0 / 0.28); }
.ed--night .tbd { color: var(--ember); border-color: oklch(0.735 0.155 65 / 0.55); }
.ed--night .sidepanel { border-color: oklch(1 0 0 / 0.18); }
.ed--night .iconbtn { color: var(--paper-1); border-color: oklch(1 0 0 / 0.28); }
@media (hover: hover) {
    .ed--night .iconbtn:hover { background: oklch(1 0 0 / 0.12); border-color: var(--ember); }
}
.ed--night .iconbtn:focus-visible { background: oklch(1 0 0 / 0.12); border-color: var(--ember); }
.ed--night .iconbtn:active { background: oklch(1 0 0 / 0.2); transform: scale(0.92); }

/* --- 04 · the cards answer the pointer ---------------------------------- */
.daycard { position: relative; }
.ed--night .daycard-media {
    position: relative;
    overflow: hidden;
}
/* a terracotta rule wipes across the head of the card under the pointer */
.daycard::after {
    content: "";
    position: absolute;
    top: -2px;
    left: 0;
    height: 2px;
    width: 100%;
    background: var(--ember);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.5s var(--ease-entry);
}
@media (hover: hover) {
    .daycard:hover::after { transform: scaleX(1); }
    .daycard:hover .daycard-name { color: var(--ember); }
}
.daycard-name { transition: color var(--t-fast); }

/* --- 06 · the scores fill as the section arrives -------------------------- */
.meters { margin-top: 1.75rem; }
.meter {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 0.5rem 1rem;
    padding: 0.85rem 0 0.9rem;
}
.meter dt { color: var(--paper-2); font-size: 0.875rem; }
.meter dd {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.0625rem;
    color: var(--paper-1);
    text-align: right;
}
.meter-track {
    grid-column: 1 / -1;
    height: 2px;
    background: oklch(1 0 0 / 0.16);
    /* No `overflow: hidden`: the fill is the track scaled down from the left,
       so nothing can spill — and an overflow ancestor would make the fill's
       `view()` timeline bind to a box that never scrolls, freezing it. */
}
.meter-fill {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, var(--terracotta-bright), var(--ember));
    transform: scaleX(var(--fill, 0));
    transform-origin: left;
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        @keyframes meterFill { from { transform: scaleX(0); } to { transform: scaleX(var(--fill, 0)); } }
        .meter-fill {
            animation: meterFill linear both;
            animation-timeline: view();
            animation-range: entry 30% cover 42%;
        }
    }
}

/* ==========================================================================
   THE ARCH MARK
   Replaces the section numerals and the roman list indices. It is the shape
   painted on the walls of the rooms, so the index reads as the house rather
   than as a catalogue.
   ========================================================================== */

.idx-arch {
    width: 0.85em;
    height: 0.85em;
    stroke-width: 1.9;
    color: var(--terracotta-deep);
    vertical-align: -0.08em;
    transition: transform var(--t-mid), color var(--t-fast);
}
.ed-num .idx-arch { width: 1.15rem; height: 1.15rem; }
.filmrail-num .idx-arch { width: 1.2rem; height: 1.2rem; color: var(--ember); }

/* the mark on a selected or open row stands up straighter and warms */
.plate[aria-selected="true"] .idx-arch,
.rowlist-btn[aria-pressed="true"] .idx-arch,
.acc-btn[aria-expanded="true"] .idx-arch {
    color: var(--terracotta);
    transform: scaleY(1.18);
    transform-origin: bottom;
}
@media (hover: hover) {
    .rowlist-btn:hover .idx-arch,
    .acc-btn:hover .idx-arch { transform: scaleY(1.1); transform-origin: bottom; }
}
.rowlist-btn:focus-visible .idx-arch,
.acc-btn:focus-visible .idx-arch { transform: scaleY(1.1); transform-origin: bottom; }

/* Real press feedback on the three controls that had a hover and nothing for
   a finger: the shared-space rows, the FAQ questions and the room plates. */
.rowlist-btn:active .idx-arch,
.acc-btn:active .idx-arch { transform: scaleY(1.22); transform-origin: bottom; }
.rowlist-btn:active,
.acc-btn:active { background: oklch(0.216 0.019 48 / 0.05); }
.ed--night .acc-btn:active { background: oklch(1 0 0 / 0.06); }
.plate-btn:active img { transform: scale(0.99); filter: saturate(1); }

/* the numeral slots were sized for two digits of Bricolage */
.ed-num, .plate-idx, .rowlist-idx, .daycard-idx, .acc-idx {
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

/* ==========================================================================
   THE FOLD — a whole section that collapses
   Practical sits directly above the footer and stays shut until someone wants
   it. `<details>` carries the state, so it works with JS off and is keyboard
   operable without a line of script.
   ========================================================================== */

.ed--fold { padding-block: clamp(2.5rem, 6vw, 4.5rem); }

.fold-summary {
    display: block;
    cursor: pointer;
    list-style: none;
    padding-block: 0.5rem;
    border-radius: 4px;
}
.fold-summary::-webkit-details-marker { display: none; }

.fold-marker { display: flex; align-items: center; gap: clamp(0.75rem, 2vw, 1.25rem); }

.fold-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: clamp(1rem, 3vw, 2.5rem);
    flex-wrap: wrap;
    margin-top: clamp(0.75rem, 2vw, 1.1rem);
}
.fold-title { display: block; margin: 0; }

.fold-hint {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    /* `flex: none` sizes to max-content, and this label is long enough in caps
       to push the layout viewport wider than a phone. */
    flex: 0 1 auto;
    min-width: 0;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-3);
    transition: color var(--t-fast);
}
@media (max-width: 760px) {
    .fold-hint-open { display: none; }
}
.fold-chev {
    font-size: 1.1rem;
    color: var(--terracotta-deep);
    transition: transform var(--t-mid);
}
details[open] .fold-chev { transform: rotate(180deg); }
details[open] .fold-hint-open { visibility: hidden; }

@media (hover: hover) {
    .fold-summary:hover .fold-hint { color: var(--terracotta-deep); }
}
.fold-summary:focus-visible { outline: 2px solid var(--terracotta-bright); outline-offset: 6px; }
.fold-summary:active .fold-chev { transform: scale(0.9); }
details[open] .fold-summary:active .fold-chev { transform: rotate(180deg) scale(0.9); }

@keyframes foldOpen {
    from { opacity: 0; transform: translate3d(0, -10px, 0); }
    to   { opacity: 1; transform: none; }
}
.fold-body {
    padding-top: clamp(1.5rem, 4vw, 2.5rem);
    animation: foldOpen 0.42s var(--ease-entry) both;
}
.fold-body > * { animation: foldOpen 0.46s var(--ease-entry) both; }
.fold-body > *:nth-child(2) { animation-delay: 80ms; }

/* ==========================================================================
   03 · THE HOUSE — master / detail
   The index on the left, and the thing it controls beside it: image, title,
   blurb and facts as one block. They used to be in separate columns with the
   picture 600px below the button that changed it.
   ========================================================================== */

.house {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.75rem, 4vw, 3rem);
    margin-top: clamp(2rem, 5vw, 3.5rem);
    align-items: start;
}
@media (min-width: 900px) {
    .house { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
    /* the index stays with you while you read the detail beside it */
    .house-index {
        position: sticky;
        top: calc(var(--header-h) + 2rem);
    }
}

.house-index .ed-aside--plain { margin-top: 1.5rem; }

.house-stage {
    position: relative;
    background: var(--sand-100);
    border: 1px solid var(--hairline-ink);
    overflow: hidden;
}
/* every panel occupies the same cell, so switching never reflows the page */
.house-stage .detail-figure {
    margin: 0;
    grid-area: 1 / 1;
}
.house-stage { display: grid; }
.house-stage .detail-figure img {
    width: 100%;
    max-width: none;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    height: auto;
    display: block;
}
.detail-blurb {
    font-size: 0.9375rem;
    line-height: 1.6;
    color: var(--ink-2);
    padding: 1rem clamp(1rem, 2vw, 1.35rem) 1.15rem;
    margin: 0;
    text-wrap: pretty;
}

.house-meta {
    margin-top: clamp(1.25rem, 3vw, 1.75rem);
    padding-top: 1.1rem;
    border-top: 2px solid var(--ink-1);
}
.house-meta .sidepanel-title { margin-top: 0.35rem; }
.house-meta .factlist { margin-top: 1.25rem; }

/* ==========================================================================
   04 · DAY CARDS
   Four things in parallel rather than a fourth accordion. 03, 04 and 08 were
   all the same disclosure pattern, so the whole page read as one long list.
   ========================================================================== */

.daycards {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 3vw, 2rem);
    margin-top: clamp(2rem, 5vw, 3rem);
    padding: 0;
    list-style: none;
}
@media (min-width: 560px) { .daycards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .daycards { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.daycard {
    display: flex;
    flex-direction: column;
    border-top: 2px solid var(--ink-1);
    padding-top: 1rem;
}

.daycard-media {
    margin: 0 0 1.1rem;
    overflow: hidden;
    background: var(--sand-100);
}
.daycard-media img {
    width: 100%;
    /* Two of the four day photographs are landscape and two are portrait, so a
       square loses the least from either — 4:5 was cutting 47% off the wide
       ones. */
    aspect-ratio: 1 / 1;
    object-fit: cover;
    display: block;
    transition: transform 1s var(--ease-out), filter var(--t-mid);
    filter: saturate(0.94);
}
@media (hover: hover) {
    .daycard:hover .daycard-media img { transform: scale(1.06); filter: saturate(1.02); }
}

.daycard-body { display: flex; flex-direction: column; flex-grow: 1; }

.daycard-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0 0 0.55rem;
}
.daycard-idx {
    font-family: var(--font-display);
    font-weight: 700;
    font-stretch: 78%;
    font-size: 0.75rem;
    color: var(--terracotta-deep);
}
.daycard-when { font-size: 0.75rem; color: var(--ink-3); }

.daycard-name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1.125rem, 1.6vw, 1.3125rem);
    line-height: 1.12;
    letter-spacing: -0.02em;
    color: var(--ink-1);
    margin: 0 0 0.6rem;
    text-wrap: balance;
}
.daycard-copy {
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--ink-2);
    margin: 0 0 1rem;
    text-wrap: pretty;
}
.daycard .taglist { margin-bottom: 1rem; }

.daycard-foot {
    margin: auto 0 0;
    padding-top: 0.85rem;
    border-top: 1px solid var(--hairline-ink);
    display: flex;
    justify-content: flex-end;
}
.daycard-price {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1rem;
    color: var(--ink-1);
}

/* ==========================================================================
   SCROLL-LINKED LIFE

   Everything here runs on the native `view()` timeline, so it is driven by the
   scroller itself rather than by a listener — no JS, nothing to throttle, and
   it degrades to "already in place" in browsers without it. Transform, opacity
   and clip-path only.
   ========================================================================== */

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {

        /* Photographs uncover rather than fade: the frame wipes up off the
           image while it settles out of a slight rise.

           The animation goes on the CONTAINER, never on the <img> inside it.
           `view()` resolves against the nearest ancestor scroll container, and
           these wrappers are `overflow: hidden` — put it on the image and the
           timeline binds to a box that never scrolls, so the animation applies
           and then sits frozen at its end state. */
        @keyframes plateUncover {
            from { clip-path: inset(88% 0 0 0); transform: translate3d(0, 26px, 0); }
            to   { clip-path: inset(0 0 0 0);   transform: none; }
        }
        .plate-btn,
        .daycard-media,
        .house-stage {
            animation: plateUncover linear both;
            animation-timeline: view();
            animation-range: entry 8% cover 34%;
        }

        /* Section rules draw themselves as the marker arrives. */
        @keyframes ruleDraw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
        .ed-marker .ed-rule {
            animation: ruleDraw linear both;
            animation-timeline: view();
            animation-range: entry 20% cover 18%;
            transition: none;
        }

    }
}

/* ==========================================================================
   INTERACTION MOTION

   Every swap in 02-09 was an instant `hidden` flip: pick a tab, open a
   question, choose a shared room, and the content teleported. The attribute
   toggle is untouched — the tests pin it and it is what keeps the page working
   with JS off — but an element coming back from `display:none` restarts its
   animations, so the incoming panel can play itself in for free.

   Transform and opacity only, and each surface enters from where it logically
   comes from: the tab row drops from its button, the accordion unfurls
   downward, the detail figure crosses from the list it belongs to.
   ========================================================================== */

@keyframes panelIn {
    from { opacity: 0; transform: translate3d(0, 10px, 0); }
    to   { opacity: 1; transform: none; }
}
@keyframes unfurl {
    from { opacity: 0; clip-path: inset(0 0 100% 0); transform: translate3d(0, -6px, 0); }
    to   { opacity: 1; clip-path: inset(0 0 -10% 0); transform: none; }
}
@keyframes crossIn {
    from { opacity: 0; transform: translate3d(14px, 0, 0) scale(0.99); }
    to   { opacity: 1; transform: none; }
}
@keyframes plateIn {
    from { opacity: 0; transform: scale(1.015); }
    to   { opacity: 1; transform: none; }
}

/* 04 · the accordion actually opens now */
.acc-panel:not([hidden]) { animation: unfurl 0.44s var(--ease-entry) both; }
/* its two halves follow the panel rather than arriving with it */
.acc-panel:not([hidden]) > * { animation: panelIn 0.42s var(--ease-entry) both; }
.acc-panel:not([hidden]) > *:nth-child(2) { animation-delay: 70ms; }

/* 05 · route tables, and their rows in sequence */
.routes:not([hidden]) > * { animation: panelIn 0.40s var(--ease-entry) both; }
.routes:not([hidden]) > *:nth-child(2) { animation-delay: 45ms; }
.routes:not([hidden]) > *:nth-child(3) { animation-delay: 90ms; }
.routes:not([hidden]) > *:nth-child(4) { animation-delay: 135ms; }
.routes:not([hidden]) > *:nth-child(n+5) { animation-delay: 180ms; }

/* 03 · the shared-space figure crosses in from the list beside it */
.detail-figure:not([hidden]) { animation: crossIn 0.46s var(--ease-entry) both; }

/* 06 · the plate settles rather than cutting */
.gallery-main.is-swapping img { animation: plateIn 0.42s var(--ease-out) both; }
/* 07 · so does the quote */
.quote-figure.is-swapping .quote,
.quote-figure.is-swapping .quote-foot { animation: panelIn 0.40s var(--ease-entry) both; }
.quote-figure.is-swapping .quote-foot { animation-delay: 60ms; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 1180px) {
    .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
    :root { --header-h: 72px; }
    .nav { display: none; }
    .burger { display: flex; }

    .scroll-cue { display: none; }
}

@media (max-width: 760px) {
    .form-row { grid-template-columns: 1fr; }
    .footer-grid { grid-template-columns: 1fr; }
    .toasts { left: 1rem; right: 1rem; max-width: none; }
}

/* ==========================================================================
   REDUCED MOTION — full reset, shipped (WCAG 2.3.3)
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
    .blob { animation: none; }
    .scroll-cue .icon { animation: none; }
    .reveal { opacity: 1; transform: none; }
    .fold-body, .fold-body > * { animation: none; }
    .idx-arch { transform: none !important; }
    .meter-fill { animation: none; }
    .daycard::after { transition: none; }
    .acc-panel:not([hidden]),
    .acc-panel:not([hidden]) > *,
    .routes:not([hidden]) > *,
    .detail-figure:not([hidden]),
    .gallery-main.is-swapping img,
    .quote-figure.is-swapping .quote,
    .quote-figure.is-swapping .quote-foot { animation: none; clip-path: none; }
    .ed-marker .ed-rule { transform: none; }
    @media (hover: hover) {
        .card:hover { transform: none; }
        .card:hover .card-media img { transform: none; }
        .btn:hover { transform: none; }
    }
    .card:focus-within { transform: none; }
    .card:focus-within .card-media img { transform: none; }
    .btn:focus-visible { transform: none; }
    /* The reel is never downloaded here, so the poster is what is on screen.
       Zeroing the per-beat offset stops the film travelling; `!important` on
       a custom property beats the per-frame inline value, so it takes one
       declaration rather than a transform reset. */
    .panel { --y: 0px !important; }
}

/* ==========================================================================
   ADDENDA
   ========================================================================== */

/* Anchor targets must clear the fixed header */
.section, .footer { scroll-margin-top: var(--header-h); }

/* Header-only wordmark swap — the footer copy must never inherit it */
.header .brand-word--ink { display: none; }
.header.is-solid .brand-word--cream { display: none; }
.header.is-solid .brand-word--ink { display: block; }
.brand-word--static { display: block; }



/* Two-tone mark: its cream element disappears on cream, so light surfaces get the ink cut */
.header .brand-mark--ink { display: none; }
.header.is-solid .brand-mark--cream { display: none; }
.header.is-solid .brand-mark--ink { display: block; }

/* Small screens: the text CTA crowds the burger off the edge (and body has
   overflow-x:clip, so it silently disappears rather than overflowing).
   The drawer carries the same CTA, so drop it from the bar. */
@media (max-width: 760px) {
    .header-actions .btn--primary { display: none; }
    .brand-word { height: 20px; }
}

/* ==========================================================================
   EDITORIAL SECTIONS (02–09)
   Direction A. Layout lives in CSS so breakpoints can override it; JS only
   toggles state classes and aria attributes.
   ========================================================================== */

.ed { position: relative; z-index: 2; padding-block: clamp(3.5rem, 8vw, 6.5rem); }

.ed-marker {
    display: flex;
    align-items: baseline;
    gap: clamp(0.75rem, 2vw, 1.25rem);
    margin-bottom: 1.5rem;
}
.ed-num {
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 78%;
    font-size: 0.9375rem;
    letter-spacing: 0.08em;
    color: var(--terracotta-deep);
}
.ed-kicker {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-3);
    white-space: nowrap;
}
/* The hinge out of the film. Section 01's rule ends near the bottom of the
   payoff frame; this one draws itself from the same edge as section 02 arrives,
   so the line the visitor has been following the whole way down carries into
   the editorial page instead of the film simply stopping. */
.ed-rule {
    flex-grow: 1;
    height: 1px;
    background: var(--hairline-ink);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.9s var(--ease-entry) 140ms;
}
.ed-marker.is-in .ed-rule { transform: scaleX(1); }
.ed-meta {
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
    white-space: nowrap;
}
@media (max-width: 760px) { .ed-meta { display: none; } }

.ed-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-stretch: 100%;
    font-size: clamp(2.25rem, 7vw, 4.75rem);
    line-height: 0.95;
    letter-spacing: -0.03em;
    color: var(--ink-1);
    text-wrap: balance;
    margin: 0;
    max-width: 15ch;
}
.ed-lede {
    font-size: clamp(1rem, 1.6vw, 1.0625rem);
    line-height: 1.62;
    color: var(--ink-2);
    max-width: 46ch;
    margin: 1.75rem 0 0;
}
.ed-aside {
    font-size: 0.75rem;
    line-height: 1.55;
    color: var(--ink-3);
    border-top: 1px solid var(--hairline-ink);
    padding-top: 0.75rem;
}

.ed-intro { display: flex; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: flex-start; margin-top: 2.25rem; }
.ed-intro > p { flex-grow: 1; margin: 0; }
.ed-intro > .ed-aside { width: 152px; flex: none; }
@media (max-width: 760px) { .ed-intro > .ed-aside { display: none; } }

/* --- plates: the asymmetric room grid --- */

.plates {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: clamp(1.25rem, 3vw, 1.75rem);
    margin-top: clamp(2rem, 5vw, 2.5rem);
    align-items: start;
}
.plate { margin: 0; grid-column: span 12; }
.plate-btn {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    cursor: pointer;
}
.plate-btn img { width: 100%; object-fit: cover; display: block; transition: filter var(--t-mid); filter: saturate(0.94); }
.plate[aria-selected="true"] .plate-btn { outline: 2px solid var(--terracotta-deep); outline-offset: 5px; }
.plate[aria-selected="true"] .plate-btn img { filter: none; }

.plate-cap {
    display: flex;
    gap: 0.75rem;
    align-items: baseline;
    margin-top: 1.1rem;
    padding-top: 0.8rem;
    border-top: 1px solid oklch(0.216 0.019 48 / 0.3);
    transition: border-color var(--t-fast);
}
.plate[aria-selected="true"] .plate-cap { border-top: 2px solid var(--terracotta-deep); padding-top: calc(0.8rem - 1px); }
.plate-idx { font-family: var(--font-display); font-weight: 700; font-stretch: 78%; font-size: 0.75rem; color: var(--terracotta-deep); width: 0.9rem; flex: none; }
.plate-name { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.015em; color: var(--ink-1); font-size: 1.0625rem; }
.plate[aria-selected="true"] .plate-name { font-weight: 700; }
.plate-spec { font-size: 0.78rem; color: var(--ink-3); margin-top: 0.2rem; }
.plate-rate { font-family: var(--font-display); font-weight: 700; font-size: 1.0625rem; font-variant-numeric: tabular-nums; color: var(--ink-1); }

@media (min-width: 760px) {
    .plate { grid-column: span 6; }
}
/* Three columns of different widths on one row: a tall portrait, a wide
   landscape, a narrow portrait. The asymmetry comes from the column widths and
   the photographs' own shapes, so the tops align and the bottoms stay ragged.
   The old lead(7)+sub(5)+sub(5) on a 12-col grid wrapped the third plate onto a
   second row and left most of it empty — the hole in the middle of 02. */
@media (min-width: 900px) {
    .plate--lead,
    .plate--sub { grid-column: span 6; padding-top: 0; }
    .plates:has(.plate--sub + .plate--sub) .plate--lead { grid-column: span 5; }
    .plates:has(.plate--sub + .plate--sub) .plate--sub { grid-column: span 4; padding-top: clamp(1.5rem, 4vw, 3rem); }
    .plates:has(.plate--sub + .plate--sub) .plate--sub:last-of-type { grid-column: span 3; padding-top: clamp(3rem, 7vw, 5.5rem); }
}

/* --- selection bar --- */

.ratebar {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    align-items: center;
    margin-top: clamp(2.25rem, 5vw, 3.75rem);
    padding-top: 1.4rem;
    border-top: 2px solid var(--ink-1);
}
@media (min-width: 900px) { .ratebar { grid-template-columns: 1fr auto auto; gap: 2rem; } }

.ratebar-label { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); }
.ratebar-name { font-family: var(--font-display); font-weight: 600; font-size: 1.375rem; letter-spacing: -0.015em; margin-top: 0.3rem; color: var(--ink-1); }

.stepper { display: flex; align-items: center; gap: 0.875rem; }
.stepper-btn {
    width: 34px; height: 34px;
    border-radius: 50%;
    border: 1px solid oklch(0.216 0.019 48 / 0.3);
    background: transparent;
    color: var(--ink-1);
    display: grid; place-items: center;
    font-size: 1.05rem; line-height: 1;
    cursor: pointer;
    transition: background-color var(--t-fast), border-color var(--t-fast);
}
@media (hover: hover) {
    .stepper-btn:hover { background: oklch(0.216 0.019 48 / 0.06); border-color: var(--ink-1); }
}
.stepper-btn:focus-visible { background: oklch(0.216 0.019 48 / 0.06); border-color: var(--ink-1); }
.stepper-btn:active { background: oklch(0.216 0.019 48 / 0.13); border-color: var(--ink-1); transform: scale(0.92); }
.stepper-val { text-align: center; min-width: 4.5rem; }
.stepper-num { font-family: var(--font-display); font-weight: 700; font-size: 1.375rem; font-variant-numeric: tabular-nums; color: var(--ink-1); }
.stepper-unit { font-size: 0.65rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); }

.ratebar-total { display: flex; align-items: center; gap: 1.4rem; }
.ratebar-sum { text-align: right; }
.ratebar-fig { font-family: var(--font-display); font-weight: 700; font-size: 1.625rem; font-variant-numeric: tabular-nums; margin-top: 0.2rem; color: var(--ink-1); }

/* --- list + detail (The House) --- */

.split { display: grid; grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 2.75rem); margin-top: clamp(2rem, 5vw, 3.5rem); align-items: start; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 336px; } }

.rowlist { display: flex; flex-direction: column; }
.rowlist-btn {
    display: flex; align-items: center; gap: 1rem;
    width: 100%; text-align: left;
    background: none; border: 0;
    border-bottom: 1px solid oklch(0.216 0.019 48 / 0.18);
    padding: 1.05rem 0;
    cursor: pointer;
    color: var(--ink-1);
    transition: border-color var(--t-fast);
}
.rowlist-btn[aria-pressed="true"] { border-bottom: 2px solid var(--terracotta-deep); padding-bottom: calc(1.05rem - 1px); }
.rowlist-idx { font-family: var(--font-display); font-weight: 700; font-stretch: 78%; font-size: 0.75rem; color: var(--terracotta-deep); width: 1rem; flex: none; }
.rowlist-name { font-family: var(--font-display); font-size: 1.1875rem; letter-spacing: -0.015em; font-weight: 500; }
.rowlist-btn[aria-pressed="true"] .rowlist-name { font-weight: 700; }
.rowlist-meta { font-size: 0.78rem; color: var(--ink-3); font-variant-numeric: tabular-nums; margin-left: auto; }
.rowlist-arrow { flex: none; color: oklch(0.478 0.026 58); font-size: 1.05rem; transition: color var(--t-fast), transform var(--t-fast); }
.rowlist-btn[aria-pressed="true"] .rowlist-arrow { color: var(--terracotta-deep); transform: translateX(3px); }

.detail-figure { margin: 2rem 0 0; }
.detail-figure img {
    width: 100%;
    max-width: 700px;
    height: auto;
    display: block;
}
.detail-blurb { font-size: 0.9rem; line-height: 1.6; color: var(--ink-2); margin: 1rem 0 0; padding-top: 0.8rem; border-top: 1px solid oklch(0.216 0.019 48 / 0.3); }

/* Mobile-first, so the pair that used to need 899 AND 900 needs one value. */
.sidepanel { border-top: 1px solid var(--hairline-ink); padding-top: 1.5rem; }
@media (min-width: 900px) {
    .sidepanel {
        border-top: 0;
        padding-top: 0;
        border-left: 1px solid var(--hairline-ink);
        padding-left: clamp(1.25rem, 3vw, 2rem);
    }
}
.sidepanel-kicker { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-3); }
.sidepanel-title { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.5rem, 3vw, 1.875rem); letter-spacing: -0.02em; line-height: 1.1; margin-top: 0.6rem; color: var(--ink-1); }

.factlist { margin-top: 1.6rem; }
.factlist > div { display: flex; justify-content: space-between; gap: 1rem; padding: 0.7rem 0; border-bottom: 1px solid oklch(0.216 0.019 48 / 0.12); font-size: 0.84rem; }
.factlist dt { color: var(--ink-3); }
.factlist dd { font-weight: 600; text-align: right; color: var(--ink-1); margin: 0; }

/* --- accordion (Days Out, Before You Come) --- */

.acc { display: flex; flex-direction: column; margin-top: clamp(2rem, 5vw, 3.25rem); border-top: 2px solid var(--ink-1); }
.acc-item { border-bottom: 1px solid oklch(0.216 0.019 48 / 0.18); }
.acc-btn {
    display: grid;
    grid-template-columns: 1.25rem 1fr auto;
    gap: 0.9rem;
    align-items: center;
    width: 100%; text-align: left;
    background: none; border: 0;
    padding: 1.25rem 0;
    cursor: pointer;
    color: var(--ink-1);
}

.acc-idx { font-family: var(--font-display); font-weight: 700; font-stretch: 78%; font-size: 0.75rem; color: var(--terracotta-deep); }
.acc-name { font-family: var(--font-display); font-size: clamp(1.0625rem, 2.4vw, 1.375rem); letter-spacing: -0.02em; font-weight: 500; }
.acc-btn[aria-expanded="true"] .acc-name { font-weight: 700; }
.acc-when { font-size: 0.8125rem; color: var(--ink-3); }
.acc-price { font-size: 0.8125rem; text-align: right; }
.acc-chev { flex: none; color: oklch(0.478 0.026 58); transition: transform var(--t-fast), color var(--t-fast); font-size: 1.05rem; }
.acc-btn[aria-expanded="true"] .acc-chev { transform: rotate(180deg); color: var(--terracotta-deep); }
/* Narrow first: the meta wraps under the name and the chevron sits beside it.
   The wide five-column row is the override, so this pair costs one value. */
.acc-when, .acc-price { grid-column: 2; text-align: left; }
.acc-chev { grid-row: 1; grid-column: 3; }
@media (min-width: 760px) {
    .acc-btn { grid-template-columns: 1.25rem 1fr 8rem 7rem 1.5rem; gap: 1.25rem; }
    .acc-when, .acc-price { grid-column: auto; }
    .acc-price { text-align: right; }
    .acc-chev { grid-row: auto; grid-column: auto; }
}

.acc-panel { display: grid; grid-template-columns: 1fr; gap: 1.5rem; padding: 0 0 1.75rem; }
@media (min-width: 760px) { .acc-panel { grid-template-columns: 250px 1fr; gap: 2rem; padding-left: 2.6rem; } }
.acc-panel img { width: 100%; height: auto; display: block; }
.acc-panel p { font-size: 0.9375rem; line-height: 1.62; color: var(--ink-2); margin: 0 0 1rem; }
.acc-answer { font-size: clamp(0.9375rem, 1.7vw, 1rem); line-height: 1.65; color: var(--ink-2); margin: 0 0 1.5rem; max-width: 62ch; }
[hidden] { display: none !important; }

.taglist { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.taglist li { font-size: 0.75rem; color: var(--ink-2); border: 1px solid oklch(0.216 0.019 48 / 0.2); border-radius: var(--r-full); padding: 0.3rem 0.75rem; }

/* --- tabs (Getting Here) --- */

.tabs { display: flex; gap: clamp(1rem, 3vw, 1.875rem); margin-top: clamp(2rem, 4vw, 3rem); border-bottom: 1px solid oklch(0.216 0.019 48 / 0.3); overflow-x: auto; }
.tab {
    background: none; border: 0;
    padding: 0 0 0.75rem;
    margin-bottom: -1px;
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--ink-3);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--t-fast);
}
.tab[aria-selected="true"] { font-weight: 700; color: var(--ink-1); border-bottom-color: var(--terracotta-deep); }

.routes { display: flex; flex-direction: column; }
.routes > div { display: grid; grid-template-columns: 1.25rem 1fr auto; gap: 1rem; align-items: baseline; padding: 1.05rem 0; border-bottom: 1px solid oklch(0.216 0.019 48 / 0.14); }
.route-name { font-family: var(--font-display); font-weight: 600; font-size: 1.0625rem; letter-spacing: -0.015em; color: var(--ink-1); }
.route-note { font-size: 0.8125rem; color: var(--ink-3); margin-top: 0.25rem; line-height: 1.5; }
.route-val { font-family: var(--font-display); font-weight: 700; font-size: 0.9375rem; font-variant-numeric: tabular-nums; color: var(--ink-2); text-align: right; }

/* --- gallery --- */

.gallery {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.1rem, 2.5vw, 1.75rem);
    margin-top: clamp(1.5rem, 4vw, 2rem);
}
/* Title and lede beside the print, caption pinned to the foot of that column
   so it lines up with the bottom of the plate. */
.gallery { grid-template-columns: 1fr; }
@media (min-width: 900px) {
    .gallery {
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
        column-gap: clamp(1.5rem, 4vw, 3.5rem);
        align-items: stretch;
    }
    .gallery-side { grid-column: 1; grid-row: 1; }
    .gallery-main { grid-column: 2; grid-row: 1; }
    .gallery-thumbs { grid-column: 1 / -1; grid-row: 2; }
}
.gallery-side { display: flex; flex-direction: column; }
.gallery-heading { font-size: clamp(1.875rem, 3.4vw, 3rem); margin-bottom: clamp(0.9rem, 2vw, 1.25rem); }
.gallery-lede { margin-bottom: 2rem; }
.gallery-side .gallery-cap { margin-top: auto; }
.gallery-main .gallery-mount { margin-inline: 0; }
/* The mount is the board the print sits on; the caption below it stays on the
   page ground, where its ink colours were measured. */
/* The mount hugs the print rather than framing a lot of empty board: the
   image height is fixed so the row never jumps vertically, and the mount's
   width follows whatever shape the photograph actually is. */
.gallery-mount {
    width: fit-content;
    max-width: 100%;
    margin-inline: auto;
    background: var(--sand-100);
    border: 1px solid var(--hairline-ink);
    padding: clamp(0.6rem, 1.2vw, 1rem);
    overflow: hidden;
}
.gallery-main img {
    height: clamp(320px, 56vh, 620px);
    width: auto;
    max-width: 100%;
    display: block;
    transition: transform 1.2s var(--ease-out);
}
@media (hover: hover) {
    .gallery-mount:hover img { transform: scale(1.03); }
}
.gallery-cap { display: flex; flex-wrap: wrap; align-items: baseline; gap: 1.1rem; padding-top: 0.875rem; border-top: 2px solid var(--ink-1); }
@media (min-width: 900px) {
    .gallery-cap { align-content: end; padding-bottom: 0.5rem; }
    .gallery-cap .gallery-cap-body { flex-basis: 100%; }
}
.gallery-cap-body { flex-grow: 1; }
.gallery-title { font-family: var(--font-display); font-weight: 600; font-size: 1.3125rem; letter-spacing: -0.02em; color: var(--ink-1); }
.gallery-sub { font-size: 0.8125rem; color: var(--ink-3); margin-top: 0.25rem; }
/* A filmstrip: every plate on one line, scrollable on a narrow screen, and no
   half-empty final row to make the section look unfinished. */
.gallery-thumbs {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    scrollbar-width: thin;
    padding-bottom: 0.4rem;
    scroll-snap-type: x proximity;
}
.gallery-thumbs .thumb {
    flex: 0 0 auto;
    width: clamp(62px, 7.2vw, 96px);
    scroll-snap-align: start;
}
.thumb { padding: 0; border: 0; background: none; line-height: 0; display: block; cursor: pointer; }
.thumb img { width: 100%; aspect-ratio: 1 / 1; height: auto; object-fit: cover; display: block; opacity: 0.55; transition: opacity var(--t-fast), transform var(--t-fast); }
.thumb[aria-pressed="true"] { outline: 2px solid var(--terracotta-deep); outline-offset: 3px; }
.thumb[aria-pressed="true"] img,
.thumb:focus-visible img { opacity: 1; }
@media (hover: hover) {
    .thumb:hover img { opacity: 1; }
}
.thumb:active img { opacity: 1; transform: scale(0.96); }

.iconbtn {
    width: 36px; height: 36px;
    border-radius: 50%;
    border: 1px solid oklch(0.216 0.019 48 / 0.3);
    background: transparent;
    color: var(--ink-1);
    display: grid; place-items: center;
    cursor: pointer;
    flex: none;
    transition: background-color var(--t-fast), border-color var(--t-fast);
}
@media (hover: hover) {
    .iconbtn:hover { background: oklch(0.216 0.019 48 / 0.06); border-color: var(--ink-1); }
}
.iconbtn:focus-visible { background: oklch(0.216 0.019 48 / 0.06); border-color: var(--ink-1); }
.iconbtn:active { background: oklch(0.216 0.019 48 / 0.13); border-color: var(--ink-1); transform: scale(0.92); }
.iconbtn .icon { font-size: 1rem; }

/* --- voices --- */

.quote {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.5rem, 4vw, 2.5rem);
    line-height: 1.18;
    letter-spacing: -0.025em;
    color: var(--ink-1);
    margin: 0;
    text-wrap: pretty;
}
.quote-foot { display: flex; align-items: center; gap: 1.1rem; margin-top: 1.875rem; padding-top: 1rem; border-top: 2px solid var(--ink-1); flex-wrap: wrap; }
.quote-who { font-family: var(--font-display); font-weight: 700; font-size: 1rem; letter-spacing: -0.01em; color: var(--ink-1); }
.quote-meta { font-size: 0.78rem; color: var(--ink-3); margin-top: 0.2rem; }
.quote-count { font-size: 0.75rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.tbd {
    display: inline-block;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    border: 1px dashed oklch(0.545 0.148 40 / 0.6);
    color: var(--terracotta-darker);
    background: oklch(0.735 0.155 65 / 0.12);
    white-space: nowrap;
}
.notice {
    display: flex; align-items: center; gap: 0.875rem;
    margin-top: 1.25rem;
    padding: 0.8rem 1.1rem;
    background: oklch(0.735 0.155 65 / 0.12);
    border-left: 2px solid var(--terracotta-deep);
}
.notice .icon { color: var(--terracotta-deep); font-size: 1.1rem; flex: none; }
.notice p { font-size: 0.8125rem; line-height: 1.5; color: var(--ink-2); margin: 0; }
/* ink-2 on umber is unreadable — the night ramp again */
.ed--night .notice { background: oklch(0.735 0.155 65 / 0.14); border-left-color: var(--ember); }
.ed--night .notice p { color: var(--paper-2); }
.ed--night .notice .icon { color: var(--ember); }

/* --- reserve: availability calendar --- */

.reserve { display: grid; grid-template-columns: 1fr; gap: clamp(1.75rem, 4vw, 2.875rem); align-items: start; margin-top: clamp(1.75rem, 4vw, 2.75rem); }
@media (min-width: 900px) { .reserve { grid-template-columns: 1fr 314px; } }

.cal-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.25rem; }
.cal-month { font-family: var(--font-display); font-weight: 600; font-size: 1.3125rem; letter-spacing: -0.015em; min-width: 10rem; color: var(--ink-1); }
.cal-clear { background: none; border: 0; font-size: 0.78rem; color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: 0; margin-left: auto; }
@media (hover: hover) {
    .cal-clear:hover { color: var(--terracotta-deep); }
}
.cal-clear:focus-visible { color: var(--terracotta-deep); }
.cal-clear:active { color: var(--terracotta-darker); }

.cal-dows, .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
.cal-dows { margin-bottom: 0.375rem; }
.cal-dows span { text-align: center; font-size: 0.65rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); padding-bottom: 0.375rem; }

.cal-day {
    height: 42px;
    border: 0;
    background: none;
    font: inherit;
    font-size: 0.84rem;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    color: var(--ink-1);
    display: grid; place-items: center;
    cursor: pointer;
    position: relative;
    transition: background-color var(--t-fast);
}
@media (hover: hover) {
    .cal-day:hover:not(:disabled) { background: oklch(0.216 0.019 48 / 0.07); }
}
.cal-day:focus-visible:not(:disabled) { background: oklch(0.216 0.019 48 / 0.07); }
.cal-day:active:not(:disabled) { background: oklch(0.216 0.019 48 / 0.15); transform: scale(0.9); }
.cal-day:disabled { cursor: default; }
.cal-day[data-state="past"] { color: oklch(0.545 0.026 58); text-decoration: line-through; }
.cal-day[data-state="taken"] { color: oklch(0.545 0.026 58); }
.cal-day[data-state="taken"]::after {
    content: "";
    position: absolute;
    left: 22%; right: 22%; bottom: 7px;
    height: 1.5px;
    background: oklch(0.545 0.026 58);
}
.cal-day[data-state="edge"] { background: var(--terracotta-deep); color: oklch(1 0 0); font-weight: 700; }
.cal-day[data-state="between"] { background: oklch(0.735 0.155 65 / 0.22); font-weight: 600; }
.cal-blank { height: 42px; }

.cal-legend { display: flex; flex-wrap: wrap; gap: 1.1rem; margin-top: 1rem; font-size: 0.72rem; color: var(--ink-3); }
.cal-legend span { display: inline-flex; align-items: center; gap: 0.4rem; }
.cal-swatch { width: 12px; height: 12px; border-radius: 3px; flex: none; }

.reserve-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 1.875rem; padding-top: 1.25rem; border-top: 1px solid oklch(0.216 0.019 48 / 0.18); }
@media (max-width: 560px) { .reserve-controls { grid-template-columns: 1fr; } }
.ctl-label { font-size: 0.65rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 0.6rem; }

.checks { display: flex; flex-direction: column; gap: 0.55rem; }
.check { display: flex; align-items: center; gap: 0.6rem; background: none; border: 0; padding: 0; text-align: left; cursor: pointer; color: var(--ink-2); font-size: 0.84rem; }
.check-box { width: 17px; height: 17px; border-radius: 4px; flex: none; display: grid; place-items: center; border: 1px solid oklch(0.216 0.019 48 / 0.35); transition: background-color var(--t-fast), border-color var(--t-fast); }
.check[aria-pressed="true"] .check-box { background: var(--terracotta-deep); border-color: var(--terracotta-deep); }
.check-box .icon { color: oklch(1 0 0); font-size: 0.7rem; opacity: 0; }
.check[aria-pressed="true"] .check-box .icon { opacity: 1; }

.summary-panel { border: 1px solid oklch(0.216 0.019 48 / 0.22); padding: clamp(1.25rem, 3vw, 1.625rem); }
.roomchoice { display: flex; flex-direction: column; margin-top: 1rem; }
.roomchoice-btn { display: flex; align-items: center; gap: 0.7rem; width: 100%; background: none; border: 0; border-bottom: 1px solid oklch(0.216 0.019 48 / 0.12); padding: 0.75rem 0; cursor: pointer; text-align: left; }
.roomchoice-btn[aria-pressed="true"] { border-bottom-color: var(--terracotta-deep); }
.roomchoice-dot { width: 13px; height: 13px; border-radius: 50%; flex: none; border: 4px solid transparent; box-shadow: inset 0 0 0 1px oklch(0.216 0.019 48 / 0.35); transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.roomchoice-btn[aria-pressed="true"] .roomchoice-dot { border-color: var(--terracotta-deep); box-shadow: none; }
.roomchoice-name { font-size: 0.84rem; font-weight: 500; color: var(--ink-1); }
.roomchoice-btn[aria-pressed="true"] .roomchoice-name { font-weight: 700; }
.roomchoice-cap { display: block; font-size: 0.72rem; color: var(--ink-3); margin-top: 0.125rem; }
.roomchoice-rate { margin-left: auto; font-family: var(--font-display); font-weight: 700; font-size: 0.875rem; font-variant-numeric: tabular-nums; color: var(--ink-1); }

.sumlines { margin: 1.375rem 0 0; padding-top: 1rem; border-top: 1px solid oklch(0.216 0.019 48 / 0.18); display: flex; flex-direction: column; gap: 0.55rem; }
.sumlines > div { display: flex; justify-content: space-between; gap: 0.75rem; font-size: 0.84rem; }
.sumlines dt { color: var(--ink-3); }
.sumlines dd { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-1); margin: 0; }
.sumtotal { display: flex; justify-content: space-between; align-items: baseline; margin-top: 1.125rem; padding-top: 1rem; border-top: 2px solid var(--ink-1); }
.sumtotal-fig { font-family: var(--font-display); font-weight: 700; font-size: 1.875rem; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--ink-1); }
.sumfoot { font-size: 0.72rem; line-height: 1.55; color: var(--ink-3); margin: 0.75rem 0 0; text-align: center; }

@media (prefers-reduced-motion: reduce) {
    .plate-btn img, .rowlist-arrow, .acc-chev, .thumb img, .cal-day { transition: none; }
    .rowlist-btn[aria-pressed="true"] .rowlist-arrow { transform: none; }
}
.ed { scroll-margin-top: var(--header-h); }

/* Touch targets: pad to a usable size without changing the visual weight */
.cal-clear { padding: 0.75rem 0.5rem; margin-right: -0.5rem; }
.check { padding-block: 0.65rem; }
.checks { gap: 0; }

/* caption parts are spans (valid inside <figcaption>) — stack them */
.plate-cap-body { flex-grow: 1; min-width: 0; }
.plate-name, .plate-spec { display: block; }
