/* ============================================================
   MATTHEW HOUSE - DETAIL VIEW STANDARD
   Verbatim port of _handoff/Program Detail Mock (Program Detail.html
   inline block + the program-wizards.css kit rules it uses).

   EVERY rule is scoped under #mhDetail so the mock's generic class names
   (.modal .row .chip .tile .day .field .icf .term .kv .flag .meter ...)
   cannot leak into the app - and, just as important, so the id-level
   specificity beats any single-class app/MudBlazor rule that would
   otherwise leak IN (the .static/MudBlazor collision lesson).

   This is the APP-WIDE detail shell: Program is the first host, Client /
   Household / Subsidy are next, so nothing here is Program-specific.

   Dropped from the mock on purpose: the canvas chrome (.frame/.fr-label/
   .dv-vbar variant switcher/.dv-sheet spec sheet) and the cream demo body -
   the standing rule is ONE cool-gray background app-wide.
   Dark mode is re-keyed from the mock's [data-theme="dark"] to the app's
   body.dark. Plain hyphens and plain quotes only.
   ============================================================ */

/* TERM-DATES-01 (Aug 15 2026): the weekday picker on the Term settings SCHEDULE step.
   The same seven-button row the term wizard uses, rebuilt on THIS surface's tokens
   rather than borrowing the wizard's scoped copy - #pgWiz's version cannot reach here
   and duplicating its literals would drift the moment either palette moved. */
/* THE SCHEDULE TAB'S STATE FILTER (CEO, Aug 15 2026). Active / Complete / Cancelled / All.
   Built on THIS surface's tokens rather than borrowing .mh-app .seg: that lives outside
   #mhDetail's scope and would inherit the app palette instead of the detail one, so the
   pill would not match the record it sits in. Same counted-toggle shape as the Program
   Terms buckets so the app has one idiom, not two. */
#mhDetail .dv-seg{
  display:inline-flex;gap:4px;padding:4px;margin:0 0 16px;
  background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);border-radius:var(--r-pill);
}

/* `.dv-schedbar` / `.dv-addterm` WERE DELETED (CEO, Aug 17 2026). They wrapped the
   Schedule filter so an Add Term button could sit beside it - but Add Term is in the
   record's (...) menu too, and two doors into one room on one screen is one too many.
   The menu kept it because it works from Overview and Roster as well as Schedule.
   Nothing else used either class; the filter is back to a bare .dv-seg above. */
#mhDetail .dv-seg button{
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 15px;border:0;background:none;border-radius:var(--r-pill);cursor:pointer;
  font-family:var(--font-sans);font-size:12.5px;font-weight:650;color:var(--ink-3);
  transition:background var(--t),color var(--t);
}
#mhDetail .dv-seg button:hover{color:var(--ink-1)}
#mhDetail .dv-seg button.on{background:var(--brand);color:#fff}
#mhDetail .dv-seg button span{
  font-size:11px;font-weight:700;padding:1px 7px;border-radius:var(--r-pill);
  background:rgba(40,60,80,.10);
}
#mhDetail .dv-seg button.on span{background:rgba(255,255,255,.22)}

/* THE TERM SETTINGS FORM USES THE FULL PANE (CEO, Aug 15 2026). `.dv-form` caps at 920px,
   which is right for a two-column personal record and wrong here: the pane is 1178px, so
   the form left 258px of empty column on its right while the read view beside it filled
   the width. This is what EditFormClass exists for - Subsidy opts out the same way.

   WRITTEN AS `.dv-form.tm-form`, AND THAT IS THE WHOLE FIX. The first attempt was
   `#mhDetail .tm-form`, which has the SAME specificity as `#mhDetail .dv-form` (one id,
   one class) - so the cap simply won on source order, being later in this file. Measured:
   the class was on the element and the computed max-width was still 920px. Two classes
   out-rank one, so this now wins wherever either rule sits. */
#mhDetail .dv-form.tm-form{max-width:none}

/* PROGRAM DETAIL'S EDIT FORM DOES THE SAME (CEO, Aug 17 2026). Term Settings was fixed on
   Aug 15 and Program Detail - the shell's FIRST host, and the screen Term Settings was
   built to match - was left behind. Measured before changing anything: computed max-width
   920px, form 920px, pane 1106px, so every edit step carried a 186px dead gutter on its
   right while the read view beside it filled the width.

   TWO CLASSES, for the reason written above: `#mhDetail .pg-form` alone ties with
   `#mhDetail .dv-form` on specificity and loses on source order, because the cap sits at
   line ~721 of this file - later than here. That exact mistake cost a round on Aug 15.
   Measure the computed value; do not re-read the rule. */
#mhDetail .dv-form.pg-form{max-width:none}

/* THE SEVEN DAYS FILL THEIR ROW, like every other field on the form. As content-width
   buttons they clustered at the left of a full-width label and read as a stray toolbar
   rather than as one control. Equal columns also make the row scannable - Wednesday is
   always in the middle, wherever the pane is sized. */
#mhDetail .tm-dow{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px}
#mhDetail .tm-dow button{
  min-width:0;padding:12px 6px;border-radius:var(--r-sm);cursor:pointer;
  border:1px solid var(--f-rest-bd);background:var(--f-rest-bg);box-shadow:var(--f-rest-sh);
  font-family:var(--font-sans);font-size:13.5px;font-weight:650;color:var(--ink-2);
  transition:background var(--t),color var(--t),border-color var(--t);
}
#mhDetail .tm-dow button:hover{background:var(--f-hover-bg)}
#mhDetail .tm-dow button.on{background:var(--brand);border-color:var(--brand);color:#fff;box-shadow:none}

#mhDetail{
  --font-sans:'Hanken Grotesk',ui-sans-serif,system-ui,-apple-system,sans-serif;
  --font-mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;

  /* LOCKED detail-view tokens (brief section 1): rail #2E4A43 -> #213A33 */
  --brand:#2E4A43; --brand-600:#375A50; --brand-700:#213A33;
  --brand-tint:rgba(46,74,67,.12); --brand-tint-2:rgba(46,74,67,.20);
  --brand-glow:rgba(46,74,67,.35);
  --dv-rail-a:#2E4A43; --dv-rail-b:#213A33;

  --ink-1:#1C2733; --ink-2:#3B474B; --ink-3:#677579; --ink-4:#9AA7B3;
  --danger:#C0473F; --danger-bg:#F7E3E1; --danger-ink:#8C312B;

  --bg-canvas:#E8EBF0;
  --f-rest-bg:#DFE4EA; --f-rest-bd:rgba(40,60,80,.10); --f-rest-sh:inset 0 1px 2px rgba(40,60,80,.10);
  --f-hover-bg:#E4E8ED;
  --f-focus-bg:#FFFFFF; --f-focus-bd:rgba(40,60,80,.16); --f-focus-sh:0 10px 28px rgba(40,60,80,.14);

  --line:#D9DFE7;
  --r-sm:9px; --r-md:12px; --r-lg:16px; --r-pill:999px;
  --ease:cubic-bezier(.2,.7,.25,1); --t:.2s var(--ease);

  font-family:var(--font-sans);
  color:var(--ink-1);
}
body.dark #mhDetail{
  --bg-canvas:#1A232B;
  --ink-1:#EAF0F4; --ink-2:#C2CDD5; --ink-3:#8C9AA5; --ink-4:#5E6E7A;
  --brand:#3A5D51; --brand-600:#8FBBA5;
  --brand-tint:rgba(143,187,165,.18); --brand-tint-2:rgba(143,187,165,.26);
  --brand-glow:rgba(20,40,32,.6);
  --danger-bg:rgba(192,71,63,.18); --danger-ink:#F0A9A3;
  --f-rest-bg:#121A20; --f-rest-bd:rgba(180,210,235,.10); --f-rest-sh:inset 0 1px 2px rgba(0,0,0,.4);
  --f-hover-bg:#16202A;
  --f-focus-bg:#222E38; --f-focus-bd:rgba(150,190,225,.28); --f-focus-sh:0 12px 30px rgba(0,0,0,.5);
  --line:rgba(180,210,235,.12);
}
#mhDetail *{box-sizing:border-box}

/* =========================================================
   CONTAINER - full page OR centered overlay (brief 2.3)
   ========================================================= */
#mhDetail.dv-stage{position:relative;display:flex;flex:1;min-height:0}
#mhDetail.dv-stage>.modal{flex:1;min-width:0;min-height:0}
/* page mode inside the app content area: give the shell a workable height */
#mhDetail.dv-stage.page{height:calc(calc(100 * var(--mh-vh)) - 190px);min-height:660px}
#mhDetail.dv-stage.ovr{position:fixed;inset:0;z-index:1200;padding:20px;
  align-items:center;justify-content:center;overflow:hidden}
/* the overlay box matches CLIENT DETAIL (.cdbox in mh-clientdetail.css) exactly -
   width:min(1520px,calc(97 * var(--mh-vw))) / height:min(calc(93 * var(--mh-vh)),920px). Only the PANE grows: the rail
   keeps its fixed 340px, so the extra width all goes to the detail section. */
#mhDetail.dv-stage.ovr>.modal{flex:none;width:min(1520px,calc(97 * var(--mh-vw)));max-width:none;
  height:min(calc(93 * var(--mh-vh)),920px);max-height:none;position:relative;z-index:2;border-radius:20px;
  box-shadow:0 50px 110px -22px rgba(8,18,14,.62)}
/* NO MAGNIFIER ON THE BACKDROP (CEO, Jul 29 2026). This carried cursor:zoom-out, so hovering
   anywhere outside the mock turned the pointer into a zoom-out glass - promising a
   click-to-dismiss that the INERT BACKDROP LAW forbids (a backdrop click never closes a detail
   or a wizard). The cursor was the last trace of the behaviour that law removed. Plain default:
   the area is not interactive, so it must not look interactive. */
#mhDetail .dv-behind{position:absolute;inset:0;z-index:1;background:rgba(12,24,20,.55);
  cursor:default;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
/* The tab-row slot the mock gave to the close X now holds the OVERFLOW (...) button,
   in both containers; closing moved to a plain Close button in the footer. */

/* =========================================================
   MODAL SHELL (kit)
   ========================================================= */
#mhDetail .modal{position:relative;display:flex;flex-direction:column;height:100%;overflow:hidden;
  background:#fff;border-radius:24px;border:1px solid var(--line);
  box-shadow:0 40px 90px -20px rgba(28,39,51,.35),0 4px 14px rgba(28,39,51,.08)}
#mhDetail .modal.wz2{flex-direction:row;background:var(--bg-canvas)}
#mhDetail .m-head{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:22px 26px 20px;flex:none}
#mhDetail .m-ey{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--brand);margin:0 0 6px}
#mhDetail .m-title{font-size:24px;font-weight:800;letter-spacing:-.02em;color:var(--ink-1);margin:0;line-height:1.05}
#mhDetail .m-x{width:40px;height:40px;flex:none;border-radius:12px;border:none;background:var(--f-rest-bg);color:var(--ink-2);cursor:pointer;display:grid;place-items:center;transition:background var(--t),color var(--t)}
#mhDetail .m-x:hover{background:#E1E6EA;color:var(--ink-1)}
body.dark #mhDetail .m-x:hover{background:#2C3A46}
#mhDetail .m-x svg{width:18px;height:18px;stroke:currentColor;stroke-width:2.2;fill:none;stroke-linecap:round}
#mhDetail .m-body{flex:1;min-height:0;overflow:auto;padding:8px 26px 26px;
  scrollbar-width:none;-ms-overflow-style:none}
#mhDetail .m-body::-webkit-scrollbar{width:0;height:0;display:none}
#mhDetail .m-foot{flex:none;display:flex;align-items:center;gap:12px;padding:18px 36px;
  border-top:1px solid var(--line);background:var(--bg-canvas)}
#mhDetail .m-foot .spacer{flex:1}
#mhDetail .m-foot .foot-hint{flex:none;white-space:nowrap;font-size:12.5px;color:var(--ink-3);font-weight:500}
#mhDetail .m-foot .foot-hint svg{width:14px;height:14px;vertical-align:-2px;margin-right:6px;stroke:var(--brand-600);stroke-width:2;fill:none}

/* THE TWO-LINE VARIANT (Aug 15 2026). Only when a host supplies FooterHintSub - the
   single-line footer every other record uses is untouched.

   BOTH LINES LEFT-ALIGNED, AND THE ICON ON THE FIRST ONE (CEO). The first pass centred
   the pair and used `align-items:center` on the row - which centres the clock against
   the whole two-line BLOCK, dropping it into the gap between the lines. It read as a
   sinking icon, and it was: with one line the block IS the line, with two it is twice
   as tall and the middle moves down.
   `flex-start` pins the icon to the top, and the 2px nudge centres it on the first
   line's own 18px line box ((18 - 14) / 2) rather than on its top edge. */
#mhDetail .m-foot .foot-hint.two{display:inline-flex;align-items:flex-start;gap:0}
#mhDetail .m-foot .foot-hint.two svg{flex:none;margin-right:8px;margin-top:2px;vertical-align:baseline}
#mhDetail .m-foot .foot-hint.two .fh-tx{display:flex;flex-direction:column;align-items:flex-start;line-height:1.45}
#mhDetail .m-foot .foot-hint.two .fh-sub{font-size:11.5px;color:var(--ink-4);font-weight:500}

/* text selection: chrome is not selectable, real content is */
#mhDetail{-webkit-user-select:none;user-select:none}
#mhDetail input,#mhDetail textarea,#mhDetail .pd-desc,#mhDetail .sum-qr-v{-webkit-user-select:text;user-select:text}

/* =========================================================
   RAIL (wz2) - identity + fact list
   ========================================================= */
#mhDetail .rail{width:340px;flex:none;position:relative;overflow:hidden;color:#fff;padding:0;
  display:flex;flex-direction:column;border-right:1px solid var(--line);
  background:radial-gradient(120% 55% at 90% 3%,rgba(255,255,255,.14),transparent 42%),
             linear-gradient(162deg,var(--dv-rail-a) 0%,var(--dv-rail-b) 100%)}
#mhDetail .rail-head{flex:none;position:relative;padding:26px 26px 22px;display:flex;align-items:center;gap:14px;border-bottom:1px solid rgba(255,255,255,.15)}
#mhDetail .rail-ic{flex:none;width:48px;height:48px;border-radius:14px;background:rgba(255,255,255,.15);color:#fff;display:grid;place-items:center;box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
#mhDetail .rail-ic svg{width:41px;height:45px;fill:currentColor;stroke:none}
#mhDetail .rail-title{font-size:23px;font-weight:800;letter-spacing:-.02em;line-height:1.1;text-align:left;text-transform:uppercase}
#mhDetail .rail-scroll{flex:1;min-height:0;overflow:auto;padding:24px 26px 26px;display:flex;flex-direction:column;
  scrollbar-width:none;-ms-overflow-style:none}
#mhDetail .rail-scroll::-webkit-scrollbar{width:0;height:0;display:none}
#mhDetail .sum{display:flex;flex-direction:column}
/* the rail portrait - leads the panel, directly under the section title. Separate from
   the code tile below it: a face and a barcode are two different things. */
/* ============================================================
   RAIL PROFILE PHOTO - the app's ONE photo control, ported from Client Detail
   (.mh-app #clDetail .mh-photo ...). Same geometry, same pine gradient, same
   person glyph empty state, same clay camera button. Not a lookalike.
   The circle is NOT the popover's parent boundary problem: .cd-photomenu is
   absolutely positioned and the circle does not clip (no overflow:hidden here).
   ============================================================ */
#mhDetail .mh-photo{position:relative;align-self:center;width:112px;height:112px;border-radius:50%;
  margin:2px 0 16px;cursor:pointer;background:linear-gradient(150deg,#5E8C81,#2F4640);
  border:2.5px solid rgba(234,241,237,.5);
  box-shadow:inset 0 0 0 3px rgba(255,255,255,.16),0 6px 18px rgba(0,0,0,.26);
  display:grid;place-items:center}
#mhDetail .mh-ini{width:100%;height:100%;font-family:var(--mh-font-head);font-weight:600;font-size:30px;
  color:#F4F0E6;display:grid;place-items:center}
#mhDetail .mh-ini svg{width:46%;height:46%}
#mhDetail .mh-photo img{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;object-fit:cover;display:none}
#mhDetail .mh-photo.has img{display:block}
#mhDetail .mh-photo.has .mh-ini{display:none}
#mhDetail .mh-ov{position:absolute;inset:0;border-radius:50%;background:rgba(20,32,28,.55);color:#fff;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;font-size:10px;
  font-weight:800;letter-spacing:.5px;text-transform:uppercase;opacity:0;transition:opacity .18s}
#mhDetail .mh-ov svg{width:16px;height:16px}
#mhDetail .mh-photo:hover .mh-ov{opacity:1}
#mhDetail .mh-photo:focus-visible{outline:none;box-shadow:inset 0 0 0 3px rgba(255,255,255,.16),0 0 0 4px rgba(255,255,255,.6)}
#mhDetail .mh-btn{position:absolute;right:-2px;bottom:-2px;width:28px;height:28px;border-radius:50%;
  background:var(--mh-clay,#C97B5A);color:#fff;display:grid;place-items:center;
  box-shadow:0 0 0 2.5px var(--dv-rail-a);transition:opacity .18s}
#mhDetail .mh-btn svg{width:13px;height:13px}
/* CAMERA BUTTON VISIBILITY (CEO, Jul 27 2026): it is a PROMPT, not decoration.
   No photo  -> always visible, because "add one" is the thing to do next.
   Photo set -> hidden, so the portrait is just the person; it comes back on hover, on
                keyboard focus, and while the options popover is open, then hides again
                when the staff member moves on.
   The empty state keeps it permanently, so `.has` is the only case that hides. */
#mhDetail .mh-photo.has .mh-btn{opacity:0}
#mhDetail .mh-photo.has:hover .mh-btn,
#mhDetail .mh-photo.has:focus-within .mh-btn,
#mhDetail .mh-photo.has:has(.cd-photomenu) .mh-btn{opacity:1}
/* the studio popover must clear the rail */
#mhDetail .mh-photo .cd-photomenu{z-index:60}
#mhDetail .sum-name{font-size:22px;font-weight:800;letter-spacing:-.02em;color:#fff;line-height:1.14;margin-top:2px;
  text-align:center;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
/* Type chip sits directly under the name, status under the chip (CEO order, Jul 27 2026). */
#mhDetail .sum-type+.pd-state{margin-top:10px}
/* a rail fact that leads somewhere behaves like a control, not a label */
#mhDetail .sum-row.act{cursor:pointer;border-radius:10px;margin:0 -8px;padding-left:8px;padding-right:8px;
  transition:background var(--t)}
#mhDetail .sum-row.act:hover{background:rgba(255,255,255,.10)}
#mhDetail .sum-row.act:focus-visible{outline:none;background:rgba(255,255,255,.14);box-shadow:0 0 0 2px rgba(255,255,255,.45)}
#mhDetail .sum-type{align-self:center;margin-top:12px;font-size:12px;font-weight:700;letter-spacing:.01em;color:#fff;background:rgba(255,255,255,.17);border-radius:999px;padding:5px 13px}
#mhDetail .pd-state{align-self:center;margin-top:10px;white-space:nowrap;display:inline-flex;align-items:center;gap:9px;padding:7px 15px;border-radius:999px;background:rgba(255,255,255,.13);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);font-size:12.5px;font-weight:700;color:#fff}
#mhDetail .pd-state i{width:8px;height:8px;border-radius:999px;background:#A8D5C9;box-shadow:0 0 0 3px rgba(168,213,201,.25)}
#mhDetail .pd-state.is-off{background:rgba(255,255,255,.1)}
#mhDetail .pd-state.is-off i{background:rgba(255,255,255,.5);box-shadow:none}
#mhDetail .pd-state.is-arch{background:rgba(255,255,255,.08);color:rgba(255,255,255,.76)}
#mhDetail .pd-state.is-arch i{background:#D9B26A;box-shadow:0 0 0 3px rgba(217,178,106,.2)}
/* Record-level rail buttons, directly under the identity block (DetailShell.RailActions).
   The shell owns only the gap - the buttons themselves are the host's. */
#mhDetail .sum-actions{margin-top:16px;display:flex;flex-direction:column;gap:10px}
#mhDetail .sum-ctx{margin-top:16px;display:flex;align-items:center;gap:11px;padding:12px 13px;border-radius:var(--r-md);background:rgba(255,255,255,.11);box-shadow:inset 0 0 0 1px rgba(255,255,255,.15)}
#mhDetail .sum-ctx svg{width:24px;height:26px;flex:none;fill:rgba(255,255,255,.85);stroke:none}
#mhDetail .sum-ctx-k{font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.6)}
#mhDetail .sum-ctx-v{font-size:14.5px;font-weight:700;color:#fff;margin-top:2px}

/* identity slot - QR + code, or round photo + code (brief 3.3) */
#mhDetail .sum-qr{margin-top:18px;display:flex;align-items:center;gap:14px;padding:13px;border-radius:var(--r-md);
  background:rgba(255,255,255,.11);border:none;box-shadow:inset 0 0 0 1px rgba(255,255,255,.15);
  cursor:pointer;transition:background var(--t)}
#mhDetail .sum-qr:hover{background:rgba(255,255,255,.16)}
/* THE canonical MH QR tile - identical to #pgWiz .sum-qr .qr-frame (New Program
   wizard), Client Detail and Household: SvgPine in a white frame with the pine
   MH mark centred on top. ECC-H is why the logo never breaks the scan. */
#mhDetail .sum-qr .qr-frame{width:78px;height:78px;flex:none;position:relative;border-radius:8px;background:#fff;padding:5px;display:block;line-height:0}
#mhDetail .sum-qr .qr-frame svg{width:100%;height:100%;display:block}
#mhDetail .qr-logo{position:absolute;inset:0;margin:auto;display:grid;place-items:center;background:var(--brand-700);pointer-events:none}
#mhDetail .sum-qr .qr-logo{width:20px;height:20px;border-radius:6px;box-shadow:0 0 0 3px #fff}
#mhDetail .sum-qr .qr-logo img{width:13px;height:13px;display:block;object-fit:contain}
/* a host with no QR yet: the code still reads, but the tile is not a button */
#mhDetail .sum-qr.is-static{cursor:default}
#mhDetail .sum-qr.is-static:hover{background:rgba(255,255,255,.11)}
#mhDetail .sum-qr-meta{display:flex;flex-direction:column;gap:4px;min-width:0}
#mhDetail .sum-qr-k{font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.6)}
#mhDetail .sum-qr-v{font-family:var(--font-mono);font-size:15px;font-weight:600;letter-spacing:.02em;color:#fff;overflow-wrap:anywhere}
#mhDetail .sum-qr .qr-mini{margin-left:auto;background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.22);color:#fff}
#mhDetail .sum-qr .qr-mini:hover{background:#fff;border-color:#fff;color:var(--dv-rail-a);box-shadow:none}

/* fact list - max 6 rows, rest goes to the More details card (brief 2.1) */
#mhDetail .sum-list{margin-top:18px;padding-top:6px;border-top:1px solid rgba(255,255,255,.16);display:flex;flex-direction:column}
#mhDetail .sum-row{display:flex;align-items:center;gap:13px;padding:11px 0}
#mhDetail .sum-ic{flex:none;width:34px;height:34px;border-radius:10px;background:rgba(255,255,255,.1);box-shadow:inset 0 0 0 1px rgba(255,255,255,.15);display:grid;place-items:center;color:rgba(255,255,255,.85)}
#mhDetail .sum-ic svg{width:17px;height:17px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .sum-rc{min-width:0;display:flex;flex-direction:column;gap:3px}
#mhDetail .sum-k{font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.6)}
#mhDetail .sum-v{font-size:15px;font-weight:600;color:#fff;line-height:1.35;overflow-wrap:anywhere}
#mhDetail .sum-v small{display:block;font-size:13.5px;font-weight:500;color:rgba(255,255,255,.72);margin-top:3px}
/* fact-row variant (c): the chip value reads as PLAIN TEXT in the rail - same
   type as .sum-v, no pill background - so Attendance sits level with every other
   fact. (The same fact still renders as a tinted .flag in the More details card.) */
#mhDetail .sum-pill{align-self:flex-start;display:inline-flex;align-items:center;gap:7px;padding:0;border-radius:0;background:none;box-shadow:none;font-size:15px;font-weight:600;color:#fff;line-height:1.35}
#mhDetail .sum-more{position:sticky;bottom:-26px;z-index:2;margin:4px 0 -26px;display:flex;align-items:center;gap:13px;width:100%;padding:12px 0 26px;border:none;
  background:linear-gradient(180deg,rgba(33,58,51,0),rgba(33,58,51,.94) 42%);cursor:pointer;
  font-family:var(--font-sans);font-size:13.5px;font-weight:700;color:rgba(255,255,255,.72);text-align:left;transition:color var(--t)}
#mhDetail .sum-more:hover{color:#fff}
#mhDetail .sum-more .sum-ic{background:rgba(255,255,255,.06);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
#mhDetail .sum-more:hover .sum-ic{background:rgba(255,255,255,.14)}

/* Host-owned rail furniture between the code tile and the facts (DetailShell.RailExtras).
   The shell owns only the gap and the rules around it - everything inside is the host's,
   styled by the host's own sheet, so this can never dictate what a future host puts here. */
#mhDetail .sum-extra{margin-top:18px;padding-top:16px;border-top:1px solid rgba(255,255,255,.16);display:flex;flex-direction:column;gap:14px}
/* A host whose rail extras are CONDITIONAL (Subsidy's pending-change and participation
   notes) still hands the shell a fragment, so the slot exists even when it draws nothing -
   which left a rule and 34px of dead space under the code tile. */
#mhDetail .sum-extra:empty{display:none}
/* It sits directly above the facts list, which draws its own top rule - drop the second
   line so the two blocks are not separated by a double divider. */
#mhDetail .sum-extra+.sum-list{margin-top:16px;padding-top:0;border-top:none}

/* rail collapses to a top summary strip under ~1100px (brief 5) */
#mhDetail .modal.dv-narrow{flex-direction:column}
#mhDetail .modal.dv-narrow>.rail{width:auto;flex:none;padding:0;border-right:none;border-bottom:1px solid rgba(255,255,255,.16)}
#mhDetail .rail-strip{display:flex;align-items:center;gap:16px;padding:15px 22px}
#mhDetail .rail-strip .rail-ic{width:44px;height:44px;border-radius:13px}
#mhDetail .rail-strip .rail-ic svg{width:30px;height:33px}
#mhDetail .rail-strip .sp{flex:1}
#mhDetail .rs-id{min-width:0;display:flex;flex-direction:column;gap:7px}
#mhDetail .rs-name{font-size:19px;font-weight:800;letter-spacing:-.02em;line-height:1.15;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#mhDetail .rs-meta{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
#mhDetail .rs-meta .sum-type,#mhDetail .rs-meta .pd-state{margin:0;align-self:auto;padding:4px 11px;font-size:11.5px}
#mhDetail .rs-dot{font-size:12px;font-weight:600;color:rgba(255,255,255,.6)}
#mhDetail .rs-facts{flex:none;display:flex;align-items:center;gap:9px;padding:9px 14px;border:none;border-radius:999px;background:rgba(255,255,255,.12);box-shadow:inset 0 0 0 1px rgba(255,255,255,.16);color:#fff;font-family:var(--font-sans);font-size:12.5px;font-weight:700;cursor:pointer;transition:background var(--t)}
#mhDetail .rs-facts:hover{background:rgba(255,255,255,.2)}
#mhDetail .rs-facts svg{width:15px;height:15px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .rs-code{flex:none;display:flex;align-items:center;gap:12px;padding:9px 13px;border-radius:var(--r-md);background:rgba(255,255,255,.11);box-shadow:inset 0 0 0 1px rgba(255,255,255,.15)}
#mhDetail .rs-code .qr-frame{width:38px;height:38px;position:relative;border-radius:8px;background:#fff;padding:2px;line-height:0;display:block}
#mhDetail .rs-code .qr-frame svg{width:100%;height:100%;display:block}
#mhDetail .rs-code .qr-logo{width:11px;height:11px;border-radius:3.5px;box-shadow:0 0 0 1.6px #fff}
#mhDetail .rs-code .qr-logo img{width:7px;height:7px;display:block;object-fit:contain}
/* narrow strip: the portrait keeps its place ahead of the name, same as the wide rail */
#mhDetail .rs-face{flex:none;width:44px;height:44px;padding:0;border:none;border-radius:999px;overflow:hidden;
  cursor:pointer;line-height:0;background:rgba(255,255,255,.12);box-shadow:0 0 0 2px rgba(255,255,255,.3);
  transition:transform var(--t),box-shadow var(--t)}
#mhDetail .rs-face img{width:100%;height:100%;object-fit:cover;display:block}
#mhDetail .rs-face .mh-ini{width:100%;height:100%;display:grid;place-items:center;color:#F4F0E6}
#mhDetail .rs-face .mh-ini svg{width:52%;height:52%}
#mhDetail .rs-face{background:linear-gradient(150deg,#5E8C81,#2F4640)}
#mhDetail .rs-face:hover{transform:scale(1.06);box-shadow:0 0 0 2px #fff}
#mhDetail .rs-face:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(255,255,255,.75)}
#mhDetail .rs-code{cursor:pointer;transition:background var(--t)}
#mhDetail .rs-code:hover{background:rgba(255,255,255,.16)}
#mhDetail .rs-code.is-static{cursor:default}
#mhDetail .rs-code.is-static:hover{background:rgba(255,255,255,.11)}
#mhDetail .rs-code .sum-qr-k{color:rgba(255,255,255,.6)}
#mhDetail .rs-code .sum-qr-v{color:#fff}

/* =========================================================
   PANE
   ========================================================= */
#mhDetail .pane{position:relative;flex:1;min-width:0;display:flex;flex-direction:column;background:var(--bg-canvas);container-type:inline-size}
/* The tab pill and the (...) travel TOGETHER, centred in the pane (CEO, Jul 27 2026).
   `safe` again: when the row is too wide to centre, this falls back to flex-start so the
   first tab stays reachable instead of being pushed off the left edge.
   Edit mode is unaffected - `.dv-steps{flex:1}` fills the row, so there is nothing to centre. */
#mhDetail .pane-top{flex:none;padding:28px 36px 0;display:flex;align-items:center;justify-content:safe center;gap:14px}
/* THE PILL FILLS THE ROW, LIKE THE EDIT STEPPER (CEO, Jul 29 2026). Read mode and edit mode
   are the same surface one keypress apart, so the two rows now have the same geometry:
   `flex:1` here is what `.dv-steps{flex:1}` already did below. It used to be `flex:0 1 auto`
   (hug the labels), which made the tab row a different width from the stepper on the very
   same pane. The (...) keeps its place at the right end of the row. */
#mhDetail .dv-tabwrap{position:relative;flex:1;min-width:0}
#mhDetail .pane-head{flex:none;padding:22px 36px 20px}
#mhDetail .pane-title{font-size:27px;font-weight:800;letter-spacing:-.025em;color:var(--ink-1);margin:0;line-height:1.08;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
#mhDetail .pane-sub{font-size:15px;color:var(--ink-3);margin:9px 0 0;font-weight:500;line-height:1.45}
#mhDetail .pane .m-body{padding:0 36px 22px}

/* tab pill: one grid for every host - fills the pane in equal columns while the labels fit,
   holds each label's own width and scrolls with edge fades when they do not (brief 2.2) */
/* THE TAB ROW IS THE EDIT STEPPER'S TWIN (CEO, Jul 29 2026). The stepper below is
   `repeat(var(--dv-tabs),1fr)` filling the pane, and the read tabs are the same row on the
   same pane, so they get the same rule. Two earlier attempts each failed one host:
     - repeat(N,1fr) alone forced every column to the WIDEST label, which is fine when the
       row fills the pane but squashed Client Detail's 8 tabs below their own words;
     - grid-auto-columns:max-content + width:max-content sized each tab to its label but shrank
       the whole pill away from the stepper's width.
   `minmax(max-content,1fr)` is both: every column is at least its own label, and any space
   left over is shared out EQUALLY, so <=5-tab hosts (Program, Student, Housing Subsidy) fill
   the row in equal columns exactly like the stepper, while Client Detail's 8 tabs keep their
   labels intact and overflow into the scroll variant below. --dv-tabs is read again here.
   Applies to all four shell hosts: Program, Student, Client and Housing Subsidy.
   `overflow-x:auto` lives HERE, not only on .scroll, because "<=5 tabs always fits" was never
   true: Student Detail's five labels come to 766px in a 764px pill, and with the old
   overflow:visible the last tab poked 2px past the pill's own rounded edge. Any variant that
   runs out of room now scrolls inside the pill instead of spilling outside it - the scrollbar
   is hidden on every variant for the same reason. */
#mhDetail .pd-tabs{display:grid;grid-template-columns:repeat(var(--dv-tabs,3),minmax(max-content,1fr));gap:4px;padding:5px;border-radius:14px;background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);box-shadow:var(--f-rest-sh);width:auto;max-width:100%;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
#mhDetail .pd-tabs::-webkit-scrollbar{width:0;height:0;display:none}
/* TAB LABELS ARE UPPERCASE (CEO, Jul 27 2026). Done in CSS, not by rewriting the Label
   strings, so the C# tab definitions stay readable and every host inherits it for free. */
#mhDetail .pd-tabs button{border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:12.5px;font-weight:800;text-transform:uppercase;letter-spacing:.045em;color:var(--ink-3);padding:11px 14px;border-radius:10px;display:flex;align-items:center;justify-content:center;gap:8px;transition:background var(--t),color var(--t),box-shadow var(--t)}
#mhDetail .pd-tabs button:hover{color:var(--ink-1);background:rgba(40,60,80,.05)}
#mhDetail .pd-tabs button .n{font-size:11px;font-weight:800;padding:2px 7px;border-radius:999px;background:rgba(40,60,80,.1);color:var(--ink-3)}
body.dark #mhDetail .pd-tabs button .n{background:rgba(180,210,235,.14);color:var(--ink-2)}
#mhDetail .pd-tabs button[aria-selected="true"]{background:var(--brand);color:#fff;box-shadow:0 4px 12px -2px var(--brand-glow)}
#mhDetail .pd-tabs button[aria-selected="true"] .n{background:rgba(255,255,255,.24);color:#fff}
/* STILL A GRID (Jul 29 2026). This used to swap to `display:flex; justify-content:safe center`,
   which threw away the equal columns for every 6+ tab host - a 6-tab row that DID fit the pane
   sat centred and hugging instead of filling, so one shell rendered two different tab looks
   depending on how many tabs a host declared. Keeping the grid means the sizing rule above is
   the ONLY one: fill equally while there is room, overflow when there is not. Nothing is
   centred here on purpose - the grid's first column starts at scrollLeft:0, so the first tab
   can never be stranded off the left edge (which is what `safe` was guarding against).
   All this adds over the base rule now is smooth scrolling: overflow-x and the hidden
   scrollbar moved up to .pd-tabs, where every variant needs them. */
#mhDetail .pd-tabs.scroll{scroll-behavior:smooth}
/* ONE padding value for BOTH variants (Jul 29 2026). This used to carry its own 11px 13px,
   because the grid variant was 11px 6px back when equal 1fr columns supplied the width. Now
   that both variants are the same grid, a separate value here would make the 6+ tab hosts
   (Client Detail) sit 2px tighter per tab than the <=5 hosts (Program, Student, Housing
   Subsidy). It inherits the base padding instead, so every tab in the app fits its label with
   exactly the same breathing room. The old `flex:none` went with the flex variant - the grid's
   `minmax(max-content,...)` is what stops a button being squeezed now. */
#mhDetail .dv-fade{position:absolute;top:6px;bottom:6px;width:46px;z-index:3;pointer-events:none;opacity:0;transition:opacity var(--t)}
#mhDetail .dv-fade.l{left:2px;border-radius:11px 0 0 11px;background:linear-gradient(90deg,var(--f-rest-bg) 30%,rgba(223,228,234,0))}
#mhDetail .dv-fade.r{right:2px;border-radius:0 11px 11px 0;background:linear-gradient(270deg,var(--f-rest-bg) 30%,rgba(223,228,234,0))}
#mhDetail .dv-tabwrap[data-l="1"] .dv-fade.l,#mhDetail .dv-tabwrap[data-r="1"] .dv-fade.r{opacity:1}
body.dark #mhDetail .dv-fade.l{background:linear-gradient(90deg,var(--f-rest-bg) 30%,rgba(18,26,32,0))}
body.dark #mhDetail .dv-fade.r{background:linear-gradient(270deg,var(--f-rest-bg) 30%,rgba(18,26,32,0))}

/* =========================================================
   CARDS / STATS
   ========================================================= */
#mhDetail .pd-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding-bottom:4px}
#mhDetail .pd-card{background:var(--f-focus-bg);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px 19px;display:flex;flex-direction:column;min-width:0}
#mhDetail .pd-card.full{grid-column:1/-1}
/* BARE: a section whose CHILDREN are the white cards. Keeps the .pd-ch heading and the
   grid rhythm, drops the panel behind them - white inside white read as one flat slab. */
#mhDetail .pd-card.bare{background:none;border:none;padding:0}
#mhDetail .pd-ch{display:flex;align-items:center;gap:10px;margin-bottom:15px}
#mhDetail .pd-ch h4{margin:0;font-size:11.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3)}
#mhDetail .pd-ch svg{width:16px;height:16px;flex:none;stroke:var(--brand-600);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
/* THE COUNT BELONGS TO THE HEADING, NOT THE OTHER SIDE OF THE CARD (CEO, Aug 2 2026).
   `margin-left:auto` threw the tag to the far right, so "CHILDREN" and its "2" sat a
   full card-width apart and read as two unrelated things. It now sits in the flex row's
   natural 10px gap: CHILDREN (2), ALL PROGRAMS (3).
   SHARED RULE - this moves the count on EVERY detail host (Student, Program, Client,
   Household, Subsidy, My Profile), which is the point: they are the same component. */
#mhDetail .pd-ch .tag{font-size:11.5px;font-weight:700;color:var(--brand-600);background:var(--brand-tint);border-radius:999px;padding:4px 11px;white-space:nowrap}
#mhDetail .meter{height:12px;border-radius:999px;background:var(--f-rest-bg);box-shadow:var(--f-rest-sh);display:flex;overflow:hidden}
#mhDetail .meter i{display:block;background:linear-gradient(90deg,var(--brand),var(--brand-600));transition:width .5s var(--ease)}
#mhDetail .meter u{display:block;background:repeating-linear-gradient(45deg,var(--brand-tint-2) 0 5px,transparent 5px 10px);transition:width .5s var(--ease)}
#mhDetail .lgnd{display:flex;gap:16px;margin-top:11px;font-size:12px;font-weight:600;color:var(--ink-3)}
#mhDetail .lgnd span{display:flex;align-items:center;gap:7px}
#mhDetail .lgnd b{width:9px;height:9px;border-radius:3px;background:var(--brand)}
#mhDetail .lgnd .w{background:var(--brand-tint-2)}
#mhDetail .lgnd .o{background:var(--f-rest-bg);box-shadow:inset 0 0 0 1px var(--f-rest-bd)}
#mhDetail .tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-top:16px}
#mhDetail .tile{background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);border-radius:var(--r-md);padding:12px 13px}
#mhDetail .tile .v{font-size:24px;font-weight:800;letter-spacing:-.02em;color:var(--ink-1);line-height:1;overflow-wrap:anywhere}
#mhDetail .tile .v .sub{font-size:14px;color:var(--ink-4)}
#mhDetail .tile .k{font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-4);margin-top:7px}
#mhDetail .terms{display:flex;flex-direction:column;gap:10px}
#mhDetail .term{display:flex;align-items:center;gap:12px;padding:12px 13px;border-radius:var(--r-md);background:var(--f-rest-bg);border:1px solid var(--f-rest-bd)}
#mhDetail .term>div{min-width:0}
#mhDetail .term .tic{width:36px;height:36px;flex:none;border-radius:10px;background:var(--brand-tint);color:var(--brand-600);display:grid;place-items:center}
#mhDetail .term .tic svg{width:17px;height:17px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .term .k{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-4)}
#mhDetail .term .v{font-size:15px;font-weight:700;color:var(--ink-1);margin-top:2px;overflow-wrap:anywhere}
#mhDetail .term .v.none{color:var(--ink-4);font-weight:600}
#mhDetail .term .rt{margin-left:auto;font-size:11.5px;font-weight:700;color:var(--brand-600);background:var(--brand-tint);border-radius:999px;padding:4px 10px;white-space:nowrap}
#mhDetail .pd-desc{font-size:14.5px;line-height:1.6;color:var(--ink-2);margin:0;text-wrap:pretty}
#mhDetail .kv{display:grid;grid-template-columns:repeat(3,1fr);gap:14px 18px}
#mhDetail .kv .k{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-4)}
#mhDetail .kv .v{font-size:14.5px;font-weight:700;color:var(--ink-1);margin-top:5px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;overflow-wrap:anywhere}
#mhDetail .kv .v.off{color:var(--ink-4);font-weight:600}
#mhDetail .dv-sub{font-weight:500;color:var(--ink-3)}
#mhDetail .flag{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;font-size:12.5px;font-weight:700;padding:5px 11px;border-radius:999px;background:var(--brand-tint);color:var(--brand-600)}
#mhDetail .flag svg{width:13px;height:13px;stroke:currentColor;stroke-width:2.6;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .flag.no{background:var(--f-rest-bg);color:var(--ink-4)}

/* =========================================================
   LIST ROWS (roster + schedule)

   NAME CHANGE, and the only one in this file: the mock calls this row ".row".
   Bootstrap (loaded app-wide, App.razor line 10) owns .row and .row>* - it sets
   flex-wrap:wrap, -12px side margins, and width:100%/max-width:100%/flex-shrink:0
   on EVERY child. Those are different properties from the ones the mock sets, so
   #mhDetail specificity never overrode them: each cell took a full line and the
   roster/schedule rows rendered as stacked blocks instead of one line. Renamed to
   .dv-row/.dv-rows so the framework can never reach them again. Rules are the
   mock's, byte for byte, with only the selector renamed.
   ========================================================= */
#mhDetail .dv-rows{display:flex;flex-direction:column;gap:8px}
#mhDetail .dv-row{display:flex;align-items:center;gap:13px;padding:11px 14px;border-radius:var(--r-md);background:var(--f-focus-bg);border:1px solid var(--line);transition:border-color var(--t),transform var(--t),box-shadow var(--t)}
#mhDetail .dv-row:hover{border-color:var(--f-focus-bd);transform:translateX(2px)}
#mhDetail .dv-row>div{min-width:0}
#mhDetail .dv-row.act{cursor:pointer}
#mhDetail .dv-row.act:hover{box-shadow:0 12px 26px -18px rgba(28,39,51,.75)}
body.dark #mhDetail .dv-row.act:hover{box-shadow:0 12px 26px -18px #000}
#mhDetail .dv-row.act:focus-visible{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-tint)}
#mhDetail .dv-row .go{width:18px;height:18px;flex:none;color:var(--ink-4);display:grid;place-items:center;transition:transform var(--t),color var(--t)}
#mhDetail .dv-row .go svg{width:100%;height:100%;stroke:currentColor;stroke-width:2.2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .dv-row.act:hover .go{transform:translateX(3px);color:var(--brand-600)}
#mhDetail .av-btn{flex:none;position:relative;border:none;padding:0;background:none;cursor:pointer;border-radius:999px;line-height:0;transition:transform var(--t),box-shadow var(--t)}
#mhDetail .av-btn:hover{transform:scale(1.07);box-shadow:0 0 0 3px var(--brand-tint)}
#mhDetail .av-btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--brand-glow)}
#mhDetail .av{width:38px;height:38px;flex:none;border-radius:999px;display:grid;place-items:center;font-size:13px;font-weight:800;color:#fff;background:linear-gradient(150deg,#6E9C92,#4E7C72);overflow:hidden}
#mhDetail .av img{width:100%;height:100%;object-fit:cover;display:block}
#mhDetail .av.w{background:linear-gradient(150deg,#8b9fa6,#637980)}
body.dark #mhDetail .av.w{background:linear-gradient(150deg,#5B6C75,#3E4C55)}
#mhDetail .qr-mini{width:36px;height:36px;flex:none;border-radius:10px;border:1px solid var(--f-rest-bd);background:var(--f-rest-bg);color:var(--ink-2);cursor:pointer;display:grid;place-items:center;transition:background var(--t),color var(--t),border-color var(--t),box-shadow var(--t)}
#mhDetail .qr-mini:hover{background:var(--brand);border-color:var(--brand);color:#fff;box-shadow:0 7px 16px -5px var(--brand-glow)}
#mhDetail .qr-mini svg{width:18px;height:18px;stroke:currentColor;stroke-width:1.9;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .dv-row .nm{font-size:14.5px;font-weight:700;color:var(--ink-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#mhDetail .dv-row .mt{font-size:12.5px;font-weight:500;color:var(--ink-3);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#mhDetail .dv-row .sp{flex:1}
#mhDetail .chip{font-size:11.5px;font-weight:700;padding:5px 11px;border-radius:999px;background:var(--brand-tint);color:var(--brand-600);white-space:nowrap}
#mhDetail .chip.grey{background:var(--f-rest-bg);color:var(--ink-3)}
#mhDetail .dv-row .att{font-family:var(--font-mono);font-size:12.5px;font-weight:600;color:var(--ink-2);white-space:nowrap}
#mhDetail .more{text-align:center;font-size:12.5px;font-weight:600;color:var(--ink-3);padding:12px 0 2px}
#mhDetail .sec-lbl{display:flex;align-items:center;gap:10px;margin:20px 0 11px;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4)}
#mhDetail .sec-lbl:first-child{margin-top:0}
#mhDetail .sec-lbl .rule{flex:1;height:1px;background:var(--line)}
#mhDetail .day{width:60px;flex:none;display:flex;flex-direction:column;align-items:center;gap:4px;border-radius:12px;background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);padding:9px 0 8px}
#mhDetail .day .w{display:block;font-size:9.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--brand-600);line-height:1}
#mhDetail .day .d{display:block;font-size:21px;font-weight:800;letter-spacing:-.02em;color:var(--ink-1);line-height:1}
#mhDetail .day .m{display:block;font-size:9.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-4);line-height:1}
#mhDetail .dv-row.next{border-color:var(--brand);box-shadow:0 6px 18px -10px var(--brand-glow)}
#mhDetail .dv-row.next .day{background:var(--brand);border-color:var(--brand)}
#mhDetail .dv-row.next .day .d,#mhDetail .dv-row.next .day .m{color:#fff}
#mhDetail .dv-row.next .day .w{color:rgba(255,255,255,.75)}
#mhDetail .bars{display:flex;align-items:flex-end;gap:3px;height:26px;margin-right:2px}
#mhDetail .bars i{width:5px;height:18px;border-radius:2px;background:var(--brand-tint-2)}
#mhDetail .bars i.on{background:var(--brand)}

/* =========================================================
   EMPTY STATES (brief 2.4)
   ========================================================= */
#mhDetail .dv-empty{display:flex;flex-direction:column;align-items:center;text-align:center;padding:54px 24px 58px}
#mhDetail .dv-eic{width:62px;height:62px;border-radius:20px;margin-bottom:16px;display:grid;place-items:center;background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);color:var(--ink-4)}
#mhDetail .dv-eic svg{width:25px;height:25px;stroke:currentColor;stroke-width:1.8;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .dv-empty h5{margin:0;font-size:16.5px;font-weight:800;letter-spacing:-.01em;color:var(--ink-2)}
#mhDetail .dv-empty p{margin:7px 0 0;max-width:360px;font-size:13.5px;font-weight:500;line-height:1.55;color:var(--ink-4);text-wrap:pretty}
#mhDetail .dv-empty .ui-btn{margin-top:21px}
#mhDetail .dv-empty.inline{align-items:flex-start;text-align:left;padding:2px 0 0}
#mhDetail .dv-empty.inline .dv-eic{width:40px;height:40px;border-radius:12px;margin-bottom:12px}
#mhDetail .dv-empty.inline .dv-eic svg{width:18px;height:18px}
#mhDetail .dv-empty.inline h5{font-size:14.5px}
#mhDetail .dv-empty.inline .ui-btn{margin-top:14px;height:38px;padding:0 15px;font-size:13px}

/* =========================================================
   BUTTONS + OVERFLOW MENU (brief 2.7)
   ========================================================= */
#mhDetail .ui-btn{height:48px;padding:0 22px;border-radius:var(--r-md);font-family:var(--font-sans);font-size:14.5px;font-weight:700;cursor:pointer;border:1px solid transparent;display:inline-flex;align-items:center;justify-content:center;gap:9px;white-space:nowrap;transition:background var(--t),border-color var(--t),box-shadow var(--t),color var(--t),transform var(--t)}
#mhDetail .ui-btn svg{width:18px;height:18px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .ui-btn.primary{background:var(--brand);color:#fff;box-shadow:0 8px 18px -4px var(--brand-glow)}
#mhDetail .ui-btn.primary:hover{background:var(--brand-600);box-shadow:0 10px 22px -4px var(--brand-glow)}
#mhDetail .ui-btn.primary:active{transform:translateY(1px)}
#mhDetail .ui-btn.secondary{background:var(--f-focus-bg);color:var(--brand-600);border-color:var(--f-focus-bd);box-shadow:0 1px 2px rgba(40,60,80,.06)}
#mhDetail .ui-btn.secondary:hover{background:#EEF2F4}
body.dark #mhDetail .ui-btn.secondary:hover{background:#2C3A46}
#mhDetail .ui-btn.is-cancel{background:transparent;color:var(--ink-2);border-color:transparent;box-shadow:none}
#mhDetail .ui-btn.is-cancel:hover{background:rgba(40,60,80,.07);color:var(--ink-1)}
#mhDetail .ui-btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
/* No margin-left:auto - it sits immediately right of the tab pill and the pair is centred
   together by .pane-top, rather than the button being exiled to the far edge. */
#mhDetail .dv-more{position:relative;flex:none}
#mhDetail .dv-more-btn{width:48px;padding:0}
#mhDetail .dv-more-btn svg{width:20px;height:20px;fill:currentColor;stroke:none}
#mhDetail .dv-more-btn[aria-expanded="true"]{background:var(--brand-tint);border-color:transparent;color:var(--brand-600)}
#mhDetail .dv-menu{position:absolute;right:0;bottom:calc(100% + 10px);z-index:40;min-width:244px;padding:7px;border-radius:var(--r-md);background:var(--f-focus-bg);border:1px solid var(--f-focus-bd);box-shadow:var(--f-focus-sh),0 24px 52px -20px rgba(28,39,51,.4);display:flex;flex-direction:column;gap:2px;animation:mhdvUp .16s var(--ease)}
@keyframes mhdvUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
/* justify-content is set explicitly: a bare app-global `button{justify-content:center}`
   rule was centring the icon+label pair inside the 244px menu. text-align does not
   fix a flex container - only justify-content does. (Same trap as the Bootstrap .row
   collision: a property our rule never set is a property the global still owns.) */
#mhDetail .dv-mi{display:flex;align-items:center;justify-content:flex-start;gap:12px;width:100%;padding:10px 12px;border:none;border-radius:var(--r-sm);background:none;cursor:pointer;font-family:var(--font-sans);font-size:14px;font-weight:600;color:var(--ink-1);text-align:left;transition:background var(--t),color var(--t)}
/* locked item - present so staff can see it is coming, but inert until the section is built */
#mhDetail .dv-mi:disabled{opacity:.42;cursor:not-allowed}
#mhDetail .dv-mi:disabled:hover{background:none}
#mhDetail .dv-mi:disabled:hover svg{color:var(--ink-3)}
#mhDetail .dv-mi .lock{margin-left:auto;flex:none;font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-4)}
#mhDetail .dv-mi svg{width:17px;height:17px;flex:none;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round;color:var(--ink-3)}
#mhDetail .dv-mi:hover{background:var(--f-rest-bg)}
#mhDetail .dv-mi:hover svg{color:var(--brand-600)}
#mhDetail .dv-mi.danger{color:var(--danger)}
#mhDetail .dv-mi.danger svg{color:var(--danger)}
#mhDetail .dv-mi.danger:hover{background:var(--danger-bg);color:var(--danger-ink)}
#mhDetail .dv-mi.danger:hover svg{color:var(--danger-ink)}
/* the (...) button now sits in the TAB ROW, so its menu drops DOWN from the button
   instead of rising out of the footer. Higher specificity than the base rule above. */
#mhDetail .pane-top .dv-menu{top:calc(100% + 10px);bottom:auto;animation-name:mhdvPop}
#mhDetail .dv-msep{height:1px;margin:5px 4px;background:var(--line)}
#mhDetail .dv-scrim{position:fixed;inset:0;z-index:30;background:transparent}
/* .modal carries z-index:2 -> it is a STACKING CONTEXT, so the overflow menu inside it can
   never out-rank this scrim no matter what z-index the menu is given. Lift the MODAL over the
   scrim while the menu is open; the scrim still covers everything outside it.
   Specificity matters: the z-index:2 comes from #mhDetail.dv-stage.ovr>.modal, so the override
   must match that selector or it silently loses. Page mode needs no rule - the modal has no
   z-index there, so it is not a stacking context and the menu wins on its own. */
#mhDetail.dv-stage.ovr>.modal.menu-open{z-index:31}

/* The mock's .toast is intentionally absent: save / update / remove confirmations use
   the app-standard MudBlazor snackbar, so the shell never shows a second, different
   notification of its own. */

/* =========================================================
   EDIT SHEET + STUDENT PEEK (overlays inside the shell)
   ========================================================= */
#mhDetail .ov{position:absolute;inset:0;z-index:80;display:grid;place-items:center;padding:34px;background:rgba(24,36,30,.5)}
#mhDetail .sheet{width:640px;max-height:100%;display:flex;flex-direction:column;background:var(--bg-canvas);border-radius:22px;overflow:hidden;box-shadow:0 40px 90px -20px rgba(28,39,51,.55)}
#mhDetail .sheet .m-head{padding:24px 28px 18px}
#mhDetail .sheet .m-body{padding:4px 28px 26px;overflow:auto}
#mhDetail .sheet .m-foot{padding:16px 28px;background:var(--bg-canvas);border-top:1px solid var(--line)}
#mhDetail .sheet .fgrid{gap:17px 18px}
#mhDetail .sheet.sm{width:430px}
#mhDetail .sheet.sm .m-body{padding:2px 26px 24px;text-align:center}
#mhDetail .pk-av{width:112px;height:112px;margin:2px auto 0;border-radius:999px;overflow:hidden;background:var(--f-rest-bg);box-shadow:0 0 0 4px var(--brand-tint),0 14px 30px -14px rgba(28,39,51,.5);cursor:pointer;border:none;padding:0;display:grid;place-items:center;font-size:34px;font-weight:800;color:#fff;transition:transform var(--t)}
#mhDetail .pk-av:hover{transform:scale(1.04)}
/* display only: the peek SHOWS the photo, it does not open it.
   Named .pk-plain, not .static - a bare .static is a known MudBlazor collision
   (see this file's header) and generic names are what the .row bug was made of. */
#mhDetail .pk-av.pk-plain{cursor:default;transition:none}
#mhDetail .pk-av.pk-plain:hover{transform:none}
#mhDetail .pk-av img{width:100%;height:100%;object-fit:cover;display:block}
#mhDetail .pk-nm{font-size:20px;font-weight:800;letter-spacing:-.02em;color:var(--ink-1);margin:15px 0 0}
#mhDetail .pk-cd{font-family:var(--font-mono);font-size:12.5px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);margin-top:5px}
#mhDetail .pk-chips{display:flex;justify-content:center;gap:8px;margin-top:13px;flex-wrap:wrap}
#mhDetail .pk-list{margin-top:18px;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;text-align:left;background:var(--f-focus-bg)}
#mhDetail .pk-list .r{display:flex;justify-content:space-between;gap:14px;padding:11px 14px;font-size:13.5px}
#mhDetail .pk-list .r+.r{border-top:1px solid var(--line)}
#mhDetail .pk-list .r .k{color:var(--ink-3);font-weight:600}
#mhDetail .pk-list .r .v{color:var(--ink-1);font-weight:700;overflow-wrap:anywhere;text-align:right}

/* QR / avatar zoom lightbox */
/* The photo lightbox DOES close on click, so it keeps a cursor - but `pointer`, not the
   zoom-out glass (CEO: no zoom icon anywhere in the app). */
#mhDetail .qr-zoom{position:absolute;inset:0;z-index:120;display:grid;place-items:center;padding:28px;background:rgba(24,36,30,.55);cursor:pointer}
#mhDetail .qr-zoom-card{background:#fff;border-radius:20px;padding:26px;display:flex;flex-direction:column;align-items:center;gap:13px;box-shadow:0 30px 70px -20px rgba(0,0,0,.5)}
body.dark #mhDetail .qr-zoom-card{background:var(--f-focus-bg)}
/* the DEFAULT QR view - same card as #pgWiz .qr-zoom-card, logo and all */
#mhDetail .qr-zoom-card .qr-frame{width:min(300px,44vmin);height:min(300px,44vmin);display:block;position:relative;border-radius:10px;background:#fff;padding:10px}
#mhDetail .qr-zoom-card .qr-frame svg{width:100%;height:100%;display:block}
#mhDetail .qr-zoom-card .qr-logo{width:46px;height:46px;border-radius:11px;box-shadow:0 0 0 6px #fff}
#mhDetail .qr-zoom-card .qr-logo img{width:30px;height:30px;display:block;object-fit:contain}
#mhDetail .qr-zoom-code{font-family:var(--font-mono);font-size:20px;font-weight:600;letter-spacing:.04em;color:var(--ink-1)}
#mhDetail .qr-zoom-hint{font-size:12px;color:var(--ink-4)}
#mhDetail .qr-zoom-card .zc-av{width:min(220px,34vmin);height:min(220px,34vmin);border-radius:999px;overflow:hidden;box-shadow:0 0 0 5px var(--brand-tint);display:grid;place-items:center;background:linear-gradient(150deg,#6E9C92,#4E7C72);color:#fff;font-size:64px;font-weight:800}
#mhDetail .qr-zoom-card .zc-av img{width:100%;height:100%;object-fit:cover;display:block}
#mhDetail .qr-zoom-card .zc-nm{font-size:19px;font-weight:800;letter-spacing:-.02em;color:var(--ink-1)}

/* =========================================================
   FIELDS (the MH DEFAULT FIELD standard - inset cool shell)
   ========================================================= */
#mhDetail .fgrid{display:grid;grid-template-columns:1fr 1fr;gap:18px 20px}
#mhDetail .fgrid .full{grid-column:1/-1}
#mhDetail .field{display:flex;flex-direction:column;gap:8px;min-width:0}
#mhDetail .field>label{font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);display:flex;align-items:center;gap:6px}
#mhDetail .field .req{color:var(--danger)}
/* SECTION HEADING inside the edit form.
   `grid-column:1/-1` is the important line: .fgrid is a two-column grid, so without it every
   heading was consuming ONE CELL and rendering beside a field instead of above the block.
   That single omission is what made the whole form unreadable - headings sitting next to
   inputs, sections impossible to tell apart. It spans, always. */
#mhDetail .fsec{grid-column:1/-1;display:flex;align-items:center;gap:12px;margin:22px 0 4px}
#mhDetail .fgrid>.fsec:first-child{margin-top:0}
#mhDetail .fsec .bub{flex:none;width:34px;height:34px;border-radius:11px;display:grid;place-items:center;
  background:var(--brand-tint);color:var(--brand-600)}
#mhDetail .fsec .bub svg{width:18px;height:18px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
/* UPPERCASE, like every other heading and toggle in the shell (CEO, Jul 27 2026). Done in
   CSS so the C# section titles stay readable sentences. */
#mhDetail .fsec h3{font-size:15px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-1);margin:0;white-space:nowrap}
#mhDetail .fsec .rule{flex:1;height:1px;background:var(--line)}
#mhDetail .divider{height:1px;background:var(--line);margin:22px 0}

/* =========================================================
   IN-PANE EDIT - the record's body becomes the form, in place. No stacked window.
   The stepper takes the tab pill's slot so the chrome never jumps; the form sits on
   the same canvas the cards sat on, capped so fields never stretch to absurd widths.
   ========================================================= */
#mhDetail .dv-steps{flex:1;min-width:0;display:grid;grid-template-columns:repeat(var(--dv-tabs,2),1fr);gap:4px;
  padding:5px;border-radius:14px;background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);box-shadow:var(--f-rest-sh)}
#mhDetail .dv-steps.single{grid-template-columns:1fr}
/* Uppercase, matching the tab pill it replaces - the two occupy the same slot, so they must
   read as the same control. */
#mhDetail .dv-steps button{text-transform:uppercase;letter-spacing:.045em;font-weight:800;
  border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:12.5px;
  font-weight:700;color:var(--ink-3);padding:11px 10px;border-radius:10px;display:flex;align-items:center;
  justify-content:center;gap:9px;min-width:0;transition:background var(--t),color var(--t),box-shadow var(--t)}
#mhDetail .dv-steps button:hover{color:var(--ink-1);background:rgba(40,60,80,.05)}
#mhDetail .dv-steps button[aria-selected="true"]{background:var(--brand);color:#fff;box-shadow:0 4px 12px -2px var(--brand-glow)}
#mhDetail .dv-steps .stp{flex:none;width:20px;height:20px;border-radius:999px;display:grid;place-items:center;
  font-size:11px;font-weight:800;background:rgba(40,60,80,.1);color:var(--ink-3);line-height:1}
#mhDetail .dv-steps .stp svg{width:12px;height:12px;stroke:currentColor;stroke-width:2.6;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .dv-steps button[aria-selected="true"] .stp{background:rgba(255,255,255,.24);color:#fff}
#mhDetail .dv-steps button.done .stp{background:var(--brand-tint-2);color:var(--brand-600)}
body.dark #mhDetail .dv-steps .stp{background:rgba(180,210,235,.14);color:var(--ink-2)}

/* the "you are editing" eyebrow, so the mode is never ambiguous at a glance */
#mhDetail .dv-editflag{display:inline-flex;align-items:center;gap:7px;margin-bottom:11px;padding:5px 12px;
  border-radius:999px;background:var(--brand-tint);color:var(--brand-600);
  font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
#mhDetail .dv-editflag svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}

#mhDetail .dv-form{max-width:920px;padding-bottom:6px}
#mhDetail .dv-formerr{margin:0 0 16px}
#mhDetail .dv-formnote{font-size:13px;color:var(--ink-3);margin:2px 0 0;font-weight:500;line-height:1.55}
/* a value the form shows but does not own (status) - reads as a field, is not an input */
#mhDetail .icf.locked-face{cursor:default;background:var(--f-rest-bg);opacity:.75}
#mhDetail .icf.locked-face:hover{background:var(--f-rest-bg)}

/* labelled progress bar. NOT .lgnd - that is the Program capacity KEY, whose <b> is a
   colour swatch; borrowing it for a caption drew a stray dark square with nothing to key. */
#mhDetail .sd-meterrow{margin-top:18px}
#mhDetail .sd-meter-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  margin:0 0 9px;font-size:12.5px;font-weight:600;color:var(--ink-3)}
#mhDetail .sd-meter-h b{font-size:13.5px;font-weight:800;color:var(--ink-1);font-variant-numeric:tabular-nums}

/* children step - a .dv-row that is also a checkbox target */
#mhDetail .sd-pickrow{cursor:pointer;user-select:none}
#mhDetail .sd-pickrow:hover{border-color:var(--brand-tint-2)}
#mhDetail .sd-pickrow.is-on{border-color:var(--brand);background:var(--brand-tint)}
#mhDetail .sd-pick{flex:none;padding:0;align-items:center}
#mhDetail .sd-addkidbtn{display:flex;flex-direction:column;justify-content:flex-end}
#mhDetail .sd-addkidbtn .ui-btn{height:50px}
#mhDetail .icf{position:relative;display:flex;align-items:center;gap:11px;min-height:50px;padding:0 15px;background:var(--f-rest-bg);
  border:1px solid var(--f-rest-bd);box-shadow:var(--f-rest-sh);border-radius:var(--r-md);
  transition:background var(--t),border-color var(--t),box-shadow var(--t)}
#mhDetail .icf:hover:not(:focus-within){background:var(--f-hover-bg)}
#mhDetail .icf:focus-within,#mhDetail .icf.open{background:var(--f-focus-bg);border-color:var(--f-focus-bd);box-shadow:var(--f-focus-sh)}
/* KILL the app-global .mh-app :is(input,textarea,select) skin so the visible field
   is the .icf shell ONLY (no "field inside the field" ghost, no green focus ring). */
#mhDetail .icf :is(input,select,textarea),
#mhDetail .icf :is(input,select,textarea):hover,
#mhDetail .icf :is(input,select,textarea):focus,
#mhDetail .icf :is(input,select,textarea):focus-visible{
  flex:1;min-width:0;background:transparent !important;border:0 !important;box-shadow:none !important;
  border-radius:0 !important;padding:0 !important;min-height:0 !important;height:auto !important;
  outline:none !important;text-align:left !important;
  font-family:var(--font-sans);font-size:15px;font-weight:500;color:var(--ink-1)}
#mhDetail .icf input::placeholder,#mhDetail .icf textarea::placeholder{color:var(--ink-4);font-weight:400}
/* CATCH-ALL: a control that is not inside an .icf still must not inherit the app-global
   sage placeholder (`.mh-app :is(input,textarea)::placeholder{color:var(--mh-ctrl-ico)}`,
   mh-theme.css:189 = #6E948B). That green was leaking into the document modal's notes box.
   Scoped to the id so it beats the global rule and covers every current and future host. */
#mhDetail :is(input,textarea)::placeholder{color:var(--ink-4);font-weight:400;opacity:1}
#mhDetail .icf.area{align-items:stretch;padding:13px 15px;min-height:104px}
#mhDetail .icf.area textarea{resize:none;min-height:78px;line-height:1.55}
#mhDetail .ic{width:19px;height:19px;flex:none;display:grid;place-items:center;color:var(--ink-3)}
#mhDetail .ic svg{width:100%;height:100%;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;fill:none}
#mhDetail .ic.mh svg{width:19px;height:20px;fill:var(--ink-3);stroke:none}
#mhDetail .icf:focus-within .ic.mh svg,#mhDetail .icf.open .ic.mh svg{fill:var(--brand-600)}
#mhDetail .chev{transition:transform var(--t)}
#mhDetail .icf.open .chev{transform:rotate(180deg)}
/* AN ERROR OUTRANKS HOVER, FOCUS AND OPEN - it holds its red until the VALUE is fixed.
   `.field.err .icf` is (1,2,0) and lost to `.icf:hover:not(:focus-within)` (1,3,0), so
   hovering a rejected field repainted it as if nothing were wrong. */
#mhDetail .field.err .icf,
#mhDetail .field.err .icf:hover,
#mhDetail .field.err .icf:hover:not(:focus-within),
#mhDetail .field.err .icf:focus-within,
#mhDetail .field.err .icf.open{border-color:var(--danger);background:var(--danger-bg)}
#mhDetail .field.err .icf:focus-within{box-shadow:0 0 0 3px rgba(192,71,63,.24)}
#mhDetail .field-err{font-size:12px;font-weight:600;color:var(--danger)}

/* The rest of the app's DEFAULT warning design, ported from #enrollWiz (the surface the
   CEO named as the standard): the LABEL and its asterisk turn danger-ink, and the field
   carries a red line with the warning glyph underneath. Without these the red wash was
   only half the design. */
#mhDetail .field.err>label,
#mhDetail .field.err>label .req{color:var(--danger-ink)}
#mhDetail .fld-msg{display:flex;align-items:center;gap:6px;margin:7px 0 0;font-size:12.5px;font-weight:650;line-height:1.35;color:var(--danger-ink)}
#mhDetail .fld-msg svg{width:14px;height:14px;flex:none;stroke:currentColor;stroke-width:2.2;fill:none;stroke-linecap:round}
#mhDetail .field:not(.err) .fld-msg{display:none}
/* An error should SNAP in, not fade: the field's own background/border transition would
   otherwise animate the wash over 200ms. */
#mhDetail .field.err .icf{transition:none}
/* One shake as the error appears. NO `both` - a retained fill-mode transform stays a
   STACKING CONTEXT for good, which traps an open dropdown (z-index:1000) inside its own
   field and lets the next field paint over the list. The rule below is the belt to that
   braces: an open field out-ranks the ones after it regardless. */
#mhDetail .field.err .icf{animation:mhFldShk .34s cubic-bezier(.36,.07,.19,.97)}
@keyframes mhFldShk{10%,90%{transform:translateX(-1.5px)}20%,80%{transform:translateX(3px)}30%,50%,70%{transform:translateX(-5px)}40%,60%{transform:translateX(5px)}}
#mhDetail .field:has(> .icf.open){position:relative;z-index:5}
#mhDetail .field.locked .icf{opacity:.62;pointer-events:none}
#mhDetail .icf .num{text-align:left !important}
#mhDetail .trail{display:flex;flex-direction:column;gap:2px;flex:none}
#mhDetail .stepper{width:26px;height:20px;flex:none;border-radius:6px;border:1px solid var(--f-rest-bd);background:rgba(255,255,255,.5);cursor:pointer;display:grid;place-items:center;color:var(--ink-2);transition:background var(--t),color var(--t)}
#mhDetail .stepper:hover{background:#fff;color:var(--brand-600)}
body.dark #mhDetail .stepper{background:rgba(255,255,255,.06)}
body.dark #mhDetail .stepper:hover{background:rgba(255,255,255,.12)}
#mhDetail .stepper svg{width:11px;height:11px;stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .stepper[data-step="up"] svg{transform:rotate(180deg)}
/* the open field (and its popup) must paint above its siblings */
#mhDetail .field:has(.icf.open){position:relative;z-index:60}

/* type-to-search dropdown (MH DEFAULT FIELD standard part 3) */
#mhDetail .icf.has-sel{cursor:pointer}
#mhDetail .sel-face{flex:1;min-width:0;font-family:var(--font-sans);font-size:15px;font-weight:500;color:var(--ink-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;text-align:left !important}
#mhDetail .sel-face.ph{color:var(--ink-4);font-weight:400}
#mhDetail .icf .sel-search{flex:1;min-width:0;font-family:var(--font-sans);font-size:15px;font-weight:500;color:var(--ink-1);cursor:text}
#mhDetail .icf .sel-search::placeholder{color:var(--ink-4);font-weight:400}
#mhDetail .selpop{position:absolute;left:0;right:0;top:calc(100% + 8px);z-index:1000;background:var(--f-focus-bg);border:1px solid var(--f-focus-bd);border-radius:var(--r-md);box-shadow:var(--f-focus-sh),0 22px 48px -18px rgba(28,39,51,.34);padding:7px;display:flex;flex-direction:column;gap:3px;max-height:288px;overflow:auto;scrollbar-width:none;-ms-overflow-style:none;animation:mhdvPop .16s var(--ease)}
@keyframes mhdvPop{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
#mhDetail .selpop.up{top:auto;bottom:calc(100% + 8px);animation-name:mhdvUp}
#mhDetail .selpop::-webkit-scrollbar{width:0;height:0;display:none}
#mhDetail .sel-opt{text-align:left !important;justify-content:flex-start !important;border:none;background:none;font-family:var(--font-sans);font-size:14.5px;font-weight:600;color:var(--ink-1);padding:11px 14px;border-radius:var(--r-sm);cursor:pointer;display:flex !important;align-items:center;gap:10px;width:100%;transition:background var(--t),color var(--t)}
#mhDetail .sel-opt:hover{background:var(--f-rest-bg)}
#mhDetail .sel-opt.on{background:var(--brand-tint);color:var(--brand-600);font-weight:700}
#mhDetail .sel-opt.on::after{content:"\2713";margin-left:auto;color:var(--brand);font-weight:800}
#mhDetail .selpop .cb-empty{padding:13px 14px;font-size:13.5px;font-weight:600;color:var(--ink-3)}

/* checkbox (kit) */
#mhDetail .opt{display:flex;align-items:flex-start;gap:11px;cursor:pointer;user-select:none;padding:3px 0}
#mhDetail .opt input{position:absolute;opacity:0;width:0;height:0}
#mhDetail .box{width:22px;height:22px;flex:none;border-radius:7px;margin-top:1px;background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);box-shadow:var(--f-rest-sh);display:grid;place-items:center;transition:background var(--t),border-color var(--t)}
#mhDetail .box.round{border-radius:999px}
#mhDetail .box .dot{width:10px;height:10px;border-radius:999px;background:#fff;opacity:0;transform:scale(.4);transition:opacity var(--t),transform var(--t)}
#mhDetail .opt input:checked+.box{background:var(--brand);border-color:var(--brand);box-shadow:inset 0 1px 2px rgba(0,0,0,.14)}
#mhDetail .opt input:checked+.box.round{box-shadow:inset 0 0 3px rgba(0,0,0,.12)}
#mhDetail .opt input:checked+.box .dot{opacity:1;transform:scale(1);box-shadow:0 1px 2px rgba(40,60,80,.4)}
#mhDetail .opt .opt-txt{font-size:14.5px;font-weight:500;color:var(--ink-1);line-height:1.35}

/* =========================================================
   DATE FIELD - the frozen shared MhDatePicker, reskinned to .icf.
   The mock's date field (.icf.dpk) is a masked MM/DD/YYYY input + the
   calendar icon + a chevron that opens the calendar. Unlike the enroll
   wizard's date field, this one KEEPS the chevron (mock-faithful).
   The calendar POPOVER itself is untouched.
   ========================================================= */
#mhDetail .mh-dp-d{width:100%}
#mhDetail .dp .dp-field{
  height:auto;min-height:50px;gap:11px;padding:0 15px;cursor:text;
  background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);box-shadow:var(--f-rest-sh);
  border-radius:var(--r-md);user-select:auto;
  transition:background var(--t),border-color var(--t),box-shadow var(--t)}
#mhDetail .dp:not(.open) .dp-field:hover{background:var(--f-hover-bg)}
#mhDetail .dp.open .dp-field{background:var(--f-focus-bg);border-color:var(--f-focus-bd);box-shadow:var(--f-focus-sh)}
#mhDetail .dp .dpf-ico{width:19px;height:19px;color:var(--ink-3)}
#mhDetail .dp.open .dpf-ico{color:var(--brand-600)}
#mhDetail .dp .dpf-val{font-size:15px;font-weight:500;color:var(--ink-1);font-variant-numeric:tabular-nums}
#mhDetail .dp .dpf-val.empty{color:var(--ink-4);font-weight:400}
#mhDetail .dp .dpf-chev{width:18px;height:18px;color:var(--ink-4);transition:transform var(--t)}
#mhDetail .dp.open .dpf-chev{transform:rotate(180deg);color:var(--brand-600)}
/* the masked input: the mask string IS the value, so it never uses ::placeholder */
#mhDetail .dp .dpf-mask,
#mhDetail .dp .dpf-mask:hover,
#mhDetail .dp .dpf-mask:focus,
#mhDetail .dp .dpf-mask:focus-visible{
  flex:1;min-width:0;width:100%;
  background:transparent !important;border:0 !important;box-shadow:none !important;
  border-radius:0 !important;padding:0 !important;min-height:0 !important;height:auto !important;
  outline:none !important;text-align:left !important;
  font-family:var(--font-sans);font-size:15px;font-weight:500;color:var(--ink-1);
  font-variant-numeric:tabular-nums;cursor:text;user-select:text}
#mhDetail .dp .dpf-mask.partial{letter-spacing:.01em}
/* no animation, and reveal the popover only once the JS has PLACED it (the placed
   one carries an inline position:fixed) - otherwise Blazor paints it at its
   stylesheet default first and it visibly jumps. */
#mhDetail .dp .dp-pop{transition:none !important;transform:none !important}
#mhDetail .dp.open .dp-pop{transform:none !important;visibility:hidden;z-index:1200}
#mhDetail .dp.open .dp-pop[style*="position: fixed"]{visibility:visible}
#mhDetail .field:has(.dp.open){position:relative;z-index:80}
#mhDetail .field.err .dp .dp-field{border-color:var(--danger) !important;background:var(--danger-bg) !important;box-shadow:none !important}
#mhDetail .field.locked .dp{pointer-events:none;opacity:.62}

/* =========================================================
   RESPONSIVE - 3-column cap, stepped, never auto-filled (brief 5)
   ========================================================= */
@container (max-width:1000px){#mhDetail .kv{grid-template-columns:repeat(2,1fr)}}
@container (max-width:720px){
  #mhDetail .pd-grid,#mhDetail .kv{grid-template-columns:1fr}
  #mhDetail .tiles{grid-template-columns:repeat(2,1fr)}
  #mhDetail .fgrid{grid-template-columns:1fr}
}

/* the rail's "N more in Overview" row flashes the More details card it jumps to */
@keyframes mhdvFlash{0%,100%{box-shadow:0 0 0 0 rgba(0,0,0,0)}25%{box-shadow:0 0 0 4px var(--brand-tint-2)}}
#mhDetail .pd-card.dv-flash{animation:mhdvFlash 1.2s var(--ease)}

/* =========================================================
   STUDENT DETAIL (host #2) - the only classes the Program host did not need:
   the children KPI card grid, the completion picker inside a list row, and the
   case-note surface. All prefixed sd- and scoped #mhDetail.

   LAW OBSERVED: no framework-generic name survives here. The Household mock's
   .mcard / .add-fam and the Client overlay's .note are NOT reused - Bootstrap
   and the app-global stylesheets own names like .note/.card/.row, and id
   scoping settles only the properties BOTH rules set.
   ========================================================= */

/* ---- children KPI cards: 3-column cap, stepped, never auto-filled ---- */
#mhDetail .sd-kids{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:13px;margin-top:4px}
#mhDetail .sd-kid{
  display:flex;flex-direction:column;gap:12px;min-width:0;text-align:left;
  background:var(--f-focus-bg);border:1px solid var(--line);border-radius:var(--r-md);
  padding:14px 15px;cursor:pointer;font:inherit;color:inherit;
  transition:border-color var(--t),transform var(--t),box-shadow var(--t)}
#mhDetail .sd-kid:hover{border-color:var(--brand-tint-2);transform:translateY(-1px);box-shadow:0 12px 26px -20px rgba(28,39,51,.55)}
#mhDetail .sd-kid:focus-visible{outline:none;box-shadow:0 0 0 3px var(--brand-glow)}
#mhDetail .sd-kid-h{display:flex;align-items:center;gap:11px;min-width:0}
#mhDetail .sd-kav{width:42px;height:42px;flex:none;border-radius:999px;display:grid;place-items:center;
  font-size:14px;font-weight:800;color:#fff;background:linear-gradient(150deg,#6E9C92,#4E7C72);overflow:hidden}
#mhDetail .sd-kav img{width:100%;height:100%;object-fit:cover;display:block}
#mhDetail .sd-kid-id{min-width:0;flex:1}
/* per-card edit: a child is a different record, so this opens a popup, not the in-pane form */
#mhDetail .sd-kedit{flex:none;width:30px;height:30px;border-radius:9px;border:1px solid var(--f-rest-bd);
  background:var(--f-rest-bg);color:var(--ink-3);cursor:pointer;display:grid;place-items:center;
  transition:background var(--t),color var(--t),border-color var(--t)}
#mhDetail .sd-kedit svg{width:15px;height:15px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .sd-kedit:hover{background:var(--brand);border-color:var(--brand);color:#fff}
#mhDetail .sd-kedit:focus-visible{outline:none;box-shadow:0 0 0 3px var(--brand-glow)}
#mhDetail .sd-knm{font-size:14.5px;font-weight:700;color:var(--ink-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#mhDetail .sd-kmeta{font-size:12px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
#mhDetail .sd-kstats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
#mhDetail .sd-kstats .k{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-4)}
#mhDetail .sd-kstats .v{font-size:14px;font-weight:600;color:var(--ink-2);margin-top:3px;overflow-wrap:anywhere}

/* the Add tile is a WALK-IN affordance only - the razor decides, this just draws it */
#mhDetail .sd-kid.sd-kadd{
  align-items:center;justify-content:center;gap:9px;text-align:center;
  background:var(--f-rest-bg);border-style:dashed;border-color:var(--f-rest-bd);color:var(--ink-3);min-height:112px}
#mhDetail .sd-kid.sd-kadd:hover{border-color:var(--brand);color:var(--brand-600);background:var(--f-hover-bg)}
#mhDetail .sd-kplus{width:34px;height:34px;border-radius:999px;display:grid;place-items:center;background:var(--brand-tint);color:var(--brand-600)}
#mhDetail .sd-kplus svg{width:18px;height:18px}
#mhDetail .sd-klbl{font-size:13px;font-weight:700;letter-spacing:.01em}

/* completion picker - the app's own rounded popup, never the OS <select> menu */
/* the closed field and the open menu are the SAME width - a menu wider than its trigger
   reads as a different control popping out from under it */
#mhDetail .sd-comp{position:relative;flex:none;display:flex;align-items:center;justify-content:space-between;
  gap:8px;cursor:pointer;width:190px;
  padding:7px 12px;border-radius:999px;background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);
  box-shadow:var(--f-rest-sh);transition:background var(--t),border-color var(--t)}
#mhDetail .sd-comp:hover{background:var(--f-hover-bg)}
#mhDetail .sd-comp.open{background:var(--f-focus-bg);border-color:var(--f-focus-bd);box-shadow:var(--f-focus-sh)}
#mhDetail .sd-comp-face{font-size:12.5px;font-weight:700;color:var(--ink-2);white-space:nowrap}
#mhDetail .sd-comp-chev{line-height:0;color:var(--ink-4);transition:transform var(--t)}
#mhDetail .sd-comp-chev svg{width:14px;height:14px}
#mhDetail .sd-comp.open .sd-comp-chev{transform:rotate(180deg)}
/* reuse the field kit's popup so spacing, radius and hover match every other dropdown */
/* left+right:0 with width:auto stretches to the trigger's BORDER box; width:100% measured
   the content box instead and came up 2px short. */
#mhDetail .sd-comppop{top:calc(100% + 8px);left:0;right:0;width:auto;min-width:0;box-sizing:border-box}

/* ---- completion picker living inside a .dv-row ---- */
#mhDetail .sd-setsel{position:relative;flex:none;display:flex;align-items:center}
#mhDetail .sd-setsel select{
  appearance:none;-webkit-appearance:none;font:inherit;font-size:12.5px;font-weight:700;
  color:var(--ink-2);background:var(--f-rest-bg);border:1px solid var(--f-rest-bd);
  border-radius:999px;padding:6px 30px 6px 13px;cursor:pointer;box-shadow:var(--f-rest-sh);
  transition:background var(--t),border-color var(--t)}
#mhDetail .sd-setsel select:hover{background:var(--f-hover-bg)}
#mhDetail .sd-setsel select:focus-visible{outline:none;background:var(--f-focus-bg);border-color:var(--f-focus-bd)}
#mhDetail .sd-setchev{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--ink-4);line-height:0}
#mhDetail .sd-setchev svg{width:14px;height:14px}

/* ---- case notes ---- */
#mhDetail .sd-noteadd{position:relative;display:flex;flex-direction:column;gap:10px;margin:2px 0 16px}
#mhDetail .sd-noteadd .icf.area textarea{min-height:88px}
#mhDetail .sd-noteact{display:flex;justify-content:flex-end}
#mhDetail .sd-note{border-top:1px solid var(--line);padding:14px 0 2px}
#mhDetail .sd-note:first-of-type{border-top:none;padding-top:4px}
#mhDetail .sd-note-h{display:flex;align-items:center;gap:9px}
#mhDetail .sd-note-h .sp{flex:1}
#mhDetail .sd-note-av{width:28px;height:28px;flex:none;border-radius:999px;display:grid;place-items:center;
  font-size:11px;font-weight:800;color:#fff}
#mhDetail .sd-note-who{font-size:13.5px;font-weight:700;color:var(--ink-1)}
#mhDetail .sd-note-when{font-size:11.5px;font-weight:600;color:var(--ink-4);white-space:nowrap}
#mhDetail .sd-note-b{font-size:14px;line-height:1.65;color:var(--ink-2);margin:8px 0 0 37px;white-space:pre-wrap;overflow-wrap:anywhere}

/* @-mention picker - anchored above the textarea, positioned by the shared mentions.js */
#mhDetail .sd-mentionpop{
  position:absolute;left:0;bottom:calc(100% + 6px);z-index:90;width:min(320px,100%);
  max-height:232px;overflow:auto;padding:6px;
  background:var(--f-focus-bg);border:1px solid var(--line);border-radius:var(--r-md);
  box-shadow:var(--f-focus-sh)}
#mhDetail .sd-mentionopt{
  display:flex;align-items:center;gap:9px;width:100%;padding:7px 9px;border:none;background:none;
  border-radius:8px;cursor:pointer;font:inherit;justify-content:flex-start;text-align:left}
#mhDetail .sd-mentionopt:hover,#mhDetail .sd-mentionopt.on{background:var(--brand-tint)}
#mhDetail .sd-mentionav{width:24px;height:24px;flex:none;border-radius:999px;display:grid;place-items:center;
  font-size:10px;font-weight:800;color:#fff}
#mhDetail .sd-mentionnm{font-size:13.5px;font-weight:600;color:var(--ink-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

@container (max-width:1000px){#mhDetail .sd-kids{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container (max-width:720px){#mhDetail .sd-kids{grid-template-columns:1fr}}

/* =========================================================
   CHILD CARDS - ported from the Enroll Student wizard mock
   (_handoff/Student Enrollment Wizard/Program Wizards/Enroll Student Wizard.html,
   .kids-grid / .kid-card / .kc-av / .kc-nm / .kc-meta / .kc-act / .kid-add).
   Centred column, avatar on top, Edit at the BOTTOM CENTRE - not a corner glyph.
   ========================================================= */
#mhDetail .kids-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:4px}
#mhDetail .kid-card{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:9px;padding:18px 14px;border:1px solid var(--line);border-radius:16px;background:var(--f-focus-bg);
  cursor:pointer;font:inherit;color:inherit;transition:box-shadow var(--t),border-color var(--t)}
#mhDetail .kid-card:hover{border-color:var(--f-focus-bd);box-shadow:0 12px 26px -16px rgba(28,39,51,.4)}
#mhDetail .kid-card:focus-visible{outline:none;box-shadow:0 0 0 3px var(--brand-glow)}
#mhDetail .kc-av{width:64px;height:64px;border-radius:99px;overflow:hidden;background:var(--f-rest-bg);
  box-shadow:inset 0 0 0 1px var(--f-rest-bd);display:grid;place-items:center;flex:none}
#mhDetail .kc-av img{width:100%;height:100%;object-fit:cover;display:block}
#mhDetail .kc-av .mh-ini{width:100%;height:100%;display:grid;place-items:center;color:var(--ink-4)}
#mhDetail .kc-av .mh-ini svg{width:52%;height:52%}
#mhDetail .kc-nm{font-size:14.5px;font-weight:800;color:var(--ink-1);letter-spacing:-.01em;overflow-wrap:anywhere}
#mhDetail .kc-meta{font-size:12px;color:var(--ink-3);font-weight:600}
#mhDetail .kc-act{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 10px;border-radius:8px;
  border:1px solid var(--f-rest-bd);background:var(--f-focus-bg);color:var(--ink-2);font-size:11.5px;
  font-weight:700;font-family:var(--font-sans);cursor:pointer;transition:color var(--t),border-color var(--t)}
#mhDetail .kc-act svg{width:13px;height:13px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mhDetail .kc-act:hover{color:var(--brand-600);border-color:var(--brand)}
#mhDetail .kc-edit-b{margin-top:4px}
#mhDetail .kid-add{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:11px;
  min-height:158px;padding:18px;border:1.6px dashed var(--f-rest-bd);border-radius:16px;
  background:rgba(255,255,255,.24);color:var(--ink-3);cursor:pointer;font-family:var(--font-sans);
  transition:border-color var(--t),background var(--t),color var(--t)}
#mhDetail .kid-add:hover{border-color:var(--brand);background:var(--f-hover-bg);color:var(--brand-600)}
#mhDetail .kid-plus{width:38px;height:38px;border-radius:999px;display:grid;place-items:center;
  background:var(--brand-tint);color:var(--brand-600);font-size:22px;font-weight:700;line-height:1}
#mhDetail .kid-add-l{font-size:13px;font-weight:700}
@container (max-width:1000px){#mhDetail .kids-grid{grid-template-columns:repeat(2,1fr)}}
@container (max-width:720px){#mhDetail .kids-grid{grid-template-columns:1fr}}

/* =========================================================
   THE CHILD WIZARD - ported from the Enroll Student wizard mock
   (_handoff/Student Enrollment Wizard/Program Wizards/Enroll Student Wizard.html,
   lines 142-182 + 664-671: .kid-ov / .kid-shell / .kid-rail / .kid-pane).

   Rail + pane, exactly like the record shell one layer down: the rail is the
   CHILD's identity while you fill it in, the pane is the two steps. It sits over
   the student's pane on purpose - the pane belongs to the student, and a child is
   a different person, so it can never take it over (the one exception to the
   in-pane edit law).

   Scoped #mhDetail and kid- prefixed. .kid-card / .kc-* / .kid-add above are the
   CARD grid from the same mock and are untouched by these rules.
   ========================================================= */
/* flex centring, not grid, to match #mhDetail.dv-stage.ovr exactly: a grid track auto-sizes
   to its item, so max-width:100% resolved against a track that had already grown and the
   shell could overflow the overlay. A flex item clamps. */
#mhDetail .kid-ov{position:absolute;inset:0;z-index:84;display:flex;align-items:center;
  justify-content:center;overflow:hidden;padding:20px;
  background:rgba(12,24,20,.55);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  container-type:inline-size;opacity:0;transition:opacity .2s var(--ease)}
#mhDetail .kid-ov.in{opacity:1}
/* THE SAME BOX AS THE RECORD SHELL it sits on top of - width/height copied from
   #mhDetail.dv-stage.ovr>.modal, which in turn matches Client Detail's .cdbox. A child is a
   whole person; giving its wizard a smaller window made it read as a dialog about the
   student rather than a record of its own. --mh-vw/--mh-vh, never bare vw/vh: the app-wide
   zoom inflates the bare units (see the Display resolution law). */
#mhDetail .kid-shell{display:flex;width:min(1520px,calc(97 * var(--mh-vw)));
  height:min(calc(93 * var(--mh-vh)),920px);max-width:100%;max-height:100%;
  background:var(--bg-canvas);border-radius:20px;overflow:hidden;
  box-shadow:0 50px 110px -22px rgba(8,18,14,.62)}

/* ---- rail: 340px and the SAME gradient as the record shell's rail (--dv-rail-a/b), not a
   second green. It also makes the camera button's ring - which is drawn in --dv-rail-a so it
   reads as punched out of the rail - land on the colour it was designed for. ---- */
#mhDetail .kid-rail{width:340px;flex:none;overflow:auto;scrollbar-width:none;
  background:radial-gradient(120% 55% at 90% 3%,rgba(255,255,255,.14),transparent 42%),
             linear-gradient(162deg,var(--dv-rail-a) 0%,var(--dv-rail-b) 100%);
  color:#fff;padding:32px 24px;display:flex;flex-direction:column;align-items:center;text-align:center}
#mhDetail .kid-rail::-webkit-scrollbar{width:0;display:none}
/* NO .kid-photo rules. The child rail renders the app's canonical .mh-photo control (see
   RAIL PROFILE PHOTO above), so the gradient circle, the person glyph, the hover veil, the
   clay camera button and the popover z-index are all inherited, not restated. The one thing
   that needs saying here is the spacing inside THIS rail. */
#mhDetail .kid-rail .mh-photo{margin:0 0 2px}
#mhDetail .kid-photo-ini{font-size:34px;font-weight:800;letter-spacing:-.02em;color:#fff}
#mhDetail .kid-photo-ph{display:grid;place-items:center;color:rgba(255,255,255,.85)}
#mhDetail .kid-photo-ph svg{width:40px;height:40px;stroke:currentColor;stroke-width:1.7;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
#mhDetail .kid-rnm{margin-top:14px;font-size:19px;font-weight:800;letter-spacing:-.01em;color:#fff;
  overflow-wrap:anywhere}
#mhDetail .kid-rnm.empty{color:rgba(255,255,255,.55)}
#mhDetail .kid-rsub{margin-top:4px;font-size:12px;font-weight:600;color:rgba(255,255,255,.7)}
#mhDetail .kid-rfacts{margin-top:18px;width:100%;border-top:1px solid rgba(255,255,255,.16);
  padding-top:6px;display:flex;flex-direction:column}
#mhDetail .kid-rfact{display:flex;align-items:center;gap:11px;padding:9px 0;text-align:left}
#mhDetail .kid-rfact .ic{width:30px;height:30px;flex:none;border-radius:9px;background:rgba(255,255,255,.1);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.15);display:grid;place-items:center}
#mhDetail .kid-rfact .ic svg{width:15px;height:15px;stroke:rgba(255,255,255,.85);stroke-width:2;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
#mhDetail .kid-rfact .k{font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:rgba(255,255,255,.6)}
#mhDetail .kid-rfact .v{font-size:13.5px;font-weight:700;color:#fff;margin-top:2px;overflow-wrap:anywhere}

/* ---- pane ---- */
/* min-HEIGHT:0 as well as min-width: when the shell stacks (narrow), the pane is a flex
   ITEM in a column and would refuse to shrink below its content - which pushed the footer
   out of the overflow:hidden shell and made Cancel / Continue unclickable. */
#mhDetail .kid-pane{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;background:var(--bg-canvas)}
#mhDetail .kid-head{flex:none;padding:26px 32px 4px}
#mhDetail .kid-top{display:flex;align-items:center;gap:16px;margin-bottom:16px}
#mhDetail .kid-top .prog-count{font-size:12.5px;font-weight:700;color:var(--brand-600);
  letter-spacing:.01em;white-space:nowrap}
#mhDetail .kid-top .prog-bar{flex:1;min-width:0;height:7px;border-radius:99px;
  background:var(--f-rest-bg);overflow:hidden}
#mhDetail .kid-top .prog-bar i{display:block;height:100%;border-radius:99px;background:var(--brand);
  transition:width .35s var(--ease)}
#mhDetail .kid-ey{font-family:var(--font-mono);font-size:10.5px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--brand-600)}
/* WIZARD TITLES ARE UPPERCASE, APP-WIDE (CEO, Jul 31 2026).
   Owned by CSS, never by the string. The same child wizard reached "EDIT CHILD" from the
   Enroll wizard (hardcoded caps in the markup) and "Edit child" from here (sentence case),
   because two hosts each spelled their own title. A transform makes the casing a property
   of the CHROME, so it holds for dynamic titles too and cannot drift again.
   Tracking goes slightly POSITIVE: the sentence-case setting used -.01em, and negative
   tracking on capitals closes the letters up until the word reads as one shape. */
#mhDetail .kid-head h3{font-size:20px;font-weight:800;letter-spacing:.02em;margin:6px 0 0;color:var(--ink-1);
  text-transform:uppercase}
#mhDetail .kid-head p{font-size:13px;color:var(--ink-3);margin:6px 0 0;line-height:1.45}
#mhDetail .kid-body{flex:1;min-height:0;overflow:auto;padding:20px 32px 24px;scrollbar-width:none}
#mhDetail .kid-body::-webkit-scrollbar{width:0;display:none}
#mhDetail .kid-foot{flex:none;display:flex;align-items:center;gap:12px;padding:16px 32px;
  border-top:1px solid var(--line);background:var(--bg-canvas)}
#mhDetail .kid-foot .spacer{flex:1}
#mhDetail .kid-same{margin:0 0 16px}

/* ---- review ---- */
#mhDetail .kid-rev{border:1px solid var(--line);border-radius:14px;overflow:hidden}
#mhDetail .kid-rev .h{font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:var(--brand);padding:10px 14px;background:var(--f-rest-bg);border-bottom:1px solid var(--line)}
#mhDetail .kid-rrow{display:flex;justify-content:space-between;gap:14px;padding:11px 14px;font-size:13.5px}
#mhDetail .kid-rrow+.kid-rrow{border-top:1px solid var(--line)}
#mhDetail .kid-rrow .k{color:var(--ink-3);font-weight:600;flex:none}
#mhDetail .kid-rrow .v{color:var(--ink-1);font-weight:700;text-align:right;overflow-wrap:anywhere}
#mhDetail .kid-rrow .v.off{color:var(--ink-4);font-weight:500}

/* ---- a field this surface can SEE but not write ---- */
/* The mock's .field.locked: greyed and inert, never removed. A field that vanishes
   reads as "we hold no value"; a greyed one reads as "this is the value, elsewhere". */
#mhDetail .field.locked>label{opacity:.62}
#mhDetail .field.locked .icf{pointer-events:none;background:var(--f-rest-bg);opacity:.62;box-shadow:none}

/* Below ~840px of overlay width the rail cannot hold its 320px and the form at once.
   Container query, not @media: the app-wide zoom (mh.scale) makes viewport units lie. */
@container (max-width:840px){
  #mhDetail .kid-shell{flex-direction:column}
  #mhDetail .kid-rail{width:auto;flex:none;padding:20px 22px;flex-direction:row;text-align:left;
    align-items:center;gap:16px;overflow:visible}
  #mhDetail .kid-rail .mh-photo{width:60px;height:60px;margin:0;border-width:2px}
  #mhDetail .kid-rail .mh-btn{width:20px;height:20px;box-shadow:0 0 0 2px var(--dv-rail-a)}
  #mhDetail .kid-rail .mh-btn svg{width:10px;height:10px}
  #mhDetail .kid-rail .mh-ov{font-size:0;gap:0}
  #mhDetail .kid-rail .mh-ov svg{width:18px;height:18px}
  #mhDetail .kid-photo-ph svg{width:22px;height:22px}
  #mhDetail .kid-rnm{margin-top:0;font-size:16px}
  #mhDetail .kid-rfacts{display:none}
  #mhDetail .kid-head{padding:20px 22px 2px}
  #mhDetail .kid-body{padding:16px 22px 20px}
  #mhDetail .kid-foot{padding:14px 22px}
  #mhDetail .kid-body .fgrid{grid-template-columns:1fr}
}

/* =============================================================================
   AN OPEN ROW-LEVEL PICKER MUST OUT-RANK THE ROWS BELOW IT (CEO, Aug 2 2026)
   -----------------------------------------------------------------------------
   The completion picker in Student Details > Enrollment > ALL PROGRAMS opened
   BEHIND the next two rows: you could see their "In Progress" chips painted over
   its options, so the list was there but half of it was unreachable.

   `.dv-row` carries `transition: ... transform ...` and `:hover{transform:...}`.
   A transform makes an element a STACKING CONTEXT, so the moment a later row is
   hovered - which is exactly what happens while the user moves the mouse down the
   open list - that row is promoted above the popup, no matter that the popup
   carries z-index:1000. The popup was never "behind" in source order; it lost to a
   sibling that got promoted underneath the pointer.

   Same shape as the two `:has(.icf.open)` rules further up (lines ~707/718) that
   fixed this for the edit-form fields. Lifting the ROW lifts the popup with it,
   because the popup lives inside it.
   ============================================================================= */
#mhDetail .dv-row:has(.sd-comp.open),
#mhDetail .dv-row:has(.icf.open),
#mhDetail .dv-row:has(.selpop){position:relative;z-index:70}
/* ...and the row must not be promoted over it by a hover while the list is open. */
#mhDetail .dv-rows:has(.sd-comp.open) .dv-row:hover{transform:none}


/* ============================================================================
   SESSION-CANCEL-01 (CEO, Aug 4 2026) - cancel ONE day of a term.
   Arizona heat days: the class on the 6th is called off, the rest of the term
   runs. The row stays on the list, visibly cancelled, because a session that
   silently vanished here would still appear in the attendance matrix and the
   reports - and staff would just see an unexplained gap.
   ============================================================================ */

/* the per-row action. Quiet until hovered: this list is read far more often than
   it is acted on, and a column of red buttons would make a normal schedule look
   like a problem. */
#mhDetail .dv-row .dv-sx{display:inline-flex;align-items:center;gap:6px;flex:none;
  font-family:var(--font-sans);font-size:11.5px;font-weight:700;padding:5px 10px;
  border-radius:999px;border:1px solid var(--line);background:var(--f-rest-bg);
  color:var(--ink-3);cursor:pointer;opacity:.55;
  transition:opacity var(--t),background var(--t),border-color var(--t),color var(--t)}
#mhDetail .dv-row:hover .dv-sx{opacity:1}
#mhDetail .dv-row .dv-sx:focus-visible{opacity:1;outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-tint)}
#mhDetail .dv-row .dv-sx svg{width:13px;height:13px;stroke-width:2.4}
#mhDetail .dv-row .dv-sx.danger:hover{background:#fdecec;border-color:#f3c4c3;color:#b0312f}
body.dark #mhDetail .dv-row .dv-sx.danger:hover{background:rgba(176,49,47,.18);border-color:rgba(243,196,195,.3);color:#f0a9a6}
#mhDetail .dv-row .dv-sx:not(.danger):hover{background:var(--brand-tint);border-color:var(--brand);color:var(--brand-600)}

/* a cancelled day. Dimmed, not hidden - and the date badge keeps its colour so
   the row is still scannable by date. */
#mhDetail .dv-row.is-cancelled{background:var(--f-rest-bg);border-style:dashed}
#mhDetail .dv-row.is-cancelled .nm{text-decoration:line-through;color:var(--ink-3)}
#mhDetail .dv-row.is-cancelled .day{opacity:.6}
#mhDetail .chip.warn{background:#fff3e0;color:#9a5b12}
body.dark #mhDetail .chip.warn{background:rgba(154,91,18,.24);color:#f0c48a}

/* THE CONFIRM, inline under the row it belongs to. Amber, not red: cancelling a
   heat day is a normal decision, not an accident being caught. It sits under its
   own row so the date being cancelled is never off-screen behind a backdrop -
   which is exactly what a modal would have done. */
#mhDetail .dv-confirm{margin:-2px 0 2px 0;padding:12px 14px;border-radius:var(--r-md);
  background:#fff8e6;border:1px solid #f0d9a0;display:flex;flex-direction:column;gap:9px}
body.dark #mhDetail .dv-confirm{background:rgba(154,110,18,.16);border-color:rgba(240,217,160,.28)}
#mhDetail .dv-confirm-q{font-size:13px;font-weight:600;color:#7a5510;line-height:1.45}
body.dark #mhDetail .dv-confirm-q{color:#f0c48a}
#mhDetail .dv-confirm-in{font-family:var(--font-sans);font-size:13px;padding:8px 12px;
  border-radius:var(--r-sm);border:1px solid #e2d3ae;background:#fff;color:var(--ink-1);width:100%;box-sizing:border-box}
body.dark #mhDetail .dv-confirm-in{background:var(--f-rest-bg);border-color:rgba(240,217,160,.24);color:var(--ink-1)}
#mhDetail .dv-confirm-in:focus-visible{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-tint)}
#mhDetail .dv-confirm-err{font-size:12.5px;font-weight:600;color:#b0312f}
#mhDetail .dv-confirm-acts{display:flex;gap:8px;flex-wrap:wrap}
#mhDetail .dv-cf{font-family:var(--font-sans);font-size:12.5px;font-weight:700;
  border-radius:var(--r-sm);padding:7px 13px;cursor:pointer;transition:background var(--t),border-color var(--t),color var(--t)}
#mhDetail .dv-cf.no{background:#fff;border:1px solid #e2d3ae;color:#7a5510}
#mhDetail .dv-cf.no:hover{background:#fdf3df}
body.dark #mhDetail .dv-cf.no{background:transparent;border-color:rgba(240,217,160,.3);color:#f0c48a}
#mhDetail .dv-cf.yes{background:#b0312f;border:1px solid #b0312f;color:#fff}
#mhDetail .dv-cf.yes:hover{background:#962825;border-color:#962825}
#mhDetail .dv-cf.yes:disabled{opacity:.6;cursor:default}
