/* Kiosk bottom-right corner column, single-sourced.

   The Restrooms button and the feedback-QR card sit side by side in the
   bottom-right, and THREE other rules reserve space against them: the search
   dock's right padding, the keyboard group's right gutter, and the button's own
   offset. Those were hard-coded against a 168px-wide QR card; the card was later
   widened to 208px (#449 touchless accent) and only the card changed, so the
   Restrooms button ended up 28px underneath it — and since the card carries
   z-index 9999 against the button's 2, the card won and the label rendered as
   "Restroo" on every directory and search screen in the estate (KC 7/24 polish
   run). Deriving the offsets means widening the card again can't silently
   re-break it. */
:root {
    --kiosk-corner-gap: 12px;
    --kiosk-qr-w: 208px;
    --kiosk-qr-right: 12px;
    --kiosk-restroom-w: 100px;
    /* Sits immediately left of the QR card, one gap clear of it. */
    --kiosk-restroom-right: calc(var(--kiosk-qr-right) + var(--kiosk-qr-w) + var(--kiosk-corner-gap));
    /* Full width of the corner column — what everything else must clear. */
    --kiosk-corner-col: calc(var(--kiosk-restroom-right) + var(--kiosk-restroom-w));
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.fade {
    animation-duration: 0.75s;
    animation-delay: 0.5s;
    animation-name: fadeIn;
    animation-timing-function: cubic-bezier(.26, .53, .74, 1.48);
    animation-fill-mode: backwards;
}

.centered-element {
    display: block;
    margin: 0 auto;
}

.centering-container {
    align-items: center;
    display: flex;
    width: 100%;
    height: 100vh;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* ============================================================
   Kiosk Mode Styles
   ============================================================ */

/* Full viewport, no scrolling, no pinch-to-zoom */
.kiosk {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    position: fixed;
    top: 0;
    left: 0;
    touch-action: none;
}

/* Branded building header — split layout (Innerface spec #272/#273):
   left side is full dark color with hospital identity; right side is a
   discrete signage PANEL at the PDF's native 268:69 aspect ratio (≈3.88:1).
   Confining the panel preserves the exact bezier curve slope through the
   badge — stretching it to full kiosk width compresses the slope. */
.kiosk-header {
    height: 110px;
    min-height: 110px;
    max-height: 110px;
    position: relative;
    overflow: hidden;
    z-index: 10;
    display: flex;
    align-items: stretch;
}

/* Light-shade strip extension — runs from the left edge of the page to
   the signage panel, filling the bottom band that continues the bezier's
   horizontal tangent. Bezier left endpoint sits at y=25.27 viewBox units
   of 69 = 36.62% from top, so the strip top sits at 36.62% of the header
   height and extends to the bottom. */
.kiosk-header-strip-extension {
    position: absolute;
    left: 0;
    bottom: 0;
    right: calc(110px * 268 / 69); /* stop where the panel begins */
    top: calc(110px * 25.27 / 69); /* match the bezier's left-endpoint y */
    z-index: 0;
    pointer-events: none;
}

/* Left side — hospital identity vertically centered on the full banner
   height. The strip extension passes behind the text; text sits above
   both the dark band and the light strip, white reads cleanly on either. */
.kiosk-header-left {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    padding-left: 24px;
    z-index: 1;
}

.kiosk-header-hospital {
    color: #FFFFFF;
    font-family: 'Montserrat', sans-serif;
    font-size: 1.8rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    white-space: nowrap;
    line-height: 1;
}

.kiosk-header-subtitle {
    color: rgba(255, 255, 255, 0.85);
    font-family: 'Lato', sans-serif;
    font-size: 1rem;
    font-weight: 400;
    letter-spacing: 0.03em;
    line-height: 1;
}

/* Right side — the signage panel. Width = header_height × 268/69 ≈ 427px,
   so the bezier and content render at exactly the PDF swatch's proportions. */
.kiosk-header-panel {
    position: relative;
    flex: 0 0 auto;
    width: calc(110px * 268 / 69);
    height: 100%;
}

/* Signage SVG — fills the panel exactly. ViewBox matches the PDF swatch's
   panel coordinates (268pt × 69pt). preserveAspectRatio="none" is safe
   because the panel container has the same 3.88:1 aspect ratio. All three
   elements (swoop, badge, letter) live inside this SVG and scale as one
   unit — no independent CSS positioning can drift from the PDF geometry. */
.kiosk-header-signage {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

/* Footer band — sits in the 80%-shade area at the bottom of the panel.
   Matches the "You Are in the MOB X" footer on the Innerface signs. */
.kiosk-header-footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 35%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
    /* #489: real side margins so the label never kisses the bezel — the
       fitKioskFooter helper scales long labels down inside this padding. */
    padding: 0 18px;
}

.kiosk-header-footer-text {
    color: #FFFFFF;
    font-family: 'Montserrat', sans-serif;
    font-size: 1.15rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
    white-space: nowrap;
}

.kiosk-header-footer-text strong {
    font-weight: 800;
}

/* Building letter badge (#229, #272): transparent fill so the banner shows
   through, white perimeter, white letter — matches the physical signage
   plaque in the Innerface brand spec (square corners, no drop shadow).
   Kyle 5/19: "there probably is not a drop shadow on the painted ones".

   Geometry derived from the PDF SWATCH (left-column design) per KC's
   reference (artifact hca-brand-spec):
   - PDF swatch panel: 268 × 69 pt. Badge: 37.7 × 37.7 pt positioned at
     panel-relative (209.86, 6.34). Bezier passes through the badge at
     84.2% from badge top — i.e., only the bottom ~16% of the badge
     interior crosses into the 80%-shade band.
   - Bezier control points (panel-relative): M(268,44.91) C(181.5,27.86)
     (93.8,23.39) (0,25.27). At badge x-center (228.71), y ≈ 38.07.
     Crossing fraction: (38.07 − 6.34) / 37.7 = 84.2%.
   - Scale to 110 px header: factor 110/69 = 1.594.
     Badge: 37.7 × 1.594 ≈ 60 px.
     Curve y at badge x (right edge of viewport, stretched): ≈ 68 px.
     Badge top: 68 − 60 × 0.842 ≈ 18 px so the curve crosses the badge
     at the same 84% from-top point as the PDF. */
.kiosk-header-badge {
    position: absolute;
    top: 18px;
    right: 24px;
    width: 60px;
    height: 60px;
    z-index: 2;
    background: transparent;
    color: #FFFFFF;
    border: 3px solid #FFFFFF;
    border-radius: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Montserrat', sans-serif;
    font-size: 2.25rem;
    font-weight: 800;
    line-height: 1;
}

.kiosk-header-building-label {
    color: #FFFFFF;
    font-family: 'Montserrat', sans-serif;
    font-size: 1.55rem;
    font-weight: 700;
    white-space: nowrap;
}


/* Main content fills remaining viewport below header */
.kiosk .kiosk-content {
    position: absolute;
    top: 110px;
    bottom: 0;
    left: 0;
    right: 0;
    overflow: hidden;
    padding: 0;
}

/* Placeholder screen for loading state */
.kiosk-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    width: 100%;
}

/* Touch-friendly sizing for kiosk interactive elements */
.kiosk .mud-button {
    min-height: 56px;
    min-width: 56px;
    font-size: 1.25rem;
    border-radius: 8px;
}

.kiosk .mud-button-root {
    padding: 12px 24px;
}

.kiosk .mud-input,
.kiosk .mud-input-control {
    font-size: 1.375rem;
}

.kiosk .mud-input-control .mud-input-root {
    min-height: 56px;
    font-size: 1.375rem;
}

/* Large touch targets for list items */
.kiosk .mud-list-item {
    min-height: 64px;
    padding: 12px 16px;
    font-size: 1.25rem;
}

/* Icon sizing for kiosk visibility */
.kiosk .mud-icon-root {
    font-size: 1.65rem;
}

/* Ensure high contrast text rendering */
.kiosk {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Disable text selection on kiosk (touchscreen terminals) */
.kiosk {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
}

/* Hide scrollbars that may appear within components */
.kiosk *::-webkit-scrollbar {
    display: none;
}

.kiosk * {
    -ms-overflow-style: none;
    scrollbar-width: none;
}

/* ============================================================
   Kiosk Search Layout
   ============================================================ */

/* Full-height flex layout: search bar, results, keyboard */
.kiosk-search-layout {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    /* Smooth fade-in from splash → directory transition (KC 5/20:
       "the directory kind of pops in"). Longer than the generic
       kiosk-fade-in and uses ease-out so the directory eases into
       place instead of snapping. */
    animation: kiosk-directory-enter 0.5s ease-out;
}

@keyframes kiosk-directory-enter {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ── Search Bar ─────────────────────────────────────────── */
.kiosk-search-bar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding: 12px 16px;
    gap: 8px;
    background: rgba(0, 0, 0, 0.15);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.kiosk-search-bar .kiosk-search-input .mud-input-outlined-border {
    animation: search-pulse 4s ease-in-out infinite;
}

@keyframes search-pulse {
    0%, 100% { border-color: rgba(255, 255, 255, 0.23); }
    50% { border-color: rgba(38, 198, 218, 0.6); }
}

.kiosk-search-bar .kiosk-search-input {
    flex: 1;
}

/* The search field gets a fill so it reads as a real text input instead of
   a transparent outline, which had too little contrast against the dock on
   the wall kiosks (Yvonne 6/8, #359: "make it white… like a text input
   box"). Dark mode gets a subtle lift; light mode goes solid white (below
   with the other .kiosk-light overrides). */
.kiosk-search-bar .kiosk-search-input .mud-input-outlined {
    background: rgba(255, 255, 255, 0.10);
}

.kiosk-search-bar .kiosk-search-input .mud-input-root {
    min-height: 64px;
    font-size: 1.65rem;
}


.kiosk-search-bar .kiosk-search-clear {
    min-width: 56px;
    min-height: 56px;
}

/* "Cancel" dismiss-keyboard button (replaces the bare keyboard-hide glyph). */
.kiosk-search-bar .kiosk-search-cancel {
    min-height: 56px;
    padding: 0 22px;
    font-size: 1.15rem;
    flex-shrink: 0;
}

/* ── Bottom search dock (KC 6/3) ────────────────────────────
   The search bar lives at the bottom of the directory. The keyboard is
   hidden until the field is tapped, then slides up beneath this dock so
   the bar stays pinned to the top of the keyboard. */
.kiosk-search-dock {
    border-bottom: none;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    /* Resting row: the search pill fills the left; the Restrooms button and the
       feedback-QR occupy the corner column on the right. Reserve padding so the
       pill ends just left of that column; small left inset for the pill's glow. */
    padding-left: 16px;
    padding-right: calc(var(--kiosk-corner-col) + 16px);
}

/* Keyboard open → the dock is raised above the keyboard, so the search input
   spans full width. The Restrooms + QR cards stay visible (bottom-right); the
   keyboard+numpad group reserves a right gutter for them (see below). */
.kiosk-search-dock-open {
    padding-left: 16px;
    padding-right: 16px;
}

.kiosk-search-input-wrap {
    flex: 1;
    min-width: 0;
    cursor: pointer;
}

.kiosk-search-input-wrap * {
    cursor: pointer;
}

.kiosk-search-dock .kiosk-search-input {
    width: 100%;
}

/* Resting "Touch To Search" pill — big blue CTA that pulses once every
   1.5s to invite a tap (KC 6/3). Tapping it opens the keyboard. */
.kiosk-search-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    width: 100%;
    min-height: 76px;
    padding: 0 32px;
    border-radius: 999px;
    background: linear-gradient(135deg, #2D9CDB 0%, #1565C0 100%);
    color: #fff;
    font-family: 'Montserrat', sans-serif;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    cursor: pointer;
    box-shadow: 0 6px 20px rgba(33, 122, 205, 0.4);
    animation: kiosk-cta-pulse 1.5s ease-in-out infinite;
}

.kiosk-search-cta-icon {
    font-size: 2.2rem !important;
}

/* Glow pulse (no transform) — reads as a pulse without changing size, so it
   never bleeds past the clipped edge and stays tap-reliable. */
@keyframes kiosk-cta-pulse {
    0%, 100% { box-shadow: 0 6px 18px rgba(33, 122, 205, 0.30); filter: brightness(1); }
    50%      { box-shadow: 0 8px 36px rgba(45, 156, 219, 0.85); filter: brightness(1.09); }
}

/* ── Results Area ───────────────────────────────────────── */
.kiosk-results {
    flex: 1;
    overflow-y: auto;
    padding: 0;
    touch-action: pan-y;
}

.kiosk-route-steps {
    touch-action: pan-y;
}

.kiosk-results-header {
    padding: 8px 20px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.kiosk-results-message {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 24px;
}

/* ── Result Rows ────────────────────────────────────────── */
.kiosk-result-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 80px;
    padding: 12px 20px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    cursor: pointer;
    transition: background-color 0.15s ease, transform 0.1s ease;
}

.kiosk-result-row:active {
    background: color-mix(in srgb, var(--building-light, #26C6DA) 35%, transparent);
    transform: scale(0.985);
}

.kiosk-result-selected {
    background: color-mix(in srgb, var(--building-dark, #26C6DA) 18%, transparent);
    border-left: 4px solid var(--building-dark, #26C6DA);
}

.kiosk-result-practice-row {
    background: rgba(255, 255, 255, 0.04);
}

.kiosk-result-left {
    flex: 1;
    min-width: 0;
    padding-right: 16px;
}

.kiosk-result-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 700;
}

.kiosk-result-specialty {
    margin-top: 2px;
}

.kiosk-result-practice {
    white-space: nowrap;
}

.kiosk-result-location {
    margin-top: 2px;
}

/* ── On-Screen Keyboard ────────────────────────────────── */
.kiosk-keyboard-container {
    flex-shrink: 0;
    /* QWERTY + numpad sit side by side as one centered group. The right padding
       reserves the bottom-right corner column (Restrooms + feedback-QR) so the
       group centers in the space to their LEFT and never collides with them
       (Kyle 6/3). Derived, so it tracks the card widths. */
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 28px;
    background: rgba(0, 0, 0, 0.25);
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    padding: 8px calc(var(--kiosk-corner-col) + 16px) 12px 12px;
}

.kiosk-keyboard {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-width: 760px;
    margin: 0;
}

.kiosk-keyboard-row {
    display: flex;
    justify-content: center;
    gap: 5px;
}

/* Individual key */
.kiosk-key.mud-button {
    min-height: 60px;
    min-width: 60px;
    flex: 1;
    max-width: 80px;
    font-size: 1.375rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    border-radius: 8px;
    padding: 8px 4px;
}

/* Bottom row special keys */
.kiosk-keyboard-bottom {
    gap: 8px;
}

.kiosk-key-space.mud-button {
    flex: 4;
    max-width: 400px;
}

.kiosk-key-clear.mud-button {
    flex: 1.5;
    max-width: 140px;
    font-size: 1.1rem;
}

.kiosk-key-backspace.mud-button {
    flex: 1.5;
    max-width: 140px;
    font-size: 1.1rem;
}

/* ============================================================
   Isometric floor-stack (#339) — shared by the POC page and the
   kiosk elevator/stairs transition overlay.
   ============================================================ */
.iso-stack-stage {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.iso-stack-svg {
    width: 100%;
    height: 100%;
    /* Approved iso squash + a gentle static skew so the rectangular plates
       read as 3D plates with visible walls. In-plane 2D affine only — no
       CSS-3D, no rotation/spin (Kyle 5/26). */
    transform: scale(1.04, 0.62) skewX(-20deg);
    transform-origin: 50% 50%;
}
.iso-floor { transition: opacity 0.12s linear; }

/* Kiosk elevator/stairs transition: the iso stack covers the flat map area
   (the step bubble + QR stay on top via their own higher z-index). */
.kiosk-iso-overlay {
    position: absolute;
    inset: 0;
    z-index: 4;
    background: radial-gradient(ellipse at 50% 40%, #EAF2FA 0%, #D6E6F4 70%, #C7DCEF 100%);
    /* Crossfade the iso in over the live 2D map (which the camera left framed on
       the elevator) so entering the rise dissolves rather than cutting (#339). */
    animation: kiosk-fade-in 0.6s ease-out;
}
.kiosk-iso-overlay .iso-stack-stage { height: 100%; }

/* ============================================================
   Kiosk 3D Map View
   ============================================================ */

.kiosk-map-toggle.mud-button {
    min-width: 130px;
    min-height: 56px;
    flex-shrink: 0;
    font-size: 1.1rem;
    font-weight: 600;
}

.kiosk-map-area {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: kiosk-fade-in 0.15s ease;
}

.kiosk-banner {
    flex-shrink: 0;
    padding: 12px 20px;
    background: rgba(0, 0, 0, 0.7);
    text-align: center;
    cursor: pointer;
    user-select: none;
}

.kiosk-map-container {
    width: 100%;
    height: 100%;
}

/* ── Sky-bridge crossing screen (KC 6/30) ──────────────────────────────
   A constrained schematic shown on the "Cross the sky bridge" step:
   [origin building] === bridge === [destination building], with a dot
   traversing from origin to destination. Opaque, so it also hides the
   building-to-building floor swap underneath. */
/* Palette matches the kiosk floor map (light theme) so the crossing screen
   reads as part of the same wayfinding system: bg = map bg, buildings = suite
   fill + wall stroke, bridge = hallway floor with wall edges, dot = walker. */
.kiosk-cross-overlay {
    position: absolute;
    inset: 0;
    z-index: 6;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #D6E6F4;          /* IDLE_BG_COLOR */
    animation: kiosk-cross-in 350ms ease-out both;
}
.kiosk-cross-overlay.exiting { animation: kiosk-cross-out 450ms ease-in both; }
@keyframes kiosk-cross-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes kiosk-cross-out { from { opacity: 1; } to { opacity: 0; } }

.kiosk-cross-diagram {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0 6%;
}
.kiosk-cross-bldg {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 44px;
    border-radius: 18px;
    /* background is the building's brand color (inline) — matches its badge */
    border: 5px solid #5C6770;    /* WALL_COLOR_LIGHT — building outline */
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.12);
}
.kiosk-cross-badge {
    width: clamp(72px, 12vw, 140px);
    height: auto;
    display: block;
}
.kiosk-cross-bldg > span {       /* text fallback (no badge for this letter) */
    font-size: clamp(28px, 5vw, 64px);
    font-weight: 800;
    color: #fff;
}
.kiosk-cross-bridge {
    flex: 1 1 auto;
    position: relative;
    align-self: center;
    height: 44px;
    margin: 0 -5px;                    /* tuck under the building walls */
    background: #BAC3CA;               /* HALLWAY_COLOR_LIGHT */
    border-top: 6px solid #5C6770;     /* wall edges = the two "lines" */
    border-bottom: 6px solid #5C6770;
}
/* the walker dot traversing origin -> destination */
.kiosk-cross-dot {
    position: absolute;
    top: 50%;
    width: 34px;
    height: 34px;
    margin: -17px 0 0 -17px;
    border-radius: 50%;
    background: #FFEB3B;               /* WALKER_COLOR */
    border: 4px solid #F9A825;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    animation: kiosk-cross-travel 2.4s ease-in-out infinite;
}
@keyframes kiosk-cross-travel {
    0%   { left: 0%;   opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    100% { left: 100%; opacity: 0; }
}

.kiosk-map-container canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
}

/* Back to directory button */
.kiosk-back-btn.mud-button {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 10;
    min-height: 48px;
    font-size: 1.1rem;
    font-weight: 600;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(8px);
    border-radius: 10px;
}

/* Map-first route screen (#282 redesign): full-width map, a mobile-handoff
   QR card top-right (where the step panel was), and the current step as a
   friendly bubble at bottom-center. */
.kiosk-route-qr {
    position: absolute;
    top: 16px;
    right: 16px;
    z-index: 10;
    background: rgba(255, 255, 255, 0.96);
    border-radius: 16px;
    padding: 14px 14px 10px;
    text-align: center;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
}

.kiosk-route-qr-img {
    width: 150px;
    height: 150px;
    margin: 0 auto;
}

.kiosk-route-qr-caption {
    margin-top: 8px;
    font-weight: 600;
    color: #37474F;
    font-size: 0.95rem;
    line-height: 1.2;
}

/* Step progress bar — thin accent line along the very bottom edge that elapses
   toward the next step so the auto-advance wait reads as intentional (Kyle 6/16).
   The .razor bumps @key to restart it each step; duration is set inline per step. */
.kiosk-step-progress {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 4px;
    background: rgba(0, 0, 0, 0.08);
    z-index: 10;
    overflow: hidden;
    pointer-events: none;
}
.kiosk-step-progress-fill {
    height: 100%;
    width: 0;
    background: var(--building-dark, #26C6DA);
    animation-name: kiosk-step-progress-fill;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
}
@keyframes kiosk-step-progress-fill {
    from { width: 0; }
    to { width: 100%; }
}

.kiosk-step-bubble {
    position: fixed;          /* pin to viewport bottom, not the (taller) map item */
    bottom: 32px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 18px;
    max-width: 72%;
    padding: 18px 30px;
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(10px);
    color: #263238;
    border-radius: 9999px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22);
    animation: kiosk-fade-in 0.2s ease;
}

.kiosk-step-bubble-icon {
    flex-shrink: 0;
    color: #EA9F23;
}

.kiosk-step-bubble-text {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.15;
}

.kiosk-step-bubble-sub {
    font-size: 1rem;
    color: #607D8B;
    margin-top: 2px;
}

/* Route navigation — right-side step panel */
.kiosk-route-panel {
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(12px);
    border-left: 1px solid rgba(255, 255, 255, 0.1);
}

.kiosk-route-panel .mud-selected-item {
    border-left: 4px solid var(--mud-palette-primary);
    background: rgba(38, 198, 218, 0.12);
}

.kiosk-route-panel .kiosk-step-inactive {
    opacity: 0.4;
    transition: opacity 0.2s;
    border-left: 4px solid transparent;
}

.kiosk-route-panel .kiosk-step-inactive:hover {
    opacity: 0.7;
}

/* Navigate icon on directory rows */
.kiosk-result-navigate {
    margin-left: 12px;
    font-size: 1.65rem;
}

.kiosk-result-right {
    flex-shrink: 0;
    text-align: right;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Floor navigation overlay */
.kiosk-floor-nav {
    position: absolute;
    top: 50%;
    right: 16px;
    transform: translateY(-50%);
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    background: rgba(0, 0, 0, 0.6);
    border-radius: 12px;
    padding: 8px;
    backdrop-filter: blur(8px);
}

.kiosk-floor-btn.mud-button {
    min-width: 56px;
    min-height: 56px;
    border-radius: 50%;
}

.kiosk-floor-label {
    min-width: 80px;
    text-align: center;
    padding: 4px 8px;
}

/* ============================================================
   Floor Plan Editor
   ============================================================ */

.floor-plan-canvas-container {
    border: 1px solid rgba(255, 255, 255, 0.12);
}

/* Option 2 — full-bleed canvas; all chrome floats on top as glass panels.
   The editor fills the whole content area; the map is the page. */
.fp-fullbleed {
    position: relative;
    width: 100%;
    /* The app bar is Dense (48px) everywhere — the 64px var fallback left a
       16px white bar under the stage (KC 7/6). */
    height: calc(100vh - 48px);
    overflow: hidden;
    /* One shared glass aesthetic for EVERY floating control over the map
       (top bar, floors panel, tool dock, zoom). Change it here, change it
       everywhere. */
    --fp-glass-bg: rgba(255, 255, 255, 0.82);
    --fp-glass-border: 1px solid rgba(0, 0, 0, 0.08);
    --fp-glass-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
    --fp-glass-blur: blur(8px);
    --fp-glass-radius: 12px;
    --fp-glass-ink: #44525f;
    --fp-glass-ink-strong: #16202b;
}
.fp-stage { position: absolute; inset: 0; }
.fp-canvas-wrap { position: absolute; inset: 0; }

/* Thin activity strip pinned to the stage top during an in-place floor
   switch (Item B) — floats above the still-mounted canvas. */
.fp-floorswitch-progress {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    z-index: 130;
}

/* ── Inspector (Item F1) — right-side floating properties panel ── */
.fp-inspector {
    position: absolute;
    top: 118px;
    right: 10px;
    width: 264px;
    max-height: calc(100% - 200px);
    overflow-y: auto;
    z-index: 110;
    display: flex;
    flex-direction: column;
    background: var(--fp-glass-bg);
    backdrop-filter: var(--fp-glass-blur);
    border-radius: var(--fp-glass-radius);
    animation: fp-inspector-in 0.16s ease-out;
}
@keyframes fp-inspector-in {
    from { opacity: 0; transform: translateX(8px); }
    to   { opacity: 1; transform: translateX(0); }
}
.fp-inspector-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    color: var(--fp-glass-ink-strong);
}
.fp-inspector-title {
    flex: 1;
    font-weight: 600 !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fp-inspector-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
}
.fp-inspector-footer {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
}

/* ── Campus Shapes panel rows (Item F2) ── */
.cm-shapes-list {
    overflow-y: auto;
    max-height: 55vh;
    padding: 4px 0;
}
.cm-shape-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 10px;
}
.cm-shape-row:hover { background: rgba(0, 0, 0, 0.04); }
.cm-shape-kind {
    flex-shrink: 0;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fp-glass-ink);
    background: rgba(0, 0, 0, 0.06);
    border-radius: 4px;
    padding: 1px 6px;
    min-width: 58px;
    text-align: center;
}
.cm-shape-label {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cm-shape-count {
    flex-shrink: 0;
    font-size: 11px;
    opacity: 0.5;
}

/* ── Mobile route map, Option B (KC 7/6, #156) ──
   Lives inside the /go page's 100dvh flex shell: the map takes a fixed
   share of the column (not of the whole viewport), the step list under it
   is the only thing that scrolls. On-map arrows removed (KC 7/6) — the
   footer's Previous/Next is the one step driver. */
.go-map-wrap {
    position: relative;
    flex: 0 0 38%;
    min-height: 200px;
    border-radius: 12px;
    overflow: hidden;
    background: #1e1e1e;
}
.go-map-canvas { position: absolute; inset: 0; }

/* Campus stage on the phone route (KC 7/15) — from-property directions open
   on the campus map with the serving lots highlighted, before the first
   in-building step. Opaque over the floor canvas, like the crossing screen. */
.go-campus-overlay {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #D6E6F4;          /* IDLE_BG_COLOR — matches the map surfaces */
    padding: 8px;
    animation: kiosk-cross-in 250ms ease-out both;
}
.go-campus-overlay svg {
    max-width: 100%;
    max-height: 100%;
}

/* Sky-bridge crossing on the phone route (KC 7/15) — the kiosk crossing
   schematic scaled into the go-map pane. Opaque over the canvas so the
   origin→destination floor swap never flashes through. Reuses the kiosk's
   fade-in and dot-travel keyframes. */
.go-cross-overlay {
    position: absolute;
    inset: 0;
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #D6E6F4;          /* IDLE_BG_COLOR — matches the kiosk screen */
    animation: kiosk-cross-in 250ms ease-out both;
}
.go-cross-diagram {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0 7%;
}
.go-cross-bldg {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px 18px;
    border-radius: 12px;
    /* background is the building's brand color (inline) — matches its badge */
    border: 3px solid #5C6770;    /* WALL_COLOR_LIGHT */
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}
.go-cross-badge {
    width: clamp(44px, 16vw, 72px);
    height: auto;
    display: block;
}
.go-cross-bldg > span {          /* text fallback (no badge for this letter) */
    font-size: clamp(20px, 7vw, 34px);
    font-weight: 800;
    color: #fff;
}
.go-cross-bridge {
    flex: 1 1 auto;
    position: relative;
    align-self: center;
    height: 26px;
    margin: 0 -3px;                    /* tuck under the building walls */
    background: #BAC3CA;               /* HALLWAY_COLOR_LIGHT */
    border-top: 4px solid #5C6770;
    border-bottom: 4px solid #5C6770;
}
.go-cross-dot {
    position: absolute;
    top: 50%;
    width: 20px;
    height: 20px;
    margin: -10px 0 0 -10px;
    border-radius: 50%;
    background: #FFEB3B;               /* WALKER_COLOR */
    border: 3px solid #F9A825;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
    animation: kiosk-cross-travel 2.4s ease-in-out infinite;
}
/* The renderer creates a bare canvas and relies on the CONTAINER's CSS to
   size it (same contract as .kiosk-map-container canvas) — without this the
   canvas renders at internal pixel size and overflows off-center (KC 7/6). */
.go-map-canvas canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
}
.go-map-handle {
    flex-shrink: 0;
    text-align: center;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--mud-palette-primary);
    padding: 6px 0 8px;
    cursor: pointer;
    user-select: none;
}

/* ── Tenant assigner + Floor Roster (KC 7/6) ── */
.tenant-assigner-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}
.roster-grid {
    display: flex;
    flex-direction: column;
    max-height: 62vh;
    overflow-y: auto;
}
.roster-row {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 10px 4px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
}
.roster-row:last-child { border-bottom: none; }
.roster-vacant { background: rgba(255, 167, 38, 0.05); }
.roster-suite {
    flex-shrink: 0;
    width: 90px;
    padding-top: 4px;
}
.roster-assigner { flex: 1; min-width: 0; }

/* ── Autosave status pill (Item F3) ── */
.fp-savepill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    align-self: center;
    user-select: none;
}
.fp-savepill-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}
.fp-savepill.is-saved  { color: #2E7D32; background: rgba(46, 125, 50, 0.10); }
.fp-savepill.is-dirty  { color: #B26A00; background: rgba(255, 167, 38, 0.14); }
.fp-savepill.is-saving { color: #1565C0; background: rgba(21, 101, 192, 0.10); }
.fp-savepill.is-saving .fp-savepill-dot { animation: fp-savepill-pulse 1s ease-in-out infinite; }
@keyframes fp-savepill-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.3; }
}

/* top-left stack: the bar and the floors panel share one flex column so the
   floors panel always sits BELOW the bar regardless of the bar's height. The
   wrapper is click-through; its children re-enable pointer events. */
.fp-topleftstack {
    position: absolute;
    top: 10px;
    left: 10px;
    right: 10px;
    z-index: 115;
    display: flex;
    flex-direction: column;
    gap: 10px;
    pointer-events: none;
}
.fp-topleftstack > * { pointer-events: auto; }

.fp-topchrome {
    order: 1;
    display: flex;
    flex-direction: column;
    gap: 0;
    background: var(--fp-glass-bg);
    backdrop-filter: var(--fp-glass-blur);
    border: var(--fp-glass-border);
    border-radius: var(--fp-glass-radius);
    padding: 3px 10px;
    box-shadow: var(--fp-glass-shadow);
}
/* keep the two rows tight inside the glass bar */
.fp-topchrome .mud-paper { padding-top: 2px !important; padding-bottom: 2px !important; }
/* inner Mud surfaces go transparent so the glass shows through */
.fp-topchrome .mud-paper { background: transparent !important; box-shadow: none !important; }

.fp-floors-float {
    order: 2;
    align-self: flex-start;
    max-height: 60vh;
    background: var(--fp-glass-bg) !important;
    backdrop-filter: var(--fp-glass-blur);
    border: var(--fp-glass-border);
    border-radius: var(--fp-glass-radius);
    box-shadow: var(--fp-glass-shadow);
}

/* Animated expand/collapse (0fr→1fr grid-track transition) — content stays
   mounted, so both open and close animate; the inner wrapper's overflow:hidden
   + min-width/height:0 let the track compress to nothing. */
.fp-collapse {
    display: grid;
    grid-template-rows: 0fr;
    grid-template-columns: 0fr;
    transition: grid-template-rows .22s ease, grid-template-columns .22s ease;
    min-height: 0;
}
.fp-collapse.open {
    grid-template-rows: 1fr;
    grid-template-columns: 1fr;
}
.fp-collapse-inner {
    overflow: hidden;
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    /* Fade with the size transition. The visibility flip is load-bearing, not
       cosmetic: hidden subtrees aren't rasterized, so revealing forces a fresh
       paint. Without it, Chromium reuses the blank texture it cached while the
       content sat clipped inside the collapsed track under a backdrop-filter
       panel (opacity alone won't fix it — that animates on the compositor
       without re-rastering). Hidden immediately on open (delay 0), but only
       after the collapse finishes on close, so the fade-out stays visible. */
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s ease, visibility 0s linear .24s;
}
/* CAUTION: keep fp-collapse for plain content (text rows, swatches) only.
   MudBlazor components inside get their own paint layers, which Chromium
   culls when first rasterized inside the collapsed clip — they stay blank
   after expanding. Panels full of Mud controls (Floors, Shapes) mount via
   @if with .fp-panel-in instead. */
.fp-panel-in {
    display: flex;
    flex-direction: column;
    min-height: 0;
    animation: fp-panel-in .18s ease-out;
}
@keyframes fp-panel-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
}
.fp-collapse.open > .fp-collapse-inner {
    opacity: 1;
    visibility: visible;
    transition: opacity .2s ease, visibility 0s;
}

/* Legend flyout — same collapsed-chip glass as the Floors panel above it */
.fp-legend-float {
    order: 3;
    align-self: flex-start;
    max-height: 55vh;
    overflow-y: auto;
    background: var(--fp-glass-bg) !important;
    backdrop-filter: var(--fp-glass-blur);
    border: var(--fp-glass-border);
    border-radius: var(--fp-glass-radius);
    box-shadow: var(--fp-glass-shadow);
}
/* Two columns so every section is visible at once without a tall tower;
   sections keep together via break-inside. */
.fp-legend-body {
    padding: 4px 12px 10px;
    width: 380px;
    columns: 2;
    column-gap: 18px;
}
.fp-legend-group {
    break-inside: avoid;
    margin-bottom: 6px;
}
.fp-legend-sec {
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fp-glass-ink);
    opacity: 0.75;
    margin: 8px 0 3px;
}
.fp-legend-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--fp-glass-ink-strong);
    padding: 2px 0;
    white-space: nowrap;
}
.fp-legend-note {
    font-size: 10.5px;
    opacity: 0.55;
    margin-left: 2px;
}
/* Swatch chip sits on canvas-dark so colors read exactly as on stage */
.fp-legend-sw {
    flex: 0 0 auto;
    width: 30px;
    height: 18px;
    border-radius: 4px;
    background: #1e1e1e;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 1px;
}
.fp-legend-sw i { display: inline-block; width: 16px; height: 10px; border-radius: 2px; }
.fp-legend-sw i + i { width: 5px; }                        /* multi-chip (occupied palette) */
.fp-legend-sw i:first-child:not(:last-child) { width: 5px; }
.fp-legend-sw i.ln { width: 20px; height: 0; border-top: 3px solid; border-radius: 0; }
.fp-legend-sw i.bar { width: 16px; height: 5px; border-radius: 1px; }
.fp-legend-sw i.sq { width: 11px; height: 11px; border-radius: 3px; }
.fp-legend-sw i.dot { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid #0d1b33; }

/* Corners key inside the suite inspector — same dot colors as VertexDotFill */
.fp-corner-key {
    display: flex;
    gap: 12px;
    font-size: 11px;
    color: var(--fp-glass-ink);
    padding-top: 2px;
}
.fp-corner-key span { display: inline-flex; align-items: center; gap: 5px; }
.fp-corner-key i { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid #0d1b33; }

/* Bottom hint strip — inline preview-color swatches while a draw tool is active */
.fp-hint-dash {
    display: inline-block;
    width: 20px;
    border-top: 3px dashed;
    vertical-align: middle;
}
.fp-hint-bar {
    display: inline-block;
    width: 16px;
    height: 5px;
    border-radius: 1px;
    vertical-align: middle;
}

.floor-plan-svg {
    display: block;
}

.floor-plan-svg polyline {
    vector-effect: non-scaling-stroke;
}

.floor-plan-svg circle {
    vector-effect: non-scaling-stroke;
}

/* Bottom-center floating tool dock (#A3) — shares the glass aesthetic */
.fp-tooldock {
    position: absolute;
    left: 50%;
    bottom: 44px; /* raised so the controls-key hint line below it stays visible */
    transform: translateX(-50%);
    z-index: 120;
    display: flex;
    align-items: center;
    gap: 2px;
    max-width: calc(100% - 32px);
    overflow-x: auto;
    background: var(--fp-glass-bg);
    backdrop-filter: var(--fp-glass-blur);
    border: var(--fp-glass-border);
    border-radius: var(--fp-glass-radius);
    padding: 6px 8px;
    box-shadow: var(--fp-glass-shadow);
}
.fp-tool {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    color: var(--fp-glass-ink);
    padding: 6px 9px;
    border-radius: 9px;
    cursor: pointer;
    user-select: none;
    min-width: 48px;
}
.fp-tool span { font-size: 10px; line-height: 1; white-space: nowrap; }
.fp-tool .mud-icon-root { font-size: 20px; }
.fp-tool:hover { background: rgba(0, 0, 0, 0.06); color: var(--fp-glass-ink-strong); }
.fp-tool.on { background: #ea9f23; color: #1a1205; }
.fp-tool.on .mud-icon-root { color: #1a1205; }
.fp-dock-div { width: 1px; height: 30px; background: rgba(0, 0, 0, 0.12); margin: 0 4px; flex: 0 0 auto; }

/* Suite vertex handles (KC 7/8): a generous 15px transparent hit circle makes
   grabbing/highlighting forgiving; the visible dot grows and gains a white
   outline on hover so the corner you're about to grab is unmistakable. */
/* Hover bump is a relative scale, not an absolute r: the dot radii are
   pixel-anchored SVG units now (PxToSvg), so a hard-coded SVG-unit size
   balloons when zoomed in (KC 8/20). */
.fp-vtx-dot { transition: transform .08s ease, stroke .08s ease; transform-box: fill-box; transform-origin: center; }
.fp-vtx-hit:hover + .fp-vtx-dot { transform: scale(1.25); stroke: #ffffff; }

/* Floating zoom controls — shares the glass aesthetic */
.fp-zoom {
    position: absolute;
    bottom: 12px;
    right: 12px;
    z-index: 100;
    display: flex;
    align-items: center;
    gap: 2px;
    background: var(--fp-glass-bg);
    backdrop-filter: var(--fp-glass-blur);
    border: var(--fp-glass-border);
    border-radius: var(--fp-glass-radius);
    padding: 2px 6px;
    box-shadow: var(--fp-glass-shadow);
}
.fp-zoom .mud-icon-button { color: var(--fp-glass-ink); }
.fp-zoom-label { min-width: 40px; text-align: center; color: var(--fp-glass-ink); }

/* Background alignment panel (#481) — glass card on the right edge, clear of
   the top-left stack, the bottom tool dock and the zoom controls. */
.fp-alignpanel {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 130;
    width: 340px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--fp-glass-bg);
    backdrop-filter: var(--fp-glass-blur);
    border: var(--fp-glass-border);
    border-radius: var(--fp-glass-radius);
    padding: 10px 14px 12px;
    box-shadow: var(--fp-glass-shadow);
    color: var(--fp-glass-ink-strong);
}
.fp-align-hint { opacity: 0.8; margin-bottom: 4px; }
.fp-align-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.fp-align-row .mud-slider { flex: 1 1 auto; }
.fp-align-lbl {
    flex: 0 0 62px;
    font-size: 12px;
    color: var(--fp-glass-ink);
}
.fp-align-val {
    flex: 0 0 46px;
    text-align: right;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--fp-glass-ink);
}
.fp-align-row .mud-icon-button { color: var(--fp-glass-ink); padding: 2px; }
.fp-align-actions {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

.floor-sidebar-item:hover .floor-reorder-buttons {
    opacity: 1 !important;
}

/* Feedback popup */
@keyframes kiosk-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.kiosk-feedback-popup {
    position: fixed;
    bottom: 16px;
    right: 16px;
    z-index: 50;
    background: rgba(0, 0, 0, 0.75);
    backdrop-filter: blur(8px);
    padding: 12px;
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    align-items: center;
}
/* Splash / idle screen */
.kiosk-splash {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    background: #D6E6F4;
    cursor: pointer;
    position: relative;
}

.kiosk-splash-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.75rem 1rem 0.5rem;
    z-index: 1;
    background: linear-gradient(to bottom, #f0f0f0 30%, transparent 100%);
}

.kiosk-splash-title {
    font-family: 'Montserrat', sans-serif;
    font-size: 4.5rem;
    font-weight: 800;
    color: #1a2332;
    text-align: center;
    letter-spacing: 0.15em;
    text-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), 0 8px 40px rgba(0, 0, 0, 0.2);
}

.kiosk-splash-footer {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem 2.5rem;
    z-index: 1;
    pointer-events: none;
}

.kiosk-splash-cta {
    font-family: 'Montserrat', sans-serif;
    font-size: 2.4rem;
    font-weight: 800;
    /* Matches the FIND YOUR WAY title color (KC 5/20). */
    color: #1a2332;
}

.kiosk-splash-restroom {
    position: fixed;
    bottom: 12px;
    /* Bottom-left corner — clear of the feedback-QR on the bottom-right, which
       they used to overlap when the QR widened (Kyle). */
    left: 12px;
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 100px;
    height: 100px;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(8px);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: rgba(255, 255, 255, 0.8);
    font-family: 'Montserrat', sans-serif;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease;
}

.kiosk-splash-restroom .mud-icon-root {
    font-size: 2.5rem;
}

.kiosk-splash-restroom:active {
    background: rgba(0, 0, 0, 0.7);
}

/* Restroom gender picker page */
.kiosk-restroom-picker {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

.kiosk-restroom-picker-content {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.kiosk-restroom-picker-buttons {
    display: flex;
    gap: 48px;
}

.kiosk-restroom-picker-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    width: 240px;
    height: 280px;
    background: rgba(255, 255, 255, 0.08);
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-radius: 20px;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.kiosk-restroom-picker-btn:active {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.3);
}

.kiosk-restroom-icon {
    width: 96px;
    height: 96px;
    font-size: 96px !important;
}

/* Directory restroom button */
.kiosk-directory-restroom {
    position: fixed;
    bottom: 12px;
    /* Right side: [search pill] … [Restrooms] [feedback-QR] (Kyle 6/3). */
    right: var(--kiosk-restroom-right);
    /* Above the QR card rather than under it: if these ever overlap again, the
       label a visitor needs should win over the marketing QR (KC 7/24). */
    z-index: 10000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: var(--kiosk-restroom-w);
    height: 100px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: rgba(255, 255, 255, 0.8);
    font-family: 'Montserrat', sans-serif;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease;
}

.kiosk-directory-restroom .mud-icon-root {
    font-size: 2.5rem;
}

.kiosk-directory-restroom:active {
    background: rgba(255, 255, 255, 0.18);
}

/* 10-key numpad on the right side of the keyboard container. Phone-style
   3x4 grid (1-9, blank, 0, blank) so visitors can search by suite number
   without using the QWERTY (Teresa 5/19). */
.kiosk-numpad {
    /* In-flow beside the QWERTY (part of the centered keyboard group). */
    display: grid;
    grid-template-columns: repeat(3, 60px);
    grid-auto-rows: 60px;
    gap: 5px;
    flex-shrink: 0;
}

.kiosk-numpad-key.mud-button {
    min-height: 60px;
    min-width: 60px;
    font-size: 1.5rem;
    font-weight: 700;
    border-radius: 8px;
    padding: 0;
}

.kiosk-numpad-spacer {
    /* Empty grid cell — keeps "0" centered in the bottom row */
}

/* QR-handoff popup — full-screen takeover offering phone-scan or kiosk path */
.kiosk-qr-handoff {
    position: absolute;
    inset: 0;
    background: rgba(10, 16, 28, 0.92);
    backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    animation: kiosk-fade-in 0.18s ease;
}

.kiosk-qr-handoff-card {
    display: flex;
    align-items: stretch;
    gap: 0;
    background: rgba(20, 28, 42, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 24px;
    padding: 48px 56px;
    box-shadow: 0 20px 80px rgba(0, 0, 0, 0.6);
    max-width: 90%;
}

.kiosk-qr-handoff-left {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 48px 0 0;
    min-width: 320px;
}

.kiosk-qr-handoff-qr {
    background: white;
    padding: 16px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.kiosk-qr-handoff-caption {
    margin-top: 20px;
    color: rgba(255, 255, 255, 0.95);
    font-size: 1.25rem;
    font-weight: 700;
    text-align: center;
    letter-spacing: 0.2px;
}

.kiosk-qr-handoff-divider {
    width: 1px;
    background: rgba(255, 255, 255, 0.12);
    margin: 0 0;
}

/* Cross-campus notice card (#479): the campus map panel showing YOU ARE HERE
   and GO HERE side by side, and the scan-to-continue QR under the copy. The
   map keeps its own aspect — it sits in the left slot the way the handoff QR
   does, so the two cards feel like the same family. */
.kiosk-unroutable-map {
    width: 620px;
    max-width: 46vw;
    height: 420px;
    padding: 0 40px 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.kiosk-unroutable-map .kiosk-campus {
    width: 100%;
    height: 100%;
}

.kiosk-unroutable-qr {
    margin-top: 28px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.kiosk-unroutable-qr > div:first-child {
    background: white;
    padding: 14px;
    border-radius: 12px;
    line-height: 0;
}

.kiosk-unroutable-qr .kiosk-qr-handoff-caption {
    margin-top: 14px;
    font-size: 1.1rem;
}

.kiosk-qr-handoff-right {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 0 0 56px;
    min-width: 340px;
}

.kiosk-qr-handoff-right .mud-button {
    min-height: 72px;
    font-size: 1.2rem;
    border-radius: 12px;
}

/* Feature-flag toast — brief on-screen confirmation when a flag is toggled */
.kiosk-flag-toast {
    position: fixed;
    top: 24px;
    right: 24px;
    z-index: 10000;
    background: rgba(20, 28, 42, 0.95);
    color: #FFD54F;
    border: 1px solid rgba(255, 213, 79, 0.4);
    border-radius: 10px;
    padding: 10px 18px;
    font-family: monospace;
    font-size: 0.95rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
    animation: kiosk-fade-in 0.18s ease;
}

/* Feedback QR widget — outer-left slot beside the Restrooms button */
.kiosk-feedback-qr {
    position: fixed;
    bottom: 12px;
    /* Bottom-RIGHT now (Kyle 6/3) so it stops covering provider names on the
       left of the directory list. The width feeds --kiosk-restroom-right and the
       reserved gutters, so changing it moves everything else with it. */
    right: var(--kiosk-qr-right);
    width: var(--kiosk-qr-w);
    z-index: 9999;
    background: rgba(30, 40, 55, 0.92);
    backdrop-filter: blur(12px);
    padding: 20px;
    border-radius: 16px;
    border: 2px solid rgba(38, 198, 218, 0.45);   /* prominent touchless accent (#449) */
    display: flex;
    flex-direction: column;
    align-items: center;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
}

.kiosk-feedback-qr-title {
    color: rgba(255, 255, 255, 0.95);
    text-align: center;
    margin-top: 12px;
    font-weight: 800;
    font-size: 1.1rem;
}


/* ============================================================
   Kiosk Light Theme (toggled via Shift+L; bound to
   SessionStateService.KioskLightMode, applied via the
   .kiosk-light class on the MudLayout root).
   Each rule overrides a dark-mode surface; keep them grouped
   here so the dark theme above stays untouched.
   ============================================================ */

.kiosk.kiosk-light {
    color: #1F2330;
}

/* Search bar */
.kiosk-light .kiosk-search-bar {
    background: rgba(0, 0, 0, 0.04);
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
/* #382: the white field on the near-white keyboard dock had too little edge
   contrast on camera for the older population (Yvonne 6/8 — "can this be a
   different color?"). Bold teal border so it clearly reads as a search box. */
.kiosk-light .kiosk-search-bar .mud-input-outlined-border {
    border-color: #1797A6 !important;
    border-width: 2.5px !important;
}
/* #359: solid white field in light mode — see the dark-mode rule up top. */
.kiosk-light .kiosk-search-bar .kiosk-search-input .mud-input-outlined {
    background: #FFFFFF;
}

/* Results list — rows, headers, divider */
.kiosk-light .kiosk-results {
    background: #FFFFFF;
}
.kiosk-light .kiosk-results-header {
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.kiosk-light .kiosk-result-row {
    color: #1F2330;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.kiosk-light .kiosk-result-practice-row {
    background: rgba(0, 0, 0, 0.025);
}
.kiosk-light .kiosk-result-row .mud-typography-body2,
.kiosk-light .kiosk-result-row .kiosk-result-location,
.kiosk-light .kiosk-result-row .kiosk-result-specialty {
    color: rgba(0, 0, 0, 0.6);
}

/* Keyboard area */
.kiosk-light .kiosk-keyboard-container {
    background: rgba(0, 0, 0, 0.04);
    border-top: 1px solid rgba(0, 0, 0, 0.08);
}
.kiosk-light .kiosk-key.mud-button {
    background: #FFFFFF;
    color: #1F2330;
    border: 1px solid rgba(0, 0, 0, 0.1);
}
.kiosk-light .kiosk-key.mud-button:active {
    background: rgba(0, 0, 0, 0.05);
}

/* Back-to-Directory pill */
.kiosk-light .kiosk-back-btn.mud-button {
    background: rgba(255, 255, 255, 0.92);
    color: #1F2330;
    border: 1px solid rgba(0, 0, 0, 0.1);
}

/* Restrooms button (splash + directory variants share base layout) */
.kiosk-light .kiosk-splash-restroom,
.kiosk-light .kiosk-directory-restroom {
    background: rgba(255, 255, 255, 0.92);
    color: #1F2330;
    border: 1px solid rgba(0, 0, 0, 0.1);
}

/* Route panel — title, step list, footer */
.kiosk-light .kiosk-route-panel {
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(12px);
    border-left: 1px solid rgba(0, 0, 0, 0.08);
    color: #1F2330;
}
.kiosk-light .kiosk-route-panel .mud-typography,
.kiosk-light .kiosk-route-panel .mud-list-item {
    color: #1F2330;
}
.kiosk-light .kiosk-route-panel .kiosk-step-inactive {
    color: rgba(0, 0, 0, 0.4);
}

/* QR-handoff popup overlay */
.kiosk-light .kiosk-qr-handoff {
    background: rgba(244, 245, 247, 0.94);
}
.kiosk-light .kiosk-qr-handoff-card {
    background: #FFFFFF;
    border: 1px solid rgba(0, 0, 0, 0.08);
}
.kiosk-light .kiosk-qr-handoff-caption {
    color: #1F2330;
}
.kiosk-light .kiosk-qr-handoff-divider {
    background: rgba(0, 0, 0, 0.12);
}
.kiosk-light .kiosk-qr-handoff-right .mud-typography {
    color: #1F2330;
}

/* Feedback QR pill */
.kiosk-light .kiosk-feedback-qr {
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid rgba(0, 0, 0, 0.08);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
}
.kiosk-light .kiosk-feedback-qr-title {
    color: #1F2330;
}

/* Splash background — cool blue / deep navy that matches both the
   campus map letterbox color and the navigation canvas background,
   so the kiosk reads as one consistent surface across all screens
   (KC 5/20: "extend it to the navigation maps too"). */
.kiosk-light .kiosk-splash {
    background: #D6E6F4;
}
.kiosk:not(.kiosk-light) .kiosk-splash {
    background: #0F1B2E;
    color: #FFFFFF;
}
.kiosk:not(.kiosk-light) .kiosk-splash-title,
.kiosk:not(.kiosk-light) .kiosk-splash-cta {
    color: #FFFFFF;
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}

/* ============================================================
   Campus Map (ground-floor splash) — Carto basemap with our own
   building polygons overlaid and a YOU-ARE-HERE highlight.
   ============================================================ */

.kiosk-campus {
    flex: 1;
    min-height: 0;
    height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.kiosk-campus-svg {
    width: 100%;
    height: 100%;
    max-height: 100%;
    user-select: none;
}

/* Zoom layer between the (overflow-clipped) campus container and the SVG.
   The exit zoom animates here so the SVG keeps its isometric squash intact
   (option 2, Kyle 6/3). Fills the container; the SVG fills it in turn. */
.kiosk-campus-zoom {
    width: 100%;
    height: 100%;
}

/* Idle mode (splash): the campus is shown stationary in its natural
   orientation. Earlier iterations rotated the whole canvas with a CSS
   perspective tilt; that was distracting (Kyle 5/26) and conflicted with
   the alignment-effect principle for you-are-here maps. Motion is now
   carried by the current-building strobe (kiosk-campus-here-pulse) and
   the YOU ARE HERE callout bob (kiosk-campus-here-bob). */
.kiosk-campus-idle .kiosk-campus-svg {
    /* Light blue surround in case the SVG ever doesn't fill the splash
       (e.g. extreme aspect ratios). */
    background-color: #D6E6F4;
    /* Isometric view (CBRE 6/2): a 2D vertical squash fakes the tilt while
       keeping everything in-plane — so buildings can be extruded with real
       walls (drawn in the SVG) to read as 3D massing, and the YOU ARE HERE
       callout can counter-scale to stay upright. No CSS 3D, so no spinning-
       disorientation issue Kyle flagged. */
    transform: scale(1.06, 0.6);
    transform-origin: 50% 44%;
    transition: transform 0.6s ease;
}

/* Drop shadow on the map — applied to the inner shadow group (image +
   frame + polygons) so the SVG <text> labels stay outside the filter
   and render crisply (drop-shadow rasterizes its content; doing it on
   a parent group blurred the labels — KC 5/20). */
.kiosk-campus-idle .kiosk-campus-shadow {
    filter: drop-shadow(0 12px 24px rgba(0, 0, 0, 0.35));
}

/* The floating building badges sit OUTSIDE the shadow-filter group (so they
   stay crisp), so give them their own drop shadow — straight down, matching
   the isometric ground shadow's angle — so the lifted plaques read as
   floating (CBRE 6/3). */
.kiosk-campus-badge-img {
    filter: drop-shadow(0 7px 12px rgba(0, 0, 0, 0.4));
}

/* "Touch to Begin" exit transition (KC 5/20): zoom toward the current
   building's actual on-screen position and fade out. The kiosk-hotkeys
   helper (kioskCampusBeginExit) writes the building's screen-relative
   position into --focus-x / --focus-y so the zoom origin is the
   highlighted polygon. */
.kiosk-campus-exiting .kiosk-campus-zoom {
    transform-origin: var(--focus-x, 50%) var(--focus-y, 50%);
    animation: kiosk-campus-exit 700ms ease-in forwards;
}
.kiosk-campus-exiting .kiosk-splash-header,
.kiosk-campus-exiting .kiosk-splash-footer {
    animation: kiosk-campus-fadeout 350ms ease-in forwards;
}
.kiosk-splash:has(.kiosk-campus-exiting) .kiosk-splash-header,
.kiosk-splash:has(.kiosk-campus-exiting) .kiosk-splash-footer {
    animation: kiosk-campus-fadeout 350ms ease-in forwards;
}

@keyframes kiosk-campus-exit {
    0%   { transform: scale(1);   opacity: 1; }
    70%  { transform: scale(2.4); opacity: 0.65; }
    100% { transform: scale(3.6); opacity: 0; }
}

@keyframes kiosk-campus-fadeout {
    to { opacity: 0; }
}

/* Splash header + footer banners — KC 5/20: make these transparent
   AND absolute-positioned so the campus map can render full-bleed
   underneath them. Without absolute positioning they'd still take up
   vertical space in the splash's flex column and clip the rotating
   map's corners at that internal boundary. */
.kiosk-splash-header,
.kiosk-splash-footer {
    background: transparent !important;
    position: absolute;
    left: 0;
    right: 0;
    z-index: 2;
    pointer-events: none;
}
.kiosk-splash-header { top: 0; }
.kiosk-splash-footer { bottom: 0; }
.kiosk-splash > .kiosk-campus,
.kiosk-splash > .kiosk-map-container {
    flex: 1 1 100%;
}

/* Campus zones — the stylized "ground" the buildings sit on. Traced by
   the admin in the campus-map editor; each type has a fixed map-like
   fill. Drawn beneath the building polygons. */
.kiosk-campus-zone {
    stroke-width: 2;
    stroke-linejoin: round;
}
.kiosk-campus-zone-greenspace { fill: #C6DCA8; stroke: #A9C487; }
/* Parking + road both read as dark "asphalt" so pavement is unmistakable
   at a glance and clearly distinct from buildings/walkable destinations
   (CBRE 6/2). Road is a touch lighter than parking so the two surfaces
   differentiate where they meet (CBRE 6/3). Desaturated dark gray with a
   slightly lighter edge stroke. */
.kiosk-campus-zone-parking    { fill: #3A3A3D; stroke: #4A4A4E; }
.kiosk-campus-zone-road       { fill: #616169; stroke: #70707A; }
.kiosk-campus-zone-walkway    { fill: #E8DCC0; stroke: #CFBF99; }

/* Campus paths — roads + sky bridges traced as open polylines (KC 5/25).
   Stroked, never filled. Round caps/joins so intersections and branches
   read as a continuous ribbon. Stroke-widths are in basemap pixel
   units; tuned for ~1200px-wide reference images. */
.kiosk-campus-path {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.kiosk-campus-path-road      { stroke: #616169; stroke-width: 14; }
.kiosk-campus-path-skybridge { stroke: #C9B589; stroke-width: 12; }

/* Procedural parking-stall striping + parked cars (CBRE 6/3), generated
   per lot in CampusMapView. Stall lines are a soft light gray on the
   asphalt — present but not harsh. Cars carry a faint dark edge for
   definition and are filled with desaturated tones so they don't pull
   focus. */
.kiosk-campus-stall line,
.kiosk-campus-stall path { stroke: #9AA0A6; stroke-width: 0.7; stroke-opacity: 0.5; fill: none; }
.kiosk-campus-car { stroke: #26262A; stroke-width: 0.3; stroke-opacity: 0.55; }

/* Hospital marker — universal "H on blue" sign treatment (KC 5/25).
   Polygon fill is a light blue (building's PrimaryColor); on top sits
   a darker-blue square tile with the white H inside, mirroring the
   MOB letter-badge style: sharp corners, no stroke. */
.kiosk-campus-hospital-tile {
    fill: #003DA5;
    stroke: none;
}
.kiosk-campus-label-hospital {
    fill: #FFFFFF;
    font-family: 'Lato', sans-serif;
    font-weight: 900;
    font-size: 32px;
    text-anchor: middle;
    dominant-baseline: central;
}

/* Building letter badge (CBRE 6/2): solid tile in the building's brand
   color with a white border + white letter, replacing the old "MOB C"
   text. Mirrors the hospital sign treatment for the rest of campus. */
.kiosk-campus-letter-tile {
    stroke: #FFFFFF;
    stroke-width: 2;
}
.kiosk-campus-label-letter {
    fill: #FFFFFF;
    font-family: 'Montserrat', sans-serif;
    font-weight: 800;
    font-size: 28px;
    text-anchor: middle;
    dominant-baseline: central;
}

.kiosk-campus-zone-label {
    fill: #5A6270;
    font-family: 'Lato', sans-serif;
    font-weight: 700;
    font-size: 16px;
    text-anchor: middle;
    dominant-baseline: middle;
    paint-order: stroke;
    stroke: rgba(255,255,255,0.9);
    stroke-width: 3;
    stroke-linejoin: round;
}
.kiosk:not(.kiosk-light) .kiosk-campus-zone-label {
    fill: #C8CEDA;
    stroke: rgba(0,0,0,0.7);
}

/* Distance-landmark labels floating past the campus edge for orientation
   (Yvonne 3/30) — muted, uppercase, tracked-out so they read as "off in the
   distance, this way" rather than competing with the building badges. */
.kiosk-campus-landmark {
    fill: #8A98A6;
    font-family: 'Inter', -apple-system, sans-serif;
    font-weight: 600;
    font-size: 36px;
    letter-spacing: 2px;
    text-transform: uppercase;
    text-anchor: middle;
    dominant-baseline: middle;
    opacity: 0.25;
}

/* Building entrance markers on the campus overview (#324): an upright,
   billboarded green badge with a white border and a white entrance
   pictogram (style chosen in Settings). Green is the universal entrance
   color; it reads on grass, asphalt, or a building roof. */
.kiosk-campus-entrance-badge {
    fill: #2E7D32;
    stroke: #FFFFFF;
    stroke-width: 2.5;
}

/* Orange frame around the basemap — picks up the building palette's
   dark color (CBRE gold #EA9F23 for MOB C) so the frame matches the
   kiosk-header swoop on the same page (KC 5/20 experiment). */
.kiosk-campus-frame {
    fill: none;
    stroke: var(--building-dark, #EA9F23);
    stroke-width: 5;
    pointer-events: none;
}

.kiosk-campus-building {
    fill: var(--building-dark, #1976D2);
    fill-opacity: 1;
    stroke: var(--building-dark, #1976D2);
    stroke-width: 2;
    stroke-opacity: 1;
    transition: fill-opacity 0.3s ease;
}

.kiosk-campus-here {
    fill: var(--building-dark, #1976D2);
    fill-opacity: 1;
    stroke-width: 3;
    stroke-opacity: 1;
    animation: kiosk-campus-here-pulse 2.4s ease-in-out infinite;
}

@keyframes kiosk-campus-here-pulse {
    0%, 100% { fill-opacity: 1; }
    50%      { fill-opacity: 0.82; }
}

/* YOU ARE HERE callout bob — the whole dialog (body + tail + label)
   floats up and down a few units so the eye catches it without
   anything rotating or skewing (Kyle 5/26). Period matches the
   building strobe so the two animations feel coordinated. Pure
   translate — the tail's point shape is preserved. */
.kiosk-campus-here-bob {
    transform-box: fill-box;
    transform-origin: center;
    animation: kiosk-campus-here-bob 2.4s ease-in-out infinite;
}

@keyframes kiosk-campus-here-bob {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-6px); }
}

.kiosk-campus-label {
    fill: #1F2330;
    font-family: 'Montserrat', sans-serif;
    font-weight: 800;
    font-size: 24px;
    text-anchor: middle;
    dominant-baseline: middle;
    paint-order: stroke;
    stroke: rgba(255,255,255,0.92);
    stroke-width: 4;
    stroke-linejoin: round;
}

/* Basemap image opacity on the kiosk splash (KC 5/25). 50% lets the
   colored polygons and the YOU ARE HERE dialog read as the primary
   foreground while the campus context shows through more subtly. */
.kiosk-campus-basemap {
    opacity: 0.5;
}

/* "You are here" callout dialog (KC 5/25). Angular red dialog box
   with a downward-pointing tail "originating from" the current
   building. The dialog body uses a wayfinding/emergency red so it
   pops against any building color. */
.kiosk-campus-here-dialog {
    fill: #DC2626;
    stroke: #7F1D1D;
    stroke-width: 2;
    stroke-linejoin: miter;  /* sharp corners — angular, not rounded */
}
/* GO HERE — the cross-campus destination callout (#479). Green against the
   red YOU ARE HERE so the pair reads at a glance from across a lobby. */
.kiosk-campus-dest-dialog {
    fill: #15803D;
    stroke: #14532D;
    stroke-width: 2;
    stroke-linejoin: miter;
}
.kiosk-campus-here-label {
    fill: #FFFFFF;
    font-family: 'Montserrat', sans-serif;
    font-weight: 800;
    font-size: 18px;
    letter-spacing: 0.12em;
    text-anchor: middle;
    dominant-baseline: central;
    paint-order: stroke;
    stroke: rgba(0,0,0,0.30);
    stroke-width: 1;
    stroke-linejoin: round;
}

/* Dark-theme overrides for the campus building labels (the kiosk
   renders the drawn shapes on a deep-navy SVG background in dark mode;
   labels need contrast). The here-dialog stays red in either theme. */
.kiosk:not(.kiosk-light) .kiosk-campus-label {
    fill: #FFFFFF;
    stroke: rgba(0,0,0,0.75);
}

/* ============================================================
   Kiosk self-setup screen (/kiosksetup/{siteId}) — KioskSetupLayout
   + KioskSetupPage. Full-viewport dark picker an installer taps
   through once on first boot. Big touch targets, no scrolling.
   ============================================================ */
.kiosk-setup-root {
    position: fixed;
    inset: 0;
    background: #141b27;
    color: #e8ecf3;
    overflow: hidden;
}

.kiosk-setup-screen {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vh 4vw;
    box-sizing: border-box;
}

.kiosk-setup-center {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.kiosk-setup-card {
    width: 100%;
    max-width: 1100px;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
}

.kiosk-setup-title {
    font-weight: 700;
    text-align: center;
}

.kiosk-setup-subtitle {
    color: #aab2c2;
    text-align: center;
    margin-top: 6px;
    margin-bottom: 28px;
    font-weight: 400;
}

.kiosk-setup-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
    align-content: flex-start;
    width: 100%;
    overflow-y: auto;
}

/* Big touch tile. The --tile custom property is the building's brand color,
   used for a left accent bar and the press state. */
.kiosk-setup-tile {
    --tile: #546E7A;
    flex: 0 1 320px;
    min-height: 132px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 6px;
    padding: 22px 26px;
    border: 2px solid rgba(255, 255, 255, 0.10);
    border-left: 10px solid var(--tile);
    border-radius: 14px;
    background: #1e2735;
    color: #e8ecf3;
    cursor: pointer;
    text-align: left;
    transition: background 0.12s ease, transform 0.05s ease, border-color 0.12s ease;
    font-family: inherit;
}

.kiosk-setup-tile:hover {
    background: #26303f;
    border-color: rgba(255, 255, 255, 0.22);
}

.kiosk-setup-tile:active {
    transform: scale(0.985);
    background: var(--tile);
    border-color: var(--tile);
}

.kiosk-setup-tile-title {
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 1.6rem;
    line-height: 1.15;
}

.kiosk-setup-tile-sub {
    font-size: 1.05rem;
    color: #aab2c2;
}

.kiosk-setup-tile:active .kiosk-setup-tile-sub {
    color: rgba(255, 255, 255, 0.85);
}

/* From-home landing (#433): the ZIP is the primary input, so make it large,
   centred and spaced so it reads as the first thing to do. */
.fromhome-zip-field input {
    font-size: 1.6rem;
    text-align: center;
    letter-spacing: 4px;
    font-weight: 600;
}

.fromhome-zip-field input::placeholder {
    font-size: 1rem;
    letter-spacing: normal;
    font-weight: 400;
}

/* NO / YES labels flanking the accessible-parking switch — the active side is
   highlighted so the current choice is unmistakable (#433). */
.fromhome-yesno {
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: 1px;
    color: var(--mud-palette-text-disabled);
    transition: color 0.15s ease;
}

.fromhome-yesno-on {
    color: var(--mud-palette-info);
}


/* Two-finger horizontal scroll must pan the map, never trigger Chrome's
   back/forward history swipe. The editors' wheel handlers preventDefault,
   but any gap (a re-render swapping the SVG node, cursor over the
   inspector) let leftover horizontal deltas become navigation (KC 8/20).
   Kiosks are touchscreens, so there is no trackpad behavior to lose. */
html, body {
    overscroll-behavior-x: none;
}
