/* =============================================================================
   Mobile overrides.  Scoped under `html.mobile-device` (added to <html> by a
   clientside callback that inspects navigator.userAgent).  Desktop browsers
   never match and are untouched.

   Architecture (see app.py "Mobile-first" comment):
   - The STATIC viewport is `width=device-width`, so every page reflows to the
     real phone width in portrait.  CRITICAL: if ANY element is wider than the
     screen, the browser expands the layout viewport to fit it and zooms the
     whole page out (defeating mobile-first).  So the global rules below cap
     widths and make the navbar fit.
   - `/prediction` (html.route-prediction) is ALSO device-width now. It used to
     force a 1280px viewport for Plotly drawline, but that overflowed/cropped in
     real fullscreen landscape, so the wide viewport was dropped: landscape uses
     the real device width (~800-900px, plenty for drawing) and portrait puts the
     chart in a horizontal scroller.  The route-scoped rules below build the
     immersive landscape chart and bump chart fonts (now at native size).
   ========================================================================== */


/* --- Global: never let content force the viewport wider than the screen ----
   A single overflowing element zooms the whole page out, so we defend against
   it broadly.  Individual wide widgets (tables, iframes, charts) also get
   max-width:100% in their page-specific rules. */

html.mobile-device,
html.mobile-device body {
  /* lang.css pins `html, body { min-width: 1280px }` as a fallback for the old
     forced-desktop strategy.  That single rule anchors the whole page to 1280
     and defeats device-width.  Release it on ALL mobile pages -- including
     /prediction, which no longer forces a 1280 viewport (the wide viewport
     overflowed/cropped in real fullscreen landscape; the chart now uses the real
     device-width, with a horizontal-scroll chart in portrait). Leaving it pinned
     here was the recurring "1280 keeps popping up" + ~30% horizontal crop. */
  min-width: 0 !important;
  overflow-x: hidden;
  max-width: 100vw;
}

/* Final landscape composition: header | graph | footer. Kept after the legacy
   landscape rules above so these declarations win. */
@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #navbar-container {
    display: none !important;
  }

  html.route-prediction.mobile-device #page-content > div {
    position: relative !important;
    height: 100dvh !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
    padding: 4px 6px !important;
    gap: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary,
  html.route-prediction.mobile-device #prediction-source-plaque,
  html.route-prediction.mobile-device #prediction-units-row,
  html.route-prediction.mobile-device .prediction-header,
  html.route-prediction.mobile-device #prediction-mobile-actions {
    height: 46px !important;
    min-height: 46px !important;
    box-sizing: border-box !important;
    z-index: 5 !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary {
    position: absolute !important;
    top: 4px !important;
    left: 6px !important;
    width: 300px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    margin: 0 !important;
    color: #2c5282 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    padding: 0 10px !important;
    font-size: 26px !important;
    font-weight: 800 !important;
    line-height: 1.1 !important;
    text-align: center !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary #round-indicator {
    width: 100% !important;
    height: 100% !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    margin: 0 !important;
    padding: 0 !important;
    text-align: center !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque {
    position: absolute !important;
    top: 4px !important;
    left: 318px !important;
    right: 420px !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 6px !important;
    width: auto !important;
    padding: 0 10px !important;
    margin: 0 !important;
    overflow: hidden !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque .prediction-source-line {
    display: flex !important;
    align-items: baseline !important;
    min-width: 0 !important;
    flex: 1 1 auto !important;
    gap: 6px !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque .prediction-source-label {
    flex: 0 0 auto !important;
    color: #4a5568 !important;
    font-size: 15px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #data-source-display {
    flex: 0 1 auto !important;
    min-width: 0 !important;
    max-width: 180px !important;
    color: #111827 !important;
    font-size: 17px !important;
    font-weight: 800 !important;
    font-style: normal !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #prediction-chart-meta {
    flex: 0 0 auto !important;
    height: auto !important;
    padding: 0 !important;
    margin: 0 !important;
    color: #111827 !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    font-size: 17px !important;
    font-weight: 800 !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #generic-source-metadata-display {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-units-row {
    position: absolute !important;
    top: 4px !important;
    right: 6px !important;
    left: auto !important;
    bottom: auto !important;
    width: 404px !important;
    display: flex !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 10px !important;
    margin: 0 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    font-size: 18px !important;
  }

  html.route-prediction.mobile-device #prediction-units-row #prediction-units-label,
  html.route-prediction.mobile-device #prediction-units-row #glucose-unit-selector {
    height: auto !important;
    padding: 0 !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device #prediction-chart-submit-wrap {
    position: static !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: 100% !important;
    display: block !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    position: absolute !important;
    top: 46px !important;
    left: 6px !important;
    right: 6px !important;
    bottom: 34px !important;
    z-index: 1 !important;
    width: auto !important;
    max-width: none !important;
    height: auto !important;
    min-height: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    overflow: hidden !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container > #glucose-graph,
  html.route-prediction.mobile-device #prediction-glucose-chart-container #glucose-graph-graph {
    width: 100% !important;
    min-width: 0 !important;
    height: 100% !important;
    min-height: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-header {
    position: absolute !important;
    left: 6px !important;
    bottom: 4px !important;
    width: 220px !important;
    display: block !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device .prediction-header #header-app-title,
  html.route-prediction.mobile-device .prediction-header #header-description,
  html.route-prediction.mobile-device .prediction-header > div > div:nth-child(2) {
    display: none !important;
  }

  html.route-prediction.mobile-device #header-how-to-play {
    height: 46px !important;
    display: flex !important;
    align-items: center !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-toggle {
    width: 220px !important;
    height: 46px !important;
    padding: 0 12px !important;
    color: #1f2a44 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    font-size: 18px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble {
    position: fixed !important;
    left: 160px !important;
    right: 160px !important;
    top: 129px !important;
    max-height: calc(100dvh - 178px) !important;
    overflow: auto !important;
    z-index: 30 !important;
    padding: 16px 46px 16px 18px !important;
    font-size: 19px !important;
    line-height: 1.4 !important;
  }

  html.route-prediction.mobile-device #prediction-mobile-actions {
    position: absolute !important;
    right: 6px !important;
    bottom: 4px !important;
    width: 548px !important;
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-fullscreen-button {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-actions {
    width: 100% !important;
    height: 46px !important;
    display: flex !important;
    flex-direction: row !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device #submit-button,
  html.route-prediction.mobile-device #finish-study-button {
    flex: 0 0 270px !important;
    width: 270px !important;
    height: 46px !important;
    min-height: 46px !important;
    margin: 0 !important;
    padding: 8px 12px !important;
    font-size: 22px !important;
    line-height: 1.2 !important;
  }
}

/* Absolute final landscape corrections: this block intentionally sits last so
   it wins over the older repeated landscape rules above. */
@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    top: 46px !important;
    bottom: 30px !important;
    z-index: 1 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble {
    left: 160px !important;
    right: 160px !important;
    top: 129px !important;
    max-height: calc(100dvh - 178px) !important;
    font-size: 42px !important;
    line-height: 1.16 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble *,
  html.route-prediction.mobile-device .header-how-to-play-bubble .header-how-to-play-body {
    font-size: 42px !important;
    line-height: 1.16 !important;
  }
}

@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #navbar-container {
    display: none !important;
  }

  html.route-prediction.mobile-device #page-content > div {
    position: relative !important;
    height: 100dvh !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
    padding: 4px 6px !important;
    gap: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary,
  html.route-prediction.mobile-device #prediction-source-plaque,
  html.route-prediction.mobile-device #prediction-units-row,
  html.route-prediction.mobile-device .prediction-header,
  html.route-prediction.mobile-device #prediction-mobile-actions {
    height: 46px !important;
    min-height: 46px !important;
    box-sizing: border-box !important;
    z-index: 5 !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary {
    position: absolute !important;
    top: 4px !important;
    left: 6px !important;
    width: 300px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-start !important;
    margin: 0 !important;
    color: #2c5282 !important;
    font-size: 20px !important;
    font-weight: 800 !important;
    line-height: 1.1 !important;
    text-align: left !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque {
    position: absolute !important;
    top: 4px !important;
    left: 318px !important;
    right: 420px !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 6px !important;
    width: auto !important;
    padding: 0 10px !important;
    margin: 0 !important;
    overflow: hidden !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque .prediction-source-line {
    display: flex !important;
    align-items: baseline !important;
    min-width: 0 !important;
    flex: 1 1 auto !important;
    gap: 6px !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque .prediction-source-label {
    flex: 0 0 auto !important;
    color: #4a5568 !important;
    font-size: 15px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #data-source-display {
    flex: 0 1 auto !important;
    min-width: 0 !important;
    max-width: 180px !important;
    color: #111827 !important;
    font-size: 17px !important;
    font-weight: 800 !important;
    font-style: normal !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #prediction-chart-meta {
    flex: 0 0 auto !important;
    height: auto !important;
    padding: 0 !important;
    margin: 0 !important;
    color: #111827 !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    font-size: 17px !important;
    font-weight: 800 !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #generic-source-metadata-display {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-units-row {
    position: absolute !important;
    top: 4px !important;
    right: 6px !important;
    left: auto !important;
    bottom: auto !important;
    width: 404px !important;
    display: flex !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 10px !important;
    margin: 0 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    font-size: 18px !important;
  }

  html.route-prediction.mobile-device #prediction-units-row #prediction-units-label,
  html.route-prediction.mobile-device #prediction-units-row #glucose-unit-selector {
    height: auto !important;
    padding: 0 !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 14px !important;
    width: auto !important;
  }

  html.route-prediction.mobile-device #prediction-chart-submit-wrap {
    position: static !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: 100% !important;
    display: block !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    position: absolute !important;
    top: 46px !important;
    left: 6px !important;
    right: 6px !important;
    bottom: 34px !important;
    z-index: 1 !important;
    width: auto !important;
    max-width: none !important;
    height: auto !important;
    min-height: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    overflow: hidden !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container > #glucose-graph,
  html.route-prediction.mobile-device #prediction-glucose-chart-container #glucose-graph-graph {
    width: 100% !important;
    min-width: 0 !important;
    height: 100% !important;
    min-height: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-header {
    position: absolute !important;
    left: 6px !important;
    bottom: 4px !important;
    width: 220px !important;
    display: block !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device .prediction-header #header-app-title,
  html.route-prediction.mobile-device .prediction-header #header-description,
  html.route-prediction.mobile-device .prediction-header > div > div:nth-child(2) {
    display: none !important;
  }

  html.route-prediction.mobile-device #header-how-to-play {
    height: 46px !important;
    display: flex !important;
    align-items: center !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-toggle {
    width: 220px !important;
    height: 46px !important;
    padding: 0 12px !important;
    color: #1f2a44 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    font-size: 18px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble {
    position: fixed !important;
    left: 160px !important;
    right: 160px !important;
    top: 129px !important;
    max-height: calc(100dvh - 178px) !important;
    overflow: auto !important;
    z-index: 30 !important;
    padding: 16px 46px 16px 18px !important;
    font-size: 19px !important;
    line-height: 1.4 !important;
  }

  html.route-prediction.mobile-device #prediction-mobile-actions {
    position: absolute !important;
    right: 6px !important;
    bottom: 4px !important;
    width: 548px !important;
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-fullscreen-button {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-actions {
    width: 100% !important;
    height: 46px !important;
    display: flex !important;
    flex-direction: row !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device #submit-button,
  html.route-prediction.mobile-device #finish-study-button {
    flex: 0 0 270px !important;
    width: 270px !important;
    height: 46px !important;
    min-height: 46px !important;
    margin: 0 !important;
    padding: 8px 12px !important;
    font-size: 22px !important;
    line-height: 1.2 !important;
  }
}

/* Tap reliability: the viewport allows zoom (user-scalable=yes), so mobile
   browsers wait ~300 ms after each tap for a possible double-tap-zoom and treat
   rapid taps as zoom gestures -- which SWALLOWS clicks, so a button/link only
   fires after several taps (reported: "Next worked on the 4th click", and the
   landing link "fired on the third tap"). `touch-action: manipulation` tells the
   browser there is no double-tap-zoom on these elements, so every tap fires its
   click immediately. Pinch-to-zoom is preserved. NOT applied to the /prediction
   chart, which manages its own touch-action for drawline. */
html.mobile-device:not(.route-prediction) a,
html.mobile-device:not(.route-prediction) button,
html.mobile-device:not(.route-prediction) .ui.button,
html.mobile-device:not(.route-prediction) [role="button"],
html.mobile-device:not(.route-prediction) label,
html.mobile-device:not(.route-prediction) input,
html.mobile-device:not(.route-prediction) .form-check {
  touch-action: manipulation;
}

html.mobile-device:not(.route-prediction) img,
html.mobile-device:not(.route-prediction) iframe,
html.mobile-device:not(.route-prediction) table,
html.mobile-device:not(.route-prediction) .dash-table-container {
  max-width: 100% !important;
}

/* Form controls: the classic chriddyp Dash CSS gives <input> a wide default,
   and dcc.Input wraps it in an inline-block `.dash-input-container` that sizes
   to that wide content -- inflating every ancestor and overflowing the phone.
   Force the whole subtree to block layout capped at the viewport width. */
html.mobile-device:not(.route-prediction) #page-content,
html.mobile-device:not(.route-prediction) #page-content * {
  max-width: 100% !important;
  box-sizing: border-box !important;
}

html.mobile-device .dash-input-container,
html.mobile-device .dash-input,
html.mobile-device .dash-input-element,
html.mobile-device input:not([type="checkbox"]):not([type="radio"]),
html.mobile-device textarea,
html.mobile-device select,
html.mobile-device .dash-dropdown,
html.mobile-device .Select,
html.mobile-device .Select-control {
  display: block !important;
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
}

/* Consent / option checkboxes (dbc.Checklist) render a real
   <input type="checkbox"> next to its label.  The generic input rule above
   used to stretch them to display:block; width:100%, which pushed the label to
   the next line and rendered the box as a full-width empty rectangle.  Keep
   them as small inline boxes sitting beside their (wrapping) label text. */
html.mobile-device .form-check,
html.mobile-device .dash-checklist .form-check,
html.mobile-device label.form-check-label {
  display: flex !important;
  align-items: flex-start !important;
  gap: 8px !important;
  width: 100% !important;
}
html.mobile-device input[type="checkbox"],
html.mobile-device input[type="radio"] {
  display: inline-block !important;
  width: 18px !important;
  min-width: 18px !important;
  height: 18px !important;
  margin: 3px 0 0 0 !important;
  flex: 0 0 auto !important;
}
html.mobile-device .form-check-label {
  display: inline !important;
  width: auto !important;
}

/* dcc.Input applies the Python `style=` to the WRAPPER (.dash-input-container),
   leaving the real <input.dash-input-element> with the tiny chriddyp default --
   which renders as an inset double-box.  Flatten the wrapper and style the
   actual input so it's a single full-width, finger-friendly field. */
html.mobile-device .dash-input-container {
  padding: 0 !important;
  border: none !important;
  background: none !important;
}
html.mobile-device input.dash-input-element {
  padding: 12px 14px !important;
  font-size: 17px !important;
  height: auto !important;
  min-height: 48px !important;
  border: 1px solid #ccc !important;
  border-radius: 6px !important;
}


/* --- Mobile navbar (MobileNavBar: burger + title + language flag) ----------
   The desktop `massive tabular menu` is ~1280px wide and would expand the
   viewport; on mobile we render the compact MobileNavBar instead.  This bar is
   intrinsically narrow so it never widens the layout viewport. */

html.mobile-device .mobile-navbar {
  width: 100%;
  box-sizing: border-box;
}

html.mobile-device .mobile-nav-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #2185d0;            /* Fomantic blue, matches desktop navbar */
  color: #fff;
  padding: 8px 12px;
  box-sizing: border-box;
}

/* Wizard Next button: when the consent gate disables it, make it obviously
   inert (grey + not-allowed), not a dimmed-but-still-blue Fomantic button that
   reads as "clickable but broken". The className is swapped to
   `startup-next-disabled` by gate_mobile_consent_step. */
html.mobile-device #startup-next.startup-next-disabled,
html.mobile-device #startup-next:disabled {
  background-color: #9aa5b1 !important;
  background-image: none !important;
  color: #f1f5f9 !important;
  cursor: not-allowed !important;
  opacity: 1 !important;
  box-shadow: none !important;
}

html.mobile-device .mobile-nav-burger {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  font-size: 26px;
  line-height: 1;
  color: #fff;
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}

html.mobile-device .mobile-nav-burger:active {
  background: rgba(255, 255, 255, 0.18);
}

html.mobile-device .mobile-nav-title {
  flex: 1 1 auto;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

html.mobile-device .mobile-nav-lang {
  flex: 0 0 auto;
}

/* The language dropdown reused from desktop: keep it compact and white-on-blue. */
html.mobile-device .mobile-nav-lang .lang-dropdown {
  color: #fff !important;
  font-size: 15px;
  padding: 6px 4px !important;
}
html.mobile-device .mobile-nav-lang .lang-flag {
  height: 18px !important;
}
/* Open the hover menu to the LEFT so it doesn't overflow the right edge. */
html.mobile-device .mobile-nav-lang .lang-dropdown > .menu {
  left: auto !important;
  right: 0 !important;
}

/* Drawer: full-width stacked links, toggled by the burger. */
html.mobile-device .mobile-nav-drawer {
  background: #1a6fb0;
  width: 100%;
  box-sizing: border-box;
}
html.mobile-device .mobile-nav-drawer .mobile-nav-link {
  display: block;
  padding: 16px 18px;
  color: #fff;
  font-size: 18px;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}
html.mobile-device .mobile-nav-drawer .mobile-nav-link.active {
  background: rgba(255, 255, 255, 0.16);
  font-weight: 700;
}
html.mobile-device .mobile-nav-drawer .mobile-nav-link:active {
  background: rgba(255, 255, 255, 0.24);
}


/* --- Buttons: finger-friendly tap targets (Apple HIG / Material: >=44px) --- */

html.mobile-device .ui.button,
html.mobile-device button.ui {
  min-height: 52px !important;
  font-size: 17px !important;
}

html.mobile-device .landing-mobile-cta.ui.button {
  display: block !important;
  text-decoration: none !important;
}

html.mobile-device #startup-next:disabled,
html.mobile-device #startup-next[disabled] {
  background: #9ca3af !important;
  color: #ffffff !important;
  cursor: not-allowed !important;
  opacity: 0.75 !important;
}

/* The desktop validation callback rewrites #landing-continue's inline width to
   220px; force it full-width on mobile. */
html.mobile-device #landing-continue,
html.mobile-device .landing-continue-mobile {
  width: 100% !important;
}


/* --- Startup wizard inputs: never clip the field box ----------------------
   The flattened dcc.Input wrapper could collapse shorter than the 48px input,
   clipping its bottom border, and the 6px gap made adjacent boxes look
   bottomless.  Force the wrapper to grow with the input and give each field
   breathing room. */
html.mobile-device #startup-page .dash-input-container {
  overflow: visible !important;
  height: auto !important;
  margin-bottom: 16px !important;
}
html.mobile-device #startup-page input.dash-input-element {
  margin-bottom: 0 !important;
}
html.mobile-device #startup-page .dash-dropdown,
html.mobile-device #startup-page .Select {
  margin-bottom: 16px !important;
}

/* Number fields (age, CGM/diabetes duration): Dash renders its own
   `.dash-input-stepper` -/+ buttons inside the input wrapper.  Once the input
   is forced full-width (display:block) on mobile, those steppers wrap to a
   second line and render as stray "-"/"+" controls below the field.  They add
   nothing on a touch keypad, so hide them (and the native webkit spinner). */
html.mobile-device .dash-input-stepper {
  display: none !important;
}
html.mobile-device input[type="number"] {
  -moz-appearance: textfield !important;
  appearance: textfield !important;
}
html.mobile-device input[type="number"]::-webkit-outer-spin-button,
html.mobile-device input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none !important;
  margin: 0 !important;
}


/* --- Info pages (about / faq / contact / demo) ---------------------------- */

html.mobile-device .info-page {
  /* The desktop `max-width: clamp(320px, 85vw, 1400px)` centres the page and
     wastes ~15-30% of a phone's width as side margins.  On mobile let the
     content use the full viewport (padding is the only inset). */
  max-width: 100% !important;
  padding: 16px clamp(12px, 4vw, 24px) 32px !important;
}

html.mobile-device .demo-page .demo-fullscreen-button.ui.button {
  width: 100% !important;
  margin-top: 14px !important;
  padding: 15px 18px !important;
  font-size: 18px !important;
  border-radius: 12px !important;
}

/* --- Contact page: bigger fonts, sized so the team email is the longest
   single line and still fits with a comfortable safety margin -------------- */
html.mobile-device .contact-page .contact-intro {
  font-size: 17px !important;
  line-height: 1.55 !important;
  color: #374151 !important;
}
html.mobile-device .contact-page h2 {
  font-size: 24px !important;
}
/* The general team email is the binding longest unbreakable line; size it up
   to fill the reclaimed width while keeping a ~12-18% safety margin. */
html.mobile-device .contact-page .contact-general-email {
  font-size: 20px !important;
  white-space: nowrap !important;
}

/* Contact tables: on a phone the 2-3 column tables squeeze the link/email cell
   so narrow that long URLs/emails wrap with ugly 1-2 char danglers ("...rostock."
   / "de").  Collapse each table to a single stacked column so every value gets
   the full viewport width (most links then fit on one line), and use a slightly
   narrower link font that breaks cleanly when a token is still too long. */
html.mobile-device .info-page .contact-table thead {
  display: none !important;
}
html.mobile-device .info-page .contact-table,
html.mobile-device .info-page .contact-table tbody,
html.mobile-device .info-page .contact-table tr,
html.mobile-device .info-page .contact-table td {
  display: block !important;
  width: 100% !important;
}
html.mobile-device .info-page .contact-table tr {
  padding: 8px 0 !important;
  border-bottom: 1px solid rgba(15, 23, 42, 0.10) !important;
}
html.mobile-device .info-page .contact-table td {
  padding: 1px 0 !important;
  border-bottom: none !important;
}
/* Secondary plain-text cells (e.g. the LinkedIn role) — kept a touch smaller
   and muted so the link/heading hierarchy reads cleanly. */
html.mobile-device .info-page .contact-table td {
  font-size: 17px !important;
}
/* First cell of each row (the name / platform) reads as the row's heading, so
   it should be the largest text in the row, proportional to the beefed links. */
html.mobile-device .info-page .contact-table td:first-child {
  font-weight: 700 !important;
  color: #0f172a !important;
  font-size: 22px !important;
}
/* Per-contact emails / link labels: beefed up to the team-email size and still
   on one line.  The long study emails are the binding line here. */
html.mobile-device .info-page .contact-table a {
  font-size: 20px !important;
  letter-spacing: -0.01em !important;
  overflow-wrap: anywhere !important;
  word-break: normal !important;
}
/* Short link labels (social/platform URLs, "Open profile") have plenty of room,
   so make them slightly bigger and bolder to read as proper tap targets. */
html.mobile-device .info-page .contact-table a[href^="http"] {
  font-size: 21px !important;
  font-weight: 600 !important;
}


/* --- Consent form page (/consent-form): full-bleed TOS-style reader --------
   The standalone consent page used to nest the scrolling text inside a bordered
   card with margins, wasting space and showing a box-in-a-box.  On mobile make
   it one full-width scrollable panel that fills the screen, with the back
   button anchored below it (the iframe owns the only scrollbar). */
html.mobile-device #consent-form-page .consent-form-shell {
  padding: 12px !important;
}
html.mobile-device #consent-form-page .consent-form-text {
  border-radius: 10px !important;
}


/* ===========================================================================
   /prediction ONLY (html.route-prediction). Builds the immersive chart and
   sizes chart fonts. (Historically these compensated for a 1280 scale-down;
   /prediction is now device-width, so they render at native size.)
   =========================================================================== */

/* Chart tick / axis labels: bumped up from Plotly's small default. */
html.route-prediction.mobile-device .js-plotly-plot .xtick text,
html.route-prediction.mobile-device .js-plotly-plot .ytick text,
html.route-prediction.mobile-device .js-plotly-plot .legendtext {
  font-size: 16px !important;
}

html.route-prediction.mobile-device .js-plotly-plot .xtitle,
html.route-prediction.mobile-device .js-plotly-plot .ytitle {
  font-size: 18px !important;
}

html.route-prediction.mobile-device .js-plotly-plot .gtitle {
  font-size: 20px !important;
}

/* Blanket text bump on the chart page. */
html.route-prediction.mobile-device body :not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(.js-plotly-plot *) {
  font-size: 18px !important;
}

/* Tighten outer padding so the chart gets vertical room. */
html.route-prediction.mobile-device #page-content > div {
  padding-top: 8px !important;
  padding-bottom: 8px !important;
  gap: 10px !important;
}

html.route-prediction.mobile-device #prediction-glucose-chart-container {
  min-height: 380px;
}

html.route-prediction.mobile-device #submit-button {
  min-height: 64px !important;
  font-size: 22px !important;
}

/* Immersive landscape: collapse all chrome (navbar, the instructional header,
   round indicator) so the chart fills the screen.  Native Plotly only -- never
   CSS-rotate (breaks drawline touch mapping). */

/* Persistent "Go fullscreen" button. Hidden everywhere by default; shown only on
   mobile /prediction in PORTRAIT as a prominent bottom CTA. It's the gesture-
   reliable way into the immersive landscape view when the wizard Start-button
   auto-trigger didn't run (e.g. re-entering /prediction from the burger menu).
   In landscape it stays hidden -- that orientation is already the immersive,
   playable layout, and a floating button would overlap the chart/draw area. */
.prediction-fullscreen-button {
  display: none;
}
@media (orientation: portrait) {
  html.route-prediction.mobile-device,
  html.route-prediction.mobile-device body {
    min-width: 0 !important;
    max-width: 100vw !important;
    overflow-x: hidden !important;
    background: #f8fafc !important;
  }

  html.route-prediction.mobile-device #page-content {
    max-width: 100vw !important;
    overflow-x: hidden !important;
    box-sizing: border-box !important;
  }

  html.route-prediction.mobile-device #page-content > div {
    width: 100% !important;
    max-width: 100% !important;
    padding: 12px !important;
    gap: 6px !important;
    box-sizing: border-box !important;
  }

  html.route-prediction.mobile-device .prediction-header {
    padding: 2px 10px !important;
    margin-bottom: 0 !important;
    border-radius: 10px !important;
    order: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-header #header-app-title {
    display: none !important;
  }

  html.route-prediction.mobile-device .prediction-header > div {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 2px !important;
  }

  html.route-prediction.mobile-device .prediction-header > div > div {
    flex: 0 0 auto !important;
    width: 100% !important;
    padding-right: 0 !important;
  }

  html.route-prediction.mobile-device #header-description {
    display: none !important;
  }

  html.route-prediction.mobile-device #header-how-to-play {
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
    font-size: 15px !important;
    line-height: 1.3 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-toggle {
    cursor: pointer !important;
    font-weight: 800 !important;
    color: #2c5282 !important;
    padding: 2px 0 !important;
    touch-action: manipulation !important;
    border: 0 !important;
    background: transparent !important;
    font: inherit !important;
    text-align: left !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-toggle::before {
    content: "▶ ";
  }

  html.route-prediction.mobile-device #header-how-to-play:has(.header-how-to-play-bubble[style*="block"]) .header-how-to-play-toggle::before {
    content: "▼ ";
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble {
    position: relative !important;
    margin-top: 0 !important;
    padding: 2px 0 4px 24px !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-close {
    display: none !important;
  }

  html.route-prediction.mobile-device #header-how-to-play .header-how-to-play-body {
    padding: 0 !important;
  }

  html.route-prediction.mobile-device #data-source-display,
  html.route-prediction.mobile-device #generic-source-metadata-display {
    font-size: 14px !important;
    line-height: 1.25 !important;
  }

  html.route-prediction.mobile-device #data-source-display {
    color: #111827 !important;
    font-size: 16px !important;
    font-weight: 800 !important;
    font-style: normal !important;
  }

  html.route-prediction.mobile-device #generic-source-metadata-display {
    width: 100% !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
  }

  html.route-prediction.mobile-device #header-data-source-label {
    font-size: 14px !important;
  }

  html.route-prediction.mobile-device #round-indicator {
    display: block !important;
    margin-bottom: 0 !important;
    font-size: inherit !important;
    font-weight: inherit !important;
    color: inherit !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary {
    display: block !important;
    order: -1 !important;
    text-align: center !important;
    margin: 0 !important;
    color: #2c5282 !important;
    font-size: 19px !important;
    font-weight: 800 !important;
    line-height: 1.25 !important;
  }

  html.route-prediction.mobile-device #prediction-round-tagline {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-units-row {
    justify-content: flex-end !important;
    flex-wrap: nowrap !important;
    gap: 8px !important;
    margin-top: 4px !important;
    margin-bottom: 4px !important;
    margin-left: auto !important;
    align-self: flex-end !important;
    padding: 7px 10px !important;
    width: fit-content !important;
    border: 1px solid rgba(75, 95, 130, 0.18) !important;
    border-radius: 10px !important;
    background: #ffffff !important;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08) !important;
    font-size: 15px !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 12px !important;
    width: auto !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector .form-check {
    width: auto !important;
    margin: 0 !important;
    display: flex !important;
    align-items: center !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector input[type="radio"] {
    margin-top: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-chart-meta {
    width: auto !important;
    margin-right: 0 !important;
    color: #111827 !important;
    font-weight: 800 !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-chart-submit-wrap {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
    min-width: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    width: 100% !important;
    max-width: 100% !important;
    height: 370px !important;
    min-height: 370px !important;
    overflow-x: scroll !important;
    overflow-y: hidden !important;
    box-sizing: border-box !important;
    padding: 0 0 10px 0 !important;
    background: #ffffff !important;
    border: 4px solid #c4d7ee !important;
    border-radius: 14px !important;
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.12) !important;
    scrollbar-color: #2185d0 #dbeafe !important;
    scrollbar-width: auto !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container::-webkit-scrollbar {
    height: 22px !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container::-webkit-scrollbar-track {
    background: #dbeafe !important;
    border-radius: 999px !important;
    box-shadow: inset 0 0 0 2px #bfdbfe !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container::-webkit-scrollbar-thumb {
    background: #2185d0 !important;
    border: 4px solid #dbeafe !important;
    border-radius: 999px !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container > #glucose-graph,
  html.route-prediction.mobile-device #prediction-glucose-chart-container #glucose-graph-graph {
    width: 900px !important;
    min-width: 900px !important;
    height: 340px !important;
    min-height: 340px !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque {
    display: flex !important;
    flex-direction: column !important;
    gap: 4px !important;
    width: 100% !important;
    box-sizing: border-box !important;
    padding: 10px 14px !important;
    background: #f7fafc !important;
    border-radius: 10px !important;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08) !important;
  }

  html.route-prediction.mobile-device .prediction-source-line {
    display: flex !important;
    align-items: baseline !important;
    gap: 6px !important;
    min-width: 0 !important;
    width: 100% !important;
  }

  html.route-prediction.mobile-device .prediction-source-label {
    flex: 0 0 auto !important;
    color: #4a5568 !important;
    font-size: 14px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device .prediction-source-name {
    flex: 0 1 auto !important;
    min-width: 0 !important;
    color: #111827 !important;
    font-size: 16px !important;
    font-weight: 800 !important;
    font-style: normal !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device .prediction-source-time::before {
    content: "·";
    margin-right: 6px;
  }

  html.route-prediction.mobile-device .prediction-source-metadata {
    color: #2c5282 !important;
    font-size: 14px !important;
    font-style: italic !important;
    font-weight: 500 !important;
    line-height: 1.2 !important;
    width: 100% !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
  }

  html.route-prediction.mobile-device #prediction-mobile-actions {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important;
    gap: 10px 12px !important;
    align-items: stretch !important;
    width: 100% !important;
    box-sizing: border-box !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-actions {
    grid-column: 2 !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: stretch !important;
    align-items: stretch !important;
    gap: 8px !important;
    width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-progress-label {
    display: none !important;
  }

  html.route-prediction.mobile-device #submit-button,
  html.route-prediction.mobile-device #finish-study-button {
    width: 100% !important;
    height: 60px !important;
    min-height: 60px !important;
    margin: 0 !important;
    padding: 8px 10px !important;
    font-size: 17px !important;
    line-height: 1.15 !important;
    border-radius: 10px !important;
    white-space: normal !important;
  }

  html.route-prediction.mobile-device .prediction-fullscreen-button {
    display: flex;
    grid-column: 1 !important;
    grid-row: 1 / span 2 !important;
    width: 100%;
    min-height: 128px;
    align-items: center;
    justify-content: center;
    padding: 14px 12px;
    box-sizing: border-box;
    font-size: 18px;
    font-weight: 800;
    line-height: 1.2;
    text-align: center;
    color: #fff;
    background: #2185d0;
    border: 0;
    border-radius: 14px;
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.26);
    cursor: pointer;
    touch-action: manipulation;
    white-space: normal;
  }
  html.route-prediction.mobile-device .prediction-fullscreen-button:active {
    transform: scale(0.97);
  }
}

/* NOTE: gated on orientation + coarse pointer ONLY. We deliberately dropped the
   old `max-device-width: 1024px` clause: on real phones the landscape device-width
   can exceed 1024 (high-DPI / the 1280 layout viewport this page forces), so that
   clause made the media query FAIL on rotation and the immersive layout never
   applied -- the chart stayed full-size and Submit/Finish fell off the bottom.
   The `html.mobile-device` selector scope already restricts this to phones, so
   the device-width clause was both redundant and the bug. */
@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #navbar-container,
  html.route-prediction.mobile-device .prediction-header,
  html.route-prediction.mobile-device #prediction-round-summary,
  html.route-prediction.mobile-device #prediction-source-plaque {
    display: none !important;
  }
  /* Pin the page to exactly one viewport and let the chart flex-fill whatever
     height is left after the (compact) units row and the submit button.  The
     old fixed `min-height: 82vh` on the chart, stacked under the units row and
     above submit, overflowed past 100vh and cropped the x-axis + submit off the
     bottom of the screen. */
  html.route-prediction.mobile-device #page-content > div {
    /* 100dvh (dynamic viewport height) = the CURRENTLY visible area, which
       shrinks when the browser chrome (address bar) is shown. Plain 100vh is the
       chrome-excluded tall viewport, so with the address bar visible the bottom
       control strip (Submit/Finish) was pushed below the fold and unreachable
       (overflow:hidden + the chart eats touch-scroll). dvh keeps it on-screen. */
    height: 100dvh !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
    padding: 4px 6px !important;
    gap: 4px !important;
  }
  html.route-prediction.mobile-device #prediction-units-row {
    position: absolute !important;
    left: 6px !important;
    right: 550px !important;
    bottom: 4px !important;
    z-index: 2 !important;
    height: 46px !important;
    margin-bottom: 0 !important;
    display: flex !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    white-space: nowrap !important;
    font-size: 22px !important;
  }
  html.route-prediction.mobile-device #prediction-chart-meta {
    max-width: 270px !important;
    height: 46px !important;
    display: flex !important;
    align-items: center !important;
    box-sizing: border-box !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    margin-right: auto !important;
    padding: 0 12px !important;
    color: #1f2a44 !important;
    background: linear-gradient(180deg, #ffffff 0%, #eef3f8 100%) !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.9),
      inset 0 -1px 0 rgba(25, 45, 75, 0.08),
      0 1px 3px rgba(25, 45, 75, 0.18) !important;
  }
  html.route-prediction.mobile-device #prediction-units-label {
    height: 46px !important;
    display: flex !important;
    align-items: center !important;
    box-sizing: border-box !important;
    margin: 0 !important;
    padding: 0 8px 0 10px !important;
    color: #1f2a44 !important;
    background: rgba(255, 255, 255, 0.94) !important;
    border: 1px solid rgba(75, 95, 130, 0.25) !important;
    border-right: 0 !important;
    border-radius: 8px 0 0 8px !important;
  }
  html.route-prediction.mobile-device #glucose-unit-selector {
    height: 46px !important;
    display: flex !important;
    align-items: center !important;
    box-sizing: border-box !important;
    gap: 8px !important;
    padding: 0 10px 0 6px !important;
    background: rgba(255, 255, 255, 0.94) !important;
    border: 1px solid rgba(75, 95, 130, 0.25) !important;
    border-left: 0 !important;
    border-radius: 0 8px 8px 0 !important;
  }
  html.route-prediction.mobile-device #glucose-unit-selector .form-check {
    display: flex !important;
    align-items: center !important;
    margin: 0 !important;
    min-height: 0 !important;
  }
  html.route-prediction.mobile-device #glucose-unit-selector .form-check-input {
    margin: 0 4px 0 0 !important;
  }
  html.route-prediction.mobile-device #glucose-unit-selector .form-check-label {
    margin: 0 !important;
  }
  /* chart + action row wrapper becomes a column that owns the remaining height */
  html.route-prediction.mobile-device #prediction-chart-submit-wrap {
    flex: 1 1 auto !important;
    display: flex !important;
    flex-direction: column !important;
    min-height: 0 !important;
    gap: 4px !important;
  }
  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
  }
  html.route-prediction.mobile-device #prediction-actions {
    flex: 0 0 46px !important;
    display: flex !important;
    flex-direction: row !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    width: 100% !important;
    padding-left: 330px !important;
  }
  html.route-prediction.mobile-device #prediction-progress-label {
    display: none !important;
  }
  html.route-prediction.mobile-device #submit-button,
  html.route-prediction.mobile-device #finish-study-button {
    flex: 0 0 auto !important;
    width: 264px !important;
    height: 46px !important;
    min-height: 46px !important;
    font-size: 22px !important;
    line-height: 1.2 !important;
    margin: 0 !important;
    padding: 8px 12px !important;
  }
}

/* Final landscape composition: header | graph | footer. Kept after the legacy
   landscape rules above so these declarations win. */
@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #navbar-container {
    display: none !important;
  }

  html.route-prediction.mobile-device #page-content > div {
    position: relative !important;
    height: 100dvh !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
    padding: 4px 6px !important;
    gap: 0 !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary,
  html.route-prediction.mobile-device #prediction-source-plaque,
  html.route-prediction.mobile-device #prediction-units-row,
  html.route-prediction.mobile-device .prediction-header,
  html.route-prediction.mobile-device #prediction-mobile-actions {
    height: 46px !important;
    min-height: 46px !important;
    box-sizing: border-box !important;
    z-index: 5 !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary {
    position: absolute !important;
    top: 4px !important;
    left: 6px !important;
    width: 300px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: flex-start !important;
    margin: 0 !important;
    color: #2c5282 !important;
    font-size: 20px !important;
    font-weight: 800 !important;
    line-height: 1.1 !important;
    text-align: left !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque {
    position: absolute !important;
    top: 4px !important;
    left: 318px !important;
    right: 420px !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 6px !important;
    width: auto !important;
    padding: 0 10px !important;
    margin: 0 !important;
    overflow: hidden !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque .prediction-source-line {
    display: flex !important;
    align-items: baseline !important;
    min-width: 0 !important;
    flex: 1 1 auto !important;
    gap: 6px !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque .prediction-source-label {
    flex: 0 0 auto !important;
    color: #4a5568 !important;
    font-size: 15px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #data-source-display {
    flex: 0 1 auto !important;
    min-width: 0 !important;
    max-width: 180px !important;
    color: #111827 !important;
    font-size: 17px !important;
    font-weight: 800 !important;
    font-style: normal !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #prediction-chart-meta {
    flex: 0 0 auto !important;
    height: auto !important;
    padding: 0 !important;
    margin: 0 !important;
    color: #111827 !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    font-size: 17px !important;
    font-weight: 800 !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #prediction-source-plaque #generic-source-metadata-display {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-units-row {
    position: absolute !important;
    top: 4px !important;
    right: 6px !important;
    left: auto !important;
    bottom: auto !important;
    width: 404px !important;
    display: flex !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 10px !important;
    margin: 0 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    font-size: 18px !important;
  }

  html.route-prediction.mobile-device #prediction-units-row #prediction-units-label,
  html.route-prediction.mobile-device #prediction-units-row #glucose-unit-selector {
    height: auto !important;
    padding: 0 !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device #prediction-chart-submit-wrap {
    position: static !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: 100% !important;
    display: block !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    position: absolute !important;
    top: 54px !important;
    left: 6px !important;
    right: 6px !important;
    bottom: 54px !important;
    width: auto !important;
    max-width: none !important;
    height: auto !important;
    min-height: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    overflow: hidden !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container > #glucose-graph,
  html.route-prediction.mobile-device #prediction-glucose-chart-container #glucose-graph-graph {
    width: 100% !important;
    min-width: 0 !important;
    height: 100% !important;
    min-height: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-header {
    position: absolute !important;
    left: 6px !important;
    bottom: 4px !important;
    width: 220px !important;
    display: block !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device .prediction-header #header-app-title,
  html.route-prediction.mobile-device .prediction-header #header-description,
  html.route-prediction.mobile-device .prediction-header > div > div:nth-child(2) {
    display: none !important;
  }

  html.route-prediction.mobile-device #header-how-to-play {
    height: 46px !important;
    display: flex !important;
    align-items: center !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-toggle {
    width: 220px !important;
    height: 46px !important;
    padding: 0 12px !important;
    color: #1f2a44 !important;
    background: #ffffff !important;
    border: 1px solid rgba(75, 95, 130, 0.35) !important;
    border-radius: 8px !important;
    box-shadow: 0 1px 3px rgba(25, 45, 75, 0.18) !important;
    font-size: 18px !important;
    font-weight: 800 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble {
    position: fixed !important;
    left: 110px !important;
    right: 110px !important;
    top: 70px !important;
    max-height: calc(100dvh - 140px) !important;
    overflow: auto !important;
    z-index: 30 !important;
    padding: 16px 50px 16px 18px !important;
    background: #ffffff !important;
    border: 2px solid #93c5fd !important;
    border-radius: 12px !important;
    box-shadow: 0 18px 40px rgba(15, 23, 42, 0.32) !important;
    font-size: 80px !important;
    line-height: 1.12 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-close {
    position: absolute !important;
    top: 10px !important;
    right: 12px !important;
    left: auto !important;
    width: 32px !important;
    height: 32px !important;
    border: 1px solid rgba(75, 95, 130, 0.25) !important;
    border-radius: 999px !important;
    background: #f8fafc !important;
    color: #334155 !important;
    font-size: 24px !important;
    line-height: 1 !important;
    text-align: center !important;
    cursor: pointer !important;
    z-index: 31 !important;
    padding: 0 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-body {
    padding-right: 34px !important;
    font-size: 80px !important;
    line-height: 1.12 !important;
  }

  html.route-prediction.mobile-device #prediction-mobile-actions {
    position: absolute !important;
    right: 6px !important;
    bottom: 4px !important;
    width: 548px !important;
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  html.route-prediction.mobile-device .prediction-fullscreen-button {
    display: none !important;
  }

  html.route-prediction.mobile-device #prediction-actions {
    width: 100% !important;
    height: 46px !important;
    display: flex !important;
    flex-direction: row !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device #submit-button,
  html.route-prediction.mobile-device #finish-study-button {
    flex: 0 0 270px !important;
    width: 270px !important;
    height: 46px !important;
    min-height: 46px !important;
    margin: 0 !important;
    padding: 8px 12px !important;
    font-size: 22px !important;
    line-height: 1.2 !important;
  }
}

/* Absolute compact portrait corrections. This block must stay last because the
   file contains older repeated prediction rules that otherwise override it. */
@media (orientation: portrait) {
  html.route-prediction.mobile-device #page-content > div {
    position: relative !important;
    padding: 4px 14px !important;
    gap: 4px !important;
  }

  html.route-prediction.mobile-device #prediction-round-summary {
    order: -2 !important;
    height: 44px !important;
    min-height: 44px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 138px 0 0 !important;
    margin: 0 !important;
    font-size: 18px !important;
    line-height: 1.1 !important;
    text-align: center !important;
  }

  html.route-prediction.mobile-device #round-indicator {
    width: 100% !important;
    margin: 0 !important;
    line-height: 1.1 !important;
  }

  html.route-prediction.mobile-device #prediction-units-row {
    position: absolute !important;
    top: 4px !important;
    right: 14px !important;
    left: auto !important;
    bottom: auto !important;
    width: 132px !important;
    height: 44px !important;
    min-height: 44px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 5px !important;
    padding: 2px 6px !important;
    margin: 0 !important;
    align-self: auto !important;
    box-sizing: border-box !important;
    font-size: 12px !important;
    line-height: 1 !important;
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
  }

  html.route-prediction.mobile-device #prediction-units-label {
    margin: 0 !important;
    padding: 0 !important;
    font-size: 12px !important;
    line-height: 1 !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector {
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 0 !important;
    width: auto !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector .form-check {
    width: auto !important;
    min-height: 0 !important;
    height: 19px !important;
    margin: 0 !important;
    display: flex !important;
    align-items: center !important;
    gap: 4px !important;
    line-height: 1 !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector input[type="radio"] {
    width: 14px !important;
    min-width: 14px !important;
    height: 14px !important;
    margin: 0 !important;
  }

  html.route-prediction.mobile-device #glucose-unit-selector .form-check-label {
    margin: 0 !important;
    font-size: 13px !important;
    line-height: 1 !important;
    white-space: nowrap !important;
  }

  html.route-prediction.mobile-device .prediction-header {
    order: -1 !important;
    padding: 0 !important;
    margin: 0 !important;
    border-radius: 8px !important;
  }

  html.route-prediction.mobile-device .prediction-header > div {
    gap: 0 !important;
  }

  html.route-prediction.mobile-device #header-how-to-play {
    line-height: 1.05 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-toggle {
    width: 100% !important;
    min-height: 32px !important;
    padding: 4px 10px !important;
    font-size: 16px !important;
    line-height: 1.05 !important;
  }

  html.route-prediction.mobile-device .header-how-to-play-bubble {
    padding: 2px 0 3px 22px !important;
    line-height: 1.16 !important;
  }

  html.route-prediction.mobile-device #prediction-chart-submit-wrap {
    gap: 4px !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container {
    height: 392px !important;
    min-height: 392px !important;
  }

  html.route-prediction.mobile-device #prediction-glucose-chart-container > #glucose-graph,
  html.route-prediction.mobile-device #prediction-glucose-chart-container #glucose-graph-graph {
    height: 362px !important;
    min-height: 362px !important;
  }

  html.route-prediction.mobile-device #prediction-mobile-actions {
    gap: 6px 10px !important;
    grid-template-rows: 86px !important;
    align-items: stretch !important;
  }

  html.route-prediction.mobile-device #prediction-actions {
    height: 86px !important;
    min-height: 86px !important;
    max-height: 86px !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    justify-content: stretch !important;
    gap: 6px !important;
  }

  html.route-prediction.mobile-device #submit-button,
  html.route-prediction.mobile-device #finish-study-button {
    flex: 0 0 40px !important;
    width: 100% !important;
    height: 40px !important;
    min-height: 40px !important;
    max-height: 40px !important;
    margin: 0 !important;
    padding: 4px 8px !important;
    font-size: 16px !important;
    line-height: 1.05 !important;
    border-radius: 10px !important;
  }

  html.route-prediction.mobile-device .prediction-fullscreen-button {
    height: 86px !important;
    min-height: 86px !important;
    max-height: 86px !important;
    padding: 7px 10px !important;
    font-size: 16px !important;
    line-height: 1.1 !important;
    border-radius: 12px !important;
  }
}

/* --- Landscape header fine-tuning (final override, must stay last) ----------
   The Round and Units chips had excess whitespace while the Source plaque was
   squashed (filename hidden, only half the time range visible). Shrink Round to
   75% (300->225) and Units to 60% (404->242) of their width and pull the Source
   plaque's left/right edges in so it gets the freed space. Also drop the
   how-to-play bubble font 20% (80->64). Appended last so it wins over the three
   earlier (duplicated) landscape blocks. */
@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #prediction-round-summary {
    width: 225px !important;
  }
  html.route-prediction.mobile-device #prediction-source-plaque {
    left: 237px !important;
    right: 252px !important;
  }
  html.route-prediction.mobile-device #prediction-units-row {
    width: 242px !important;
  }
  html.route-prediction.mobile-device .header-how-to-play-bubble,
  html.route-prediction.mobile-device .header-how-to-play-body {
    font-size: 64px !important;
  }
}

/* =====================================================================
   Format B/C CSV upload button + Format B upload gate.
   The single dcc.Upload (id='upload-data') is relocated from the header into
   the submit action row so it stays reachable in immersive landscape (where the
   header is hidden). It is styled as a button matching Submit and sits to its
   LEFT. `.prediction-upload-gate` replaces the chart for "my data only" (B)
   until a file is uploaded. Appended last so these win.
   ===================================================================== */
/* The dcc.Upload ROOT element is div#upload-data -- that is the real flex/grid
   item. The className we pass lands on an inner node, so style AND size the
   button via #upload-data itself (targeting the inner class left it width:0). */
#upload-data {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  cursor: pointer;
  background-color: #2185d0;
  color: #fff !important;
  border: 0;
  border-radius: 6px;
  font-weight: 700;
  text-align: center;
  touch-action: manipulation;
  width: 300px;
  height: 60px;
  font-size: 20px;
  margin: 0 auto 10px auto;
  overflow: hidden;
  white-space: nowrap;
}
#upload-data:active { transform: scale(0.97); }
/* Hitbox fix: the real dcc.Upload dropzone is the inner .prediction-upload-button
   (it holds the hidden <input type=file>), which otherwise shrinks to the text
   (~64x20) so only the label was clickable -- the rest of the blue rectangle did
   nothing. Make the dropzone fill #upload-data so the WHOLE button opens the file
   dialog. The absolutely-positioned inner <input> (inset:0) then covers it too. */
#upload-data > .prediction-upload-button {
  width: 100% !important;
  height: 100% !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}
/* The label text lives in #header-upload-prompt (a nested element), which the
   broad `body :not(...) { font-size:18px !important }` rule shrinks -- making
   "Upload" thinner/smaller than the Fomantic buttons. Two IDs beat that rule, so
   match the sibling buttons' size + weight here. */
#upload-data #header-upload-prompt {
  margin: 0;
  color: #fff;
  font-size: 20px !important;
  font-weight: 700 !important;
}
#upload-data a { color: #fff; text-decoration: none; }

.prediction-upload-gate {
  padding: 28px 24px;
  margin: 20px auto;
  max-width: 780px;
  background: #eef5ff;
  border: 1px dashed #2185d0;
  border-radius: 12px;
  color: #1f2a44;
  line-height: 1.45;
  text-align: center;
}
/* Enlarge the gate PANE text (~2x) and scale it with the viewport width. Must be
   ID-scoped: a broad `html.route-prediction.mobile-device body :not(...)`
   `font-size:18px !important` rule outweighs a class selector, so only an ID
   selector (higher specificity) wins here. */
#prediction-upload-gate {
  font-size: clamp(34px, 2.8vw, 56px) !important;
}

/* Format-B gated state (no upload yet): hide the Source plaque entirely -- its
   time/metadata reflect the stale example seed and are meaningless here. Must
   beat the immersive-landscape rule that re-shows the plaque with !important. */
#prediction-chart-submit-wrap.b-gated #prediction-source-plaque {
  display: none !important;
}

/* ---- Uniform action buttons for formats B/C (`has-upload`) ----
   The action strip holds Fullscreen + Upload + Submit + Finish. `display:contents`
   on #prediction-actions promotes Submit/Finish up so all four are siblings of the
   strip and can be sized identically. A-mode (no `has-upload`) keeps its original
   Fullscreen(2x)+Submit/Finish layout untouched. */

/* Portrait B/C: 2x2 grid -> column 1 = Fullscreen / Upload, column 2 = Submit /
   Finish; all four identical. (column flow fills top-to-bottom then next column.) */
@media (orientation: portrait) {
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    grid-template-rows: 1fr 1fr !important;
    grid-auto-flow: column !important;
    gap: 10px 12px !important;
    align-items: stretch !important;
    width: 100% !important;
    margin: 0 !important;
  }
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #prediction-actions {
    display: contents !important;
  }
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload .prediction-fullscreen-button,
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #upload-data,
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #submit-button,
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #finish-study-button {
    grid-row: auto !important;
    grid-column: auto !important;
    width: 100% !important;
    min-width: 0 !important;
    height: 48px !important;
    min-height: 48px !important;
    margin: 0 !important;
    font-size: 20px !important;
    box-sizing: border-box !important;
  }
}

/* Landscape B/C: one row of three equal buttons (Upload | Submit | Finish),
   Fullscreen hidden. Widen the strip from 548px so three ~264px buttons fit
   (they overflowed left onto the How-to-play toggle at 548px). */
@media (orientation: landscape) and (pointer: coarse) {
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload {
    display: flex !important;
    flex-direction: row !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    width: 828px !important;
  }
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #prediction-actions {
    display: contents !important;
  }
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #upload-data,
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #submit-button,
  html.route-prediction.mobile-device #prediction-mobile-actions.has-upload #finish-study-button {
    flex: 1 1 0 !important;
    width: 0 !important;
    min-width: 0 !important;
    height: 46px !important;
    min-height: 46px !important;
    font-size: 20px !important;
    margin: 0 !important;
    box-sizing: border-box !important;
  }
  /* Gate fills the freed chart area. The top header chips (Round/Source/Units)
     are absolutely positioned over the first ~50px, so push the gate below them
     to avoid clipping. No display override here -- the toggle callback owns
     display via inline style. */
  html.route-prediction.mobile-device .prediction-upload-gate {
    flex: 0 0 auto !important;
    margin: 68px auto 8px auto !important;
    max-width: 92% !important;
  }
}
