/* ============================================================
 * /walking-sim — full-shell dfl wrapper.
 *
 * Same pattern as `.ts-flush-shell` (see assets/tile_selector.css):
 * a position:fixed host that escapes the page Container in app.py
 * and pins flush against the AppShell header + navbar offsets, so
 * the DashFlexLayout uses every remaining pixel of AppShellMain.
 * The walker map gets the left pane (67%); HUD + Controls tabs
 * share the right (33%).
 * ============================================================ */

.ws-flush-shell {
    position:           fixed;
    top:                var(--app-shell-header-offset, 56px);
    left:               var(--app-shell-navbar-offset, 0px);
    right:              0;
    bottom:             0;
    z-index:            10;
    background:         var(--mantine-color-body);
    border-top:         1px solid var(--mantine-color-default-border);
    border-left:        1px solid var(--mantine-color-default-border);
    overflow:           hidden;
}

/* DashFlexLayout fills its host. */
.ws-flush-shell > .flexlayout__layout,
.ws-flush-shell > div {
    height: 100%;
    width:  100%;
}

/* The dfl is now mounted into ``#ws-flex-host`` (a callback fills it once
 * the viewport resolves), one level deeper than the flush-shell — give
 * the FlexLayout it holds the full box. */
#ws-flex-host > .flexlayout__layout {
    height: 100%;
    width:  100%;
}

/* The map pane wrapper — relative-positioned so the touch joystick
   (.dl2-joystick is absolutely positioned) anchors to the map, not
   the dfl tab. height:100% so the dl2.Map fills the pane. */
.ws-map-pane {
    position:        relative;
    height:          100%;
    width:           100%;
    overflow:        hidden;
}
.ws-map-pane > .leaflet-container,
.ws-map-pane > div[id="ws-map"] {
    height: 100% !important;
    width:  100% !important;
}

/* Right-pane panes — let the HUD / Controls stacks scroll if the
   viewport gets short, while the dfl tab itself remains fixed. */
.ws-side-pane {
    height:    100%;
    width:     100%;
    overflow:  auto;
}

/* ============================================================
 * Mode-gated chrome.
 *
 * WALK mode: the user is driving the character; pan/zoom are NOT theirs
 *   to touch (the rAF loop drives camera-follow), so the +/- zoom
 *   control would be misleading. Hide it.
 * EXPLORE mode: the map is a normal dl2 map (pan/zoom freely). The zoom
 *   control reappears.
 *
 * Class is set by the ws-mode -> className clientside callback in
 * docs/walking-sim/example.py. Animated so the swap doesn't jar.
 * ============================================================ */
.ws-flush-shell .leaflet-control-zoom {
    transition: opacity 180ms ease, transform 180ms ease;
}
.ws-mode-walk .leaflet-control-zoom {
    opacity:        0;
    transform:      translateY(-4px) scale(0.94);
    pointer-events: none;
}

/* ============================================================
 * Liquid-glass DashRCJoystick overlay.
 *
 * The on-map joystick lives in the bottom-right corner of the
 * walker map (above Leaflet controls). Its container is the
 * .ws-joystick-overlay div; the inner DashRCJoystick exposes
 * its base + controller via className / controllerClassName
 * (set in pages/map/walking_sim.py::_joystick_overlay).
 *
 * The look is the same "liquid glass" treatment used on the
 * harbor map and the drop-a-pin drawer (`map_index.css`):
 * translucent body tint + backdrop-filter blur. Light mode is
 * a soft white pane over the satellite imagery; dark mode
 * inverts to a smoked-charcoal pane. The controller (the puck
 * the user drags) gets a brass-tinted core in light mode and
 * a tidal-blue core in dark mode so it reads as the affordance
 * regardless of theme.
 * ============================================================ */

.ws-joystick-overlay {
    position:           absolute;
    bottom:             20px;
    right:              20px;
    z-index:            1100;             /* above leaflet controls (1000) */
    user-select:        none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    touch-action:       none;
    pointer-events:     auto;
    /* The joystick fades back a hair when idle so it doesn't
       compete with the map; hover/touch nudges it back to full. */
    opacity:            0.82;
    transition:         opacity 160ms ease, transform 160ms ease;
}
.ws-joystick-overlay:hover,
.ws-joystick-overlay:active,
.ws-joystick-overlay:focus-within {
    opacity:            1;
}

/* Hide the whole overlay in EXPLORE mode — the rAF loop sits out and
   the user is panning the map freely; the joystick has nothing to
   drive. Mirrors the dl2-joystick visibility rule. */
.ws-mode-explore .ws-joystick-overlay {
    opacity:            0;
    pointer-events:     none;
    transform:          translateY(8px) scale(0.94);
}

/* === The base (the disc you drag inside of) === */
.ws-rc-joystick-base {
    /* Mantine body-tinted glass: 55% body color over whatever the
       map is showing, with a strong blur + saturation pump so the
       satellite imagery behind reads as out-of-focus glass. */
    background:
        color-mix(in srgb,
                  var(--mantine-color-body, #ffffff) 55%,
                  transparent) !important;
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    backdrop-filter:    blur(14px) saturate(160%);
    /* Subtle harbor-tinted border so the disc is legible against
       water + land alike. */
    border:             1px solid color-mix(in srgb,
                            var(--mantine-color-harbor-6, #1c7ed6) 55%,
                            transparent) !important;
    box-shadow:
        0 10px 28px -6px rgba(0, 0, 0, 0.30),
        inset 0 1px 0 rgba(255, 255, 255, 0.32);
    border-radius:      50%;
    cursor:             grab;
}
.ws-rc-joystick-base:active {
    cursor:             grabbing;
}

/* === The controller (the puck the user drags) === */
.ws-rc-joystick-controller {
    background:
        radial-gradient(circle at 35% 30%,
            color-mix(in srgb,
                var(--mantine-color-brass-3, #fcc419) 92%, transparent) 0%,
            color-mix(in srgb,
                var(--mantine-color-brass-6, #f59f00) 88%, transparent) 78%,
            color-mix(in srgb,
                var(--mantine-color-brass-8, #e67700) 92%, transparent) 100%
        ) !important;
    border:             2px solid color-mix(in srgb,
                            var(--mantine-color-body, #ffffff) 80%,
                            transparent) !important;
    box-shadow:
        0 6px 14px rgba(0, 0, 0, 0.32),
        inset 0 1px 0 rgba(255, 255, 255, 0.45);
}

/* === Dark-mode treatment ===
 * Mantine sets `data-mantine-color-scheme="dark"` on <html>; we key
 * off that so the joystick reads as a smoked-glass pane with a
 * tidal-blue puck against the satellite imagery. The light-mode
 * defaults above stay in place for everyone else. */
:where(html[data-mantine-color-scheme="dark"]) .ws-rc-joystick-base {
    background:
        color-mix(in srgb,
            var(--mantine-color-dark-7, #1a1b1e) 55%,
            transparent) !important;
    border-color:       color-mix(in srgb,
                            var(--mantine-color-harbor-4, #4dabf7) 60%,
                            transparent) !important;
    box-shadow:
        0 10px 28px -6px rgba(0, 0, 0, 0.55),
        inset 0 1px 0 rgba(255, 255, 255, 0.10);
}
:where(html[data-mantine-color-scheme="dark"]) .ws-rc-joystick-controller {
    background:
        radial-gradient(circle at 35% 30%,
            color-mix(in srgb,
                var(--mantine-color-tidal-3, #74c0fc) 92%, transparent) 0%,
            color-mix(in srgb,
                var(--mantine-color-tidal-5, #339af0) 88%, transparent) 78%,
            color-mix(in srgb,
                var(--mantine-color-tidal-8, #1864ab) 92%, transparent) 100%
        ) !important;
    border-color:       color-mix(in srgb,
                            var(--mantine-color-dark-2, #c9c9c9) 70%,
                            transparent) !important;
}

/* On phones, scoot the joystick a touch further from the edges so
   the user's thumb has room and the puck doesn't get clipped by the
   browser's pull-to-refresh affordance. */
@media (max-width: 640px) {
    .ws-joystick-overlay {
        bottom: 28px;
        right:  16px;
    }
}

/* =====================================================================
 * First-person 360° perspective (v0.23.0)
 *
 * The DashPannellum viewer is an absolute overlay over the dl2 map,
 * shown only in fp mode (the ws-shell className mirror writes
 * .ws-mode-fp). The viewer + canvas stay mounted in every mode — the
 * v0.11.14 "callback ids must exist in every branch" lesson — so only
 * display is toggled here. The joystick (z 1100) stays on top and keeps
 * driving movement; gaze-relative steering happens in
 * assets/walking_sim_fp.js.
 * ===================================================================== */

.ws-fp-overlay {
    position:   absolute;
    inset:      0;
    z-index:    1050;                /* above leaflet (1000), below joystick */
    display:    none;
    background: #0a1622;             /* pre-boot void behind the viewer */
}

.ws-mode-fp .ws-fp-overlay {
    display: block;
}

/* FP hides the Leaflet zoom chrome the same way WALK does. */
.ws-mode-fp .leaflet-control-zoom {
    opacity:        0;
    pointer-events: none;
}

/* Perspective switch — floating top-left, liquid-glass like the joystick. */
.ws-perspective-overlay {
    position: absolute;
    top:      12px;
    left:     12px;
    z-index:  1100;
}

.ws-perspective-overlay .mantine-SegmentedControl-root {
    background: color-mix(in srgb,
                    var(--mantine-color-body, #fff) 55%, transparent);
    backdrop-filter:         blur(10px) saturate(140%);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    border: 1px solid color-mix(in srgb,
                var(--mantine-color-harbor-4, #5D7A99) 35%, transparent);
    box-shadow: 0 4px 14px rgba(11, 22, 40, 0.18);
}

/* Sprite-state emoji chip — WS_FP writes textContent directly. */
.ws-fp-statechip {
    position:       absolute;
    top:            12px;
    right:          12px;
    z-index:        1060;
    pointer-events: none;
    font-family:    ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size:      13px;
    padding:        4px 10px;
    border-radius:  999px;
    color:          var(--mantine-color-gray-0, #f8f9fa);
    /* Intentional fixed dark glass (same rationale as the trail color):
       the chip rides over satellite imagery in both app themes, so it
       deliberately never adapts. */
    background:     rgba(11, 22, 40, 0.55);
    backdrop-filter:         blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(238, 244, 250, 0.18);
}

/* Esri credit line — in FP the imagery renders through our canvas, so the
   Leaflet attribution control no longer covers it. */
.ws-fp-attrib {
    position:       absolute;
    bottom:         4px;
    right:          8px;
    z-index:        1060;
    pointer-events: none;
    font-size:      10px;
    line-height:    1.3;
    color:          rgba(238, 244, 250, 0.65);
    text-shadow:    0 1px 2px rgba(11, 22, 40, 0.8);
    max-width:      70%;
    text-align:     right;
}

@media (max-width: 640px) {
    .ws-perspective-overlay {
        top:  8px;
        left: 8px;
    }
    .ws-fp-statechip {
        top:   8px;
        right: 8px;
    }
}
