/* /Components/BeltChip.razor.rz.scp.css */
.cc-belt[b-2xbrznyq6m] { display: inline-flex; align-items: center; gap: 0.375rem; font-size: 0.875rem; }
.cc-belt__bar[b-2xbrznyq6m] { position: relative; display: inline-block; width: 1.75rem; height: 0.625rem; border-radius: 2px; background: var(--cc-belt, transparent); outline: 1px solid var(--theme-text-muted, currentColor); }
.cc-belt__bar[b-2xbrznyq6m]::after { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 3px; transform: translateX(-50%); background: var(--theme-text-main, currentColor); opacity: 0.45; }
/* /Components/Enrolment/AgreementSigner.razor.rz.scp.css */
/* The agreement sits in its own scroll box so "read to the end" is a real, checkable thing. Tokens only. */
.bu-agree[b-6hp7azzde2] { display: flex; flex-direction: column; gap: var(--structure-gap-sm, 0.5rem); }
.bu-agree__scroll[b-6hp7azzde2] {
  max-height: min(40vh, 24rem); overflow-y: auto; padding: 0.75rem 1rem;
  border: 1px solid var(--theme-border-inactive); background: var(--theme-bg-surface, transparent);
}
.bu-agree__scroll:focus-visible[b-6hp7azzde2] { outline: 2px solid var(--theme-x-focus-ring, var(--theme-border-active)); outline-offset: 2px; }
.bu-agree__controls[b-6hp7azzde2] { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); }
.bu-agree__controls[disabled][b-6hp7azzde2] { opacity: 0.55; }
.bu-agree__controls legend[b-6hp7azzde2] { padding: 0 0 var(--structure-gap-xs, 0.25rem); color: var(--theme-text-main); font-weight: 600; }
/* /Components/Enrolment/EnrolmentCard.razor.rz.scp.css */
/* B2 membership card in the student drawer: structure and spacing only. Colour comes from the skin tokens (greyscale Primer first, Executive Blue and the
   other skins restyle through --theme-*). No colour literals here. */
.bu-enrol-card[b-zscg1h3rcj] {
  list-style: none; display: flex; flex-direction: column; gap: 0.5rem; min-width: 0;
  border: 1px solid var(--theme-border-inactive); border-radius: var(--structure-radius-panel, 4px); padding: 0.75rem 1rem;
}
.bu-enrol-card p[b-zscg1h3rcj] { margin: 0; }
.bu-enrol-card__head[b-zscg1h3rcj] { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; }
.bu-enrol-card__name[b-zscg1h3rcj] { overflow-wrap: anywhere; }
.bu-enrol-card__row[b-zscg1h3rcj] { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
.bu-enrol-card__section[b-zscg1h3rcj] { display: flex; flex-direction: column; gap: 0.5rem; border-top: 1px solid var(--theme-border-inactive); padding-top: 0.5rem; }
.bu-enrol-card__heading[b-zscg1h3rcj] { margin: 0; font-size: 0.9375rem; font-weight: 600; text-transform: none; letter-spacing: normal; }
.bu-enrol-pay-list[b-zscg1h3rcj] { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.bu-enrol-pay-list li[b-zscg1h3rcj] { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; }
.bu-enrol-change[b-zscg1h3rcj] { display: flex; flex-direction: column; gap: 0.5rem; border-top: 1px solid var(--theme-border-inactive); padding-top: 0.5rem; }
.bu-enrol-card__history ul[b-zscg1h3rcj] { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.25rem; }
.bu-enrol-card__history summary[b-zscg1h3rcj] { cursor: pointer; min-height: 44px; display: flex; align-items: center; }
/* /Components/Enrolment/PlanChip.razor.rz.scp.css */
/* B2 membership chip. Tokens only (Primer greyscale base, skins restyle through --theme-*). The state tints the border; the words stay in the
   normal text colour so contrast holds in every skin, and the state is always spelled out (WCAG 1.4.1). */
.cc-plan[b-5375ntn980] {
  --_p: var(--theme-border-inactive);
  display: inline-flex; align-items: center; gap: 0.25rem;
  min-height: 24px; max-width: 100%; min-width: 0; padding: 0 0.5rem; box-sizing: border-box; font-size: 0.8125rem; font-weight: 600;
  color: var(--theme-text-main, inherit);
  border: 1px solid var(--_p); border-radius: 999px;
}
.cc-plan--ok[b-5375ntn980] { --_p: color-mix(in srgb, var(--theme-state-healthy, var(--theme-border-active)) 55%, var(--theme-text-main, currentColor)); }
.cc-plan--watch[b-5375ntn980] { --_p: color-mix(in srgb, var(--theme-state-warning, var(--theme-border-active)) 55%, var(--theme-text-main, currentColor)); }
.cc-plan__name[b-5375ntn980] { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* #503 compact (roster row): the mark alone; the plan name and status are still the tooltip and the screen-reader name. */
.cc-plan__words[b-5375ntn980] { display: inline-flex; align-items: center; gap: 0.25rem; min-width: 0; }
.cc-plan--compact[b-5375ntn980] { position: relative; padding: 0 0.375rem; min-width: 24px; justify-content: center; }
.cc-plan--compact .cc-plan__words[b-5375ntn980] {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* /Components/Enrolment/StudentMembershipPanel.razor.rz.scp.css */
/* B2 membership section of the student drawer: spacing only (tokens, no colour literals). */
.bu-enrol-list[b-f1e7j7prvi] { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
/* /Components/Events/EventInvitePanel.razor.rz.scp.css */
/* Invite people: tokens only. Greyscale skeleton; the skin owns the look. */
.evi[b-en63lyah91] { display: flex; flex-direction: column; gap: var(--structure-gap-md); border: 1px solid var(--theme-border-inactive); padding: var(--structure-gap-md); }
.evi h3[b-en63lyah91] { margin: 0; }
.evi-filters[b-en63lyah91] { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: var(--structure-gap-sm); }
.evi-actions[b-en63lyah91] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: center; }
.evi-people[b-en63lyah91] { list-style: none; margin: 0; padding: 0; max-block-size: 18rem; overflow-y: auto; display: flex; flex-direction: column; gap: var(--structure-gap-xs); border: 1px solid var(--theme-border-inactive); }
.evi-person[b-en63lyah91] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: center; padding: var(--structure-gap-xs) var(--structure-gap-sm); min-block-size: var(--structure-touch-min); }
.evi-warn[b-en63lyah91] { font-weight: 700; }
.evi-qr[b-en63lyah91] { margin: 0; display: flex; gap: var(--structure-gap-sm); align-items: center; }
.evi .bu-input[b-en63lyah91] { inline-size: 100%; min-block-size: var(--structure-touch-min); }
.evi .bu-btn[b-en63lyah91], .evi .bu-btn-secondary[b-en63lyah91] { min-block-size: var(--structure-touch-min); }
/* /Components/Events/EventPageBuilder.razor.rz.scp.css */
/* The page builder: tokens only, greyscale Primer structure; the skin colours it. Phone-first single column. */
.evb[b-l6d9clzrjy] { display: flex; flex-direction: column; gap: var(--structure-gap-md); }
.evb-section[b-l6d9clzrjy] { border-top: 1px solid var(--theme-border-inactive); padding-top: var(--structure-gap-md); }
.evb-section h3[b-l6d9clzrjy] { margin: 0 0 var(--structure-gap-sm); }
.evb-actions[b-l6d9clzrjy] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); margin-block: var(--structure-gap-sm); }
.evb-actions .bu-btn[b-l6d9clzrjy], .evb-actions .bu-btn-secondary[b-l6d9clzrjy], .evb-save .bu-btn[b-l6d9clzrjy] { min-height: var(--structure-touch-min); }
.evb-choices[b-l6d9clzrjy] { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--structure-gap-xs); min-width: 0; }
.evb .bu-check-label[b-l6d9clzrjy] { display: flex; align-items: flex-start; gap: var(--structure-gap-sm); min-height: var(--structure-touch-min); padding-block: var(--structure-gap-xs); }
.evb .bu-check-label input[type="checkbox"][b-l6d9clzrjy], .evb .bu-check-label input[type="radio"][b-l6d9clzrjy] { flex: 0 0 auto; inline-size: 1.5rem; block-size: 1.5rem; margin-block-start: 0.1rem; }
.evb .bu-input[b-l6d9clzrjy] { inline-size: 100%; min-block-size: var(--structure-touch-min); }
.evb-row[b-l6d9clzrjy] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--structure-gap-sm); padding: var(--structure-gap-sm); border: 1px solid var(--theme-border-inactive); margin-bottom: var(--structure-gap-sm); }
.evb-row-actions[b-l6d9clzrjy] { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--structure-gap-sm); }
.evb-schools[b-l6d9clzrjy] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); margin-block: var(--structure-gap-sm); }
.evb-chip[b-l6d9clzrjy] { display: inline-flex; align-items: center; gap: var(--structure-gap-xs); padding: 0 var(--structure-gap-sm); border: 1px solid var(--theme-border-inactive); min-height: var(--structure-touch-min); }
.evb-hits[b-l6d9clzrjy] { list-style: none; margin: 0 0 var(--structure-gap-sm); padding: 0; display: flex; flex-direction: column; gap: var(--structure-gap-xs); }
.evb-hits .bu-btn-secondary[b-l6d9clzrjy] { min-height: var(--structure-touch-min); inline-size: 100%; text-align: start; }
.evb-waiver[b-l6d9clzrjy] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-md); align-items: center; }
.evb-save[b-l6d9clzrjy] { position: sticky; bottom: 0; padding-block: var(--structure-gap-sm); background: var(--theme-surface, canvas); border-top: 1px solid var(--theme-border-inactive); }
.reg-qr[b-l6d9clzrjy] { margin: var(--structure-gap-sm) 0; display: flex; flex-direction: column; gap: var(--structure-gap-sm); align-items: flex-start; }
@media (max-width: 640px) { .evb-row[b-l6d9clzrjy] { grid-template-columns: minmax(0, 1fr); } }
/* /Components/Events/EventRegistrantList.razor.rz.scp.css */
/* The registrant list: tokens only. Rows are cards on a phone (the door is a phone or a tablet); the check-in button is a 44px-plus target. */
.evl[b-nad0cjhzp4] { display: flex; flex-direction: column; gap: var(--structure-gap-md); }
.evl-totals[b-nad0cjhzp4] { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: var(--structure-gap-sm); margin: 0; }
.evl-totals div[b-nad0cjhzp4] { border: 1px solid var(--theme-border-inactive); padding: var(--structure-gap-sm); }
.evl-totals dt[b-nad0cjhzp4] { color: var(--theme-text-muted); font-size: 0.8125rem; }
.evl-totals dd[b-nad0cjhzp4] { margin: 0; font-size: 1.25rem; font-weight: 700; }
.evl-toolbar[b-nad0cjhzp4] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-md); align-items: flex-end; justify-content: space-between; }
.evl-find[b-nad0cjhzp4] { flex: 1 1 14rem; }
.evl-toolbar-actions[b-nad0cjhzp4], .evl-actions[b-nad0cjhzp4] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); }
.evl .bu-input[b-nad0cjhzp4] { inline-size: 100%; min-block-size: var(--structure-touch-min); }
.evl .bu-btn[b-nad0cjhzp4], .evl .bu-btn-secondary[b-nad0cjhzp4] { min-block-size: var(--structure-touch-min); }
.evl-rows[b-nad0cjhzp4] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--structure-gap-sm); }
.evl-row[b-nad0cjhzp4] { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--structure-gap-sm) var(--structure-gap-md); align-items: center; padding: var(--structure-gap-sm); border: 1px solid var(--theme-border-inactive); }
.evl-main[b-nad0cjhzp4] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: baseline; }
.evl-side[b-nad0cjhzp4] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: center; justify-content: flex-end; }
.evl-checkin[b-nad0cjhzp4] { min-inline-size: 7rem; }
.evl-checked[b-nad0cjhzp4] { font-weight: 700; }
.evl-warn[b-nad0cjhzp4] { font-weight: 700; }
.evl-detail[b-nad0cjhzp4] { grid-column: 1 / -1; display: flex; flex-direction: column; gap: var(--structure-gap-sm); border-top: 1px solid var(--theme-border-inactive); padding-top: var(--structure-gap-sm); }
.evl-facts[b-nad0cjhzp4] { display: grid; gap: var(--structure-gap-xs); margin: 0; }
.evl-facts div[b-nad0cjhzp4] { display: grid; grid-template-columns: 9rem 1fr; gap: var(--structure-gap-sm); }
.evl-facts dt[b-nad0cjhzp4] { color: var(--theme-text-muted); font-size: 0.875rem; }
.evl-facts dd[b-nad0cjhzp4] { margin: 0; overflow-wrap: anywhere; }
.evl-pay[b-nad0cjhzp4] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--structure-gap-sm); }
.evl-pay .evl-actions[b-nad0cjhzp4], .evl-pay p[b-nad0cjhzp4] { grid-column: 1 / -1; }
@media (max-width: 640px) {
  .evl-row[b-nad0cjhzp4] { grid-template-columns: minmax(0, 1fr); }
  .evl-side[b-nad0cjhzp4] { justify-content: flex-start; }
  .evl-facts div[b-nad0cjhzp4] { grid-template-columns: 1fr; gap: 0; }
  .evl-pay[b-nad0cjhzp4] { grid-template-columns: minmax(0, 1fr); }
}
.evl-invited[b-nad0cjhzp4] { display: flex; flex-direction: column; gap: var(--structure-gap-sm); }
.evl-invited-rows[b-nad0cjhzp4] { list-style: none; margin: 0; padding: 0; max-block-size: 12rem; overflow-y: auto; display: flex; flex-direction: column; gap: var(--structure-gap-xs); }
.evl-invited-row[b-nad0cjhzp4] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: center; }
/* /Components/Events/EventRegistrationDrawer.razor.rz.scp.css */
/* The event registration drawer: tokens only (Executive Blue and the greyscale skeleton both read them). The shell is the shared .bu-drawer. */
.evd[b-7z7xu945oq] { min-width: 0; }
.evd-tabs[b-7z7xu945oq] { display: flex; gap: var(--structure-gap-sm); margin-bottom: var(--structure-gap-md); }
.evd-tab[b-7z7xu945oq] { min-height: var(--structure-touch-min); }
.evd-tab[aria-selected="true"][b-7z7xu945oq] { border-bottom: 3px solid var(--theme-border-active, currentColor); font-weight: 700; }
/* /Components/Homework/DrillList.razor.rz.scp.css */
/* #448: the XP chip is a small tag after the title, never a full-width bar. */
.bu-hw-xp[b-icagx709lv] { display: inline-flex; width: fit-content; max-width: 100%; align-self: flex-start; margin-left: var(--structure-gap-xs); white-space: nowrap; }
/* /Components/Homework/ReviewStrip.razor.rz.scp.css */
/* The Overview strip: the count and its one button on a single line; each waiting piece of work in the dialog gets air between them. */
.bu-hw-strip[b-fw1yq1o1ys] { display: flex; align-items: center; justify-content: space-between; gap: var(--structure-gap-md); flex-wrap: wrap; }
.bu-hw-review-item[b-fw1yq1o1ys] { margin-bottom: var(--structure-gap-md); }
/* /Components/Homework/StudentHomeworkPanel.razor.rz.scp.css */
/* #448: a row's state badge never wraps to two lines, and the destructive Cancel sits on its own line below the badges with a clear gap. */
.bu-hw-row[b-zx0gbs204y] { align-items: flex-start; }
.bu-hw-row-actions[b-zx0gbs204y] { display: flex; flex-direction: column; align-items: flex-end; gap: var(--structure-gap-sm); min-width: 0; }
.bu-hw-row-actions .bu-badge[b-zx0gbs204y] { white-space: nowrap; }
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/*
  MainLayout.razor.css — scoped component styling for the admin shell.
  Structure/spacing only; color via --theme-* tokens.
*/

[b-7e32cke0ad] .bu-rail {
    box-shadow: var(--theme-x-elevation-1);
}

[b-7e32cke0ad] main.bu-main {
    display: flex;
    flex-direction: column;
}

/* --- Console no-scroll shell cap (R-0709-15 point 1: "the console page must NOT
   scroll... overflow hidden on the shell") -----------------------------------------
   The outer .bu-slab (this component's own root — rail + main + footer stacked) is
   min-height:100vh with NO max-height by default (see bento-grid.css .bu-slab), so it
   grows past the viewport whenever rail+main+footer's natural content height exceeds
   100vh — exactly what was measured live (1014px content in a 900px viewport). Every
   OTHER admin page (Sessions, ThemeSettings, Curriculum, Internal hub...) legitimately
   wants that natural-scroll behavior, so this cap is scoped with :has() to ONLY the
   page whose routed content contains .bu-console-body (Home.razor's console shell) —
   not a blanket change to the shared layout. bu-has-fixed-rail distinguishes this
   OUTER .bu-slab from Home.razor's own nested <section class="bu-slab"> (which also
   "has" .bu-console-body as a descendant but lacks this class), so the selector below
   matches exactly one element.

   NOTE ON ::deep: this rule deliberately omits ::deep on the FIRST selector below —
   .bu-slab.bu-has-fixed-rail is this component's OWN root element (authored directly
   in MainLayout.razor), so Blazor already self-scopes it with this file's [b-xxxx]
   attribute directly. ::deep compiles to a DESCENDANT combinator ("[b-xxxx] .selector"),
   which requires an ANCESTOR carrying the attribute — the root element has none (its
   ancestors are outside this component), so a ::deep version of this selector silently
   never matches. The second rule targets main.bu-main, which genuinely IS a descendant
   of the root .bu-slab, so ::deep's descendant form is correct there (matches the same
   way the pre-existing "::deep main.bu-main" rule above already does). */
.bu-slab.bu-has-fixed-rail:has(.bu-console-body)[b-7e32cke0ad] {
    height: 100vh;
    max-height: 100vh;
    overflow: hidden;
}

[b-7e32cke0ad] .bu-slab.bu-has-fixed-rail:has(.bu-console-body) > main.bu-main {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

@media (max-width: 640px) {
    [b-7e32cke0ad] .bu-rail {
        padding: var(--structure-gap-sm) var(--structure-gap-md);
    }
}

/* EB-13 (2026-10-10): footer text sat at x=16 while the rail brand and every
   panel sat at x=32 on desktop — the Primer's .bu-soffit pads gap-md, the rail
   and .bu-bay-grid pad gap-xl. Matched to the bay grid's side inset (and its
   768px phone step), so the copyright lines up with the content above it.
   Scoped to this layout's own footer: .bu-soffit is also the filter-row shape
   on the internal pages, which must keep the Primer value. */
footer.bu-soffit[b-7e32cke0ad] {
    padding-left: var(--structure-gap-xl);
    padding-right: var(--structure-gap-xl);
}

@media (max-width: 768px) {
    footer.bu-soffit[b-7e32cke0ad] {
        padding-left: var(--structure-gap-md);
        padding-right: var(--structure-gap-md);
    }
}

/* TEMPORARY per owner order 2026-07-02 — REMOVE alongside the markup in
   MainLayout.razor when login/admin nav ships. Quiet, small, footer-appropriate. */
[b-7e32cke0ad] .bu-footer-internal-temp {
    font-size: var(--structure-text-xs);
    color: var(--theme-text-muted);
    margin-left: var(--structure-gap-md);
}

[b-7e32cke0ad] .bu-footer-internal-temp a {
    color: var(--theme-text-muted);
}
/* /Components/MemberPassCard.razor.rz.scp.css */
.bu-pass-card[b-stt8j5ett0] {
    box-sizing: border-box;
    width: 3.375in;
    height: 2.125in;
    flex: 0 0 auto;
    padding: 0.1in;
    border: 1px solid #000;
    border-radius: 0.125in;
    background: #fff;
    color: #000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    text-align: center;
    overflow: hidden;
    break-inside: avoid;
}

.bu-pass-name[b-stt8j5ett0] {
    box-sizing: border-box;
    width: 100%;
    height: 0.4in;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
    font-weight: 700;
    line-height: 1.15;
}

.bu-pass-qr[b-stt8j5ett0] {
    width: 1.1in;
    height: 1.1in;
    flex: 0 0 auto;
    image-rendering: pixelated;
}

.bu-pass-link[b-stt8j5ett0] {
    box-sizing: border-box;
    width: 100%;
    height: 0.3in;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
    font-size: 5.5pt;
    line-height: 1.2;
}
/* /Components/Messaging/MessagingPanel.razor.rz.scp.css */
/* Messaging panel: tokens only. Greyscale skeleton; the skin owns the look. No transform on containers. */
.msg[b-k4sathbitp] { display: flex; flex-direction: column; gap: var(--structure-gap-lg); }
.msg-compose[b-k4sathbitp], .msg-history[b-k4sathbitp] { display: flex; flex-direction: column; gap: var(--structure-gap-md); }
.msg-compose h3[b-k4sathbitp], .msg-history h3[b-k4sathbitp] { margin: 0; }
.msg-compose .bu-input[b-k4sathbitp] { inline-size: 100%; min-block-size: var(--structure-touch-min); }
.msg-compose .bu-btn[b-k4sathbitp], .msg-compose .bu-btn-secondary[b-k4sathbitp], .msg-history .bu-btn-secondary[b-k4sathbitp] { min-block-size: var(--structure-touch-min); }
.msg-people[b-k4sathbitp] { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); max-block-size: 12rem; overflow-y: auto; }
.msg-body-copy[b-k4sathbitp] { white-space: pre-wrap; overflow-wrap: anywhere; margin: 0 0 var(--structure-gap-sm); }
/* /Components/Pages/AssessmentSheetPrint.razor.rz.scp.css */
.bu-sheet-toolbar[b-2tq8rvcnh0] {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 1rem;
}

.bu-sheet-head[b-2tq8rvcnh0], .bu-sheet-group[b-2tq8rvcnh0] {
    padding: 0 1rem;
}

.bu-sheet-table[b-2tq8rvcnh0] {
    width: 100%;
    border-collapse: collapse;
}

.bu-sheet-table th[b-2tq8rvcnh0],
.bu-sheet-table td[b-2tq8rvcnh0] {
    border: 1px solid currentColor;
    padding: 0.35rem 0.5rem;
    text-align: left;
    vertical-align: top;
}

.bu-sheet-notes[b-2tq8rvcnh0] {
    min-width: 2in;
}

.bu-sheet-group[b-2tq8rvcnh0] {
    break-inside: avoid;
}

@media print {
    .bu-sheet-toolbar[b-2tq8rvcnh0] {
        display: none;
    }
}
/* /Components/Pages/CertificatePrint.razor.rz.scp.css */
.bu-cert-toolbar[b-28lk2jvaao] {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 1rem;
}

.bu-cert[b-28lk2jvaao] {
    margin: 0 auto;
    max-width: 9.5in;
    padding: 0.75in 0.5in;
    border: 6px double currentColor;
    text-align: center;
}

.bu-cert-logo[b-28lk2jvaao] {
    max-height: 1.2in;
    max-width: 3in;
}

.bu-cert-school[b-28lk2jvaao] {
    font-size: 1.4rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.bu-cert-name[b-28lk2jvaao] {
    font-size: 2.2rem;
    font-weight: 700;
    margin: 0.4rem 0;
}

.bu-cert-rank[b-28lk2jvaao] {
    font-size: 1.8rem;
    font-weight: 700;
    margin: 0.4rem 0 0;
}

.bu-cert-foot[b-28lk2jvaao] {
    display: flex;
    justify-content: space-around;
    margin-top: 0.9in;
}

.bu-cert-foot > div[b-28lk2jvaao] {
    display: flex;
    flex-direction: column;
    min-width: 3in;
}

.bu-cert-line[b-28lk2jvaao] {
    border-bottom: 1px solid currentColor;
    min-height: 1.6rem;
    padding: 0 0.5rem;
}

@media print {
    .bu-cert-toolbar[b-28lk2jvaao] {
        display: none;
    }

    .bu-cert[b-28lk2jvaao] {
        break-inside: avoid;
    }
}

/* R-1027-20: a batch prints one certificate per page. */
.bu-cert + .bu-cert[b-28lk2jvaao] {
    break-before: page;
    margin-top: 1rem;
}
/* /Components/Pages/ClassCalendar.razor.rz.scp.css */
/*
  ClassCalendar.razor.css - scoped structure for the class calendar page (R-1023-11). Structure and spacing only; colour comes from
  the --theme-* tokens via calendar-render.css. Replaces Sessions.razor.css (the Class Sessions list page is retired).
*/

/* #313: small divider label between "Usual for this class" and everyone else in the class panel roster. */
[b-6p4i9i33ir] .bu-roster-divider {
    margin: var(--structure-gap-sm) 0 0;
    font-size: var(--structure-text-sm, 0.875rem);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 1px solid currentColor;
    opacity: 0.8;
    min-height: 0;
}

[b-6p4i9i33ir] input.bu-input[type="search"] {
    min-height: var(--structure-touch-min);
    width: 100%;
    box-sizing: border-box;
}
/* /Components/Pages/Curriculum.razor.rz.scp.css */
/*
  Curriculum.razor.css — scoped layout for the Admin curriculum page's rank ladder
  (D-15 / D-24, 2026-08-29 live-walkthrough findings).

  Structure and spacing only, no color: everything here exists to give a rank row a
  stable two-column shape — a text column that wraps, and a fixed-width action column
  that every "Edit" button lands in — instead of buttons flowing inline after a rank's
  RequirementsText and ending up at a different x on every row (and wrapping under the
  row entirely once the text ran long). Because no rule here assigns color, no
  render-*.css counterpart is needed and no partial-skin fallthrough is possible
  (D-S07-SKIN-02) — same posture as .bu-form-actions in bento-grid.css.

  Selectors are plain (no ::deep): every element they match is authored directly in
  Curriculum.razor, so Blazor's scope attribute is already on it.
*/

/* The ladder <ol> keeps .bu-brick's flex column; it only sheds the list marker box,
   which a flex container renders inconsistently anyway, and the row padding, which
   now belongs to the row itself. */
.bu-ladder[b-h30dn9s9zz] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.bu-ladder[b-h30dn9s9zz]  .bu-ladder-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: var(--structure-gap-md);
    padding: var(--structure-gap-sm) 0;
}

.bu-ladder[b-h30dn9s9zz]  .bu-ladder-main {
    display: flex;
    flex-direction: column;
    gap: var(--structure-gap-xs);
    /* flex-basis 0 + min-width 0 is what actually holds the row together: without
       min-width:0 a long unbroken requirements string sets the column's minimum
       content width and pushes the action column off to the right. */
    flex: 1 1 0;
    min-width: 0;
}

.bu-ladder[b-h30dn9s9zz]  .bu-ladder-requirements {
    /* Seeded requirements are full paragraphs and their "[YOUR SCHOOL: ...]" gap
       marker sits at the very END of the string — so this wraps completely and is
       never clipped, ellipsized or line-clamped. */
    overflow-wrap: anywhere;
    white-space: normal;
    font-size: var(--structure-text-sm);
    line-height: 1.4;
}

/* The stable action column: same width on every row, so the buttons form one
   straight edge whether a rank's text is six words or six lines. */
.bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions {
    display: flex;
    justify-content: flex-end;
    align-items: flex-start;
    gap: var(--structure-gap-sm);
    flex: 0 0 auto;
    width: 7rem;
}

/* ADM-EB-18 (2026-10-10): the row's Edit is now .bu-btn-secondary (the secondary
   role's class); the selector follows it. */
.bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions > .bu-control,
.bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions > .bu-btn-secondary {
    width: 100%;
}

/* An open inline edit form owns the whole row — no action column beside it. */
.bu-ladder[b-h30dn9s9zz]  .bu-ladder-edit {
    flex: 1 1 100%;
    min-width: 0;
}

/* CURR-10 / E23 accuracy note: .bu-brick already supplies the stacked column, this
   only separates it from the preview list above and the apply row below. */
.bu-curriculum-note[b-h30dn9s9zz] {
    margin-top: var(--structure-gap-sm);
}

/* -----------------------------------------------------------------------
   R-0904-01 multi-style: "Styles you teach" (Section a0) and the per-style
   heading meta line in "Your curriculum" (Section b).

   Same posture as everything above — structure and spacing only, no colour.
   The muted tone on the count/provenance lines comes from composing
   .bu-text-muted in the markup, which every render-*.css already defines, so
   this file still assigns no colour and still needs no render counterpart
   (D-S07-SKIN-02, no partial-skin fallthrough).
   ----------------------------------------------------------------------- */

/* Like .bu-ladder: keep .bu-brick's flex column, shed only the list marker box
   and the default list padding. */
.bu-style-list[b-h30dn9s9zz] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.bu-style-item[b-h30dn9s9zz] {
    display: flex;
    flex-direction: column;
    gap: var(--structure-gap-xs);
    padding: var(--structure-gap-sm) 0;
    min-width: 0;
}

/* Name and rank count share one line while there is room, and the count drops
   under the name rather than squeezing a long style name when there isn't.
   Baseline (not centre) so the smaller count sits on the name's baseline. */
.bu-style-headline[b-h30dn9s9zz] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--structure-gap-sm);
    min-width: 0;
}

.bu-style-name[b-h30dn9s9zz] {
    min-width: 0;
    overflow-wrap: anywhere;
}

.bu-style-count[b-h30dn9s9zz] {
    flex: 0 0 auto;
    font-size: var(--structure-text-sm);
}

/* A governing-body line is a full sentence in the seeded catalog (IFMA's, for
   one, names the standard, its year and why it was chosen), so it wraps in full
   at the smaller size — never clipped, ellipsized or line-clamped, same rule the
   requirements text follows. */
.bu-style-provenance[b-h30dn9s9zz] {
    overflow-wrap: anywhere;
    white-space: normal;
    font-size: var(--structure-text-sm);
    line-height: 1.4;
}

/* The meta line under a per-style <h3> in the ladder. .bu-brick supplies the
   column; this only pulls it up against its own heading (the .bu-reveal above it
   already spent 8px below) and keeps it off the first rank row. */
.bu-style-groupmeta[b-h30dn9s9zz] {
    padding-top: 0;
    padding-bottom: var(--structure-gap-xs);
}

/* Each style group's own "Add rank" sits closer to that group's ladder than to
   the next style's heading, so it reads as belonging to the ladder above it. */
.bu-style-groupactions[b-h30dn9s9zz] {
    margin-top: var(--structure-gap-xs);
}

/* Narrow console widths (or a very narrow slide-out host later): the action column
   stops being a column and the row stacks, rather than squeezing the text to a
   two-word ribbon. The buttons still line up — they are simply left-aligned under
   their own row. */
@media (max-width: 640px) {
    .bu-ladder[b-h30dn9s9zz]  .bu-ladder-row {
        flex-wrap: wrap;
    }

    .bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions {
        width: auto;
        justify-content: flex-start;
    }

    .bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions > .bu-control,
    .bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions > .bu-btn-secondary {
        width: auto;
    }
}

/* Slice curr: a rank row carries move up / down, Requirements, Edit and Remove, so its action column is wider, wraps, and its buttons keep
   their own width (the old column was sized for one Edit button). */
.bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions.bu-rank-actions {
    width: auto;
    max-width: 15rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions.bu-rank-actions > .bu-btn-secondary {
    width: auto;
}

@media (max-width: 640px) {
    .bu-ladder[b-h30dn9s9zz]  .bu-ladder-actions.bu-rank-actions {
        flex: 1 1 100%;
        max-width: 100%;
        justify-content: flex-start;
    }
}

/* ---- R-1026-01 compact Edit rows: one line (chip, summary) with the buttons on the right, centred on the 44px buttons ---- */
.bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact {
    align-items: center;
}

.bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact .bu-rank-row__main {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--structure-gap-xs) var(--structure-gap-md);
}

.bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact .bu-rank-summary {
    flex: 1 1 10rem;
    min-width: 0;
}

.bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact .bu-ladder-actions.bu-rank-actions {
    flex-wrap: nowrap;
    align-items: center;
    max-width: none;
    justify-content: flex-end;
}

@media (max-width: 640px) {
    /* On a phone the row wraps: the belt and its one-line summary first (full width, so a long name like "Black Belt (1st-6th Degree)" is not squeezed
       beside three 44px buttons), then the arrows and Manage on a line of their own. */
    .bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact {
        flex-wrap: wrap;
    }

    .bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact .bu-rank-row__main {
        flex: 1 1 100%;
    }

    .bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact .bu-rank-summary {
        flex: 0 1 auto;
    }

    .bu-ladder[b-h30dn9s9zz]  .bu-rank-row--compact .bu-ladder-actions.bu-rank-actions {
        flex: 1 1 100%;
        max-width: 100%;
        width: auto;
        justify-content: flex-start;
    }
}
/* /Components/Pages/Home.razor.rz.scp.css */
/*
  Home.razor.css — scoped sizing rules for the Command Console (PG-017),
  R-S9-02 wide-short landscape rebuild.

  Structure/spacing only, no color (color stays in render-*.css per the
  Primer's color law) — this file exists purely to make the shared
  bento-grid.css primitives (.bu-slab / .bu-console-header / .bu-console-body /
  .bu-tab-rail / .bu-slideout-well) FIT one viewport-height window on this
  page, instead of the page growing tall and scrolling. bento-grid.css itself
  is untouched: its .bu-console-body/.bu-tab-rail/.bu-slideout-well rules stay
  as shared defaults for any other page that reuses them; this file only
  narrows their sizing for the one page bound to the Layout Law (Section 17
  of BUP-INTERNAL-ADMIN-SPEC-001_DRAFT.md).

  ::deep is required because MainLayout.razor's <main class="bu-main"> and
  this page's own top-level markup are simple HTML elements without a
  component boundary of their own around .bu-console-header/.bu-console-body
  (Blazor scoped CSS otherwise only matches elements written directly in this
  component's own markup, and .bu-slab/.bu-console-header/.bu-console-body ARE
  written directly here, but the nested TabRail/SlideOutPanel component
  output needs ::deep to be reachable, same pattern as MainLayout.razor.css).
*/

[b-s0gr9oc2jy] .bu-slab {
    /* MainLayout's own .bu-slab (fixed nav rail + footer) still scrolls
       normally — this rule only applies to Home.razor's own nested
       <section class="bu-slab"> wrapper, so it fills whatever height
       MainLayout's <main class="bu-main"> gives it rather than growing
       past the viewport. */
    min-height: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
}

[b-s0gr9oc2jy] .bu-console-header,
[b-s0gr9oc2jy] .bu-nav {
    /* Compact, fixed-height top strip — never stacks additional full-width
       rows above the console body (that stacking was the R-S9-02 portrait-
       column defect this pass fixes).

       Height is the documented console header height, not "as small as it will
       go": BUP-UIUX-KEY-COMMAND_2026-07-13 specifies
       `grid-template-rows: var(--cc-header-h, 52px) 1fr` with
       `.cc-header { height: var(--cc-header-h, 52px) }`. Consolidating the two
       old header rows into one collapsed this to roughly 34px, which the owner
       correctly called "not a header, just a bar" (2026-08-21). Restoring the
       specified 52px gives the bar real presence and room for the brand lockup
       without giving back the second row. */
    flex: 0 0 auto;
    flex-wrap: wrap;
    min-height: var(--cc-header-h, 52px);
    padding-left: var(--structure-gap-xl);
    padding-right: var(--structure-gap-xl);
}

[b-s0gr9oc2jy] .bu-console-body {
    /* Wide-short landscape: the rail+pane region claims the remaining
       viewport height and does not grow past it — the pane's own content
       scrolls internally (see .bu-slideout-well below) instead of the whole
       page scrolling.

       R-0709-15 shell v2 (2026-07-09): the console now has FIVE grid
       children in DOM order — left <TabRail>, a left <div class="bu-mullion">,
       the CENTER wrapper (<div class="bu-console-center"> hosting
       <SlideOutPanel> + the diagnostic-drawer overlay), a right
       <div class="bu-mullion">, then the right <TabRail>. Five explicit
       column tracks (rail | mullion | 1fr center | mullion | rail) keeps
       grid auto-placement putting each DOM child into its own column, left
       to right, in ONE row — same fix rationale as the prior 3-track note
       this replaces (owner walkthrough 2026-07-08/09, R-S9-02): declaring
       every track explicitly avoids CSS grid wrapping an item into an
       implicit second row when the DOM child count doesn't match the track
       count.

       RAIL TRACKS ARE BOUNDED, NEVER `auto` (2026-08-21, owner walkthrough).
       With `auto` rail tracks the browser sizes them from rail content while
       the centre track's minmax(0, 1fr) is free to shrink to zero — so opening
       the "Coming soon" disclosure on BOTH rails handed the entire row to the
       rails (measured live on QA: centre 1331px -> 0px, each rail -> 847px)
       and the console appeared to break, recoverable only by reloading the
       page. Capping both rail tracks makes that state unreachable: expanding
       the disclosure can now only scroll the rail internally (overflow-y
       below), never reflow the grid. */
    /* DEAD BAND BETWEEN RAIL AND PANEL — R-0904-03 (owner screenshots of
       admin.qa.beltup.online, 2026-09-04: "a stray vertical divider sits
       between the left rail and the content panel"). The measurement he sent
       matches this rule exactly: the rail ended at x=256 and the panel did not
       begin until x=337 — an 81px band of nothing, built from FIVE stacked
       contributions none of which was intended as a group:
           24px  grid gap (rail track -> mullion track)
         + 16px  .bu-mullion's own margin-left  (bento-grid.css .bu-mullion)
         +  1px  the divider line itself
         + 16px  .bu-mullion's margin-right
         + 24px  grid gap (mullion track -> centre track)
       — because the mullion track was `auto`, so it sized to the divider's
       whole MARGIN box, and a full grid gap was then added on each side of it.

       The mullion track IS the gutter now: each `auto` track becomes one
       explicit --structure-gap-lg (24px) track, column-gap drops to 0 so no
       further gap is added around it, and the divider element itself collapses
       to zero width (see the .bu-mullion rule below). The panel begins one
       consistent 24px gutter after the rail — the Primer's standard grid
       gutter, which is what the gap was already meant to be before the mullion
       inflated it. row-gap is declared explicitly because zeroing column-gap
       alone would leave the shared `gap` shorthand (bento-grid.css
       .bu-console-body) as the only source of vertical spacing, and the
       single-column phone collapse below still needs it. */
    grid-template-columns: minmax(0, 14rem) var(--structure-gap-lg) minmax(0, 1fr) var(--structure-gap-lg) minmax(0, 14rem);
    column-gap: 0;
    row-gap: var(--structure-gap-lg);
    flex: 1 1 auto;
    min-height: 0;
    height: 0; /* combined with flex:1 1 auto, forces the grid to size from
                  the flex-computed height rather than its content, so the
                  rail/pane can cap their own height at 100% of this box
                  instead of growing the page. */
    padding-top: 0;
    padding-bottom: var(--structure-gap-lg);
}

[b-s0gr9oc2jy] .bu-console-body > .bu-mullion {
    /* R-0904-03, second half of the dead-band repair above. The divider is a
       decorative aria-hidden element (Home.razor renders it purely so the
       5-track grid keeps one DOM child per track); with the track itself now
       sized as the gutter, the element must contribute NOTHING to it. Left as
       it was, its 33px margin box (16 + 1 + 16) would overflow the 24px track
       it now sits in — the track is a fixed length and cannot grow to fit it —
       and the divider would paint 16px into the gutter with its line landing
       off-centre against the centre pane.

       Zero width + zero margin rather than `display: none`: a display:none
       grid child is removed from auto-placement entirely, so the remaining
       three children would shift left into tracks 1/2/3 (rail | 24px gutter |
       rail) and the console would collapse. The element stays in the grid and
       stops painting — its skin rule is a background-color on a 1px box
       (render-cobalt-dark.css / render-greyscale-skeleton.css .bu-mullion), so
       a zero-width box draws nothing. NO COLOUR IS TOUCHED HERE; the reskin is
       still gated by R-0829-02. */
    width: 0;
    margin: 0;
}

[b-s0gr9oc2jy] .bu-console-center {
    /* Positioning context for the diagnostic drawer overlay (.bu-drawer-host
       in bento-grid.css is position:absolute; inset:0 inside this wrapper).
       Fills the center grid track, caps at the console body's height, and
       clips so the drawer's slide-in transform never pokes out past the
       center column into the rails (R-0709-15 point 1: overflow hidden on
       the shell, panels scroll internally instead). */
    position: relative;
    height: 100%;
    min-height: 0;
    min-width: 0;
    overflow: hidden;
}

[b-s0gr9oc2jy] .bu-tab-rail {
    /* Vertical side rail per Section 17 ("existing .bu-rail class in a
       vertical orientation" — TabRail.razor already renders a column-flex
       nav; this just lets it stretch the full height of the console body
       instead of only sizing to its own content, and scroll its own list
       independently if the 17-entry registry list is taller than the
       viewport, keeping the ONE WINDOW law even with many rail entries).
       !important overrides bento-grid.css's shared sticky/visible-overflow
       defaults (written for a short 2-4 tab rail, not a 17-entry list) —
       scoped to this page only, not a change to the shared Primer file. */
    position: static !important;
    align-self: stretch !important;
    height: 100% !important;
    max-height: 100% !important;
    overflow-y: auto !important;
}

[b-s0gr9oc2jy] .bu-slideout-well {
    /* THE DEFECT (R-0904-03, owner screenshots 2026-09-04): "most tabs leave a
       very large dead area below the content". This rule and the one below it
       used to read `height: 100%` for the well, the panel AND the placeholder
       together, so all three stretched to the full console-body height whether
       or not the active tab had content to fill it. A short tab — Dashboard
       with empty states, Payments, any stub — therefore drew a bordered,
       frosted panel several hundred pixels taller than its own content: a
       mostly-empty box, which is exactly what he photographed.

       The well is now a flex column that SIZES TO ITS PANEL (height: auto) and
       is CAPPED at the console body (max-height: 100%, resolved against
       .bu-console-center's definite height above). Nothing is stretched to fill
       and no content is padded out to reach a floor: a short tab simply draws a
       short panel, and the region below it is plain shell background rather
       than an empty panel.

       THE WITHIN-FOLD LAW IS UNCHANGED for tabs that DO fill. max-height: 100%
       still forbids the panel growing past the shell, the panel below shrinks
       into that cap, and its own overflow-y scrolls the excess — the same
       behaviour `height: 100%` produced, reached by shrinking instead of by
       stretching. The outer no-scroll shell cap (MainLayout.razor.css) is
       untouched. */
    display: flex;
    flex-direction: column;
    height: auto;
    max-height: 100%;
    min-height: 0;
}

[b-s0gr9oc2jy] .bu-slideout-content,
[b-s0gr9oc2jy] .bu-slideout-placeholder {
    /* The panel is the box the skin actually paints, so the "sensible minimum"
       belongs here, not on the invisible well: 20rem is the Primer's own shared
       320px floor (bento-grid.css .bu-slideout-well / .bu-slideout-content /
       .bu-slideout-placeholder), so a tab with almost nothing in it still reads
       as a panel and not as a sliver.

       flex: 0 1 auto is what makes the pair work — the panel takes its own
       content height (grow 0: never stretched to fill the well), and shrinks
       only once that content is taller than the cap above, at which point
       overflow-y takes over. */
    height: auto;
    min-height: 20rem;
    flex: 0 1 auto;
}

[b-s0gr9oc2jy] .bu-slideout-content {
    overflow-y: auto;
}

@media (max-width: 768px) {
    /* Collapse to a single column on a phone.
       The Primer already does this (bento-grid.css .bu-console-body breakpoint),
       but THIS file's unconditional 5-track rule outranks it at every width, so
       the console kept two 14rem rails on a 390px screen — 448px of rails in a
       390px viewport. That is the root cause of most of the phone findings the
       layout walkthrough reported on 2026-08-22: tab buttons rendering from
       x=219 to x=431, metrics and tables overflowing, and content pinned against
       the screen edge. Rails become ordinary stacked blocks here; the wide-short
       ONE WINDOW law is a desktop/landscape law and was never meant to force a
       three-column shell onto a portrait phone. */
    [b-s0gr9oc2jy] .bu-console-body {
        grid-template-columns: 1fr;
        height: auto;
        padding: 0 var(--structure-gap-md) var(--structure-gap-lg);
    }

    /* The vertical dividers only make sense between side-by-side columns. */
    [b-s0gr9oc2jy] .bu-mullion {
        display: none;
    }

    [b-s0gr9oc2jy] .bu-tab-rail {
        height: auto !important;
        max-height: none !important;
        overflow-y: visible !important;
        /* The Primer turns rails into a WRAPPING ROW below 768px, which suits a
           short 2-4 tab rail. This one carries 13 entries plus a <details>
           group: as flex-row items the buttons and the disclosure collide
           (measured: 8 overlapping pairs, up to 150x32px). A phone wants one
           full-width tap target per line anyway. */
        flex-direction: column !important;
        flex-wrap: nowrap !important;
        width: 100%;
        /* The base rule stretches the rail to fill its grid row, which is right for
           a full-height desktop column but wrong here: the row is sized from the
           OTHER items, so once the buttons total more than the row height the rail
           spills into the row below and lands on top of the next rail (measured:
           8-28px overlaps). Sizing to content lets the row grow instead. */
        align-self: start !important;
    }

    [b-s0gr9oc2jy] .bu-tab-rail-stubs,
    [b-s0gr9oc2jy] .bu-tab-btn {
        width: 100%;
    }

    [b-s0gr9oc2jy] .bu-console-center {
        height: auto;
        overflow: visible;
    }
}

@media (max-width: 900px) {
    /* Phone-landscape still honors the Law (wide-short, one window); only
       genuine narrow-portrait viewports fall back to the Primer's existing
       stacked-rail behavior (bento-grid.css .bu-console-body breakpoint) —
       matching the ruling's explicit "phone landscape" reference case. */
    [b-s0gr9oc2jy] .bu-tab-rail {
        max-height: none;
        overflow-y: visible;
    }

    /* R-0904-03 note: `height: auto` is now the BASE behaviour for all three
       (see .bu-slideout-well / .bu-slideout-content above), so these three
       declarations are redundant at this breakpoint and are kept only as the
       explicit statement of intent this block was written to make.

       The desktop cap (max-height: 100% on the well) is deliberately NOT lifted
       here. Between 769px and 900px .bu-console-center is still
       `height: 100%; overflow: hidden` — only the 768px block above turns that
       off — so a panel allowed to grow past the cap at these widths would be
       CLIPPED by the centre wrapper, not scrolled. Capped, it scrolls its own
       content exactly as it does on a full desktop. */
    [b-s0gr9oc2jy] .bu-slideout-well,
    [b-s0gr9oc2jy] .bu-slideout-content,
    [b-s0gr9oc2jy] .bu-slideout-placeholder {
        height: auto;
    }
}

[b-s0gr9oc2jy] .bu-embedded-page > .bu-slab > .bu-bay-grid:first-of-type h1,
[b-s0gr9oc2jy] .bu-embedded-page h1 {
    /* A routed page embedded in the console already has its name on screen twice —
       the right-rail tab and the panel header. Its own page-level <h1> is the third.
       Hidden here rather than removed from the page, because /sessions,
       /theme-settings and /curriculum are still reachable directly and need their
       headings when they are the whole page. Scoped to this component, so it can
       never affect those standalone routes. */
    display: none;
}

/* ADM-EB-16 (2026-10-10): with its <h1> hidden (rule above) the intro card's
   .bu-reveal was left EMPTY but still spent its margin plus the panel gap,
   ~12px of dead space at the top of every embedded page. Drop the empty slot. */
[b-s0gr9oc2jy] .bu-embedded-page .bu-reveal:has(> h1:only-child) {
    display: none;
}

/* ADM-EB-17a (2026-10-10): section headings inside the well were two sizes one
   tab apart — h3 (16px) on Dashboard, Payments and Retention, h2 (18px) on the
   embedded settings pages. The embedded pages keep their h2 elements (they are
   page sections when visited standalone), but inside the console they render at
   the console's section step, 16px. VISUAL ONLY: the heading level itself is
   still h2 under the well's h2 title; changing the element needs a parameter on
   five shared pages and is listed as not done. */
[b-s0gr9oc2jy] .bu-embedded-page .bu-reveal h2 {
    font-size: var(--structure-text-base);
}

/* ADM-EB-23 (2026-10-10): the Dashboard's Upcoming Classes rows are full-width
   .bu-control buttons, and .bu-control centres its label, so every session name
   sat centred in a long cobalt-outlined bar under a left-aligned heading and a
   left-aligned "View all". Same shape as the Primer's own full-width list
   buttons (.bu-tab-btn, bento-grid.css): left-aligned. Written directly in this
   component's markup, so no ::deep. */
.cc-upcoming-row[b-s0gr9oc2jy] {
    justify-content: flex-start;
    text-align: left;
    width: 100%;
}

/* #502: a to-do line on the Overview's Today row (the follow-ups line sits with the homework strip): the words left, the one action right. */
[b-s0gr9oc2jy] .cc-todo-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--structure-gap-md);
}
[b-s0gr9oc2jy] [data-testid="today-todo"] .bu-brick {
    align-items: flex-start;
    text-align: left;
}

/* #516: the "Get your school ready" card: each step is one line, the words left and its one button right (the Primer's .bu-brick stacks and centres). */
[b-s0gr9oc2jy] [data-testid="setup-card"] .bu-brick {
    align-items: stretch;
    text-align: left;
}
[b-s0gr9oc2jy] [data-testid="setup-card"] .cc-todo-row {
    flex-direction: row;
    align-items: center;
}

/* #503: the Roster's toolbar (counts + Add student) sits closer to the search below it, so more rows show on a short screen. */
[b-s0gr9oc2jy] .bu-slideout-body > .bu-toolbar {
    margin-bottom: var(--structure-gap-sm);
}
/* /Components/Pages/Internal/Gates.razor.rz.scp.css */
/*
  Gates.razor.css — scoped styling for the platform-admin gate console.
  Data table with row separation; compact reason input. Structure/spacing
  only; color via --theme-* tokens. Pattern mirrors LeadFunnel.razor.css.
*/

[b-whi6e1c0ug] table {
    width: 100%;
    border-collapse: collapse;
}

[b-whi6e1c0ug] th,
[b-whi6e1c0ug] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-whi6e1c0ug] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

[b-whi6e1c0ug] .bu-gates-reason-input {
    width: 10rem;
}
/* /Components/Pages/Internal/InternalDiagLog.razor.rz.scp.css */
/*
  InternalDiagLog.razor.css — scoped styling for the read-only diagnostic log
  viewer. Data table with row separation; message column wraps rather than
  truncating. Structure/spacing only; color via --theme-* tokens. Pattern
  mirrors Gates.razor.css.
*/

[b-90dtbdpyg9] table {
    width: 100%;
    border-collapse: collapse;
}

[b-90dtbdpyg9] th,
[b-90dtbdpyg9] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
    vertical-align: top;
}

[b-90dtbdpyg9] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}
/* /Components/Pages/Internal/InternalSiteMap.razor.rz.scp.css */
/*
  InternalSiteMap.razor.css — scoped styling for the DB-backed build-log sitemap
  console. Data table with row separation; compact status-select + flip action.
  Structure/spacing only; color via --theme-* tokens. Pattern mirrors Gates.razor.css.
*/

[b-2cfgdns8i1] table {
    width: 100%;
    border-collapse: collapse;
}

[b-2cfgdns8i1] th,
[b-2cfgdns8i1] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-2cfgdns8i1] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

/* A grid nested inside a panel (the footer stat row) is a layout device, not a padded surface:
   the panel already supplies the inset. Left at the Primer's default it added a SECOND gutter —
   another 24px top/bottom and 32px each side on top of the panel's own padding, pushing the
   stats ~56px in from the panel edge while the table above sits at 24px (WT-0915-021). Same
   rule the Primer applies inside the console well (.bu-slideout-body .bu-bay-grid). */
[b-2cfgdns8i1] .bu-panel .bu-bay-grid {
    padding: 0;
}

/* S4 site map: node cards (details), ruling line, tags. Structure only; colour via --theme-* tokens, state also carried by text. */
[b-2cfgdns8i1] .sm-node {
    border-bottom: 1px solid var(--theme-border-inactive);
    padding: var(--structure-gap-xs) 0;
}

[b-2cfgdns8i1] .sm-node > summary {
    cursor: pointer;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--structure-gap-xs);
}

[b-2cfgdns8i1] .sm-ruling {
    font-size: var(--structure-text-sm);
    font-weight: var(--structure-weight-bold);
}

[b-2cfgdns8i1] .sm-free {
    color: var(--theme-text-muted);
}

[b-2cfgdns8i1] .sm-body {
    padding: var(--structure-gap-sm) var(--structure-gap-md);
}

[b-2cfgdns8i1] .sm-dl dt {
    font-weight: var(--structure-weight-bold);
    margin-top: var(--structure-gap-xs);
}

[b-2cfgdns8i1] .sm-dl dd {
    margin: 0;
}

[b-2cfgdns8i1] .sm-refs,
[b-2cfgdns8i1] .sm-sections,
[b-2cfgdns8i1] .sm-legend {
    margin: 0;
    padding-left: var(--structure-gap-md);
}

[b-2cfgdns8i1] .sm-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--structure-gap-sm);
}

[b-2cfgdns8i1] .sm-filters label {
    display: flex;
    flex-direction: column;
    gap: var(--structure-gap-xs);
    font-size: var(--structure-text-sm);
}

[b-2cfgdns8i1] .sm-filters label:has(input[type="checkbox"]) {
    flex-direction: row;
    align-items: center;
}

[b-2cfgdns8i1] .sm-chip {
    margin-right: var(--structure-gap-sm);
}

[b-2cfgdns8i1] .sm-text {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

[b-2cfgdns8i1] .sm-flip {
    display: flex;
    gap: var(--structure-gap-xs);
    margin-top: var(--structure-gap-sm);
}
/* /Components/Pages/Internal/InternalStories.razor.rz.scp.css */
/*
  InternalStories.razor.css — scoped styling for the Story Registry console.
  Data table with row separation; story-text column is wide/wraps rather than
  truncating (full text must remain readable, per the spec's "read-only display
  of the full story text" requirement). Structure/spacing only; color via
  --theme-* tokens. Pattern mirrors Gates.razor.css.
*/

[b-m40r6bhpmr] table {
    width: 100%;
    border-collapse: collapse;
}

[b-m40r6bhpmr] th,
[b-m40r6bhpmr] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
    vertical-align: top;
}

[b-m40r6bhpmr] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

[b-m40r6bhpmr] .bu-stories-text-cell {
    max-width: 32rem;
    white-space: normal;
}

/* A grid nested inside a panel (the footer stat row) is a layout device, not a padded surface:
   the panel already supplies the inset. Left at the Primer's default it added a SECOND gutter
   on top of the panel's own padding (WT-0915-021). Same rule the Primer applies inside the
   console well (.bu-slideout-body .bu-bay-grid). */
[b-m40r6bhpmr] .bu-panel .bu-bay-grid {
    padding: 0;
}
/* /Components/Pages/Internal/InternalTicketDetail.razor.rz.scp.css */
/*
  InternalTicketDetail.razor.css — scoped styling for the ticket detail page (the
  detail half of the list/detail pair, spec Section 12.3). Same label-above-input and
  textarea conventions as InternalTickets.razor.css.
*/

/* Field labels, moved onto the Primer's label tokens — same repair as InternalTickets.razor.css
   (read its note for the full reasoning). Was display:block; font-size: xs (12px);
   margin-bottom: xs: below the 13px label step every other console form uses (D-16), and the
   margin stacked on the cell's own 4px flex gap. Size / weight / leading are the label tokens
   now; display:block and the margin are deleted. The colour line stays untouched — aligning it
   with the other console forms is a colour decision that waits on R-0829-02. */
[b-4o29whhg8n] label {
    font-size: var(--structure-text-label);
    font-weight: var(--structure-weight-medium);
    line-height: 1.3;
    color: var(--theme-text-muted);
}

[b-4o29whhg8n] textarea.bu-input {
    width: 100%;
    resize: vertical;
}

[b-4o29whhg8n] select.bu-input,
[b-4o29whhg8n] input.bu-input {
    width: 100%;
}

/* A grid nested inside a panel (the three form sections) is a layout device, not a padded
   surface: the panel already supplies the inset. At the Primer's default each nested grid added
   a SECOND gutter (24px top/bottom, 32px each side) on top of the panel's own padding
   (WT-0915-021). Same rule the Primer applies inside the console well
   (.bu-slideout-body .bu-bay-grid). */
[b-4o29whhg8n] .bu-panel .bu-bay-grid {
    padding: 0;
}
/* /Components/Pages/Internal/InternalTickets.razor.rz.scp.css */
/*
  InternalTickets.razor.css — scoped styling for the trouble-ticketing console.
  Create-form field labels stacked above inputs; data table with row separation
  and a compact status-select + transition action per row. Structure/spacing
  only; color via --theme-* tokens. Pattern mirrors Gates.razor.css.
*/

[b-z297em039z] table {
    width: 100%;
    border-collapse: collapse;
}

[b-z297em039z] th,
[b-z297em039z] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-z297em039z] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

/* Field labels, moved onto the Primer's label tokens. This rule used to set display:block,
   font-size: xs (12px) and margin-bottom: xs. It fought the Primer's label scale twice: 12px
   sits below the 13px label step every other console form uses (bento-grid.css
   `.bu-field label`, D-16), and its margin stacked on top of the cell's own flex gap (4px
   gap + 4px margin = 8px caption->input where the rest of the console has 4px). Now: size /
   weight / leading are the label tokens (13px / 500 / 1.3), display:block and the margin are
   deleted (the .bu-brick cell is already a flex column with a 4px gap).
   The colour line stays, untouched: this page uses the muted text token where every other console
   form's label uses the secondary text token (via .bu-field label in the skin). The cells are
   .bu-brick, not .bu-field, precisely so this stays true — switching them would swap the label
   colour. Aligning the two is a colour decision: it waits on R-0829-02 (REQ-UNIFORM-006), and
   when it lands this whole rule can go and the cells can become .bu-field. */
[b-z297em039z] label {
    font-size: var(--structure-text-label);
    font-weight: var(--structure-weight-medium);
    line-height: 1.3;
    color: var(--theme-text-muted);
}

[b-z297em039z] textarea.bu-input {
    width: 100%;
    resize: vertical;
}

/* A grid nested inside a panel (the create form, the filter row) is a layout device, not a padded
   surface: the panel already supplies the inset. At the Primer's default each nested grid added a
   SECOND gutter (24px top/bottom, 32px each side) on top of the panel's own padding (WT-0915-021).
   Same rule the Primer applies inside the console well (.bu-slideout-body .bu-bay-grid). */
[b-z297em039z] .bu-panel .bu-bay-grid {
    padding: 0;
}
/* /Components/Pages/Internal/LeadFunnel.razor.rz.scp.css */
/*
  LeadFunnel.razor.css — scoped styling for the internal lead funnel
  console. Stat tiles rendered as .bu-metric-shaped cards, data table with
  row separation. Structure/spacing only; color via --theme-* tokens.
*/

[b-ffahxup80a] .bu-bay-2.bu-panel {
    text-align: center;
    align-items: center;
}

[b-ffahxup80a] table {
    width: 100%;
    border-collapse: collapse;
}

[b-ffahxup80a] th,
[b-ffahxup80a] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-ffahxup80a] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

[b-ffahxup80a] tbody tr:hover {
    background-color: var(--theme-bg-card);
}

[b-ffahxup80a] span.bu-control {
    background-color: var(--theme-x-bg-sunken);
    border: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-xs);
    min-height: auto;
    min-width: auto;
    display: inline-block;
    /* 2px 8px literal -> spacing tokens (4px 8px, the same pill proportion .bu-badge
       uses): this chip is the only raw spacing in the file (REQ-UNIFORM). */
    padding: var(--structure-gap-xs) var(--structure-gap-sm);
}

/* R4 inline-style cleanup (2026-07-04): stat-tile value shape, moved out of
   LeadFunnel.razor's inline style attributes. Structure/spacing only.
   The stat LABEL rule that lived here (font-weight: bold) is DELETED: the label now
   composes the Primer's .bu-metric-label (12px / medium / uppercase, the same label every
   other KPI tile in the console uses) instead of setting its own weight. */
[b-ffahxup80a] .bu-leadfunnel-stat-value {
    /* was 1.5rem (24px) — larger than the 22px page title above it. Console law (D-16,
       bento-grid.css .bu-metric-value): a read-only value never exceeds the section title,
       so it takes the same step the Primer's .bu-metric-value does (18px / semibold). The
       value colour is left alone — it still takes the secondary text colour via .bu-brick
       while every other KPI value takes main text; that is a colour decision, which waits
       on R-0829-02. */
    font-size: var(--structure-text-md);
    font-weight: var(--structure-weight-semibold);
    line-height: var(--structure-leading-tight);
}
/* /Components/Pages/Internal/Onion.razor.rz.scp.css */
/*
  Onion.razor.css - scoped styling for /internal/onion. Theme tokens only; the three semantic state colours
  (healthy / warning / error) stay coloured under the grayscale skeleton, and every colour is paired with text.
  Readable from 1280 to 1920 wide: chips auto-fill, tables scroll inside .onion-tbl instead of squeezing.
*/

.onion-key[b-sxpzdagk4n] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs) var(--structure-gap-md); font-size: var(--structure-text-xs); color: var(--theme-text-muted); }
.onion-key span[b-sxpzdagk4n] { display: inline-flex; align-items: center; gap: var(--structure-gap-xs); }
.onion-dot[b-sxpzdagk4n] { width: 0.65rem; height: 0.65rem; border-radius: 50%; display: inline-block; flex: none; }
.onion-dot.is-low[b-sxpzdagk4n], .onion-chip .bar > .is-low[b-sxpzdagk4n] { background: var(--theme-state-error); }
.onion-dot.is-mid[b-sxpzdagk4n], .onion-chip .bar > .is-mid[b-sxpzdagk4n] { background: var(--theme-state-warning); }
.onion-dot.is-high[b-sxpzdagk4n], .onion-chip .bar > .is-high[b-sxpzdagk4n] { background: var(--theme-state-healthy); }
td.is-low[b-sxpzdagk4n], dd.is-low[b-sxpzdagk4n] { color: var(--theme-state-error); }
td.is-mid[b-sxpzdagk4n], dd.is-mid[b-sxpzdagk4n] { color: var(--theme-state-warning); }
td.is-high[b-sxpzdagk4n], dd.is-high[b-sxpzdagk4n] { color: var(--theme-state-healthy); }

.onion-st[b-sxpzdagk4n] { font-size: var(--structure-text-xs); letter-spacing: 0.04em; text-transform: uppercase; font-weight: var(--structure-weight-bold); }
.st-live[b-sxpzdagk4n] { color: var(--theme-state-healthy); }
.st-deploy[b-sxpzdagk4n] { color: var(--theme-accent-primary); }
.st-review[b-sxpzdagk4n], .st-build[b-sxpzdagk4n] { color: var(--theme-state-warning); }
.st-plan[b-sxpzdagk4n] { color: var(--theme-text-muted); }
.st-none[b-sxpzdagk4n] { color: var(--theme-state-error); }

.onion-ring[b-sxpzdagk4n] { display: grid; gap: var(--structure-gap-sm); padding: var(--structure-gap-md); border-radius: var(--structure-radius-panel); border: 2px solid var(--theme-border-inactive); background: var(--theme-bg-surface); }
.onion-ring.r1[b-sxpzdagk4n] { border-color: var(--theme-border-active); border-width: 3px; background: var(--theme-bg-card); }
.onion-ring.r2[b-sxpzdagk4n] { border-color: var(--theme-border-active); }
.onion-ringhead[b-sxpzdagk4n] { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: var(--structure-gap-sm); }
.onion-ringhead b[b-sxpzdagk4n] { text-transform: uppercase; letter-spacing: 0.03em; font-weight: var(--structure-weight-bold); }
.onion-ringhead small[b-sxpzdagk4n] { color: var(--theme-text-muted); }

.onion-chips[b-sxpzdagk4n] { display: grid; grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr)); gap: var(--structure-gap-sm); }
.onion-chip[b-sxpzdagk4n] { all: unset; box-sizing: border-box; cursor: pointer; display: grid; gap: var(--structure-gap-xs); min-width: 0; min-height: var(--structure-touch-min); padding: var(--structure-gap-sm); border-radius: var(--structure-radius-panel); border: 1px solid var(--theme-border-inactive); background: var(--theme-bg-card); }
.onion-chip:hover[b-sxpzdagk4n], .onion-chip[aria-pressed="true"][b-sxpzdagk4n] { border-color: var(--theme-border-active); }
.onion-chip:focus-visible[b-sxpzdagk4n] { outline: 2px solid var(--theme-border-active); outline-offset: 2px; }
.onion-chip .nm[b-sxpzdagk4n] { display: flex; gap: var(--structure-gap-xs); align-items: flex-start; font-weight: var(--structure-weight-semibold); font-size: var(--structure-text-sm); }
.onion-chip .nm i[b-sxpzdagk4n] { font-style: normal; font-family: var(--structure-font-family-mono); font-size: var(--structure-text-xs); color: var(--theme-text-muted); }
.onion-chip .bar[b-sxpzdagk4n] { height: 6px; border-radius: 3px; background: var(--theme-border-inactive); overflow: hidden; display: block; }
.onion-chip .bar > span[b-sxpzdagk4n] { display: block; height: 100%; }
.onion-chip .meta[b-sxpzdagk4n] { display: flex; justify-content: space-between; gap: var(--structure-gap-xs); font-size: var(--structure-text-xs); color: var(--theme-text-muted); }
.onion-chip .pct[b-sxpzdagk4n] { font-family: var(--structure-font-family-mono); font-variant-numeric: tabular-nums; color: var(--theme-text-main); }

.onion-detail dl[b-sxpzdagk4n] { display: grid; grid-template-columns: max-content 1fr; gap: var(--structure-gap-xs) var(--structure-gap-md); margin: var(--structure-gap-sm) 0 0; }
.onion-detail dt[b-sxpzdagk4n] { color: var(--theme-text-muted); }
.onion-detail dd[b-sxpzdagk4n] { margin: 0; min-width: 0; }

.onion-tbl[b-sxpzdagk4n] { overflow-x: auto; }
.onion-tbl table[b-sxpzdagk4n] { width: 100%; border-collapse: collapse; }
.onion-tbl th[b-sxpzdagk4n], .onion-tbl td[b-sxpzdagk4n] { text-align: left; vertical-align: top; padding: var(--structure-gap-sm) var(--structure-gap-xs); border-bottom: 1px solid var(--theme-border-inactive); font-size: var(--structure-text-sm); }
.onion-tbl thead th[b-sxpzdagk4n] { color: var(--theme-text-muted); text-transform: uppercase; font-size: var(--structure-text-xs); letter-spacing: 0.05em; font-weight: var(--structure-weight-bold); }
.onion-tbl td.n[b-sxpzdagk4n] { font-family: var(--structure-font-family-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.onion-ringtag[b-sxpzdagk4n] { font-family: var(--structure-font-family-mono); font-size: var(--structure-text-xs); padding: 0 var(--structure-gap-xs); border: 1px solid var(--theme-border-active); border-radius: var(--structure-radius-panel); white-space: nowrap; }

.onion-placer[b-sxpzdagk4n] { display: grid; gap: var(--structure-gap-md); }
.onion-step[b-sxpzdagk4n] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--structure-gap-sm); }
.onion-step p[b-sxpzdagk4n] { margin: 0; flex: 1 1 22rem; }
.onion-step button[b-sxpzdagk4n] { min-height: var(--structure-touch-min); }
.onion-verdict[b-sxpzdagk4n] { border-left: 4px solid var(--theme-border-active); padding: var(--structure-gap-sm) var(--structure-gap-md); background: var(--theme-bg-surface); }
.onion-foot[b-sxpzdagk4n] { font-size: var(--structure-text-xs); }

.onion-node[b-sxpzdagk4n] { display: inline-block; margin-right: var(--structure-gap-md); }
/* /Components/Pages/Internal/Plans.razor.rz.scp.css */
/*
  Plans.razor.css — scoped styling for the platform-admin subscription plan
  console. Data table with row separation; fixed-width numeric editors sized
  per column. Structure/spacing only; color via --theme-* tokens. Pattern
  mirrors LeadFunnel.razor.css.
*/

[b-kfggwip09j] table {
    width: 100%;
    border-collapse: collapse;
}

[b-kfggwip09j] th,
[b-kfggwip09j] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-kfggwip09j] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

[b-kfggwip09j] .bu-plans-price-input {
    width: 8rem;
}

[b-kfggwip09j] .bu-plans-cap-input {
    width: 6rem;
}

[b-kfggwip09j] .bu-plans-overage-input {
    width: 7rem;
}

[b-kfggwip09j] .bu-plans-txnfee-input {
    width: 6rem;
}
/* /Components/Pages/Internal/Scenes.razor.rz.scp.css */
/*
  Scenes.razor.css — scoped styling for the platform-admin scene console.
  Data table with row separation; retired-row dimming. Structure/spacing
  only; color via --theme-* tokens. Pattern mirrors LeadFunnel.razor.css.
*/

[b-uqde9apr8r] table {
    width: 100%;
    border-collapse: collapse;
}

[b-uqde9apr8r] th,
[b-uqde9apr8r] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-uqde9apr8r] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

[b-uqde9apr8r] tr.bu-scenes-row--retired {
    opacity: 0.5;
}
/* /Components/Pages/MemberPassPrint.razor.rz.scp.css */
.bu-pass-toolbar[b-sj2dsmld0z] {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 1rem;
}

.bu-pass-page[b-sj2dsmld0z] {
    display: flex;
    justify-content: center;
    padding: 1rem;
}

.bu-pass-page--grid[b-sj2dsmld0z] {
    display: grid;
    grid-template-columns: repeat(2, 3.375in);
    grid-auto-rows: 2.125in;
    column-gap: 0.5in;
    row-gap: 0.25in;
    justify-content: center;
    align-content: start;
}

.bu-pass-page--single[b-sj2dsmld0z] {
    align-items: center;
    min-height: 60vh;
}

@media print {
    .bu-pass-toolbar[b-sj2dsmld0z] {
        display: none;
    }

    .bu-pass-page[b-sj2dsmld0z] {
        padding: 0;
        break-after: page;
        break-inside: avoid;
    }

    .bu-pass-page:last-of-type[b-sj2dsmld0z] {
        break-after: auto;
    }

    /* printable area of Letter with 0.5in margins is 7.5in x 10in */
    .bu-pass-page--single[b-sj2dsmld0z] {
        height: 10in;
        min-height: 0;
        align-items: center;
        justify-content: center;
    }

    .bu-pass-page--grid[b-sj2dsmld0z] {
        height: 10in;
    }
}
/* /Components/Pages/Onboarding.razor.rz.scp.css */
/*
  Onboarding.razor.css — scoped styling for the onboarding wizard. R-0708-01
  rebuild: ONE vertical column (bu-bay-12 throughout, never bu-bay-6 pairs) —
  step numbers, unlock order, and visual order are the same sequence.
  Structure/spacing only; color via --theme-* tokens.

  2026-10-10 admin consistency pass (palette frozen: R-0829-02 / SRS 6B REQ-UNIFORM-006 —
  scale). This file holds only the WIZARD COLUMN shapes (Loading + the four steps);
  the shared gate pattern now lives ONCE in the Primer, next to .bu-gate, so the three
  gate surfaces cannot drift apart again.
*/

/* ===========================================================================
   WIZARD COLUMN — Loading + the four steps (WT-0915-042).
   =========================================================================== */

/* WT-0915-042: every panel was 1361px wide with inputs stretched full width, and each
   panel sat in its own .bu-bay-grid (24px padding + 24px padding = 48px gaps). One grid,
   one centred column. The measure is derived from the Primer's own width token (half of
   --structure-container-max = 600px: ~65 characters of body text per line, inside the
   45-75 readable range; fields ~550px) — no new length literal. Panels cap at the
   measure and fill the gutters below it, so a phone is unaffected. overflow-wrap:
   anywhere because the column is now narrow enough that a long email or the otpauth://
   URI would otherwise push past the panel edge. */
.bu-onboarding-column[b-v2rsfkcprk] {
    --onboarding-measure: calc(var(--structure-container-max) / 2);
}

.bu-onboarding-column > .bu-panel[b-v2rsfkcprk] {
    width: 100%;
    max-width: var(--onboarding-measure);
    justify-self: center;
    overflow-wrap: anywhere;
}

/* WT-0915-042: Name + Phone share a row. Two short text fields stacked cost ~90px of the
   ~790px available between the rail and the 1440x900 fold; paired, "Next" lands at
   ~830px. Source order is unchanged (tab and reading order). Each .bu-field keeps its
   own 16px bottom margin, so the pair's rhythm matches a lone field's. One column on a
   phone. */
.bu-onboarding-pair[b-v2rsfkcprk] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--structure-gap-md);
}

@media (max-width: 640px) {
    .bu-onboarding-pair[b-v2rsfkcprk] {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* The otpauth:// URI is one unbroken token (Step 4 manual-entry fallback). */
.bu-onboarding-uri[b-v2rsfkcprk] {
    overflow-wrap: anywhere;
}

/* WT-0915-042: the progress line is the h1's subtitle inside the header's .bu-reveal. A
   .bu-brick carries 8px of padding top and bottom for standing alone in a panel; as a
   subtitle it only needs the h1's own 8px margin above it, and the 16px saved keeps
   "Next" further inside the 1440x900 fold. */
.bu-onboarding-progress[b-v2rsfkcprk] {
    padding-block: 0;
}

/* WT-0915-042: the column is narrow enough that the long consent sentences (Texas Moat
   is ~170 characters) wrap to three lines. .bu-field-row centres the 20px box on the
   whole wrapped label, leaving it floating mid-paragraph. Pin the box to the FIRST line
   instead: top-align the row; the label carries the 44px touch band itself as padding
   ((44px - one 1.55 line) / 2 above and below its first line), so a one-line label is
   exactly 44px and a wrapped one grows past it, and the box is offset by the same band
   ((44px - 20px) / 2) so its centre is the first line's centre at any line count.
   Self-contained on purpose: it sets every property it depends on, so it holds with or
   without the Primer's `.bu-field-row > label` min-height rule (which it supersedes
   inside onboarding steps, at the same 44px target). 20px is the Primer's checkbox size. */
[b-v2rsfkcprk] .bu-onboarding-step .bu-field-row {
    align-items: flex-start;
}

[b-v2rsfkcprk] .bu-onboarding-step .bu-field-row > label {
    display: block;
    min-height: var(--structure-touch-min);
    padding-block: calc((var(--structure-touch-min) - var(--structure-text-base) * var(--structure-leading-base)) / 2);
}

[b-v2rsfkcprk] .bu-onboarding-step .bu-field-row input[type="checkbox"] {
    margin-top: calc((var(--structure-touch-min) - 20px) / 2);
}

/* WT-0915-042: badge + step title share one line ("CURRENT  1. Verify your information")
   instead of stacking (~76px of header per step panel -> ~37px). The badge was
   align-self:flex-start, which only mattered if the reveal was a flex row — it now is. */
[b-v2rsfkcprk] .bu-bay-12.bu-onboarding-step > .bu-reveal {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--structure-gap-sm);
}

[b-v2rsfkcprk] .bu-bay-12.bu-onboarding-step span.bu-brick {
    display: inline-block;
    align-self: center;
    padding: 2px var(--structure-gap-sm);
    border-radius: var(--structure-radius-max);
    font-size: var(--structure-text-xs);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background-color: var(--theme-bg-card);
    border: 1px solid var(--theme-border-active);
    color: var(--theme-text-muted);
}

/* Was margin-top:xs to separate a stacked badge from the title; the badge now sits beside
   the title (reveal rule above), so the h2 carries no margin of its own. */
[b-v2rsfkcprk] .bu-bay-12.bu-onboarding-step h2 {
    margin: 0;
}

[b-v2rsfkcprk] .bu-bay-12.bu-onboarding-step em {
    color: var(--theme-text-muted);
    font-size: var(--structure-text-sm);
}

/* R4 inline-style cleanup (2026-07-04): the remaining spots that previously
   used a raw style="" attribute directly in Onboarding.razor. */
[b-v2rsfkcprk] p.bu-brick[role="alert"].bu-onboarding-stripe-banner {
    font-weight: var(--structure-weight-bold);
}

[b-v2rsfkcprk] form.bu-onboarding-autologin {
    display: none;
}

[b-v2rsfkcprk] table {
    width: 100%;
    border-collapse: collapse;
}

[b-v2rsfkcprk] th,
[b-v2rsfkcprk] td {
    text-align: left;
    padding: var(--structure-gap-sm) var(--structure-gap-xs);
    border-bottom: 1px solid var(--theme-border-inactive);
    font-size: var(--structure-text-sm);
}

[b-v2rsfkcprk] thead th {
    color: var(--theme-text-muted);
    font-weight: var(--structure-weight-bold);
    text-transform: uppercase;
    font-size: var(--structure-text-xs);
    letter-spacing: 0.05em;
}

[b-v2rsfkcprk] .bu-reveal.bu-onboarding-roster-heading {
    margin-top: var(--structure-gap-md);
}

/* Stage-2b Plan Pivot/Safety Valve panel (SRS-SECTION-03 SS3.2.3, 2026-07-17).
   Structure/spacing only, greyscale-Primer-skeleton-first - no new color system,
   reuses .bu-panel/.bu-brick tokens exactly like the finalgate panel above it. */
[b-v2rsfkcprk] .bu-panel.bu-onboarding-tierpanel {
    margin-top: var(--structure-gap-sm);
    margin-bottom: var(--structure-gap-md);
}

[b-v2rsfkcprk] .bu-panel.bu-onboarding-tierpanel h3 {
    margin-top: 0;
}

/* B35: price is one inline run ("$99/month") and the feature bullets sit inside the card. */
[b-v2rsfkcprk] .bu-onboarding-planname,
[b-v2rsfkcprk] .bu-onboarding-price {
    display: block;
    margin-block: 0;
}

[b-v2rsfkcprk] .bu-panel.bu-onboarding-tierpanel ul {
    margin-inline: 0;
    padding-inline-start: var(--structure-gap-md);
    list-style-position: outside;
}

/* B17: order summary sits above the pay step's fields. */
[b-v2rsfkcprk] .bu-panel.bu-onboarding-ordersummary {
    margin-bottom: var(--structure-gap-md);
}

[b-v2rsfkcprk] button.bu-onboarding-finish-btn {
    margin-top: var(--structure-gap-md);
}
/* /Components/Pages/PublicPageQrPrint.razor.rz.scp.css */
.bu-pass-toolbar[b-a5tk08qisz] {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 1rem;
}

.bu-qr-sheet[b-a5tk08qisz] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1rem;
    padding: 1.5rem 1rem;
    max-width: 7.5in;
    margin: 0 auto;
}

.bu-qr-name[b-a5tk08qisz] {
    margin: 0;
    font-size: 3.25rem;
    line-height: 1.1;
    overflow-wrap: anywhere;
}

.bu-qr-lede[b-a5tk08qisz] {
    margin: 0;
    font-size: 1.75rem;
}

.bu-qr-img[b-a5tk08qisz] {
    width: 5.1in; /* ~60% of a letter page width */
    aspect-ratio: 1;
    max-width: 100%;
    image-rendering: pixelated;
}

.bu-qr-url[b-a5tk08qisz] {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 700;
    overflow-wrap: anywhere;
}

@media print {
    .bu-pass-toolbar[b-a5tk08qisz] {
        display: none;
    }

    /* BUG-2 (#418): the skin colours headings and paragraphs with light --theme-* text, which printed near-white on white paper.
       Paper is always black on white, whatever the skin: the sheet and everything in it is forced dark. */
    .bu-qr-sheet[b-a5tk08qisz],
    .bu-qr-sheet *[b-a5tk08qisz] {
        color: #000 !important;
        background: transparent !important;
        text-shadow: none !important;
    }
}
/* /Components/Pages/StaffManagement.razor.rz.scp.css */
/* Staff area: structure only (colour comes from the skin). 44px targets, stacks at 375. */
.bu-staff-add button[b-gs9cvwbiz0],
.bu-staff-invite button[b-gs9cvwbiz0] {
    min-height: 44px;
    min-width: 44px;
}

.bu-staff-role[b-gs9cvwbiz0] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
}

.bu-staff-role input[type="checkbox"][b-gs9cvwbiz0] {
    width: 24px;
    height: 24px;
}

.bu-staff-invite input[b-gs9cvwbiz0] {
    width: 100%;
    margin-bottom: 0.5rem;
}

/* #506: the staff table. Structure only; colour comes from the theme tokens and the Primer .bu-table / .bu-badge.
   The more menu opens INLINE beside its button (never an overlay): the table wrapper clips anything that hangs outside it, and a menu that opens inside the row cannot
   be cut off or land under another row. */
.bu-staff-name[b-gs9cvwbiz0] { font-weight: 600; white-space: nowrap; }
.bu-staff-chips[b-gs9cvwbiz0] { display: flex; flex-wrap: wrap; gap: 0.25rem 0.5rem; }
.bu-staff-actions-cell[b-gs9cvwbiz0] { width: 1%; white-space: nowrap; text-align: right; }
.bu-staff-actions[b-gs9cvwbiz0] { display: inline-flex; flex-wrap: nowrap; align-items: center; justify-content: flex-end; gap: 0.5rem; margin: 0; }
.bu-staff-more[b-gs9cvwbiz0] { min-width: 44px; min-height: 44px; font-size: 1.25rem; line-height: 1; }
.bu-staff-menu[b-gs9cvwbiz0] { display: inline-flex; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
.bu-staff-menu .bu-control[b-gs9cvwbiz0] { min-height: 44px; }
@media (max-width: 640px) { .bu-staff-table-wrap[b-gs9cvwbiz0] { overflow-x: auto; } }
.bu-staff-edit[b-gs9cvwbiz0] { min-height: 44px; min-width: 44px; }

/* #506 follow-up (1280 wide, where the centre panel is only ~650px between the two menus): the row stays one compact line of cells. Tighter cell padding, the
   two status words at the small text size and held to two lines, smaller chips, so the roles column gets the room and the chips wrap to two lines at most. */
.bu-staff-table th[b-gs9cvwbiz0],
.bu-staff-table td[b-gs9cvwbiz0] { padding-inline: 0.5rem; vertical-align: middle; }
.bu-staff-table td[data-testid="staff-twofactor"][b-gs9cvwbiz0],
.bu-staff-table td[data-testid="staff-status"][b-gs9cvwbiz0] { font-size: var(--structure-text-sm); width: 7.5rem; }
.bu-staff-chips .bu-badge[b-gs9cvwbiz0] { padding: 0.125rem 0.5rem; font-size: var(--structure-text-xs); }
/* /Components/Pages/TestDayListPrint.razor.rz.scp.css */
.bu-sheet-toolbar[b-d8nl9e8j1m] {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 1rem;
}

.bu-sheet-head[b-d8nl9e8j1m], .bu-sheet-group[b-d8nl9e8j1m] {
    padding: 0 1rem;
}

.bu-sheet-table[b-d8nl9e8j1m] {
    width: 100%;
    border-collapse: collapse;
}

.bu-sheet-table th[b-d8nl9e8j1m],
.bu-sheet-table td[b-d8nl9e8j1m] {
    border: 1px solid currentColor;
    padding: 0.35rem 0.5rem;
    text-align: left;
    vertical-align: top;
}

.bu-sheet-notes[b-d8nl9e8j1m] {
    min-width: 2in;
}

.bu-sheet-group[b-d8nl9e8j1m] {
    break-inside: avoid;
}

@media print {
    .bu-sheet-toolbar[b-d8nl9e8j1m] {
        display: none;
    }
}
/* /Components/Payments/IncomePanel.razor.rz.scp.css */
/* B2 income records: structure and spacing only (tokens, no colour literals). */
.bu-income[b-gwwa78oizp] { display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); margin-top: var(--structure-gap-lg, 2rem); }
.bu-income p[b-gwwa78oizp] { margin: 0; }
.bu-income__controls[b-gwwa78oizp] { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 1rem; }
.bu-income__table[b-gwwa78oizp] { width: 100%; border-collapse: collapse; }
.bu-income__table th[b-gwwa78oizp], .bu-income__table td[b-gwwa78oizp] { padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--theme-border-inactive); text-align: left; }
.bu-income__table thead th[b-gwwa78oizp], .bu-income__table tfoot th[b-gwwa78oizp], .bu-income__table tfoot td[b-gwwa78oizp] { font-weight: 600; }
.bu-income__table tbody th[b-gwwa78oizp] { font-weight: 400; }
.bu-income__table .bu-income__num[b-gwwa78oizp] { text-align: right; font-variant-numeric: tabular-nums; }
.bu-income__table caption[b-gwwa78oizp] { text-align: left; padding-bottom: 0.5rem; }
.bu-income__record[b-gwwa78oizp] { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
.bu-income__record .bu-btn[b-gwwa78oizp] { min-height: 44px; }
/* /Components/Payments/MemberDuesPanel.razor.rz.scp.css */
/* RW-14 who has paid / Record this month: structure and spacing only (tokens, no colour literals). */
.bu-dues[b-eo2wt3s3ex] { display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); margin-top: var(--structure-gap-lg, 2rem); }
.bu-dues p[b-eo2wt3s3ex] { margin: 0; }
.bu-dues__controls[b-eo2wt3s3ex] { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 1rem; }
.bu-dues__table[b-eo2wt3s3ex] { width: 100%; border-collapse: collapse; }
.bu-dues__table th[b-eo2wt3s3ex], .bu-dues__table td[b-eo2wt3s3ex] { padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--theme-border-inactive); text-align: left; }
.bu-dues__table thead th[b-eo2wt3s3ex] { font-weight: 600; }
.bu-dues__table tbody th[b-eo2wt3s3ex] { font-weight: 400; }
.bu-dues__table .bu-dues__num[b-eo2wt3s3ex] { text-align: right; font-variant-numeric: tabular-nums; }
.bu-dues__table input[type="checkbox"][b-eo2wt3s3ex] { width: 1.5rem; height: 1.5rem; }
.bu-dues__amount[b-eo2wt3s3ex] { max-width: 7rem; text-align: right; }
/* /Components/Payments/StudentPaymentsPanel.razor.rz.scp.css */
/* B2 payment path card: spacing only (tokens, no colour literals). */
.bu-pay-path[b-xepbzy4vi0] { display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); margin-top: var(--structure-gap-md, 1rem); }
.bu-pay-path p[b-xepbzy4vi0] { margin: 0; }
.bu-pay-path__choices[b-xepbzy4vi0] { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.bu-pay-path__gateway[b-xepbzy4vi0] { display: flex; flex-direction: column; gap: 0.75rem; max-width: 32rem; }
/* /Components/PersonLink.razor.rz.scp.css */
/* A person's name or avatar that opens their profile: reads as text, looks interactive, keeps a 44px target and the skin's focus ring. */
.cc-person-link[b-mtq0fbddpq] { font: inherit; color: inherit; background: transparent; border: 0; padding: 0 0.25rem; min-height: 44px; cursor: pointer; text-align: left; text-decoration: underline; text-underline-offset: 0.2em; }
.cc-person-link:hover[b-mtq0fbddpq] { background: var(--theme-bg-surface, transparent); }
.cc-person-link:focus-visible[b-mtq0fbddpq] { outline: 2px solid var(--theme-x-focus-ring, var(--theme-border-active)); outline-offset: 2px; }
/* /Components/Plans/PlanEditor.razor.rz.scp.css */
/* B1 Memberships editor: structure and spacing only. Colour comes from the skin tokens already on .bu-panel / .bu-badge / .bu-alert
   (greyscale Primer first, Executive Blue and the other skins restyle through --theme-*). No colour literals here. The child components (form, template cards) are styled through ::deep from this root. */
.bu-plans[b-x220ht4kih] { display: flex; flex-direction: column; gap: 1rem; }

/* Section headings are in-panel labels, not page titles: plain weight and size, never the page-level heading look. */
[b-x220ht4kih] .bu-plan-heading { font-size: 1.1rem; font-weight: 600; text-transform: none; letter-spacing: normal; margin: 0 0 0.25rem; }

[b-x220ht4kih] .bu-plan-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }

[b-x220ht4kih] .bu-plan-list, [b-x220ht4kih] .bu-plan-cards { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
[b-x220ht4kih] .bu-plan-cards { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }

[b-x220ht4kih] .bu-plan-card, [b-x220ht4kih] .bu-plan-row { border: 1px solid var(--theme-border-inactive); border-radius: var(--structure-radius-panel, 4px); padding: 0.75rem 1rem; }
[b-x220ht4kih] .bu-plan-card { display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; }
[b-x220ht4kih] .bu-plan-card__name { margin: 0; }

/* #429: the row is a compact card, one tidy row. The old rule never set flex-direction, so .bu-panel's column won and the 18rem basis
   below became a HEIGHT (340px rows, Edit centred). The row is no longer a .bu-panel, so the executive skin cannot strip its edge. */
[b-x220ht4kih] .bu-plan-row { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; }
[b-x220ht4kih] .bu-plan-row__main { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; flex: 1 1 18rem; min-width: 0; }
[b-x220ht4kih] .bu-plan-row__main > p { flex-basis: 100%; margin: 0; }
[b-x220ht4kih] .bu-plan-row__name { overflow-wrap: anywhere; }

[b-x220ht4kih] .bu-plan-form { display: flex; flex-direction: column; gap: 1rem; }
[b-x220ht4kih] .bu-plan-section { border: 1px solid var(--theme-border-inactive); border-radius: var(--structure-radius-panel, 4px); padding: 0.75rem 1rem 1rem; display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; }
[b-x220ht4kih] .bu-plan-section > legend { padding: 0 0.5rem; }

[b-x220ht4kih] .bu-plan-preview__price { margin: 0; font-size: 1.25rem; font-weight: 600; }

[b-x220ht4kih] .bu-plan-discounts { display: flex; flex-direction: column; gap: 0.5rem; }
[b-x220ht4kih] .bu-plan-discount-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 1rem; }
[b-x220ht4kih] .bu-plan-discount-row label { display: flex; flex-direction: column; gap: 0.25rem; }

[b-x220ht4kih] .bu-plan-history ul, [b-x220ht4kih] .bu-plan-retired ul { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.5rem; }
[b-x220ht4kih] .bu-plan-history li, [b-x220ht4kih] .bu-plan-retired li { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }

/* The status badge says its state in WORDS (and a leading mark), never colour alone. */
[b-x220ht4kih] .bu-plan-status[data-status="LIVE"]::before { content: "\2713\00a0"; }
[b-x220ht4kih] .bu-plan-status[data-status="DRAFT"]::before { content: "\270E\00a0"; }
[b-x220ht4kih] .bu-plan-status[data-status="RETIRED"]::before { content: "\2212\00a0"; }
/* /Components/Records/DataExportPanel.razor.rz.scp.css */
/* RW-29 Download everything: structure and spacing only (tokens, no colour literals). */
.bu-export[b-4gec5h5f4n] { display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); margin-top: var(--structure-gap-lg, 2rem); }
.bu-export p[b-4gec5h5f4n], .bu-export ul[b-4gec5h5f4n] { margin: 0; }
.bu-export .bu-btn[b-4gec5h5f4n] { min-height: 44px; }
/* /Components/Records/MonthlySummaryPanel.razor.rz.scp.css */
/* RW-27 monthly page: structure and spacing only (tokens, no colour literals). */
.bu-monthly[b-k3q2afx8ay] { display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); margin-top: var(--structure-gap-lg, 2rem); }
.bu-monthly p[b-k3q2afx8ay] { margin: 0; }
/* /Components/Records/OwnerReportsPanel.razor.rz.scp.css */
/* US-223 owner reports: structure and spacing only (tokens, no colour literals); the bar takes its fill from the text colour so any skin themes it. */
.bu-owner-reports[b-g6btrii6ma] { display: flex; flex-direction: column; gap: var(--structure-gap-md, 1rem); margin-top: var(--structure-gap-lg, 2rem); }
.bu-owner-reports p[b-g6btrii6ma] { margin: 0; }
.bu-report[b-g6btrii6ma] { display: flex; flex-direction: column; gap: var(--structure-gap-sm, 0.5rem); }
.bu-report h4[b-g6btrii6ma] { margin: 0; }
.bu-report table[b-g6btrii6ma] { width: 100%; border-collapse: collapse; }
.bu-report th[b-g6btrii6ma], .bu-report td[b-g6btrii6ma] { text-align: left; padding: 0.25rem 0.5rem; }
.bu-report-bar-cell[b-g6btrii6ma] { width: 40%; }
.bu-report-bar[b-g6btrii6ma] { display: block; height: 0.6rem; min-width: 2px; background: currentColor; opacity: 0.55; border-radius: 2px; }
.bu-report-bar + .bu-report-bar[b-g6btrii6ma] { margin-top: 2px; opacity: 0.25; }
.bu-sr-only[b-g6btrii6ma] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* /Components/Registration/AddPersonDrawer.razor.rz.scp.css */
/* The Add-person drawer's own bits (the drawer shell is the shared .bu-drawer): tokens only. */
.reg-roles[b-2xtansia6n] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); margin-top: var(--structure-gap-xs); }
.reg-roles button[aria-pressed="true"][b-2xtansia6n] { font-weight: var(--structure-weight-bold); }
.reg-someone-else[b-2xtansia6n] { margin-bottom: var(--structure-gap-sm); }
.reg-emergency[b-2xtansia6n] { margin: var(--structure-gap-sm) 0; }
.reg-emergency summary[b-2xtansia6n] { cursor: pointer; min-height: 44px; display: flex; align-items: center; }
/* /Components/Registration/ContactField.razor.rz.scp.css */
/* Existing-person check under a contact box: tokens only (greyscale Primer + skin). Buttons wrap on a phone and stay touch-sized. */
.reg-match[b-earkltzz67] { margin-top: var(--structure-gap-xs); }
.reg-match p[b-earkltzz67] { margin: 0 0 var(--structure-gap-xs); overflow-wrap: anywhere; }
.reg-match-actions[b-earkltzz67] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); }
.reg-match-actions button[aria-pressed="true"][b-earkltzz67] { font-weight: var(--structure-weight-bold); border-color: var(--theme-border-active, currentColor); }
/* /Components/Registration/EntryLinkFooter.razor.rz.scp.css */
/* Show QR / Copy link footer of every Add drawer: tokens only. The QR and the link text wrap inside a phone sheet. */
.reg-footer[b-0osrk30hw1] { margin-top: var(--structure-gap-md); padding-top: var(--structure-gap-sm); border-top: 1px solid var(--theme-border-inactive); }
.reg-footer-buttons[b-0osrk30hw1] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); }
.reg-qr[b-0osrk30hw1] { margin: var(--structure-gap-sm) 0 0; display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: flex-start; }
.reg-qr img[b-0osrk30hw1] { background: #fff; padding: 0.5rem; max-width: 100%; height: auto; }
.reg-qr figcaption[b-0osrk30hw1] { flex: 1 1 12rem; min-width: 0; display: flex; flex-direction: column; gap: var(--structure-gap-xs); }
.reg-links[b-0osrk30hw1] { margin-top: var(--structure-gap-sm); }
.reg-link-list[b-0osrk30hw1] { list-style: none; margin: 0; padding: 0; }
.reg-link-row[b-0osrk30hw1] { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--structure-gap-xs); padding: var(--structure-gap-xs) 0; border-bottom: 1px solid var(--theme-border-inactive); }
.reg-link-name[b-0osrk30hw1] { display: block; overflow-wrap: anywhere; }
.reg-link-actions[b-0osrk30hw1] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); }
/* /Components/Registration/RegistrationQueueBanner.razor.rz.scp.css */
/* The new-registrations strip: the count and its one button on a single line (the Executive Blue console skin colours it through the tokens). */
.reg-queue-strip[b-3qcxedtll3] { display: flex; align-items: center; justify-content: space-between; gap: var(--structure-gap-md); flex-wrap: wrap; border-left: 4px solid var(--theme-border-active); }
/* /Components/Registration/RegistrationReviewDrawer.razor.rz.scp.css */
/* The review drawer: tokens only (Executive Blue and the greyscale skeleton both read them). The shell is the shared .bu-drawer. */
.reg-review-drawer[b-hpagjd2pjz] { width: min(620px, 100%); overflow-y: auto; }
.reg-queue-list[b-hpagjd2pjz] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--structure-gap-sm); }
.reg-queue-row[b-hpagjd2pjz] { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "main action" "flags action"; gap: var(--structure-gap-xs) var(--structure-gap-md); align-items: center; }
.reg-queue-main[b-hpagjd2pjz] { grid-area: main; display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); align-items: baseline; }
.reg-queue-flags[b-hpagjd2pjz] { grid-area: flags; display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); }
.reg-queue-row > button[b-hpagjd2pjz] { grid-area: action; min-height: var(--structure-touch-min); }
.reg-person[b-hpagjd2pjz] { margin-block: var(--structure-gap-md); }
.reg-fields[b-hpagjd2pjz] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--structure-gap-sm); }
.reg-fields .bu-input[b-hpagjd2pjz] { width: 100%; min-height: var(--structure-touch-min); }
.reg-styles[b-hpagjd2pjz] { border: 0; margin: var(--structure-gap-sm) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--structure-gap-md); }
.reg-styles legend[b-hpagjd2pjz] { width: 100%; padding: 0 0 var(--structure-gap-xs); }
.reg-match[b-hpagjd2pjz] { margin-top: var(--structure-gap-sm); padding-top: var(--structure-gap-xs); border-top: 1px solid var(--theme-border-inactive); }
.reg-match-choice[b-hpagjd2pjz] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-md); }
.reg-evidence[b-hpagjd2pjz] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--structure-gap-xs); }
.reg-actions[b-hpagjd2pjz] { display: flex; flex-wrap: wrap; gap: var(--structure-gap-sm); margin-top: var(--structure-gap-md); }
.reg-actions .bu-btn[b-hpagjd2pjz], .reg-actions .bu-btn-secondary[b-hpagjd2pjz] { min-height: var(--structure-touch-min); }
@media (max-width: 640px) { .reg-fields[b-hpagjd2pjz] { grid-template-columns: minmax(0, 1fr); } .reg-queue-row[b-hpagjd2pjz] { grid-template-columns: minmax(0, 1fr); grid-template-areas: "main" "flags" "action"; } }
/* /Components/RosterList.razor.rz.scp.css */
/* #390 list tools: the search box and style filter sit side by side (they wrap on a narrow panel); the count reads beside them. */
.cc-roster-list__tools[b-7ett01mtwv] { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 1rem; margin-top: 1rem; margin-bottom: 0.5rem; }  /* #436: the label sat 9px under the stat tiles on Retention */
.cc-roster-list__tools .bu-field[b-7ett01mtwv] { flex: 1 1 14rem; margin: 0; }
.cc-roster-list__tools p[b-7ett01mtwv] { flex: 0 0 auto; margin: 0; }
.cc-roster-list__group[b-7ett01mtwv] { margin: 0.75rem 0 0.25rem; font-weight: 600; }

/* #503: Retention groups (Needs attention / Keep an eye on / On track), each a plain heading with its count. */
.cc-roster-list__group[data-group][b-7ett01mtwv] { display: flex; align-items: baseline; gap: 0.5rem; }
/* /Components/RosterMeters.razor.rz.scp.css */
/* REQ-ROSTER-METERS-001 + R-1024-02 compact ring meters. Tokens only: the ring stroke is the skin's semantic state colour, the track the
   neutral border token, the text the theme text tokens, so every skin (including the greyscale skeleton, which keeps its state colours)
   restyles it. Value text inside and the state icon beside the name always accompany the colour. Four rings sit in one tight row. */
.cc-meters[b-1ahm0wrgu3] { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 0.25rem 0.125rem; flex: 1 1 100%; align-items: flex-start; }
.cc-meter[b-1ahm0wrgu3] { position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.0625rem; flex: 0 0 4rem; width: 4rem; --_tone: var(--theme-text-muted, currentColor); }
.cc-ring[b-1ahm0wrgu3] { position: relative; display: block; width: 44px; height: 44px; flex: none; }
.cc-ring__svg[b-1ahm0wrgu3] { display: block; width: 100%; height: 100%; transform: rotate(-90deg); }
.cc-ring__track[b-1ahm0wrgu3], .cc-ring__fill[b-1ahm0wrgu3] { fill: none; stroke-width: 3.5; }
.cc-ring__track[b-1ahm0wrgu3] { stroke: var(--theme-border-inactive, rgba(128, 128, 128, 0.45)); }
.cc-ring__fill[b-1ahm0wrgu3] { stroke: var(--_tone); stroke-linecap: butt; }
.cc-ring__v[b-1ahm0wrgu3] {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 0 5px; font-size: 0.625rem; line-height: 1.05; font-weight: 700; overflow: hidden; overflow-wrap: anywhere;
  color: var(--theme-text-main, currentColor);
}
.cc-meter__k[b-1ahm0wrgu3] { font-size: 0.6875rem; line-height: 1.1; white-space: nowrap; opacity: 0.85; color: var(--theme-text-muted, currentColor); }
.cc-meter__i[b-1ahm0wrgu3] { color: var(--_tone); font-weight: 700; }
/* The full plain sentence for the row's aria-describedby and for copy/paste; invisible on screen. */
.cc-meter__sr[b-1ahm0wrgu3] { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.cc-meter--ok[b-1ahm0wrgu3] { --_tone: var(--theme-state-healthy, var(--theme-x-state-info, currentColor)); }
.cc-meter--watch[b-1ahm0wrgu3] { --_tone: var(--theme-state-warning, currentColor); }
.cc-meter--risk[b-1ahm0wrgu3] { --_tone: var(--theme-state-error, currentColor); }
.cc-meter--neutral[b-1ahm0wrgu3] { --_tone: var(--theme-text-muted, currentColor); }
/* Motion: the ring fill only animates when motion is allowed. */
@media (prefers-reduced-motion: no-preference) {
  .cc-ring__fill[b-1ahm0wrgu3] { transition: stroke-dasharray 0.4s ease; }
}
:root[data-reduced-motion="true"] .cc-ring__fill[b-1ahm0wrgu3] { transition: none; }
/* Print: keep the ring and its value legible on paper (backgrounds are dropped, strokes and text are not). */
@media print {
  .cc-ring__svg[b-1ahm0wrgu3] { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .cc-ring__track[b-1ahm0wrgu3] { stroke: rgba(0, 0, 0, 0.25); }
  .cc-ring__fill[b-1ahm0wrgu3] { stroke: black; }
  .cc-ring__v[b-1ahm0wrgu3], .cc-meter__k[b-1ahm0wrgu3] { color: black; opacity: 1; }
}
@media (forced-colors: active) {
  .cc-ring__track[b-1ahm0wrgu3] { stroke: GrayText; }
  .cc-ring__fill[b-1ahm0wrgu3] { stroke: Highlight; }
  .cc-ring__v[b-1ahm0wrgu3] { color: CanvasText; }
}
/* Wide row (container query on RosterRow's wrapper): the four rings share the row's first line (a sixth grid column) instead of taking a line of
   their own, so the row is one line tall. Narrower: they sit as a tight row under the cells and wrap (4 x 4rem fits a 390px phone in one row,
   never scrolling sideways). */
@container (min-width: 38rem) {
  .cc-meters[b-1ahm0wrgu3] { grid-column: 8; grid-row: 1; flex: none; flex-wrap: nowrap; gap: 0; }  /* Issue 503: the 8th column now (waiver and plan icons are 6 and 7) */
}

/* Issue 503: plain captions. A neutral ring's icon was a bare dash, so the caption read "— Churn" / "— Attend"; a toned ring keeps its shape icon (a
   warning, a triangle, a tick) beside the word, a neutral one is just the word. The words inside a neutral EMPTY ring ("No style", "No data", "Not tracked")
   were tiny and repeated the caption, so they stay in the tooltip and the screen-reader sentence only. A neutral ring with a real value (3/5) keeps it. */
.cc-meter--neutral .cc-meter__i[b-1ahm0wrgu3] { display: none; }
.cc-meter--neutral[data-fill="0"] .cc-ring__v[b-1ahm0wrgu3] { visibility: hidden; }
/* Wide row (issue 503): smaller rings so the row is one ~50px line. */
@container (min-width: 38rem) {
  .cc-meter[b-1ahm0wrgu3] { flex: 0 0 3.25rem; width: 3.25rem; }
  .cc-ring[b-1ahm0wrgu3] { width: 32px; height: 32px; }
  .cc-ring__v[b-1ahm0wrgu3] { font-size: 0.5625rem; padding: 0 3px; }
  .cc-meter__k[b-1ahm0wrgu3] { font-size: 0.625rem; }
  .cc-meters[b-1ahm0wrgu3] { gap: 0; }
}
/* /Components/RosterRow.razor.rz.scp.css */
/* #269 roster-row avatar ring. Tokens only; skins restyle via --theme-* and the optional
   --cc-ring-* overrides. Ring contrast on Executive Blue canvas #030403 (>=3:1, WCAG 1.4.11): error 5.5, warning 12.3,
   ok/active (state-info) 7.8, no-data (text-muted) 9.8; the old accent-primary was 2.4. Every ring/focus colour is mixed 45% toward --theme-text-main so it clears 3:1 against canvas and surface in EVERY skin (RosterRowTests parses all skins). Gold (testing-eligible) is intentionally absent: no data binds it. */
.cc-roster-row[b-4e4a7vf4nd] {
  width: 100%; text-align: left; font: inherit; color: inherit; background: transparent; border: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem;
  min-height: 44px; padding: 0.5rem 0.75rem; cursor: pointer;
  border-bottom: 1px solid var(--theme-border-inactive);
}
.cc-roster-row:hover[b-4e4a7vf4nd] { background: var(--theme-bg-surface, transparent); }
.cc-roster-row:focus-visible[b-4e4a7vf4nd] { outline: 2px solid color-mix(in srgb, var(--theme-x-focus-ring, var(--theme-border-active)) 55%, var(--theme-text-main, #fff)); outline-offset: -2px; }
.cc-avatar[b-4e4a7vf4nd] { width: 44px; height: 44px; border-radius: 50%; position: relative; flex: none; margin: 3px; }
.cc-avatar__ring[b-4e4a7vf4nd] {
  position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid var(--_ring, var(--theme-border-inactive));
  box-shadow: 0 0 8px var(--_ring, transparent);
}
.cc-avatar__face[b-4e4a7vf4nd] {
  position: absolute; inset: 0; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--theme-bg-card, var(--theme-border-inactive)); color: var(--theme-text-muted, currentColor);
}
.cc-avatar__img[b-4e4a7vf4nd] { width: 100%; height: 100%; object-fit: cover; }
.cc-avatar__glyph[b-4e4a7vf4nd] { width: 70%; height: 70%; }
.cc-avatar__initials[b-4e4a7vf4nd] { font-weight: 600; letter-spacing: 0.02em; }
.cc-avatar--risk[b-4e4a7vf4nd] { --_ring: color-mix(in srgb, var(--cc-ring-risk, var(--theme-state-error)) 55%, var(--theme-text-main, #fff)); }
/* #480: a new student with no check-in yet: the neutral muted ring, never the green "safe" or red "risk" one */
.cc-avatar--new[b-4e4a7vf4nd], .cc-avatar--nodata[b-4e4a7vf4nd] { --_ring: var(--cc-ring-nodata, var(--theme-text-muted)); }
.cc-avatar--watch[b-4e4a7vf4nd] { --_ring: color-mix(in srgb, var(--cc-ring-watch, var(--theme-state-warning)) 55%, var(--theme-text-main, #fff)); }
.cc-avatar--ok[b-4e4a7vf4nd], .cc-avatar--active[b-4e4a7vf4nd] { --_ring: color-mix(in srgb, var(--cc-ring-ok, var(--theme-state-healthy, var(--theme-x-state-info))) 55%, var(--theme-text-main, #fff)); }
.cc-roster-row__name[b-4e4a7vf4nd] { flex: 1 1 10rem; min-width: 0; font-weight: 600; }
/* #436: the name and its MINOR badge sit on one line with a real gap (the badge touched the name; on a long name it wrapped below it and
   made that row taller than its neighbours). Only the name text wraps; the badge never does. */
.cc-roster-row__name[b-4e4a7vf4nd] { display: flex; align-items: center; gap: 0.5rem; }
.cc-roster-row__nametext[b-4e4a7vf4nd] { min-width: 0; overflow-wrap: anywhere; }
.cc-roster-row__name > .bu-badge-tag[b-4e4a7vf4nd] { flex: none; white-space: nowrap; }
.cc-roster-row__cell[b-4e4a7vf4nd] { flex: 0 1 9rem; }
.cc-roster-row__date[b-4e4a7vf4nd] { white-space: nowrap; }
.cc-roster-row__k[b-4e4a7vf4nd] { display: inline-block; opacity: 0.7; margin-right: 0.25rem; }
.cc-roster-row__state[b-4e4a7vf4nd] { font-weight: 600; }
/* Glow animation only when motion is allowed; otherwise a static ring. */
@media (prefers-reduced-motion: no-preference) {
  .cc-avatar--risk .cc-avatar__ring[b-4e4a7vf4nd] { animation: cc-vibe-b-4e4a7vf4nd 1.6s ease-in-out infinite; }
}
:root[data-reduced-motion="true"] .cc-avatar--risk .cc-avatar__ring[b-4e4a7vf4nd] { animation: none; }
@keyframes cc-vibe-b-4e4a7vf4nd {
  0%, 100% { box-shadow: 0 0 4px var(--_ring, transparent); }
  50% { box-shadow: 0 0 12px var(--_ring, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .cc-avatar--risk .cc-avatar__ring[b-4e4a7vf4nd] { animation: none; }
}
/* US-203 / REQ-ROSTER-001 AC-7: belts sit OUTSIDE the avatar, one [style][belt] pair per style. Style tags use the PROPOSED style-colour token
   names (BUP-UI-STYLE-COLOURS-PROPOSAL-001) with neutral fallbacks until the palette is approved; the belt colour is data (DagNodes.BeltColorHex)
   set inline as --cc-belt, and a rank with no colour shows a hollow neutral bar. The rank name is always text. */
.cc-roster-row__styles[b-4e4a7vf4nd] { display: flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; flex: 2 1 16rem; min-width: 0; }
.cc-style-pair[b-4e4a7vf4nd] { display: inline-flex; align-items: center; gap: 0.375rem; white-space: nowrap; }
.cc-style[b-4e4a7vf4nd] { --_style: var(--theme-text-muted); border-left: 4px solid var(--_style); padding: 0 0.375rem; font-weight: 600; font-size: 0.875rem; }
.cc-style--1[b-4e4a7vf4nd] { --_style: var(--theme-style-1, var(--theme-text-muted)); }
.cc-style--2[b-4e4a7vf4nd] { --_style: var(--theme-style-2, var(--theme-text-muted)); }
.cc-style--3[b-4e4a7vf4nd] { --_style: var(--theme-style-3, var(--theme-text-muted)); }
.cc-style--4[b-4e4a7vf4nd] { --_style: var(--theme-style-4, var(--theme-text-muted)); }
.cc-style--5[b-4e4a7vf4nd] { --_style: var(--theme-style-5, var(--theme-text-muted)); }
.cc-style--6[b-4e4a7vf4nd] { --_style: var(--theme-style-6, var(--theme-text-muted)); }
.cc-style--7[b-4e4a7vf4nd] { --_style: var(--theme-style-7, var(--theme-text-muted)); }
.cc-style--8[b-4e4a7vf4nd] { --_style: var(--theme-style-8, var(--theme-text-muted)); }
.cc-roster-row__drivers[b-4e4a7vf4nd] { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; font-size: 0.875rem; }
.cc-roster-row__driver[b-4e4a7vf4nd] { overflow-wrap: anywhere; }

/* BUG-5 (#421, QA 3ceba79): rows with a [style][belt] chip pair and rows with only a rank lined up differently, because the flex-wrap row
   let the chip group (flex 2 1 16rem) push "Last seen" and the status onto another line. On a wide row the five cells now sit in FIXED grid
   columns - avatar | name | rank or belt chips | last seen | status - so every row aligns whatever it holds; meters and drivers span the row.
   "Last seen" label and value stay on one line. Narrow screens keep the wrapping flex row above. */
@media (min-width: 700px) {
  .cc-roster-row[b-4e4a7vf4nd] {
    display: grid;
    grid-template-columns: auto minmax(11rem, 1.2fr) minmax(11rem, 2fr) minmax(10rem, 0.9fr) minmax(7rem, 0.6fr);
    column-gap: 1rem;
    row-gap: 0.5rem;
    align-items: center;
  }
  .cc-roster-row__name[b-4e4a7vf4nd], .cc-roster-row__styles[b-4e4a7vf4nd], .cc-roster-row__cell[b-4e4a7vf4nd] { min-width: 0; }
  .cc-roster-row__cell[b-4e4a7vf4nd] { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .cc-roster-row__drivers[b-4e4a7vf4nd] { grid-column: 1 / -1; }
}

/* B2: the membership chip gets its own full-width line under the name so the plan name is whole (the tooltip and aria-label carry it in full too). */
.cc-roster-row__cell--plan[b-4e4a7vf4nd] { flex: 1 1 100%; max-width: 100%; }
@media (min-width: 900px) { .cc-roster-row__cell--plan[b-4e4a7vf4nd] { grid-column: 2 / -1; overflow: visible; text-overflow: clip; } }

/* R-1024-02: the ring meters are small, so on a row wide enough they take a sixth column on the row's first line (RosterMeters.razor.css) and the
   row is one line tall. "Wide enough" is the ROW's own width (a container query on the wrapper), not the viewport: the console's centre column is
   narrow on a 1440px screen. "Last seen" stacks its small label over the date so the column is narrow. Narrower rows keep the rings in a tight row
   under the cells (and wrap on a phone). */
.cc-roster-row__box[b-4e4a7vf4nd] { container-type: inline-size; width: 100%; }
@container (min-width: 50rem) {
  .cc-roster-row[b-4e4a7vf4nd] { grid-template-columns: auto minmax(7rem, 2fr) minmax(9rem, 1.1fr) minmax(5.25rem, 0.6fr) minmax(5rem, 0.5fr) auto; column-gap: 0.75rem; }
  .cc-roster-row__k[b-4e4a7vf4nd] { display: block; margin: 0; font-size: 0.6875rem; line-height: 1.1; }
  /* A name that does not fit wraps at word breaks (the MINOR badge drops under it) instead of snapping mid-word. */
  .cc-roster-row__name[b-4e4a7vf4nd] { flex-wrap: wrap; row-gap: 0.125rem; }
  .cc-roster-row__nametext[b-4e4a7vf4nd] { overflow-wrap: break-word; }
}
/* Phone: the date and the status share a line instead of each taking one. */
@media (max-width: 699px) {
  .cc-roster-row__cell[b-4e4a7vf4nd] { flex: 0 1 auto; }
}
/* #463: with a drawer open the list is narrow and the waiver cell (one of the nowrap, clipped cells above) cut "Waiver needed" to "Waiver needec".
   The chip is a status the owner must read whole: its cell wraps instead of clipping, so it never loses a letter. */
.cc-roster-row__cell--waiver[b-4e4a7vf4nd] { white-space: normal; overflow: visible; text-overflow: clip; min-width: 0; overflow-wrap: normal; }
/* #466 (QA 105bb49): in the narrow last grid column the chip wrapped one word per line. Like the plan chip it now takes its own
   full-width line (under the name, across the remaining columns) and the chip text never breaks inside a word. */
.cc-roster-row__cell--waiver[b-4e4a7vf4nd] { flex: 1 1 100%; max-width: 100%; }
@media (min-width: 700px) { .cc-roster-row__cell--waiver[b-4e4a7vf4nd] { grid-column: 2 / -1; } }
.cc-roster-row__cell--waiver[b-4e4a7vf4nd]  .cc-waiver { white-space: nowrap; border-radius: 0.75rem; padding-block: 0.125rem; max-width: 100%; }

/* #483: the status ("New — no check-in yet") was a nowrap clipped cell and read "— New — n…". The state is something the owner must read whole, so it wraps at word breaks
   (never inside a word) instead of clipping; the full text is also its title. */
.cc-roster-row__cell.cc-roster-row__state[b-4e4a7vf4nd] { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: normal; }

/* #503 (owner usability sweep 2026-10-26): on a wide row EVERYTHING is one line - avatar | name (+ Minor badge) | style and belt | last seen | status |
   waiver icon | plan icon | four ring meters - about 50px tall, so a 16-student school shows 10+ rows on a 1920x889 screen instead of 4. The waiver and plan chips are
   icons with the words as their tooltip (and still read aloud), not a second and third line. The status keeps its #483 wrap rule above for a row too narrow
   to hold it, but the column is wide enough for "New — no check-in yet". [PILLAR-1: behavioral science] a scannable list: the same fields in the same columns,
   one row per person, so the eye compares down a column instead of reading each row as a paragraph. */
/* Threshold 38rem (not 50rem): a 1280px laptop's centre column is only ~700px wide, and below the old threshold the row fell back to the wrapping layout (132-156px rows, 3 visible). */
@container (min-width: 38rem) {
  .cc-roster-row__k[b-4e4a7vf4nd] { display: block; margin: 0; font-size: 0.6875rem; line-height: 1.1; }
  .cc-roster-row[b-4e4a7vf4nd] { grid-template-columns: auto minmax(5rem, 2fr) minmax(6rem, 1.4fr) minmax(4rem, 0.5fr) minmax(6.5rem, 1fr) auto auto auto; column-gap: 0.75rem; row-gap: 0; padding: 0.35rem 0.75rem; min-height: 0; }
  .cc-roster-row__cell--waiver[b-4e4a7vf4nd] { grid-column: 6; grid-row: 1; flex: none; overflow: visible; }
  .cc-roster-row__cell--plan[b-4e4a7vf4nd] { grid-column: 7; grid-row: 1; flex: none; overflow: visible; }
  .cc-avatar[b-4e4a7vf4nd] { width: 36px; height: 36px; }
  .cc-roster-row__name[b-4e4a7vf4nd] { flex-wrap: nowrap; }
  .cc-roster-row__nametext[b-4e4a7vf4nd] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* #504 / #503: the "Why" disclosure sits under its row, outside the row button. */
.cc-roster-row__why[b-4e4a7vf4nd] { padding: 0 0.75rem 0.375rem 4rem; border-bottom: 1px solid var(--theme-border-inactive); font-size: 0.875rem; }
.cc-roster-row__why > summary[b-4e4a7vf4nd] { cursor: pointer; display: inline-block; min-height: 24px; color: var(--theme-text-muted, inherit); }
.cc-roster-row__why > summary:focus-visible[b-4e4a7vf4nd] { outline: 2px solid var(--theme-text-main, currentColor); outline-offset: 2px; }  /* text colour: always >= 3:1 on the surface */
.cc-roster-row__why[open] > summary[b-4e4a7vf4nd] { color: var(--theme-text-main, inherit); }
/* The top reason reads in the normal text colour (contrast), the "Why:" caption stays muted; the summary is one line that truncates, the full list is the expand. */
.cc-roster-row__why-top[b-4e4a7vf4nd] { color: var(--theme-text-main, inherit); }
.cc-roster-row__why > summary[b-4e4a7vf4nd] { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-roster-row__why[open] > summary[b-4e4a7vf4nd] { white-space: normal; }

/* A short laptop screen (800px high): the list must still show 10 rows, so the row trades its padding for height (about 51px); a taller screen keeps the 56px row. */
@media (max-height: 820px) {
  @container (min-width: 38rem) { .cc-roster-row[b-4e4a7vf4nd] { padding-block: 0.1875rem; } }
}
/* /Components/Shared/AccountBell.razor.rz.scp.css */
/*
  AccountBell.razor.css - R-1031-01 console header corner (notification bell + signed-in name menu).
  Structure and spacing only, tokens only: surfaces and text colours come from the skin through the shared
  .bu-panel / .bu-control classes (R-0823-01 skeleton vs skin). The one colour here is the semantic state
  token on the waiting-count badge (--state-error, the same token bento-grid.css uses for a gap/problem count).
*/

.bu-account[b-er9v0t5byg] {
    display: flex;
    align-items: center;
    gap: var(--structure-gap-sm);
    min-width: 0;
    flex-wrap: wrap;   /* name + bell wrap onto a second line instead of pushing the header sideways at 390px */
}

.bu-account__item[b-er9v0t5byg] {
    position: relative;
}

.bu-account [hidden][b-er9v0t5byg] {
    display: none;
}

.bu-account__bell[b-er9v0t5byg] {
    position: relative;
    gap: var(--structure-gap-xs);
}

.bu-account__bell svg[b-er9v0t5byg] {
    width: 1.25rem;
    height: 1.25rem;
    flex: 0 0 auto;
}

.bu-account__count[b-er9v0t5byg] {
    min-width: 1.25rem;
    padding: 0 var(--structure-gap-xs);
    border-width: 1px;
    border-style: solid;
    border-radius: var(--structure-radius-max);
    border-color: var(--state-error);
    color: var(--state-error);
    font-size: var(--structure-text-xs);
    font-weight: var(--structure-weight-bold);
    line-height: 1.25rem;
    text-align: center;
}

.bu-account__name[b-er9v0t5byg] {
    max-width: 14rem;
}

.bu-account__name-text[b-er9v0t5byg] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The dropdown panels hang under their trigger and stay inside the viewport on a phone. */
.bu-account__panel[b-er9v0t5byg] {
    position: absolute;
    top: calc(100% + var(--structure-gap-xs));
    right: 0;
    z-index: var(--structure-z-overlay);
    min-width: 16rem;
    max-width: min(24rem, calc(100vw - 2 * var(--structure-gap-md)));
    padding: var(--structure-gap-md);
}

.bu-account__panel--menu[b-er9v0t5byg] {
    min-width: 10rem;
}

.bu-account__panel-title[b-er9v0t5byg] {
    margin: 0 0 var(--structure-gap-sm);
    font-size: var(--structure-text-md);
}

.bu-account__list[b-er9v0t5byg] {
    display: grid;
    gap: var(--structure-gap-sm);
    margin: 0;
    padding: 0;
    list-style: none;
}

.bu-account__panel form[b-er9v0t5byg] {
    margin: 0;
}

@media (max-width: 480px) {
    .bu-account__panel[b-er9v0t5byg] {
        position: fixed;
        left: var(--structure-gap-md);
        right: var(--structure-gap-md);
        top: auto;
        max-width: none;
    }
}

/* 390px: the name button may shrink (its text ellipsizes) so name + bell + the Mat / door buttons wrap cleanly in the header's action row. */
@media (max-width: 480px) {
    .bu-account[b-er9v0t5byg] {
        max-width: 100%;
    }

    .bu-account__item:first-child:not(:only-child)[b-er9v0t5byg] {
        flex: 0 0 auto;
    }

    .bu-account__name[b-er9v0t5byg] {
        max-width: calc(100vw - 2 * var(--structure-gap-md) - 5rem);
    }
}
/* /Components/Shared/PageNav.razor.rz.scp.css */
.bu-page-nav[b-vrhouwzams] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--structure-gap-sm);
    padding: var(--structure-gap-sm) var(--structure-gap-xl);
}

@media print {
    .bu-page-nav[b-vrhouwzams] {
        display: none !important;
    }
}
/* /Components/StudentStylesPanel.razor.rz.scp.css */
/* The drawer's Styles row is a block (heading, then one line per style), not the label/value pair of the other drawer fields. */
.cc-student-styles[b-96v4og2wro] { display: flex; flex-direction: column; align-items: stretch; gap: 0.5rem; }
.cc-student-styles__item[b-96v4og2wro] { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.25rem 0.75rem; }
/* #513: the row's buttons are one right-aligned group (a lone wrapped group stays at the right edge); the remove question takes the full row. */
.cc-student-styles__actions[b-96v4og2wro] { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-end; gap: var(--structure-gap-sm); margin-left: auto; }
.cc-student-styles__item > [data-testid="drawer-remove-ask"][b-96v4og2wro] { flex: 1 1 100%; }
/* /Components/Waivers/SignOnDeviceDialog.razor.rz.scp.css */
/* The signing text sits in its own scroll box so "read to the end" is a real, checkable thing. Tokens only. */
.bu-waiver-scroll[b-5ghikid21u] {
  max-height: min(45vh, 28rem); overflow-y: auto; padding: 0.75rem 1rem; margin: 0.5rem 0;
  border: 1px solid var(--theme-border-inactive); background: var(--theme-bg-surface, transparent);
}
.bu-waiver-scroll:focus-visible[b-5ghikid21u] { outline: 2px solid var(--theme-x-focus-ring, var(--theme-border-active)); outline-offset: 2px; }
.bu-waiver-controls[b-5ghikid21u] { border: 0; margin: 0; padding: 0; min-width: 0; }
.bu-waiver-controls[disabled][b-5ghikid21u] { opacity: 0.55; }
.bu-waiver-controls[b-5ghikid21u] { display: flex; flex-direction: column; gap: var(--structure-gap-md); }
.bu-waiver-controls legend[b-5ghikid21u] { padding: 0 0 var(--structure-gap-xs); color: var(--theme-text-main); font-weight: 600; }
/* /Components/Waivers/StudentWaiverPanel.razor.rz.scp.css */
/* Drawer section: tokens only. The history is a plain list; actions sit under each row, wrapped, on touch-sized buttons. */
.bu-waiver-history[b-to0t1szwx5] { list-style: none; margin: 0; padding: 0; }
.bu-waiver-history li[b-to0t1szwx5] { padding: 0.5rem 0; border-bottom: 1px solid var(--theme-border-inactive); }
.bu-waiver-history__actions[b-to0t1szwx5] { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.375rem; }
.bu-waiver-wrap[b-to0t1szwx5] { white-space: normal; max-width: 100%; text-align: left; }

/* #444: a waiver row is a title line (title left, badge right, wrapping as a group) with the paper note on its OWN full-width line below,
   never squeezed into a narrow right-hand column. */
.bu-waiver-row[b-to0t1szwx5] { flex-wrap: wrap; align-items: baseline; }
.bu-waiver-row__title[b-to0t1szwx5] { flex: 1 1 8rem; min-width: 0; overflow-wrap: anywhere; }
.bu-waiver-row__state[b-to0t1szwx5] { flex: 0 1 auto; display: flex; flex-wrap: wrap; gap: var(--structure-gap-xs); justify-content: flex-end; align-items: center; }
.bu-waiver-row > [data-testid="waiver-paper-note"][b-to0t1szwx5] { flex: 1 1 100%; overflow-wrap: anywhere; }
/* /Components/Waivers/WaiverBadge.razor.rz.scp.css */
/* A1 waiver chip. Tokens only (Primer greyscale base, skins restyle through --theme-*). The state colour is the border and icon;
   the words stay in the normal text colour so contrast holds in every skin, and the state is always spelled out (WCAG 1.4.1). */
.cc-waiver[b-1tn7763jzq] {
  --_w: var(--theme-border-inactive);
  display: inline-flex; align-items: center; gap: 0.25rem;
  min-height: 24px; padding: 0 0.5rem; font-size: 0.8125rem; font-weight: 600; white-space: nowrap;
  color: var(--theme-text-main, inherit);
  border: 1px solid var(--_w); border-radius: 999px;
}
.cc-waiver--ok[b-1tn7763jzq] { --_w: color-mix(in srgb, var(--theme-state-healthy, var(--theme-border-active)) 55%, var(--theme-text-main, currentColor)); }
.cc-waiver--watch[b-1tn7763jzq] { --_w: color-mix(in srgb, var(--theme-state-warning, var(--theme-border-active)) 55%, var(--theme-text-main, currentColor)); }
.cc-waiver--risk[b-1tn7763jzq] { --_w: color-mix(in srgb, var(--theme-state-error, var(--theme-border-active)) 55%, var(--theme-text-main, currentColor)); }
.cc-waiver__paper[b-1tn7763jzq] { font-weight: 500; opacity: 0.85; border-left: 1px solid var(--_w); padding-left: 0.375rem; }
/* #503 compact (roster row), corrected for REQ-WAIVER-006 AC-1: a distinct icon PLUS a short visible word per state (full words in the tooltip/aria-label);
   the word truncates with an ellipsis instead of wrapping, so the row stays one line. The "Paper" tag is hidden here (the drawer shows it). */
.cc-waiver--compact[b-1tn7763jzq] { padding: 0 0.375rem; max-width: 100%; min-width: 0; }
.cc-waiver--compact .cc-waiver__text[b-1tn7763jzq] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.cc-waiver--compact .cc-waiver__paper[b-1tn7763jzq] { display: none; }
/* /Components/Waivers/WaiverDocument.razor.rz.scp.css */
/* The rendered waiver text. The inner tags come from the Api as plain html (no scope attribute), so they are reached with ::deep. */
.bu-waiver-doc[b-msqweak9v4] { line-height: 1.5; overflow-wrap: anywhere; }
.bu-waiver-doc[b-msqweak9v4]  h2, .bu-waiver-doc[b-msqweak9v4]  h3, .bu-waiver-doc[b-msqweak9v4]  h4 { margin: 1rem 0 0.5rem; }
.bu-waiver-doc[b-msqweak9v4]  p { margin: 0 0 0.75rem; }
.bu-waiver-doc[b-msqweak9v4]  ul { margin: 0 0 0.75rem 1.25rem; padding: 0; }
.bu-waiver-doc[b-msqweak9v4]  hr { border: 0; border-top: 1px solid var(--theme-border-inactive); margin: 1rem 0; }
/* /Components/Waivers/WaiverEditor.razor.rz.scp.css */
/* Waiver editor: Primer structure with tokens only. The cards stack (wide desktop first); the text box is as tall as a page of text. */
.bu-waiver-banner[b-mg9yxx93fk] { border: 1px solid var(--theme-border-active, var(--theme-border-inactive)); padding: 0.5rem 0.75rem; font-weight: 600; }
/* #507: each waiver is its own bordered card, so two waivers never read as one run-on block. It is deliberately NOT a .bu-panel: the console skins flatten every
   .bu-panel inside an embedded page into a borderless section (render-executive-blue.css, ADM-EB-16/17b), which is what made the two waivers run together. */
.bu-waiver-card[b-mg9yxx93fk] { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: var(--structure-gap-md, 1rem); border: 1px solid var(--theme-border-inactive); padding: 1rem 1.25rem; }
.bu-waiver-card p[b-mg9yxx93fk] { margin: 0; }
.bu-waiver-counts button[b-mg9yxx93fk] { min-height: 44px; margin: 0 0 0 0.25rem; vertical-align: middle; }
.bu-waiver-unsigned[b-mg9yxx93fk] { border-top: 1px solid var(--theme-border-inactive); margin-top: 0.25rem; padding-top: 0.75rem; }
.bu-waiver-unsigned-list[b-mg9yxx93fk] { list-style: none; margin: 0; padding: 0; }
.bu-waiver-unsigned-list li[b-mg9yxx93fk] { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; padding: 0.5rem 0; border-bottom: 1px solid var(--theme-border-inactive); }
.bu-waiver-unsigned-name[b-mg9yxx93fk] { font-weight: 600; flex: 1 1 12rem; }
.bu-waiver-body[b-mg9yxx93fk] { width: 100%; min-height: 20rem; font-family: inherit; line-height: 1.45; resize: vertical; }
.bu-waiver-insert[b-mg9yxx93fk] { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.bu-waiver-insert select[b-mg9yxx93fk] { flex: 1 1 14rem; max-width: 24rem; }
.bu-waiver-settings[b-mg9yxx93fk] { border: 1px solid var(--theme-border-inactive); padding: 0.5rem 0.75rem; margin: 0.75rem 0; }
.bu-waiver-preview[b-mg9yxx93fk] { border: 1px solid var(--theme-border-inactive); padding: 0.75rem 1rem; margin: 0.75rem 0; max-height: 32rem; overflow-y: auto; background: var(--theme-bg-surface, transparent); }
.bu-waiver-publish[b-mg9yxx93fk] { border-top: 1px solid var(--theme-border-inactive); margin-top: 1rem; padding-top: 0.75rem; }
.bu-waiver-version-list[b-mg9yxx93fk] { list-style: none; margin: 0; padding: 0; }
.bu-waiver-version-list li[b-mg9yxx93fk] { padding: 0.5rem 0; border-bottom: 1px solid var(--theme-border-inactive); }
.bu-waiver-version-list button[b-mg9yxx93fk] { margin-left: 0.75rem; }
/* /Components/Waivers/WaiverPrintPage.razor.rz.scp.css */
.bu-waiver-toolbar[b-pv96au1bnb] { display: flex; gap: 0.75rem; align-items: center; padding: 1rem; }
.bu-waiver-sheet[b-pv96au1bnb] { max-width: 7.5in; margin: 0 auto; padding: 0 1rem 1rem; }
.bu-waiver-sheet__head h1[b-pv96au1bnb] { margin: 0 0 0.25rem; font-size: 1.5rem; overflow-wrap: anywhere; }
.bu-waiver-sheet__head p[b-pv96au1bnb] { margin: 0; }
.bu-waiver-sign[b-pv96au1bnb] { break-inside: avoid; page-break-inside: avoid; margin-top: 1.5rem; padding-top: 0.75rem; border-top: 2px solid currentColor; }
.bu-waiver-sign h2[b-pv96au1bnb] { margin: 0 0 0.75rem; font-size: 1.1rem; }
.bu-waiver-line[b-pv96au1bnb] { display: flex; align-items: flex-end; gap: 0.75rem; margin: 0 0 0.9rem; }
.bu-waiver-line--tall[b-pv96au1bnb] { margin-top: 1.5rem; margin-bottom: 1.1rem; }
.bu-waiver-k[b-pv96au1bnb] { flex: none; min-width: 11rem; font-weight: 600; }
.bu-waiver-blank[b-pv96au1bnb] { flex: 1 1 auto; border-bottom: 1px solid currentColor; min-height: 1.4rem; }
.bu-waiver-note[b-pv96au1bnb] { font-size: 0.85rem; }
.bu-waiver-footer[b-pv96au1bnb] { display: flex; align-items: center; gap: 0.75rem; max-width: 7.5in; margin: 1.5rem auto 0; padding: 0.5rem 1rem; border-top: 1px solid currentColor; font-size: 0.8rem; }
.bu-waiver-footer__qr[b-pv96au1bnb] { image-rendering: pixelated; width: 0.7in; height: 0.7in; }
/* On paper: the footer repeats at the bottom of EVERY page, the toolbar disappears, paragraphs do not split. */
@media print {
  .bu-waiver-toolbar[b-pv96au1bnb] { display: none; }
  /* #438: paper is black on white in EVERY skin (a skin's light-on-dark text colours must never reach the page or the PDF). */
  .bu-waiver-sheet[b-pv96au1bnb], .bu-waiver-sheet[b-pv96au1bnb]  *, .bu-waiver-footer[b-pv96au1bnb], .bu-waiver-footer *[b-pv96au1bnb] { color: #000 !important; background: transparent !important; text-shadow: none !important; box-shadow: none !important; }
  .bu-waiver-footer[b-pv96au1bnb] { position: fixed; left: 0; right: 0; bottom: 0; margin: 0; max-width: none; background: #fff !important; border-top: 1px solid #000; }
  .bu-waiver-sheet[b-pv96au1bnb]  p { break-inside: avoid; page-break-inside: avoid; }
}
