/* ============================================================
   HYPER-LOCALISATION — hyper-location.css
   ------------------------------------------------------------
   Visual layer for the AI Hyper-Localisation feature. Three zones:

     1. The FAB pin's ACTIVE state — turns the existing green-line
        SVG into a glowing, breathing "live" indicator. The user's
        eye is drawn back to the left rail every time they enter
        the page, so they always know the feature is engaged.

     2. The modal's premium redesign — orange/blue gradient hero,
        privacy reassurance row, and an entirely separate "active"
        body that swaps in when location is already on (showing
        current suburb + Turn off / Refresh actions).

     3. The chip styling for the GPS-resolved location inside the
        search bar — a subtle pin icon prefix + a faint pulse so
        it reads as "this one came from GPS, not from typing".

   All colours map to the Ikhayalami brand tokens:
     --ikh-orange  #F58220
     --ikh-blue    #1E90FF (approx — used for premium gradients)
     --ikh-green   #22C55E (used for location/safety/positive states)
   ============================================================ */

/* ===========================================================
   1. FAB ACTIVE STATE
   ----------------------------------------------------------- */

/* The base SVG strokes are already #22c55e (green). When ACTIVE
   we layer a deeper saturation, a radial halo, and a slow breath
   so the icon reads as "live". We avoid moving the icon (zero
   transform) because the FAB stack already has hover transforms;
   stacking them would jitter on hover. */

.engagement-btn.loc-btn.hl-active {
    border-color: rgba(34, 197, 94, 0.6) !important;
    background: radial-gradient(circle at 50% 45%, rgba(34, 197, 94, 0.18) 0%, rgba(34, 197, 94, 0.06) 45%, rgba(255, 255, 255, 1) 85%) !important;
    box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.35), 0 8px 28px rgba(34, 197, 94, 0.32), inset 0 1px 0 rgba(255, 255, 255, 1) !important;
    animation: hl-fab-breath 3.6s ease-in-out infinite;
}

@keyframes hl-fab-breath {
    0%, 100% {
        box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.35), 0 8px 28px rgba(34, 197, 94, 0.32), inset 0 1px 0 rgba(255, 255, 255, 1);
    }

    50% {
        box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.55), 0 10px 36px rgba(34, 197, 94, 0.48), inset 0 1px 0 rgba(255, 255, 255, 1);
    }
}

/* Tiny "live" dot in the top-right corner of the FAB — like the
   notification bell does. Pure CSS, no DOM changes needed. */
.engagement-btn.loc-btn.hl-active::after {
    content: '';
    position: absolute;
    top: 6px;
    right: 6px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #22c55e;
    border: 2px solid #fff;
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);
    animation: hl-live-dot 2s ease-out infinite;
    pointer-events: none;
}

@keyframes hl-live-dot {
    0% {
        box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);
    }

    70% {
        box-shadow: 0 0 0 10px rgba(34, 197, 94, 0);
    }

    100% {
        box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
    }
}

/* When the SVG's scan beam is inside an active FAB, speed it up
   slightly so the icon reads as actively transmitting. */
.engagement-btn.loc-btn.hl-active .fab-loc-scan {
    animation-duration: 1.8s !important;
    opacity: 0.95 !important;
}

/* Loading state — applied during the geolocation prompt. The
   icon dims and we rotate the inner crosshair to suggest "looking". */
.engagement-btn.loc-btn.hl-loading {
    pointer-events: none;
    opacity: 0.7;
}

    .engagement-btn.loc-btn.hl-loading .fab-icon-svg {
        animation: hl-fab-seeking 1.2s linear infinite;
    }

@keyframes hl-fab-seeking {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}

/* ===========================================================
   2. THE MODAL — premium redesign
   ----------------------------------------------------------- */

/* Lift the modal content a tier above the default Bootstrap card.
   We're keeping the .glass-modal frame the site already uses but
   swapping the body for our own hierarchy. */

#locationModal .modal-content {
    border-radius: 24px;
    overflow: hidden;
    background: linear-gradient(180deg, #ffffff 0%, #fafbfc 100%);
}

/* The hero block — gradient orange tile with a soft sweep that
   echoes the AI scan beams across the rest of the site. */
#locationModal .hl-hero {
    position: relative;
    padding: 32px 32px 28px;
    text-align: center;
    background: radial-gradient(circle at 50% 0%, rgba(245, 130, 32, 0.10) 0%, rgba(245, 130, 32, 0.00) 60%), linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(250, 251, 252, 1) 100%);
    overflow: hidden;
}

    /* A faint horizontal scan beam across the hero — picks up the
   same "AI scanning" motif as the search bar's Describe-It icon. */
    #locationModal .hl-hero::before {
        content: '';
        position: absolute;
        top: 50%;
        left: -10%;
        width: 120%;
        height: 1px;
        background: linear-gradient(90deg, transparent 0%, rgba(245, 130, 32, 0.0) 30%, rgba(245, 130, 32, 0.35) 50%, rgba(245, 130, 32, 0.0) 70%, transparent 100%);
        animation: hl-hero-scan 4s ease-in-out infinite;
        pointer-events: none;
    }

@keyframes hl-hero-scan {
    0%, 100% {
        transform: translateY(-40px);
        opacity: 0.4;
    }

    50% {
        transform: translateY(40px);
        opacity: 0.9;
    }
}

/* The hero pin icon container */
#locationModal .hl-hero-icon {
    width: 84px;
    height: 84px;
    margin: 0 auto 18px;
    border-radius: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #F58220 0%, #FF9A3C 100%);
    box-shadow: 0 10px 28px rgba(245, 130, 32, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.35);
    position: relative;
}

    #locationModal .hl-hero-icon::after {
        content: '';
        position: absolute;
        inset: -6px;
        border-radius: 28px;
        border: 1px solid rgba(245, 130, 32, 0.25);
        animation: hl-hero-ring 3s ease-out infinite;
        pointer-events: none;
    }

@keyframes hl-hero-ring {
    0% {
        transform: scale(0.92);
        opacity: 0.8;
    }

    100% {
        transform: scale(1.18);
        opacity: 0;
    }
}

#locationModal .hl-hero-icon i {
    color: #fff;
    font-size: 2.4rem;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15));
}

/* Title + sub */
#locationModal .hl-title {
    font-weight: 800;
    font-size: 1.4rem;
    color: #1A1A1F;
    margin: 0 0 6px;
    letter-spacing: -0.01em;
}

#locationModal .hl-sub {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #F58220;
    font-weight: 600;
    margin: 0 0 16px;
}

#locationModal .hl-copy {
    font-size: 0.92rem;
    line-height: 1.55;
    color: #4A4A55;
    margin: 0 auto 0;
    max-width: 380px;
}

/* The benefits row — three pill chips that show the user what
   the feature actually does, no more "load-shedding" copy. */
#locationModal .hl-benefits {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: center;
    padding: 18px 28px 4px;
    background: #fff;
}

#locationModal .hl-benefit {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 999px;
    background: rgba(245, 130, 32, 0.07);
    border: 1px solid rgba(245, 130, 32, 0.15);
    font-size: 0.78rem;
    color: #5A4030;
    font-weight: 500;
    white-space: nowrap;
}

    #locationModal .hl-benefit i {
        color: #F58220;
        font-size: 0.85rem;
    }

/* Privacy reassurance strip */
#locationModal .hl-privacy {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 14px 24px;
    margin: 14px 24px 0;
    border-radius: 14px;
    background: rgba(34, 197, 94, 0.06);
    border: 1px solid rgba(34, 197, 94, 0.18);
}

    #locationModal .hl-privacy i {
        color: #22c55e;
        font-size: 1rem;
        flex-shrink: 0;
        margin-top: 2px;
    }

#locationModal .hl-privacy-text {
    font-size: 0.78rem;
    color: #2D3D32;
    line-height: 1.45;
    margin: 0;
}

    #locationModal .hl-privacy-text strong {
        color: #1A4A28;
        font-weight: 600;
    }

/* CTA row */
#locationModal .hl-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 20px 24px 24px;
}

@media (min-width: 480px) {
    #locationModal .hl-actions {
        flex-direction: row-reverse; /* Primary on the right */
        justify-content: space-between;
    }
}

#locationModal .hl-allow-btn {
    background: linear-gradient(135deg, #F58220 0%, #FF9A3C 100%);
    border: 0;
    border-radius: 999px;
    padding: 13px 28px;
    color: #fff;
    font-weight: 600;
    font-size: 0.95rem;
    box-shadow: 0 6px 18px rgba(245, 130, 32, 0.35);
    flex: 1;
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

    #locationModal .hl-allow-btn:hover {
        transform: translateY(-1px);
        box-shadow: 0 8px 22px rgba(245, 130, 32, 0.45);
        filter: brightness(1.05);
    }

#locationModal .hl-notnow-btn {
    background: transparent;
    border: 1px solid #E2E2E7;
    border-radius: 999px;
    padding: 13px 24px;
    color: #6A6A75;
    font-weight: 500;
    font-size: 0.95rem;
    flex: 0 0 auto;
    transition: background 0.15s ease, border-color 0.15s ease;
}

    #locationModal .hl-notnow-btn:hover {
        background: #F5F5F7;
        border-color: #D2D2D7;
    }

/* ─── BODY VISIBILITY SWITCH ─────────────────────────────────
   Three mutually-exclusive bodies live inside the modal:
     1. CONSENT  — visible by default (no class on #locationModal)
     2. CONFIRM  — visible when #locationModal has .hl-modal-confirm
     3. ACTIVE   — visible when #locationModal has .hl-modal-active
   hyper-location.js toggles exactly one of those classes at a time. */

#locationModal .hl-confirm-body,
#locationModal .hl-active-body {
    display: none;
}

#locationModal.hl-modal-confirm .hl-consent-body,
#locationModal.hl-modal-confirm .hl-active-body {
    display: none;
}

#locationModal.hl-modal-confirm .hl-confirm-body {
    display: block;
}

#locationModal.hl-modal-active .hl-consent-body,
#locationModal.hl-modal-active .hl-confirm-body {
    display: none;
}

#locationModal.hl-modal-active .hl-active-body {
    display: block;
}

#locationModal .hl-active-hero {
    padding: 28px 32px 22px;
    text-align: center;
    background: radial-gradient(circle at 50% 0%, rgba(34, 197, 94, 0.12) 0%, rgba(34, 197, 94, 0.00) 65%), linear-gradient(180deg, #fff 0%, #fafbfc 100%);
}

#locationModal .hl-active-icon {
    width: 72px;
    height: 72px;
    margin: 0 auto 14px;
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #16A34A 0%, #22C55E 100%);
    box-shadow: 0 10px 24px rgba(34, 197, 94, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

    #locationModal .hl-active-icon i {
        color: #fff;
        font-size: 2rem;
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.12));
    }

#locationModal .hl-active-status {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: #22C55E;
    font-weight: 700;
    margin: 0 0 6px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

    #locationModal .hl-active-status::before {
        content: '';
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: #22C55E;
        box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);
        animation: hl-live-dot 2s ease-out infinite;
    }

#locationModal .hl-active-place {
    font-weight: 800;
    font-size: 1.5rem;
    color: #1A1A1F;
    margin: 0;
    letter-spacing: -0.01em;
}

#locationModal .hl-active-meta {
    color: #6A6A75;
    font-size: 0.8rem;
    margin-top: 4px;
}

#locationModal .hl-active-actions {
    display: flex;
    gap: 10px;
    padding: 18px 24px 24px;
}

#locationModal .hl-refresh-btn {
    flex: 0 0 auto;
    background: #fff;
    border: 1px solid #E2E2E7;
    border-radius: 999px;
    padding: 12px 18px;
    color: #4A4A55;
    font-weight: 500;
    font-size: 0.9rem;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    transition: background 0.15s ease, border-color 0.15s ease;
}

    #locationModal .hl-refresh-btn:hover {
        background: #F5F5F7;
        border-color: #D2D2D7;
    }

    #locationModal .hl-refresh-btn.is-spinning i {
        animation: hl-fab-seeking 1s linear infinite;
    }

#locationModal .hl-disable-btn {
    flex: 1;
    background: #fff;
    border: 1px solid rgba(239, 68, 68, 0.3);
    border-radius: 999px;
    padding: 12px 22px;
    color: #EF4444;
    font-weight: 600;
    font-size: 0.9rem;
    transition: background 0.15s ease, border-color 0.15s ease;
}

    #locationModal .hl-disable-btn:hover {
        background: rgba(239, 68, 68, 0.07);
        border-color: rgba(239, 68, 68, 0.5);
    }

/* ===========================================================
   3. CHIP STYLING — the GPS-sourced location chip
   -----------------------------------------------------------
   places.js renders chips with .lcr-chip. When ours is added
   we mark it via the JS adding .lcr-chip--gps when isHyperLocal
   is true — but we ALSO target [data-hyperlocal] for future-
   proofing in case places.js renders from a property. */

.lcr-chip--gps,
.lcr-chip[data-hyperlocal="true"] {
    background: linear-gradient(135deg, rgba(34, 197, 94, 0.10) 0%, rgba(34, 197, 94, 0.04) 100%) !important;
    border-color: rgba(34, 197, 94, 0.35) !important;
    position: relative;
}

    .lcr-chip--gps .lcr-chip-geo,
    .lcr-chip[data-hyperlocal="true"] .lcr-chip-geo {
        color: #22C55E !important;
        animation: hl-chip-pulse 2.6s ease-in-out infinite;
    }

@keyframes hl-chip-pulse {
    0%, 100% {
        transform: scale(1);
        opacity: 1;
    }

    50% {
        transform: scale(1.15);
        opacity: 0.7;
    }
}

/* ===========================================================
   4. Mobile tweaks
   ----------------------------------------------------------- */

@media (max-width: 480px) {
    #locationModal .hl-hero {
        padding: 24px 20px 22px;
    }

    #locationModal .hl-title {
        font-size: 1.2rem;
    }

    #locationModal .hl-copy {
        font-size: 0.88rem;
    }

    #locationModal .hl-benefits {
        padding: 14px 18px 0;
    }

    #locationModal .hl-privacy {
        margin: 12px 18px 0;
        padding: 12px 16px;
    }

    #locationModal .hl-actions {
        padding: 16px 18px 20px;
    }

    #locationModal .hl-active-hero {
        padding: 22px 20px 18px;
    }

    #locationModal .hl-active-actions {
        padding: 16px 18px 20px;
    }
}

/* ===========================================================
   5. Toasts — match analytics.js + cookies.js convention
   -----------------------------------------------------------
   Defined here too so hyper-location.js works even if the
   analytics module hasn't loaded its toast CSS yet. */

.ikb-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translate(-50%, 24px);
    background: #1A1A1F;
    color: #fff;
    padding: 12px 22px;
    border-radius: 999px;
    font-size: 0.88rem;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
    opacity: 0;
    transition: opacity 0.35s ease, transform 0.35s ease;
    z-index: 10050;
    max-width: 90vw;
    text-align: center;
    pointer-events: none;
}

.ikb-toast-show {
    opacity: 1;
    transform: translate(-50%, 0);
}

.ikb-toast-success {
    background: linear-gradient(135deg, #16A34A 0%, #22C55E 100%);
}

.ikb-toast-info {
    background: linear-gradient(135deg, #1A1A1F 0%, #2C2C36 100%);
}

.ikb-toast-warn {
    background: linear-gradient(135deg, #B45309 0%, #F58220 100%);
}

/* ===========================================================
   6. CONFIRM BODY — premium "confirm or correct" UI
   -----------------------------------------------------------
   The new step between consent and active. Shows the AI's
   resolved suburb as a pre-selected primary, plus 4 nearby
   alternatives ranked by distance. Tapping any option flips
   the selection; tapping "Confirm" commits.
   =========================================================== */

#locationModal .hl-confirm-hero {
    position: relative;
    padding: 26px 28px 18px;
    text-align: center;
    background: radial-gradient(circle at 50% 0%, rgba(86, 196, 248, 0.10) 0%, rgba(86, 196, 248, 0.00) 60%), linear-gradient(180deg, #fff 0%, #fafbfc 100%);
    overflow: hidden;
}

#locationModal .hl-confirm-icon {
    width: 72px;
    height: 72px;
    margin: 0 auto 14px;
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #56C4F8 0%, #1E90FF 100%);
    box-shadow: 0 10px 24px rgba(30, 144, 255, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.35);
    position: relative;
}

    #locationModal .hl-confirm-icon i {
        color: #fff;
        font-size: 2rem;
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.12));
        position: relative;
        z-index: 1;
    }

/* Pulsing ring — emphasises "this is the AI's reading" */
#locationModal .hl-confirm-ring {
    position: absolute;
    inset: -7px;
    border-radius: 26px;
    border: 1px solid rgba(30, 144, 255, 0.30);
    animation: hl-confirm-ring-pulse 2.6s ease-out infinite;
    pointer-events: none;
}

@keyframes hl-confirm-ring-pulse {
    0% {
        transform: scale(0.92);
        opacity: 0.85;
    }

    100% {
        transform: scale(1.18);
        opacity: 0;
    }
}

#locationModal .hl-confirm-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: #1E90FF;
    font-weight: 700;
    margin: 0 0 6px;
}

    #locationModal .hl-confirm-status i {
        font-size: 0.78rem;
    }

#locationModal .hl-confirm-title {
    font-weight: 800;
    font-size: 1.4rem;
    color: #1A1A1F;
    margin: 0 0 6px;
    letter-spacing: -0.01em;
}

#locationModal .hl-confirm-sub {
    font-size: 0.86rem;
    color: #5A5A65;
    line-height: 1.5;
    margin: 0 auto;
    max-width: 380px;
}

/* ── Section labels (AI pick / Nearby) ────────────────── */

#locationModal .hl-confirm-section {
    padding: 14px 22px 4px;
}

    #locationModal .hl-confirm-section:nth-child(2) {
        padding-top: 18px; /* breathing room around "AI pick" first section */
    }

#locationModal .hl-confirm-section-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.10em;
    color: #8A8A95;
    font-weight: 700;
    margin: 0 4px 8px;
}

    #locationModal .hl-confirm-section-label i {
        color: #F58220;
        font-size: 0.85rem;
    }

#locationModal .hl-confirm-options {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ── Option button — base ───────────────────────────────
   Used by both the AI pick card and each nearby alt. */

#locationModal .hl-option {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 12px 14px;
    border-radius: 14px;
    background: #fff;
    border: 1.5px solid #E8E8EE;
    cursor: pointer;
    text-align: left;
    transition: border-color 0.18s ease, background 0.18s ease, transform 0.12s ease, box-shadow 0.18s ease;
    font: inherit;
}

    #locationModal .hl-option:hover {
        border-color: #C6D8FF;
        background: #FAFBFF;
        transform: translateY(-1px);
    }

    #locationModal .hl-option:active {
        transform: translateY(0);
    }

#locationModal .hl-option-tick {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid #D2D2D7;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.18s ease, border-color 0.18s ease;
    background: #fff;
}

    #locationModal .hl-option-tick i {
        color: #fff;
        font-size: 0.85rem;
        opacity: 0;
        transition: opacity 0.18s ease;
    }

#locationModal .hl-option-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

#locationModal .hl-option-name {
    font-weight: 700;
    font-size: 0.95rem;
    color: #1A1A1F;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#locationModal .hl-option-meta {
    font-size: 0.75rem;
    color: #7A7A85;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#locationModal .hl-option-pin {
    color: #B8B8C2;
    font-size: 1.1rem;
    flex-shrink: 0;
}

/* ── Selected state ───────────────────────────────────── */

#locationModal .hl-option-selected {
    border-color: #1E90FF;
    background: linear-gradient(135deg, rgba(30, 144, 255, 0.06) 0%, rgba(86, 196, 248, 0.03) 100%);
    box-shadow: 0 4px 14px rgba(30, 144, 255, 0.10);
}

    #locationModal .hl-option-selected .hl-option-tick {
        border-color: #1E90FF;
        background: linear-gradient(135deg, #1E90FF 0%, #56C4F8 100%);
    }

        #locationModal .hl-option-selected .hl-option-tick i {
            opacity: 1;
        }

    #locationModal .hl-option-selected .hl-option-pin {
        color: #1E90FF;
    }

/* ── AI primary — distinguished with an orange tint and a
      subtle "AI" sparkle treatment on the pin icon ────── */

#locationModal .hl-option-primary {
    background: linear-gradient(135deg, rgba(245, 130, 32, 0.04) 0%, rgba(255, 154, 60, 0.02) 100%);
    border-color: rgba(245, 130, 32, 0.25);
    position: relative;
}

    #locationModal .hl-option-primary:hover {
        border-color: rgba(245, 130, 32, 0.45);
        background: linear-gradient(135deg, rgba(245, 130, 32, 0.07) 0%, rgba(255, 154, 60, 0.04) 100%);
    }

    #locationModal .hl-option-primary .hl-option-pin {
        color: #F58220;
        animation: hl-confirm-sparkle 2.2s ease-in-out infinite;
    }

@keyframes hl-confirm-sparkle {
    0%, 100% {
        transform: scale(1);
        opacity: 0.9;
    }

    50% {
        transform: scale(1.15);
        opacity: 1;
    }
}

#locationModal .hl-option-primary.hl-option-selected {
    border-color: #F58220;
    background: linear-gradient(135deg, rgba(245, 130, 32, 0.10) 0%, rgba(255, 154, 60, 0.05) 100%);
    box-shadow: 0 6px 18px rgba(245, 130, 32, 0.18);
}

    #locationModal .hl-option-primary.hl-option-selected .hl-option-tick {
        border-color: #F58220;
        background: linear-gradient(135deg, #F58220 0%, #FF9A3C 100%);
    }

/* ── Skeleton placeholder while nearby loads ─────────── */

#locationModal .hl-option-skel {
    background: linear-gradient(90deg, #F5F5F7 0%, #FAFAFC 50%, #F5F5F7 100%);
    background-size: 200% 100%;
    animation: hl-skel-shimmer 1.4s linear infinite;
    border-color: transparent;
    cursor: default;
    min-height: 48px;
}

    #locationModal .hl-option-skel:hover {
        transform: none;
        background: linear-gradient(90deg, #F5F5F7 0%, #FAFAFC 50%, #F5F5F7 100%);
        background-size: 200% 100%;
    }

#locationModal .hl-skel-bar {
    height: 12px;
    width: 60%;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.05);
}

@keyframes hl-skel-shimmer {
    0% {
        background-position: 200% 0;
    }

    100% {
        background-position: -200% 0;
    }
}

#locationModal .hl-option-empty {
    padding: 14px;
    text-align: center;
    font-size: 0.8rem;
    color: #9A9AA5;
    background: #FAFAFC;
    border: 1px dashed #E2E2E7;
    border-radius: 12px;
    cursor: default;
}

/* ── Accuracy banner — shows GPS fix quality above the AI pick ── */

#locationModal .hl-accuracy {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.78rem;
    line-height: 1.4;
    border-radius: 10px;
    border: 1px solid transparent;
}

    #locationModal .hl-accuracy i {
        flex: 0 0 auto;
        font-size: 1rem;
        line-height: 1.2;
        margin-top: 1px;
    }

    #locationModal .hl-accuracy span {
        flex: 1 1 auto;
    }

/* Severity skins */
#locationModal .hl-accuracy-good {
    background: #EAF7EE;
    border-color: #C6EAD2;
    color: #1F6E3A;
}

#locationModal .hl-accuracy-fair {
    background: #FFF7E6;
    border-color: #FFE3B0;
    color: #8A5A00;
}

#locationModal .hl-accuracy-poor {
    background: #FFEFE6;
    border-color: #FFCDAE;
    color: #A04A1A;
}

#locationModal .hl-accuracy-very-poor {
    background: #FDEAEA;
    border-color: #F4B7B7;
    color: #8A1A1A;
}

/* ── Actions row — Cancel + Confirm ───────────────────── */

#locationModal .hl-confirm-actions {
    display: flex;
    gap: 10px;
    padding: 18px 22px 22px;
}

#locationModal .hl-confirm-cancel {
    flex: 0 0 auto;
    background: #fff;
    border: 1px solid #E2E2E7;
    border-radius: 999px;
    padding: 12px 22px;
    color: #6A6A75;
    font-weight: 500;
    font-size: 0.92rem;
    transition: background 0.15s ease, border-color 0.15s ease;
}

    #locationModal .hl-confirm-cancel:hover {
        background: #F5F5F7;
        border-color: #D2D2D7;
    }

#locationModal .hl-confirm-commit {
    flex: 1;
    background: linear-gradient(135deg, #F58220 0%, #FF9A3C 100%);
    border: 0;
    border-radius: 999px;
    padding: 13px 24px;
    color: #fff;
    font-weight: 700;
    font-size: 0.95rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-shadow: 0 6px 18px rgba(245, 130, 32, 0.35);
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
    position: relative;
}

    #locationModal .hl-confirm-commit:hover {
        transform: translateY(-1px);
        box-shadow: 0 8px 22px rgba(245, 130, 32, 0.45);
        filter: brightness(1.05);
    }

    #locationModal .hl-confirm-commit.is-committing {
        pointer-events: none;
        opacity: 0.85;
    }

        #locationModal .hl-confirm-commit.is-committing i {
            animation: hl-fab-seeking 0.9s linear infinite;
        }

/* ── Mobile tweaks for the confirm body ───────────────── */

@media (max-width: 480px) {
    #locationModal .hl-confirm-hero {
        padding: 22px 18px 14px;
    }

    #locationModal .hl-confirm-title {
        font-size: 1.2rem;
    }

    #locationModal .hl-confirm-sub {
        font-size: 0.82rem;
    }

    #locationModal .hl-confirm-section {
        padding: 12px 16px 4px;
    }

    #locationModal .hl-confirm-actions {
        padding: 16px 16px 18px;
        gap: 8px;
    }

    #locationModal .hl-option {
        padding: 11px 12px;
        gap: 10px;
    }

    #locationModal .hl-option-name {
        font-size: 0.9rem;
    }
}

/* ===========================================================
   7. BUTTON LOADING STATE — Allow / Confirm spinner
   -----------------------------------------------------------
   Used by the Allow Location button on the consent body and
   the Confirm button on the confirm body. The instant the
   user clicks, the button shows a spinner + "Locating…" text
   AND is fully disabled so repeated taps go nowhere.
   =========================================================== */

#locationModal .hl-allow-btn.is-loading,
#locationModal .hl-confirm-commit.is-committing {
    pointer-events: none;
    cursor: progress;
    /* Slight desaturation so the button visibly reads as "busy" */
    filter: saturate(0.85) brightness(1.02);
}

#locationModal .hl-allow-btn:disabled,
#locationModal .hl-confirm-commit:disabled {
    /* Override Bootstrap's default disabled fade — we keep our
       gradient at 85% opacity so users still see the button
       clearly. The spinner does the "busy" signalling. */
    opacity: 0.85;
}

#locationModal .hl-btn-spinner {
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-right: 0.55em;
    vertical-align: -0.15em;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
    animation: hl-btn-spin 0.8s linear infinite;
    flex-shrink: 0;
}

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

#locationModal .hl-btn-text {
    font-weight: inherit;
    letter-spacing: 0.01em;
}

/* ============================================================
   v5 STATES — folded in from hyper-location-v5-patch.css
   ------------------------------------------------------------
   These rules were previously shipped as a separate patch file.
   They are now part of the main stylesheet so there is a single
   source of truth. (The old hyper-location-v5-patch.css link can
   be removed from _Layout.cshtml.)

   Visual states introduced in hyper-location.js v5:
     • .hl-accuracy-warn       — warning banner (datacentre/VPN/no fix)
     • .hl-option-lowconf      — muted AI pick when confidence is low
     • .hl-option-meta-warn    — inline warning text inside the AI pick
     • .hl-confirm-commit.is-disabled-lowconf — explicit disabled state
   ============================================================ */

/* ── Warning banner ── */
#locationModal .hl-accuracy-warn {
    background: #FDEDED;
    border-color: #F4B7B7;
    color: #8A1A1A;
    border-left-width: 3px;
    box-shadow: 0 1px 0 rgba(138, 26, 26, 0.04);
}

    #locationModal .hl-accuracy-warn i {
        color: #B23A3A;
    }

/* ── Muted AI pick when confidence is low ── */
#locationModal .hl-option-primary.hl-option-lowconf {
    background: #FAFAFC;
    border-color: #E2E2E7;
    box-shadow: none;
    opacity: 0.85;
}

    #locationModal .hl-option-primary.hl-option-lowconf .hl-option-pin {
        color: #8A8A92;
    }

    #locationModal .hl-option-primary.hl-option-lowconf .hl-option-tick {
        opacity: 0;
    }

    #locationModal .hl-option-primary.hl-option-lowconf.hl-option-selected {
        background: #fff;
        border-color: #1F6E3A;
        opacity: 1;
    }

        #locationModal .hl-option-primary.hl-option-lowconf.hl-option-selected .hl-option-tick {
            opacity: 1;
        }

/* ── Inline warning meta line inside the AI pick row ── */
#locationModal .hl-option-meta-warn {
    color: #B23A3A;
    font-size: 0.74rem;
    font-style: italic;
    margin-top: 2px;
}

/* ── Explicit disabled-commit state ── */
#locationModal .hl-confirm-commit.is-disabled-lowconf {
    cursor: not-allowed;
    opacity: 0.55;
}

    #locationModal .hl-confirm-commit.is-disabled-lowconf:hover {
        opacity: 0.55;
        transform: none;
    }

/* ============================================================
   v6 — GPS-REQUIREMENT NOTICE (consent body)
   ------------------------------------------------------------
   Persistent inline panel shown inside the consent body when a
   location attempt fails. Unlike the transient toast, this stays
   on screen so the user can read why GPS is required and what to
   do next. Hyper-Localisation is a GPS-precision feature: we do
   not fall back to IP/network (wrong) or manual entry (defeats
   the purpose), so this panel carries the explanation instead.

   Severity is conveyed with an amber accent for "needs action /
   not supported on this device" — calmer than the red datacentre
   warning, because this isn't an error the user caused.
   ============================================================ */
#locationModal .hl-gps-notice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 4px 0 14px;
    padding: 12px 14px;
    background: #FFF7EC;
    border: 1px solid #F6D9A8;
    border-left: 3px solid #F58220;
    border-radius: 12px;
    text-align: left;
    animation: hl-gps-notice-in 0.32s cubic-bezier(0.25, 1, 0.5, 1);
}

    /* [hidden] must win even though the flex display above is more
   specific — keep the panel fully hidden until the JS reveals it. */
    #locationModal .hl-gps-notice[hidden] {
        display: none;
    }

#locationModal .hl-gps-notice-icon {
    color: #F58220;
    font-size: 1.05rem;
    line-height: 1.4;
    flex-shrink: 0;
    margin-top: 1px;
}

#locationModal .hl-gps-notice-content {
    flex: 1;
    min-width: 0;
}

#locationModal .hl-gps-notice-title {
    margin: 0 0 2px;
    font-size: 0.82rem;
    font-weight: 800;
    color: #8A4B00;
    letter-spacing: -0.01em;
}

#locationModal .hl-gps-notice-text {
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.5;
    color: #7A5320;
}

    /* Inline "how to" steps the JS may add for the OS-disabled case. */
    #locationModal .hl-gps-notice-text strong {
        color: #8A4B00;
        font-weight: 700;
    }

@keyframes hl-gps-notice-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ============================================================
   v6 — ACCURACY EXPECTATIONS DISCLOSURE (consent body)
   ------------------------------------------------------------
   A quiet, always-visible line shown BEFORE the user clicks
   Allow Location, with an expandable <details> carrying the full
   GPS-vs-WiFi-vs-IP explanation. Sets expectations up front so
   desktop users (esp. agency staff) know this is a GPS feature
   before they hit a failure — without shouting at casual buyers.
   ============================================================ */
#locationModal .hl-accuracy-note {
    margin: 2px 0 14px;
    text-align: left;
    border: 1px solid rgba(0, 0, 0, 0.07);
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.015);
    overflow: hidden;
}

#locationModal .hl-accuracy-note-summary {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    font-size: 0.76rem;
    line-height: 1.45;
    color: #6C757D;
    cursor: pointer;
    list-style: none;
    user-select: none;
    transition: background 0.2s ease;
}

    #locationModal .hl-accuracy-note-summary:hover {
        background: rgba(0, 0, 0, 0.03);
    }

    /* Hide the default disclosure triangle across browsers. */
    #locationModal .hl-accuracy-note-summary::-webkit-details-marker {
        display: none;
    }

    #locationModal .hl-accuracy-note-summary::marker {
        content: "";
    }

#locationModal .hl-accuracy-note-icon {
    color: #56C4F8;
    font-size: 0.95rem;
    line-height: 1.4;
    flex-shrink: 0;
    margin-top: 1px;
}

/* The "How accuracy works" affordance — looks tappable. */
#locationModal .hl-accuracy-note-more {
    color: #F58220;
    font-weight: 700;
    white-space: nowrap;
}

/* Rotate-in caret cue on the right so users know it expands. */
#locationModal .hl-accuracy-note-summary::after {
    content: "\F282"; /* bootstrap-icons chevron-down */
    font-family: "bootstrap-icons";
    margin-left: auto;
    font-size: 0.8rem;
    color: #ADB5BD;
    transition: transform 0.25s ease;
    flex-shrink: 0;
}

#locationModal .hl-accuracy-note[open] .hl-accuracy-note-summary::after {
    transform: rotate(180deg);
}

#locationModal .hl-accuracy-note-detail {
    padding: 2px 12px 12px;
    border-top: 1px solid rgba(0, 0, 0, 0.05);
    animation: hl-accuracy-detail-in 0.28s ease;
}

    #locationModal .hl-accuracy-note-detail p {
        margin: 8px 0 0;
        font-size: 0.74rem;
        line-height: 1.55;
        color: #6C757D;
    }

        #locationModal .hl-accuracy-note-detail p strong {
            color: #495057;
            font-weight: 700;
        }

@keyframes hl-accuracy-detail-in {
    from {
        opacity: 0;
        transform: translateY(-3px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ============================================================
   v6 — WIDER CONSENT MODAL + ONE-VIEWPORT FIT
   ------------------------------------------------------------
   The consent body now carries the accuracy-expectations
   disclosure on top of the hero, benefits and privacy note.
   At Bootstrap's default 500px width with the original padding
   it could overflow the viewport on shorter laptop screens and
   require scrolling. We widen the dialog and tighten the
   vertical rhythm so the whole consent screen fits in one
   viewport on a typical laptop (≥720px tall).

   Scope: width applies to the whole modal (harmless for the
   confirm/active bodies, which are shorter); the spacing
   reductions are scoped to the consent body so the confirm and
   active screens keep their original, roomier rhythm.
   ============================================================ */
#locationModal .modal-dialog {
    /* Wider than the Bootstrap default so longer translations (e.g.
       isiXhosa, isiZulu, Sesotho) reflow into fewer lines and the
       whole consent screen — including the expanded accuracy
       disclosure — still fits in one viewport. Capped with a vw
       fallback so it never touches the screen edges on smaller
       laptops. */
    max-width: min(760px, calc(100vw - 48px));
}

/* ── One-viewport vertical tightening (consent body only) ── */
#locationModal .hl-consent-body .hl-hero {
    padding: 22px 40px 14px;
}

/* The hero paragraph is capped at 380px by default, which forces it
   to wrap into many short lines — wasteful vertically, especially in
   longer languages (isiXhosa/isiZulu). Now that the modal is wider,
   let the copy use that width so it flows into 2–3 lines instead of
   5+. Also tighten the line-height a touch for a denser block. */
#locationModal .hl-consent-body .hl-copy {
    max-width: 600px;
    line-height: 1.45;
    font-size: 0.88rem;
}

/* Pull the uppercase sub-label closer to the title. */
#locationModal .hl-consent-body .hl-sub {
    margin-bottom: 10px;
}

#locationModal .hl-consent-body .hl-benefits {
    margin: 10px 0;
    padding: 12px 28px 4px;
}

/* Trim the privacy strip: remove the top margin and reduce its own
   internal vertical padding to recover height. Keep the 24px side
   margins so its left/right edges align with the accuracy disclosure
   and gps-notice bands below it (which also use a 24px inset). */
#locationModal .hl-consent-body .hl-privacy {
    margin: 0 24px 8px;
    padding-top: 11px;
    padding-bottom: 11px;
}

/* Tighten the disclosure summary so the collapsed row is shorter. */
#locationModal .hl-consent-body .hl-accuracy-note-summary {
    padding-top: 9px;
    padding-bottom: 9px;
}

/* Tighten the accuracy-disclosure detail paragraphs — smaller gaps
   between the four tiers keeps the expanded state compact. */
#locationModal .hl-consent-body .hl-accuracy-note-detail p {
    margin-top: 6px;
    line-height: 1.45;
}

/* The accuracy disclosure and the (hidden until needed) gps
   notice both live in a horizontal band — give them a consistent
   side inset so they align with the hero text. (.hl-actions
   already carries its own 24px side padding, so it is NOT given
   margins here — that would double the inset.) */
#locationModal .hl-consent-body .hl-accuracy-note,
#locationModal .hl-consent-body .hl-gps-notice {
    margin-left: 24px;
    margin-right: 24px;
}

/* Tighten only the actions' top padding to recover vertical space;
   keep the original 24px sides and bottom. */
#locationModal .hl-consent-body .hl-actions {
    padding-top: 6px;
}

/* If a very short screen still can't fit everything, let the
   modal body scroll internally rather than pushing buttons off
   the bottom of the viewport. The dialog stays centered. */
@media (max-height: 760px) {
    #locationModal .modal-content {
        max-height: 92vh;
        overflow-y: auto;
    }
}

/* On narrow phones, tighten the side insets of the inset bands so
   text has more room. (Width itself is handled by the min() rule
   above, which already keeps a gutter on every screen size.) */
@media (max-width: 660px) {
    #locationModal .hl-consent-body .hl-privacy,
    #locationModal .hl-consent-body .hl-accuracy-note,
    #locationModal .hl-consent-body .hl-gps-notice {
        margin-left: 16px;
        margin-right: 16px;
    }
}
