/*
 * styles/mobile.css — Museum of Economic Models — Mobile & Touch Overrides
 * =========================================================================
 * Loaded immediately after styles/gallery.css. All new mobile/touch rules
 * live here. Do NOT alter this file for desktop-only changes; use gallery.css.
 *
 * Breakpoints (documented here; add as a comment block in every new section)
 * ---------------------------------------------------------------------------
 *   xs  ≤ 380 px          iPhone SE portrait, small Android
 *   sm  381 – 600 px      typical phone portrait
 *   md  601 – 900 px      phone landscape, small tablet portrait
 *   lg  901 – 1280 px     tablet landscape, small laptop
 *   xl  > 1280 px         desktop — current default, untouched
 *
 *   768 px is an intentional EXCEPTION to the tiers above: it is the single
 *   shared "tablet content-collapse" breakpoint (multi-column grids → one
 *   column, compact chrome). All such collapses use 768; do not reintroduce
 *   720/760/820 etc. Tier boundaries (600/900/1280) are for layout regions;
 *   768 is for content that stops fitting around iPad width.
 *
 * Category labels (task spec A–I):
 *   A  Viewport sizing & safe area
 *   B  Touch-friendly entry path
 *   C  Touch target sizing (≥ 44 × 44 px)
 *   D  Top-bar collapse & view-controls docking
 *   E  Hint bar
 *   F  Modals
 *   G  Performance — images  (srcset / lazy in HTML; see MoEM_Gallery.html)
 *   H  Performance — scripts (defer in HTML; see MoEM_Gallery.html)
 *   I  Two-finger rotate gesture (svg-renderer.js)
 *   J  Subsite audit note (MoEM_mobile_changes.md)
 */


/* ==========================================================================
   A — Viewport sizing & safe area
   Applies to all viewports; dvh / env() values silently fall back on
   browsers without support (env = 0, dvh = 100vh).
   ========================================================================== */

/* A1: Dynamic viewport height — fixes the iOS Safari address-bar gap */
body {
  height: 100vh;        /* safe fallback for very old browsers */
  height: 100dvh;       /* dynamic viewport height */
}

#viewport {
  height: 100vh;        /* fallback */
  height: 100dvh;
}

/* A2: Notch-aware nav bar padding */
#nav-bar {
  padding-top: env(safe-area-inset-top, 0px);
  /* Let height grow with the top inset rather than clip */
  min-height: calc(68px + env(safe-area-inset-top, 0px));
  height: auto;
}

/* A3: Push persistent overlay elements above the home-indicator / rounded
       corners at the bottom of the screen. */
#filikon-companion {
  bottom: max(1.25rem, env(safe-area-inset-bottom, 0px));
}
#view-controls {
  bottom: max(1.25rem, env(safe-area-inset-bottom, 0px));
}
#hint {
  bottom: max(1.25rem, env(safe-area-inset-bottom, 0px));
}
/* Panorama & pano header */
#pano-overlay {
  padding-top: env(safe-area-inset-top, 0px);
}


/* ==========================================================================
   B — Touch-friendly entry path
   @media (hover: none) and (pointer: coarse)  →  touchscreen device
   ========================================================================== */

@media (hover: none) and (pointer: coarse) {

  /* B1: Mini-map — always visible on touch as primary room-navigation.
         Overrides the gallery.css rule that hides it at ≤ 600 px.     */
  #mini-map {
    display: block !important;
    width: 180px;
    /* Anchor below the (possibly taller) notch-aware nav bar */
    top: calc(80px + env(safe-area-inset-top, 0px));
  }

  /* B2: Slightly thicker room borders for finger-tap precision */
  #mini-map .map-room {
    stroke-width: 2px;
  }

  /* B3: Filikon badge — text-swap is performed by the is-touch JS block.
         Ensure the pill wraps without overflowing on small screens.    */
  #filikon-badge .badge-pill {
    white-space: normal;
    text-align: center;
    max-width: 96px;
    font-size: 0.50rem;
    line-height: 1.35;
  }

  /* B4: Hide the "Bring me into a room!" badge text on touch;
         the JS will insert the map-instruction text instead.
         If JS hasn't run yet, this keeps the layout sane.             */
  body.is-touch #filikon-badge .badge-pill {
    /* Text is replaced by JS; this prevents a flash of the old label  */
    display: block;
  }
}


/* ==========================================================================
   C — Touch target sizing  (min 44 × 44 px on all touch breakpoints)
   @media (hover: none) and (pointer: coarse)
   Hit areas expanded via min-size or ::before pseudo-elements.
   Visual size of icons is unchanged.
   ========================================================================== */

@media (hover: none) and (pointer: coarse) {

  /* C1: View-control buttons */
  .ctrl-btn {
    min-width: 44px;
    min-height: 44px;
    width: 44px;
    height: 44px;
    position: relative;   /* anchor for ::before hit-area extension */
  }
  .ctrl-btn::before {
    content: '';
    position: absolute;
    inset: -6px;
  }

  /* C2: Detail-panel close button */
  #detail-close {
    width: 44px;
    height: 44px;
  }

  /* C3: Pannellum custom hotspots */
  #pano-container .custom-hotspot {
    width: 44px;
    height: 44px;
    margin-left: -22px;
    margin-top: -22px;
    font-size: 15px;
  }
  /* Door hotspot stays larger — already > 44 px */
  #pano-container .custom-hotspot.door-hotspot {
    width: 60px;
    height: 60px;
    margin-left: -30px;
    margin-top: -30px;
  }

  /* C4: POV HUD navigation buttons */
  .pov-btn {
    min-height: 44px;
    padding: 0.75rem 1rem;
  }

  /* C5: Nav-center icon buttons (feedback / newsletter) */
  .nav-center button {
    min-width: 44px;
    min-height: 44px;
    position: relative;
  }
  .nav-center button::before {
    content: '';
    position: absolute;
    inset: -6px;
  }

  /* C6: Market-widget slider thumb — bump to 28 px */
  input[type="range"]::-webkit-slider-thumb {
    width: 28px !important;
    height: 28px !important;
  }
  input[type="range"]::-moz-range-thumb {
    width: 28px !important;
    height: 28px !important;
  }

  /* C7: r2-widget sort / hydra buttons — taller touch target */
  .r2-sc-b,
  .r2-hydra-btn,
  .r2-fp-btn {
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}


/* ==========================================================================
   D — Top-bar collapse, hamburger menu, view-controls docking, Filikon resize
   ========================================================================== */

/* ── D0: Hamburger button — always in DOM; shown only on xs / sm ─────── */
.ham-btn {
  display: none;                  /* hidden on desktop by default */
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}
.ham-line {
  display: block;
  width: 22px;
  height: 2px;
  background: rgba(255, 255, 255, 0.88);
  border-radius: 2px;
  transition: transform 0.22s ease, opacity 0.22s ease;
  pointer-events: none;
}
/* Animated ✕ when the panel is open */
body.ham-open .ham-btn .ham-line:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
body.ham-open .ham-btn .ham-line:nth-child(2) {
  opacity: 0;
  transform: scaleX(0);
}
body.ham-open .ham-btn .ham-line:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ── D1: Drop-down hamburger panel — base styles (all breakpoints) ───── */
#ham-panel {
  display: none;                  /* hidden on desktop */
  position: fixed;
  top: calc(68px + env(safe-area-inset-top, 0px));
  left: 0;
  right: 0;
  background: rgba(15, 15, 15, 0.97);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
  z-index: 99;
  /* Starts off-screen above nav; slides down on open */
  transform: translateY(-110%);
  opacity: 0;
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1),
              opacity   0.20s ease;
  pointer-events: none;
}
#ham-panel.open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}
.ham-panel-inner {
  display: flex;
  flex-direction: column;
  padding: 0.5rem 1.5rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
  gap: 0;
}
/* Shared styles for links and action buttons in the panel */
.ham-link,
.ham-action {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 0;
  border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  background: transparent;
  color: rgba(255, 255, 255, 0.82);
  font: 600 0.88rem / 1.2 'Inter', sans-serif;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  width: 100%;
  text-align: left;
  font-family: inherit;
  transition: color 0.15s;
}
.ham-link:last-child,
.ham-action:last-child {
  border-bottom: none;
}
.ham-link:hover,
.ham-action:hover,
.ham-link:active,
.ham-action:active {
  color: #fff;
}
/* Icon inside the panel item */
.ham-item-icon {
  width: 18px;
  height: 18px;
  opacity: 0.55;
  flex-shrink: 0;
}

/* ── D2: Nav collapse — xs / sm (≤ 600 px) ───────────────────────────── */
@media (max-width: 600px) {

  /* Show hamburger, hide original desktop nav items */
  .ham-btn  { display: flex; }
  /* display:block lets the transition run; transform hides it. top clears the
     tightened nav bar below. (Merged — was two #ham-panel rules.) */
  #ham-panel {
    display: block;
    top: calc(56px + env(safe-area-inset-top, 0px));
  }

  .nav-center { display: none !important; }
  .nav-links  { display: none !important; }

  /* Tighten nav bar height on xs/sm */
  #nav-bar {
    min-height: calc(56px + env(safe-area-inset-top, 0px));
    padding-left: 1rem;
    padding-right: 0.75rem;
  }
  .nav-logo-img {
    max-height: 32px;
    width: auto;
    height: auto;
  }
  /* Mini-map re-anchored to tighter nav height */
  #mini-map {
    top: calc(68px + env(safe-area-inset-top, 0px));
  }

  /* ── D3: Filikon — smaller avatar, repositioned to bottom-right ──── */
  #filikon-companion {
    left: auto;
    right: 1rem;
    bottom: max(1rem, env(safe-area-inset-bottom, 0px));
    /* keep pointer-events:none on the wrapper; avatar stays interactive */
  }
  #filikon-companion .filikon-avatar {
    width: 64px;
    height: 64px;
  }
  /* Recalculate badge offset for smaller avatar */
  #filikon-badge {
    bottom: 74px;
  }
  #filikon-badge .badge-pill {
    max-width: 80px;
    font-size: 0.46rem;
  }

  /* ── D4: View controls — on phones, zoom & rotate are redundant with native
     gestures (pinch = zoom, two-finger twist = rotate, drag = pan), so we hide
     them and keep only the guided-tour toggle. This declutters the bottom strip
     and removes the footer collision. */
  #btn-zoom-in,
  #btn-zoom-out,
  #btn-rot-ccw,
  #btn-rot-cw,
  #view-label {
    display: none !important;
  }
  #view-controls {
    right: auto;
    left: 50%;
    transform: translateX(-50%);
    flex-direction: row;
    gap: 0.3rem;
    align-items: center;
    /* Sit clear of the fixed legal footer (up to ~2 link rows) plus safe area */
    bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px));
    background: rgba(20, 20, 20, 0.82);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    padding: 0.3rem;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.1);
  }
  /* Flatten the ctrl-rows into one horizontal strip */
  .ctrl-row {
    display: contents;
  }
}

/* xs only (≤ 380 px): extra tightening */
@media (max-width: 380px) {
  #nav-bar {
    min-height: calc(52px + env(safe-area-inset-top, 0px));
    padding-left: 0.75rem;
    padding-right: 0.5rem;
  }
  #ham-panel {
    top: calc(52px + env(safe-area-inset-top, 0px));
  }
  .nav-logo-img { max-height: 28px; }
  #filikon-companion .filikon-avatar {
    width: 56px;
    height: 56px;
  }
  #filikon-badge { bottom: 66px; }
  #mini-map { width: 160px; }
}


/* ==========================================================================
   E — Hint bar
   xs / sm (≤ 600 px): pill → full-width bar pinned to the very bottom
   ========================================================================== */

@media (max-width: 600px) {
  #hint {
    /* Stretch full width, pin to bottom */
    left: 0;
    right: 0;
    transform: none;
    bottom: 0;
    max-width: 100vw;
    border-radius: 0;
    /* Internal padding respects the home-indicator notch */
    padding: 0.45rem 1rem max(0.45rem, env(safe-area-inset-bottom, 0px));
    /* Allow text to wrap */
    white-space: normal;
    text-align: center;
    line-height: 1.5;
    font-size: 0.65rem;
    /* Ensure it sits below the view-controls bar */
    z-index: 98;
  }
}


/* ==========================================================================
   F — Modals
   xs / sm (≤ 600 px): scrollable, full-width, single-column layouts
   ========================================================================== */

/* ── F1: Welcome modal ────────────────────────────────────────────────── */
@media (max-width: 600px) {
  #welcome-modal {
    align-items: flex-start;
    overflow-y: auto;
    /* Pad for notch top + home indicator bottom */
    padding:
      max(1rem, env(safe-area-inset-top, 1rem))
      0.75rem
      max(1rem, env(safe-area-inset-bottom, 1rem));
  }
  #welcome-card {
    width: 100%;
    padding: 1.75rem 1.25rem 1.5rem;
    border-radius: 12px;
    /* vertically centred within the padded scroll container */
    margin: auto 0;
    max-height: none;
  }
  #welcome-card h1 {
    font-size: 1.35rem;
  }
  /* F1a: State-2 wbuttons — one button per line */
  #welcome-card .wbuttons {
    flex-direction: column;
    align-items: stretch;
    gap: 0.65rem;
  }
  #welcome-card .wbuttons button {
    width: 100%;
  }
  /* Shrink Filikon hero so it doesn't dominate small screens */
  #welcome-card .filikon-hero {
    width: 90px;
    height: 90px;
    margin-bottom: 0.5rem;
  }
  /* State 1 pitch layout — already handled by gallery.css ≤ 640 px block;
     tighten further for xs/sm */
  .welcome-pitch-text p {
    font-size: 0.95rem;
  }

/* ── F2: Detail panel — slide from bottom, full-width on xs/sm ────────── */
  #detail-panel {
    width: 100vw;
    left: 0;
    right: 0;
    height: 100vh;        /* fallback */
    height: 100dvh;
    /* Override the slide-from-right with slide-from-bottom */
    transform: translateY(100%);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1);
    box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.45);
  }
  #detail-panel.open {
    transform: translateY(0);
  }

  /* Drag handle visual (element added to HTML in Step 2) */
  .detail-drag-handle {
    display: block;
    width: 36px;
    height: 4px;
    background: #c0bbb5;
    border-radius: 2px;
    margin: 0.6rem auto 0.4rem;
  }
  /* Mobile header: sticky strip at top of panel */
  .detail-mobile-header {
    display: block;
    position: sticky;
    top: 0;
    z-index: 6;
    background: #f5f1ec;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    padding-bottom: 0.4rem;
    /* Reserve space for the absolute-positioned close button */
    min-height: 54px;
  }
  /* F2a: Close button — 44 px touch target, pinned to the sticky header */
  #detail-close {
    width: 44px;
    height: 44px;
    top: 0.5rem;
    right: 0.75rem;
    z-index: 7;
  }
  /* Ensure scroll content has breathing room at the bottom */
  #detail-content {
    padding-bottom: calc(2.5rem + max(0px, env(safe-area-inset-bottom, 0px)));
  }

/* ── F3: Widget modal (#widget-modal) — fit to screen on xs/sm ──────── */
  #widget-modal {
    padding: 0;
    align-items: flex-start;
    overflow-y: auto;
  }
  #widget-modal-inner {
    width: 100%;
    border-radius: 0;
    min-height: 100dvh;
    padding:
      max(1.5rem, env(safe-area-inset-top, 1.5rem))
      1rem
      max(2rem, env(safe-area-inset-bottom, 2rem));
    /* Disable the 3-D whirl-in on very small screens (too disorienting) */
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  /* Keep close button touchable */
  #widget-modal-close {
    width: 44px;
    height: 44px;
  }
  /* Single-column comparison cards */
  #widget-modal-inner .market-comparison {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }
  /* Shrink graph slightly */
  #widget-modal-inner #marketGraph {
    height: 200px;
  }

/* ── F4: DN-Lab widget modal (#r2-widget-modal) — xs/sm ──────────────── */
  #r2-widget-modal {
    padding: 0;
    align-items: flex-start;
    overflow-y: auto;
  }
  #r2-widget-modal-inner {
    width: 100%;
    border-radius: 0;
    min-height: 100dvh;
    padding:
      max(1.5rem, env(safe-area-inset-top, 1.5rem))
      1rem
      max(2rem, env(safe-area-inset-bottom, 2rem));
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  #r2-widget-modal-close {
    width: 44px;
    height: 44px;
  }
  /* r2-sort-grid: already 1-column in gallery.css; reinforced here */
  .r2-sort-grid {
    grid-template-columns: 1fr;
  }
  /* Hydra grid: already handled in gallery.css ≤ 600 px; reinforced */
  .r2-hydra-grid {
    grid-template-columns: 1fr;
  }
  /* Flagpole direction buttons — stack vertically */
  .r2-fp-buttons {
    flex-direction: column;
    gap: 0.55rem;
  }
  .r2-fp-btn {
    width: 100%;
    justify-content: center;
  }
  /* Shrink min-height on steps container (no need for 380 px on mobile) */
  .r2-dn-steps {
    min-height: auto;
  }

/* ── F5: Other full-screen modals (About, Intro, Feedback) — xs/sm ───── */
  #about-modal,
  #intro-modal,
  #feedback-modal,
  #newsletter-modal,
  #floormap-modal {
    align-items: flex-start;
    overflow-y: auto;
    padding:
      max(0.75rem, env(safe-area-inset-top, 0.75rem))
      0.75rem
      max(1rem, env(safe-area-inset-bottom, 1rem));
  }
  #about-modal-inner,
  #intro-modal-inner,
  #feedback-modal-inner,
  #newsletter-modal-inner,
  #floormap-modal-inner {
    width: 100%;
    border-radius: 12px;
    /* Let the modal scroll without fixed heights */
    max-height: none;
    margin: auto 0;
  }
  /* About: collapse the 3-column learn grid */
  .about-learn-grid {
    grid-template-columns: 1fr !important;
  }
}


/* ── Mobile modal stability: drop backdrop blur on phones/small tablets ──────
   `backdrop-filter: blur()` on a fixed, scrolling modal composited over the
   live-rendering gallery SVG causes "torn-tile" black artifacts on weaker
   mobile GPUs (especially while content loads on slow connections). An opaque
   dark backdrop with no blur looks nearly identical and renders reliably.
   `!important` is required to override the blur set by the open/close keyframe
   animations (per CSS spec, !important declarations beat animations). */
@media (max-width: 900px) {
  #intro-modal,
  #about-modal,
  #feedback-modal,
  #newsletter-modal,
  #floormap-modal {
    background: rgba(6, 4, 2, 0.94) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* Persistent chrome: drop the live blur on phones/tablets too. Their
     backgrounds are already near-opaque, so the look is unchanged but the GPU
     no longer re-blurs the moving gallery behind them every frame. */
  #nav-bar,
  #mini-map,
  #view-controls,
  footer {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  /* Compensate for the lost blur on the most translucent of these. */
  #view-controls {
    background: rgba(20, 20, 20, 0.92) !important;
  }
}


/* ── Bottom-strip layout: keep the fixed legal footer clear of floating UI ───
   The footer is position:fixed (body doesn't scroll) and holds the legally
   required Impressum/Datenschutz links, so it must stay visible. On phones it
   was being clipped by the control bar and the Filikon avatar. Fix: make the
   footer compact and predictable in height, then raise the floating elements
   to sit just above it. */
@media (max-width: 600px) {
  footer {
    padding: 0.45rem 1rem max(0.45rem, env(safe-area-inset-bottom, 0.45rem));
  }
  .footer-inner {
    gap: 0.25rem;
  }
  .footer-links {
    gap: 0.85rem;
  }
  .footer-links a {
    font-size: 0.72rem;
  }
  .copyright {
    font-size: 0.62rem;
  }
  /* Lift Filikon (bottom-right) clear of the footer band */
  #filikon-companion {
    bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px));
  }
}


/* ==========================================================================
   md breakpoint — 601 – 900 px (phone landscape, small tablet)
   Light fixes: safe-area anchoring, mini-map sizing
   ========================================================================== */

@media (min-width: 601px) and (max-width: 900px) {
  #view-controls {
    bottom: max(1rem, env(safe-area-inset-bottom, 0px));
    right:  max(1rem, env(safe-area-inset-right, 0px));
  }
  #hint {
    bottom: max(1rem, env(safe-area-inset-bottom, 0px));
  }
  #filikon-companion {
    bottom: max(1rem, env(safe-area-inset-bottom, 0px));
  }
  #mini-map {
    width: 170px;
    top: calc(88px + env(safe-area-inset-top, 0px));
  }
}


/* ==========================================================================
   Detail-panel drag handle — desktop: hidden
   (The .detail-mobile-header and .detail-drag-handle elements are always in
   the DOM; they are visually suppressed on desktop.)
   ========================================================================== */

.detail-mobile-header {
  display: none;            /* hidden on desktop / md / lg */
}
.detail-drag-handle {
  display: none;
}

/* ── Quick-search palette — small screens ───────────────────────────────── */
@media (max-width: 600px) {
  #quicksearch-modal { padding: 4vh 0.6rem 3vh; }
  #qs-kbd  { display: none; }   /* no hardware Esc worth advertising */
  #qs-hint { display: none; }
  /* The nav search bubble yields to the hamburger entry point on xs/sm. */
  #quicksearch-btn { display: none; }
}
