*, *::before, *::after {
    box-sizing: border-box;
}

:root {
    --surface-page: #f7f4ee;
    --surface: #fffaf2;
    --surface-strong: #ffffff;
    --surface-muted: #f2eadf;
    --line: #e6ded0;
    --line-strong: #d9ccb9;
    --text: #27221d;
    --text-muted: #6f675e;
    --brand: #2e7558;
    --brand-dark: #1f4035;
    --brand-soft: #dcefe6;
    --accent: #f26f5b;
    --accent-dark: #df5d4c;
    --info: #3b82a0;
    --shadow-soft: 0 16px 40px rgba(64, 52, 38, 0.14);
    --shadow-small: 0 4px 16px rgba(64, 52, 38, 0.10);
}

html, body {
    margin: 0;
    overflow-x: hidden;
}

img, svg, video {
    max-width: 100%;
    height: auto;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.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."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ---- App shell (Home page) ----
   The map page is a fixed-viewport app shell, not a scrolling document: header and (on large screens)
   footer take their natural height and the map fills whatever's left, so the page never scrolls and the
   footer never gets clipped. See MainLayout.razor for the container that applies this. */

.app-shell {
    /* dvh accounts for the mobile browser address bar; vh is a fallback for browsers without it -
       invalid declarations are dropped entirely, so the vh rule stays in effect where dvh is unsupported. */
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

/* ---- Points map (Home page) ---- */

.home-map {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.map-shell {
    position: relative;
    width: 100%;
    height: 100%;
    min-height: 12rem;
    overscroll-behavior: contain;
    background: #e6efe5;
    z-index: 0;
}

.map-shell .leaflet-container {
    width: 100%;
    height: 100%;
    font-family: inherit;
    background: #e6efe5;
}

.point-marker__wrap {
    position: relative;
    width: 28px;
    height: 40px;
}

.point-marker__pin {
    position: relative;
    display: block;
    filter: drop-shadow(0 1px 4px rgba(64, 52, 38, 0.38));
}

/* Ground-ring pulse shared with the search marker below (see marker-pulse-ring) - present in the markup
   for every point marker but only animated for the selected one (rule below), so an unselected marker
   sits still. */
.point-marker__pulse {
    position: absolute;
    left: 50%;
    bottom: -2px;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    border-radius: 999px;
    opacity: 0;
}

.point-marker--selected .point-marker__pulse {
    opacity: 0.6;
    animation: marker-pulse-ring 1.8s ease-out infinite;
}

/* Animated/transformed on the pin SVG itself, not on .point-marker (the outer div) - Leaflet positions
   markers via an inline `transform: translate3d(...)` on that outer div, and a CSS animation targeting
   the same property there would override the marker's position instead of just scaling it in place. */
.point-marker--selected .point-marker__pin {
    transform-origin: 50% 100%;
    animation: point-marker-pulse 1.6s ease-in-out infinite;
}

@keyframes point-marker-pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.12);
    }
}

@keyframes marker-pulse-ring {
    0% {
        transform: scale(1);
        opacity: 0.8;
    }
    100% {
        transform: scale(3.4);
        opacity: 0;
    }
}

/* Address search highlight - see js/map.js setSearchMarker/buildSearchHighlightIcon. Two staggered
   rings rippling out from the searched spot, no pin/dot shape and no severity color so it never reads
   as a rated point - just "look here". The whole thing fades itself out at the end of its fixed
   lifetime (SEARCH_HIGHLIGHT_DURATION_MS in map.js, matched here) and gets removed from the map, rather
   than sitting there permanently and cluttering it after a visitor has already looked. */
.search-highlight {
    position: relative;
    width: 64px;
    height: 64px;
    animation: search-highlight-fade 3.2s ease-in forwards;
}

.search-highlight__ring {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 16px;
    height: 16px;
    margin: -8px 0 0 -8px;
    border-radius: 999px;
    border: 2px solid var(--info);
    animation: search-highlight-ring 1.6s ease-out infinite;
}

.search-highlight__ring--delay {
    animation-delay: 0.8s;
}

.search-highlight__dot {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 8px;
    height: 8px;
    margin: -4px 0 0 -4px;
    border-radius: 999px;
    background: var(--info);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.9);
}

@keyframes search-highlight-ring {
    0% {
        transform: scale(0.4);
        opacity: 0.9;
    }
    100% {
        transform: scale(3.2);
        opacity: 0;
    }
}

@keyframes search-highlight-fade {
    0%, 65% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

.cluster-marker__bubble {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 2px solid #fff;
    border-radius: 999px;
    color: #fff;
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
    box-shadow: 0 2px 10px rgba(64, 52, 38, 0.34);
}

.map-status {
    position: absolute;
    top: 0.75rem;
    left: 50%;
    z-index: 10;
    max-width: min(28rem, calc(100% - 1.5rem));
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    border: 1px solid rgba(230, 222, 208, 0.8);
    background: rgba(255, 250, 242, 0.94);
    box-shadow: var(--shadow-small);
    color: var(--text);
    font-size: 0.78rem;
    backdrop-filter: blur(4px);
}

.map-status--error {
    color: #9f2f24;
}

.map-status button {
    flex: 0 0 auto;
    border-radius: 999px;
    background: var(--brand);
    padding: 0.25rem 0.65rem;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
}

/* Shares the bottom row with the "submit request" button (see Home.razor) - a flex row rather than
   two independently-positioned absolutes so the legend shrinks/wraps instead of running underneath
   the button on narrow screens. */
.map-bottom-bar {
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    bottom: 0.75rem;
    z-index: 10;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.5rem;
}

.map-legend {
    display: flex;
    flex: 0 1 auto;
    min-width: 0;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    padding: 0.5rem 0.75rem;
    border-radius: 0.75rem;
    border: 1px solid rgba(230, 222, 208, 0.8);
    background: rgba(255, 250, 242, 0.92);
    box-shadow: var(--shadow-small);
    font-size: 0.75rem;
    color: var(--text-muted);
    backdrop-filter: blur(4px);
}

.map-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.map-legend__dot {
    display: inline-block;
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 999px;
}

/* ---- Point details panel: bottom sheet on mobile/tablet, side panel from xl (1280px) up ----
   Deliberately has no backdrop - the map stays fully interactive (pan/zoom/click other markers)
   while the panel is open instead of being dimmed and blocked behind a modal overlay.

   The xl breakpoint below intentionally matches Header's own breakpoint for showing its persistent
   "submit request" button (see Header.razor's "xl:flex"/"xl:hidden" split) and Home.razor's floating
   map-bottom-bar button, which is hidden via the same "xl:hidden". Below 1280px the sheet fully covers
   those floating controls at the bottom of the map instead of sitting beside them as a side panel would
   - so there is never a viewport width where the panel and the floating submit button/legend are both
   visible and overlapping.

   The mobile sheet opens to a "peek" height by default - tall enough to read the essentials but short
   enough to leave a strip of map (and any other nearby markers) visible/tappable underneath. Tapping the
   handle expands it to read the full description/gallery/translate panel. Both the open/close and the
   peek/expand transitions are animated (slide + height), never an abrupt pop. */

.point-panel {
    position: fixed;
    z-index: 46;
    left: 0;
    right: 0;
    bottom: 0;
    height: min(50vh, 34rem);
    height: min(50dvh, 34rem);
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-radius: 1.5rem 1.5rem 0 0;
    box-shadow: 0 -14px 42px rgba(64, 52, 38, 0.18);
    overflow: hidden;
    animation: point-panel-enter-mobile 280ms cubic-bezier(0.32, 0.72, 0, 1);
    transition: height 280ms cubic-bezier(0.32, 0.72, 0, 1);
}

.point-panel--expanded {
    height: min(88vh, 54rem);
    height: min(88dvh, 54rem);
}

/* Kept mounted (see PointDetailsPanel's HandleClosedAsync) for exactly as long as this animation runs,
   so the sheet slides away instead of vanishing the instant the parent nulls out PointId. */
.point-panel--closing {
    animation: point-panel-exit-mobile 220ms cubic-bezier(0.32, 0.72, 0, 1) forwards;
    pointer-events: none;
}

@keyframes point-panel-enter-mobile {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

@keyframes point-panel-exit-mobile {
    from { transform: translateY(0); }
    to { transform: translateY(100%); }
}

.point-panel__handle-btn {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    width: 100%;
    padding: 0.55rem 0 0.4rem;
    border: 0;
    background: none;
    cursor: pointer;
}

.point-panel__handle-btn:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
    border-radius: 999px;
}

.point-panel__handle {
    width: 2.5rem;
    height: 0.3rem;
    border-radius: 999px;
    background: var(--line-strong);
    transition: background-color .15s ease;
}

.point-panel__handle-btn:hover .point-panel__handle,
.point-panel__handle-btn:focus-visible .point-panel__handle {
    background: var(--text-muted);
}

.point-panel__close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 999px;
    background: var(--surface-muted);
    color: var(--text);
}

.point-panel__content {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0.5rem 1.25rem 1.75rem;
}

.point-panel__loading {
    color: var(--text-muted);
}

.point-gallery {
    display: flex;
    gap: 0.5rem;
    margin: -1.25rem -1.25rem 1rem;
    padding: 0 1.25rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
}

.point-gallery__item-btn {
    flex: 0 0 82%;
    max-width: 320px;
    aspect-ratio: 4 / 3;
    display: block;
    padding: 0;
    border: 0;
    background: none;
    cursor: zoom-in;
    scroll-snap-align: start;
}

.point-gallery__item {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 0.8rem;
}

/* From the xl side-panel breakpoint (see the .point-panel media query below) the fixed 26rem-wide panel
   has no room to feel like a horizontal-scroll carousel - a snap-scrolling strip that width just shows
   one cramped photo at a time. A small two-column grid uses the panel's width instead of fighting it;
   the first photo (usually the most representative one) gets a bigger, single-photo-wide cell when
   there's more than one photo. */
@media (min-width: 1280px) {
    .point-gallery {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 0.5rem;
        margin: 0 0 1.1rem;
        padding: 0;
        overflow: visible;
        scroll-snap-type: none;
    }

    .point-gallery__item-btn {
        flex: unset;
        width: 100%;
        max-width: none;
        aspect-ratio: 4 / 3;
        scroll-snap-align: none;
    }

    .point-gallery__item-btn:only-child {
        grid-column: 1 / -1;
        aspect-ratio: 16 / 9;
    }
}

.point-panel__address {
    margin: 0.6rem 0 0.35rem;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--text);
}

.point-panel__published-at {
    display: block;
    margin: 0 0 0.6rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.point-panel__description {
    color: var(--text-muted);
    line-height: 1.6;
    white-space: pre-wrap;
}

.severity-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.65rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
}

.severity-badge--low { background: #dcefe6; color: #27634b; }
.severity-badge--medium { background: #fff0c2; color: #8a5b08; }
.severity-badge--high { background: #ffe0c8; color: #a44b16; }
.severity-badge--critical { background: #ffe1dc; color: #a7382d; }

.status-badge {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    padding: 0.3rem 0.75rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.status-badge--created { background: #dcebf3; color: #236174; }
.status-badge--approved { background: #dcefe6; color: #27634b; }
.status-badge--rejected { background: #ffe1dc; color: #a7382d; }
.status-badge--new { background: #dcebf3; color: #236174; }
.status-badge--reviewed { background: #dcefe6; color: #27634b; }
.status-badge--visible { background: #dcefe6; color: #27634b; }
.status-badge--hidden { background: #f1e8dc; color: #7a6a52; }

.feedback-category-badge {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    padding: 0.3rem 0.75rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.feedback-category-badge--bug { background: #ffe1dc; color: #a7382d; }
.feedback-category-badge--suggestion { background: #dcebf3; color: #236174; }
.feedback-category-badge--other { background: #f2eadf; color: #6f675e; }

.like-button, .copy-link-button {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.95rem;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface-strong);
    color: var(--text);
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.2;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.like-button--active {
    background: #ffe1dc;
    border-color: #f6b5aa;
    color: #a7382d;
}

.like-button:disabled {
    opacity: 0.6;
}

.copy-link-button--copied {
    background: #dcefe6;
    border-color: #bce0cd;
    color: #27634b;
}

.translate-panel {
    margin-top: 0.75rem;
}

.translate-panel__controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.translate-panel__select {
    min-height: 2.5rem;
    padding: 0.4rem 0.6rem;
    border-radius: 0.6rem;
    border: 1px solid var(--line);
    background: var(--surface-strong);
    color: var(--text);
    font-size: 0.85rem;
}

.translate-button {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface-strong);
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.2;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.translate-button:disabled {
    opacity: 0.6;
}

.translate-panel__result {
    margin-top: 0.6rem;
    padding: 0.75rem 0.9rem;
    border-radius: 0.8rem;
    background: var(--surface-strong);
    border: 1px solid var(--line);
    color: var(--text);
    line-height: 1.6;
    white-space: pre-wrap;
}

.translate-panel__error {
    margin-top: 0.5rem;
    font-size: 0.85rem;
    color: #a7382d;
}

.point-address-siblings {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--line);
}

.point-address-siblings__label {
    margin: 0 0 0.4rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.point-address-siblings__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.point-address-siblings__item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.4rem;
    border-radius: 0.65rem;
    transition: background-color .12s ease;
}

.point-address-siblings__item:hover,
.point-address-siblings__item:focus-visible {
    background: var(--brand-soft);
}

.point-address-siblings__item-date {
    font-size: 0.85rem;
    color: var(--text-muted);
}

@media (min-width: 1280px) {
    .point-panel {
        top: 5rem;
        bottom: 1rem;
        left: auto;
        right: 1rem;
        width: 26rem;
        height: auto;
        max-height: none;
        border-radius: 1.25rem;
        animation: point-panel-enter-desktop 240ms cubic-bezier(0.32, 0.72, 0, 1);
        transition: none;
    }

    .point-panel--expanded {
        height: auto;
    }

    .point-panel--closing {
        animation: point-panel-exit-desktop 200ms cubic-bezier(0.32, 0.72, 0, 1) forwards;
    }

    .point-panel__handle-btn {
        display: none;
    }
}

@keyframes point-panel-enter-desktop {
    from { transform: translateX(1.5rem); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

@keyframes point-panel-exit-desktop {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(1.5rem); opacity: 0; }
}

/* ---- Header nav links (desktop bar + mobile drawer) ----
   NavLink applies "active" automatically when the current URL matches the link's href. */

.nav-link.active {
    color: var(--brand-dark);
    font-weight: 600;
}

.nav-link-mobile.active {
    border-color: var(--brand-dark);
    color: var(--brand-dark);
    background: var(--brand-soft);
    font-weight: 600;
}

/* ---- Mobile nav drawer (Header) ----
   Slides in from the left rather than dropping down from the top, which used to push page content
   down and contribute to page-level scroll. Stays in the DOM at all times (visibility/transform toggled
   via the --open modifier) so the slide transition can play instead of the panel just popping in. */

.nav-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 55;
    background: rgba(39, 34, 29, 0.4);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}

.nav-drawer-backdrop--open {
    opacity: 1;
    pointer-events: auto;
}

.nav-drawer {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 56;
    display: flex;
    flex-direction: column;
    width: min(20rem, 85vw);
    background: var(--surface);
    box-shadow: 16px 0 40px rgba(64, 52, 38, 0.2);
    transform: translateX(-100%);
    transition: transform .25s ease;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.nav-drawer--open {
    transform: translateX(0);
}

/* ---- Address search (Header) ---- */

/* The search box has its own clear button (aria-label="Очистить поиск"); without this, WebKit/Blink
   also draw their native type=search cancel icon right next to it, showing two "x" glyphs at once. */
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
    appearance: none;
}

.pointsearch__backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: transparent;
}

.pointsearch__panel {
    position: absolute;
    z-index: 41;
    top: calc(100% + 0.5rem);
    left: 0;
    width: 100%;
    max-width: 26rem;
    max-height: 22rem;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--surface);
    border-radius: 1rem;
    box-shadow: var(--shadow-soft);
    border: 1px solid var(--line);
}

.pointsearch__status {
    margin: 0;
    padding: 1.5rem 1.25rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.9rem;
}

.pointsearch__error {
    padding: 0.25rem;
}

.pointsearch__status--error {
    color: #b91c1c;
}

.pointsearch__section-label {
    margin: 0;
    padding: 0.6rem 0.75rem 0.2rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.pointsearch__list {
    list-style: none;
    margin: 0;
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.pointsearch__item {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    width: 100%;
    padding: 0.6rem 0.65rem;
    border-radius: 0.65rem;
    text-align: left;
    background: transparent;
    transition: background-color .12s ease;
}

.pointsearch__item:hover,
.pointsearch__item:focus-visible {
    background: var(--brand-soft);
}

.pointsearch__item-dot {
    flex-shrink: 0;
    display: block;
    width: 0.6rem;
    height: 0.6rem;
    margin-top: 0.35rem;
    border-radius: 999px;
}

.pointsearch__item-pin {
    flex-shrink: 0;
    width: 1.1rem;
    height: 1.1rem;
    margin-top: 0.1rem;
    color: var(--text-muted);
}

.pointsearch__item-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.pointsearch__item-address {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--text);
}

.pointsearch__item-preview {
    font-size: 0.8rem;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

/* ---- Address search: mobile fullscreen overlay ---- */

.pointsearch__mobile-overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    background: var(--surface);
}

.pointsearch__mobile-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--line);
}

.pointsearch__mobile-results {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 1rem;
}

/* ---- Profile menu (Header, desktop/Compact ProfileBadge) ---- */

.profile-menu__backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
    background: transparent;
}

.profile-menu__panel {
    position: absolute;
    z-index: 41;
    top: calc(100% + 0.5rem);
    right: 0;
    min-width: 12rem;
    padding: 0.4rem;
    background: var(--surface);
    border-radius: 0.9rem;
    box-shadow: var(--shadow-soft);
    border: 1px solid var(--line);
}

.profile-menu__name {
    margin: 0;
    padding: 0.5rem 0.65rem 0.35rem;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text);
}

.profile-menu__logout {
    display: flex;
    align-items: center;
    min-height: 2.5rem;
    padding: 0 0.65rem;
    border-radius: 0.65rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-muted);
    transition: background-color .12s ease, color .12s ease;
}

.profile-menu__logout:hover,
.profile-menu__logout:focus-visible {
    background: var(--brand-soft);
    color: var(--brand-dark);
}

/* ---- Location picker (Submit request form) ---- */

.location-picker-map-shell {
    position: relative;
}

/* Positioning context for the map plus its overlaid toggle/address badge - kept as a separate element
   from .location-picker-map-shell so the expanded state (below) can turn the shell into a full-viewport
   centering backdrop without disturbing this element's own box, which the toggle/badge are positioned
   relative to in both states. */
.location-picker-map-panel {
    position: relative;
}

.location-picker-map {
    position: relative;
    width: 100%;
    height: 16rem;
    border-radius: 1rem;
    overflow: hidden;
    background: #e6efe5;
    z-index: 0;
}

.location-picker-map .leaflet-container {
    width: 100%;
    height: 100%;
    font-family: inherit;
    background: #e6efe5;
}

@media (min-width: 1024px) {
    .location-picker-map {
        height: 20rem;
    }
}

/* Expanded picker view - a large centered panel over a dimmed backdrop, not a true fullscreen takeover
   (a visitor picking a point should still see they're in an overlay above the page, not on a different
   screen). See LocationPickerMap.razor's ToggleExpandAsync/map.js's beginMapResize+endMapResize for the
   JS side that keeps Leaflet's view centered through the jump. Scoped through the shell's modifier class
   rather than one directly on .location-picker-map itself - that element's `class` attribute belongs to
   Leaflet after init (see the comment in the .razor file), so Blazor must never be the one flipping a
   class on it. */
.location-picker-map-shell--expanded {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.25rem;
    background: rgba(24, 20, 16, .55);
}

.location-picker-map-shell--expanded .location-picker-map-panel {
    width: 100%;
    max-width: 1100px;
    height: min(80vh, calc(100dvh - 2.5rem));
}

.location-picker-map-shell--expanded .location-picker-map {
    height: 100%;
    box-shadow: var(--shadow-soft);
}

.location-picker-map__toggle {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    z-index: 1;
    display: inline-flex;
    height: 2.25rem;
    width: 2.25rem;
    align-items: center;
    justify-content: center;
    border-radius: 0.6rem;
    border: 1px solid var(--line);
    background: rgba(255, 255, 255, .92);
    color: var(--text-muted);
    box-shadow: 0 1px 3px rgba(24, 20, 16, .18);
    transition: background-color .12s ease, color .12s ease;
}

.location-picker-map__toggle:hover,
.location-picker-map__toggle:focus-visible {
    background: #fff;
    color: var(--brand-dark);
}

/* Only ever rendered while expanded (see LocationPickerMap.razor) - positioned relative to
   .location-picker-map-panel like the toggle button, so it always overlays the map panel itself
   (whatever size that currently is) instead of drifting relative to the viewport. */
.location-picker-map__address {
    position: absolute;
    left: 0.6rem;
    bottom: 0.6rem;
    right: 0.6rem;
    z-index: 1;
    /* Purely informational, unlike the toggle button - it must never intercept clicks meant for the map
       underneath. It's a DOM sibling of the Leaflet container, not a descendant, so without this a click
       landing in this strip (nearly the full width of the map) would bubble straight past Leaflet's own
       click handler (bound to the container itself) instead of reaching it - the point picker would look
       like it stopped responding, with the address stuck on whatever it last resolved to. */
    pointer-events: none;
    border-radius: 0.75rem;
    border: 1px solid var(--line);
    background: rgba(255, 250, 242, .95);
    color: var(--text);
    box-shadow: var(--shadow-small);
    padding: 0.55rem 0.85rem;
    font-size: 0.85rem;
    line-height: 1.35;
}

/* ---- My requests (list + details) ---- */

.request-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 1rem;
    border: 1px solid var(--line);
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(64, 52, 38, 0.05);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.request-card:hover {
    border-color: #bce0cd;
    box-shadow: var(--shadow-small);
}

.request-card__thumb {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 9;
    background: var(--surface-muted);
}

.request-card__badge {
    position: absolute;
    left: 0.75rem;
    top: 0.75rem;
}

.request-card__body {
    padding: 0.9rem 1rem 1.1rem;
}

.comment-timeline {
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
}

.comment-timeline__item {
    position: relative;
    padding: 0 0 1.5rem 1.75rem;
}

.comment-timeline__item:last-child {
    padding-bottom: 0;
}

.comment-timeline__item::before {
    content: "";
    position: absolute;
    left: 0.3125rem;
    top: 1.3rem;
    bottom: -0.15rem;
    width: 2px;
    background: var(--line);
}

.comment-timeline__item:last-child::before {
    display: none;
}

.comment-timeline__dot {
    position: absolute;
    left: 0;
    top: 0.35rem;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 999px;
    background: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.comment-timeline__date {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    color: #9a8f82;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.comment-timeline__text {
    margin: 0.25rem 0 0;
    color: var(--text);
    line-height: 1.6;
    white-space: pre-wrap;
}

/* ---- Moderation section: denser "working tool" layout, table on tablet/desktop, cards on phones ---- */

.mod-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 1.25rem;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid var(--line);
}

.mod-tab {
    min-height: 2.5rem;
    padding: 0 1rem;
    border-radius: 0.6rem 0.6rem 0 0;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-muted);
    background: transparent;
    transition: background-color .12s ease, color .12s ease;
}

.mod-tab:hover {
    color: var(--brand-dark);
    background: var(--brand-soft);
}

.mod-tab--active {
    color: var(--brand);
    background: var(--brand-soft);
}

.mod-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
    text-align: left;
}

.mod-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 0.6rem 0.6rem;
    background: #f2eadf;
    border-bottom: 1px solid var(--line);
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

.mod-table tbody td {
    padding: 0.6rem 0.6rem;
    border-bottom: 1px solid #f1e8dc;
    vertical-align: middle;
    color: var(--text);
}

.mod-table tbody tr:hover {
    background: #fbf6ed;
}

.mod-table tbody tr:last-child td {
    border-bottom: none;
}

.mod-table__actions-col {
    white-space: nowrap;
    text-align: right;
}

.mod-table__submuted {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.7rem;
    color: #9a8f82;
    white-space: nowrap;
}

.mod-table .severity-badge,
.mod-table .status-badge {
    padding: 0.15rem 0.5rem;
    font-size: 0.68rem;
}

.mod-table .mod-action-btn {
    min-height: 2rem;
    padding: 0 0.6rem;
    font-size: 0.76rem;
}

.mod-table .mod-actions {
    margin-right: 0;
    gap: 0.35rem;
}

.mod-table__address-col {
    max-width: 15rem;
}

.mod-table__address-link {
    display: block;
    max-width: 15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--text);
}

.mod-table__address-link:hover {
    color: var(--brand);
    text-decoration: underline;
}

@media (max-width: 900px) {
    .mod-table__address-col,
    .mod-table__address-link {
        max-width: 9rem;
    }

    .mod-table .own-request-badge {
        white-space: normal;
        max-width: 9rem;
    }
}

.own-request-badge {
    display: inline-flex;
    align-self: flex-start;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    background: #fff0c2;
    color: #8a5b08;
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
}

.mod-actions {
    display: inline-flex;
    gap: 0.4rem;
    margin-right: 0.6rem;
}

.mod-action-btn {
    display: inline-flex;
    min-height: 2.25rem;
    align-items: center;
    padding: 0 0.85rem;
    border-radius: 0.5rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: #fff;
    transition: background-color .12s ease, opacity .12s ease;
}

.mod-action-btn--approve {
    background: var(--brand);
}

.mod-action-btn--approve:hover:not(:disabled) {
    background: var(--brand-dark);
}

.mod-action-btn--reject {
    background: var(--accent);
}

.mod-action-btn--reject:hover:not(:disabled) {
    background: var(--accent-dark);
}

.mod-action-btn:disabled {
    cursor: not-allowed;
    background: var(--line-strong);
    color: var(--text-muted);
    opacity: 0.8;
}

.mod-action-btn--lg {
    min-height: 3rem;
    padding: 0 1.5rem;
    font-size: 0.9rem;
}

.mod-view-link {
    display: inline-flex;
    min-height: 2.25rem;
    align-items: center;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--brand);
}

.mod-view-link:hover {
    color: var(--brand-dark);
    text-decoration: underline;
}

.mod-own-request-notice {
    color: #8a5b08;
    font-size: 0.9rem;
}

.mod-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1.5rem;
}

.mod-pagination__btn {
    display: inline-flex;
    min-height: 2.5rem;
    align-items: center;
    padding: 0 1rem;
    border-radius: 0.6rem;
    border: 1px solid var(--line);
    background: var(--surface);
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text);
    transition: border-color .12s ease, background-color .12s ease;
}

.mod-pagination__btn:hover:not(:disabled) {
    border-color: #bce0cd;
    background: var(--brand-soft);
}

.mod-pagination__btn:disabled {
    cursor: not-allowed;
    opacity: 0.45;
}

.mod-pagination__label {
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* ---- Moderation cards (narrow screens: same data as the table, stacked) ---- */

.mod-card {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem;
    border-radius: 1rem;
    border: 1px solid var(--line);
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(64, 52, 38, 0.05);
}

.mod-card__header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.mod-card__address {
    margin: 0;
    font-weight: 700;
    color: var(--text);
}

a.mod-card__address:hover {
    color: var(--brand);
    text-decoration: underline;
}

.mod-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.mod-card__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--line);
}

/* ---- Confirm dialog (approve / reject / delete photo) ---- */

.confirm-overlay {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 0;
    background: rgba(39, 34, 29, 0.46);
}

.confirm-dialog {
    width: 100%;
    max-width: 28rem;
    max-height: 90vh;
    max-height: 90dvh;
    overflow-y: auto;
    padding: 1.5rem;
    background: var(--surface);
    border-radius: 1.25rem 1.25rem 0 0;
    box-shadow: 0 -14px 42px rgba(64, 52, 38, 0.22);
}

.confirm-dialog__title {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--text);
}

.confirm-dialog__message {
    margin: 0.6rem 0 0;
    color: var(--text-muted);
    line-height: 1.55;
}

.confirm-dialog__body {
    margin-top: 1rem;
}

.confirm-dialog__error {
    margin: 0.75rem 0 0;
    padding: 0.6rem 0.85rem;
    border-radius: 0.6rem;
    background: #fff0ed;
    border: 1px solid #f6b5aa;
    color: #a7382d;
    font-size: 0.85rem;
}

.confirm-dialog__actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    margin-top: 1.5rem;
}

.confirm-dialog__cancel {
    display: inline-flex;
    min-height: 2.75rem;
    align-items: center;
    padding: 0 1.1rem;
    border-radius: 0.6rem;
    border: 1px solid var(--line-strong);
    background: var(--surface-strong);
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text);
}

.confirm-dialog__cancel:hover:not(:disabled) {
    background: #fbf6ed;
}

.confirm-dialog__confirm {
    display: inline-flex;
    min-height: 2.75rem;
    align-items: center;
    padding: 0 1.4rem;
    border-radius: 0.6rem;
    background: var(--brand);
    color: #fff;
    font-size: 0.875rem;
    font-weight: 700;
}

.confirm-dialog__confirm:hover:not(:disabled) {
    background: var(--brand-dark);
}

.confirm-dialog__confirm--danger {
    background: var(--accent);
}

.confirm-dialog__confirm--danger:hover:not(:disabled) {
    background: var(--accent-dark);
}

.confirm-dialog__cancel:disabled,
.confirm-dialog__confirm:disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

@media (min-width: 640px) {
    .confirm-overlay {
        align-items: center;
        padding: 1rem;
    }

    .confirm-dialog {
        border-radius: 1.25rem;
    }
}

/* ---- Photo lightbox (map point cards, request details/review) ---- */

/* Gated on [open] so the dialog stays subject to the UA's default `dialog:not([open]) { display: none }`
   until openDialog() calls showModal() - author styles otherwise win the cascade over UA styles
   regardless of specificity, which would force it visible (outside the top layer) for a frame first. */
.lightbox-overlay[open] {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 1rem;
    border: 0;
    background: rgba(20, 17, 13, 0.92);
    color: #fff;
    touch-action: none;
}

.lightbox-overlay::backdrop {
    background: transparent;
}

/* Leaves room at the bottom for .lightbox-footer (counter + thumbnail strip) so a tall/portrait photo
   never renders underneath it. */
.lightbox-overlay--with-strip {
    padding-bottom: 6.5rem;
}

@media (min-width: 640px) {
    .lightbox-overlay--with-strip {
        padding-bottom: 7.5rem;
    }
}

.lightbox-overlay:focus {
    outline: none;
}

.lightbox-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.lightbox-image {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 0.5rem;
}

.lightbox-close,
.lightbox-nav {
    position: absolute;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 999px;
    border: 0;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
}

.lightbox-close:hover,
.lightbox-nav:hover {
    background: rgba(255, 255, 255, 0.26);
}

.lightbox-close {
    top: max(0.75rem, env(safe-area-inset-top));
    right: max(0.75rem, env(safe-area-inset-right));
    font-size: 1.05rem;
}

.lightbox-nav {
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.6rem;
    line-height: 1;
}

.lightbox-nav--prev {
    left: max(0.5rem, env(safe-area-inset-left));
}

.lightbox-nav--next {
    right: max(0.5rem, env(safe-area-inset-right));
}

/* Groups the counter and the jump-to-photo thumbnail strip into one bottom-anchored block, faded in on
   a gradient so both stay legible over a bright photo without needing their own individual pill
   backgrounds to compete with the thumbnails. */
.lightbox-footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1.5rem max(0.75rem, env(safe-area-inset-right)) max(0.85rem, env(safe-area-inset-bottom)) max(0.75rem, env(safe-area-inset-left));
    background: linear-gradient(to top, rgba(20, 17, 13, 0.85), rgba(20, 17, 13, 0));
    pointer-events: none;
}

.lightbox-footer > * {
    pointer-events: auto;
}

.lightbox-counter {
    padding: 0.3rem 0.85rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 600;
}

.lightbox-thumbs {
    display: flex;
    gap: 0.4rem;
    max-width: 100%;
    padding: 0.2rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
}

.lightbox-thumb {
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 0.5rem;
    overflow: hidden;
    background: none;
    opacity: 0.55;
    cursor: pointer;
    scroll-snap-align: center;
    transition: opacity .15s ease, border-color .15s ease;
}

.lightbox-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.lightbox-thumb:hover {
    opacity: 0.85;
}

.lightbox-thumb--active {
    opacity: 1;
    border-color: #fff;
}

@media (min-width: 640px) {
    .lightbox-nav {
        width: 3rem;
        height: 3rem;
    }

    .lightbox-nav--prev {
        left: 1.5rem;
    }

    .lightbox-nav--next {
        right: 1.5rem;
    }

    .lightbox-thumb {
        width: 3.5rem;
        height: 3.5rem;
    }
}

/* ---- Moderation section switcher (Заявки / Обратная связь) ---- */

.mod-section-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
}

.mod-section-tab {
    display: inline-flex;
    min-height: 2.25rem;
    align-items: center;
    padding: 0 1rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--surface-muted);
    transition: background-color .12s ease, color .12s ease;
}

.mod-section-tab:hover {
    background: var(--line);
}

.mod-section-tab--active,
.mod-section-tab--active:hover {
    color: #fff;
    background: var(--brand);
}

/* ---- Feedback form honeypot ----
   Hidden via CSS only (not display:none/JS) so simple bots that only skip JS-hidden or
   display:none/type=hidden fields still fill this one in, tripping the server-side check. */

.hp-field {
    position: absolute;
    left: -5000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ---- First-visit onboarding ---- */

.onboarding-open { scroll-behavior: auto; }
.onboarding-overlay {
    position: fixed;
    inset: 0;
    z-index: 80;
    background: rgba(24, 20, 16, .68);
    backdrop-filter: blur(2px);
}
.onboarding-target {
    position: relative !important;
    z-index: 81 !important;
    border-radius: 1rem;
    background: var(--surface);
    box-shadow: 0 0 0 5px #fff, 0 0 0 9px var(--accent), 0 12px 40px rgba(0,0,0,.28);
}
.onboarding-card {
    position: fixed;
    z-index: 82;
    width: min(380px, calc(100vw - 24px));
    max-height: calc(100dvh - 24px);
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 1.25rem;
    background: var(--surface-strong);
    padding: 1.35rem;
    box-shadow: 0 24px 70px rgba(20,17,13,.3);
}
.onboarding-card--welcome {
    top: 50%;
    left: 50%;
    width: min(520px, calc(100vw - 24px));
    transform: translate(-50%, -50%);
}
.onboarding-card__top, .onboarding-card__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}
.onboarding-card__eyebrow {
    color: var(--brand);
    font-size: .75rem;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.onboarding-card__close {
    width: 2rem;
    height: 2rem;
    border-radius: 999px;
    color: var(--text-muted);
}
.onboarding-card__close:hover { background: var(--surface-muted); }
.onboarding-card__icon { margin-top: .75rem; font-size: 2.25rem; }
.onboarding-card h2 { margin: .7rem 0 0; font-size: 1.35rem; font-weight: 800; color: var(--text); }
.onboarding-card p { margin: .55rem 0 0; line-height: 1.6; color: var(--text-muted); }
.onboarding-progress { display: flex; gap: .35rem; margin: 1.25rem 0; }
.onboarding-progress span { height: .3rem; flex: 1; border-radius: 999px; background: var(--line); }
.onboarding-progress span.is-active { background: var(--brand); }
.onboarding-card__actions > div { display: flex; gap: .5rem; }
.onboarding-skip, .onboarding-back, .onboarding-next {
    min-height: 2.65rem;
    padding: 0 .9rem;
    border-radius: .65rem;
    font-size: .85rem;
    font-weight: 700;
}
.onboarding-skip { padding-left: 0; color: var(--text-muted); text-decoration: underline; }
.onboarding-back { border: 1px solid var(--line-strong); color: var(--text-muted); }
.onboarding-next { background: var(--brand); color: white; }
.onboarding-next:hover { background: var(--brand-dark); }

@media (max-width: 639px) {
    .onboarding-card--spotlight {
        top: auto !important;
        bottom: max(12px, env(safe-area-inset-bottom));
        left: 12px !important;
    }
}

/* ---- Warm visual tone over Tailwind CDN utilities ---- */

.bg-white { background-color: var(--surface) !important; }
.bg-slate-50 { background-color: var(--surface-page) !important; }
.bg-slate-100 { background-color: var(--surface-muted) !important; }
.bg-slate-200 { background-color: var(--line) !important; }

.border-slate-100 { border-color: #eee7dc !important; }
.border-slate-200 { border-color: var(--line) !important; }
.border-slate-300 { border-color: var(--line-strong) !important; }

.text-slate-300 { color: #b8afa3 !important; }
.text-slate-400 { color: #9a8f82 !important; }
.text-slate-500 { color: var(--text-muted) !important; }
.text-slate-600 { color: #5d554d !important; }
.text-slate-700 { color: #3f3932 !important; }
.text-slate-800 { color: var(--text) !important; }
.text-slate-900 { color: #1f1a16 !important; }

.placeholder\:text-slate-400::placeholder {
    color: #9a8f82 !important;
}

.hover\:bg-slate-50:hover { background-color: #fbf6ed !important; }
.hover\:bg-slate-100:hover { background-color: var(--brand-soft) !important; }
.hover\:bg-slate-200:hover { background-color: var(--line) !important; }
