/* =========================================
   Fluid Root Font-Size System
   (OceanX-style: 1rem = one design unit that
   scales with viewport. All sizing is rem.)
   ========================================= */

html {
  /* Mobile: scales from ~8px (320px) → 14px (538px+) */
  font-size: clamp(8px, 2.6vw, 14px);
  scroll-behavior: smooth;
}

/* Desktop: deliberate reset at layout boundary.
   Scales from 10px (floor) → 14px at ~1647px */
@media (min-width: 1024px) {
  html {
    font-size: clamp(10px, 0.85vw, 14px);
  }
}

/* Large desktop: nudge floor up to 11px */
@media (min-width: 1440px) {
  html {
    font-size: clamp(11px, 0.85vw, 14px);
  }
}

/* 4K: uncap and let it grow, ceiling at 16px */
@media (min-width: 2560px) {
  html {
    font-size: min(0.65vw, 16px);
  }
}

@font-face{
    font-family:'RadioGrotesk';
    /* WOFF2 first (better/cleaner rasterisation on Windows DirectWrite), OTF kept as fallback */
    src:url('./fonts/PPRadioGrotesk-Regular.woff2') format('woff2'),
        url('./fonts/PPRadioGrotesk-Regular.otf') format('opentype');
    font-weight:400;
    font-style:normal;
    font-display: swap;
  }
  @font-face{
    font-family:'RadioGrotesk';
    src:url('./fonts/PPRadioGrotesk-Bold.woff2') format('woff2'),
        url('./fonts/PPRadioGrotesk-Bold.otf') format('opentype');
    font-weight:700;
    font-style:normal;
    font-display: swap;
  }
html,body{height:100%;margin:0; background-color: #000000;}
canvas{display:block}
#ui-toggle{
    display:none; /* Hidden - use keyboard shortcut (` or U) to toggle UI */
  }
  #ui-panel{
    position:fixed; top:48px; left:12px; z-index:30; width:290px; max-height:90vh;
    overflow:auto; background:rgba(0,0,0,0.7); color:#eee; border:1px solid #333;
    border-radius:10px; padding:10px 10px 12px; backdrop-filter: blur(4px);
    font:12px/1.35 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  }
  #ui-panel.hidden{ display:none }
  #ui-panel h3{ margin:8px 0 6px; font-size:12px; font-weight:700; color:#ddd; }
  #ui-panel .row{ display:flex; align-items:center; gap:8px; margin:6px 0 }
  #ui-panel label{ flex:1 1 auto; }
  #ui-panel input[type="range"]{ width:120px; }
  #ui-panel input[type="checkbox"]{ transform: translateY(1px); }
  #ui-panel .val{ width:46px; text-align:right; color:#bbb; font-variant-numeric: tabular-nums; }
  #ui-panel hr{ border:0; border-top:1px solid #333; margin:8px 0 }
  #ui-panel .subtle{ color:#aaa }


/* Navbar / Logo */
#navbar{
    position: fixed;
    top: 2rem;
    left: 2rem;
    right: 2rem;
    z-index: 12;
    display: flex;
    align-items: center;
    justify-content: space-between;
    pointer-events: none;
}

#site-logo{
    width: 2.18rem;
    height: 2.18rem;
    border-radius: 50%;
    background: #5aa0ff; /* default; will be animated via JS */
    pointer-events: auto;
}

#navbar-actions{
    display: flex;
    align-items: center;
    gap: 1.05rem; /* breathing room between Sound and the hamburger */
    pointer-events: none;
}

.audio-btn {
    position: relative;
    z-index: auto;
    min-width: 0;
    height: 2.9rem;
    padding: 0 0.8rem 0 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.85rem;
    border: 1.8px solid transparent;
    border-radius: 999px;
    background: rgba(8, 10, 11, 0);
    color: rgba(255, 255, 255, 0.30);
    font-family: "RadioGrotesk", sans-serif;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.015em;
    text-transform: uppercase;
    cursor: pointer;
    box-sizing: border-box;
    overflow: hidden;
    isolation: isolate;
    pointer-events: auto;
    /* backdrop-filter: blur(10px); */
    -webkit-backdrop-filter: blur(10px);
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease, opacity 0.18s ease, box-shadow 0.18s ease;
}

.audio-btn::before {
    content: "";
    position: absolute;
    inset: 0px;
    border-radius: inherit;
    border: 1.8px solid currentColor;
    background: transparent;
    clip-path: inset(0 100% 0 0 round 999px);
    transition: clip-path 0.32s cubic-bezier(0.22, 1, 0.36, 1), border-color 0.18s ease;
    z-index: 1;
    pointer-events: none;
}

.audio-btn:hover:not([aria-pressed="true"]) {
    color: #FFFFFF;
}

.audio-btn:hover::before {
    clip-path: inset(0 0 0 0 round 999px);
}

.audio-btn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    flex: 0 0 1.85rem;
    pointer-events: none;
    position: relative;
    z-index: 2;
}

.audio-btn__svg {
    width: 100%;
    height: 100%;
    display: block;
}

.audio-btn__ring,
.audio-btn__flat,
.audio-btn__wave {
    fill: none;
    stroke: currentColor;
    stroke-width: 2.1;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.audio-btn__flat {
    opacity: 0.98;
    transition: opacity 0.2s ease;
}

.audio-btn__wave-viewport {
    opacity: 0;
    transition: opacity 0.2s ease;
}

.audio-btn__wave-track {
    transform: translate3d(0, 0, 0);
    will-change: transform;
}

.audio-btn__ring {
    opacity: 1;
}

.audio-btn__label {
    display: inline-block;
    line-height: 1;
    transform: translateY(0px);
    white-space: nowrap;
    position: relative;
    z-index: 2;
}

/* OceanX-style slide animation for audio button label */
.audio-btn__mask {
    position: relative;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    z-index: 2;
}

.audio-btn__word--2 {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    line-height: 1;
    transform: translateY(150%);
    white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
    .audio-btn:hover .audio-btn__word--1 {
        transform: translateY(-150%);
    }

    .audio-btn:hover .audio-btn__word--2 {
        transform: translateY(0);
    }

    .audio-btn__word {
        transition: transform 0.8s cubic-bezier(0.19, 1, 0.22, 1);
        will-change: transform;
    }
}

.audio-btn[aria-pressed="true"] {
    background: transparent;
    border-color: transparent;
    color: rgba(239, 248, 0, 0.96);
    box-shadow: none;
}

.audio-btn[aria-pressed="true"] .audio-btn__mask {
    color: #ffffff;
}

.audio-btn[aria-pressed="true"]::before {
    border-color: var(--audio-btn-accent, #F6FF00);
}

.audio-btn[aria-pressed="true"] .audio-btn__flat {
    opacity: 0;
}

.audio-btn[aria-pressed="true"] .audio-btn__wave-viewport {
    opacity: 1;
}

.audio-btn[aria-pressed="true"] .audio-btn__wave-track {
    animation: audio-btn-wave-slide 1.9s linear infinite;
}

.audio-btn:focus-visible {
    outline: 1px solid rgba(185, 228, 86, 0.78);
    outline-offset: 1px;
}

@keyframes audio-btn-wave-slide {
    from {
        transform: translate3d(0, 0, 0);
    }
    to {
        transform: translate3d(-24px, 0, 0);
    }
}

@media (prefers-reduced-motion: reduce) {
  .audio-btn::before {
    transition: border-color 0.18s ease;
  }

  .audio-btn:hover::before {
    clip-path: none;
  }

  .audio-btn[aria-pressed="true"] .audio-btn__wave-track {
    animation: none;
  }
}

/* Section CTA Button — matches .audio-btn style */
.section-btn {
    position: relative;
    z-index: auto;
    align-self: flex-start;
    min-width: 0;
    height: 2.5rem;
    padding: 0 0.9rem 0 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.8rem;
    border: 1.5px solid #696A6A;
    border-radius: 999px;
    background: rgba(8, 10, 11, 0);
    color: rgba(255, 255, 255, 0.88);
    font-family: "RadioGrotesk", sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.015em;
    text-transform: uppercase;
    cursor: pointer;
    box-sizing: border-box;
    overflow: hidden;
    isolation: isolate;
    -webkit-backdrop-filter: blur(10px);
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease, opacity 0.18s ease, box-shadow 0.18s ease;
}

.section-btn[hidden] {
    display: none;
}

.section-btn::before {
    content: "";
    position: absolute;
    inset: 0px;
    border-radius: inherit;
    border: 1.5px solid currentColor;
    background: transparent;
    clip-path: inset(0 100% 0 0 round 999px);
    transition: clip-path 0.32s cubic-bezier(0.22, 1, 0.36, 1), border-color 0.18s ease;
    z-index: 1;
    pointer-events: none;
}

.section-btn:hover {
    color: #FFFFFF;
    border-color: rgba(255, 255, 255, 0.28);
    background: rgba(22, 24, 26, 0);
}

.section-btn:hover::before {
    clip-path: inset(0 0 0 0 round 999px);
}

.section-btn__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    flex: 0 0 1rem;
    pointer-events: none;
    position: relative;
    z-index: 2;
}

.section-btn__icon svg {
    width: 100%;
    height: 100%;
    display: block;
}

.section-btn__label {
    display: inline-block;
    line-height: 1;
    white-space: nowrap;
    position: relative;
    z-index: 2;
}

/* OceanX-style slide animation for button label */
.section-btn__mask {
    position: relative;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    z-index: 2;
}

.section-btn__word--2 {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    line-height: 1;
    transform: translateY(150%);
    white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
    .section-btn:hover .section-btn__word--1 {
        transform: translateY(-150%);
    }

    .section-btn:hover .section-btn__word--2 {
        transform: translateY(0);
    }

    .section-btn__word {
        transition: transform 1.2s cubic-bezier(0.19, 1, 0.22, 1);
        will-change: transform;
    }
}

.section-btn:focus-visible {
    outline: 1px solid rgba(185, 228, 86, 0.78);
    outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
  .section-btn::before {
    transition: border-color 0.18s ease;
  }

  .section-btn:hover::before {
    clip-path: none;
  }
}

#mobile-menu-button {
    position: fixed;
    top: 3.8rem;
    right: 3.8rem;
    z-index: 12;
    width: 3.4rem;
    height: 3.4rem;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0;
    border: 0;
    background: transparent;
    color: #f2f5f8;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

#mobile-menu-button span {
    width: 2.4rem;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.2s ease, opacity 0.2s ease;
}

#mobile-menu-button[aria-expanded="true"] span:nth-child(1) {
    transform: translateY(8px) rotate(45deg);
}

#mobile-menu-button[aria-expanded="true"] span:nth-child(2) {
    opacity: 0;
}

#mobile-menu-button[aria-expanded="true"] span:nth-child(3) {
    transform: translateY(-8px) rotate(-45deg);
}

/* ---------------- Chapter Menu ---------------- */
#menu-toggle {
    pointer-events: auto;
    position: relative;
    width: 2rem;
    height: 2rem;
    margin-left: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: #f2f5f8;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.42rem;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    outline: none;
}

#menu-toggle:focus,
#menu-toggle:focus-visible {
    outline: none;
}

#menu-toggle span {
    display: block;
    width: 1.8rem;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}

#menu-toggle[aria-expanded="true"] span:nth-child(1) {
    transform: translateY(0.55rem) rotate(45deg);
}

#menu-toggle[aria-expanded="true"] span:nth-child(2) {
    opacity: 0;
}

#menu-toggle[aria-expanded="true"] span:nth-child(3) {
    transform: translateY(-0.55rem) rotate(-45deg);
}

/* Keep the navbar (logo, sound, hamburger) above the menu overlay so it
   stays interactive while the menu is open. */
body.menu-open #navbar {
    z-index: 61;
}

#chapter-menu {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(6, 8, 9, 0.55);
    backdrop-filter: blur(77px);
    -webkit-backdrop-filter: blur(77px);
    display: flex;
    align-items: center;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.65s ease, visibility 0s linear 0.65s;
}

#chapter-menu.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 0.65s ease;
}

/* Subtle dot pattern over the blurred backdrop */
#chapter-menu::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: radial-gradient(rgba(97, 97, 97, 0.043) 1px, transparent 1.4px);
    background-size: 16px 16px;
    background-position: center;
}

#chapter-menu-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    box-sizing: border-box;
    /* Side padding matches the navbar margin (2rem) so the content reaches
       the side margins. The whole block is vertically centred by the parent. */
    padding: 0 2rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    /* Align the heading's top with the top of the chapter list. */
    align-items: start;
}

#chapter-menu-heading {
    font-family: "RadioGrotesk", sans-serif;
    font-weight: 400;
    font-size: clamp(2.6rem, 5vw, 4.6rem);
    line-height: 1.02;
    letter-spacing: -0.01em;
    color: #2a2e2f;
    -webkit-user-select: none;
    user-select: none;
}

#chapter-menu-list {
    display: flex;
    flex-direction: column;
}

/* Mobile-only home for the sound toggle, which main.js moves in here from the
   navbar. Kept out of the grid flow on desktop, where it is empty. */
#chapter-menu-audio {
    display: none;
}

.chapter-item {
    position: relative;
    display: grid;
    grid-template-columns: minmax(6.5rem, auto) 1.6rem 1fr;
    align-items: center;
    gap: clamp(1rem, 2vw, 2rem);
    width: 100%;
    padding: clamp(1rem, 1.6vw, 1.5rem) 0;
    border: 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.09);
    background: transparent;
    text-align: left;
    cursor: pointer;
    font-family: "RadioGrotesk", sans-serif;
    -webkit-tap-highlight-color: transparent;
    transition: opacity 0.3s ease;
}

/* Only dividers between rows: no line above the first or below the last. */
.chapter-item:last-child {
    border-bottom: 0;
}

.chapter-item__num {
    font-size: clamp(1.4rem, 2.4vw, 2.4rem);
    font-weight: 400;
    color: #5a5f60;
    transition: color 0.3s ease;
}

.chapter-item__dot {
    width: 0.62rem;
    height: 0.62rem;
    border-radius: 50%;
    justify-self: center;
    background: var(--menu-accent, #eaff00);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.chapter-item__title {
    font-size: clamp(1.4rem, 2.4vw, 2.4rem);
    font-weight: 400;
    color: #f4f6f7;
    background: linear-gradient(90deg, #FFF 2.36%, #999 99.99%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    transition: color 0.3s ease, opacity 0.3s ease;
}

/* Hover: dim the rest of the list, keep the hovered chapter bright */
@media (hover: hover) and (pointer: fine) {
    #chapter-menu-list:hover .chapter-item { opacity: 0.3; }
    #chapter-menu-list:hover .chapter-item:hover { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    #chapter-menu,
    #menu-toggle span,
    .chapter-item,
    .chapter-item__num,
    .chapter-item__title,
    .chapter-item__dot {
        transition-duration: 0.001s;
    }
}

@media (max-width: 900px) {
    #chapter-menu-inner {
        grid-template-columns: 1fr;
        gap: 2.5rem;
        align-content: center;
    }

    #chapter-menu-heading {
        font-size: clamp(2rem, 8vw, 3rem);
    }

    .chapter-item {
        grid-template-columns: auto 1.2rem 1fr;
        gap: 1rem;
    }
}

/* Loading Screen Styles */
#loading-screen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(180deg, #070809 0%, #080F0F 100%);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 1.4rem;
    z-index: 9999;
    opacity: 1;
    transition: opacity 1s ease-out; /* Customizable fade duration */
  }
  
  #loading-screen.fade-out {
    opacity: 0;
    pointer-events: none;
  }
  
  #loading-screen.hidden {
    display: none;
  }
  
  #loading-circle-container {
    position: relative;
    width: 5.5rem;
    height: 5.5rem;
  }

  #loading-percent {
    font-family: "RadioGrotesk", sans-serif;
    font-size: 0.9rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    color: #f5ff4b;
    opacity: 0.92;
    font-variant-numeric: tabular-nums;
    text-align: center;
    min-width: 64px;
  }
  
  #loading-circle-bg {
    position: absolute;
    width: 5.5rem;
    height: 5.5rem;
    border-radius: 50%;
    background-color: #171C1C;
  }

  #loading-circle-fill {
    position: absolute;
    width: 5.5rem;
    height: 5.5rem;
    border-radius: 50%;
    background-color: #F6FF00;
    clip-path: inset(100% 0 0 0);
    transform-origin: center;
  }



  /* FLOATING TEXT STYLE */

#floating-text {
    position: fixed;
    top: 50%;
    left: 2rem;
    transform: translate(1%, -50%);
    z-index: 5;
    pointer-events: none;
    text-align: left;
    width: min(80vw, 39rem);
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* Intro section layout override - center title only */
#floating-text.intro {
    left: 50%;
    transform: translate(-50%, -90%);
    width: auto;
    max-width: 100vw;
    align-items: center;
    text-align: center;
    pointer-events: none;
}

#floating-text.intro .section-eyebrow,
#floating-text.intro .section-body {
    display: none;
}

#floating-text.intro .section-title {
    text-align: center;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 5.5rem;
    font-style: normal;
    font-weight: 400;
    line-height: 0.975;
    background: linear-gradient(180deg, #FFF 61.69%, rgba(13, 19, 22, 0.00) 91.76%);
    background-clip: text;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

#floating-text.welcome {
    left: 50%;
    transform: translate(-50%, -65%);
    width: min(90vw, 680px);
    max-width: 860px;
    align-items: center;
    text-align: center;
    gap: 1.25rem;
}

#floating-text.welcome .section-body {
    display: none;
}

#floating-text.welcome .section-title {
    text-align: center;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 2.35rem;
    font-style: normal;
    font-weight: 400;
}

#floating-text.welcome .section-body {
    max-width: 60ch;
}

#floating-text.end {
    left: 50%;
    transform: translate(-50%, -60%);
    width: min(90vw, 640px);
    max-width: 780px;
    align-items: center;
    text-align: center;
    gap: 1.2rem;
}

#floating-text.end .section-eyebrow {
    display: none;
}

#floating-text.end .section-title {
    text-align: center;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 2.1rem;
    font-style: normal;
    font-weight: 400;
    line-height: 118%;
    letter-spacing: 0.05rem;
    background: linear-gradient(90deg, #FFFFFF 0%, #8F8F8F 95%);
    background-clip: text;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

#floating-text.end .section-body {
    max-width: 58ch;
}

#floating-text .section-text {
    pointer-events: auto;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

#floating-text .section-eyebrow {
    font-family: "RadioGrotesk", sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.32rem;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.66);
    margin: 0;
}

#floating-text .section-title {
    margin: 0;
    /* Bottom padding (offset by a matching negative margin so layout/spacing is
       unchanged) extends the -webkit-background-clip: text paint box past the
       baseline, so descenders on the last line (g, p, y) aren't clipped. */
    padding-bottom: 0.18em;
    margin-bottom: -0.18em;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 3.25rem;
    font-weight: 400;
    line-height: 115%;
    background: linear-gradient(90deg, #FFF 0%, #858585 100%);
    background-clip: text;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

#floating-text .section-title.is-typing::after {
    content: '|';
    display: inline-block;
    -webkit-text-fill-color: rgba(255, 255, 255, 0.5);
    color: rgba(255, 255, 255, 0.5);
    animation: typewriter-blink 0.7s step-end infinite;
    font-weight: 100;
}

@keyframes typewriter-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0; }
}

#floating-text .section-body {
    margin: 0;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 1.05rem;
    font-weight: 100;
    line-height: 1.6;
    color: rgba(223, 234, 240, 0.94);
    max-width: 38ch;
}

/* Inline "Read More" tag pill — swaps in for the eyebrow when expanded */
#floating-text .section-tag {
    align-self: flex-start;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.92);
    border: 1.5px solid rgba(255, 255, 255, 0.45);
    border-radius: 999px;
    padding: 0.45rem 1rem;
    line-height: 1;
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}

#floating-text .section-tag[hidden] {
    display: none;
}

/* Inline detail: extra body text revealed underneath the title */
#floating-text .section-detail {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 0.55s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.45s ease;
    will-change: grid-template-rows;
}

#floating-text .section-detail[hidden] {
    display: none;
}

#floating-text.is-expanded .section-detail {
    grid-template-rows: 1fr;
    opacity: 1;
}

/* The collapsing wrapper must clip its overflow for the grid trick to work */
#floating-text .section-detail__inner {
    overflow: hidden;
    min-height: 0;
    /* Mirror the divider's 1.4rem gap above the body. The flex `gap` (0.75rem) on
       .section-text already sits between the detail and the button, so add the
       remainder here to make body→button match divider→body. */
    padding-bottom: 0.65rem;
}

#floating-text .section-detail__divider {
    border: 0;
    border-top: 1px solid rgba(214, 223, 230, 0.32);
    margin: 0 0 1.4rem;
}

#floating-text .section-detail__body {
    font-family: "RadioGrotesk", sans-serif;
    font-size: 1.1rem;
    font-weight: 100;
    line-height: 1.6;
    letter-spacing: 0.16px;
    background: linear-gradient(90deg, #FFF 0%, #CBCBCB 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: #CBCBCB; /* fallback */
    max-width: 100%;
    max-height: min(42vh, 30rem);
    overflow-y: auto;
    padding-right: 0.4rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

#floating-text .section-detail__body::-webkit-scrollbar {
    width: 3px;
}

#floating-text .section-detail__body::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 2px;
}

#floating-text .section-detail__body p {
    margin: 0;
}

#floating-text .section-detail__body p + p {
    margin-top: 1.1em;
}

@media (prefers-reduced-motion: reduce) {
    #floating-text .section-detail {
        transition: opacity 0.2s ease;
    }
}

/* ── Read More overlay panel ──────────────────────────────────────────────
   A self-contained panel that slides in from the left and sits OVER the top
   of the scene. The section text/visual behind it is never touched, so there
   is no reflow. Two parts: an image header with the title inside, and a
   solid-colour body section below. */
:root {
    --read-panel-w: clamp(31rem, 42vw, 44rem);
    --panel-accent: #5E96FF;
    --panel-body-bg: #0A1117;
}

#read-panel-bg {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--read-panel-w);
    max-width: 92vw;
    /* Below the navbar (z-index 12) so the logo / sound / menu stay on top,
       but above the floating text (z-index 5) and the canvas. */
    z-index: 9;
    pointer-events: none;
    background: var(--panel-body-bg);
    transform: translateX(calc(-100% - 24px));
    transition: transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1);
    will-change: transform;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

#read-panel-bg.is-open {
    transform: translateX(0);
    pointer-events: auto;
}

/* Image header — the title sits inside, anchored to the bottom of the image */
.read-panel__media {
    position: relative;
    flex: 0 0 auto;
    box-sizing: border-box;
    min-height: 42%;
    padding: 6rem 2.5rem 2.5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    background: linear-gradient(155deg, #2E4965 0%, #1B3149 46%, #0A1320 100%);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

.read-panel__title {
    margin: 0;
    font-family: "RadioGrotesk", sans-serif;
    font-size: clamp(2rem, 2.7vw, 2.85rem);
    font-weight: 400;
    line-height: 1.15;
    text-transform: uppercase;
    word-spacing: 0.35em;
    color: var(--panel-accent);
    display: flex;
    flex-direction: column;
}

/* Title segments split on a blank line: top reads left, bottom reads right. */
.read-panel__title-seg {
    display: block;
    white-space: pre-line;
    text-align: left;
}

.read-panel__title-seg--end {
    text-align: right;
    margin-top: 1.1em;
}

/* Body section — solid configurable background, scrolls if copy overflows */
.read-panel__content {
    flex: 1 1 auto;
    box-sizing: border-box;
    padding: 4rem 2.5rem 3rem;
    background: var(--panel-body-bg);
    /* Pull up 1px so the solid body covers any sub-pixel seam between the
       grainy image header and this block (otherwise a faint hairline shows). */
    position: relative;
    margin-top: -1px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

.read-panel__content::-webkit-scrollbar { width: 3px; }
.read-panel__content::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 2px;
}

.read-panel__body {
    font-family: Helvetica, Arial, sans-serif;
    font-size: 1.2rem;
    font-weight: 300;
    line-height: 1.32;
    letter-spacing: 0.01em;
    color: #D3D3D3;
}

.read-panel__body p { margin: 0; }
.read-panel__body p + p { margin-top: 1.32em; }

.read-panel__sources { margin-top: 1.32em; }
.read-panel__sources[hidden] { display: none; }

.read-panel__sources-label {
    display: block;
    font-family: Helvetica, Arial, sans-serif;
    font-size: 1.02rem;
    font-weight: 400;
    letter-spacing: 0.01em;
    color: #DEE5EC;
    margin-bottom: 0.55rem;
}

.read-panel__sources-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.read-panel__sources-list a {
    font-family: "RadioGrotesk", sans-serif;
    font-size: 0.88rem;
    font-weight: 100;
    line-height: 1.4;
    color: var(--panel-accent);
    text-decoration: none;
    border-bottom: 1px solid color-mix(in srgb, var(--panel-accent) 40%, transparent);
    padding-bottom: 1px;
    width: fit-content;
    transition: border-color 0.2s ease, opacity 0.2s ease;
}

.read-panel__sources-list a:hover {
    border-bottom-color: var(--panel-accent);
    opacity: 0.85;
}

/* Read Less = the Read More button, restyled to the Figma spec: 2px section-
   coloured border, dark translucent fill, white bold label, coloured dot. */
.read-panel__close {
    position: absolute;
    /* Vertically centred on the navbar row (navbar: top 2rem, ~2.9rem tall) */
    top: 2.2rem;
    right: 1.75rem;
    z-index: 3;
    align-self: auto;
    border-width: 2.428px;
    border-style: solid;
    border-color: color-mix(in srgb, var(--panel-accent) 40%, transparent);
    background: rgba(0, 0, 0, 0.3);
    color: #FFFFFF;
    font-weight: 700;
}

.read-panel__close .section-btn__icon {
    color: var(--panel-accent);
}

.read-panel__close:hover {
    color: #FFFFFF;
    border-color: transparent;
    background: rgba(0, 0, 0, 0.42);
}

/* Keep the sliding fill ring on the accent colour even though the label
   (driven by `color`) stays white. */
.read-panel__close:hover::before {
    border-color: var(--panel-accent);
}

#scroll-indicator {
    position: fixed;
    left: 50%;
    bottom: 5.2rem;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.4rem;
    font-family: "RadioGrotesk", sans-serif;
    font-size: 0.72rem;
    letter-spacing: 0.32rem;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.6);
    opacity: 0;
    pointer-events: none;
    z-index: 4;
    transition: opacity 0.35s ease, transform 0.35s ease;
}

.scroll-indicator__label {
    display: inline-block;
    padding-left: 0.48rem;
}

.scroll-indicator__line {
    width: 1px;
    height: 4.2rem;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0) 100%);
    transform-origin: top;
    transform: scaleY(0.7);
    opacity: 0.3;
    transition: opacity 0.35s ease, transform 0.35s ease;
}

#floating-text.welcome + #scroll-indicator {
    opacity: 0.8;
    transform: translate(-50%, -8px);
}

#floating-text.welcome + #scroll-indicator .scroll-indicator__line {
    transform: scaleY(1);
    opacity: 0.8;
}

#section-progress-nav {
    position: fixed;
    right: 2rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 9;
    width: 2px;
    height: 30rem;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.section-progress__track {
    display: none;
}

.section-progress__fill {
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.95);
    transform-origin: top center;
    transform: scaleY(0);
    transition: transform 0.2s ease;
}

.section-progress__markers {
    --section-progress-step: 0.25rem;
    position: relative;
    width: 100%;
    height: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: calc(var(--section-progress-step) * 2.5);
    pointer-events: none;
    z-index: 1;
}

.section-progress__marker {
    position: relative;
    width: 6px;
    height: 6px;
    border: 0;
    border-radius: 50%;
    background: #dcdcdc74;
    transition: background-color 0.25s ease;
}

.section-progress__marker::after {
    content: '';
    position: absolute;
    inset: -4px;
    border: 1px solid transparent;
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.25s ease, border-color 0.25s ease;
}

.section-progress__marker.is-active {
    background: #f5ff4b;
}

/* .section-progress__marker.is-active::after {
    border-color: #f5ff4b;
    opacity: 1;
} */

.section-progress-observer-root {
    position: fixed;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 120px;
    overflow-y: auto;
    opacity: 0;
    pointer-events: none;
}

.section-progress-observer-sentinel {
    width: 1px;
    height: 120px;
}


.closer-to-home .title {
    font-size: 14px;
    color: #ffa84d;
}

/* Gradient overlay for section text legibility */
.section-gradient-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 50vw;
    height: 100vh;
    pointer-events: none;
    z-index: 2;
    opacity: 1;
    transition: opacity 0.4s ease;
    /* Base colour of the text-legibility gradient, as an "r, g, b" triplet so the
       stops below can vary alpha. Driven per section from JS (--overlay-rgb), and
       cross-faded in lockstep with the background blend. Defaults to #090F13.
       --overlay-alpha is a global opacity multiplier (1 = as authored, 0 = invisible),
       so a section colour ending in 00 (e.g. #09091300) makes the overlay transparent. */
    --overlay-rgb: 9, 15, 19;
    --overlay-alpha: 1;
}

.section-gradient-overlay::before {
    content: '';
    position: absolute;
    inset: 0;
    /* Colour -> transparent fade on an ease-out (smoothstep) alpha curve rather
       than a few linear stops. A linear ramp reaches 0 with an abrupt slope change
       that the eye reads as a line (Mach banding); easing the tail so alpha
       approaches 0 with near-zero slope removes it. Many stops also minimise 8-bit
       banding (the DOM overlay is not covered by the WebGL dither pass). */
    background: linear-gradient(90deg,
        rgba(var(--overlay-rgb), calc(1.000 * var(--overlay-alpha))) 0%,
        rgba(var(--overlay-rgb), calc(0.939 * var(--overlay-alpha))) 11%,
        rgba(var(--overlay-rgb), calc(0.784 * var(--overlay-alpha))) 22%,
        rgba(var(--overlay-rgb), calc(0.575 * var(--overlay-alpha))) 32%,
        rgba(var(--overlay-rgb), calc(0.352 * var(--overlay-alpha))) 43%,
        rgba(var(--overlay-rgb), calc(0.156 * var(--overlay-alpha))) 54%,
        rgba(var(--overlay-rgb), calc(0.061 * var(--overlay-alpha))) 61%,
        rgba(var(--overlay-rgb), calc(0.014 * var(--overlay-alpha))) 67%,
        rgba(var(--overlay-rgb), calc(0.000 * var(--overlay-alpha))) 72%
    );
    transform: translateZ(0);
}

.section-gradient-overlay::after {
    content: '';
    position: absolute;
    inset: 0;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    /* Ease-out mask so the blurred backdrop dissolves into the raw backdrop with a
       gentle slope instead of a hard edge. A masked backdrop-filter shows a seam
       wherever its opacity changes faster than the blur radius can hide; the long
       low-alpha tail spreads that transition out below perception. */
    mask-image: linear-gradient(90deg,
        rgba(0, 0, 0, 1.000) 0%,
        rgba(0, 0, 0, 0.896) 12%,
        rgba(0, 0, 0, 0.648) 23%,
        rgba(0, 0, 0, 0.425) 32%,
        rgba(0, 0, 0, 0.216) 41%,
        rgba(0, 0, 0, 0.061) 49%,
        rgba(0, 0, 0, 0.014) 54%,
        rgba(0, 0, 0, 0.000) 58%
    );
    -webkit-mask-image: linear-gradient(90deg,
        rgba(0, 0, 0, 1.000) 0%,
        rgba(0, 0, 0, 0.896) 12%,
        rgba(0, 0, 0, 0.648) 23%,
        rgba(0, 0, 0, 0.425) 32%,
        rgba(0, 0, 0, 0.216) 41%,
        rgba(0, 0, 0, 0.061) 49%,
        rgba(0, 0, 0, 0.014) 54%,
        rgba(0, 0, 0, 0.000) 58%
    );
    transform: translateZ(0);
}

.section-gradient-overlay.hidden {
    opacity: 0;
}

/* "Hide UI" mode (toggle with the H key): clears every piece of chrome so only the
   3D scene is visible — useful for clean viewing or screenshots. !important so it
   overrides per-element opacity set inline by GSAP/section transitions. */
body.chrome-hidden #navbar,
body.chrome-hidden #floating-text,
body.chrome-hidden #scroll-indicator,
body.chrome-hidden #section-progress-nav,
body.chrome-hidden #ui-panel,
body.chrome-hidden #ui-toggle,
body.chrome-hidden #mobile-menu-button,
body.chrome-hidden #chapter-menu {
    opacity: 0 !important;
    pointer-events: none !important;
}

@media (max-width: 768px) {
  /* Nav */
  #navbar {
    top: calc(1.6rem + env(safe-area-inset-top));
    left: 1.6rem;
    right: 1.6rem;
  }

  #site-logo {
    width: 2.4rem;
    height: 2.4rem;
  }

  #menu-toggle {
    margin-left: 0.8rem;
  }

  /* Sound lives in the chapter menu on mobile, under the heading. */
  #chapter-menu-audio {
    display: flex;
    grid-column: 1;
    align-items: center;
  }

  /* Dev controls hamburger is replaced by the chapter menu on mobile;
     the dev panel remains available via the ` / U keyboard shortcut. */
  #mobile-menu-button {
    display: none;
  }

  /* Dev panel */
  #ui-panel {
    top: calc(5.8rem + env(safe-area-inset-top));
    left: 1.2rem;
    width: min(88vw, 36rem);
    max-height: min(72vh, 56rem);
    z-index: 14;
  }

  /* Regular sections become a bottom strip. The centred screens (intro, welcome,
     end) are deliberately excluded from every rule in this group: they keep their
     desktop treatment on mobile — horizontally centred, vertically middle, centred
     text, their own title sizes and gradients. main.js toggles exactly one of those
     three classes per section, so the :not() chain selects only regular sections. */
  #floating-text:not(.intro):not(.welcome):not(.end) {
    position: fixed;
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100vw;
    max-width: none;
    transform: none;
    z-index: 8;
    text-align: left;
    align-items: flex-start;
    gap: 0.8rem;
    padding: 2.2rem 2.4rem calc(3.2rem + env(safe-area-inset-bottom));
    border: 0;
    border-radius: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    overflow: visible;
    box-sizing: border-box;
  }

  #floating-text::before {
    content: none;
  }

  /* .intro is `width: auto` (shrink-to-fit) on desktop. Paired with `left: 50%`
     and no `right`, the available width is only half the viewport — 195px of 390px
     on a phone — so the two-line title wrapped to four and the vertical fade
     gradient swallowed the last line. Wide viewports hide this (half of 1440px is
     ample). An explicit centred box restores the intended two-line layout;
     translate(-50%) still centres it. */
  #floating-text.intro {
    width: min(92vw, 34rem);
    max-width: none;
  }

  /* .section-btn and .section-detail are children of .section-text, not of
     #floating-text, so this single gap sets the spacing between every stacked
     item: eyebrow, tag, title, body, inline detail and the Read More button. */
  #floating-text:not(.intro):not(.welcome):not(.end) .section-text {
    gap: 0.85rem;
    width: 100%;
    min-width: 0;
  }


  /* Title: constrained for bottom strip — fluid rem alone would be too large */
  #floating-text:not(.intro):not(.welcome):not(.end) .section-title {
    font-size: clamp(1.6rem, 7.2vw, 2.6rem);
    line-height: 1.14;
    letter-spacing: 0;
    text-align: left;
    color: #f2f5f7;
    background: none;
    -webkit-text-fill-color: currentColor;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    white-space: normal;
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
  }

  /* Eyebrow scales with the larger title. Letter-spacing stays in rem so the
     tracking grows with it rather than looking cramped. */
  #floating-text:not(.intro):not(.welcome):not(.end) .section-eyebrow {
    font-size: clamp(0.85rem, 3.1vw, 1.05rem);
    letter-spacing: 0.26rem;
  }

  /* Body: bumped alongside the title; layout constraints below. */
  #floating-text:not(.intro):not(.welcome):not(.end) .section-body {
    font-size: clamp(1.15rem, 4vw, 1.45rem);
    line-height: 1.45;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    color: rgba(233, 240, 245, 0.9);
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
  }

  /* Inline detail fits the bottom strip on small screens */
  #floating-text .section-detail__body {
    font-size: 0.92rem;
    max-width: 100%;
    max-height: min(34vh, 18rem);
  }

  #floating-text .section-detail__divider {
    margin: 0 0 1rem;
  }

  /* Match the smaller mobile divider gap (1rem) minus the mobile flex gap (0.85rem),
     so widening that gap above doesn't also widen the space below the detail block. */
  #floating-text .section-detail__inner {
    padding-bottom: 0.15rem;
  }

  #floating-text .section-tag {
    font-size: 0.66rem;
    padding: 0.4rem 0.85rem;
  }

  /* Panel keeps the desktop geometry on mobile — anchored left, full height,
     sliding in from the left — but goes edge to edge. */
  #read-panel-bg {
    width: 100vw;
    max-width: none;
  }

  .read-panel__media {
    min-height: 38%;
    /* Top padding clears the navbar row, which the Read Less pill now shares
       with the hamburger (see .read-panel__close). */
    padding: 7.5rem 1.9rem 1.9rem;
  }

  .read-panel__content {
    padding: 2rem 1.9rem calc(2.4rem + env(safe-area-inset-bottom));
  }

  /* Fluid rather than a fixed rem so the two-lines-per-segment wrap holds from
     small Androids up to large phones. The media header has room for this: it keeps
     its 38% min-height and the body copy still doesn't need to scroll. */
  .read-panel__title {
    font-size: clamp(2.1rem, 6.6vw, 2.6rem);
  }

  /* Read Less sits in the navbar row, immediately left of the hamburger. The
     navbar has no Sound button on mobile, so that slot is free.
       right  = navbar inset (1.6) + hamburger width (2) + navbar gap (1.05)
       top    = navbar inset (1.6) + half the row height (2.4/2 = 1.2)
                minus half the pill height (2.5/2 = 1.25), so it centres on the
                logo/hamburger row.
     It stays a child of the panel, so it slides in with the panel rather than
     needing its own animation. */
  .read-panel__close {
    top: calc(1.55rem + env(safe-area-inset-top));
    right: 4.65rem;
  }

  /* Scroll cue shows on mobile too. Visibility is driven purely by the
     `#floating-text.welcome + #scroll-indicator` sibling rule, so it appears on the
     welcome screen only, same as desktop — nothing here needs to toggle it. Bumped
     to sit alongside the larger mobile type, and lifted clear of the home
     indicator. */
  #scroll-indicator {
    bottom: calc(4.6rem + env(safe-area-inset-bottom));
    font-size: clamp(0.8rem, 2.7vw, 0.95rem);
  }

  /* No progress rail on mobile — the chapter menu covers navigation. */
  #section-progress-nav {
    display: none;
  }

  /* Colour fade and blur move from the left edge to the bottom edge, rising up
     behind the text strip. These rotate the desktop gradients rather than masking
     them: previously a 180deg mask was laid over a still-90deg colour ramp, so the
     colour was fading left→right underneath a vertical mask.

     `0deg` puts the 0% stop at the bottom, so both run bottom→up. The stop
     positions are the desktop ones scaled by 0.9, which is a uniform
     reparameterisation — the eased alpha curve (and so its freedom from Mach
     banding, see the desktop rules) is preserved exactly, just over a shorter
     distance so the fade clears the text instead of washing up the whole screen.
     Blur still ends before the colour does, matching the desktop 58/72 ratio. */
  .section-gradient-overlay {
    width: 100vw;
    height: 100vh;
  }

  .section-gradient-overlay::before {
    background: linear-gradient(0deg,
        rgba(var(--overlay-rgb), calc(1.000 * var(--overlay-alpha))) 0%,
        rgba(var(--overlay-rgb), calc(0.939 * var(--overlay-alpha))) 10%,
        rgba(var(--overlay-rgb), calc(0.784 * var(--overlay-alpha))) 20%,
        rgba(var(--overlay-rgb), calc(0.575 * var(--overlay-alpha))) 29%,
        rgba(var(--overlay-rgb), calc(0.352 * var(--overlay-alpha))) 39%,
        rgba(var(--overlay-rgb), calc(0.156 * var(--overlay-alpha))) 49%,
        rgba(var(--overlay-rgb), calc(0.061 * var(--overlay-alpha))) 55%,
        rgba(var(--overlay-rgb), calc(0.014 * var(--overlay-alpha))) 60%,
        rgba(var(--overlay-rgb), calc(0.000 * var(--overlay-alpha))) 65%
    );
  }

  .section-gradient-overlay::after {
    mask-image: linear-gradient(0deg,
        rgba(0, 0, 0, 1.000) 0%,
        rgba(0, 0, 0, 0.896) 11%,
        rgba(0, 0, 0, 0.648) 21%,
        rgba(0, 0, 0, 0.425) 29%,
        rgba(0, 0, 0, 0.216) 37%,
        rgba(0, 0, 0, 0.061) 44%,
        rgba(0, 0, 0, 0.014) 49%,
        rgba(0, 0, 0, 0.000) 52%
    );
    -webkit-mask-image: linear-gradient(0deg,
        rgba(0, 0, 0, 1.000) 0%,
        rgba(0, 0, 0, 0.896) 11%,
        rgba(0, 0, 0, 0.648) 21%,
        rgba(0, 0, 0, 0.425) 29%,
        rgba(0, 0, 0, 0.216) 37%,
        rgba(0, 0, 0, 0.061) 44%,
        rgba(0, 0, 0, 0.014) 49%,
        rgba(0, 0, 0, 0.000) 52%
    );
  }
}
