:root {
    --bg: #000;
    --fg: #f5f5f4;
    --accent: #d6ff3c;
    --panel: rgba(10, 10, 10, 0.55);
    --panel-strong: rgba(10, 10, 10, 0.75);
    --panel-border: rgba(255, 255, 255, 0.12);
    --font-display: "Inter", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font-display);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    /* The page is non-scrolling — POI navigation is tap-only. The story
       sections collapse to height: 0 below; this guards against any
       residual scroll height from late-loaded panels. */
    overflow: hidden;
    height: 100%;
    overscroll-behavior: none;
    /* Disable browser-level touch gestures (scroll, pinch-to-zoom,
       double-tap zoom). This is what was breaking iOS pinch after the
       first user-initiated `play()` — iOS engaged a media-aware gesture
       session that consumed the pinch before PlayCanvas saw it. With
       touch-action: none the browser delivers raw pointer events. */
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
}

/* Persistent background viewer iframe.
   pointer-events: auto so click+drag rotates the camera at any moment.
   Wheel + 1-finger touch are forwarded back up to the parent for scrolling
   (handled inside the viewer's bridge script). */
#viewer-frame {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    border: 0;
    background: #000;
    z-index: 0;
}

body.free-roam .panel {
    opacity: 0 !important;
    transition: opacity 0.4s ease;
    pointer-events: none;
}

/* Loader (covers page until viewer reports first frame). */
#loader {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.6s ease;
}
#loader.hidden {
    opacity: 0;
    pointer-events: none;
}
.loader-inner { width: min(420px, 70vw); text-align: center; }
.loader-bar {
    width: 100%;
    height: 2px;
    background: rgba(255, 255, 255, 0.15);
    overflow: hidden;
    margin-bottom: 1rem;
    position: relative;
}
.loader-bar-fill {
    height: 100%;
    width: 30%;
    background: var(--accent);
    transform: translateX(-100%);
    animation: loaderSlide 1.6s cubic-bezier(.5,0,.5,1) infinite;
}
@keyframes loaderSlide {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(400%); }
}
.loader-text {
    font-size: 0.75rem;
    letter-spacing: 0.4em;
    color: rgba(255, 255, 255, 0.55);
}

/* Brand: KAUST logo + ANPERC – HIGH BAY wordmark. Clickable — jumps the
   tour back to the top. */
#brand {
    position: fixed;
    top: 1.4rem;
    left: 1.6rem;
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 0.95rem;
    cursor: pointer;
    user-select: none;
    background: transparent;
    border: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    transition: transform 0.2s ease, opacity 0.2s ease;
}
#brand:hover {
    transform: translateY(-1px);
}
#brand:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
    border-radius: 4px;
}
#kaust-logo {
    height: 38px;
    width: auto;
    user-select: none;
    /* Single soft shadow — readable, not heavy. */
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.45));
}
.brand-text {
    font-size: 0.82rem;
    letter-spacing: 0.32em;
    font-weight: 600;
    color: var(--fg);
    transition: opacity 0.4s ease;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}

/* Story scroll container */
#story {
    position: relative;
    z-index: 10;
    pointer-events: none;
}

/* Story sections collapse to zero height — there's no page scroll any
   more. Annotation panels are position:fixed so they don't depend on
   section height for placement. */
.section {
    position: relative;
    height: 0;
    min-height: 0;
    width: 100vw;
    pointer-events: none;
}
#story { height: 0; min-height: 0; }

/* POI panels are pinned to the top-left, directly below the POI menu. */
.section--annotation .panel {
    position: fixed;
    left: 1.6rem;
    top: 27rem;
    margin: 0;
    width: clamp(220px, 22vw, 320px);
    max-width: 320px;
    max-height: calc(100vh - 28rem);
    overflow-y: auto;
    text-align: left;
    /* Right padding clears the universal close button at top-right. */
    padding-right: 2.6rem;
}

.panel {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 1.6rem 1.8rem;
    background: var(--panel);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--panel-border);
    border-radius: 4px;
    opacity: 0;
    transform: translateY(20px);
    pointer-events: auto;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
    will-change: opacity, transform;
}

.panel-eyebrow {
    font-size: 0.65rem;
    letter-spacing: 0.4em;
    color: var(--accent);
    margin-bottom: 0.7rem;
    text-transform: uppercase;
}
.panel-title {
    font-size: clamp(1.5rem, 2.6vw, 2.4rem);
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1.15;
    margin: 0 0 0.85rem;
}
.panel-text {
    font-size: 1rem;
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.78);
    margin: 0;
}

.panel-tags {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.panel-tags li {
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    color: rgba(255, 255, 255, 0.78);
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    padding: 0.25rem 0.65rem;
}

/* Collapse toggle for annotation panels. Hidden on desktop — body-text
   panels there have plenty of room — shown only inside the mobile layout. */
.panel-collapse { display: none; }

/* Manual close button — the proximity loop normally manages panel
   visibility, but the user can dismiss the current panel with this if
   they don't want to read it. The dismissal resets when the camera
   leaves the POI's exit radius, so coming back later shows it again. */
.panel-close {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    width: 24px;
    height: 24px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: rgba(255, 255, 255, 0.85);
    border-radius: 3px;
    font-size: 1.05rem;
    line-height: 1;
    padding: 0;
    cursor: pointer;
    z-index: 1;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.panel-close:hover {
    background: rgba(255, 90, 90, 0.18);
    border-color: rgba(255, 90, 90, 0.5);
    color: #ffd9d9;
}

.kbd-row { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; margin-top: 0.5rem; }
kbd {
    display: inline-block;
    padding: 0.2rem 0.55rem;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 3px;
}

/* Persistent POI menu, pinned just below the KAUST logo at top-left. */
#poi-menu {
    position: fixed;
    left: 1.6rem;
    top: 4.6rem;
    transform: none;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    /* Top padding leaves room for the help + collapse buttons anchored
       top-right (collapse) and top-left (help). */
    padding: 2.4rem 0.9rem 0.85rem;
    background: var(--panel-strong);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--panel-border);
    border-radius: 6px;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
    min-width: 200px;
    transition: opacity 0.3s ease, transform 0.3s ease;
}
.poi-body {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
/* Collapse toggle anchored top-LEFT of the menu (mirror of the help
   button's top-right). When collapsed, the body is hidden and the menu
   shrinks to just the title bar. */
.poi-collapse {
    position: absolute;
    top: 0.4rem;
    left: 0.4rem;
    width: 26px;
    height: 26px;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: rgba(255, 255, 255, 0.85);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    z-index: 1;
}
.poi-collapse:hover { background: rgba(255, 255, 255, 0.12); }
#poi-menu.collapsed .poi-body { display: none; }
#poi-menu.collapsed { padding: 0.4rem 0.9rem; min-width: 0; }
/* When the menu is collapsed, drop the room reserved for the buttons —
   the title bar is the whole panel. */
#poi-menu.collapsed .btn-help,
#poi-menu.collapsed .poi-collapse {
    position: static;
    display: inline-block;
}
#poi-menu.collapsed {
    display: inline-flex;
    flex-direction: row;
    gap: 0.4rem;
    align-items: center;
}

.poi-list {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.poi-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.5rem 0.65rem;
    background: transparent;
    border: 0;
    color: rgba(255, 255, 255, 0.7);
    font-family: inherit;
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    text-align: left;
    cursor: pointer;
    border-radius: 3px;
    transition: background 0.15s ease, color 0.15s ease;
    width: 100%;
}
.poi-item:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--fg);
}
.poi-item.active {
    color: var(--fg);
    background: rgba(214, 255, 60, 0.08);
}
.poi-item.active .poi-num {
    background: var(--accent);
    color: #000;
    border-color: var(--accent);
}
.poi-num {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.25);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.85);
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.poi-label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.poi-actions {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-top: 0.4rem;
    padding-top: 0.6rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.poi-btn {
    width: 100%;
    padding: 0.6rem 0.75rem;
    border: 1px solid rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.05);
    color: var(--fg);
    font-family: inherit;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.32em;
    cursor: pointer;
    border-radius: 3px;
    transition: background 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}
.poi-btn:hover {
    background: rgba(255, 255, 255, 0.12);
    transform: translateY(-1px);
}
.poi-btn--explore {
    background: var(--accent);
    color: #000;
    border-color: var(--accent);
}
.poi-btn--explore:hover {
    background: #c8f02b;
    box-shadow: 0 6px 18px rgba(214, 255, 60, 0.3);
}
.poi-btn--exit {
    background: rgba(255, 90, 90, 0.18);
    border-color: rgba(255, 90, 90, 0.45);
    color: #ffd9d9;
}
.poi-btn--exit:hover {
    background: rgba(255, 90, 90, 0.32);
}

/* FPS counter — visible only with ?debug in the URL. Reads the iframe's
   actual postrender rate (the splat viewer uses on-demand rendering so
   this fluctuates with scene activity, e.g. it climbs while a video
   screen is decoding new frames). */
.debug-fps {
    position: fixed;
    top: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 90;
    padding: 0.25rem 0.6rem;
    background: rgba(15, 15, 15, 0.85);
    border: 1px solid rgba(214, 255, 60, 0.45);
    color: var(--accent);
    font-size: 0.72rem;
    letter-spacing: 0.18em;
    border-radius: 3px;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}
body:not([data-mm-debug="true"]) .debug-fps { display: none; }

/* PICK COORD helper — gated by ?debug. Lets the operator point at a
   collision surface (any wall / floor / equipment in the voxel grid)
   and capture its world coordinate, ready to drop into a manifest. */
.pick-coord {
    position: fixed;
    /* Sits just below the FPS pill at the top-centre of the viewport
       so it doesn't compete with the brand (top-left) or the minimap
       (top-right). */
    top: 2.5rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 85;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.5rem;
    background: rgba(15, 15, 15, 0.92);
    border: 1px solid rgba(214, 255, 60, 0.45);
    border-radius: 4px;
    font-size: 0.65rem;
    letter-spacing: 0.08em;
    color: var(--fg);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}
body:not([data-mm-debug="true"]) .pick-coord { display: none; }
.pick-coord-btn,
.pick-coord-copy {
    padding: 0.3rem 0.55rem;
    background: rgba(214, 255, 60, 0.18);
    border: 1px solid rgba(214, 255, 60, 0.5);
    color: var(--accent);
    border-radius: 3px;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.65rem;
    letter-spacing: 0.18em;
    font-weight: 600;
    flex: 0 0 auto;
}
.pick-coord-btn:hover,
.pick-coord-copy:hover {
    background: rgba(214, 255, 60, 0.32);
}
.pick-coord-btn[data-armed="true"] {
    background: var(--accent);
    color: #000;
}
.pick-coord-readout {
    color: rgba(255, 255, 255, 0.78);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Pathfinding debug minimap — visible only with ?debug in the URL. */
.path-debug {
    position: fixed;
    right: 1rem;
    top: 1rem;
    z-index: 80;
    background: rgba(15, 15, 15, 0.92);
    border: 1px solid rgba(214, 255, 60, 0.4);
    border-radius: 6px;
    padding: 0.7rem;
    color: var(--fg);
    font-size: 0.7rem;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    user-select: none;
}
.path-debug[hidden] { display: none; }
.path-debug.collapsed .path-debug-body { display: none; }
.path-debug-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.path-debug.collapsed { padding: 0.4rem 0.7rem; }
.mm-collapse {
    width: 1.6rem;
    height: 1.6rem;
    border: 1px solid rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.85);
    border-radius: 3px;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}
.mm-collapse:hover { background: rgba(255, 255, 255, 0.12); }
/* Calibration UI is debug-only; the body element gets `data-mm-debug="false"`
   when the page is opened without ?debug, hiding the controls + handles. */
body:not([data-mm-debug="true"]) .minimap-img-controls,
body:not([data-mm-debug="true"]) .path-debug-hint {
    display: none;
}
.path-debug-title {
    font-size: 0.65rem;
    letter-spacing: 0.32em;
    color: var(--accent);
    margin-bottom: 0.4rem;
}
/* Crop the canvas's wide black margins down to just the visible photo
   column. Canvas itself stays 320x640 so the calibrated MINIMAP_IMG
   transform doesn't need to change; we just shift it left by 80 px (the
   image's x offset) and clip the wrapper to the image's 162 px width. */
.path-debug-clip {
    width: 162px;
    height: 640px;
    overflow: hidden;
}
.path-debug-clip > canvas {
    display: block;
    margin-left: -80px;
}
#path-debug-canvas {
    display: block;
    width: 320px;
    height: 640px;
    image-rendering: pixelated;
    background: #000;
    border-radius: 3px;
}
.path-debug-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 0.75rem;
    margin-top: 0.45rem;
    font-size: 0.65rem;
    color: rgba(255, 255, 255, 0.7);
}
.path-debug-legend i {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin-right: 4px;
    vertical-align: -2px;
    border-radius: 2px;
}
.path-debug-legend .leg-walk    { background: #2c7c4f; }
.path-debug-legend .leg-blocked { background: #2a2a2a; }
.path-debug-legend .leg-path    { background: #d6ff3c; }
.path-debug-legend .leg-cam     { background: #ff5a5a; border-radius: 50%; }
.path-debug-legend .leg-poi     { background: #4a90e2; border-radius: 50%; }
.path-debug-legend .leg-pick    { background: #ffa040; border-radius: 50%; }
.path-debug-hint {
    margin-top: 0.4rem;
    font-size: 0.65rem;
    color: rgba(255, 255, 255, 0.55);
    line-height: 1.4;
}
.minimap-img-controls {
    margin-top: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.7rem;
    color: rgba(255, 255, 255, 0.78);
}
.mm-img-readout {
    font-family: ui-monospace, Menlo, monospace;
    font-size: 0.7rem;
    color: rgba(214, 255, 60, 0.9);
}
.mm-img-hint {
    font-size: 0.65rem;
    color: rgba(255, 255, 255, 0.45);
    line-height: 1.4;
}
.mm-img-rot-buttons {
    display: flex;
    gap: 0.3rem;
}
.mm-img-rot-buttons button {
    flex: 1;
}
.minimap-img-controls label {
    display: grid;
    grid-template-columns: 3rem 1fr 3rem;
    align-items: center;
    gap: 0.4rem;
}
.minimap-img-controls input[type="range"] {
    width: 100%;
}
.minimap-img-controls span {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: rgba(255, 255, 255, 0.55);
}
.minimap-img-controls button {
    margin-top: 0.3rem;
    padding: 0.25rem 0.4rem;
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 2px;
    font-size: 0.65rem;
    letter-spacing: 0.08em;
    cursor: pointer;
}

/* Path recorder — visible only with ?record in the URL. Top-center. */
.record-panel {
    position: fixed;
    top: 1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 80;
    background: rgba(15, 15, 15, 0.92);
    border: 1px solid rgba(255, 90, 90, 0.45);
    border-radius: 6px;
    padding: 0.7rem 0.95rem;
    width: min(560px, 92vw);
    color: var(--fg);
    font-size: 0.78rem;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
.record-panel[hidden] { display: none; }
.rec-title {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.7rem;
    letter-spacing: 0.32em;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.85);
}
.rec-counter {
    margin-left: auto;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    letter-spacing: 0.04em;
    color: var(--accent);
    user-select: all;
}
.rec-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: rgba(255, 90, 90, 0.4);
    transition: background 0.2s ease;
    flex: 0 0 auto;
}
.record-panel.recording .rec-dot {
    background: #ff5a5a;
    box-shadow: 0 0 8px rgba(255, 90, 90, 0.9);
    animation: recPulse 1s ease-in-out infinite;
}
@keyframes recPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}
.rec-actions {
    display: flex;
    gap: 0.45rem;
    margin: 0.6rem 0 0.3rem;
}
.rec-btn {
    flex: 1;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: var(--fg);
    padding: 0.45rem;
    font-family: inherit;
    font-size: 0.7rem;
    letter-spacing: 0.22em;
    font-weight: 700;
    border-radius: 3px;
    cursor: pointer;
    transition: background 0.15s ease;
}
.rec-btn:hover { background: rgba(255, 255, 255, 0.14); }
.rec-btn--start { background: rgba(255, 90, 90, 0.18); border-color: rgba(255, 90, 90, 0.45); color: #ffd9d9; }
.rec-btn--start:hover { background: rgba(255, 90, 90, 0.32); }
.rec-btn--stop { background: rgba(255, 200, 90, 0.18); border-color: rgba(255, 200, 90, 0.45); color: #ffe7c7; }
.rec-btn--stop:hover { background: rgba(255, 200, 90, 0.32); }
.rec-hint {
    font-size: 0.7rem;
    color: rgba(255, 255, 255, 0.6);
    line-height: 1.45;
    margin-top: 0.2rem;
}

/* Scene-calibration debug panel — visible only with ?debug in the URL. */
.debug-panel {
    position: fixed;
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 80;
    background: rgba(15, 15, 15, 0.92);
    border: 1px solid rgba(214, 255, 60, 0.4);
    border-radius: 6px;
    padding: 0.9rem 1.1rem 0.85rem;
    width: min(560px, 92vw);
    color: var(--fg);
    font-size: 0.78rem;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
.debug-panel[hidden] { display: none; }
.debug-title {
    font-size: 0.65rem;
    letter-spacing: 0.32em;
    color: var(--accent);
    margin-bottom: 0.6rem;
}
.debug-row {
    display: grid;
    grid-template-columns: 60px 1fr 70px 12px;
    align-items: center;
    gap: 0.6rem;
    margin: 0.35rem 0;
}
.debug-row label {
    font-weight: 600;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.85);
}
.debug-slider { width: 100%; accent-color: var(--accent); }
.debug-num {
    background: rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: var(--fg);
    padding: 0.25rem 0.4rem;
    border-radius: 3px;
    font-family: inherit;
    font-size: 0.78rem;
    text-align: right;
}
.debug-unit { color: rgba(255, 255, 255, 0.6); }
.debug-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.55rem;
}
.debug-actions button {
    flex: 1;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: var(--fg);
    padding: 0.4rem;
    font-family: inherit;
    font-size: 0.7rem;
    letter-spacing: 0.22em;
    font-weight: 700;
    border-radius: 3px;
    cursor: pointer;
    transition: background 0.15s ease;
}
.debug-actions button:hover { background: rgba(255, 255, 255, 0.14); }
.debug-readout {
    margin-top: 0.55rem;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.78rem;
    color: var(--accent);
    user-select: all;
    word-break: break-all;
    white-space: pre-wrap;
}
.debug-hint {
    margin-top: 0.35rem;
    font-size: 0.7rem;
    color: rgba(255, 255, 255, 0.55);
    line-height: 1.4;
}
.debug-divider {
    height: 1px;
    background: rgba(255, 255, 255, 0.12);
    margin: 0.7rem 0 0.5rem;
}
#debug-ground[data-active="true"] {
    background: rgba(214, 255, 60, 0.25);
    border-color: var(--accent);
    color: var(--accent);
}

/* Video calibration panel — same visual language as #path-debug.
   (The per-video playback controls are now 3D entities rendered inside
   the iframe by viewer/index.js, so they rotate with the plane and can
   be occluded by walls. This panel is the only video-related DOM UI.) */
.video-debug {
    position: fixed;
    left: 1rem;
    bottom: 1rem;
    z-index: 90;
    background: rgba(15, 15, 15, 0.95);
    border: 1px solid rgba(255, 200, 60, 0.6);
    border-radius: 6px;
    padding: 0.7rem 0.8rem;
    color: var(--fg);
    font-size: 0.7rem;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    user-select: none;
    /* Wide enough to fit pos.z / rot.z without overflow. The 3-column
       grid gives roughly (panelWidth − padding) / 3 per cell, and
       number-with-spinner inputs need ~110px of breathing room each. */
    width: 360px;
    box-sizing: border-box;
}
.video-debug[hidden] { display: none; }
body:not([data-mm-debug="true"]) .video-debug { display: none; }
.video-debug .vd-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.4rem;
}
.video-debug .vd-title {
    font-size: 0.65rem;
    letter-spacing: 0.32em;
    color: rgba(255, 200, 60, 0.95);
}
.video-debug .vd-close {
    width: 1.4rem; height: 1.4rem;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: rgba(255, 255, 255, 0.85);
    border-radius: 3px;
    cursor: pointer;
    line-height: 1;
    padding: 0;
}
.video-debug .vd-id {
    font-size: 0.75rem;
    color: var(--accent);
    margin-bottom: 0.5rem;
    word-break: break-all;
}
.video-debug .vd-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 0.35rem;
    margin-bottom: 0.5rem;
}
.video-debug .vd-grid label {
    display: flex;
    flex-direction: column;
    font-size: 0.65rem;
    color: rgba(255, 255, 255, 0.7);
    letter-spacing: 0.04em;
    min-width: 0;
}
.video-debug .vd-grid input[type="number"] {
    margin-top: 0.15rem;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: var(--fg);
    border-radius: 3px;
    padding: 0.25rem 0.35rem;
    font-family: inherit;
    font-size: 0.72rem;
    /* Without explicit min-width number inputs render their default
       intrinsic width (~120px in Chromium) and overflow the grid cell. */
    min-width: 0;
    width: 100%;
}
.video-debug .vd-checkbox,
.video-debug .vd-scale {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    gap: 0.4rem;
}
.video-debug .vd-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 0.3rem;
}
.video-debug .vd-actions-label {
    font-size: 0.6rem;
    letter-spacing: 0.18em;
    color: rgba(255, 255, 255, 0.55);
    margin-right: 0.15rem;
    min-width: 1.6rem;
}
.video-debug .vd-actions button {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: var(--fg);
    border-radius: 3px;
    padding: 0.3rem 0.5rem;
    font-family: inherit;
    font-size: 0.65rem;
    letter-spacing: 0.06em;
    cursor: pointer;
    min-width: 1.7rem;
}
.video-debug .vd-actions button:hover {
    background: rgba(255, 255, 255, 0.12);
}
.video-debug .vd-actions .vd-rotate {
    background: rgba(120, 180, 255, 0.12);
    border-color: rgba(120, 180, 255, 0.4);
    color: rgba(190, 220, 255, 0.95);
}
.video-debug .vd-actions .vd-rotate:hover {
    background: rgba(120, 180, 255, 0.22);
}
.video-debug .vd-actions .vd-copy {
    background: rgba(255, 200, 60, 0.18);
    border-color: rgba(255, 200, 60, 0.5);
    color: rgba(255, 220, 120, 1);
    font-weight: 600;
}
.video-debug .vd-hint {
    font-size: 0.62rem;
    color: rgba(255, 255, 255, 0.55);
    line-height: 1.35;
}

/* Help button: always visible, top right. */
.btn-help {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    z-index: 1;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: var(--fg);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1;
    padding: 0;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.btn-help:hover {
    background: rgba(214, 255, 60, 0.18);
    border-color: var(--accent);
    color: var(--accent);
    transform: translateY(-1px);
}

/* Help / first-visit overlay. */
.help-overlay {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    padding: 1rem;
    animation: helpFadeIn 0.25s ease forwards;
}
/* `display: flex` above beats the user-agent [hidden] rule, so make the
   hidden attribute actually hide it. */
.help-overlay[hidden] { display: none; }
@keyframes helpFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
.help-card {
    background: rgba(15, 15, 15, 0.92);
    border: 1px solid var(--panel-border);
    border-radius: 8px;
    padding: 2rem 2rem 1.6rem;
    max-width: 540px;
    width: 100%;
    box-shadow: 0 26px 70px rgba(0, 0, 0, 0.55);
}
.help-eyebrow {
    font-size: 0.7rem;
    letter-spacing: 0.4em;
    color: var(--accent);
    margin-bottom: 0.55rem;
}
.help-title {
    margin: 0 0 0.4rem;
    font-size: 2rem;
    letter-spacing: 0.18em;
    font-weight: 600;
}
.help-lede {
    margin: 0 0 1.4rem;
    font-size: 0.9rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.72);
}
.help-subtitle {
    margin: 0 0 0.8rem;
    font-size: 0.7rem;
    letter-spacing: 0.32em;
    color: var(--accent);
    text-transform: uppercase;
    font-weight: 600;
}
.help-list {
    list-style: none;
    margin: 0 0 1.6rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.help-list li {
    display: grid;
    grid-template-columns: 110px 1fr;
    gap: 1rem;
    align-items: start;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.94rem;
}
.help-key {
    font-size: 0.7rem;
    letter-spacing: 0.22em;
    font-weight: 700;
    color: var(--accent);
    padding-top: 0.15rem;
    text-transform: uppercase;
}
.help-actions {
    display: flex;
    justify-content: flex-end;
}
.help-actions .poi-btn {
    width: auto;
    padding: 0.7rem 1.4rem;
}

@media (max-width: 720px) {
    .help-card { padding: 1.4rem 1.2rem 1rem; }
    .help-list li { grid-template-columns: 90px 1fr; gap: 0.6rem; font-size: 0.88rem; }
    .help-title { font-size: 1.3rem; }
}

/* ---------------------------------------------------------------------------
   Mobile / coarse-pointer layout. The body class is set in main.js so we
   detect coarse pointers (iPad in any orientation, touchscreen laptops) the
   same way as narrow viewports. Page scroll is disabled — touch-drag is
   reserved for camera rotation only — and the POI menu becomes a horizontal
   landscape strip pinned to the bottom of the screen.
--------------------------------------------------------------------------- */

body.is-mobile, body.is-mobile html {
    overflow: hidden;
    height: 100%;
    /* iOS Safari treats touch-action:none on the body as a hint that the
       page is its own gesture surface, which prevents the rubber-band
       overscroll bounce when the user drags inside the iframe. */
    overscroll-behavior: none;
}

/* Brand shrinks to just the KAUST mark; the brand-text would otherwise
   overlap the help button on a narrow viewport. */
body.is-mobile .brand-text { display: none; }
body.is-mobile #kaust-logo { height: 32px; }

/* POI menu → bottom landscape strip. Horizontal flex, scrollable so any
   number of POIs fit. */
body.is-mobile #poi-menu {
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    transform: none;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    flex-direction: row;
    align-items: stretch;
    gap: 0.4rem;
    /* Top padding only needs to clear the help button when it sits inside
       the strip. */
    padding: 0.55rem 0.6rem;
    min-width: 0;
    /* Allow horizontal scroll of overflowing POI items. */
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    /* Respect iOS home-indicator safe area. */
    padding-bottom: calc(0.55rem + env(safe-area-inset-bottom));
}

body.is-mobile .poi-list {
    flex-direction: row;
    gap: 0.3rem;
    /* Size to content so the actions (EXPLORE / ?) sit cleanly AFTER the
       last POI item rather than overlapping it. The strip itself
       (#poi-menu) handles overflow scrolling when total content > viewport. */
    flex: 0 0 auto;
}

body.is-mobile .poi-item {
    flex: 0 0 auto;
    width: auto;
    padding: 0.45rem 0.7rem;
    font-size: 0.72rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    white-space: nowrap;
}
body.is-mobile .poi-item .poi-label {
    max-width: 9rem;
}

body.is-mobile .poi-actions {
    flex-direction: row;
    gap: 0.3rem;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
    flex: 0 0 auto;
}
body.is-mobile .poi-btn {
    width: auto;
    padding: 0.45rem 0.85rem;
    font-size: 0.65rem;
    letter-spacing: 0.22em;
}

/* Help button sits inside the menu top-right on desktop. On the bottom
   strip the top-right corner of the viewport is already claimed by the
   collapsed minimap title bar, so we tuck the help button at the end of
   the strip via flex order — it stays accessible and doesn't collide. */
body.is-mobile #poi-menu .btn-help {
    position: static;
    order: 99;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    align-self: center;
}

/* Mobile collapse button: at the start of the bottom strip. */
body.is-mobile .poi-collapse {
    position: static;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    align-self: center;
    order: -1;
}

/* The .poi-body wrapper around list + actions becomes a horizontal flex
   row on mobile to preserve the strip layout. */
body.is-mobile .poi-body {
    display: flex;
    flex-direction: row;
    gap: 0.3rem;
    flex: 0 0 auto;
}

/* When collapsed on mobile, hide the body but keep the collapse + help
   buttons reachable as a tiny strip. */
body.is-mobile #poi-menu.collapsed {
    padding: 0.4rem 0.6rem;
    padding-bottom: calc(0.4rem + env(safe-area-inset-bottom));
}

/* Annotation panel sits above the bottom POI strip, never overlapping it. */
body.is-mobile .section--annotation .panel {
    position: fixed;
    left: 0.6rem;
    right: 0.6rem;
    top: auto;
    bottom: 5.2rem;
    width: auto;
    max-width: none;
    max-height: 32vh;
    padding: 0.6rem 0.9rem 0.6rem 0.9rem;
    /* Right padding clears both the close button (top-right) and the
       collapse button immediately to its left. */
    padding-right: 4rem;
}
body.is-mobile .panel-title { font-size: 1.1rem; margin-bottom: 0.4rem; }
body.is-mobile .panel-text { font-size: 0.85rem; line-height: 1.4; }
body.is-mobile .panel-tags { margin-top: 0.5rem; }

/* Collapse toggle is shown only on mobile annotation panels. Sits to
   the LEFT of the universal close button so they don't stack. */
body.is-mobile .section--annotation .panel-collapse {
    display: flex;
    position: absolute;
    top: 0.4rem;
    right: 2.2rem;
    width: 26px;
    height: 26px;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.06);
    color: var(--fg);
    border-radius: 3px;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    cursor: pointer;
    z-index: 1;
}
body.is-mobile .section--annotation .panel-collapse:hover {
    background: rgba(255, 255, 255, 0.12);
}

/* Collapsed state hides the body (description + tags) but keeps the
   eyebrow ("STOP 06") + title visible. The panel shrinks to its content. */
body.is-mobile .section--annotation .panel--collapsed {
    max-height: none;
    padding-bottom: 0.5rem;
}
body.is-mobile .section--annotation .panel--collapsed .panel-body {
    display: none;
}
body.is-mobile .section--annotation .panel--collapsed .panel-title {
    margin-bottom: 0;
}

/* Minimap starts collapsed on mobile (handled in JS); shrink padding so the
   collapsed title bar doesn't crowd the brand. */
body.is-mobile .path-debug {
    right: 0.5rem;
    top: 0.5rem;
    padding: 0.5rem;
}
