/* ==========================================================================
   Castle Whisper — heritage theme
   Mobile-first, portrait & landscape, no build step required.
   ========================================================================== */

:root {
    /* Earthy heritage palette */
    --ink: #2b2018;
    --ink-soft: #5a4738;
    --stone: #6b5844;
    --stone-dark: #4a3b2c;
    --cream: #f6efe3;
    --parchment: #e9dcc4;
    --parchment-dim: #d8c6a6;
    --gold: #b8893a;
    --gold-bright: #e0b969;
    --brick: #8c4a2f;
    --moss: #5f6b48;
    --night: #17110c;
    --night-soft: #241a12;

    --narrator: #7a6a4f;
    --william: #8c4a2f;

    --radius: 14px;
    --radius-lg: 22px;
    --shadow: 0 10px 30px rgba(23, 17, 12, .28);
    --shadow-soft: 0 4px 14px rgba(23, 17, 12, .18);

    --font-display: "Cinzel", "Trajan Pro", Georgia, "Times New Roman", serif;
    --font-body: "Lora", Georgia, "Iowan Old Style", serif;
    --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

    /* Safe areas for notched phones */
    --pad-top: max(14px, env(safe-area-inset-top));
    --pad-bottom: max(14px, env(safe-area-inset-bottom));
    --pad-left: max(16px, env(safe-area-inset-left));
    --pad-right: max(16px, env(safe-area-inset-right));
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

/*
   The UA stylesheet's [hidden] { display: none } is only a plain element rule,
   so ANY class that sets a display value beats it and the element stays on
   screen. That has now been patched one selector at a time six times over
   (.ar-hint[hidden], .sheet[hidden], .model-sheet[hidden] …) and it caught the
   scanner's torch button too. One rule, once, instead — the per-selector ones
   below are left in place but are now redundant.

   Anything toggled from JavaScript uses el.hidden, so this is the switch the
   whole app depends on.
*/
[hidden] {
    display: none !important;
}

html,
body {
    margin: 0;
    padding: 0;
    min-height: 100%;
}

body {
    font-family: var(--font-body);
    color: var(--ink);
    background: var(--night);
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    overscroll-behavior-y: none;
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: .02em;
    margin: 0 0 .4em;
    line-height: 1.15;
}

p { line-height: 1.65; margin: 0 0 1em; }
a { color: var(--gold); }

/* ------------------------------------------------------------------ layout */

.page {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    background:
        radial-gradient(120% 90% at 50% 0%, rgba(184, 137, 58, .18), transparent 60%),
        linear-gradient(180deg, #241a12 0%, #17110c 45%, #120d09 100%);
}

.page--parchment {
    background:
        radial-gradient(120% 80% at 50% -10%, rgba(255, 255, 255, .55), transparent 55%),
        linear-gradient(180deg, var(--cream) 0%, var(--parchment) 100%);
    color: var(--ink);
}

.shell {
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
    padding: var(--pad-top) var(--pad-right) var(--pad-bottom) var(--pad-left);
    flex: 1;
    display: flex;
    flex-direction: column;
}

/* ----------------------------------------------------------------- topbar */

.topbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0 18px;
}

.topbar__back {
    font-family: var(--font-ui);
    font-size: 14px;
    text-decoration: none;
    color: var(--parchment);
    background: rgba(246, 239, 227, .1);
    border: 1px solid rgba(232, 220, 196, .25);
    border-radius: 999px;
    padding: 8px 14px;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
}

.page--parchment .topbar__back {
    color: var(--stone-dark);
    background: rgba(107, 88, 68, .08);
    border-color: rgba(107, 88, 68, .25);
}

.topbar__title {
    font-family: var(--font-display);
    font-size: 15px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--gold-bright);
    margin-left: auto;
}

.page--parchment .topbar__title { color: var(--brick); }

/* ---------------------------------------------------------------- landing */

.hero {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 24px 0 12px;
}

.hero__crest {
    width: 108px;
    height: 108px;
    margin-bottom: 18px;
    filter: drop-shadow(0 6px 18px rgba(184, 137, 58, .4));
}

.hero__brand {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 12px;
}

.hero__logo {
    width: 100%;
    max-width: min(350px, 86vw);
    height: auto;
    display: block;
    filter: drop-shadow(0 10px 30px rgba(0, 0, 0, .75)) drop-shadow(0 2px 12px rgba(184, 137, 58, .45));
}

.hero__eyebrow {
    font-family: var(--font-ui);
    font-size: 12px;
    letter-spacing: .34em;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 10px;
}

.hero__title {
    font-size: clamp(38px, 12vw, 62px);
    color: var(--cream);
    text-shadow: 0 4px 24px rgba(0, 0, 0, .55);
    margin-bottom: 6px;
}

.hero__subtitle {
    font-size: clamp(15px, 4.4vw, 19px);
    color: var(--parchment-dim);
    max-width: 30ch;
    margin: 0 auto 4px;
}

.hero__location {
    font-family: var(--font-ui);
    font-size: 12px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: rgba(232, 220, 196, .5);
    margin-bottom: 26px;
}

.divider {
    width: 160px;
    height: 1px;
    margin: 0 auto 26px;
    background: linear-gradient(90deg, transparent, var(--gold), transparent);
}

/* ---------------------------------------------------------------- buttons */

.btn {
    font-family: var(--font-ui);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: .02em;
    border: 0;
    border-radius: 999px;
    padding: 16px 26px;
    min-height: 54px;
    width: 100%;
    max-width: 420px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    cursor: pointer;
    text-decoration: none;
    transition: transform .12s ease, box-shadow .18s ease, opacity .18s ease;
    touch-action: manipulation;
}

.btn:active { transform: scale(.975); }

.btn--primary {
    color: #2a1c08;
    background: linear-gradient(180deg, var(--gold-bright), var(--gold));
    box-shadow: 0 8px 22px rgba(184, 137, 58, .38);
}

.btn--secondary {
    color: var(--cream);
    background: linear-gradient(180deg, #3d2f23, #2a1f16);
    border: 1px solid rgba(224, 185, 105, .4);
    box-shadow: 0 4px 14px rgba(23, 17, 12, .25);
}

.page--parchment .btn--secondary {
    color: var(--stone-dark);
    background: linear-gradient(180deg, #fdfbf7, #f2e7d5);
    border: 1px solid rgba(184, 137, 58, .5);
    box-shadow: 0 3px 10px rgba(43, 32, 24, .12);
}

.btn--secondary:hover {
    border-color: rgba(224, 185, 105, .7);
}

.btn--sm {
    min-height: 38px;
    padding: 7px 16px;
    font-size: 13px;
    width: auto;
    font-weight: 600;
}

.btn--ghost {
    color: var(--parchment);
    background: rgba(246, 239, 227, .08);
    border: 1px solid rgba(232, 220, 196, .3);
}

.page--parchment .btn--ghost {
    color: var(--stone-dark);
    background: rgba(107, 88, 68, .07);
    border-color: rgba(107, 88, 68, .3);
}

.btn--danger {
    color: var(--cream);
    background: rgba(140, 74, 47, .85);
    border: 1px solid rgba(140, 74, 47, .5);
}

.btn[disabled],
.btn[aria-disabled="true"] {
    opacity: .45;
    pointer-events: none;
}

.btn-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 100%;
}

/* ---------------------------------------------------------- system checks */

.checks {
    width: 100%;
    max-width: 420px;
    margin: 22px auto 0;
    padding: 14px 16px;
    border-radius: var(--radius);
    background: rgba(246, 239, 227, .06);
    border: 1px solid rgba(232, 220, 196, .16);
    font-family: var(--font-ui);
    font-size: 13px;
    color: var(--parchment-dim);
    text-align: left;
}

.check {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 6px 0;
}

.check__dot {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    margin-top: 1px;
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 700;
    background: rgba(232, 220, 196, .2);
    color: var(--parchment);
}

.check[data-state="ok"] .check__dot { background: #4b7a4b; color: #eaf6ea; }
.check[data-state="warn"] .check__dot { background: var(--gold); color: #2a1c08; }
.check[data-state="fail"] .check__dot { background: var(--brick); color: #fdeee7; }

.check__label { flex: 1; }
.check__note { display: block; opacity: .7; font-size: 12px; margin-top: 2px; }

/* -------------------------------------------------------------- map page */

.progress {
    font-family: var(--font-ui);
    margin-bottom: 20px;
}

.progress__label {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 8px;
}

.page--parchment .progress__label { color: var(--brick); }

.progress__track {
    height: 8px;
    border-radius: 999px;
    background: rgba(107, 88, 68, .25);
    overflow: hidden;
}

.progress__fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--gold), var(--gold-bright));
    transition: width .5s ease;
}

.notice {
    font-family: var(--font-ui);
    font-size: 14px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: rgba(184, 137, 58, .16);
    border: 1px solid rgba(184, 137, 58, .4);
    color: var(--ink);
    margin-bottom: 18px;
}

.cp-list {
    list-style: none;
    margin: 0 0 24px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.cp-card {
    position: relative;
    display: flex;
    gap: 14px;
    align-items: center;
    padding: 16px;
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, rgba(255, 255, 255, .78), rgba(233, 220, 196, .6));
    border: 1px solid rgba(107, 88, 68, .28);
    box-shadow: var(--shadow-soft);
    text-decoration: none;
    color: inherit;
    transition: transform .14s ease, box-shadow .2s ease;
}

.cp-card:active { transform: scale(.99); }

.cp-card[data-status="locked"] {
    opacity: .58;
    filter: grayscale(.35);
    pointer-events: none;
}

.cp-card[data-status="done"] {
    border-color: rgba(95, 107, 72, .55);
    background: linear-gradient(180deg, rgba(238, 244, 228, .85), rgba(214, 226, 198, .7));
}

.cp-card__num {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 19px;
    color: var(--cream);
    background: linear-gradient(180deg, var(--stone), var(--stone-dark));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25);
}

.cp-card[data-status="done"] .cp-card__num { background: linear-gradient(180deg, #6f8055, #4f5c3c); }

.cp-card__body { flex: 1; min-width: 0; }

.cp-card__title {
    font-family: var(--font-display);
    font-size: 18px;
    margin: 0 0 2px;
}

.cp-card__sub {
    font-size: 13.5px;
    color: var(--ink-soft);
    margin: 0;
    line-height: 1.4;
}

.cp-card__tag {
    display: inline-block;
    margin-top: 8px;
    font-family: var(--font-ui);
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(107, 88, 68, .16);
    color: var(--stone-dark);
}

.cp-card[data-status="done"] .cp-card__tag { background: rgba(95, 107, 72, .22); color: #3f4a2e; }
.cp-card[data-status="locked"] .cp-card__tag { background: rgba(43, 32, 24, .14); }

.cp-card__chev { flex: 0 0 auto; opacity: .5; font-size: 20px; }

/* --------------------------------------------------- Landing Background */

.landing-bg-backdrop {
    position: fixed;
    inset: 0;
    z-index: 0;
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    opacity: 0.36;
    filter: saturate(1.15) brightness(0.85);
    pointer-events: none;
    transform: translateZ(0);
}

.landing-bg-overlay {
    position: fixed;
    inset: 0;
    z-index: 0;
    background: radial-gradient(circle at 50% 30%, rgba(36, 26, 18, 0.42) 0%, rgba(23, 17, 12, 0.82) 65%, rgba(18, 13, 9, 0.96) 100%);
    pointer-events: none;
}

.page--landing {
    position: relative;
    z-index: 1;
    background: transparent !important;
}

.page--landing .checks {
    background: rgba(23, 17, 12, 0.72);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(184, 137, 58, 0.35);
}

/* ----------------------------------------------------------- Map Background */

.has-map-bg {
    background-color: #1c150e !important;
}

.map-bg-backdrop {
    position: fixed;
    inset: 0;
    z-index: 0;
    background-size: cover;
    background-position: center top;
    background-repeat: no-repeat;
    opacity: 0.40;
    filter: saturate(1.18) contrast(1.08);
    pointer-events: none;
    transform: translateZ(0);
}

.map-bg-overlay {
    position: fixed;
    inset: 0;
    z-index: 0;
    background: radial-gradient(circle at 50% 20%, rgba(246, 239, 227, 0.50) 0%, rgba(235, 223, 203, 0.78) 55%, rgba(220, 206, 180, 0.94) 100%);
    pointer-events: none;
}

.has-map-bg .page--parchment {
    position: relative;
    background: transparent !important;
    min-height: 100vh;
}

.has-map-bg .shell {
    position: relative;
    z-index: 1;
}

.has-map-bg .topbar {
    justify-content: space-between;
    background: rgba(255, 255, 255, 0.72);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(184, 137, 58, 0.35);
    border-radius: 999px;
    padding: 6px 14px;
    margin-bottom: 14px;
    box-shadow: 0 4px 18px rgba(43, 32, 24, 0.1);
}

.topbar__brand {
    display: flex;
    align-items: center;
    justify-content: center;
}

.topbar__logo {
    height: 38px;
    width: auto;
    display: block;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.25));
}

.topbar__map-btn {
    font-family: var(--font-ui);
    font-size: 13px;
    font-weight: 600;
    color: var(--brick);
    background: rgba(184, 137, 58, 0.18);
    border: 1px solid rgba(184, 137, 58, 0.45);
    border-radius: 999px;
    padding: 6px 14px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    transition: all 0.2s;
}
.topbar__map-btn:hover {
    background: rgba(184, 137, 58, 0.32);
    color: var(--ink);
}

.topbar__btn {
    min-height: 36px;
    padding: 6px 14px;
    font-size: 13px;
    width: auto;
}

/* ------------------------------------------- Interactive Map & Floating Pins */
.interactive-map-card {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(248, 242, 231, 0.88));
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(184, 137, 58, 0.45);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 26px rgba(43, 32, 24, 0.14);
    padding: 14px;
    margin-bottom: 16px;
}

.interactive-map-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    gap: 10px;
}

.interactive-map-card__badge {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--gold);
    display: block;
    margin-bottom: 2px;
}

.interactive-map-card__title {
    font-family: var(--font-display);
    font-size: 16px;
    color: var(--ink);
    margin: 0;
    font-weight: 600;
}

.interactive-map-card__footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid rgba(184, 137, 58, 0.2);
}

.map-viewport {
    position: relative;
    width: 100%;
    border-radius: 12px;
    overflow: hidden;
    background: #1e1610;
    box-shadow: inset 0 0 16px rgba(0, 0, 0, 0.35);
}

.map-viewport__img {
    display: block;
    width: 100%;
    height: auto;
    user-select: none;
    -webkit-user-drag: none;
}

.map-viewport--modal {
    max-height: 72vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid rgba(184, 137, 58, 0.35);
}

/* Floating Checkpoint Pins on the Map */
.map-pin {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: center;
    pointer-events: auto;
}

.map-pin__btn {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
    position: relative;
    transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.18s ease;
    border: 2px solid #ffffff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
    user-select: none;
}

.map-pin__btn:active,
.map-pin__btn:hover {
    transform: scale(1.18);
}

.map-pin__btn--ready {
    background: linear-gradient(135deg, #f5d378, #b8893a);
    color: #24180d;
    box-shadow: 0 4px 14px rgba(184, 137, 58, 0.65), 0 0 0 3px rgba(224, 185, 105, 0.5);
}

.map-pin__btn--done {
    background: linear-gradient(135deg, #7c9456, #4b5a32);
    color: #ffffff;
    box-shadow: 0 4px 12px rgba(75, 90, 50, 0.55), 0 0 0 3px rgba(124, 148, 86, 0.45);
}

.map-pin__btn--locked {
    background: linear-gradient(135deg, #44372c, #261c14);
    color: #a39281;
    border-color: rgba(255, 255, 255, 0.35);
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
}

.map-pin__pulse {
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    border: 2.5px solid #e0b969;
    opacity: 0.85;
    animation: mapPinPulse 1.8s infinite ease-out;
    pointer-events: none;
}

@keyframes mapPinPulse {
    0% {
        transform: scale(0.85);
        opacity: 0.95;
    }
    70% {
        transform: scale(1.65);
        opacity: 0;
    }
    100% {
        transform: scale(1.65);
        opacity: 0;
    }
}

.map-pin__chip {
    margin-top: 4px;
    background: rgba(23, 17, 12, 0.88);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: #f6efe3;
    font-size: 10px;
    font-weight: 600;
    font-family: var(--font-ui);
    padding: 2px 7px;
    border-radius: 999px;
    border: 1px solid rgba(224, 185, 105, 0.45);
    white-space: nowrap;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
    pointer-events: none;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.map-legend {
    display: flex;
    align-items: center;
    gap: 12px;
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 600;
    color: var(--stone-dark);
}

.legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
}

.legend-dot--ready {
    background: #e0b969;
    box-shadow: 0 0 0 2px #b8893a;
}

.legend-dot--done {
    background: #5f6b48;
    box-shadow: 0 0 0 2px #4b5a32;
}

.legend-dot--locked {
    background: #6b5844;
}

.map-hint {
    font-size: 11px;
    color: var(--stone);
    font-style: italic;
}

.has-map-bg .progress {
    background: rgba(255, 255, 255, 0.76);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(184, 137, 58, 0.3);
    border-radius: var(--radius-md);
    padding: 10px 14px;
    box-shadow: 0 4px 16px rgba(43, 32, 24, 0.08);
}

.map-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    margin-bottom: 14px;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.88), rgba(246, 239, 227, 0.82));
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(184, 137, 58, 0.45);
    border-radius: var(--radius-lg);
    box-shadow: 0 6px 20px rgba(43, 32, 24, 0.12);
}

.map-banner__thumb {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    background-size: cover;
    background-position: center;
    border: 1px solid rgba(184, 137, 58, 0.5);
    flex-shrink: 0;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}

.map-banner__content {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    text-align: left;
}

.map-banner__badge {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gold-dark);
}

.map-banner__title {
    font-family: var(--font-display);
    font-size: 14px;
    color: var(--ink);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.map-banner__action {
    font-size: 12px;
    padding: 6px 14px;
    white-space: nowrap;
    min-height: auto;
}

.has-map-bg .cp-card {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(248, 242, 231, 0.84));
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(184, 137, 58, 0.38);
    box-shadow: 0 6px 22px rgba(43, 32, 24, 0.1);
}

.has-map-bg .cp-card[data-status="done"] {
    background: linear-gradient(180deg, rgba(240, 248, 233, 0.94), rgba(224, 236, 212, 0.88));
    border-color: rgba(95, 107, 72, 0.65);
}

/* --------------------------------------------------------------- AR page */

.ar-page {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100vw !important;
    max-width: 100vw !important;
    height: 100vh !important;
    height: 100dvh !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: hidden !important;
    background: #000;
}

/*
   Stacking on the AR page, bottom to top:
     0  the camera <video> AR.js injects into <body>
     1  the WebGL canvas (transparent, so the video shows through)
    10  the .ar-ui overlay
*/
.ar-page video,
.ar-page #arjs-video {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    z-index: 1 !important;
    max-width: none !important;
    max-height: none !important;
}

.ar-page a-scene {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    height: 100dvh !important;
    z-index: 2 !important;
    background: transparent !important;
    overflow: visible !important;
}

.ar-page canvas.a-canvas,
.ar-page .a-canvas {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    z-index: 3 !important;
    background: transparent !important;
    max-width: none !important;
    max-height: none !important;
    touch-action: none !important;
}

.ar-ui {
    position: fixed;
    inset: 0;
    z-index: 10;
    display: flex;
    flex-direction: column;
    pointer-events: none; /* only children opt back in */
}

.ar-ui > * { pointer-events: auto; }

/* top strip */
.ar-top {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--pad-top) var(--pad-right) 10px var(--pad-left);
    background: linear-gradient(180deg, rgba(23, 17, 12, .78), transparent);
}

.ar-top__back {
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: rgba(23, 17, 12, .55);
    border: 1px solid rgba(232, 220, 196, .3);
    color: var(--parchment);
    text-decoration: none;
    font-size: 18px;
    flex: 0 0 auto;
}

.ar-top__meta { min-width: 0; flex: 1; }

.ar-top__step {
    font-family: var(--font-ui);
    font-size: 11px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--gold-bright);
    /* "Checkpoint 4 of 5" at this tracking is wider than the strip leaves it
       once four icon buttons are in the row; clip rather than wrap, so the
       title below never gets pushed down. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ar-top__title {
    font-family: var(--font-display);
    font-size: 17px;
    color: var(--cream);
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ar-icon-btn {
    width: 42px;
    height: 42px;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1px solid rgba(232, 220, 196, .3);
    background: rgba(23, 17, 12, .55);
    color: var(--parchment);
    font-size: 17px;
    cursor: pointer;
}

.ar-icon-btn[aria-pressed="true"] {
    background: var(--gold);
    color: #2a1c08;
    border-color: var(--gold-bright);
}

/* 3D Model Floating Controls (Zoom & Rotate) */
.ar-model-controls {
    position: fixed;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 25;
    display: flex;
    flex-direction: column;
    gap: 7px;
    background: rgba(23, 17, 12, 0.78);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid rgba(255, 212, 121, 0.35);
    border-radius: 30px;
    padding: 8px 5px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    pointer-events: auto;
    touch-action: manipulation;
}

.ar-ctrl-btn {
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1px solid rgba(232, 220, 196, 0.22);
    background: rgba(255, 255, 255, 0.08);
    color: var(--gold-bright, #ffd479);
    font-size: 15px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s ease;
    user-select: none;
    -webkit-user-select: none;
}

.ar-ctrl-btn:active {
    background: var(--gold-bright, #ffd479);
    color: #17110c;
    transform: scale(0.92);
}

/* middle: hints & marker prompt */
.ar-middle {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px 16px;
    pointer-events: none;
}

.ar-hint {
    position: relative;
    font-family: var(--font-ui);
    font-size: 14px;
    text-align: center;
    color: var(--cream);
    background: rgba(23, 17, 12, .62);
    border: 1px solid rgba(232, 220, 196, .22);
    border-radius: var(--radius);
    padding: 12px 30px 12px 16px;
    max-width: 320px;
    backdrop-filter: blur(6px);
    transition: opacity .3s ease;
    /* The band around it stays click-through so taps reach the 3D behind;
       only the close button opts back in. */
    pointer-events: none;
}

.ar-hint[hidden] { display: none; }

.ar-hint__close {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--parchment-dim);
    font-size: 19px;
    line-height: 1;
    cursor: pointer;
    pointer-events: auto;
}

.ar-hint__close:active { color: var(--cream); }

.ar-hint__scan {
    display: block;
    width: 78px;
    height: 78px;
    margin: 0 auto 10px;
    border: 2px dashed rgba(224, 185, 105, .8);
    border-radius: 10px;
    animation: pulse 1.8s ease-in-out infinite;
}

@keyframes pulse {
    0%, 100% { opacity: .45; transform: scale(.94); }
    50%      { opacity: 1;   transform: scale(1.02); }
}

@media (prefers-reduced-motion: reduce) {
    .ar-hint__scan { animation: none; }
}

/* bottom: dialogue sits above the app bar and leaves the camera visible */
.ar-bottom {
    position: relative;
    padding: 18px var(--pad-right) 8px var(--pad-left);
    background: linear-gradient(0deg, rgba(23, 17, 12, .72) 55%, transparent);
}

/* --------------------------------------------------------- dialogue card */

.dialogue {
    width: 100%;
    max-width: 560px;
    margin: 0 auto 12px;
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, rgba(246, 239, 227, .97), rgba(233, 220, 196, .95));
    border: 1px solid rgba(184, 137, 58, .55);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.dialogue--flat {
    background: linear-gradient(180deg, #fbf6ec, #eee2cc);
    box-shadow: var(--shadow-soft);
}

.dialogue__head {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 12px;
    background: var(--narrator);
    color: var(--cream);
}

.dialogue[data-speaker="william"] .dialogue__head { background: var(--william); }

.dialogue__avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .18);
    border: 1px solid rgba(255, 255, 255, .35);
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    overflow: hidden;
}

.dialogue__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.dialogue__name {
    font-family: var(--font-display);
    font-size: 14px;
    letter-spacing: .06em;
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dialogue__collapse {
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    border: 0;
    background: none;
    color: #fff;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    transition: transform .28s ease;
}

.dialogue__speak {
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, .4);
    background: rgba(255, 255, 255, .15);
    color: #fff;
    font-size: 14px;
    cursor: pointer;
    display: grid;
    place-items: center;
}

.dialogue__speak[aria-pressed="true"] { background: rgba(255, 255, 255, .38); }

/* Collapsible region: header stays, body + controls fold away so the visitor
   can see the marker they are pointing at. */
.dialogue__panel {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows .28s ease, opacity .2s ease;
}

.dialogue__panel > div { overflow: hidden; }

.dialogue[data-collapsed="true"] .dialogue__panel {
    grid-template-rows: 0fr;
    opacity: 0;
}

.dialogue[data-collapsed="true"] .dialogue__collapse { transform: rotate(180deg); }

.dialogue__body {
    padding: 11px 14px 2px;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--ink);
    /* Deliberately small: this floats over a live camera. Roughly four lines,
       scrollable beyond that, and collapsible away entirely. */
    max-height: 14dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* Blinking cursor while the line is being typed out. */
.dialogue__caret {
    display: inline-block;
    width: 2px;
    height: 1em;
    margin-left: 1px;
    vertical-align: -0.14em;
    background: var(--brick);
    animation: caret 1s step-end infinite;
}

@keyframes caret { 50% { opacity: 0; } }

.dialogue[data-typing="false"] .dialogue__caret { display: none; }

@media (prefers-reduced-motion: reduce) {
    .dialogue__caret { animation: none; }
    .dialogue__panel { transition: none; }
}

.dialogue__foot {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 14px 9px;
}

.dialogue__dots { display: flex; gap: 6px; flex: 1; }

.dialogue__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: rgba(107, 88, 68, .3);
}

.dialogue__dot[data-active="true"] { background: var(--gold); }

.dialogue__nav {
    font-family: var(--font-ui);
    font-size: 13px;
    font-weight: 600;
    border: 0;
    background: none;
    color: var(--stone-dark);
    padding: 8px 6px;
    min-height: 40px;
    cursor: pointer;
}

.dialogue__nav--next { color: var(--brick); }

/* ------------------------------------------------------------ AR app bar */

/* A compact bottom bar instead of stacked full-width buttons — it keeps three
   actions reachable by thumb while giving the camera back most of the screen. */
.ar-appbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: flex;
    align-items: stretch;
    gap: 4px;
    padding: 6px max(6px, env(safe-area-inset-right)) var(--pad-bottom) max(6px, env(safe-area-inset-left));
    background: linear-gradient(0deg, rgba(15, 11, 7, .96), rgba(23, 17, 12, .88));
    border-top: 1px solid rgba(184, 137, 58, .35);
    backdrop-filter: blur(10px);
}

.ar-appbar__item {
    flex: 1 1 0;
    min-width: 0;
    min-height: 52px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 6px 4px;
    border: 0;
    border-radius: 14px;
    background: transparent;
    color: var(--parchment);
    font-family: var(--font-ui);
    text-decoration: none;
    cursor: pointer;
    touch-action: manipulation;
    transition: background .16s ease, transform .12s ease;
}

.ar-appbar__item:active { transform: scale(.96); }

.ar-appbar__icon { font-size: 17px; line-height: 1; }

.ar-appbar__label {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .02em;
    max-width: 100%;
    text-align: center;
    /* Labels change at runtime ("Rebuilding…"), so never let one wrap the bar. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The checkpoint's own action gets the gold treatment. */
.ar-appbar__item--primary {
    flex: 1.6 1 0;
    color: #2a1c08;
    background: linear-gradient(180deg, var(--gold-bright), var(--gold));
    box-shadow: 0 4px 14px rgba(184, 137, 58, .35);
}

.ar-appbar__item--primary .ar-appbar__icon { font-size: 18px; }

.ar-appbar__item[disabled] { opacity: .5; pointer-events: none; }

/* The overlay column must stop above the bar. */
.ar-ui { padding-bottom: 78px; }

/* --------------------------------------------------------- info sheet */

.sheet {
    position: fixed;
    inset: 0;
    z-index: 40;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(12, 9, 6, .6);
    backdrop-filter: blur(3px);
    padding: 16px;
    padding-bottom: var(--pad-bottom);
}

.sheet[hidden] { display: none; }

.sheet__panel {
    width: 100%;
    max-width: 560px;
    max-height: 78dvh;
    overflow-y: auto;
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, #fbf6ec, #eadcc2);
    border: 1px solid rgba(184, 137, 58, .6);
    box-shadow: var(--shadow);
    padding: 20px;
    animation: rise .28s ease;
}

@keyframes rise {
    from { transform: translateY(24px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

.sheet__year {
    font-family: var(--font-display);
    font-size: 30px;
    color: var(--brick);
    margin: 0 0 2px;
}

.sheet__role {
    font-family: var(--font-ui);
    font-size: 11px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--stone);
    margin-bottom: 8px;
}

.sheet__title { font-size: 20px; margin-bottom: 8px; }
.sheet__text { font-size: 15px; line-height: 1.65; color: var(--ink-soft); }

/* The builder portraits are badge illustrations that carry their own frame and
   name banner, so they are shown whole rather than cropped into a circle. */
.sheet__figure {
    width: 140px;
    height: 140px;
    margin: 0 auto 14px;
    display: block;
}

.sheet__figure img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    filter: drop-shadow(0 4px 10px rgba(23, 17, 12, .22));
}

.sheet__close {
    margin-top: 16px;
    width: 100%;
}

/* -------------------------------------------------------- error overlay */

.ar-error {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: linear-gradient(180deg, #241a12, #120d09);
}

.ar-error[hidden] { display: none; }

.ar-error__panel {
    max-width: 420px;
    text-align: center;
    color: var(--parchment);
}

.ar-error__icon { font-size: 44px; margin-bottom: 12px; }
.ar-error__title { color: var(--cream); font-size: 22px; }
.ar-error__text { font-size: 15px; color: var(--parchment-dim); }
.ar-error__text code {
    font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
    font-size: 13px;
    background: rgba(246, 239, 227, .1);
    padding: 2px 6px;
    border-radius: 6px;
}

/* --------------------------------------------------------- ending page */

.ending-bg-backdrop {
    position: fixed;
    inset: 0;
    z-index: 0;
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    opacity: 0.28;
    filter: saturate(1.1) brightness(0.8);
    pointer-events: none;
    transform: translateZ(0);
}

.ending-bg-overlay {
    position: fixed;
    inset: 0;
    z-index: 0;
    background: radial-gradient(circle at 50% 25%, rgba(36, 26, 18, 0.45) 0%, rgba(23, 17, 12, 0.85) 60%, rgba(18, 13, 9, 0.98) 100%);
    pointer-events: none;
}

.page--ending {
    position: relative;
    z-index: 1;
    background: transparent !important;
}

.topbar--ending {
    justify-content: space-between;
    margin-bottom: 12px;
}

.topbar__title--ending {
    font-family: var(--font-display);
    font-size: 16px;
    color: var(--gold-bright);
    letter-spacing: 0.05em;
}

.ending-hero {
    text-align: center;
    margin-bottom: 24px;
}

.ending-artwork {
    position: relative;
    max-width: 480px;
    width: 100%;
    margin: 6px auto 14px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.65), 0 0 0 1px rgba(224, 185, 105, 0.4);
    background: #17110c;
    cursor: pointer;
}

.ending-artwork__img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: contain;
    transition: transform 0.3s ease;
}

.ending-artwork:hover .ending-artwork__img {
    transform: scale(1.015);
}

.ending-artwork-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
    margin: 0 auto 24px;
    flex-wrap: wrap;
    max-width: 480px;
}

.ending-modal__panel {
    max-width: 580px;
    max-height: 94vh;
    padding: 16px;
    overflow-y: auto;
    background: rgba(28, 20, 14, 0.96);
    border: 1px solid rgba(224, 185, 105, 0.5);
    border-radius: var(--radius-lg);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.85);
}

.ending-modal__top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
}

.ending-modal__title {
    font-family: var(--font-display);
    font-size: 16px;
    color: var(--gold-bright);
    letter-spacing: 0.04em;
}

.ending-modal__body {
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    background: #000;
}

.ending-modal__img {
    display: block;
    width: 100%;
    height: auto;
}

.ending-seal {
    width: 120px;
    height: 120px;
    margin: 0 auto 18px;
    display: block;
    filter: drop-shadow(0 8px 22px rgba(184, 137, 58, .45));
}

.ending__heading {
    text-align: center;
    /* "Congratulations" is 15 characters of Cinzel — 8vw is the largest step
       that still fits a 360px phone without clipping. */
    font-size: clamp(24px, 8vw, 46px);
    color: var(--gold-bright);
    margin-bottom: 4px;
    overflow-wrap: break-word;
}

.ending__sub {
    text-align: center;
    font-family: var(--font-ui);
    font-size: 13px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: rgba(232, 220, 196, .6);
    margin-bottom: 24px;
}

.ending__cards {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-bottom: 26px;
}

.ending__cards .dialogue { margin-bottom: 0; }
.ending__cards .dialogue__body { max-height: none; }

/* --------------------------------------------------------------- footer */

.foot-note {
    font-family: var(--font-ui);
    font-size: 12px;
    color: rgba(232, 220, 196, .45);
    text-align: center;
    padding: 18px 0 6px;
}

.page--parchment .foot-note { color: rgba(43, 32, 24, .5); }

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------- landscape tweaks */

@media (orientation: landscape) and (max-height: 520px) {
    .ar-bottom { padding-top: 8px; }
    .dialogue__body { max-height: 26dvh; font-size: 14px; padding: 8px 12px 2px; }
    .dialogue { max-width: 60vw; margin-left: 0; }
    .ar-middle { display: none; }
    .ar-appbar__item { flex-direction: row; gap: 7px; min-height: 44px; }
    .ar-appbar__label { font-size: 12px; }
    .ar-ui { padding-bottom: 60px; }
    .hero { padding: 8px 0; }
    .hero__crest { width: 72px; height: 72px; margin-bottom: 8px; }
}

@media (min-width: 720px) {
    .cp-card__title { font-size: 20px; }
    .dialogue__body { font-size: 16.5px; }
}

/* ------------------------------------------------------------- AR toast */

/* Sits inside .ar-bottom and floats just above it, so it clears the dialogue
   card whatever height that card happens to be. */
.ar-toast {
    position: absolute;
    left: 50%;
    transform: translateX(-50%) translateY(10px);
    bottom: 100%;
    margin-bottom: 8px;
    z-index: 30;
    max-width: min(88vw, 420px);
    padding: 10px 16px;
    border-radius: 999px;
    font-family: var(--font-ui);
    font-size: 13.5px;
    text-align: center;
    color: var(--cream);
    background: rgba(23, 17, 12, .86);
    border: 1px solid rgba(224, 185, 105, .5);
    box-shadow: var(--shadow-soft);
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s ease, transform .25s ease;
}

.ar-toast[data-visible="true"] {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}




/* ---------------------------------------------------------- ?debug=1 panel */

.ar-debug {
    position: fixed;
    inset: auto 8px calc(var(--pad-bottom) + 84px) 8px;
    z-index: 90;
    max-height: 56dvh;
    overflow: auto;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: rgba(10, 8, 5, .95);
    border: 1px solid var(--gold);
    color: var(--parchment);
    font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
    font-size: 11px;
    line-height: 1.5;
}

.ar-debug strong {
    display: block;
    font-family: var(--font-ui);
    font-size: 12px;
    color: var(--gold-bright);
    margin-bottom: 8px;
}

.ar-debug pre {
    margin: 0 0 10px;
    white-space: pre-wrap;
    word-break: break-all;
}

.ar-debug b { color: var(--gold-bright); font-weight: 600; }

.ar-debug button {
    font-family: var(--font-ui);
    font-size: 12px;
    margin-right: 6px;
    padding: 7px 14px;
    min-height: 36px;
    border-radius: 999px;
    border: 1px solid rgba(232, 220, 196, .35);
    background: rgba(246, 239, 227, .1);
    color: var(--parchment);
}

/* ================================================== 3D view sheet + speaker */

.model-sheet {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 12px;
    padding-bottom: var(--pad-bottom);
    background: rgba(12, 9, 6, .72);
    backdrop-filter: blur(4px);
}

.model-sheet[hidden] { display: none; }

.model-sheet__panel {
    width: 100%;
    max-width: 560px;
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-lg);
    background: linear-gradient(180deg, #241a12, #17110c);
    border: 1px solid rgba(184, 137, 58, .55);
    box-shadow: var(--shadow);
    overflow: hidden;
    animation: rise .28s ease;
}

.model-sheet__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 8px 11px 16px;
    border-bottom: 1px solid rgba(184, 137, 58, .28);
}

.model-sheet__title {
    flex: 1;
    font-family: var(--font-display);
    font-size: 15px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--gold-bright);
}

.model-sheet__close {
    width: 38px;
    height: 38px;
    border: 0;
    background: none;
    color: var(--parchment-dim);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
}

/* The turntable. Fixed aspect so the canvas never collapses to zero height. */
.model-sheet__stage {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    max-height: 46dvh;
    background:
        radial-gradient(70% 60% at 50% 38%, rgba(184, 137, 58, .16), transparent 70%),
        #12100c;
}

.model-sheet__canvas { display: block; width: 100%; height: 100%; }

.model-sheet__loading {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-family: var(--font-ui);
    font-size: 13px;
    color: var(--parchment-dim);
}

.model-sheet__loading[hidden] { display: none; }

.model-sheet__picker {
    display: flex;
    gap: 8px;
    padding: 12px 14px 0;
}

.model-sheet__pick {
    flex: 1;
    min-height: 42px;
    padding: 9px 12px;
    border-radius: 999px;
    border: 1px solid rgba(232, 220, 196, .28);
    background: rgba(246, 239, 227, .06);
    color: var(--parchment);
    font-family: var(--font-ui);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}

.model-sheet__pick[aria-pressed="true"] {
    background: linear-gradient(180deg, var(--gold-bright), var(--gold));
    border-color: var(--gold-bright);
    color: #2a1c08;
}

.model-sheet__caption {
    margin: 10px 16px 0;
    font-family: var(--font-ui);
    font-size: 12.5px;
    color: var(--parchment-dim);
    text-align: center;
}

/* .model-sheet__actions is gone with the "Open in AR" button it held; the
   sheet's caption is now its last row, so it carries the bottom padding. */
.model-sheet__caption { padding-bottom: 16px; }

/* ------------------------------------------------------------ the speakers */

/* Both figures sit in the same box at the left edge and cross-fade, so
   changing speaker never waits on a fetch. */
.ar-speakers {
    position: fixed;
    left: 0;
    bottom: 0;
    z-index: 5;
    height: 56dvh;
    max-height: 470px;
    pointer-events: none;
}

.ar-speaker {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 100%;
    background-repeat: no-repeat;
    background-position: 0% 0;

    /* Idle: gone. Only the speaker is ever on screen. */
    opacity: 0;
    filter: saturate(.8) brightness(.7) drop-shadow(0 8px 24px rgba(0, 0, 0, .6));
    transform: translateX(-24%) translateY(6%) scale(.97);
    transform-origin: bottom left;
    transition: opacity .4s ease, filter .4s ease, transform .4s ease;
}

/* Whoever is speaking. */
.ar-speaker[data-active="true"] {
    opacity: 1;
    filter: saturate(1) brightness(1) drop-shadow(0 10px 28px rgba(0, 0, 0, .65));
    transform: translateX(-18%) translateY(0) scale(1);
}

/* The one who is not speaking goes entirely. A faint ghost behind the active
   figure read as an overlap rather than as company, and pulled the eye away
   from whoever was actually talking. */

/*
   Sprite strip: one still pose per line of narration, not a loop.

   Cycling the frames read as fidgeting rather than storytelling, so the frame
   is chosen when the line changes and then held. ar-boot.js sets
   background-position-x; with N frames on an N00%-wide strip, frame i sits at
   i / (N - 1) of the position — 0%, 25%, 50%, 75%, 100% for five.

   Only the change is eased, so a new pose settles instead of snapping.
*/
.ar-speaker[data-animated="true"] {
    transition: opacity .4s ease, filter .4s ease, transform .4s ease,
                background-position-x .25s ease;
}

@media (orientation: landscape) and (max-height: 520px) {
    .ar-speakers { height: 92dvh; }
}

@media (prefers-reduced-motion: reduce) {
    .ar-speaker,
    .ar-speaker[data-animated="true"] { transition: none; }
}

/* Gyroscope off: same icon, visibly inactive rather than a different glyph. */
.ar-icon-btn.is-off { opacity: .55; }
.ar-icon-btn[disabled] { opacity: .35; pointer-events: none; }

/* ============================================================== the scanner
   /scan — the in-app QR reader.

   Structurally the same idea as the AR page: a full-bleed camera with a fixed
   overlay on top of it. It does NOT reuse .ar-page, because that hides
   overflow to keep the A-Frame canvas still, and this page has to scroll to
   the "already found" list underneath.
   ========================================================================== */

.scan-page {
    background: var(--night);
    color: var(--cream);
}

.scanner {
    position: relative;
    min-height: 100dvh;
    overflow: hidden;
}

.scanner__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #000;
}

/* Darkened so the white overlay text stays legible over whatever the camera
   happens to be pointing at. */
.scanner__shade {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(180deg, rgba(23, 17, 12, .78) 0%, rgba(23, 17, 12, .18) 32%,
                        rgba(23, 17, 12, .3) 62%, rgba(23, 17, 12, .9) 100%);
}

.scanner__ui {
    position: relative;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    padding: var(--pad-top) var(--pad-right) var(--pad-bottom) var(--pad-left);
    gap: 14px;
}

.scanner__top {
    display: flex;
    align-items: center;
    gap: 12px;
}

.scanner__top-meta { flex: 1; min-width: 0; }

.scanner__title {
    font-size: 19px;
    color: var(--cream);
    margin: 0;
    text-shadow: 0 2px 10px rgba(0, 0, 0, .6);
}

/* --------------------------------------------------------------- reticle */

.scanner__frame {
    position: relative;
    width: min(70vw, 300px);
    aspect-ratio: 1;
    margin: auto;
    flex: 0 0 auto;
}

.scanner__frame span {
    position: absolute;
    width: 34px;
    height: 34px;
    border: 3px solid var(--gold-bright);
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .5));
}

.scanner__frame span:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0; }
.scanner__frame span:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; border-radius: 0 6px 0 0; }
.scanner__frame span:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; border-radius: 0 0 0 6px; }
.scanner__frame span:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; border-radius: 0 0 6px 0; }

/* A slow pulse says "still looking" without implying a progress bar. */
.scanner[data-state="scanning"] .scanner__frame span { animation: scanner-pulse 1.9s ease-in-out infinite; }
.scanner[data-state="found"]    .scanner__frame span { border-color: #7fd18a; animation: none; }

@keyframes scanner-pulse {
    0%, 100% { opacity: .55; }
    50%      { opacity: 1; }
}

.scanner__hint {
    text-align: center;
    font-family: var(--font-ui);
    font-size: 14px;
    line-height: 1.5;
    color: var(--cream);
    background: rgba(23, 17, 12, .62);
    border: 1px solid rgba(224, 185, 105, .28);
    border-radius: 999px;
    padding: 9px 16px;
    margin: 0 auto;
    max-width: 34em;
    backdrop-filter: blur(6px);
}

/* -------------------------------------------------------------- the bottom */

.scanner__bottom {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: center;
    text-align: center;
}

.scanner__note {
    font-size: 13px;
    line-height: 1.6;
    color: rgba(246, 239, 227, .82);
    max-width: 34em;
    margin: 0;
}

.notice--dark {
    background: rgba(140, 74, 47, .3);
    border-color: rgba(224, 185, 105, .45);
    color: var(--cream);
}

/* ------------------------------------------------------------ manual entry */

.scanner__manual {
    width: 100%;
    max-width: 420px;
    background: rgba(23, 17, 12, .72);
    border: 1px solid rgba(224, 185, 105, .3);
    border-radius: var(--radius);
    padding: 14px;
    text-align: left;
}

.scanner__label {
    display: block;
    font-family: var(--font-ui);
    font-size: 12px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gold-bright);
    margin-bottom: 8px;
}

.scanner__row { display: flex; gap: 8px; }

.scanner__input {
    flex: 1;
    min-width: 0;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
    /* 16px exactly: anything smaller and iOS zooms the page on focus. */
    font-size: 16px;
    letter-spacing: .12em;
    color: var(--cream);
    background: rgba(0, 0, 0, .35);
    border: 1px solid rgba(246, 239, 227, .28);
    border-radius: 10px;
    padding: 11px 12px;
}

.scanner__input:focus {
    outline: 2px solid var(--gold);
    outline-offset: 1px;
}

.scanner__go { width: auto; padding-inline: 20px; }

/* ---------------------------------------------------------- camera refused */

.scanner__fallback {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 22px;
    background: rgba(18, 13, 9, .93);
}

.scanner__fallback[hidden] { display: none; }

.scanner__fallback-panel {
    max-width: 420px;
    text-align: center;
    color: var(--cream);
}

.scanner__fallback-panel h2 { color: var(--gold-bright); font-size: 21px; }
.scanner__fallback-panel p { font-size: 14px; line-height: 1.65; color: rgba(246, 239, 227, .86); }
.scanner__fallback-icon { font-size: 40px; margin-bottom: 10px; }

/* ------------------------------------------------------------ already found */

.scan-found {
    position: relative;
    background: linear-gradient(180deg, #17110c, #120d09);
    padding: 26px 0 34px;
}

.scan-found__head {
    font-size: 15px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 14px;
}

.scan-found .cp-card {
    background: rgba(246, 239, 227, .94);
}

@media (prefers-reduced-motion: reduce) {
    .scanner[data-state="scanning"] .scanner__frame span { animation: none; opacity: .85; }
}

/*
   Narrow phones: the panorama's top strip carries four icon buttons (voice,
   voice source, gyroscope, 3D view) once the 3D sheet moved up here, and at
   42px each that squeezes the checkpoint title into two lines on a 360px
   screen. Shrink the buttons rather than the title — 36px is still comfortably
   over the 24px minimum touch target once the padding around them is counted.
*/
@media (max-width: 400px) {
    .ar-top { gap: 7px; }

    .ar-top__back,
    .ar-icon-btn {
        width: 36px;
        height: 36px;
        font-size: 15px;
    }

    .ar-top__step { font-size: 9.5px; letter-spacing: .1em; }
    .ar-top__title { font-size: 16px; }
}

/* ========================================================== the celebration
   The popup shown the instant a checkpoint's QR code opens it, plus its
   confetti canvas. See resources/views/partials/scan-success.blade.php and
   public/js/celebrate.js.

   --cheer-accent is set per checkpoint from the inline style attribute, so
   each stop has its own colour without a stylesheet per checkpoint.
   ========================================================================== */

.cheer {
    position: fixed;
    inset: 0;
    z-index: 60;                    /* over the app bar (20) and the sheets */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--pad-top) 20px var(--pad-bottom);
    background: rgba(14, 10, 6, .82);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: cheer-in .28s ease both;

    /* The scroll lives HERE, not on the card.
       A scroll container clips its children, and the seal deliberately hangs
       half-way outside the card's top edge — putting overflow on the card cut
       33 of its 68 pixels clean off. */
    overflow-y: auto;
    overscroll-behavior: contain;
}

@keyframes cheer-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Full-bleed, and never in the way: the card sits above it. */
.cheer__confetti {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.cheer__card {
    position: relative;
    width: 100%;
    max-width: 360px;
    flex: 0 0 auto;
    text-align: center;
    /* Room for the seal's overhang, so it never lands on the scrim edge. */
    margin-top: 38px;
    padding: 54px 24px 24px;
    border-radius: var(--radius-lg);
    background:
        radial-gradient(120% 70% at 50% 0%, rgba(255, 255, 255, .6), transparent 60%),
        linear-gradient(180deg, var(--cream) 0%, var(--parchment) 100%);
    border: 1px solid rgba(184, 137, 58, .55);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
    animation: cheer-rise .42s cubic-bezier(.16, 1, .3, 1) both;
}

@keyframes cheer-rise {
    from { transform: translateY(22px) scale(.94); opacity: 0; }
    to   { transform: none; opacity: 1; }
}

/* ------------------------------------------------------------- the seal */

/* Half outside the card, like a wax seal pressed over its edge. */
.cheer__seal {
    position: absolute;
    top: -34px;
    left: 50%;
    transform: translateX(-50%);
    width: 68px;
    height: 68px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: radial-gradient(circle at 34% 28%, #fff6e2, var(--cheer-accent) 78%);
    border: 3px solid var(--cream);
    box-shadow: 0 8px 20px rgba(0, 0, 0, .4);
    animation: cheer-stamp .5s cubic-bezier(.34, 1.56, .64, 1) .1s both;
}

/* Pressed down, the way a stamp lands. */
@keyframes cheer-stamp {
    from { transform: translateX(-50%) scale(.3) rotate(-18deg); opacity: 0; }
    to   { transform: translateX(-50%) scale(1) rotate(0); opacity: 1; }
}

.cheer__seal-emblem {
    font-size: 30px;
    line-height: 1;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .3));
}

/* -------------------------------------------------------------- the copy */

.cheer__eyebrow {
    font-family: var(--font-ui);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--cheer-accent);
    margin: 0 0 10px;
}

.cheer__step {
    display: block;
    letter-spacing: .14em;
    color: var(--stone);
    font-weight: 600;
    margin-bottom: 3px;
}

.cheer__hooray {
    font-family: var(--font-display);
    font-size: 27px;
    line-height: 1.1;
    color: var(--brick);
    margin: 0 0 6px;
}

.cheer__title {
    font-family: var(--font-display);
    font-size: 17px;
    color: var(--ink);
    margin: 0 0 8px;
}

.cheer__blurb {
    font-size: 14px;
    line-height: 1.6;
    color: var(--ink-soft);
    margin: 0 0 18px;
}

/* ------------------------------------------------------------- the stamps */

.cheer__stamps {
    display: flex;
    gap: 7px;
    justify-content: center;
    margin-bottom: 8px;
}

.cheer__stamp {
    width: 26px;
    height: 26px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    font-family: var(--font-ui);
    font-size: 11px;
    font-weight: 700;
    border: 1.5px dashed rgba(43, 32, 24, .3);
    color: rgba(43, 32, 24, .4);
}

.cheer__stamp[data-state="found"] {
    border-style: solid;
    border-color: transparent;
    background: rgba(95, 107, 72, .85);
    color: var(--cream);
}

/* The one just scanned: accented, and given a beat of its own. */
.cheer__stamp[data-state="now"] {
    border-style: solid;
    border-color: transparent;
    background: var(--cheer-accent);
    color: #fff;
    transform: scale(1.16);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .55);
    animation: cheer-pop .45s cubic-bezier(.34, 1.56, .64, 1) .34s both;
}

@keyframes cheer-pop {
    from { transform: scale(.4); opacity: 0; }
    to   { transform: scale(1.16); opacity: 1; }
}

.cheer__count {
    font-family: var(--font-ui);
    font-size: 12px;
    color: var(--stone);
    margin: 0 0 18px;
}

.cheer__go {
    max-width: none;
    background: linear-gradient(180deg, var(--gold-bright), var(--cheer-accent));
    border-color: var(--cheer-accent);
}

/* ------------------------------------------------------------ small print */

@media (max-height: 620px) {
    .cheer__card { padding-top: 46px; }
    .cheer__seal { width: 58px; height: 58px; top: -29px; }
    .cheer__seal-emblem { font-size: 25px; }
    .cheer__hooray { font-size: 23px; }
    .cheer__blurb { margin-bottom: 12px; }
}

/*
   Reduced motion: the card still appears, because it carries information the
   visitor needs. Only the movement goes. celebrate.js checks the same query
   and skips the confetti entirely rather than drawing it still.
*/
@media (prefers-reduced-motion: reduce) {
    .cheer,
    .cheer__card,
    .cheer__seal,
    .cheer__stamp[data-state="now"] {
        animation: none;
    }

    .cheer__stamp[data-state="now"] { transform: scale(1.16); }
}

/* ------------------------------------------------- the celebration banner
   Stage 1 of the scan celebration: the artwork from assets/popup/, alone on
   the scrim for a beat before the card arrives.

   Sized on width alone. The art is a wide banner with its own transparent
   margin, so height follows from the aspect ratio and there is nothing to
   letterbox.
   ========================================================================== */

.cheer__banner {
    position: relative;
    width: 100%;
    max-width: 460px;
    text-align: center;
    animation: cheer-banner .58s cubic-bezier(.2, 1.5, .35, 1) both;
}

.cheer__banner img {
    display: block;
    width: 100%;
    height: auto;
    /* The art has its own glow; this grounds it on the dark scrim without
       adding a visible edge. */
    filter: drop-shadow(0 18px 34px rgba(0, 0, 0, .55));
}

/* Overshoot and settle — a banner that slides in politely does not read as a
   celebration. */
@keyframes cheer-banner {
    0%   { transform: scale(.5) translateY(26px); opacity: 0; }
    100% { transform: none; opacity: 1; }
}

.cheer__tap {
    font-family: var(--font-ui);
    font-size: 12px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: rgba(246, 239, 227, .62);
    margin: 14px 0 0;
    /* Held back until the auto-advance is nearly due, so it only appears for
       somebody who is looking at it rather than through it. */
    animation: cheer-fade-in .5s ease 1.5s both;
}

@keyframes cheer-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Stage 2 arrives while stage 1 is still leaving, and both are flex items of
   .cheer for that moment. Left in the row the banner is squeezed from 335px to
   67px by the card claiming its width — the exit reads as a sideways squash
   instead of a lift. Taking it out of flow lets the card have the row while the
   banner animates away over the top of it. */
.cheer__banner[data-leaving="true"] {
    position: absolute;
    left: 50%;
    top: 50%;
    /* An absolutely positioned element resolves 100% against its containing
       block's PADDING box, so the 20px the scrim pads by has to come back off
       or the banner jumps 335px -> 375px as it starts to leave. */
    width: min(calc(100% - 40px), 460px);
    margin: 0;
    transform-origin: center;
    animation: cheer-banner-out .3s ease both;
    pointer-events: none;
}

/* Centred by hand, because the element is absolute now and the flex
   centring no longer applies to it. */
@keyframes cheer-banner-out {
    from { transform: translate(-50%, -50%) scale(1); opacity: 1; }
    to   { transform: translate(-50%, -50%) scale(1.08) translateY(-18px); opacity: 0; }
}

@media (max-width: 400px) {
    .cheer__banner { max-width: 100%; }
    .cheer__tap { font-size: 11px; }
}

@media (prefers-reduced-motion: reduce) {
    .cheer__banner,
    .cheer__banner[data-leaving="true"],
    .cheer__tap { animation: none; }
}
