/* ==========================================================================
   ObserviSec — mobile and installed-app corrections
   Load AFTER the Next.js stylesheet.

   The built pages carry their layout in inline style attributes, which
   outrank any stylesheet rule, so the overrides below use !important
   where and only where they are correcting an inline value. Rules that
   add something new (safe areas, overscroll, tap behaviour) do not.

   Breakpoints run downward here rather than mobile-first, because this
   file corrects an existing desktop-authored layout instead of defining
   one. The permanent fix belongs in src/app/**; see DEPLOY.md.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Base behaviour on touch devices
   -------------------------------------------------------------------------- */

html {
  /* Stops Chrome's pull-to-refresh firing when a downward drag on the
     globe reaches the top of the page. Without this, panning the map
     south reloads the app. */
  overscroll-behavior-y: contain;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  overscroll-behavior-y: contain;
  /* Kills the grey flash Android paints over every tapped element,
     which on a map reads as a rendering glitch. */
  -webkit-tap-highlight-color: transparent;
}

/* Long-pressing to pan a map should not start a text selection. */
.maplibregl-map,
.maplibregl-map * {
  -webkit-user-select: none;
  user-select: none;
}

/* --------------------------------------------------------------------------
   2. Safe areas

   Only active when the viewport meta carries viewport-fit=cover. In
   standalone mode there is no browser chrome, so the header sits under
   the status bar and the bottom panel under the gesture pill unless
   these insets are honoured.
   -------------------------------------------------------------------------- */

header .os-brandrow {
  padding-left: calc(20px + env(safe-area-inset-left)) !important;
  padding-right: calc(20px + env(safe-area-inset-right)) !important;
}

#mobile-nav {
  padding-bottom: env(safe-area-inset-bottom);
}

main {
  padding-left: max(0px, env(safe-area-inset-left));
  padding-right: max(0px, env(safe-area-inset-right));
}

footer {
  padding-bottom: calc(32px + env(safe-area-inset-bottom)) !important;
}

/* MapLibre's own controls and attribution. */
.maplibregl-ctrl-bottom-left,
.maplibregl-ctrl-bottom-right {
  margin-bottom: env(safe-area-inset-bottom);
}

/* --------------------------------------------------------------------------
   3. Touch targets

   Android's guidance is 48dp; WCAG 2.2 AA asks for 24px minimum and AAA
   for 44px. The built markup lands at roughly 26-28px on the menu button
   and the map layer switches, which is below all three.
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {
  #menu-btn {
    min-height: 44px;
    min-width: 64px;
    padding: 12px 16px !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
  }

  #mobile-nav a {
    min-height: 48px;
    padding: 16px 20px !important;
    display: flex !important;
    align-items: center;
  }

  /* The map's layer toggles are rendered as role="switch" buttons,
     which is a stable hook regardless of build hash. */
  [role='switch'] {
    min-height: 44px;
    padding: 10px 6px !important;
  }

  /* Contact rows and any other button inside a surface panel. */
  .surface button {
    min-height: 40px;
  }

  /* 10px uppercase monospace is the site's label style. It survives on
     a desktop monitor and does not on a phone held at arm's length. */
  .label {
    font-size: 11px;
    letter-spacing: 0.14em;
  }
}

/* --------------------------------------------------------------------------
   4. The map's bottom-right panel

   Built as a fixed 280px block pinned to right:16 bottom:16. On a 360px
   Galaxy that is 78% of the screen width, and it lands on top of the
   MapLibre zoom controls, which are pinned to the same corner. Below
   640px it becomes a full-width sheet and the controls move above it.

   Scoped with body:has(.maplibregl-map) so it only applies on the globe
   page, and div:has(> .surface) so it survives a rebuild with new
   class hashes.
   -------------------------------------------------------------------------- */

@media (max-width: 640px) {
  body:has(.maplibregl-map) div:has(> .surface) {
    left: 12px !important;
    right: 12px !important;
    bottom: calc(12px + env(safe-area-inset-bottom)) !important;
    width: auto !important;
  }

  body:has(.maplibregl-map) .surface {
    padding: 14px !important;
    max-height: 42dvh !important;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Lift the zoom/compass stack clear of the sheet. */
  body:has(.maplibregl-map) .maplibregl-ctrl-bottom-right {
    bottom: calc(46dvh + env(safe-area-inset-bottom));
  }

  body:has(.maplibregl-map) .maplibregl-ctrl-bottom-left {
    max-width: 62vw;
  }
}

/* Landscape on a phone: very little vertical room, so the sheet has to
   give most of it back to the map. */
@media (max-width: 900px) and (orientation: landscape) and (pointer: coarse) {
  body:has(.maplibregl-map) div:has(> .surface) {
    left: auto !important;
    right: calc(12px + env(safe-area-inset-right)) !important;
    width: 260px !important;
  }

  body:has(.maplibregl-map) .surface {
    max-height: 56dvh !important;
  }

  body:has(.maplibregl-map) .maplibregl-ctrl-bottom-right {
    bottom: env(safe-area-inset-bottom);
    margin-right: 280px;
  }
}

/* --------------------------------------------------------------------------
   5. Content pages

   /military renders a table inside overflow-x:auto, which is correct.
   These rules stop the scroll from feeling broken and keep long strings
   from forcing the page itself sideways.
   -------------------------------------------------------------------------- */

@media (max-width: 640px) {
  main {
    overflow-x: hidden;
  }

  main table {
    font-size: 13px;
  }

  main th,
  main td {
    white-space: nowrap;
  }

  main p,
  main li,
  main dd {
    overflow-wrap: break-word;
  }
}

/* --------------------------------------------------------------------------
   6. Installed-app trim

   In standalone mode the app is launched from the home screen, so the
   in-page "install" prompt has nothing left to offer.
   -------------------------------------------------------------------------- */

@media (display-mode: standalone) {
  [data-os-install-prompt] {
    display: none !important;
  }
}

/* --------------------------------------------------------------------------
   7. Focus and motion floor
   -------------------------------------------------------------------------- */

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
