/* lint-rules:ignore-font-size-file lint-rules:ignore-hex-file
 *
 * Grandfathered: this file pre-dates strict enforcement of the type-scale
 * (--fs-xs/sm/base/lg/xl) and hex-color rules. Existing declarations are
 * exempt; new declarations should use tokens. The grandfathering is a
 * known debt; see scripts/lint-rules.py for context.
 */
/* ── MOBILE NAV ── */
.mobile-menu-btn{display:none;background:none;border:1px solid var(--border);border-radius:6px;padding:6px 9px;cursor:pointer;color:var(--text2);font-size:18px;line-height:1;flex-shrink:0;}
.mobile-menu-btn:hover{color:var(--text);border-color:var(--border2);}
.nav-overlay{position:fixed;inset:0;z-index:9990;background:rgba(0,0,0,.55);opacity:0;pointer-events:none;transition:opacity .2s ease;}
.nav-overlay.open{opacity:1;pointer-events:auto;}
.nav-drawer{position:fixed;top:0;left:0;bottom:0;z-index:9999;isolation:isolate;width:min(80vw,280px);background:var(--surface);border-right:1px solid var(--border);display:flex;flex-direction:column;padding:16px 0 max(16px,env(safe-area-inset-bottom));transform:translateX(-100%);transition:transform .22s cubic-bezier(.4,0,.2,1);-webkit-overflow-scrolling:touch;overflow-y:auto;}
.nav-drawer.open{transform:translateX(0);}
.nav-drawer-header{display:flex;align-items:center;justify-content:space-between;padding:0 20px 16px;border-bottom:1px solid var(--border);margin-bottom:8px;flex-shrink:0;}
.nav-drawer-title{font-family:var(--font-ui);font-size:14px;font-weight:600;color:var(--text);}
.nav-close{background:none;border:none;color:var(--muted);font-size:24px;cursor:pointer;padding:4px 8px;line-height:1;}
.nav-close:hover{color:var(--text);}
.nav-drawer-item{display:flex;align-items:center;gap:10px;padding:13px 20px;color:var(--text2);font-size:14px;font-family:var(--font-ui);cursor:pointer;border:none;background:none;width:100%;text-align:left;transition:background .15s,color .15s;border-left:2px solid transparent;}
.nav-drawer-item:hover,.nav-drawer-item.active{background:var(--surface2);color:var(--text);}
.nav-drawer-item.active{border-left-color:var(--accent);}
.nav-drawer-icon{font-size:14px;width:20px;text-align:center;}

/* ── Drawer hierarchy (Phase 6, growth plan v2) ──────────────────
   All drawer items are always visible — the More/Less toggle was
   removed. Primary items render in full text color; secondary items
   stay at the default --text2 (muted-ish) that .nav-drawer-item
   already declares. Hover and active bring any item to full color.

   .nav-drawer-eyebrow is the "Analysis" label between the primary
   and secondary groups, marking the transition without a hard
   border. Small uppercase letterspaced label that visually reads
   as a section marker. */
.nav-drawer .nav-drawer-item[data-nav-group="primary"]{color:var(--text);}

.nav-drawer-eyebrow{padding:14px 20px 6px;color:var(--muted);font-size:var(--fs-xs);letter-spacing:.12em;text-transform:uppercase;font-weight:600;font-family:var(--font-ui);}

body.no-scroll{overflow:hidden;}

/* ── TABLE MOBILE SCROLL ── */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;}

/* ── LIGHT MODE ADJUSTMENTS ── */
[data-theme="light"] .badge-easy{background:rgba(100,116,139,.12);}
[data-theme="light"] .run-type-badge{font-weight:600;}
[data-theme="light"] .info-box{background:rgba(14,165,233,.06);border-color:rgba(14,165,233,.2);}

/* ── MOBILE LAYOUT (≤768px) ──
 *
 * Five rules were removed from this block as part of the mobile-fix
 * pass and now live in the dedicated mobile-fix blocks below:
 *   - .race-grid grid-template-columns      → now 1fr at ≤768
 *   - table font-size:10px                  → now var(--fs-xs) at ≤768
 *   - td/thead th padding:8px 10px          → now 10px 12px at ≤768
 *   - .section-head flex-direction:column   → now flex-wrap:wrap at ≤768
 * The .race-grid override in the 480 block below was also removed since
 * the new 768 rule already brings it to a single column.
 */
@media(max-width:768px){
  .header-nav{display:none;}
  .mobile-menu-btn{display:flex;align-items:center;}
  .header-logo{padding:0 16px;font-size:12px;}
  .header-right{padding:0 12px;gap:8px;}
  .athlete-pill span.athlete-name{display:none;}
  .page-inner{padding:16px 12px;}
  .controls-bar{padding:12px 14px;gap:8px;}
  .stats-grid{grid-template-columns:1fr 1fr;gap:8px;}
  .stat-card{padding:12px 14px;}
  .stat-value{font-size:18px;}
  .hero-card-value{font-size:24px;}
  .overview-hero{grid-template-columns:1fr;gap:8px;}
  .two-col{grid-template-columns:1fr;}
  .three-col{grid-template-columns:1fr;}
  .chart-panel-head{padding:12px 14px;}
  .chart-body{padding:12px;}
  .zoom-hint{display:none;}
  .readiness-score-wrap{flex-direction:column;align-items:flex-start;}
  .readiness-factors{grid-template-columns:1fr 1fr;}
  .fitness-metrics{grid-template-columns:1fr;}
  .formula-row{flex-direction:column;}
  .formula-input{min-width:unset;width:100%;}
  /* On narrow viewports, tighten the line-height of the wrapped
     feature list so the middle-dot inline run reads as one paragraph
     of text, not three loose lines. Font size unchanged — the desktop
     12px is fine on mobile too. */
  .connect-features{line-height:1.7;}
}
@media(max-width:480px){
  .stats-grid{grid-template-columns:1fr;}
  .readiness-factors{grid-template-columns:1fr;}
}

/* ============================================================
 * MOBILE-FIX PASS
 *
 * Rules below target overflow and overlap issues found on phones
 * and small tablets. Organized by breakpoint, then by issue. Each
 * rule names the symptom it fixes in a comment for traceability.
 * ============================================================ */

/* ── ≤768px ── small tablets and large phones ────────────────── */
@media (max-width: 768px) {

  /* Activity Log + admin tables — readability and tap targets.
     The prior rules (font-size:10px, padding:8px 10px) sat below
     comfortable phone reading. 11px hits --fs-xs and gives back
     enough padding for thumb taps. */
  table { font-size: var(--fs-xs); }
  td, thead th { padding: 10px 12px; }
  thead th { font-size: var(--fs-xs); letter-spacing: 0.08em; }

  /* Right-edge scroll affordance on .table-scroll. A 24px gradient
     fading to surface hints there's more table to the right of the
     visible columns. Pure CSS, no JS scroll listener. */
  .table-scroll { position: relative; }
  .table-scroll::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 24px;
    background: linear-gradient(to right, transparent, var(--surface));
    pointer-events: none;
  }

  /* Race-grid: previously 1fr 1fr at 481–768. At 414px each card
     was ~195px wide and the 24px race-card-time + range bar +
     model rows read cramped. Single column from 768 down. */
  .race-grid { grid-template-columns: 1fr; }

  /* Section-head: the prior column-stack collapsed inline control
     clusters (Race page Unit/Based-on/Lookback, Fatigue Window)
     into vertical stacks of full-width selects. Wrapping keeps
     title + controls horizontal and lets the cluster drop to its
     own row only when it doesn't fit. */
  .section-head {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
  }
}

/* ── ≤640px ── all phones in portrait ────────────────────────── */
@media (max-width: 640px) {

  /* Stat-strip: flex row of 4–6 cells with white-space:nowrap and
     22px horizontal padding per cell overflowed on Training (6
     cells), Race (3–6), Fatigue (5), VO2 (4–5), HR (4). Grid
     handles wrapping; row-gap separates rows without overlapping. */
  .stat-strip {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding: 14px 16px;
    row-gap: 14px;
    column-gap: 8px;
  }
  .stat-strip-cell {
    padding: 0;
    border-right: none;
    white-space: normal;
  }
  .stat-strip-cell:first-child { padding-left: 0; }
  .stat-strip-cell:last-child  { padding-right: 0; }

  /* Controls-bar: full-width stack at phone widths. The 641–700px
     band keeps the existing components.css column-direction rule
     (no change to that band). Below 640 the selects also fill the
     column so they're tappable. */
  .controls-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .controls-bar .ctrl { width: 100%; }
  .controls-bar select { width: 100%; min-width: 0; }
  .controls-bar .btn-reset-zoom { align-self: flex-end; }

  /* Section-head right cluster: the right side of section-head on
     Race and Fatigue pages is `<div style="display:flex;...">`
     with 2–3 inline `.ctrl`s. Forcing wrap on that inner div lets
     the ctrls drop to a second row instead of overflowing. */
  .section-head > div:last-child {
    flex-wrap: wrap;
    gap: 8px 12px;
  }

  /* Plan-preview-pills: 7-col grid shrinks each pill to ~44px on
     a 375px viewport, ellipsis-clipping chip text and cramping
     the mileage line. Wrapping to 3-up gives 3 rows (3 + 3 + 1)
     with readable chips. */
  .plan-preview-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .plan-preview-pills .plan-pill {
    flex: 1 1 calc(33.333% - 4px);
    min-width: 0;
    padding: 8px 6px;
  }
  .plan-preview-pills .plan-pill.is-today {
    padding: 7px 5px;
  }
  .plan-preview-pills .plan-pill-chip {
    font-size: var(--fs-xs);
  }

  /* Pace-profile-bands: 4 bands at 4-col on phones ellipsis-clipped
     pace ranges like "7:00-7:45/mi". 2-up keeps each band readable. */
  .pace-profile-bands {
    grid-template-columns: repeat(2, 1fr);
    row-gap: 10px;
  }

  /* Fatigue page 7-day plan grid: desktop minmax(128px) only fits
     2 per row at 375px. minmax(96px) fits 3, keeping the 7-day
     view compact at 3 rows (3 + 3 + 1). Pairs with the inline-
     style cleanup in index.html (.fat-plan-grid class in components.css). */
  .fat-plan-grid {
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  }
}

/* ── ≤480px ── phones in portrait, narrow phones ─────────────── */
@media (max-width: 480px) {

  /* Stat-strip: drop from 3-up to 2-up. At 360px portrait, 3-up
     leaves each cell ~105px which is borderline for values like
     "7:32 /mi" with their unit suffix. 2-up reads cleanly. */
  .stat-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .stat-strip-value { font-size: 16px; }

  /* Race-times row: 60px dist column was tight on the smallest
     phones. 50px keeps "Marathon" wrapping to two lines but the
     value column reads cleanly. Time drops to --fs-base so it
     doesn't crowd the CI / trend on the next grid row. */
  .race-times-row {
    grid-template-columns: 50px 1fr;
  }
  .race-times-time { font-size: var(--fs-base); }

  /* Chart-panel-head: title block on the left + zoom-hint /
     reset-zoom on the right collide on narrow widths and wrap
     onto a misaligned second line. Stacking is cleaner. */
  .chart-panel-head {
    flex-direction: column;
    align-items: flex-start;
    padding: 12px 14px;
    gap: 8px;
  }
  .chart-panel-toggle > summary > .chart-panel-head-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  /* Modal: overlay padding 40px top + 20px sides cramped the
     modal on phones. Tighter sides give the body 24px more
     usable width; bottom keeps generous room for the actions
     bar to sit above any home indicator. */
  .modal-overlay {
    padding: 16px 12px 40px;
  }
  .modal-header {
    padding: 14px 16px;
  }
  .modal-body {
    padding: 16px;
  }
  .modal-actions {
    padding: 12px 16px;
  }
}


/* ============================================================
 * HERO CARD MOBILE CHROME (Phase 1 redesign)
 *
 * Mobile feedback: the trio of bordered cards stacked vertically
 * felt cluttered. Phase 1 consolidates them into one hero card.
 * Mobile chrome quiets further: drop the border + background, keep
 * only the left tone stripe + a hairline divider below. Desktop
 * keeps full card chrome (see .hero-card in components.css).
 *
 * The hero stays the visual focal point of mobile Overview, but
 * reads as typography on the page rather than a boxed widget.
 * ============================================================ */

/* ── ≤768px ── small tablets and large phones ────────────────── */
@media (max-width: 768px) {

  /* Quiet chrome: drop border + background, keep left stripe +
     hairline divider. Padding shifts so the stripe gutter on the
     left becomes the only chrome cue. */
  .hero-card {
    background: transparent;
    border: none;
    border-left: 3px solid var(--tone);
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    padding: 16px 0 20px 16px;
    margin-bottom: 20px;
  }

  /* Footer divider goes from solid hairline to dashed at mobile
     sizes — the dashed read is softer and visually distinguishes
     it from the card-bottom hairline that now also exists. */
  .hero-card-footer {
    border-top: 1px dashed var(--border);
  }

  /* Action cluster (info button) sits inline at mobile widths — no
     absolute positioning, since the card no longer has a chrome
     "corner" to anchor against. */
  .hero-card-actions {
    position: static;
    margin-top: 12px;
    justify-content: flex-end;
  }
}

/* ── ≤480px ── narrow phones (320–480px) ─────────────────────────
 *
 * Hero column drops below the headline. Three-row vertical stack:
 * headline area, then hero number, then footer. The hero number
 * stops being a right-column ornament and becomes its own block
 * with its own scale.
 *
 * The streak ring re-anchors next to the score in stacked mode
 * since there's no right column to wrap around.
 */
@media (max-width: 480px) {

  .hero-card-body {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  /* Hero column: left-aligned in stacked mode, no right padding
     needed (no absolute actions to clear). */
  .hero-card-hero {
    text-align: left;
    padding-right: 0;
  }

  /* Spark slides to the left edge of the hero column since the
     column is now left-aligned. */
  .hero-card-spark {
    margin-left: 0;
  }

  /* Ring re-anchors beside the score in stacked mode. The ~72px
     left offset clears the typical 2-digit score width; for
     3-digit scores (impossible in 0-100 range) it would overlap,
     but the bound makes this safe. */
  .hero-card-ring {
    top: 0;
    right: auto;
    left: 72px;
    transform: none;
    width: 48px;
    height: 48px;
  }

  /* Smaller text at narrow widths — the headline can use the full
     row, so it doesn't need the desktop --fs-lg size. */
  .hero-card-headline { font-size: var(--fs-base); }
  .hero-card-hero-value { font-size: var(--fs-lg); }

  /* Post-run distance scale follows the same logic. */
  .hero-card-run-distance { font-size: var(--fs-lg); }
}


/* ============================================================
 * MOBILE SWIPE STRIP ACTIVATION (Phase 2)
 *
 * At ≤768px the horizontal strip takes over from the vertical stack.
 * The legacy surfaces (this-week, todays-number, whats-new) still
 * paint on every render — CSS hides them on mobile and shows the
 * strip instead. Both code paths stay live so the vertical stack
 * remains available on desktop without a code-fork.
 * ============================================================ */

@media (max-width: 768px) {

  /* Reveal the strip host. The default rule in components.css hides
     it; this rule opts in for mobile. */
  .strip-cards-host {
    display: block;
  }

  /* Hide the legacy vertical-stack surfaces on mobile. Their content
     is duplicated into the strip via composeStripCards(). */
  #ov-this-week,
  #ov-todays-number,
  #ov-whats-new {
    display: none;
  }
}
