/* ===========================
   Ownovo CSS Utilities
   Centralized reusable styles for the application.

   Design system v2 - editorial green brand (see Other/WebsiteDesign).

   IMPORTANT: Brand colors here MUST stay in sync with ThemeService.cs.
   When updating brand colors, update BOTH files.
   Dark-mode overrides below are driven by `data-theme="dark"` on <html>.
   =========================== */

/* ===========================
   Ownovo Design Tokens - brand primitives
   =========================== */
:root {
    /* --- Brand greens --- */
    --ovo-green-900: #1E3F36;
    --ovo-green-700: #2F5D50;   /* Primary */
    --ovo-green-500: #4A8574;
    --ovo-green-100: #E4ECE8;
    --ovo-green-50:  #F2F6F4;

    /* --- Neutrals --- */
    --ovo-ink:       #1A1A1A;
    --ovo-ink-soft:  #3A3A38;
    --ovo-muted:     #6B7163;
    --ovo-line:      #D8D5CC;
    --ovo-surface:   #FAFAF7;   /* Paper */
    --ovo-white:     #FFFFFF;

    /* --- Semantic --- */
    --ovo-accent:     var(--ovo-green-700);
    --ovo-accent-ink: var(--ovo-green-900);
    --ovo-bg:         var(--ovo-surface);
    --ovo-bg-elev:    var(--ovo-white);
    --ovo-text:       var(--ovo-ink);
    --ovo-text-muted: var(--ovo-muted);
    --ovo-border:     var(--ovo-line);

    /* --- Type --- */
    --ovo-font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
    --ovo-font-body:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --ovo-font-mono:    'JetBrains Mono', ui-monospace, Menlo, monospace;

    /* --- Radius --- */
    --ovo-radius-sm: 4px;
    --ovo-radius:    8px;
    --ovo-radius-lg: 16px;

    /* --- Spacing scale (4px base) --- */
    --ovo-space-1: 4px;
    --ovo-space-2: 8px;
    --ovo-space-3: 12px;
    --ovo-space-4: 16px;
    --ovo-space-5: 24px;
    --ovo-space-6: 32px;
    --ovo-space-8: 48px;
    --ovo-space-10: 64px;

    /* --- Elevation --- */
    --ovo-shadow-sm: 0 1px 2px rgba(30, 63, 54, 0.06);
    --ovo-shadow:    0 4px 12px rgba(30, 63, 54, 0.08);
    --ovo-shadow-lg: 0 12px 32px rgba(30, 63, 54, 0.12);
}

/* ===========================
   App-scoped aliases (stable names used across the codebase)
   These map legacy --color-* names to the Ownovo tokens so existing
   classes don't need mass rename. Mirrors ThemeService.CurrentTheme.
   =========================== */
:root {
    /* Brand */
    --color-primary:       var(--ovo-green-700);
    --color-primary-hover: var(--ovo-green-900);
    --color-secondary:     var(--ovo-ink-soft);
    --color-tertiary:      var(--ovo-green-500);

    /* Semantic - kept in muted editorial register */
    --color-info:    #4A6B7A;
    --color-success: #4C8C6A;
    --color-warning: #D48A2A;
    --color-error:   #B04444;
    --color-error-hover:         #8A3535;
    --color-error-bg-subtle:     #FEF3F3;
    --color-error-border-subtle: #F2C5C5;

    /* Tier / listing badges */
    --color-badge-featured:      #D4AF37;         /* gold */
    --color-badge-featured-text: #1A1A1A;
    --color-badge-premium:       var(--ovo-green-700);
    --color-badge-basic:         #6B7280;         /* neutral grey */

    /* Surfaces */
    --color-background:        var(--ovo-surface);
    --color-background-light:  var(--ovo-green-50);
    --color-background-medium: var(--ovo-green-100);
    --color-surface:           var(--ovo-white);
    --color-surface-muted:     var(--ovo-green-50);
    --color-white:             var(--ovo-white);
    --color-black:             var(--ovo-ink);

    /* Text */
    --color-text-primary:   var(--ovo-ink);
    --color-text-secondary: var(--ovo-muted);
    --color-text-disabled:  #BDBDBD;
    --color-text-muted:     var(--ovo-muted);

    /* Icons - editorial palette on green brand */
    --color-icon-default: #5A6B61;   /* Slate Ink - informational */
    --color-icon-muted:   #8A938B;   /* Soft Slate - secondary/disabled */
    --color-icon-primary: var(--ovo-green-700);
    --color-icon-success: #4C8C6A;
    --color-icon-warning: #D48A2A;
    --color-icon-alert:   #B04444;

    /* Action */
    --color-action-default:  var(--ovo-muted);
    --color-action-disabled: #BDBDBD;

    /* Borders */
    --color-divider:        var(--ovo-line);
    --color-border-light:   var(--ovo-line);
    --color-border-medium:  #C9C6BC;
    --color-border-subtle:  rgba(26, 26, 26, 0.08);

    /* Dark accent (for footers, etc.) */
    --color-dark: var(--ovo-green-900);

    /* Shadows */
    --shadow-sm:          var(--ovo-shadow-sm);
    --shadow-md:          var(--ovo-shadow);
    --shadow-lg:          var(--ovo-shadow-lg);
    --shadow-card-hover:  var(--ovo-shadow);
    --shadow-button:      0 2px 8px rgba(30, 63, 54, 0.16);
    --shadow-button-hover:0 6px 16px rgba(30, 63, 54, 0.22);

    /* Spacing */
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 2rem;

    /* Border Radius */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 16px;
    --radius-xl: 999px;

    /* Transitions */
    --transition-fast:   0.2s ease;
    --transition-medium: 0.3s ease;

    /* Z-Index Layers */
    --z-sticky:  50;
    --z-header:  100;
    --z-overlay: 200;
    --z-modal:   1000;
}

/* ===========================
   Dark theme - activated via <html data-theme="dark">
   Mirrors MudBlazor PaletteDark in ThemeService.cs.
   =========================== */
[data-theme="dark"] {
    /* Ownovo primitives shift */
    --ovo-accent:     #6FAE9B;
    --ovo-bg:         #14201B;
    --ovo-bg-elev:    #1C2A24;
    --ovo-text:       #F2F0E9;
    --ovo-text-muted: #A8ADA0;
    --ovo-border:     #2E3C36;

    /* Alias remap */
    --color-primary:       #6FAE9B;
    --color-primary-hover: #8BC4B3;
    --color-secondary:     #A8ADA0;
    --color-tertiary:      var(--ovo-green-500);

    --color-info:    #7DA3B0;
    --color-success: #7AB898;
    --color-warning: #E0A358;
    --color-error:   #D47070;
    --color-error-hover:         #A85555;
    --color-error-bg-subtle:     #3A1F1F;
    --color-error-border-subtle: #5A3030;

    --color-badge-featured:      #D4AF37;
    --color-badge-featured-text: #1A1A1A;
    --color-badge-premium:       #6FAE9B;
    --color-badge-basic:         #8A938B;

    --color-background:        #14201B;
    --color-background-light:  #1C2A24;
    --color-background-medium: #243229;
    --color-surface:           #1C2A24;
    --color-surface-muted:     #243229;
    --color-white:             #1C2A24;   /* component "white" surfaces */
    --color-black:             #F2F0E9;

    --color-text-primary:   #F2F0E9;
    --color-text-secondary: #A8ADA0;
    --color-text-disabled:  #5D6660;
    --color-text-muted:     #A8ADA0;

    --color-icon-default: #A8ADA0;
    --color-icon-muted:   #6F7871;
    --color-icon-primary: #6FAE9B;
    --color-icon-success: #7AB898;
    --color-icon-warning: #E0A358;
    --color-icon-alert:   #D47070;

    --color-divider:       #2E3C36;
    --color-border-light:  #2E3C36;
    --color-border-medium: #3A4942;
    --color-border-subtle: rgba(242, 240, 233, 0.08);

    --color-dark: #0E1915;

    --shadow-sm:         0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-md:         0 4px 14px rgba(0, 0, 0, 0.45);
    --shadow-lg:         0 12px 36px rgba(0, 0, 0, 0.55);
    --shadow-card-hover: 0 6px 20px rgba(0, 0, 0, 0.50);
    --shadow-button:     0 2px 10px rgba(0, 0, 0, 0.45);
    --shadow-button-hover: 0 6px 18px rgba(0, 0, 0, 0.55);
}

/* ===========================
   Global body typography
   =========================== */
html,
body {
    background-color: var(--ovo-bg);
    color: var(--ovo-text);
}

body {
    font-family: var(--ovo-font-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, .ovo-display {
    font-family: var(--ovo-font-display);
    font-weight: 500;
    letter-spacing: -0.02em;
}

.ovo-eyebrow {
    font-family: var(--ovo-font-body);
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    font-size: 12px;
    color: var(--ovo-accent);
}

/* ===========================
   Reusable Card Styles
   =========================== */

/* Property Card Hover Effect - Used across PropertyResultCard and other cards */
.property-card-hover {
    transition: all var(--transition-fast);
    cursor: pointer;
}

.property-card-hover:hover {
    box-shadow: var(--shadow-card-hover) !important;
    transform: translateY(-2px);
}

.property-card-hover:hover .property-image {
    transform: scale(1.05);
}

/* SRCH-021: list card highlighted when its map pin is clicked (mirror of the
   card-hover -> pin-highlight bridge). Added/removed in property-map-manager.js. */
.property-result-card.is-pin-selected {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
    box-shadow: var(--shadow-card-hover) !important;
}

.property-image {
    transition: transform var(--transition-medium);
}

/* Card Border Styling */
.card-border-light {
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
}

/* Info Item Cards - Used in PropertyDetailModal and other detail views */
.info-item-card {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    padding: 1rem;
    background-color: var(--color-background-light);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    transition: all var(--transition-fast);
}

.info-item-card:hover {
    background-color: var(--color-background-medium);
    border-color: var(--color-border-medium);
    box-shadow: var(--shadow-sm);
}

/* ===========================
   Custom Scrollbar Styling
   =========================== */

/* Default Scrollbar - Applied to scrollable containers */
.custom-scrollbar::-webkit-scrollbar,
.property-search-results::-webkit-scrollbar,
.property-search-results-content::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.custom-scrollbar::-webkit-scrollbar-track,
.property-search-results::-webkit-scrollbar-track,
.property-search-results-content::-webkit-scrollbar-track {
    background: var(--color-surface-muted);
}

.custom-scrollbar::-webkit-scrollbar-thumb,
.property-search-results::-webkit-scrollbar-thumb,
.property-search-results-content::-webkit-scrollbar-thumb {
    background: var(--color-border-medium);
    border-radius: 4px;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover,
.property-search-results::-webkit-scrollbar-thumb:hover,
.property-search-results-content::-webkit-scrollbar-thumb:hover {
    background: var(--color-icon-muted);
}

/* ===========================
   MudBlazor Component Overrides
   =========================== */

/* ============================================================================
   DIALOG SIZING — TWO global shapes. Defined ONCE here; dialogs just pick one.
   MudBlazor puts the `Class` from <MudDialog Class="…"> onto the .mud-dialog
   surface, so both classes are compound selectors on .mud-dialog. !important
   beats MudBlazor's own .mud-dialog rules.

     .ovo-dialog-full     → full screen height. The big type: forms, editors,
                            lists, detail views, the property quick-view, gallery.
                            Title + actions pinned; only the body scrolls.
     .ovo-dialog-confirm  → compact, content-sized confirmation / "are you sure?"
                            box. (DialogService.ShowMessageBox already renders this
                            shape by default, so message-box confirmations need no
                            class — the class is here for custom confirm dialogs.)

   Do NOT re-declare dialog height in any component's scoped .razor.css — apply
   one of these two classes instead.
   ============================================================================ */

/* FULL HEIGHT — the exact rules that worked before, now gated behind the class
   (previously these hit `.mud-dialog` globally, which wrongly sized confirmations
   too). Restored verbatim from git HEAD. */
.mud-dialog.ovo-dialog-full {
    height: 100dvh !important;
    max-height: 100dvh !important;
    border-radius: 0px !important;
}

.mud-dialog.ovo-dialog-full .mud-dialog-content {
    max-width: 1169px !important;
    width: 100% !important;
    margin: 0px auto !important;
    max-height: 94vh !important;
    height: auto !important;
    display: flex;
    flex-direction: column;
}

.mud-dialog-container.mud-dialog-center:has(.mud-dialog.ovo-dialog-full) {
    align-items: normal !important;
}

/* CONFIRMATION — compact, content-sized "are you sure?" box. */
.mud-dialog.ovo-dialog-confirm {
    height: auto !important;
    max-height: 90vh !important;
}

/* MOBILE — every FULL-HEIGHT popup goes truly full-screen on phones. Feedback #172 + #175:
   the .ovo-dialog-full shape is already 100dvh tall at all widths, but on a narrow phone it
   still opened as a CENTRED, margined dialog (MaxWidth cap + side gutters + rounded corners),
   so a full-height popup was NOT full-width — content squeezed into a strip with wasted side
   margins (the search quick-view read as "cramped"; #175 asked for the general rule: a
   full-height popup must be full-width on mobile). Below 768px we drop the side margins, the
   width cap and the rounded corners so ANY .ovo-dialog-full (quick-view, gallery lightbox,
   off-grid profile, forms, editors, admin dialogs) fills the viewport edge-to-edge. This
   deliberately does NOT touch .ovo-dialog-confirm — compact "are you sure?" boxes stay small,
   exactly matching the reporter's "if it is the full height popup" condition. Mobile only;
   desktop/tablet-landscape keep the centred dialog. Placed after the .ovo-dialog-full block so
   source order wins on the shared .mud-dialog-content selector. */
@media (max-width: 768px) {
    .mud-dialog-container.mud-dialog-center:has(.mud-dialog.ovo-dialog-full) {
        padding: 0 !important;
    }

    .mud-dialog.ovo-dialog-full {
        width: 100% !important;
        max-width: 100% !important;
        height: 100dvh !important;
        max-height: 100dvh !important;
        margin: 0 !important;
        border-radius: 0 !important;
    }

    .mud-dialog.ovo-dialog-full .mud-dialog-content {
        max-width: 100% !important;
        max-height: 100dvh !important;
        margin: 0 !important;
    }
}

/* MudPaper - Global Footer Styling (overridden by .footer-dark below) */
.mud-main-content .mud-paper.mt-auto {
    box-shadow: none !important;
}

/* ===========================
   Footer Utilities
   =========================== */

/* Footer within search results or scrollable containers */
.footer-inline {
    margin-top: 40px;
    margin-bottom: 0;
    background: transparent;
    position: relative;
    contain: layout style paint;
}

.footer-inline .mud-paper {
    box-shadow: none !important;
    position: relative !important;
    overflow: hidden !important;
}

.footer-inline .mud-paper *[style*="position: fixed"],
.footer-inline .mud-paper *[style*="position: absolute"] {
    position: relative !important;
}

/* Hide MainLayout footer on property search page */
body:has(.property-search-container) .mud-main-content > .mud-paper.mt-auto {
    display: none !important;
}

/* ===========================
   Loading & State Utilities
   =========================== */

/* Modal Loading State */
.modal-loading,
.modal-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 400px;
    padding: 2rem;
    text-align: center;
}

.modal-error {
    color: var(--color-error);
}

/* Empty State */
.empty-state {
    text-align: center;
    padding: 60px 20px;
    background-color: var(--color-surface-muted);
    border: 1px dashed var(--color-border-subtle);
    border-radius: var(--radius-md);
}

.empty-state-icon {
    font-size: 64px;
    color: var(--color-icon-muted);
    margin-bottom: 16px;
}

.empty-state-title {
    font-size: 24px;
    font-weight: 600;
    color: var(--color-text-primary);
    margin-bottom: 8px;
}

.empty-state-text {
    font-size: 16px;
    color: var(--color-text-secondary);
}

/* ===========================
   Button Utilities
   =========================== */

/* Primary CTA Button */
.cta-button-primary {
    font-weight: 600 !important;
    text-transform: none !important;
    letter-spacing: 0.01em !important;
    border-radius: var(--radius-md) !important;
    padding: 0.75rem 1.5rem !important;
    font-size: 1rem !important;
    box-shadow: var(--shadow-button) !important;
}

.cta-button-primary:hover {
    box-shadow: var(--shadow-button-hover) !important;
    transform: translateY(-1px);
}

/* Secondary CTA Button */
.cta-button-secondary {
    font-weight: 600 !important;
    text-transform: none !important;
    letter-spacing: 0.01em !important;
    border-radius: var(--radius-md) !important;
    padding: 0.75rem 1.5rem !important;
    font-size: 1rem !important;
    transition: all var(--transition-fast) !important;
}

.cta-button-secondary:hover {
    background-color: var(--color-background-light) !important;
}

/* Rounded Button (e.g., Save Search) */
.button-rounded {
    border-radius: 20px;
    text-transform: none;
    font-weight: 500;
}

/* ===========================
   Image & Media Utilities
   =========================== */

/* Image with fallback placeholder */
.image-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    gap: 0.5rem;
    color: var(--color-icon-muted);
    background-color: var(--color-surface-muted);
}

/* Thumbnail placeholder */
.thumbnail-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    background-color: var(--color-surface-muted);
    border: 1px dashed var(--color-border-medium);
}

/* Image overlay effects */
.image-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.6);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: white;
    gap: 0.25rem;
}

/* ===========================
   Layout Utilities
   =========================== */

/* Sticky Header */
.sticky-header {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    background-color: var(--color-surface);
    border-bottom: 1px solid var(--color-border-light);
    box-shadow: var(--shadow-md);
}

/* Flex utilities */
.flex-center {
    display: flex;
    align-items: center;
    justify-content: center;
}

.flex-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.flex-column {
    display: flex;
    flex-direction: column;
}

/* ===========================
   Typography Utilities
   =========================== */

/* Text truncation */
.text-truncate-1 {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.text-truncate-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.text-truncate-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ===========================
   Badge & Chip Utilities
   =========================== */

/* Filter badge */
.filter-badge {
    background: var(--color-primary);
    color: white;
    border-radius: var(--radius-xl);
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 600;
}

/* Feature chip styling */
.feature-chip-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
}

/* ===========================
   Responsive Utilities
   =========================== */

/* Hide on mobile */
@media (max-width: 768px) {
    .hide-mobile {
        display: none !important;
    }
}

/* Hide on desktop */
@media (min-width: 769px) {
    .hide-desktop {
        display: none !important;
    }
}

/* ===========================
   Management Dashboard Styles
   =========================== */

/* Summary Cards */
.summary-card {
    border: 1px solid rgba(0, 0, 0, 0.08);
}

/* Icon Color Classes - See STYLES.md for usage guidelines */
.icon-muted {
    color: var(--color-icon-muted) !important;
}

.icon-slate,
.icon-default {
    color: var(--color-icon-default) !important;
}

.icon-primary {
    color: var(--color-icon-primary) !important;
}

.icon-success {
    color: var(--color-icon-success) !important;
}

.icon-warning {
    color: var(--color-icon-warning) !important;
}

.icon-alert {
    color: var(--color-icon-alert) !important;
}

.text-muted {
    color: var(--color-text-secondary) !important;
}

/* Alert Bar */
.alert-bar {
    background-color: var(--color-surface-muted);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
}

.alert-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.875rem;
    color: var(--color-text-secondary);
}

.alert-item--critical {
    color: var(--color-error);
}

/* Loadshedding banner - rendered inside MudMainContent (below fixed AppBar) when
   ShowNationalBanner is on. Two visual states: stable (green, stage 0) vs active (amber, stage 1+).
   !important on background-color overrides MudPaper's default surface colour. */
.mud-paper.loadshedding-banner {
    border-radius: 0 !important;
    width: 100%;
    min-height: 44px;
}

.mud-paper.loadshedding-banner--active {
    background-color: rgba(212, 138, 42, 0.18) !important;
    border-bottom: 1px solid rgba(212, 138, 42, 0.40) !important;
    color: #6E4416;
}

.mud-paper.loadshedding-banner--stable {
    background-color: rgba(47, 93, 80, 0.12) !important;
    border-bottom: 1px solid rgba(47, 93, 80, 0.28) !important;
    color: #2F5D50;
}

[data-theme="dark"] .mud-paper.loadshedding-banner--active {
    background-color: rgba(224, 163, 88, 0.20) !important;
    border-bottom: 1px solid rgba(224, 163, 88, 0.40) !important;
    color: #F2D9B6;
}

[data-theme="dark"] .mud-paper.loadshedding-banner--stable {
    background-color: rgba(106, 156, 137, 0.18) !important;
    border-bottom: 1px solid rgba(106, 156, 137, 0.34) !important;
    color: #C8E0D5;
}

/* Property results grid (home featured + search results)
   Responsive auto-fill grid: as many 300px-min columns as fit, single column below 1024px. */
.property-results-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
    margin-bottom: 20px;
}

@media (max-width: 1024px) {
    .property-results-grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }
}

@media (max-width: 768px) {
    .property-results-grid {
        gap: 16px;
    }
}

/* PropertyResultCard image-overlay action buttons - glassy, consistent, and
   sized so the Share/Favorite/More trio never collides with the left-side badges. */
.property-card-action-btn,
.property-card-action-menu > .mud-menu-activator .mud-icon-button,
.property-card-action-menu .mud-icon-button {
    width: 32px !important;
    height: 32px !important;
    min-width: 32px !important;
    padding: 0 !important;
    background: rgba(255, 255, 255, 0.92) !important;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.18);
    border-radius: 50%;
    transition: background-color 0.15s ease, transform 0.15s ease;
}

.property-card-action-btn:hover,
.property-card-action-menu .mud-icon-button:hover {
    background: #ffffff !important;
    transform: translateY(-1px);
}

.property-card-action-btn .mud-icon-root,
.property-card-action-menu .mud-icon-button .mud-icon-root {
    width: 18px;
    height: 18px;
    font-size: 18px;
}

/* The /search overflow menu (Hide / Add-to-compare) IS shown on search cards.
   The action row (Share + Favorite + More) right-aligns; the badges on the left
   reserve space on the right (see .property-card-badges max-width) so the two
   never collide on a narrow card. */

/* PropertyResultCard - single-row specs (bedrooms / bathrooms / area).
   nowrap per item, bullet separators, uniform icon color - professional and skimmable. */
.property-card-specs {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
    color: var(--color-text-secondary);
    font-size: 13px;
    flex-wrap: nowrap;
    overflow: hidden;
    line-height: 1.2;
}

.property-card-specs .property-card-spec {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    flex-shrink: 0;
}

.property-card-specs .property-card-spec + .property-card-spec::before {
    content: "";
    display: inline-block;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--color-border-subtle, #d0d4d2);
    margin-right: 10px;
    margin-left: -10px;
}

.property-card-specs .property-card-spec-icon {
    width: 16px !important;
    height: 16px !important;
    font-size: 16px !important;
}

.property-card-specs .property-card-spec strong {
    font-weight: 600;
    color: var(--color-text-primary);
}

.property-card-specs .property-card-spec-label {
    color: var(--color-text-secondary);
    font-weight: 400;
}

/* PropertyResultCard - SA feature badges (fibre / pool / solar).
   Icon-only by default to save horizontal space; the whole row expands to show
   labels when the user clicks any chip. Tooltips surface the label on hover. */
.property-card-features {
    display: flex;
    gap: 6px;
    margin-top: 8px;
    flex-wrap: wrap;
    cursor: pointer;
}

.property-card-feature {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    height: 28px;
    min-width: 28px;
    padding: 0 4px;
    border-radius: 14px;
    background: var(--color-surface-muted, #f3f5f4);
    border: 1px solid var(--color-border-subtle, #e3e6e4);
    font-size: 11px;
    color: var(--color-text-secondary);
    transition: padding 0.15s ease, background-color 0.15s ease;
}

.property-card-feature .property-card-feature-label {
    display: none;
    font-weight: 500;
    white-space: nowrap;
}

.property-card-feature.is-expanded {
    padding: 0 10px 0 6px;
}

.property-card-feature.is-expanded .property-card-feature-label {
    display: inline;
}

.property-card-feature:hover {
    background: var(--color-surface, #fff);
    border-color: var(--color-border-light, #c9d2ce);
}

.property-card-feature .mud-icon-root {
    width: 16px;
    height: 16px;
    font-size: 16px;
}

/* Property Management Cards */
.property-card {
    transition: box-shadow 0.2s;
    border: 1px solid var(--color-border-subtle);
}

.property-card:hover {
    box-shadow: var(--shadow-card-hover) !important;
}

/* Deleted listings stay visible to the owner (so they see the address is
   theirs) but are visually muted to read as read-only. */
.property-card--deleted {
    opacity: 0.65;
    background: var(--color-surface-muted);
}

.property-card--deleted:hover {
    opacity: 0.85;
}

/* Stats Row */
.stats-row {
    color: var(--color-text-secondary);
    font-size: 0.8125rem;
}

.stat-item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.stat-item--clickable {
    cursor: pointer;
    border-radius: 4px;
    padding: 2px 4px;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.stat-item--clickable:hover,
.stat-item--clickable:focus-visible {
    background-color: var(--ovo-green-50, rgba(47, 93, 80, 0.08));
    color: var(--ovo-green-700, #2F5D50);
    outline: none;
}

.stat-item--clickable:hover .stat-icon,
.stat-item--clickable:focus-visible .stat-icon {
    color: var(--ovo-green-700, #2F5D50) !important;
    opacity: 1;
}

.stat-icon {
    color: var(--color-icon-muted) !important;
    opacity: 0.8;
}

/* Inquiry modal - clickwrap consent line under the message field. Anchors must
   inherit size or MudBlazor's body styles blow them up larger than the caption. */
.inquiry-consent-note {
    margin: 1rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--color-divider);
    text-align: center;
    font-size: 0.6875rem;
    line-height: 1.4;
    color: var(--color-text-secondary);
}

.inquiry-consent-note a {
    font-size: inherit;
    font-weight: 500;
    color: var(--color-primary);
    text-decoration: none;
}

.inquiry-consent-note a:hover {
    text-decoration: underline;
}

/* Inquiry - unread highlight on the dashboard list */
.inquiry-card--unread {
    border-left: 3px solid var(--ovo-green-700, #2F5D50) !important;
    background-color: var(--ovo-green-50, rgba(47, 93, 80, 0.04));
}

/* Inquiry - sender meta line (timestamp + email + phone) */
.inquiry-meta {
    color: var(--color-text-secondary);
    font-size: 0.8125rem;
    gap: 0.75rem;
    margin-top: 4px;
}

.inquiry-meta__item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.inquiry-contact-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--color-text-secondary);
    text-decoration: none;
    border-bottom: 1px dashed transparent;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.inquiry-contact-link:hover,
.inquiry-contact-link:focus-visible {
    color: var(--ovo-green-700, #2F5D50);
    border-bottom-color: currentColor;
    outline: none;
}

/* Inquiry - status pipeline (clickable chip group) */
.inquiry-status-pipeline {
    padding: 8px 12px;
    border-radius: 6px;
    background-color: var(--color-surface-muted);
    border: 1px solid var(--color-border-subtle);
}

.inquiry-status-pipeline__label {
    color: var(--color-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.7rem;
    margin-right: 4px;
}

/* Warning Badges */
.warning-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background-color: var(--color-surface-muted);
    color: var(--color-text-secondary);
}

.warning-badge--alert {
    background-color: rgba(176, 68, 68, 0.12);
    color: var(--color-error);
}

/* Toolbar */
.toolbar-paper {
    background-color: var(--color-surface-muted);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
}

/* Price Display */
.price-text {
    color: var(--color-text-primary);
    font-weight: 600;
}

/* Property Table */
.property-table {
    border: 1px solid var(--color-border-subtle);
}

/* Text Utilities */
.text-truncate {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.font-weight-medium {
    font-weight: 500;
}

/* ===========================
   Card Hover Effects
   =========================== */

/* Generic hover card effect - used on Dashboard, etc. */
.hover-card {
    transition: transform 0.2s, box-shadow 0.2s;
}

.hover-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}

/* ===========================
   Social Login Buttons
   =========================== */

.social-button {
    text-transform: none;
    font-weight: 500;
    border-color: var(--color-border-light);
}

.social-button:hover {
    border-color: var(--color-primary);
    background-color: var(--color-surface-muted);
}

/* ===========================
   Google Search Box
   =========================== */

.google-search-white-bg .mud-input,
.google-search-white-bg .mud-input-slot,
.google-search-white-bg .mud-input-root,
.google-search-white-bg.mud-input-outlined,
.google-search-white-bg.mud-input-filled {
    background-color: #fff !important;
    border-radius: var(--radius-sm) !important;
}

.google-search-white-bg .mud-input-outlined .mud-input-slot,
.google-search-white-bg.mud-input-control {
    border-radius: var(--radius-sm) !important;
}

.google-search-white-bg .mud-input-outlined {
    border: 1px solid var(--color-border-light) !important;
}

.google-search-white-bg:hover .mud-input-outlined {
    border-color: var(--color-primary) !important;
}

/* ===========================
   Home search dropdown - Ownovo-first, Google below
   =========================== */

.search-suggestion {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    padding: 4px 0;
}

.search-suggestion__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.search-suggestion .ownovo-pill {
    flex: 0 0 auto;
    align-self: center;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #fff;
    background: var(--ovo-green-700);
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
}

/* Divider between the last Ownovo row and the first Google row. */
.search-suggestion.is-ownovo + .search-suggestion.is-google {
    border-top: 1px solid var(--color-border-light);
    padding-top: 10px;
    margin-top: 6px;
}

/* ===========================
   Photo Upload Component
   =========================== */

.drop-zone-active {
    background-color: var(--mud-palette-primary-lighten) !important;
}

.photo-preview-card {
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* Uniform 4:3 cropped tiles. The seller's grid is a management surface, so every
   tile must be the SAME shape however the photos were shot - a mixed grid of
   contained photos reads as broken. The whole photo is shown where it matters
   (the property page hero and the full-screen viewer). See "Listing photo framing". */
.photo-preview-thumb {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    background-color: var(--color-surface-muted, #f4f6f8);
    overflow: hidden;
}

.photo-preview-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.photo-preview-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.7;
    color: #fff;
    background: rgba(0, 0, 0, 0.62);
}

.photo-preview-badge-portrait {
    left: auto;
    right: 8px;
    font-weight: 500;
    background: rgba(0, 0, 0, 0.45);
}

.photo-preview-meta {
    flex: 1 1 auto;
}

/* ===========================
   Listing photo framing (portal standard)

   Photos are stored at their original aspect ratio - never distorted, never
   rotated, never hard-cropped on ingest. Presentation decides the shape:
     - small cards / thumbnails crop to fill (object-fit: cover), which is what
       Rightmove, Zillow and Property24 do and what buyers expect of a grid;
     - any LARGE viewing surface shows the whole photo inside its landscape
       frame, letterboxed over a blurred copy of itself, so a portrait shot
       reads properly instead of having its middle band sliced out.
   The lightbox already contains the full image (ImageLightboxDialog.razor.css).
   =========================== */

.ovo-photo-frame-backdrop {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Scaled up so the blur's soft edge never shows inside the frame. */
    transform: scale(1.15);
    filter: blur(24px) brightness(0.9);
    pointer-events: none;
    user-select: none;
}

/* ===========================
   Listing Wizard - Package cards
   =========================== */

.package-card {
    border: 2px solid transparent;
    transition: border-color 0.15s ease, transform 0.15s ease;
}

.package-card:hover {
    transform: translateY(-2px);
}

.package-card-selected {
    border-color: var(--ovo-green-700, #2F5D50);
}

.photo-manager-card {
    height: 100%;
}

/* ===========================
   Email Verification Banner
   =========================== */

.email-verification-banner {
    position: sticky;
    top: 0;
    z-index: 1300;
    margin: 0;
    border-radius: 0;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* ===========================
   Passkey Setup Prompt Banner
   =========================== */

/* Deliberately NOT sticky: it is an optional nudge, not a warning, and it must not
   compete for the sticky slot with the email-verification banner. That is exactly why
   the component is rendered INSIDE MudMainContent - anything non-sticky placed outside
   it renders behind the fixed AppBar and is invisible (same trap the loadshedding
   banner hit). Do not move it back out without also pinning it like
   .email-verification-banner. */
.passkey-prompt-banner {
    margin: 0;
    border-radius: 0;
}

/* ===========================
   Loading Overlay
   =========================== */

.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    transition: opacity 0.2s ease;
}

/* ===========================
   Dashboard Styles
   =========================== */

/* Avatar neutral styling */
.avatar-neutral {
    background-color: var(--color-surface-muted) !important;
    color: var(--color-text-secondary) !important;
}

/* Role chip styling */
.role-chip {
    border-color: var(--color-border-light) !important;
    color: var(--color-text-secondary) !important;
}

/* Notification items */
.notification-item {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    background-color: var(--color-surface-muted);
    border-radius: var(--radius-sm);
    color: var(--color-text-secondary);
}

.notification-item .mud-icon-root {
    color: var(--color-icon-muted);
}

/* Height utility */
.h-100 {
    height: 100%;
}

/* ===========================
   Footer (Dark Theme Section)
   =========================== */

.footer-dark {
    background-color: var(--ovo-green-900) !important;
    color: rgba(250, 250, 247, 0.82) !important;
    border-top: 1px solid rgba(250, 250, 247, 0.06) !important;
}

.footer-dark .mud-typography {
    color: rgba(250, 250, 247, 0.74) !important;
}

.footer-dark .mud-typography.footer-heading {
    color: #F2F0E9 !important;
    font-family: var(--ovo-font-display);
    font-weight: 500;
    letter-spacing: -0.01em;
}

.footer-dark .mud-link {
    color: rgba(250, 250, 247, 0.74) !important;
    transition: color var(--transition-fast);
}

.footer-dark .mud-link:hover {
    color: #E4ECE8 !important;
}

.footer-dark .footer-copyright {
    color: rgba(250, 250, 247, 0.52) !important;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
}

.footer-dark .mud-icon-button {
    color: rgba(250, 250, 247, 0.74) !important;
}

.footer-dark .mud-icon-button:hover {
    color: #E4ECE8 !important;
    background-color: rgba(250, 250, 247, 0.06) !important;
}

.footer-dark .mud-icon.icon-slate {
    color: rgba(250, 250, 247, 0.65) !important;
}

.footer-dark .mud-divider {
    background-color: rgba(250, 250, 247, 0.10) !important;
}

/* ---------------------------
   Footer — Newsletter form
   Plain HTML form (deliberately not a MudBlazor island — see
   NewsletterSubscription.razor). The legacy template classes
   (.newsletters / .bloq-email / .email) carry no CSS of their own, so
   they are styled here to match the dark footer + green v2 system.
   --------------------------- */
.footer-dark .newsletters {
    text-align: center;
    max-width: 560px;
    margin: 0 auto 1.25rem;
}

.footer-dark .newsletters h3 {
    color: #F2F0E9;
    font-family: var(--ovo-font-display);
    font-weight: 500;
    letter-spacing: -0.01em;
    font-size: 1.5rem;
    margin: 0 0 0.5rem;
}

.footer-dark .newsletters p {
    color: rgba(250, 250, 247, 0.74);
    font-family: var(--ovo-font-body);
    font-size: 0.9375rem;
    line-height: 1.6;
    margin: 0;
}

.footer-dark .bloq-email {
    max-width: 520px;
    margin: 0 auto;
}

.footer-dark .bloq-email .email {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: stretch;
}

.footer-dark .bloq-email input[type="email"] {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--ovo-font-body);
    font-size: 0.9375rem;
    color: #F2F0E9;
    background-color: rgba(250, 250, 247, 0.06);
    border: 1px solid rgba(250, 250, 247, 0.18);
    border-radius: var(--radius-md);
    padding: 0 1rem;
    height: 48px;
    transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.footer-dark .bloq-email input[type="email"]::placeholder {
    color: rgba(250, 250, 247, 0.5);
}

.footer-dark .bloq-email input[type="email"]:focus {
    outline: none;
    border-color: var(--ovo-green-500);
    background-color: rgba(250, 250, 247, 0.10);
}

.footer-dark .bloq-email input[type="submit"],
.footer-dark .bloq-email .newsletter-submit {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    font-family: var(--ovo-font-body);
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--ovo-green-900);
    background-color: #F2F0E9;
    border: none;
    border-radius: var(--radius-md);
    padding: 0 1.5rem;
    height: 48px;
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.footer-dark .bloq-email input[type="submit"]:hover,
.footer-dark .bloq-email .newsletter-submit:hover {
    background-color: #FFFFFF;
}

/* Loading state: spinner shows while the fetch in newsletter.js is in flight */
.footer-dark .bloq-email .newsletter-submit:disabled {
    cursor: default;
}

.footer-dark .bloq-email .newsletter-submit__spinner {
    display: none;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(31, 60, 50, 0.3);
    border-top-color: var(--ovo-green-900);
    border-radius: 50%;
    animation: ovo-spin 0.6s linear infinite;
}

.footer-dark .bloq-email .newsletter-submit.is-loading .newsletter-submit__spinner {
    display: inline-block;
}

@keyframes ovo-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .footer-dark .bloq-email .newsletter-submit__spinner {
        animation-duration: 1.5s;
    }
}

.footer-dark .bloq-email label.error {
    display: block;
    color: #F6B8B0;
    font-size: 0.8125rem;
    margin-bottom: 0.5rem;
    text-align: center;
}

.footer-dark .bloq-email .subscription-success {
    flex-basis: 100%;
    color: var(--ovo-green-100);
    font-size: 0.875rem;
    margin: 0.25rem 0 0;
    text-align: center;
}

/* Stack the field + button on narrow screens */
@media (max-width: 575px) {
    .footer-dark .bloq-email input[type="submit"],
    .footer-dark .bloq-email .newsletter-submit {
        flex: 1 1 100%;
    }
}

/* ---------------------------
   Lightweight toast popup (vanilla JS — see newsletter.js)
   A circuit-free notification for the plain-HTML footer newsletter form, so it
   can confirm with a popup instead of a full-page reload. Branded to match the
   green v2 system; not a substitute for MudSnackbar inside interactive pages.
   --------------------------- */
.ovo-toast-host {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: center;
    width: max-content;
    max-width: calc(100vw - 32px);
    pointer-events: none;
}

.ovo-toast {
    pointer-events: auto;
    cursor: pointer;
    font-family: var(--ovo-font-body);
    font-size: 0.9375rem;
    line-height: 1.4;
    color: #FFFFFF;
    background-color: var(--ovo-green-700);
    border-radius: var(--radius-md);
    padding: 0.875rem 1.25rem;
    box-shadow: 0 8px 24px rgba(30, 63, 54, 0.28);
    opacity: 0;
    transform: translateY(12px);
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}

.ovo-toast.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.ovo-toast--success { background-color: var(--ovo-green-700); }
.ovo-toast--info    { background-color: var(--ovo-green-900); }
.ovo-toast--error   { background-color: #B23B3B; }

@media (prefers-reduced-motion: reduce) {
    .ovo-toast {
        transform: none;
        transition: opacity var(--transition-fast);
    }
    .ovo-toast.is-visible {
        transform: none;
    }
}

/* ===========================
   Page transition - fade in
   Applied to the main content container so route changes don't "pop" in.
   Respects prefers-reduced-motion.
   =========================== */
@keyframes ownovo-fade-in {
    from {
        opacity: 0;
        transform: translateY(4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.page-fade-in {
    animation: ownovo-fade-in var(--transition-medium) ease-out both;
}

@media (prefers-reduced-motion: reduce) {
    .page-fade-in {
        animation: none;
    }
}

/* ===========================
   Province tile hover - lifts the Explore-by-province tiles on hover.
   =========================== */
.province-tile:hover {
    box-shadow: var(--shadow-card-hover) !important;
    transform: translateY(-2px);
}

/* ===========================
   EmptyState - keeps the placeholder breathing room and centred.
   =========================== */
.empty-state-container {
    background-color: transparent;
    border: 1px dashed var(--color-divider);
    border-radius: var(--radius-lg);
}

/* ===========================
   Property detail page - hero gallery layout.
   Primary image on the left, optional thumbnail strip on the right.
   On <md it stacks.
   =========================== */
.property-detail-gallery {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 8px;
    height: 460px;
    overflow: hidden;
    position: relative; /* anchors .property-detail-gallery-preloads */
}

/* Virtual tour iframe wrapper - responsive 16:9 box that scales with the column
   width. The inner iframe is absolutely positioned to fill the wrapper so
   Matterport / YouTube / Vimeo all render edge-to-edge without scrollbars. */
.property-detail-virtual-tour {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--color-surface-muted, #f4f6f8);
}

.property-detail-virtual-tour iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Off-screen preload sandbox - lets the broken-image handler probe images
   in the "+more" pool without affecting layout. opacity:0 (not display:none
   or visibility:hidden) guarantees browsers actually fetch them. */
.property-detail-gallery-preloads {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

.property-detail-preload {
    width: 1px;
    height: 1px;
    object-fit: cover;
}

.property-detail-gallery-primary {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background-color: var(--color-surface-muted, #f4f6f8);
    min-height: 0;
    height: 100%;
}

/* contain, not cover: a portrait photo shows whole over its blurred backdrop
   rather than having a horizontal band cropped out of its middle. A landscape
   photo fills the frame exactly as before, so the backdrop never shows. */
.property-detail-hero-img {
    position: relative;
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.property-detail-hero-fallback {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.property-detail-gallery-thumbs {
    display: flex;
    flex-direction: column;
    gap: 8px;
    height: 100%;
    min-height: 0;
    min-width: 0;
}

.property-detail-thumb {
    flex: 1 1 0;
    width: 100%;
    min-height: 0;
    object-fit: cover;
    border-radius: var(--radius-lg);
    cursor: pointer;
    opacity: 0.95;
    transition: opacity 0.15s ease;
    border: none;
    display: block;
}

.property-detail-thumb:hover {
    opacity: 1;
}

.property-detail-thumb-more {
    flex: 0 0 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--color-surface-muted, #f4f6f8);
    color: var(--color-text-secondary);
    border-radius: var(--radius-lg);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
}

.property-detail-map-placeholder {
    height: 260px;
    background-color: var(--color-surface-muted, #f4f6f8);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

@media (max-width: 960px) {
    .property-detail-gallery {
        grid-template-columns: 1fr;
        height: auto;
    }
    .property-detail-gallery-primary {
        height: 280px;
    }
    .property-detail-gallery-thumbs {
        flex-direction: row;
        height: 72px;
    }
    .property-detail-thumb {
        height: 100%;
    }
    .property-detail-thumb-more {
        height: 100%;
        font-size: 0.8rem;
    }
}

/* -------------------------------------------------------------
   Property detail - right-hand aside (contact card + bond estimate)

   Shared by BOTH /properties/{id} and the search quick-view dialog
   (PropertyDetailModal renders the same PropertyDetailView body).

   Feedback #181: the aside was hard-wired to `position: sticky; top: 100px`. A sticky
   block that is TALLER than (scroll container height - top offset) has a permanently
   unreachable tail: it pins at the offset and simply never moves again. On the
   reporter's 1536x695 viewport the contact card alone filled the ~550px of visible
   room, so the "Estimate your bond" card underneath it could never be scrolled into
   view - the sidebar visibly froze while the left column carried on scrolling.

   Fix: only stick when the viewport is genuinely tall enough to hold the card, and cap
   the height so the tail stays reachable even at the threshold. Below the gate the
   aside is a normal static column that scrolls with the rest of the page.
   ------------------------------------------------------------- */
.property-detail-aside {
    position: static;
}

@media (min-height: 860px) {
    .property-detail-aside {
        position: sticky;
        top: 100px;
        /* Backstop for the tallest variant (agent branding + reveal-contact button):
           an internal scrollbar is preferable to content that cannot be reached.
           No overscroll-behavior here - scroll chaining to the page is wanted. */
        max-height: calc(100vh - 120px);
        overflow-y: auto;
    }
}

/* Inside the quick-view dialog the scrolling ancestor is .mud-dialog-content, not the
   window, and the thing to clear at the top is the dialog's own sticky back-bar (~60px)
   rather than the 100px site header - so the offset tightens and the cap is measured
   against the dialog's own height. */
@media (min-height: 860px) {
    .property-detail-dialog-body .property-detail-aside {
        top: 76px;
        max-height: calc(94vh - 96px);
    }
}

/* -------------------------------------------------------------
   Compare Properties page
   ------------------------------------------------------------- */
.compare-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1rem;
    align-items: stretch;
}

.compare-column {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    background: var(--color-surface, #fff);
}

.compare-column-image {
    position: relative;
    width: 100%;
    height: 180px;
    overflow: hidden;
    cursor: pointer;
    background: var(--color-background-light, #f5f5f5);
}

.compare-column-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--transition-medium);
}

.compare-column-image:hover img {
    transform: scale(1.04);
}

.compare-column-image-fallback {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.compare-remove-btn {
    position: absolute !important;
    top: 8px;
    right: 8px;
    background: rgba(255, 255, 255, 0.92) !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.compare-remove-btn:hover {
    background: #fff !important;
}

.compare-column-body {
    padding: 1rem 1.125rem 1.25rem;
    display: flex;
    flex-direction: column;
    flex: 1;
}

.compare-price {
    font-weight: 700;
    margin-bottom: 0.125rem;
}

.compare-title {
    font-weight: 500;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.6em;
    margin-bottom: 0.25rem;
}

.compare-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.375rem 0;
    font-size: 0.875rem;
    border-bottom: 1px dashed var(--color-border-light);
}

.compare-row:last-of-type {
    border-bottom: none;
}

.compare-row-label {
    color: var(--color-text-secondary, #5f6b7a);
    flex-shrink: 0;
}

.compare-row-value {
    color: var(--color-text-primary, #222);
    font-weight: 500;
    text-align: right;
}

.compare-features {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem 0.75rem;
    margin-top: 0.5rem;
}

.compare-feature {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.8125rem;
    line-height: 1.2;
}

.compare-feature-off {
    color: var(--color-text-disabled, #9ba4ae);
    text-decoration: line-through;
}

.compare-add-slot {
    border: 1.5px dashed var(--color-border-medium, #d4d9df);
    background: transparent;
    min-height: 420px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.compare-floating-cta {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1200;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
    border-radius: var(--radius-lg, 12px);
}

/* ===========================
   Agent / Agency Directory Cards
   =========================== */
.directory-card {
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
    border: 1px solid var(--color-border-light);
}

.directory-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-card-hover);
    border-color: var(--color-primary);
}

/* Agency profile cover banner (LinkedIn-style hero). The inline `style`
   attribute on the .agency-cover-banner element supplies the background
   (image or brand gradient); this rule reserves the layout box. Aspect
   ratio narrows on small screens so the banner doesn't dominate the
   viewport on mobile. */
.agency-cover-banner {
    width: 100%;
    aspect-ratio: 16 / 5;
    border-radius: 16px;
    background-color: var(--color-surface-muted);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    box-shadow: var(--shadow-card);
}

@media (max-width: 600px) {
    .agency-cover-banner {
        aspect-ratio: 16 / 8;
        border-radius: 12px;
    }
}

/* Dashboard settings cards */
.settings-card {
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
    border: 1px solid var(--color-border-light);
}

.settings-card:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-card-hover);
    border-color: var(--color-primary);
}

/* Saved property cards */
.saved-property-card {
    transition: box-shadow var(--transition-fast);
    border: 1px solid var(--color-border-light);
}

.saved-property-card:hover {
    box-shadow: var(--shadow-card-hover);
}

/* Dashboard stat cards (clickable drill-down) */
.stat-card {
    cursor: pointer;
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.stat-card:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-card-hover);
}



/* Notification bell menu */
.notification-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-primary);
    margin-top: 6px;
    flex-shrink: 0;
}

/* Notifications page row */
.notification-row {
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.notification-row:hover {
    background: var(--color-surface-muted);
}

.notification-row.unread {
    border-left: 3px solid var(--color-primary);
}

/* ===========================
   Ownovo brand - header / app-bar polish
   =========================== */
.ovo-appbar {
    backdrop-filter: saturate(160%) blur(8px);
    -webkit-backdrop-filter: saturate(160%) blur(8px);
    border-bottom: 1px solid var(--color-border-subtle);
}

.ovo-logo-img {
    height: 44px;
    width: auto;
    display: block;
}

/* Nav link - understated editorial register */
.ovo-nav-link.mud-button-root {
    color: var(--color-text-primary);
    font-weight: 500;
    font-size: 0.9375rem;
    letter-spacing: 0.01em;
    text-transform: none;
    border-radius: var(--radius-sm);
    padding: 6px 12px;
}

.ovo-nav-link.mud-button-root:hover {
    background-color: var(--color-surface-muted);
    color: var(--color-primary);
}

/* Pill CTA button used in header / hero */
.ovo-cta {
    border-radius: 999px !important;
    text-transform: none !important;
    font-weight: 500 !important;
    letter-spacing: 0.01em !important;
    padding: 8px 20px !important;
}

/* Theme toggle button */
.ovo-theme-toggle {
    color: var(--color-text-secondary) !important;
}

.ovo-theme-toggle:hover {
    color: var(--color-primary) !important;
    background-color: var(--color-surface-muted) !important;
}

/* Mobile nav drawer - force viewport-anchored positioning so it doesn't
   inherit the MudLayout's full-page height (Blazor renders drawer as
   position:absolute inside .mud-layout, which makes it 8000+ px tall). */
.mud-drawer.mud-drawer-temporary.mud-drawer-pos-left {
    position: fixed !important;
    top: 0 !important;
    bottom: 0 !important;
    height: 100vh !important;
    height: 100dvh !important;
    max-height: 100vh !important;
    max-height: 100dvh !important;
    overflow-y: auto !important;
    z-index: 1301 !important;
}

.mud-drawer-overlay,
.mud-overlay-drawer {
    z-index: 1300 !important;
}

.mud-drawer .mud-drawer-content {
    height: 100% !important;
    overflow-y: auto !important;
    display: flex !important;
    flex-direction: column !important;
}

/* Direct flex children of drawer-content default to flex:1 0 auto in MudBlazor,
   which stretches the MudDivider/MudNavMenu. Constrain them to content size. */
.mud-drawer .mud-drawer-content > .mud-divider {
    flex: 0 0 auto !important;
    height: 1px !important;
    min-height: 1px !important;
}

.mud-drawer .mud-drawer-content > .mud-navmenu {
    flex: 0 0 auto !important;
}

.mud-drawer .mud-nav-menu {
    padding: 8px 0;
}

.mud-drawer .mud-nav-link {
    color: var(--color-text-primary);
    font-weight: 500;
}

.mud-drawer .mud-nav-group .mud-nav-link {
    padding-left: 24px;
}

/* Dark-theme body selector compatibility with blazor-error-ui */
[data-theme="dark"] #blazor-error-ui {
    background-color: #243229;
    color: #F2F0E9;
}

/* Hero overlay - editorial green scrim works on all bg photos */
.ovo-hero-scrim::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(30, 63, 54, 0.45) 0%, rgba(30, 63, 54, 0.72) 100%);
    z-index: 1;
}

/* Homepage hero - brand-token background replacing legacy template bg */
#hero-area {
    background-image:
        linear-gradient(180deg, rgba(30, 63, 54, 0.55) 0%, rgba(30, 63, 54, 0.75) 100%),
        url('../images/home-page/HomePageBanner1.jpg');
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
    color: #fff;
    min-height: 100vh !important;
    min-height: 100dvh !important;
}

#hero-area .hero-main,
#hero-area .welcome-text {
    position: relative;
    z-index: 2;
}

/* Hero search box - fluid on small screens, capped on desktop */
#hero-area .hero-search-stack {
    width: 100%;
    max-width: 640px;
}

#hero-area .hero-search-stack .mud-autocomplete,
#hero-area .hero-search-box {
    width: 100% !important;
    max-width: 100% !important;
}

/* Tablet+ (≥768px): modest growth */
@media (min-width: 768px) {
    #hero-area .hero-search-stack {
        max-width: clamp(480px, 50vw, 560px);
    }
}

/* Desktop (≥1200px): a bit wider, still narrower than the headline */
@media (min-width: 1200px) {
    #hero-area .hero-search-stack {
        max-width: 600px;
    }

    #hero-area .hero-search-box .mud-input-slot {
        font-size: 1.05rem;
        padding-block: 0.7rem;
    }

    #hero-area .hero-search-box .mud-input-adornment .mud-icon-button {
        width: 48px;
        height: 48px;
    }
}

/* Extra-large screens (≥1600px): nudge slightly wider */
@media (min-width: 1600px) {
    #hero-area .hero-search-stack {
        max-width: 680px;
    }
}

@media (max-width: 768px) {
    #hero-area {
        background-attachment: scroll !important;
        background-position: 50% 40% !important;
        min-height: 560px !important;
    }

    #hero-area .hero-main {
        padding-inline: 16px !important;
    }

    #hero-area .hero-search-stack {
        padding-inline: 8px;
        max-width: 100%;
        box-sizing: border-box;
    }

    #hero-area .hero-search-box {
        width: 100% !important;
        max-width: 100% !important;
    }
}

@media (max-width: 480px) {
    #hero-area {
        min-height: 480px !important;
    }
}

/* iOS Safari renders `background-attachment: fixed` + `background-size: cover`
   unreliably - the hero image vanishes (reported on iPad landscape, where the
   <=768px scroll override below does not apply). Drop `fixed` on every touch
   device so the image always paints; desktop mouse users keep the parallax. */
@media (hover: none), (pointer: coarse) {
    #hero-area {
        background-attachment: scroll !important;
    }
}

/* Province quick-access chips in hero */
#hero-area .hero-province-chips {
    width: 100%;
    max-width: 900px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin-top: 4px;
}

#hero-area .hero-province-label {
    color: rgba(255, 255, 255, 0.75);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-size: 0.72rem;
}

#hero-area .hero-province-chip-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
}

#hero-area .hero-province-chip {
    display: inline-flex;
    align-items: center;
    padding: 6px 14px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.55);
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.2;
    text-decoration: none;
    backdrop-filter: blur(2px);
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

#hero-area .hero-province-chip:hover,
#hero-area .hero-province-chip:focus-visible {
    background: var(--ovo-white, #fff);
    color: var(--ovo-green-700, #2F5D50);
    border-color: var(--ovo-white, #fff);
    transform: translateY(-1px);
    text-decoration: none;
    outline: none;
}

@media (max-width: 480px) {
    #hero-area .hero-province-chip {
        padding: 5px 12px;
        font-size: 0.8125rem;
    }
}

/* Hero Buy / Rent intent toggle - glassy segmented control over the photo */
#hero-area .hero-txn-toggle {
    display: inline-flex;
    padding: 4px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.4);
    backdrop-filter: blur(4px);
}

#hero-area .hero-txn-segment {
    appearance: none;
    border: none;
    background: transparent;
    color: #fff;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1;
    padding: 9px 28px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

#hero-area .hero-txn-segment.is-active {
    background: var(--ovo-white, #fff);
    color: var(--ovo-green-700, #2F5D50);
}

#hero-area .hero-txn-segment:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* Alternating tinted section band on the home page - breaks the cream monotony */
.home-band {
    background: var(--ovo-green-50, #F2F6F4);
}

/* ===========================
   Navigation progress overlay (markup in App.razor, toggled by js/nav-progress.js)
   Branded veil + animated Ownovo "liquid" loader that masks the enhanced-
   navigation scroll-to-top flash. Idle state is transparent + click-through.
   =========================== */
#ownovo-nav-overlay {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ovo-surface, #FAFAF7);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 140ms ease, visibility 0s linear 140ms;
}

#ownovo-nav-overlay.is-active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: none; /* instant cover - the scroll snap lands ~16ms after the click */
}

#ownovo-nav-overlay .ownovo-nav-loader {
    width: 64px;
    height: 64px;
}

#ownovo-nav-overlay .ovo-nav-tile { fill: var(--ovo-green-700, #2F5D50); }
#ownovo-nav-overlay .ovo-nav-key  { fill: var(--ovo-surface, #FAFAF7); }

#ownovo-nav-overlay .ovo-nav-arch {
    fill: none;
    stroke: var(--ovo-surface, #FAFAF7);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

#ownovo-nav-overlay .ovo-nav-liquid {
    fill: var(--ovo-green-500, #4A8574);
    transform: translateY(40px); /* resting level when idle */
}

/* Animate only while the veil is up - no CPU cost when idle. */
#ownovo-nav-overlay.is-active .ovo-nav-liquid {
    animation: ownovo-nav-rise 2.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

@keyframes ownovo-nav-rise {
    0%       { transform: translateY(40px); }
    45%, 55% { transform: translateY(-2px); }
    100%     { transform: translateY(40px); }
}

/* The loader intentionally animates even under prefers-reduced-motion: it is a
   small, contained, functional progress indicator - not decorative motion - and
   a frozen loader reads as broken. The veil itself appears without movement. */

/* Why-Ownovo trust-signal icon badges - one consistent brand treatment */
.trust-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 76px;
    height: 76px;
    border-radius: 50%;
    background: var(--ovo-green-100, #E4ECE8);
}

/* ===========================
   Blazor reconnect modal - centered, branded
   =========================== */
#components-reconnect-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(30, 63, 54, 0.55);
    padding: 16px;
    box-sizing: border-box;
}

#components-reconnect-modal > * {
    max-width: 360px;
    width: 100%;
    background: var(--color-surface, #fff);
    color: var(--color-text-primary, #1a1a1a);
    border-radius: 12px;
    padding: 24px 20px;
    text-align: center;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.9375rem;
    line-height: 1.45;
    box-shadow: 0 12px 40px rgba(0,0,0,0.25);
}

#components-reconnect-modal a,
#components-reconnect-modal button {
    display: inline-block;
    margin-top: 12px;
    padding: 8px 18px;
    border-radius: 999px;
    background: var(--ovo-green-700, #2F5D50);
    color: #fff;
    text-decoration: none;
    font-weight: 500;
    border: none;
    cursor: pointer;
}

#components-reconnect-modal a:hover,
#components-reconnect-modal button:hover {
    background: var(--ovo-green-900, #1E3F36);
}

/* ===========================
   POPIA cookie consent banner
   =========================== */
.cookie-consent-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1400;
    display: flex;
    justify-content: center;
    padding: 16px;
    pointer-events: none;
}

.cookie-consent-banner .cookie-consent-card {
    pointer-events: auto;
    max-width: 720px;
    width: 100%;
    border: 1px solid var(--ovo-line);
    border-radius: 12px;
    background: var(--ovo-white);
}

[data-theme="dark"] .cookie-consent-banner .cookie-consent-card {
    background: var(--ovo-ink-soft, #1f2623);
    border-color: rgba(255,255,255,0.08);
}

@media (max-width: 600px) {
    .cookie-consent-banner {
        padding: 8px;
    }
}

/* ===========================
   Pre-launch "coming soon" gate (/coming-soon)
   Full-screen standalone page - no header, no footer, no nav.
   =========================== */
.coming-soon {
    min-height: 100vh;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--ovo-space-5);
    background:
        radial-gradient(1200px 600px at 80% -10%, rgba(74, 133, 116, 0.18), transparent 60%),
        radial-gradient(900px 500px at -10% 110%, rgba(30, 63, 54, 0.22), transparent 60%),
        linear-gradient(180deg, var(--ovo-green-900) 0%, #13302A 100%);
    color: var(--ovo-white);
    font-family: var(--ovo-font-body);
}

.coming-soon__card {
    width: 100%;
    max-width: 520px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--ovo-radius-lg);
    padding: var(--ovo-space-8) var(--ovo-space-6);
    box-shadow: var(--ovo-shadow-lg);
    text-align: center;
    backdrop-filter: blur(4px);
}

.coming-soon__logo {
    width: 120px;
    height: auto;
    margin: 0 auto var(--ovo-space-5);
    display: block;
    filter: brightness(0) invert(1);
}

.coming-soon__headline {
    font-family: var(--ovo-font-display);
    font-weight: 500;
    font-size: clamp(1.75rem, 4vw, 2.25rem);
    line-height: 1.2;
    margin: 0 0 var(--ovo-space-3);
    color: var(--ovo-white);
    letter-spacing: -0.01em;
}

.coming-soon__lede {
    font-size: 0.95rem;
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.78);
    margin: 0 auto var(--ovo-space-6);
    max-width: 40ch;
}

.coming-soon__action {
    display: inline-block;
    appearance: none;
    border: 1px solid rgba(255, 255, 255, 0.35);
    background: transparent;
    color: var(--ovo-white);
    font-family: var(--ovo-font-body);
    font-weight: 500;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
    padding: 10px 22px;
    border-radius: var(--ovo-radius);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.coming-soon__action:hover,
.coming-soon__action:focus-visible {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.55);
    outline: none;
}

.coming-soon__form {
    margin-top: var(--ovo-space-4);
    text-align: left;
    max-width: 320px;
    margin-left: auto;
    margin-right: auto;
}

.coming-soon__label {
    display: block;
    font-size: 0.8rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.7);
    margin-bottom: var(--ovo-space-2);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.coming-soon__input {
    width: 100%;
    padding: 10px 14px;
    font-size: 1rem;
    font-family: var(--ovo-font-body);
    background: rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: var(--ovo-radius);
    color: var(--ovo-white);
    transition: border-color 0.15s ease, background 0.15s ease;
}

.coming-soon__input:focus-visible {
    outline: none;
    border-color: var(--ovo-green-500);
    background: rgba(0, 0, 0, 0.35);
}

.coming-soon__submit {
    width: 100%;
    appearance: none;
    border: 0;
    background: var(--ovo-green-500);
    color: var(--ovo-green-900);
    font-family: var(--ovo-font-body);
    font-weight: 600;
    font-size: 0.95rem;
    padding: 11px 20px;
    margin-top: var(--ovo-space-4);
    border-radius: var(--ovo-radius);
    cursor: pointer;
    transition: background 0.15s ease;
}

.coming-soon__submit:hover,
.coming-soon__submit:focus-visible {
    background: #5E9A88;
    outline: none;
}

.coming-soon__error {
    color: #FFC9C2;
    font-size: 0.85rem;
    margin: var(--ovo-space-3) 0 0;
}

/* =========================================================================
   PASSWORD REVEAL TOGGLE (global)
   Vanilla-JS show/hide button wired by the [data-password-toggle] handler in
   site-helpers.js. Keyed on .form-floating.has-password-toggle (NOT scoped to
   .account-card) so it works everywhere a password field lives: the Login /
   Register / Reset auth cards AND the Identity Manage pages (Change / Set
   password, Delete account). Sits over the right edge of the input; reserve
   right padding so masked text never runs under it.
   ========================================================================= */
.form-floating.has-password-toggle > .form-control {
    padding-right: 3rem;
}

/* Edge (Chromium keeps the -ms- prefixed pseudo-elements) draws its OWN reveal
   "eye" and clear "x" inside a password input the moment the field has content,
   pinned to the same right edge our .password-toggle sits on. Typing therefore
   made a second eye slide in from behind ours and flicker per keystroke - the
   "eye glitches while typing" report (feedback #210, Edge 150). Suppress the
   native affordances only where we render our own control, so a password field
   without a toggle keeps the browser's. Our toggle flips the input to
   type="text" when revealed, at which point these no longer apply anyway. */
.form-floating.has-password-toggle > .form-control::-ms-reveal,
.form-floating.has-password-toggle > .form-control::-ms-clear,
.coming-soon__input-wrap > .coming-soon__input::-ms-reveal,
.coming-soon__input-wrap > .coming-soon__input::-ms-clear {
    display: none;
    width: 0;
    height: 0;
    margin: 0;
}

.form-floating.has-password-toggle > .password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 56px;
    padding: 0;
    margin: 0;
    border: none;
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: color 0.15s ease;
}

.form-floating.has-password-toggle > .password-toggle:hover {
    color: var(--color-primary);
}

.form-floating.has-password-toggle > .password-toggle:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -3px;
    border-radius: 4px;
    color: var(--color-primary);
}

/* Icon swap: eye when hidden, eye-off when revealed (aria-pressed="true"). */
.password-toggle .pt-eye-off {
    display: none;
}

.password-toggle[aria-pressed="true"] .pt-eye {
    display: none;
}

.password-toggle[aria-pressed="true"] .pt-eye-off {
    display: inline;
}

/* Coming-soon gate variant: dark card, so the toggle is tinted for the dark
   surface and positioned over the (shorter) .coming-soon__input. */
.coming-soon__input-wrap {
    position: relative;
}

.coming-soon__input-wrap > .coming-soon__input {
    padding-right: 2.75rem;
}

.coming-soon__input-wrap > .password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: transparent;
    color: rgba(255, 255, 255, 0.7);
    cursor: pointer;
    transition: color 0.15s ease;
}

.coming-soon__input-wrap > .password-toggle:hover,
.coming-soon__input-wrap > .password-toggle:focus-visible {
    color: var(--ovo-white);
    outline: none;
}

.coming-soon__footer {
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.5);
    margin: var(--ovo-space-8) 0 0;
    letter-spacing: 0.04em;
}

@media (max-width: 480px) {
    .coming-soon__card {
        padding: var(--ovo-space-6) var(--ovo-space-4);
    }
    .coming-soon__logo {
        width: 96px;
    }
}

/* ------------------------------------------------------------------------- */
/* Off-Grid Readiness panel (PropertyDetailView)                             */
/* ------------------------------------------------------------------------- */
.off-grid-panel {
    border-radius: 14px;
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-background-light) 140%);
}

.off-grid-header {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
}

.off-grid-ring {
    position: relative;
    width: 92px;
    height: 92px;
    flex-shrink: 0;
}

.off-grid-ring svg {
    display: block;
    transition: transform 0.3s ease;
}

.off-grid-ring-text {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.off-grid-ring-score {
    font-family: var(--font-display, 'Fraunces', serif);
    font-size: 26px;
    font-weight: 600;
    line-height: 1;
    color: var(--color-text-primary);
    letter-spacing: -0.02em;
}

.off-grid-ring-total {
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-secondary);
    margin-top: 3px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.off-grid-header-text {
    flex: 1 1 280px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.off-grid-eyebrow {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-secondary);
}

.off-grid-title.mud-typography {
    font-family: var(--font-display, 'Fraunces', serif);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.15;
    margin: 0;
}

.off-grid-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 6px;
}

.off-grid-tier-chip,
.off-grid-verify-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}

.off-grid-tier-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.off-grid-verify-chip .mud-icon-root {
    width: 14px;
    height: 14px;
    font-size: 14px;
}

.off-grid-verify-chip--high {
    background: rgba(47, 93, 80, 0.08);
    color: var(--ovo-green-700);
    border: 1px solid rgba(47, 93, 80, 0.22);
}

.off-grid-verify-chip--medium {
    background: rgba(32, 102, 148, 0.08);
    color: #1F6694;
    border: 1px solid rgba(32, 102, 148, 0.22);
}

.off-grid-verify-chip--muted {
    background: var(--color-surface-muted);
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.10));
}

.off-grid-explainer {
    margin: 18px 0 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--color-text-secondary);
}

/* Tier spectrum scale */
.off-grid-scale {
    margin-top: 22px;
}

.off-grid-scale-track {
    position: relative;
    display: flex;
    width: 100%;
    height: 8px;
    border-radius: 999px;
    overflow: visible;
    background: var(--color-background-medium);
}

.off-grid-scale-seg {
    height: 100%;
    display: block;
}

.off-grid-scale-seg:first-child {
    border-top-left-radius: 999px;
    border-bottom-left-radius: 999px;
}

.off-grid-scale-seg:last-child {
    border-top-right-radius: 999px;
    border-bottom-right-radius: 999px;
}

.off-grid-scale-seg--dep {
    background: rgba(154, 165, 160, 0.35);
}

.off-grid-scale-seg--par {
    background: rgba(232, 164, 74, 0.35);
}

.off-grid-scale-seg--ready {
    background: rgba(47, 93, 80, 0.35);
}

.off-grid-scale-marker {
    position: absolute;
    top: 50%;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    border: 3px solid var(--color-surface);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
}

.off-grid-scale-labels {
    display: flex;
    width: 100%;
    margin-top: 10px;
    font-size: 11px;
    font-weight: 500;
    color: var(--color-text-secondary);
    letter-spacing: 0.02em;
}

.off-grid-scale-labels span {
    text-align: center;
}

.off-grid-scale-labels span:first-child {
    text-align: left;
}

.off-grid-scale-labels span:last-child {
    text-align: right;
}

/* Expansion */
.off-grid-expansion {
    margin-top: 18px;
    background: transparent !important;
}

.off-grid-expansion .mud-expansion-panel {
    background: var(--color-background-light) !important;
    border-radius: 10px !important;
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.06)) !important;
    box-shadow: none !important;
}

.off-grid-expansion .mud-expansion-panel::before {
    display: none;
}

.off-grid-expansion-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    color: var(--color-text-primary);
    font-size: 14px;
}

.off-grid-expansion-title .mud-icon-root {
    color: var(--ovo-green-700);
}

.off-grid-expansion-lede {
    margin: 0 0 16px;
    font-size: 13px;
    line-height: 1.6;
    color: var(--color-text-secondary);
}

.off-grid-breakdown {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 20px;
}

@media (max-width: 599px) {
    .off-grid-breakdown {
        grid-template-columns: 1fr;
    }
}

.off-grid-factor {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.off-grid-factor-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--color-text-primary);
}

.off-grid-factor-icon {
    color: var(--ovo-green-700);
    width: 16px !important;
    height: 16px !important;
    font-size: 16px !important;
}

.off-grid-factor-label {
    flex: 1;
    font-weight: 500;
}

.off-grid-factor-weight {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--color-text-secondary);
    font-size: 12px;
}

.off-grid-factor-bar {
    height: 6px;
    width: 100%;
    background: var(--color-background-medium);
    border-radius: 999px;
    overflow: hidden;
}

.off-grid-factor-bar > span {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, var(--ovo-green-500) 0%, var(--ovo-green-700) 100%);
    border-radius: 999px;
}

@media (max-width: 599px) {
    .off-grid-header {
        gap: 14px;
    }
    .off-grid-ring {
        width: 76px;
        height: 76px;
    }
    .off-grid-ring svg {
        width: 76px;
        height: 76px;
    }
    .off-grid-ring-score {
        font-size: 22px;
    }
    .off-grid-title.mud-typography {
        font-size: 1.25rem;
    }
}

/* ------------------------------------------------------------------------- */
/* Solar yield panel (PropertyDetailView, sibling of Off-Grid Readiness)     */
/* ------------------------------------------------------------------------- */
.property-solar-yield-panel {
    border-radius: 14px;
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-background-light) 140%);
}

.property-solar-yield-header {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
}

.property-solar-yield-icon {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: 14px;
    padding: 12px;
    background: var(--ovo-green-50, #E8F1EE);
    color: var(--ovo-green-700, #2F5D50) !important;
}

.property-solar-yield-text {
    flex: 1 1 280px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.property-solar-yield-eyebrow {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-secondary);
}

.property-solar-yield-title.mud-typography {
    font-family: var(--font-display, 'Fraunces', serif);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.15;
    margin: 0;
}

.property-solar-yield-headline {
    font-size: 20px;
    font-weight: 600;
    color: var(--color-text-primary);
    margin-top: 4px;
}

.property-solar-yield-sub {
    font-size: 13px;
    color: var(--color-text-secondary);
}

.property-solar-yield-expansion {
    margin-top: 18px;
    background: transparent !important;
}

.property-solar-yield-expansion .mud-expansion-panel {
    background: var(--color-background-light) !important;
    border-radius: 10px !important;
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.06)) !important;
    box-shadow: none !important;
}

.property-solar-yield-expansion .mud-expansion-panel::before {
    display: none;
}

.property-solar-yield-expansion-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    color: var(--color-text-primary);
    font-size: 14px;
}

.property-solar-yield-expansion-title .mud-icon-root {
    color: var(--ovo-green-700);
}

.property-solar-yield-expansion-lede {
    margin: 0 0 12px;
    font-size: 13px;
    line-height: 1.6;
    color: var(--color-text-secondary);
}

.property-solar-yield-assumptions {
    margin: 0 0 14px;
    padding-left: 20px;
    font-size: 13px;
    line-height: 1.7;
    color: var(--color-text-primary);
}

.property-solar-yield-assumptions li + li {
    margin-top: 2px;
}

.property-solar-yield-disclaimer {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--color-text-secondary);
    font-style: italic;
}

@media (max-width: 599px) {
    .property-solar-yield-header {
        gap: 14px;
    }
    .property-solar-yield-icon {
        width: 48px;
        height: 48px;
    }
    .property-solar-yield-title.mud-typography {
        font-size: 1.25rem;
    }
    .property-solar-yield-headline {
        font-size: 18px;
    }
}

/* ------------------------------------------------------------------------- */
/* Off-Grid banner (AddListing Features step - hero card)                    */
/* ------------------------------------------------------------------------- */
.ai-generate-callout {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 18px;
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(47, 93, 80, 0.05) 0%, rgba(47, 93, 80, 0.02) 100%);
    border: 1px dashed rgba(47, 93, 80, 0.35);
}

.ai-generate-callout__icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--ovo-green-700, #2F5D50);
    color: #fff;
}

.ai-generate-callout__icon .mud-icon-root {
    color: #fff;
}

.ai-generate-callout__text {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.ai-generate-callout__text strong {
    color: var(--color-text-primary);
    font-size: 0.95rem;
    line-height: 1.3;
}

.ai-generate-callout__text span {
    color: var(--color-text-secondary);
    font-size: 0.825rem;
    line-height: 1.4;
}

@media (max-width: 600px) {
    .ai-generate-callout {
        flex-wrap: wrap;
    }
    .ai-generate-callout__text {
        flex-basis: 100%;
    }
}

.off-grid-banner {
    position: relative;
    display: flex;
    align-items: stretch;
    gap: 24px;
    padding: 22px 24px;
    border-radius: 16px;
    background:
        radial-gradient(circle at 0% 0%, rgba(47, 93, 80, 0.14) 0%, rgba(47, 93, 80, 0) 55%),
        radial-gradient(circle at 100% 100%, rgba(232, 164, 74, 0.14) 0%, rgba(232, 164, 74, 0) 55%),
        linear-gradient(180deg, var(--color-surface) 0%, var(--color-background-light) 100%);
    border: 1px solid rgba(47, 93, 80, 0.18);
    overflow: hidden;
}

.off-grid-banner::before {
    content: "";
    position: absolute;
    inset: 0 0 0 0;
    width: 4px;
    background: linear-gradient(180deg, var(--ovo-green-700) 0%, var(--ovo-green-500) 100%);
    border-top-left-radius: 16px;
    border-bottom-left-radius: 16px;
}

.off-grid-banner--complete {
    border-color: rgba(47, 93, 80, 0.35);
    background:
        radial-gradient(circle at 0% 0%, rgba(47, 93, 80, 0.18) 0%, rgba(47, 93, 80, 0) 55%),
        linear-gradient(180deg, rgba(47, 93, 80, 0.04) 0%, var(--color-background-light) 100%);
}

.off-grid-banner-art {
    position: relative;
    flex-shrink: 0;
    width: 84px;
    height: 84px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.off-grid-banner-art .mud-icon-root {
    position: relative;
    z-index: 2;
    width: 36px;
    height: 36px;
    font-size: 36px;
    color: var(--ovo-green-700);
}

.off-grid-banner-art-ring,
.off-grid-banner-art-ring--outer {
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}

.off-grid-banner-art-ring {
    inset: 14px;
    background: rgba(47, 93, 80, 0.12);
    z-index: 1;
}

.off-grid-banner-art-ring--outer {
    inset: 0;
    border: 1px dashed rgba(47, 93, 80, 0.35);
    z-index: 0;
}

.off-grid-banner-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.off-grid-banner-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ovo-green-700);
    align-self: flex-start;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(47, 93, 80, 0.10);
}

.off-grid-banner-eyebrow .mud-icon-root {
    width: 12px;
    height: 12px;
    font-size: 12px;
    color: var(--ovo-green-700);
}

.off-grid-banner-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    font-family: var(--font-display, 'Fraunces', serif);
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--color-text-primary);
}

.off-grid-banner-optional {
    font-family: var(--font-body, 'Inter', sans-serif);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--color-text-secondary);
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--color-surface-muted);
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
}

.off-grid-banner-badge {
    font-family: var(--font-body, 'Inter', sans-serif);
    font-size: 13px;
    font-weight: 600;
    color: var(--ovo-green-900);
    padding: 4px 12px;
    border-radius: 999px;
    background: rgba(47, 93, 80, 0.12);
    border: 1px solid rgba(47, 93, 80, 0.25);
}

.off-grid-banner-text {
    margin: 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--color-text-secondary);
    max-width: 70ch;
}

.off-grid-banner-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 6px;
}

.off-grid-banner-hint {
    font-size: 12px;
    color: var(--color-text-secondary);
    font-style: italic;
}

@media (max-width: 599px) {
    .off-grid-banner {
        flex-direction: column;
        align-items: flex-start;
        padding: 18px 18px 18px 22px;
        gap: 16px;
    }
    .off-grid-banner-art {
        width: 64px;
        height: 64px;
    }
    .off-grid-banner-art .mud-icon-root {
        width: 28px;
        height: 28px;
        font-size: 28px;
    }
    .off-grid-banner-title {
        font-size: 1.25rem;
    }
}

/* ------------------------------------------------------------------------- */
/* Off-Grid reminder dialog                                                  */
/* ------------------------------------------------------------------------- */
.off-grid-reminder-dialog .mud-dialog {
    border-radius: 16px;
    overflow: hidden;
}

.off-grid-reminder {
    position: relative;
    padding: 8px 4px 4px;
    text-align: center;
}

.off-grid-reminder-art {
    width: 64px;
    height: 64px;
    margin: 0 auto 14px;
    border-radius: 50%;
    background:
        radial-gradient(circle, rgba(47, 93, 80, 0.16) 0%, rgba(47, 93, 80, 0.04) 70%);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dashed rgba(47, 93, 80, 0.35);
}

.off-grid-reminder-art .mud-icon-root {
    width: 32px;
    height: 32px;
    font-size: 32px;
    color: var(--ovo-green-700);
}

.off-grid-reminder-eyebrow {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ovo-green-700);
    margin-bottom: 6px;
}

.off-grid-reminder-title {
    font-family: var(--font-display, 'Fraunces', serif);
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--color-text-primary);
    margin-bottom: 10px;
}

.off-grid-reminder-body {
    margin: 0 auto 16px;
    max-width: 46ch;
    font-size: 14px;
    line-height: 1.65;
    color: var(--color-text-secondary);
}

.off-grid-reminder-perks {
    list-style: none;
    padding: 12px 16px;
    margin: 0;
    border-radius: 12px;
    background: var(--color-background-light);
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.06));
    display: flex;
    flex-direction: column;
    gap: 8px;
    text-align: left;
}

.off-grid-reminder-perks li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: var(--color-text-primary);
}

.off-grid-reminder-perks .mud-icon-root {
    width: 16px;
    height: 16px;
    font-size: 16px;
    color: var(--ovo-green-700);
    flex-shrink: 0;
}

/* ───────────────────────────────────────────────────────────
   Feedback widget - floating launcher + dialog attachments
   Shown in top-right corner when Feedback.Enabled is on.
   ─────────────────────────────────────────────────────────── */
.ovo-feedback-launcher {
    position: fixed;
    top: 80px;
    right: 16px;
    z-index: 1300;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
}

.ovo-feedback-launcher .ovo-feedback-fab {
    pointer-events: auto;
    box-shadow: 0 4px 12px rgba(30, 63, 54, 0.25);
    border-radius: 50%;
    width: 44px;
    height: 44px;
}

.ovo-feedback-launcher .ovo-feedback-fab:hover {
    box-shadow: 0 6px 16px rgba(30, 63, 54, 0.35);
}

.ovo-feedback-launcher .ovo-feedback-fab-secondary {
    pointer-events: auto;
    background: var(--color-surface, #fff) !important;
    border-radius: 50% !important;
    width: 36px !important;
    height: 36px !important;
    box-shadow: 0 2px 8px rgba(30, 63, 54, 0.18);
}

.ovo-feedback-launcher .ovo-feedback-fab-secondary:hover {
    box-shadow: 0 4px 12px rgba(30, 63, 54, 0.28);
}

.ovo-feedback-comment-system {
    background: var(--color-surface-subtle, #f6f9f7) !important;
    border: 1px dashed var(--color-border, #e0e0e0);
}

@media (max-width: 600px) {
    .ovo-feedback-launcher {
        top: auto;
        bottom: 16px;
        right: 16px;
    }
}

.ovo-feedback-thumb {
    position: relative;
    width: 96px;
    height: 96px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--color-surface-alt, #f5f5f5);
    border: 1px solid var(--color-border, #e0e0e0);
}

.ovo-feedback-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ovo-feedback-thumb-remove {
    position: absolute !important;
    top: 2px;
    right: 2px;
    background: rgba(0, 0, 0, 0.55) !important;
    color: #fff !important;
    width: 24px !important;
    height: 24px !important;
    padding: 0 !important;
}

.ovo-feedback-thumb-remove:hover {
    background: rgba(0, 0, 0, 0.75) !important;
}

.ovo-feedback-thumb-label {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2px 6px;
    font-size: 11px;
    color: #fff;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
    text-align: right;
}

.ovo-feedback-admin-thumb {
    display: block;
    width: 120px;
    height: 90px;
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid var(--color-border, #e0e0e0);
}

.ovo-feedback-admin-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ovo-feedback-dupes {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
    max-height: 180px;
    overflow-y: auto;
}

.ovo-feedback-dupe {
    padding: 0.5rem 0.625rem;
    border-radius: 6px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
}

.ovo-feedback-dupe-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    font-size: 0.72rem;
    color: var(--color-text-secondary);
    margin-bottom: 0.125rem;
}

.ovo-feedback-dupe-msg {
    font-size: 0.85rem;
    color: var(--color-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

/* =================================================================
   Add Listing - Features step: icon+label toggle pills
   ================================================================= */

.feat-section {
    margin-bottom: 28px;
}

.feat-section-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}

.feat-section-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--ovo-green-50);
    color: var(--ovo-green-700);
}

.feat-section-icon .mud-icon-root {
    width: 20px;
    height: 20px;
    font-size: 20px;
    color: var(--ovo-green-700);
}

.feat-section-title {
    font-family: var(--font-display, 'Fraunces', serif);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--color-text-primary);
    margin: 0;
    line-height: 1.2;
}

.feat-section-sub {
    margin: 2px 0 0;
    font-size: 13px;
    line-height: 1.4;
    color: var(--color-text-secondary);
}

.feat-pill-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 10px;
}

.feat-inline-select {
    margin-top: 14px;
    max-width: 360px;
}

.feat-inline-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px;
    margin-top: 14px;
}

.rooms-panels .mud-expansion-panel {
    border-radius: 8px;
}

.feat-pill {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    padding: 10px 14px;
    border: 1px solid var(--color-border-light);
    border-radius: 10px;
    background: var(--color-surface);
    color: var(--color-text-primary);
    font-family: var(--font-body, 'Inter', sans-serif);
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.25;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, color .15s ease, box-shadow .15s ease;
}

.feat-pill:hover {
    border-color: var(--ovo-green-500);
    background: var(--ovo-green-50);
}

.feat-pill:focus-visible {
    outline: none;
    border-color: var(--ovo-green-700);
    box-shadow: 0 0 0 3px rgba(47, 93, 80, 0.2);
}

.feat-pill .mud-icon-root {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    font-size: 20px;
    color: var(--color-text-secondary);
    transition: color .15s ease;
}

.feat-pill--on {
    border-color: var(--ovo-green-700);
    background: var(--ovo-green-700);
    color: #FFFFFF;
    box-shadow: 0 2px 6px rgba(47, 93, 80, 0.18);
}

.feat-pill--on .mud-icon-root {
    color: #FFFFFF;
}

.feat-pill--on:hover {
    background: var(--ovo-green-900);
    border-color: var(--ovo-green-900);
}

.feat-compliance {
    position: relative;
    padding: 18px 20px;
    margin-bottom: 28px;
    border-radius: 12px;
    border: 1px solid var(--color-border-light);
    background: var(--color-surface-muted);
}

.feat-compliance-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 14px;
}

.feat-compliance-head > .mud-icon-root {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    font-size: 22px;
    color: var(--ovo-green-700);
    margin-top: 2px;
}

.feat-compliance-title {
    font-family: var(--font-display, 'Fraunces', serif);
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--color-text-primary);
    margin: 0;
    line-height: 1.2;
}

.feat-compliance-sub {
    margin: 2px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-text-secondary);
    max-width: 70ch;
}

@media (max-width: 599px) {
    .feat-section { margin-bottom: 22px; }
    .feat-section-head { margin-bottom: 10px; gap: 10px; }
    .feat-section-icon { width: 32px; height: 32px; }
    .feat-section-icon .mud-icon-root { width: 18px; height: 18px; font-size: 18px; }
    .feat-section-title { font-size: 1rem; }
    .feat-section-sub { font-size: 12px; }

    .feat-pill-grid {
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
        gap: 8px;
    }

    .feat-pill {
        padding: 9px 12px;
        font-size: 0.8125rem;
        min-height: 42px;
    }

    .feat-compliance { padding: 16px; }
}

/* ---- Add Listing · Basics step subgroups + dominant price ---- */
.ovo-form-subgroup {
    padding: 8px 0 4px;
}

.ovo-form-subgroup + .ovo-form-subgroup {
    margin-top: 8px;
    border-top: 1px solid var(--color-border-subtle);
    padding-top: 20px;
}

.ovo-form-subgroup-label {
    display: block;
    margin: 0 0 6px;
    font-family: var(--font-display, 'Fraunces', serif);
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--color-text-primary);
}

.ovo-form-subgroup-hint {
    margin: 0 0 14px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--color-text-secondary);
}

.ovo-price-field .mud-input-slot input {
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--color-text-primary);
}

.ovo-price-field .mud-input-adornment-start {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--ovo-green-700);
}

.ovo-price-field .mud-input-label {
    font-weight: 600;
}

.ovo-inline-hint {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--color-text-secondary);
}

.ovo-inline-hint--warn {
    color: var(--color-warning);
}

.ovo-listing-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.ovo-listing-header-text {
    min-width: 0;
    flex: 1;
}

.ovo-draft-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 999px;
    background: var(--ovo-green-50, rgba(47, 93, 80, 0.06));
    border: 1px solid var(--color-border-subtle);
    font-size: 12px;
    line-height: 1;
    color: var(--color-text-secondary);
    white-space: nowrap;
    flex: 0 0 auto;
    margin-top: 6px;
}

.ovo-draft-status-icon {
    font-size: 16px !important;
    width: 16px !important;
    height: 16px !important;
    color: var(--ovo-green-700);
}

.ovo-draft-status-label {
    font-weight: 500;
}

.ovo-draft-status-time {
    color: var(--color-text-primary);
    font-variant-numeric: tabular-nums;
}

.ovo-draft-status-action.mud-button-text {
    min-width: 0;
    padding: 2px 6px;
    height: auto;
    font-size: 12px;
    font-weight: 500;
    text-transform: none;
    line-height: 1;
}

@media (max-width: 600px) {
    .ovo-listing-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .ovo-draft-status {
        margin-top: 0;
    }
}

@media (max-width: 599px) {
    .ovo-price-field .mud-input-slot input { font-size: 1.25rem; }
    .ovo-price-field .mud-input-adornment-start { font-size: 1.0625rem; }
}

/* ---- Add Listing: sticky stepper header + bottom navigation ---- */
/* Keep the step indicator pinned under the app bar while the step content scrolls. */
.ovo-listing-stepper .mud-stepper-nav {
    position: sticky;
    top: var(--mud-appbar-height, 64px);
    z-index: 11;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border-subtle);
    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.04);
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
}

@media (max-width: 599px) {
    .ovo-listing-stepper .mud-stepper-nav {
        top: var(--mud-appbar-height, 56px);
    }

    /* Add Listing on phones (feedback #176): the wizard sat inside THREE stacked
       horizontal gutters - MudContainer (16px) + .mud-stepper-content (24px) + each
       step's .pa-4 paper (16px) = ~112px of side padding on a 375px screen, so the
       form fields were badly cramped. Trim the two structural gutters hard and the
       step papers a little so the inputs get the width back. Phone-only; desktop keeps
       the roomy gutters. */
    .mud-container.ovo-listing-container {
        padding-left: 10px !important;
        padding-right: 10px !important;
    }

    .ovo-listing-stepper .mud-stepper-content {
        padding-left: 8px !important;
        padding-right: 8px !important;
    }

    .ovo-listing-stepper .mud-paper.pa-4 {
        padding-left: 12px !important;
        padding-right: 12px !important;
    }

    .ovo-listing-stepper .mud-paper.pa-6 {
        padding-left: 14px !important;
        padding-right: 14px !important;
    }
}

.listing-nav {
    position: sticky;
    bottom: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 8px 16px;
    margin-top: 16px;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border-subtle);
    box-shadow: 0 -6px 18px rgba(15, 23, 42, 0.06);
    border-bottom-left-radius: 8px;
    border-bottom-right-radius: 8px;
}

.listing-nav-left,
.listing-nav-right {
    display: flex;
    align-items: center;
    gap: 10px;
}

.listing-nav-exit.mud-button-root {
    height: 36px;
    font-weight: 500;
    font-size: 0.875rem;
    text-transform: none;
    letter-spacing: 0;
    color: var(--color-text-secondary);
    padding: 0 10px;
}

.listing-nav-exit.mud-button-root:hover {
    color: var(--color-text-primary);
    background: var(--color-surface-muted);
}

.listing-nav-back.mud-button-root {
    min-width: 96px;
    height: 36px;
    font-weight: 600;
    font-size: 0.875rem;
    text-transform: none;
    letter-spacing: 0;
    color: var(--color-text-secondary);
    border-color: var(--color-border-light);
}

.listing-nav-back.mud-button-root:hover {
    color: var(--color-text-primary);
    background: var(--color-surface-muted);
    border-color: var(--color-border-medium);
}

.listing-nav-next.mud-button-root,
.listing-nav-publish.mud-button-root {
    min-width: 140px;
    height: 36px;
    font-weight: 600;
    font-size: 0.875rem;
    text-transform: none;
    letter-spacing: 0;
    padding: 0 16px;
    box-shadow: 0 2px 8px rgba(47, 93, 80, 0.2);
}

.listing-nav-next.mud-button-root:hover,
.listing-nav-publish.mud-button-root:hover {
    box-shadow: 0 4px 14px rgba(47, 93, 80, 0.32);
}

@media (max-width: 599px) {
    .listing-nav {
        flex-wrap: wrap;
        gap: 8px;
        padding: 8px 10px;
        margin-top: 12px;
    }
    .listing-nav-left {
        order: 2;
        flex: 1 1 100%;
        justify-content: flex-start;
    }
    .listing-nav-right {
        order: 1;
        flex: 1 1 100%;
        justify-content: space-between;
        gap: 8px;
    }
    .listing-nav-exit.mud-button-root {
        padding: 0 8px;
        font-size: 0.8125rem;
    }
    .listing-nav-back.mud-button-root {
        min-width: 0;
        flex: 0 0 auto;
        padding: 0 12px;
    }
    .listing-nav-next.mud-button-root,
    .listing-nav-publish.mud-button-root {
        flex: 1 1 auto;
        min-width: 0;
        padding: 0 12px;
    }
}

/* ---- Add Listing: emphasise the active step in the header ---- */
.ovo-listing-stepper .mud-stepper-nav .mud-step .mud-step-label-icon {
    transition: transform 180ms ease, box-shadow 180ms ease, background-color 180ms ease;
}

.ovo-listing-stepper .mud-stepper-nav .mud-step.active .mud-step-label-icon {
    background-color: var(--ovo-green-700, #2F5D50);
    color: #fff;
    transform: scale(1.18);
    box-shadow: 0 0 0 4px rgba(47, 93, 80, 0.18),
                0 4px 12px rgba(47, 93, 80, 0.28);
}

.ovo-listing-stepper .mud-stepper-nav .mud-step.active .mud-step-label-content-title {
    color: var(--ovo-green-800, #24463C);
    font-weight: 700;
}

.ovo-listing-stepper .mud-stepper-nav .mud-step:not(.active):not(.completed) .mud-step-label-icon {
    opacity: 0.7;
}

/* ---- Admin · Application Settings ---- */
.app-settings-panel {
    overflow: hidden;
    border-radius: 10px;
}

/* Section -> Category sidebar layout. Section headers are accordion-collapsible so
   the nav stays short enough to fit in the viewport without its own scrollbar -
   page scroll is the only scroll, the right pane drives it.
   align-items: start lets the nav size to its content while the right pane grows. */
.app-settings-grid {
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    align-items: start;
}

.app-settings-nav {
    position: sticky;
    top: 16px;
    background: var(--color-surface-muted);
    border-right: 1px solid var(--color-border-subtle);
    padding: 6px 0 8px;
    /* Internal scroll only kicks in if the user expands every section AND the total
       overflows the viewport. By default the nav fits, so no inner scrollbar shows. */
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    align-self: start;
}

/* Section header (accordion). Full-width clickable button. */
.app-settings-section-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 12px;
    background: transparent;
    border: none;
    border-top: 1px solid var(--color-border-subtle);
    cursor: pointer;
    text-align: left;
    color: var(--color-text-primary);
    font-size: 0.8125rem;
}

.app-settings-section-row:first-of-type {
    border-top: none;
}

.app-settings-section-row:hover {
    background: rgba(47, 93, 80, 0.04);
}

.app-settings-section-chevron {
    flex: 0 0 auto;
    color: var(--color-text-secondary);
}

.app-settings-section-icon {
    color: var(--ovo-green-700, #2F5D50);
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
}

.app-settings-section-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-secondary);
}

.app-settings-section-row.expanded .app-settings-section-label {
    color: var(--color-text-primary);
}

.app-settings-section-count {
    flex: 0 0 auto;
    min-width: 22px;
    text-align: center;
    padding: 1px 6px;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.06);
    color: var(--color-text-secondary);
    font-size: 0.7rem;
    font-weight: 600;
}

/* Category buttons render only when their section is expanded. */
.app-settings-cat-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 6px 12px 6px 36px;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    text-align: left;
    cursor: pointer;
    color: var(--color-text-secondary);
    font-size: 0.8125rem;
}

.app-settings-cat-item:hover {
    background: rgba(47, 93, 80, 0.04);
    color: var(--color-text-primary);
}

.app-settings-cat-item.active {
    background: var(--color-surface);
    color: var(--color-text-primary);
    border-left-color: var(--ovo-green-700, #2F5D50);
    font-weight: 600;
}

.app-settings-cat-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-settings-cat-count {
    flex: 0 0 auto;
    min-width: 22px;
    text-align: center;
    padding: 1px 6px;
    border-radius: 10px;
    background: rgba(47, 93, 80, 0.10);
    color: var(--ovo-green-700, #2F5D50);
    font-size: 0.7rem;
    font-weight: 600;
}

.app-settings-cat-item.active .app-settings-cat-count {
    background: var(--ovo-green-700, #2F5D50);
    color: #fff;
}

.app-settings-content {
    padding: 24px 28px;
    min-width: 0;
}

@media (max-width: 960px) {
    .app-settings-grid {
        grid-template-columns: 200px minmax(0, 1fr);
    }
    .app-settings-content { padding: 18px 20px; }
}

@media (max-width: 599px) {
    /* Phone: drop sticky behaviour, stack sidebar above content as a strip. */
    .app-settings-grid {
        grid-template-columns: minmax(0, 1fr);
    }
    .app-settings-nav {
        position: static;
        max-height: 320px;
        border-right: none;
        border-bottom: 1px solid var(--color-border-subtle);
    }
    .app-settings-content { padding: 16px; }
}

/* Ensure the panel area takes the remaining width next to the vertical tab rail
   and that panel children stack vertically (MudBlazor's panels-slider is a flex-row
   by default, which would otherwise lay our setting rows out side-by-side). */
.app-settings-tabs .mud-tabs-panels {
    flex: 1 1 auto;
    min-width: 0;
    width: 100%;
    overflow: hidden;
}

.app-settings-tabs .mud-tabs-panels-slider-wrapper,
.app-settings-tabs .mud-tabs-panels-slider {
    display: block !important;
    width: 100% !important;
    min-width: 0;
}

.app-settings-tabs .mud-tab-panel,
.app-settings-tabs .mud-tabs-panel,
.app-settings-tabpanel {
    display: block !important;
    width: 100% !important;
    min-width: 0;
    flex: 0 0 auto;
}

/* Vertical tab rail - keep the category list scannable and give each label room. */
.app-settings-tabs .mud-tabs-tabbar {
    flex: 0 0 220px;
    min-width: 220px;
    max-width: 220px;
    background: var(--color-surface-muted);
    border-right: 1px solid var(--color-border-subtle);
}

.app-settings-tabs .mud-tab {
    justify-content: flex-start;
    text-align: left;
    padding: 0 16px;
    min-height: 44px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--color-text-secondary);
    border-left: 3px solid transparent;
}

.app-settings-tabs .mud-tab.mud-tab-active {
    color: var(--color-text-primary);
    background: var(--color-surface);
    border-left-color: var(--ovo-green-700, #2F5D50);
    font-weight: 600;
}

.app-settings-tabs .mud-tab:hover {
    background: rgba(47, 93, 80, 0.04);
}

.app-settings-tabs .mud-tab .mud-icon-root {
    margin-right: 10px;
    font-size: 1.125rem;
}

/* Panel header: category title + match summary */
.app-settings-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 12px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--color-border-subtle);
}

/* Sub-section heading inside a crowded category (e.g. Off-Grid > Weight/Tier/Range) */
.app-settings-subhead {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 22px 0 10px;
}

.app-settings-subhead-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.app-settings-subhead-rule {
    flex: 1 1 auto;
    height: 1px;
    background: var(--color-border-subtle);
}

/* Each setting row: meta (text) | editor | save button */
.app-settings-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 320px) auto;
    align-items: start;
    gap: 18px;
    padding: 14px 0;
    border-bottom: 1px dashed var(--color-border-subtle);
}

.app-settings-row:last-child {
    border-bottom: none;
}

.app-settings-meta {
    min-width: 0;
}

.app-settings-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 2px;
}

.app-settings-display {
    font-weight: 600;
    color: var(--color-text-primary);
}

.app-settings-typechip.mud-chip {
    height: 20px;
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: lowercase;
}

.app-settings-key {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
    word-break: break-all;
}

.app-settings-desc {
    margin-top: 4px;
    font-size: 0.875rem;
    color: var(--color-text-secondary);
    line-height: 1.45;
}

.app-settings-updated {
    margin-top: 6px;
    font-size: 0.72rem;
    color: var(--color-text-secondary);
    opacity: 0.8;
}

.app-settings-editor {
    min-width: 0;
    display: flex;
    align-items: center;
}

.app-settings-editor .mud-input-control,
.app-settings-editor .mud-picker {
    width: 100%;
}

.app-settings-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-top: 2px;
}

/* Tablet: stack editor under meta, keep save button right-aligned below */
@media (max-width: 960px) {
    .app-settings-tabs .mud-tabs-tabbar {
        min-width: 180px;
    }
    .app-settings-row {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "meta meta"
            "editor actions";
        gap: 12px;
    }
    .app-settings-meta  { grid-area: meta; }
    .app-settings-editor { grid-area: editor; }
    .app-settings-actions { grid-area: actions; }
}

/* Phone: flatten to single column, drop the vertical rail down to a scrollable strip */
@media (max-width: 599px) {
    .app-settings-tabs {
        flex-direction: column;
    }
    .app-settings-tabs .mud-tabs-tabbar {
        min-width: 0;
        width: 100%;
        border-right: none;
        border-bottom: 1px solid var(--color-border-subtle);
    }
    .app-settings-tabs .mud-tab {
        border-left: none;
        border-bottom: 3px solid transparent;
    }
    .app-settings-tabs .mud-tab.mud-tab-active {
        border-bottom-color: var(--ovo-green-700, #2F5D50);
        border-left-color: transparent;
    }
    .app-settings-row {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "meta"
            "editor"
            "actions";
    }
    .app-settings-actions {
        justify-content: flex-start;
    }
}

/* ===== Property context panel (nearby POIs / solar) ===== */
.property-context-panel {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    padding: 20px;
    margin: 24px 0;
}
.property-context-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}
.property-context-title {
    font-family: var(--font-display);
    font-size: 1.35rem;
    margin: 0;
    color: var(--color-text-primary);
}
.property-context-subtle {
    font-size: 0.85rem;
    color: var(--color-text-muted);
}
.property-context-skeleton {
    padding: 8px 0;
}
.property-context-categories {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 14px;
}
.property-context-chip {
    appearance: none;
    border: 1px solid var(--color-border);
    background: var(--color-surface-alt, #fff);
    color: var(--color-text-primary);
    padding: 6px 14px;
    border-radius: 999px;
    font-size: 0.9rem;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.property-context-chip:hover {
    border-color: var(--ovo-green-700, #2F5D50);
}
.property-context-chip.is-active {
    background: var(--ovo-green-700, #2F5D50);
    border-color: var(--ovo-green-700, #2F5D50);
    color: #fff;
}
.property-context-chip-count {
    background: rgba(0, 0, 0, 0.08);
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 0.75rem;
}
.property-context-chip.is-active .property-context-chip-count {
    background: rgba(255, 255, 255, 0.22);
}
.property-context-list {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--color-border);
}
.property-context-row {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 10px 4px;
    border-bottom: 1px solid var(--color-border);
}
.property-context-row-icon {
    width: 24px;
    height: 24px;
    border-radius: 6px;
    background-color: var(--ovo-green-50, #E8F1EE);
    background-position: center;
    background-repeat: no-repeat;
    background-size: 16px 16px;
}
.property-context-row-logo {
    width: 24px;
    height: 24px;
    border-radius: 6px;
    object-fit: contain;
    background: #fff;
    border: 1px solid var(--color-border);
    padding: 2px;
}
.property-context-row-phone {
    margin-left: 8px;
    font-size: 0.85rem;
    color: var(--ovo-green-700, #2F5D50);
    text-decoration: none;
    white-space: nowrap;
}
.property-context-row-phone:hover { text-decoration: underline; }
.property-context-row-name {
    color: var(--color-text-primary);
    font-size: 0.95rem;
}
.property-context-row-brand {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}
.property-context-row-distance {
    color: var(--color-text-secondary);
    font-size: 0.85rem;
    white-space: nowrap;
}
/* Per-category icon hooks - point at the existing brand icon SVGs if present, else
   leave the green tile as a recognisable placeholder. */
.property-context-icon-school        { background-image: url('/images/icons/categories/school.svg'); }
.property-context-icon-hospital      { background-image: url('/images/icons/categories/hospital.svg'); }
.property-context-icon-supermarket   { background-image: url('/images/icons/categories/shopping.svg'); }
.property-context-icon-fuel          { background-image: url('/images/icons/categories/fuel.svg'); }
.property-context-icon-police        { background-image: url('/images/icons/categories/police.svg'); }
.property-context-icon-park          { background-image: url('/images/icons/categories/park.svg'); }
.property-context-icon-placeofworship { background-image: url('/images/icons/categories/worship.svg'); }
.property-context-icon-bank          { background-image: url('/images/icons/categories/bank.svg'); }

.property-context-solar {
    margin-top: 16px;
    padding: 12px;
    background: var(--ovo-green-50, #E8F1EE);
    border-radius: 10px;
    display: flex;
    align-items: center;
    gap: 12px;
}
.property-context-solar-icon {
    width: 36px;
    height: 36px;
    border-radius: 8px;
    background: var(--ovo-green-700, #2F5D50);
    flex: 0 0 auto;
}
.property-context-solar-headline {
    font-weight: 600;
    color: var(--color-text-primary);
}
.property-context-solar-sub {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
}

/* Mobile: chip strip stays scrollable, panel padding shrinks. */
@media (max-width: 640px) {
    .property-context-panel {
        padding: 14px;
        margin: 16px 0;
    }
    .property-context-categories {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        margin-left: -14px;
        margin-right: -14px;
        padding: 0 14px 4px;
    }
    .property-context-chip {
        flex: 0 0 auto;
    }
}

/* ===== POI overlay markers on Google base map =====
   Google "place chip" style: white-filled circle with a coloured ring, bold coloured
   letter inside, small triangular tail anchoring the location. The SVG inside .poi-dot
   carries fill / stroke / shadow; the wrapper just sizes + positions and applies a hover
   transform. Anchored at bottom-centre so the tail tip touches the geographic point. */
.poi-dot {
    width: 28px;
    height: 34px;
    cursor: pointer;
    display: inline-block;
    line-height: 0;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
    transform-origin: 50% 100%;
    transition: transform 0.1s ease-out;
}
.poi-dot:hover {
    transform: scale(1.12);
    z-index: 5;
}
.poi-dot svg {
    pointer-events: none;
    display: block;
}

/* ===== POI InfoWindow card =====
   Mirrors Google Maps' own POI overlay layout: compact header with logo + name +
   category subtitle, action rows for phone/website/hours, primary CTA at the
   bottom (Directions). Google wraps the content in .gm-style-iw; we tune that
   wrapper at the bottom of this block so it has rounder corners and softer
   shadow than the default. */
.poi-info {
    font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    color: var(--color-text-primary);
    width: 280px;
    padding: 0;
    line-height: 1.4;
}
.poi-info-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 4px 4px 12px;
}
/* Inline close button that sits to the right of the title row, replacing Google's
   default header (suppressed via headerDisabled: true on the InfoWindow). */
.poi-info-close {
    appearance: none;
    background: transparent;
    border: 0;
    padding: 4px;
    margin: -2px -2px 0 0;
    color: var(--color-text-muted);
    cursor: pointer;
    border-radius: 6px;
    line-height: 0;
    flex: 0 0 auto;
    transition: background 0.12s ease, color 0.12s ease;
}
.poi-info-close:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--color-text-primary);
}
.poi-info-close svg { display: block; }
.poi-info-logo {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    overflow: hidden;
    background: #F1F3F4;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
}
.poi-info-logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #FFFFFF;
    padding: 4px;
}
.poi-info-initials {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #FFFFFF;
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: 0.01em;
}
/* Initials-tile palette = Google-native POI palette so a category reads as the
   same colour everywhere (map dot, InfoWindow logo, list-row logo fallback). */
.poi-info-logo-school      { background: #0F9D58; }
.poi-info-logo-hospital    { background: #EA4335; }
.poi-info-logo-supermarket { background: #4285F4; }
.poi-info-logo-fuel        { background: #F09300; }
.poi-info-logo-police      { background: #1F3A5F; }
.poi-info-logo-park        { background: #0F9D58; }
.poi-info-logo-worship     { background: #7B8794; }
.poi-info-logo-bank        { background: #F2A100; }

.poi-info-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.poi-info-name {
    margin: 0;
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.25;
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.poi-info-subtitle {
    margin: 0;
    font-size: 0.82rem;
    color: var(--color-text-secondary);
    line-height: 1.3;
}

/* Action rows */
.poi-info-meta {
    list-style: none;
    margin: 0;
    padding: 10px 4px;
    border-top: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.poi-info-meta li { margin: 0; padding: 0; }
.poi-info-row {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.85rem;
    color: var(--color-text-primary);
    line-height: 1.3;
    word-break: break-word;
}
.poi-info-row svg {
    flex: 0 0 auto;
    color: var(--color-text-muted);
}
.poi-info-row-link {
    color: var(--color-text-primary);
    text-decoration: none;
}
.poi-info-row-link:hover {
    color: var(--ovo-green-700, #2F5D50);
}
.poi-info-row-link:hover svg {
    color: var(--ovo-green-700, #2F5D50);
}

/* Primary CTA */
.poi-info-foot {
    padding: 10px 4px 4px;
    border-top: 1px solid var(--color-border);
    display: flex;
    justify-content: flex-end;
}
.poi-info-action {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--ovo-green-700, #2F5D50);
    text-decoration: none;
    padding: 6px 10px;
    border-radius: 6px;
    transition: background 0.12s ease;
}
.poi-info-action:hover {
    background: rgba(47, 93, 80, 0.08);
}
.poi-info-action svg { flex: 0 0 auto; }

/* Tone down Google's InfoWindow chrome: rounder corners, softer shadow. The
   selectors only apply when our content is inside a Google InfoWindow. */
.gm-style-iw.gm-style-iw-c {
    border-radius: 12px !important;
    padding: 14px 14px 12px !important;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18) !important;
    max-height: none !important;
    /* background: Google injects the InfoWindow chrome background ONCE per session; when the
       map is torn down and rebuilt (enhanced-nav away and back) that injected style is gone and
       NOT re-added, so the popup bubble renders fully transparent ("transparent border", first
       open fine, broken only after returning to the map). We restore it here - our CSS is in the
       static <head> and is always present. Verified: forcing this flips a rebuilt-map popup from
       rgba(0,0,0,0) back to solid white. */
    background: #ffffff !important;
}
/* The little pointer/tail under the bubble loses its white the same way - restore it too. */
.gm-style .gm-style-iw-tc::after { background: #ffffff !important; }
/* max-height: none is the important bit. Google sets an INLINE max-height on the
   InfoWindow content box sized to the space it thinks is free above the anchor. After
   an enhanced-nav map rebuild (/search -> calculator -> back) that value comes back too
   small, and because we force overflow:hidden the card gets clipped at the BOTTOM with
   the bare (transparent) chrome showing through - the "cut off at the bottom + transparent
   border" popup. Our card is a fixed, self-contained size, so lift the clamp and let the
   box size to the card; the card never needs to scroll. */
.gm-style-iw-d { overflow: hidden !important; padding: 0 !important; max-height: none !important; }

.search-map-poi-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 8px 0;
    flex-shrink: 0; /* never let this steal height from the map below it */
}
.search-map-poi-toolbar .property-context-chip {
    padding: 4px 12px;
    font-size: 0.85rem;
}

/* ── Dual-thumb price range slider (PropertySearchFilters) ───────────────────
   Two native range inputs overlaid on one track. Inputs are pointer-transparent
   so only the thumbs are grabbable; the min input sits on top so its thumb
   stays reachable when the two thumbs are close. */
.price-range {
    position: relative;
    height: 36px;
    width: 100%;
}
.price-range__track,
.price-range__fill {
    position: absolute;
    top: 50%;
    height: 4px;
    transform: translateY(-50%);
    border-radius: 2px;
    pointer-events: none;
}
.price-range__track {
    left: 0;
    right: 0;
    background: var(--color-border-medium);
}
.price-range__fill {
    background: var(--color-primary);
}
.price-range__input {
    -webkit-appearance: none;
    appearance: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 36px;
    margin: 0;
    background: none;
    pointer-events: none; /* track ignores clicks; thumbs re-enable below */
}
.price-range__input--min { z-index: 4; }
.price-range__input--max { z-index: 3; }
.price-range__input::-webkit-slider-runnable-track,
.price-range__input::-moz-range-track {
    background: transparent;
    height: 4px;
    border: none;
}
.price-range__input::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    pointer-events: auto;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background: var(--color-primary);
    border: 2px solid #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
    cursor: pointer;
}
.price-range__input::-moz-range-thumb {
    pointer-events: auto;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background: var(--color-primary);
    border: 2px solid #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
    cursor: pointer;
}
.price-range__input:focus-visible::-webkit-slider-thumb {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* ── QA tester overlay (TesterOverlay.razor) ───────────────────────────── */
.ovo-tester-launcher {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 1300;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;
}
.ovo-tester-launcher .ovo-tester-fab,
.ovo-tester-launcher .ovo-tester-fab-secondary {
    pointer-events: auto;
    box-shadow: 0 4px 12px rgba(30, 63, 54, 0.3);
}
/* Only the OUTLINED "view all" button gets a solid surface circle so its coloured
   icon reads on any page. Filled buttons keep their own coloured background (a white
   background here would hide the white filled-variant icon). */
.ovo-tester-launcher .ovo-tester-fab-outlined {
    background: var(--color-surface, #fff) !important;
}
.ovo-tester-launcher .ovo-tester-fab:hover {
    box-shadow: 0 6px 18px rgba(30, 63, 54, 0.4);
}
/* Small "N on this page" badge on the launcher */
.ovo-tester-launcher .ovo-tester-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    background: var(--mud-palette-warning, #ed6c02);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
    pointer-events: none;
}

.ovo-tester-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 400px;
    max-width: 92vw;
    z-index: 1310;
    background: var(--color-surface, #fff);
    border-left: 1px solid var(--color-border, #e0e0e0);
    box-shadow: -4px 0 24px rgba(0, 0, 0, 0.18);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.ovo-tester-panel-header {
    padding: 14px 16px;
    border-bottom: 1px solid var(--color-border, #e0e0e0);
    background: var(--color-surface-muted, #f6f9f7);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.ovo-tester-panel-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 12px 14px;
}
.ovo-tester-case {
    border: 1px solid var(--color-border, #e0e0e0);
    border-radius: 8px;
    padding: 10px 12px;
    margin-bottom: 10px;
    background: var(--color-surface, #fff);
}
.ovo-tester-case-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
}
.ovo-tester-case-code {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--color-text-secondary, #5f6f69);
}

/* "Find on page" highlight flashed on the element a tester case targets */
.ovo-tester-highlight {
    outline: 3px solid var(--mud-palette-warning, #ed6c02) !important;
    outline-offset: 2px;
    background-color: rgba(237, 108, 2, 0.12) !important;
    border-radius: 4px;
    scroll-margin: 120px;
    animation: ovoTesterPulse 0.7s ease-in-out 0s 3;
    position: relative;
    z-index: 1;
}
@keyframes ovoTesterPulse {
    0%, 100% { box-shadow: 0 0 0 4px rgba(237, 108, 2, 0.25); }
    50%      { box-shadow: 0 0 0 10px rgba(237, 108, 2, 0.45); }
}

/* Full-page fallback flash when a specific control can't be pinpointed */
.ovo-tester-highlight-page {
    animation: ovoTesterPageFlash 0.8s ease-in-out 0s 3;
    outline: 4px solid rgba(237, 108, 2, 0.5);
    outline-offset: -4px;
    border-radius: 6px;
}
@keyframes ovoTesterPageFlash {
    0%, 100% { background-color: transparent; }
    50%      { background-color: rgba(237, 108, 2, 0.10); }
}

/* "Currently testing" pinned card at the top of the overlay panel (survives navigation) */
.ovo-tester-pinned {
    border-bottom: 1px solid var(--color-border, #e0e0e0);
    background: var(--color-surface-subtle, #fff7ef);
    padding: 8px 12px 10px;
}
.ovo-tester-pinned-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--mud-palette-warning, #ed6c02);
    margin-bottom: 4px;
}


/* Authenticator (2FA) setup QR code - server-rendered inline SVG on
   /Account/Manage/EnableAuthenticator. The SVG carries a viewBox and no width/height,
   so the size is controlled here. White plate is deliberate: the QR must stay
   black-on-white to scan, whatever the surrounding surface. */
.authenticator-qr {
    width: 100%;
    max-width: 220px;
    margin: 0 0 1rem;
    padding: 8px;
    background: #ffffff;
    border: 1px solid var(--color-border, #e0e0e0);
    border-radius: 8px;
}
.authenticator-qr svg {
    display: block;
    width: 100%;
    height: auto;
}
