/* ============================================
   oKEYo — SITE STYLESHEET
   ============================================
   Structure, tokens and layout live in base.css (imported below).

   This file holds only what is specific to oKEYo:
     - the font files and token overrides
     - the glass chrome: nav tiles, grid corners, the corner info panel
     - the hero wordmark and its handover to the 3D copy in scene.js
     - the definition clouds

   Note: css/responsive.css exists but index.html does not link it, so
   nothing in it applies. Link it or delete it — right now it is neither.
   ============================================ */

@import url("base.css");

/* ---------- FONTS ---------- */
@font-face {
    font-family: "Quablo";
    src: url("../fonts/Quablo-Medium.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Roma";
    src: url("../fonts/TifoTrial-Roma.otf") format("opentype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Milano";
    src: url("../fonts/TifoTrial-Milano.otf") format("opentype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* ---------- SITE DESIGN TOKENS ---------- */
/* Overrides base.css defaults. Light-theme values are inherited from base. */
:root {
    --fg: #fff5ca;
    --accentColor: #246996;
    --font-sans:    "Quablo", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --font-display: "Roma", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --font-text:    "Milano", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* ---------- BRAND MARK EXTRAS ---------- */
/* Inlined icon art carries no fill of its own, so the theme drives it. Sized
   here rather than through base.css's .brand-mark img rules, which exist to
   invert black bitmaps — wrong for art that already reads --fg. */
/* Sized to sit inside the round plate with room to breathe on every side */
.brand-mark .brand-icon {
    width: 34px;
    height: auto;
    display: block;
    color: var(--fg);
}

.brand-mark .brand-icon path {
    fill: currentColor;
    transition: fill var(--theme-fade);
}

/* ---------- HERO OVERLAY ---------- */
/* base.css sets difference blending here, which was written for a flat
   background. With the engraved sky moving behind it the wordmark inverted
   against every passing cloud, so it composites normally instead. Overridden
   here rather than edited in base.css, which the other sites share — and this
   file is imported after it, so an equal-specificity rule is enough. */
.hero-definition-overlay {
    mix-blend-mode: normal;
}

.bottom-bar {
    display: none;
}

.site-sky {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}

.site-sky canvas {
    display: block;
    width: 100%;
    height: 100%;
}

.site-texture {
    position: fixed;
    inset: 0;
    z-index: 500;
    pointer-events: none;
    background-image: url("../images/site-texture.jpg");
    background-repeat: repeat;
    mix-blend-mode: overlay;
    opacity: 0.5;
}

.glass {
    background-color: color-mix(in srgb, currentColor 7%, transparent);
    -webkit-backdrop-filter: blur(7.5px) saturate(140%);
    backdrop-filter: blur(7.5px) saturate(140%);
    border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
    border-radius: 3px;
    box-shadow: inset 0 1px 0 color-mix(in srgb, currentColor 20%, transparent),
                0 10px 28px rgba(0, 0, 0, 0.45),
                0 2px 6px rgba(0, 0, 0, 0.3);
    will-change: backdrop-filter;
}

.site-grid-top-right.glass {
    justify-self: end;
    align-self: start;
    padding: 10px 14px;
}

.site-grid-bottom-left.glass {
    justify-self: start;
    align-self: end;
    padding: 12px 14px;
}

.site-grid-bottom-right.glass {
    justify-self: end;
    align-self: end;
    padding: 10px 14px;
}

/* ---------- CORNER INFO PANEL ---------- */
/* The credit for the definitions, folded away behind an (i) in the copyright
   corner. The cell is anchored to the bottom of its grid track, so the panel
   opening makes the plate grow upward into the page rather than pushing the
   copyright line off the bottom of the window. */
.grid-info-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.grid-info-toggle {
    display: flex;
    background: none;
    border: none;
    color: var(--fg);
    line-height: 1;
    padding: 0;
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.2s ease;
    pointer-events: all;
}

.grid-info-toggle:hover,
.grid-info-toggle:focus-visible,
.grid-info-toggle.is-open {
    opacity: 1;
}

.grid-info-icon {
    width: 14px;
    height: 14px;
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
}

/* Collapsed to nothing in both directions — a panel that kept its width while
   closed would hold the glass plate open at the width of copy nobody can see.
   Also hidden outright, so the link inside is only reachable once it is open.
   GSAP drives width, height, opacity and visibility together. */
.grid-info-panel {
    position: relative;
    width: 0;
    height: 0;
    opacity: 0;
    visibility: hidden;
    overflow: hidden;
}

/* Out of flow, so the copy is laid out once at its full width and then
   revealed by the panel opening around it. In flow it would re-wrap on every
   frame of the tween, and the words would crawl. */
.grid-info-text {
    position: absolute;
    top: 0;
    right: 0;
    width: 250px;
    text-align: right;
    font-size: 11px;
    font-weight: 300;
    letter-spacing: 0.06em;
    line-height: 1.5;
    color: var(--fg);
    opacity: 0.7;
    /* Read as the gap above the copyright line; counted into the height the
       panel opens to, since an absolute child cannot push the panel taller */
    padding-bottom: 8px;
}

.grid-info-link {
    color: var(--fg);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.site-nav {
    position: fixed;
    top: 50%;
    left: var(--grid-pad);
    transform: translateY(-50%);
    width: 124px;
    z-index: 120;
    display: flex;
    flex-direction: column;
    gap: 10px;
    perspective: 900px;
    pointer-events: auto;
}

.nav-tile {
    display: flex;
    align-items: flex-end;
    min-height: 62px;
    padding: 12px 14px;
    color: var(--fg);
    text-decoration: none;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.nav-tile:hover,
.nav-tile:focus-visible {
    opacity: 1;
    background-color: color-mix(in srgb, currentColor 14%, transparent);
    border-color: color-mix(in srgb, currentColor 48%, transparent);
}

.nav-tile-label {
    font-size: 12px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    line-height: 1.2;
}

.gallery-img {
    flex: 0 0 auto;
    height: 100vh;
    overflow: hidden;
}

.gallery-img img {
    height: 100%;
    width: auto;
    object-fit: cover;
    min-width: 300px;
}

.brand-mark {
    top: var(--grid-pad);
    left: var(--grid-pad);
    width: 76px;
    height: 76px;
    padding: 0;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    opacity: 1;
    pointer-events: all;
    z-index: 130;
}

.site-grid {
    opacity: 1;
}
.menu-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: none;
    z-index: 150;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
}

.menu-overlay.is-open {
    visibility: visible;
}

.menu-cell-top-left {
    grid-column: 1 / -1;
    grid-row: 1;
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 20px;
    padding-left: 80px;
    opacity: 0;
}

.menu-cell-content {
    grid-column: 1;
    grid-row: 2;
    overflow-y: auto;
    padding-right: 40px;
    padding-top: 0;
    opacity: 0;
    display: flex;
}

.menu-cell-reserve {
    grid-column: 2;
    grid-row: 2;
    display: grid;
    grid-template-rows: 50vh auto;
    padding-left: 16px;
    opacity: 0;
}

.menu-cell-bottom-nav {
    grid-column: 1 / -1;
    grid-row: 3;
    display: flex;
    align-items: center;
    gap: 20px;
    padding-top: 16px;
    opacity: 0;
}

.menu-reserve-link {
    font-size: clamp(24px, 3vw, 36px);
    color: var(--fg);
    opacity: 1;
    text-decoration: none;
    display: block;
    padding: 5px 0;
}

.reserve-cursor {
    position: fixed;
    top: 0;
    left: 0;
    width: 120px;
    height: 120px;
    border: 1px solid var(--fg);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 9999;
    opacity: 0;
    transform: translate(-110%, -110%);
    border-radius: 50%;
    transition: opacity 0.2s ease;
    background: var(--bg);
}

.reserve-cursor.is-visible {
    opacity: 1;
}

.reserve-cursor-label {
    font-family: inherit;
    font-size: 9px;
    font-weight: 300;
    letter-spacing: 0.2em;
    color: var(--fg);
    text-transform: uppercase;
    text-align: center;
    line-height: 1.4;
}

.menu-tab-btn {
    background: none;
    border: none;
    color: transparent;
    -webkit-text-stroke: 1px var(--fg);
    text-stroke: 1px var(--fg);
    font-family: var(--font-display);
    font-size: clamp(32px, 8vw, 90px);
    font-weight: 300;
    cursor: pointer;
    opacity: 0.4;
    padding: 0;
}

.menu-tab-btn.is-active {
    color: var(--fg);
    -webkit-text-stroke: 0px transparent;
    text-stroke: 0px transparent;
    opacity: 1;
}

/* Tab panels */
.menu-tab-panel {
    display: none;
    opacity: 0;
}

.menu-tab-panel.is-active {
    display: block;
}

/* Sub-tab layout within each main panel */
.panel-subtab-layout {
    display: grid;
    grid-template-columns: 180px 1fr;
    gap: 0 40px;
    height: 100%;
}

.panel-subtab-btn {
    background: none;
    border: none;
    color: var(--fg);
    font-family: inherit;
    font-size: clamp(14px, 2vw, 18px);
    font-weight: 300;
    text-align: left;
    cursor: pointer;
    opacity: 0.3;
    letter-spacing: -.01em;
    padding: 5px 0;
}

.panel-subtab-btn.is-active {
    opacity: 1;
}

.panel-subtab-btn.is-active::after {
    content: " —";
    opacity: 0.5;
}

.panel-subtab-pane {
    display: none;
    opacity: 0;
}

.panel-subtab-pane.is-active {
    display: block;
    opacity: 1;
}

/* ---------- DEFINITION (hero overlay) ---------- */
.definition-phonetic {
    opacity: 0;
    transform: translateY(20px);
    /* Single grid cell everything shares, so the logos stack for the crossfade
       while the container still sizes itself to their natural height */
    display: grid;
    align-items: center;
    /* Containing block for the rotate prompt */
    position: relative;
    /* The inlined wordmark's intrinsic width is 715px, which would overflow a
       phone; cap it and let it shrink from there */
    width: min(600px, 100%);
}

.definition-logo {
    grid-area: 1 / 1;
    width: 100%;
    height: auto;
    display: block;
    opacity: 0;
    will-change: opacity;
    /* The overlay is pointer-events: none, so only the visible logo opts back in */
    pointer-events: none;
}

.definition-logo.is-active {
    opacity: 1;
    pointer-events: auto;
}

/* Inlined logo art: shapes carry no fill of their own, so the theme drives them */
svg.definition-logo {
    color: var(--fg);
}

/* ---------- INTRO REELS ---------- */
/* While the site loads, the KEY is replaced by three reels of Roma glyphs
   counting up. The real letters are held back until the reels land on them.

   The two o's carry no transform rule of their own on purpose: main.js turns
   them through GSAP's svgOrigin, which bakes the centre into a matrix in the
   SVG's own user space. A transform-box of fill-box here would re-anchor that
   matrix to each path's bbox corner and throw both o's off the canvas. */

.definition-phonetic.is-loading .logo-key-letter {
    opacity: 0;
}

/* Stacked in the same grid cell as the wordmark, so it inherits the exact box
   the viewBox is mapped into and its user units line up with the letters' */
.logo-reels {
    grid-area: 1 / 1;
    width: 100%;
    height: auto;
    display: block;
    pointer-events: none;
    color: var(--fg);
}

.logo-reels path,
.logo-reels polygon,
.logo-reels text {
    fill: currentColor;
}

.logo-reels text {
    font-family: var(--font-display);
    text-anchor: middle;
}

svg.definition-logo path,
svg.definition-logo polygon {
    fill: currentColor;
    transition: fill var(--theme-fade);
}

/* ---------- DIMENSIONAL WORDMARK HANDOVER ---------- */
/* The flat wordmark drains its colour away as an extruded copy fades up in
   the same spot. Both sides are deliberately slow: the swap should read as
   one object gaining depth, not as two logos trading places.

   The transition is gated on .has-3d, which scene.js only adds once the glass
   copy exists — otherwise it would fight the logo slider, which drives this
   same opacity from GSAP frame by frame.

   The glass itself needs no rule here: it lives in the sky canvas, and
   scene.js simply shows the mesh at handover. */
.definition-phonetic.has-3d svg.definition-logo {
    transition: opacity 1.8s ease, filter 1.8s ease;
}

body.is-dimensional .definition-phonetic svg.definition-logo {
    opacity: 0;
    filter: saturate(0);
    pointer-events: none;
}

/* ---------- LETTER HOVER ---------- */
.logo-letter {
    transform-box: fill-box;
    transform-origin: 50% 50%;
    transition: opacity 0.35s ease, transform 0.4s cubic-bezier(.2, .7, .3, 1);
}

/* Everything recedes, the hovered letter comes forward */
svg.definition-logo.has-hover .logo-letter {
    opacity: 0.18;
}

svg.definition-logo.has-hover .logo-letter.is-hovered {
    opacity: 1;
    transform: scale(1.14);
}

/* ---------- LETTER NOTE ---------- */
.letter-note {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 300;
    max-width: 300px;
    font-family: var(--font-display);
    font-size: clamp(16px, 1.5vw, 21px);
    line-height: 1.3;
    letter-spacing: 0.01em;
    color: var(--fg);
    text-align: left;
    text-wrap: balance;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    /* JS writes translate() + the tilt; opacity alone is transitioned so the
       note never visibly slides between letters */
    transition: opacity 0.35s ease, visibility 0s linear 0.35s;
    will-change: transform;
}

.letter-note.is-visible {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.35s ease, visibility 0s linear 0s;
}

/* ---------- LETTER SKETCH (bottom-right reference art) ---------- */
.letter-sketch {
    position: fixed;
    right: 10px;
    bottom: 10px;
    z-index: 150;
    width: clamp(130px, 15vw, 220px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.35s ease, visibility 0s linear 0.35s;
}

.letter-sketch.is-visible {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.35s ease, visibility 0s linear 0s;
}

.letter-sketch img {
    width: 100%;
    height: auto;
    display: block;
    /* Source art is black, so it needs inverting on the dark background only */
    filter: invert(1);
    transition: filter var(--theme-fade);
}

body.theme-light .letter-sketch img {
    filter: invert(0);
}

/* ---------- LOGO SLIDER CONTROLS ---------- */
.logo-slider-controls {
    display: flex;
    align-items: center;
    gap: 18px;
    padding-bottom: 4px;
}

.logo-nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: none;
    padding: 6px 2px;
    cursor: pointer;
    color: var(--fg);
    font-family: inherit;
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    opacity: 0.65;
    transition: opacity 0.3s ease;
}

.logo-nav-btn:hover,
.logo-nav-btn:focus-visible {
    opacity: 1;
}

.logo-nav-btn[disabled] {
    opacity: 0.25;
    cursor: default;
}

.logo-slider-count {
    font-size: 11px;
    letter-spacing: 0.14em;
    color: var(--fg);
    opacity: 0.5;
    font-variant-numeric: tabular-nums;
}

/* Logo-only keeps the arrows but collapses their wording. Animating max-width
   as well as opacity lets the arrows draw together instead of leaving a gap. */
.logo-nav-label,
.logo-slider-count {
    display: inline-block;
    max-width: 12em;
    overflow: hidden;
    white-space: nowrap;
    transition: opacity 0.35s ease, max-width 0.45s ease;
}

body.logo-only .logo-nav-label,
body.logo-only .logo-slider-count {
    opacity: 0;
    max-width: 0;
}

/* ---------- PILL SWITCHERS (background + view) ---------- */
/* Both toggles share one look; only their active-state rules differ */
.bg-switcher,
.view-switcher {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: none;
    border: none;
    padding: 6px 2px;
    cursor: pointer;
    color: var(--fg);
    font-family: inherit;
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    white-space: nowrap;
}

.logo_Option_number {
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--fg);
}

.definition-text {
    font-size: clamp(12px, 1.2vw, 16px);
    /* Each logo picks its own voice via data-text-font; serif is the default */
    font-family: var(--font-sans);
    letter-spacing: 0.08em;
    max-width: 800px;
    color: var(--fg);
    /* Reserve the tallest copy's height up front. The overlay is a centred
       column, so a change in line count here would otherwise shove the logo. */
    min-height: 4.8em;
    margin-top: 24px;
}

.definition-text.is-sans {
    font-family: var(--font-sans);
}

.definition-hint {
    font-family: var(--font-sans);
    font-size: clamp(16px, 1.4vw, 20px);
    letter-spacing: 0.02em;
    color: var(--fg);
    opacity: 0;
    /* Always occupies its line so toggling it never moves the logo */
    visibility: hidden;
}

/* ---------- GSAP initial states ---------- */
.hero-definition-overlay .definition-text {
    opacity: 0;
}

/* ---------- INDEX LANDING: WEBSITES VIEW ---------- */
/* Scoped to .is-index so it never touches counter.html / okeyo.html, which
   still run the original Logo Only <-> Everything toggle */
body.is-index .hero-definition-overlay {
    transition: opacity 0.5s ease, visibility 0s linear 0s;
}

body.is-index.showing-websites .hero-definition-overlay {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}

/* Design Hierarchy — clicking the visual grows it, moves it toward the left
   and swaps in the numbered wireframe, with a text panel filling the space
   that opens up beside it. The centred flex row does the "move left" for
   free: while the detail panel is collapsed the row's only real content is
   the image, so justify-content: center reads as the image being centred;
   once the detail panel gains width, centring the combined row leaves the
   image sitting left of centre. */
.website-hierarchy {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0;
    width: 100%;
    /* Fades in after the principles row has grown in above it */
    opacity: 0;
    transition: opacity 0.5s ease;
}

body.is-index.showing-websites .website-hierarchy {
    opacity: 1;
    transition: opacity 0.5s ease 0.45s;
}

.website-hierarchy.is-expanded {
    gap: 48px;
    align-items: center;
}

.website-visual-image {
    display: block;
    width: 100%;
    max-width: 900px;
    height: auto;
}

/* Stepper: only the active section renders */
.website-hierarchy-section {
    display: none;
}

.website-hierarchy-section.is-active {
    display: block;
}

.hierarchy-nav-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: var(--fg);
    opacity: 0.6;
    transition: opacity 0.3s ease;
}

.hierarchy-nav-arrow:hover,
.hierarchy-nav-arrow:focus-visible {
    opacity: 1;
}

.hierarchy-nav-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 1px solid transparent;
    border-radius: 50%;
    background: none;
    font-family: var(--font-display);
    font-size: 14px;
    color: var(--fg);
    opacity: 0.5;
    cursor: pointer;
    transition: opacity 0.3s ease, border-color 0.3s ease;
}

.hierarchy-nav-number:hover {
    opacity: 0.85;
}

.hierarchy-nav-number.is-active {
    opacity: 1;
    border-color: var(--fg);
}

/* Sat on .main-content until the definition clouds moved in alongside the
   hero. A blend mode applies to the element as a group, so descendants cannot
   opt back out of it — and darkening --fg against the sky leaves the copy with
   nothing to read as. The hero is what wanted the blend, so it carries it. */
.section-hero {
    mix-blend-mode: darken;
}

.definition-cloud-layer {
    position: fixed;
    inset: 0;
    pointer-events: none;
}

.definition-cloud {
    position: absolute;
    width: min(clamp(300px, 40vw, 500px), 84vw);
    padding: clamp(20px, 2.8vh, 38px) clamp(24px, 2.4vw, 42px);
    text-align: left;
    opacity: 0;
    will-change: transform, opacity, filter;
}

.definition-cloud::before {
    content: "";
    position: absolute;
    inset: -6%;
    z-index: -1;
    background:
        radial-gradient(34% 34% at 26% 38%,
            color-mix(in srgb, var(--bg) 92%, transparent) 0%,
            color-mix(in srgb, var(--bg) 55%, transparent) 58%,
            transparent 100%),
        radial-gradient(32% 32% at 74% 44%,
            color-mix(in srgb, var(--bg) 90%, transparent) 0%,
            color-mix(in srgb, var(--bg) 52%, transparent) 58%,
            transparent 100%),
        radial-gradient(28% 30% at 46% 22%,
            color-mix(in srgb, var(--bg) 88%, transparent) 0%,
            color-mix(in srgb, var(--bg) 50%, transparent) 60%,
            transparent 100%),
        radial-gradient(30% 30% at 36% 72%,
            color-mix(in srgb, var(--bg) 86%, transparent) 0%,
            color-mix(in srgb, var(--bg) 48%, transparent) 60%,
            transparent 100%),
        radial-gradient(28% 28% at 66% 74%,
            color-mix(in srgb, var(--bg) 86%, transparent) 0%,
            color-mix(in srgb, var(--bg) 48%, transparent) 60%,
            transparent 100%),
        radial-gradient(48% 46% at 50% 50%,
            color-mix(in srgb, var(--bg) 95%, transparent) 0%,
            color-mix(in srgb, var(--bg) 66%, transparent) 54%,
            transparent 100%);
    filter: blur(22px);
}

.definition-cloud-title {
    font-family: var(--font-display);
    font-size: clamp(18px, 1.5vw, 24px);
    line-height: 1.05;
    letter-spacing: 0.01em;
    color: var(--fg);
    overflow-wrap: anywhere;
}

.definition-cloud-body {
    font-family: var(--font-text);
    font-size: clamp(13px, 1.15vw, 16px);
    letter-spacing: 0.08em;
    line-height: 1.55;
    color: var(--fg);
    opacity: 0.82;
    margin-top: 10px;
}


/* ---------- SECTION TRANSITION (word scroll) ---------- */
/* The definition that plays between the wordmark and a panel. Each word sits
   in a mask of its own so it can travel out from behind its own line rather
   than sliding across the one above it — that masking is what reads as the
   copy being scrolled through rather than simply faded. */
.section-transition {
    position: fixed;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    padding: 40px;
    text-align: center;
    pointer-events: none;
    visibility: hidden;
}

.section-transition.is-live {
    visibility: visible;
}

.transition-title {
    font-family: var(--font-sans);
    font-size: clamp(34px, 6vw, 84px);
    line-height: 1;
    letter-spacing: 0.01em;
    color: var(--fg);
    max-width: 14ch;
}

.transition-body {
    font-family: var(--font-text);
    font-size: clamp(15px, 1.8vw, 24px);
    line-height: 1.5;
    letter-spacing: 0.06em;
    color: var(--fg);
    opacity: 0.86;
    max-width: 26ch;
}

/* A wrapping unit and nothing else — no mask, and nothing to slide out from
   behind. The word is held together so a line still breaks between words
   rather than mid-word, while the sweep inside it runs character by
   character. */
.t-word {
    display: inline-block;
    white-space: pre;
}

/* inline-block so the per-character filter has a box of its own to render
   into. Kerning is lost either way once the text is split into elements, so
   there is nothing to be gained by leaving these inline. */
.t-char {
    display: inline-block;
    will-change: opacity, filter;
}

/* ---------- SECTION PANELS ---------- */
.section-stage {
    position: fixed;
    inset: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(6px, 1.3vh, 16px) clamp(6px, 1.3vw, 16px);
    pointer-events: none;
}

.section-stage.is-open {
    pointer-events: auto;
}

/* Sized to the panel so the close button has a corner to sit on. Panels are
   absolute inside it, which also stops a taller one shifting the shorter one
   when a section is swapped. */
.section-frame {
    position: relative;
    width: min(874px, 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    /* Breathing room inside the shape's safe rectangle. The safe rectangle
       itself arrives as --quad-* from sections.js. */
    --panel-pad: clamp(8px, 1vw, 14px);
}

/* The plate's edge, drawn out here rather than on the panel: a border on the
   panel is clipped along with everything else, so it traces the box and not
   the shape. Stretched to the frame, which is exactly the panel's box. */
.panel-edge {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    pointer-events: none;
    opacity: 0;
    color: var(--fg);
}

.panel-edge polygon {
    fill: none;
    stroke: currentColor;
    stroke-opacity: 0.45;
    stroke-width: 1;
    /* The viewBox is stretched to the panel, so the stroke has to opt out of
       being stretched with it or it thickens on one axis */
    vector-effect: non-scaling-stroke;
}

/* A heavier glass than .glass gives. That one is tuned for the small chrome
   panes, where 7.5px is plenty; across a plate this size the sky reads
   straight through it and takes the copy with it. The tint is mixed out of
   --bg rather than currentColor so the plate darkens behind the type instead
   of staining it.

   Border, radius and shadow are all dropped: the panel is clipped to a
   quadrilateral, and every one of them is drawn on the rectangular box and
   then clipped, so they either trace the wrong outline or disappear. The
   .panel-edge polygon above draws the real one. */
.section-panel.glass {
    -webkit-backdrop-filter: blur(22px) saturate(140%);
    backdrop-filter: blur(22px) saturate(140%);
    background-color: color-mix(in srgb, var(--bg) 62%, transparent);
    border: none;
    border-radius: 0;
    box-shadow: none;
}

.section-panel {
    position: relative;
    width: 100%;
    max-height: min(87vh, 828px);
    /* No padding of its own — the shape's safe rectangle sets the inset, and
       .section-panel-inner takes it as a margin */
    padding: 0;
    /* The shard copies are absolutely placed against this box, and the panel
       is its own containing block for them */
    overflow: hidden;
}

.section-panel-inner {
    /* Margin rather than padding: it holds the whole box — scrollbar and all
       — inside the quadrilateral, where padding would leave the bar out on
       the panel's edge for the clip to cut through */
    margin: var(--quad-t, 0px) var(--quad-r, 0px) var(--quad-b, 0px) var(--quad-l, 0px);
    padding: var(--panel-pad);
    max-height: calc(min(87vh, 828px) - var(--quad-t, 0px) - var(--quad-b, 0px));
    overflow-y: auto;
    /* Room for the scrollbar so the copy doesn't sit under it */
    padding-right: 12px;
    /* Firefox */
    scrollbar-width: thin;
    scrollbar-color: var(--fg) transparent;
}

/* WebKit reads none of the two properties above, so the same bar again */
.section-panel-inner::-webkit-scrollbar {
    width: 3px;
}

.section-panel-inner::-webkit-scrollbar-track {
    background: transparent;
}

.section-panel-inner::-webkit-scrollbar-thumb {
    background-color: var(--fg);
    border-radius: 3px;
}

.section-panel-title {
    font-family: var(--font-sans);
    font-size: clamp(26px, 3.4vw, 44px);
    line-height: 1;
    letter-spacing: 0.01em;
    color: var(--fg);
    margin-bottom: clamp(16px, 2vw, 26px);
}

.section-panel-body {
    font-family: var(--font-text);
    font-size: clamp(13px, 1.1vw, 15px);
    line-height: 1.65;
    letter-spacing: 0.04em;
    color: var(--fg);
}

.section-panel-body p + p {
    margin-top: 0.9em;
}

.section-note {
    opacity: 0.45;
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-top: 1.4em;
}

/* Sits on the panel's own corner rather than the window's, so it travels
   with the panel at any width */
.section-close {
    position: absolute;
    top: calc(var(--quad-t, 0px) + 4px);
    right: calc(var(--quad-r, 0px) + 4px);
    z-index: 4;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--fg);
    font-family: inherit;
    font-size: 26px;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transform: rotate(45deg);
    transition: opacity 0.2s ease;
    pointer-events: auto;
}

.section-close:hover,
.section-close:focus-visible {
    opacity: 1 !important;
}

/* ---------- MENU LIST ---------- */
.menu-group + .menu-group {
    margin-top: clamp(22px, 3vh, 34px);
}

.menu-group-title {
    font-family: var(--font-text);
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    opacity: 0.55;
    padding-bottom: 8px;
    margin-bottom: 14px;
    border-bottom: 1px solid color-mix(in srgb, currentColor 20%, transparent);
}

.menu-item + .menu-item {
    margin-top: 14px;
}

/* The cost is pushed to the far edge and the name takes what is left, so a
   long drink name wraps instead of colliding with the number */
.menu-item-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
}

.menu-item-name {
    font-family: var(--font-sans);
    font-size: clamp(15px, 1.4vw, 19px);
    letter-spacing: 0.01em;
}

.menu-item-cost {
    flex: none;
    font-family: var(--font-text);
    font-size: 13px;
    letter-spacing: 0.06em;
    opacity: 0.7;
}

.menu-item-desc {
    opacity: 0.7;
    margin-top: 3px;
    max-width: 52ch;
}

/* ---------- FAQ + CONTACT ---------- */
.faq-list dt {
    font-family: var(--font-sans);
    font-size: clamp(14px, 1.3vw, 17px);
    letter-spacing: 0.01em;
    margin-top: 20px;
}

.faq-list dt:first-child {
    margin-top: 0;
}

.faq-list dd {
    opacity: 0.72;
    margin-top: 5px;
    max-width: 58ch;
}

.contact-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.contact-label {
    display: block;
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    opacity: 0.45;
    margin-bottom: 4px;
}

.contact-list a {
    color: var(--fg);
    text-decoration: underline;
    text-underline-offset: 3px;
    font-size: clamp(14px, 1.3vw, 17px);
    line-height: 1.4;
}

.contact-social {
    display: flex;
    gap: 18px;
}

/* ---------- NAV TILE CRACK ---------- */
/* Drawn over the tile while its section is up. Stretched to the tile rather
   than fitted, so the break runs to every edge whatever shape the tile is. */
.tile-crack {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    overflow: visible;
    color: var(--fg);
}

.tile-crack polygon {
    fill: currentColor;
    stroke: currentColor;
    /* viewBox units, and the box is stretched, so this is nominal — it reads
       as a hairline at every tile size */
    stroke-width: 0.7;
    stroke-opacity: 0.55;
    vector-effect: non-scaling-stroke;
}

/* The tile is the crack's containing block, and the label has to stay on top
   of it rather than under the facets */
.nav-tile {
    position: relative;
}

.nav-tile-label {
    position: relative;
    z-index: 1;
}

/* ---------- NAV ACTIVE STATE ---------- */
.nav-tile.is-active {
    background-color: color-mix(in srgb, currentColor 18%, transparent);
    border-color: color-mix(in srgb, currentColor 55%, transparent);
}

/* ---------- NAVIGATION MODE TOGGLE ---------- */
/* Meander or Direct, in the copyright corner. The choice is kept in
   localStorage by js/sections.js, so a returning visitor lands on whichever
   they picked last time. */
.nav-mode {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    padding: 0;
    background: none;
    border: none;
    color: var(--fg);
    font-family: inherit;
    line-height: 1;
    cursor: pointer;
    pointer-events: all;
}

.nav-mode-label {
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: 0.35;
    transition: opacity 0.3s ease;
}

/* Whichever side is live reads at full strength; the other steps back */
.nav-mode[aria-checked="false"] .nav-mode-label:first-of-type,
.nav-mode[aria-checked="true"] .nav-mode-label:last-of-type {
    opacity: 1;
}

.nav-mode-track {
    position: relative;
    width: 26px;
    height: 12px;
    flex: none;
    border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
    border-radius: 7px;
    transition: border-color 0.3s ease;
}

.nav-mode-thumb {
    position: absolute;
    top: 1px;
    left: 1px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: currentColor;
    transition: transform 0.35s cubic-bezier(.2, .7, .3, 1);
}

.nav-mode[aria-checked="true"] .nav-mode-thumb {
    transform: translateX(12px);
}

/* Lit only while the offer above it is up, so the copy has something to point
   at. Both are turned on and off together in sections.js. */
.nav-mode.is-hinted .nav-mode-track {
    border-color: currentColor;
    animation: navModePulse 2.4s ease-in-out infinite;
}

@keyframes navModePulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 45%, transparent); }
    50%      { box-shadow: 0 0 0 5px color-mix(in srgb, currentColor 0%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
    .nav-mode.is-hinted .nav-mode-track {
        animation: none;
    }
}

/* ---------- SKIP CTA ---------- */
/* Collapsed rather than merely transparent when it is done with: the corner
   plate sizes itself to its content, and an invisible line of copy would hold
   it open at a height nobody can see. */
.nav-hint {
    display: block;
    max-height: 0;
    padding: 0;
    margin: 0;
    overflow: hidden;
    background: none;
    border: none;
    color: var(--fg);
    font-family: var(--font-text);
    font-size: 11px;
    letter-spacing: 0.06em;
    line-height: 1.4;
    text-align: right;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.45s ease, max-height 0.45s ease, margin-bottom 0.45s ease;
}

.nav-hint.is-live {
    max-height: 3em;
    margin-bottom: 8px;
    opacity: 0.8;
    pointer-events: all;
}

.nav-hint:hover,
.nav-hint:focus-visible {
    opacity: 1;
}

.nav-hint u {
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}
