/* App chrome — consumes the theme tokens in tokens.css.
   All colors come from CSS variables so every tenant theme just works. */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  line-height: 1.55;
}

a { color: var(--secondary, var(--accent)); }

/* Skip link — visible only when focused */
.skip-link {
  position: absolute; left: .5rem; top: -3rem; z-index: 100;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: .5rem .9rem; text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus { top: .5rem; }

/* Keyboard focus outlines (a11y) */
.btn:focus-visible,
.att-opt:focus-within,
.topnav a:focus-visible,
.result-item:focus-visible,
.skip-link:focus-visible,
.nav-toggle:focus-visible,
select:focus-visible,
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

h1 { font-family: var(--font-display); font-weight: 600; font-size: 1.6rem; margin: 0 0 .25rem; }
h2 { font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; margin: 0 0 .5rem; }
.muted { color: var(--ink-muted); }
code { background: var(--surface-2); padding: .1rem .35rem; border-radius: var(--radius-sm); }

/* Top bar */
.topbar { background: var(--accent); color: var(--accent-ink); }
.topbar-inner {
  max-width: var(--w-page); margin: 0 auto; padding: var(--space-3) var(--space-5);
  display: flex; align-items: center; justify-content: space-between;
}
.brand { color: var(--accent-ink); text-decoration: none; font-weight: 600; font-family: var(--font-display); margin-right: auto; }
.lang-switch { display: inline-flex; gap: .35rem; margin-right: auto; margin-left: .75rem; font-size: .78rem; }
/* Nav/lang text stays at full accent-ink so it clears WCAG AA (≥4.5:1) on every
   tenant accent (pilates #a85f4b = 4.76:1); active state is shown by weight +
   underline, not by dimming, which would drop contrast below AA. */
.lang-switch a { color: var(--accent-ink); text-decoration: none; }
.lang-switch a.active { font-weight: 600; text-decoration: underline; }
.topnav { display: flex; align-items: center; gap: 1rem; }
.topnav a { color: var(--accent-ink); text-decoration: none; }
.topnav a:hover { text-decoration: underline; }
.topnav .logout-form { display: inline; margin: 0; }
.topnav .linklike { background: none; border: none; color: var(--accent-ink);
  cursor: pointer; font: inherit; padding: 0; }
.topnav .linklike:hover { text-decoration: underline; }
.role-chip {
  background: var(--accent-soft); color: var(--accent-strong);
  font-size: .75rem; padding: .15rem .55rem; border-radius: 999px; text-transform: capitalize;
}

/* Hamburger toggle — hidden on desktop, shown < 640px via media query */
.nav-toggle {
  display: none;
  flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; padding: 10px;
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm);
  cursor: pointer;
}
.nav-toggle-bar {
  display: block; height: 2px; width: 100%;
  background: var(--accent-ink); border-radius: 2px;
}

/* Layout */
.container { max-width: var(--w-page); margin: 0 auto; padding: var(--space-7) var(--space-5); }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--space-5) var(--space-6); margin-bottom: var(--space-5);
  box-shadow: var(--shadow);
}
.auth-card { max-width: var(--w-narrow); margin: var(--space-7) auto; }
/* the same width for signed-in pages, but left-aligned with everything else */
.page-narrow { max-width: var(--w-narrow); }
.auth-foot { margin: 1rem 0 0; font-size: .9rem; }

.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); margin-bottom: var(--space-5); }
/* cards with content (not single figures) need more room before they pair up */
.grid.grid-cards { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.stat { display: flex; flex-direction: column; gap: .25rem; margin: 0; }
.stat-label { font-size: .75rem; color: var(--ink-muted); text-transform: uppercase; letter-spacing: .04em; }
.stat-value { font-size: 1.25rem; font-weight: 500; text-transform: capitalize; }

/* Forms */
label { display: block; font-size: .85rem; color: var(--ink); font-weight: 500; margin-bottom: .85rem; }
/* help text under a field reads lighter and smaller than its label */
label .muted { font-size: .8rem; font-weight: 400; color: var(--ink-muted); }
.help { display: block; font-size: .8rem; font-weight: 400; color: var(--ink-muted); margin-top: .25rem; }
/* "Add …" panels: a button that opens the form, above the list it adds to */
.create-panel > summary { list-style: none; }
.create-panel > summary::-webkit-details-marker { display: none; }
.create-panel { background: transparent; border: 0; box-shadow: none; padding: 0; margin-bottom: 1rem; }
.create-panel[open] { background: var(--surface); border: 1px solid var(--border);
                      box-shadow: var(--shadow); padding: 1.25rem; }
.create-panel[open] > summary { margin-bottom: 1rem; }
/* text-like inputs only — a checkbox or radio styled as a full-width text box looked broken */
input:not([type=checkbox]):not([type=radio]):not([type=color]):not([type=file]):not([type=range]), textarea {
  display: block; width: 100%; margin-top: .3rem; padding: .55rem .65rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-size: 1rem;
  font-family: var(--font-sans);
}
input[type=checkbox], input[type=radio] { width: auto; margin: 0 .4rem 0 0; accent-color: var(--accent); }
input:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

.btn {
  display: inline-block; cursor: pointer; border: 1px solid var(--border);
  background: var(--surface); color: var(--ink); text-decoration: none;
  padding: .55rem 1.1rem; border-radius: var(--radius-sm); font-size: 1rem;
}
.btn:hover { background: var(--surface-2); }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.btn-accent { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
/* full width only where meant: sign-in cards and explicit .btn-block */
.btn-block, .auth-card .btn-accent { width: 100%; text-align: center; }
.btn-accent:hover { background: var(--accent-strong); }

/* Flash */
.flash { padding: .65rem .9rem; border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: .9rem; border: 1px solid var(--border); }
.flash-error { background: var(--pill-fail-bg); color: var(--pill-fail-ink); border-color: var(--fail-line); }
.flash-warn { background: var(--pill-warn-bg); color: var(--pill-warn-ink); border-color: var(--warn-line); }
.flash-success { background: var(--pill-paid-bg); color: var(--pill-paid-ink); border-color: var(--paid-line); }
.flash-info { background: var(--accent-soft); color: var(--accent-strong); }
.field-error { display: block; color: var(--pill-fail-ink); font-size: .8rem; margin-top: .25rem; }
input[aria-invalid="true"] { border-color: var(--danger); }

/* Tables */
.table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.table th { text-align: left; font-weight: 500; color: var(--ink-muted); font-size: .78rem;
  text-transform: uppercase; letter-spacing: .03em; padding: .4rem .5rem; border-bottom: 1px solid var(--border); }
.table td { padding: .55rem .5rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tr:last-child td { border-bottom: none; }

/* A site that charges differently, set apart on the public price list */
.site-block { border-left: 3px solid var(--accent); padding-left: 1rem; margin: 2rem 0; }
.site-block .site-heading { margin-top: 0; }
.site-block h2:not(.site-heading) { font-size: 1.05rem; }

/* The `hidden` attribute must win. Any class that sets `display` (like .btn's
   inline-block) otherwise overrides the browser's own [hidden] rule, and an
   element the code has hidden stays on screen. */
[hidden] { display: none !important; }

/* Site tabs — one ladder/list at a time when a studio has several sites */
.tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 1rem; }
.tabs .tab { display: inline-block; text-decoration: none; color: var(--ink-muted);
  border: 1px solid var(--border); border-radius: 999px; padding: .3rem .85rem;
  font-size: .85rem; background: var(--surface); }
.tabs .tab:hover { background: var(--surface-2); color: var(--ink); }
.tabs .tab.is-active { background: var(--accent-soft); color: var(--accent-strong);
  border-color: var(--accent); }

/* Pills */
.pill { display: inline-block; background: var(--accent-soft); color: var(--accent-strong);
  font-size: .75rem; padding: .12rem .5rem; border-radius: 999px; margin: 0 .2rem .2rem 0; }
.pill-warn { background: var(--pill-warn-bg); color: var(--pill-warn-ink); }
.pill-paid { background: var(--pill-paid-bg); color: var(--pill-paid-ink); }
.pill-open { background: var(--pill-open-bg); color: var(--pill-open-ink); }
.pill-pending { background: var(--pill-pending-bg); color: var(--pill-pending-ink); }
.pill-failed { background: var(--pill-fail-bg); color: var(--pill-fail-ink); }
.pill-void { background: var(--pill-void-bg); color: var(--pill-void-ink); }
.pill-refunded { background: var(--accent-soft); color: var(--accent-strong); }

.qr { margin: .5rem 0 1rem; }
.qr svg { width: 190px; height: 190px; background: #fff; padding: 8px; border-radius: var(--radius-sm); }
.code-block { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: .75rem 1rem; overflow-x: auto;
  font-size: .85rem; white-space: pre-wrap; }

/* Composer recipient picker */
.recipient-box { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .5rem; margin-bottom: 1rem; }
.chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.chip { background: var(--accent-soft); color: var(--accent-strong); border-radius: 999px; padding: .2rem .6rem; font-size: .82rem; }
.chip a { color: var(--accent-strong); text-decoration: none; margin-left: .25rem; }
.recipient-box input[type=text] { border: none; margin: .3rem 0 0; padding: .35rem; }
.recipient-box input[type=text]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.results { display: flex; flex-direction: column; }
.result-item { padding: .45rem .5rem; cursor: pointer; border-radius: var(--radius-sm); }
.result-item:hover,
.result-item.is-active { background: var(--surface-2); }
.result-empty { padding: .45rem .5rem; font-size: .85rem; }

/* Billing */
/* Notices, by meaning — never one color for all three, or a failed payment
   looks no more urgent than "we're reviewing your registration". */
.notice { background: var(--accent-soft); border-color: var(--accent-line); }
.notice-action { background: var(--pill-warn-bg); border-color: var(--warn-line); }
.notice-danger { background: var(--pill-fail-bg); border-color: var(--fail-line); }
.notice-action h2, .notice-action strong { color: var(--pill-warn-ink); }
.notice-danger h2, .notice-danger strong { color: var(--pill-fail-ink); }
.stat-value.owes { color: var(--pill-fail-ink); }
.stat-value--alert { color: var(--danger); font-weight: 700; }
.stat-note { font-size: .75rem; color: var(--ink-muted); }
.method-row { padding: .5rem 0; border-bottom: 1px solid var(--border); }
.method-add { display: flex; gap: .5rem; flex-wrap: wrap; }
td.neg { color: var(--pill-paid-ink); }

/* Buttons / layout helpers */
.btn-inline { width: auto; }
.btn-danger { background: var(--surface); color: var(--pill-fail-ink); border-color: var(--fail-line); }
.btn-danger:hover { background: var(--pill-fail-bg); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }

/* Forms */
.form-wide, .page-form { max-width: var(--w-form); }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 1rem; }
select { display: block; width: 100%; margin-top: .3rem; padding: .55rem .65rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); font-size: 1rem; }
fieldset.sensitive { border: 1px solid var(--warn-line); border-radius: var(--radius-sm); padding: .5rem 1rem 1rem; margin: 0 0 1rem; background: var(--surface); }
fieldset.sensitive legend { font-size: .8rem; color: var(--pill-warn-ink); padding: 0 .4rem; }
.checkbox { display: flex; align-items: center; gap: .5rem; font-size: .9rem; color: var(--ink); margin-bottom: 1rem; }
.checkbox.inline { display: inline-flex; margin: 0 1rem .4rem 0; }
.checkbox input { width: auto; margin: 0; }
.tag-picker { margin-bottom: 1rem; }

/* Lists / inline forms */
.clean-list { list-style: none; padding: 0; margin: .5rem 0 0; }
.clean-list li { padding: .35rem 0; border-bottom: 1px solid var(--border); }
.clean-list li:last-child { border-bottom: none; }
.inline-form { display: inline-flex; align-items: center; gap: .4rem; margin: 0; }
.inline-form input, .inline-form select { margin-top: 0; }
/* used across templates but never defined */
.stack { display: grid; gap: .75rem; }
.small { font-size: .85rem; }
/* a form's buttons: their own row, aligned with the fields rather than their labels */
.form-actions { grid-column: 1 / -1; display: flex; gap: .5rem; align-items: center; margin-top: .25rem; }
.inline-label { display: flex; align-items: center; gap: .5rem; margin: 0; }
.inline-label select { width: auto; margin: 0; }

/* Attendance (mobile-friendly, large tap targets) */
.att-row { display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: .6rem 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.att-row:last-child { border-bottom: none; }
.att-name { font-weight: 500; }
.att-buttons { display: flex; gap: .5rem; }
.att-opt { display: inline-flex; align-items: center; justify-content: center; gap: .4rem; cursor: pointer;
  min-height: 44px; min-width: 44px;
  border: 1px solid var(--border); border-radius: 999px; padding: .5rem 1rem; font-size: .9rem; }
.att-opt input { width: auto; margin: 0; }
.att-actions { margin: 0 0 1rem; }
.att-opt:has(input:checked).att-present { background: var(--pill-paid-bg); border-color: var(--paid-line); color: var(--pill-paid-ink); }
.att-opt:has(input:checked).att-late { background: var(--pill-warn-bg); border-color: var(--warn-line); color: var(--pill-warn-ink); }
.att-opt:has(input:checked).att-absent { background: var(--pill-fail-bg); border-color: var(--fail-line); color: var(--pill-fail-ink); }

/* Platform tenant list */
.tenant-list { list-style: none; padding: 0; margin: 0; }
.tenant-list li { display: flex; align-items: center; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid var(--border); }
.dot { width: 14px; height: 14px; border-radius: 50%; background: var(--accent); display: inline-block; }

/* Ledger / statement legibility */
.legend { font-size: .82rem; color: var(--ink-muted); margin: 0 0 .75rem; }
.ledger-type { font-size: .75rem; color: var(--ink-muted); }
.amt { font-variant-numeric: tabular-nums; white-space: nowrap; }
.amt-in  { color: var(--success); }   /* money in: payment / credit / refund */
.amt-owes { color: var(--danger); font-weight: 600; }   /* aged / owed emphasis */
.amt-out { color: var(--ink); }        /* money owed: charge / adjustment up */
.status-note { display: block; font-size: .75rem; color: var(--ink-muted); }

/* Let wide tables scroll horizontally on small screens */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ============================================================
   Responsive — phone-first (instructors & parents).
   No @media existed before; collapse nav, stack forms, scroll tables.
   ============================================================ */
@media (max-width: 640px) {
  .container { padding: 1.25rem 1rem; }

  .nav-toggle { display: inline-flex; }

  /* Collapse primary nav behind the hamburger */
  .topnav {
    display: none;
    flex-direction: column;
    align-items: flex-start;
    gap: .25rem;
    width: 100%;
    order: 3;               /* drop below brand + toggle */
    margin-top: .5rem;
    padding-top: .5rem;
    border-top: 1px solid var(--accent-soft);
  }
  .topnav.is-open { display: flex; }
  .topnav a, .topnav .role-chip { padding: .55rem 0; }
  .topnav a { min-height: 44px; display: flex; align-items: center; }

  .topbar-inner { flex-wrap: wrap; }

  /* Single-column forms */
  .form-grid { grid-template-columns: 1fr; }
  .form-wide { max-width: 100%; }

  /* Stat grids relax to one/two columns naturally via auto-fit already */

  /* Wide tables: scroll horizontally rather than overflow the viewport.
     display:block makes the table its own scroll container (internals still
     render as a grid inside it), so every .table is covered without a
     per-template wrapper. */
  .table { font-size: .88rem; }
  /* Comparison grids (.table-keep) and the wizard's import preview keep their
     columns and scroll; every other table stacks, below. */
  .table.table-keep, .wiz-list {
    font-size: .88rem;
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }

  /* Attendance rows stack name over the option buttons */
  .att-row { align-items: flex-start; }
  .att-buttons { width: 100%; }
  .att-opt { flex: 1; }

  .row-between { flex-wrap: wrap; }
}

/* Two-way message threads (parent↔studio inbox) */
.thread { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.thread .msg { max-width: 80%; padding: .5rem .75rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2); }
.thread .msg-mine { align-self: flex-end; background: var(--accent-soft);
  color: var(--accent-strong); border-color: transparent; }
.thread .msg-them { align-self: flex-start; }
.thread .msg-meta { font-size: .8rem; margin-bottom: .15rem; }
.thread .msg-body { white-space: pre-wrap; }

/* Legal pages + the quiet footer that links to them */
.prose { max-width: var(--w-prose); }
.prose h2 { font-size: 1.1rem; margin: 1.75rem 0 .5rem; }
.prose p, .prose li { line-height: 1.6; }
.prose ul { padding-left: 1.25rem; }
.site-foot { max-width: var(--w-page); margin: 0 auto; padding: 1.5rem 1.25rem 2rem;
             font-size: .85rem; color: var(--ink-muted); }
.site-foot a { color: inherit; }

/* Grouped top menu: a few sections, each a small dropdown */
.navgroup { position: relative; }
.navgroup > summary { list-style: none; cursor: pointer; color: var(--accent-ink);
                      padding: .25rem 0; white-space: nowrap; }
.navgroup > summary::-webkit-details-marker { display: none; }
.navgroup > summary::after { content: "▾"; font-size: .7em; margin-left: .3em; opacity: .75; }
.navgroup > summary:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.navgroup.is-current > summary, .topnav > a[aria-current="page"] { font-weight: 600; }
.navmenu { position: absolute; top: calc(100% + .5rem); left: 0; z-index: 20;
           min-width: 13rem; padding: .35rem 0; background: var(--surface);
           border: 1px solid var(--border); border-radius: var(--radius-sm);
           box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
           display: flex; flex-direction: column; }
.navgroup-account .navmenu { left: auto; right: 0; }
.navmenu a, .navmenu .linklike { color: var(--ink); padding: .45rem .9rem; text-align: left;
                                 font: inherit; text-decoration: none; }
.topnav .navmenu a, .topnav .navmenu .linklike { color: var(--ink); }
.navmenu a:hover, .navmenu .linklike:hover { background: var(--accent-soft); text-decoration: none; }
.navmenu a[aria-current="page"] { font-weight: 600; }
.navmenu .logout-form { margin: 0; border-top: 1px solid var(--border); padding-top: .25rem; }
.topnav { flex: 1; justify-content: flex-end; }
.navgroup-account { margin-left: .5rem; padding-left: 1rem;
                    border-left: 1px solid color-mix(in srgb, var(--accent-ink) 30%, transparent); }
@media (max-width: 640px) {
  .navgroup > summary { padding: .55rem 0; min-height: 44px; display: flex; align-items: center; }
  .navmenu { position: static; box-shadow: none; border: 0; background: transparent;
             padding: 0 0 .5rem .75rem; min-width: 0; }
  .topnav .navmenu a, .topnav .navmenu .linklike { color: var(--accent-ink); padding: .45rem 0; }
  .navmenu a:hover, .navmenu .linklike:hover { background: transparent; text-decoration: underline; }
  .navmenu .logout-form { border-top: 0; }
  .navgroup-account { margin-left: 0; padding-left: 0; border-left: 0; }
}

/* Member home: one attention card, then one compact card per person */
.attention ul { list-style: none; margin: 0; padding: 0; }
.attention li { display: flex; align-items: center; justify-content: space-between;
                gap: 1rem; padding: .6rem 0; border-top: 1px solid var(--border); }
.attention li:first-child { border-top: 0; padding-top: .25rem; }
.person h2 { margin: 0; }
.upcoming { margin: .75rem 0 .25rem; }
.upcoming li { display: flex; justify-content: space-between; gap: 1rem; padding: .3rem 0; }
.actions { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0; }
.contact { margin-top: 2rem; }
@media (max-width: 640px) {
  .upcoming li { flex-direction: column; gap: 0; }
}

/* Numbers line up: right-aligned, equal-width digits */
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Family billing: one balance, one Pay button */
.balance-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.balance-amount { font-size: 2.25rem; font-weight: 700; line-height: 1.1;
                  font-variant-numeric: tabular-nums; }
.balance-amount.owes { color: var(--danger); }
.balance-alert { color: var(--danger); margin: .75rem 0 0; }
.ledger-list { margin: 1rem 0 .5rem; border-top: 1px solid var(--border); }
.ledger-list li { display: flex; justify-content: space-between; gap: 1rem;
                  padding: .5rem 0; border-bottom: 1px solid var(--border); }
.method-row { display: flex; align-items: center; justify-content: space-between;
              gap: .75rem; flex-wrap: wrap; }
.method-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.method-add-wrap { margin-top: 1rem; }
.method-add-wrap > summary { list-style: none; }
.method-add-wrap > summary::-webkit-details-marker { display: none; }
.method-add-wrap[open] > summary { display: none; }
.table th.num, .table td.num { text-align: right; }

/* Quiet row actions: text, not buttons */
.btn-text { background: none; border: 0; padding: .25rem .35rem; font: inherit; font-size: .92rem;
            color: var(--secondary, var(--accent)); text-decoration: underline; cursor: pointer; }
.btn-text:hover { text-decoration-thickness: 2px; }
.method-actions { gap: .15rem; }
@media (max-width: 640px) {
  .history, .history td, .history th { white-space: normal; }
  .history .col-balance { display: none; }
  .history td:first-child { white-space: nowrap; }
  .method-row { padding: .65rem 0; }
}

/* Phones: a table whose rows carry actions (Pay, Book, Buy, Drop…) stacks each
   row instead of scrolling sideways, so the button is never off-screen. The
   first cell reads as the row's title, the last (the actions) gets its own
   full-width line, and the cells between sit inline. Add .table-keep to opt out. */
@media (max-width: 640px) {
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) {
    display: block; overflow: visible; white-space: normal;
  }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) thead { display: none; }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) tbody { display: block; }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) tr {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .75rem;
    padding: .75rem 0; border-bottom: 1px solid var(--border);
  }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) tr:last-child { border-bottom: 0; }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) td {
    display: block; padding: 0; border: 0;
  }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) td:first-child { flex: 1 1 100%; }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) td:last-child { flex: 1 1 100%; margin-top: .4rem; }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) td:last-child .inline-form { flex-wrap: wrap; }
  .table:has(td form, td .btn, td .btn-text):not(.table-keep) td[colspan] { flex-basis: 100%; }
}

/* Book page: grouped by day, one button per class */
.book-for { margin: 0 0 1rem; }
.pass-line { margin: 0; }
.buy-wrap { margin-top: .75rem; }
.buy-wrap > summary { list-style: none; }
.buy-wrap > summary::-webkit-details-marker { display: none; }
.buy-wrap[open] > summary { display: none; }
.book-day h2 { font-size: 1rem; margin: 0 0 .25rem; }
.book-action { text-align: right; white-space: nowrap; }
.book-action .inline-form { justify-content: flex-end; }
@media (max-width: 640px) {
  /* Book: the button shares the line with "6 spots left" */
  .book-day .table:has(td form, td .btn, td .btn-text):not(.table-keep) tr { align-items: center; }
  .book-day .table:has(td form, td .btn, td .btn-text):not(.table-keep) td.book-action {
    flex: 0 0 auto; margin: 0 0 0 auto;
  }
}

/* Public studio page */
.pub-hero { padding: var(--space-6) 0 var(--space-7); max-width: var(--w-prose); }
.pub-hero h1 { font-size: clamp(1.8rem, 4.5vw, 2.6rem); line-height: 1.15; margin: 0 0 .75rem;
               text-wrap: balance; }
.pub-lede { font-size: 1.1rem; color: var(--ink-muted); margin: 0 0 1.5rem; }
.pub-cta { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.btn-lg { padding: .7rem 1.4rem; font-size: 1.05rem; }
.pub-schedule h2, .pub-section h2 { font-size: 1.25rem; margin: 0 0 .5rem; }
.pub-day { font-size: .75rem; text-transform: uppercase; letter-spacing: .06em;
           color: var(--ink-muted); font-weight: 600; margin: 1.25rem 0 .25rem; }
.pub-list { list-style: none; margin: 0; padding: 0; }
.pub-list li { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
               padding: .55rem 0; border-bottom: 1px solid var(--border); }
.pub-list li:last-child { border-bottom: 0; }
.pub-name { font-weight: 600; }
.pub-meta { display: block; font-size: .85rem; }
.pub-right { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pub-section { margin: 2rem 0; }
.pub-review { margin: 0 0 1rem; padding: 0 0 1rem; border-bottom: 1px solid var(--border); }
.pub-review p { margin: .25rem 0; }
.pub-stars { color: var(--accent); letter-spacing: .1em; }
.pub-contact { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem; margin: 0; }
.pub-contact dt { color: var(--ink-muted); }
.pub-contact dd { margin: 0; }
@media (max-width: 640px) {
  /* the opened menu drops below the brand line, full width */
  .topnav { flex: 1 1 100%; justify-content: flex-start; }
}

/* One page-header pattern: title left, one primary action, extras under More */
.page-head { display: flex; align-items: center; justify-content: space-between;
             gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.page-head h1 { margin: 0; }
.page-actions { display: flex; align-items: center; gap: .5rem; }
.back-link { display: inline-block; font-size: .9rem; margin-bottom: .5rem; }
.more { position: relative; }
.more > summary { list-style: none; }
.more > summary::-webkit-details-marker { display: none; }
.more-menu { position: absolute; right: 0; top: calc(100% + .35rem); z-index: 15; min-width: 14rem;
             background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
             box-shadow: 0 8px 24px rgba(16, 24, 40, .12); padding: .35rem 0; display: flex; flex-direction: column; }
.more-menu a { padding: .45rem .9rem; color: var(--ink); text-decoration: none; }
.more-menu a:hover { background: var(--accent-soft); }
.search-row { display: flex; align-items: center; gap: .75rem; margin: 0 0 1rem; }
.search-row input[type=search] { max-width: 24rem; }
.hh-person { padding: .6rem 0; border-bottom: 1px solid var(--border); }
.hh-person:last-child { border-bottom: 0; }
.hh-person p { margin: .2rem 0 0; }
.ledger-list .lines { display: block; font-size: .85rem; }
.nowrap { white-space: nowrap; }
/* A "reveal" disclosure: its button disappears once the form is open */
.reveal > summary { list-style: none; }
.reveal > summary::-webkit-details-marker { display: none; }
.reveal[open] > summary { display: none; }

/* On phones every table with column headings stacks: one block per row, the
   first cell as its title, an amount at the right, and the rest below — each
   carrying its column heading (copied onto the cells by base.html) so a number
   is never left unexplained. Read-only tables used to scroll sideways instead,
   hiding columns past the edge. A short table with no headings just wraps.
   .table-keep opts a true comparison grid out. */
@media (max-width: 640px) {
  .table:has(thead):not(.table-keep) { display: block; overflow: visible; white-space: normal; }
  .table:has(thead):not(.table-keep) thead { display: none; }
  .table:has(thead):not(.table-keep) tbody, .table:has(thead):not(.table-keep) tfoot { display: block; }
  .table:has(thead):not(.table-keep) tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .75rem;
                               padding: .75rem 0; border-bottom: 1px solid var(--border); }
  .table:has(thead):not(.table-keep) tr:last-child { border-bottom: 0; }
  .table:has(thead):not(.table-keep) td, .table:has(thead):not(.table-keep) th { display: block; padding: 0; border: 0; }
  .table:has(thead):not(.table-keep) td:first-child { flex: 1 1 auto; order: 0; }
  .table:has(thead):not(.table-keep) td.num { order: 1; margin-left: auto; text-align: right; }
  .table:has(thead):not(.table-keep) td:not(:first-child):not(.num) { flex: 1 1 100%; order: 2; }
  .table:has(thead):not(.table-keep) td[data-label]:not(:first-child)::before,
  .table:has(thead):not(.table-keep) td.num[data-label]:first-child::before {
    content: attr(data-label); display: inline-block; min-width: 6.5rem; margin-right: .5rem;
    font-size: .78rem; color: var(--ink-muted); }
  /* beside a row's name, its amount at the top right explains itself */
  .table:has(thead):not(.table-keep) tr:has(> td:first-child:not(.num)) td.num[data-label]::before { content: none; }
  /* a row of only figures (an aging summary): each label left, figure right */
  .table:has(thead):not(.table-keep) tr:not(:has(> td:not(.num))) td {
    flex: 1 1 100%; display: flex; justify-content: space-between; margin: 0; }
  .table:has(thead):not(.table-keep) tr:not(:has(> td:not(.num))) td::before { min-width: 0; text-align: left; }
  .table:has(thead):not(.table-keep) td:empty { display: none; }
}
}
.form-buttons { display: flex; gap: .5rem; align-items: flex-end; }
.page-actions .btn { white-space: nowrap; }
.page-actions .inline-form { flex-wrap: nowrap; }
@media (max-width: 640px) {
  .page-actions { flex-wrap: wrap; }
  .page-actions .inline-form { flex-wrap: wrap; }
}

/* Wide pages (the calendar): more room before anything scrolls */
.container.container--wide { max-width: var(--w-wide); }

/* Settings: short sections, one save bar that stays in reach */
.settings-section h2 { font-size: 1.05rem; margin: 0 0 .75rem; }
.settings-section .help + .checkbox, .settings-section .checkbox + .help { margin-top: .15rem; }
.save-bar { position: sticky; bottom: 0; padding: .75rem 0; background: linear-gradient(transparent, var(--bg) 35%);
            display: flex; justify-content: flex-end; }

/* Spacing utilities — the only way a template adjusts a gap (no inline margins).
   Last in the file so they win over a component's own margin. */
.m-0 { margin: 0; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }
.mt-1 { margin-top: var(--space-1); } .mb-1 { margin-bottom: var(--space-1); } .my-1 { margin-block: var(--space-1); } .ml-1 { margin-left: var(--space-1); }
.mt-2 { margin-top: var(--space-2); } .mb-2 { margin-bottom: var(--space-2); } .my-2 { margin-block: var(--space-2); } .ml-2 { margin-left: var(--space-2); }
.mt-3 { margin-top: var(--space-3); } .mb-3 { margin-bottom: var(--space-3); } .my-3 { margin-block: var(--space-3); } .ml-3 { margin-left: var(--space-3); }
.mt-4 { margin-top: var(--space-4); } .mb-4 { margin-bottom: var(--space-4); } .my-4 { margin-block: var(--space-4); } .ml-4 { margin-left: var(--space-4); }
.mt-5 { margin-top: var(--space-5); } .mb-5 { margin-bottom: var(--space-5); } .my-5 { margin-block: var(--space-5); } .ml-5 { margin-left: var(--space-5); }
.mt-6 { margin-top: var(--space-6); } .mb-6 { margin-bottom: var(--space-6); } .my-6 { margin-block: var(--space-6); } .ml-6 { margin-left: var(--space-6); }
.mt-7 { margin-top: var(--space-7); } .mb-7 { margin-bottom: var(--space-7); } .my-7 { margin-block: var(--space-7); } .ml-7 { margin-left: var(--space-7); }
.center-block { margin-inline: auto; }

/* Staff inbox: name and time, then a one-line preview of the last message */
.inbox-list li + li { border-top: 1px solid var(--border); }
.inbox-row { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3) 0;
             color: inherit; text-decoration: none; }
.inbox-row:hover strong, .inbox-row:hover > span:first-child > span:first-child { text-decoration: underline; }
.inbox-preview { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: .9rem; }

/* Billing's payments-status chip doubles as the way to Payouts */
.pay-state { text-decoration: none; align-self: center; font-size: .8rem; }
.pay-state:hover { text-decoration: underline; }

/* Attendance: the day's classes as full-width rows, big enough between classes */
.day-list { display: grid; gap: var(--space-2); }
.day-row { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4);
           min-height: 56px; padding: var(--space-3) var(--space-5); background: var(--surface);
           border: 1px solid var(--border); border-radius: var(--radius); color: inherit;
           text-decoration: none; box-shadow: var(--shadow); }
.day-row:hover { border-color: var(--accent); }

/* Palette picker (setup's first step and admin Branding) */
.palette-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: var(--space-2); }
.palette-opt { display: flex; align-items: center; gap: var(--space-2); cursor: pointer;
               border: 2px solid var(--border); border-radius: var(--radius);
               padding: var(--space-2) var(--space-3); background: var(--surface); }
.palette-opt:has(input:checked) { border-color: var(--accent); }
.palette-opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.palette-opt input { position: absolute; opacity: 0; }
.palette-opt .swatch { display: inline-flex; border-radius: 999px; overflow: hidden;
                       border: 1px solid var(--border); flex: none; }
.palette-opt .swatch-half { width: 20px; height: 28px; display: block; }
.palette-name { font-size: .92rem; }

/* A fieldset that's just a group with a label-style legend (no box) */
fieldset.m-0 { border: 0; padding: 0; min-width: 0; }
.label-like { font-size: .85rem; font-weight: 500; color: var(--ink); padding: 0; margin-bottom: var(--space-2); }
