/* ============================================================================
   Bremswerk — mobile.css
   Mobile / iPhone presentation layer. TWO kinds of rules live here:

   1. Breakpoint-gated overrides of the DESKTOP landing/deck (inside the
      MOBILE media query below) — single smooth column, hamburger, collapsible
      cards, trimmed lap table. Desktop is untouched above the breakpoint.
   2. Namespaced `.m-*` component styles for the mobile-only DOM that
      mobile-shell.js / mobile-replay.js create (hamburger drawer, the mobile
      study dialog). These are NOT media-gated — the elements only exist on
      mobile, and the study dialog must keep working when a phone rotates to
      landscape (844px wide > the 768px breakpoint).

   MOBILE breakpoint (keep in step with isMobile() in mobile-shell.js):
   width ≤ 768px, OR a coarse-pointer (touch) device up to 920px — so a phone
   held in landscape still gets the mobile shell.
   ========================================================================= */

/* ── 1. Landing / deck overrides (breakpoint-gated) ─────────────────────── */
@media (max-width: 768px), (pointer: coarse) and (max-width: 920px) {

    /* Masthead: wordmark left, burger right. The desktop nav's Upload button +
       session chip + auth slot relocate into the drawer (mobile-shell.js moves
       the live nodes, so their listeners survive). */
    .masthead { padding: .65rem 1rem; }
    .masthead__nav > .btn[data-open-upload] { display: none; }
    .masthead__nav > .meta-chip { display: none; }

    main.wrap { padding-left: .8rem; padding-right: .8rem; }

    /* Hero (empty state): tighten for a phone. */
    .hero__title { font-size: clamp(1.7rem, 8vw, 2.4rem); }
    .hero__cta { flex-direction: column; align-items: flex-start; gap: .7rem; }

    /* Deck: ONE smooth column where Track, Sessions, Summary and Laps are each a
       first-class card, UNIFORMLY spaced — not grouped into a rail/stage. Every gap
       (rail↔between-cards, deck rail→stage, stage between-cards) is the SAME 1.25rem so
       nothing reads as nested inside anything else (operator). The empty #railPanels is
       removed from flow (below) so it can't inject a double gap after Sessions. */
    .deck { grid-template-columns: 1fr; gap: 1.25rem; }
    .rail { gap: 1.25rem; }
    .stage { gap: 1.25rem; }
    #railPanels:empty { display: none; }

    /* Dock arrows (rail ⟷ main zone toggles) are meaningless in one column. */
    .panel__dock { display: none; }

    /* Summary stats: an aligned 3×2 grid instead of a free-wrap row. */
    .stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
    .stat-row .stat { min-width: 0; }

    /* Lap table: drop Start + Max Lat + the compare checkbox column (no 2-lap compare on
       mobile) so Lap · Time · Max · Δprev · ▶ fit a phone width. We KEEP "Δ prev" (gap to the
       previous lap — the useful lap-to-lap read on a phone) and HIDE "Δ best" (gap to the
       session best), which otherwise made SIX cells collide in the five-track grid. */
    .lap-table:not(.lap-table--compact) .lap-head,
    .lap-table:not(.lap-table--compact) .lap-row {
        grid-template-columns: 72px 76px 66px 1fr 34px;
    }
    .lap-table:not(.lap-table--compact) .lap-c--check,
    .lap-table:not(.lap-table--compact) .lap-c--start,
    .lap-table:not(.lap-table--compact) .lap-c--maxlat,
    .lap-table:not(.lap-table--compact) .lap-c--delta,          /* Δ best — hidden on phones (keep Δ prev) */
    .lap-table:not(.lap-table--compact) .lap-h:nth-child(1),
    .lap-table:not(.lap-table--compact) .lap-h:nth-child(3),
    .lap-table:not(.lap-table--compact) .lap-h:nth-child(6),
    .lap-table:not(.lap-table--compact) .lap-h:nth-child(8) { display: none; }   /* Δ best header */
    /* Δ prev is now the last value column (no second Δ to breathe from) → drop its right pad. */
    .lap-table:not(.lap-table--compact) .lap-c--deltaprev { padding-right: 0; }
    .lap-actions__hint { display: none; }
    .lap-c--play { min-width: 30px; min-height: 30px; }

    /* Bigger touch targets on the session cards' remove ✕. */
    .session-card__rm { min-width: 28px; min-height: 28px; }

    /* Whole-session "Watch session" is desktop-only — the mobile study view is
       single-lap (a session-spanning lap would show "LAP SESSION" + a session-long
       timer). ▶ per lap + Attach video remain the mobile paths into video. */
    .summary__watch { display: none; }

    /* Upload modal → a full-width sheet. */
    dialog.modal:not(.modal--replay):not(.m-replay) {
        width: calc(100vw - 1.6rem);
        max-width: none;
        margin: auto .8rem;
    }

    /* Video attach/calibration modal (already 1-column ≤820px): let it fill. */
    dialog.modal--attach { width: calc(100vw - 1.2rem); max-width: none; }
}

/* ── 2. Hamburger + drawer (mobile-shell.js DOM; exists only on mobile) ──── */
.m-burger {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 40px;
    height: 36px;
    padding: 0 9px;
    background: transparent;
    border: 1px solid var(--edge);
    border-radius: var(--r-sm);
    cursor: pointer;
}
.m-burger span {
    display: block;
    height: 2px;
    border-radius: 1px;
    background: var(--ink);
    transition: transform .18s ease, opacity .18s ease;
}
/* Burger → ✕ morph while the drawer is open. */
.m-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.m-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.m-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Drawer: a panel that slides down from under the sticky masthead. */
.m-drawer {
    position: fixed;
    top: 0;                          /* refined to the masthead's bottom on open */
    left: 0;
    right: 0;
    z-index: 19;                     /* just under .masthead's 20 */
    display: flex;
    flex-direction: column;
    gap: .15rem;
    padding: .7rem .9rem 1rem;
    border-bottom: 1px solid var(--edge);
    background: rgba(10, 12, 15, .97);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    box-shadow: var(--shadow);
    transform: translateY(-105%);
    transition: transform .22s cubic-bezier(.2, .7, .2, 1);
}
.m-drawer.is-open { transform: translateY(0); }
.m-drawer__item {
    display: flex;
    align-items: center;
    gap: .6rem;
    width: 100%;
    padding: .7rem .6rem;
    background: transparent;
    border: 0;
    border-radius: var(--r-sm);
    color: var(--ink);
    font-family: var(--cond);
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
}
.m-drawer__item:active { background: rgba(255, 255, 255, .06); }
.m-drawer__item svg { width: 18px; height: 18px; flex: 0 0 auto; }
.m-drawer__item--primary { color: var(--accent-hi); }
/* Account / session-count row: hosts the RELOCATED live #authSlot + #sessionCount. */
.m-drawer__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .8rem;
    padding: .35rem .6rem .8rem;
    border-bottom: 1px solid var(--edge);
    margin-bottom: .45rem;
}
/* (the masthead hide rule is `>`-scoped, so the relocated chip shows here untouched) */
/* Backdrop that closes the drawer on an outside tap. */
.m-scrim {
    position: fixed;
    inset: 0;
    z-index: 18;
    background: rgba(0, 0, 0, .45);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}
.m-scrim.is-open { opacity: 1; pointer-events: auto; }

/* ── Collapsible cards (chevron injected by mobile-shell.js / mobile-replay.js) ──
   The chevron's BASE look is NOT gated — the element only exists when the
   mobile JS created it, and the study dialog keeps its chevrons even when a
   rotated phone's width exceeds the breakpoint. */
.m-chevron {
    position: absolute;
    top: .5rem;
    right: .5rem;
    z-index: 5;
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--edge);
    border-radius: var(--r-sm);
    color: var(--ink-2);
    cursor: pointer;
}
.m-chevron svg { width: 14px; height: 14px; transition: transform .18s ease; }
.m-chevron[aria-expanded="false"] svg { transform: rotate(-90deg); }

/* Gated: these selectors restyle DESKTOP-built deck elements (.laps__action,
   .summary__titlerow) to clear the chevron — they must never leak upmarket. */
@media (max-width: 768px), (pointer: coarse) and (max-width: 920px) {
/* Collapsed card: keep the title strip (label + chevron), hide the body. The
   .panel label is absolutely positioned, so give the collapsed card a fixed
   title-strip height instead of relying on content flow. */
.panel.m-collapsed { min-height: 44px; }
.panel.m-collapsed > :not(.panel__label):not(.m-chevron) { display: none !important; }
.panel--track.m-collapsed { padding-bottom: .5rem; }
.summary.m-collapsed .stat-row,
.summary.m-collapsed .summary__metarow { display: none !important; }
/* Sessions is now its own card (the Track card is a separate sibling ABOVE it), so its
   chevron collapses only the session LIST (the header stays) and no longer hides Track. */
.sessions-card { position: relative; }
.sessions-card.m-collapsed .session-list { display: none !important; }
/* Push the Sort button (and the chevron after it) right. Putting margin-left:auto on the
   CHEVRON instead absorbs all free space and leaves Sort bunched against the "Sessions"
   title (justify-content:space-between then has nothing to distribute). */
.sessions-card > .rail__head > .sort { margin-left: auto; }
.sessions-card > .rail__head > .m-chevron { position: static; margin-left: .4rem; }
/* Laps panel: NOT collapsible on mobile (it's the whole point of the app — operator), so no
   chevron is added; keep the Study button where it was (no chevron to make room for). */
.panel--laps .laps__action { right: .8rem; }
/* Summary card: chevron sits on the card corner; make room on the title row. */
.summary { position: relative; }
.summary .m-chevron { top: .8rem; }
.summary .summary__titlerow { padding-right: 38px; }
}   /* end collapsible-cards media block */

/* ── 3. Mobile study view (.m-replay — mobile-replay.js DOM) ──────────────
   NOT media-gated: the dialog only exists on mobile, and it must keep working
   when the phone rotates to landscape (width > breakpoint). */
dialog.m-replay {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100dvh;
    max-width: 100vw;
    max-height: 100dvh;
    margin: 0;
    padding: 0;
    border: 0;
    background: var(--bg);
    color: var(--ink);
    display: flex;
    flex-direction: column;
    overflow: hidden;               /* the cards column scrolls, not the dialog */
}
dialog.m-replay::backdrop { background: #000; }

/* Header */
.m-replay__head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .7rem;
    border-bottom: 1px solid var(--edge);
}
.m-replay__titlewrap { min-width: 0; flex: 1 1 auto; }
.m-replay__title {
    margin: 0;
    font-family: var(--cond);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-hi);
    white-space: nowrap;
}
.m-replay__session { color: var(--ink-2); }
.m-replay__sub {
    margin: 0;
    font-size: .68rem;
    color: var(--ink-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.m-replay__x {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid var(--edge);
    border-radius: var(--r-sm);
    color: var(--ink-2);
    font-size: .9rem;
    cursor: pointer;
}

/* MAP | VIDEO segmented toggle */
.m-seg {
    flex: 0 0 auto;
    display: inline-flex;
    border: 1px solid var(--edge);
    border-radius: var(--r-sm);
    overflow: hidden;
}
.m-seg__btn {
    padding: .45em .8em;
    background: transparent;
    border: 0;
    color: var(--ink-2);
    font-family: var(--cond);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    cursor: pointer;
}
.m-seg__btn + .m-seg__btn { border-left: 1px solid var(--edge); }
.m-seg__btn.is-on { background: var(--accent); color: #fff; }

/* Top anchor (map or video) */
.m-anchor {
    position: relative;
    flex: 0 0 auto;
    height: min(42vh, 380px);
    min-height: 220px;
    background: #0f1318;
    border-bottom: 1px solid var(--edge);
}
.m-anchor__mapbox, .m-anchor__vidbox { position: absolute; inset: 0; }
.m-anchor__mapstage { position: absolute; inset: 0; }
.m-anchor__maptools {
    position: absolute;
    top: .5rem;
    right: .5rem;
    z-index: 1100;                  /* above Leaflet panes/controls */
    display: flex;
    gap: .4rem;
}
.m-anchor__vidbox { background: #000; }
.m-anchor__vidhost { position: absolute; inset: 0; }
.m-anchor__vidhost .bw-video-host,
.m-anchor__vidhost .plyr { width: 100%; height: 100%; }
.m-anchor__vidhost .plyr video { width: 100%; height: 100%; object-fit: contain; background: #000; }
.m-anchor__vidhost .plyr__controls,
.m-anchor__vidhost .plyr__control--overlaid { display: none !important; }
.m-anchor__vidnote {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 1rem;
    text-align: center;
    color: var(--ink-2);
    font-size: .8rem;
    pointer-events: none;
}
.m-anchor__vidchrome {
    position: absolute;
    top: .5rem;
    right: .5rem;
    z-index: 20;
    display: flex;
    gap: .4rem;
}
/* Transparent track map over the video (the ONE allowed overlay). */
.m-anchor__ovlmap {
    position: absolute;
    top: 6%;
    right: 4%;
    width: 52%;
    height: 62%;
    z-index: 10;
    opacity: .9;
    pointer-events: none;
}

/* Transport — desktop .replay__* classes carry the look; mobile tweaks: */
.m-transport { flex: 0 0 auto; gap: .55rem; padding: .5rem .8rem .5rem .6rem; background: var(--surface-0); }
.m-transport__stop {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid var(--edge);
    border-radius: 50%;
    cursor: pointer;
}
.m-transport__stopsq { width: 11px; height: 11px; border-radius: 2px; background: var(--ink-2); }
.m-transport__stop:active .m-transport__stopsq { background: var(--accent); }
.m-transport__total { font-family: var(--mono); font-size: .78rem; color: var(--ink-2); white-space: nowrap; }
.m-replay .replay__clock { font-size: .8rem; }

/* Cards column (scrolls) */
.m-replay__cards {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;   /* don't chain into pull-to-refresh */
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding: .7rem .7rem 1.2rem;
}
.m-card {
    flex: 0 0 auto;                 /* the cards COLUMN scrolls; cards never shrink */
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    background: linear-gradient(180deg, var(--surface-1), var(--surface-0));
    overflow: hidden;
}
.m-card__bar {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .55rem .5rem .55rem .9rem;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.m-card__title {
    font-family: var(--cond);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ink-2);
}
.m-card__extra { margin-left: auto; font-family: var(--mono); font-size: .72rem; color: var(--ink-2); }
.m-card__chev { position: static; flex: 0 0 auto; }
.m-card.m-collapsed .m-card__body { display: none; }
.m-card__body { padding: 0 .5rem .6rem; }
/* Gauges: the widget defaults to inline-flex (sizes to its content), so it sat inset
   inside the Gauges card. On mobile make it FILL the card and spread its columns edge-to-
   edge so it reads as a full-width widget (operator). */
.m-card__body > .bw-gauges { display: flex; width: 100%; justify-content: space-between; }

/* Readout ROW: live value pills on the left, UNFUSE pushed hard-right on the same row. */
.m-readoutrow { display: flex; align-items: center; gap: .5rem; padding: 0 .3rem .45rem; }
/* Live readout strip (replaces the timeline's floating legend on mobile) */
.m-readout {
    flex: 1 1 auto;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem .6rem;
}
/* The reparented UNFUSE button — hard right, never shrinks. */
.m-unfuse { margin-left: auto; flex: 0 0 auto; }
.m-readout__pill {
    display: inline-flex;
    align-items: center;
    gap: .35em;
    font-family: var(--mono);
    font-size: .78rem;
    color: var(--ink-hi);
}
.m-readout__pill small { color: var(--ink-3); font-size: .8em; }
.m-readout__pill--tap { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.m-readout__pill--tap:active { opacity: .6; }
.m-readout__dot { width: 7px; height: 7px; border-radius: 50%; align-self: center; }
/* Throttle/brake 0-100% bar (a track + a coloured fill driven by JS width). */
.m-readout__bar { width: 34px; height: 5px; border-radius: 3px; background: rgba(255,255,255,.1); overflow: hidden; align-self: center; }
.m-readout__barfill { display: block; height: 100%; width: 0; border-radius: 3px; transition: width .05s linear; }
/* SMOOTH toggle is desktop-detail — hide it on the mobile study (operator). */
.m-replay .bw-tl-smooth { display: none; }

/* Moving-window telemetry: the scroller is the ±10s viewport; the inner is the
   whole lap laid out wide (JS sets its width + drives scrollLeft). The viewport wraps
   the scroller and carries the edge gutters (which must stay pinned to the screen
   edges, so they live OUTSIDE the scrolled content). */
.m-tlviewport { position: relative; }
.m-tlscroll { position: relative; overflow: hidden; }
.m-tlinner { position: relative; }
/* Reserved page-scroll GUTTERS over the graph's LEFT/RIGHT edges (top set in JS to sit
   BELOW the chips row so chip taps aren't swallowed). A touch that STARTS here pans the
   PAGE vertically (touch-action:pan-y) instead of scrubbing; only the middle scrubs. An
   in-progress scrub keeps pointer-capture, so the gutters gate touch-STARTS only. */
.m-tl-gutter { position: absolute; bottom: 0; width: 34px; z-index: 6; touch-action: pan-y; }
.m-tl-gutter--l { left: 0; }
.m-tl-gutter--r { right: 0; }
.m-replay .bw-timeline { width: 100%; }
/* The chips/controls strip stays put while the graph slides under it.
   NB .bw-timeline's own overflow:hidden would become the sticky containment
   scroller (killing the stick) — the scroller (.m-tlscroll) clips instead. */
.m-replay .bw-timeline { overflow: visible; }
.m-replay .bw-tl-controls {
    position: sticky;
    left: 0;
    z-index: 5;
    background: linear-gradient(180deg, var(--surface-1), rgba(18, 23, 29, .92));
}
/* Floating value legends are right-anchored in the WIDE body → off-window. The
   .m-readout strip above replaces them. */
.m-replay .bw-tl-legend { display: none !important; }
/* Height (½) toggle is desktop-two-group ergonomics — hide on mobile. */
.m-replay .bw-tl-height { display: none; }
/* Touch: dragging the plot must scrub, never pan/zoom the page. */
.m-replay .bw-tl-stage { touch-action: none; }

/* Landscape player: while fused is up it owns the screen (z-2500); dim the rest. */
dialog.m-replay.is-fused .m-replay__head,
dialog.m-replay.is-fused .m-anchor,
dialog.m-replay.is-fused .m-replay__cards { visibility: hidden; }

/* Landscape phone (the normal, non-fused view): shrink the anchor so the
   telemetry stays reachable. */
@media (orientation: landscape) and (max-height: 480px) {
    .m-anchor { height: 52vh; min-height: 160px; }
}
