:root {
    --bg-dark: #0c0906;
    --text: #f3e7d6;
    --text-dim: #c9b299;
    --gilt: rgba(198, 160, 92, 0.85);
    --gilt-solid: #c6a05c;
    --glow: rgba(255, 190, 110, 0.45);
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: hidden;
}

body {
    font-family: Georgia, "Times New Roman", serif;
    color: var(--text);
    background: var(--bg-dark);
}

#scene {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    outline: none;
    cursor: default;
}

.vignette {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 2;
    background: radial-gradient(ellipse at 50% 42%, transparent 40%, rgba(0, 0, 0, 0.55) 100%);
}

/* Intro / loading veil */
/* Boot fade: a black veil over the first procedural frames, faded out on
   ready so the scene doesn't pop in mid-build. */
.boot {
    position: fixed;
    inset: 0;
    z-index: 30;
    background: #050302;
    pointer-events: none;
    opacity: 1;
    transition: opacity 0.3s ease;
}

.boot.gone {
    opacity: 0;
}

/* Entry: no full-screen splash — just a small pill capturing the one click
   pointer lock requires. The canvas shows through behind it. */
.intro {
    position: fixed;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    cursor: pointer;
    transition: opacity 0.5s ease;
}

.intro.fading {
    opacity: 0;
    pointer-events: none;
}

.intro.gone {
    display: none;
}

.intro-pill {
    padding: 0.7rem 1.5rem;
    border-radius: 999px;
    background: rgba(10, 6, 4, 0.62);
    border: 1px solid rgba(198, 160, 92, 0.4);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5), 0 0 40px var(--glow);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    animation: pill-pulse 2.4s ease-in-out infinite;
}

.intro-pill-text {
    font-size: 0.92rem;
    letter-spacing: 0.14em;
    color: var(--text);
    text-transform: uppercase;
}

@keyframes pill-pulse {
    0%, 100% { transform: scale(1); opacity: 0.9; }
    50% { transform: scale(1.03); opacity: 1; }
}

/* Transient controls hint shown just after entering, then auto-fades. */
.controls-hint {
    position: fixed;
    left: 50%;
    bottom: clamp(4.5rem, 12vh, 7rem);
    transform: translateX(-50%);
    z-index: 6;
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    background: rgba(10, 6, 4, 0.5);
    border: 1px solid rgba(198, 160, 92, 0.22);
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    color: rgba(201, 178, 153, 0.85);
    white-space: nowrap;
    max-width: 92vw;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.6s ease;
}

.controls-hint.visible {
    opacity: 1;
}

/* HUD chrome */
.hud {
    position: fixed;
    z-index: 5;
}

.hud-header {
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 1.1rem 1.6rem;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(5, 3, 2, 0.55), transparent);
}

.hud-nav {
    display: flex;
    gap: 1.4rem;
    pointer-events: auto;
}

.mute-btn {
    pointer-events: auto;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--text-dim);
    font-size: 1rem;
    line-height: 1;
    align-self: center;
    transition: color 0.2s ease;
}

.mute-btn:hover,
.mute-btn:focus-visible {
    color: var(--text);
    outline: none;
}

.mute-btn .mute-off {
    display: none;
}

.mute-btn.muted .mute-on {
    display: none;
}

.mute-btn.muted .mute-off {
    display: inline;
    opacity: 0.55;
}

/* Radar: circular top-down mini-map of the room, bottom-left — a brass
   instrument scope. A plain DOM/canvas overlay (not three.js) redrawn from
   the main frame loop. North-up: it never rotates with the player; while
   walking it stays player-centred and zoomed close, and eases out to frame
   the whole room when paused. */
.radar {
    left: 1.1rem;
    bottom: 1.1rem;
    width: 264px;
    height: 264px;
    padding: 6px;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 40%, rgba(26, 17, 10, 0.78), rgba(5, 3, 2, 0.86));
    border: 1px solid rgba(198, 160, 92, 0.85);
    box-shadow:
        0 0 0 3px rgba(22, 13, 7, 0.9),
        0 0 0 4.5px rgba(198, 160, 92, 0.45),
        0 12px 32px rgba(0, 0, 0, 0.55),
        0 0 22px rgba(198, 160, 92, 0.14),
        inset 0 0 26px rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.radar canvas {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
}

/* When the pointer isn't locked (paused / not yet entered), the radar's year
   labels and aisle mouths become clickable teleport targets. */
.radar.interactive canvas {
    cursor: pointer;
}

/* Persistent Esc hint, shown for the whole time the reading overlay is open
   (unlike .controls-hint, which is transient). */
.esc-hint {
    position: fixed;
    right: 1.4rem;
    bottom: 1.4rem;
    z-index: 12;
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    background: rgba(10, 6, 4, 0.5);
    border: 1px solid rgba(198, 160, 92, 0.22);
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    color: rgba(201, 178, 153, 0.85);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.esc-hint.visible {
    opacity: 1;
}

/* Fallback (no WebGL / no JS) */
.fallback {
    position: fixed;
    inset: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.6rem;
    padding: 2rem;
    background: var(--bg-dark);
}

.fallback[hidden] {
    display: none;
}

.fallback a {
    color: var(--gilt-solid);
}

/* First-person HUD: reticle, aim label, pause veil, teleport fade */
.reticle {
    position: fixed;
    z-index: 4;
    left: 50%;
    top: 50%;
    width: 5px;
    height: 5px;
    margin: -2.5px 0 0 -2.5px;
    border-radius: 50%;
    background: rgba(243, 231, 214, 0.55);
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.8);
    pointer-events: none;
    transition: transform 0.15s ease, background 0.15s ease;
}

.reticle.aiming {
    transform: scale(1.9);
    background: var(--gilt-solid);
    box-shadow: 0 0 10px var(--glow);
}

/* Aim bubble: a prominent tooltip near the reticle whose background is set
   inline (from JS) to the aimed book's own leather color, with the text
   color chosen for contrast against it — reads as a little book-colored
   speech bubble rather than a plain label. */
.aim-bubble {
    position: fixed;
    z-index: 4;
    left: 50%;
    top: calc(50% + 2.4rem);
    transform: translateX(-50%) translateY(-4px) scale(0.96);
    max-width: 380px;
    padding: 0.55rem 1.15rem;
    text-align: center;
    font-style: italic;
    font-size: 1.05rem;
    line-height: 1.3;
    letter-spacing: 0.02em;
    color: var(--text);
    background: rgba(10, 6, 3, 0.72);
    border: 1px solid rgba(198, 160, 92, 0.45);
    border-radius: 999px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(0, 0, 0, 0.25) inset;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease, transform 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.aim-bubble.visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
}

.pause {
    position: fixed;
    inset: 0;
    z-index: 15;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    text-align: center;
    background: rgba(5, 3, 2, 0.62);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

.pause.visible {
    opacity: 1;
    pointer-events: auto;
    cursor: pointer;
}

.pause-text {
    margin: 0;
    font-size: 1.4rem;
    font-style: italic;
    letter-spacing: 0.16em;
    color: var(--text);
    text-transform: uppercase;
}

.pause-sub {
    margin: 0;
    font-size: 0.85rem;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    animation: pill-pulse 2.4s ease-in-out infinite;
}

/* Subtle gilt link on the pause veil that navigates back to the site root.
   Its own click stops propagation (in library.js) so it isn't swallowed by
   the veil's click-to-resume handler. */
.pause-home {
    margin-top: 1.4rem;
    font-size: 0.82rem;
    font-style: italic;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    text-decoration: none;
    border-bottom: 1px solid rgba(198, 160, 92, 0.3);
    padding-bottom: 2px;
    pointer-events: auto;
    transition: color 0.2s ease, border-color 0.2s ease;
}

.pause-home:hover,
.pause-home:focus-visible {
    color: var(--text);
    border-color: var(--gilt);
    outline: none;
}

.fade {
    position: fixed;
    inset: 0;
    z-index: 18;
    background: #050302;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.24s ease;
}

.fade.visible {
    opacity: 1;
}

body.playing #scene {
    cursor: none;
}


/* ==========================================================================
   Paper note — plain, fully legible reading card (no blurred filler)
   ========================================================================== */

.paper-view {
    position: fixed;
    inset: 0;
    z-index: 16;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2.5rem 1rem;
    background: rgba(4, 2, 1, 0);
    backdrop-filter: blur(0);
    -webkit-backdrop-filter: blur(0);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s ease, background 0.4s ease, backdrop-filter 0.4s ease;
}

.paper-view[hidden] {
    display: none;
}

.paper-view.open {
    opacity: 1;
    pointer-events: auto;
    background: rgba(4, 2, 1, 0.82);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

.paper-card {
    position: relative;
    width: min(88vw, 640px);
    padding: clamp(2.4rem, 6vw, 4rem) clamp(2rem, 6vw, 4.5rem);
    background:
        radial-gradient(120% 100% at 50% 0%, #fbf5e6 0%, #f4ecd8 55%, #e9ddc0 100%);
    border-radius: 5px;
    box-shadow:
        0 30px 80px rgba(0, 0, 0, 0.7),
        0 2px 0 rgba(255, 255, 255, 0.25) inset,
        0 0 0 1px rgba(0, 0, 0, 0.35);
    transform: scale(0.94) translateY(18px);
    transition: transform 0.5s cubic-bezier(0.22, 0.8, 0.3, 1);
}

.paper-view.open .paper-card {
    transform: scale(1) translateY(0);
}

.paper-text {
    margin: 0;
    text-align: center;
    font-family: Georgia, "Times New Roman", serif;
    font-size: clamp(1.3rem, 3.6vw, 1.9rem);
    line-height: 1.5;
    color: #2b2318;
}

.paper-close {
    z-index: 17;
}

@media (prefers-reduced-motion: reduce) {
    .paper-view {
        transition: opacity 0.2s ease, background 0.2s ease;
    }

    .paper-card,
    .paper-view.open .paper-card {
        transform: none;
        transition: none;
    }
}

/* ==========================================================================
   Reading overlay — opened two-page book spread
   ========================================================================== */

.backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0);
    z-index: 10;
    transition: background 0.42s ease;
}

.backdrop.visible {
    background: rgba(4, 2, 1, 0.82);
    backdrop-filter: blur(3px);
}

.stage {
    position: fixed;
    inset: 0;
    z-index: 11;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(0.4rem, 2vw, 2.2rem);
    padding: 2.5rem 1rem;
    pointer-events: none;
}

.stage[hidden] {
    display: none;
}

/* The book: a landscape spread of two pages joined at a central gutter. */
.book {
    --edge: #b9a074;
    --page: #f4ecd8;
    --page-edge: #e9ddc0;
    --ink: #2b2318;
    --ink-faded: #b7a992;

    position: relative;
    width: min(92vw, 1180px);
    height: min(82vh, 760px);
    display: block;
    border-radius: 5px;
    background:
        /* page tint from centre outward */
        radial-gradient(120% 100% at 50% 0%, #fbf5e6 0%, var(--page) 45%, var(--page-edge) 100%);
    box-shadow:
        0 30px 80px rgba(0, 0, 0, 0.7),
        0 2px 0 rgba(255, 255, 255, 0.25) inset,
        0 0 0 1px rgba(0, 0, 0, 0.35),
        0 0 0 12px var(--edge),
        0 0 0 13px rgba(0, 0, 0, 0.45);
    pointer-events: auto;
    opacity: 0;
    transform: scale(0.94) translateY(18px);
    transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.22, 0.8, 0.3, 1);
    overflow: hidden;
}

.stage.open .book {
    opacity: 1;
    transform: scale(1) translateY(0);
}

/* Subtle paper grain + faint horizontal ruling for realism. */
.book::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image:
        repeating-linear-gradient(
            0deg,
            transparent 0,
            transparent 1.55rem,
            rgba(120, 90, 50, 0.035) 1.55rem,
            rgba(120, 90, 50, 0.035) calc(1.55rem + 1px)),
        radial-gradient(60% 40% at 20% 15%, rgba(160, 120, 70, 0.06), transparent 70%),
        radial-gradient(60% 40% at 82% 88%, rgba(160, 120, 70, 0.06), transparent 70%);
    mix-blend-mode: multiply;
    z-index: 1;
}

/* The two pages: one continuous text flow laid out as two newspaper-style
   columns, so it fills the left page top-to-bottom and then continues at the
   top of the right page — strictly consecutive, with the gutter falling
   between the columns. Overflow is clipped so no page ever looks half-empty. */
.page-flow {
    position: absolute;
    inset: clamp(2.6rem, 6vh, 3.6rem) clamp(2.2rem, 4.5vw, 4rem);
    column-count: 2;
    column-gap: clamp(2.4rem, 6vw, 5rem);
    column-fill: auto;
    overflow: hidden;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1.2rem;
    line-height: 1.62;
    text-align: justify;
    hyphens: auto;
    color: var(--ink);
    z-index: 2;
}

/* Filler text — present but explicitly not meant to be read. */
.page-flow .filler {
    color: var(--ink-faded);
    filter: blur(2.2px);
    opacity: 0.42;
    user-select: none;
}

/* The actual quote: crisp ink, marker-highlighted, the eye's anchor. It may
   break across the gutter (end of left column → top of right) so the flow
   stays consecutive. */
.page-flow .quote {
    color: var(--ink);
    font-weight: 500;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    /* highlighter sweep — saturated marker yellow, uneven ends, slight
       translucency so the paper grain still reads through. */
    background-image: linear-gradient(
        101deg,
        rgba(255, 232, 92, 0) 0.15rem,
        rgba(255, 214, 40, 0.9) 0.5rem,
        rgba(255, 205, 28, 0.82) calc(100% - 0.5rem),
        rgba(255, 232, 92, 0) calc(100% - 0.1rem));
    border-radius: 0.4em 0.7em 0.45em 0.6em;
    padding: 0.08em 0.06em;
    box-shadow: 0 0.06em 0 rgba(214, 168, 20, 0.35);
}

.page-flow .quote-line {
    display: inline;
}

/* Running heads (author / title) and page numbers. */
.running-head {
    position: absolute;
    top: clamp(1.1rem, 3vh, 1.7rem);
    font-size: 0.68rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(90, 70, 45, 0.55);
    font-variant: small-caps;
    z-index: 3;
    pointer-events: none;
}

.running-head-left {
    left: clamp(2.2rem, 4.5vw, 4rem);
    font-style: italic;
}

.running-head-right {
    right: clamp(2.2rem, 4.5vw, 4rem);
    letter-spacing: 0.1em;
}

.page-number {
    position: absolute;
    bottom: clamp(1rem, 2.6vh, 1.5rem);
    font-size: 0.78rem;
    color: rgba(90, 70, 45, 0.5);
    z-index: 3;
    pointer-events: none;
}

.page-number-left {
    left: clamp(2.2rem, 4.5vw, 4rem);
}

.page-number-right {
    right: clamp(2.2rem, 4.5vw, 4rem);
}

/* Central gutter: shadow of the binding where the pages meet. */
.gutter {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 12%;
    transform: translateX(-50%);
    pointer-events: none;
    z-index: 2;
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(60, 42, 22, 0.03) 30%,
        rgba(40, 26, 12, 0.22) 48%,
        rgba(30, 18, 8, 0.32) 50%,
        rgba(40, 26, 12, 0.22) 52%,
        rgba(60, 42, 22, 0.03) 70%,
        transparent 100%);
}

/* Faint darkening toward the outer page edges, like a bound book. */
.page-shade {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 2;
    background:
        linear-gradient(90deg, rgba(50, 34, 16, 0.16), transparent 12%),
        linear-gradient(270deg, rgba(50, 34, 16, 0.16), transparent 12%);
}

/* Navigation arrows flanking the book. */
.nav-arrow {
    flex: 0 0 auto;
    pointer-events: auto;
    width: clamp(2.6rem, 5vw, 3.6rem);
    height: clamp(2.6rem, 5vw, 3.6rem);
    border-radius: 50%;
    border: 1px solid rgba(198, 160, 92, 0.4);
    background: rgba(30, 21, 13, 0.55);
    color: var(--text);
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
}

.nav-arrow span {
    display: block;
    margin-top: -0.15em;
}

.nav-arrow:hover:not(:disabled) {
    background: rgba(52, 37, 22, 0.85);
    border-color: var(--gilt);
    transform: scale(1.06);
}

.nav-arrow:disabled {
    opacity: 0.2;
    cursor: default;
}

.nav-arrow[hidden] {
    visibility: hidden;
    opacity: 0;
}

/* Caption below the spread: title, author·year, page indicator. */
.book-caption {
    position: fixed;
    left: 50%;
    bottom: clamp(0.8rem, 3vh, 1.8rem);
    transform: translateX(-50%);
    display: flex;
    align-items: baseline;
    gap: 0.9rem;
    z-index: 12;
    pointer-events: none;
    text-align: center;
    max-width: 90vw;
    flex-wrap: wrap;
    justify-content: center;
}

.stage[hidden] ~ .book-caption {
    display: none;
}

.caption-title {
    font-size: 1.02rem;
    font-style: italic;
    color: var(--text);
}

.caption-author {
    font-size: 0.82rem;
    letter-spacing: 0.06em;
    color: var(--text-dim);
}

.caption-indicator {
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    color: var(--gilt);
    border: 1px solid rgba(198, 160, 92, 0.4);
    border-radius: 3px;
    padding: 0.05rem 0.45rem;
}

/* Book-to-book navigation (same year) inside the reading overlay. */
.book-nav {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    pointer-events: auto;
}

.book-nav[hidden] {
    display: none;
}

.book-nav-btn {
    font: inherit;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    color: var(--gilt);
    background: rgba(20, 14, 8, 0.5);
    border: 1px solid rgba(198, 160, 92, 0.45);
    border-radius: 3px;
    padding: 0.12rem 0.55rem;
    cursor: pointer;
    transition: background 0.15s ease, opacity 0.15s ease;
}

.book-nav-btn:hover:not(:disabled) {
    background: rgba(198, 160, 92, 0.22);
}

.book-nav-btn:disabled {
    opacity: 0.32;
    cursor: default;
}

.book-nav-pos {
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    min-width: 5.5rem;
    text-align: center;
}

/* Page-turn: the flowing text lifts and fades while its content is swapped,
   then settles back — a quick, non-blocking turn between quotes or books. */
.page-flow {
    transition: opacity 0.16s ease, transform 0.16s ease;
}

.page-flow.turning {
    opacity: 0;
    transform: translateX(-1.4%) skewY(-0.4deg);
}

.close-btn {
    position: fixed;
    top: 1.4rem;
    right: 1.6rem;
    background: rgba(30, 21, 13, 0.6);
    border: 1px solid rgba(198, 160, 92, 0.4);
    color: var(--text);
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    font-size: 1.15rem;
    cursor: pointer;
    z-index: 13;
    pointer-events: auto;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.close-btn:hover {
    background: rgba(52, 37, 22, 0.9);
    border-color: var(--gilt);
}

@media (max-width: 760px) {
    .stage {
        gap: 0.3rem;
        padding: 1.2rem 0.4rem;
    }

    .book {
        width: 94vw;
        height: 74vh;
    }

    /* Too narrow for a real spread — fold to a single readable page. */
    .page-flow {
        column-count: 1;
        inset: 2.4rem 1.5rem;
        text-align: left;
        hyphens: none;
    }

    .gutter,
    .running-head-right,
    .page-number-right {
        display: none;
    }

    .nav-arrow {
        position: fixed;
        bottom: 4.2rem;
        z-index: 13;
    }

    .nav-prev {
        left: 1rem;
    }

    .nav-next {
        right: 1rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .backdrop {
        transition: background 0.2s ease;
    }

    .book {
        transition: opacity 0.2s ease;
        transform: none;
    }

    .stage.open .book {
        transform: none;
    }
}
