/* @cascade-order: 2 — do not reorder. Split 3/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. In this file
   specifically, the form control family was consolidated into v3.css on
   2026-09-08 (see the FORMS block there). Earlier headers cited
   tests/unit/css-split-equality.test.js, which does not exist.
   Contains: the Settings sections (compact layout, settings rows, toggle
   groups, the Staff table, class/discipline/age-group management), the price
   list tab, the waiver template editor, and print/embed controls.
   The Design System THEME TAB — once the largest single section here, ~588
   lines from the file's top — was deleted with its sub-tab in the admin-UI
   plan's Phase 6 (owner decision 8), along with its markup in index.html, its
   ~640-line playground in app.js, and the one `.design-section` media override
   that lived in 50-history-admin-camps.css.
   The FILENAME is deliberately unchanged: `@cascade-order` is positional and
   `css-split-structure.test.js` reads it per file, so renaming a split file is
   a cascade edit in its own right and does not belong in a deletion PR.
   Original line range: 4037-6289. */
/* Note: Schedule toolbar and list styles are in the CLASS TYPE section below */

.settings-section {
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
}

.settings-section-title {
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  margin: 0 0 var(--space-4) 0;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.settings-card-layout {
  max-width: 700px;
}

/* Settings Row - clean horizontal layout */
.settings-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border-subtle);
}

.settings-row:last-child {
  border-bottom: none;
}

.settings-label {
  width: 120px;
  flex-shrink: 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  font-weight: var(--font-medium);
}

.settings-value {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.settings-value.flex-grow {
  flex: 1;
}

/* Input with action button */
.input-with-action {
  display: flex;
  flex: 1;
  max-width: 350px;
}

.input-with-action .form-input {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: none;
}

/* The join is for every button in the slot; the FIELD CHROME is only for one
   that has no weight of its own. All five original consumers were
   `.btn-ghost` — a show/hide eye, a Test — so the subtle fill read as part of
   the field. The camp import modal's Fetch is the modal's primary action in
   the same slot (ADR-0129), and an unconditional background would have
   silently flattened it to look like the eye icon. */
.input-with-action .btn {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.input-with-action .btn:not(.btn-primary):not(.btn-secondary):not(.btn-danger) {
  border: 1px solid var(--color-border);
  background: var(--color-bg-subtle);
}

/* Date range inline */
.date-range-inline {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.date-range-inline .form-input {
  width: 150px;
}

/* Text link */
.text-link {
  color: var(--color-accent);
  text-decoration: none;
}

.text-link:hover {
  text-decoration: underline;
}

/* Badge - base class */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  font-size: var(--text-xs);
  font-weight: 500;
  border-radius: 4px;
  white-space: nowrap;
}

/* "You" on the signed-in staff member's own row. Deliberately NOT a
   `.state-chip`: it marks WHO is reading, not what state the row is in, and
   it stays unfilled so it cannot be mistaken for one. It carried TWO
   declarations — this one (solid accent) and a `.sticker.you-badge` (bare)
   that outranked it at 0,2,0 and therefore won everywhere. The winner's
   values are kept here, the loser is gone. */
.you-badge {
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: normal;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}

/* The scroll column carries the card rhythm. In the design that gap lives on
   .schedule-list, which is the scroll's ONLY child; ours holds the all-day
   cards, the two slot anchors, the separator and the timed list as siblings, so
   the 4px belongs here. flex + min-height:0 is also what bounds the timed list
   so it scrolls while the all-day cards stay put — this is the sidebar's own
   scroll window: overflow-y:auto here, not on .schedule-sidebar, keeps the
   fixed .schedule-day-block above it from moving. */
.schedule-scroll {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-height: 0;
  flex: 1;
  overflow-y: auto;
}

.schedule-day-badge {
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  background: var(--color-bg-muted);
  color: var(--color-text-secondary);
  min-width: 40px;
  text-align: center;
}

.schedule-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.schedule-name {
  font-weight: var(--font-semibold);
  color: var(--color-text);
  font-size: var(--text-base);
}

.schedule-time {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* Action buttons */
.action-btn {
  padding: var(--space-1) var(--space-2);
  border: none;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.action-btn:hover {
  opacity: 0.85;
}

.action-btn.go-btn {
  background: var(--color-success);
  color: #fff;
}

.action-btn.cancel-btn {
  background: var(--color-danger);
  color: #fff;
}

/* Note: Schedule list and class row styles are in the CLASS TYPE MANAGEMENT section below */

.custom-select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23666' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10l-5 5z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 30px;
}

.error-text {
  color: var(--color-danger);
  font-size: var(--text-sm);
  margin-top: var(--space-2);
}

/* Age group selector */
.age-group-selector {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* `.age-group-btn` + `.age-group-btn.selected` were here and are DELETED
   (ADR-0129): one of the census's "7 names for selected" with ZERO emitters. */

/* --------------------------------------------------------------------------
   SCHEDULE TOOLBAR & FILTERS
   -------------------------------------------------------------------------- */
/* `.schedule-toolbar` was here and is DELETED (ADR-0124). A toolbar above a
   list, declared and never once emitted — the cleanest possible version of the
   thing this row exists to stop. */

.schedule-filters {
  display: flex;
  gap: var(--space-2);
}

.schedule-filter {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font-size: var(--text-sm);
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   SCHEDULE LIST (Simple Flat View)
   -------------------------------------------------------------------------- */
.schedule-full-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* ──────────────────────────────────────────────────────────────────────
   SCHEDULE ADMIN PREVIEW (Settings → Classes → Weekly Schedule)

   The Settings → Classes panel renders the same .sheet element the
   public embed + print PDF use, scoped here so admin-only affordances
   (click-to-edit cards, click-to-add empty cells, hidden-class dimming)
   don't leak into the public surfaces.

   .sheet uses CSS container queries (container-type: size; sizes in
   cqh / cqi). That means the wrapper MUST have explicit width AND
   height for the typography to compute. We use aspect-ratio so the
   sheet matches landscape paper at any container width.
   ────────────────────────────────────────────────────────────────────── */

.schedule-admin-wrap {
  width: 100%;
  /* Cap at the same canvas the print PDF uses (11in × 96dpi ≈ 1056px).
     On wide desktop the preview stops at print size instead of
     stretching across the whole settings panel. */
  max-width: 1100px;
  aspect-ratio: 11 / 8.5;             /* landscape letter, matches print canvas */
  min-height: 500px;                  /* mobile fallback so cqh text stays readable */
  margin: 0 auto;
  background: var(--color-bg-elevated, var(--color-bg-elevated));
  border-radius: var(--radius-md);
  overflow: hidden;                   /* clip the .sheet square corners to the rounded wrap */
}

/* Click affordance on every class card. The renderer also sets
   cursor:pointer inline when onClassClick is wired ; the outline below
   adds a hover signal so admin sees the card is interactive.
   outline-offset is negative so the ring sits INSIDE the card boundary —
   no clipping by the wrapper or neighbor cells. */
.schedule-admin-wrap .sheet .class {
  cursor: pointer;
}
.schedule-admin-wrap .sheet .class:hover {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* Hidden classes (showOnWebsite=false). Dashed border + dimmed so admin
   sees they're hidden but can still click to edit/restore. NO colored
   left-stripe (per ~/.claude/rules/design-dont-overdo.md). */
.schedule-admin-wrap .sheet .class.is-hidden {
  opacity: 0.55;
  border-style: dashed !important;
}

/* Empty-cell hover affordance. The renderer emits data-day + data-hour
   on every cell; we treat any .cell that contains no .class as empty.
   Hover shows a discreet "+" so admin can click any slot to seed an
   add-modal pre-filled with that day/time. */
.schedule-admin-wrap .sheet .cell:not(:has(.class)) {
  cursor: pointer;
  position: relative;
}
.schedule-admin-wrap .sheet .cell:not(:has(.class)):hover {
  background: color-mix(in srgb, var(--color-accent) 6%, transparent);
}
.schedule-admin-wrap .sheet .cell:not(:has(.class))::after {
  content: '+';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.2cqh;
  font-weight: 300;
  color: var(--color-text-muted);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.schedule-admin-wrap .sheet .cell:not(:has(.class)):hover::after {
  opacity: 1;
}

/* --------------------------------------------------------------------------
   CLASS TYPE MANAGEMENT MODAL
   -------------------------------------------------------------------------- */

.types-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  max-height: 300px;
  overflow-y: auto;
  padding: var(--space-2);
  background: var(--color-bg-subtle);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

.type-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg-subtle);
  border-radius: var(--radius-md);
}

.type-row .type-color-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex-shrink: 0;
}

.type-row .type-name {
  flex: 1;
  font-weight: var(--font-medium);
}

.type-name-input {
  flex: 1;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text);
}

.add-type-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  background: var(--color-bg-subtle);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}

.color-picker-inline {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

.color-swatch {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid transparent;
  flex-shrink: 0;
  cursor: pointer;
  transition: transform 0.1s ease;
}

.color-swatch:hover {
  transform: scale(1.15);
}

.color-swatch.selected {
  border-color: var(--color-text);
  box-shadow: 0 0 0 2px var(--color-bg-elevated);
}

.small-btn {
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-xs);
}

/* --------------------------------------------------------------------------
   CLASS PREVIEW (Modal)
   -------------------------------------------------------------------------- */
.class-preview {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  background: var(--color-bg-subtle);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

.class-preview-dot {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  flex-shrink: 0;
  transition: background 0.2s ease;
}

.class-preview-text {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-text);
}

/* --------------------------------------------------------------------------
   MANAGE TYPES MODAL
   -------------------------------------------------------------------------- */
.input-with-btn {
  display: flex;
  gap: var(--space-2);
  align-items: stretch;
}

.input-with-btn input[type="text"] {
  flex: 1;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  background: var(--color-bg);
  color: var(--color-text);
}

.type-name {
  font-size: var(--text-sm);
  font-weight: 500;
}

/* Inline types list (tags style) */
.types-list-inline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.types-list-inline .type-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  background: var(--color-bg-subtle);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.types-list-inline .type-item .remove-type-btn {
  padding: 2px 6px;
  font-size: 0.7143rem;
  line-height: 1;
}

/* Add mapping row */
.add-mapping-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-2);
}

.add-mapping-row select {
  flex: 1;
}

.add-mapping-row input[type="color"] {
  width: 40px;
  height: 32px;
  padding: 2px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

/* Color mappings list */
.color-mappings-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: 200px;
  overflow-y: auto;
}

.color-mapping-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  background: var(--color-bg-subtle);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.color-mapping-item .color-input {
  width: 32px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.color-mapping-item .mapping-label {
  flex: 1;
  font-size: var(--text-sm);
}

.color-mapping-item .remove-mapping-btn {
  padding: 2px 6px;
  font-size: 0.7143rem;
}

/* ── Admin WYSIWYG price editor — input chrome ONLY. The admin emits
   the SAME markup as the public embed (`.pl-page.pl-editorial …`) and
   shares ALL sizing/layout with it through the single
   `.pl-page:not(.pl-page--canvas)` rule in price-list-sheet.css
   (predetermined width, content height, flowing footer, small-screen
   grid collapse). The only thing genuinely admin-specific is the
   editable-input styling below. No width/height/grid/footer overrides
   live here anymore — that triplication was removed so the stylesheet
   stays the single source of truth for the digital sheet. */

/* The website-only prices sit under the sheet as a second, shorter sheet
   (`buildWebOnlyPage`): the gap is the one thing that separates them. */
.pl-admin-wrap > .pl-page + .pl-page {
  margin-top: 24px;
}

/* Editable price inputs — keep the sheet's font-weight/size/color via
   the `.ed-price` / `.ed-bprice` rules; only adjust input-specific
   chrome (border, padding, spin buttons). */
.pl-admin-wrap .pl-admin-input {
  width: 50px;
  padding: 0 4px;
  margin: 0 0 0 2px;
  border: 1px solid transparent;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: right;
  border-radius: 3px;
  -moz-appearance: textfield;
  vertical-align: baseline;
}

.pl-admin-wrap .pl-admin-input::-webkit-outer-spin-button,
.pl-admin-wrap .pl-admin-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.pl-admin-wrap .pl-admin-input:hover {
  border-color: rgba(0, 0, 0, 0.18);
}

.pl-admin-wrap .pl-admin-input:focus {
  outline: none;
  border-color: currentColor;
  background: #fff;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 16%, transparent);
}

/* ==========================================================================
   WAIVER TEMPLATE EDITOR (Waivers → Templates) — admin edit chrome
   --------------------------------------------------------------------------
   The waiver *document* look comes from waiver-sheet.css (.waiver-page scope),
   loaded app-wide so this preview is pixel-identical to the public page. This
   block adds ONLY the admin chrome: the toolbar, the stage backdrop, and the
   inline-editable affordances — same "editable but blends in" pattern as
   `.pl-admin-input` / `.asr-num` (transparent until hover, clear ring on focus).
   ========================================================================== */

.waiver-admin {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Toolbar — sticky so actions stay reachable while scrolling the tall preview. */
.waiver-admin-toolbar {
  position: sticky;
  top: var(--page-pin-h);
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3);
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.waiver-admin-toolbar-left,
.waiver-admin-toolbar-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.waiver-admin-id {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.waiver-admin-name {
  padding: 4px 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font-size: var(--text-sm);
  min-width: 240px;
  font-weight: var(--font-semibold);
}

.waiver-admin-name-static {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text);
}

.waiver-admin-id-hint,
.waiver-admin-meta {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.waiver-admin-version {
  padding: 4px 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font-size: var(--text-sm);
  max-width: 200px;
}

.waiver-admin-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.waiver-admin-readonly {
  font-size: var(--text-xs);
  font-style: italic;
  color: var(--color-text-muted);
}

/* Stage — sits the preview on the same backdrop the public page uses (its body
   bg, which the app does not load). */
.waiver-admin-stage {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* The public .waiver-page forces min-height:100vh; inside a tab the preview
   should size to its content. */
.waiver-admin-page.waiver-page {
  min-height: 0;
}

/* Fixed (non-editable) chrome — `inert` handles interaction; this is a belt
   for browsers without inert support. */
.waiver-admin-fixed {
  pointer-events: none;
}

.waiver-admin-sig-placeholder {
  height: 150px;
}

/* The shared `.waiver-page .waiver-initials-row { display: flex }` rule would
   defeat the [hidden] attribute the editor toggles on the initials preview
   (an explicit display beats the UA [hidden]{display:none}); re-assert it. */
.waiver-page .waiver-admin-initials-row[hidden] {
  display: none;
}

/* Editable sections — per-card hover tools (move / remove). */
.waiver-admin-section {
  position: relative;
}

.waiver-admin-tools {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.15s;
}

.waiver-admin-section:hover .waiver-admin-tools,
.waiver-admin-section:focus-within .waiver-admin-tools {
  opacity: 1;
}

.waiver-admin-tool {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text-muted);
  font-size: 0.8rem;
  cursor: pointer;
}

.waiver-admin-tool:hover:not(:disabled) {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.waiver-admin-tool-danger:hover:not(:disabled) {
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.waiver-admin-tool:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.waiver-admin-initials-toggle {
  margin-top: 8px;
}

.waiver-admin-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin-top: 4px;
  padding: 10px;
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  cursor: pointer;
}

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

/* Inline-editable fields — look like the rendered text, reveal a faint outline
   on hover, clear blue ring on focus (mirrors `.pl-admin-input` / `.asr-num`).
   Each replicates the public element's typography so the preview reads true. */

.waiver-admin-title:hover,
.waiver-admin-body:hover,
.waiver-admin-consent:hover {
  border-color: color-mix(in srgb, currentColor 22%, transparent);
}

.waiver-admin-title:focus,
.waiver-admin-body:focus,
.waiver-admin-consent:focus {
  outline: none;
  border-color: var(--color-accent);
  background: #fff;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 16%, transparent);
}

/* Title — looks like .waiver-section-title (h3). */
.waiver-admin-title {
  font-family: inherit;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  display: block;
  width: 100%;
  margin: 0 0 12px;
  padding: 2px 6px;
  background: transparent;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--color-text);
}

/* Body — looks like the bordered .waiver-section-body box, editable. */
.waiver-admin-body {
  font-family: inherit;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  display: block;
  width: 100%;
  margin-bottom: 16px;
  padding: 12px;
  border-color: var(--color-border-subtle);
  background: #f8fafc;
  font-size: 0.8125rem;
  color: #334155;
  line-height: 1.6;
  resize: vertical;
  min-height: 80px;
}

/* Consent — editable text inside the yellow .consent-section. */
.waiver-admin-consent {
  font-family: inherit;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  flex: 1;
  padding: 6px 8px;
  background: rgba(255,255,255,0.5);
  font-size: 0.8125rem;
  color: #334155;
  line-height: 1.5;
  resize: vertical;
  min-height: 80px;
}

/* The small-screen grid collapse (3 → 2 → 1 col), title shrink, and
   footer stacking now live ONCE in price-list-sheet.css under the
   `:not(.pl-page--canvas)` @media blocks — they cover the embed AND
   the admin preview from a single place (admin pages are never
   .pl-page--canvas). The admin-scoped duplicates that used to sit here
   were removed; do not re-add them. */

/* ==========================================================================
   PRINT / EMBED CONTROLS (Classes tab)
   ========================================================================== */

/* Reused label style for the schedule + price-list consolidated control
   rows. The container row itself uses `.pl-controls-row` /
   `.pl-control-cell` defined elsewhere; only the label is shared. */
.print-mode-label {
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Custom-dimensions input row (Letter vs Custom toggle reveals this).
   Shared by the schedule + price-list consolidated sections. */
.size-input-group {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.size-input-group .form-input {
  width: 70px;
  text-align: center;
}

.size-separator {
  color: var(--color-text-muted);
  font-weight: var(--font-medium);
}

.size-unit {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.embed-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

/* The schedule's Age Groups field is the shared pick-several control
   (foundation/multi-select.js, summary mode) — the bespoke `.checklist-*`
   family that used to live here was a second implementation of it, down to its
   own caret and its own open/closed styling (census §A3). All that is left is
   the one thing that IS this row's business: the control sits in a row of
   form controls, so it gets a real width instead of collapsing to its label. */
.pl-control-cell .multi-select {
  min-width: 200px;
}

/* Consolidated Price List section — see Settings → Pricing.
   Layout: one top row with every control + terminal action (Layout /
   Title / B&W / Size / PDF / Embed / Preview); then optional Custom-
   dimensions row when Size = Custom; then the WYSIWYG preview; then
   Save Prices. Save stays below the preview because it's the "commit
   my edits" action — the three terminal actions consume current state. */
.pl-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.pl-controls-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3) var(--space-4);
}

/* Each cell is a tight column: label on top (uppercase, small) over an
   input. Width is intrinsic — selects size to their longest option, not
   to the row's leftover space. */
.pl-control-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 0 0 auto;
  min-width: 0;
}

.pl-control-cell .form-input {
  width: auto;
}

/* B&W cell aligns to the bottom of the row so the checkbox sits on the
   same baseline as the select inputs (which have a label-row above). */
.pl-bw-cell {
  align-self: flex-end;
  /* Tighten vertical padding so the checkbox text aligns with select
     text vertically — selects are ~32px tall; matching here keeps the
     baseline clean. */
  padding-bottom: 6px;
}

/* Action buttons hug the right edge so controls cluster on the left
   and terminal actions on the right. On narrow viewports they wrap to
   their own row underneath the controls. */
.pl-action-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-left: auto;
  align-self: flex-end;
}

/* Custom-dimensions cell sits inline to the right of the Size select
   when Size = Custom. The inputs are narrow (W × H × in) so the row
   accommodates the cell + action buttons without wrapping on a normal-
   width admin layout. */
.pl-custom-cell .size-input-group {
  align-items: center;
  gap: 6px;
  /* Match select height (~32px) so the inline group's baseline aligns
     with the surrounding selects. */
  height: 32px;
}

.pl-custom-cell .form-input {
  width: 54px;
  text-align: center;
}

.pl-custom-cell .size-unit {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
#settings-header-link:empty {
  display: none;
}

/* The sticky things inside a Settings page (the roles card, the waiver editor's
   toolbar) start below the pinned page head (`--page-pin-h`, the header plus the
   sibling band when one shows), so it never covers them. */

/* The `hidden` attribute on the back arrow, the sibling band, the intro, the
   map's groups and the header's Cancel and Save Changes is honoured by the global
   `[hidden] { display: none !important }` (00-shell-layout-members.css). */
#tab-settings > .settings-subnav {
  flex: none;
}

/* The page body must not shrink below its content: a long page scrolls the tab
   (and the pinned header stays), it does not squeeze the body. */
#tab-settings > .page-body {
  display: flex;
  flex-direction: column;
}

/* ── The intro: what the page controls on its own line, then a quieter line
   with where it shows and how it saves. ──────────────────────────────────── */
.settings-intro {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: var(--space-4);
}
.settings-purpose {
  margin: 0;
  max-width: 820px;
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--color-text);
}
.settings-meta {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.settings-meta-label {
  margin-right: 2px;
  font-weight: var(--font-semibold);
  color: var(--color-text-secondary);
}
.settings-shows {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 8px;
}
.settings-shows-item,
.settings-save-model {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
/* One line per page: icon, name, status chip, chevron. */
.settings-index-row {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  width: 100%;
  height: 36px;
  padding: 0 10px;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.settings-index-row:hover {
  background: var(--hover-row, var(--color-bg-subtle));
}
.settings-index-row:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.settings-index-icon {
  font-size: 15px;
  text-align: center;
  color: var(--color-accent);
}
.settings-index-name {
  overflow: hidden;
  font-weight: var(--font-medium);
  color: var(--color-text);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.settings-index-end {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--color-text-muted);
}
.settings-index-end .bi {
  font-size: 11px;
}

/* ==========================================================================
   WEBSITE PAGES (ADR-0165, ADR-0268: Announcement, Opening hours, Booking & buy links, Contact & social) — 2026-10-12
   --------------------------------------------------------------------------
   A list of links is ONE column: the card's name on the left, its link in the
   middle, its state on the right, a hairline between rows. Never two cards or
   two links to a row. The callout is the conflict strip ("someone else changed
   this while you were typing") and the empty-hours warning; it is a whole
   border with a tint, never a one-sided accent. Components (.titled-section,
   .state-chip, .form-input, .form-checkbox) are only USED here.
   ========================================================================== */
.settings-link-list {
  display: flex;
  flex-direction: column;
}
.settings-link-row {
  display: grid;
  grid-template-columns: minmax(150px, 230px) minmax(0, 1fr) minmax(0, 270px);
  gap: 6px 12px;
  align-items: center;
  padding: 6px 0;
}
.settings-link-row + .settings-link-row {
  border-top: 1px solid var(--color-border-subtle);
}
.settings-link-label {
  font-size: var(--text-md);
  color: var(--color-text);
}
.settings-link-state {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.settings-link-fallback {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.settings-callout {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: var(--space-3);
  padding: 8px 10px;
  border: 1px solid color-mix(in srgb, var(--color-info) 30%, transparent);
  border-radius: var(--radius-md);
  background: var(--color-info-tint);
  font-size: var(--text-sm);
  color: var(--color-text);
}
/* The margin spaces the callout from what follows it; as the last child of its
   container there is nothing to space, and it would only stretch the container
   (the group event's #ge-note doubled the page column's gap). */
.settings-callout:last-child {
  margin-bottom: 0;
}
.settings-callout-text {
  flex: 1 1 auto;
  min-width: 0;
}
.settings-callout.is-warn {
  border-color: color-mix(in srgb, var(--color-warning) 35%, transparent);
  background: var(--color-warning-tint);
}
.settings-callout[hidden] {
  display: none;
}
/* The banner window's preview (Announcements, ADR-0276): the WEBSITE's own banner page in a frame, so nothing
   here styles the banner itself. The frame renders at the chosen width (desktop 1024, phone 390) and is scaled
   down to fit and centred; `announcement-admin.js` sets its width, height and scale. */
.settings-banner-preview {
  position: relative;
  overflow: hidden;
  margin-top: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.settings-banner-preview iframe {
  position: absolute;
  top: 0;
  left: 50%;
  display: block;
  border: 0;
  transform-origin: top center;
  translate: -50% 0;
}
/* Opening hours: a day a row, the Open switch, then the two times. */
.settings-hours {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 560px;
  margin-bottom: var(--space-3);
}
.settings-hours-row {
  display: grid;
  grid-template-columns: 110px 80px minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 8px;
  align-items: center;
}
.settings-hours-day {
  font-weight: var(--font-medium);
}
.settings-hours-to {
  color: var(--color-text-muted);
}
/* A list of typed rows, each two values and a remove button: the hours the day
   pickers cannot read (Opening hours) and the closed days (Closed days). */
.settings-entry-rows {
  margin-top: var(--space-3);
}
.settings-entry-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
  gap: 8px;
  align-items: center;
  margin-bottom: 4px;
}

/* ==========================================================================
   SHEET PAGES (ADR-0165: Weekly schedule and Price list) — 2026-10-12
   --------------------------------------------------------------------------
   The two pages whose body is the app's OWN sheet editor (the website embed and
   the print, never redrawn) get only a frame around it. This block is the frame's
   one line of its own: which prices also drive check-in and camps. The chip is a
   tinted rectangle at `--radius-sm`, not a pill.
   ========================================================================== */
.settings-uses-line {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  line-height: 1.9;
  color: var(--color-text-secondary);
}
/* A footnote inside a section (a titled section, the schedule's sheet card) is spaced by
   that section's own flex gap; its top margin would stack on the gap. */
:is(.titled-section, .pl-section) > .settings-footnote {
  margin: 0;
}
.settings-uses {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  background: var(--color-warning-tint);
  color: var(--color-warning-ink);
  font-size: var(--text-xs);
  white-space: nowrap;
}

/* ==========================================================================
   CHECK-IN PROMPTS PAGE (ADR-0165, first page built on the frame) — 2026-10-12
   --------------------------------------------------------------------------
   One card per payment reminder: a switch, a state chip, When / On / Off lines
   with the one that is true right now emphasised, and the Off line marked as a
   warning while it is the current one. The locked pass exception is the same
   card with a lock where the switch is. Components (.toggle-switch, .toggle-row,
   .state-chip, .titled-section) are only USED here; the card is `.toggle-row`
   too, so `runToggleSave` can find its row. No one-sided accent borders, no
   gradients, no pill radii.
   ========================================================================== */
.settings-prompts {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.settings-prompt {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--space-3);
  padding: var(--space-3) 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-prompt.is-fixed {
  background: var(--color-bg-subtle);
}
.settings-prompt-lock {
  width: 44px;
  font-size: 18px;
  line-height: 24px;
  text-align: center;
  color: var(--color-text-muted);
}
.settings-prompt-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.settings-prompt-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-height: 24px;
  font-weight: var(--font-semibold);
}
.settings-prompt-line {
  display: grid;
  grid-template-columns: 4.6em minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-prompt-line > span:first-child {
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.settings-prompt-line.is-current {
  color: var(--color-text);
}
.settings-prompt-line.is-current.is-warn {
  font-weight: var(--font-medium);
  color: var(--color-warning-ink);
}
.settings-prompt-warn-icon {
  margin-right: 6px;
}
.settings-prompt-price {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}
.settings-footnote {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.settings-footnote-icon {
  margin-right: 6px;
}
/* A page name inside a footnote: it navigates (data-settings-tab), so it is a button that reads as a link. */
.settings-footnote-link {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--color-accent);
  cursor: pointer;
}
.settings-footnote-link:hover {
  text-decoration: underline;
}

/* ==========================================================================
   ADMIN GROUP PAGES (ADR-0165): shared page parts — 2026-10-12
   --------------------------------------------------------------------------
   The Square connection, Waiver form, Account clean-up, Duplicate accounts and
   Backups & repair pages share a vertical stack of cards and boxes. This block
   holds what more than one of them wears: the page stack, the status card, the
   numbered steps, the copy row, the choice cards in a row and the Careful box.
   Whole borders only; no gradients, no pill radii.
   ========================================================================== */
.settings-page-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.settings-status-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-status-card > div {
  flex: 1 1 260px;
  min-width: 0;
}
.settings-status-icon {
  font-size: 24px;
  color: var(--color-text-muted);
}
.settings-status-icon.is-ok {
  color: var(--color-success);
}
.settings-status-icon.is-warn {
  color: var(--color-warning-ink);
}
.settings-status-title {
  font-weight: var(--font-semibold);
}
.settings-status-sub {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 760px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.settings-step {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 10px;
}
.settings-step-num {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--color-accent-tint);
  color: var(--color-accent);
  font-weight: var(--font-bold);
}
.settings-step-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.settings-step-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-top: 3px;
  font-weight: var(--font-semibold);
}
.settings-copy-row {
  display: flex;
  gap: 6px;
}
.settings-copy-row > input {
  flex: 1;
  min-width: 0;
  color: var(--color-text-secondary);
}
/* The count row at the top of Account clean-up: a chip and a figure each. */
.settings-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
}
.settings-summary > .legend-fact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-md);
  color: var(--color-text-secondary);
}
.settings-summary > .legend-fact strong {
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
/* Each rule is its own box, so four rules read as four at a glance even when a
   sentence wraps (owner comment on the prototype, 2026-10-12). */
.settings-rules {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 860px;
}
.settings-rule {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  align-items: baseline;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-rule p {
  margin: 0;
  line-height: 1.9;
}
/* A number inside a sentence. Scoped through the rule: v3.css's
   `.form-input { width: 100% }` loads after this file and ties a bare class. */
.settings-rule .settings-inline-num {
  display: inline-block;
  width: 4.5em;
  height: 26px;
  padding: 0 6px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.settings-rule .settings-inline-num.is-sm {
  width: 3.5em;
}
.settings-rule .settings-inline-num.is-lg {
  width: 5em;
}
/* The Careful box: a rare or irreversible action, visibly apart from the
   everyday settings above it. A whole border and a tint, no one-sided accent. */
.settings-careful {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--color-danger) 30%, transparent);
  border-radius: var(--radius-md);
  background: var(--color-danger-tint);
}
.settings-careful p {
  margin: 0;
  font-size: var(--text-sm);
}
.settings-careful-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: var(--font-semibold);
  color: var(--color-danger);
}
/* The danger button is the danger TINT, which is the box's own fill: lift it onto
   the page surface so the action reads as a button, with a whole border. */
.settings-careful .btn-danger {
  border: 1px solid color-mix(in srgb, var(--color-danger) 40%, transparent);
}
.settings-careful .btn-danger:not(:hover):not(:active) {
  background: var(--color-bg-elevated);
}
.settings-careful-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}
.settings-preview-result {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-preview-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: var(--text-md);
}
.settings-compare {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-compare strong {
  color: var(--color-text);
  font-size: var(--text-md);
}
/* Backups & repair: the three backup cards, and the repair tools inside the Careful box. */
.settings-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: 8px;
}
.settings-info-card {
  padding: 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-info-card p {
  margin: 4px 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-info-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: var(--font-semibold);
}
.settings-tool {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-tool-text {
  display: flex;
  flex: 1 1 300px;
  flex-direction: column;
  gap: 1px;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-tool-text strong {
  font-size: var(--text-md);
  color: var(--color-text);
}
.settings-tool-result {
  margin-top: 4px;
  font-weight: var(--font-medium);
  color: var(--color-text);
}
/* The bar above an editor a page opens in place of its summary (Waiver form). */
.settings-editor-bar {
  margin-bottom: var(--space-2);
}
/* ==========================================================================
   CLEANING ROTA PAGE (ADR-0165, second page built on the frame) — 2026-10-12
   --------------------------------------------------------------------------
   The rooms list is the shared Settings row (`.type-item`, settings-row.js);
   this block adds the one fact it shows beside the name, the week grid, and
   the checklist inside the shift window. Each rota cell is a button that opens
   the shift's window. The empty cell is a recessed tint, not a coloured
   border. Whole borders only; no gradients, no pill radii.
   ========================================================================== */
.settings-row-fact {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
/* A row whose NAME wins: it takes the width it needs, and the facts beside it
   (right-aligned) take what is left and end in an ellipsis. The shared row gives
   the name `flex: 1` and the meta `flex-shrink: 0`, which on a phone squeezes
   the name to "Wash...". The Cleaning rota's room rows and the Staff page's
   people rows both pass this through settingsRow's `className`. */
.settings-row-fit .type-item-name {
  flex: 0 1 auto;
}
.settings-row-fit .type-item-meta {
  flex: 1 1 0;
  min-width: 0;
  justify-content: flex-end;
}
/* ...but a meta that is ONE state chip and nothing else has no text to
   ellipsise: the chip keeps its width and the name is the one that gives way.
   With the rule above, a long Square service name ("Birthday Party - Kids (7
   and under)") took the row, the meta box went to 0 and its chip ("Room 1
   (Birthday party)") overflowed back over the name (From Square, ~1024px,
   2026-10-19). */
.settings-row-fit .type-item-meta:has(> .state-chip:only-child) {
  flex: 0 0 auto;
}
.settings-row-fit:has(> .type-item-meta > .state-chip:only-child) .type-item-name {
  /* The name takes the free width, so the chips line up at the row's right edge
     rather than sitting wherever each name happens to end. */
  flex: 1 1 0;
  min-width: 0;
}
/* The grid is wider than a phone: it scrolls sideways inside its own box
   rather than shrinking the cells until the room names are unreadable. */
.settings-rota {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  overflow-x: auto;
}
.settings-rota-row {
  display: grid;
  grid-template-columns: 96px repeat(7, minmax(84px, 1fr));
  gap: var(--space-1);
}
.settings-rota-day {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--color-text-secondary);
  text-align: center;
}
.settings-rota-shift {
  display: flex;
  flex-direction: column;
  justify-content: center;
  font-weight: var(--font-semibold);
}
.settings-rota-hours {
  font-size: var(--text-xs);
  font-weight: var(--font-normal);
  color: var(--color-text-muted);
}
.settings-rota-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 50px;
  padding: 5px 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-xs);
  text-align: left;
  cursor: pointer;
}
.settings-rota-cell:hover {
  border-color: var(--color-accent);
}
.settings-rota-cell.is-unassigned {
  background: var(--color-bg-subtle);
  color: var(--color-text-muted);
}
.settings-checks {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ==========================================================================
   STAFF PAGE (ADR-0165, third page built on the frame) — 2026-10-12
   --------------------------------------------------------------------------
   One column of people lists beside a card saying what each role can do. A
   person is the shared Settings row (`.type-item`, settings-row.js) with an
   avatar in the lead slot; this block adds what is the people's own: the
   two-column layout, the fixed-width cells that keep email, role and last
   sign-in lined up from row to row, the inline role select, and the Add
   window's role cards. Whole borders only; no gradients, no pill radii (the
   avatar is the one circle, as the account menu's is).
   ========================================================================== */
.settings-staff-lists {
  display: flex;
  flex-direction: column;
}
.settings-section-note {
  margin: 0;
  font-size: var(--text-sm);
  max-width: 760px;
}
/* Not on a note that is also `.text-danger` (the error line): that utility is the design system's and used to come later. */
.settings-section-note:where(:not(.text-danger)) {
  color: var(--color-text-secondary);
}
/* The cells after the name (`.settings-row-fit`) are right-aligned fixed widths,
   and the email is the one that gives (it ends in an ellipsis). */
.settings-person-email {
  flex: 0 1 220px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.settings-person-role {
  flex: 0 0 11em;
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--color-text);
}
.settings-person-row .settings-row-fact {
  flex: 0 0 auto;
  min-width: 11em;
  text-align: right;
}
/* Scoped through the row: v3.css's `.form-input { width: 100% }` loads after this
   file and ties a bare class, so the fixed width needs the extra specificity. */
.settings-person-row .settings-role-select {
  flex: 0 0 11em;
  width: 11em;
  height: 26px;
  padding: 0 6px;
}
.settings-inline-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-roles-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-subtle);
  position: sticky;
  top: calc(var(--page-pin-h) + 12px);
}
.settings-roles-title {
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.settings-role {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.settings-role strong {
  color: var(--color-text);
}
/* Under its lists (.side-layout's one column) the roles card scrolls with them. */
@media (max-width: 1100px) {
  .settings-roles-card {
    position: static;
  }
}

/* ==========================================================================
   MEMBER APP LOGINS PAGE (ADR-0165, fourth page built on the frame) — 2026-10-12
   --------------------------------------------------------------------------
   The list of sign-ins beside the accounts the selected one opens. The account
   rows are the shared Settings row (`.type-item`, settings-row.js) and the
   state words are `.state-chip`; this block adds the list column, its items,
   the detail pane and the Link window's chosen-account line. The phone shows
   the list OR the detail (mobile.css). Whole borders only; no gradients, no
   pill radii.
   ========================================================================== */
.settings-logins {
  display: grid;
  grid-template-columns: minmax(260px, 340px) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}
.settings-logins-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.settings-login-group {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-bg-elevated);
}
.settings-login-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 10px;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.settings-login-item + .settings-login-item {
  border-top: 1px solid var(--color-border-subtle);
}
.settings-login-item:hover {
  background: var(--color-bg-subtle);
}
.settings-login-item.is-selected {
  background: var(--color-accent-tint);
}
.settings-login-email {
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  overflow-wrap: anywhere;
}
.settings-login-sub {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.settings-logins-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  min-height: 200px;
  padding: 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-elevated);
}
.settings-logins-detail > .btn {
  align-self: flex-start;
}
.settings-login-head h4 {
  margin: 0 0 4px;
  font-size: var(--text-lg);
  overflow-wrap: anywhere;
}
.settings-logins-cap {
  margin: 0 0 var(--space-3);
  padding: 8px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-warning-tint);
  color: var(--color-warning-ink);
  font-size: var(--text-sm);
}
/* The Link window: the chosen account, in place of the search field. */
.settings-link-picked {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 6px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-subtle);
  font-weight: var(--font-medium);
}
@media (max-width: 760px) {
  .settings-logins {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ==========================================================================
   CLASS TYPES & AGE GROUPS PAGE (ADR-0165, fifth page built on the frame)
   — 2026-10-12
   --------------------------------------------------------------------------
   Two lists in the shared Settings row beside each other (`.schedule-config-grid`,
   the two-column grid the old fold used, 40-checkin-history.css). The rows are
   `settingsRow`s with a colour dot for a class type and a `.settings-row-fact`
   for its length and weekly count; this block adds what the edit window says
   about a change. No one-sided accent borders, no gradients, no pill radii.
   ========================================================================== */
.settings-hint-warn {
  gap: 6px;
}

/* ==========================================================================
   MEMBERSHIPS & PASSES PAGE (ADR-0165, sixth page built on the frame)
   — 2026-10-12
   --------------------------------------------------------------------------
   The app's three columns (`.access-config-grid`, 50-history-admin-camps.css) of
   shared Settings rows. A membership or pass row IS its badge, so an archived
   one (badge, the Archived chip, three controls) is wider than a third of the
   page: this modifier, passed through `settingsRow`'s `className`, lets the chip
   and the controls wrap onto a second line instead of leaving the column. The
   badge itself is never restyled.
   ========================================================================== */
.settings-row-wrap {
  flex-wrap: wrap;
  row-gap: 2px;
}
.settings-row-wrap > .row-actions {
  margin-left: auto;
}
/* A pass whose full name differs from its badge label (ADR-0207) names itself in
   full on the line under its badge and controls, instead of squeezing beside
   them to an ellipsis: the shared `.type-item-name` is `flex: 1` over a zero
   basis and clips, and a column is a third of the page. */
.settings-row-named .type-item-name {
  order: 1;
  flex: 1 0 100%;
  white-space: normal;
}

/* ==========================================================================
   SQUARE PRODUCTS PAGE (ADR-0165, seventh page built on the frame) — 2026-10-12
   --------------------------------------------------------------------------
   The rows are the shared Settings row with the badge the product grants in the
   meta slot (`getMappingBadge`, over renderBadge, never restyled). This block is
   the mapping window's sentence: "When someone buys X, give 10 [badge] passes",
   a recessed tint with the badges set on the text's line. No one-sided accent
   borders, no gradients, no pill radii.
   ========================================================================== */
.settings-sentence {
  margin-top: var(--space-3);
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: var(--color-bg-subtle);
  font-size: var(--text-md);
  line-height: 1.8;
}
.settings-sentence .pass-badge {
  vertical-align: middle;
}
