/* ============================================
   Base — reset and root element styles
   Depends on tokens.css custom properties.
   ============================================ */

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

html, body {
  height: 100%;
  overflow: hidden;
  font-family: var(--font-geist);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-text-primary);
  background: var(--color-canvas);
  -webkit-font-smoothing: antialiased;
}

/* iOS standalone PWA + black-translucent status bar (#86): the web view is only
   (screen − safe-area-inset-top) tall and anchored at the physical top, so the
   bottom inset's worth of pixels falls OUTSIDE the layout viewport as a blank
   strip. No height on a fixed child (#map/#app) can paint there — confirmed on
   device: even #map's own background didn't reach the bottom. The fix works at
   the document level: making <html> taller than the viewport forces WebKit to
   extend the renderable region to the full physical screen, after which the
   fixed full-bleed layers fill the bottom. `100%` (not vh/dvh) resolves against
   the initial containing block; + the top inset closes the exact deficit.
   Canonical iOS-PWA fix; see dev.to/karmasakshi PWA-on-iOS guide. */
html {
  min-height: calc(100% + env(safe-area-inset-top, 0px));
}

/* Mobile Safari (browser, not installed PWA) bottom gap (#86): Safari reports
   safe-area-inset-top: 0, so the standalone fix above is inert here. Safari's
   own quirk is the classic 100vh bug — with the bottom address bar shown it
   paints only the *dynamic* viewport (dvh), leaving a white strip above the bar
   up to the large viewport. Pin the full-bleed layers to the large viewport
   unit (lvh), which does not shrink when the address bar is visible, so the map
   fills down behind the bar. Scoped to browser display-mode so the PWA (which
   relies on the html min-height fix) is untouched. */
@media all and (display-mode: browser) {
  #app { height: 100lvh; }
}

/* Pin the app shell to the full viewport including the iOS safe areas so the
   full-bleed map and its controls reach every screen edge in standalone PWA
   mode. Sized by the dynamic viewport (100dvh) from the top rather than
   `inset: 0`, because on iOS a fixed element's `bottom: 0` lands above the
   home-indicator safe area and leaves a blank strip. Must not create a
   containing block for the fixed #map (no transform/filter/contain). (#52) */
#app {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: -webkit-fill-available;
  /* See #map in map.css: max() of the two candidates fills the screen in both
     the standalone PWA (calc) and Safari (100vh) contexts. (#52) */
  height: max(100vh, calc(100dvh + env(safe-area-inset-top, 0px)));
}

/* ---- Theme switch crossfade (#52) ----
   CSS custom properties don't animate, so we crossfade the properties that
   consume the theme tokens. The transition is scoped to a temporary class set
   on <html> only while a theme switch is in flight (see theme.js), so it never
   interferes with hover/focus state changes during normal use. */
html.theme-transitioning,
html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
  transition: background-color var(--duration-slow) ease-in-out,
              color var(--duration-slow) ease-in-out,
              border-color var(--duration-slow) ease-in-out,
              fill var(--duration-slow) ease-in-out,
              stroke var(--duration-slow) ease-in-out !important;
}

@media (prefers-reduced-motion: reduce) {
  html.theme-transitioning,
  html.theme-transitioning *,
  html.theme-transitioning *::before,
  html.theme-transitioning *::after {
    transition: none !important;
  }
}
