/* @cascade-order: 9 — do not reorder. Split 10/10 of the former
   monolithic style.css (see docs/ui-pattern-audit.md and ADR-0095-style-css-split-into-ten-contiguous-files).
   Originally a contiguous slice of style.css in @cascade-order. That
   ordering is still enforced (tests/unit/css-split-structure.test.js);
   byte-for-byte reconstruction is NOT enforced and must not be relied on
   — the split files have been edited independently since. Earlier headers
   cited tests/unit/css-split-equality.test.js, which does not exist.
   Contains: The waiver tab, quick references, group visits, event calendar, reduced-motion overrides, the camp check-in redesign + modals, cleaning schedule, website config admin, member logins, and the trailing V3 ports (schedule density, the class check-in card, the check-in popover).
   Original line range: 19142-21260. */
/* ============================================================================
   WAIVERS PAGE (ADR-0174 / 0175 / 0176): unlinked waivers, duplicates, one waiver
   --------------------------------------------------------------------------
   New pieces only, prefixed `wv-`. Rows are v3's `.camp-reg-row`, chips are
   `.state-chip`, the band is `.settings-subnav`, the field is `.attendance-search`.
   No one-sided coloured borders, no gradients, no pills (`--radius-sm`).
   ========================================================================== */

#tab-waivers > .settings-subnav { flex: none; }
.wv-page { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.wv-panel { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
#tab-waivers .attendance-toolbar > .wv-count { flex: none; }
#tab-waivers .waiver-status-detail { white-space: normal; }
.wv-count { font-size: var(--text-sm); color: var(--color-text-secondary); }
.wv-subnav-count {
  display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 18px; padding: 0 5px;
  margin-left: 6px; border-radius: var(--radius-sm); background: var(--color-bg-subtle);
  font-size: var(--text-xs); font-variant-numeric: tabular-nums; color: var(--color-text-secondary);
}
.settings-subnav-item.active .wv-subnav-count { background: var(--color-accent-tint); color: var(--color-accent); }
.wv-faint { color: var(--color-text-muted); font-size: var(--text-sm); }
.wv-title { font-weight: var(--font-medium); }
.wv-more { color: var(--color-text-muted); font-size: var(--text-sm); }
.wv-bad { color: var(--color-danger); }
.wv-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--text-sm); overflow-wrap: anywhere; }
.wv-req { font-weight: var(--font-normal); font-size: var(--text-xs); color: var(--color-text-muted); margin-left: 4px; }
.wv-danger { color: var(--color-danger); border-color: color-mix(in srgb, var(--color-danger) 40%, var(--color-border)); }
.wv-lead { margin: 0 0 var(--space-3); color: var(--color-text-secondary); }

/* The list: one column, rows are the two-line `.camp-reg-row`. */
.wv-list { background: var(--color-bg-elevated); border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; }
.wv-row { grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; }
.wv-row.is-click { cursor: pointer; }
.wv-row.is-click:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.wv-row .camp-reg-what .who { white-space: normal; }
.wv-row .what { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0 4px; white-space: normal; }
.wv-row-extra { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; min-width: 0; }
.wv-row-actions { align-items: center; justify-content: flex-end; }
/* On a row it is also `.row-actions` (rowActions()), whose display and gap are the design system's and used to come later. */
.wv-row-actions:where(:not(.row-actions)) { display: inline-flex; gap: 6px; }
.wv-more-row { display: flex; justify-content: center; padding: var(--space-2); }
.wv-list > .wv-more-row { border-top: 1px solid var(--color-border-subtle); }
.wv-open-btn .bi { color: var(--color-text-muted); }

/* One signed waiver, read-only: the shared record view (v3.css, ADR-0218) plus its own pieces. */
.wv-signature { font-family: 'Brush Script MT', 'Segoe Script', cursive; font-size: 30px; padding: 6px 0 2px; border-bottom: 1px solid var(--color-border); }
/* A drawn signature and initials are ink on paper: they keep a white backing in both themes, or dark ink vanishes in dark mode. */
.wv-signature-img { max-width: 100%; max-height: 120px; background: white; border-bottom: 1px solid var(--color-border); }
.wv-initials { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 0; }
.wv-initial-img { height: 32px; background: white; border: 1px solid var(--color-border); border-radius: var(--radius-sm); }
.record-card.wv-text { padding: 0; } /* (0,2,0): outranks v3.css's .record-card padding, which loads later */
.wv-text > summary { cursor: pointer; padding: 10px 14px; font-size: var(--text-md); }
.wv-text-body { padding: 0 14px 12px; }
.wv-text-h { margin: 10px 0 2px; font-size: var(--text-sm); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.wv-text-p { margin: 0; font-size: var(--text-sm); color: var(--color-text-secondary); line-height: 1.5; }
.wv-text-summary { margin: 4px 0 0; font-size: var(--text-xs); font-weight: var(--font-semibold); color: var(--color-text-secondary); }
.wv-note { font-size: var(--text-sm); color: var(--color-text-muted); }
.wv-note .bi { margin-right: 6px; }

/* The account search's confirm step (choosing the person is the shared `.choice`, ADR-0231). */
.wv-pick-note { margin-top: var(--space-2); padding: 8px 10px; border-radius: var(--radius-md); background: var(--color-info-tint); font-size: var(--text-sm); }
.wv-picked { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-2); padding: 8px 12px; border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-bg-subtle); }
.wv-picked-what { display: flex; flex-direction: column; min-width: 0; }
.wv-picked-what small { color: var(--color-text-muted); }

/* The people-covered rows give the name the room: it is the row's subject. */
.kv-row.wv-kv-people { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) auto; }
#wv-unlinked-q { text-overflow: ellipsis; }


/* The merge compare: one row per detail. A detail that differs is red, a detail that matches is one muted "Same". */
.wv-cmp { display: grid; gap: 6px 16px; align-items: baseline; font-size: var(--text-sm); }
.wv-cmp-head { padding-bottom: 4px; }
.wv-cmp-label { color: var(--color-text-muted); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .04em; }
.wv-cmp-same { grid-column: 2 / -1; color: var(--color-text-muted); }
.wv-cmp-same-cell { color: var(--color-text-muted); }
.wv-cmp-diff { color: var(--color-danger); font-weight: 600; overflow-wrap: anywhere; }
.wv-cmp-rule { grid-column: 1 / -1; height: 1px; background: var(--color-border); margin: 4px 0; }
.wv-cmp-holds { display: flex; flex-wrap: wrap; gap: 4px; }
/* The set compare marks every value against the other accounts (duplicate-set-view.js, ADR-0255): green has a twin, amber is a typo
   from one, red has none, a blank is muted and never red. A column left out of the merge dims and takes no part. */
.wv-cmp-match { color: var(--color-success); overflow-wrap: anywhere; }
.wv-cmp-match > .bi { margin-right: 2px; }
.wv-cmp-near { color: var(--color-paused); font-weight: 600; overflow-wrap: anywhere; }
.wv-cmp-missing { color: var(--color-text-muted); font-style: italic; }
.wv-cmp-age { color: var(--color-text-muted); font-weight: var(--font-normal); }
.wv-cmp-out { opacity: .45; }
.wv-cmp-out:is(.wv-cmp-match, .wv-cmp-near, .wv-cmp-diff) { color: var(--color-text-secondary); font-weight: var(--font-normal); }
.wv-cmp-out.wv-cmp-head { opacity: 1; }
.wv-verdict { margin-bottom: var(--space-4); }
.wv-verdict .wv-lead { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-bottom: var(--space-2); color: var(--color-text); }
.wv-verdict-chips { display: flex; flex-wrap: wrap; gap: 6px; }
@media (max-width: 520px) { .wv-cmp { gap: 6px 10px; } }

/* The family compare (one column per household) and the set compare (one column per account): the same grid, scrolling sideways when wide. */
.wv-fam-scroll { overflow-x: auto; max-width: 100%; }
.wv-cmp-fam, .wv-cmp-set { min-width: min-content; align-items: start; }
/* A column is as wide as its Keep / Merge / Leave out choice, a household's as an account's; a long value (an email)
   wraps inside its column, a column left out included, and never runs into the next one. */
.wv-cmp-fam, .wv-cmp-set { grid-template-columns: 96px repeat(var(--cols), minmax(200px, 1fr)); }
.wv-cmp-fam > div, .wv-cmp-set > div { min-width: 0; overflow-wrap: anywhere; }
.wv-cmp-chip { min-height: 22px; margin-bottom: 6px; }
.wv-cmp-tick { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: var(--text-xs); color: var(--color-text-secondary); cursor: pointer; }
.wv-fam-sub { margin-top: 4px; color: var(--color-text-muted); font-size: var(--text-xs); }
.wv-fam-swap { padding: 0; height: auto; }
.wv-fam-none { color: var(--color-text-muted); }
.wv-fam-name { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.wv-fam-small { font-size: var(--text-xs); color: var(--color-text-muted); }
.wv-fam-small.wv-bad { color: var(--color-danger); font-weight: 600; }
.wv-fam-block { margin-top: 4px; }
.wv-fam-tick { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: var(--text-xs); color: var(--color-danger); font-weight: 600; cursor: pointer; }
.wv-fam-result { margin: var(--space-3) 0 0; }
@media (max-width: 520px) { .wv-cmp-fam, .wv-cmp-set { grid-template-columns: 72px repeat(var(--cols), minmax(200px, 1fr)); } }
/* In a window the footnote is one sentence that wraps: the icon stays inline with its text. */
.modal-body .wv-footnote { display: block; margin-top: var(--space-3); }
.modal-body .wv-footnote > .bi:first-child { margin-right: 6px; }


/* ============================================================================
   WAIVER TAB ; Admin waiver management
   ============================================================================ */

/* --- Waiver Card (templates tab) --- */

.waiver-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-2);
  background: var(--color-bg-elevated);
  transition: border-color 0.15s;
}

.waiver-card:hover {
  border-color: var(--color-accent);
}

.waiver-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.waiver-card-name {
  font-weight: var(--font-semibold);
  font-size: var(--text-md);
}

.waiver-card-badges {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

.waiver-card-meta {
  display: flex;
  gap: var(--space-3);
  font-size: var(--text-base);
  color: var(--color-text-muted);
  flex-wrap: wrap;
}

/* Waiver detail modal */
.waiver-detail .detail-section {
  margin-bottom: 20px;
}

.waiver-detail .detail-section h4 {
  font-size: var(--text-md);
  font-weight: var(--font-bold);
  margin: 0 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text);
}

.waiver-detail .detail-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 4px 0;
  gap: 12px;
}

.waiver-detail .detail-label {
  font-weight: var(--font-semibold);
  font-size: var(--text-base);
  color: var(--color-text-muted);
  min-width: 120px;
  flex-shrink: 0;
}

.waiver-detail .detail-value {
  font-size: var(--text-base);
  color: var(--color-text);
  text-align: right;
}

.linked-account-card {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px 10px;
  background: var(--color-bg-subtle);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.linked-account-name {
  font-weight: var(--font-semibold);
  margin-bottom: var(--space-1);
  font-size: var(--text-base);
  color: var(--color-text);
}

.linked-account-details {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* SmartWaiver Detail View */
.sw-detail-waiver {
  margin-bottom: var(--space-6);
}
.sw-detail-waiver:last-child {
  margin-bottom: 0;
}

.sw-detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-subtle);
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-4);
  gap: var(--space-3);
  flex-wrap: wrap;
}
.sw-detail-header-dates {
  display: flex;
  gap: var(--space-5);
  flex-wrap: wrap;
}
.sw-detail-header-date {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sw-detail-header-date .label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--font-semibold);
}
.sw-detail-header-date .value {
  font-size: var(--text-md);
  font-weight: var(--font-semibold);
  color: var(--color-text);
}
.sw-detail-header-id {
  font-family: monospace;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-align: right;
}

.sw-participant-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-3);
  overflow: hidden;
}
.sw-participant-card:last-child {
  margin-bottom: 0;
}
.sw-participant-name {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-subtle);
  border-bottom: 1px solid var(--color-border-subtle);
}
.sw-participant-name .name {
  font-size: var(--text-lg);
  font-weight: var(--font-bold);
  color: var(--color-text);
}
.sw-participant-name .age {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-weight: var(--font-normal);
}
.sw-participant-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
}
.sw-participant-field {
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--color-border-subtle);
}
.sw-participant-field:nth-last-child(-n+2) {
  border-bottom: none;
}
.sw-participant-field.full-width {
  grid-column: 1 / -1;
}
.sw-participant-field .label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--font-semibold);
  margin-bottom: 1px;
}
.sw-participant-field .value {
  font-size: var(--text-base);
  color: var(--color-text);
  line-height: 1.4;
}

.sw-detail-section-title {
  font-size: var(--text-sm);
  font-weight: var(--font-bold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: var(--space-5) 0 var(--space-3);
}
.sw-detail-section-title:first-child {
  margin-top: 0;
}

/* Nav chrome (.sw-tab-nav / .sw-tab) now reuses the shared .settings-subnav
   / .settings-subnav-item component's .tray modifier — see
   10-forms-account-settings.css. .sw-tab-panel (below) is unrelated content
   wrapping and stays. */

@media (max-width: 600px) {
  .sw-participant-body {
    grid-template-columns: 1fr;
  }
  .sw-participant-field:nth-last-child(-n+2) {
    border-bottom: 1px solid var(--color-border-subtle);
  }
  .sw-participant-field:last-child {
    border-bottom: none;
  }
  .sw-detail-header {
    flex-direction: column;
    align-items: flex-start;
  }
  .sw-detail-header-id {
    text-align: left;
  }
}

/* ==========================================================================
   GROUP VISITS
   ========================================================================== */

.gv-section-count {
  font-weight: normal;
}

/* ==========================================================================
   EVENT CALENDAR (Events tab ; month grid view, 2-column layout)
   ========================================================================== */

.cal-layout {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: var(--space-4);
  align-items: start;
}

.cal-side {
  position: sticky;
  top: var(--page-pin-h);
  align-self: start;
}

.cal-pane {
  min-width: 0; /* let event cards shrink instead of overflowing the row */
}

.cal-month-nav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}

.cal-month-label {
  font-weight: 600;
  font-size: var(--text-sm);
  flex: 1;
  text-align: center;
}

.cal-today-btn {
  margin-left: auto;
}

.cal-grid {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-border);
}

.cal-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--color-border);
}

.cal-weekday-row {
  background: var(--color-bg-subtle);
}

.cal-weekday {
  padding: 4px 2px;
  text-align: center;
  font-size: 0.7143rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--color-text-secondary);
  text-transform: uppercase;
  background: var(--color-bg-subtle);
}

.cal-cell {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  justify-items: center;
  align-items: start;
  min-height: 44px;
  padding: 4px 2px 3px;
  background: var(--color-bg-elevated);
  color: var(--color-text);
  border: none;
  cursor: pointer;
  transition: background 100ms ease;
  font-family: inherit;
}

.cal-cell:hover:not(.is-selected) {
  background: var(--color-bg-subtle);
}

[data-theme="dark"] .cal-cell:hover:not(.is-selected) {
  background: var(--color-bg-muted);
}

.cal-cell.is-other-month {
  background: var(--color-bg-subtle);
  color: var(--color-text-muted);
}

.cal-cell.is-today .cal-cell-day {
  color: var(--color-accent);
  font-weight: 700;
}

.cal-cell.is-selected {
  background: var(--color-accent);
  color: #fff;
}

.cal-cell.is-selected .cal-cell-day {
  color: #fff;
}

.cal-cell.is-selected .cal-cell-count {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.cal-cell-day {
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1;
}

.cal-cell-count {
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 14px;
  padding: 0 5px;
  border-radius: 4px;
  background: var(--color-accent);
  color: #fff;
  font-size: 0.7143rem;
  font-weight: 600;
  line-height: 1;
}

.cal-cell.is-other-month .cal-cell-count {
  background: var(--color-text-muted);
}

@media (max-width: 600px) {
  .cal-layout {
    grid-template-columns: 1fr;
  }
  .cal-side {
    position: static;
  }
  .cal-cell {
    min-height: 48px;
  }
}

/* ==========================================================================
   GROUP EVENTS (ADR-0177): the list, the calendar's rows and the event page.
   ----------------------------------------------------------------------------
   Ported from the approved mockup's `wk-` rules for the events page, prefixed
   `.ge-`, over the app's own components: the two-line row (`.camp-reg-row`),
   the roster row (`.attendance-row.is-roster`), `.state-chip`, `.info-bar`,
   `.settings-callout`, `.attendance-toolbar`, the `.cal-*` family above and the
   `.gv-*` progress / section classes. Only what those do not already say lives
   here. Tokens are `v3.css :root`'s. No one-sided accent borders, no gradients,
   no pills (`--radius-sm` / `--radius-md` only).
   ========================================================================== */

/* The tab is a column that scrolls and its body must not shrink (the Settings
   frame's rule): a long roster scrolls the tab, the header stays whole. */
#tab-events > .page-body {
  display: flex;
  flex-direction: column;
}
#tab-events > .class-checkin-header {
  flex: none;
}

.ge-page {
  gap: var(--space-3);
  min-width: 0;
}
.ge-count {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.ge-faint {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
.ge-danger-text {
  color: var(--color-danger);
}
.ge-back {
  flex: none;
}

/* ── the list: days, and a row per event ─────────────────────────────────── */
.ge-days {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.ge-day {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ge-day-head {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ge-day-head.is-today {
  color: var(--color-accent);
}
.ge-list {
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.ge-row {
  grid-template-columns: minmax(0, 1fr) auto auto;
}
.ge-row.ge-click {
  cursor: pointer;
}
.ge-row.ge-click:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.ge-row.is-muted {
  opacity: 0.6;
}
.ge-row .camp-reg-what .who {
  white-space: normal;
}
.ge-row-extra {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  min-width: 0;
}
.ge-row-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ge-chev {
  color: var(--color-text-muted);
  font-size: 12px;
}
.ge-phrase {
  font-size: var(--text-md);
  white-space: nowrap;
}
.ge-more-row {
  display: flex;
  justify-content: center;
  padding: var(--space-2);
}

/* ── the event page ──────────────────────────────────────────────────────── */
/* The list beside the Booking and Share cards (v3.css `.side-layout`), a little
   wider than its default and with a narrower label column (the longest label is
   "Booked by") so an email address fits on one line. */
.ge-layout {
  --side-w: 300px;
  --kv-k-w: 72px;
}
.kv-row .ge-meta-input {
  height: 26px;
  padding: 0 6px;
}
.kv-row .ge-expected-input {
  justify-self: start;
  width: 4.2em;
  height: 26px;
  padding: 0 6px;
  font-variant-numeric: tabular-nums;
}
.ge-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 14px;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.ge-card-title {
  margin: 0 0 4px;
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-secondary);
}
.ge-roster {
  padding: 0;
  gap: 0;
  overflow: visible;
}
/* A toolbar that tops a bordered card keeps its own inset: the general
   `.page-body .attendance-toolbar` rule drops side padding so a free-standing
   band lines up with the list under it, which here put the Add field and the
   buttons against the card's edges. */
.page-body .ge-card > .ge-roster-bar,
.ge-roster-bar {
  flex-wrap: wrap;
  row-gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-border);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.ge-add {
  position: relative;
  flex: 1 1 260px;
  min-width: 0;
  display: flex;
}
.ge-roster-wrap {
  min-height: 0;
}
.ge-roster .ge-roster-list :is(.ge-guest, .ge-checkin) {
  padding: 6px 12px;
}
.ge-side {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.ge-share {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 0;
}
.ge-share + .ge-share {
  border-top: 1px solid var(--color-border-subtle);
}
.ge-share-head {
  display: flex;
  flex-direction: column;
}
.ge-share-foot {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* ── windows: paste, match, print preview ────────────────────────────────── */
.ge-modal-lead {
  margin: 0 0 var(--space-3);
  color: var(--color-text-secondary);
}
.ge-picked {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-2);
  padding: 8px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-subtle);
}
.ge-picked[hidden] {
  display: none;
}
.ge-pick-note {
  margin-top: var(--space-2);
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: var(--color-info-tint);
  font-size: var(--text-sm);
}
.ge-pick-note[hidden] {
  display: none;
}
/* The second door of the unmatched guest's Check in window: the event's waiver
   on this device. A tinted block, the sentence then the button. */
.ge-new-visitor {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: var(--color-bg-subtle);
}
.print-sheet {
  max-height: 60vh;
  overflow: auto;
  padding: 18px 20px;
  background: #fff;
  color: #111;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.print-sheet-title {
  font-size: 18px;
  font-weight: 700;
}
.print-sheet-sub {
  margin-bottom: 10px;
  font-size: 12px;
  color: #555;
}
.print-sheet-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.print-sheet-table th {
  padding: 4px 6px;
  border-bottom: 2px solid #111;
  font-size: 10px;
  letter-spacing: 0.05em;
  text-align: left;
  text-transform: uppercase;
}
.print-sheet-table td {
  padding: 5px 6px;
  border-bottom: 1px solid #ddd;
}
.print-sheet-note {
  margin-top: 10px;
  font-size: 11px;
  color: #555;
}

/* ============================================================================
   PER-DAY CLASS CANCELLATIONS (staff-internal)
   Visual treatment applied to every schedule surface (left-sidebar items,
   main day-schedule cards, mobile schedule sheet, class-checkin header)
   when a class has a `classCancellationsForDay` doc for the viewed date.
   Uses existing warning tokens; no decorative border accents.
   The shared `.*-cancelled-pill` rule below covers every inline pill so
   they stay visually identical across surfaces.
   ============================================================================ */

/* The pill inside the class-checkin banner (app-shell.html's `.cc-notice.warn`
   + `.cc-cancelled-pill`) — NOT a header ornament. This used to be a second,
   standalone pill sitting next to the class name, duplicating the banner's
   job with its own colours; the banner is the one place the design puts a
   "cancelled" marker, so the header copy was deleted. Values match
   base.css's `.cc-cancelled-pill` exactly. */

/* Camp schedule card's own reason note (a different component — the all-day
   card, not the class-checkin header). */
/* `.class-card-cancelled-meta` was here and is DELETED with the rest of the
   day-schedule card (ADR-0132). `renderDaySchedule` was its only emitter, and it
   had already stopped writing one — the `cancelledMeta` local it interpolated
   was hard-coded to `''` above the template. */

/* Shared "Cancelled"/"Ending" label. On the sidebar item and the
   universal-search popover it replaces the age line.
   Subtle: just the word in warning color, no background or tint. */
.class-item-cancelled-label {
  color: var(--color-warning);
  font-weight: 600;
}

/* `.schedule-class-card.cancelled-today` and its two descendants were here and
   are DELETED (ADR-0132): their only emitter was `app.js`'s `renderDaySchedule`,
   which could never paint — its `#day-schedule` container has never existed in
   any tracked revision of index.html. The live sidebar item's cancelled
   treatment is `.class-item-cancelled-label` above; the class-checkin header's
   is `.class-checkin-header.is-cancelled-today` below. */

/* ---- Class check-in header (inline pill + strikethrough; NO new row) ---- */
.class-checkin-header.is-cancelled-today .class-header-name {
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  opacity: 0.7;
}

/* The Cancel / Restore item's tone lives with the rest of the overflow menu's
   tones in v3.css now: ONE `.overflow-menu-item-warning` modifier, toggled by
   the state. `-cancel` / `-restore` were a second naming of the same idea and
   both lost to `.overflow-menu-item.danger` anyway, so Cancel AND Restore both
   rendered amber (census §A1). */

/* Camp check-in schedule card uses .class-item-count directly — no custom badge CSS needed. */

/* ==========================================================================
   CAMP CHECK-IN REDESIGN — operational day check-in surface
   All overrides of shared selectors (.stat-item, .row-time,
   .attendance-row) are scoped to #tab-camp-checkin so the class/event
   check-in pages that share those selectors are unaffected.
   ========================================================================== */

/* --- Header stats: reuse the app's bordered .stat-item card; only add the
       clickable filter affordance + semantic tone colors (no custom look). --- */
#tab-camp-checkin .stat-item.clickable { cursor: pointer; transition: border-color 0.12s, background 0.12s; }
#tab-camp-checkin .stat-item.clickable:hover { border-color: var(--color-camp); }
#tab-camp-checkin .stat-item.is-active {
  border-color: var(--color-camp);
  background: color-mix(in srgb, var(--color-camp) 8%, var(--color-bg-elevated));
}
#tab-camp-checkin .stat-item .stat-value.warn { color: var(--color-warning); }
#tab-camp-checkin .stat-item .stat-value.danger { color: var(--color-danger); }

/* --- Toolbar --- */
/* `.search-wrap` / `.search-icon-el` removed — dead the moment the toolbar
   rewrite (this port) replaced that markup with `.attendance-search`, the
   shared field object. Same orphan in v3.css's own `.camp-toolbar
   .search-wrap` (crosswalked from `.cc-bar .search-wrap`, itself never
   rendered once the field changed) — removed there too. */
/* Unified Clear button: hidden via [hidden] (override .filter-chip's display) */

/* Brown camp button variant (shares the .btn base; only color changes) */

/* The camp's two day-state banners ARE B Notice — `.class-checkin-banner.warn`,
   the same component the class page uses — so the bespoke `.camp-lock-banner` /
   `.camp-day-warning` box is gone rather than kept alongside it. It was a
   rounded bordered card with `margin: 8px 0 0`: no horizontal margin, so its
   border ran flush into both edges of the flush V3 card and the text had no
   side inset at all. Those rules were pre-V3 production CSS that the handoff
   bundle re-absorbed verbatim, not a design decision. */

/* A locked day dims + disables the presence actions (the server rules reject
   them anyway; this is the visible affordance). */

/* A completed CAMP is frozen history — readable, never writable. On top of the
   day-lock dimming, the remaining write affordances in the toolbar go too
   (roll call writes the day-meta doc). Print + filters stay live: reviewing a
   past week is the whole reason the card is still on the schedule. */

/* Completed camp on the sidebar schedule: same minimal treatment as a
   cancelled class — a muted status label in the detail lines, no tint. */

/* Manage-groups modal rows (A6) */
.camp-group-manage-list { display: flex; flex-direction: column; gap: 8px; }
.camp-group-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--color-border);
  border-radius: var(--radius-md); background: var(--color-bg-subtle);
}
.camp-group-row-name { font-size: 0.9286rem; font-weight: 500; }

/* Present-column count badge (brown pill) */

/* --- Rows: both columns reuse the app .attendance-row + .row-main component.
       Camp stacks the name above the time/medical line (column layout). --- */
/* Zero the card-body padding so section/family bands span the full card width
   AND sit flush to the top (no exposed card-body padding gap above the first
   group). Rows and headers supply their own padding. */
/* Scoped to .row-main, not the whole row: opacity on an ancestor still
   composites a position:fixed descendant translucently even though the
   fixed element's own viewport position is unaffected (verified — the
   coordinates are correct, only the paint is blended) — the 3-dot menu
   (.member-overflow-menu, position:fixed) rendered unreadable and its
   buttons became hard to hit reliably. Actions (View, the 3-dot menu) stay
   at full opacity/clickability; only the name/time/badges dim. */

/* Camp row/header flag-pill family — a flag, not the note itself (full text
   is a hover title + the View popover). All four share one shape; only the
   color, icon, and label differ. The family-header aggregate flag reuses
   .roster-item-medical directly (same pill, same meaning) rather than a
   separate class. line-height:1 matters here: without it the pill inherits
   .row-name's/.camp-family-header's line-height, which gives the icon and
   text mismatched line-boxes to center within and makes the icon look
   off-center next to the text (same fix .status-icon already uses
   elsewhere). text-transform reset matters for the family-header instance,
   which sits inside .camp-family-header's uppercase styling. */

/* --- Section subtitles (Late Pickup / Checked Out / No-Show): tinted full-width
       bands, matching the family band treatment. --- */

/* --- Family cluster header: blue band (full-width background). --- */
[data-theme="dark"] #tab-camp-checkin .camp-family-header {
  background: color-mix(in srgb, var(--color-classes) 15%, var(--color-bg-elevated));
  color: color-mix(in srgb, var(--color-classes) 55%, #fff);
}
#tab-camp-checkin .camp-family-icon {
; border-radius: 3px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
}

/* Family member rows: subtle blue tint + slight indent (full-width). */

/* ==========================================================================
   CAMP CHECK-IN MODALS — checkout alert panels + roll-call counter
   ========================================================================== */
.alert-panel {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px; margin-bottom: 12px;
  border-radius: var(--radius-md); font-size: 0.9286rem;
}
.alert-panel.danger { background: color-mix(in srgb, var(--color-danger) 8%, transparent); border: 1px solid color-mix(in srgb, var(--color-danger) 20%, transparent); }
.alert-panel.warning { background: color-mix(in srgb, var(--color-warning) 8%, transparent); border: 1px solid color-mix(in srgb, var(--color-warning) 20%, transparent); }
.alert-panel.success { background: color-mix(in srgb, var(--color-success) 8%, transparent); border: 1px solid color-mix(in srgb, var(--color-success) 20%, transparent); }
.alert-icon { font-size: 1.2857rem; flex-shrink: 0; }
.alert-icon.danger { color: var(--color-danger); }
.alert-icon.warning { color: var(--color-warning); }
.alert-icon.success { color: var(--color-success); }
.alert-body { flex: 1; }
.alert-body strong { display: block; font-size: 0.9286rem; font-weight: 600; }
.alert-body small { font-size: 0.7857rem; color: var(--color-text-secondary); }
.alert-amount { font-size: 1.2143rem; font-weight: 700; }
.alert-amount.danger { color: var(--color-danger); }
.alert-amount.warning { color: var(--color-warning); }
.alert-amount.success { color: var(--color-success); }
.checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 0.9286rem; cursor: pointer; margin-top: 4px; }
.checkbox-row input { width: 15px; height: 15px; accent-color: var(--color-camp); cursor: pointer; }

.rc-hdr { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.rc-time { font-size: 0.7857rem; color: var(--color-text-muted); }
.rc-count { font-size: 2.1429rem; font-weight: 700; text-align: center; color: var(--color-camp); line-height: 1; }
.rc-sublabel { font-size: 0.8571rem; color: var(--color-text-muted); text-align: center; margin: 3px 0 12px; }
.rc-progress { height: 4px; background: var(--color-bg-subtle); border-radius: var(--radius-full); margin-bottom: 14px; overflow: hidden; }
.rc-progress-bar { height: 100%; background: var(--color-camp); border-radius: var(--radius-full); transition: width 0.3s; }
.rc-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--color-border-subtle); }
.rc-name { flex: 1; font-size: 0.9286rem; font-weight: 500; }
.rc-name.counted { color: var(--color-text-muted); }
.rc-toggle {
  width: 30px; height: 30px; border-radius: var(--radius-full);
  border: 2px solid var(--color-border); background: transparent;
  color: var(--color-text-muted); display: inline-flex;
  align-items: center; justify-content: center; font-size: 1rem; transition: all 0.15s; flex-shrink: 0;
}
.rc-toggle:hover { border-color: var(--color-camp); color: var(--color-camp); }
.rc-toggle.counted { background: var(--color-success); border-color: var(--color-success); color: #fff; }
.rc-list { max-height: 50vh; overflow-y: auto; }

/* The camp header holds the day-navigation strip; right-align it (like the
   original overview strip) and let it shrink + scroll within the header. */

/* ============================================================================
   CLEANING SCHEDULE
   The read-only views of the cleaning schedule: the weekly sheet and the
   by-room checklist on Quick References (and in print). The editor is the
   Cleaning rota page in 20-settings-design-system.css. Reuses design tokens;
   whole borders + subtle tints only (no side-strip accents, no gradients).
   ============================================================================ */

/* The cleaning schedule reuses the class-schedule WYSIWYG sheet (.sheet, styled
   in print-schedule-sheet.css) with two shift rows per day. This block only
   provides the sized wrapper. */

/* Sized container so the .sheet's container-query (cqh/cqi) units compute.
   Caps at the print canvas (11in landscape) like .schedule-admin-wrap. */
.clean-sheet-wrap {
  width: 100%;
  max-width: 1100px;
  aspect-ratio: 11 / 8.5;
  min-height: 460px;
  margin: 0 auto;
  background: var(--color-bg-elevated);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* --- Bottom "By Section / Room" checklist (view + print) --- */
.clean-rooms { margin-top: var(--space-6); }
.clean-rooms-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.clean-rooms-title { font-size: var(--text-lg); font-weight: var(--font-bold); margin: 0; }
.clean-rooms-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-3); }
.clean-room {
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
}
.clean-room-name { font-size: var(--text-md); font-weight: var(--font-bold); margin: 0 0 var(--space-2); }
.clean-room-tasks { list-style: disc; padding-left: var(--space-5); margin: 0; display: flex; flex-direction: column; gap: 2px; }
.clean-room-task { font-size: var(--text-sm); }

/* Sign-in access (Account & Family tab) — a directional flow: each app login
   (email) is assigned to this account. Inline, no modal. Reuses the app card +
   button system. */

/* In-account App access strip — READ-ONLY. Logins that can open this account,
   plus one "Manage logins →" door into the Member Logins tab. */
.ml-strip { display: flex; flex-direction: column; gap: var(--space-3, 12px); align-items: flex-start; }
.ml-strip-label { font-size: var(--text-sm, 0.8125rem); color: var(--color-text-secondary, #5c5852); margin: 0; }
.ml-strip-empty { font-size: var(--text-sm, 0.8125rem); color: var(--color-text-muted, #8a877f); margin: 0; }
.ml-strip-list { list-style: none; margin: 0; padding: 0; width: 100%; }
.ml-strip-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2, 8px);
  padding: 6px 0; border-bottom: 1px solid var(--color-border-subtle, #e8e5df);
}
.ml-strip-email { font-weight: var(--font-medium, 500); word-break: break-word; }

/* ==========================================================================
   SCHEDULE DENSITY — V3 (design-system/schedule-sidebar.html)

   Nothing here. The whole density system -- `.past`, `.next-slot`,
   `.mini.is-live`, `.schedule-time-label`, `.class-item-slot-time` -- is
   authored in v3.css, and renderSchedulePanel now emits those class names
   directly. This file used to carry a byte-equivalent second copy under
   group-descendant selectors (`.schedule-time-group.future .schedule-class-item`
   and friends) plus local names for two components the design already named.
   Two owners of one appearance is exactly what the design doctrine forbids:
   look is defined once, and pages override PLACEMENT only.

   One intentional divergence is below, and it is not a look: which ELEMENT
   owns a gap the design expresses through a sibling combinator production's
   DOM can't reach. (The one-line row's shrink ratios live in v3.css with the
   rest of `.mini`, ADR-0239.)
   ========================================================================== */

/* THE SEPARATOR OWNS ITS OWN GAP — the label can't reach back for it.

   base.css puts the space below the all-day divider on the LABEL, not the
   rule: `.schedule-time-label` defaults to `padding-top: space-3`, and
   `.schedule-allday-end + .schedule-time-label` drops that to `space-1` --
   "the divider's own top margin already supplies the gap [above it], so the
   label drops to space-1". A THIRD rule, `.schedule-list > .schedule-time-
   label:first-child { padding-top: 0 }`, is what actually governs the visible
   result, because in the design's own markup the divider and the label are
   siblings in one flat list, so the label after it is also that list's first
   child — both selectors describe the same element and `:first-child` (written
   later) wins outright, zeroing the padding the sibling rule had only reduced.

   Production's DOM is not flat: `.schedule-allday-end` sits in `.schedule-
   scroll`, one level above `#schedule-class-list`, which is the dynamic list's
   OWN container (index.html: "the design's container and its ONLY owner").
   The adjacent-sibling combinator can never cross that boundary, so it never
   fires here -- but `:first-child` still does, because "Earlier" genuinely is
   the list's first child regardless of what precedes the container. The
   result: zero padding with no reduced padding to fall back to. Measured
   `padding: 0px 2px 4px` on "Earlier", 4px of gap total where the design reads
   as roughly space-1 (4px) BELOW a divider that itself carries visible weight
   above it -- the divider read as sitting directly on the label.

   Chasing this by fixing the label's selector answers to production's DOM
   structure would be another read of the same brittle mechanism: the design
   expresses "the gap after the divider" as a property of whatever happens to
   follow it, which only worked in the specimen's flat markup. The robust
   version puts the gap where the divider itself always is, whether or not the
   next element is reachable by a combinator: a bottom margin on the divider,
   sized to the same `--space-1` the design's reduced case names, and the list
   keeps zeroing its first child's own padding since the divider now supplies
   the space instead. Report to the designer -- production's nested scroll
   container is why this needs restating as the separator's own rule.

   `.app-container.shell .schedule-sidebar .schedule-allday-end` — matching (and
   one class past) v3.css:1493's own selector, which sets the shell's inset via
   the `margin` SHORTHAND (all four sides, bottom included) and would otherwise
   win regardless: v3.css loads after this file, and a bare `.schedule-allday-
   end` here ties it on specificity, which load order then decides against us. */
.app-container.shell .schedule-sidebar .schedule-allday-end {
  margin-bottom: var(--space-1);
}

/* Card-LEVEL actions only (export, overflow). Row actions never appear here. */

/* Chips wrap to a second line and the row grows; it never scrolls sideways
   and never truncates a filter. min-height keeps the resting state the same
   height as the filtered one, so the table below does not move under the
   cursor when a chip appears. */

/* An applied filter reads as a fact with a way out: key, value, and the x
   that drops it. */

/* ==========================================================================
   CLASS CHECK-IN CARD (cc-*) — V3, ported verbatim from base.css
   design-reference/design-system/base.css "PAGE CARD COMPONENTS".

   Component appearance is defined HERE and only here. Pages may override
   PLACEMENT (position, margins, grid areas) — never appearance.
   Insets: card-level bands (header, field bar, notices) 16px; pane
   internals (pane heads, rows) 14px.
   --class-color falls back to NEUTRAL: absence of colour is the signal
   that nothing is scoped.
   ========================================================================== */
/* Coach chip — LOCKED borderless treatment (app-shell + Universal Search
   Results agree; class-checkin's bordered pill lost the audit). */
/* Scoped check-in field. The label names the action, not the mechanism. */
/* `.search-clear` moved to v3.css, beside the field it sits in (ADR-0128).
   It was never this file's: it landed here when ADR-0095 split `style.css`,
   which left the app's one clear button declared in the misc-ports file while
   v3.css carried a comment saying `style.css` owned it. */
/* Panes + rows (14px internal inset). Flush by default — a single list has no
   2nd-level card AND runs full-width, edge to edge, exactly like Universal
   Search Results / Recent Accounts (H1: "rows sit flush in the main card, no
   inner card"). The 14px gutter and the bordered/bg card only appear when a
   pane sits beside another one in a dual list (H2: "two adjacent lists need a
   boundary a single list doesn't"). */
/* a settings value is not a pass: pass-badge colors are locked to categories */
/* Empty pane state */
/* Notices: cancelled class, past date, locked, viewer (band inset 16px;
   pages with a bleed gutter override the LEFT inset only) */
/* Square corners per the system rule "no pill radius"; overturned from
   radius-full at audit sign-off (2026-08-18). */
/* Search dropdown (L3: shadow allowed) */
/* Overflow menus (L3). Floating by default; a spec page showing one inline
   overrides position/display locally — placement only. */
/* No-account banner + next steps (search results with zero matches).
   `.search-no-account-banner` itself is NOT redefined here — this was a
   pre-V3 leftover (rounded card, full border, `margin:14px`) that out-aged
   the crosswalked flush-banner rule (v3.css, from `.cc-no-account`) sitting
   right above this block in this same file. Same specificity, same file:
   source order made THIS one win for every property v3.css doesn't also
   touch — which is exactly `margin`, so the banner carried a stray 14px gap
   on all sides that the design's flush, border-bottom-only treatment never
   had. The title/next-steps/hint below are a real elaboration on the
   design's single-line specimen, not part of that collision — untouched. */
/* Universal search band scope label */

/* --------------------------------------------------------------------------
   Class check-in rows inside a cc-pane. The pane owns the 14px inset, so the
   rows carry vertical padding only and their divider is the lighter
   --color-border-subtle: a long list needs a rule that separates without
   ruling.
   -------------------------------------------------------------------------- */
/* .attendance-row is deliberately NOT in this list: the design makes it a
   4-column grid (v3.css:1168) -- name | badges | time | 26px overflow -- and
   app.js's row builder returns exactly those four as DIRECT children because
   of it. This panel-scoped selector out-specifies the bare one, so it was
   silently turning the grid back into a flex row and the columns went ragged
   down the list instead of aligning. .suggestion-row IS flex in the design
   (v3.css:1040), so it stays; .roster-row no longer renders anywhere on this
   panel (the class-checkin roster PANEL was removed -- the field's own
   suggestions are the roster now), so it was dropped from here too. */
.class-checkin-panel .suggestion-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 14px;
  border-bottom: 1px solid var(--color-border-subtle);
  transition: background 0.15s ease;
}

.class-checkin-panel .attendance-row:hover {
  background: var(--hover-row);
}

.class-checkin-panel .attendance-row .member-overflow {
  margin-left: auto;
}

/* `.class-checkin-panel .attendance-row .row-actions` was a scoped copy of the
   slot's own declaration and is deleted with ADR-0130: `.row-actions` is
   declared once in v3.css, and the roster row's wider gap rides
   `.attendance-row.is-roster .row-actions` there. */

.class-checkin-panel .row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.class-checkin-panel .row-name {
  font-weight: var(--font-normal);
}

.class-checkin-panel .row-time {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* The empty state is a pane-internal, so it takes the pane inset too. */

/* The padding is the pane inset only for a plain empty state: `.fill` and `.panel` own their padding. */
.class-checkin-panel .empty-state:where(:not(.fill, .panel)) {
  padding: var(--space-6) 14px;
}
.class-checkin-panel .empty-state {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* ==========================================================================
   CHECK-IN POPOVER (.mini-schedule-popup)

   Fifty-two rules used to sit here, "ported verbatim from base.css". They were
   byte-identical to v3.css's, checked line by line — a second owner of a whole
   component that could only ever drift. v3.css owns the popover; what remains
   below is the ONE thing that is genuinely ours.
   ========================================================================== */

/* The design's destination row is a <div>, so its rule declares no background,
   no border and no text-align -- it never needed to. Ours is a <button>, for
   the keyboard and the semantics, which means the UA's ButtonFace grey, a 2px
   outset bevel and centred text arrive underneath. Reset them here: the row
   must be a flat, left-aligned surface so the .next / .in / .dim tints are the
   only fill it has. */
.mini-schedule-popup .mini-schedule-item {
  background: none;
  border: 0;
  text-align: left;
  font-family: inherit;
  appearance: none;
  -webkit-appearance: none;
}

/* ============================================================================
 * Stock (ADR-0290): the list across the page, its categories as columns when
 * the page has the room, under the All / To buy chips; how to count alone at
 * the side (design-system.css `.side-layout`, where a page keeps its "Needs a
 * look" box).
 * ========================================================================== */

#tab-stock .side-layout { --side-w: 320px; }
#tab-stock .stock-views { margin-bottom: var(--space-3); }

/* An item's level tag sits in a slot as wide as the widest tag (Soon), centred, so the tags of a list make one straight
   column beside the numbers whatever they say, and an OK row keeps the same empty slot. */
#tab-stock .stock-level { display: inline-flex; align-items: center; justify-content: center; width: 4.25rem; }

/* Where the side drops under the list (an iPad, the Fold), how to count comes first: it is read before counting. */
@media (max-width: 1100px) {
  #tab-stock .side-layout > aside { order: -1; }
}

#tab-stock .stock-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: var(--space-5) var(--space-4);
  align-items: start;
}

/* The grid's gap spaces the sections; the stacked sections' own margin would push every column after the first down. */
#tab-stock .stock-columns > .titled-section { margin-top: 0; }

/* Settings > Stock items: each category a table with the same columns, so the limits line up from one table to the
   next; a row is one target (it opens the item's window). */
.stock-items-table { table-layout: fixed; }
.stock-items-table th:nth-child(1) { width: 64px; }
.stock-items-table th:nth-child(3), .stock-items-table th:nth-child(4) { width: 160px; }
.stock-items-table th:nth-child(5) { width: 140px; }
.stock-items-table th:nth-child(6) { width: 56px; }
.stock-items-table .stock-item-photo { padding-top: var(--space-1); padding-bottom: var(--space-1); }
.stock-items-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.stock-items-table .stock-item-edit { text-align: right; }
.stock-item-row { cursor: pointer; }

/* A stock item's photo (tab/stock-photo.js): the box as staff will see it on the shelf. One fixed frame, the picture
   fitted inside it, so nothing moves while it loads or if it never does. Full width at the top of the count sheet and
   Bought window; a small square in the Settings table; a mid square beside its buttons in the item window. */
.stock-photo { display: flex; align-items: center; justify-content: center; height: 180px; margin-bottom: var(--space-3); border-radius: var(--radius-sm); background: var(--color-bg-subtle); overflow: hidden; }
.stock-photo > img { width: 100%; height: 100%; object-fit: contain; }
.stock-photo.is-thumb { width: 40px; height: 40px; margin: 0; }
.stock-photo.is-thumb > img, .stock-photo.is-field > img { object-fit: cover; }
.stock-photo.is-field { width: 96px; height: 96px; margin: 0; flex: none; color: var(--color-text-secondary); font-size: 1.5rem; }
.stock-photo.is-field > img:not([hidden]) + .bi { display: none; }
.stock-photo-field { display: flex; align-items: center; gap: var(--space-3); }
.stock-photo-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
