/* scenario_results.mobile.css -- the phone layout for the scenario-results
   applet. Loaded after scenario_results.css and overrides it only inside the
   one media query below; the desktop sheet is never edited for phone reasons
   (the seam rule with proj/applet-improvements, PLAN-mobile-explore-mvp §5).

   Layout on a phone: the map owns the screen; a bottom bar (Controls · Results)
   raises one of two sheets -- the sidebar as a full-height sheet from the top,
   the measurements dock as a drag-to-resize bottom sheet. The legend collapses to
   a title chip at top-left. Every dock panel reflows to one vertical stack and
   a table wider than the phone scrolls inside its own box (ruling D3). The
   mode-choice decomposition becomes one card per mode (treatment B), which
   needs sheets.js to copy the column headers into `td[data-label]`. The
   sidebar sheet is denser than the desktop sidebar it is made of: 36px
   targets, 13px type, one-row scenario and button+select rows (S9).

   The media query MUST stay byte-identical to LAYOUT_MQ in layout.js, so the
   CSS and the JS can never disagree about which layout is on screen. */

/* Phone-only chrome. These rules sit outside the media query on purpose:
   the markup is always present, and on a desktop it must not render. */
#mobile-bar { display: none; }
#mobile-summary { display: none; }
#panel-close { display: none; }
.sheet-handle { display: none; }
#ctrl-3d { display: none; }

@media (max-width: 760px), (max-height: 500px) {
  /* 38px summary strip + 46px button row. No safe-area term: the viewport
     meta has no `viewport-fit=cover`, so the browser keeps the page above
     the home indicator / gesture bar itself and `env(safe-area-inset-*)`
     reads 0. With cover, the inset became a ~20-34px empty grey band under
     the buttons on Android Chrome edge-to-edge (Taylor, 2026-09-12). */
  :root { --bar-h: 84px; }

  /* ---- The frame ---- */
  /* `dvh` tracks mobile Safari's URL bar; `vh` is the fallback for browsers
     without it. Both #app and body lose their flex column: the two sheets and
     the bar are all fixed, so nothing needs to share the height any more. */
  body { display: block; }
  #app { display: block; height: 100vh; height: 100dvh; }
  #map-area { position: absolute; inset: 0 0 var(--bar-h) 0; }

  /* ---- The bar ---- */
  #mobile-bar {
    display: flex; flex-direction: column; position: fixed; left: 0; right: 0; bottom: 0;
    height: var(--bar-h); z-index: 10;
    background: var(--n-f7); border-top: 1px solid var(--n-dd);
  }
  /* The summary strip: indicator · value on one line. The value never
     shrinks; the indicator takes the rest and ellipsizes (the legend chip
     names it in full). No zone name: ids mean nothing to a reader and a
     tract name ellipsized at 390px carried nothing the map's highlight does
     not. It sits inside the bar (not above it as a sibling) so the sheets,
     which stop at --bar-h, leave it visible: pick an indicator in Controls
     and the readout changes under the sheet's foot. */
  #mobile-summary {
    display: flex; align-items: center; gap: 6px; height: 38px;
    padding: 0 12px; font-size: 14px; line-height: 1.2; color: var(--n-55);
    border-bottom: 1px solid var(--n-e4); white-space: nowrap;
  }
  /* The name is a button (S12) that opens the indicator menu below. It
     looks like the text it was: no chrome, the strip's font and colour, an
     arrow as the one affordance -- a flex sibling of the text rather than
     its tail, so the ellipsis on a long profile-suffixed title cannot
     swallow it. The visible text stays the legend title, which carries the
     profile suffix and units the sidebar labels lack. */
  #ms-ind {
    flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
    height: 100%; margin: 0; padding: 0; border: 0; background: none;
    font: inherit; color: inherit; text-align: left; cursor: pointer;
  }
  /* The headline: 16px on one line. When the name does not fit at that size
     (a profile suffix -- "People per km² ($68k–$113k · Car · LTS≤1)"),
     summary.js sets `.wrap` on the button and the name alone drops to 13px
     over two clamped lines; the value keeps its size. The strip's 38px is
     what two 15px lines need, so --bar-h never moves. */
  #ms-ind-text {
    flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    font-size: 16px; font-weight: 600; color: var(--n-22);
  }
  #ms-ind.wrap #ms-ind-text {
    font-size: 13px; line-height: 15px; white-space: normal;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    line-clamp: 2;
  }
  #ms-ind:has(#ms-ind-text:not(:empty))::after { content: "\25BE"; flex: none; margin-left: 4px; color: var(--n-88); }
  #ms-ind[aria-expanded="true"]::after { content: "\25B4"; }
  #ms-ind:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 3px; }

  /* ---- The indicator menu ---- */
  /* Opens upward from the strip over the map, capped at 60% of the screen
     so the map stays in view (the 26-row Advanced list scrolls inside; the
     10-row basic list shows whole). Above the sheets and the bar. Group
     headings are the sidebar's row labels; the active row is ticked. */
  #ms-ind-menu {
    position: fixed; left: 8px; right: 8px; bottom: calc(var(--bar-h) + 6px);
    max-height: 60vh; max-height: 60dvh; overflow-y: auto; overscroll-behavior: contain;
    z-index: 11; padding: 4px 0; background: var(--n-ff); border: 1px solid var(--n-cc);
    border-radius: 10px; box-shadow: 0 6px 24px var(--shade-22); outline: none;
  }
  #ms-ind-menu[hidden] { display: none; }
  .msm-head {
    padding: 8px 14px 3px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--n-6b);
  }
  .msm-head + .msm-head, .msm-opt + .msm-head { border-top: 1px solid var(--n-ee); margin-top: 4px; }
  .msm-opt {
    display: flex; align-items: center; gap: 8px; min-height: 40px;
    padding: 6px 14px 6px 34px; font-size: 14px; color: var(--n-22); cursor: pointer; position: relative;
  }
  .msm-opt[aria-selected="true"] { font-weight: 600; color: var(--accent-deep-2); }
  .msm-opt[aria-selected="true"]::before {
    content: "\2713"; position: absolute; left: 14px; color: var(--accent); font-weight: 700;
  }
  .msm-opt.msm-cur, .msm-opt:active { background: var(--accent-tint-2); }
  .msm-swatch { flex: none; width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--shade-15); }
  #ms-val { flex: 0 0 auto; margin-left: auto; font-weight: 600; color: var(--n-22);
            font-variant-numeric: tabular-nums; }
  #ms-val.placeholder { font-weight: 400; color: var(--n-88); font-style: italic; }
  #ms-ind:has(#ms-ind-text:not(:empty)) + #ms-val:not(:empty)::before {
    content: "\00b7"; margin-right: 6px; color: var(--n-aa); font-weight: 400; font-style: normal;
  }
  #bar-buttons { display: flex; flex: 1; gap: 8px; padding: 5px 10px; }
  #bar-buttons button {
    flex: 1; font-size: 13px; font-weight: 600; border: 1px solid var(--n-cc);
    border-radius: 8px; background: var(--n-ff); color: var(--n-22); cursor: pointer;
  }
  #bar-buttons button[aria-expanded="true"] {
    background: var(--accent); border-color: var(--accent); color: var(--on-accent);
  }

  /* ---- The sidebar sheet (#panel, "Controls") ---- */
  /* Full-height: its content is ~880px tall and no partial height shows a
     useful amount of it. `min-width: 0` is load-bearing, not cosmetic -- below
     380px the desktop `min-width: 380px` is what widened the layout viewport
     and left the map 0px wide (AUDIT-phone-viewports §2). Slides down from the
     top, so it and the dock never fight over the same edge. */
  #panel {
    position: fixed; inset: 0 0 var(--bar-h) 0;
    width: auto; min-width: 0; max-width: none;
    border-right: none; z-index: 9; overflow-y: auto;
    transform: translateY(-105%); transition: transform .18s ease-out;
  }
  #panel.open { transform: none; }
  #panel-close {
    display: block; position: absolute; top: 6px; right: 8px; z-index: 1;
    border: none; background: none; font-size: 24px; line-height: 1;
    padding: 4px 8px; color: var(--n-77); cursor: pointer;
  }

  /* ---- The sheet's density (S9, Taylor's ruling 2026-09-11) ---- */
  /* The desktop sidebar stacked its title block three lines deep, let every
     button + select row wrap so each select sat alone at half width, and
     put 11px type in 40px boxes. On a phone that was 1227px of sheet for a
     panel that reads fine at ~980 (DRAFT-controls-density.md). */

  /* Header: title · nav · one line of subtitle / copyright / Advanced. The
     title is the least useful line on a phone (the nav says where you are),
     so it is a quiet 12px; the block is a wrapping flex row so the subtitle
     and the footer can share a line without touching the markup. */
  #panel-title { display: flex; flex-wrap: wrap; align-items: center; padding: 8px 12px 6px; }
  #panel-title h2 { flex: 0 0 100%; font-size: 12px; font-weight: 600; color: var(--n-55); line-height: 18px; padding-right: 32px; }
  #panel-title .applet-nav { flex: 0 0 100%; margin-top: 4px; border-radius: 6px; }
  #panel-title .applet-nav a { padding: 7px 8px; font-size: 12px; }
  #panel-title .subtitle { flex: 0 1 auto; margin: 5px 6px 0 0; font-size: 11px; color: var(--n-55); }
  #panel-title .subtitle:empty { display: none; }
  #panel-title .title-footer { flex: 1 1 auto; margin-top: 5px; gap: 8px; }
  #panel-title .copyright { margin: 0 auto 0 0; font-size: 11px; color: var(--n-6b); }
  #panel-title .subtitle:not(:empty) + .title-footer .copyright::before { content: "\00b7\00a0"; }
  .adv-toggle { font-size: 11px; color: var(--n-6b); gap: 5px; }
  .adv-toggle input { width: 16px; height: 16px; }

  /* One label style for every section head: SCENARIO and TRAVELER PROFILE
     were small caps, Indicators and City Snapshot were 14px bold titles.
     #6b6b6b is the lightest grey that clears 4.5:1 on the #f0f0f0 heads
     (#777 is 3.9 -- the desktop's small caps fail axe on the same ground). */
  .sec-label, .traveler-label, .picker-label {
    font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--n-6b);
  }
  .sec-label { padding: 6px 12px; }
  .section-body { padding: 6px 10px 8px; }
  #snapshot-digest { font-size: 11px; text-transform: none; letter-spacing: 0; font-weight: 400; }

  /* Scenario: `SCENARIO [baseline v]` on one row. The flat-scenario Explore
     grid carries its own "Scenario" header cell -- a repeat of the section
     label -- over an empty axis-name column that pushed the select to 2/3
     width. Header row hidden, empty column collapsed; a multi-axis study
     keeps the axis-name column, which carries real names there. */
  #scenario-picker { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 6px 10px; }
  #scenario-picker .scenario-section-header { flex: 0 0 auto; margin: 0; }
  #scenario-table-container { flex: 1 1 160px; min-width: 0; }
  .scenario-table { margin-top: 0; }
  .scenario-table-explore .st-header { display: none; }
  .scenario-table-explore .st-axis-name:empty { display: none; }
  .scenario-table-explore { grid-template-columns: minmax(0, 1fr); }
  .scenario-table-explore:has(.st-axis-name:not(:empty):not(.st-header)) {
    grid-template-columns: minmax(0, 90px) minmax(0, 1fr);
  }

  /* Traveler profile: the header's 6px bottom margin only earns its place
     when the Specific controls are open under it. */
  #traveler-section { padding: 6px 10px; }
  .traveler-header { margin-bottom: 0; }
  #uc-specific-controls.visible { margin-top: 6px; }
  .uc-toggle-strip { border-radius: 6px; }
  .uc-toggle-btn { font-size: 12px; padding: 0 12px; }
  .traveler-grid { gap: 6px; }

  /* Indicator rows: 13px type in a 36px box, 3px gaps. A button and its
     select share the row again -- the S1 sheet let `.ind-row-inline` wrap,
     which dropped every select to its own half-width line; now the button
     label wraps to a second line before the row does. The select's cap is
     what "All destinations" needs at 13px. */
  .ind-group { margin-bottom: 6px; }
  .ind-row { margin-bottom: 3px; }
  .ind-btn { font-size: 13px; padding: 5px 9px; margin-bottom: 3px; border-radius: 5px; }
  .ind-row-inline { flex-wrap: nowrap; gap: 6px; }
  .ind-row-inline > .ind-btn { white-space: normal; line-height: 1.25; }
  .row-select { flex: 0 1 auto; max-width: 54%; padding: 3px 4px; }
  /* Below 340px "All destinations" runs under its own chevron at any cap
     worth having, so the select drops to a full-width line of its own. */
  @media (max-width: 340px) {
    .ind-row-inline { flex-wrap: wrap; }
    .ind-row-inline > .row-select { flex: 1 1 100%; max-width: 100%; }
  }
  .imp-row-label { font-size: 12px; padding: 3px 3px 3px 0; }
  .imp-btns { gap: 4px; margin: 0 0 5px; }
  .imp-btn.ind-btn { min-height: 32px; font-size: 12px; padding: 3px 9px 3px 7px; }
  .tip { width: 15px; height: 15px; font-size: 10px; line-height: 15px; }
  /* Compare mode is desktop-only for the MVP (ruling D6): hidden by CSS, never
     removed from the DOM, so app.js's wiring is untouched. The whole
     Explore/Compare strip goes, not just the Compare button -- a one-button
     toggle is a control with nothing to choose. */
  #mode-toggle, #compare-view-toggle { display: none; }

  /* ---- The dock sheet (#measurements, "Results") ---- */
  /* Opens at one height and is then dragged by its handle to any height
     between 120px and 24px short of the top (sheet_drag.js writes an inline
     px height; the S12 partial/tall toggle is gone, Taylor 2026-09-12). The
     opening height is a glance, not a reading height: 35dvh on an 844px
     phone gives #mp-body ~230px -- the lead rows of any panel (the mapped
     number and its decomposition) with most of the map still on show. It was
     52dvh (~390px of body, the destination panel whole); Taylor cut it to
     two-thirds (2026-09-12). Anything with a table wants dragging up
     (AUDIT §5). */
  #measurements {
    position: fixed; left: 0; right: 0; bottom: var(--bar-h); top: auto;
    flex: none; height: 35vh; height: 35dvh; z-index: 8;
    border-top: 1px solid var(--n-dd); border-radius: 14px 14px 0 0;
    box-shadow: 0 -4px 18px var(--shade-16);
    transform: translateY(105%); transition: transform .18s ease-out;
  }
  #measurements.open { transform: none; }
  /* The handle row is 44px on a phone, tall enough to also carry the ⇆ / ✕
     buttons at its right (below); the grip sits in its upper half. It is the
     drag surface: `touch-action: none` keeps the browser from turning the
     gesture into a page scroll or pull-to-refresh before the pointer events
     see it. */
  .sheet-handle {
    display: flex; justify-content: center; padding: 8px 0 0; height: 44px;
    box-sizing: border-box; cursor: grab; flex: 0 0 auto; touch-action: none;
    border-radius: 14px 14px 0 0; background: var(--n-f7); position: relative;
  }
  /* The drag hitbox reaches 24px past the row into the header / body (an
     invisible absolutely positioned box, so nothing moves). The ⇆ / ✕
     buttons come later in the DOM and stay on top of it. */
  .sheet-handle::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 24px; }
  .sheet-handle span { width: 38px; height: 4px; border-radius: 2px; background: var(--n-cc); }
  /* The header (S12 ruling): no context line and no O -> D pills on phones.
     The context repeated what the summary strip under the sheet already
     says (indicator · value), and zone ids are H3 cells that say nothing to
     a reader. What is left is the OD family's stage prompt, and the two
     icon-only buttons (⇆ / ✕, the aria-labels carry the verbs), which are
     lifted out of the header's flow onto the handle row. Outside the OD
     family the prompt is empty and the header collapses to nothing, so the
     body starts 44px from the sheet's top. */
  #mp-header { flex-wrap: wrap; padding: 0 12px 6px; }
  #mp-header .mp-spacer, #mp-header .mp-od, #mp-header .mp-btn-label, #mp-header #mp-context { display: none; }
  #mp-header .mp-stage { flex: 1 1 0; min-width: 0; white-space: normal; }
  #mp-header .mp-stage:empty { display: none; }
  #mp-header:has(.mp-stage:empty) { padding: 0; border-bottom: none; }
  #mp-header .mp-btn {
    position: absolute; top: 4px; width: 36px; padding: 0; text-align: center; font-size: 15px;
  }
  #mp-header #mp-clear { right: 8px; }
  #mp-header #mp-swap { right: 50px; }
  #mp-header #mp-clear::before { content: "\2715"; font-size: 13px; }
  #mp-body { max-height: none; overflow-y: auto; }

  /* ---- The legend ---- */
  /* Top-left keeps it clear of the bottom sheets and of MapLibre's controls
     at top-right. Always open and basic (Taylor, 2026-09-12): the title and
     the colour ramp -- or the category / mode swatches that stand in for a
     ramp -- and map.js's own "Map Overlays" fold, which starts closed. The
     Advanced block (scale mode, opacity, height, cap sliders) folds in
     with the overlays: it is ordered after them and hidden while the fold
     is closed (sheets.js mirrors the fold as `.adv-folded`); app.js's
     Advanced checkbox still decides whether it exists at all. The 3D
     toggle and the compare-view row are desktop-only here; the 3D toggle
     is relayed through the #ctrl-3d map control below. */
  #legend {
    top: 10px; left: 10px; right: auto; bottom: auto;
    max-width: min(62vw, 240px); padding: 6px 8px;
    /* Below the sheets (8, 9): a fully raised dock's handle sits at 24px from
       the top and the desktop's z-index 900 would put the chip on top of it.
       Still above MapLibre's controls (z 2). */
    z-index: 5;
    /* A three-column grid: row 1 is the title with the overlays fold's
       glyph at its right; row 2 is min . bar . max (the ramp's labels flank
       the bar rather than sit under it -- Taylor, 2026-09-12, vertical
       space); every other child spans the row. `.leg-labels` and
       `#legend-overlays` become `display: contents` so their children are
       placed by the grid directly; the `order`s put min, bar, max ahead of
       every order-0 child so auto-placement lands the three together. */
    display: grid; grid-template-columns: auto 1fr auto; column-gap: 6px; align-items: center;
  }
  #legend > * { grid-column: 1 / -1; }
  #legend .leg-labels, #legend #legend-overlays { display: contents; }
  #legend #leg-title { grid-row: 1; grid-column: 1 / 3; font-size: 12px; line-height: 16px; margin: 0 0 3px; }
  #legend #leg-min { grid-column: 1; order: -3; color: var(--n-55); }
  #legend .leg-bar { grid-column: 2; order: -2; margin: 0; min-width: 100px; height: 10px; }
  #legend #leg-max { grid-column: 3; order: -1; color: var(--n-55); }
  /* The fold's heading is the "Map Overlays ►" line map.js builds; on a
     phone only its arrow shows, as a glyph on the title row (the heading
     text stays in the DOM for screen readers). The tap target is the
     whole 16px row across the third column. The divider moves to the
     fold's body so a closed fold costs no height at all. */
  #legend #legend-overlays-toggle {
    grid-row: 1; grid-column: 3; justify-self: end; margin: 0 0 3px;
    font-size: 0; line-height: 16px; padding: 0 0 0 10px; cursor: pointer;
  }
  #legend #legend-overlays-toggle .collapse-arrow { font-size: 12px; color: var(--n-77); margin: 0; }
  #legend #legend-overlays-body { grid-column: 1 / -1; order: 3; border-top: 1px solid var(--n-dd); margin: 6px 0 0; padding: 3px 0 0; }
  #legend #leg-advanced { order: 4; margin: 6px 0 0; }
  #legend.adv-folded #leg-advanced { display: none !important; }
  #legend #btn-3d-toggle, #legend #leg-compare-view { display: none !important; }

  /* ---- The 2D/3D map control ---- */
  /* sheets.js appends it to MapLibre's top-right corner under the compass
     and top-down buttons, styled as one more control group; the text names
     the view a tap gives, and that label is the whole state display -- no
     active colour (Taylor, 2026-09-12). Hidden off the phone layout, where
     the legend's own toggle is the control. */
  #ctrl-3d { display: block; }
  #ctrl-3d button { font-size: 11px; font-weight: 700; color: var(--n-33); display: flex; align-items: center; justify-content: center; }
  #ctrl-3d button:disabled { color: var(--n-bb); }

  /* ---- The dock panels: the reflow (ruling D3) ---- */
  /* Every panel becomes one vertical stack. The three flex rows and the
     multicolumn body are what laid the desktop dock out sideways; the
     `max-width: none`s release the columns that were sized for a 1280px
     dock. A table wider than the phone scrolls inside its own box. */
  #mp-body { columns: auto; column-gap: normal; column-rule: none; }
  .pn-mc-main, .dcp-cols, .stp-cols { flex-direction: column; align-items: stretch; gap: 10px; }
  .dcp-col-mid, .stp-col-lead, .pn-mc-side { max-width: none; flex-basis: auto; }
  /* .dcp-col-cats is the panel that actually loses data on a desktop dock at
     phone width -- it collapsed to 4px and was clipped with no scrollbar
     (AUDIT §5). Stacked and released it gets the full width back. */
  .dcp-col-cats { flex: 0 0 auto; }
  .stp-col-tbl, .dcp-col-cats { overflow-x: auto; max-width: 100%; }
  .dcp-col-cats table { min-width: max-content; }
  /* Two-up category sub-tables stack when the pair does not fit. */
  .dcp-cat-cols { flex-wrap: wrap; }
  /* The cumulative panel's purpose + by-mode tables are a flex row on the
     desktop; at 390px the second table sat entirely off-screen to the right
     of the scroll box, with nothing to say it was there (found reading the
     panels, 2026-09-11). Stacked, each scrolls on its own. */
  #mp-body .cum-tbls { flex-direction: column; align-items: stretch; }
  #mp-body .cum-tbls > table { max-width: 100%; }
  #mp-body .cum-tbls > * { overflow-x: auto; }

  /* ---- Mode choice: one card per mode (treatment B, ruled 2026-09-11) ---- */
  /* The column headers become in-row labels via `td::before { content:
     attr(data-label) }`; sheets.js copies each `thead th` into the cells after
     every render. If the labeler has not run (JS off, or a render it did not
     see) the cells simply show without labels -- the numbers are still right,
     and the formula line under the table still names the columns in order. */
  .pn-mc-tbl { flex: 0 0 auto; max-width: 100%; overflow-x: visible; }
  .pn-decomp, .pn-decomp tbody { display: block; width: 100%; }
  .pn-decomp thead { display: none; }
  .pn-decomp tbody tr {
    display: block; width: 100%;
    margin: 0 0 8px; padding: 6px 8px; border-radius: 6px;
    border: 1px solid var(--shade-12);
  }
  /* Label left, value(s) packed right: a cell may hold more than one node
     ("$0.597" + its "(1.7)" span), and `space-between` would spread them. */
  #mp-body .pn-decomp td {
    display: flex; justify-content: flex-end; align-items: baseline;
    flex-wrap: wrap; gap: 4px 8px; padding: 2px 0; border: 0;
    text-align: right; min-width: 0; white-space: normal;
  }
  #mp-body .pn-decomp td::before {
    content: attr(data-label); text-align: left; color: var(--n-66);
    font-weight: 400; font-size: 11px; flex: 0 0 auto; margin-right: auto;
  }
  /* The mode-specific cell holds N chips; they wrap instead of widening the
     card (Walk's three chips overflowed 390px by 27px in the S2 mock). */
  #mp-body .pn-decomp td.pn-decomp-chips { max-width: none; row-gap: 4px; }
  /* The mode name is the card's heading, not a labelled row. */
  #mp-body .pn-decomp td:first-child {
    display: block; text-align: left; font-weight: 600;
    font-size: 14px; margin-bottom: 4px;
  }
  #mp-body .pn-decomp td:first-child::before { content: none; }
  /* The mapped-mode marks were drawn as cell-edge box-shadows on a row of
     cells; on a card they become the card's own border. */
  #mp-body .pn-decomp tr.pn-mapped-mode { border-color: var(--n-44); border-width: 2px; }
  #mp-body .pn-decomp tr.pn-mapped-mode td,
  #mp-body .pn-decomp tr.pn-mapped-mode td:first-child { box-shadow: none; }
  /* The collapsed unavailable-modes row is a sentence with colspan; it keeps
     its own styling and gets no label. */
  #mp-body .pn-decomp tr.pn-mode-unavail { border: none; padding: 0 2px; }
  #mp-body .pn-decomp tr.pn-mode-unavail td:first-child {
    font-size: 10px; font-weight: 400; margin: 0;
  }
  #mp-body .pn-decomp tr.pn-mode-unavail td::before { content: none; }

  /* ---- Type and touch targets ---- */
  /* 36px is the floor for a finger (S9 ruling; was 40 -- well above WCAG
     2.5.8's 24px, under Apple's 44pt guideline). 42 targets were under it
     and every <select> was at 12px (AUDIT §3). `#app` is for specificity:
     the desktop sheet sizes selects by class and id.
     Selects are 13px at rest and 16px on focus: iOS Safari zooms the page
     when a focused control's type is under 16px, and it decides at focus
     time -- the usual workaround, NOT yet verified on a real phone (S8;
     fall back to 16px at rest if it zooms). */
  #app select, #app input, #app textarea { font-size: 13px; }
  #app select:focus, #app input:focus, #app textarea:focus { font-size: 16px; }
  #app select { padding: 4px 6px; line-height: 22px; min-height: 32px; }
  .ind-btn, .mp-btn, .uc-toggle-btn, .mode-btn, .norm-btn, #btn-3d-toggle { min-height: 36px; }
  .uc-toggle-strip { flex-wrap: wrap; }
  input[type="range"] { height: 28px; }
}
