/* Desktop pass — ≥1100px layouts: use the width, kill the dead gutters (owned by desktop-pass agent) */
/* =====================================================================
   REFINEMENT PASS (Jul 2 2026, desktop-refinement agent) — two jobs:
   1 · SKEW AUDIT (Nick: "items skew at this width"). Programmatic
       playwright audit at 1280/1440/1920, every view + every Health and
       Business sub-tab. Findings:
       · Health Trends .dc-linechart (3 SVGs, viewBox 300×90,
         preserveAspectRatio="none") — styles.css sizes them 100%×70px,
         so at the ≥1100 content column they rendered 1050–1074×70 =
         4.5–4.6× horizontal distortion (Nick's screenshot). FIX: at
         ≥1100 the .dc-trends card goes 3-up (rangebar + note span all)
         and each chart gets aspect-ratio:300/90 + height:auto → uniform
         ~1.1× scale, zero distortion. Static markup verified
         (index.html:334-365: rangebar · note · 3× .dc-trend-group).
       · #mkChart (marker modal, viewBox 300×130, pAR=none) had the same
         latent stretch (~1.6×) in the 520px sheet — same aspect-ratio
         lock at ≥1100. Mobile untouched.
       · Chart.js canvases: ZERO attr-vs-CSS mismatches at all 3 widths
         (all 8 charts are responsive:true + maintainAspectRatio:false;
         belt-and-braces resize nudge added in pop.js v3).
       · .dc-m .spark sparklines: NOT skewed — no CSS width, they size
         intrinsically from the viewBox (100×26), uniform at all widths.
       · .pp-hero/.pp-upnext scroll overflow = the intentional
         overflow:hidden decorative corner circles, not clipping.
       · No stretched images, no text clipping found.
   2 · RAIL UPGRADE (Nick: "left hand menu could use some love") — at
       ≥1100 the 104px icon strip becomes a 216px navigation panel:
       wordmark, full-width icon+label rows, gold-dot active state.
       CSS-only on the frozen .tabbar/.tab/.tab-ic/.tab-lbl hooks;
       900–1099 keeps the 104px rail, <900 keeps the pill — untouched.
   ===================================================================== */
/* =====================================================================
   DESKTOP PASS (Jul 2 2026).
   Nick: "looks much better on mobile than desktop — lots of negative
   space on the sides of each view, just kind of boring."
   Loads LAST in <head> (after styles/reskin-family/reskin-dash/pop/
   mobile-audit) so equal-specificity selectors here win all ties.
   CSS ONLY. Everything is scoped ≥1100px ("wide"); the existing ≥900px
   rail + mid-step rules in styles.css are untouched, and NOTHING below
   900px changes. No behavior changes: [hidden] panels stay hidden, no
   interactive reordering — grids live on static containers only
   (index.html children verified static per selector; JS-generated
   content arrives INSIDE those containers).
   ===================================================================== */

/* Health .hl-aside wrapper (index.html, all 5 person panels): below 1100px it
   must be layout-inert so the mobile flow is byte-identical to the pre-wrapper
   markup — display:contents makes its children lay out as if they were direct
   panel children. At ≥1100 js/health-masonry.js re-homes its children into the
   masonry columns (§9) and the emptied aside stays behind as a zero-footprint
   display:contents shell (it's part of the pristine-restore snapshot). */
.hl-aside{display:contents;}

@media (min-width:1100px){

  :root{ --dw:1200px; }   /* effective content max (rail excluded) */

  /* HIDDEN GUARD — this pass puts display:grid on several id-selected
     panels (#bp-*, #fin-snapshot-panel; #hp-* are plain block now that
     Health packing moved to js/health-masonry.js). An id rule out-ranks
     styles.css's .hp-panel[hidden]{display:none}, which would leave
     app.js-hidden panels visible — so re-assert [hidden] at id
     specificity FIRST. Hidden must always stay hidden. */
  #bp-overview[hidden],#bp-finance[hidden],#bp-clients[hidden],#bp-sidekicks[hidden],
  #hp-nick[hidden],#fin-snapshot-panel[hidden]{display:none;}

  /* -------------------------------------------------------------------
     1 · CANVAS — the app frame dissolves into a full-bleed cream canvas.
     styles.css ≥900 paints body cream-2 with a 1180px cream .app island
     (= the giant dead gutters Nick flagged). At wide, the whole canvas
     is cream and the content column centers itself in it.
     ------------------------------------------------------------------- */
  body{background:var(--cream);}
  /* padding-left 216px = the upgraded rail (section 11); styles.css ≥900
     set 104px for the icon strip, which still applies 900–1099. */
  .app{max-width:none;background:transparent;padding-left:216px;}

  /* Ambient organic shapes in the gutters — very subtle, fixed, behind
     everything (z-index:-1 child of body paints above the body/canvas
     background but below all content), pointer-events off, inset:0 so
     they can never create scrollbars. body::before/::after verified
     unused by every earlier stylesheet (grepped Jul 2 2026). */
  /* left:216px (not inset:0) so the gradient box starts at the rail's
     edge — the ambient shapes spill out from behind the 216px rail
     instead of being swallowed under it (refinement pass). */
  body::before,body::after{
    content:"";position:fixed;top:0;right:0;bottom:0;left:216px;
    z-index:-1;pointer-events:none;
  }
  /* Polish pass Jul 2: Nick still saw "lots of negative space" — the
     first-pass alphas were too timid. Roughly doubled (gold .10→.16,
     lilac .5→.65, sage .45→.6) + one extra gold pool lower-left so a
     short view (Shopping) never reads as bare canvas. */
  body::before{ /* left gutter: lilac high, sage mid-low, gold pool at the foot */
    background:
      radial-gradient(circle 500px at -120px 16%, rgba(233,221,241,0.65), transparent 62%),
      radial-gradient(circle 400px at 6% 96%, rgba(226,232,210,0.6), transparent 65%),
      radial-gradient(circle 330px at -60px 76%, rgba(217,154,58,0.12), transparent 65%);
  }
  body::after{ /* right gutter: gold high, lilac low */
    background:
      radial-gradient(circle 580px at calc(100% + 150px) 8%, rgba(217,154,58,0.16), transparent 62%),
      radial-gradient(circle 360px at 98% 74%, rgba(233,221,241,0.55), transparent 65%);
  }

  /* -------------------------------------------------------------------
     2 · CONTENT WIDTH — raise the column to ~1200px and center it in
     the canvas (the .app no longer centers content since it's now
     full-bleed; padding-left:104px = the ink rail, inherited from
     styles.css ≥900). Per-view id selectors repeat the generic rule to
     out-rank reskin-family's 760px caps + pop.css's pp-mount caps.
     ------------------------------------------------------------------- */
  .page,.topbar,.hero{
    max-width:var(--dw);margin-left:auto;margin-right:auto;
  }
  .view[data-view="health"] .page,
  .view[data-view="business"] .page,
  #view-todo .page,#view-calendar .page,#view-shopping .page,#view-finances .page,
  #view-todo .topbar,#view-calendar .topbar,#view-shopping .topbar,#view-finances .topbar{
    max-width:var(--dw);margin-left:auto;margin-right:auto;
  }
  .segmented,
  #view-todo .segmented,#view-shopping .segmented,#view-finances .segmented{
    max-width:var(--dw);margin-left:auto;margin-right:auto;padding:0 36px;
  }
  .hp-switcher{max-width:var(--dw);margin-left:auto;margin-right:auto;padding:0 36px;}
  .pp-mount,
  #view-todo .pp-mount,#view-shopping .pp-mount,#view-finances .pp-mount{
    max-width:var(--dw);margin-left:auto;margin-right:auto;padding:0 36px;
  }
  /* Calendar's mounts live INSIDE main.page (already padded + capped) */
  #view-calendar .pp-mount{max-width:none;padding:0;margin-left:0;margin-right:0;}

  /* Vertical rhythm (polish pass): pages start higher — the mobile-first
     safe-area topbar padding is dead height on a desktop canvas. */
  .topbar{padding-top:16px;padding-bottom:10px;}

  /* -------------------------------------------------------------------
     3 · TYPE SCALE — the wider canvas must not make elements feel small.
     ------------------------------------------------------------------- */
  .topbar h1{font-size:34px;}
  .hm-greet1{font-size:28px;}
  .hm-greet2{font-size:34px;}
  #view-home .skippy-text.hm-affirm{font-size:14px;}
  .hm-stat-num{font-size:40px;}
  .pp-stat{font-size:64px;}
  .pp-hero{padding:24px 28px;}
  .pp-hero::before{width:210px;height:210px;top:-80px;right:-56px;}
  .pp-hero::after{width:116px;height:116px;top:34px;right:-40px;}
  .pp-cal-day{font-size:40px;}
  .pp-cal-num{font-size:44px;}
  .pp-up-title{font-size:24px;}

  /* -------------------------------------------------------------------
     4 · HOME (#view-home) — denser 3-col bento: UP NEXT spans 2, the
     H&S butter bar and the plum Skippy tile share the last row.
     (Same static .hm-grid areas styles.css already re-maps at ≥900.)
     ------------------------------------------------------------------- */
  .hm-grid{
    gap:14px;
    grid-template-columns:repeat(3,1fr);
    grid-template-areas:
      "upnext upnext todo"
      "today  shop   fin"
      "biz    biz    kids";
  }
  .hm-upnext{padding:20px 22px;}
  .hm-biz{padding:18px 22px;}
  .hm-biz-num{font-size:30px;}

  /* -------------------------------------------------------------------
     5 · TO-DO (#view-todo) — hero already spans the full column; the
     segmented control shows ONE .todo-panel at a time (app.js toggles
     [hidden]), so the zero-behavior-change move is a 2-col grid of the
     visible panel's task cards. .td-list is the stable app.js-rendered
     container; children arrive at runtime and auto-place.
     ------------------------------------------------------------------- */
  #view-todo .td-list{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:10px 14px;align-items:stretch;
  }
  #view-todo .td-list > *{min-width:0;}
  #view-todo .td-list .hc-empty{grid-column:1 / -1;}

  /* -------------------------------------------------------------------
     6 · CALENDAR (#view-calendar) — editorial 2-col: date hero + week
     strip + UP NEXT banner + Today timeline stack left (~58%); the
     Upcoming agenda card sits right (~42%), sticky. The .page has
     exactly 5 static children (verified index.html:1456-1480); the
     agenda card is identified by its frozen #agenda-list hook.
     ------------------------------------------------------------------- */
  #view-calendar .page{
    display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);
    column-gap:22px;row-gap:0;align-items:start;
  }
  #view-calendar .page > *{grid-column:1;min-width:0;}
  #view-calendar .page > .card:has(#agenda-list){
    /* span 30 (not 4): a spanning item's extra height distributes EQUALLY
       across all spanned auto rows — over 4 rows that inflates visible
       gaps between the left column's cards; over 30 rows (26 of them
       empty, 0-height) the share per real row is negligible. */
    grid-column:2;grid-row:1 / span 30;
    position:sticky;top:20px;
    max-height:calc(100vh - 40px);overflow-y:auto;
  }

  /* -------------------------------------------------------------------
     7 · SHOPPING (#view-shopping) — hero full width above; the .page
     splits 2-col: store panels left (~62%), the add-item form card
     right (~38%, sticky). .page children verified (index.html:1608-57):
     1 .shop-add-card · 2-6 .shop-panel ×5. app.js shows ONE panel at a
     time by toggling [hidden] (display:none ⇒ not a grid item), so all
     five panels can safely share grid cell 1/1 — never force-shown.
     The panels' item lists still flow 2-col inside the left column.
     ------------------------------------------------------------------- */
  #view-shopping .page{
    display:grid;grid-template-columns:minmax(0,1.63fr) minmax(0,1fr);
    column-gap:22px;row-gap:0;align-items:start;
  }
  #view-shopping .page > .shop-panel{grid-column:1;grid-row:1;min-width:0;}
  #view-shopping .page > .shop-add-card{
    grid-column:2;grid-row:1 / span 20; /* empty 0-height absorber rows */
    align-self:start;position:sticky;top:20px;
    margin-top:12px;min-width:0;
  }
  #view-shopping .shop-list{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:10px;row-gap:0;align-items:stretch;
  }
  #view-shopping .shop-list > *{min-width:0;}
  #view-shopping .td-prio + .td-prio{border-top:none;}
  #view-shopping .shop-list .td-prio:nth-child(n+3){
    border-top:1px solid rgba(110,48,24,0.15);
  }
  #view-shopping .shop-list .hc-empty{grid-column:1 / -1;}

  /* -------------------------------------------------------------------
     8 · FINANCES (#view-finances) — snapshot goes 2-col: decisions +
     insights + averages left (~58%); the long "By category" card right
     (~42%). Children are JS-generated in a variable set (era card and
     insights may be absent), so nth-child is unsafe — the category card
     is the only one containing .fin-group-h group headers (:has()).
     Row-gap stays 0; the cards' own margin-top provides rhythm, and the
     right card's 40-row span parks its overflow in empty 0-height rows.
     ------------------------------------------------------------------- */
  #fin-snapshot-panel{
    display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);
    column-gap:22px;row-gap:0;align-items:start;
  }
  #fin-snapshot-panel > *{grid-column:1;min-width:0;}
  #fin-snapshot-panel > .card:has(.fin-group-h){grid-column:2;grid-row:1 / span 40;}
  /* placeholder / not-wired state = a single card → let it span */
  #fin-snapshot-panel > .card:only-child{grid-column:1 / -1;}
  /* Target Planner is a label+input ledger — cap it at a readable width */
  #fin-plan-root{max-width:820px;margin-left:auto;margin-right:auto;}

  /* -------------------------------------------------------------------
     9 · HEALTH (#view-health, ALL 5 person panels) — deterministic JS
     masonry. REBUILT Jul 3 2026 (3rd rewrite): CSS multicolumn
     (column-fill:balance) can't guarantee packing — it left ragged
     column bottoms, stranded the bio-age card half-width between the
     two span-all heroes, and trapped the wide marker grids in a narrow
     column (Nick's screenshots). Packing is now COMPUTED by
     js/health-masonry.js, which partitions each panel into:
       ZONE A · row     — the reps hero (.hc-hero) full-width up top.
                          (Pass 2, Jul 3: the protocol tracker is NO
                          LONGER a row — its NOW-left/chips-right band
                          left the right ~40% empty below the short chip
                          strip. It now packs into the masonry as one
                          tall card, chips stacked below the NOW card at
                          column width, i.e. its natural mobile flow.)
       ZONE B · masonry — card units moved into real column divs
                          (.hmz-cols > .hmz-col ×2, ×3 ≥1500px), each
                          appended to the currently-shortest column.
                          Pass 2: multi-card sections are SPLIT — title
                          glued to its first card, every further card
                          its own unit — so packing balances at card
                          granularity and bottoms end within ~one card
                          of even (a whole "Patterns" tower no longer
                          strands dead space beside short neighbours);
       ZONE C · bands   — the genuinely wide data runs (Daily metrics,
                          Trends, Correlation, Individual markers,
                          Derived & composite) as full-width .hmz-band
                          rows at the bottom, marker grids 4-up/5-up via
                          styles.css. Pass 2: ONLY a genuinely over-long
                          band (>1200px — in practice the long lab
                          grids) gets the 620px cap + "Show all";
                          Daily metrics renders full-height, no inner
                          scrollbar.
     The script re-runs on load / resize / person-tab + view switches /
     async renders / <details> toggles, and restores the pristine DOM
     below 1100px or on any error — mobile flow stays byte-identical,
     and with JS off the panel is plain vertical flow (correct, just
     less dense). The rules below style ONLY the script's wrappers plus
     a few full-width-band refinements.
     ------------------------------------------------------------------- */
  #view-health .hp-panel{display:block;}
  #view-health .hp-panel[hidden]{display:none;}

  /* masonry containers (only exist while the script has laid out) */
  #view-health .hmz-cols{
    display:grid;grid-template-columns:repeat(var(--hmz-n,2),minmax(0,1fr));
    gap:0 22px;align-items:start;margin-top:6px;
  }
  /* sparse panels (Ollie) — one centered, width-constrained column so the few
     cards read as an intentional stack, not a lopsided 2-col with dead space */
  #view-health .hmz-cols.hmz-one{max-width:860px;margin-left:auto;margin-right:auto;}
  #view-health .hmz-col{display:flex;flex-direction:column;min-width:0;}
  #view-health .hmz-col > *{min-width:0;}
  /* a column is roughly phone-width, so grids nested INSIDE a column card
     render at their mobile density (overrides styles.css's global ≥900
     4-up / ≥1200 5-up .dc-grid3 rules, which are for full-width bands) */
  #view-health .hmz-col .dc-grid3{grid-template-columns:repeat(2,1fr);}

  /* Placement units (.hmz-unit) — each cohesive section/cluster is wrapped so
     it moves + measures atomically and the vertical rhythm is uniform + clean
     (a "designed" 18px gap between units, not the heterogeneous inline margins
     the raw cards carry). .hmz-ubody holds the section's cards. */
  #view-health .hmz-unit{display:flex;flex-direction:column;min-width:0;}
  #view-health .hmz-col > .hmz-unit{margin-top:18px;}
  #view-health .hmz-col > .hmz-unit:first-child{margin-top:0;}
  #view-health .hmz-unit > .section-title{margin-top:0;}
  #view-health .hmz-ubody{display:flex;flex-direction:column;min-width:0;}
  #view-health .hmz-ubody > :first-child{margin-top:0 !important;}

  /* Section scroll-cap. Units are placed whole (title + all cards in one
     column) so cohesive tools (Chantelle's Cycle optimizer, Nick's EQ block)
     never scatter. A genuinely tall NON-interactive narrative unit (measured
     body > SEC_CAP, e.g. Nick's "Patterns we're tracking") has its body folded
     into this bounded scroll box by the script so it can't tower over its
     neighbour and strand dead space; interactive/tool units are never capped. */
  #view-health .hmz-ubody.hmz-scrollcap{
    max-height:560px;overflow-y:auto;overscroll-behavior:contain;
    padding-right:6px;
  }

  /* Full-width feature block (Chantelle's Cycle & hormone optimizer) — a
     cohesive tool given the whole width, above the marker bands. Its inner
     .dc-grid3 (the 4 cycle phases) uses the full-width 4-up/5-up rules from
     styles.css (it is NOT inside .hmz-col), so the phases lay out in one row. */
  #view-health .hmz-fullsec{margin-top:12px;}
  #view-health .hmz-fullsec > .section-title:first-child{margin-top:0;}

  /* Reps hero (Nick's "TODAY'S 3 REPS" terracotta banner) is a full-width row.
     Lay its reps ACROSS the width instead of stacked on the left half, so the
     right side isn't empty (Nick, Jul 3 2026: "if terracotta reps are full
     width they'll all be on one line"). auto-fit fills the banner with as many
     rep columns as fit; the label spans the full first line above them. */
  #view-health .hc-hero .hc-hero-rows{
    display:grid;
    grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
    gap:14px 34px;align-items:start;
  }

  /* pop.css hides the static daily-protocol card via a `.pt-live >`
     direct-child rule that can't see into a column — the script tags the
     title + details .hmz-daily-proto and it's hidden by class instead. The
     :has() rule collapses the now-empty wrapper so it leaves no ghost gap. */
  #view-health .hp-panel.pt-live .hmz-daily-proto{display:none;}
  #view-health .hp-panel.pt-live .hmz-unit:has(> .hmz-daily-proto){display:none;}

  /* ZONE C bands — full width. .hmz-capped is only applied by the script
     to bands over ~1200px tall (the long lab grids), never blanket. */
  #view-health .hmz-band{min-width:0;}
  #view-health .hmz-band.hmz-capped:not(.hmz-open){
    max-height:620px;overflow-y:auto;overscroll-behavior:contain;
    padding-right:6px;
  }
  #view-health .hmz-more{
    display:inline-flex;align-items:center;border:0;cursor:pointer;
    font-family:"Space Grotesk","Hanken Grotesk",system-ui,sans-serif;
    font-weight:600;font-size:12.5px;color:var(--ink,#241b26);
    background:#efe6d6;border-radius:999px;padding:8px 16px;margin:12px 0 4px;
  }
  #view-health .hmz-more:hover{background:#e4d6bf;}

  /* Derived & composite grid uses the full band width */
  #view-health .hmz-band .dc-dgrid{grid-template-columns:repeat(auto-fit,minmax(230px,1fr));}

  /* Protocol tracker — pass 2: packed INTO a masonry column as one tall
     card (the old full-width NOW-left/chips-right row left the right
     ~40% empty below the short chip strip). Chips stack below the NOW
     card via their untouched mobile styles; no desktop override needed. */

  /* Icon-blowup guard (kept from the previous pass): purely defensive —
     stops any future unsized inline SVG from stretching to its container
     width (the "giant icon" failure of layout attempt #2). It explicitly
     EXCLUDES the full-width line/marker charts, which are MEANT to fill
     their card; max-width:100% never shrinks a correctly-sized icon. */
  #view-health .hp-panel svg:not(.dc-linechart):not(.mk-chart){
    max-width:100%;
  }

  /* -------------------------------------------------------------------
     10 · BUSINESS (#view-business) — widen + let the density breathe.
     Finance-tab KPI row goes 6-up (6 static tiles = one clean row);
     chart cards pair 2-up. Static children per panel verified Jul 2:
       #bp-finance: 1 note · 2 flags · 3 kpis · 4t/5 waterfall ·
         6t/7 revChart · 8t/9 loanChart · 10t/11 ratios · 12+ full.
       #bp-overview: 1 kpis · 2t/3 flags · 4t/5 watch · 6t/7 week ·
         8t/9 tasks · 10 note.
       #bp-clients: 1t/2 statusChart · 3t/4 newClientChart · 5t/6 roster.
       #bp-sidekicks: 1 kpis · 2t/3 skChart · 4t/5 topClientChart · 6t/7 table.
     Paired cards stretch to equal height per row (default align).
     ------------------------------------------------------------------- */
  #view-business #biz-fkpis{grid-template-columns:repeat(6,1fr);}

  /* Overview — judgment|watch, then work|on-deck */
  #bp-overview{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:20px;row-gap:0;
  }
  #bp-overview > *{grid-column:1 / -1;min-width:0;}
  #bp-overview > :nth-child(2){grid-column:1;grid-row:2;}
  #bp-overview > :nth-child(3){grid-column:1;grid-row:3;}
  #bp-overview > :nth-child(4){grid-column:2;grid-row:2;}
  #bp-overview > :nth-child(5){grid-column:2;grid-row:3;}
  #bp-overview > :nth-child(6){grid-column:1;grid-row:4;}
  #bp-overview > :nth-child(7){grid-column:1;grid-row:5;}
  #bp-overview > :nth-child(8){grid-column:2;grid-row:4;}
  #bp-overview > :nth-child(9){grid-column:2;grid-row:5;}

  /* Finance — waterfall|ratios, revenue|loan */
  #bp-finance{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:20px;row-gap:0;
  }
  #bp-finance > *{grid-column:1 / -1;min-width:0;}
  #bp-finance > :nth-child(4){grid-column:1;grid-row:4;}
  #bp-finance > :nth-child(5){grid-column:1;grid-row:5;}
  #bp-finance > :nth-child(10){grid-column:2;grid-row:4;}
  #bp-finance > :nth-child(11){grid-column:2;grid-row:5;}
  #bp-finance > :nth-child(6){grid-column:1;grid-row:6;}
  #bp-finance > :nth-child(7){grid-column:1;grid-row:7;}
  #bp-finance > :nth-child(8){grid-column:2;grid-row:6;}
  #bp-finance > :nth-child(9){grid-column:2;grid-row:7;}

  /* Clients — the two charts side by side, roster full width */
  #bp-clients{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:20px;row-gap:0;
  }
  #bp-clients > *{grid-column:1 / -1;min-width:0;}
  #bp-clients > :nth-child(1){grid-column:1;grid-row:1;}
  #bp-clients > :nth-child(2){grid-column:1;grid-row:2;}
  #bp-clients > :nth-child(3){grid-column:2;grid-row:1;}
  #bp-clients > :nth-child(4){grid-column:2;grid-row:2;}

  /* Sidekicks — status chart | top-clients chart, workforce full width */
  #bp-sidekicks{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:20px;row-gap:0;
  }
  #bp-sidekicks > *{grid-column:1 / -1;min-width:0;}
  #bp-sidekicks > :nth-child(2){grid-column:1;grid-row:2;}
  #bp-sidekicks > :nth-child(3){grid-column:1;grid-row:3;}
  #bp-sidekicks > :nth-child(4){grid-column:2;grid-row:2;}
  #bp-sidekicks > :nth-child(5){grid-column:2;grid-row:3;}

  /* -------------------------------------------------------------------
     10.5 · SKEW FIXES (refinement audit, Jul 2) — hand-drawn SVGs with
     preserveAspectRatio="none" must render at their viewBox aspect or
     the strokes/dots distort (the Trends bug in Nick's screenshot).
     ------------------------------------------------------------------- */
  /* Trends card: 3 groups side by side; rangebar + note span the row.
     Children are static markup (rangebar · note · 3× .dc-trend-group). */
  #view-health .dc-trends{
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    column-gap:24px;row-gap:0;align-items:start;
  }
  #view-health .dc-trends > .dc-rangebar,
  #view-health .dc-trends > .dc-trend-note{grid-column:1 / -1;}
  #view-health .dc-trends > .dc-trend-group{min-width:0;margin-bottom:0;}
  /* aspect-ratio matches the viewBox (300×90) → uniform scaling, zero
     distortion, ~1.1× at the 3-up column width. */
  #view-health .dc-linechart{height:auto;aspect-ratio:300 / 90;}
  /* Marker-modal chart: same latent stretch (viewBox 300×130 forced to
     100%×130px in the 520px sheet ≈ 1.6×) — aspect lock at wide only.
     app.js only toggles its inline display, never width/height. */
  .mk-chart{height:auto;aspect-ratio:300 / 130;}

  /* -------------------------------------------------------------------
     11 · NAVIGATION RAIL — 104px icon strip → 216px panel. Same frozen
     hooks (.tabbar/.tab/.tab-ic/.tab-lbl/.tab-badge/.is-active), pure
     CSS. desktop.css loads last, so equal-specificity overrides of the
     styles.css ≥900 rail rules win.
     ------------------------------------------------------------------- */
  .tabbar{
    width:216px;max-width:216px;
    align-items:stretch;gap:4px;
    padding:calc(env(safe-area-inset-top) + 20px) 14px 20px;
  }
  /* Wordmark. The gold dot is a background radial on the ::before box
     itself — width:max-content tracks the text, so the dot always sits
     just past "Family" regardless of font loading. */
  .tabbar::before{
    content:"Deck Family";display:block;width:max-content;max-width:100%;
    font-family:"Space Grotesk","Hanken Grotesk",system-ui,sans-serif;
    font-weight:700;font-size:18px;line-height:1.25;letter-spacing:-0.01em;
    color:#f6efe3;
    padding:2px 14px 2px 8px;margin:0 0 20px;
    background:radial-gradient(circle 2px at calc(100% - 6px) calc(100% - 9px),
      var(--gold) 99%, transparent) no-repeat;
  }
  /* Tabs become full-width rows: 18px icon + the unhidden label. */
  .tab{
    width:100%;height:auto;flex:0 0 auto;
    display:flex;align-items:center;justify-content:flex-start;gap:10px;
    padding:11px 14px;border-radius:14px;
    color:#9b8ba0;
    transition:color .15s ease, background .15s ease;
  }
  .tab-ic{font-size:18px;line-height:1;}
  .tab .tab-ic svg{width:18px;height:18px;}
  /* Un-sr-only the label (styles.css clips it below 1100 — mobile and
     the 104px strip keep the icon-only look). */
  .tab-lbl{
    position:static;width:auto;height:auto;margin:0;padding:0;
    overflow:visible;clip:auto;clip-path:none;white-space:nowrap;border:0;
    font-size:13px;font-weight:600;letter-spacing:.01em;
  }
  .tab.is-active{background:#3d2e40;color:#f6efe3;}
  /* Active gold dot moves from under-the-icon to the row's right edge. */
  .tab.is-active::after{
    left:auto;right:12px;bottom:auto;top:50%;transform:translateY(-50%);
  }
  /* To-do badge: styles.css pins it to the icon's top-right corner
     (absolute inside .tab-ic). On a row, park it right-aligned instead —
     .tab-ic goes static so the badge resolves against the .tab
     (position:relative via styles.css), sitting before the active dot. */
  .tab .tab-ic{position:static;}
  .tab-badge{top:50%;right:28px;transform:translateY(-50%);}

}/* end ≥1100 */

/* =====================================================================
   PER-VIEW WATERMARK (polish pass Jul 2) — a huge outlined display word
   naming the current view, parked bottom-right BEHIND everything. Fills
   the canvas short views (Shopping) leave empty.
   Why .app::after and not .view::after: styles.css animates every shown
   view (viewIn, fill-mode both), and the retained transform makes each
   .view a containing block for fixed descendants — a fixed ::after on
   the section would pin to the section's bottom (= page bottom), not
   the viewport. .app is untransformed (position:relative only), so its
   fixed pseudo positions to the viewport and can never create
   scrollbars. body:has(#view-X:not([hidden]))) picks the word from the
   router's own [hidden] toggling — zero JS. :has()-less browsers just
   get no watermark (content stays ""). z-index:-1 paints above the body
   canvas but below all content (same layering as the ambient shapes).
   ===================================================================== */
@media (min-width:1280px){
  .app::after{
    content:"";position:fixed;right:26px;bottom:2px;z-index:-1;
    pointer-events:none;user-select:none;
    font-family:"Space Grotesk","Hanken Grotesk",system-ui,sans-serif;
    font-weight:700;font-size:140px;line-height:1;letter-spacing:-0.04em;
    white-space:nowrap;
    color:transparent;-webkit-text-stroke:1.5px rgba(90,38,96,0.07);
  }
  body:has(#view-home:not([hidden])) .app::after{content:"home";}
  body:has(#view-calendar:not([hidden])) .app::after{content:"calendar";}
  body:has(#view-todo:not([hidden])) .app::after{content:"todo";}
  body:has(#view-finances:not([hidden])) .app::after{content:"finances";}
  body:has(#view-health:not([hidden])) .app::after{content:"health";}
  body:has(#view-business:not([hidden])) .app::after{content:"business";}
  body:has(#view-shopping:not([hidden])) .app::after{content:"shopping";}
  body:has(#view-skippy:not([hidden])) .app::after{content:"skippy";}
}

/* =====================================================================
   ≥1400 — one extra density step: the 12-tile Overview KPI wall goes
   6-up (two clean rows instead of three).
   ===================================================================== */
@media (min-width:1400px){
  #view-business #biz-ovkpis{grid-template-columns:repeat(6,1fr);}
}

/* =====================================================================
   HOVER (desktop pointers only) — cards lift 2px with a slightly deeper
   shadow, chips darken. Scoped ≥1100 so nothing below 900 changes.
   ===================================================================== */
@media (min-width:1100px) and (hover:hover){
  .card,.dc-m,.dc-gz,.biz-kpi,
  .hm-upnext,.hm-stat,.hm-biz,.hm-small,.hm-kids,
  #view-todo .td-prio,.pp-upnext,.sk-kidcard,.sk-hub-card{
    transition:transform .15s ease, box-shadow .15s ease;
  }
  .card:hover,.dc-m:hover,.dc-gz:hover,.biz-kpi:hover{
    transform:translateY(-2px);
    box-shadow:0 6px 18px rgba(36,27,38,0.10), var(--hairline);
  }
  .hm-upnext:hover,.hm-small-fin:hover,#view-todo .td-prio:hover,
  .sk-kidcard:hover,.sk-hub-card:hover{
    transform:translateY(-2px);
    box-shadow:0 6px 18px rgba(36,27,38,0.10);
  }
  /* flat pastel/plum/clay tiles: lift with a softer shadow */
  .hm-stat:hover,.hm-biz:hover,.hm-kids:hover,.hm-small-shop:hover,.pp-upnext:hover{
    transform:translateY(-2px);
    box-shadow:0 6px 16px rgba(36,27,38,0.08);
  }
  /* chips darken */
  .seg-btn:hover:not(.is-active),.hp-btn:hover:not(.is-active){
    background:#e4d6bf;color:#6a5b46;
  }
  .oor-toggle:not(.on):hover{background:rgba(143,157,111,0.22);}
  /* rail rows (refinement pass) */
  .tab:hover:not(.is-active){background:rgba(61,46,64,.6);color:#d9cfe0;}
}

/* Respect reduced motion: keep the shadows, kill the movement. */
@media (min-width:1100px) and (prefers-reduced-motion:reduce){
  .card:hover,.dc-m:hover,.dc-gz:hover,.biz-kpi:hover,
  .hm-upnext:hover,.hm-stat:hover,.hm-biz:hover,.hm-small:hover,.hm-kids:hover,
  #view-todo .td-prio:hover,.pp-upnext:hover,.sk-kidcard:hover,.sk-hub-card:hover{
    transform:none;
  }
}
