/* ====================================================================
   ios.css — iOS Safari & touch-device compatibility layer.
   Loaded AFTER style.css / landing.css so its rules win where needed.
   Goals:
     1. Honour the iPhone safe areas (notch, home indicator).
     2. Stop iOS Safari shrinking the viewport when the URL bar moves.
     3. Stop input zoom-in (16px minimum form font-size).
     4. Kill the ugly grey tap flash and the 300ms tap delay.
     5. Disable :hover on touch (so cards don't get stuck "hovered").
     6. Restore smooth scroll on iOS, prevent pull-to-refresh on the map.
     7. Make tap targets reach 44pt on phones.
   ==================================================================== */

/* ── 1. Base — applies on every device, harmless elsewhere ─────────── */

html {
    /* Stop iOS portrait→landscape zooming the text. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    /* Kill the iOS rubber-band white flash at the top edge. */
    background-color: var(--bg-primary, #fafaf9);
    /* Smooth fonts on retina. */
    -webkit-font-smoothing: antialiased;
    /* Stops the page glitching when the keyboard opens. */
    -webkit-overflow-scrolling: touch;
}

* {
    /* Remove the grey square that flashes on tap. */
    -webkit-tap-highlight-color: transparent;
}

/* Re-enable text selection in obvious content blocks. iOS can be aggressive
   with disabling it when -webkit-tap-highlight-color is set above. */
p, h1, h2, h3, h4, h5, h6, li, span, a, input, textarea, label, code, pre {
    -webkit-touch-callout: default;
}

/* ── 2. Stop the 300ms tap delay & double-tap zoom on controls ─────── */

a,
button,
[role="button"],
.q-skip,
.q-cta,
.q-back,
.q-choice,
.q-btn-next,
.q-btn-launch,
.q-btn-borough-go,
.q-borough-pill,
.q-skip-mini,
.nav-cta,
.hero-search button,
.btn-primary,
.btn-secondary,
.btn-close,
.compare-card-focus,
.scoped-results-mode,
.mobile-scoped-results-expand,
.terrain-basis-pill,
.suggestion-item,
.arrival-cta,
.arrival-link,
.arrival-progress-item,
.map-mode-chrome button,
.maplibregl-ctrl button,
input[type="submit"],
input[type="button"],
input[type="reset"],
input[type="checkbox"],
input[type="radio"] {
    touch-action: manipulation;
}

/* ── 3. Form inputs — 16px min font on phones to defeat iOS auto-zoom */

@media screen and (max-width: 900px) {
    input,
    select,
    textarea,
    .hero-search input,
    #search-input,
    #landing-input,
    .q-input,
    .site-evaluation-input {
        font-size: 16px !important;
    }
    /* iOS gives select boxes a default rounded look — keep ours flat. */
    select {
        -webkit-appearance: none;
        appearance: none;
    }
}

/* iOS-only: strip its native chrome from form widgets. We don't touch
   border-radius here so the design system's existing radii are preserved. */
input[type="text"],
input[type="email"],
input[type="search"],
input[type="number"],
input[type="tel"],
input[type="url"],
input[type="password"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
textarea,
select {
    -webkit-appearance: none;
    appearance: none;
}
button,
input[type="submit"],
input[type="button"],
input[type="reset"] {
    -webkit-appearance: none;
    appearance: none;
}

/* Strip Safari's "search" decorations so type="search" looks identical
   to text/email visually, while still giving iOS the search keyboard. */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration {
    -webkit-appearance: none;
    appearance: none;
    display: none;
}

/* ── 4. Viewport — use small/dynamic viewport units when available ─── */

/* Sets a JS-driven --vh fallback for older iOS versions, and dvh where
   the browser supports it. The .ios-h-screen class can be used in new
   markup; we also retro-patch the known 100vh sites here. */

:root {
    --vh: 1vh;          /* JS in app.js / arrival.js sets this to window.innerHeight*0.01 */
    --vw: 1vw;
}

@supports (height: 100dvh) {
    .app-layout {
        height: 100dvh;
    }
    .hero {
        min-height: 100dvh;
    }
    .questionnaire-page {
        min-height: 100dvh;
    }
    .q-container {
        min-height: 100dvh;
    }
    .scan-page,
    .scan-map {
        height: 100dvh;
    }
    .credits-page {
        min-height: 100dvh;
    }
}

/* Fallback for any iOS version without dvh. */
@supports not (height: 100dvh) {
    .app-layout {
        height: calc(var(--vh, 1vh) * 100);
    }
    .hero {
        min-height: calc(var(--vh, 1vh) * 100);
    }
    .questionnaire-page,
    .q-container {
        min-height: calc(var(--vh, 1vh) * 100);
    }
    .scan-page,
    .scan-map {
        height: calc(var(--vh, 1vh) * 100);
    }
    .credits-page {
        min-height: calc(var(--vh, 1vh) * 100);
    }
}

/* ── 5. Safe-area insets — respect notch & home indicator ──────────── */

.landing-nav,
.q-nav,
.credits-nav {
    padding-left: max(1.25rem, env(safe-area-inset-left));
    padding-right: max(1.25rem, env(safe-area-inset-right));
    padding-top: env(safe-area-inset-top);
}

.credits-page {
    padding-bottom: env(safe-area-inset-bottom);
}
.credits-main {
    padding-left: max(0rem, env(safe-area-inset-left));
    padding-right: max(0rem, env(safe-area-inset-right));
}

.hero {
    padding-left: max(1.5rem, env(safe-area-inset-left));
    padding-right: max(1.5rem, env(safe-area-inset-right));
    padding-bottom: max(5rem, calc(5rem + env(safe-area-inset-bottom)));
}

.landing-footer {
    padding-bottom: max(2rem, calc(2rem + env(safe-area-inset-bottom)));
    padding-left: max(1.5rem, env(safe-area-inset-left));
    padding-right: max(1.5rem, env(safe-area-inset-right));
}

.app-layout,
.scan-map {
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
    box-sizing: border-box;
}

/* The map workspace positions each overlay in an explicit safe-area slot.
   Padding the entire grid as well would apply the notch/home inset twice. */
body.app-page .app-layout {
    padding: 0;
}

/* Scan page chrome — keep the brand/skip clear of the notch and the
   bottom HUD clear of the home indicator. */
.scan-brand {
    top: max(1.5rem, calc(0.85rem + env(safe-area-inset-top))) !important;
    left: max(2rem, calc(1.1rem + env(safe-area-inset-left))) !important;
}
.scan-skip {
    top: max(1.5rem, calc(0.85rem + env(safe-area-inset-top))) !important;
    right: max(2rem, calc(1.1rem + env(safe-area-inset-right))) !important;
}
.scan-hud {
    padding-bottom: max(2.5rem, calc(1.4rem + env(safe-area-inset-bottom))) !important;
    padding-left: max(2.5rem, calc(1.4rem + env(safe-area-inset-left))) !important;
    padding-right: max(2.5rem, calc(1.4rem + env(safe-area-inset-right))) !important;
}
.scan-phases {
    bottom: max(2.5rem, calc(1.4rem + env(safe-area-inset-bottom))) !important;
}
@media (max-width: 768px) {
    .scan-brand {
        top: max(1rem, calc(0.55rem + env(safe-area-inset-top))) !important;
        left: max(1.25rem, calc(0.85rem + env(safe-area-inset-left))) !important;
    }
    .scan-skip {
        top: max(1rem, calc(0.55rem + env(safe-area-inset-top))) !important;
        right: max(1.25rem, calc(0.85rem + env(safe-area-inset-right))) !important;
    }
    .scan-hud {
        padding-bottom: max(1.5rem, calc(0.85rem + env(safe-area-inset-bottom))) !important;
        padding-left: max(1.25rem, calc(0.85rem + env(safe-area-inset-left))) !important;
        padding-right: max(1.25rem, calc(0.85rem + env(safe-area-inset-right))) !important;
    }
}

.panel-right {
    padding-bottom: env(safe-area-inset-bottom);
}

.arrival-shell {
    padding-bottom: max(4rem, calc(4rem + env(safe-area-inset-bottom)));
}

/* ── 6. Hover gate — only run hover styles on real hover devices ───── */
/*
   On iOS the :hover pseudo-class sticks until the user taps somewhere
   else. We disable the hover-only effects we know cause "stuck" looks
   by reverting them when hover isn't supported.
*/
@media (hover: none) {
    .nav-cta:hover,
    .landing-nav.scrolled .nav-cta:hover,
    .hero-search button:hover,
    .compare-card-focus:hover,
    .suggestion-item:hover,
    .filter-group label:hover,
    .terrain-basis-pill:hover,
    .q-skip:hover,
    .btn-close:hover {
        background: inherit;
        color: inherit;
        border-color: inherit;
    }
    /* Specific re-targets where the rule above is too generic. */
    .hero-search button:hover { background: var(--accent); }
    .landing-nav .nav-cta:hover { border-color: transparent; }
}

/* ── 7. Scroll containers — momentum + no rubber-band on the map ──── */

.suggestions,
.panel-right,
.panel-left,
.arrival-stage,
.post-scan-arrival,
.q-container {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

/* The map page must not scroll the body when the user pinch-pans. */
body.app-page,
body.scan-page {
    overscroll-behavior: none;
    /* Allow MapLibre to own gestures without iOS Safari's two-finger pan
       triggering page scroll. */
    touch-action: pan-x pan-y;
    margin: 0;
}

/* Lock the html element on iOS so dragging the map doesn't bounce the
   whole page. We scope this to is-ios to leave desktop alone. */
html.is-ios body.app-page,
html.is-ios body.scan-page {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* The maplibre canvas owns all touch on the map area. */
.maplibregl-canvas,
.scan-map .maplibregl-canvas,
#map canvas,
#deck-canvas {
    touch-action: none;
}

/* ── 8. Tap-target minimum sizing on phones ────────────────────────── */

@media (pointer: coarse), (max-width: 768px) {
    .nav-cta,
    .q-skip,
    .terrain-basis-pill,
    .map-mode-chrome button,
    .maplibregl-ctrl button,
    .arrival-link,
    .compare-card-focus,
    .btn-close {
        min-height: 44px;
        min-width: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    /* Make sure suggestion list items are easily tappable. */
    .suggestion-item {
        padding: 0.85rem 1rem;
        min-height: 44px;
    }
}

/* ── 9. Mobile layout — make app and arrival usable on a phone ─────── */

@media (max-width: 768px) {
    /* Map app: the panel becomes a full-width sheet anchored to the
       bottom of the screen, MapLibre fills the rest. */
    .app-layout {
        grid-template-columns: 1fr !important;
        grid-template-rows: 1fr;
    }
    .panel-right {
        position: fixed !important;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        width: 100%;
        max-height: var(--panel-sheet-max-height, 94dvh);
        border-left: none;
        border-top: 1px solid var(--border);
        border-radius: 16px 16px 0 0;
        box-shadow: 0 -12px 40px rgba(0,0,0,0.18);
        padding-bottom: max(1rem, env(safe-area-inset-bottom));
        overflow-y: auto;
    }
    .app-layout:has(.panel-right.hidden) {
        grid-template-columns: 1fr !important;
    }
    .map-mode-chrome {
        top: calc(var(--map-safe-top) + var(--map-mobile-scope-height) + 0.45rem);
        right: var(--map-safe-right);
        bottom: auto;
        left: var(--map-safe-left);
    }
    .mobile-rail-fab {
        min-height: 44px;
        min-width: 44px;
    }
    .panel-left {
        padding-bottom: max(1.2rem, env(safe-area-inset-bottom));
    }
    .map-zoom-hint {
        top: calc(var(--map-safe-top) + var(--map-mobile-scope-height) + 6.65rem);
        left: var(--map-safe-left);
        font-size: 0.68rem;
        padding: 0.42rem 0.55rem;
    }
    /* Provenance/source-stack rail wraps cleanly on phones. */
    .provenance-bar {
        flex-direction: column;
        align-items: stretch;
        gap: 0.4rem;
        padding: 0.85rem 1rem;
    }
    .provenance-mark {
        border-right: none;
        border-bottom: 1px solid rgba(241, 232, 214, 0.18);
        padding-right: 0;
        padding-bottom: 0.4rem;
        margin-right: 0;
        margin-bottom: 0.2rem;
    }
    .provenance-item {
        border-right: none;
        padding: 0.25rem 0;
    }
    /* Hero copy gets enough breathing room above the OS status bar. */
    .hero {
        padding-top: max(5rem, calc(4rem + env(safe-area-inset-top)));
    }
    .hero-title {
        font-size: clamp(1.9rem, 8vw, 2.4rem);
        line-height: 1.12;
    }
    /* Arrival files (01/02/03 progress) wrap better. */
    .arrival-files {
        flex-wrap: wrap;
        gap: 0.4rem 0.6rem;
    }
}

/* ── 10. iOS-only refinements (Safari & Chrome on iOS) ─────────────── */

@supports (-webkit-touch-callout: none) {
    /* Stop iOS putting an inset shadow inside text inputs. */
    input,
    textarea {
        background-clip: padding-box;
    }
    /* Better scroll behaviour for the panel-right sheet. */
    .panel-right {
        -webkit-overflow-scrolling: touch;
    }
    /* iOS Safari ignores `cursor: pointer` but expects role/href to
       trigger fastclick. Make sure custom buttons are <button>-styled. */
    [role="button"]:not(:disabled) {
        cursor: pointer;
    }
}

/* ── 11. Reduced motion — already used by style.css; reinforce here ── */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

/* ── 12. Print & PWA standalone ────────────────────────────────────── */

@media (display-mode: standalone) {
    /* When installed to the home screen, hide elements that lead away. */
    body { overscroll-behavior: none; }
}
