/* =============================================================================
   Matthew House - design system (LOCKED tokens from mh-dashboard.html).
   Everything is scoped under .mh-app so it wins over Bootstrap/MudBlazor base
   styles without class collisions. MudThemeProvider mirrors these same tokens
   so MudBlazor components (tables, dialogs, dropdowns) inherit the look.
   ========================================================================== */

:root {
  /* ---- viewport tokens (Display resolution) --------------------------------
     1% of the REAL viewport, immune to the root `zoom` the Display-resolution
     engine applies. Root zoom multiplies painted lengths by Z, but vh/vw are
     resolved in LAYOUT px and are NOT divided back down, so `100vh` paints as
     innerHeight * Z: at xlarge (1.30) every vh-sized overlay ran ~20% off the
     screen. shell.js applyViewportTokens() overwrites these with the measured
     values wherever it writes the zoom (and App.razor's pre-boot script sets
     them before first paint).

     These literal fallbacks are the SAFETY NET: if the script never runs,
     calc(92 * var(--mh-vh)) collapses to exactly 92vh - the app's old
     behaviour - so a missing token can degrade, never break the layout.
     RULE: any height/width that must respect the SCREEN uses these, never a
     bare vh/vw. Ordinary px/rem/% lengths still scale with the zoom, which is
     the whole point of zoom. */
  --mh-vh: 1vh;
  --mh-vw: 1vw;

  --mh-cream:    #E8EBF0;
  --mh-cream-2:  #F1F4F7;
  --mh-surface:  #FFFFFF;
  --mh-slate:    #34454D;   /* dark text / headings only - NOT the sidebar surface */
  --mh-slate-2:  #2A383F;
  --mh-sidebar:  #2E4A43;   /* deep pine-sage, derived from brand green - reads green, not blue */
  --mh-sidebar-2:#213A33;
  --mh-green:    #4E7C72;
  --mh-green-d:  #3D655D;
  --mh-clay:     #C97B5A;
  --mh-clay-d:   #B5663F;
  --mh-ink:      #2A2F31;
  --mh-muted:    #8A8B83;
  --mh-line:     #D9DFE7;
  --mh-line-cool:#D9DFE7;   /* cool-grey hairline for the cool #E8EBF0 surfaces (Teams) - NOT the warm app line */

  --mh-success:  #4E7C72;
  --mh-warning:  #D89B3D;
  --mh-warning-d:#9A6B1E;
  --mh-danger:   #B0463C;
  --mh-info:     #5E7A83;

  --mh-r-card:   14px;
  --mh-r-input:  14px;
  --mh-r-btn:    16px;
  --mh-r-pill:   999px;

  --mh-shadow:    0 10px 28px rgba(52,69,77,.10);
  --mh-shadow-sm: 0 2px 10px rgba(52,69,77,.07);
  --mh-shadow-lg: 0 24px 60px rgba(52,69,77,.16);

  /* KICKOFF 23 (event-chip lightening): a UNIFORM filter applied over the inline DB
     chip colors (lkp_EventType/lkp_ReminderType.ColorHex stays authoritative). It is
     contrast(<1)+brightness so the DARK types (Meeting/Court) lift a lot while the
     PALE types (gold Reminder) are pulled toward mid instead of blowing out to white -
     so white chip text stays legible on every chip. Tuned per theme (light vs dark
     differ) and capped at what the palest chip can hold. */
  --pl-chip-filter:       contrast(.64) brightness(1.2);
  --pl-chip-filter-hover: contrast(.64) brightness(1.28);

  /* ===== FILLED SOFT control set (PROMPT FS1 + BrandRetint) =====
     Brand pine/teal control scale. Token NAMES kept as --mh-sage-* (consumed by
     both the --mh-ctrl-* layer below and the light-only wizard modal), but VALUES
     were reseeded sage->pine/teal so controls read Matthew House brand, not grass
     sage. These NEVER flip with dark mode. The page palette (--mh-green/cream/...)
     is untouched: Filled Soft is applied to CONTROLS only. Anchor: accent #4E7C72
     is the existing brand --green (matches .tip / .btn--p chrome). */
  --mh-sage-50:  #F3F6F5;
  --mh-sage-100: #E3EAE8;
  --mh-sage-200: #BCCDC9;
  --mh-sage-300: #98B3AD;
  --mh-sage-400: #5E9388;
  --mh-sage-500: #4E7C72;
  --mh-sage-600: #6E948B;
  --mh-sage-700: #3D655D;
  /* Semantic control tokens - app-wide controls reference THESE so they flip
     correctly in dark (see body.dark override). Light = the brand pine values. */
  --mh-ctrl-fill:         var(--mh-sage-50);   /* rest fill: textbox/select/search/combo */
  --mh-ctrl-fill-2:       var(--mh-sage-100);  /* checkbox-off / toggle-track-off */
  --mh-ctrl-border:       var(--mh-sage-200);  /* radio border */
  --mh-ctrl-focus-border: var(--mh-sage-300);  /* border on focus */
  --mh-ctrl-accent:       var(--mh-sage-500);  /* ON / checked / focus accent (#4E7C72 brand) */
  --mh-ctrl-accent-2:     var(--mh-sage-700);  /* deeper accent / selected (#3D655D) */
  --mh-ctrl-ico:          var(--mh-sage-600);  /* leading icon / placeholder */
  --mh-ctrl-selected:     var(--mh-sage-700);  /* selected-option text */
  --mh-ctrl-r:            12px;                 /* control radius (DESIGN --r-md) */
  --mh-ctrl-focus-ring:   0 0 0 3px rgba(78,124,114,.55);  /* brand pine @55% */
  /* Brand-teal caret for native selects (appearance:none gets this as a bg image).
     -caret = closed (points down); -caret-up = open (points up) - swapped on select:open
     so every native <select> shows the SAME open/close arrow change as the custom combos. */
  --mh-ctrl-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236E948B' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  --mh-ctrl-caret-up: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236E948B' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 15l6-6 6 6'/></svg>");
  /* SVG check for the custom appearance:none checkbox (white stroke, shown on :checked) */
  --mh-ctrl-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6L9 17l-5-5'/></svg>");

  /* Design font system (Addendum D1): Hanken Grotesk = head + body, IBM Plex Mono =
     data identifiers (--mono), Source Serif 4 = loaded accent applied nowhere yet.
     Urbanist/Fraunces/Public Sans retired (faces kept in mh-fonts.css). */
  --mh-font-head: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mh-font-body: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  --mh-font-serif: 'Source Serif 4', Georgia, serif;

  --sidebar-w: 264px;
}

/* ===== dark mode token overrides (sets the cascade; toggled via body.dark) ===== */
body.dark {
  --mh-cream:#151C1A; --mh-cream-2:#1C2421; --mh-surface:#222B27;
  --mh-ink:#EBE7DB; --mh-muted:#9AA49C; --mh-line:#33403A; --mh-line-cool:#313A40;
  --mh-shadow:0 10px 28px rgba(0,0,0,.35); --mh-shadow-sm:0 2px 10px rgba(0,0,0,.3);
  /* KICKOFF 23: dark-mode chip lightening (tuned separately - dark cells tolerate a
     bit more lift; contrast<1 still protects the gold/pale chips). */
  --pl-chip-filter:       contrast(.66) brightness(1.24);
  --pl-chip-filter-hover: contrast(.66) brightness(1.32);
  /* Filled Soft dark variant: the FS file is light-only, so derive dark here.
     On dark surfaces use a translucent-light fill instead of the pine fill; keep
     the brand accent (lifted to sage-400 = #5E9388 for contrast) on focus/on
     states, ring stays the brand-pine rgba. */
  --mh-ctrl-fill:         rgba(255,255,255,.06);
  --mh-ctrl-fill-2:       rgba(255,255,255,.11);
  --mh-ctrl-border:       rgba(255,255,255,.16);
  --mh-ctrl-focus-border: var(--mh-sage-400);
  --mh-ctrl-accent:       var(--mh-sage-400);
  --mh-ctrl-accent-2:     var(--mh-sage-300);
  --mh-ctrl-ico:          #9FB6A0;
  --mh-ctrl-selected:     var(--mh-sage-300);
  --mh-ctrl-focus-ring:   0 0 0 3px rgba(78,124,114,.55);
  --mh-ctrl-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239FB6A0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  --mh-ctrl-caret-up: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239FB6A0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 15l6-6 6 6'/></svg>");
}
body.dark ::-webkit-scrollbar-thumb { background:#3A4742; }

html, body {
  height: 100%;
  margin: 0;
}
body {
  background:
    radial-gradient(1200px 600px at 78% -10%, rgba(201,123,90,.06), transparent 60%),
    radial-gradient(900px 500px at -5% 0%, rgba(78,124,114,.06), transparent 55%),
    var(--mh-cream);
  color: var(--mh-ink);
  font-family: var(--mh-font-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: #d8d0bf; border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }

/* ===== app shell grid (narrow pine icon rail + main) ===== */
.mh-app { display: grid; grid-template-columns: auto 1fr; min-height: calc(100 * var(--mh-vh)); }
.mh-app * { box-sizing: border-box; }
.mh-app h1, .mh-app h2, .mh-app h3, .mh-app h4 {
  font-family: var(--mh-font-head); font-weight: 600; letter-spacing: -.4px; margin: 0;
}
/* Form controls don't inherit font-family from their parent by UA default - force every
   shell control to pick up Hanken Grotesk (the body font). Explicit per-control
   font-family rules (var(--mh-font-body)/var(--mono)) still win on higher specificity. */
.mh-app button, .mh-app input, .mh-app select, .mh-app textarea { font-family: inherit; }
/* Reusable mono utility (Addendum D1): IBM Plex Mono for inline data identifiers /
   codes only - MH codes, record IDs, reference codes. NOT dates, money, phone, counts. */
.mh-app .mono { font-family: var(--mono); }

/* =============================================================================
   FILLED SOFT - shared control layer (PROMPT FS1). The app-wide DEFAULT for every
   control, scoped to .mh-app. Soft sage fill + transparent border at rest -> white
   surface + sage border + focus ring on focus. Feature areas that still carry
   bespoke higher-specificity rules override this until they are repointed to the
   same --mh-ctrl-* tokens (phased rollout). Decisions: native <select> keeps its
   native menu (only the closed control gets the look); checkbox/radio are restyled
   CSS-only via appearance:none (no markup change).
   ============================================================================= */
.mh-app :is(input[type=text], input[type=search], input[type=email], input[type=tel],
  input[type=password], input[type=number], input[type=date], input[type=time],
  input[type=url], input[type=month], input[type=week], input:not([type]), textarea, select) {
  font-family: inherit; font-size: 14px; font-weight: 500; color: var(--mh-ink);
  background-color: var(--mh-ctrl-fill); border: 1px solid transparent;
  border-radius: var(--mh-ctrl-r); padding: 12px 14px; box-sizing: border-box;
  transition: background .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.mh-app :is(input, textarea)::placeholder { color: var(--mh-ctrl-ico); opacity: .6; }
.mh-app :is(input[type=text], input[type=search], input[type=email], input[type=tel],
  input[type=password], input[type=number], input[type=date], input[type=time],
  input[type=url], input[type=month], input[type=week], input:not([type]), textarea, select):focus {
  outline: none; background-color: var(--mh-surface);
  border-color: var(--mh-ctrl-focus-border); box-shadow: var(--mh-ctrl-focus-ring);
}
.mh-app textarea { min-height: 76px; resize: vertical; line-height: 1.55; }
/* ---------------------------------------------------------------------------
   Native <select> caret - ONE geometry app-wide (DROPDOWN UNIFICATION):
   . appearance:none on every engine + ::-ms-expand hidden  -> never the OS double-arrow
   . a single caret SVG, fixed 14px, pinned right 14px + vertically centered  -> the
     arrow sits in the exact same spot as every other combo (matches "All Countries")
   . on :open the caret swaps to the up-chevron  -> the same open/close arrow change the
     custom combos animate. (Native OS-drawn menus can't tween a background image, so this
     is a crisp flip; real-element chevrons below get the 180deg rotate transition.)
   Scoped per-context select rules re-declare background-image at higher specificity, so
   each carries its own matching `select:open` line (see mh-clientwizard/household/etc).
   --------------------------------------------------------------------------- */
/* `:not([multiple])` raises specificity to (0,2,1) so these caret longhands win over the
   FILLED-SOFT :is(...) base rule above (also 0,2,1) on source order - without it the base
   rule's `padding` + (former) `background` shorthand clobbered the caret. Normal single
   selects all match; a rare multi-select wants no caret anyway. */
.mh-app select:not([multiple]) {
  appearance: none; -webkit-appearance: none; -moz-appearance: none; cursor: pointer; padding-right: 40px;
  background-image: var(--mh-ctrl-caret); background-repeat: no-repeat;
  background-position: right 14px center; background-size: 14px 14px;
}
.mh-app select::-ms-expand { display: none; }
.mh-app select:not([multiple]):open { background-image: var(--mh-ctrl-caret-up); }

/* -----------------------------------------------------------------------------
   NATIVE SELECT with the SMOOTH date-picker rotate (.mh-selwrap).
   A background-image caret can't tween a rotation, so a select that wants the
   identical smooth 180deg rotate is wrapped in a tight .mh-selwrap span carrying a
   REAL overlaid .selchev svg. The wrapper hugs the select, so the chevron sits at the
   select's right edge, vertically centered (svg is display:block -> no baseline drift).
   `background-image:none !important` kills the select's own flip-caret so there's never
   a double arrow (needed because several scoped caret rules carry id-level specificity).
   ----------------------------------------------------------------------------- */
.mh-app .mh-selwrap { position: relative; display: block; width: 100%; }
.mh-app .mh-selwrap > select { width: 100%; background-image: none !important; }
.mh-app .mh-selwrap > .selchev {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  width: 14px; height: 14px; color: var(--mh-ctrl-ico); pointer-events: none;
  display: grid; place-items: center;
  transition: transform .2s cubic-bezier(.2,.7,.25,1);
}
.mh-app .mh-selwrap > .selchev svg { width: 100%; height: 100%; display: block; }
.mh-app .mh-selwrap:has(> select:open) > .selchev { transform: translateY(-50%) rotate(180deg); }
/* inline variant for toolbar/compact selects that must keep their natural (auto) width -
   a full-width block wrapper would blow those out of a flex row. */
.mh-app .mh-selwrap.is-inline { display: inline-block; width: auto; vertical-align: middle; }
.mh-app .mh-selwrap.is-inline > select { width: auto; }

/* ============================================================================
   KICKOFF 20: the shared MhDatePicker TRIGGER (.dp-field) matches the standard
   control box. When the picker landed, its mock chrome (58px tall, white fill,
   1.5px hard border, 14px radius, 17px bold value, 22px accent icon, 4px ring)
   leaked into every date field. This maps the trigger to the same --mh-ctrl-*
   layer every other input/select uses: padding-driven height, translucent sage
   fill, invisible rest border, --mh-ctrl-r radius, 14px/500 value, a subtle muted
   calendar glyph + small caret, and the 3px brand focus ring. Light + dark come
   free from the theme tokens. The picker POPOVER + MhDatePicker.razor LOGIC are
   NOT touched (frozen) - this only restyles the trigger box. Specificity here is
   .mh-app .dp-field (low), so the higher-specificity per-context fixes that
   already match their local inputs (.ad-dp admin pill, .ob-dp onboard) keep their
   look; this only replaces the leaked BASE everywhere else. App-wide, one source. */
.mh-app .dp-field {
  height: auto; box-sizing: border-box; gap: 9px; padding: 12px 14px;
  background: var(--mh-ctrl-fill); border: 1px solid transparent;
  border-radius: var(--mh-ctrl-r); color: var(--mh-ink);
}
.mh-app .dp-field:hover { border-color: var(--mh-ctrl-focus-border); }
.mh-app .dp.open .dp-field {
  background: var(--mh-surface); border-color: var(--mh-ctrl-focus-border);
  box-shadow: var(--mh-ctrl-focus-ring);
}
.mh-app .dp-field .dpf-ico { width: 16px; height: 16px; color: var(--mh-ctrl-ico); }
.mh-app .dp-field .dpf-val { font-size: 14px; font-weight: 500; color: var(--mh-ink); }
.mh-app .dp-field .dpf-val.empty { color: var(--mh-ctrl-ico); font-weight: 500; }
.mh-app .dp-field .dpf-chev { width: 14px; height: 14px; color: var(--mh-ctrl-ico); }

/* Checkbox - 20px sage pill, white check on accent when checked */
.mh-app input[type=checkbox] {
  appearance: none; -webkit-appearance: none; margin: 0; flex: none; cursor: pointer;
  width: 20px; height: 20px; border-radius: var(--mh-r-pill); border: 1px solid transparent;
  background-color: var(--mh-ctrl-fill-2); background-repeat: no-repeat; background-position: center;
  transition: background-color .16s ease, box-shadow .16s ease;
}
.mh-app input[type=checkbox]:checked { background-color: var(--mh-ctrl-accent); background-image: var(--mh-ctrl-check); }
.mh-app input[type=checkbox]:focus-visible { outline: none; box-shadow: var(--mh-ctrl-focus-ring); }
/* Radio - sage circle, sage dot when checked */
.mh-app input[type=radio] {
  appearance: none; -webkit-appearance: none; margin: 0; flex: none; cursor: pointer;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1.5px solid var(--mh-ctrl-border); background: var(--mh-ctrl-fill);
  transition: border-color .16s ease, background .16s ease, box-shadow .16s ease;
}
.mh-app input[type=radio]:checked {
  border-color: var(--mh-ctrl-accent); background-color: var(--mh-surface);
  background-image: radial-gradient(circle at center, var(--mh-ctrl-accent) 0 4.5px, transparent 5.5px);
}
.mh-app input[type=radio]:focus-visible { outline: none; box-shadow: var(--mh-ctrl-focus-ring); }
/* Universal states */
.mh-app :is(input, select, textarea):disabled { opacity: .5; filter: grayscale(.45); pointer-events: none; }
.mh-app :is(input, select, textarea).is-error { outline: 2px solid var(--mh-danger); outline-offset: 2px; border-color: transparent; box-shadow: none; }
.mh-app .err-text { font-size: 12px; line-height: 1.4; color: var(--mh-danger); margin-top: 7px; display: flex; align-items: center; gap: 5px; font-weight: 600; }
.mh-app .err-text svg { width: 13px; height: 13px; flex: none; }
.mh-app .lock-note { font-size: 11.5px; color: var(--mh-muted); margin-top: 7px; display: flex; align-items: center; gap: 5px; }
.mh-app .lock-note svg { width: 12px; height: 12px; flex: none; }

/* ============ ICON RAIL (pine, icon-over-label; Zoom Workplace style) ============ */
.mh-app .sidebar { background: linear-gradient(180deg, var(--mh-sidebar) 0%, var(--mh-sidebar-2) 100%); color:#c9d3d6; display:flex; flex-direction:column; }
.mh-app .sidebar.zr { width:86px; min-width:86px; padding:14px 0 10px; align-items:center; gap:8px; overflow:visible; position:sticky; top:0; height:calc(100 * var(--mh-vh)); }
.mh-app .sidebar.zr .zr-brand { flex:none; }
.mh-app .sidebar.zr .zr-logo { width:50px; height:auto; display:block; filter:drop-shadow(0 4px 10px rgba(0,0,0,.3)); }
.mh-app .sidebar.zr .zr-nav { flex:1; width:100%; display:flex; flex-direction:column; align-items:center; gap:3px; padding:8px 0; overflow-y:auto; overflow-x:visible; scrollbar-width:none; min-height:0; }
.mh-app .sidebar.zr .zr-nav::-webkit-scrollbar { display:none; }
.mh-app .sidebar.zr .zr-item { position:relative; width:70px; padding:9px 4px 8px; border:none; background:none; border-radius:16px; overflow:hidden; display:flex; flex-direction:column; align-items:center; gap:5px; color:#bcc8c5; cursor:pointer; font-family:inherit; transition:background .18s, color .18s, transform .18s; text-decoration:none; }
.mh-app .sidebar.zr .zr-item:hover { background:rgba(255,255,255,.08); color:#fff; }
.mh-app .sidebar.zr .zr-item:hover .zr-ic { transform:translateY(-1px); }
.mh-app .sidebar.zr .zr-ic { width:26px; height:26px; display:grid; place-items:center; transition:transform .18s; }
.mh-app .sidebar.zr .zr-ic svg { width:24px; height:24px; }
/* UPPERCASE RAIL LABELS (CEO, Jul 29 2026) - and the rail must NOT grow to take them.
   The item is 70px wide with 4px gutters = 62px of usable label width. Measured uppercase in
   the real font at this size: PROGRAM 51.4 / SERVICES 49.0 / REPORTS 45.8 / CLIENTS 42.1 /
   TEAMS 35.1 / ADMIN 34.0 / HOME 30.8 - every one comfortably inside 62px, so the size is
   UNCHANGED and the 86px rail is untouched. */
.mh-app .sidebar.zr .zr-lb { font-size:10.5px; font-weight:700; letter-spacing:.02em; line-height:1;
  text-transform:uppercase; white-space:nowrap; }
/* (The temporary [data-section="people"] .zr-lb font-size override lived here. It existed
   only because "VOLUNTEERS" was the single uppercase label wider than the 62px label box.
   The Volunteers tab was removed on Jul 29 2026 - Volunteers is a card on the Services hub
   now - so the override went with it. Every remaining label fits at the standard 10.5px:
   PROGRAM 52, SERVICES 49, PLANNER 47, REPORTS 46, CLIENTS 42, TEAMS 35, ADMIN 34, HOME 31. */
/* Reports glyph: rotated a quarter-turn anticlockwise (CEO Jul 29) so its ruled bars stand
   up as columns and the mark reads as a chart. Rotation lives on the SVG, not on .zr-ic -
   .zr-ic owns the zrPop scale animation for the active item and the two would overwrite
   each other on the same property. */
.mh-app .sidebar.zr .zr-item[data-section="reports"] .zr-ic svg { transform:rotate(-90deg); }
.mh-app .sidebar.zr .zr-item.on { background:#F1F4F7; color:#2E4A43; box-shadow:0 6px 16px rgba(0,0,0,.18); }
.mh-app .sidebar.zr .zr-item.on .zr-ic { animation:zrPop .34s cubic-bezier(.34,1.45,.5,1); }
.mh-app .sidebar.zr .zr-foot { flex:none; width:100%; display:flex; justify-content:center; padding-top:8px; border-top:1px solid rgba(255,255,255,.1); }
.mh-app .sidebar.zr .zr-lock { position:absolute; top:6px; right:10px; width:13px; height:13px; border-radius:4px; background:rgba(216,155,61,.9); box-shadow:0 0 0 2px rgba(33,58,51,.5); }
.mh-app .sidebar.zr .zr-lock::after { content:""; position:absolute; inset:3px 3px auto 3px; height:4px; border:1.4px solid #2E4A43; border-bottom:none; border-radius:3px 3px 0 0; }
/* KICKOFF 26: Teams unread red dot. Anchored to the icon (.zr-ic position:relative) and
   absolutely positioned, so it sits ON the icon's top-right edge with ZERO layout shift -
   the icon and label never move a pixel. The ring matches the surface under it (pine rail
   when idle, cream pill when the Teams item is active) so it stays crisp in both themes. */
.mh-app .sidebar.zr .zr-ic { position:relative; overflow:visible; }
.mh-app .sidebar.zr .zr-dot { position:absolute; top:-2px; right:-2px; width:9px; height:9px; border-radius:50%; background:#E5484D; box-shadow:0 0 0 2px var(--mh-sidebar); pointer-events:none; }
.mh-app .sidebar.zr .zr-item.on .zr-dot { box-shadow:0 0 0 2px #F1F4F7; }
@keyframes zrPop { 0%{ transform:scale(.78); } 55%{ transform:scale(1.12); } 100%{ transform:scale(1); } }

/* ============ MAIN ============ */
.mh-app .main { display: flex; flex-direction: column; min-width: 0; }

.mh-app .topbar {
  height: 70px; flex: none; display: flex; align-items: center; gap: 18px;
  padding: 0 30px; background: rgba(255,255,255,.72); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--mh-line); position: sticky; top: 0; z-index: 20;
}
.mh-app .topbar .ttl { font-size: 21px; font-weight: 600; font-family: var(--mh-font-head); letter-spacing: -.4px; }
.mh-app .topbar .crumb { font-size: 12.5px; color: var(--mh-muted); margin-top: 1px; }
/* =============================================================================
   FILLED SOFT - shared search component (FS1-FIX). ONE rule group for every search
   box so the topbar search (.search), the Clients-list search (.mh-srch) and future
   searches (.kp-search etc.) are visually IDENTICAL in height, padding, radius, icon
   and focus treatment. Only width differs by context, deliberately. The inner-input
   :focus override cancels the shared base-layer :focus ring (which otherwise leaks a
   second ring + white fill onto the inner input), so only the wrapper's single tight
   FS ring shows - no ballooning halo.
   ============================================================================= */
.mh-app .search, .mh-app .mh-srch {
  display: flex; align-items: center; gap: 10px;
  background: var(--mh-ctrl-fill); border: 1px solid transparent; border-radius: var(--mh-r-pill);
  padding: 10px 16px; color: var(--mh-ctrl-ico); font-size: 14px;
  transition: background .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.mh-app .search { margin: 0 auto; position: relative; width: min(440px, calc(36 * var(--mh-vw))); cursor: text; }   /* topbar: wider + popup anchor */
.mh-app .mh-srch { width: 252px; max-width: calc(42 * var(--mh-vw)); }                                              /* list filter: narrower, deliberate */
.mh-app .search:focus-within, .mh-app .mh-srch:focus-within {
  background: var(--mh-surface); border-color: var(--mh-ctrl-focus-border); box-shadow: var(--mh-ctrl-focus-ring);
}
.mh-app .search svg, .mh-app .mh-srch svg { width: 16px; height: 16px; flex: none; color: var(--mh-ctrl-ico); stroke-width: 2; }
.mh-app .search input, .mh-app .mh-srch input {
  flex: 1; min-width: 0; border: none; background: none; outline: none; padding: 0;
  font-family: inherit; font-size: 14px; font-weight: 500; color: var(--mh-ink);
}
.mh-app .search input:focus, .mh-app .mh-srch input:focus { background: none; border: none; box-shadow: none; }
.mh-app .search input::placeholder, .mh-app .mh-srch input::placeholder { color: var(--mh-ctrl-ico); opacity: .6; }
/* FS clear (x) button - matches DESIGN's .clear pattern, same icon size everywhere */
.mh-app .search .clear, .mh-app .mh-srch .clear { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; cursor: pointer; flex: none; border: none; background: none; padding: 0; }
.mh-app .search .clear svg, .mh-app .mh-srch .clear svg { width: 13px; height: 13px; color: var(--mh-ctrl-ico); opacity: .6; }
.mh-app .search .clear:hover svg, .mh-app .mh-srch .clear:hover svg { opacity: 1; }
.mh-app .search-pop { position: absolute; top: calc(100% + 8px); left: 0; right: 0; background: var(--mh-surface); border-radius: 16px; box-shadow: 0 24px 60px rgba(33,58,51,.18); padding: 8px; display: none; z-index: 90; max-height: 380px; overflow-y: auto; cursor: default; }
.mh-app .search-pop.on { display: block; }
/* =============================================================================
   DESIGN ASSET - "Inset Cool Field" search bar (Phase 2). Landed BYTE-EXACT from
   _handoff/Search Bars/inset-cool-field/Searchbar-inset-cool-field.html: DESIGN's own
   palette, NOT re-tinted to brand tokens. The asset's own vars (--ink-3 #6B7269,
   --r-pill 999px, --ease, --font-sans Hanken Grotesk) are inlined as literals because
   the app does not define them. .bigbar is the shared base; .b14 the recessed cool
   fill that lifts to white on focus. GLOBAL variant carries the MH logo, TAB variant a
   search icon. This is the canonical search component for every tab going forward.
   ============================================================================= */
.mh-app .bigbar { width: 100%; max-width: 600px; margin: 0 auto; display: flex; align-items: center; gap: 18px; height: 62px; padding: 0 26px; border-radius: 999px; transition: box-shadow .2s cubic-bezier(.2,.7,.25,1), border-color .2s cubic-bezier(.2,.7,.25,1), background .2s cubic-bezier(.2,.7,.25,1); }
.mh-app .bigbar.b14 { background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); }
.mh-app .bigbar.b14:focus-within { background: #fff; border-color: rgba(40,60,80,.16); box-shadow: 0 10px 28px rgba(40,60,80,.12); }
.mh-app .bigbar .mh { width: 30px; height: 30px; flex: none; object-fit: contain; }
.mh-app .bigbar .search-ic { width: 22px; height: 22px; flex: none; display: grid; place-items: center; color: #6B7269; }
.mh-app .bigbar .search-ic svg { width: 21px; height: 21px; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.mh-app .bigbar .divider { width: 1px; height: 30px; background: rgba(40,60,80,.16); flex: none; }
.mh-app .bigbar input { flex: 1; border: none; background: none; outline: none; font-family: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, sans-serif; font-size: 17px; font-weight: 500; color: #1C2733; min-width: 0; }
.mh-app .bigbar input:focus { background: none; border: none; box-shadow: none; }
.mh-app .bigbar input::placeholder { color: #9AA7B3; font-weight: 400; }
/* Phase 3 Add-on B - geometry + placement only (NOT skin). The DESIGN look stays from
   .bigbar.b14 above (cool fill, lift-to-white focus, pill radius, inset/focus shadows,
   logo/icon, divider, placeholder); only SIZE and POSITION are restored to the previous
   footprint, read from the preserved .search / .mh-srch rules earlier in this file
   (global min(440px,36vw); per-tab 252px / max 42vw; padding 10/16; font 14; icon 16).
   Global bar stays centered in the topbar and anchors the typeahead popup; the per-tab
   bar is right-aligned next to the All-countries filter. */
/* In-flow flex placement (fixes the laptop overlap): the global search is a flex child
   that sits in the middle gap between the title and the right action cluster, capped at
   440px and centered via auto margins. It shrinks with the viewport down to nothing and
   the icon cluster (Planner / Dark / Notifications / New / user) stays pinned at the right,
   so the search resizes in place and can NEVER overlap or shift the icons. (Was absolutely
   centered with a 100vw-1108px width that collided with the icons on narrow laptops.) */
.mh-app .gsearch { flex: 0 1 440px; min-width: 0; margin: 0 auto; position: relative; }
.mh-app .topbar #plannerBtn { margin-left: 0; }
.mh-app .gsearch .bigbar { height: 42px; padding: 0 16px; gap: 12px; max-width: none; }
.mh-app .gsearch .bigbar .mh { width: 22px; height: 22px; }
.mh-app .gsearch .bigbar .divider { height: 22px; }
.mh-app .gsearch .bigbar input { font-size: 14px; }
.mh-app .cl-srchbar { flex: none; width: 252px; max-width: calc(42 * var(--mh-vw)); height: 40px; padding: 0 16px; gap: 10px; margin: 0 0 0 auto; }
.mh-app .cl-srchbar .search-ic { width: 18px; height: 18px; }
.mh-app .cl-srchbar .search-ic svg { width: 17px; height: 17px; }
.mh-app .cl-srchbar .divider { height: 20px; }
.mh-app .cl-srchbar input { font-size: 14px; }
/* Dark-mode treatment for BOTH DESIGN search bars (global topbar .bigbar.b14 and the
   per-tab .cl-srchbar) - they were landed fixed-light. Scoped body.dark override, light
   look untouched. Reuses the app's real dark tokens and mirrors the established
   .search/.mh-srch dark field treatment (recessed fill at rest, lift to the dark surface
   + pine focus ring on focus, NOT white). */
body.dark .mh-app .bigbar.b14 { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app .bigbar.b14:focus-within { background: var(--mh-surface); border-color: var(--mh-ctrl-focus-border); box-shadow: var(--mh-ctrl-focus-ring); }
body.dark .mh-app .bigbar input { color: var(--mh-ink); }
body.dark .mh-app .bigbar input::placeholder { color: var(--mh-ctrl-ico); }
body.dark .mh-app .bigbar .search-ic { color: var(--mh-ctrl-ico); }
body.dark .mh-app .bigbar .divider { background: var(--mh-ctrl-border); }
/* global-search typeahead result rows (the mock left #searchPop unwired; these
   scoped sp- classes render the live sp_SearchGlobal results in-theme) */
.mh-app .sp-group { font-size: 10.5px; letter-spacing: .7px; text-transform: uppercase; color: var(--mh-muted); font-weight: 800; padding: 9px 10px 5px; }
.mh-app .sp-item { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 11px; cursor: pointer; }
.mh-app .sp-item:hover, .mh-app .sp-item.on { background: var(--mh-cream-2); }
.mh-app .sp-ic { width: 30px; height: 30px; border-radius: 9px; flex: none; display: grid; place-items: center; background: rgba(78,124,114,.12); color: var(--mh-green-d); }
.mh-app .sp-ic svg { width: 16px; height: 16px; }
.mh-app .sp-body { flex: 1; min-width: 0; }
.mh-app .sp-ttl { font-size: 13.5px; font-weight: 700; color: var(--mh-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mh-app .sp-sub { font-size: 11.5px; color: var(--mh-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mh-app .sp-code { font-family: var(--mono); font-size: 11px; font-weight: 700; color: var(--mh-muted); font-variant-numeric: tabular-nums; white-space: nowrap; margin-left: auto; }
.mh-app .sp-empty { padding: 22px; text-align: center; color: var(--mh-muted); font-size: 13px; }
.mh-app .icon-btn {
  width: 42px; height: 42px; flex: none; border-radius: 13px; border: 1px solid rgba(78,124,114,.32); background: var(--mh-surface);
  display: grid; place-items: center; cursor: pointer; position: relative; color: var(--mh-slate); transition: background .15s, border-color .15s;
}
.mh-app .icon-btn:hover { background: var(--mh-cream-2); border-color: var(--mh-green); }
/* The mock leaves these inline SVGs un-sized and lets the browser default size them;
   under the .mh-app grid scope they collapse to 0x0, so size them explicitly. Sized to
   26px so the planner + dark-toggle icons match the bell (P1-2): all three topbar
   icon-btns now present an identical 26px glyph. The id-specific #bellBtn svg rule
   (also 26px) still governs the bell. */
.mh-app .icon-btn svg { width: 26px; height: 26px; }
.mh-app .icon-btn .badge { position: absolute; top: 8px; right: 9px; width: 8px; height: 8px; border-radius: 50%; background: var(--mh-clay); border: 2px solid var(--mh-surface); }

/* topbar utility button colours (planner + dark toggle in pine) */
.mh-app #plannerBtn, .mh-app #darkBtn { color: var(--mh-sidebar); }

/* animated notification bell + its menu (MH_notify pushes into this) */
.mh-app .bell-wrap { position: relative; }
.mh-app #bellBtn svg { width: 26px; height: 26px; }
.mh-app #bellBtn #bellIcoLive { display: none; }
.mh-app #bellBtn.unread #bellIcoLive { display: block; }
.mh-app #bellBtn.unread #bellIcoStill { display: none; }
.mh-app #bellBtn .badge { display: none; }
/* Badge visibility is gated on UNSEEN items (has-unseen), DECOUPLED from the shake (.unread):
   after the bell is opened the ring stops but the badge stays at the unseen count, counting
   down only as individual items are clicked. */
.mh-app #bellBtn.has-unseen .badge { display: flex; align-items: center; justify-content: center; position: absolute; top: -5px; right: -5px; width: auto; min-width: 18px; height: 18px; padding: 0 5px; border: none; border-radius: 999px; background: #E0483C; color: #fff; font-size: 10px; font-weight: 800; line-height: 1; text-align: center; box-shadow: 0 0 0 2px var(--mh-surface); z-index: 3; }
/* FB-11 rev3 (FINAL): the panel sizes to its WIDEST child (width: max-content), and
   the tab row is an UNCAPPED child, so the panel automatically widens to whatever the
   five tabs plus their badges need at ANY magnitude - single, double, or triple digit.
   There is deliberately NO max-width on the panel: a panel cap would cap the tab row
   and reintroduce the clip. Only the notification TEXT is capped (.bm-ttl/.bm-sub
   never sprawl - see .bm-feed) and the panel is >= every child's max-content width; the
   nowrap tab row is the widest such child and is uncapped, so the panel is always at
   least as wide as the tab row's natural width, at any badge width - by construction,
   not by measured pixels. min-width is a modest readable minimum for the empty state (in
   which the tabs sit centered); the tab row itself is the real driver above that. */
.mh-app .bell-menu { position: absolute; right: 0; top: 52px; width: max-content; min-width: 336px; background: var(--mh-surface); border-radius: 16px; box-shadow: var(--mh-shadow-lg); z-index: 130; overflow: hidden; display: none; }
.mh-app .bell-menu.on { display: block; }

/* FB-11 rev2: caret arrow anchoring the panel to the bell. Drawn on .bell-wrap (not
   the panel, which is overflow:hidden) so it is never clipped; shown only while the
   panel is open. Surface-coloured with a hairline, adapts in dark mode. */
.mh-app .bell-wrap:has(.bell-menu.on)::after { content: ""; position: absolute; top: 45px; right: 13px; z-index: 131; width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 8px solid var(--mh-surface); filter: drop-shadow(0 -1px 0 var(--mh-line)); pointer-events: none; }
.mh-app .bm-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--mh-line); }
.mh-app .bm-head h4 { font-size: 15px; }
.mh-app .bm-head .lnk { font-size: 12.5px; color: var(--mh-green); font-weight: 700; cursor: pointer; }
/* FB-11 rev3/rev4: single line, nowrap, UNCAPPED - the panel's ONLY width driver.
   Its natural max-content flows up to the max-content panel, so the panel always fits
   it and nowrap can never clip, at any badge magnitude. No width/max-width here.
   rev4: justify-content center so in the compact (empty / min-width) state the tabs sit
   centered; once badges widen the row to the panel width it fills and reads left-anchored. */
.mh-app .bm-tabs { display: flex; flex-wrap: nowrap; justify-content: center; gap: 5px; padding: 9px 12px; border-bottom: 1px solid var(--mh-line); }
.mh-app .bm-tab { border: none; background: var(--mh-cream-2); font-family: inherit; font-size: 11.5px; font-weight: 700; color: var(--mh-muted); padding: 5px 10px; border-radius: 999px; cursor: pointer; transition: .13s; display: inline-flex; align-items: center; gap: 5px; }
.mh-app .bm-tab:hover { color: var(--mh-ink); }
.mh-app .bm-tab.on { background: var(--mh-green); color: #fff; }
/* P4: per-tab unread count badge - matches the bell badge language; hidden at zero. */
.mh-app .bm-tabcount { display: none; }
.mh-app .bm-tabcount.on { display: inline-flex; align-items: center; justify-content: center; min-width: 15px; height: 15px; padding: 0 4px; border-radius: 999px; background: #E0483C; color: #fff; font-size: 9.5px; font-weight: 800; line-height: 1; }
.mh-app .bm-tab.on .bm-tabcount.on { background: #fff; color: var(--mh-green); }
/* FB-11 rev4: the feed is made STRUCTURALLY incapable of driving the panel width, which
   fixes the tab-click resize glitch (feeds differ per tab, incl. the empty state, so a
   width-driving feed made the panel jump on every tab switch). width:0 gives the feed a
   zero preferred size, so it contributes nothing to the panel's max-content; min-width:100%
   makes it fill whatever width the TAB ROW defines. Its content therefore always wraps to
   the panel width and can never expand it. Panel width now depends ONLY on the tab row. */
.mh-app .bm-feed { max-height: 380px; overflow-y: auto; width: 0; min-width: 100%; }
.mh-app .bm-item { display: flex; gap: 11px; padding: 12px 16px; border-bottom: 1px solid var(--mh-line); cursor: pointer; }
.mh-app .bm-item:last-child { border-bottom: none; }   /* tidy bottom (the "Synced from..." footer was removed) */
.mh-app .bm-item:hover { background: var(--mh-cream-2); }
.mh-app .bm-item.read { opacity: .5; }
.mh-app .bm-body { flex: 1; min-width: 0; }
/* FB-11 rev4: no text width cap needed anymore - the feed can no longer drive the panel
   width (see .bm-feed), so long messages simply wrap to the panel width. overflow-wrap
   still breaks any single over-long token so it can never force horizontal overflow. */
.mh-app .bm-ttl { font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.mh-app .bm-sub { font-size: 12px; color: var(--mh-muted); overflow-wrap: anywhere; }
.mh-app .bm-tag { display: inline-block; margin-top: 4px; font-size: 9px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 1px 7px; border-radius: 999px; }
.mh-app .bm-tag.bm-clients { background: rgba(78,124,114,.15); color: var(--mh-green-d); }
.mh-app .bm-tag.bm-programs { background: rgba(94,122,131,.16); color: var(--mh-slate); }
.mh-app .bm-tag.bm-planner { background: rgba(216,155,61,.18); color: var(--mh-warning-d); }
.mh-app .bm-tag.bm-personal { background: rgba(201,123,90,.16); color: var(--mh-clay-d); }
.mh-app .bm-right { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; margin-left: auto; }
.mh-app .bm-time { font-size: 11px; color: var(--mh-muted); white-space: nowrap; }
.mh-app .bm-empty { padding: 26px; text-align: center; color: var(--mh-muted); font-size: 13px; }

/* Option B: brand-glyph tile, mirrors the Upcoming Reminders. A NEUTRAL light tile in
   light mode (the two-tone MhBrandIcon carries its own colour) and the SAME clean light
   chip the reminders use in dark mode (rgba(234,239,237,.94)) so the baked glyphs read
   crisp and the bell matches the reminders in BOTH themes. Sized for the denser bell row. */
.mh-app .bm-ic { width: 30px; height: 30px; border-radius: 9px; flex: none; margin-top: 1px; display: grid; place-items: center; background: rgba(73,102,112,.10); }
.mh-app .bm-ic svg { width: 17px; height: 17px; }
body.dark .mh-app .bm-ic { background: rgba(234,239,237,.94); }
/* N1: compact due-countdown chip on a reminder row */
.mh-app .bm-due { font-size: 10px; font-weight: 800; letter-spacing: .02em; padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.mh-app .bm-due.ok   { background: rgba(78,124,114,.15); color: var(--mh-green-d); }
.mh-app .bm-due.warn { background: rgba(216,155,61,.18); color: var(--mh-warning-d); }
.mh-app .bm-due.bad  { background: rgba(224,72,60,.16);  color: #E0483C; }

/* +New contextual button + fan-out menu (the single top-right create slot) */
.mh-app .top-action-wrap { position: relative; }
.mh-app .top-menu { position: absolute; right: 0; top: 52px; width: 236px; background: var(--mh-surface); border-radius: 16px; box-shadow: var(--mh-shadow-lg); z-index: 140; overflow: hidden; display: none; padding: 7px; }
.mh-app .top-menu.on { display: block; animation: fadeDown .15s ease; }
.mh-app .tm-head { font-size: 10.5px; letter-spacing: .7px; text-transform: uppercase; color: var(--mh-muted); font-weight: 700; padding: 6px 10px 8px; }
.mh-app .tm-item { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 11px; cursor: pointer; font-size: 13.5px; font-weight: 600; color: var(--mh-ink); }
.mh-app .tm-item:hover { background: var(--mh-cream-2); }
.mh-app .tm-item .tm-ic { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex: none; color: #fff; }
.mh-app .tm-item .tm-ic svg { width: 16px; height: 16px; }
@keyframes fadeDown { from { opacity: 0; transform: translateY(-7px); } to { opacity: 1; transform: none; } }

/* profile chip + dropdown */
.mh-app .tb-user-wrap { position: relative; flex: none; }
.mh-app .tb-user { display: flex; align-items: center; gap: 10px; padding: 5px 12px 5px 5px; border: 1px solid rgba(78,124,114,.32); border-radius: 999px; background: var(--mh-surface); cursor: pointer; transition: .15s; flex: none; }
.mh-app .tb-user:hover { border-color: var(--mh-green); background: var(--mh-cream-2); }
.mh-app .tb-user .tb-av { width: 34px; height: 34px; border-radius: 50%; background: linear-gradient(145deg,#4E7C72,#2E4A43); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 13px; flex: none; }
.mh-app .tb-user .tb-nm { font-size: 13px; font-weight: 700; color: var(--mh-ink); white-space: nowrap; line-height: 1.15; }
.mh-app .tb-user .tb-rl { font-size: 11px; color: var(--mh-muted); white-space: nowrap; line-height: 1.15; }
.mh-app .tb-chev { width: 14px; height: 14px; color: var(--mh-muted); margin-left: 2px; transition: transform .2s cubic-bezier(.2,.7,.25,1); }
/* rotate the account-menu caret when its menu is open (same 180deg flip as every combo) */
.mh-app .tb-user-wrap:has(.tb-menu.on) .tb-chev { transform: rotate(180deg); }
.mh-app .tb-menu { position: absolute; top: calc(100% + 10px); right: 0; width: 248px; background: var(--mh-surface); border-radius: 16px; box-shadow: 0 24px 60px rgba(33,58,51,.18); padding: 8px; display: none; z-index: 95; }
.mh-app .tb-menu.on { display: block; animation: fadeDown .16s ease; }
.mh-app .tbm-head { display: flex; align-items: center; gap: 10px; padding: 10px 10px 12px; border-bottom: 1px solid var(--mh-line); margin-bottom: 6px; }
.mh-app .tbm-head .tb-av { width: 38px; height: 38px; border-radius: 50%; background: linear-gradient(145deg,#4E7C72,#2E4A43); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 13.5px; flex: none; }
/* The text block must be allowed to shrink (min-width:0) so a long name/email
   truncates with an ellipsis inside the menu instead of spilling past its right edge. */
.mh-app .tbm-head > div { min-width: 0; flex: 1 1 auto; }
.mh-app .tbm-nm { font-size: 13.5px; font-weight: 800; color: var(--mh-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mh-app .tbm-sub { font-size: 11px; color: var(--mh-muted); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mh-app .tbm-item { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 10px; cursor: pointer; font-size: 13px; font-weight: 700; color: var(--mh-ink); text-decoration: none; }
.mh-app .tbm-item svg { width: 16px; height: 16px; color: var(--mh-muted); }
.mh-app .tbm-item:hover { background: var(--mh-cream-2); }
.mh-app .tbm-item.danger { color: var(--mh-danger); }
.mh-app .tbm-item.danger svg { color: var(--mh-danger); }
.mh-app .tbm-div { height: 1px; background: var(--mh-line); margin: 6px 4px; }

/* Transparent catcher that closes Blazor-driven menus on an outside click.
   z-index MUST sit below the topbar's stacking context (.topbar is position:sticky
   z-index:20, which traps its descendant menus at that level). At z-index 85 the
   backdrop painted ABOVE the whole topbar subtree and swallowed real clicks on the
   user/+New menu items (P1-1 defect). Sitting at 15 keeps it above page content
   (static, z-index auto) so outside-click still closes, while the topbar menus
   paint above it and stay clickable. */
.mh-app .menu-backdrop { position: fixed; inset: 0; z-index: 15; background: transparent; border: none; padding: 0; margin: 0; cursor: default; }

.mh-app .btn {
  font-family: var(--mh-font-body); font-weight: 700; font-size: 14px; border: none; cursor: pointer;
  border-radius: var(--mh-r-btn); padding: 0 18px; height: 44px; display: inline-flex; align-items: center; gap: 8px;
  transition: background .15s, transform .06s, box-shadow .15s; white-space: nowrap; text-decoration: none;
}
.mh-app .btn svg { width: 17px; height: 17px; }
.mh-app .btn--primary { background: var(--mh-green); color: #fff; box-shadow: 0 8px 18px rgba(78,124,114,.28); }
.mh-app .btn--primary:hover { background: var(--mh-green-d); box-shadow: 0 10px 22px rgba(78,124,114,.34); }
.mh-app .btn--clay { background: var(--mh-clay); color: #fff; box-shadow: 0 8px 18px rgba(201,123,90,.3); }
.mh-app .btn--clay:hover { background: var(--mh-clay-d); }
.mh-app .btn--ghost { background: var(--mh-surface); color: var(--mh-ink); border: 1.5px solid var(--mh-line); }
.mh-app .btn--ghost:hover { background: var(--mh-cream-2); border-color: #C3CCC9; }
.mh-app .btn:active { transform: translateY(1px); }

/* ===== The shared "+ New / create" button (#topAction) - the ONE New-wizard launcher on
   every page (Dashboard "+ New", Clients "Add Client", Program "New Program / Enroll",
   Housing Subsidy "New Subsidy", Planner "New Event"...). Redesigned to the + Widgets pill
   language: the animated Matthew House brand gradient, fully-round corners, sized (42px) to
   match the topbar's icon buttons. Only THIS button changes - wizard Save/Done/Enroll
   primaries keep the flat green. ===== */
.mh-app #topAction {
  height: 42px; border-radius: 999px; padding: 0 20px; border: none; color: #fff;
  background: linear-gradient(120deg, #2E4A43 0%, var(--mh-green) 50%, #2E4A43 100%);
  background-size: 220% 100%; background-position: 0% 50%;
  animation: wg-brandshift 120s ease-in-out infinite;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--mh-green) 30%, transparent);
  transition: filter .15s, box-shadow .15s, transform .06s;
}
.mh-app #topAction:hover { filter: brightness(1.06); box-shadow: 0 9px 22px color-mix(in srgb, var(--mh-green) 40%, transparent); }
.mh-app #topAction:active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) { .mh-app #topAction { animation: none; } }

/* Dashboard-only: the + New pill sits inside the SAME "Inset Cool Field" ring as + Widgets
   (cool fill + hairline + inset shadow). The inner gradient pill shrinks so the ring's total
   height still matches the topbar's icon buttons. */
.mh-app .top-action-wrap.taw-ring { display: inline-flex; align-items: center; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: 999px; padding: 4px; }
.mh-app .top-action-wrap.taw-ring #topAction { height: 32px; padding: 0 16px; box-shadow: none; }
.mh-app .top-action-wrap.taw-ring #topAction:hover { box-shadow: none; }
body.dark .mh-app .top-action-wrap.taw-ring { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }

.mh-app .content { padding: 28px 30px 40px; overflow: auto; flex: 1; min-height: 0; }

/* greeting */
.mh-app .greet-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 22px; flex-wrap: wrap; padding: 0 26px; }
/* Inset the greeting + period filter by the frosted-sage frame padding (.mh-fs is
   padding:26px) so the greeting lines up with the KPI cards' LEFT edge and the filter
   with their RIGHT edge. Filter outline (border) removed per design. */
.mh-app .greet-row .seg { border-color: transparent; }
.mh-app .greet h1 { font-size: 30px; }
.mh-app .greet p { color: var(--mh-muted); font-size: 14.5px; margin: 6px 0 0; }
.mh-app .seg { display: inline-flex; background: var(--mh-surface); border: 1px solid var(--mh-line); border-radius: var(--mh-r-pill); padding: 4px; box-shadow: var(--mh-shadow-sm); }
.mh-app .seg button { border: none; background: none; cursor: pointer; font-family: var(--mh-font-body); font-weight: 600; font-size: 13px; color: var(--mh-muted); padding: 7px 16px; border-radius: 999px; transition: .15s; }
.mh-app .seg button.on { background: var(--mh-slate); color: #fff; }

/* KPI cards */
.mh-app .kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 22px; }
.mh-app .kpi {
  position: relative; overflow: hidden; background: var(--mh-surface);
  border-radius: var(--mh-r-card); padding: 20px 20px 18px; box-shadow: var(--mh-shadow-sm); transition: transform .18s, box-shadow .18s;
}
.mh-app .kpi:hover { transform: translateY(-3px); box-shadow: var(--mh-shadow); }
.mh-app .kpi .top { display: flex; align-items: center; gap: 11px; }
.mh-app .kpi .ico { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; color: #fff; flex: none; }
.mh-app .kpi .ico svg { width: 21px; height: 21px; }
.mh-app .kpi .delta { margin-left: auto; font-size: 12px; font-weight: 700; padding: 3px 9px; border-radius: 999px; display: inline-flex; align-items: center; gap: 3px; }
.mh-app .delta.up { color: var(--mh-green-d); background: rgba(78,124,114,.13); }
.mh-app .delta.flat { color: var(--mh-muted); background: rgba(138,139,131,.13); }
.mh-app .delta.ok { color: var(--mh-warning-d); background: rgba(216,155,61,.16); }
.mh-app .kpi .num { font-family: var(--mh-font-head); font-size: 38px; font-weight: 600; line-height: 1; margin-top: 16px; }
.mh-app .kpi .lbl { font-size: 13px; color: var(--mh-muted); margin-top: 5px; }

/* KPI click-to-select + corner arrow (mh-dashboard.html lines 879-891) */
.mh-app .kpi { cursor: pointer; }
.mh-app .kpi .kpi-arrow { margin-left: 8px; width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid var(--mh-line); background: var(--mh-surface); color: var(--mh-ink); display: grid; place-items: center; cursor: pointer; flex: none; transition: .18s; padding: 0; }
.mh-app .kpi .kpi-arrow:hover { border-color: var(--mh-green); color: var(--mh-green); transform: translate(1px,-1px); }
.mh-app .kpi .kpi-arrow svg { width: 15px; height: 15px; }
.mh-app .kpi.active { background: linear-gradient(140deg,#4E7C72,#2E4A43); border-color: transparent; box-shadow: 0 16px 32px rgba(46,74,67,.30); }
.mh-app .kpi.active .num { color: #fff; }
.mh-app .kpi.active .lbl { color: rgba(255,255,255,.82); }
.mh-app .kpi.active .ico { background: rgba(255,255,255,.18) !important; }
.mh-app .kpi.active .delta { color: #fff !important; background: rgba(255,255,255,.20) !important; }
.mh-app .kpi.active .kpi-arrow { background: #fff; color: #2E4A43; border-color: #fff; }

/* main grid */
.mh-app .grid { display: grid; grid-template-columns: 1.62fr 1fr; gap: 18px; align-items: start; }
.mh-app .card {
  /* Bootstrap's .card sets color:var(--bs-body-color) (#212529); without our own
     token here, card text ignores the dark cascade. Bind it to the theme ink. */
  color: var(--mh-ink);
  background: var(--mh-surface); border: none; border-radius: var(--mh-r-card);
  box-shadow: var(--mh-shadow-sm); overflow: hidden;
}
.mh-app .card__head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; }
.mh-app .card__head h3 { font-size: 18px; }
/* All-caps section title. OPT-IN ONLY - it is a class on the two Program Sessions headings,
   NOT a rule on `.card__head h3`, which every card in the app shares and which would have
   shouted every section title on every screen. Caps at 18px close up without tracking, so the
   letter-spacing is part of the treatment, not decoration; the size drops a touch because
   uppercase reads larger than the same title in sentence case. */
.mh-app .card__head h3.sec-caps { font-size: 16.5px; letter-spacing: .06em; }
.mh-app .card__head .lnk { font-size: 13px; font-weight: 700; color: var(--mh-green); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; text-decoration: none; }
.mh-app .card__head .mini { font-size: 12.5px; font-weight: 600; color: var(--mh-muted); border: 1px solid var(--mh-line); border-radius: 999px; padding: 5px 12px; cursor: pointer; display: inline-flex; gap: 6px; align-items: center; }

/* families table */
.mh-app table { width: 100%; border-collapse: collapse; }
.mh-app thead th { text-align: left; font-size: 11px; letter-spacing: .8px; text-transform: uppercase; color: var(--mh-muted); font-weight: 700;
  padding: 11px 22px; background: var(--mh-cream-2); border-top: 1px solid var(--mh-line); border-bottom: 1px solid var(--mh-line); }
.mh-app tbody td { padding: 13px 22px; font-size: 14px; border-bottom: 1px solid var(--mh-line); }
.mh-app tbody tr:last-child td { border-bottom: 0; }
.mh-app tbody tr { transition: background .12s; }
.mh-app tbody tr:hover { background: var(--mh-cream-2); }
.mh-app .fam { display: flex; align-items: center; gap: 12px; }
.mh-app .fam .av { width: 38px; height: 38px; border-radius: 11px; flex: none; display: grid; place-items: center; color: #fff; font-weight: 700; font-size: 13px; font-family: var(--mh-font-head); }
/* Attendance program picker: reuse .pg-card as a clickable KPI card that opens the roster. */
.mh-app .att-cardpick .pg-card.att-pcard { cursor: pointer; }
/* "View attendance" CTA reuses the Household View look (.btn-household): green label with
   underline-grow + circular arrow ring that fills on hover. Card-level hover drives it. */
.mh-app .att-viewrow { display: flex; justify-content: flex-end; margin-top: 8px; }
.mh-app .att-viewbtn { pointer-events: none; }   /* the whole card handles the click */
.mh-app .att-pcard:hover .bh-ring { background: #5E8157; border-color: #5E8157; color: #fff; }
/* STUDENT SEARCH HITS on the Students tab's class list (CEO, Jul 31 2026). Deliberately ROWS,
   not cards: they sit above a grid of class cards, and a second grid of cards would read as
   more classes. A row list says "these are results", and it stays readable at 20 matches.
   Heading + count reuse the household members-header recipe so this is not a new vocabulary. */
.mh-app .pg-hits { margin-bottom: 22px; }
.mh-app .pg-hits-h { display: flex; align-items: center; gap: 10px; font-family: var(--mh-font-head); font-size: 13px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--mh-muted); margin-bottom: 12px; }
.mh-app .pg-hits-h .hi { width: 26px; height: 26px; border-radius: 8px; flex: none; display: grid; place-items: center; background: rgba(46,74,67,.12); color: var(--mh-green-d, #3D655D); }
.mh-app .pg-hits-h .hi svg { width: 15px; height: 15px; }
.mh-app .pg-hits-h .count { font-size: 11.5px; font-weight: 600; letter-spacing: 0; text-transform: none; padding: 3px 10px; border-radius: 999px; background: var(--mh-surface); border: 1px solid var(--mh-line); color: var(--mh-muted); }
.mh-app .pg-hitlist { display: flex; flex-direction: column; gap: 8px; }
.mh-app .pg-hit { display: flex; align-items: center; gap: 14px; padding: 11px 16px; border-radius: 14px; background: var(--mh-surface); border: 1px solid var(--mh-line); box-shadow: var(--mh-shadow-sm); cursor: pointer; transition: transform .14s, box-shadow .14s, border-color .14s; min-width: 0; }
.mh-app .pg-hit:hover { transform: translateY(-2px); box-shadow: var(--mh-shadow); border-color: var(--mh-green); }
.mh-app .pg-hit .idc-ph { width: 42px; height: 42px; font-size: 14px; }
.mh-app .pg-hit-main { flex: 1; min-width: 0; }
.mh-app .pg-hit-n { font-family: var(--mh-font-head); font-size: 15px; font-weight: 700; color: var(--mh-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mh-app .pg-hit-s { font-size: 11.5px; font-weight: 600; color: var(--mh-muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mh-app .pg-hit-s .sep { opacity: .5; margin: 0 6px; }
.mh-app .pg-hit-go { width: 34px; height: 34px; border-radius: 50%; flex: none; border: 1.5px solid #9BB795; color: #4C6A46; display: grid; place-items: center; transition: background .2s, border-color .2s, color .2s; }
.mh-app .pg-hit-go svg { width: 17px; height: 17px; }
.mh-app .pg-hit:hover .pg-hit-go { background: #5E8157; border-color: #5E8157; color: #fff; }
.mh-app .att-pcard:hover .bh-label::after { width: 100%; }
.mh-app .att-pcard:hover .bh-ring svg { transform: translateX(2px); }
/* CLASS-NAME row above the matrix: the class name, then its LIVE indicator (CEO, Jul 29 2026).
   Was the back-to-cards row; the "All programs" button and every .att-back rule went with it -
   the filter row's program selector is the one way out of a roster now. `align-items:center` is
   what centres the taller Live pill on the 18px title, and the title itself now starts in the
   same column as the "Attendance" page heading. */
/* The Live pill is CENTRED IN THE ROW, the class name stays left (CEO, Jul 29 2026).
   A 3-column grid is what makes both true at once: the name takes column 1, the pill takes
   the `auto` middle column, and the two equal 1fr columns either side of it put the pill on
   the row's centre line. `margin:0 auto` on a flex row would NOT do this - it centres the
   pill in the space LEFT OVER after the name, which is off-centre by half the name's width.
   Column 3 is deliberately empty; it exists only to balance column 1. */
.mh-app .att-backrow { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 14px; margin-bottom: 14px; }
.mh-app .att-backttl { font-family: var(--mh-font-head); font-weight: 600; font-size: 18px; color: var(--mh-ink); }
/* ENROLL-02: the heading names the TERM, and the term's meeting pattern reads under it as a
   quiet second line. Nested inside .att-backttl (not a sibling) so the 3-column grid above
   keeps the Live lamp centred. */
.mh-app .att-backsub { display: block; font-family: var(--mh-font-body); font-weight: 500; font-size: 12.5px; color: var(--mh-muted); margin-top: 2px; }
/* Attendance matrix: CIRCULAR, clickable student avatars (adults + kids) -> photo-zoom lightbox. */
.mh-app .att-grid .fam .av { border-radius: 50%; overflow: hidden; cursor: pointer; transition: transform .12s ease, box-shadow .12s ease; }
.mh-app .att-grid .fam .av:hover { transform: scale(1.07); box-shadow: 0 4px 14px rgba(40,60,80,.25); }
.mh-app .att-grid .fam .av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mh-app .fam .nm { font-weight: 600; }
.mh-app .fam .sub { font-size: 12px; color: var(--mh-muted); }
.mh-app .team { font-size: 13.5px; color: var(--mh-ink); }
.mh-app .team.none { color: var(--mh-muted); font-style: italic; }

.mh-app .pill { display: inline-flex; align-items: center; gap: 6px; border-radius: var(--mh-r-pill); padding: 4px 11px; font-size: 12px; font-weight: 600; }
.mh-app .pill .dot { width: 7px; height: 7px; border-radius: 50%; }
.mh-app .pill.success { background: rgba(78,124,114,.13); color: var(--mh-green-d); } .mh-app .pill.success .dot { background: var(--mh-success); }
.mh-app .pill.warning { background: rgba(216,155,61,.16); color: var(--mh-warning-d); } .mh-app .pill.warning .dot { background: var(--mh-warning); }
.mh-app .pill.danger  { background: rgba(176,70,60,.13); color: var(--mh-danger); } .mh-app .pill.danger .dot { background: var(--mh-danger); }
.mh-app .pill.info    { background: rgba(94,122,131,.14); color: var(--mh-info); } .mh-app .pill.info .dot { background: var(--mh-info); }

/* right rail */
.mh-app .rail { display: flex; flex-direction: column; gap: 18px; }

/* calendar */
.mh-app .cal__head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px 12px; }
.mh-app .cal__head h3 { font-size: 18px; }
.mh-app .cal__nav { display: flex; align-items: center; gap: 6px; }
.mh-app .cal__nav button { width: 30px; height: 30px; border-radius: 9px; border: 1px solid var(--mh-line); background: var(--mh-surface); cursor: pointer; display: grid; place-items: center; color: var(--mh-slate); }
.mh-app .cal__nav button:hover { background: var(--mh-cream-2); }
.mh-app .cal__nav .mo { font-weight: 700; font-size: 13.5px; min-width: 96px; text-align: center; }
.mh-app .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; padding: 4px 16px 18px; }
.mh-app .cal-grid .dow { text-align: center; font-size: 10.5px; font-weight: 700; letter-spacing: .5px; color: var(--mh-muted); text-transform: uppercase; padding-bottom: 4px; }
.mh-app .cal-cell { aspect-ratio: 1 / 1; border-radius: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; color: var(--mh-ink); cursor: pointer; position: relative; transition: background .12s; }
.mh-app .cal-cell:hover { background: var(--mh-cream-2); }
.mh-app .cal-cell.muted { color: #c7c3b6; font-weight: 500; }
.mh-app .cal-cell.today { background: var(--mh-slate); color: #fff; box-shadow: 0 6px 14px rgba(52,69,77,.3); }
.mh-app .cal-cell .ev { display: flex; gap: 2px; margin-top: 3px; height: 5px; }
.mh-app .cal-cell .ev i { width: 5px; height: 5px; border-radius: 50%; }
.mh-app .ev .g { background: var(--mh-green); } .mh-app .ev .c { background: var(--mh-clay); } .mh-app .ev .w { background: var(--mh-warning); } .mh-app .ev .d { background: var(--mh-danger); }
.mh-app .cal-cell.today .ev i { box-shadow: 0 0 0 1.5px var(--mh-slate); }

/* reminders */
.mh-app .rem { padding: 6px 14px 12px; }
.mh-app .rem-item { display: flex; gap: 12px; align-items: center; padding: 11px 8px; border-radius: 12px; transition: background .12s; cursor: pointer; }
.mh-app .rem-item:hover { background: var(--mh-cream-2); }
.mh-app .rem-ico { width: 38px; height: 38px; border-radius: 11px; flex: none; display: grid; place-items: center; }
.mh-app .rem-ico svg { width: 18px; height: 18px; }
.mh-app .rem-ico.warning { background: rgba(216,155,61,.16); color: var(--mh-warning-d); }
.mh-app .rem-ico.danger  { background: rgba(176,70,60,.13); color: var(--mh-danger); }
.mh-app .rem-ico.info    { background: rgba(94,122,131,.14); color: var(--mh-info); }
.mh-app .rem-ico.success { background: rgba(78,124,114,.13); color: var(--mh-green-d); }
/* Dark mode only: the two-tone brand glyphs are baked with mid/dark hues (pine #496670,
   teal #5E7A83) that go muddy on the faint dark reminder tiles. Give the icon chip a clean
   light backdrop in dark mode (mirrors the light theme, which reads fine) so every glyph
   stays crisp. Planner reminders only (.rem-item); the Dashboard uses .rem-row and is
   untouched. !important overrides the per-row inline ColorHex tile set by IcoStyle. */
body.dark .mh-app .rem-item .rem-ico { background: rgba(234, 239, 237, .94) !important; }
/* Same clean light chip for the Dashboard "Upcoming Reminders" preview in dark mode.
   It uses .rem-row inside the .reminders panel and gets a dark tone tile from the
   frosted-sage shell (body.dark .mh-fs .rem-ico), which muddies the baked glyphs.
   Scoped to .reminders so only the dashboard preview tiles change. */
body.dark .mh-app .mh-fs .reminders .rem-ico { background: rgba(234, 239, 237, .94) !important; }
/* KICKOFF 17: the Recent Activity feed now uses the SAME .rem-ico chip + brand glyphs.
   The frosted-sage shell sets .rem-ico background to var(--tbg) (a per-row tile the
   reminders set inline); activity rows set no tile, so give them a clean UNIFORM chip in
   BOTH themes - a faint cool tile in light, near-white in dark - so the baked two-tone
   glyphs stay crisp (mirrors the reminders dark rule above). The .activity scope beats the
   frosted .mh-fs .rem-ico rule. */
.mh-app .mh-fs .activity .rem-ico { background: rgba(94, 122, 131, .12); }
body.dark .mh-app .activity .rem-ico,
body.dark .mh-app .mh-fs .activity .rem-ico { background: rgba(234, 239, 237, .94) !important; }
.mh-app .rem-body { min-width: 0; flex: 1; }
.mh-app .rem-ttl { font-size: 13.5px; font-weight: 600; }
.mh-app .rem-sub { font-size: 12px; color: var(--mh-muted); }
.mh-app .rem-when { font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.mh-app .rem-when.warning { color: var(--mh-warning-d); }
.mh-app .rem-when.danger { color: var(--mh-danger); }
.mh-app .rem-when.info { color: var(--mh-info); }
.mh-app .rem-when.success { color: var(--mh-green-d); }

/* activity */
.mh-app .feed { padding: 8px 22px 18px; }
.mh-app .feed-item { display: flex; gap: 14px; padding: 12px 0; position: relative; }
.mh-app .feed-item:not(:last-child)::before { content:""; position: absolute; left: 18px; top: 40px; bottom: -12px; width: 1.5px; background: var(--mh-line); }
.mh-app .feed-dot { width: 37px; height: 37px; border-radius: 50%; flex: none; display: grid; place-items: center; z-index: 1; border: 1px solid var(--mh-line); background: var(--mh-surface); }
.mh-app .feed-dot svg { width: 17px; height: 17px; }
.mh-app .feed-ttl { font-size: 14px; font-weight: 600; }
.mh-app .feed-sub { font-size: 12.5px; color: var(--mh-muted); margin-top: 1px; }
.mh-app .feed-time { margin-left: auto; font-size: 11.5px; color: var(--mh-muted); white-space: nowrap; }

/* coming-soon stub */
.mh-app .stub { max-width: 560px; margin: 40px auto; text-align: center; background: var(--mh-surface);
  border-radius: var(--mh-r-card); box-shadow: var(--mh-shadow-sm); padding: 48px 40px; }
.mh-app .stub .badge-soon { display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--mh-clay-d); background: rgba(201,123,90,.13); border-radius: 999px; padding: 5px 14px; margin-bottom: 18px; }
.mh-app .stub .ico { width: 64px; height: 64px; border-radius: 18px; margin: 0 auto 20px; display: grid; place-items: center;
  background: linear-gradient(145deg, var(--mh-green), var(--mh-slate)); color: #fff; }
.mh-app .stub .ico svg { width: 30px; height: 30px; }
.mh-app .stub h1 { font-size: 27px; margin-bottom: 10px; }
.mh-app .stub p { color: var(--mh-muted); font-size: 14.5px; line-height: 1.6; margin: 0; }

/* staggered page-load reveal */
.mh-app .reveal { opacity: 0; transform: translateY(10px); animation: mh-rise .5s cubic-bezier(.22,.61,.36,1) forwards; }
@keyframes mh-rise { to { opacity: 1; transform: none; } }
.mh-app .d1{animation-delay:.04s}.mh-app .d2{animation-delay:.10s}.mh-app .d3{animation-delay:.16s}
.mh-app .d4{animation-delay:.22s}.mh-app .d5{animation-delay:.30s}.mh-app .d6{animation-delay:.38s}

/* ============ PLANNER ============ */
.mh-app .pl-head { display:flex; align-items:flex-end; justify-content:space-between; gap:20px; margin-bottom:16px; }
.mh-app .pl-head h1 { font-size:30px; }
.mh-app .pl-sub { color:var(--mh-muted); font-size:14.5px; margin:6px 0 0; }
.mh-app .pl-tabs { display:flex; gap:2px; border-bottom:1px solid var(--mh-line); margin-bottom:18px; }
/* Planner's horizontal tab row (Calendar / Agenda / Upcoming Reminders) is uppercase too.
   This rule is `.pl-tabs .pl-tab`, NOT the bare `.pl-tab`: the Program views panel reuses the
   same class name in a vertical rail (.pg-side) and is styled separately above. */
.mh-app .pl-tab { border:none; background:none; font-family:var(--mh-font-body); font-weight:600; font-size:14px; color:var(--mh-muted); padding:10px 16px; cursor:pointer; border-bottom:2.5px solid transparent; margin-bottom:-1px; transition:.15s; display:inline-flex; align-items:center; gap:7px; }
.mh-app .pl-tabs .pl-tab { text-transform:uppercase; letter-spacing:.05em; font-size:13px; font-weight:700; }
.mh-app .pl-tab:hover { color:var(--mh-ink); }
.mh-app .pl-tab.on { color:var(--mh-green-d); border-bottom-color:var(--mh-green); }
.mh-app .pl-tab .tagn { font-size:11px; font-weight:700; padding:1px 7px; border-radius:999px; background:rgba(216,155,61,.2); color:var(--mh-warning-d); }

.mh-app .pl-cal-toolbar { display:flex; align-items:center; gap:14px; margin-bottom:14px; flex-wrap:wrap; }
/* KICKOFF 23 (item 11) + refinement: the filter controls (Today, prev/next arrows,
   Month/Week/Day switcher) keep their soft --mh-surface fill + subtle shadow so they
   read as controls, but with NO outer border/outline (the de-framing stays). The
   active view pill + hover wash are unchanged. */
/* Calendar controls (Today, prev/next arrows, Month/Week/Day) wear the search bar's
   "Inset Cool Field": cool fill #DFE4EA + hairline + inset shadow, lift-to-white on hover.
   The Month/Week/Day active pill keeps its dark highlight. Dark flip in the body.dark block. */
.mh-app .pl-today { border:1px solid rgba(40,60,80,.08); background:#DFE4EA; box-shadow:inset 0 1px 2px rgba(40,60,80,.10); border-radius:var(--mh-r-pill); padding:8px 16px; font-weight:700; font-size:13px; cursor:pointer; color:var(--mh-ink); font-family:var(--mh-font-body); }
.mh-app .pl-today:hover { background:#fff; border-color:rgba(40,60,80,.16); box-shadow:0 10px 28px rgba(40,60,80,.12); }
.mh-app .pl-nav { display:flex; align-items:center; gap:6px; }
.mh-app .pl-nav button { width:32px; height:32px; border-radius:9px; border:1px solid rgba(40,60,80,.08); background:#DFE4EA; box-shadow:inset 0 1px 2px rgba(40,60,80,.10); cursor:pointer; display:grid; place-items:center; color:var(--mh-slate); transition:background .15s, border-color .15s, box-shadow .15s; }
.mh-app .pl-nav button:hover { background:#fff; border-color:rgba(40,60,80,.16); box-shadow:0 10px 28px rgba(40,60,80,.12); }
.mh-app .pl-nav button svg { width:16px; height:16px; }
.mh-app .pl-month { font-family:var(--mh-font-head); font-size:20px; font-weight:600; min-width:150px; text-align:center; }
.mh-app .pl-views { display:inline-flex; background:#DFE4EA; box-shadow:inset 0 1px 2px rgba(40,60,80,.10); border:1px solid rgba(40,60,80,.08); border-radius:var(--mh-r-pill); padding:4px; }
body.dark .mh-app :is(.pl-today, .pl-nav button, .pl-views) { background:var(--mh-ctrl-fill); border-color:var(--mh-line); box-shadow:inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app :is(.pl-today:hover, .pl-nav button:hover) { background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .pl-views button { border:none; background:none; font-family:var(--mh-font-body); font-weight:600; font-size:13px; color:var(--mh-muted); padding:6px 14px; border-radius:999px; cursor:pointer; }
.mh-app .pl-views button.on { background:var(--mh-slate); color:#fff; }
.mh-app .pl-legend { margin-left:auto; display:flex; gap:13px; flex-wrap:wrap; }
.mh-app .pl-legend span { display:inline-flex; align-items:center; gap:6px; font-size:12px; color:var(--mh-muted); font-weight:500; }
.mh-app .pl-legend i { width:9px; height:9px; border-radius:3px; }

.mh-app .pl-cal-wrap { display:grid; grid-template-columns:1fr 268px; gap:18px; align-items:start; }
/* KICKOFF 23 (item 9): the calendar has NO outer paper frame - the .pl-cal container
   stays transparent with no card shadow, sitting on the Planner bg (var(--mh-cream)).
   REFINEMENT: the day cells get their soft inner surface fill BACK (cells were white
   via the old card; with the card gone they are filled directly) so events sit on a
   proper backing. Headers/all-day keep their prior cream-2 tint. The faint
   theme-aware hairline separators (color-mix on --mh-ink, reads light AND dark) are
   unchanged. Frame OFF, cell fill ON. */
.mh-app .pl-cal { background:transparent; border-radius:0; box-shadow:none; overflow:hidden; }
.mh-app .pl-dow { display:grid; grid-template-columns:repeat(7,1fr); background:var(--mh-cream-2); border-bottom:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); }
.mh-app .pl-dow div { text-align:center; font-size:11px; letter-spacing:.6px; text-transform:uppercase; color:var(--mh-muted); font-weight:700; padding:10px 0; }
.mh-app .pl-grid { display:grid; grid-template-columns:repeat(7,1fr); grid-auto-rows:114px; }
.mh-app .pl-cell { background:var(--mh-surface); border-right:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); border-bottom:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); padding:6px 7px; overflow:hidden; cursor:pointer; transition:background .12s; }
.mh-app .pl-cell:nth-child(7n) { border-right:none; }
.mh-app .pl-cell:hover { background:var(--mh-cream-2); }
.mh-app .pl-cell .dnum { font-size:13px; font-weight:600; color:var(--mh-ink); display:inline-grid; place-items:center; width:24px; height:24px; }
.mh-app .pl-cell.muted .dnum { color:#c7c3b6; }
.mh-app .pl-cell.today .dnum { background:var(--mh-green); color:#fff; border-radius:50%; box-shadow:0 4px 10px rgba(78,124,114,.4); }
.mh-app .ev-chip { font-size:11px; font-weight:600; color:#fff; padding:2px 7px; border-radius:6px; margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; cursor:pointer; }
.mh-app .ev-more { font-size:11px; color:var(--mh-muted); font-weight:600; margin-top:3px; padding-left:2px; }

/* ===== calendar Month/Week/Day upgrade ===== */
.mh-app .pl-cell { position:relative; }
/* The "+ New" add affordance only belongs on real, in-month blank cells. Grayed
   (adjacent-month) cells navigate to their month instead of creating, so no hint there. */
.mh-app .pl-cell.blank:not(.muted):hover::after { content:'+ New'; position:absolute; right:7px; top:6px; font-size:10px; color:var(--mh-green); font-weight:700; }
.mh-app .pl-tg-scroll { max-height:566px; overflow-y:auto; }
.mh-app .pl-tg { display:grid; }
.mh-app .pl-tg.week { grid-template-columns:62px repeat(7,1fr); }
.mh-app .pl-tg.day { grid-template-columns:62px 1fr; }
/* REFINEMENT: Week/Day surfaces filled back - day headers + all-day keep their prior
   cream-2 tint (also OPAQUE so the sticky headers still mask scrolled content); the
   hour slots + gutter get the white surface fill so timed events sit on a backing. */
.mh-app .pl-dhdr { text-align:center; padding:9px 0; border-left:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); border-bottom:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); background:var(--mh-cream-2); position:sticky; top:0; z-index:2; }
.mh-app .pl-dhdr .dn { font-size:11px; text-transform:uppercase; letter-spacing:.5px; color:var(--mh-muted); font-weight:700; }
.mh-app .pl-dhdr .dd { font-family:var(--mh-font-head); font-size:18px; font-weight:600; line-height:1.5; }
.mh-app .pl-dhdr.today .dd { color:#fff; background:var(--mh-green); width:30px; height:30px; border-radius:50%; display:inline-grid; place-items:center; box-shadow:0 4px 10px rgba(78,124,114,.4); }
.mh-app .pl-corner { background:var(--mh-cream-2); border-bottom:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); position:sticky; top:0; z-index:2; }
.mh-app .pl-hr { background:var(--mh-surface); font-size:11px; color:var(--mh-muted); text-align:right; padding:5px 8px 0 0; border-top:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); height:52px; box-sizing:border-box; }
.mh-app .pl-slot { background:var(--mh-surface); border-top:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); border-left:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); height:52px; padding:2px; cursor:pointer; position:relative; transition:background .1s; box-sizing:border-box; }
.mh-app .pl-slot:hover { background:var(--mh-cream-2); }
.mh-app .pl-slot:hover::after { content:'+ New'; position:absolute; right:5px; top:4px; font-size:10px; color:var(--mh-green); font-weight:700; }
.mh-app .pl-slot.has-ev:hover::after { content:none; }
.mh-app .pl-slot.has-ev .pl-ev2 { cursor:pointer; }
.mh-app .pl-ev2 { font-size:11px; font-weight:600; color:#fff; border-radius:6px; padding:3px 7px; height:100%; box-sizing:border-box; overflow:hidden; cursor:pointer; }
.mh-app .pl-allday { display:flex; flex-wrap:wrap; gap:6px; padding:10px 14px; border-bottom:1px solid color-mix(in srgb, var(--mh-ink) 9%, transparent); background:var(--mh-cream-2); }
.mh-app .pl-allday .lab { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--mh-muted); align-self:center; margin-right:4px; }
.mh-app .pl-tag { font-size:11.5px; font-weight:600; color:#fff; border-radius:999px; padding:3px 10px; }
.mh-app .pl-daytitle { font-family:var(--mh-font-head); font-size:17px; font-weight:600; padding:12px 16px 4px; }
.mh-app .pl-month { cursor:pointer; user-select:none; }

/* ===== P3 lifecycle states on calendar items (Completed vs Overdue) ===== */
/* Overdue: desaturated / "locked" look + a red edge marker. Completed: distinct
   green edge + strike-through, clearly NOT the same as overdue. */
.mh-app .ev-chip.overdue, .mh-app .pl-ev2.overdue, .mh-app .pl-tag.overdue {
  filter:grayscale(.7); opacity:.62; box-shadow:inset 3px 0 0 var(--mh-danger);
}
.mh-app .ev-chip.done, .mh-app .pl-ev2.done, .mh-app .pl-tag.done {
  opacity:.85; box-shadow:inset 3px 0 0 #2F7D4F; text-decoration:line-through; text-decoration-thickness:1px;
}

/* ===== P3 hover: "lit / selected" feedback on every clickable schedule item =====
   Pure styling. Layers ON TOP of the lifecycle visuals: the completed (green edge
   + strike) and overdue (desaturated + red edge) treatments are restated in their
   own :hover rules so the highlight never hides them. Ring colour is token-driven
   (color-mix on --mh-ink) so it reads in both light and dark. */
.mh-app .ev-chip, .mh-app .pl-ev2, .mh-app .pl-tag {
  cursor:pointer;
  /* KICKOFF 23 (item 9): lighten the event colors with a UNIFORM filter applied over
     the inline DB color (lkp_EventType/lkp_ReminderType.ColorHex). The source colour
     stays authoritative + nothing is hardcoded; white text stays legible. Amount is
     theme-tuned via --pl-chip-filter (see :root + body.dark). */
  filter: var(--pl-chip-filter);
  transition: box-shadow .13s ease, transform .13s ease, filter .13s ease, opacity .13s ease;
}
/* normal (upcoming) item: lift + highlight ring + soft elevation + slight brighten */
.mh-app .ev-chip:hover, .mh-app .pl-ev2:hover, .mh-app .pl-tag:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--mh-ink) 40%, transparent), 0 5px 12px rgba(42,47,49,.24);
  filter: var(--pl-chip-filter-hover);
}
/* completed item hovered: keep the green edge + strike, add the same lit ring/lift */
.mh-app .ev-chip.done:hover, .mh-app .pl-ev2.done:hover, .mh-app .pl-tag.done:hover {
  transform: translateY(-1px);
  box-shadow: inset 3px 0 0 #2F7D4F, 0 0 0 2px color-mix(in srgb, var(--mh-ink) 40%, transparent), 0 5px 12px rgba(42,47,49,.24);
  filter: brightness(1.04);
  opacity:.92;
}
/* overdue item hovered: desaturation + red edge PRESERVED, just lifted + lit */
.mh-app .ev-chip.overdue:hover, .mh-app .pl-ev2.overdue:hover, .mh-app .pl-tag.overdue:hover {
  transform: translateY(-1px);
  box-shadow: inset 3px 0 0 var(--mh-danger), 0 0 0 2px color-mix(in srgb, var(--mh-ink) 40%, transparent), 0 5px 12px rgba(42,47,49,.24);
  filter: grayscale(.7) brightness(1.12);
  opacity:.82;
}

/* ===== P3 context menu (View / Complete / Delete) ===== */
.mh-app .pl-menu-scrim { position:fixed; inset:0; z-index:300; background:transparent; }
.mh-app .pl-menu { position:fixed; z-index:301; min-width:200px; max-width:260px; background:var(--mh-surface);
  border:1px solid var(--mh-line); border-radius:12px; box-shadow:0 14px 34px rgba(42,47,49,.22);
  padding:6px; transform-origin:top left; animation:pl-menu-in .1s ease-out; }
@keyframes pl-menu-in { from { opacity:0; transform:scale(.96); } to { opacity:1; transform:scale(1); } }
.mh-app .pl-menu-head { padding:7px 9px 9px; border-bottom:1px solid var(--mh-line); margin-bottom:4px; }
.mh-app .pl-menu-kind { display:block; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.4px; color:var(--mh-muted); }
.mh-app .pl-menu-ttl { display:block; font-size:13px; font-weight:600; color:var(--mh-ink); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mh-app .pl-menu-item { display:block; width:100%; text-align:left; background:none; border:none; cursor:pointer;
  font-family:var(--mh-font-body); font-size:13.5px; font-weight:600; color:var(--mh-ink); padding:9px 10px; border-radius:8px; }
.mh-app .pl-menu-item:hover:not(:disabled) { background:var(--mh-cream-2); }
.mh-app .pl-menu-item:disabled { color:var(--mh-muted); cursor:default; }
.mh-app .pl-menu-item.danger { color:var(--mh-danger); }
.mh-app .pl-menu-item.danger:hover { background:rgba(176,70,60,.1); }

/* ===== P3 delete confirm (centered) ===== */
/* Compound selector (0,3,0) so it beats the later `.mh-app .pl-overlay`
   (justify-content:flex-end, 0,2,0) on specificity regardless of source order -
   otherwise the base rule wins and shoves the centered card (e.g. the Delete
   confirm) to the right edge. `.pl-overlay--center` is always paired with
   `.pl-overlay` on the same element, so the compound always matches. */
.mh-app .pl-overlay.pl-overlay--center { justify-content:center; align-items:center; }
.mh-app .pl-confirm { background:var(--mh-surface); border-radius:16px; box-shadow:var(--mh-shadow-lg); padding:24px; max-width:380px; width:calc(90 * var(--mh-vw)); animation:pl-menu-in .12s ease-out; }
.mh-app .pl-confirm h3 { font-family:var(--mh-font-head); font-size:18px; margin:0 0 8px; color:var(--mh-ink); }
.mh-app .pl-confirm p { font-size:13.5px; color:var(--mh-muted); line-height:1.5; margin:0 0 18px; }
.mh-app .pl-confirm-actions { display:flex; justify-content:flex-end; gap:10px; }
.mh-app .btn--danger { background:var(--mh-danger); color:#fff; box-shadow:0 8px 18px rgba(176,70,60,.26); }
.mh-app .btn--danger:hover { background:#933a31; }

/* ===== P3 read-only View detail ===== */
.mh-app .pl-view { margin-top:14px; }
.mh-app .pl-vstatus { display:inline-block; font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.4px;
  padding:4px 11px; border-radius:999px; margin-bottom:14px; }
.mh-app .pl-vstatus.up { background:rgba(78,124,114,.16); color:var(--mh-green-d); }
.mh-app .pl-vstatus.done { background:rgba(47,125,79,.16); color:#2F7D4F; }
.mh-app .pl-vstatus.overdue { background:rgba(176,70,60,.14); color:var(--mh-danger); }
.mh-app .pl-vrow { display:grid; grid-template-columns:108px 1fr; gap:10px; padding:10px 0; border-bottom:1px solid var(--mh-line); }
.mh-app .pl-vrow:last-child { border-bottom:none; }
.mh-app .pl-vrow span { font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--mh-muted); padding-top:2px; }
.mh-app .pl-vrow b { font-size:14px; font-weight:600; color:var(--mh-ink); white-space:pre-wrap; }

.mh-app .pl-rail { display:flex; flex-direction:column; gap:16px; }

/* ----- Planner rail mini-calendar (green-circle style, scoped to .pl-rail .cal-grid.mc) ----- */
.mh-app .pl-rail .cal-grid.mc { grid-template-columns:repeat(7,1fr); gap:7px 0; padding:4px 2px 4px !important; }
.mh-app .pl-rail .cal-grid.mc .dow { font-size:10.5px; color:var(--mh-muted); font-weight:700; text-align:center; padding-bottom:3px; }
.mh-app .pl-rail .cal-grid.mc .cal-cell { aspect-ratio:auto; height:34px; background:transparent !important; border-radius:0; box-shadow:none !important;
  display:flex; flex-direction:column; align-items:center; justify-content:center; position:relative; font-size:13px; font-weight:600; color:var(--mh-ink); cursor:pointer; }
.mh-app .pl-rail .cal-grid.mc .cal-cell.muted { color:#c7c3b6; }
.mh-app .pl-rail .cal-grid.mc .mc-n { width:28px; height:28px; border-radius:50%; display:grid; place-items:center; transition:background .12s; }
.mh-app .pl-rail .cal-grid.mc .cal-cell:hover .mc-n { background:var(--mh-cream-2); }
.mh-app .pl-rail .cal-grid.mc .cal-cell.today .mc-n { background:rgba(78,124,114,.16); color:var(--mh-green-d); }
.mh-app .pl-rail .cal-grid.mc .cal-cell.selected .mc-n { background:var(--mh-green); color:#fff; box-shadow:0 4px 10px rgba(78,124,114,.4); }
.mh-app .pl-rail .cal-grid.mc .mc-dot { position:absolute; bottom:0; left:50%; transform:translateX(-50%); width:5px; height:5px; border-radius:50%; background:var(--mh-green); }
.mh-app .pl-rail .cal-grid.mc .cal-cell.selected .mc-dot { background:var(--mh-green-d); }
/* KICKOFF 23 refinement: the two right-rail cards (mini-cal + Staff Calendars, which
   holds the staff toggles) keep their soft --mh-surface fill + subtle shadow so they
   are not bare - but NO creamy outer border/frame (there never was one; the de-framing
   stays). The calendar grid + page bg are untouched. */
.mh-app .pl-card { background:var(--mh-surface); border-radius:var(--mh-r-card); box-shadow:var(--mh-shadow-sm); padding:16px; }
.mh-app .pl-card h4 { font-size:14px; margin-bottom:10px; }
.mh-app .pl-filter label { display:flex; align-items:center; gap:10px; font-size:13px; color:var(--mh-ink); padding:6px 0; cursor:pointer; }
.mh-app .pl-filter input { accent-color:var(--mh-green); width:15px; height:15px; }
.mh-app .pl-filter .swatch { width:11px; height:11px; border-radius:3px; flex:none; }
.mh-app .pl-filter .nm2 { margin-left:auto; font-size:11.5px; color:var(--mh-muted); }

/* KICKOFF 24: US Holidays rail card rows - same typography/spacing as the Staff
   Calendars rows (name left in ink, date right in muted), on the same .pl-card. */
.mh-app .pl-hol-row { display:flex; align-items:center; gap:10px; padding:6px 0; }
.mh-app .pl-hol-nm { font-size:13px; color:var(--mh-ink); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mh-app .pl-hol-dt { margin-left:auto; font-size:11.5px; color:var(--mh-muted); flex:none; }
.mh-app .pl-hol-empty { font-size:12.5px; color:var(--mh-muted); padding:4px 0; }

.mh-app .pl-agenda-day { font-family:var(--mh-font-head); font-size:15px; font-weight:600; margin:20px 0 9px; color:var(--mh-slate); }
.mh-app .pl-agenda-day:first-child { margin-top:0; }
.mh-app .pl-ag-item { display:flex; align-items:stretch; gap:13px; background:var(--mh-surface); border-radius:12px; padding:12px 15px; margin-bottom:8px; box-shadow:var(--mh-shadow-sm); cursor:pointer; transition:transform .12s; }
.mh-app .pl-ag-item:hover { transform:translateX(2px); }
.mh-app .pl-ag-bar { width:4px; border-radius:4px; flex:none; }
.mh-app .pl-ag-time { font-size:13px; font-weight:700; color:var(--mh-ink); width:76px; flex:none; align-self:center; }
.mh-app .pl-ag-ttl { font-size:14px; font-weight:600; }
.mh-app .pl-ag-sub { font-size:12px; color:var(--mh-muted); margin-top:1px; }

.mh-app .pl-overlay { position:fixed; inset:0; background:rgba(42,47,49,.42); z-index:200; display:flex; justify-content:flex-end; }
.mh-app .pl-sheet { width:440px; max-width:calc(92 * var(--mh-vw)); background:var(--mh-surface); height:100%; box-shadow:var(--mh-shadow-lg); padding:24px 24px 32px; overflow-y:auto; animation:pl-slideIn .25s ease; }
@keyframes pl-slideIn { from{transform:translateX(50px);opacity:.5} to{transform:none;opacity:1} }
.mh-app .pl-sheet-top { display:flex; align-items:flex-start; justify-content:space-between; }
.mh-app .pl-sheet h3 { font-size:20px; }
.mh-app .pl-x { border:none; background:var(--mh-cream); width:34px; height:34px; border-radius:10px; cursor:pointer; font-size:18px; color:var(--mh-slate); }
.mh-app .pl-seg2 { display:inline-flex; background:var(--mh-cream); border:1px solid var(--mh-line); border-radius:var(--mh-r-pill); padding:4px; margin:14px 0 18px; }
.mh-app .pl-seg2 button { border:none; background:none; font-family:var(--mh-font-body); font-weight:600; font-size:13px; color:var(--mh-muted); padding:7px 20px; border-radius:999px; cursor:pointer; }
.mh-app .pl-seg2 button.on { background:var(--mh-green); color:#fff; }
.mh-app .pl-field { margin-bottom:14px; }
.mh-app .pl-field label { display:block; font-size:11.5px; font-weight:700; color:var(--mh-muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:6px; }
/* FS1 Phase 3: repointed onto the shared --mh-ctrl-* layer (was bespoke mh-line/surface). */
.mh-app .pl-field input, .mh-app .pl-field select, .mh-app .pl-field textarea { width:100%; border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:12px 14px; font-family:var(--mh-font-body); font-size:14px; color:var(--mh-ink); background-color:var(--mh-ctrl-fill); box-sizing:border-box; transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
/* planner main-page selects: same unified caret + open flip (base rule above uses
   background-COLOR now so the caret longhands here are not clobbered) */
.mh-app .pl-field select { padding-right:40px; background-image:var(--mh-ctrl-caret); background-repeat:no-repeat; background-position:right 14px center; background-size:14px 14px; }
.mh-app .pl-field select:open { background-image:var(--mh-ctrl-caret-up); }
.mh-app .pl-field textarea { min-height:72px; resize:vertical; }
.mh-app .pl-field input:focus, .mh-app .pl-field select:focus, .mh-app .pl-field textarea:focus { outline:none; background-color:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .pl-row2 { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
/* Guidance under a .pl-field control. Muted on purpose: validation messages are the only
   thing in these sheets allowed to read as an alert. Additive - it styles nothing that
   does not opt in by carrying the class. */
.mh-app .pl-field .pl-hint { display:block; margin-top:6px; font-size:12px; font-weight:500; line-height:1.35; color:var(--mh-muted); }
/* Amber, deliberately NOT the validation red: this advises, it never blocks Create. */
.mh-app .pl-field .pl-hint.is-warn { color:#8a5a12; font-weight:600; }

/* ---- ROW OPENS THE RECORD (Program Sessions) ------------------------------------
   A row that navigates has to LOOK like it does before it is clicked, or the feature
   is only discoverable by accident. Three signals, all cheap: the pointer, a lift on
   hover, and a chevron that slides in from the right edge.

   The chevron column is always in the DOM at zero opacity rather than being inserted
   on hover - appearing content reflows the row and makes the hover feel like a jump.
   Focus-visible gets the SAME treatment as hover, so keyboard users see exactly what
   mouse users see; the outline is the app's focus ring, not a browser default.

   Selector is `.row-open`, NOT `tr.row-open`: the Recently-issued list is a stack of divs
   (.wd-prow), not a table, and it must behave identically. Two near-identical rules that
   drift is exactly how one list ends up clickable and the other not. */
.mh-app .row-open { cursor: pointer; transition: background .14s ease, box-shadow .14s ease; }
.mh-app .row-open:hover { background: var(--mh-hover, #f4f7f9); }
.mh-app .row-open:focus-visible { outline: none; background: var(--mh-hover, #f4f7f9); box-shadow: inset 3px 0 0 var(--mh-green); }
.mh-app tr.row-open .row-chev { width: 26px; padding-right: 14px; text-align: right; vertical-align: middle; }
.mh-app .row-open .row-chev { display: inline-flex; align-items: center; }
.mh-app .row-open .row-chev svg { width: 16px; height: 16px; color: var(--mh-muted);
  opacity: 0; transform: translateX(-4px); transition: opacity .14s ease, transform .14s ease; }
.mh-app .row-open:hover .row-chev svg,
.mh-app .row-open:focus-visible .row-chev svg { opacity: 1; transform: none; }
/* The row's own action buttons stop propagation in markup; this keeps them looking
   like the exception they are rather than inheriting the row's pointer affordance. */
.mh-app .row-open .ns-act,
.mh-app .row-open .btn { cursor: pointer; }

/* ---- PROGRAM SESSIONS KPI STRIP -------------------------------------------------
   Four measurements above the two work-queue tables. Deliberately NOT a card grid:
   these are read-only figures, so they get a flat tile with no hover, no cursor and
   no action - nothing here should look clickable. Fixed 4-up on desktop, 2-up on
   tablet, 1-up on phone; it is a fixed set of four, so auto-fit is not wanted. */
.mh-app .kpi-strip { display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-bottom:16px; }
.mh-app .kpi { background:var(--mh-surface); border:1px solid var(--mh-line); border-radius:var(--mh-card-r,14px);
  box-shadow:var(--mh-shadow-sm); padding:14px 16px; display:flex; flex-direction:column; gap:2px; min-width:0; }
.mh-app .kpi-k { font-size:11.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--mh-muted); }
.mh-app .kpi-v { font-family:var(--mh-font-head); font-size:26px; line-height:1.15; color:var(--mh-ink); }
.mh-app .kpi-s { font-size:12px; font-weight:500; color:var(--mh-muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* A zero here is information, not an alarm - it is muted, never red. */
.mh-app .kpi.is-zero .kpi-v { color:var(--mh-muted); }
/* Live now is the only tile that earns colour, because it is the only one that predicts
   whether the kiosk will accept a scan. */
.mh-app .kpi.is-live { border-color:#bfe0d2; background:#f2f9f6; }
.mh-app .kpi.is-live .kpi-v { color:var(--mh-green-d); }
.mh-app .kpi.is-live .kpi-s { color:#2f6b54; font-weight:600; }
@media (max-width:1100px) { .mh-app .kpi-strip { grid-template-columns:repeat(2,1fr); } }
@media (max-width:620px)  { .mh-app .kpi-strip { grid-template-columns:1fr; } }

/* ---- GIFT CARD ROSTER: face beside the name -------------------------------------
   Reuses .idc-ph so the crop, the ring and the initials fallback are the SAME recipe
   as the Students cards - a second avatar implementation is how two screens end up
   showing the same person differently. Only the SIZE is overridden: .idc-ph is 56px
   for a KPI card, which would set the row height on a table. 34px matches the row's
   own rhythm and keeps the ring from touching the cell edges. */
.mh-app .gc-person { display: flex; align-items: center; gap: 11px; min-width: 0; }
.mh-app .gc-person .gc-ph { width: 34px; height: 34px; font-size: 12px; letter-spacing: .3px;
  box-shadow: 0 0 0 2px var(--mh-surface), 0 0 0 3px var(--mh-line); }
.mh-app .gc-person .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Gift-card roster sub-line: whose threshold this is, and the attend-all-days count.
   Quiet by default so it never competes with the "Gift ready" pill; green only when the
   attendance rule is actually satisfied. */
.mh-app .gc-sub { display:block; margin-top:4px; font-size:11.5px; font-weight:500; line-height:1.3; color:var(--mh-muted); }
.mh-app .gc-sub.is-ok { color:#2f6b46; font-weight:650; }
/* From / To / Duration on the appointment tab: three equal columns, same gap. */
.mh-app .pl-row3 { display:grid; grid-template-columns:1fr 1fr 1fr; gap:12px; }
.mh-app .pl-check { display:flex; align-items:center; gap:9px; font-size:13.5px; color:var(--mh-ink); margin-bottom:14px; }
/* checkbox left to the global FS pill (--mh-ctrl-*); no bespoke accent-color override */
.mh-app .pl-sheet-actions { display:flex; gap:10px; justify-content:flex-end; margin-top:6px; }

/* ============================================================
   KICKOFF 27 - "Schedule new event" centered popup (.ecs-*)
   Shell only. The branded card (mock "Direction C") rendered in
   the app's pine brand, reusing the pl-overlay mechanism + the
   tm-modal-m3 dialog family. All create logic lives in the .razor;
   this is presentation. Light + dark.
   ============================================================ */
/* deeper, CENTERED backdrop. .mh-app .pl-overlay (justify-content:flex-end) is later
   in source than .pl-overlay--center, so it wins on equal specificity and shoves the
   card right. This .pl-overlay.ecs-overlay selector is more specific (0,3,0) AND later,
   so it pins the card dead-center for real. */
.mh-app .pl-overlay.ecs-overlay { justify-content:center; align-items:center;
  background:radial-gradient(120% 90% at 50% 0%, rgba(52,69,77,.5) 38%, rgba(20,28,26,.66)); padding:40px 24px; overflow:auto; }

/* the card */
.mh-app .ecs-card { width:478px; max-width:100%; background:var(--mh-surface); border-radius:26px;
  display:flex; flex-direction:column; max-height:min(840px, calc(calc(100 * var(--mh-vh)) - 80px)); overflow:hidden;
  box-shadow:0 50px 110px rgba(13,22,26,.5), 0 8px 24px rgba(13,22,26,.28); animation:pl-menu-in .14s ease-out; }

/* branded header band - pine gradient + decorative arcs */
.mh-app .ecs-band { position:relative; overflow:hidden; flex:0 0 auto; padding:26px 28px; color:#fff;
  background:radial-gradient(135% 140% at 12% -10%, #5E8A7E 0%, var(--mh-green) 48%, var(--mh-green-d) 100%); }
.mh-app .ecs-band .ecs-arc { position:absolute; border-radius:50%; border:1.5px solid rgba(255,255,255,.16); pointer-events:none; }
.mh-app .ecs-band .ecs-arc.a1 { width:300px; height:300px; right:-120px; top:-160px; }
.mh-app .ecs-band .ecs-arc.a2 { width:470px; height:470px; right:-210px; top:-240px; border-color:rgba(255,255,255,.1); }
.mh-app .ecs-band .ecs-arc.a3 { width:150px; height:150px; left:-70px; bottom:-86px; border-color:rgba(255,255,255,.12); }
.mh-app .ecs-head { position:relative; z-index:2; display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.mh-app .ecs-eyebrow { display:inline-flex; align-items:center; gap:7px; font-size:11px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:rgba(255,255,255,.82); }
.mh-app .ecs-eyebrow svg { width:13px; height:13px; }
.mh-app .ecs-band h2 { font-family:var(--mh-font-head); font-weight:700; font-size:24px; color:#fff; margin:10px 0 0; letter-spacing:-.01em; line-height:1.05; }
.mh-app .ecs-x { width:36px; height:36px; border-radius:11px; display:grid; place-items:center; flex:0 0 auto;
  border:none; cursor:pointer; font-size:22px; line-height:1; color:#fff; background:rgba(255,255,255,.16); transition:.15s; }
.mh-app .ecs-x:hover { background:rgba(255,255,255,.3); transform:rotate(90deg); }

/* scroll body */
.mh-app .ecs-body { padding:20px 28px 8px; overflow-y:auto; flex:1 1 auto; min-height:0; }

/* segmented tab bar (recessed pills) */
.mh-app .ecs-tabs { display:flex; gap:3px; padding:5px; border-radius:13px; background:var(--mh-cream-2); border:1px solid var(--mh-line); margin:0 0 20px; }
.mh-app .ecs-tabs button { flex:1; height:40px; border-radius:9px; font-family:var(--mh-font-body); font-size:13px; font-weight:700; color:var(--mh-muted);
  display:flex; align-items:center; justify-content:center; background:none; border:none; cursor:pointer; transition:.15s; white-space:nowrap; }
.mh-app .ecs-tabs button:hover { color:var(--mh-ink); }
.mh-app .ecs-tabs button.on { background:var(--mh-green); color:#fff; box-shadow:0 5px 13px rgba(78,124,114,.34); }

/* fields - DESIGN's clean white control: thin COOL hairline (NOT the warm creamy
   --mh-line that was leaking the paper outline), 50px tall, 12px radius. Use
   background-COLOR (not the background shorthand) so the global select caret
   (--mh-ctrl-caret background-image, set on .mh-app select) survives - the shorthand
   was wiping it, which is why the dropdown chevrons disappeared. */
.mh-app .ecs-body .pl-field input, .mh-app .ecs-body .pl-field select, .mh-app .ecs-body .pl-field textarea {
  background-color:var(--mh-surface); border:1.5px solid var(--mh-line-cool); }
.mh-app .ecs-body .pl-field input, .mh-app .ecs-body .pl-field select { height:50px; padding:0 14px; }
/* re-add the dropdown chevron: the base .pl-field select rule uses the `background`
   SHORTHAND (more specific than the global .mh-app select caret rule), which resets
   background-image to none. Restore the caret explicitly so every select reads as a
   dropdown (DESIGN shows a chevron on each). */
.mh-app .ecs-body .pl-field select { padding-right:40px;
  background-image:var(--mh-ctrl-caret); background-repeat:no-repeat; background-position:right 14px center; background-size:14px 14px; }
.mh-app .ecs-body .pl-field select:focus { background-image:var(--mh-ctrl-caret); background-repeat:no-repeat; background-position:right 14px center; background-size:14px 14px; }
/* open state flips to the up-chevron (both the rest + focus carets are re-declared above,
   so :open needs to out-specify both) */
.mh-app .ecs-body .pl-field select:open,
.mh-app .ecs-body .pl-field select:focus:open { background-image:var(--mh-ctrl-caret-up); }
.mh-app .ecs-body .pl-field input:focus, .mh-app .ecs-body .pl-field select:focus, .mh-app .ecs-body .pl-field textarea:focus {
  background-color:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }

/* all-day = DESIGN's real switch (hidden checkbox keeps the @bind; track+knob spans
   render the toggle exactly per sched.css: 42x24 track, 18px knob w/ shadow, teal-on). */
.mh-app .ecs-body .ecs-switch { display:inline-flex; align-items:center; gap:11px; cursor:pointer; margin-bottom:14px; user-select:none; }
.mh-app .ecs-body .ecs-switch input { position:absolute; opacity:0; width:0; height:0; margin:0; pointer-events:none; }
.mh-app .ecs-body .ecs-track { position:relative; width:42px; height:24px; border-radius:20px; background:var(--mh-ctrl-fill-2); flex:0 0 auto; transition:background .2s ease; }
.mh-app .ecs-body .ecs-knob { position:absolute; top:3px; left:3px; width:18px; height:18px; border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(33,50,58,.3); transition:left .2s ease; }
.mh-app .ecs-body .ecs-switch input:checked + .ecs-track { background:var(--mh-green); }
.mh-app .ecs-body .ecs-switch input:checked + .ecs-track .ecs-knob { left:21px; }
.mh-app .ecs-body .ecs-switch input:focus-visible + .ecs-track { box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .ecs-body .ecs-tlabel { font-size:14px; font-weight:600; color:var(--mh-ink); }

/* MULTI-DATE / RECURRING: Repeats control + mini-calendar multi-date picker */
.mh-app .ecs-body .ecs-repeat { margin:-2px 0 14px; padding:13px; border:1px solid var(--mh-line-cool);
  border-radius:13px; background:var(--mh-cream-2); }
.mh-app .ecs-body .ecs-repeatnote { display:flex; align-items:flex-start; gap:9px; margin:0 0 14px; padding:11px 13px;
  border:1px solid var(--mh-line-cool); border-radius:12px; background:var(--mh-cream-2); font-size:12.5px;
  font-weight:600; color:var(--mh-slate); line-height:1.4; }
.mh-app .ecs-body .ecs-repeatnote svg { width:16px; height:16px; flex:none; margin-top:1px; }
.mh-app .ecs-body .ecs-repeat-sum { margin-top:10px; font-size:12.5px; font-weight:700; color:var(--mh-green-d); }
.mh-app .ecs-body .ecs-mini { user-select:none; }
.mh-app .ecs-body .ecs-mini-hd { display:flex; align-items:center; justify-content:space-between; margin-bottom:9px; }
.mh-app .ecs-body .ecs-mini-title { font-size:13.5px; font-weight:700; color:var(--mh-ink); }
.mh-app .ecs-body .ecs-mini-nav { width:28px; height:28px; border:1px solid var(--mh-line); border-radius:8px;
  background:var(--mh-surface); color:var(--mh-ink); font-size:16px; line-height:1; cursor:pointer; transition:.13s; }
.mh-app .ecs-body .ecs-mini-nav:hover { border-color:var(--mh-green); color:var(--mh-green-d); }
.mh-app .ecs-body .ecs-mini-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:4px; }
.mh-app .ecs-body .ecs-mini-dow { text-align:center; font-size:10.5px; font-weight:700; color:var(--mh-muted);
  text-transform:uppercase; padding-bottom:3px; }
.mh-app .ecs-body .ecs-mini-cell { aspect-ratio:1/1; display:flex; align-items:center; justify-content:center;
  border:1px solid transparent; border-radius:9px; background:transparent; color:var(--mh-ink); font-size:12.5px;
  font-weight:600; cursor:pointer; transition:.12s; font-family:inherit; }
.mh-app .ecs-body .ecs-mini-cell:hover { background:var(--mh-surface); border-color:var(--mh-line); }
.mh-app .ecs-body .ecs-mini-cell.empty { cursor:default; }
.mh-app .ecs-body .ecs-mini-cell.empty:hover { background:transparent; border-color:transparent; }
.mh-app .ecs-body .ecs-mini-cell.on { background:var(--mh-green); border-color:var(--mh-green); color:#fff; }
.mh-app .ecs-body .ecs-mini-cell.on:hover { background:var(--mh-green-d); border-color:var(--mh-green-d); }

/* fixed footer */
.mh-app .ecs-foot { flex:0 0 auto; display:flex; align-items:center; justify-content:flex-end; gap:12px;
  padding:16px 28px 22px; border-top:1px solid var(--mh-line-cool); }

/* dark theme: deeper card shadow (controls + switch flip via the theme tokens) */
body.dark .mh-app .ecs-card { box-shadow:0 50px 110px rgba(0,0,0,.6), 0 8px 24px rgba(0,0,0,.4); }

/* ============================================================
   KICKOFF 30 - ParticipantPicker (.pp-*): smart "With" typeahead.
   Client / Household / Outside-contact, grouped dropdown + inline add.
   Styled to the design system, theme-aware. Lives inside .ecs-body
   (the wizard) but scoped on its own so it can be reused elsewhere.
   ============================================================ */
.mh-app .pp-root { position:relative; }

/* the closed control - matches the wizard field (white, 50px, cool hairline) */
.mh-app .pp-field { display:flex; align-items:center; gap:10px; height:50px; padding:0 14px;
  background:var(--mh-surface); border:1.5px solid var(--mh-line-cool); border-radius:var(--mh-ctrl-r);
  transition:border-color .15s ease, box-shadow .15s ease; }
.mh-app .pp-field:focus-within { border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .pp-srch-ic { color:var(--mh-ctrl-ico); width:17px; height:17px; flex:0 0 auto; display:grid; place-items:center; }
.mh-app .pp-srch-ic svg { width:17px; height:17px; }
.mh-app .pp-input { flex:1; min-width:0; border:none; background:none; outline:none; font-family:var(--mh-font-body);
  font-size:14px; color:var(--mh-ink); }
.mh-app .pp-input::placeholder { color:var(--mh-ctrl-ico); }
/* The picker input sits inside a wizard .pl-field, so the global
   `.ecs-body .pl-field input` rule (border + 50px height + white fill) LEAKS onto
   it and paints a second box stacked inside .pp-field. Neutralize it (higher
   specificity + later source) so .pp-field is the ONLY control box. Same applies
   to the inline add-form inputs (.pp-ainp keep their own border but not the 50px). */
.mh-app .ecs-body .pl-field .pp-input,
.mh-app .ecs-body .pl-field .pp-input:focus {
  border:none; height:auto; padding:0; background:transparent; box-shadow:none; }
.mh-app .ecs-body .pl-field .pp-ainp { height:44px; }

/* outside-click catcher + the dropdown */
.mh-app .pp-backdrop { position:fixed; inset:0; z-index:300; background:transparent; }
.mh-app .pp-menu { position:absolute; z-index:301; top:calc(100% + 6px); left:0; right:0; max-height:300px; overflow-y:auto;
  background:var(--mh-surface); border:1px solid var(--mh-line-cool); border-radius:14px;
  box-shadow:var(--mh-shadow-lg); padding:6px; animation:pl-menu-in .12s ease-out; }
.mh-app .pp-hint { padding:14px 12px; font-size:13px; color:var(--mh-muted); text-align:center; }

/* grouped result headers + option rows */
.mh-app .pp-grouphd { font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--mh-muted); padding:9px 10px 5px; }
.mh-app .pp-opt { display:flex; align-items:center; gap:11px; width:100%; text-align:left; border:none; background:none;
  cursor:pointer; padding:8px 10px; border-radius:10px; transition:background .12s ease; }
.mh-app .pp-opt:hover { background:var(--mh-cream-2); }
.mh-app .pp-opt-ic { width:32px; height:32px; flex:0 0 auto; border-radius:9px; display:grid; place-items:center; }
.mh-app .pp-opt-ic svg { width:17px; height:17px; }
.mh-app .pp-opt-ic.pp-client    { background:rgba(78,124,114,.14); color:var(--mh-green-d); }
.mh-app .pp-opt-ic.pp-household  { background:rgba(78,124,114,.14); color:var(--mh-green-d); }
.mh-app .pp-opt-ic.pp-external   { background:rgba(201,123,90,.16); color:var(--mh-clay-d); }
.mh-app .pp-opt-main { flex:1; min-width:0; display:flex; flex-direction:column; }
.mh-app .pp-opt-nm { font-size:14px; font-weight:600; color:var(--mh-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mh-app .pp-opt-sub { font-size:12px; color:var(--mh-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mh-app .pp-opt-code { font-family:var(--mono); font-size:11px; color:var(--mh-muted); flex:0 0 auto; }

/* footer "Add as outside contact" */
.mh-app .pp-addrow { display:flex; align-items:center; gap:11px; width:100%; text-align:left; border:none; cursor:pointer;
  padding:9px 10px; border-radius:10px; background:none; margin-top:4px; border-top:1px solid var(--mh-line-cool);
  font-size:13.5px; color:var(--mh-ink); transition:background .12s ease; }
.mh-app .pp-addrow:hover { background:var(--mh-cream-2); }
.mh-app .pp-addtxt b { font-weight:700; }

/* inline new-outside-contact form */
.mh-app .pp-addhd { font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--mh-muted); padding:8px 10px 6px; }
.mh-app .pp-addform { display:flex; flex-direction:column; gap:9px; padding:4px 8px 8px; }
.mh-app .pp-ainp { height:44px; padding:0 13px; border:1.5px solid var(--mh-line-cool); border-radius:10px;
  background:var(--mh-surface); font-family:var(--mh-font-body); font-size:14px; color:var(--mh-ink); outline:none; transition:border-color .15s ease, box-shadow .15s ease; }
.mh-app .pp-ainp:focus { border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .pp-ainp::placeholder { color:var(--mh-ctrl-ico); }
.mh-app .pp-aerr { font-size:12.5px; color:var(--mh-danger); }
.mh-app .pp-addactions { display:flex; justify-content:flex-end; gap:9px; margin-top:2px; }
.mh-app .pp-abtn { height:40px; padding:0 16px; border-radius:10px; border:none; cursor:pointer; font-family:var(--mh-font-body); font-weight:700; font-size:13.5px; transition:background .15s ease; }
.mh-app .pp-abtn.ghost { background:var(--mh-surface); border:1.5px solid var(--mh-line-cool); color:var(--mh-ink); }
.mh-app .pp-abtn.ghost:hover { background:var(--mh-cream-2); }
.mh-app .pp-abtn.primary { background:var(--mh-green); color:#fff; }
.mh-app .pp-abtn.primary:hover { background:var(--mh-green-d); }
.mh-app .pp-abtn:disabled { opacity:.6; cursor:default; }

/* selected = a chip (kind icon + name + clear x) */
.mh-app .pp-chip { display:inline-flex; align-items:center; gap:10px; max-width:100%; height:50px; padding:0 8px 0 12px;
  background:var(--mh-cream-2); border:1.5px solid var(--mh-line-cool); border-radius:var(--mh-ctrl-r); }
.mh-app .pp-chip-ic { width:30px; height:30px; flex:0 0 auto; border-radius:8px; display:grid; place-items:center; }
.mh-app .pp-chip-ic svg { width:16px; height:16px; }
.mh-app .pp-chip-ic.pp-client, .mh-app .pp-chip-ic.pp-household { background:rgba(78,124,114,.16); color:var(--mh-green-d); }
.mh-app .pp-chip-ic.pp-external { background:rgba(201,123,90,.18); color:var(--mh-clay-d); }
.mh-app .pp-chip-nm { font-size:14px; font-weight:600; color:var(--mh-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mh-app .pp-chip-org { font-size:12.5px; color:var(--mh-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mh-app .pp-chip-x { margin-left:auto; flex:0 0 auto; width:30px; height:30px; border:none; background:none; cursor:pointer;
  border-radius:8px; font-size:20px; line-height:1; color:var(--mh-muted); transition:background .12s ease, color .12s ease; }
.mh-app .pp-chip-x:hover { background:rgba(176,70,60,.12); color:var(--mh-danger); }

/* ============================================================
   KICKOFF 28 - Event/Appointment detail as a CENTERED two-pane
   popup (.ed-*). Replaces the old right-side pl-sheet detail.
   Mock "Two-pane" mapped to app pine tokens + dark; cool hairline;
   chip color is DB-driven; status pill reuses .pl-vstatus tokens.
   ============================================================ */
.mh-app .pl-overlay.ed-overlay { justify-content:center; align-items:center;
  background:radial-gradient(120% 90% at 50% 0%, rgba(52,69,77,.5) 38%, rgba(20,28,26,.66)); padding:40px 24px; overflow:auto; }

/* the card - two-pane (main + cool meta rail) */
.mh-app .ed-card { width:640px; max-width:100%; background:var(--mh-surface); border-radius:24px; display:flex; overflow:hidden;
  max-height:min(620px, calc(calc(100 * var(--mh-vh)) - 80px)); box-shadow:0 50px 110px rgba(13,22,26,.5), 0 8px 24px rgba(13,22,26,.28);
  animation:pl-menu-in .14s ease-out; }
.mh-app .ed-card--single { width:460px; }

/* main pane */
.mh-app .ed-main { flex:1; min-width:0; display:flex; flex-direction:column; padding:26px 28px 24px; overflow-y:auto; }
.mh-app .ed-top { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.mh-app .ed-eyebrow { display:inline-flex; align-items:center; gap:7px; font-size:11px; font-weight:800; letter-spacing:.14em;
  text-transform:uppercase; color:var(--mh-green-d); }
.mh-app .ed-eyebrow svg { width:13px; height:13px; }
.mh-app .ed-x { width:36px; height:36px; border-radius:11px; display:grid; place-items:center; flex:0 0 auto; border:none; cursor:pointer;
  font-size:22px; line-height:1; color:var(--mh-muted); background:var(--mh-cream-2); transition:.15s; }
.mh-app .ed-x:hover { background:var(--mh-line-cool); color:var(--mh-ink); }
.mh-app .ed-main h2 { font-family:var(--mh-font-head); font-weight:700; font-size:25px; color:var(--mh-ink); margin:16px 0 0; line-height:1.14; letter-spacing:-.01em; }
.mh-app .ed-badgerow { display:flex; flex-direction:row; align-items:center; flex-wrap:nowrap; gap:9px; margin-top:14px; }
/* the status pill reuses .pl-vstatus, which carries a standalone margin-bottom; zero it
   here so the pill + type chip sit cleanly centered on ONE row. */
.mh-app .ed-badgerow .pl-vstatus { margin-bottom:0; }
.mh-app .ed-chip { display:inline-flex; align-items:center; gap:7px; font-size:12.5px; font-weight:700; padding:5px 11px;
  border-radius:8px; background:var(--mh-cream-2); color:var(--mh-ink); }
.mh-app .ed-chip-dot { width:8px; height:8px; border-radius:50%; flex:0 0 auto; }

/* when-block */
.mh-app .ed-when { margin-top:22px; padding:16px 18px; border-radius:14px; display:flex; align-items:center; gap:16px;
  background:rgba(78,124,114,.07); border:1px solid rgba(78,124,114,.18); }
.mh-app .ed-datetile { flex:0 0 auto; width:62px; height:70px; border-radius:13px; overflow:hidden; display:flex; flex-direction:column;
  text-align:center; box-shadow:0 8px 18px rgba(73,102,112,.28); }
.mh-app .ed-datetile .m { background:linear-gradient(135deg,var(--mh-green),var(--mh-green-d)); color:#fff; font-size:10.5px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; padding:6px 0 4px; }
.mh-app .ed-datetile .d { flex:1; display:grid; place-items:center; background:var(--mh-surface); font-family:var(--mh-font-head); font-size:28px; font-weight:700; color:var(--mh-ink); }
.mh-app .ed-wtext { min-width:0; }
.mh-app .ed-wk { font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--mh-muted); display:flex; align-items:center; gap:8px; }
.mh-app .ed-wk svg { width:14px; height:14px; color:var(--mh-green); }
.mh-app .ed-wv { font-family:var(--mh-font-head); font-size:19px; font-weight:700; color:var(--mh-ink); margin-top:9px; }
.mh-app .ed-wt { font-size:13.5px; color:var(--mh-green-d); font-weight:600; margin-top:4px; }

/* reminder/task inline meta (single-pane, replaces the rail) */
.mh-app .ed-inlinemeta { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-top:20px; }
.mh-app .ed-im .ed-rk { display:flex; align-items:center; gap:8px; }

/* notes */
.mh-app .ed-nlabel { font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--mh-muted); margin:24px 0 10px; }
.mh-app .ed-nbox { font-size:14.5px; color:var(--mh-ink); line-height:1.55; white-space:pre-wrap; }
.mh-app .ed-nbox.empty { color:var(--mh-muted); font-style:italic; }
.mh-app .ed-foot { margin-top:auto; padding-top:26px; display:flex; align-items:center; gap:12px; }

/* meta rail - cool neutral */
.mh-app .ed-rail { flex:0 0 232px; background:var(--mh-cream-2); border-left:1px solid var(--mh-line-cool); padding:26px 22px;
  display:flex; flex-direction:column; overflow-y:auto; }
.mh-app .ed-railhead { font-size:10.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--mh-muted); padding-bottom:6px; }
.mh-app .ed-rk { font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--mh-muted); display:flex; align-items:center; gap:8px; }
.mh-app .ed-rk svg { width:14px; height:14px; color:var(--mh-green); flex:0 0 auto; }
.mh-app .ed-rmeta { padding:15px 0; border-bottom:1px solid var(--mh-line-cool); }
.mh-app .ed-rmeta:first-of-type { border-top:1px solid var(--mh-line-cool); }
.mh-app .ed-rv { font-size:14.5px; font-weight:600; color:var(--mh-ink); margin-top:9px; display:flex; align-items:center; gap:9px; word-break:break-word; }
.mh-app .ed-rv.muted { color:var(--mh-muted); font-weight:500; font-style:italic; }
.mh-app .ed-av { width:32px; height:32px; border-radius:50%; display:grid; place-items:center; color:#fff; font-weight:800; font-size:12px; flex:0 0 auto;
  background:linear-gradient(135deg,var(--mh-green),var(--mh-green-d)); box-shadow:0 2px 6px rgba(73,102,112,.3); }

/* ===== PHASE 3 STEP 1b: multi-assign (participant cluster, tile count, multi-select) ===== */
/* detail-panel avatar cluster for a shared appointment (organizer + co-assignees) */
.mh-app .ed-avstack { display:inline-flex; align-items:center; flex:0 0 auto; }
.mh-app .ed-avstack .ed-av { width:26px; height:26px; font-size:10px; margin-left:-8px; border:2px solid var(--mh-surface); box-shadow:none; }
.mh-app .ed-avstack .ed-av:first-child { margin-left:0; }
.mh-app .ed-avnames { font-size:12.5px; font-weight:500; color:var(--mh-muted); line-height:1.4; }
/* small participant-count badge on a calendar tile */
.mh-app .ev-cnt { display:inline-block; margin-left:5px; padding:0 5px; border-radius:8px; background:rgba(255,255,255,.28);
  font-size:9.5px; font-weight:800; line-height:1.55; vertical-align:middle; }
.mh-app .pl-multi-hint { font-size:11.5px; color:var(--mh-muted); margin-top:7px; }

/* ===== Reusable CheckboxPicker: NAME left / SQUARE CHECKBOX right, whole-row toggle,
   pine tint when selected. Shared by the Planner staff pickers + (later) the country
   filter. Works in light AND dark. ===== */
.mh-app .mhpick { display:flex; flex-direction:column; gap:4px; max-height:200px; overflow-y:auto;
  background:var(--mh-ctrl-fill); border-radius:var(--mh-ctrl-r); padding:6px; }
.mh-app .mhpick-row { display:flex; align-items:center; gap:12px; width:100%; text-align:left;
  padding:11px 14px; border:none; border-radius:12px; background:transparent; cursor:pointer;
  font-family:var(--mh-font-body); font-size:14px; font-weight:600; color:var(--mh-ink);
  transition:background .14s ease, box-shadow .14s ease; }
.mh-app .mhpick-row:hover { background:var(--mh-surface); }
.mh-app .mhpick-row:disabled { cursor:default; }
.mh-app .mhpick-row.on { background:rgba(78,124,114,.12); box-shadow:inset 0 0 0 1px rgba(78,124,114,.30); }
.mh-app .mhpick-row.on:hover { background:rgba(78,124,114,.17); }
.mh-app .mhpick-main { flex:1 1 auto; min-width:0; display:flex; align-items:center; gap:10px; }
.mh-app .mhpick-nm { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mh-app .mhpick-badge { flex:0 0 auto; font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.5px;
  color:var(--mh-green-d); background:rgba(78,124,114,.16); padding:3px 8px; border-radius:999px; }
/* the square checkbox pinned to the right edge */
.mh-app .mhpick-box { flex:0 0 auto; width:22px; height:22px; border-radius:6px; display:grid; place-items:center;
  border:2px solid #C2CAD0; background:var(--mh-surface); color:#fff; transition:background .14s ease, border-color .14s ease; }
.mh-app .mhpick-box svg { width:15px; height:15px; opacity:0; transition:opacity .12s ease; }
.mh-app .mhpick-box.on { background:var(--mh-green); border-color:var(--mh-green); }
.mh-app .mhpick-box.on svg { opacity:1; }
/* dark */
body.dark .mh-app .mhpick-row.on { background:rgba(94,138,126,.20); box-shadow:inset 0 0 0 1px rgba(94,138,126,.44); }
body.dark .mh-app .mhpick-row.on:hover { background:rgba(94,138,126,.27); }
body.dark .mh-app .mhpick-box { border-color:rgba(255,255,255,.30); background:transparent; }
body.dark .mh-app .mhpick-box.on { background:var(--mh-green); border-color:var(--mh-green); }

/* ===== CheckboxCombo: a closed field that opens the picker rows (same design) ===== */
.mh-app .mhcombo { position:relative; }
.mh-app .mhcombo-trigger { width:100%; display:flex; align-items:center; gap:10px; padding:12px 14px;
  border:1px solid transparent; border-radius:var(--mh-ctrl-r); background:var(--mh-ctrl-fill); cursor:pointer;
  font-family:var(--mh-font-body); font-size:14px; color:var(--mh-ink); text-align:left;
  transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .mhcombo-trigger:hover { background:var(--mh-surface); }
.mh-app .mhcombo-trigger.open { background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .mhcombo-val { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mh-app .mhcombo-val.ph { color:var(--mh-muted); }
.mh-app .mhcombo-chev { flex:0 0 auto; width:14px; height:14px; color:var(--mh-ctrl-ico); display:grid; place-items:center; transition:transform .2s cubic-bezier(.2,.7,.25,1); }
.mh-app .mhcombo-chev svg { width:100%; height:100%; display:block; }
.mh-app .mhcombo-trigger.open .mhcombo-chev { transform:rotate(180deg); }
/* the opened panel expands the form in-flow (never clipped by the sheet overflow) */
.mh-app .mhcombo-panel { margin-top:7px; background:var(--mh-surface); border:1px solid var(--mh-line);
  border-radius:14px; box-shadow:0 14px 34px rgba(20,28,26,.14); padding:5px; }
.mh-app .mhcombo-panel .mhpick { background:transparent; padding:2px; max-height:210px; }
body.dark .mh-app .mhcombo-panel { box-shadow:0 18px 40px rgba(0,0,0,.44); }

/* dark: deeper card shadow (surfaces/lines flip via tokens) */
body.dark .mh-app .ed-card { box-shadow:0 50px 110px rgba(0,0,0,.6), 0 8px 24px rgba(0,0,0,.4); }

/* ============================================================
   PHASE 3 STEP 1c - the 30-minute FULL-SCREEN "starting soon"
   alert (.ua-*). Reuses the .ed-* detail card, presented as a
   fixed, viewport-covering takeover above the whole shell.
   ============================================================ */
.mh-app .ua-overlay { position:fixed; inset:0; z-index:100090; display:grid; place-items:center; padding:32px 20px;
  background:radial-gradient(120% 90% at 50% 0%, rgba(52,69,77,.62) 34%, rgba(16,23,21,.82)); overflow:auto;
  animation:ua-fade .16s ease-out; }
@keyframes ua-fade { from { opacity:0; } to { opacity:1; } }
.mh-app .ua-card { animation:pl-menu-in .16s ease-out; }
/* the alert accent: a warm amber eyebrow so it reads as "act now", distinct from the calm detail view */
.mh-app .ua-eyebrow { color:#B26A2E; }
.mh-app .ua-eyebrow svg { width:14px; height:14px; }
.mh-app .ua-lead { margin-top:12px; font-size:15px; line-height:1.4; color:var(--mh-muted); }
.mh-app .ua-lead b { color:var(--mh-ink); font-weight:800; }
.mh-app .ua-err { margin-top:12px; background:#fdecec; color:#b0312f; border:1px solid #f3c4c3; border-radius:12px;
  padding:10px 14px; font-size:13.5px; }

/* the "Mark completed?" confirmation, layered above the alert card */
.mh-app .ua-confirm-scrim { position:fixed; inset:0; z-index:9010; display:grid; place-items:center; padding:24px;
  background:rgba(16,23,21,.5); }
.mh-app .ua-confirm { width:380px; max-width:100%; background:var(--mh-surface); border-radius:18px; padding:22px 24px 20px;
  box-shadow:0 40px 90px rgba(13,22,26,.5); animation:pl-menu-in .14s ease-out; }
.mh-app .ua-confirm h3 { font-family:var(--mh-font-head); font-weight:700; font-size:18px; color:var(--mh-ink); margin:0; }
.mh-app .ua-confirm p { margin:8px 0 0; font-size:13.5px; color:var(--mh-muted); line-height:1.45; }
.mh-app .ua-confirm-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:18px; }

body.dark .mh-app .ua-eyebrow { color:#E0A768; }
body.dark .mh-app .ua-err { background:rgba(176,49,47,.16); color:#f3b7b5; border-color:rgba(176,49,47,.4); }
body.dark .mh-app .ua-confirm { box-shadow:0 40px 90px rgba(0,0,0,.6); }

.mh-app .pl-rem-actions { display:flex; align-items:center; gap:14px; margin-left:auto; align-self:center; }
/* Fixed, right-aligned date column so the due date sits clear of the Done button and
   the dates + buttons line up vertically across every reminder row. */
.mh-app .pl-rem-actions .rem-when { min-width:48px; text-align:right; }
.mh-app .pl-mini-btn { border:1px solid var(--mh-line); background:var(--mh-surface); border-radius:8px; padding:5px 11px; font-size:11.5px; font-weight:600; cursor:pointer; color:var(--mh-ink); }
.mh-app .pl-mini-btn:hover { background:var(--mh-cream-2); }
.mh-app .pl-mini-btn.done:hover { border-color:var(--mh-green); color:var(--mh-green-d); }

/* responsive */
@media (max-width: 1100px) {
  .mh-app .kpis { grid-template-columns: repeat(2, 1fr); }
  .mh-app .grid { grid-template-columns: 1fr; }
}
/* The new pine icon rail is only 86px wide, so it stays visible at every width.
   (The old wide-sidebar hide-below-820px rule is retired.) */

/* ============================================================================
   PROGRAM MODULE (Phase 2) - Programs cards · Students rosters · detail popup
   Mirrors mh-dashboard.html #view-program, scoped under .mh-app.
   ========================================================================== */
@keyframes pgPulse { 0%,100%{box-shadow:0 0 0 3px rgba(78,124,114,.18)} 50%{box-shadow:0 0 0 6px rgba(78,124,114,.05)} }
@keyframes wdPop { from{opacity:0;transform:translateY(14px) scale(.985)} to{opacity:1;transform:none} }

/* POLISH-04 ITEM 3: KILL THE CREAMY OUTLINES across the Program section. The warm app
   hairline (--mh-line: #E6E0D4) reads as an off-white/cream outline that Shaker finds
   annoying on the Program cards, tiles, panels, inputs and dashed tiles. We rebind the
   token to brand Pine at 30% alpha, scoped to the Program shell (.pg-wrap) and to every
   Program-owned overlay (.pg-scope marker on each modal root, since the overlays render
   as siblings OUTSIDE .pg-wrap). This cascades to every var(--mh-line) border in the
   section - pg-stats/foot2/btn/add dashed tile, ns-act, att-grid, sched-tbl, exp-menu,
   the enroll/detail/report modal dividers and inputs - so nothing creamy remains. Any
   hardcoded cream hexes (#F0ECE3, #d6cdba) are re-pointed just below. Dark uses a hair
   more alpha so the Pine line stays legible on the dark surfaces. */
.mh-app .pg-wrap, .mh-app .pg-scope { --mh-line: rgba(78,124,114,.30); }
body.dark .mh-app .pg-wrap, body.dark .mh-app .pg-scope { --mh-line: rgba(78,124,114,.42); }

/* Programs cards. POLISH-02: .pg-grid now follows the shared CARD-GRID LAW (3-col
   cap, 16px gutters, 3->2->1 responsive) for parity with the Clients .idgrid - see
   the grouped :is() selector below. No local grid definition here. */
.mh-app .pg-card { background:var(--mh-surface); border-radius:var(--mh-r-card); box-shadow:var(--mh-shadow-sm); padding:20px; transition:transform .18s, box-shadow .18s; display:flex; flex-direction:column; }
.mh-app .pg-card:hover { transform:translateY(-3px); box-shadow:var(--mh-shadow); }
.mh-app .pg-card-top { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; position:relative; }
.mh-app .pg-type { font-size:11.5px; font-weight:700; color:#fff; padding:3px 11px; border-radius:999px; }
.mh-app .pg-code { font-family:var(--mono); font-size:11.5px; color:var(--mh-muted); font-weight:600; }
.mh-app .pg-card h3 { font-size:18px; margin:0 0 3px; }
.mh-app .pg-lead { font-size:12.5px; color:var(--mh-muted); margin-bottom:14px; }
.mh-app .pg-stats { display:grid; grid-template-columns:1fr 1fr; gap:11px 16px; padding:14px 0; border-top:1px solid var(--mh-line); border-bottom:1px solid var(--mh-line); }
.mh-app .pg-stats > div { display:flex; flex-direction:column; gap:2px; }
.mh-app .pg-stats .k { font-size:10.5px; text-transform:uppercase; letter-spacing:.5px; color:var(--mh-muted); font-weight:700; }
.mh-app .pg-stats .v { font-size:14px; font-weight:600; color:var(--mh-ink); }
.mh-app .pg-pts { font-size:12px; font-weight:700; color:var(--mh-green-d); background:rgba(78,124,114,.12); padding:3px 10px; border-radius:999px; }
/* POLISH: the pills row (.pg-card-foot: Attendance tracked / pts-day) was glued to the
   .pg-stats divider above it (0px gap) - top-heavy and visually "connected" to the line.
   padding-top matches the 13px gap below the row so the pills sit centered in the band,
   clear of the hairline. Applies to the live .pg-part banner too when a session is open. */
.mh-app .pg-bottom { margin-top:auto; display:flex; flex-flow:row wrap; align-items:center; column-gap:10px; row-gap:12px; padding-top:13px; }
/* participation banner + the Attendance-tracked / pts-day pills share ONE row (they wrap
   only when the card is too narrow); the buttons row / view-attendance row take their own line. */
.mh-app .pg-bottom > .pg-foot2, .mh-app .pg-bottom > .att-viewrow { flex-basis:100%; }
.mh-app .pg-card-foot { display:flex; align-items:center; gap:10px; }
.mh-app .pg-live { display:inline-flex; align-items:center; gap:6px; font-size:11px; font-weight:700; color:var(--mh-muted); }
.mh-app .pg-live .lt { width:8px; height:8px; border-radius:50%; background:var(--mh-line); box-shadow:0 0 0 3px rgba(0,0,0,.03); }
.mh-app .pg-live.on { color:var(--mh-green-d); }
.mh-app .pg-live.on .lt { background:var(--mh-success); box-shadow:0 0 0 3px rgba(78,124,114,.18); animation:pgPulse 1.8s infinite; }
.mh-app .pg-count { font-weight:700; }
.mh-app .pg-count.soon { color:var(--mh-warning-d); }
.mh-app .pg-part { display:flex; align-items:center; gap:6px; font-size:12px; font-weight:600; color:var(--mh-green-d); background:rgba(78,124,114,.08); border:1px solid rgba(78,124,114,.18); border-radius:10px; padding:7px 11px; }
.mh-app .pg-part .lt { width:8px; height:8px; border-radius:50%; background:var(--mh-success); }
.mh-app .pg-part b { font-family:var(--mh-font-head); }
.mh-app .pg-foot2 { display:flex; align-items:center; gap:8px; padding-top:13px; border-top:1px solid var(--mh-line); }
.mh-app .pg-btn { border:1.5px solid var(--mh-line); background:var(--mh-surface); border-radius:10px; padding:7px 14px; font-family:var(--mh-font-body); font-weight:700; font-size:12.5px; color:var(--mh-ink); cursor:pointer; transition:.15s; }
.mh-app .pg-btn:hover { background:var(--mh-cream-2); border-color:var(--mh-green); }   /* POLISH-04 ITEM 3: cream hover border -> Pine */
.mh-app .pg-btn.done { color:var(--mh-green-d); border-color:rgba(78,124,114,.4); }
.mh-app .pg-btn.done:hover { background:rgba(78,124,114,.08); }
.mh-app .pg-btn.rm { color:var(--mh-danger); border-color:rgba(176,70,60,.28); margin-left:auto; }
.mh-app .pg-btn.rm:hover { background:rgba(176,70,60,.07); }
.mh-app .pg-seg { margin-bottom:0; }   /* POLISH-02: seg now aligns inside the flex .toolbar row */
.mh-app .pg-seg button span { font-size:11px; font-weight:700; padding:1px 7px; border-radius:999px; background:rgba(0,0,0,.06); margin-left:6px; }
.mh-app .pg-seg button.on span { background:rgba(255,255,255,.22); }
.mh-app .pg-card.completed { opacity:.92; }
.mh-app .pg-card.completed .pg-type { filter:grayscale(.35); }
.mh-app .pg-done-badge { display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:700; color:var(--mh-muted); background:var(--mh-cream-2); border-radius:999px; padding:3px 11px; }
.mh-app .pg-add { border:2px dashed var(--mh-line); border-radius:var(--mh-r-card); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; color:var(--mh-muted); cursor:pointer; min-height:210px; transition:.15s; }
.mh-app .pg-add:hover { border-color:var(--mh-green); color:var(--mh-green-d); background:var(--mh-cream-2); }
.mh-app .pg-add .plus { width:44px; height:44px; border-radius:50%; background:var(--mh-cream-2); display:grid; place-items:center; }
.mh-app .pg-add:hover .plus { background:rgba(78,124,114,.14); }
.mh-app .pg-empty { text-align:center; padding:70px 20px; }
.mh-app .pg-empty .ic { width:74px; height:74px; border-radius:50%; background:var(--mh-cream-2); display:inline-grid; place-items:center; margin-bottom:18px; color:var(--mh-muted); }
.mh-app .pg-empty h3 { font-size:21px; margin-bottom:6px; }
.mh-app .pg-empty p { color:var(--mh-muted); font-size:14px; margin-bottom:20px; }
.mh-app .pg-stub { text-align:center; padding:90px 20px; }
.mh-app .pg-stub .ic { width:64px; height:64px; border-radius:50%; background:var(--mh-cream-2); display:inline-grid; place-items:center; margin-bottom:14px; color:var(--mh-muted); }

/* Program report modal (REBUILD-02B) - ported verbatim from mh-dashboard.html 796,827-839. */
.mh-app .qr-modal { position:fixed; inset:0; background:rgba(33,50,58,.5); z-index:420; display:none; align-items:center; justify-content:center; padding:24px; }
/* POLISH: MudBlazor snackbars/toasts default to z-index 1500 (--mud-zindex-snackbar), which
   sits BEHIND the full-screen detail overlays (#hhDetail 99990) so "Student suspended" etc.
   popped up hidden behind the mock. Lift them above everything (incl. the QR pass 100060). */
:root { --mud-zindex-snackbar: 100090; }
.mud-snackbar-provider,
.mud-snackbar-location-top-start, .mud-snackbar-location-top-center, .mud-snackbar-location-top-end,
.mud-snackbar-location-bottom-start, .mud-snackbar-location-bottom-center, .mud-snackbar-location-bottom-end { z-index: 100090 !important; }
.mh-app .report-card { width:560px; max-width:calc(94 * var(--mh-vw)); max-height:calc(90 * var(--mh-vh)); overflow:auto; background:var(--mh-surface); border-radius:20px; box-shadow:0 24px 70px rgba(33,50,58,.4); padding:26px 28px; animation:wdPop .18s ease; }
.mh-app .report-head { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:18px; }
.mh-app .report-head h3 { font-family:var(--mh-font-head); font-size:22px; font-weight:700; color:var(--mh-ink); margin:0; }
.mh-app .rp-meta { font-size:13px; color:var(--mh-muted); margin-top:4px; }
.mh-app .rp-stats { display:grid; grid-template-columns:repeat(5,1fr); gap:10px; margin-bottom:18px; }
.mh-app .rp-stat { background:var(--mh-cream-2); border-radius:12px; padding:12px 8px; text-align:center; }
.mh-app .rp-stat b { display:block; font-family:var(--mh-font-head); font-size:20px; color:var(--mh-ink); }
.mh-app .rp-stat span { font-size:10px; color:var(--mh-muted); font-weight:700; text-transform:uppercase; letter-spacing:.3px; }
.mh-app .rp-tbl { width:100%; border-collapse:collapse; }
.mh-app .rp-tbl th { text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.4px; color:var(--mh-muted); font-weight:700; padding:9px 10px; border-bottom:1px solid var(--mh-line); }
.mh-app .rp-tbl td { padding:10px; border-bottom:1px solid var(--mh-line); font-size:14px; }   /* POLISH-04 ITEM 3: cream -> theme line (Pine in .pg-scope) */
.mh-app .rp-foot { display:flex; justify-content:flex-end; gap:10px; margin-top:18px; }
@media print { .mh-app body * { visibility:hidden !important; } .mh-app .report-card, .mh-app .report-card * { visibility:visible !important; } .mh-app .report-card { position:fixed; top:20px; left:50%; transform:translateX(-50%); box-shadow:none; max-height:none; } .mh-app .rp-foot { display:none; } }
.mh-app .pg-stub h3 { font-family:var(--mh-font-head); font-size:20px; color:var(--mh-slate); margin-bottom:6px; }
.mh-app .pg-stub p { color:var(--mh-muted); font-size:13.5px; }

/* shared form bits */
.mh-app .pl-sec-divider { font-family:var(--mh-font-head); font-size:15px; font-weight:600; color:var(--mh-slate); margin:20px 0 12px; padding-top:16px; border-top:1px solid var(--mh-line); }
.mh-app .dow-toggle { display:flex; gap:6px; flex-wrap:wrap; }
.mh-app .dow-toggle button { width:38px; height:38px; border-radius:10px; border:1.5px solid var(--mh-line); background:var(--mh-surface); font-family:var(--mh-font-body); font-weight:700; font-size:12px; color:var(--mh-muted); cursor:pointer; }
.mh-app .dow-toggle button.on { background:var(--mh-green); color:#fff; border-color:var(--mh-green); }

/* Students */
.mh-app .ns-bar { display:flex; align-items:flex-end; gap:22px; background:var(--mh-surface); border-radius:var(--mh-r-card); box-shadow:var(--mh-shadow-sm); padding:18px 20px; margin-bottom:18px; flex-wrap:wrap; }
/* Sessions kiosk-status bar: vertically CENTER the status text, checked-in meter, and Launch button. */
.mh-app .ns-bar.ns-kiosk { align-items:center; }
.mh-app .ns-prog { flex:1; min-width:240px; }
.mh-app .ns-prog label, .mh-app .ns-cap label { display:block; font-size:11.5px; font-weight:700; color:var(--mh-muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:6px; }
.mh-app .ns-prog select { width:100%; border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:12px 40px 12px 14px; font-family:var(--mh-font-body); font-size:14px; font-weight:600; color:var(--mh-ink); background-color:var(--mh-ctrl-fill); background-image:var(--mh-ctrl-caret); background-repeat:no-repeat; background-position:right 14px center; background-size:14px 14px; transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .ns-prog select:open { background-image:var(--mh-ctrl-caret-up); }
.mh-app .ns-prog select:focus { outline:none; background-color:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .ns-cap { min-width:210px; }
.mh-app .ns-cap-row { display:flex; align-items:baseline; justify-content:space-between; font-size:11.5px; font-weight:700; color:var(--mh-muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:6px; }
.mh-app .ns-cap-row b { font-family:var(--mh-font-head); font-size:18px; color:var(--mh-ink); letter-spacing:0; }
.mh-app .ns-meter { height:8px; border-radius:999px; background:var(--mh-cream-2); overflow:hidden; }
.mh-app .ns-meter span { display:block; height:100%; background:linear-gradient(90deg,var(--mh-green),var(--mh-green-d)); border-radius:999px; transition:width .3s; }
.mh-app .ns-cap-sub { font-size:12px; color:var(--mh-muted); margin-top:7px; }
.mh-app .ns-cap-sub b { color:var(--mh-clay-d); }
/* CAPACITY-ONLY STRIP (Jul 28 2026): once the class picker moved up into the filter row this
   bar holds nothing but the readout, so the meter FILLS THE CARD instead of sitting in a 210px
   stub with two-thirds of the card empty beside it. .ns-cap keeps its min-width for every other
   consumer (the kiosk bar, the sessions bar) - only this variant stretches. */
.mh-app .ns-bar--cap { align-items:stretch; }
.mh-app .ns-bar--cap .ns-cap { flex:1 1 auto; min-width:0; }
/* Full = the contract's pending_intake amber, the app's one warning hue. A green bar at 100%
   would read as "good" when what it actually means is "no seats left". */
.mh-app .ns-meter.is-full span { background:linear-gradient(90deg,#A67820,#7A5612); }
/* the same meter, reused small inside a class KPI card */
.mh-app .pg-cardmeter { margin:2px 0 12px; height:6px; }
.mh-app .ns-seg { margin-bottom:16px; }
.mh-app .ns-seg button span { font-size:11px; font-weight:700; padding:1px 7px; border-radius:999px; background:rgba(0,0,0,.06); margin-left:6px; }
.mh-app .ns-seg button.on span { background:rgba(255,255,255,.22); }
.mh-app .ns-into { font-size:13px; color:var(--mh-muted); margin:-2px 0 16px; }
.mh-app .ns-into b { color:var(--mh-ink); }
.mh-app .ns-pos { font-family:var(--mh-font-head); font-weight:700; font-size:15px; color:var(--mh-green-d); }
.mh-app .ns-act { display:inline-flex; gap:6px; }
.mh-app .ns-act button { border:1px solid var(--mh-line); background:var(--mh-surface); border-radius:9px; padding:5px 11px; font-family:var(--mh-font-body); font-size:12px; font-weight:600; color:var(--mh-ink); cursor:pointer; }
.mh-app .ns-act button:hover { background:var(--mh-cream-2); }
.mh-app .ns-act button.go { color:var(--mh-green-d); border-color:rgba(78,124,114,.4); }
.mh-app .ns-act button.rm { color:var(--mh-danger); border-color:rgba(176,70,60,.3); }
/* POLISH-04 ITEM 4: student KPI card footer - the secondary Exit/Remove action sits on the
   LEFT of the .idc-hhrow (margin-right:auto) opposite the primary View/Promote .btn-household,
   mirroring the Clients archived-card Restore-left pattern. Quiet by default, danger on hover. */
.mh-app .pg-stu-card .idc-hhrow { align-items:center; }
.mh-app .pg-exit-btn { margin-right:auto; border:1.5px solid var(--mh-line); background:var(--mh-surface); border-radius:10px; padding:7px 15px; font-family:var(--mh-font-body); font-weight:700; font-size:12.5px; color:var(--mh-muted); cursor:pointer; transition:.15s; }
.mh-app .pg-exit-btn:hover { color:var(--mh-danger); border-color:rgba(176,70,60,.5); background:rgba(176,70,60,.06); }
/* POLISH: child detail + add-child modals (rendered OUTSIDE #hhDetail, so the #hhDetail
   .hhedit styling can't reach them - style the fields here). */
.mh-app .stu-childmodal { width:440px; max-width:calc(94 * var(--mh-vw)); text-align:left; }
.mh-app .stu-childhero { display:flex; align-items:center; gap:14px; margin-bottom:18px; }
.mh-app .stu-childav { width:56px; height:56px; border-radius:50%; flex:none; display:grid; place-items:center; color:#fff; font-weight:800; font-size:17px; }
.mh-app .stu-childtype { font-size:10.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--mh-muted); }
.mh-app .stu-childmodal h3 { margin:2px 0; font-size:20px; }
.mh-app .stu-childsub { font-size:12.5px; color:var(--mh-muted); }
.mh-app .stu-childgrid2 { display:grid; grid-template-columns:1fr 1fr; gap:14px 16px; margin-bottom:18px; }
.mh-app .stu-childgrid2 .k { font-size:10.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--mh-muted); margin-bottom:3px; }
.mh-app .stu-childgrid2 .v { font-size:14px; font-weight:600; color:var(--mh-ink); }
.mh-app .stu-childedit { display:grid; grid-template-columns:1fr 1fr; gap:12px 14px; margin-bottom:14px; }
.mh-app .stu-childedit .hhfld { display:flex; flex-direction:column; gap:5px; min-width:0; }
.mh-app .stu-childedit .hhfld.full { grid-column:1 / -1; }
.mh-app .stu-childedit label { font-size:10.5px; font-weight:800; letter-spacing:.4px; text-transform:uppercase; color:var(--mh-muted); }
.mh-app .stu-childedit input { width:100%; font-family:inherit; font-size:13.5px; border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:11px 13px; color:var(--mh-ink); background:var(--mh-ctrl-fill); transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .stu-childedit input:focus { outline:none; border-color:var(--mh-ctrl-focus-border); background-color:var(--mh-surface); box-shadow:var(--mh-ctrl-focus-ring); }
/* The student initials sit in the reused .idc-ph circle (no PhotoPath from the roster proc). */
.mh-app .pg-stu-card .idc-ph { font-size:17px; }
/* Export roster menu (REBUILD-03) - ported from mh-dashboard.html 543-547. */
.mh-app .exp-wrap { position:relative; }
/* Sits BELOW the button with a real gap (CEO, Aug 3 2026). The old top:26px was a magic number
   measured against one button height, so the menu crowded the trigger and clipped its focus ring.
   calc(100% + 8px) hangs it off the wrapper's own height, so it stays correct if the toolbar
   button ever changes size. */
.mh-app .exp-menu { position:absolute; right:0; top:calc(100% + 8px); width:172px; background:var(--mh-surface); border:1px solid var(--mh-line); border-radius:12px; box-shadow:var(--mh-shadow-lg); z-index:60; padding:6px; display:none; }
/* Just under the menu (60) rather than the shared backdrop's 15, so it reliably catches clicks
   on the roster cards and toolbar beneath it while the menu itself stays clickable. */
.mh-app .exp-backdrop { z-index:59; }
.mh-app .exp-menu.on { display:block; animation:fadeDown .14s ease; }
.mh-app .exp-item { display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:9px; font-size:13px; font-weight:600; color:var(--mh-ink); cursor:pointer; }
.mh-app .exp-item:hover { background:var(--mh-cream-2); }
/* Student detail Status & access + enroll children/attachments (REBUILD-03B, mock 563,754-782,859). */
.mh-app .wd-access { display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.mh-app .wd-access .acc-state { font-weight:700; font-size:14px; }
.mh-app .wd-abtn { border:1.5px solid var(--mh-line); background:var(--mh-surface); border-radius:10px; padding:9px 16px; font-family:var(--mh-font-body); font-weight:700; font-size:13px; cursor:pointer; }
.mh-app .wd-abtn.susp { color:var(--mh-warning-d); border-color:rgba(216,155,61,.45); }
.mh-app .wd-abtn.deact { color:var(--mh-danger); border-color:rgba(176,70,60,.4); }
.mh-app .wd-abtn.react { color:var(--mh-green-d); border-color:rgba(78,124,114,.45); }
.mh-app .wd-abtn:hover { background:var(--mh-cream-2); }
.mh-app .wd-accbanner { border-radius:12px; padding:12px 16px; font-size:13.5px; font-weight:600; margin-bottom:12px; display:flex; align-items:center; gap:10px; }
.mh-app .wd-accbanner.susp { background:rgba(216,155,61,.12); border:1px solid rgba(216,155,61,.4); color:var(--mh-warning-d); }
.mh-app .wd-accbanner.deact { background:rgba(176,70,60,.1); border:1px solid rgba(176,70,60,.35); color:var(--mh-danger); }
.mh-app .rsn-ic.susp { background:rgba(216,155,61,.16); color:var(--mh-warning-d); }
.mh-app .rsn-ic.deact { background:rgba(176,70,60,.13); color:var(--mh-danger); }
.mh-app .rsn-text { width:100%; border:1.5px solid var(--mh-line); border-radius:11px; padding:11px 13px; font-family:var(--mh-font-body); font-size:14px; color:var(--mh-ink); background:var(--mh-surface); box-sizing:border-box; margin-bottom:16px; resize:vertical; min-height:72px; }
.mh-app .rsn-text:focus { outline:none; border-color:var(--mh-green); }
.mh-app .btn.rsn-susp { background:var(--mh-warning); color:#fff; }
.mh-app .wk-addbtn { display:inline-flex; align-items:center; justify-content:center; gap:7px; width:100%; border:1.5px dashed var(--mh-line); background:none; border-radius:11px; padding:10px 14px; font-family:var(--mh-font-body); font-weight:700; font-size:13px; color:var(--mh-green-d); cursor:pointer; }
.mh-app .wk-addbtn:hover { background:var(--mh-cream-2); border-color:var(--mh-green); }
.mh-app .att-drop { display:flex; flex-direction:column; align-items:center; gap:8px; border:1.6px dashed var(--mh-line); border-radius:12px; padding:22px; color:var(--mh-muted); cursor:pointer; text-align:center; font-size:13.5px; font-weight:600; transition:.15s; }
.mh-app .att-drop:hover { border-color:var(--mh-green); color:var(--mh-green-d); background:var(--mh-cream-2); }
.mh-app .att-drop b { color:var(--mh-green-d); }
.mh-app .ns-name { cursor:pointer; }
.mh-app .ns-name:hover { color:var(--mh-green); text-decoration:underline; }
.mh-app .en-seg { display:inline-flex; background:var(--mh-cream); border:1px solid var(--mh-line); border-radius:var(--mh-r-pill); padding:4px; margin:6px 0 18px; }
.mh-app .en-seg button { border:none; background:none; font-family:var(--mh-font-body); font-weight:600; font-size:13px; color:var(--mh-muted); padding:7px 20px; border-radius:999px; cursor:pointer; }
.mh-app .en-seg button.on { background:var(--mh-green); color:#fff; }
.mh-app .wk-kidpick { display:flex; align-items:center; gap:10px; padding:10px 12px; border:1px solid var(--mh-line); border-radius:11px; margin-bottom:8px; cursor:pointer; font-size:14px; color:var(--mh-ink); }
.mh-app .wk-kidpick:hover { background:var(--mh-cream-2); }
.mh-app .wk-kidpick em { color:var(--mh-muted); font-style:normal; font-size:12.5px; margin-left:auto; }
.mh-app .ns-roster table { width:100%; border-collapse:collapse; }
.mh-app .ns-roster th { text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.5px; color:var(--mh-muted); font-weight:700; padding:8px 10px; border-bottom:1px solid var(--mh-line); }
.mh-app .ns-roster td { padding:11px 10px; border-bottom:1px solid var(--mh-line); font-size:13.5px; vertical-align:middle; }
.mh-app .ns-roster tr:last-child td { border-bottom:none; }
.mh-app .ns-roster td.team { color:var(--mh-muted); }
.mh-app .ns-roster .nm { font-weight:700; color:var(--mh-ink); }
.mh-app .ns-roster .sub { font-size:12px; color:var(--mh-muted); }

/* REBUILD-04: Program schedules table + kiosk launch guard (ported from mh-dashboard.html
   595-598 / 695-697; #F0ECE3 swapped for var(--mh-line) so it stays theme-correct). */
.mh-app .sched-tbl { width:100%; border-collapse:collapse; }
.mh-app .sched-tbl th { text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.4px; color:var(--mh-muted); font-weight:700; padding:11px 16px; border-bottom:1px solid var(--mh-line); }
.mh-app .sched-tbl td { padding:11px 16px; border-bottom:1px solid var(--mh-line); }
.mh-app .sched-tbl tr:last-child td { border-bottom:none; }
/* COLUMN WIDTHS (Aug 15 2026). Two passes, and the second is the one that matters.
   FIRST: adding the Edit button gave the actions column a second control, and with no
   widths declared the browser took that space out of the neighbours - "Aug 25 - Dec 15,
   2026" broke onto two lines and every row grew taller. Fixed by naming a column that
   absorbs slack and holding the rest to one line.
   SECOND: that slack was put on the term NAME, which then ate every spare pixel - the
   name column ran to well over half the table and threw Dates / Days / Pts / Status out
   to the right edge, far from the row they describe. The slack belongs on the ACTIONS
   column instead: its buttons are right-aligned, so the empty space lands harmlessly
   between the data and the buttons, and the four data columns close back up against the
   name where they can be read as one group. The name still gets a generous share and is
   still the only column allowed to wrap. */
.mh-app .sched-tbl th:first-child,
.mh-app .sched-tbl td:first-child { width:44%; }
.mh-app .sched-tbl th:last-child,
.mh-app .sched-tbl td:last-child { width:100%; }
.mh-app .sched-tbl th:not(:first-child),
.mh-app .sched-tbl td:not(:first-child) { white-space:nowrap; }
/* The two action buttons are a pair and must never stack. */
.mh-app .sched-tbl td:last-child .ns-act { flex-wrap:nowrap; justify-content:flex-end; }
/* The class time, beside its weekday. Quieter than the day because the day is what you
   scan for and the time is what you check once you have found it. */
.mh-app .sched-tbl .sc-time { margin-left:7px; color:var(--mh-muted); font-size:12px; font-variant-numeric:tabular-nums; }
/* The bucket seg sits in the card heading, so it must not inherit the heading's weight. */
.mh-app .card__head .seg.sess-statusseg { flex:none; }
.mh-app .kiosk-guard { display:flex; align-items:center; gap:10px; background:rgba(216,155,61,.12); border:1px solid rgba(216,155,61,.4); color:var(--mh-warning-d); border-radius:12px; padding:12px 16px; margin-bottom:18px; font-size:13.5px; font-weight:600; }
.mh-app .kiosk-guard svg { width:18px; height:18px; flex:none; }

/* Student detail popup */
.mh-app .wd-sheet, .wd-sheet { position:relative; width:880px; max-width:calc(94 * var(--mh-vw)); max-height:calc(88 * var(--mh-vh)); display:flex; flex-direction:column; overflow:hidden; background:var(--mh-surface); border-radius:22px; box-shadow:0 24px 70px rgba(33,50,58,.35); animation:wdPop .2s ease; }
.mh-app .wd-x, .wd-x { position:absolute; top:16px; right:16px; background:rgba(255,255,255,.18); color:#fff; border:none; width:34px; height:34px; border-radius:50%; font-size:19px; line-height:1; cursor:pointer; z-index:5; display:grid; place-items:center; }
.mh-app .wd-x:hover { background:rgba(255,255,255,.3); }
.mh-app .wd-hero { display:flex; gap:30px; align-items:center; padding:30px 38px; background:linear-gradient(135deg,#2E4A43 0%,#3D655D 60%,#4E7C72 100%); color:#fff; position:relative; overflow:hidden; }
.mh-app .wd-hero::after { content:""; position:absolute; right:-60px; top:-60px; width:240px; height:240px; border-radius:50%; border:2px solid rgba(255,255,255,.06); }
.mh-app .wd-photo-img { width:108px; height:108px; border-radius:26px; background:linear-gradient(145deg,#9FBDB2,#34454D); display:grid; place-items:center; font-family:var(--mh-font-head); font-size:38px; font-weight:800; color:#fff; box-shadow:0 10px 28px rgba(0,0,0,.25); border:4px solid rgba(255,255,255,.9); flex:0 0 auto; }
.mh-app .wd-hero-info { flex:1; min-width:0; position:relative; z-index:1; }
.mh-app .wd-badges { display:flex; align-items:center; gap:10px; margin-bottom:8px; flex-wrap:wrap; }
.mh-app .wd-code { font-family:var(--mono); font-size:12px; font-weight:700; letter-spacing:.05em; color:rgba(255,255,255,.85); background:rgba(255,255,255,.16); border-radius:999px; padding:4px 12px; }
.mh-app .wd-hero-info h2 { font-family:var(--mh-font-head); font-size:30px; font-weight:800; margin:0 0 10px; color:#fff; letter-spacing:-.01em; }
.mh-app .wd-chips { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:16px; }
.mh-app .wd-chips span { font-size:12.5px; font-weight:600; background:rgba(255,255,255,.14); border-radius:999px; padding:5px 13px; color:#fff; }
.mh-app .wd-quickstats { display:flex; gap:30px; }
.mh-app .wd-quickstats b { display:block; font-family:var(--mh-font-head); font-size:23px; color:#fff; line-height:1.1; }
.mh-app .wd-quickstats span { font-size:10.5px; text-transform:uppercase; letter-spacing:.6px; color:rgba(255,255,255,.72); font-weight:700; }
.mh-app .wd-body { padding:24px 38px; display:grid; grid-template-columns:1fr 1fr; gap:18px; overflow:auto; }
.mh-app .wd-card { background:var(--mh-cream-2); border-radius:16px; padding:18px 20px; box-shadow:var(--mh-shadow-sm); }
.mh-app .wd-card.wide { grid-column:1 / -1; }
.mh-app .wd-card h4 { font-family:var(--mh-font-head); font-size:15px; font-weight:600; color:var(--mh-slate); margin:0 0 15px; display:flex; align-items:center; gap:8px; }
.mh-app .wd-grid { display:grid; grid-template-columns:1fr 1fr; gap:13px 20px; }
.mh-app .wd-f .l { display:block; font-size:10.5px; text-transform:uppercase; letter-spacing:.4px; color:var(--mh-muted); font-weight:700; margin-bottom:3px; }
.mh-app .wd-f .v { font-size:14.5px; color:var(--mh-ink); font-weight:600; }
.mh-app .wd-prow { display:flex; align-items:center; gap:13px; padding:11px 0; border-top:1px solid var(--mh-line); }
.mh-app .wd-prow:first-child { border-top:none; padding-top:0; }
.mh-app .wd-prow .av { width:42px; height:42px; border-radius:12px; display:grid; place-items:center; color:#fff; font-weight:800; font-size:14px; flex:0 0 auto; }
.mh-app .wd-prow .nm { font-size:15px; font-weight:700; color:var(--mh-ink); }
.mh-app .wd-prow .sub { font-size:12.5px; color:var(--mh-muted); }
.mh-app .wd-foot { background:var(--mh-surface); border-top:1px solid var(--mh-line); padding:16px 38px; display:flex; justify-content:flex-end; gap:10px; }
.mh-app .wd-pts-row { display:flex; align-items:center; justify-content:space-between; gap:14px; }
.mh-app .wd-pts-big { font-family:var(--mh-font-head); font-size:34px; font-weight:800; color:var(--mh-green-d); line-height:1; }
.mh-app .wd-pts-big span { display:block; font-family:var(--mh-font-body); font-size:11px; text-transform:uppercase; letter-spacing:.4px; color:var(--mh-muted); font-weight:700; margin-top:4px; }
.mh-app .wd-setsel { border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:8px 11px; font-family:var(--mh-font-body); font-size:13px; font-weight:600; color:var(--mh-ink); background:var(--mh-ctrl-fill); transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .wd-setsel:focus { outline:none; background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }

/* Attendance roster + Program Sessions (Phase 3) */
.mh-app .att-bar { align-items:flex-end; }
.mh-app .att-actions { display:flex; gap:8px; align-items:flex-end; margin-left:auto; }
/* REBUILD-05: attendance matrix (ported from mh-dashboard.html 599-694, 769; #F0ECE3 -> var(--mh-line)). */
.mh-app .att-bar2 { align-items:flex-end; gap:20px; flex-wrap:wrap; }
.mh-app .att-views { display:flex; flex-direction:column; gap:10px; align-items:flex-end; }
.mh-app .att-nav { display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
/* Planner-matched cool nav buttons (.pl-today / .pl-nav): #DFE4EA inset pills, hover-lift. */
.mh-app .att-nav>button { border:1px solid rgba(40,60,80,.08); background:#DFE4EA; box-shadow:inset 0 1px 2px rgba(40,60,80,.10); border-radius:9px; width:34px; height:34px; font-size:17px; line-height:1; cursor:pointer; color:var(--mh-slate); transition:background .15s, border-color .15s, box-shadow .15s; }
.mh-app .att-nav>button#attToday { width:auto; padding:0 16px; margin-right:12px; border-radius:var(--mh-r-pill); font-family:var(--mh-font-body); font-weight:700; font-size:13px; color:var(--mh-ink); }  /* extra gap so Today is not next to the ‹ › arrows */
.mh-app .att-nav>button:hover { background:#fff; border-color:rgba(40,60,80,.16); box-shadow:0 10px 28px rgba(40,60,80,.12); }
body.dark .mh-app .att-nav>button { background:var(--mh-ctrl-fill); border-color:var(--mh-line); box-shadow:inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app .att-nav>button:hover { background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .att-custom { display:inline-flex; align-items:center; gap:10px; font-size:14px; color:var(--mh-muted); }
/* Date fields = search-bar look (cool #DFE4EA inset pill, white-on-focus), 44px tall to
   match the Weekly/Monthly/3 days/Custom toggle height. */
.mh-app .att-custom input[type=date] {
  background:#DFE4EA; border:1px solid rgba(40,60,80,.08); box-shadow:inset 0 1px 2px rgba(40,60,80,.10);
  border-radius:999px; height:44px; box-sizing:border-box; padding:0 18px;
  display:inline-flex; align-items:center;   /* vertically center the date value + calendar icon */
  font-family:var(--mh-font-body); font-size:14px; font-weight:600; color:var(--mh-ink);
  transition:background .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.mh-app .att-custom input[type=date]::-webkit-datetime-edit { padding:0; line-height:normal; }
.mh-app .att-custom input[type=date]::-webkit-calendar-picker-indicator { margin-left:6px; opacity:.55; cursor:pointer; }
.mh-app .att-custom input[type=date]:focus { outline:none; background:#fff; border-color:rgba(40,60,80,.16); box-shadow:0 10px 28px rgba(40,60,80,.12); }
body.dark .mh-app .att-custom input[type=date] { background:var(--mh-ctrl-fill); border-color:var(--mh-line); box-shadow:inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app .att-custom input[type=date]:focus { background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
/* PROGRAM FILTER BAR (Attendance / Sessions / Programs): a TRANSPARENT filter area that
   sits directly on the page (NOT a white card) - matches the other tabs' toolbars. The
   controls carry their own fills (cool .seg, inset search, #DFE4EA nav buttons) so they
   read fine on the gray page. Attendance = 2 rows (time+search / program); others = 1 row. */
.mh-app .att-filter { background:none; box-shadow:none; border-radius:0; padding:0; margin-bottom:8px; }
.mh-app .att-filter-row { display:flex; align-items:center; gap:16px; padding:10px 0; flex-wrap:wrap; }
.mh-app .att-filter-row--time .att-nav { padding-left:16px; border-left:1px solid var(--mh-line); }   /* sits next to the toggle with a subtle divider; search right-aligns */
.mh-app .att-filter-row--data { align-items:flex-end; }   /* Program on its own lane (no card, no divider) */
.mh-app .att-filter-row--data .att-prog { flex:0 1 440px; min-width:260px; }   /* Program sized to content, not full width */
.mh-app .att-filter-row--data .att-search { margin-left:auto; }     /* search hugs the right edge */
/* Sessions/Programs reuse .att-filter as a single lane: filters left, search right. */
.mh-app .att-filter-row .att-search { margin-left:auto; }           /* search hugs the right edge (single-row tabs) */
.mh-app .att-filter .mh-sel select { height:40px; box-sizing:border-box; padding-top:0; padding-bottom:0; }  /* match the 40px seg/search height */

/* PROGRAM FIELD (Attendance) styled like the search bar: cool #DFE4EA inset PILL, fully
   rounded, white-on-focus. In Chromium the native option list is upgraded via
   appearance:base-select to a rounded, spaced popup with padded rows; other browsers keep
   the native list (the field styling still applies). */
.mh-app .att-prog .mh-selwrap > select {
  background:#DFE4EA; border:1px solid rgba(40,60,80,.08); box-shadow:inset 0 1px 2px rgba(40,60,80,.10);
  border-radius:999px; padding:12px 44px 12px 20px; font-weight:600; color:var(--mh-ink);
  transition:background .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.mh-app .att-prog .mh-selwrap > select:hover { border-color:rgba(40,60,80,.16); }
.mh-app .att-prog .mh-selwrap > select:focus,
.mh-app .att-prog .mh-selwrap > select:open {
  outline:none; background:#fff; border-color:rgba(40,60,80,.16); box-shadow:0 10px 28px rgba(40,60,80,.12);
}
body.dark .mh-app .att-prog .mh-selwrap > select { background:var(--mh-ctrl-fill); border-color:var(--mh-line); box-shadow:inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app .att-prog .mh-selwrap > select:focus,
body.dark .mh-app .att-prog .mh-selwrap > select:open { background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }

@supports (appearance: base-select) {
  .mh-app .att-prog .mh-selwrap > select { appearance:base-select; }
  .mh-app .att-prog .mh-selwrap > .selchev { display:none; }                    /* base-select draws its own icon */
  .mh-app .att-prog .mh-selwrap > select::picker-icon { color:var(--mh-muted); transition:transform .2s ease; }
  .mh-app .att-prog .mh-selwrap > select:open::picker-icon { transform:rotate(180deg); }
  .mh-app .att-prog .mh-selwrap > select::picker(select) {
    appearance:base-select;
    width:300px; box-sizing:border-box;   /* SAME width as the field */
    /* GAP between field and list: translate reliably renders the offset; margin-top on an
       anchor-positioned picker does not always produce a visible gap in current Chromium. */
    translate:0 10px;
    border:1px solid var(--mh-line); border-radius:16px;
    background:var(--mh-surface); box-shadow:var(--mh-shadow-lg); padding:6px; overflow:clip;
  }
  .mh-app .att-prog .mh-selwrap > select option {
    border-radius:10px; padding:10px 14px; font-weight:500; color:var(--mh-ink);
    font-family:var(--mh-font-body); font-size:14px;
  }
  .mh-app .att-prog .mh-selwrap > select option:hover,
  .mh-app .att-prog .mh-selwrap > select option:focus { background:var(--mh-cream-2); }
  .mh-app .att-prog .mh-selwrap > select option:checked { background:var(--mh-cream-2); font-weight:700; }
  .mh-app .att-prog .mh-selwrap > select option::checkmark { display:none; }    /* selection shown via bg + bold */
}
/* Compact INLINE Program field (sits right of the search bar): width fits its content so
   the arrow sits right after the text instead of stretching the field wide. */
.mh-app .att-prog--inline { flex:0 0 auto; min-width:0; align-self:center; }
.mh-app .att-prog--inline .mh-selwrap { width:auto; }
.mh-app .att-prog--inline .mh-selwrap > select { width:300px; height:40px; box-sizing:border-box; padding:0 18px 0 20px; display:inline-flex; align-items:center; }  /* fixed 300px so field + dropdown list are the SAME width (fits the longest program name); 40px height matches the search bar; flex centers label+arrow */
/* Placeholder state ("Select a program") matches the GLOBAL topbar search placeholder
   (#9AA7B3 / --mh-ctrl-ico dark, weight 400, opacity .6). */
.mh-app .att-prog--inline .mh-selwrap > select.is-placeholder { color:#9AA7B3; opacity:.6; font-weight:400; }
body.dark .mh-app .att-prog--inline .mh-selwrap > select.is-placeholder { color:var(--mh-ctrl-ico); }
/* Filter-area search placeholders are LEFT to inherit the global .bigbar input::placeholder
   (same #9AA7B3 / --mh-ctrl-ico, weight 400, opacity .6) - so every search matches the global search. */
.mh-app .att-legend { display:flex; gap:18px; padding:14px 20px; border-bottom:1px solid var(--mh-line); font-size:12.5px; color:var(--mh-muted); font-weight:600; flex-wrap:wrap; align-items:center; }
.mh-app .att-legend span { display:inline-flex; align-items:center; gap:6px; }
.mh-app .att-legend i { width:14px; height:14px; border-radius:5px; display:inline-block; }
.mh-app .att-scroll { overflow-x:auto; }
.mh-app .att-grid { border-collapse:separate; border-spacing:0; width:100%; }
.mh-app .att-grid thead th { position:sticky; top:0; background:var(--mh-surface); z-index:2; padding:12px 6px; font-size:11px; color:var(--mh-muted); font-weight:700; text-transform:uppercase; letter-spacing:.4px; border-bottom:1px solid var(--mh-line); }
.mh-app .att-dcol { text-align:center; min-width:52px; }
.mh-app .att-dcol .dw { display:block; font-size:10px; }
.mh-app .att-dcol .dn { display:block; font-family:var(--mh-font-head); font-size:15px; color:var(--mh-ink); letter-spacing:0; text-transform:none; }
.mh-app .att-stick { position:sticky; left:0; background:var(--mh-surface); z-index:1; min-width:236px; max-width:236px; text-align:left; padding:11px 16px !important; border-right:1px solid var(--mh-line); }
.mh-app thead .att-stick { z-index:3; }
.mh-app .att-trow td { border-bottom:1px solid var(--mh-line); }
.mh-app .att-trow:hover .att-stick { background:var(--mh-cream-2); }
.mh-app .att-trow.kid .att-stick { background:var(--mh-cream-2); }
.mh-app .att-trow.kid .fam { padding-left:22px; }
.mh-app .att-name { cursor:pointer; }
.mh-app .att-name:hover { color:var(--mh-green); text-decoration:underline; }
.mh-app .att-kt { cursor:pointer; color:var(--mh-green-d); font-weight:700; margin-left:6px; white-space:nowrap; }
.mh-app .att-cell { text-align:center; height:48px; cursor:pointer; }
.mh-app .att-cell .cm { display:inline-flex; width:27px; height:27px; border-radius:8px; align-items:center; justify-content:center; border:1.5px solid var(--mh-line); color:#fff; position:relative; }
.mh-app .att-cell .cm svg { width:16px; height:16px; }
.mh-app .att-cell.empty .cm { border-color:var(--mh-line); }
.mh-app .att-cell.empty:hover .cm { border-color:var(--mh-green); background:rgba(78,124,114,.08); }
.mh-app .att-cell.done .cm { background:var(--mh-green); border-color:var(--mh-green); }
.mh-app .att-cell.auto { cursor:default; }
.mh-app .att-cell.auto .cm { box-shadow:0 0 0 3px rgba(78,124,114,.16); }
.mh-app .att-cell.miss .cm { background:rgba(176,70,60,.12); border-color:rgba(176,70,60,.4); color:var(--mh-danger); }
.mh-app .att-cell.exc .cm { background:rgba(216,155,61,.14); border-color:rgba(216,155,61,.45); color:var(--mh-warning-d); }
.mh-app .att-cell.future { cursor:default; }
.mh-app .att-cell.future .cm { border-style:dashed; opacity:.45; }
.mh-app .att-cell.closed { background:rgba(201,123,90,.10); cursor:default; }
.mh-app .att-cell.noclass { background:rgba(138,139,131,.05); cursor:default; }
.mh-app .att-dcol.closed { background:rgba(201,123,90,.08); }
.mh-app .att-dcol.closed .dw, .mh-app .att-dcol.closed .dn { color:#B5663F; }
.mh-app .att-dcol.noclass .dw, .mh-app .att-dcol.noclass .dn { color:var(--mh-muted); }
.mh-app .att-holiday-banner { display:flex; align-items:center; justify-content:center; gap:10px; background:rgba(201,123,90,.10); border:1px solid rgba(201,123,90,.35); color:#B5663F; border-radius:12px; padding:11px 16px; margin:14px 20px; font-size:13.5px; font-weight:600; line-height:1.35; text-align:center; }
.mh-app .att-holiday-banner svg { width:18px; height:18px; flex:none; }
.mh-app .att-period-wrap { position:relative; display:inline-block; }
.mh-app .att-period-btn { display:inline-flex; align-items:center; gap:8px; background:none; border:none; cursor:pointer; font-family:var(--mh-font-head); font-weight:600; font-size:15px; color:var(--mh-ink); min-width:150px; justify-content:center; padding:6px 10px; border-radius:9px; }
.mh-app .att-period-btn:hover { background:var(--mh-cream-2); }
.mh-app .att-period-btn svg { width:13px; height:13px; color:var(--mh-muted); }
.mh-app .att-navpop { position:absolute; top:46px; left:50%; transform:translateX(-50%); width:300px; background:var(--mh-surface); border:1px solid var(--mh-line); border-radius:16px; box-shadow:var(--mh-shadow-lg); z-index:200; padding:14px; display:none; }
.mh-app .att-navpop.on { display:block; }
.mh-app .anp-yr { display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
.mh-app .anp-yr span { font-family:var(--mh-font-head); font-weight:700; font-size:16px; }
.mh-app .anp-yr button { border:1px solid var(--mh-line); background:var(--mh-surface); border-radius:8px; width:30px; height:30px; cursor:pointer; font-size:15px; color:var(--mh-ink); }
.mh-app .anp-allmonth { width:100%; margin-bottom:10px; border:1px solid var(--mh-line); background:var(--mh-cream-2); border-radius:10px; padding:9px 0; font-family:var(--mh-font-body); font-weight:700; font-size:12.5px; color:var(--mh-green-d); cursor:pointer; }
.mh-app .anp-back { font-size:12px; color:var(--mh-green-d); cursor:pointer; font-weight:700; margin-bottom:10px; display:inline-block; }
.mh-app .anp-months { display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.mh-app .anp-months button { border:1px solid var(--mh-line); background:var(--mh-surface); border-radius:10px; padding:10px 0; font-family:var(--mh-font-body); font-weight:600; font-size:13px; color:var(--mh-ink); cursor:pointer; }
.mh-app .anp-months button:hover { background:var(--mh-cream-2); }
.mh-app .anp-months button.cur { background:var(--mh-green); color:#fff; border-color:var(--mh-green); }
.mh-app .anp-dhead { display:grid; grid-template-columns:repeat(7,1fr); gap:3px; margin-bottom:4px; }
.mh-app .anp-dhead span { text-align:center; font-size:9.5px; color:var(--mh-muted); font-weight:700; }
.mh-app .anp-dgrid { display:grid; grid-template-columns:repeat(7,1fr); gap:3px; }
.mh-app .anp-d { aspect-ratio:1; border-radius:7px; display:flex; align-items:center; justify-content:center; font-size:12px; cursor:pointer; color:var(--mh-ink); }
.mh-app .anp-d:hover { background:var(--mh-green); color:#fff; }
.mh-app .anp-d.empty { visibility:hidden; cursor:default; }
.mh-app .att-cell .lk { position:absolute; right:-5px; bottom:-5px; width:14px; height:14px; background:var(--mh-green-d); border-radius:50%; display:grid; place-items:center; }
.mh-app .att-cell .lk svg { width:8px; height:8px; }
.mh-app .att-ptscol { text-align:center; font-family:var(--mh-font-head); font-weight:700; color:var(--mh-green-d); min-width:54px; }
.mh-app thead .att-ptscol { color:var(--mh-muted); font-family:var(--mh-font-body); }
/* ============================================================
   ATTENDANCE STUDENT DETAIL - centered master-detail popup.
   Mock "Attendance Calendar" V3: family roster rail (adult on
   top, children below) on the left; the selected person's month
   calendar + legend + stats on the right. Replaces the old
   right-side pl-sheet drawer. Mapped to --mh-* tokens + dark.
   ============================================================ */
.mh-app .pl-overlay.att-detail { justify-content:center; align-items:center;
  background:radial-gradient(120% 90% at 50% 0%, rgba(52,69,77,.5) 38%, rgba(20,28,26,.66)); padding:40px 24px; overflow:auto; }
.mh-app .adx-card { width:820px; max-width:100%; background:var(--mh-surface); border-radius:22px; display:flex; overflow:hidden;
  max-height:min(660px, calc(calc(100 * var(--mh-vh)) - 80px)); box-shadow:0 50px 110px rgba(13,22,26,.5), 0 8px 24px rgba(13,22,26,.28);
  animation:pl-menu-in .14s ease-out; }

/* left: family roster rail (cool neutral) */
.mh-app .adx-rail { flex:0 0 266px; background:var(--mh-cream-2); border-right:1px solid var(--mh-line-cool);
  padding:20px 16px; display:flex; flex-direction:column; gap:4px; overflow-y:auto; }
.mh-app .adx-railh, .mh-app .adx-kidslbl { font-size:11px; font-weight:800; letter-spacing:.13em; text-transform:uppercase; color:var(--mh-muted); padding:0 8px; }
.mh-app .adx-railh { margin-bottom:8px; }
.mh-app .adx-kidslbl { margin:16px 0 6px; }
.mh-app .adx-ros { display:flex; align-items:center; gap:12px; width:100%; padding:11px 12px; border:none; border-radius:13px;
  background:transparent; cursor:pointer; text-align:left; font-family:var(--mh-font-body); transition:background .16s ease, box-shadow .16s ease; }
.mh-app .adx-ros:hover { background:var(--mh-surface); }
.mh-app .adx-ros.on { background:var(--mh-surface); box-shadow:var(--mh-shadow); }
.mh-app .adx-ros .av { width:40px; height:40px; border-radius:12px; display:grid; place-items:center; color:#fff; font-weight:800; font-size:13px; font-family:var(--mh-font-head); flex:0 0 auto; overflow:hidden; }
.mh-app .adx-ros .av img { width:100%; height:100%; object-fit:cover; }
.mh-app .adx-ros.child .av { width:34px; height:34px; font-size:12px; }
.mh-app .adx-rtx { flex:1; min-width:0; }
.mh-app .adx-rnm { display:block; font-size:14.5px; font-weight:700; color:var(--mh-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mh-app .adx-rsub { display:block; font-size:12px; font-weight:600; color:var(--mh-muted); margin-top:2px; }
.mh-app .adx-rbar { width:44px; height:6px; border-radius:99px; background:var(--mh-line-cool); overflow:hidden; flex:0 0 auto; }
.mh-app .adx-rbar i { display:block; height:100%; border-radius:99px; background:var(--mh-green); }

/* right: detail pane */
.mh-app .adx-detail { flex:1; min-width:0; padding:26px 28px 28px; overflow-y:auto; }
.mh-app .adx-top { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; margin-bottom:22px; }
.mh-app .adx-name { font-family:'Bricolage Grotesque',var(--mh-font-head); font-size:24px; font-weight:700; color:var(--mh-ink); line-height:1.05; letter-spacing:-.01em; }
.mh-app .adx-sub { font-size:13px; color:var(--mh-muted); font-weight:600; margin-top:7px; }
.mh-app .adx-x { flex:0 0 auto; width:38px; height:38px; border-radius:11px; display:grid; place-items:center; border:none; cursor:pointer;
  font-size:22px; line-height:1; color:var(--mh-muted); background:var(--mh-cream-2); transition:.15s; }
.mh-app .adx-x:hover { background:var(--mh-line-cool); color:var(--mh-ink); }
.mh-app .adx-legend { display:flex; flex-wrap:wrap; gap:8px 16px; margin-top:14px; }
.mh-app .adx-legend span { display:flex; align-items:center; gap:7px; font-size:12px; font-weight:600; color:var(--mh-muted); }
.mh-app .adx-legend i { width:12px; height:12px; border-radius:5px; flex:0 0 auto; }
.mh-app .adx-legend .lg-present { background:#4E7C72; }
.mh-app .adx-legend .lg-missed { background:#C15F45; }
.mh-app .adx-legend .lg-noclass { background:#F6ECE5; }

/* calendar - mock-exact sizing + colors inside the detail pane */
.mh-app .adx-detail .ad-cal .dcal-head { gap:8px; margin-bottom:9px; }
.mh-app .adx-detail .ad-cal .dcal-head span { font-size:11px; font-weight:800; letter-spacing:.06em; }
.mh-app .adx-detail .ad-cal .dcal-grid { gap:8px; }
.mh-app .adx-detail .ad-cal .dcell { border-radius:13px; font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; }
.mh-app .adx-detail .ad-cal .dcell.meet { background:var(--mh-surface); border-color:var(--mh-line); color:var(--mh-ink); }
.mh-app .adx-detail .ad-cal .dcell.closed { background:#F6ECE5; border-color:transparent; color:#B5623A; font-weight:700; }
.mh-app .adx-detail .ad-cal .dcell.noclass { background:rgba(138,139,131,.06); border-color:transparent; color:var(--mh-muted); }
.mh-app .adx-detail .ad-cal .dcell.present { background:#4E7C72; border-color:transparent; color:#fff; font-weight:800; box-shadow:0 6px 14px -4px rgba(59,95,88,.5); }
.mh-app .adx-detail .ad-cal .dcell.missed { background:#C15F45; border-color:transparent; color:#fff; font-weight:800; box-shadow:0 6px 14px -4px rgba(193,95,69,.45); }
.mh-app .adx-detail .ad-cal .dcell.excused { background:rgba(216,155,61,.9); border-color:transparent; color:#fff; font-weight:800; box-shadow:0 6px 14px -4px rgba(216,155,61,.4); }
.mh-app .adx-detail .ad-cal .dcell.today { position:relative; }
.mh-app .adx-detail .ad-cal .dcell.today::after { content:""; position:absolute; inset:0; border-radius:inherit; box-shadow:0 0 0 2px var(--mh-surface),0 0 0 4px #4E7C72; }
.mh-app .adx-detail .ad-cal .dcell.today.meet::after, .mh-app .adx-detail .ad-cal .dcell.today.closed::after, .mh-app .adx-detail .ad-cal .dcell.today.noclass::after { box-shadow:0 0 0 2px #4E7C72; }
.mh-app .adx-detail .ad-stats { margin:18px 0 0; gap:10px; }
.mh-app .adx-detail .adstat { border-radius:13px; padding:14px 14px 12px; text-align:left; }
.mh-app .adx-detail .adstat b { font-size:25px; font-weight:800; letter-spacing:-.01em; font-variant-numeric:tabular-nums; }
.mh-app .adx-detail .adstat span { font-size:10.5px; font-weight:800; letter-spacing:.1em; margin-top:8px; }

/* attendance detail overlay */
.mh-app .ad-cal .dcal-head { display:grid; grid-template-columns:repeat(7,1fr); gap:5px; margin-bottom:6px; }
.mh-app .ad-cal .dcal-head span { text-align:center; font-size:10.5px; font-weight:700; color:var(--mh-muted); text-transform:uppercase; }
.mh-app .ad-cal .dcal-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:5px; }
.mh-app .ad-cal .dcell { aspect-ratio:1; border-radius:11px; display:flex; align-items:center; justify-content:center; font-size:13.5px; font-weight:600; color:var(--mh-muted); border:1px solid transparent; }
.mh-app .ad-cal .dcell.empty { background:transparent; border:none; }
.mh-app .ad-cal .dcell.closed { background:rgba(201,123,90,.12); color:#B5663F; }
.mh-app .ad-cal .dcell.noclass { background:rgba(138,139,131,.06); color:var(--mh-muted); }
.mh-app .ad-cal .dcell.meet { background:var(--mh-surface); border-color:var(--mh-line); color:var(--mh-ink); }
.mh-app .ad-cal .dcell.present, .mh-app .ad-cal .dcell.in { background:var(--mh-green); color:#fff; border-color:var(--mh-green); font-weight:800; }
.mh-app .ad-cal .dcell.missed { background:rgba(176,70,60,.18); color:var(--mh-danger); border-color:rgba(176,70,60,.4); font-weight:800; }
.mh-app .ad-cal .dcell.excused { background:rgba(216,155,61,.18); color:var(--mh-warning-d); border-color:rgba(216,155,61,.45); font-weight:800; }
.mh-app .ad-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin:18px 0; }
.mh-app .adstat { background:var(--mh-cream-2); border-radius:12px; padding:12px; text-align:center; }
.mh-app .adstat b { display:block; font-family:var(--mh-font-head); font-size:22px; color:var(--mh-ink); }
.mh-app .adstat span { font-size:10.5px; color:var(--mh-muted); font-weight:700; text-transform:uppercase; letter-spacing:.4px; }
.mh-app .ad-kids .adk-h { font-size:11px; font-weight:700; text-transform:uppercase; color:var(--mh-muted); margin:6px 0 8px; }
.mh-app .adk-row { display:flex; align-items:center; gap:10px; padding:8px 0; border-top:1px solid var(--mh-line); }
.mh-app .adk-row .av.sm { width:38px; height:38px; border-radius:11px; display:grid; place-items:center; color:#fff; font-weight:800; font-size:13px; flex:0 0 auto; }
.mh-app .adk-n { flex:1; font-weight:600; }
.mh-app .adk-s { color:var(--mh-muted); font-size:13px; }
/* legacy single-session roster legend (kept for any stragglers) */
.mh-app .att-legend-old i { display:inline-block; width:11px; height:11px; border-radius:50%; margin-right:6px; vertical-align:-1px; }
.mh-app .att-hh { margin-top:14px; }
.mh-app .att-hh-head { display:flex; align-items:center; justify-content:space-between; background:var(--mh-cream-2); border:1px solid var(--mh-line); border-radius:11px; padding:8px 14px; margin-bottom:2px; }
.mh-app .att-hh-name { font-family:var(--mh-font-head); font-weight:600; font-size:14px; color:var(--mh-slate); }
.mh-app .ns-act-fam { border:1px solid rgba(78,124,114,.4); background:var(--mh-surface); color:var(--mh-green-d); border-radius:9px; padding:5px 12px; font-family:var(--mh-font-body); font-size:12px; font-weight:700; cursor:pointer; }
.mh-app .ns-act-fam:hover { background:rgba(78,124,114,.08); }
.mh-app .att-mark { display:flex; align-items:center; gap:10px; }
.mh-app .att-statsel { border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:8px 11px; font-family:var(--mh-font-body); font-size:13px; font-weight:600; color:var(--mh-ink); background:var(--mh-ctrl-fill); min-width:140px; transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .att-statsel:focus { outline:none; background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .att-statsel.is-present { border-color:var(--mh-green); color:var(--mh-green-d); background:rgba(78,124,114,.08); }
.mh-app .att-statsel.is-missed { border-color:rgba(176,70,60,.5); color:var(--mh-danger); background:rgba(176,70,60,.06); }
.mh-app .att-statsel.is-excused { border-color:rgba(216,155,61,.6); color:var(--mh-warning-d); background:rgba(216,155,61,.08); }
.mh-app .att-statsel.is-late { border-color:rgba(94,122,131,.5); color:#4a626b; background:rgba(94,122,131,.07); }
.mh-app .att-note { font-size:11.5px; color:var(--mh-muted); font-weight:600; }
.mh-app .pill.danger { background:rgba(176,70,60,.12); color:var(--mh-danger); }
.mh-app .pill.danger .dot { background:var(--mh-danger); }

/* Gift Card (Phase 4) - issue modal */
.mh-app .ns-prog input[type=text], .mh-app .ns-prog input[type=number] { width:100%; border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:12px 14px; font-family:var(--mh-font-body); font-size:14px; font-weight:600; color:var(--mh-ink); background:var(--mh-ctrl-fill); box-sizing:border-box; transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .ns-prog input:focus { outline:none; background:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .rsn-card { background:var(--mh-surface); border-radius:20px; box-shadow:0 24px 70px rgba(33,50,58,.35); padding:28px 30px 24px; width:480px; max-width:calc(94 * var(--mh-vw)); max-height:calc(90 * var(--mh-vh)); overflow:auto; animation:wdPop .2s ease; }
.mh-app .rsn-card h3 { font-family:var(--mh-font-head); font-size:22px; margin:0 0 4px; }
.mh-app .rsn-ic { width:50px; height:50px; border-radius:14px; display:grid; place-items:center; font-size:24px; margin-bottom:14px; }
.mh-app .rsn-sub { font-size:13.5px; color:var(--mh-muted); margin:0 0 16px; }
.mh-app .rsn-sub b { color:var(--mh-ink); }
.mh-app .rsn-l { display:block; font-size:11.5px; font-weight:700; color:var(--mh-muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:8px; }
.mh-app .rsn-select { width:100%; border:1px solid transparent; border-radius:var(--mh-ctrl-r); padding:12px 40px 12px 14px; font-family:var(--mh-font-body); font-size:14px; font-weight:600; color:var(--mh-ink); background-color:var(--mh-ctrl-fill); background-image:var(--mh-ctrl-caret); background-repeat:no-repeat; background-position:right 14px center; background-size:14px 14px; box-sizing:border-box; transition:background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .rsn-select:open { background-image:var(--mh-ctrl-caret-up); }
.mh-app .rsn-select:focus { outline:none; background-color:var(--mh-surface); border-color:var(--mh-ctrl-focus-border); box-shadow:var(--mh-ctrl-focus-ring); }
.mh-app .rsn-foot { display:flex; gap:10px; justify-content:flex-end; }
/* Gift Card screen (REBUILD-01) - ported verbatim from mh-dashboard.html
   (mock lines 814-816 pp-tbl, 821 pp-gift, 840-858 gc-*). Adopts the mock's
   class names exactly: .gc-thumb = catalog tile, .gc-card = rendered preview. */
.mh-app .pp-tbl { width:100%; border-collapse:collapse; }
.mh-app .pp-tbl th { text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.4px; color:var(--mh-muted); font-weight:700; padding:11px 16px; border-bottom:1px solid var(--mh-line); }
.mh-app .pp-tbl td { padding:12px 16px; border-bottom:1px solid var(--mh-line); }
.mh-app .pp-gift { font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.3px; color:var(--mh-warning-d); background:rgba(216,155,61,.16); border-radius:6px; padding:2px 6px; margin-left:4px; }
.mh-app .gc-modal { width:520px !important; max-width:calc(94 * var(--mh-vw)); max-height:calc(92 * var(--mh-vh)); overflow:auto; }
.mh-app .gc-modal .rsn-l { margin-top:0; }
.mh-app .gc-preview { margin:6px 0 18px; }
.mh-app .gc-card { aspect-ratio:1.6/1; width:100%; border-radius:16px; color:#fff; padding:18px 20px; display:flex; flex-direction:column; box-shadow:0 10px 28px rgba(0,0,0,.22); }
.mh-app .gc-card-top { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.mh-app .gc-card-name { font-family:var(--mh-font-head); font-size:21px; font-weight:800; letter-spacing:-.3px; }
.mh-app .gc-card-tag { font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; opacity:.85; }
.mh-app .gc-card-logo { width:32px; height:32px; }
.mh-app .gc-card-mid { flex:1; display:flex; align-items:center; }
.mh-app .gc-card-chip { width:40px; height:29px; border-radius:6px; background:linear-gradient(135deg,rgba(255,255,255,.9),rgba(255,255,255,.55)); box-shadow:inset 0 0 0 1px rgba(0,0,0,.08); }
.mh-app .gc-card-bottom { display:flex; align-items:baseline; gap:10px; }
.mh-app .gc-card-val { font-family:var(--mh-font-head); font-size:32px; font-weight:800; }
.mh-app .gc-card-lbl { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.6px; opacity:.85; }
.mh-app .gc-card-foot { font-size:11px; opacity:.8; margin-top:8px; }
/* THE SELECTED RING NEEDS ROOM TO EXIST (Aug 15 2026, CEO).
   `.gc-thumb.on` draws its ring with box-shadow, which paints OUTSIDE the element's
   box - and this row is `overflow-x:auto`, which clips on every side, not just the
   one it scrolls. With padding only at the bottom, the chosen card's ring was cut off
   along the top and the left, and the last card's along the right. It read as a
   rendering fault on the one card staff had just picked.
   The padding gives the ring its 4px back on all four sides; the matching negative
   margin keeps the row itself aligned with the rest of the modal, so nothing else
   shifts to pay for it. */
.mh-app .gc-catalog {
  display:flex; gap:12px; overflow-x:auto;
  padding:7px 7px 12px; margin:-7px -7px 0;
  scrollbar-width:thin; scrollbar-color:rgba(40,60,80,.22) transparent;
}
.mh-app .gc-catalog::-webkit-scrollbar { height:8px; }
.mh-app .gc-catalog::-webkit-scrollbar-track { background:transparent; }
.mh-app .gc-catalog::-webkit-scrollbar-thumb { background:rgba(40,60,80,.18); border-radius:99px; }
.mh-app .gc-catalog:hover::-webkit-scrollbar-thumb { background:rgba(40,60,80,.30); }

/* BIGGER TILES. These are the product being handed to somebody, and at 108x60 they
   read as swatches rather than as cards - the Matthew House name did not even fit on
   one line. 148x86 keeps the card proportion, lets every retailer name sit on a single
   line, and still shows three and a bit across so it is obvious the row scrolls. */
.mh-app .gc-thumb {
  flex:0 0 auto; width:148px; height:86px; border-radius:13px;
  border:2px solid transparent; color:#fff;
  font-family:var(--mh-font-head); font-weight:800; font-size:13.5px; line-height:1.25;
  cursor:pointer; display:flex; align-items:flex-end; padding:11px 13px; text-align:left;
  box-shadow:0 2px 8px rgba(0,0,0,.18);
  transition:transform .16s var(--mh-ease,cubic-bezier(.2,.7,.25,1)), box-shadow .16s ease;
}
.mh-app .gc-thumb:hover { transform:translateY(-2px); box-shadow:0 6px 16px rgba(0,0,0,.22); }
.mh-app .gc-thumb.on { box-shadow:0 0 0 3px var(--mh-surface),0 0 0 6px var(--mh-green),0 4px 12px rgba(0,0,0,.20); }
.mh-app .gc-values { display:flex; gap:8px; flex-wrap:wrap; }
.mh-app .gc-vchip { border:1.5px solid var(--mh-line); background:var(--mh-surface); border-radius:10px; padding:9px 15px; font-family:var(--mh-font-body); font-weight:700; font-size:14px; color:var(--mh-ink); cursor:pointer; }
.mh-app .gc-vchip.on { background:var(--mh-green); color:#fff; border-color:var(--mh-green); }

/* ============================================================================
   SECTION SUB-PANELS (Phase 1) - Clients / Program 248px collapsible side panel
   Rail -> sub-panel -> content. Collapses to a 64px icon rail. Scoped to .mh-app.
   ========================================================================== */
.mh-app .cl-wrap { display: flex; gap: 14px; height: 100%; min-height: 0; }
/* POLISH-04 ITEM 1: the rail width is pinned via an EXPLICIT flex-basis (0 0 248px),
   not width+flex:none. On a cold first paint (before web fonts settle) the browser was
   resolving flex-basis:auto against a not-yet-final width and letting the rail grab the
   whole row - collapsing .cl-body to ~20px, which wrapped the toolbar so the search box
   and the filter dropdown stacked at mismatched heights. A concrete flex-basis is
   deterministic on every render path (direct load, reload, client-side nav). The
   collapsed (64px) and <=900px (auto) states below override the basis to match. */
.mh-app .cl-side { width: 248px; flex: 0 0 248px; position: relative; background: var(--mh-surface); border-radius: 18px; display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--mh-shadow-sm); align-self: stretch; transition: flex-basis .2s ease, width .2s ease; }
.mh-app .cl-scroll { flex: 1; overflow-y: auto; padding: 14px 12px; }
.mh-app .cl-seclbl { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--mh-muted); padding: 10px 12px 6px; }
/* LEFT VIEWS PANEL ITEMS ARE UPPERCASE (CEO, Jul 31 2026).
   The section labels above them (.cl-seclbl - "VIEWS", "KIOSK", "MORE") were already
   uppercase, so the panel was talking in two voices: a shouted heading over Title Case
   items. Applied to the ITEM classes only - .cl-item and .pg-side .pl-tab - so the bare
   `.pl-tab` horizontal tab row used elsewhere is untouched. Tracking goes positive
   because capitals at this size close up without it; size drops a touch since uppercase
   reads larger than the same word in Title Case. */
.mh-app .cl-item { display: flex; align-items: center; justify-content: flex-start; gap: 11px; width: 100%; text-align: left; border: none; background: none; padding: 10px 12px; border-radius: 12px; font-family: inherit; font-size: 13px; font-weight: 700; letter-spacing: .045em; text-transform: uppercase; color: var(--mh-slate); cursor: pointer; transition: .13s; }
.mh-app .cl-item svg { width: 18px; height: 18px; color: var(--mh-muted); flex: none; }
.mh-app .cl-item:hover { background: var(--mh-cream-2); }
.mh-app .cl-item.on { background: rgba(78,124,114,.12); color: var(--mh-green-d); }
.mh-app .cl-item.on svg { color: var(--mh-green-d); }
.mh-app .cl-body { flex: 1; min-width: 0; overflow-y: auto; position: relative; padding: 4px 10px; }
.mh-app .cl-shead { padding: 14px 14px 12px; border-bottom: 1px solid var(--mh-line); }
.mh-app .cl-shead h3 { font-family: var(--mh-font-head); font-size: 19px; color: var(--mh-ink); }

.mh-app .pg-side .pg-sidetabs { display: flex; flex-direction: column; gap: 4px; padding: 8px 12px 14px; min-width: 0; }
/* Same rule as .cl-item above: the Program views panel is the same control, so it takes the
   same casing. Scoped to `.pg-side` - the bare `.pl-tab` is a horizontal tab row elsewhere. */
.mh-app .pg-side .pl-tab { display: flex; align-items: center; justify-content: flex-start; gap: 10px; width: 100%; text-align: left; border: none; background: none; padding: 11px 13px; border-radius: 11px; font-family: inherit; font-size: 13px; font-weight: 700; letter-spacing: .045em; text-transform: uppercase; color: var(--mh-slate); cursor: pointer; margin-bottom: 0; transition: .13s; }
.mh-app .pg-side .pl-tab svg { width: 18px; height: 18px; color: var(--mh-muted); flex: none; }
.mh-app .pg-side .pl-tab:hover { background: var(--mh-cream-2); }
.mh-app .pg-side .pl-tab.on { background: rgba(78,124,114,.12); color: var(--mh-green-d); border-bottom: none; }
.mh-app .pg-side .pl-tab.on svg { color: var(--mh-green-d); }
.mh-app .pg-side .pg-launch { margin: 6px 12px 4px; }

/* Canonical sidebar toggle (Phase 1E + Phase 3 Add-on A): chrome-less in BOTH the open
   and collapsed states - no background, border or shadow, arrow glyph only. Hover ->
   brand green, active -> pine. Ink color flips to cream in dark (var(--mh-ink)). The
   ONLY difference between the two states is arrow direction (+ centering when collapsed). */
.mh-app .panel-collapse { position: absolute; top: 10px; right: 10px; width: 28px; height: 28px; border: none; background: none; box-shadow: none; color: var(--mh-ink); cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 5; transition: color .15s ease; }
.mh-app .panel-collapse:hover { color: var(--mh-green); }
.mh-app .panel-collapse:active { color: var(--mh-sidebar); }
.mh-app .panel-collapse svg { width: 16px; height: 16px; }
.mh-app .cl-wrap.collapsed .cl-side { width: 64px; flex-basis: 64px; }
.mh-app .cl-wrap.collapsed .cl-item, .mh-app .cl-wrap.collapsed .pg-side .pl-tab { font-size: 0; gap: 0; justify-content: center; padding-left: 0; padding-right: 0; }
.mh-app .cl-wrap.collapsed .cl-item svg, .mh-app .cl-wrap.collapsed .pg-side .pl-tab svg { width: 20px; height: 20px; }
.mh-app .cl-wrap.collapsed .cl-seclbl, .mh-app .cl-wrap.collapsed .cl-shead h3, .mh-app .cl-wrap.collapsed .pg-launch { display: none; }
.mh-app .cl-wrap.collapsed .cl-scroll, .mh-app .cl-wrap.collapsed .pg-sidetabs { padding-top: 46px; }
.mh-app .cl-wrap.collapsed .panel-collapse svg { transition: transform .2s ease; transform: rotate(180deg); }
/* Collapsed state only adds centering on the rail edge + a slightly larger tap target.
   Chrome-strip + hover/active colors come from the shared base rule above. There is NO
   external "show" button - this same toggle expands the rail. */
.mh-app .cl-wrap.collapsed .panel-collapse { top: 12px; left: 50%; right: auto; transform: translateX(-50%); width: 32px; height: 32px; }
.mh-app .pane { display: none; }
.mh-app .pane.show { display: block; }

@media (max-width: 900px) {
  .mh-app .cl-wrap { flex-direction: column; height: auto; }
  /* Column mode: the rail is full-width and content-height, so release the fixed basis. */
  .mh-app .cl-side { width: 100%; flex-basis: auto; }
}

/* ============ DARK MODE shell overrides ============ */
body.dark .mh-app .topbar { background: rgba(21,28,26,.82); border-bottom-color: var(--mh-line); box-shadow: none; }
body.dark .mh-app .topbar .ttl { color: var(--mh-ink); }
body.dark .mh-app .topbar .crumb { color: var(--mh-muted); }
/* dark search fill comes from the FS --mh-ctrl-fill token (translucent), shared by
   .search and .mh-srch so both match in dark too (FS1-FIX). No per-search override. */
body.dark .mh-app .icon-btn { background: var(--mh-cream-2); border-color: rgba(78,124,114,.38); color: var(--mh-ink); }
body.dark .mh-app #plannerBtn, body.dark .mh-app #darkBtn { color: #fff; }
body.dark .mh-app #bellBtn svg path, body.dark .mh-app #bellBtn svg ellipse { fill: #fff; }
body.dark .mh-app .tb-user { background: var(--mh-cream-2); }
body.dark .mh-app .tb-user .tb-nm { color: var(--mh-ink); }
body.dark .mh-app .bell-menu, body.dark .mh-app .tb-menu, body.dark .mh-app .search-pop, body.dark .mh-app .top-menu { background: var(--mh-surface); border-color: var(--mh-line); }
body.dark .mh-app .card, body.dark .mh-app .kpi { box-shadow: var(--mh-shadow-sm); }
body.dark .mh-app .cl-side .cl-item, body.dark .mh-app .pg-side .pl-tab { color: #FFFFFF; }
body.dark .mh-app .cl-side .cl-item svg, body.dark .mh-app .pg-side .pl-tab svg { color: #FFFFFF; }
body.dark .mh-app .cl-side .cl-seclbl { color: #C9D4D0; }

/* =====================================================================
   PHASE 2: Clients list panes (All Clients / Households / Intake /
   Document Expiry / Archived). Ported faithfully from mh-dashboard.html
   #view-clients, re-scoped under .mh-app. Mock-only vars substituted:
   --sh-sm -> --mh-shadow-sm, --r-card -> 16px, --mh-gold -> #D89B3D.
   ===================================================================== */
/* filter toolbar + segment control */
.mh-app .toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.mh-app .filter { margin-left: auto; display: flex; align-items: center; gap: 8px; }
/* Segmented toggle (Dashboard This Week/Month/All Time, Clients, etc.) = the app default,
   now wearing the search bar's "Inset Cool Field" container (cool fill #DFE4EA + hairline +
   inset shadow), so every segmented control matches the search + dropdowns + filters. The
   active pill keeps its dark highlight. body.dark block below flips the container like the
   search bar. */
.mh-app .seg { display: inline-flex; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: 999px; padding: 4px; gap: 3px; }
.mh-app .seg button { border: none; background: none; cursor: pointer; font-family: inherit; font-weight: 600; font-size: 13px; color: var(--mh-muted); padding: 7px 16px; border-radius: 999px; transition: .15s; }
.mh-app .seg button.on { background: var(--mh-slate); color: #fff; }
body.dark .mh-app .seg { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }

/* Dashboard period control + "+ Widgets" grouped on the right of the greeting row. */
.mh-app .kpi-controls { display: inline-flex; align-items: center; gap: 10px; }
/* "+ Widgets": structured EXACTLY like the period control (.seg) so the two match 1:1 -
   a light Inset Cool Field container (.wg-seg) wrapping a dark "active" pill (.wg-btn),
   just like the selected "Month" / "This Week" button. The 4px container padding leaves
   the same light ring around the dark pill (it doesn't fill the container edge to edge). */
.mh-app .wg-seg { display: inline-flex; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: 999px; padding: 4px; }
/* The "active" pill wears the Matthew House brand gradient (the SAME pine colours as the
   "Matthew" greeting name), not flat slate. White text keeps strong contrast on it.
   It is animated: an oversized symmetric pine gradient whose position drifts very slowly
   so the lighter band sweeps from the dark side to the light side and back. One full round
   trip takes 120s (60s each way) - deliberately slow, easily over a minute per cycle. */
.mh-app .wg-btn { display: inline-flex; align-items: center; gap: 6px; border: none; background: linear-gradient(120deg, #2E4A43 0%, var(--mh-green) 50%, #2E4A43 100%); background-size: 220% 100%; background-position: 0% 50%; color: #fff; cursor: pointer; font-family: inherit; font-weight: 600; font-size: 13px; padding: 7px 16px; border-radius: 999px; transition: filter .15s; animation: wg-brandshift 120s ease-in-out infinite; }
.mh-app .wg-btn svg { width: 15px; height: 15px; }
.mh-app .wg-btn:hover { filter: brightness(1.06); }
@keyframes wg-brandshift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
@media (prefers-reduced-motion: reduce) { .mh-app .wg-btn { animation: none; } }
body.dark .mh-app .wg-seg { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }

/* Widgets panel (centered modal). Dev workspace variant + Coming-Soon variant. */
.mh-app .wg-overlay { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; background: rgba(28,32,36,.44); backdrop-filter: blur(3px); padding: 24px; }
.mh-app .wg-card { position: relative; width: min(560px, 100%); max-height: calc(86 * var(--mh-vh)); overflow-y: auto; background: var(--mh-surface); border: 1px solid var(--mh-line); border-radius: 18px; box-shadow: 0 24px 60px rgba(28,32,36,.28); padding: 30px 30px 26px; }
.mh-app .wg-card--cs { width: min(430px, 100%); text-align: center; padding: 36px 30px 30px; }
.mh-app .wg-x { position: absolute; top: 14px; right: 14px; width: 32px; height: 32px; display: grid; place-items: center; border: none; background: transparent; color: var(--mh-muted); border-radius: 9px; cursor: pointer; transition: .15s; }
.mh-app .wg-x svg { width: 18px; height: 18px; }
.mh-app .wg-x:hover { background: var(--mh-cream-2); color: var(--mh-ink); }
.mh-app .wg-eyebrow { font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--mh-green); margin-bottom: 6px; }
.mh-app .wg-ttl { font-size: 21px; font-weight: 800; color: var(--mh-ink); margin: 0 0 6px; }
.mh-app .wg-lead { font-size: 13.5px; line-height: 1.55; color: var(--mh-muted); margin: 0 0 20px; }
.mh-app .wg-card--cs .wg-lead { margin-bottom: 22px; }
.mh-app .wg-grid { display: flex; flex-direction: column; gap: 10px; }
.mh-app .wg-item { display: flex; align-items: center; gap: 13px; padding: 13px 15px; background: var(--mh-cream-2); border: 1px solid var(--mh-line); border-radius: 13px; }
.mh-app .wg-item-ic { flex: none; width: 38px; height: 38px; display: grid; place-items: center; background: var(--mh-surface); border: 1px solid var(--mh-line); border-radius: 10px; color: var(--mh-green); }
/* The duotone glyph classes are scoped to .mh-fs elsewhere; the modal renders outside
   that frame, so restate them here for the widget-card icons. */
.mh-app .wg-item-ic .mh-ico .duo { fill: currentColor; opacity: .16; }
.mh-app .wg-item-ic .mh-ico .ln { stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.mh-app .wg-item-body { flex: 1 1 auto; min-width: 0; }
.mh-app .wg-item-name { font-size: 14px; font-weight: 700; color: var(--mh-ink); }
.mh-app .wg-item-desc { font-size: 12px; color: var(--mh-muted); margin-top: 2px; }
.mh-app .wg-item-tag { flex: none; font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--mh-gold, #B07D2B); background: color-mix(in srgb, var(--mh-gold, #D89B3D) 16%, transparent); padding: 4px 9px; border-radius: 999px; }
.mh-app .wg-cs-ic { width: 60px; height: 60px; margin: 0 auto 16px; display: grid; place-items: center; color: var(--mh-green); background: color-mix(in srgb, var(--mh-green) 12%, transparent); border-radius: 50%; }
.mh-app .wg-cs-ic svg { width: 30px; height: 30px; }
.mh-app .wg-cs-close { margin-top: 4px; }

/* ===== "Add cards to your dashboard" gallery (ported from the source dashboard's card
   gallery; source tokens mapped to our --mh-* tokens so it themes light + dark). ===== */
.mh-app .wg-card--gallery { width: min(720px, calc(96 * var(--mh-vw))); max-height: calc(88 * var(--mh-vh)); padding: 0; display: flex; flex-direction: column; overflow: hidden; }
.mh-app .cg-head-row { display: flex; align-items: center; gap: 11px; padding: 24px 26px 14px; }
.mh-app .cg-hic { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; background: var(--mh-green); color: #fff; flex: none; box-shadow: 0 6px 16px color-mix(in srgb, var(--mh-green) 34%, transparent); }
.mh-app .cg-hic svg { width: 20px; height: 20px; }
.mh-app .cg-sub { font-size: 12.5px; color: var(--mh-muted); font-weight: 600; margin-top: 3px; }
.mh-app .cg-body { display: flex; flex-direction: column; gap: 22px; padding: 8px 26px 14px; overflow-y: auto; }
.mh-app .cg-group { display: flex; flex-direction: column; gap: 11px; }
.mh-app .cg-gh { display: flex; align-items: baseline; gap: 10px; font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--mh-muted); }
.mh-app .cg-gh span { text-transform: none; letter-spacing: 0; font-size: 11.5px; font-weight: 600; color: var(--mh-green); }
.mh-app .cg-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mh-app .cg-card { display: flex; align-items: center; gap: 12px; text-align: left; padding: 13px; border-radius: 14px; background: var(--mh-cream-2); border: 1px solid var(--mh-line); transition: .16s; cursor: pointer; font-family: inherit; }
.mh-app .cg-card:hover { border-color: color-mix(in srgb, var(--mh-green) 40%, transparent); background: var(--mh-surface); box-shadow: var(--mh-shadow-sm); }
.mh-app .cg-card.on { border-color: var(--mh-green); background: color-mix(in srgb, var(--mh-green) 12%, transparent); }
.mh-app .cg-card.cg-locked { opacity: .5; cursor: not-allowed; }
.mh-app .cg-card.cg-locked:hover { border-color: var(--mh-line); background: var(--mh-cream-2); box-shadow: none; }
.mh-app .cg-ic { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; color: #fff; flex: none; }
.mh-app .cg-ic svg { width: 20px; height: 20px; }
.mh-app .cg-tx { flex: 1; min-width: 0; }
.mh-app .cg-t { display: flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 700; color: var(--mh-ink); }
.mh-app .cg-soon { font-style: normal; font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--mh-muted); background: var(--mh-surface); border: 1px solid var(--mh-line); padding: 2px 6px; border-radius: 99px; }
.mh-app .cg-d { display: block; font-size: 11.5px; color: var(--mh-muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mh-app .cg-add { flex: none; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; background: var(--mh-surface); border: 1px solid var(--mh-line); color: var(--mh-muted); transition: .16s; }
.mh-app .cg-add svg { width: 16px; height: 16px; }
.mh-app .cg-card:hover .cg-add { color: var(--mh-green); border-color: color-mix(in srgb, var(--mh-green) 40%, transparent); }
.mh-app .cg-card.on .cg-add { background: var(--mh-green); border-color: var(--mh-green); color: #fff; }
.mh-app .cg-foot { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 14px 26px; border-top: 1px solid var(--mh-line); }
.mh-app .cg-foot-note { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--mh-muted); margin-right: auto; }
.mh-app .cg-foot-note svg { width: 15px; height: 15px; color: var(--mh-green); }
.mh-app .cg-foot .btn svg { width: 16px; height: 16px; }
@media (max-width: 720px) { .mh-app .cg-grid { grid-template-columns: 1fr; } }

/* .mh-srch is styled by the shared search component (FS1-FIX), defined with .search
   near the top of this file so both searches stay identical and cannot drift. */
.mh-app .mh-sel { position: relative; display: inline-flex; align-items: center; }
/* Unified to the search bar's "Inset Cool Field" (.bigbar.b14): same cool fill, hairline,
   inset shadow + lift-to-white on hover/focus, so the country dropdown, filter button and
   view toggle read as ONE family with the search on every tab (light values here; the
   body.dark block below flips them exactly like .bigbar.b14). */
.mh-app .mh-sel select { font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--mh-ink); appearance: none; -webkit-appearance: none; cursor: pointer; outline: none; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: 999px; padding: 10px 37px 10px 17px; transition: background .16s ease, border-color .16s ease, box-shadow .16s ease; }
.mh-app .mh-sel select:hover { border-color: rgba(40,60,80,.16); }
.mh-app .mh-sel select:focus { background: #fff; border-color: rgba(40,60,80,.16); box-shadow: 0 10px 28px rgba(40,60,80,.12); }
/* POLISH-04 ITEM 1: inside a toolbar (.cl-head), the filter dropdown must sit at the SAME
   height as the .cl-srchbar search box (40px) so the two controls read as a matched pair.
   Scoped to .cl-head so standalone .mh-sel uses (attendance/sessions program pickers etc)
   keep their own sizing. */
.mh-app .cl-head .mh-sel select { height: 40px; box-sizing: border-box; padding-top: 0; padding-bottom: 0; }
.mh-app .mh-sel .chev { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 14px; height: 14px; pointer-events: none; color: var(--mh-ctrl-ico); stroke-width: 2.6; transition: transform .2s cubic-bezier(.2,.7,.25,1); }
.mh-app .mh-sel .chev svg { width: 100%; height: 100%; display: block; }
/* real overlaid chevron -> smooth 180deg rotate when the native menu opens (matches the
   custom combos exactly; keep the translateY(-50%) so it stays vertically centered) */
.mh-app .mh-sel:has(select:open) .chev { transform: translateY(-50%) rotate(180deg); }
/* status pills */
.mh-app .status { font-size: 11px; font-weight: 800; padding: 4px 11px; border-radius: 999px; display: inline-flex; align-items: center; gap: 6px; }
.mh-app .idc-stats .status { font-size: 11px; }
.mh-app .st-active { color: var(--mh-green-d); background: rgba(78,124,114,.14); }
.mh-app .st-intake { color: var(--mh-info); background: rgba(94,122,131,.15); }
.mh-app .st-review { color: var(--mh-warning-d); background: rgba(216,155,61,.16); }
.mh-app .st-hold { color: var(--mh-clay-d); background: rgba(201,123,90,.16); }
.mh-app .st-arch { color: var(--mh-muted); background: rgba(138,139,131,.14); }
/* ============================================================================
   CARD-GRID LAW  -  SINGLE SOURCE OF TRUTH for every card grid in the app.
   ----------------------------------------------------------------------------
   Card grids are CAPPED at exactly 3 columns at desktop, stepping to 2 then 1
   as the viewport narrows. NEVER 4+, identical in Chrome, Edge, Firefox, and
   any engine.

   WHY (the bug this replaced): the old grids used
   `repeat(auto-fill, minmax(<min>px, 1fr))`, which lets the browser pick the
   column count from `floor((availWidth + gap) / (min + gap))`. That pixel math
   diverges per engine - scrollbar reservation (overlay vs classic), DPR/zoom
   rounding, and font metrics all shift `availWidth` by ~15-17px, enough to tip
   a borderline result from 3 to 4. Result: Edge showed 3, Chrome/Firefox 4,
   cards collapsed below comfortable width, names truncated/wrapped, and the
   card footer wandered. `repeat(N, minmax(0,1fr))` fixes N per breakpoint so
   no browser arithmetic decides design.

   >>> ALL FUTURE CARD GRIDS / CARD TABS MUST USE `.mh-cardgrid` (or be added to
   >>> the grouped selector below). Do not reintroduce auto-fill/auto-fit for
   >>> card grids. This is the one rule; everything else inherits it.

   Applied to: .idgrid (Clients households / All Clients / Expiry / Archived
   clients & households), .hh-grid, .hs-grid (Housing Subsidy), .apv-grid
   (Approvals), and .mh-cardgrid (future surfaces).
   ============================================================================ */
/* CEO directive (Jul 24): cap ALL entity card grids at EXACTLY 2 per row (was 3), so
   cards are wider and the content (e.g. Subsidy money figures) never spills. 2 -> 1 on
   narrow screens. Still deterministic repeat(N) - never auto-fill (see rationale above). */
.mh-app :is(.mh-cardgrid, .idgrid, .hh-grid, .hs-grid, .apv-grid, .pg-grid) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}
@media (max-width: 720px) {
    .mh-app :is(.mh-cardgrid, .idgrid, .hh-grid, .hs-grid, .apv-grid, .pg-grid) {
        grid-template-columns: minmax(0, 1fr);
    }
}
/* Card internals: flex column so cards in a row stretch to equal height (grid
   default) and the footer (.idc-hhrow) pins to the SAME bottom position on every
   card via margin-top:auto - buttons never wander regardless of body height. */
.mh-app .idcard { display: flex; flex-direction: column; background: var(--mh-surface); border-radius: 18px; padding: 18px 18px 14px; box-shadow: var(--mh-shadow-sm); cursor: pointer; transition: transform .16s, box-shadow .16s, border-color .16s; min-width: 0; }
.mh-app .idcard:hover { transform: translateY(-3px); box-shadow: var(--mh-shadow); border-color: var(--mh-green); }
.mh-app .idc-top { display: flex; align-items: center; gap: 14px; }
.mh-app .idc-ph { width: 56px; height: 56px; border-radius: 50%; flex: none; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 16px; letter-spacing: .5px; box-shadow: 0 0 0 3px var(--mh-surface), 0 0 0 4.5px var(--mh-line), 0 6px 14px rgba(33,58,51,.18); }
.mh-app .idcard.hoh .idc-ph { box-shadow: 0 0 0 3px var(--mh-surface), 0 0 0 4.5px #D89B3D, 0 6px 14px rgba(33,58,51,.18); }
.mh-app .idc-mid { flex: 1; min-width: 0; }
.mh-app .idc-name { font-family: var(--mh-font-head); font-size: 16.5px; font-weight: 700; color: var(--mh-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mh-app .idc-sub { font-size: 11.5px; color: var(--mh-muted); font-weight: 600; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.mh-app .idc-hohtag { display: inline-flex; align-items: center; gap: 4px; font-size: 9.5px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase; color: #A9761F; margin-top: 4px; }
/* QR consolidation: the list card QR is the approved SvgPine tile with the centered
   MH mark, and is an interactive pass entry (uniform hover + click-to-pass). */
.mh-app .idc-qr { position: relative; width: 58px; height: 58px; flex: none; background: #fff; border: 1px solid var(--mh-line); border-radius: 10px; padding: 4px; display: grid; place-items: center; cursor: pointer; transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease; }
.mh-app .idc-qr svg { width: 100%; height: 100%; display: block; }
.mh-app .idc-qr:hover { transform: scale(1.06); border-color: var(--mh-green); box-shadow: 0 6px 16px rgba(46,74,67,.22); }
.mh-app .idc-qr .qr-logo { position: absolute; inset: 0; margin: auto; width: 17px; height: 17px; background: linear-gradient(135deg,#2E4A43,#213A33); border-radius: 5px; padding: 2px; display: grid; place-items: center; box-shadow: 0 0 0 1.8px #fff; }
.mh-app .idc-qr .qr-logo img { width: 100%; height: 100%; object-fit: contain; }
.mh-app .idc-line { height: 1px; background: var(--mh-line); margin: 14px 0 10px; }
.mh-app .idc-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.mh-app .idc-stats > div { min-width: 0; text-align: center; }
.mh-app .idc-stats .k { display: block; font-size: 9.5px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--mh-muted); margin-bottom: 4px; }
.mh-app .idc-stats .v { font-size: 12.5px; font-weight: 700; color: var(--mh-ink); font-variant-numeric: tabular-nums; }
/* Archived card: the "who archived" caption under the stats (Part 1 audit display). */
.mh-app .idc-archby { font-size: 11px; font-weight: 600; color: var(--mh-muted); text-align: center; margin-top: 9px; }
/* Household card (All Households): name + status pill on one row, country flag in
   the meta line, document-health chip, 3 evenly-spaced stats, full-width action. */
.mh-app .idc-nrow { display: flex; align-items: center; gap: 9px; min-width: 0; }
.mh-app .idc-nrow .idc-name { flex: 0 1 auto; }
.mh-app .idc-nrow .status { flex: none; }
/* CEO (Aug 5 2026): the member card puts HEAD OF HOUSEHOLD on the NAME row. As a row
   item it must not carry the stacked-layout margin, must not shrink away when the name
   is long, and must not wrap mid-phrase. */
.mh-app .idc-nrow .idc-hohtag { margin-top: 0; flex: none; white-space: nowrap; }
.mh-app .idc-flag { width: 18px; height: 13.5px; border-radius: 2px; margin-right: 6px; vertical-align: -2px; object-fit: cover; box-shadow: 0 0 0 1px rgba(33,58,51,.12); }
.mh-app .idc-doc { margin-top: 8px; }
.mh-app .idc-stats3 { display: flex; justify-content: space-between; gap: 10px; }
.mh-app .idc-stats3 > div { flex: 1 1 0; text-align: left; }
.mh-app .idc-stats3 > div:nth-child(2) { text-align: center; }
.mh-app .idc-stats3 > div:last-child { text-align: right; }
/* =============================================================================
   DESIGN ASSET - Household View button (Phase 5). Landed BYTE-EXACT from
   _handoff/Household View Button/household-view-button/Household-view-button.html:
   the DESIGN's OWN grass-sage palette (NOT re-tinted to the app's pine --mh-sage-*
   tokens), inlined as literals because the app does not define them. Underline-reveal
   label + sage-filling arrow-ring, both animating together on hover. Right-aligned in
   the household KPI card via .idc-hhrow. Click behavior is unchanged (OpenHousehold).
   ============================================================================= */
.mh-app .idc-hhrow { display: flex; justify-content: flex-end; margin-top: auto; padding-top: 13px; }
/* P3 - on archived cards the Restore button takes the LEFT slot; the auto margin pushes
   any following action (Household View) to its default right position. */
.mh-app .idc-hhrow .idc-restore-left { margin-right: auto; }
.mh-app .btn-household { display: inline-flex; align-items: center; justify-content: flex-start; gap: 12px; background: transparent; border: 0; cursor: pointer; padding: 8px 2px; font-family: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, sans-serif; }
.mh-app .btn-household .bh-label { position: relative; font-weight: 700; font-size: 15.5px; color: #3D543A; letter-spacing: .005em; transition: color .2s ease; }
.mh-app .btn-household .bh-label::after { content: ""; position: absolute; left: 0; bottom: -4px; height: 2px; width: 0; background: #5E8157; border-radius: 2px; transition: width .28s cubic-bezier(.3,.7,.3,1); }
.mh-app .btn-household:hover .bh-label::after { width: 100%; }
.mh-app .btn-household .bh-ring { width: 40px; height: 40px; border-radius: 50%; flex: none; border: 1.5px solid #9BB795; color: #4C6A46; display: flex; align-items: center; justify-content: center; transition: background .22s ease, border-color .22s ease, color .22s ease; }
.mh-app .btn-household:hover .bh-ring { background: #5E8157; border-color: #5E8157; color: #fff; }
.mh-app .btn-household .bh-ring svg { width: 17px; height: 17px; transition: transform .24s cubic-bezier(.3,.7,.3,1); }
.mh-app .btn-household:hover .bh-ring svg { transform: translateX(2px); }
.mh-app .btn-household:focus-visible { outline: none; }
.mh-app .btn-household:focus-visible .bh-ring { box-shadow: 0 0 0 3px color-mix(in oklch, #5E8157 45%, transparent); }
.mh-app .btn-household:active .bh-ring { transform: translateY(1px); }
/* Phase 5 dark legibility (closing fix): the asset is a light-only component (dark-sage
   text on transparent), so on the dark card it falls to ~1.9:1. Lift ONLY the label and
   the ring's arrow icon to light sage (#9BB795 ~= 6.7:1 on the dark card, >= WCAG AA);
   the light mode stays 100% byte-exact. Hover still shows the DESIGN white icon on the
   sage fill (this :hover rule comes after, so it wins the rest-state color override). */
body.dark .mh-app .btn-household .bh-label { color: #9BB795; }
body.dark .mh-app .btn-household .bh-ring { color: #9BB795; }
body.dark .mh-app .btn-household:hover .bh-ring { color: #fff; }

/* =============================================================================
   Per-client archive control + confirm modal (Phase 6D). Pill on the member card /
   row toggles archive; the confirm modal mirrors the household status-modal confirm.
   ============================================================================= */
.mh-app .idc-archrow { display: flex; justify-content: flex-end; margin-top: auto; padding-top: 10px; }
.mh-app .cl-archbtn { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--mh-line); background: var(--mh-ctrl-fill); color: var(--mh-muted); font-family: inherit; font-size: 12px; font-weight: 700; padding: 7px 12px; border-radius: 999px; cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
.mh-app .cl-archbtn svg { width: 15px; height: 15px; }
.mh-app .cl-archbtn:hover { background: var(--mh-surface); border-color: var(--mh-warning); color: var(--mh-warning-d); }
.mh-app .cl-archbtn.is-arch { background: rgba(78,124,114,.12); border-color: transparent; color: var(--mh-green-d); }
.mh-app .cl-archbtn.is-arch:hover { border-color: var(--mh-green); background: var(--mh-surface); }
.mh-app .cl-row-arch { flex: none; width: 34px; height: 34px; padding: 0; justify-content: center; }
.mh-app .cl-row-arch svg { width: 16px; height: 16px; }
.mh-app .arch-modal { position: fixed; inset: 0; z-index: 100050; background: rgba(20,28,25,.45); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); display: grid; place-items: center; padding: 20px; }
.mh-app .arch-card { width: min(380px, calc(92 * var(--mh-vw))); background: var(--mh-surface); border-radius: 18px; box-shadow: var(--mh-shadow); padding: 24px; text-align: center; }
.mh-app .arch-ic { width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 50%; display: grid; place-items: center; background: rgba(216,155,61,.14); color: var(--mh-warning-d); }
.mh-app .arch-ic svg { width: 24px; height: 24px; }
.mh-app .arch-ttl { font-size: 17px; font-weight: 800; color: var(--mh-ink); margin: 0 0 6px; }
.mh-app .arch-sub { font-size: 13px; color: var(--mh-muted); line-height: 1.5; margin: 0 0 18px; }
.mh-app .arch-acts { display: flex; gap: 10px; justify-content: center; }
.mh-app .arch-btn { padding: 10px 20px; border-radius: 999px; font-family: inherit; font-weight: 700; font-size: 13px; cursor: pointer; border: 1px solid var(--mh-line); transition: background .15s, border-color .15s; }
.mh-app .arch-cancel { background: var(--mh-ctrl-fill); color: var(--mh-ink); }
.mh-app .arch-cancel:hover { background: var(--mh-surface); }
.mh-app .arch-go { background: var(--mh-green); border-color: var(--mh-green); color: #fff; }
.mh-app .arch-go:hover { background: var(--mh-green-d); border-color: var(--mh-green-d); }
.mh-app .arch-btn:disabled { opacity: .6; cursor: default; }
/* Onboarding card (R&P 90-day window): family + meta + progress bar + 3 stats,
   whole card opens the household overlay. No QR, no stage badge. */
.mh-app .obcard { background: var(--mh-surface); border-radius: 18px; padding: 18px 18px 14px; box-shadow: var(--mh-shadow-sm); cursor: pointer; transition: transform .16s, box-shadow .16s, border-color .16s; min-width: 0; }
.mh-app .obcard:hover { transform: translateY(-3px); box-shadow: var(--mh-shadow); border-color: var(--mh-green); }
.mh-app .ob-top { display: flex; align-items: center; gap: 14px; }
.mh-app .ob-chev { width: 18px; height: 18px; flex: none; color: var(--mh-muted); align-self: center; }
.mh-app .obcard:hover .ob-chev { color: var(--mh-green-d); }
.mh-app .ob-rp { margin-top: 14px; }
.mh-app .ob-rp-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 7px; }
.mh-app .ob-rp-day { font-size: 12.5px; font-weight: 700; color: var(--mh-ink); font-variant-numeric: tabular-nums; }
.mh-app .ob-rp-left { font-size: 11.5px; font-weight: 800; color: var(--mh-green-d); font-variant-numeric: tabular-nums; }
.mh-app .ob-rp-left.urgent { color: var(--mh-warning-d); }
.mh-app .ob-bar { height: 7px; border-radius: 999px; background: var(--mh-cream-2); overflow: hidden; }
.mh-app .ob-bar-fill { height: 100%; border-radius: 999px; transition: width .3s ease; }
.mh-app .ob-bar-fill.ok { background: var(--mh-success); }
.mh-app .ob-bar-fill.warn { background: var(--mh-warning); }
.mh-app .id-empty { grid-column: 1 / -1; text-align: center; color: var(--mh-muted); font-weight: 600; padding: 40px 0; }
.mh-app .idback { display: flex; align-items: center; gap: 14px; margin: 0 0 14px; }
/* "All Families" breadcrumb (Phase 1C): neutral Filled-Soft look to match the Filter
   and View-toggle controls at rest; hover AND active take the Matthew House pine fill
   with white text (150ms ease). */
.mh-app .idback-btn { display: inline-flex; align-items: center; gap: 8px; border: 1px solid transparent; background: var(--mh-ctrl-fill); color: var(--mh-ink); font-family: inherit; font-size: 12.5px; font-weight: 800; padding: 9px 16px; border-radius: 999px; cursor: pointer; transition: background .15s ease, border-color .15s ease, color .15s ease; }
.mh-app .idback-btn svg { width: 15px; height: 15px; }
.mh-app .idback-btn:hover, .mh-app .idback-btn:active { background: var(--mh-sidebar); border-color: transparent; color: #fff; }
.mh-app .idback-ttl { font-size: 13.5px; font-weight: 800; color: var(--mh-ink); }
.mh-app .idback-ttl span { color: var(--mh-muted); font-weight: 600; }
.mh-app .idc-act { display: flex; justify-content: flex-end; margin-top: 12px; }
/* household family cards */
/* .hh-grid columns/gap come from the CARD-GRID LAW above (single source of truth). */
.mh-app .card.hh { background: var(--mh-surface); border: none; border-radius: 18px; padding: 18px; box-shadow: var(--mh-shadow-sm); cursor: pointer; transition: transform .16s, box-shadow .16s, border-color .16s; }
.mh-app .card.hh:hover { transform: translateY(-3px); box-shadow: var(--mh-shadow); border-color: var(--mh-green); }
.mh-app .hh .top { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.mh-app .hh .av { display: grid; place-items: center; color: #fff; font-weight: 800; }
.mh-app .hh .nm { font-weight: 800; font-size: 15px; color: var(--mh-ink); }
.mh-app .hh .sub { font-size: 12px; color: var(--mh-muted); }
.mh-app .hh .mini { display: flex; gap: 18px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--mh-line); }
.mh-app .hh .mini b { font-size: 18px; font-weight: 800; display: block; color: var(--mh-ink); }
.mh-app .hh .mini span { font-size: 11px; color: var(--mh-muted); font-weight: 600; }
/* intake pipeline */
.mh-app .pipe { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.mh-app .pcol { background: var(--mh-cream-2); border-radius: 16px; padding: 12px; box-shadow: var(--mh-shadow-sm); }
.mh-app .pcol h4 { font-size: 12.5px; display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; color: var(--mh-ink); }
.mh-app .pcol .ct { font-size: 11px; font-weight: 800; color: var(--mh-muted); background: var(--mh-surface); border: 1px solid var(--mh-line); border-radius: 999px; min-width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; padding: 0 6px; }
.mh-app .pcard { background: var(--mh-surface); border-radius: 11px; padding: 11px; margin-bottom: 9px; box-shadow: var(--mh-shadow-sm); cursor: pointer; }
.mh-app .pcard .nm { font-weight: 700; font-size: 13px; color: var(--mh-ink); }
.mh-app .pcard .meta { font-size: 11px; color: var(--mh-muted); margin-top: 3px; }
.mh-app .pcard .day { margin-top: 8px; font-size: 11px; font-weight: 800; }
/* small action buttons (Renew / Restore) */
.mh-app .btn--g { display: inline-flex; align-items: center; gap: 7px; background: var(--mh-surface); color: var(--mh-ink); border: 1px solid var(--mh-line); font-family: inherit; font-weight: 700; cursor: pointer; }
.mh-app .btn--g:hover { border-color: var(--mh-green); color: var(--mh-green-d); }
.mh-app .btn--sm { height: 36px; padding: 0 13px; font-size: 12.5px; border-radius: 11px; }
/* responsive */
@media (max-width: 1024px) { .mh-app .pipe { grid-template-columns: repeat(2, 1fr); } }
/* .idgrid / .hh-grid responsive steps are owned by the CARD-GRID LAW above. */
@media (max-width: 640px) { .mh-app .pipe { grid-template-columns: 1fr; } }
/* dark-mode pane tweaks */
body.dark .mh-app .pcol { background: var(--mh-cream-2); }
body.dark .mh-app .idcard, body.dark .mh-app .card.hh, body.dark .mh-app .pcard { box-shadow: var(--mh-shadow-sm); }
body.dark .mh-app .cl-row { box-shadow: var(--mh-shadow-sm); }

/* ============================================================================
   CLIENTS REORG - card/list view switcher, Filter-by-Status panel, list rows.
   Filled Soft (--mh-ctrl-* tokens); active/selected = brand pine/teal (NOT slate).
   Status pill colors come from the lookup ColorHex (inline style), per CEO rule.
   ========================================================================== */
.mh-app .cl-head { align-items: center; }
/* card / list switcher */
/* ONE HEIGHT FOR EVERY FILTER CONTROL. The number lives here and nowhere else,
   so a new control is built to match instead of guessed at. The controls
   THEMSELVES are sized in mh-toolbar.css, which owns the toolbar kit and loads
   after this file - setting a height here while the button size stayed there is
   what briefly left a 40px button inside a 40px shell with no room to sit. */
:root { --mh-filter-h: 40px; }
.mh-app .cl-switch { display: inline-flex; gap: 3px; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: var(--mh-r-pill); padding: 3px; flex: none; }
.mh-app .cl-switch button { display: grid; place-items: center; width: 34px; height: 30px; border: none; background: none; border-radius: 999px; color: var(--mh-ctrl-ico); cursor: pointer; transition: background .15s, color .15s; }
.mh-app .cl-switch button svg { width: 17px; height: 17px; }
.mh-app .cl-switch button:hover { color: var(--mh-ctrl-selected); }
.mh-app .cl-switch button.on { background: var(--mh-ctrl-accent); color: #fff; box-shadow: var(--mh-shadow-sm); }
/* Filters button + Filter by Status panel */
/* Filters = icon-only square button, sits LEFT next to the card/list switcher. */
.mh-app .cl-filterwrap { position: relative; flex: none; }
.mh-app .cl-filterbtn { display: inline-grid; place-items: center; width: 38px; height: 36px; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: 11px; color: var(--mh-ink); cursor: pointer; transition: background .15s, border-color .15s, box-shadow .15s; }
.mh-app .cl-filterbtn svg { width: 17px; height: 17px; color: var(--mh-ctrl-ico); }
.mh-app .cl-filterbtn:not(.active):hover { background: #fff; border-color: rgba(40,60,80,.16); box-shadow: 0 10px 28px rgba(40,60,80,.12); }
/* Dark: the whole field family flips to the dark control fill + lift-to-surface on hover/
   focus, exactly like .bigbar.b14 in dark (the search bar), so search + dropdown + filter +
   view toggle stay one family in both themes. The active filter/view states are excluded so
   their brand-green highlight is preserved. */
body.dark .mh-app :is(.mh-sel select, .cl-switch, .cl-filterbtn:not(.active)) { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app :is(.mh-sel select:hover, .mh-sel select:focus, .cl-filterbtn:not(.active):hover) { background: var(--mh-surface); border-color: var(--mh-ctrl-focus-border); box-shadow: var(--mh-ctrl-focus-ring); }
/* active = brand pine fill (a real class binding, not inline @if text) */
.mh-app .cl-filterbtn.active { background: var(--mh-ctrl-selected); border-color: transparent; color: #fff; }
.mh-app .cl-filterbtn.active svg { color: #fff; }

/* ===== IMPORT / EXPORT (...) - Clients main toolbar, Aug 12 2026 ==============
   The trigger is deliberately the SAME control as .cl-filterbtn - same 38x36,
   same inset fill, same lift-to-white on hover - because it sits in the same row
   and a control that is nearly-but-not-quite the same reads as a mistake.

   NO TRANSFORM ON HOVER, ANYWHERE IN THIS BLOCK. A transform on an ancestor
   creates a containing block and buries the absolutely-positioned menu behind
   the toolbar; that has cost this app a debugging session before. Hover is
   expressed with background and box-shadow only.

   The menu reuses .ed-more from the Planner so there is ONE overflow dropdown in
   the app; .cl-iomenu only widens it and adds the heading, separator and note. */
.mh-app .cl-iowrap { position: relative; display: inline-flex; }
.mh-app .cl-iobtn { display: inline-grid; place-items: center; width: 38px; height: 36px; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: 11px; color: var(--mh-ink); cursor: pointer; transition: background .15s, border-color .15s, box-shadow .15s; }
.mh-app .cl-iobtn svg { width: 17px; height: 17px; color: var(--mh-ctrl-ico); }
.mh-app .cl-iobtn:not(.on):hover { background: #fff; border-color: rgba(40,60,80,.16); box-shadow: 0 10px 28px rgba(40,60,80,.12); }
.mh-app .cl-iobtn.on { background: var(--mh-ctrl-selected); border-color: transparent; }
.mh-app .cl-iobtn.on svg { color: #fff; }
body.dark .mh-app .cl-iobtn:not(.on) { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app .cl-iobtn:not(.on):hover { background: var(--mh-surface); border-color: var(--mh-ctrl-focus-border); box-shadow: var(--mh-ctrl-focus-ring); }

/* Same backdrop/z-index pair the status filter panel already uses, so the two
   popups in this toolbar cannot end up on different layers. */
.mh-app .cl-io-back { position: fixed; inset: 0; z-index: 40; }

/* THE MENU CARRIES ITS OWN BOX, and it has to.
   The .ed-more it reuses is scoped `.mh-app .ed-card .ed-more` - it only paints
   inside an .ed-card, which is the Planner's detail card. This menu hangs off a
   toolbar and has no such ancestor, so it inherited the CLASS and none of the
   BOX: measured live, background came back rgba(0,0,0,0) - a transparent menu
   floating over the household cards, perfectly readable to a DOM query and
   unusable to a person. Indentation in a .razor file is not nesting, and a class
   name is not a style. So the surface, border, radius and shadow are declared
   here, matching .ed-card .ed-more's values so the two menus stay one idiom. */
.mh-app .cl-iomenu {
  position: absolute; top: calc(100% + 8px); right: 0; left: auto; z-index: 41;
  width: 268px; padding: 8px;
  display: flex; flex-direction: column; align-items: stretch;
  background: var(--mh-surface, #fff);
  border: 1px solid rgba(40, 60, 80, .12);
  border-radius: var(--mh-r-md, 14px);
  box-shadow: 0 14px 40px rgba(33, 50, 58, .18);
}
.mh-app .cl-io-head { padding: 4px 10px 8px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--mh-muted); }
.mh-app .cl-iomenu .ed-more-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: none; background: none; cursor: pointer;
  font-family: inherit; font-size: 13.5px; text-align: left; justify-content: flex-start;
  padding: 9px 12px; border-radius: var(--mh-r-sm, 9px);
  color: var(--mh-ink); transition: background .15s ease;
}
.mh-app .cl-iomenu .ed-more-item:hover { background: rgba(40, 60, 80, .06); }
.mh-app .cl-iomenu .ed-more-item svg { flex: 0 0 auto; color: var(--mh-ctrl-ico); }
body.dark .mh-app .cl-iomenu { background: var(--mh-surface); border-color: var(--mh-line); box-shadow: 0 18px 46px rgba(0, 0, 0, .5); }
body.dark .mh-app .cl-iomenu .ed-more-item { color: #e6ecea; }
body.dark .mh-app .cl-iomenu .ed-more-item:hover { background: rgba(255, 255, 255, .08); }
.mh-app .cl-io-sep { height: 1px; margin: 6px 8px; background: var(--mh-line); }
.mh-app .cl-io-note { padding: 4px 10px 6px; font-size: 11.5px; line-height: 1.45; color: var(--mh-muted); }
.mh-app .cl-fp-back { position: fixed; inset: 0; z-index: 40; }
.mh-app .cl-filterpanel { position: absolute; top: calc(100% + 8px); left: 0; z-index: 41; width: 220px; background: var(--mh-surface); border: 1px solid var(--mh-line); border-radius: 14px; box-shadow: var(--mh-shadow); padding: 8px; }
.mh-app .cl-fp-h { font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--mh-muted); padding: 8px 10px 6px; }
.mh-app .cl-fp-row { display: flex; align-items: center; gap: 10px; width: 100%; border: none; background: none; padding: 9px 10px; border-radius: 10px; font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--mh-ink); cursor: pointer; transition: background .12s; }
.mh-app .cl-fp-row:hover { background: var(--mh-ctrl-fill); }
.mh-app .cl-fp-row.on { background: var(--mh-ctrl-fill); color: var(--mh-ctrl-selected); font-weight: 700; }
.mh-app .cl-fp-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.mh-app .cl-fp-nm { flex: 1; text-align: left; }
.mh-app .cl-fp-ct { font-size: 12px; font-weight: 700; color: var(--mh-muted); }
.mh-app .cl-fp-row.on .cl-fp-ct { color: var(--mh-ctrl-selected); }
.mh-app .cl-fp-ck { width: 15px; height: 15px; color: var(--mh-ctrl-accent); flex: none; }
/* list (rows) view */
.mh-app .cl-list { display: flex; flex-direction: column; gap: 8px; }
.mh-app .cl-row { display: flex; align-items: center; gap: 14px; background: var(--mh-surface); border-radius: 14px; box-shadow: var(--mh-shadow-sm); padding: 12px 16px; transition: transform .15s, box-shadow .15s; }
.mh-app .cl-row:hover { transform: translateY(-1px); box-shadow: var(--mh-shadow); }
.mh-app .cl-row-av { width: 42px; height: 42px; border-radius: 12px; flex: none; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 14px; }
/* App-wide person-avatar rule (Household Detail redesign): a real photo, else the
   ONE shared person-icon, never initials. Sizes the icon inside each PERSON
   container; the container's own light color makes it a white silhouette over the
   existing gradient. Non-person tiles (programs, gift cards) are untouched. */
.mh-app .cl-row-av > svg, .mh-app .idc-ph > svg, .mh-app .tb-av > svg, .mh-app .fam .av > svg, .mh-app .mcard .mav > svg, .kp-row .av > svg { width: 56%; height: 56%; display: block; }
/* Real card photo (Clients list): fills the badge as a clean cover-crop over the
   gradient backdrop. The container clips to its own radius (circle for .idc-ph,
   rounded square for .cl-row-av); the img is absolutely inset so its height is the
   container's fixed size (a plain height:100% would resolve against the auto grid
   track and keep the photo's portrait height). Box-shadow rings are outside the
   box, so overflow:hidden does not clip them. Mirrors the #hhDetail hero-av crop. */
.mh-app .cl-row-av, .mh-app .idc-ph { position: relative; overflow: hidden; }
.mh-app .cl-row-av > img, .mh-app .idc-ph > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* Profile photo is clickable (opens the lightbox): pointer + subtle lift so staff
   see it is interactive, whether a real photo or the person-icon default. */
.mh-app .cl-row-av.plb-trigger, .mh-app .idc-ph.plb-trigger { cursor: pointer; transition: transform .15s ease, filter .15s ease; }
.mh-app .cl-row-av.plb-trigger:hover, .mh-app .idc-ph.plb-trigger:hover { transform: scale(1.06); filter: brightness(1.07); }

/* ===== Profile photo lightbox (the big circle pop-up) =====
   Sits at z-index 100040: above the cards and #hhDetail (99990), below the QR pass
   (.qr-modal 100050). It is only ever opened from the card grid, never stacked with
   another overlay. Closes before Client Detail opens. */
.mh-app .plb { position: fixed; inset: 0; z-index: 100040; background: rgba(0,0,0,.8); display: grid; place-items: center; padding: 24px; animation: plbFade .2s ease both; }
.mh-app .plb-inner { display: flex; flex-direction: column; align-items: center; gap: 22px; animation: plbPop .24s cubic-bezier(.2,.7,.3,1.2) both; }
.mh-app .plb-circle { position: relative; width: min(80vmin, 600px); height: min(80vmin, 600px); border-radius: 50%; overflow: hidden; display: grid; place-items: center; color: #fff; box-shadow: 0 0 0 5px rgba(255,255,255,.92), 0 24px 70px rgba(0,0,0,.6); }
.mh-app .plb-circle > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.mh-app .plb-circle > svg { width: 50%; height: 50%; display: block; }
.mh-app .plb-btn { display: inline-flex; align-items: center; gap: 9px; height: 48px; padding: 0 24px; border: none; border-radius: 999px; background: var(--mh-green); color: #fff; font-family: var(--mh-font-head); font-size: 15px; font-weight: 700; cursor: pointer; box-shadow: 0 8px 22px rgba(46,74,67,.45); transition: background .15s ease, transform .15s ease; }
.mh-app .plb-btn:hover { background: var(--mh-green-d); transform: translateY(-1px); }
.mh-app .plb-btn svg { width: 18px; height: 18px; }
.mh-app .plb-x { position: fixed; top: 22px; right: 24px; z-index: 1; width: 44px; height: 44px; border-radius: 50%; border: none; background: rgba(255,255,255,.14); color: #fff; cursor: pointer; display: grid; place-items: center; transition: background .15s ease; }
.mh-app .plb-x:hover { background: rgba(255,255,255,.26); }
.mh-app .plb-x svg { width: 20px; height: 20px; }
@keyframes plbFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes plbPop { from { opacity: 0; transform: scale(.86); } to { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .mh-app .plb, .mh-app .plb-inner { animation: none; }
}
.mh-app .cl-row-main { flex: 1; min-width: 0; }
.mh-app .cl-row-nm { font-size: 14.5px; font-weight: 800; color: var(--mh-ink); display: flex; align-items: center; gap: 8px; }
.mh-app .cl-row-tag { font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--mh-green-d); background: rgba(78,124,114,.14); border-radius: 999px; padding: 2px 8px; }
.mh-app .cl-row-sub { font-size: 12.5px; color: var(--mh-muted); margin-top: 2px; }
.mh-app .cl-row .status { flex: none; }
.mh-app .cl-row-meta { display: none; flex-direction: column; align-items: flex-end; min-width: 118px; }
.mh-app .cl-row-meta .k { font-size: 10px; text-transform: uppercase; letter-spacing: .4px; color: var(--mh-muted); font-weight: 700; }
.mh-app .cl-row-meta .v { font-size: 13px; font-weight: 700; color: var(--mh-ink); }
.mh-app .cl-row-qr { width: 44px; height: 44px; flex: none; }
@media (min-width: 980px) { .mh-app .cl-row-meta { display: flex; } }

/* Part 3 - Archived LIST view. .cl-row-archmeta = the archived stamp (date+time + who, or
   the degraded household note) shown as a third line inside .cl-row-main so it is ALWAYS
   visible (the .cl-row-meta column is hidden below 980px, where this key field must not be).
   .cl-row-act = compact pill action buttons (Restore / Household View / Client Detail)
   reusing the .cl-archbtn shape with a brand-pine hover instead of the warning hover. */
.mh-app .cl-row-archmeta { font-size: 11.5px; font-weight: 600; color: var(--mh-muted); margin-top: 3px; }
.mh-app .cl-row-act { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 36px; height: 36px; border: 1px solid var(--mh-line); background: var(--mh-ctrl-fill); color: var(--mh-muted); border-radius: 999px; cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
.mh-app .cl-row-act svg { width: 16px; height: 16px; flex: none; }
.mh-app .cl-row-act:hover { background: var(--mh-surface); border-color: var(--mh-green); color: var(--mh-green-d); }
body.dark .mh-app .cl-row-act:hover { color: var(--mh-green); }

/* Part 4 - Archived date-range filter bar (From / To + Clear). Branded date inputs reuse the
   global FS control styling; this only sets compact widths and the surrounding chrome. */
/* Phase 5.2 - the ARCHIVED BETWEEN label is stacked ABOVE its date-field row, and the row
   reads as one family with the toolbar's search bar + country dropdown. */
/* Phase 5.2 R2 - the Archived-between date pair now lives INLINE inside the one toolbar row
   (Clients "archived" view). ".arch-head" bottom-aligns every control on a shared baseline so
   the tiny "ARCHIVED BETWEEN" caption can sit ABOVE its date pair without breaking the single
   row. The date fields keep the search bar's Inset Cool Field look (.arch-dp, below). Scoped to
   .arch-head so the All Clients / Households / Intake / Doc-expiry toolbars are untouched. */
/* Was align-items:flex-end, which existed ONLY so the "Archived between" caption
   could stack above the date pair without pushing the row out of line. With the
   caption gone there is nothing to bottom-align, and centre is what every other
   toolbar in the app uses - so this row now matches them instead of being a
   special case. */
.mh-app .cl-head.arch-head { align-items: center; row-gap: 12px; }
.mh-app .arch-filter { display: flex; align-items: center; gap: 4px; margin: 0; flex: none; height: var(--mh-filter-h); }
.mh-app .arch-filter-row { display: flex; align-items: center; gap: 10px; height: var(--mh-filter-h); }
.mh-app .arch-date { flex: none; width: 162px; padding: 8px 12px; font-size: 13px; }
/* Phase 5.2 - the two date fields wear the search bar's "Inset Cool Field" (.bigbar.b14): cool
   #DFE4EA fill, hairline, inset shadow, pill radius, 40px height; hover/open lift to white with a
   drop shadow, exactly like the search box's focus. Per-context (.arch-dp) so the app-wide
   .dp-field base is untouched. Dark flips to the same control tokens as .bigbar.b14 in dark. */
.mh-app .arch-filter .dp.arch-dp { flex: none; width: 172px; }
.mh-app .arch-filter .dp.arch-dp .dp-field { height: 40px; padding: 0 15px; gap: 9px; background: #DFE4EA; border: 1px solid rgba(40,60,80,.08); box-shadow: inset 0 1px 2px rgba(40,60,80,.10); border-radius: var(--mh-r-pill); }
.mh-app .arch-filter .dp.arch-dp .dp-field:hover,
.mh-app .arch-filter .dp.arch-dp.open .dp-field { background: #fff; border-color: rgba(40,60,80,.16); box-shadow: 0 10px 28px rgba(40,60,80,.12); }
body.dark .mh-app .arch-filter .dp.arch-dp .dp-field { background: var(--mh-ctrl-fill); border-color: var(--mh-line); box-shadow: inset 0 1px 2px rgba(0,0,0,.22); }
body.dark .mh-app .arch-filter .dp.arch-dp .dp-field:hover,
body.dark .mh-app .arch-filter .dp.arch-dp.open .dp-field { background: var(--mh-surface); border-color: var(--mh-ctrl-focus-border); box-shadow: var(--mh-ctrl-focus-ring); }
.mh-app .arch-filter-sep { font-size: 12.5px; font-weight: 600; color: var(--mh-muted); }
.mh-app .arch-filter-clear { border: 1px solid var(--mh-line); background: var(--mh-ctrl-fill); color: var(--mh-muted); font-family: inherit; font-size: 12px; font-weight: 700; padding: 7px 14px; border-radius: 999px; cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
.mh-app .arch-filter-clear:hover { background: var(--mh-surface); border-color: var(--mh-green); color: var(--mh-green-d); }
body.dark .mh-app .arch-filter-clear:hover { color: var(--mh-green); }
.mh-app .arch-filter-warn { font-size: 12px; font-weight: 700; color: var(--mh-danger); }
.mh-app .arch-exempt { font-size: 11px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--mh-muted); margin-left: 8px; }

/* ============================================================================
   GLOBAL confirmation toast (MudBlazor Snackbar) - ALWAYS on top (Phase 1 STEP 1
   FINAL ladder). The app's modals/overlays/wizards/dropdowns top out at z-index
   100050; the full-screen alert is 100090 and the feedback stack 100091-100094.
   At 100095 the toast is the single highest layer, so a save / edit confirmation
   stays visible over EVERYTHING - the open feedback panel and the alert included.
   (z-index only; no restyle.)
   ============================================================================ */
:root { --mud-zindex-snackbar: 100095; }
.mud-snackbar-provider { z-index: 100095; }
.mud-snackbar { z-index: 100095; }

/* STEP 1d: draft resume banner + Discard for the event-create sheet (inside .ecs-body).
   Uses the shell --mh-* tokens so it inherits light + dark. */
.mh-app .ecs-body .wz-draftbar { display:flex; align-items:center; gap:9px; margin:0 0 16px; padding:9px 14px; border-radius:12px; border:1px solid rgba(78,124,114,.28); background:rgba(78,124,114,.08); font-size:12.5px; color:var(--mh-green-d); }
.mh-app .ecs-body .wz-draftbar .ico { flex:none; width:15px; height:15px; color:var(--mh-green-d); }
.mh-app .ecs-body .wz-draftbar .ico svg { width:100%; height:100%; }
.mh-app .ecs-body .wz-drafttx { flex:1; min-width:0; line-height:1.35; }
.mh-app .ecs-body .wz-discard { flex:none; border:0; background:none; padding:4px 6px; font:inherit; font-weight:800; font-size:12px; color:var(--mh-danger); cursor:pointer; border-radius:8px; }
.mh-app .ecs-body .wz-discard:hover { background:rgba(176,70,60,.10); text-decoration:underline; }
body.dark .mh-app .ecs-body .wz-draftbar { border-color:rgba(120,170,158,.30); background:rgba(78,124,114,.18); color:var(--mh-sage-200); }
body.dark .mh-app .ecs-body .wz-draftbar .ico { color:var(--mh-sage-200); }
body.dark .mh-app .ecs-body .wz-discard { color:#e0a892; }
body.dark .mh-app .ecs-body .wz-discard:hover { background:rgba(201,123,90,.16); }

/* ===== PHASE D RULING 3: inactivity sign-out warning =========================
   Z = 100096, deliberately ONE above the snackbar / feedback ceiling (100095).
   Everything else in this app can afford to be covered; this cannot. A warning
   that renders behind something else fires invisibly, and the first thing the
   user learns is that they are back at the login page. It must outrank every
   layer it can coexist with.

   Tokens only (--mh-*), so dark mode is inherited from the body.dark cascade
   rather than re-specified: no hardcoded surface or ink here. The amber accent
   matches the UpcomingAlert "act now" eyebrow (#B26A2E) rather than the calm
   pine, because this IS a deadline. */
.mh-app .mh-idlewarn { position:fixed; inset:0; z-index:100096; display:grid; place-items:center; padding:32px 20px;
  background:radial-gradient(120% 90% at 50% 0%, rgba(52,69,77,.62) 34%, rgba(16,23,21,.82)); overflow:auto;
  animation:iw-fade .16s ease-out; }
@keyframes iw-fade { from { opacity:0; } to { opacity:1; } }
@keyframes iw-in { from { opacity:0; transform:translateY(6px) scale(.985); } to { opacity:1; transform:none; } }
.mh-app .iw-card { width:420px; max-width:100%; background:var(--mh-surface); border:1px solid var(--mh-line);
  border-radius:18px; padding:24px 26px 20px; box-shadow:0 24px 60px rgba(16,23,21,.28); text-align:center;
  animation:iw-in .16s ease-out; }
.mh-app .iw-icon { width:44px; height:44px; margin:0 auto 12px; border-radius:50%; display:grid; place-items:center;
  background:rgba(178,106,46,.12); color:#B26A2E; }
.mh-app .iw-icon svg { width:22px; height:22px; }
.mh-app .iw-title { font-size:19px; font-weight:800; color:var(--mh-ink); letter-spacing:-.01em; }
.mh-app .iw-body { margin-top:8px; font-size:14.5px; line-height:1.5; color:var(--mh-muted); }
/* tnum so the countdown does not reflow the sentence on every tick */
.mh-app .iw-count { font-weight:800; color:#B26A2E; font-variant-numeric:tabular-nums; }
.mh-app .iw-actions { margin-top:18px; display:flex; gap:10px; justify-content:center; }
.mh-app .iw-btn { min-width:132px; padding:10px 16px; border-radius:11px; border:1px solid var(--mh-line);
  background:transparent; color:var(--mh-ink); font-size:14px; font-weight:700; cursor:pointer;
  transition:background .14s ease, border-color .14s ease; }
.mh-app .iw-btn:hover { background:rgba(0,0,0,.04); }
body.dark .mh-app .iw-btn:hover { background:rgba(255,255,255,.06); }
/* --mh-green (#4E7C72) is the brand pine token. NOT --mh-pine: that token does not
   exist, and using it here silently produced an invisible button (an unresolved
   var() left the background transparent while color stayed #fff = white on white).
   The PRIMARY action of a security prompt rendered invisible and the user could only
   sign out. Caught by reading the computed style in the browser, not by the build:
   CSS fails silently, so a wrong token name is never a compile error. */
.mh-app .iw-btn--primary { background:var(--mh-green); border-color:var(--mh-green); color:#fff; }
.mh-app .iw-btn--primary:hover { filter:brightness(1.06); background:var(--mh-green); }
/* Respect the app-wide reduced-motion pref (Phase H3): the countdown is the signal,
   the animation is decoration. */
@media (prefers-reduced-motion:reduce) {
  .mh-app .mh-idlewarn, .mh-app .iw-card { animation:none; }
}

/* Program card = the entry point to the program record (detail-view standard).
   The card itself opens the record; the buttons inside it stopPropagation. */
.mh-app .pg-card.pg-clickable{cursor:pointer}
.mh-app .pg-card.pg-clickable:focus-visible{outline:2px solid var(--mh-pine,#2E4A43);outline-offset:2px}

/* =========================================================
   LIVE ATTENDANCE (kiosk -> grid)
   The grid re-reads itself while a class is running, and a kiosk cell now says
   WHICH kiosk state it is: still in the room, or scanned out again.
   ========================================================= */
/* A LITTLE BIGGER (CEO, Jul 29 2026), now that it sits beside the 18px class name instead of
   in a row of 38px filter controls: 38 -> 44px tall, 12.5 -> 13.5px, with the dot and the
   padding stepped up to match so the pill grows evenly rather than just getting taller.
   `flex:none` keeps it at its own width in the flex row - the class name takes the slack. */
.mh-app .att-live{display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 17px;border-radius:999px;flex:none;
  border:1px solid var(--mh-line);background:var(--mh-surface);color:var(--mh-muted);
  font-size:13.5px;font-weight:700;cursor:pointer;transition:background .18s,border-color .18s,color .18s}
.mh-app .att-live:hover{border-color:#C3CCC9}
.mh-app .att-live .lv-dot{width:9px;height:9px;border-radius:999px;background:var(--mh-muted);flex:none}
.mh-app .att-live .lv-n{font-weight:600;color:var(--mh-muted)}
.mh-app .att-live.on{border-color:rgba(78,124,114,.35);background:rgba(78,124,114,.08);color:#2E4A43}
.mh-app .att-live.on .lv-dot{background:#4E7C72;box-shadow:0 0 0 3px rgba(78,124,114,.22);animation:mhLivePulse 2s ease-in-out infinite}
.mh-app .att-live.on .lv-n{color:#4E7C72}
@keyframes mhLivePulse{0%,100%{box-shadow:0 0 0 3px rgba(78,124,114,.22)}50%{box-shadow:0 0 0 6px rgba(78,124,114,.05)}}
@media (prefers-reduced-motion:reduce){.mh-app .att-live.on .lv-dot{animation:none}}

/* kiosk cell, still in the room = a soft ring so "here now" reads at a glance */
.mh-app td.att-cell.done.auto.in{position:relative}
.mh-app td.att-cell.done.auto.in::after{content:"";position:absolute;right:5px;bottom:5px;width:7px;height:7px;
  border-radius:999px;background:#4E7C72;box-shadow:0 0 0 2px #fff;pointer-events:none}
body.dark .mh-app td.att-cell.done.auto.in::after{box-shadow:0 0 0 2px #222E38}
/* kiosk cell, scanned out again = present, no "here now" dot (the default look) */

/* =============================================================================
   ONE BACKGROUND FOR EVERY REMINDER / ACTIVITY ICON CHIP
   (CEO, Aug 2 2026 - from user feedback: "all icons must have same background",
   and the one they chose is the Appointment-scheduled slate.)
   -----------------------------------------------------------------------------
   BEFORE, the chip's background came from FOUR different places, which is why the
   list looked like four different designs:
     .rem-ico.warning  rgba(216,155,61,.16)  <- the CREAM on Work Authorization Expiry
     .rem-ico.danger   rgba(176,70,60,.13)
     .rem-ico.info     rgba(94,122,131,.14)  <- the one that was chosen
     .rem-ico.success  rgba(78,124,114,.13)
   plus, on the Planner only, a PER-TYPE inline tint (`background:{ColorHex}22`)
   from Planner.IcoStyle, which beat all of them.

   The GLYPH COLOUR is deliberately left alone. Only the plate behind it is
   unified - the icon still reads amber for a warning and red for something
   overdue, so no urgency information is lost.

   THIS MOVES THREE SURFACES, which is the point: Dashboard Upcoming Reminders,
   Dashboard Recent Activity and Planner Upcoming Reminders all share this chip.

   DARK MODE NEEDED THE SAME FIX - I first wrote that it did not. Measuring it proved
   otherwise: the `!important` rules further up only cover `.rem-item` and `.activity`,
   while `body.dark .mh-app .mh-fs .rem-ico` in mh-frostedsage.css computes
   `color-mix(in oklch, var(--t) 26%, #1c2226)` PER TYPE, so dark carried exactly the
   same three-way split (one blue plate, two amber, ten with none at all). Both themes
   are unified below, each to its own single plate.

   THE SPECIFICITY TRAP THIS HIT FIRST, worth keeping: the real source of the cream
   was not any of the four variants above. It is a PER-ROW CSS VARIABLE - the row sets
   `--tbg:#F7EDD8` from the reminder type's colour and `.mh-app .mh-fs .rem-ico`
   consumes it. That rule lives in mh-frostedsage.css, which loads AFTER mh-theme.css,
   so a same-specificity (0,3,0) override written here LOSES on source order and the
   chips did not move at all. `.mh-app.mh-app` doubles the class to (0,4,0) and wins
   wherever the file sits in the cascade. It also explains the THIRD state seen while
   measuring - rows with no `--tbg` at all computed `background: var(--tbg)` as
   invalid, i.e. fully transparent, so the activity feed had no plate whatsoever.
   ============================================================================= */
.mh-app.mh-app .rem-ico,
.mh-app.mh-app .rem-ico.warning,
.mh-app.mh-app .rem-ico.danger,
.mh-app.mh-app .rem-ico.info,
.mh-app.mh-app .rem-ico.success,
.mh-app.mh-app .mh-fs .rem-ico,
.mh-app.mh-app .mh-fs .reminders .rem-ico,
.mh-app.mh-app .mh-fs .activity .rem-ico { background: rgba(94, 122, 131, .14); }

/* Dark: ONE light plate for every chip, the treatment the existing !important rules
   already used for .rem-item / .activity - the brand glyphs are baked-colour artwork
   and need a light plate to read. Specificity (0,5,1) so it beats
   `body.dark .mh-app .mh-fs .rem-ico` (0,4,1) in mh-frostedsage.css, which loads later. */
body.dark .mh-app.mh-app .rem-ico,
body.dark .mh-app.mh-app .rem-ico.warning,
body.dark .mh-app.mh-app .rem-ico.danger,
body.dark .mh-app.mh-app .rem-ico.info,
body.dark .mh-app.mh-app .rem-ico.success,
body.dark .mh-app.mh-app .mh-fs .rem-ico,
body.dark .mh-app.mh-app .mh-fs .reminders .rem-ico,
body.dark .mh-app.mh-app .mh-fs .activity .rem-ico { background: rgba(234, 239, 237, .94); }

/* =============================================================================
   GIFT CARD tab heading (CEO, Aug 2 2026) - title + subtitle on the left, the
   GIFT READY meter on the right, in the row where the subtitle used to be.
   `.gc-*` prefix: `.card__head` is a SHARED class, so nothing here may leak to the
   other cards that use it (Recently issued, and every card on the other tabs).
   ============================================================================= */
.mh-app .card__head.gc-head{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;flex-wrap:wrap;}
.mh-app .gc-head .gc-head-tx{min-width:0;flex:1 1 320px;}
.mh-app .gc-head .gc-head-tx h3{margin:0;}
.mh-app .gc-head .gc-head-sub{margin:5px 0 0;font-size:12.5px;color:var(--mh-muted);line-height:1.5;max-width:62ch;}
/* The meter keeps its own width so the bar reads as a bar, not a hairline. */
.mh-app .gc-head .gc-ready{flex:0 0 auto;width:200px;}
@media (max-width:860px){ .mh-app .gc-head .gc-ready{width:100%;} }
/* The right-hand STATE on a .gc-head row (e.g. "No gift cards issued yet."). Baseline-
   aligned with the title, not the subtitle, so it reads across the top line. */
.mh-app .gc-head .gc-head-state{flex:0 0 auto;font-size:12.5px;color:var(--mh-muted);align-self:center;}

/* The word between the two custom-range date inputs. A hyphen there reads as a
   minus sign wedged between two controls, so this one says "to" (CEO, Aug 4 2026 -
   the arrow went everywhere it separated two dates). */
.att-custom .att-to{font-size:12.5px;font-weight:700;color:var(--ink-3);padding:0 2px}

/* =============================================================================
   TOPBAR THEME ICON - moon (go dark) / sun (go light).
   Driven from body.dark in CSS, NOT from JS inline styles. shell.js used to set
   .style.display on both <svg>s, but they live inside MainLayout's Blazor render
   tree: on the interactive render after a page load Blazor reasserted its own
   markup and the topbar ended up showing the light icon while the app was dark.
   A class on <body> is the one thing Blazor never rewrites, so the icon and the
   theme cannot disagree. (Reproduced and fixed Aug 9 2026.)
   ============================================================================= */
#darkIcoSun { display: none; }
body.dark #darkIcoMoon { display: none; }
body.dark #darkIcoSun  { display: block; }

/* =============================================================================
   THE ANCHORED EVENT BUBBLE (Aug 10 2026)
   The K28 detail card, converted from a centered modal into a popup that opens
   BESIDE the chip you clicked - the Google Calendar behaviour.

   ANCHORED IS A MODIFIER, NOT A SECOND CARD. .ed-card keeps every rule it already
   had; .ed-anchored only stops the overlay centering it and pins it to the click
   point. That is what keeps this ONE detail surface.

   VIEWPORT UNITS: --mh-vw / --mh-vh, never bare vw/vh - the app runs inside a root
   zoom and bare viewport units ignore it.

   THE CLAMP IS THE WHOLE TRICK. A bubble pinned to a raw click point hangs off the
   screen for any chip near the right or bottom edge. clamp() keeps it fully inside
   with a 12px margin, in CSS, with no measuring pass and no JS.
   ============================================================================= */
.mh-app .ed-overlay.ed-anchored {
  /* CENTRED, NOT PINNED. Pinning the card to the pointer is what pushed it off the
     bottom edge for chips low on the grid - no amount of shrinking fixes a card
     taller than the room beneath the thing it hangs off. Centred, it always fits;
     the ARROW carries the connection to the chip instead of the position doing it. */
  justify-content: center;
  align-items: center;
  background: transparent;          /* a bubble does not dim the calendar behind it */
  /* THE OVERLAY MUST NOT EAT THE POINTER. It covers the whole screen, so while a
     bubble was open it sat on top of every other chip and swallowed their mouseover
     - hovering the next chip did nothing and you had to click to move on. A dimming
     modal wants that; a hover bubble is the opposite, you must be able to slide
     straight from one chip to the next. The catcher goes transparent to the pointer
     and the card alone takes events back. */
  pointer-events: none;
}
.mh-app .ed-overlay.ed-anchored .ed-card {
  /* THE CARD TAKES THE POINTER BACK. The overlay above is pointer-events:none so you
     can slide from chip to chip; without this line the card INHERITS that and the
     whole bubble becomes click-through - hovering it hits whatever chip is behind,
     which swaps the bubble out, and Edit/Delete cannot be clicked at all. */
  pointer-events: auto;
  position: relative;          /* the arrow is drawn against this box */
  overflow: visible;
  height: auto;
  /* HIDDEN UNTIL PLACED. planner.js measures the card while the overlay's flex
     centring still holds it, then pins it. Without this the card would be visible
     dead-centre for one frame and jump sideways - a flicker on every hover. */
  opacity: 0;
}
/* PINNED: vertically centred, horizontally following the chip. --ed-left comes
   from planner.js already clamped onto the screen. */
/* PINNED BESIDE THE CHIP. Both coordinates come from planner.js, already clamped
   onto the screen - the card is placed NEXT TO the chip, never over it, so the
   arrow always has something to point at. */
.mh-app .ed-overlay.ed-anchored .ed-card.ed-placed {
  position: fixed;
  left: var(--ed-left, 50%);
  top: var(--ed-top, 10%);
  opacity: 1;
  transform: none;            /* the placed card is never scaled - see edPop */
  animation: edPop .16s ease-out;
}

/* OPACITY ONLY - NO TRANSFORM. A scale() on this card is not free: while it is
   applied the element is DRAWN smaller than it is laid out, so its painted left edge
   sits (width - width*scale)/2 inside the coordinate JS placed it at - 11px at 640px
   wide - and the card reads as detached from its chip. It also poisons every
   getBoundingClientRect taken during the animation. A fade is smooth and moves
   nothing. */
@keyframes edPop {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* Anyone who has asked the OS to stop moving things gets the card, not the motion. */
@media (prefers-reduced-motion: reduce) {
  .mh-app .ed-overlay.ed-anchored .ed-card { animation: none; }
}

/* =============================================================================
   THE QUICK-CREATE BUBBLE (Aug 11 2026)
   Clicking an EMPTY day cell or hour slot opens the create sheet BESIDE that cell
   rather than dead-centre, in the same anchored language as the detail bubble - and
   through the same planner.js, which is why there is no second positioner here and
   why this block is a handful of modifiers rather than a second card.

   THE BACKDROP STAYS SOLID TO THE POINTER, unlike the detail bubble's. That one lets
   clicks through so you can slide from chip to chip; here the next stray click would
   land on another cell and RESET a half-filled form, so this backdrop swallows it -
   the inert-backdrop ruling, where Cancel and Finish are the only two ways out. But a
   blocking layer you cannot see reads as a frozen app, so it keeps a faint scrim:
   enough to say "this is the thing now", not enough to dim the calendar the form is
   being filled in ABOUT.
   ============================================================================= */
.mh-app .pl-overlay.ecs-overlay.ecs-anchored {
  background: rgba(28, 38, 44, .16);   /* a hint, not the centered sheet's deep gradient */
  padding: 0;          /* the card is pinned by JS; padding only shrinks the pre-placement measure */
  overflow: visible;
}
.mh-app .ecs-overlay.ecs-anchored .ecs-card {
  position: relative;  /* the arrow is drawn against this box */
  overflow: visible;   /* ...and would be clipped straight off without this */
  /* HIDDEN UNTIL PLACED. planner.js measures the card while the overlay's flex
     centring still holds it, then pins it. Without this the card is visible
     dead-centre for one frame and jumps sideways - a flicker on every open. */
  opacity: 0;
  /* NO SCALE. The card's default animation is pl-menu-in, which scales from .96, and
     a scaled element is DRAWN inside the box it was placed at - so the card reads as
     detached from its cell, and any rect measured mid-animation is a lie. */
  animation: none;
}
/* overflow:visible let the arrow out. It also let the pine band's square corners out
   past the card's radius, so the band carries its own. */
.mh-app .ecs-overlay.ecs-anchored .ecs-band { border-radius: 26px 26px 0 0; }

/* PINNED BESIDE THE CELL. Both coordinates come from planner.js already clamped onto
   the screen; .ed-placed is the positioner's vocabulary, shared with the bubble. */
.mh-app .ecs-overlay.ecs-anchored .ecs-card.ed-placed {
  position: fixed;
  left: var(--ed-left, 50%);
  top: var(--ed-top, 10%);
  opacity: 1;
  transform: none;
  animation: edPop .16s ease-out;   /* opacity only - see edPop */
}
@media (prefers-reduced-motion: reduce) {
  .mh-app .ecs-overlay.ecs-anchored .ecs-card.ed-placed { animation: none; }
}

/* ---- the header action row: Edit / Delete / (...) / Close ------------------ */
.mh-app .ed-card .ed-actions {
  position: absolute;
  top: 10px;
  right: 12px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 2px;
}
.mh-app .ed-card .ed-act {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border: none; background: none; padding: 0;
  border-radius: 999px;
  color: var(--mh-ctrl-ico, #6B7A76);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.mh-app .ed-card .ed-act:hover,
.mh-app .ed-card .ed-act.on { background: rgba(40, 60, 80, .08); color: var(--mh-ink); }
.mh-app .ed-card .ed-act:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(78, 124, 114, .32); }

.mh-app .ed-card .ed-morewrap { position: relative; }
.mh-app .ed-card .ed-more {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  /* One width for the menu and full-width rows inside it, so the labels start on a
     single left edge instead of each row shrink-wrapping its own text. */
  width: 184px;
  align-items: stretch;
  background: var(--mh-surface, #fff);
  border: 1px solid rgba(40, 60, 80, .12);
  border-radius: var(--mh-r-md, 14px);
  box-shadow: 0 14px 40px rgba(33, 50, 58, .18);
  padding: 6px;
  display: flex;
  flex-direction: column;
  z-index: 4;
}
.mh-app .ed-card .ed-more-item {
  border: none; background: none; cursor: pointer;
  font-family: inherit; font-size: 14px;
  text-align: left;
  justify-content: flex-start;   /* MudBlazor centres every button; text-align alone
                                    does not beat it on a flex control */
  display: block; width: 100%;
  padding: 9px 12px; border-radius: var(--mh-r-sm, 9px);
  color: var(--mh-ink);
  transition: background .15s ease;
}
.mh-app .ed-card .ed-more-item:hover { background: rgba(40, 60, 80, .06); }

/* ---- guests ---------------------------------------------------------------- */
.mh-app .ed-guests { margin: 4px 0 14px; }
.mh-app .ed-gtop { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.mh-app .ed-gcount { font-size: 14px; font-weight: 700; color: var(--mh-ink); }
.mh-app .ed-gsum   { font-size: 12.5px; color: var(--mh-ink-3, #7C8A86); }
.mh-app .ed-glist  { display: flex; flex-direction: column; gap: 7px; }
.mh-app .ed-guest  { display: flex; align-items: center; gap: 10px; }
.mh-app .ed-gav {
  position: relative;
  width: 28px; height: 28px; flex: none;
  border-radius: 999px;
  display: grid; place-items: center;
  color: #fff; font-size: 11.5px; font-weight: 700;
}
/* The tick states the ANSWER. Green yes / clay no / amber maybe - one grey tick on
   everybody would read as "attending" for people who declined. */
.mh-app .ed-gtick {
  position: absolute; right: -3px; bottom: -3px;
  width: 14px; height: 14px;
  border-radius: 999px;
  display: grid; place-items: center;
  border: 2px solid var(--mh-surface, #fff);
  color: #fff;
}
.mh-app .ed-gtick svg { width: 8px; height: 8px; }
.mh-app .ed-gtick.s2 { background: #3E9E6B; }   /* Accepted  */
.mh-app .ed-gtick.s3 { background: #C15F45; }   /* Declined  */
.mh-app .ed-gtick.s4 { background: #C0902F; }   /* Tentative */
.mh-app .ed-gname { font-size: 14px; color: var(--mh-ink); display: flex; flex-direction: column; line-height: 1.25; }
.mh-app .ed-gorg  { font-size: 11.5px; color: var(--mh-ink-3, #8A9591); }

/* ---- RSVP ------------------------------------------------------------------ */
.mh-app .ed-rsvp {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--mh-line-cool, #D9DFE7);
}
.mh-app .ed-rsvpq { font-size: 14px; font-weight: 600; color: var(--mh-ink); }
.mh-app .ed-rsvpbtns { display: flex; align-items: center; gap: 6px; }
.mh-app .ed-rsvpb {
  min-width: 62px; height: 34px; padding: 0 14px;
  border-radius: 999px;
  border: 1px solid var(--mh-line-cool, #D9DFE7);
  background: var(--mh-surface, #fff);
  font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--mh-ink-2, #4A5A56);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.mh-app .ed-rsvpb:hover:not(:disabled) { background: rgba(40, 60, 80, .05); }
.mh-app .ed-rsvpb:disabled { opacity: .55; cursor: default; }
/* The chosen answer is FILLED, not merely outlined: at a glance a person must see
   WHICH way they replied, not just that they replied. */
.mh-app .ed-rsvpb.on.yes   { background: var(--mh-green, #4E7C72); border-color: var(--mh-green, #4E7C72); color: #fff; }
.mh-app .ed-rsvpb.on.no    { background: #C15F45; border-color: #C15F45; color: #fff; }
.mh-app .ed-rsvpb.on.maybe { background: #C0902F; border-color: #C0902F; color: #fff; }
.mh-app .ed-rsvpchev {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: 999px; border: 1px solid transparent; background: none;
  color: var(--mh-ctrl-ico, #6B7A76); cursor: pointer;
  transition: background .15s ease, transform .18s ease;
}
.mh-app .ed-rsvpchev:hover { background: rgba(40, 60, 80, .07); }
.mh-app .ed-rsvpchev.on { transform: rotate(180deg); }
.mh-app .ed-rsvpnote {
  margin-top: 10px; padding: 10px 12px;
  border-radius: var(--mh-r-sm, 9px);
  background: rgba(40, 60, 80, .05);
  font-size: 12.5px; color: var(--mh-ink-2, #4A5A56);
  display: flex; flex-direction: column; gap: 3px;
}
.mh-app .ed-rsvpwho { color: var(--mh-ink-3, #8A9591); }

/* ---- dark parity ----------------------------------------------------------- */
body.dark .mh-app .ed-card .ed-act { color: #a7b5b1; }
body.dark .mh-app .ed-card .ed-act:hover,
body.dark .mh-app .ed-card .ed-act.on { background: rgba(255, 255, 255, .10); color: #eef2f1; }
body.dark .mh-app .ed-card .ed-more { background: var(--mh-surface); border-color: var(--mh-line); box-shadow: 0 18px 46px rgba(0, 0, 0, .5); }
body.dark .mh-app .ed-card .ed-more-item { color: #e6ecea; }
body.dark .mh-app .ed-card .ed-more-item:hover { background: rgba(255, 255, 255, .08); }
body.dark .mh-app .ed-gcount { color: #e6ecea; }
body.dark .mh-app .ed-gsum,
body.dark .mh-app .ed-gorg,
body.dark .mh-app .ed-rsvpwho { color: #8d9a96; }
body.dark .mh-app .ed-gname,
body.dark .mh-app .ed-rsvpq { color: #e6ecea; }
body.dark .mh-app .ed-gtick { border-color: var(--mh-surface); }
body.dark .mh-app .ed-rsvpb { background: var(--mh-ctrl-fill); border-color: var(--mh-line); color: #c2d0ca; }
body.dark .mh-app .ed-rsvpb:hover:not(:disabled) { background: rgba(255, 255, 255, .08); }
body.dark .mh-app .ed-rsvpnote { background: rgba(255, 255, 255, .06); color: #c2d0ca; }


/* ---- anchored bubble: SMALLER TEXT, SAME LAYOUT ---------------------------
   Scoped to .ed-anchored so the centered card (agenda row, bell deep-link) is
   untouched. Every rule here sets a font-size and nothing else - no width, no
   padding, no max-height - because the previous attempt changed geometry and that
   is what clipped the date tile and cut the buttons off. */
.mh-app .ed-overlay.ed-anchored .ed-card    { font-size: 13px; }
.mh-app .ed-overlay.ed-anchored h2          { font-size: 18px; }
.mh-app .ed-overlay.ed-anchored .ed-eyebrow { font-size: 10.5px; }
.mh-app .ed-overlay.ed-anchored .ed-railhead{ font-size: 10px; }
.mh-app .ed-overlay.ed-anchored .ed-wv      { font-size: 13.5px; }
.mh-app .ed-overlay.ed-anchored .ed-wt      { font-size: 12px; }
.mh-app .ed-overlay.ed-anchored .ed-nlabel  { font-size: 10.5px; }
.mh-app .ed-overlay.ed-anchored .ed-nbox    { font-size: 12.5px; }
.mh-app .ed-overlay.ed-anchored .ed-gcount  { font-size: 13px; }
.mh-app .ed-overlay.ed-anchored .ed-gsum    { font-size: 11.5px; }
.mh-app .ed-overlay.ed-anchored .ed-gname   { font-size: 12.5px; }
.mh-app .ed-overlay.ed-anchored .ed-gorg    { font-size: 10.5px; }
.mh-app .ed-overlay.ed-anchored .ed-rsvpq   { font-size: 13px; }
.mh-app .ed-overlay.ed-anchored .ed-rsvpb   { font-size: 12px; }
.mh-app .ed-overlay.ed-anchored .ed-foot .btn { font-size: 12.5px; }


/* ---- the connector arrow ---------------------------------------------------
   A triangle on the card edge nearest the chip, positioned by planner.js, which
   measures both rectangles. Two stacked triangles rather than one: the outer sits
   1px further out and carries the border colour, so the arrow has the same
   hairline the card does instead of looking pasted on. --arr-pos is the offset
   ALONG that edge.

   ONE ARROW, TWO CARDS. Both the detail bubble (.ed-card) and the quick-create
   bubble (.ecs-card) are placed by the same planner.js, so they wear the same arrow:
   the rules below key on the shared marker class .mh-arrowcard, and the two colours
   that differ between cards are tokens, not a second copy of these eight rules. A
   duplicated block is how the two bubbles would quietly drift apart. */
.mh-app .mh-arrowcard {
  --arr-line: rgba(40, 60, 80, .12);          /* the hairline, matching the card's own */
  --arr-fill: var(--mh-surface, #fff);        /* the card's face */
  --arr-fill-right: var(--mh-surface, #fff);  /* its right-hand edge, usually the same */
}
/* ...but the DETAIL card's right-hand edge is its tinted meta rail, not the white
   body - so only that one token differs. Higher specificity, not source order. */
.mh-app .ed-card.mh-arrowcard    { --arr-fill-right: var(--mh-rail-bg, #F2F5F7); }
body.dark .mh-app .mh-arrowcard  { --arr-line: var(--mh-line); }
body.dark .mh-app .ed-card.mh-arrowcard { --arr-fill-right: var(--mh-surface); }

.mh-app .mh-arrowcard.arr-top::before,    .mh-app .mh-arrowcard.arr-top::after,
.mh-app .mh-arrowcard.arr-bottom::before, .mh-app .mh-arrowcard.arr-bottom::after,
.mh-app .mh-arrowcard.arr-left::before,   .mh-app .mh-arrowcard.arr-left::after,
.mh-app .mh-arrowcard.arr-right::before,  .mh-app .mh-arrowcard.arr-right::after {
  content: "";
  position: absolute;
  width: 0; height: 0;
  border: 10px solid transparent;
  pointer-events: none;
}
/* TOP */
.mh-app .mh-arrowcard.arr-top::before {
  top: -20px; left: var(--arr-pos, 50%); margin-left: -10px;
  border-bottom-color: var(--arr-line);
}
.mh-app .mh-arrowcard.arr-top::after {
  top: -18px; left: var(--arr-pos, 50%); margin-left: -10px;
  border-bottom-color: var(--arr-fill);
}
/* BOTTOM */
.mh-app .mh-arrowcard.arr-bottom::before {
  bottom: -20px; left: var(--arr-pos, 50%); margin-left: -10px;
  border-top-color: var(--arr-line);
}
.mh-app .mh-arrowcard.arr-bottom::after {
  bottom: -18px; left: var(--arr-pos, 50%); margin-left: -10px;
  border-top-color: var(--arr-fill);
}
/* LEFT */
.mh-app .mh-arrowcard.arr-left::before {
  left: -20px; top: var(--arr-pos, 50%); margin-top: -10px;
  border-right-color: var(--arr-line);
}
.mh-app .mh-arrowcard.arr-left::after {
  left: -18px; top: var(--arr-pos, 50%); margin-top: -10px;
  border-right-color: var(--arr-fill);
}
/* RIGHT */
.mh-app .mh-arrowcard.arr-right::before {
  right: -20px; top: var(--arr-pos, 50%); margin-top: -10px;
  border-left-color: var(--arr-line);
}
.mh-app .mh-arrowcard.arr-right::after {
  right: -18px; top: var(--arr-pos, 50%); margin-top: -10px;
  border-left-color: var(--arr-fill-right);
}


/* ---- add note + propose a new time ----------------------------------------
   Lives inside the RSVP expander. Everything here is scoped to .ed-anchored so the
   centered card (agenda, bell deep-link) is untouched. */
.mh-app .ed-fld { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.mh-app .ed-fldlab {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--mh-ink-3, #8A9591);
}
.mh-app .ed-note {
  width: 100%;
  font-family: inherit; font-size: 12.5px; line-height: 1.45;
  padding: 8px 10px;
  border-radius: var(--mh-r-sm, 9px);
  border: 1px solid var(--mh-line-cool, #D9DFE7);
  background: var(--mh-surface, #fff);
  color: var(--mh-ink);
  resize: vertical;
}
.mh-app .ed-note:focus { outline: none; border-color: var(--mh-green, #4E7C72); box-shadow: 0 0 0 3px rgba(78,124,114,.18); }

.mh-app .ed-fldrow { display: flex; align-items: center; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.mh-app .ed-dt {
  font-family: inherit; font-size: 12px;
  padding: 6px 8px; min-width: 0; flex: 1 1 140px;
  border-radius: var(--mh-r-sm, 9px);
  border: 1px solid var(--mh-line-cool, #D9DFE7);
  background: var(--mh-surface, #fff);
  color: var(--mh-ink);
}
.mh-app .ed-mini {
  flex: none;
  height: 28px; padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--mh-line-cool, #D9DFE7);
  background: var(--mh-surface, #fff);
  font-family: inherit; font-size: 12px; font-weight: 600;
  color: var(--mh-ink-2, #4A5A56);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.mh-app .ed-mini:hover:not(:disabled) { background: rgba(40,60,80,.05); }
.mh-app .ed-mini:disabled { opacity: .5; cursor: default; }
/* Accept is the one that MOVES the event, so it is the only filled button here. */
.mh-app .ed-mini.ok { background: var(--mh-green, #4E7C72); border-color: var(--mh-green, #4E7C72); color: #fff; }

.mh-app .ed-proprow { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--mh-line-cool, #D9DFE7); }
.mh-app .ed-propcur { font-size: 12px; color: var(--mh-ink-2, #4A5A56); margin-top: 4px; }

/* on a guest's own row */
.mh-app .ed-gnote { font-size: 11.5px; font-style: italic; color: var(--mh-ink-3, #8A9591); }
.mh-app .ed-gprop {
  display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 11.5px; font-weight: 600; color: var(--mh-green, #4E7C72); margin-top: 2px;
}
.mh-app .ed-gprop .ed-mini { height: 24px; padding: 0 10px; font-size: 11px; }

body.dark .mh-app .ed-note,
body.dark .mh-app .ed-dt,
body.dark .mh-app .ed-mini { background: var(--mh-ctrl-fill); border-color: var(--mh-line); color: #e6ecea; }
body.dark .mh-app .ed-mini:hover:not(:disabled) { background: rgba(255,255,255,.08); }
body.dark .mh-app .ed-fldlab, body.dark .mh-app .ed-gnote { color: #8d9a96; }
body.dark .mh-app .ed-propcur { color: #c2d0ca; }
body.dark .mh-app .ed-gprop { color: #9fc7bd; }
body.dark .mh-app .ed-mini.ok { background: var(--mh-green, #4E7C72); border-color: var(--mh-green, #4E7C72); color: #fff; }

/* =============================================================================
   VIEW / PANE TITLES REMOVED (CEO, Aug 13 2026)
   -----------------------------------------------------------------------------
   "The left panel already indicates that, and we have the Help Center."

   Two headings said the same thing twice on every screen:
     - the LIST views ("All Households", "Federal R&P", "Document Expiry",
       "Archived") repeated the view already selected and highlighted in the left
       panel, plus a sentence describing it;
     - the DETAIL pane repeated the tab already highlighted in the tab row
       ("Overview" -> "Everything that needs attention first, at a glance.").

   Removed in CSS, in ONE place, rather than by editing seven page files plus
   DetailShell. The markup and the strings stay exactly where they are, so this is
   one rule to delete if a screen ever wants its heading back - and no page can be
   missed or accidentally broken in the sweep.

   ONLY THE TEXT IS HIDDEN, never the .phead container: Housing Subsidy keeps its
   "Back to Services" button inside that same block, and hiding the container
   would have taken a navigation control with it.
   ============================================================================= */
.mh-app .phead h1,
.mh-app .phead .pl-sub,
.mh-app .pane-sub { display: none !important; }

/* The block that held them should not leave a gap behind. The inline
   margin-bottom on .phead is beaten with !important deliberately - the markup is
   being left untouched, so the override has to happen here. */
.mh-app .phead { margin-bottom: 0 !important; }

/* =============================================================================
   WHAT'S-NEW TOUR (Aug 13 2026)
   -----------------------------------------------------------------------------
   pointer-events:none on the dimming layers is LOAD-BEARING. The previous tour
   in this app blocked every click and had to be switched off; this one paints
   over the page without ever intercepting a click. Only .tr-card takes input.
   ============================================================================= */
.mh-app .tr-spot,
.mh-app .tr-dim { position: fixed; z-index: 100070; pointer-events: none; }

/* The cutout: a huge spread shadow paints everything EXCEPT this box. */
.mh-app .tr-spot {
  border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(24, 32, 30, .55), 0 0 0 3px rgba(255, 255, 255, .9);
  animation: trPulse 2.2s ease-in-out infinite;
}
@keyframes trPulse {
  0%, 100% { box-shadow: 0 0 0 9999px rgba(24,32,30,.55), 0 0 0 3px rgba(255,255,255,.9); }
  50%      { box-shadow: 0 0 0 9999px rgba(24,32,30,.55), 0 0 0 7px rgba(255,255,255,.45); }
}
.mh-app .tr-dim { inset: 0; background: rgba(24, 32, 30, .55); }

.mh-app .tr-card {
  position: fixed; z-index: 100071; pointer-events: auto;
  width: min(378px, calc(100vw - 32px));
  background: var(--mh-surface); color: var(--mh-ink);
  border: 1px solid rgba(78, 124, 114, .3); border-radius: 18px;
  padding: 18px 20px 16px; box-shadow: 0 24px 60px rgba(20, 32, 28, .28);
  animation: trIn .22s cubic-bezier(.22,.61,.36,1) both;
}
@keyframes trIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }

/* No target to point at -> centre it. */
.mh-app .tr-card--mid { top: 50%; left: 50%; right: auto; transform: translate(-50%, -50%); }
@keyframes trInMid { from { opacity: 0; } to { opacity: 1; } }
.mh-app .tr-card--mid { animation-name: trInMid; }

.mh-app .tr-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.mh-app .tr-badge {
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--mh-muted); background: var(--mh-ctrl-fill);
  border: 1px solid var(--mh-line); border-radius: 999px; padding: 3px 9px;
}
.mh-app .tr-x {
  width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--mh-line);
  background: var(--mh-surface); color: var(--mh-muted); display: grid; place-items: center; cursor: pointer;
}
.mh-app .tr-x:hover { color: var(--mh-ink); }
.mh-app .tr-x svg { width: 14px; height: 14px; }

.mh-app .tr-ic {
  width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center;
  background: rgba(78, 124, 114, .12); margin-bottom: 12px;
}
body.dark .mh-app .tr-ic { background: rgba(78, 124, 114, .22); }
.mh-app .tr-ic svg.mh-bi { stroke: none; }

.mh-app .tr-title { margin: 0 0 8px; font-size: 17px; font-weight: 800; line-height: 1.25; }
.mh-app .tr-body  { margin: 0 0 12px; font-size: 13.2px; line-height: 1.6; color: var(--mh-muted); }

.mh-app .tr-list { margin: 0 0 14px; padding-left: 17px; }
.mh-app .tr-list li { font-size: 12.8px; line-height: 1.65; color: var(--mh-muted); margin-bottom: 5px; }

.mh-app .tr-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.mh-app .tr-dots { display: flex; gap: 6px; }
.mh-app .tr-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--mh-line); }
.mh-app .tr-dot.on { background: var(--mh-green, #4E7C72); width: 18px; border-radius: 999px; }

.mh-app .tr-btns { display: flex; gap: 8px; }
.mh-app .tr-btn {
  height: 34px; padding: 0 14px; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 12.8px; font-weight: 700;
  border: 1px solid var(--mh-line); background: var(--mh-surface); color: var(--mh-ink);
}
.mh-app .tr-btn:hover { border-color: var(--mh-ctrl-focus-border); }
.mh-app .tr-btn.ghost { color: var(--mh-muted); }
.mh-app .tr-btn.primary { background: var(--mh-green, #4E7C72); border-color: transparent; color: #fff; }
.mh-app .tr-btn.primary:hover { background: var(--mh-green-d, #2E4A43); }

@media (max-width: 560px) {
  .mh-app .tr-card { right: 12px !important; left: 12px; width: auto; }
}
