/* VSSGEO phone lane "phonecards" (2026-09-28) — docs/design/phone/SPEC.md items 5, 7, 8 + report polish from ph-*.md.
   Pairs with phonecards.js. LOAD LAST on both pages (front door index.html and the map page), after chartfix.css.
   Every report rule is prefixed ":root body.door #panel" (specificity, not only order). Tokens only, 8-pt grid.
   Never touches #panel's own position/height (lane "sheet" owns that): only what is INSIDE the report.
   Sections: A report cards · B chip rows · C charts · D touch (no sticky hover) · E place popup · F front door. */

:root{
  --pc-hit:44px;                                             /* thumb target (Apple HIG / Material) */
  --pc-fade:linear-gradient(90deg,#000 calc(100% - 24px),transparent);   /* scroll-row edge: "there is more" */
}


/* ══ A · REPORT CARDS: one per row below 420 px ═══════════════════════════════════════════════════════════════════ */
@container win (max-width:420px){
  /* Life here: Evan's 2-up grid (Work | Getting around, Households | Money) -> one full-width card per row */
  :root body.door #panel .life{grid-template-columns:minmax(0,1fr)!important;gap:var(--vg-s2)}
  :root body.door #panel .life>div{grid-column:1/-1;padding:var(--vg-s4)}
  /* a full-width card has room for its figures side by side again, and meters at their full 10-block length */
  :root body.door #panel .life.vgc .vgc-m{max-width:160px}
  /* the two-column pairs (.pair: "who lives here" beside "life here") stay one column */
  :root body.door #panel .pair{grid-template-columns:minmax(0,1fr)!important;gap:var(--vg-s5,24px)}
  /* photo cards (Work "known for"/"biggest jobs"): the number column never squeezes the title */
  :root body.door #panel :is(#sOcc,#sInd) .orow.vwk-orow{grid-template-columns:16px 40px minmax(0,1fr) auto}
  :root body.door #panel :is(#sOcc,#sInd) .orow.vwk-orow .im{width:40px;height:40px}
  :root body.door #panel :is(#sOcc,#sInd) .orow.vwk-orow b{overflow-wrap:anywhere;hyphens:auto}
  :root body.door #panel :is(#sOcc,#sInd) .vwk-ob{width:100%;max-width:calc(var(--cols) * 11px)}
  /* "More about this group" (Time / Money / Values…): a 110-px label column left the story 230 px wide; the label
     now sits above its paragraph, the paragraph gets the full width */
  :root body.door #panel .rows .row{grid-template-columns:minmax(0,1fr)!important;row-gap:var(--vg-s1)}
  :root body.door #panel .rows .row .kicker{padding-top:0}
}
/* three stat tiles (89% / 5% / 10%) stay three across, but at 360 their labels get the whole tile */
@container win (max-width:380px){
  :root body.door #panel :is(.big3,.whofacts,.tiles3,.ostats)>div,
  :root body.door #panel :is(.big3,.whofacts)>div+div{padding:var(--vg-s3) var(--vg-s2)}
  :root body.door #panel :is(.big3,.whofacts,.tiles3,.ostats) b{font-size:18px}
  :root body.door #panel :is(.big3,.whofacts,.tiles3,.ostats) span{overflow-wrap:anywhere}
}


/* ══ B · CHIP ROWS: one line that scrolls sideways (shops, compare, widen-the-search, next questions, actions) ═══════ */
@container win (max-width:420px){
  :root body.door #panel :is(.shops,.cmp,.pk,.nextq,.heard .acts){
    display:flex!important;flex-wrap:nowrap!important;gap:var(--vg-s2);overflow-x:auto;overflow-y:hidden;
    margin-left:calc(-1 * var(--vg-s4));margin-right:calc(-1 * var(--vg-s4));padding:2px var(--vg-s4) var(--vg-s1);
    scroll-snap-type:x proximity;scroll-padding-inline:var(--vg-s4);overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
    -webkit-mask-image:var(--pc-fade);mask-image:var(--pc-fade)}
  :root body.door #panel :is(.shops,.cmp,.pk,.nextq,.heard .acts)::-webkit-scrollbar{display:none}
  :root body.door #panel :is(.shops,.cmp,.pk,.nextq,.heard .acts).pc-end{-webkit-mask-image:none;mask-image:none}   /* scrolled to the end */
  :root body.door #panel :is(.shops,.cmp,.pk,.nextq,.heard .acts)>*{flex:none;scroll-snap-align:start;white-space:nowrap;
    min-height:var(--pc-hit);display:inline-flex!important;align-items:center;margin:0!important}
  :root body.door #panel :is(.shops,.cmp)>.shop small{display:inline!important;margin:0 0 0 var(--vg-s1)!important}
}
/* arrive = blocks: chips slide in one after another, left to right, once (phonecards.js sets --pc-i, then .pc-in) */
:root body.door #panel .pc-row.pc-wait>*{opacity:0}
:root body.door #panel .pc-row.pc-in>*{animation:pc-chip .28s var(--vg-spring) both;animation-delay:calc(var(--pc-i,0) * 40ms)}
@keyframes pc-chip{from{opacity:0;transform:translateX(12px) scale(.9)}}


/* ══ C · CHARTS that must fit 360–414 ═══════════════════════════════════════════════════════════════════════════════ */
/* Work bars: the "%" was set in the display face while its digits were mono (Beth: "a different font") */
:root body.door #panel :is(#sOcc,#sInd) .vwk-val b,
:root body.door #panel :is(#sOcc,#sInd) .vwk-val b .vwk-n,
:root body.door #panel :is(#sOcc,#sInd) .orow.vwk-orow .pc :is(b,.vwk-n){font:600 14px/1.2 var(--vg-font-mono)!important;
  font-variant-numeric:tabular-nums;letter-spacing:0;font-synthesis:none}
:root body.door #panel .vwk-val b .pc-unit{margin-left:1px;font:500 .8em/1 var(--vg-font-mono);color:var(--vg-muted);letter-spacing:0}
:root body.door #panel :is(.big3,.whofacts,.tiles3,.ostats) b,
:root body.door #panel .life.vgc :is(.vgc-v,.vgc-n){font-family:var(--vg-font-mono)}
@container win (max-width:420px){
  /* Work block bars: 20 cells stay square and inside the card; label + value never collide */
  :root body.door #panel :is(#sOcc,#sInd) .vwk-row{column-gap:var(--vg-s2)}
  :root body.door #panel :is(#sOcc,#sInd) .vwk-lab b{overflow-wrap:anywhere}
  :root body.door #panel :is(#sOcc,#sInd) .vwk-blocks{max-width:100%}
  /* the keys ("share here | same share nationally", "= 10 people") wrap as whole items, never mid-phrase */
  :root body.door #panel :is(.vwk-key,.vgk-unit,.vgw .chips,.vgs-key,.vgg-key){flex-wrap:wrap;row-gap:var(--vg-s1);column-gap:var(--vg-s3)}
  :root body.door #panel :is(.vwk-key,.vgs-key,.vgg-key)>*{white-space:nowrap}
  /* who-lives-here waffle: 10 × 14 px squares (167 px) + legend; below 360 the legend drops under (lead-fixes.css) */
  :root body.door #panel .who .vgw{gap:var(--vg-s4)}
  :root body.door #panel .who .vgw .chips>span{white-space:nowrap}
  /* groups strip: the smallest groups keep a readable 4 px minimum and the labels stay inside */
  :root body.door #panel .vgg{max-width:100%;overflow:hidden}
  /* meters (.ibar / scales lane): value column never pushes the bar out */
  :root body.door #panel .ibar{grid-template-columns:minmax(0,1fr) auto}
  :root body.door #panel .vgs-bar{min-width:0}
}


/* ══ D · TOUCH: nothing stays lit after a tap (Beth: "#4 and #5 glow orange for no reason") ══════════════════════════
   On a phone the browser keeps :hover on whatever was tapped (or on the card that scrolled under the finger), so the
   brand ring + cursor glow of door-panels.css §6 stayed on. Hover = focus is a mouse idea; on touch it rests. */
@media (hover:none),(pointer:coarse){
  :root body.door #panel :is(.orow,.gbar,.go,.goal .chip,.jrow,button.grow,.mixrow,.shops>.shop,.cmp>.shop,.pk button,.nextq a,.heard .acts .chip):hover::after,
  :root body.door #panel :is(.orow,.gbar):hover::before,
  :root body.door .orow:hover::after{opacity:0!important;animation:none!important}
  :root body.door #panel :is(.orow,.gbar,.jrow,button.grow):hover{background:var(--vg-raise);border-color:var(--vg-rule);transform:none}
  :root body.door #panel :is(.shops>.shop,.cmp>.shop,.pk button,.nextq a,.heard .acts .chip,.mixrow):hover{transform:none}
  :root body.door #panel .gbar:hover img{transform:none}
  /* the press itself still answers: a quick tint while the finger is down */
  :root body.door #panel :is(.orow,.gbar,.jrow,button.grow):active{background:var(--vg-raise2)}
}


/* ══ E · PLACE POPUP (address pin card .vpop): 44 px buttons, docked, never over most of the map ═════════════════════
   Was 280 × 210 px anchored mid-map over the zoom stack, chips 26 px (Tom). Now a slim card docked to the bottom edge of
   the VISIBLE map (phonecards.js measures it: --pc-popb), full width minus 8, ~120 px tall; the pin stays visible above. */
@media (max-width:760px){
  body.door .maplibregl-popup.vpop:not(.gpop).pc-dock{position:absolute!important;transform:none!important;top:auto!important;
    left:var(--vg-s2)!important;right:var(--vg-s2)!important;bottom:var(--pc-popb,var(--vg-s2))!important;max-width:none!important;width:auto!important;z-index:5}
  body.door .maplibregl-popup.vpop.pc-dock .maplibregl-popup-tip{display:none}
  body.door .maplibregl-popup.vpop.pc-dock .maplibregl-popup-content{display:grid;grid-template-columns:minmax(0,1fr) auto var(--pc-hit);
    grid-template-rows:auto auto var(--pc-hit);column-gap:var(--vg-s2);row-gap:0;align-items:center;padding:var(--vg-s3) var(--vg-s3) var(--vg-s3) var(--vg-s4)}
  body.door .vpop.pc-dock .maplibregl-popup-content>b{grid-column:1;grid-row:1;padding-right:0!important;min-width:0;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  body.door .vpop.pc-dock .maplibregl-popup-content>small{grid-column:1;grid-row:2;margin:2px 0 0!important;min-width:0;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  body.door .vpop.pc-dock .vpa{grid-column:2;grid-row:1/3;margin:0!important}
  body.door .vpop.pc-dock .vpa .go{min-height:var(--pc-hit)!important;padding:0 var(--vg-s4)!important;white-space:nowrap}
  body.door .vpop.pc-dock .maplibregl-popup-close-button{position:static!important;grid-column:3;grid-row:1/3;
    width:var(--pc-hit)!important;height:var(--pc-hit)!important;font-size:20px}
  /* radius + drive: ONE row of 44-px chips that scrolls sideways */
  body.door .vpop.pc-dock .pc-vrow{grid-column:1/-1;grid-row:3;display:flex;align-items:center;gap:var(--vg-s2);margin:var(--vg-s2) calc(-1 * var(--vg-s3)) 0 calc(-1 * var(--vg-s4));
    padding:0 var(--vg-s3) 0 var(--vg-s4);overflow-x:auto;scrollbar-width:none;scroll-snap-type:x proximity;scroll-padding-inline:var(--vg-s4);overscroll-behavior-x:contain;
    -webkit-mask-image:var(--pc-fade);mask-image:var(--pc-fade)}
  body.door .vpop.pc-dock .pc-vrow::-webkit-scrollbar{display:none}
  body.door .vpop.pc-dock .pc-vrow.pc-end{-webkit-mask-image:none;mask-image:none}
  body.door .vpop.pc-dock .pc-vrow .vpr{display:flex;flex:none;align-items:center;gap:var(--vg-s2);margin:0!important}
  body.door .vpop.pc-dock .pc-vrow .vpr+.vpr{padding-left:var(--vg-s2);border-left:1px solid var(--vg-rule)}
  body.door .vpop.pc-dock .pc-vrow .vpr>span{flex:none;display:inline-block!important;scroll-snap-align:start;font:600 10.5px/1 var(--vg-font-display);letter-spacing:.12em;text-transform:uppercase;color:var(--vg-faint)}
  body.door .vpop.pc-dock .pc-vrow .chip{flex:none;min-height:var(--pc-hit)!important;min-width:var(--pc-hit);padding:0 var(--vg-s3)!important;
    display:inline-flex!important;align-items:center;justify-content:center;border-radius:var(--vg-pill);scroll-snap-align:start;
    font:500 13px/1 var(--vg-font-mono)}
  /* arrive = blocks: the card rises, then its chips step in left to right */
  body.door .vpop.pc-dock .maplibregl-popup-content{animation:pc-rise .3s var(--vg-spring) both;transform-origin:50% 100%}
  body.door .vpop.pc-dock .pc-vrow .chip{animation:pc-chip .26s var(--vg-spring) both;animation-delay:calc(120ms + var(--pc-i,0) * 30ms)}
  /* the boundary-pick card (.gpop) keeps its anchor; only its buttons grow */
  body.door .vpop.gpop :is(button,.go,.chip){min-height:var(--pc-hit)}
}
@keyframes pc-rise{from{opacity:0;transform:translateY(16px)}}


/* ══ F · FRONT DOOR on a phone (index.html, .fd) ══════════════════════════════════════════════════════════════════ */
.fd .fd-collapse .pc-x{display:none}                          /* desktop: the collapse icon; phones swap in the × below */
@media (max-width:760px){
  /* the hamburger: a full 44-px target */
  .fd .rail-open-btn{width:var(--pc-hit);height:var(--pc-hit);margin:0 0 0 -10px}
  /* the drawer, when shut, is not there at all (no invisible, focusable "Collapse sidebar" at x = -41: Jorge's dead tap).
     visibility waits for the slide-out to finish. phonecards.js also sets inert. */
  .fd .rail:not(.rail-open){visibility:hidden;transition:transform .24s cubic-bezier(.22,.61,.36,1),visibility 0s linear .24s}
  .fd .rail.rail-open{visibility:visible;transition:transform .24s cubic-bezier(.22,.61,.36,1),visibility 0s}
  /* inside the open drawer the desktop "collapse" icon becomes a plain close × (it already closes the drawer here) */
  .fd .fd-collapse{width:var(--pc-hit)!important;height:var(--pc-hit)!important}
  .fd .fd-collapse .pc-x{display:block}
  .fd .fd-collapse svg:not(.pc-x){display:none}

  /* "No question yet? [Open the map →]" — a real 44-px button, the sentence wraps around it cleanly */
  .fd .fdx-way{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;column-gap:var(--vg-s2);row-gap:var(--vg-s1);
    margin:var(--vg-s3) 0 0;text-wrap:balance}
  .fd .fdx-way a{display:inline-flex!important;align-items:center;justify-content:center;min-height:var(--pc-hit);padding:0 var(--vg-s4)!important;
    border:1px solid var(--vg-rule);border-radius:var(--vg-pill);background:var(--vg-raise);color:var(--vg-ink);
    font:600 14px/1 var(--vg-font-display);text-decoration:none;position:relative;isolation:isolate}
  .fd .fdx-way a:active{transform:scale(.97);background:var(--vg-raise2)}

  /* captions wrap in balanced lines: no lone "BUILDING" (Beth), no lone word under the hint */
  .fd :is(.sugg-hint,.hint,.lede,.legal){text-wrap:balance}
  .fd .sugg-hint{line-height:1.5;margin-top:var(--vg-s3)}
  /* "ASK ABOUT A PLACE…" never runs into the footer (Linda): a clear 16-px gap, the footer sits on the page colour */
  .fd .stage{padding-bottom:var(--vg-s4)}
  .fd .legal{position:relative;z-index:3;padding-top:var(--vg-s2);background:var(--vg-bg)}

  /* sheets (How it works, Plans, Log in): the close × is a 44-px target */
  .fd .x{width:var(--pc-hit)!important;height:var(--pc-hit)!important;font-size:20px;color:var(--vg-ink);border-color:color-mix(in srgb,var(--vg-ink) 22%,transparent)}
}
/* 360-px phones: the top bar (hamburger, wordmark, theme, Log in, Sign up) measured 374 px and clipped "Sign up" */
@media (max-width:380px){
  .fd .topbar{padding-left:var(--vg-s3);padding-right:var(--vg-s3);gap:var(--vg-s1)}
  .fd .topbar .right{gap:var(--vg-s1)}
  .fd .topbar :is(.btn-ghost,.btn-solid){padding-left:var(--vg-s3)!important;padding-right:var(--vg-s3)!important}
}
/* short phones (≤ 820 px tall): two examples instead of three, so the whole front door fits without a scroll */
@media (max-width:760px) and (max-height:820px){
  .fd .ticker{margin-top:var(--vg-s4)}
  .fd .tick-row>.tick:nth-child(n+3){display:none}
}

/* ══ motion off: final state, nothing moves ══ */
@media (prefers-reduced-motion:reduce){
  :root body.door #panel .pc-row>*,body.door .vpop.pc-dock :is(.maplibregl-popup-content,.pc-vrow .chip){animation:none!important;opacity:1!important}
  .fd .rail{transition:none!important}
  .fd .fdx-way a:active{transform:none}
}
