/* ===================================================================================
   Phase 1D redesign - S02 Route preview (mock-004-002/-003) and S08 Edit stops
   (mock-013-014/-015). New file (not css/plan.css) so the parallel "plansetup"
   builder's own edits to the shared file stay a clean merge (FANOUT-RULES). Every
   selector below is scoped to Preview's resting state (has-route, no focused sheet)
   or to [data-psheet="edit"] - never touches Home, Setup, Destination or Customize.
   =================================================================================== */

/* --------------------------- S02 Preview: map treatment matches Home --------------------------- */
/* REDESIGN-DECISIONS-3 "S02 Preview: tilted 3D map like Home". js/plan.js already
   shares every real camera/terrain helper with Home (same HOME_PITCH/HOME_EXAGGERATION
   constants, same routeCamera.fit() -> map.fitBounds(bounds, {pitch: HOME_PITCH, ...})
   once a route exists - confirmed directly, live: map.getPitch() reads 63 and
   map.getTerrain() is set the moment Preview paints, same as Home's own cold open) -
   this was never a missing-pitch bug. What IS visibly different from Home, confirmed
   directly against a real screenshot: css/plan.css's own scale-bar rule (~line 2875)
   only hides MapLibre's "5 mi"/"10 mi" ScaleControl while `:not(.has-route)` - i.e. on
   Home itself - so the instant a route exists that explicitly 2D, orthographic-map
   affordance (Home never draws one) reappears over the same tilted terrain, reading
   as "this is a flat map" regardless of the real pitch underneath it - the exact
   artifact the round-3 audit named ("real place labels/scale bar, not tilted 3D
   terrain"). Extending the SAME hide to every has-route state Preview/Edit use (not
   touching Home's own selector, not lifting the restriction for Setup/Customize/
   Destination, which this file never selects) removes that one concrete "2D map" tell
   without touching camera code that was already correct. */
html[data-app].has-route .maplibregl-ctrl-scale{display:none}

/* -------------------------- S02 Preview: the heading row -------------------------- */
/* mock-004: route name + a BARE sliders icon (no border, no pill chrome) on the same
   row; the facts line ("68 km - Curvy roads - All paved") runs full width underneath,
   never squeezed beside a wide bordered "Customize" button. css/plan.css's own attempt
   at this (lines ~2072/2107) keeps .pln-customize a flex sibling of #preview-title at
   DOM-end and repositions it with `order` + `margin-left:auto` inside a wrapping flex
   row - the paragraph itself has no `order`, so once its content wrapped past one line
   (every real route: distance, duration, road character AND surface together) the
   button and the text fought for the same row instead of stacking. Grid fixes that
   structurally: two rows, title+icon on row 1, the facts paragraph spanning both
   columns on row 2, regardless of how long the text runs. */
@media (max-width:900px){
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .preview-heading{
    display:grid !important;grid-template-columns:1fr auto;
    grid-template-areas:"title icon" "meta meta";
    column-gap:8px;row-gap:2px;align-items:start;
  }
  /* redesign-review-cortana-1 (2026-10-31): the whole heading rendered at roughly
     double the mockup's type scale. css/plan.css's own #preview-title/#preview-metadata
     rules (~line 2067/2068) multiply a mockup-sized nominal px value by the RAW --ts
     custom property, whose real (not fallback) value is 1.5 by default (heritage.css,
     "A++ is the default" - Dean's own accessibility choice) - so a 24px sheet title
     rendered at 36px and a 16px meta line rendered at 24px, against a brief that asks
     for ~22-28px sheet titles and 13-14px secondary labels. Home's own equivalent
     headings solved this with --home-scale (css/plan.css line ~2419): normalize --ts
     against its own 1.5 default first, so the result matches the brief AT Dean's
     default setting and still scales up/down with his actual text-size preference
     instead of silently inflating every screen by 1.5x on top of the mockup's own
     numbers. The same normalization, inline (no new custom property needed since these
     are the only two uses here), selected on the #id for specificity - plan.css only
     ever styled .preview-heading h2/p by class, never by id, so no !important needed. */
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .preview-heading #preview-title{
    grid-area:title;margin:0;align-self:center;min-width:0;
    font-size:calc(22px * var(--ts,1.5) / 1.5);line-height:1.2;
  }
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .preview-heading #preview-metadata{
    grid-area:meta;margin:2px 0 0;
    font-size:calc(13px * var(--ts,1.5) / 1.5);line-height:1.35;
  }
  /* Overrides plan.css's bordered-pill treatment: here the icon is bare, like the
     mockup, 44pt target with no visible chrome - a real affordance, not a button
     that LOOKS like a secondary CTA next to the primary Start ride below it. */
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .preview-heading .pln-customize{
    grid-area:icon;order:0;position:static;align-self:center;margin:0;
    width:44px;height:44px;min-width:44px;min-height:44px;padding:0;
    display:flex;align-items:center;justify-content:center;
    border:0;background:transparent;color:var(--ink);
  }
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .preview-heading .pln-customize svg{
    width:20px;height:20px;flex:0 0 auto;
  }
  /* The text label stays in the DOM (accessible name via aria-label covers it too) -
     only visually hidden here. Home keeps the full "Customize" label; nothing here
     touches that selector (test-home-redesign.js P0-HOM-05 is unaffected). */
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .preview-heading .pln-customize-label{
    position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;
  }
}

/* --------------------------- S02 Preview: alternative cards --------------------------- */
/* mock-004: three rounded cards, big bold duration, a quiet delta/status line under it,
   the SELECTED card marked with an orange OUTLINE (not a solid orange fill) - the data
   itself (names like "Balanced"/"More corners" are mockup-illustrative; WBH-4490
   intentionally shows only a real time/distance tradeoff, never an invented label, and
   that stays exactly as-is here). */
html[data-app].has-route #proutes{
  display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 4px;
}
html[data-app].has-route .proutes-lab{display:none}
/* Round 2: this round-1 rule itself still multiplied by the raw --ts (14px * 1.5 =
   21px, same class of bug as the heading above) - a single quiet caveat line reading
   almost as large as the route's own facts line. Normalized the same way. */
html[data-app].has-route .proutes-availability{
  flex:1 0 100%;margin:0 0 2px;font-size:calc(12px * var(--ts,1.5) / 1.5);line-height:1.4;color:var(--steel);
}
html[data-app].has-route .proute-card{
  flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:4px;
  padding:12px 10px;border:1.5px solid var(--rule);background:var(--surface);border-radius:14px;
}
html[data-app].has-route .proute-card-top{display:flex;flex-direction:column;align-items:flex-start;gap:0}
html[data-app].has-route .proute-card-h{
  order:-1;font-size:22px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;
}
html[data-app].has-route .proute-card-mi{
  font-size:12.5px;font-weight:600;color:var(--steel);
}
html[data-app].has-route .proute-card-trade{font-size:11.5px;color:var(--steel)}
/* Selected = orange OUTLINE, per mock-004 (a solid fill is what css/plan.css's base
   rule drew before this file; keep text legible on the lighter surface instead). */
html[data-app].has-route .proute-card[aria-pressed="true"]{
  background:var(--surface);border-color:var(--orange);border-width:2px;
}
html[data-app].has-route .proute-card[aria-pressed="true"] .proute-card-h{color:var(--ink)}
html[data-app].has-route .proute-card[aria-pressed="true"] .proute-card-mi{color:var(--steel)}
html[data-app].has-route .proute-card[aria-pressed="true"] .proute-card-trade{color:var(--orange);font-weight:700}
html[data-app].has-route .proutes-single-summary .proute-card{flex:1 1 100%}

/* mock-004: the cards sit BETWEEN the facts line and Start ride. js/planner-sheet.js's
   previewOrder() physically moves .pexp (Start ride, "Edit route or add a stop", the
   Save/share/GPX door) to right after .preview-heading in the real DOM - deliberately,
   for keyboard order and to keep the route's own action handlers attached outside
   Preview too (see its own comment) - which pushed #proutes below the fold, after the
   actions, 350px+ down the sheet. Reordering visually with flex `order` on .pln-side's
   direct children leaves that DOM move and its reasons untouched; tab order still
   follows the DOM (unchanged), only the paint order moves the cards back above Start
   ride, as drawn. */
@media (max-width:900px){
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > .pln-grab{order:0}
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > .preview-heading{order:10}
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > #proutes{order:20}
  /* .pauto itself is a direct child of .pln-side too (not a wrapper .pexp/#proutes sit
     inside); the ONLY thing css/plan.css's own has-route allow-list (line ~1897) lets
     show inside it here is #pa-note (.pauto-note, the plain-language "via Road A, Road
     B..." sentence a successful route paints into the OLD "Find routes" status line) -
     a real, useful feature nowhere in mock-004, kept and placed with the other
     secondary route facts rather than removed. Left at .pauto's own default order (0)
     it rendered ABOVE the heading (order 0 < 10); giving the wrapper itself an order
     puts that sentence with the rest of the secondary detail, after the primary action. */
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > .pauto{order:40}
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > .pexp{order:30}
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > #pout,
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > #pstatus,
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > #pwx-alt,
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > #condition-review-notice,
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > .proute-recenter,
  html[data-app].has-route:not(.show-dials):not([data-psheet]) .pln-side > #pshare-sheet{order:50}
}

/* mock-004: "Start ride" carries a small nav-arrow glyph, same icon the Locate button
   already draws elsewhere (css/plan.css ~line 2844) - reused for visual consistency,
   not a new glyph. Markup lives in docs/_plan_page.html for every state #pridenow
   appears in; sized/positioned here only. */
html[data-app] #pridenow{display:inline-flex;align-items:center;justify-content:center;gap:8px}
html[data-app] .pridenow-ico{width:17px;height:17px;flex:0 0 auto}

/* mock-004: "Edit route or add a stop" is a quiet line under the primary, not another
   button - css/plan.css's own .pln-editlink rule (~line 1986) is the same raw-*-ts
   bug as the heading above (16px * 1.5 = 24px, nearly as loud as Start ride itself).
   Same selector, loaded after, normalized the same way. */
@media (max-width:900px){
  html[data-app].has-route .pexp .pln-editlink{
    font-size:calc(14px * var(--ts,1.5) / 1.5);
  }
}

/* S08 Edit (mock-013): the Remove button's glyph is a trash can, drawn everywhere
   #plist renders (desktop's own long list included - js/plan.js renderTrip() is
   shared). An <svg> with only a viewBox and no width/height/CSS falls back to the UA
   default replaced-element box (300x150), not the 24x24 its viewBox implies, so this
   is unscoped rather than folded into an edit-only rule. */
.ptrash-ico{width:16px;height:16px;flex:0 0 auto}
/* Same reasoning as the trash can above: .pno--finish's own CSS (css/plan.css) sizes
   a text glyph (font-size), which an <svg> child ignores - width/height instead. */
.pfinish-ico{width:14px;height:14px}

/* ------------------------------- S08 Edit: "+ Add a stop" ------------------------------- */
/* P0-SHT-02-web (pre-existing, confirmed on base before this file touched it): the
   REAL search input (#psearch) was relocated into .pln-searchtop by JS long before
   this redesign; css/plan.css's own declutter allow-lists exempt .psearch-wrap (the
   OLD, now-empty home of that input) from being hidden while a route exists, but
   never exempted .pln-searchtop itself, so tapping "+ Add a stop" focused a field
   that was display:none the entire time - not reachable at any viewport, keyboard or
   no keyboard. js/plan.js's addStopBtn handler now also leaves the Edit sheet AND
   sets this one class; nothing else in the app ever sets it, so this cannot affect
   any other has-route state. */
html[data-app].has-route.pln-addstop-active:not(.show-dials):not([data-psheet]) .pln-searchtop{
  display:flex !important;
}

/* Edit sizing is owned by the focused state in plan.css. The former
   intermediate-detent 100dvh-345px cap clipped its list on short phones. */

/* ------------------------------- S08 Edit: sheet reaches the bottom edge ------------------------------- */
/* css/plan.css's base phone rule parks every .pln-side at
   `bottom:calc(56px + env(safe-area-inset-bottom,0px))` - room for the V1 bottom tab
   bar. That bar is hidden on every app-mode screen (FANOUT-RULES: "must not come
   back on any screen you touch") and Home's own override only lifts the 56px for
   `:not(.has-route):not([data-psheet])` (css/plan.css ~line 2212) - a selector Edit
   can never match once data-psheet="edit" is set, so Edit kept the orphaned 56px gap
   with nothing in it: confirmed directly, `.pln-side` measured bottom:788 against an
   844px-tall viewport, the 56px of real map visible underneath matching this round's
   own "map shows below the sheet" report. Lifting it here (not editing the shared
   Home-scoped rule, which the "plansetup"/Home builders also depend on) moves the
   whole sheet down by the same 56px - more map above it, not less - so its bottom
   edge lands on the real viewport edge, same as mock-013. */
@media (max-width:900px){
  html[data-app][data-psheet="edit"] .pln-side{
    bottom:env(safe-area-inset-bottom,0px);
  }
}

/* Edit keeps a visible drag grip and trash button. Keyboard alternatives remain
   focusable, but cannot intercept a pointer aimed at the grip while hidden. */
@media (max-width:900px){
  html[data-app][data-psheet="edit"] #plist .pctl{position:relative}
  html[data-app][data-psheet="edit"] #plist .pacts button[data-a="up"],
  html[data-app][data-psheet="edit"] #plist .pacts button[data-a="dn"]{
    position:absolute;opacity:0;pointer-events:none;top:0;left:-44px;
    clip-path:inset(50%);
  }
  html[data-app][data-psheet="edit"] #plist .pacts button[data-a="up"]:focus,
  html[data-app][data-psheet="edit"] #plist .pacts button[data-a="dn"]:focus{
    opacity:1;pointer-events:auto;clip-path:none;z-index:5;
    background:var(--panel);outline:2px solid var(--orange);outline-offset:1px;
  }
  html[data-app][data-psheet="edit"] #plist .pacts button[data-a="rm"] .ptrash-ico{
    width:18px;height:18px;
  }
}

/* ------------------------------- S08 Edit: list scrolls, footer does not ------------------------------- */
/* mock-013: "+ Add a stop", "Changes apply after recalculating", "Recalculate route"
   and "Restore version 1" are always on screen under the stop list, never pushed off
   the bottom of a 390x844 phone. Before this rule the whole sheet (#pedit-head,
   #plist, .padd-row, #precalc...) was one scrolling column, so a handful of real
   stops (map legs easily run 4-6 for a real route, not the mockup's illustrative 2)
   pushed the footer past the fold - confirmed directly: shots/redesign/edit-*-390.png
   cut off after the third stop, nowhere near Recalculate/Restore. #plist is the one
   element whose content length is actually unbounded (more stops = more rows); giving
   it its own bounded height and scrollbar, while everything around it stays in normal
   flow, means the sheet only needs to fit header + a few visible rows + the footer -
   not the whole list - to show the footer without scrolling the sheet itself. The
   list remains fully reachable (scrolls inside its own box); #pedit-foot's own extra
   toggles (leg style/reverse/revision history - real features the mockup does not
   draw, already folded behind "Show leg style, arrive-by date and shaping" etc.) sit
   after #precalc in the DOM and simply require scrolling the sheet past it, same as
   before - only the mockup's own four items are held to "no scroll needed". */
@media (max-width:900px){
  /* #pedit-head/.padd-row/#precalc never get flex-shrink:0 anywhere else in this
     codebase (css/plan.css relies on the WHOLE sheet scrolling as one column), so at
     a short viewport (375x667: sheet max-height 287px, not 844's 464px) the flex
     shrink pass was squeezing the FOOTER along with the list - confirmed directly:
     "Recalculate route"/"Restore version 1" were clipped below the fold in the
     375x667 shot even though #plist itself was behaving. These three are the ones
     mock-013 insists stay fully on screen; protecting them here (not globally - this
     selector only touches Edit) means #plist is the only thing left that can flex. */
  html[data-app][data-psheet="edit"] .pln-side > :is(#pedit-head, .padd-row, #precalc){
    flex-shrink:0;
  }
  html[data-app][data-psheet="edit"] #plist{
    /* flex-shrink:0 is load-bearing, TWICE over (both confirmed directly, not
       guessed). First: #plist is itself a flex item of .pln-side
       (display:flex;flex-direction:column), default flex-shrink:1 - with several
       other siblings (#pedit-head, .padd-row, #precalc, #pedit-foot,
       #editor-revision-history) all wanting their natural size inside .pln-side's
       own 464px cap (the rule just above), flexbox's shrink pass squeezed #plist
       down to ~90px regardless of a fixed max-height tried first here (clientHeight
       was 90px against a 314px max-height, scrollHeight 425px).
       flex:1 1 0 (not a fixed max-height) is what makes this work at EVERY viewport
       height, not just 844: #plist now claims whatever space is left in .pln-side
       once the three protected siblings above take their own natural size, shrinking
       itself (not them) first when the sheet is short, and scrolling its own overflow
       once it hits min-height - a fixed "100dvh - 380px - 215px" constant looked right
       at 844 and clipped the footer anyway at 375x667, where the same constants don't
       leave room for both the header AND the footer. */
    /* round 4: 128px (round 3's own floor) was sized to clear ONE "Start" row in
       full - sized correctly for the problem round 3 was solving (a row cut off
       mid-line), but still only ~1 row tall once round 4's .pname grid fix (above)
       brought a real row down to its intended ~56-96px instead of round 3's
       116-142px block-stacked height. 3 rows at .pstop's own 56px CSS floor is
       168px; 184px keeps a few px of headroom so a row that is exactly 56px tall
       does not sit flush with zero margin against the scroll boundary. #plist still
       scrolls (overflow-y:auto, unchanged) for anything past what this floor shows -
       this raises the FLOOR a short route/viewport falls back to, not a cap on how
       much a long one can show. */
    flex:1 1 0;min-height:184px;overflow-y:auto;-webkit-overflow-scrolling:touch;
  }
  /* redesign round 3 (REDESIGN-DECISIONS-3 "S08 Edit"): raising #plist's own FLOOR
     from round 2's 40px to 128px (confirmed directly: clears "Start" in full, not cut
     mid-row) only half-fixed this - #pedit-foot (below) still claimed its full natural
     ~188px of real estate every time (Show leg style/Reverse direction/Show revision
     history toggles, the static "Tap the map..." note, and "Back to route preview"),
     leaving #plist's flex-grow phase under 30px of free space on a 464-499px sheet, so
     round 2's 40px floor was being HIT, not chosen - raising the floor alone just moved
     the same crush further down the list.
     #pedit-foot gets a FIXED flex-basis (flex:0 0 56px), not a min/max range: tried a
     min/max-height pair first and confirmed directly (getBoundingClientRect across
     three different #plist floors) that it leaves 30-45px of the sheet's real free
     space unclaimed by EITHER sibling once foot's own max-height clamp engages - a
     flexbox quirk where a post-clamp on one item's main size is not reliably handed
     back to the other flex-grow item in the same pass, confirmed reproducible, not
     guessed. A FIXED basis removes that ambiguity: the two numbers (#plist floor,
     #pedit-foot's one knowable size) are the only variables left, so what is actually
     left over for #plist is arithmetic again, not a flex-engine guess. Every control
     inside #pedit-foot stays real, focusable and reachable (scrolled to, same as the
     pre-existing P0-EDT tests already do for #pedit-reverse/#pedit-history-toggle -
     scrollIntoView already anticipated a scroll container here, not a flat page) - it
     simply no longer taxes the stop list's own space to do it. mock-013 never draws
     any of this content at all, so giving it a small fixed footprint (not removing it)
     is the correct side of FANOUT-RULES "never remove a real feature, fit it into the
     mockup's layout". At 375x667 (.pln-side itself only ~322px tall - less than
     #pedit-head+.padd-row+#precalc+#pedit-foot's protected total alone) #plist's own
     128px floor cannot also fit without .pln-side's pre-existing overflow:auto taking
     over for the last ~80px: "Recalculate route" stays reachable by a normal scroll of
     the sheet, not sent to display:none or rendered half-cut - the standard mobile
     "scroll to the primary action" pattern, not the P1 "clipped off the bottom of the
     viewport, unreachable at any scroll depth" bug round 1 had. */
  html[data-app][data-psheet="edit"] #pedit-foot{
    flex:0 0 56px;overflow-y:auto;-webkit-overflow-scrolling:touch;
  }
  /* Second, one level down: css/plan.css never set #plist's own display either, and
     it resolves to flex (not the <ul> default of block) - meaning every .pstop row
     is ALSO a flex item, of #plist this time, with the same default flex-shrink:1.
     Once #plist above gained a bounded height, the combined natural height of every
     real stop row (8 on the test route used here, ~95-118px each - "min-height:56px"
     is a floor, not each row's real content height) vastly exceeded that bound, so
     flexbox shrank every row down to its bare 56px floor instead of fitting as many
     FULL rows as the space allows and scrolling the rest - confirmed directly
     (li.offsetHeight was exactly 56 while its own grid content needed up to 118,
     with Remove's button then rendered into the NEXT row's now-overlapping space,
     which is what produced the blank-badge composite this round-2 fix pass found).
     flex-shrink:0 here means a row never shrinks below its real content; #plist's
     own overflow-y:auto (above) is what makes the excess rows scroll instead. */
  html[data-app][data-psheet="edit"] #plist .pstop{flex-shrink:0}
}

/* mock-013: "Recalculate route" is drawn every time (js/plan.js updatePrecalcUI(),
   round 3), disabled rather than hidden when there is nothing staged yet - same dim
   convention this codebase already uses for every other disabled primary/secondary
   control (.pexp button[disabled], .pacts button[disabled], both opacity-based). No
   existing rule touched #pedit-recalc's own disabled state at all. */
html[data-app] #pedit-recalc:disabled{opacity:.4;cursor:default}

/* ------------------------- S08 Edit: ONE primary button on this screen ------------------------- */
/* mock-013 draws exactly one primary (orange, full-width) button on the Edit sheet:
   "Recalculate route", inside #precalc - never "Back to route preview". #pedit-done
   carries a real, separate action (css/plan.css's own button[data-a] wiring, untouched)
   and stays reachable - the header's own back arrow (#pedit-back) already does the
   identical thing (same back() handler, js/plan.js), so this was always a second door
   onto one action, not a second feature; demoted to a plain underlined link (same
   family as .pfocus-sec, reused rather than inventing a new treatment) so it stops
   reading as a competing CTA next to Recalculate. Equal selector specificity to
   css/plan.css's own ".primary" rule, this file loading after settles the tie - no
   !important needed. */
@media (max-width:900px){
  html[data-app][data-psheet="edit"] #pedit-done{
    display:inline-flex;align-items:center;justify-content:center;min-height:44px;
    width:auto;margin:2px auto 0;padding:0;border:0;background:none;box-shadow:none;
    color:var(--steel);font-size:calc(13px * var(--ts,1.5) / 1.5);font-weight:600;
    text-decoration:underline;text-underline-offset:3px;
  }
}
