/* ==========================================================================
   CityGuide Core Design System & Stylesheet
   ========================================================================== */

/* Design Tokens & Variables */
:root {
    --bg-dark: #f8fafc;
    --bg-glass: rgba(255, 255, 255, 0.7);
    --border-glass: rgba(0, 0, 0, 0.08);
    --border-glass-active: rgba(99, 102, 241, 0.3);
    
    /* Typography */
    --font-heading: 'Outfit', sans-serif;
    --font-body: 'Inter', sans-serif;
    
    /* Colors */
    --color-text-main: #0f172a;
    --color-text-muted: #64748b;
    --color-mint: #10b981;
    --color-cyan: #06b6d4;
    --color-indigo: #4f46e5;
    --color-sunset: #f97316;
    
    /* Tour marker colour */
    --cat-custom: #f97316;
    
    /* Transitions & Shadows */
    --transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    --shadow-premium: 0 4px 20px 0 rgba(0, 0, 0, 0.08);
    --shadow-glow: 0 0 15px rgba(99, 102, 241, 0.15);
    --blur-strength: 12px;
}

/* Base Reset & Layout */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: var(--font-body);
    background-color: var(--bg-dark);
    color: var(--color-text-main);
    overflow: hidden;
    height: 100vh;
    height: 100dvh;
    width: 100vw;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    letter-spacing: -0.02em;
}

/* Accessibility: a single visible keyboard-focus ring for every interactive
   control. :focus-visible only triggers for keyboard/AT navigation, so mouse
   and touch clicks stay ring-free. */
:focus-visible {
    outline: 2px solid var(--color-indigo);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Respect users who ask for less motion: neutralise the looping pulses and
   slide/scale transitions rather than animating them. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

a {
    color: var(--color-cyan);
    text-decoration: none;
    transition: var(--transition-smooth);
}
@media (hover: hover) {
    a:hover {
        color: var(--color-mint);
        text-decoration: underline;
    }
}

/* Visually hidden, still announced by screen readers. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Glassmorphism Class utility */
.glass-panel {
    background: var(--bg-glass);
    backdrop-filter: blur(var(--blur-strength));
    -webkit-backdrop-filter: blur(var(--blur-strength));
    border: 1px solid var(--border-glass);
    box-shadow: var(--shadow-premium);
}

/* App Container */
.app-container {
    display: flex;
    height: 100vh;
    height: 100dvh;
    width: 100vw;
    position: relative;
}


/* ==========================================================================
   Map Interface
   ========================================================================== */
.map-wrapper {
    flex: 1;
    position: relative;
    height: 100%;
}

#map {
    height: 100%;
    width: 100%;
    background-color: var(--bg-dark);
}

/* ==========================================================================
   Place search (top bar; navigates the map)
   ========================================================================== */
.search-box {
    position: absolute;
    top: 20px;
    left: 76px;          /* directly right of the floating button column */
    width: min(320px, calc(100% - 96px));
    z-index: 1001;       /* above the side menu so results can overlap it */
    display: flex;
    align-items: center;
    gap: 4px;
    /* Just under the 42px side-menu button, so the row reads as one line. */
    height: 40px;
    padding: 0 4px 0 14px;
    border-radius: 999px;
}

.search-box input {
    flex: 1;
    min-width: 0;
    border: none;
    background: transparent;
    outline: none;
    font-family: var(--font-body);
    font-size: 13px;
    color: var(--color-text-main);
}

.search-box input::placeholder {
    color: var(--color-text-muted);
}

/* The browser's own clear affordance would double up with our button. */
.search-box input::-webkit-search-cancel-button {
    -webkit-appearance: none;
}

/* Sits inside the bar, left of the search button. Hidden while the field is
   empty so the bar stays quiet until there is something to clear. Sized by
   touch target, not by the icon: 15px of glyph in a 30px hit area. */
#btn-search-clear {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: var(--transition-smooth);
}

#btn-search-clear[hidden] {
    display: none;
}

#btn-search-clear svg {
    width: 15px;
    height: 15px;
}

@media (hover: hover) {
    #btn-search-clear:hover {
        color: var(--color-text-main);
        background: rgba(0, 0, 0, 0.06);
    }
}

#btn-search {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: var(--color-indigo);
    color: #ffffff;
    cursor: pointer;
    transition: var(--transition-smooth);
}

#btn-search svg {
    width: 16px;
    height: 16px;
}

@media (hover: hover) {
    #btn-search:hover {
        background: #4338ca;
    }
}

.search-box.searching #btn-search {
    opacity: 0.6;
    pointer-events: none;
}

.search-results {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    right: 0;
    max-height: min(50vh, 320px);
    overflow-y: auto;
    background: rgba(255, 255, 255, 0.97);
    backdrop-filter: blur(var(--blur-strength));
    -webkit-backdrop-filter: blur(var(--blur-strength));
    border: 1px solid var(--border-glass);
    border-radius: 14px;
    box-shadow: var(--shadow-premium);
    padding: 6px;
}

.search-result {
    display: block;
    width: 100%;
    padding: 9px 11px;
    border: none;
    background: transparent;
    border-radius: 9px;
    font-family: var(--font-body);
    font-size: 13px;
    line-height: 1.4;
    color: var(--color-text-main);
    text-align: start;
    cursor: pointer;
}

@media (hover: hover) {
    .search-result:hover {
        background: rgba(99, 102, 241, 0.10);
    }
}

.search-empty {
    padding: 12px;
    font-size: 13px;
    color: var(--color-text-muted);
    text-align: center;
}

.price-note {
    margin-top: -6px;
    font-size: 11px;
    line-height: 1.4;
    color: var(--color-text-muted);
    text-align: center;
}

/* Invite-a-friend block in the buy modal. Tinted rather than bordered so it
   reads as an offer next to the bundles, not as another form field. */
.referral-box {
    /* Symmetric: without the bottom margin the restore label sat flush
       against the box. Set here rather than on .tour-prefs-prompt-label,
       which the preferences dialog shares. */
    margin: 18px 0;
    padding: 14px;
    border-radius: 12px;
    background: linear-gradient(135deg, rgba(6, 182, 212, 0.10), rgba(79, 70, 229, 0.12));
    border: 1px solid rgba(79, 70, 229, 0.22);
}

.referral-title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 14px;
    line-height: 1.35;
    margin-bottom: 10px;
    color: var(--color-text-main);
}

.referral-box .share-link-row {
    margin-bottom: 0;
}

#referral-link {
    font-size: 12px;
    color: var(--color-text-muted);
}

.referral-note {
    margin-top: 8px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--color-text-muted);
}

/* Floating Map Overlay Controls */
.map-side-menu {
    position: absolute;
    top: 20px;
    left: 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    z-index: 999;
}

.overlay-control-btn {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid var(--border-glass);
    color: var(--color-text-main);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow-premium);
    transition: var(--transition-smooth);
    position: relative;
}

.overlay-control-btn svg {
    width: 20px;
    height: 20px;
}

@media (hover: hover) {
    .overlay-control-btn:hover {
        border-color: var(--color-indigo);
        color: var(--color-indigo);
        transform: scale(1.05);
    }
}

.control-tooltip {
    position: absolute;
    left: 50px;
    background: rgba(0, 0, 0, 0.85);
    color: #ffffff;
    font-size: 11px;
    padding: 4px 8px;
    border-radius: 4px;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: var(--transition-smooth);
    border: 1px solid var(--border-glass);
}
/* Hover tooltips only where hovering is real. On touch, :hover sticks after a
   tap, so the label stayed on screen after the button was used — and showed
   through the language picker, tinting its top edge grey. */
@media (hover: hover) and (pointer: fine) {
    .overlay-control-btn:hover .control-tooltip {
        opacity: 1;
    }
}

/* Keyboard focus still announces the label (:focus-visible never matches a
   touch or mouse click). */
.overlay-control-btn:focus-visible .control-tooltip {
    opacity: 1;
}

/* Buttons System */
.primary-btn, .secondary-btn {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 13px;
    padding: 10px 18px;
    border-radius: 8px;
    cursor: pointer;
    transition: var(--transition-smooth);
    border: 1px solid transparent;
}

.primary-btn {
    background: linear-gradient(135deg, var(--color-cyan) 0%, var(--color-indigo) 100%);
    color: #ffffff;
    box-shadow: 0 4px 15px rgba(0, 229, 255, 0.2);
}
@media (hover: hover) {
    .primary-btn:hover {
        transform: translateY(-1px);
        box-shadow: 0 6px 20px rgba(0, 229, 255, 0.35);
    }
}

.secondary-btn {
    background: rgba(15, 23, 42, 0.04);
    border-color: var(--border-glass);
    color: var(--color-text-main);
}
@media (hover: hover) {
    .secondary-btn:hover {
        background: rgba(15, 23, 42, 0.08);
        color: var(--color-text-main);
    }
}

/* ==========================================================================
   Leaflet Styling Overrides for Dark Mode
   ========================================================================== */
.leaflet-bar {
    border: 1px solid var(--border-glass) !important;
    box-shadow: var(--shadow-premium) !important;
}

.leaflet-bar a {
    background-color: rgba(255, 255, 255, 0.9) !important;
    color: #0f172a !important;
    border-bottom: 1px solid var(--border-glass) !important;
    transition: var(--transition-smooth) !important;
}

@media (hover: hover) {
    .leaflet-bar a:hover {
        color: var(--color-indigo) !important;
        background-color: #ffffff !important;
    }
}

.leaflet-bar a.leaflet-disabled {
    background-color: rgba(241, 245, 249, 0.9) !important;
    color: rgba(15, 23, 42, 0.2) !important;
}

.leaflet-popup-content-wrapper {
    background: rgba(255, 255, 255, 0.95) !important;
    backdrop-filter: blur(10px) !important;
    -webkit-backdrop-filter: blur(10px) !important;
    border: 1px solid var(--border-glass) !important;
    box-shadow: var(--shadow-premium) !important;
    color: #0f172a !important;
    border-radius: 10px !important;
    padding: 4px;
}

.leaflet-popup-tip {
    background: rgba(255, 255, 255, 0.95) !important;
    border-left: 1px solid var(--border-glass) !important;
    border-bottom: 1px solid var(--border-glass) !important;
}

.leaflet-popup-content h4 {
    font-size: 14px;
    margin-bottom: 4px;
    font-family: var(--font-heading);
}

.leaflet-popup-content p {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.4;
    margin-bottom: 6px !important;
}

.leaflet-container a.leaflet-popup-close-button {
    color: var(--color-text-muted) !important;
    padding: 6px 8px 0 0 !important;
}
@media (hover: hover) {
    .leaflet-container a.leaflet-popup-close-button:hover {
        color: #0f172a !important;
    }
}

/* Custom leaflet marker pin styling (using CSS) */
.custom-div-icon {
    background: none;
    border: none;
}

.marker-pin {
    width: 30px;
    height: 30px;
    border-radius: 50% 50% 50% 0;
    position: absolute;
    transform: rotate(-45deg);
    left: 50%;
    top: 50%;
    margin: -15px 0 0 -15px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 10px rgba(0,0,0,0.4);
}

.marker-pin::after {
    content: '';
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    position: absolute;
}

/* Currently visited stop of the active tour: bigger + orange, so it stands
   out against the other (indigo) stops. Colors are set inline by tour.js. */
.marker-pin.tour-active {
    transform: rotate(-45deg) scale(1.3);
}

.marker-pin.custom { background-color: var(--cat-custom); box-shadow: 0 0 10px rgba(255, 145, 0, 0.6); }

/* Pulsing User Location Marker */
.user-location-icon {
    background: none;
    border: none;
}
.pulsing-user-dot {
    width: 14px;
    height: 14px;
    background-color: #4285F4;
    border: 2px solid #ffffff;
    border-radius: 50%;
    position: relative;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.pulsing-user-dot::before {
    content: '';
    position: absolute;
    width: 300%;
    height: 300%;
    background-color: rgba(66, 133, 244, 0.3);
    border-radius: 50%;
    left: -100%;
    top: -100%;
    animation: user-dot-pulse 1.8s infinite ease-out;
    pointer-events: none;
}
@keyframes user-dot-pulse {
    0% {
        transform: scale(0.3);
        opacity: 1;
    }
    100% {
        transform: scale(1);
        opacity: 0;
    }
}

/* ==========================================================================
   Toast Notification System
   ========================================================================== */
.toast-container {
    position: fixed;
    /* Clears the bottom control row (slider + FAB) so a toast never covers it. */
    bottom: 124px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    gap: 8px;
    z-index: 9999;
}

.toast {
    background: rgba(13, 17, 23, 0.95);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid var(--border-glass);
    border-radius: 30px;
    padding: 10px 20px;
    color: #ffffff;
    font-size: 12px;
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 8px;
    box-shadow: var(--shadow-premium);
    animation: toast-in 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}

.toast.success { border-color: rgba(0, 230, 118, 0.3); }
.toast.error { border-color: rgba(255, 82, 82, 0.3); }

.toast-icon {
    width: 14px;
    height: 14px;
}
.toast.success .toast-icon { color: var(--color-mint); }
.toast.error .toast-icon { color: #ff5252; }

/* ==========================================================================
   Animations Keyframes
   ========================================================================== */
@keyframes toast-in {
    from { transform: translateY(20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

/* ==========================================================================
   Responsive Design Adjustments
   ========================================================================== */
@media (max-width: 768px) {
    .map-side-menu {
        top: 14px;
        left: 12px;
    }

    /* Zoom buttons are not rendered on mobile (pinch-to-zoom instead);
       hide them defensively in case an engine injects its own. */
    .leaflet-control-zoom,
    .gm-bundled-control {
        display: none;
    }

    /* 16px inputs prevent iOS Safari from auto-zooming on focus */
    #restore-code-input {
        font-size: 16px;
    }
}

/* ==========================================================================
   Sightseeing Tour Generator & Audio Guide Panel
   ========================================================================== */
.tour-panel {
    position: absolute;
    bottom: 24px;
    left: 24px;
    width: 350px;
    max-height: calc(100% - 48px);
    z-index: 999;
    border-radius: 12px;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Selection view is shown as display:flex (JS): a column whose checklist can
   shrink, so the action buttons always stay visible inside the capped panel. */
#tour-selection-view {
    flex-direction: column;
    min-height: 0;
}
#tour-selection-view .primary-btn,
#tour-selection-view .secondary-btn,
#selection-credit-hint {
    flex-shrink: 0;
}

.tour-panel h3 {
    font-size: 15px;
    font-weight: 700;
    margin-bottom: 4px;
    color: var(--color-text-main);
}

.tour-panel p {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.5;
}

/* Sights Checklist selection styles */
.sights-checklist {
    margin: 12px 0;
    max-height: 250px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* No scrollbar gutter and no visible scrollbar: any reserved track insets
       the cards relative to the buttons below and makes the panel look
       lopsided. Scrolling still works; the clipped card is the affordance. */
    scrollbar-width: none;        /* Firefox */
    -ms-overflow-style: none;     /* legacy Edge */
}

.sights-checklist::-webkit-scrollbar {
    width: 0;
    height: 0;
}

.sight-select-card {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px;
    background: rgba(15, 23, 42, 0.03);
    border: 1px solid var(--border-glass);
    border-radius: 10px;
    cursor: pointer;
    transition: var(--transition-smooth);
    user-select: none;
}
@media (hover: hover) {
    .sight-select-card:hover {
        background: rgba(15, 23, 42, 0.06);
        border-color: var(--border-glass-active);
    }
}
.sight-select-card.selected {
    background: rgba(79, 70, 229, 0.06);
    border-color: rgba(99, 102, 241, 0.4);
    box-shadow: 0 0 10px rgba(99, 102, 241, 0.05);
}
.sight-select-card input[type="checkbox"] {
    margin-top: 3px;
    accent-color: var(--color-indigo);
    cursor: pointer;
    width: 16px;
    height: 16px;
}
.sight-select-info {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1;
}
.sight-select-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-main);
    font-family: var(--font-heading);
}
.sight-select-desc {
    font-size: 11px;
    color: var(--color-text-muted);
    line-height: 1.4;
    /* Keep the cards compact: clamp long Gemini descriptions to 3 lines. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Active Tour Header */
/* No divider: the sight card below already has its own border, so a rule
   between the two only adds a second line saying the same thing. The spacing
   stays — that is what separates them. */
.tour-header {
    padding-bottom: 10px;
    margin-bottom: 4px;
}

.tour-badge {
    display: inline-block;
    font-size: 9px;
    text-transform: uppercase;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: 20px;
    background: rgba(79, 70, 229, 0.1);
    color: var(--color-indigo);
    margin-bottom: 6px;
}

#tour-title-text {
    font-size: 15px;
    font-weight: 700;
    color: var(--color-text-main);
}

/* Sight Card */
.sight-card {
    background: rgba(255, 255, 255, 0.4);
    border: 1px solid var(--border-glass);
    border-radius: 8px;
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.sight-header {
    display: flex;
    align-items: center;
    gap: 8px;
}

.sight-number {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--color-indigo);
    color: #ffffff;
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.sight-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-main);
}

.sight-desc {
    font-size: 11px;
    color: var(--color-text-muted);
    line-height: 1.4;
}

/* Audio Player */
.audio-player {
    display: flex;
    align-items: center;
    gap: 10px;
    background: rgba(79, 70, 229, 0.05);
    border: 1px solid rgba(79, 70, 229, 0.15);
    border-radius: 8px;
    padding: 8px 12px;
    margin-top: 4px;
}

.play-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--color-indigo);
    color: #ffffff;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: var(--transition-smooth);
    box-shadow: 0 2px 8px rgba(79, 70, 229, 0.3);
}

@media (hover: hover) {
    .play-btn:hover:not(:disabled) {
        transform: scale(1.05);
        box-shadow: 0 4px 12px rgba(79, 70, 229, 0.45);
    }
}

/* Fetching + synthesizing a clip takes seconds, so the button reports that
   instead of looking tappable: a second tap would be a second paid request. */
.play-btn:disabled {
    cursor: default;
    box-shadow: none;
}

.play-spinner {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #ffffff;
    animation: tts-spin 0.7s linear infinite;
}

@keyframes tts-spin {
    to { transform: rotate(360deg); }
}

/* Reduced motion stops every animation globally, which would freeze the
   spinner mid-turn and read as a hang. Show a closed ring instead — static on
   purpose, with the status text carrying the meaning. */
@media (prefers-reduced-motion: reduce) {
    .play-spinner {
        border-color: #ffffff;
    }
}

.audio-status {
    font-size: 11px;
    font-weight: 600;
    color: var(--color-indigo);
}

/* Pulse Loader Animation */
.pulse-loader {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--color-indigo);
    margin: 12px auto;
    animation: pulse-loader-anim 1.5s infinite ease-in-out;
}

@keyframes pulse-loader-anim {
    0% { transform: scale(0.6); opacity: 0.8; }
    50% { transform: scale(1.1); opacity: 0.3; }
    100% { transform: scale(0.6); opacity: 0.8; }
}

/* Tour Footer Controls */
.tour-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 4px;
}

.tour-footer button {
    padding: 6px 14px;
    font-size: 11px;
}

.sight-progress {
    font-size: 11px;
    font-weight: 600;
    color: var(--color-text-muted);
}

.exit-tour-btn {
    background: none;
    border: none;
    color: #ff5252;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    /* Block + auto side margins centers it in the (non-flex) active-tour view. */
    display: block;
    margin: 14px auto 0;
    padding-top: 4px;
    transition: var(--transition-smooth);
}

@media (hover: hover) {
    .exit-tour-btn:hover {
        text-decoration: underline;
    }
}

/* Primary CTA: prominent extended FAB, bottom-right of the map. */
/* ==========================================================================
   Search-radius control (sizes the always-visible search circle)
   ========================================================================== */
/* Slider and round Generate FAB share one bottom-right row; the flex row
   centres them against each other without hard-coded offsets. */
/* Discreet but always present — legal links must not be buried in a menu.
   Bottom-left, clear of the attribution row and of the bottom controls. */
.legal-links {
    position: absolute;
    bottom: 40px;
    left: 20px;
    z-index: 998;
    display: flex;
    gap: 6px;
    font-size: 11px;
    line-height: 1;
    color: var(--color-text-muted);
}

.legal-links a {
    color: var(--color-text-muted);
    text-decoration: none;
    padding: 4px 6px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.75);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.legal-links span {
    align-self: center;
    opacity: 0.5;
}

@media (hover: hover) {
    .legal-links a:hover {
        color: var(--color-indigo);
    }
}

.modal-legal {
    margin-top: 14px;
    text-align: center;
    font-size: 12px;
    color: var(--color-text-muted);
}

.modal-legal a {
    color: var(--color-text-muted);
}

.map-bottom-controls {
    position: absolute;
    bottom: 40px;
    right: 24px;
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 12px;
}

.radius-control {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-radius: 999px;
    box-shadow: var(--shadow-premium);
}

.radius-icon {
    width: 16px;
    height: 16px;
    color: var(--color-indigo);
    flex-shrink: 0;
}

.radius-control input[type="range"] {
    width: 96px;
    accent-color: var(--color-indigo);
    cursor: pointer;
}

.radius-value {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 12px;
    color: var(--color-text-main);
    min-width: 44px;   /* keeps the slider from shifting as the text changes */
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Round, icon-only action button — the label lives in aria-label/title. */
.fab-generate {
    flex-shrink: 0;
    width: 68px;
    height: 68px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: linear-gradient(135deg, #6366f1 0%, #a855f7 100%);
    color: #ffffff;
    cursor: pointer;
    box-shadow: 0 8px 24px rgba(168, 85, 247, 0.45);
    transition: var(--transition-smooth);
}

.fab-generate svg {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
}

@media (hover: hover) {
    .fab-generate:hover {
        transform: translateY(-2px) scale(1.03);
        box-shadow: 0 12px 30px rgba(168, 85, 247, 0.6);
    }
}

.fab-generate:disabled {
    opacity: 0.7;
    cursor: default;
    transform: none;
}

/* ==========================================================================
   Tour Preferences Dialog
   ========================================================================== */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    z-index: 1002;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.modal-overlay.open {
    opacity: 1;
    pointer-events: auto;
}

.modal {
    width: 440px;
    max-width: 100%;
    border-radius: 14px;
    transform: scale(0.94);
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.modal-overlay.open .modal {
    transform: scale(1);
}

.tour-prefs-card {
    padding: 28px;
    text-align: left;
    max-height: calc(100dvh - 40px);
    overflow-y: auto;
}

.tour-prefs-card h2 {
    font-size: 22px;
    margin-bottom: 8px;
    color: var(--color-text-main);
}

.tour-prefs-desc {
    font-size: 13px;
    color: var(--color-text-muted);
    line-height: 1.5;
    margin-bottom: 18px;
}

.pref-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 18px;
}

.pref-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 999px;
    border: 1px solid var(--border-glass);
    background: rgba(255, 255, 255, 0.6);
    color: var(--color-text-muted);
    font-family: var(--font-heading);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: var(--transition-smooth);
}

@media (hover: hover) {
    .pref-chip:hover {
        border-color: var(--border-glass-active);
        color: var(--color-text-main);
    }
}

.pref-chip.selected {
    border-color: var(--color-indigo);
    background: rgba(79, 70, 229, 0.1);
    color: var(--color-indigo);
    box-shadow: 0 0 10px rgba(79, 70, 229, 0.15);
}

.pref-chip-icon {
    font-size: 13px;
    line-height: 1;
}

.tour-prefs-prompt-label {
    display: block;
    font-family: var(--font-heading);
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-main);
    margin-bottom: 6px;
}

#tour-prefs-prompt {
    width: 100%;
    resize: vertical;
    min-height: 64px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--border-glass);
    background: rgba(255, 255, 255, 0.7);
    color: var(--color-text-main);
    font-family: var(--font-body);
    font-size: 13px;
    line-height: 1.5;
    transition: var(--transition-smooth);
}

#tour-prefs-prompt:focus {
    outline: none;
    border-color: var(--color-indigo);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.12);
}

#tour-prefs-prompt::placeholder {
    color: var(--color-text-muted);
    opacity: 0.8;
}

/* ==========================================================================
   Save & Share: save button, share-link row, public tours gallery
   ========================================================================== */
#btn-save-tour {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
}

.share-link-row {
    display: flex;
    gap: 8px;
    margin-top: 4px;
}

/* Applies to both the share-link row and the credits "restore code" row, which
   reuse this class. The input must flex+shrink and the button must not, or the
   pair overflows the modal on narrow (mobile) screens. */
.share-link-row input {
    flex: 1;
    min-width: 0;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--border-glass);
    background: rgba(255, 255, 255, 0.7);
    color: var(--color-text-main);
    font-family: var(--font-body);
    font-size: 12px;
}

.share-link-row button {
    flex-shrink: 0;
    white-space: nowrap;
}

.gallery-card {
    width: 460px;
    max-width: 100%;
    padding: 24px;
    text-align: left;
}

.gallery-card h2 {
    font-size: 20px;
    margin-bottom: 14px;
    color: var(--color-text-main);
}

.gallery-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: min(60vh, 420px);
    overflow-y: auto;
}

.gallery-item {
    display: flex;
    flex-direction: column;
    gap: 3px;
    width: 100%;
    padding: 12px 14px;
    border-radius: 10px;
    border: 1px solid var(--border-glass);
    background: rgba(255, 255, 255, 0.6);
    cursor: pointer;
    text-align: left;
    transition: var(--transition-smooth);
    font-family: var(--font-body);
}

@media (hover: hover) {
    .gallery-item:hover {
        border-color: var(--color-indigo);
        background: rgba(79, 70, 229, 0.06);
    }
}

.gallery-item-title {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 14px;
    color: var(--color-text-main);
}

.gallery-item-meta {
    font-size: 12px;
    color: var(--color-text-muted);
}

.gallery-empty {
    font-size: 13px;
    color: var(--color-text-muted);
    text-align: center;
    padding: 24px 8px;
}

/* ==========================================================================
   Language switcher (flag button + popover picker)
   ========================================================================== */
.language-flag {
    font-size: 20px;
    line-height: 1;
}

/* Top/left are set from the button's live position when the picker opens
   (see settings.js) — hard-coded coordinates would detach it whenever the
   button moves in the column, and would sit under the search bar. */
.language-menu {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1002;   /* above the search bar */
    display: flex;
    flex-direction: column;
    padding: 6px;
    border-radius: 14px;
    max-height: min(70vh, 520px);
    overflow-y: auto;
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18);
    /* Same near-opaque surface as the search dropdown. The glass default let
       the map show through unevenly, so the panel read as two-tone. */
    background: rgba(255, 255, 255, 0.97);
}

.language-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px 8px 10px;
    border: none;
    background: transparent;
    border-radius: 9px;
    cursor: pointer;
    font-family: var(--font-heading);
    font-size: 14px;
    color: var(--text-dark, #1e293b);
    text-align: start;
    white-space: nowrap;
}

@media (hover: hover) {
    .language-menu-item:hover {
        background: rgba(99, 102, 241, 0.10);
    }
}

.language-menu-item.active {
    background: rgba(99, 102, 241, 0.16);
    font-weight: 600;
}

.language-menu-flag {
    font-size: 18px;
    line-height: 1;
}

/* Disclaimer shown when the app language has no pre-translated free tours. */
.gallery-lang-note {
    font-size: 12.5px;
    color: var(--color-text-muted);
    background: rgba(99, 102, 241, 0.08);
    border-radius: 8px;
    padding: 8px 12px;
    margin: 0 0 10px;
}

/* ==========================================================================
   Tour credits: side-menu badge, buy-credits modal, recovery-code modal
   ========================================================================== */

.credits-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--color-indigo);
    color: #fff;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.buy-credits-balance {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 14px;
    color: var(--color-indigo);
    margin: 0 0 4px 0;
}

.buy-credits-code {
    font-size: 12px;
    color: var(--color-text-muted);
    margin: 0 0 8px 0;
    word-break: break-all;
}

.bundle-row {
    display: flex;
    gap: 12px;
    margin: 12px 0 16px 0;
}

.bundle-card {
    flex: 1;
    /* Flex items default to min-width:auto, so the widest child (the Buy
       button, whose label differs per language) sets a floor the card cannot
       shrink below. With three bundles that pushed the row past the modal in
       German. */
    min-width: 0;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 16px 12px 12px;
    border: 1px solid var(--border-glass);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.6);
}

.bundle-highlight {
    border-color: var(--color-indigo);
    background: rgba(79, 70, 229, 0.06);
}

.bundle-badge {
    position: absolute;
    top: -9px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--color-indigo);
    color: #fff;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 10px;
    padding: 2px 8px;
    border-radius: 8px;
    white-space: nowrap;
}

.bundle-name {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 14px;
    color: var(--color-text-main);
}

.bundle-price {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 20px;
    color: var(--color-indigo);
}

.recovery-code-box {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 18px;
    letter-spacing: 1px;
    text-align: center;
    color: var(--color-text-main);
    background: rgba(79, 70, 229, 0.08);
    border: 1px dashed var(--color-indigo);
    border-radius: 10px;
    padding: 14px 8px;
    margin: 12px 0;
    user-select: all;
    -webkit-user-select: all;
}

/* ==========================================================================
   Mobile refinements (placed last so these overrides win on source order,
   after every base component rule above).
   ========================================================================== */
@media (max-width: 768px) {
    /* Comfortable touch targets: side-menu controls and modal actions all
       clear the 44px minimum, with a little more breathing room between them. */
    .map-side-menu {
        gap: 12px;
    }
    .overlay-control-btn {
        width: 48px;
        height: 48px;
    }

    /* Beside the button column, same as on desktop — the buttons keep their
       spot at the top. (Mobile side-menu buttons are 48px wide.) */
    /* The mobile side menu sits at top:14/left:12 with 48px buttons, so these
       values put the bar centred against the first button, 12px to its right. */
    .search-box {
        top: 15px;
        left: 72px;
        right: 16px;
        width: auto;
        height: 46px;   /* just under the 48px button */
        padding: 0 5px 0 15px;
    }

    .search-box input {
        font-size: 14px;
    }

    #btn-search {
        width: 38px;
        height: 38px;
    }
    .primary-btn,
    .secondary-btn {
        min-height: 48px;
        font-size: 15px;
    }

    /* Modals become bottom sheets: full-width, docked to the bottom edge and
       sliding up. This drops the floating-desktop-card look, guarantees the
       content fits a narrow screen, and reads as a native mobile pattern. */
    .modal-overlay {
        align-items: flex-end;
        padding: 0;
    }
    .modal {
        width: 100%;
        max-width: 100%;
        border-radius: 22px 22px 0 0;
        transform: translateY(100%);
    }
    .modal-overlay.open .modal {
        transform: translateY(0);
    }
    .tour-prefs-card,
    .gallery-card {
        max-height: 88dvh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: calc(24px + env(safe-area-inset-bottom));
    }

    /* Nudge the small print up to a legible size on phones. */
    .sight-desc,
    .gallery-item-meta,
    .buy-credits-code {
        font-size: 12.5px;
    }

    /* Above the bottom control row, inside the viewport. */
    .toast-container {
        bottom: calc(100px + env(safe-area-inset-bottom));
        width: calc(100% - 32px);
        align-items: center;
    }
    .toast {
        max-width: 100%;
    }

    /* One row across the screen: the slider takes the leftover width, the
       round FAB keeps its size on the right. */
    .map-bottom-controls {
        bottom: calc(24px + env(safe-area-inset-bottom));
        left: 16px;
        right: 16px;
    }

    .radius-control {
        flex: 1;
        min-width: 0;
        padding: 8px 12px;
    }

    .radius-control input[type="range"] {
        width: auto;
        flex: 1;
        min-width: 0;
    }

    .fab-generate {
        width: 60px;
        height: 60px;
    }

    .fab-generate svg {
        width: 27px;
        height: 27px;
    }

    /* The bottom controls span the full width on mobile (slider + FAB), so
       the legal links move above them rather than underneath, where they
       would sit on the map attribution. */
    .legal-links {
        bottom: 92px;
        left: 16px;
    }

    /* Three bundles on a 360px screen leave ~93px per card. Tighten
       everything that competes for that width; the longest real label
       ("20 wycieczek" in Polish) still has to fit on one line. */
    .bundle-card {
        padding: 14px 6px 10px;
    }
    .bundle-name {
        font-size: 13px;
    }
    .bundle-price {
        font-size: 18px;
    }
    .bundle-card .primary-btn {
        width: 100%;
        padding-left: 4px;
        padding-right: 4px;
        font-size: 13px;
        min-height: 40px;
    }

    /* Full-width sheet with a safe bottom inset. This lives HERE, after the
       base .tour-panel rule: it used to sit in the earlier mobile block,
       which the later base rule silently overrode at equal specificity — so
       mobile was running the 350px desktop panel, off-centre and overflowing
       the right edge. */
    .tour-panel {
        left: 12px;
        right: 12px;
        bottom: calc(12px + env(safe-area-inset-bottom));
        width: auto;
        max-height: 68vh;
        max-height: 68dvh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Sight-SELECTION step only: never cover more than half the screen — the
       map (with the numbered markers) stays visible above the sheet. The
       checklist flexes and scrolls; buttons stay pinned and are never cut
       off. Other steps (loading / active tour) keep the default 68dvh with
       scrolling — they have no map-picking interaction to protect. */
    .tour-panel.selection-step {
        max-height: 50vh;
        max-height: 50dvh;
        overflow: hidden;
    }
    #sights-checklist-container {
        flex: 1 1 auto;
        min-height: 56px;
        max-height: none !important; /* beats the inline 250px cap */
    }
}
