/* CoverMe component layer (phase 1s). Hand-written from the design system's component briefs
   (design-export/readme.md and the per-component prompt.md files). Loaded after the tokens.

   Rules (design system "Visual foundations"):
   - Only semantic tokens. Never a raw --brand-* / --neutral-<step> or a hex literal: the dark
     theme overrides the semantic layer and leaves the ramps alone.
   - Interactive edges use --border-control (3:1, WCAG 1.4.11); cards use --border-default.
   - No inline styles anywhere (CSP style-src 'self'). */

/* --- Utilities ------------------------------------------------------------------------ */

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.icon {
  display: block;
  flex: none;
}

h1,
h2,
h3,
p,
ul,
dl,
dd {
  margin: 0;
}

/* --- Shell ------------------------------------------------------------------------------ */

html {
  background: var(--surface-bg);
}

.shell {
  min-height: 100vh;
  min-height: 100dvh;
}

.skip-link {
  position: absolute;
  top: calc(var(--safe-top) + var(--space-2));
  left: calc(env(safe-area-inset-left, 0px) + var(--space-2));
  z-index: var(--z-toast);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-control);
  background: var(--surface-inverse);
  color: var(--text-inverse);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  transform: translateY(calc(-100% - var(--space-4) - var(--safe-top)));
}

.skip-link:focus,
.skip-link:hover {
  color: var(--text-inverse);
  transform: none;
}

/* The page's own focus target after "Skip to content": no ring on the whole main area. */
.page:focus {
  outline: none;
}

.page {
  width: 100%;
  max-width: var(--container-content-max);
  margin: 0 auto;
  padding: var(--space-4) calc(var(--space-3) + env(safe-area-inset-right, 0px))
    var(--space-8) calc(var(--space-3) + env(safe-area-inset-left, 0px));
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Clear the fixed tab bar and the iPhone home indicator. */
.shell--tabs .page {
  padding-bottom: calc(var(--tabbar-height) + var(--safe-bottom) + var(--space-8));
}

.page--narrow {
  max-width: var(--container-mobile-max);
}

.page--auth {
  padding-top: calc(var(--safe-top) + var(--space-16));
}

/* Keep the app-bar title in line with a narrow page's content (S-02 at desktop width). */
.shell:has(.page--narrow) .app-bar__row {
  max-width: var(--container-mobile-max);
}

/* S-01 sits on the card surface rather than the page grey (design system S-01). */
html:has(.page--auth),
.shell:has(.page--auth) {
  background: var(--surface-card);
}

/* --- Type ------------------------------------------------------------------------------- */

.page-title {
  font-size: var(--text-title-lg-size);
  line-height: var(--text-title-lg-lh);
  font-weight: var(--text-title-lg-weight);
  letter-spacing: var(--text-title-lg-tracking);
}

.lede {
  color: var(--text-secondary);
}

.eyebrow {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.help {
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  color: var(--text-secondary);
}

.fine-print {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.prose p + p {
  margin-top: var(--space-3);
}

/* --- Wordmark (brand lockup, S-01) -------------------------------------------------------- */

.wordmark {
  font-size: var(--text-title-size);
  line-height: 1;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--text-title-tracking);
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
}

a.wordmark:hover {
  color: var(--text-primary);
}

.wordmark__me {
  color: var(--color-primary-text);
}

.wordmark--lg {
  font-size: var(--text-title-lg-size);
  letter-spacing: var(--text-title-lg-tracking);
}

.lockup {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

/* The brand mark (app/web/static/img/icon.svg) beside the live-text wordmark. */
.lockup__mark {
  flex: none;
  width: 48px;
  height: 48px;
}

.lockup .lockup__gym {
  flex-basis: 100%;
}

/* --- App bar ------------------------------------------------------------------------------- */

.app-bar {
  position: sticky;
  top: 0;
  z-index: var(--z-appbar);
  padding-top: var(--safe-top);
  background: var(--surface-card);
  border-bottom: 1px solid var(--border-subtle);
}

.app-bar__row {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--appbar-height);
  max-width: var(--container-content-max);
  margin: 0 auto;
  padding: 0 calc(var(--space-2) + env(safe-area-inset-right, 0px)) 0
    calc(var(--space-3) + env(safe-area-inset-left, 0px));
}

.app-bar__title {
  font-size: var(--text-title-size);
  line-height: var(--text-title-lh);
  font-weight: var(--text-title-weight);
  letter-spacing: var(--text-title-tracking);
}

/* --- Tab bar --------------------------------------------------------------------------------- */

.tab-bar {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: var(--z-tabbar);
  display: flex;
  justify-content: center;
  padding: 0 env(safe-area-inset-right, 0px) var(--safe-bottom) env(safe-area-inset-left, 0px);
  background: var(--surface-card);
  border-top: 1px solid var(--border-subtle);
}

.tab-bar__tab {
  flex: 1 1 0;
  max-width: 180px;
  min-height: var(--tabbar-height);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 6px 2px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out);
}

.tab-bar__tab:hover {
  color: var(--text-primary);
  background: var(--neutral-subtle);
}

.tab-bar__tab[aria-current="page"] {
  color: var(--color-primary-text);
}

/* 11px micro-label: platform convention, repeats the tab's accessible name (design system
   "Type"). --text-secondary, never tertiary. */
.tab-bar__label {
  font-size: 11px;
  line-height: 11px;
  font-weight: var(--weight-semibold);
}

/* --- Buttons ------------------------------------------------------------------------------------ */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  padding: 0 var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  font-size: var(--text-body-size);
  line-height: 1.2;
  font-weight: var(--weight-semibold);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: var(--motion-press);
}

.button:active {
  transform: scale(0.98);
}

.button .icon {
  width: 18px;
  height: 18px;
}

.button--lg {
  min-height: 52px;
  padding: 0 var(--space-5);
  font-size: var(--text-body-lg-size);
}

.button--block {
  width: 100%;
}

.button--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.button--primary:hover {
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
}

.button--primary:active {
  background: var(--color-primary-pressed);
}

.button--secondary {
  background: var(--surface-card);
  border-color: var(--border-control);
  color: var(--text-primary);
}

.button--secondary:hover {
  background: var(--neutral-subtle);
}

.button--secondary:active {
  background: var(--surface-sunken);
}

.button--tertiary {
  background: transparent;
  color: var(--color-primary-text);
}

.button--tertiary:hover {
  background: var(--neutral-subtle);
  color: var(--color-primary-text);
}

.button--destructive {
  background: var(--danger-solid);
  color: var(--danger-on-solid);
}

.button--destructive:hover {
  background: var(--danger-hover);
  color: var(--danger-on-solid);
}

.button--destructive:active {
  background: var(--danger-pressed);
}

/* Disabled is a fill and a text colour, never opacity (design system "Interaction states"). */
.button:disabled,
.button[aria-disabled="true"] {
  background: var(--neutral-subtle);
  border-color: var(--border-default);
  color: var(--text-disabled);
  cursor: not-allowed;
  transform: none;
}

/* --- Form fields (Field, TextField) ------------------------------------------------------------- */

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.stack--after {
  align-items: flex-start;
  margin-top: var(--space-2);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field__label {
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.field__hint {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  color: var(--danger-text);
}

.field__error .icon {
  margin-top: 3px;
}

.field__error--list {
  flex-direction: column;
  gap: var(--space-1);
  padding: 0;
  list-style: none;
}

.field__error--list li {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

/* An error replaces the hint rather than stacking under it (Field brief). */
.field:has(.field__error) .field__hint {
  display: none;
}

.input {
  width: 100%;
  min-height: var(--tap-min);
  padding: 0 var(--space-3);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-field);
  background: var(--surface-card);
  color: var(--text-primary);
  font-size: var(--text-body-size);
  line-height: var(--text-body-lh);
}

.input[aria-invalid="true"] {
  border-color: var(--danger-solid);
}

.input:disabled {
  background: var(--surface-sunken);
  color: var(--text-disabled);
  cursor: not-allowed;
}

/* --- Cards ----------------------------------------------------------------------------------------- */

.card {
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  box-shadow: var(--elevation-1);
}

.card > .eyebrow {
  margin-bottom: var(--space-2);
}

.details__row {
  display: grid;
  grid-template-columns: minmax(7rem, 30%) 1fr;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--border-subtle);
}

.details__row:first-child {
  border-top: 0;
}

.details dt {
  font-size: var(--text-label-size);
  line-height: var(--text-body-lh);
  color: var(--text-secondary);
}

.details dd {
  overflow-wrap: anywhere;
}

/* --- Banners ------------------------------------------------------------------------------------------ */

.banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--neutral-border);
  border-radius: var(--radius-card);
  background: var(--neutral-subtle);
  color: var(--text-primary);
}

/* hidden must win over display: flex, or a banner a script has hidden still shows. */
.banner[hidden] {
  display: none;
}

/* The Notifications-off banner's wrapper (11.1, FR-NOT-09): no box, and no gap in the page's
   stack, once the browser has decided neither mode shows on this device. */
.push-banner:not(:has(> .banner:not([hidden]))) {
  display: none;
}

/* The quiet mode: one line, dismissible, informational rather than a warning. */
.banner--nudge {
  align-items: center;
}

/* In the nudge the sentence is the way to S-03, so it stays one line at 390px (11.1). */
.banner__link {
  flex: 1 1 auto;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.banner__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  margin: calc(-1 * var(--space-2)) calc(-1 * var(--space-2)) calc(-1 * var(--space-2)) 0;
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  color: inherit;
  cursor: pointer;
}

.banner__icon {
  margin-top: 1px;
  color: var(--text-secondary);
}

.banner__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.banner__title {
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  font-weight: var(--weight-semibold);
}

.banner__body {
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
}

/* A banner is a flex row; without this its action button shrinks below its own label and
   breaks it over two lines ("Turn / on", Phase 3a defect, found by looking at T-01). */
.banner .button {
  flex: none;
  white-space: nowrap;
  align-self: center;
}

.banner--warning {
  border-color: var(--warning-border);
  background: var(--warning-subtle);
  color: var(--warning-text);
}

.banner--warning .banner__icon {
  color: var(--warning-solid);
}

.banner--info {
  border-color: var(--info-border);
  background: var(--info-subtle);
  color: var(--info-text);
}

.banner--info .banner__icon {
  color: var(--info-solid);
}

.banner--success {
  border-color: var(--success-border);
  background: var(--success-subtle);
  color: var(--success-text);
}

.banner--success .banner__icon {
  color: var(--success-solid);
}

.banner--danger {
  border-color: var(--danger-border);
  background: var(--danger-subtle);
  color: var(--danger-text);
}

.banner--danger .banner__icon {
  color: var(--danger-solid);
}

/* --- Empty state ---------------------------------------------------------------------------------------- */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
  text-align: center;
}

.empty-state__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: var(--space-1);
  border-radius: var(--radius-avatar);
  background: var(--neutral-subtle);
  color: var(--text-tertiary);
}

.empty-state__title {
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-lh);
  font-weight: var(--weight-semibold);
}

.empty-state__body {
  max-width: 32rem;
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  color: var(--text-secondary);
}

/* ===========================================================================================
   Admin screens (phase 1b): A-06, A-07, A-08, A-10. Same rules as above: semantic tokens only,
   no inline styles. Component names follow the design system (StatusChip -> .tag,
   ClassTypeChip -> .ct-chip, Avatar -> .avatar, DataTable -> .table, Dialog -> .dialog).
   =========================================================================================== */

/* --- Layout -------------------------------------------------------------------------------- */

/* Slots, Users and the upload preview run wider than reading content (design "Layout rules"). */
.page--wide {
  max-width: var(--container-admin-max);
}

.shell:has(.page--wide) .app-bar__row {
  max-width: var(--container-admin-max);
}

.section {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.section__head {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.section__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.card--flush {
  padding: 0;
  overflow: hidden;
}

.card__foot {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-subtle);
}

.muted-note {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.cm-tabular {
  font-variant-numeric: tabular-nums;
}

.lockup__gym {
  margin-top: var(--space-2);
  font-size: var(--text-body-size);
  color: var(--text-secondary);
}

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.page-head__sub {
  color: var(--text-secondary);
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
}

/* --- App bar back link ------------------------------------------------------------------- */

.icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  margin-left: calc(-1 * var(--space-2));
  border-radius: var(--radius-control);
  color: var(--text-primary);
}

.icon-link:hover {
  background: var(--neutral-subtle);
  color: var(--text-primary);
}

/* --- Buttons: small size, quiet destructive, rows ------------------------------------------ */

/* 36px visually; the ::after keeps the tap target at 44px (12.5). */
.button--sm {
  position: relative;
  min-height: 36px;
  padding: 0 var(--space-3);
  font-size: var(--text-label-size);
}

.button--sm::after {
  content: "";
  position: absolute;
  inset: -4px 0;
}

.button--sm .icon {
  width: 16px;
  height: 16px;
}

.button--destructive-quiet {
  background: transparent;
  border-color: var(--danger-border);
  color: var(--danger-text);
}

.button--destructive-quiet:hover {
  background: var(--danger-subtle);
  color: var(--danger-text);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* --- Status tag (design system StatusChip) ------------------------------------------------- */

.tag {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 0 var(--space-2);
  border: 1px solid var(--neutral-border);
  border-radius: var(--radius-chip);
  background: var(--neutral-subtle);
  color: var(--neutral-text);
  font-size: var(--text-caption-size);
  line-height: 1.2;
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}

.tag--success {
  border-color: var(--success-border);
  background: var(--success-subtle);
  color: var(--success-text);
}

.tag--warning {
  border-color: var(--warning-border);
  background: var(--warning-subtle);
  color: var(--warning-text);
}

.tag--danger {
  border-color: var(--danger-border);
  background: var(--danger-subtle);
  color: var(--danger-text);
}

.tag--info {
  border-color: var(--info-border);
  background: var(--info-subtle);
  color: var(--info-text);
}

.tag--muted {
  border-color: var(--border-default);
  background: var(--surface-sunken);
  color: var(--text-secondary);
}

/* --- Class-type chip (design system ClassTypeChip). The label stays --text-primary: identity
   is carried by the dot and the border, never by colour alone. ---------------------------- */

.ct-01 { --ct: var(--ct-01); }
.ct-02 { --ct: var(--ct-02); }
.ct-03 { --ct: var(--ct-03); }
.ct-04 { --ct: var(--ct-04); }
.ct-05 { --ct: var(--ct-05); }
.ct-06 { --ct: var(--ct-06); }
.ct-07 { --ct: var(--ct-07); }
.ct-08 { --ct: var(--ct-08); }
.ct-09 { --ct: var(--ct-09); }
.ct-10 { --ct: var(--ct-10); }
.ct-11 { --ct: var(--ct-11); }
.ct-12 { --ct: var(--ct-12); }
.ct-13 { --ct: var(--ct-13); }
.ct-14 { --ct: var(--ct-14); }
.ct-15 { --ct: var(--ct-15); }
.ct-16 { --ct: var(--ct-16); }
.ct-17 { --ct: var(--ct-17); }
.ct-18 { --ct: var(--ct-18); }
.ct-19 { --ct: var(--ct-19); }
.ct-20 { --ct: var(--ct-20); }

.ct-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 2px 10px 2px 8px;
  border: 1px solid color-mix(in srgb, var(--ct, var(--ct-01)) calc(var(--ct-chip-border-alpha) * 100%), transparent);
  border-radius: var(--radius-chip);
  background: color-mix(in srgb, var(--ct, var(--ct-01)) calc(var(--ct-tint-alpha) * 100%), transparent);
  color: var(--text-primary);
  font-size: var(--text-label-size);
  line-height: 1.2;
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

.ct-chip--sm {
  min-height: 22px;
  padding: 1px 8px 1px 6px;
  font-size: var(--text-caption-size);
}

.ct-chip__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-avatar);
  background: var(--ct, var(--ct-01));
}

/* --- Avatar (initials on a generated accent) ------------------------------------------------- */

.avatar {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid color-mix(in srgb, var(--ct, var(--ct-02)) 34%, transparent);
  border-radius: var(--radius-avatar);
  background: color-mix(in srgb, var(--ct, var(--ct-02)) 16%, var(--surface-card));
  color: color-mix(in srgb, var(--ct, var(--ct-02)) 60%, var(--text-primary));
  font-size: 11px;
  line-height: 1;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
}

.avatar--m {
  width: 36px;
  height: 36px;
  font-size: var(--text-caption-size);
}

.avatar--muted {
  border-color: var(--border-default);
  background: var(--neutral-subtle);
  color: var(--text-secondary);
}

.avatar-group {
  display: inline-flex;
  align-items: center;
}

.avatar-group .avatar + .avatar {
  margin-left: -8px;
  box-shadow: 0 0 0 2px var(--surface-card);
}

.avatar-group__more {
  margin-left: 6px;
  font-size: var(--text-caption-size);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* --- Toast: confirms a completed action on the page it returns to -------------------------- */

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--success-border);
  border-radius: var(--radius-card);
  background: var(--success-subtle);
  color: var(--success-text);
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  font-weight: var(--weight-semibold);
}

.toast__icon {
  color: var(--success-solid);
}

/* --- Row list (settings rows, the admin menu) ---------------------------------------------- */

.row-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.row-list > li + li {
  border-top: 1px solid var(--border-subtle);
}

.row-list__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-2) var(--space-4);
}

.row-list__main {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  min-width: 0;
}

.row-list__icon {
  display: flex;
  color: var(--text-secondary);
}

.row-list__title {
  font-weight: var(--weight-semibold);
}

.row-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-2) var(--space-4);
  color: var(--text-primary);
  text-decoration: none;
}

.row-link:hover {
  background: var(--neutral-subtle);
  color: var(--text-primary);
}

.row-link__text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.row-link__help {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.row-link__chevron {
  color: var(--text-tertiary);
}

/* --- Form layout: grids, selects, fieldsets, segmented control ----------------------------- */

.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 720px) {
  .form-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* The chevron is drawn with two gradients on the select itself, so it stays beside the control
   whatever hint or error follows it. No image and no inline SVG. */
select.input {
  padding-right: var(--space-8);
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-secondary) 50%),
    linear-gradient(135deg, var(--text-secondary) 50%, transparent 50%);
  background-position:
    right 20px center,
    right 14px center;
  background-size: 6px 6px;
  background-repeat: no-repeat;
  cursor: pointer;
}

select.input[multiple] {
  padding-right: var(--space-1);
  background-image: none;
}
.input--multi {
  padding: var(--space-1);
  min-height: 150px;
}

.input--multi option {
  padding: var(--space-2);
  border-radius: 6px;
}

.fieldset {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.fieldset > legend {
  padding: 0;
  margin-bottom: 6px;
}

.field__hint--warning {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  color: var(--warning-text);
}

.field__hint--warning .icon {
  margin-top: 2px;
}

/* "Add new type": shown only while "Add new type" is chosen (CSS :has, no script). */
.new-type {
  display: none;
}

.form-grid:has(select[data-new-type] option[value="new"]:checked) .new-type {
  display: flex;
}

.segmented {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border-control);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
}

.segmented__option {
  position: relative;
  display: flex;
}

.segmented__input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.segmented__label {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

.segmented__input:checked + .segmented__label {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.segmented__input:focus-visible + .segmented__label {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: 1px;
}

/* --- Checkbox (a native box, sized for a thumb) ---------------------------------------------- */

.check {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  cursor: pointer;
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

.check input,
.checkbox {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--color-primary);
  cursor: pointer;
}

/* --- Filters bar (A-07, A-08) ---------------------------------------------------------------- */

.filters {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  align-items: end;
  padding: var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.filters__check,
.filters__actions {
  align-self: center;
}

@media (min-width: 900px) {
  .filters {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }
}

/* --- A-07 slot list ------------------------------------------------------------------------ */

.slot-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.slot-day {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.slot-day__head {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.slot-rows {
  margin: 0;
  list-style: none;
  padding: 0;
}

.slot-rows > li + li {
  border-top: 1px solid var(--border-subtle);
}

/* Phone: time and type on the first line, trainers and status under them. */
.slot-row {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto;
  grid-template-areas:
    "time type chev"
    "time who chev"
    "time meta chev";
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  color: var(--text-primary);
  text-decoration: none;
}

.slot-row:hover {
  background: var(--neutral-subtle);
  color: var(--text-primary);
}

.slot-row__time {
  grid-area: time;
  align-self: start;
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-lh);
  font-weight: var(--weight-semibold);
}

.slot-row__type {
  grid-area: type;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.slot-row__trainers {
  grid-area: who;
}

.slot-row__status {
  grid-area: meta;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.slot-row__source {
  grid-area: meta;
  justify-self: end;
  font-size: var(--text-caption-size);
  color: var(--text-secondary);
}

.slot-row__chevron {
  grid-area: chev;
  color: var(--text-tertiary);
}

/* Desktop: one line per slot, as a table would lay it out (design "DataTable"). */
@media (min-width: 900px) {
  .slot-row {
    grid-template-columns: 5.5rem minmax(0, 1.4fr) minmax(0, 1fr) 13rem 5rem auto;
    grid-template-areas: "time type who status source chev";
    min-height: 56px;
    padding: var(--space-2) var(--space-4);
  }

  .slot-row__time {
    align-self: center;
    font-size: var(--text-body-size);
  }

  .slot-row__status {
    grid-area: status;
  }

  .slot-row__source {
    grid-area: source;
    justify-self: start;
  }
}

.club-label {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--text-caption-size);
  color: var(--text-secondary);
}

/* --- A-07 slot detail ---------------------------------------------------------------------- */

.slot-summary {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.slot-summary__main {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.slot-key {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.slot-key code {
  font-family: var(--font-mono);
  font-size: var(--text-caption-size);
  overflow-wrap: anywhere;
}

.add-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.add-row__field {
  flex: 1 1 14rem;
}

/* --- A-08 users list ----------------------------------------------------------------------- */

.user-rows {
  margin: 0;
  padding: 0;
  list-style: none;
}

.user-rows > li + li {
  border-top: 1px solid var(--border-subtle);
}

.user-head {
  display: none;
}

/* Phone: a card per person, name first, the facts wrapped beneath it. */
.user-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-3) var(--space-4);
  color: var(--text-primary);
  text-decoration: none;
}

.user-row:hover {
  background: var(--neutral-subtle);
  color: var(--text-primary);
}

.user-row__name {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.user-row__names {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.user-row__full {
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

.user-row__display,
.user-row__role,
.user-row__slots,
.user-row__login,
.user-row__clubs {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

/* Desktop: a table, one line per person (design "DataTable"). */
@media (min-width: 900px) {
  .user-head,
  .user-row {
    display: grid;
    grid-template-columns: minmax(0, 2fr) 6rem 6.5rem 5rem 10rem minmax(0, 1.4fr);
    align-items: center;
    column-gap: var(--space-3);
  }

  .user-grid--multi {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) 6rem 6.5rem 5rem 10rem minmax(0, 1.4fr);
  }

  .user-head {
    padding: var(--space-2) var(--space-4);
    border-bottom: 1px solid var(--border-default);
    background: var(--surface-sunken);
    font-size: var(--text-caption-size);
    font-weight: var(--weight-semibold);
    color: var(--text-secondary);
  }

  .user-row {
    min-height: 60px;
    padding: var(--space-2) var(--space-4);
  }

  .user-row__role,
  .user-row__slots,
  .user-row__login,
  .user-row__clubs {
    font-size: var(--text-label-size);
  }
}

/* --- A-08 form: club chips, the slot picker ------------------------------------------------- */

.chip-checks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chip-check {
  position: relative;
  display: inline-flex;
}

.chip-check__input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.chip-check__label {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding: 0 var(--space-4);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-chip);
  background: var(--surface-card);
  color: var(--text-primary);
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

.chip-check__input:checked + .chip-check__label {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
  color: var(--color-on-primary-subtle);
}

.chip-check__input:focus-visible + .chip-check__label {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}

.picker {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.picker__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
}

.picker__search {
  flex: 1 1 14rem;
}

.picker__list {
  border: 1px solid var(--border-control);
  border-radius: var(--radius-control);
  overflow: hidden;
}

.picker__club {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px var(--space-3);
  border-bottom: 1px solid var(--color-primary-border);
  background: var(--color-primary-subtle);
  color: var(--color-on-primary-subtle);
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

.picker__count {
  margin-left: auto;
  font-size: var(--text-caption-size);
  font-weight: var(--weight-medium);
}

.picker__day {
  padding: 6px var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.picker__rows {
  margin: 0;
  padding: 0;
  list-style: none;
}

.picker__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-card);
  cursor: pointer;
}

.picker__row:has(input:checked) {
  background: var(--color-primary-subtle);
}

.picker__time {
  flex: none;
  width: 4.25rem;
  font-weight: var(--weight-semibold);
}

.picker__what {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}

.picker__who {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.picker__empty {
  padding: var(--space-5);
  text-align: center;
  font-size: var(--text-label-size);
  color: var(--text-secondary);
}

/* "In current timetable only" (off by default): CSS alone, so it works without script. */
.picker:has(.picker__only:checked) .picker__row[data-dormant] {
  display: none;
}

[hidden] {
  display: none !important;
}

/* --- A-08 account actions, the temporary password, confirmations --------------------------- */

.action-row {
  flex-wrap: wrap;
}

.action-row__text {
  flex: 1 1 16rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.secret {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-control);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
  container-type: inline-size;
}

/* F30: a credential read aloud is one unbroken line. It takes the whole row (Copy wraps below)
   and never breaks, so it shrinks instead, and only as far as it must. Passwords are 14 to 29
   characters (6.2: three words of 3 to 8 letters and two digits), about 0.62em each here. Up to
   24 fit the box at full size on a 390px phone; the template marks longer ones --long. Both are
   capped to the box, so a narrower phone shrinks rather than overflows. */
.secret__value {
  flex: 1 1 100%;
  font-family: var(--font-mono);
  font-size: min(var(--text-title-size), 100cqi / 15);
  line-height: var(--text-title-lh);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.secret__value--long {
  font-size: min(var(--text-title-size), 100cqi / 18.5);
}

.impact {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3);
  list-style: none;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
}

.impact li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.impact .icon {
  margin-top: 2px;
  color: var(--text-secondary);
}

/* --- A-06 apply to upcoming classes (a Dialog with a checklist) ----------------------------- */

.stack--tight {
  gap: var(--space-1);
}

.dialog-card {
  box-shadow: var(--elevation-2);
}

.dialog-card__lead {
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-lh);
  font-weight: var(--weight-semibold);
}

.dialog-card__question {
  color: var(--text-secondary);
}

.checklist {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  overflow: hidden;
}

.checklist > li + li {
  border-top: 1px solid var(--border-subtle);
}

.checklist__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
}

.checklist__date {
  flex: none;
  width: 6.5rem;
  font-weight: var(--weight-semibold);
}

.checklist__change {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
}

.checklist__now {
  color: var(--text-secondary);
}

.checklist__after {
  font-weight: var(--weight-semibold);
}

.checklist--muted .checklist__row {
  cursor: default;
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

/* --- A-10 Timetable group: a number with its unit beside it (design "number with unit") ----- */

.input-unit {
  display: flex;
  align-items: stretch;
  gap: var(--space-2);
}

.input--number {
  max-width: 8rem;
  font-variant-numeric: tabular-nums;
}

.input-unit__unit {
  display: flex;
  align-items: center;
  color: var(--text-secondary);
  font-size: var(--text-body-size);
  line-height: var(--text-body-lh);
}

/* ===========================================================================================
   Phase 1c: A-04 Upload timetable and A-05 Upload preview and resolve
   =========================================================================================== */

/* --- How-to steps (A-04) --------------------------------------------------------------------- */

.steps {
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.steps__step {
  counter-increment: step;
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  font-size: var(--text-body-size);
  line-height: var(--text-body-lh);
}

.steps__step::before {
  content: counter(step);
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-chip);
  background: var(--color-primary-subtle);
  color: var(--color-on-primary-subtle);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* --- File dropzone (A-04; design system FileDropzone: idle, dragging, uploading, rejected) --- */

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-4);
  border: 2px dashed var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  text-align: center;
}

/* Dragging and rejected are a border and a tint AND a message: never colour alone (12.3). */
.dropzone--dragging {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
}

.dropzone--rejected {
  border-color: var(--danger-border);
  background: var(--danger-subtle);
}

.dropzone__icon {
  display: inline-flex;
  color: var(--text-secondary);
}

.dropzone--dragging .dropzone__icon { color: var(--color-primary-text); }
.dropzone--rejected .dropzone__icon { color: var(--danger-text); }

.dropzone__field {
  width: 100%;
  max-width: 28rem;
  align-items: center;
}

.dropzone__field .field__label,
.dropzone__field .field__hint {
  text-align: center;
}

.dropzone__input {
  width: 100%;
  padding: var(--space-2) var(--space-3);
}

/* The file picker's own button, so it reads as a control rather than plain text. */
.dropzone__input::file-selector-button {
  margin-right: var(--space-3);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
  color: var(--text-primary);
  font: inherit;
  cursor: pointer;
}

.dropzone__busy {
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  color: var(--text-secondary);
}

/* --- A-05 header ------------------------------------------------------------------------------ */

.preview-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.preview-head__file {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-lh);
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

.details--compact .details__row {
  padding-block: var(--space-1);
}

/* --- Stat tiles (A-05, A-01; design system StatTile). Seven of them, and the three
   cancellation counts are never merged into one (11.4). ------------------------------------- */

.tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-05);
  padding: var(--space-3);
  border: 1px solid var(--neutral-border);
  border-radius: var(--radius-tile);
  background: var(--surface-card);
}

.tile__count {
  font-size: var(--text-title-size);
  line-height: var(--text-title-lh);
  font-weight: var(--weight-semibold);
}

.tile__label {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
}

.tile--info { border-color: var(--info-border); background: var(--info-subtle); }
.tile--info .tile__label { color: var(--info-text); }
.tile--warning { border-color: var(--warning-border); background: var(--warning-subtle); }
.tile--warning .tile__label { color: var(--warning-text); }

@media (min-width: 720px) {
  .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* --- Group heading count ---------------------------------------------------------------------- */

.section__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  margin-left: var(--space-1);
  padding: 0 var(--space-1);
  border-radius: var(--radius-chip);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* --- Import issue row (A-05; design system ImportIssueRow). A card on a phone, one line on a
   laptop, which is where Lindy will mostly be (11.4 notes). --------------------------------- */

.issue-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.issue-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.issue-row--danger { border-left-color: var(--danger-solid); }
.issue-row--warning { border-left-color: var(--warning-solid); }

.issue-row__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.issue-row__when {
  font-weight: var(--weight-semibold);
}

.issue-row__what {
  color: var(--text-secondary);
}

.issue-row__suggestion,
.issue-row__note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  color: var(--text-secondary);
}

.issue-row__suggestion .icon,
.issue-row__note .icon {
  flex: none;
  margin-top: 2px;
}

.issue-row__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.issue-row__select {
  flex: 1 1 10rem;
  min-width: 10rem;
  max-width: 16rem;
}

@media (min-width: 900px) {
  .issue-row {
    display: grid;
    grid-template-columns: minmax(14rem, 18rem) 1fr;
    align-items: start;
    column-gap: var(--space-4);
  }

  .issue-row__head { grid-column: 1; }
  .issue-row__suggestion,
  .issue-row__note { grid-column: 2; margin: 0; }
  .issue-row__actions { grid-column: 1 / -1; }
}

/* --- Notes: warnings, new slots, row errors --------------------------------------------------- */

.note-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--neutral-border);
  border-radius: var(--radius-control);
  background: var(--neutral-subtle);
  color: var(--text-primary);
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
}

.note .icon { flex: none; margin-top: 2px; }
.note--warning { border-color: var(--warning-border); background: var(--warning-subtle); color: var(--warning-text); }
.note--info { border-color: var(--info-border); background: var(--info-subtle); color: var(--info-text); }
.note--danger { border-color: var(--danger-border); background: var(--danger-subtle); color: var(--danger-text); }

/* --- Everything else: a collapsed count (8.7) ------------------------------------------------- */

.collapse__summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  cursor: pointer;
  font-weight: var(--weight-medium);
  list-style: none;
  padding: 0;
}

.collapse__summary::-webkit-details-marker { display: none; }

.collapse__chevron {
  transition: transform 120ms ease;
}

.collapse[open] .collapse__chevron { transform: rotate(180deg); }

.collapse__body { margin-top: var(--space-2); }

@media (prefers-reduced-motion: reduce) {
  .collapse__chevron { transition: none; }
}

/* --- Sticky footer: Discard and Commit (11.4) ------------------------------------------------- */

.page--preview { padding-bottom: var(--space-16); }

.preview-footer {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* Bleed to the page edges by exactly the horizontal padding .page carries (--space-3).
     It was --space-4, 4px wider, so the footer overhung the viewport on the right and
     A-05 scrolled sideways at every width (found 20 Sep 2026 by the 17.9 overflow check;
     the HTML string cannot see a layout). */
  margin: var(--space-4) calc(var(--space-3) * -1) 0;
  padding: var(--space-3) var(--space-4);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border-default);
  background: var(--surface-card);
  box-shadow: var(--elevation-2);
}

.preview-footer__blockers {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  list-style: none;
  padding: 0;
}

.preview-footer__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* The tab bar is fixed over the bottom of the page, so the footer sits above it. */
.shell--tabs .preview-footer { bottom: calc(56px + env(safe-area-inset-bottom)); }

/* --- Cover loop: T-01 to T-05 and A-02 (spec 11, 12.6) ---------------------------------------
   Every state is a class, never an inline style (NFR-SEC-04, style-src 'self'). */

.home-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.home-date {
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

/* The "2 more need cover" line. 11 T-01: an obvious tap target, not small print, so it is a
   full-width row with a 44px target (12.5). */
.more-covers {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  color: var(--text-link);
  font-weight: 600;
  text-decoration: none;
}

.more-covers--quiet {
  font-weight: 500;
  color: var(--text-secondary);
}

/* The three views (FR-TRN-01). Links, not a script toggle, so Home works with no JS. */
.viewswitch {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border-control);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
}

.viewswitch__tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 48px;
  padding: var(--space-1) var(--space-2);
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: var(--text-label-size);
  text-align: center;
  text-decoration: none;
}

.viewswitch__tab--current {
  background: var(--surface-card);
  color: var(--text-primary);
  box-shadow: var(--elevation-1);
  font-weight: 600;
}

.viewswitch__count {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.day-head {
  margin-top: var(--space-4);
  color: var(--text-secondary);
  font-size: var(--text-label-size);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.class-cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* 11 T-01 Class card: time large, class type with its colour stripe, one status line. */
.class-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-left: 4px solid var(--ct, var(--border-default));
  border-radius: var(--radius-card);
  background: var(--surface-card);
  color: inherit;
  text-decoration: none;
}

.class-card__time {
  font-size: var(--text-body-lg-size);
  font-weight: 700;
}

.class-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}

.class-card__type {
  font-weight: 600;
}

.class-card__status {
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.class-card__chevron {
  color: var(--text-secondary);
  flex: none;
}

.class-card--success .class-card__status { color: var(--success-text); }
.class-card--info .class-card__status { color: var(--info-text); }
.class-card--warning .class-card__status { color: var(--warning-text); }

/* 12.6: cancelled is muted and struck through everywhere, never just missing. */
.class-card--cancelled { opacity: 0.7; }
.class-card--cancelled .class-card__type { text-decoration: line-through; }
.class-card--cancelled .class-card__status { color: var(--text-secondary); }

/* One open request (11 T-01 and T-04). */
.request-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.request-card--urgent { border-color: var(--danger-border); }

.request-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.request-card__when {
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
}

.request-card__type { font-weight: 600; }

.request-card__tags {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.request-card__for,
.request-card__volunteers {
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.request-card__note {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
  font-size: var(--text-label-size);
}

.request-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* 11.1: offline, reads work and every write is disabled with an honest message. */
.offline-note {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--warning-border);
  border-radius: var(--radius-card);
  background: var(--warning-subtle);
  color: var(--warning-text);
  font-size: var(--text-label-size);
}

/* T-03 reads as a sheet without being one: no script, so it is a page that looks like one. */
.sheet {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.sheet__summary {
  font-size: var(--text-body-lg-size);
  font-weight: 700;
}

.sheet__who {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.cover-status {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
}

/* 11 T-02/T-05: created, volunteered, filled... in the order they happened. */
.timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  list-style: none;
  padding: 0;
  font-size: var(--text-label-size);
}

.timeline__step {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.timeline__who { font-weight: 600; }
.timeline__what { color: var(--text-secondary); }
.timeline__when { color: var(--text-secondary); margin-left: auto; }

.request-cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* --- A-01 Dashboard (11.4; Phase 2b) ------------------------------------------------------------
   The tiles are the A-05 StatTile, made tappable: each is a link to its own filter. A count of
   zero stays neutral; the tone appears only when there is something in it (12.3: urgency is
   visible, not shouty). */

.tile--link {
  color: inherit;
  text-decoration: none;
  min-height: 44px;
}

.tile--link:hover { border-color: var(--border-strong); }

.stat-tile__count {
  font-size: var(--text-title-size);
  line-height: var(--text-title-lh);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.tile--danger { border-color: var(--danger-border); background: var(--danger-subtle); }
.tile--danger .tile__label { color: var(--danger-text); }
.tile--current { outline: 2px solid var(--color-focus); outline-offset: 1px; }

.section__link {
  margin-left: var(--space-2);
  font-size: var(--text-label-size);
  font-weight: var(--weight-regular);
}

/* Needs attention: one card per class, sorted by start. The row's own action sits on it. */
.attention {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.attention-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.attention-row--urgent { border-color: var(--danger-border); }

.attention-row__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.attention-row__when {
  display: flex;
  flex-direction: column;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.attention-row__type { font-weight: 600; }

.attention-row__tags {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.attention-row__tags .tag .icon { margin-right: 2px; }

.attention-row__who {
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.attention-row__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* A volunteer's name is the Confirm button (two taps: open the app, tap the name). 44px tall
   so it is a real thumb target at the gym desk (13.1). */
.chip-form { display: contents; }

.chip-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  padding: 0 var(--space-3);
  border: 1px solid var(--success-border);
  border-radius: var(--radius-chip);
  background: var(--success-subtle);
  color: var(--success-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.chip-button:hover { border-color: var(--success-solid); }

.class-cards--compact .class-card { min-height: 52px; padding-top: var(--space-2); padding-bottom: var(--space-2); }

.freshness {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  list-style: none;
  padding: 0;
}

.freshness__club {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.freshness__name { font-weight: 600; margin-right: var(--space-1); }

.failed-count {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-2);
  color: var(--danger-text);
  font-size: var(--text-label-size);
}

/* --- S-03 Get set up (Phase 3a, 9.11) ----------------------------------------------------------- */

.setup {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.setup-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  list-style: none;
  padding: 0;
  margin: 0;
}

.setup-step {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  box-shadow: var(--elevation-1);
}

.setup-step[hidden] {
  display: none;
}

.setup-step--done {
  border-color: var(--success-border);
  background: var(--success-subtle);
  color: var(--success-text);
}

.setup-step__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-title-size);
  line-height: var(--text-title-lh);
  font-weight: var(--weight-semibold);
}

.setup-step__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: var(--text-label-size);
  font-weight: var(--weight-bold);
}

.setup-step__lede {
  color: var(--text-secondary);
}

.setup-step__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.setup-step__body[hidden] {
  display: none;
}

.setup-step__done {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--success-text);
}

.setup-step__done[hidden] {
  display: none;
}

.setup-howto {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
  margin: 0;
}

.setup-howto__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* The "picture" of each iPhone step (S-03): the glyph Safari shows, drawn large on a tile the
   shape of an iOS toolbar button, so it can be matched against the phone in the other hand. */
.setup-howto__picture {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 52px;
  height: 52px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-tile);
  background: var(--surface-sunken);
  color: var(--info-solid);
}

.setup-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-label-size);
  line-height: var(--text-label-lh);
  color: var(--text-secondary);
}

.setup-note[hidden] {
  display: none;
}

.setup .banner[hidden] {
  display: none;
}

/* --- Delivery issues on A-02, failed sends on A-08 (Phase 3a, 10.6) ----------------------------- */

.card--warning {
  border-color: var(--warning-border);
  background: var(--warning-subtle);
  color: var(--warning-text);
}

.delivery-issues {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.delivery-issues__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.delivery-issues__hint {
  margin-top: var(--space-2);
  font-size: var(--text-label-size);
}

/* ===========================================================================================
   Phase 3c: the shell (11.1; FR-NAV-01, FR-NAV-02). Below 1024px the bottom tab bar; from
   1024px the left sidebar with every item, and the content column beside it. Semantic tokens
   only, no inline styles (NFR-SEC-04).
   =========================================================================================== */

/* --- The app bar, signed in ----------------------------------------------------------------
   On a phone: the wordmark with the club under it, and the chip and bell, on the first row;
   the screen title (with its back link) under them. From 1024px the wordmark lives in the
   sidebar, and the title comes up beside the tools. */

.app-bar__grid {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "brand tools"
    "title title";
  align-items: center;
  column-gap: var(--space-3);
  max-width: var(--container-content-max);
  margin: 0 auto;
  padding: 0 calc(var(--space-2) + env(safe-area-inset-right, 0px)) 0
    calc(var(--space-3) + env(safe-area-inset-left, 0px));
}

.shell:has(.page--narrow) .app-bar__grid {
  max-width: var(--container-mobile-max);
}

.shell:has(.page--wide) .app-bar__grid {
  max-width: var(--container-admin-max);
}

.app-bar__brand {
  grid-area: brand;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding-top: var(--space-2);
}

.app-bar__grid .app-bar__row {
  grid-area: title;
  max-width: none;
  min-height: 48px;
  margin: 0;
  padding: 0;
}

.app-bar__club,
.sidebar__club {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-bar__tools {
  grid-area: tools;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  min-width: 0;
  padding-top: var(--space-2);
}

/* "Updated 3 days ago · to 14 Oct" (FR-IMP-10). Shortened with an ellipsis rather than
   wrapped or pushed off the edge on the narrowest phones. */
.freshness-chip {
  min-width: 0;
  padding: 2px var(--space-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-chip);
  background: var(--neutral-subtle);
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Amber when stale (FR-IMP-10, 12.6 warning). */
.freshness-chip--stale {
  border-color: var(--warning-border);
  background: var(--warning-subtle);
  color: var(--warning-text);
}

/* The inbox bell (FR-NAV-02): a 44px target with its unread count on the corner. */
.bell {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-control);
  color: var(--text-secondary);
}

.bell:hover,
.bell[aria-current="page"] {
  color: var(--color-primary-text);
  background: var(--neutral-subtle);
}

.bell__count {
  position: absolute;
  top: 4px;
  right: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-chip);
  background: var(--danger-solid);
  color: var(--danger-on-solid);
  font-size: 11px;
  line-height: 18px;
  font-weight: var(--weight-bold);
  text-align: center;
}

/* --- The sidebar (from 1024px) ---------------------------------------------------------------- */

.sidebar {
  display: none;
}

.sidebar__brand {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 var(--space-3);
}

.sidebar__group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sidebar__group + .sidebar__group {
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
}

.sidebar__link,
.sidebar__me {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 40px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-control);
  color: var(--text-secondary);
  font-weight: var(--weight-medium);
  text-decoration: none;
}

.sidebar__link:hover,
.sidebar__me:hover {
  color: var(--text-primary);
  background: var(--neutral-subtle);
}

.sidebar__link[aria-current="page"],
.sidebar__me[aria-current="page"] {
  color: var(--color-primary-text);
  background: var(--color-primary-subtle);
}

/* The signed-in line at the foot opens Me (11.1, ruled 23 Sep 2026). */
.sidebar__me {
  margin-top: auto;
  min-height: 52px;
}

.sidebar__me-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sidebar__me-label {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  font-weight: var(--weight-regular);
  color: var(--text-tertiary);
}

.sidebar__me-name {
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (min-width: 1024px) {
  .shell--tabs {
    padding-left: var(--sidebar-width);
  }

  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: var(--z-tabbar);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    width: var(--sidebar-width);
    padding: calc(var(--safe-top) + var(--space-4)) var(--space-3) var(--space-4);
    background: var(--surface-card);
    border-right: 1px solid var(--border-subtle);
    overflow-y: auto;
  }

  .tab-bar {
    display: none;
  }

  .shell--tabs .page {
    padding-bottom: var(--space-8);
  }

  .shell--tabs .preview-footer {
    bottom: 0;
  }

  .app-bar__brand {
    display: none;
  }

  .app-bar__grid {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "title tools";
    min-height: var(--appbar-height);
  }

  .app-bar__tools {
    padding-top: 0;
  }
}

/* --- Placeholders (brief 3c §2): one honest line ------------------------------------------- */

.placeholder {
  color: var(--text-secondary);
}

/* --- S-05 Inbox ------------------------------------------------------------------------------ */

.inbox-actions {
  display: flex;
  justify-content: flex-end;
}

.inbox {
  list-style: none;
  padding: 0;
}

.inbox-item + .inbox-item {
  border-top: 1px solid var(--border-subtle);
}

.inbox-item__button {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.inbox-item__button:hover {
  background: var(--neutral-subtle);
}

.inbox-item__icon {
  flex: none;
  display: inline-flex;
  padding-top: 2px;
  color: var(--text-secondary);
}

.inbox-item--unread .inbox-item__icon {
  color: var(--color-primary-text);
}

.inbox-item__text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.inbox-item__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.inbox-item__title {
  color: var(--text-secondary);
}

.inbox-item--unread .inbox-item__title {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}

/* One line, as S-05 asks; the whole message is on the screen it opens. */
.inbox-item__body {
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.inbox-item__when {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-lh);
  color: var(--text-tertiary);
}

.inbox-item__dot {
  flex: none;
  width: 10px;
  height: 10px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--color-primary);
}

/* --- S-04 Me ------------------------------------------------------------------------------------ */

.this-device__state,
.this-device__state p,
.sms-always {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.this-device__state[hidden] {
  display: none;
}

.my-slot {
  padding: var(--space-3) var(--space-4);
}

.my-slot + .my-slot,
.device-row + .device-row {
  border-top: 1px solid var(--border-subtle);
}

.device-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}

.device-row__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* ===========================================================================================
   Phase 3d: T-06 and A-03 Timetable, A-03 class detail and its dialogs, the tab badges.
   Design system: WeekStrip, CalendarPicker, WeekGrid (DayCard, BADGE), ClassCard, UserPicker,
   Dialog / BottomSheet, StatusChip. Semantic tokens only; no inline styles (NFR-SEC-04).
   =========================================================================================== */

/* 11.1: the week grids use the full width, exempt from the 720px cap. */
.page--full {
  max-width: none;
}

.shell:has(.page--full) .app-bar__row {
  max-width: none;
}

/* --- FR-NAV-03: tab badges ------------------------------------------------------------------ */

.nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: auto;
  border-radius: var(--radius-chip);
  background: var(--danger-solid);
  color: var(--danger-on-solid);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.tab-bar__tab {
  position: relative;
}

.tab-bar__tab .nav-badge {
  position: absolute;
  top: 4px;
  left: calc(50% + 6px);
  margin-left: 0;
}

/* --- shared small controls -------------------------------------------------------------------- */

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  background: var(--surface-card);
  color: var(--text-primary);
}

.icon-button:hover {
  background: var(--neutral-subtle);
}

.button--danger-outline {
  border: 1px solid var(--danger-border);
  background: var(--surface-card);
  color: var(--danger-text);
}

.button--danger-outline:hover {
  background: var(--danger-subtle);
}

/* --- the chips (WeekGrid BADGE): one per card, never the only signal --------------------------- */

.cm-badge {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 3px;
  padding: 1px 6px 1px 4px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-chip);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
  line-height: 17px;
  white-space: nowrap;
}

.cm-badge--tbcAdmin,
.cm-badge--urgent {
  border-color: var(--danger-border);
  background: var(--danger-subtle);
  color: var(--danger-text);
}

.cm-badge--tbc {
  border-color: var(--neutral-border);
  background: var(--neutral-subtle);
  color: var(--text-secondary);
}

.cm-badge--coveredBy {
  border-color: var(--info-border);
  background: var(--info-subtle);
  color: var(--info-text);
}

.cm-badge--covering {
  border-color: var(--success-border);
  background: var(--success-subtle);
  color: var(--success-text);
}

.cm-badge--coverRequested {
  border-color: var(--warning-border);
  background: var(--warning-subtle);
  color: var(--warning-text);
}

.cm-badge--cancelled,
.cm-badge--removed {
  background: transparent;
  color: var(--text-tertiary);
}

/* --- T-06 / A-03 header, week strip, jump and filters ---------------------------------------- */

.tt-head {
  display: none;
}

.tt-head__range {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
}

.tt-head__tools {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.week-strip {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.week-strip__arrow {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 44px;
  color: var(--text-primary);
}

.week-strip__days {
  display: flex;
  flex: 1;
  gap: 2px;
  min-width: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.week-strip__days li {
  flex: 1;
  min-width: 0;
}

.week-strip__day {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 52px;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  color: var(--text-primary);
  text-decoration: none;
}

.week-strip__day[aria-current="date"] {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.week-strip__day--beyond {
  color: var(--text-disabled);
}

.week-strip__dow {
  font-size: 11px;
  font-weight: var(--weight-semibold);
  line-height: 1;
}

.week-strip__num {
  font-size: 17px;
  font-weight: var(--weight-semibold);
  line-height: 1;
}

.week-strip__dot {
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: transparent;
}

.week-strip__day--classes .week-strip__dot {
  background: var(--border-strong);
}

.week-strip__day--today .week-strip__dot {
  background: var(--color-primary);
}

.week-strip__day[aria-current="date"] .week-strip__dot {
  background: var(--color-on-primary);
}

.week-strip__today {
  flex: none;
  padding: var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  color: var(--text-link);
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.tt-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-2);
}

.jump,
.tt-filters {
  position: relative;
}

.jump__summary,
.tt-filters__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0 var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  background: var(--surface-card);
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  list-style: none;
}

.jump__summary::-webkit-details-marker,
.tt-filters__summary::-webkit-details-marker {
  display: none;
}

.tt-filters__on {
  padding: 0 6px;
  border-radius: var(--radius-chip);
  background: var(--color-primary-subtle);
  color: var(--color-on-primary-subtle);
  font-size: var(--text-caption-size);
}

.jump__panel,
.tt-filters__form {
  margin-top: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  box-shadow: var(--elevation-2);
}

.tt-filters__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: min(320px, calc(100vw - 2 * var(--space-4)));
}

.tt-filters__actions {
  display: flex;
  gap: var(--space-2);
}

/* CalendarPicker */
.cal {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: min(320px, calc(100vw - 2 * var(--space-6)));
}

.cal__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.cal__month {
  flex: 1;
  text-align: center;
  font-size: var(--text-title-size);
  font-weight: var(--weight-semibold);
}

.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}

.cal__dow {
  padding-bottom: 2px;
  color: var(--text-tertiary);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
  text-align: center;
}

.cal__day {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.cal__day[data-today] {
  border-color: var(--color-primary-border);
  font-weight: var(--weight-semibold);
}

.cal__day[aria-current="date"] {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.cal__day--none,
.cal__day--beyond {
  color: var(--text-disabled);
  cursor: not-allowed;
}

.cal__legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
}

.cal__legend-dot {
  width: 4px;
  height: 4px;
  border-radius: 999px;
  background: var(--border-strong);
}

/* --- the phone's day list (ClassCard) ---------------------------------------------------------- */

.tt-day {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.tt-day__heading {
  margin: 0;
  font-size: var(--text-body-lg-size);
  font-weight: var(--weight-semibold);
}

.tt-day__cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.tt-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-left: 4px solid var(--ct, var(--border-default));
  border-radius: var(--radius-card);
  background: var(--surface-card);
  color: inherit;
  text-decoration: none;
}

.tt-card__time {
  flex: none;
  min-width: 64px;
  font-size: var(--text-body-lg-size);
  font-weight: var(--weight-bold);
}

.tt-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}

.tt-card__type {
  font-weight: var(--weight-semibold);
}

.tt-card__who {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.tt-card__chevron {
  flex: none;
  color: var(--text-secondary);
}

.tt-card--tbcAdmin {
  border-color: var(--danger-border);
  border-left-color: var(--danger-solid);
  background: var(--danger-subtle);
}

.tt-card--struck {
  opacity: 0.7;
}

.tt-card--struck .tt-card__time,
.tt-card--struck .tt-card__type {
  text-decoration: line-through;
}

/* --- the desktop week grid (WeekGrid, DayCard) ----------------------------------------------- */

.week-grid {
  display: none;
  overflow-x: auto;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
}

.week-grid__cols {
  display: grid;
  grid-template-columns: repeat(7, minmax(132px, 1fr));
  align-items: stretch;
  min-width: 100%;
}

.week-grid__day {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-left: 1px solid var(--border-subtle);
}

.week-grid__day:first-child {
  border-left: none;
}

.week-grid__head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: var(--space-2) 10px;
  border-bottom: 1px solid var(--border-default);
  background: var(--surface-sunken);
  color: var(--text-primary);
  text-decoration: none;
}

.week-grid__day--today .week-grid__head {
  background: var(--color-primary-subtle);
  color: var(--color-on-primary-subtle);
}

.week-grid__dow {
  color: inherit;
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
}

.week-grid__num {
  font-weight: var(--weight-semibold);
}

.week-grid__count {
  margin-left: auto;
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
}

.week-grid__cards {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  background: var(--surface-bg);
}

.week-grid__empty {
  padding: 10px 4px;
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
  text-align: center;
}

.day-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 7px 8px 7px 11px;
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--ct, var(--border-default));
  border-radius: var(--radius-control);
  background: var(--surface-card);
  box-shadow: var(--elevation-1);
  color: var(--text-primary);
  line-height: 1.25;
  text-decoration: none;
}

.day-card__time {
  font-size: 13px;
  font-weight: var(--weight-semibold);
}

.day-card__type {
  font-size: var(--text-caption-size);
  font-weight: var(--weight-medium);
  overflow-wrap: anywhere;
}

.day-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.day-card__who {
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-medium);
  overflow-wrap: anywhere;
}

.day-card--tbcAdmin {
  border-color: var(--danger-border);
  border-left-color: var(--danger-solid);
  background: var(--danger-subtle);
}

.day-card--tbcAdmin .day-card__who {
  color: var(--danger-text);
  font-weight: var(--weight-semibold);
}

.day-card--struck {
  opacity: 0.7;
  border-left-color: var(--border-strong);
}

.day-card--struck .day-card__time,
.day-card--struck .day-card__type {
  text-decoration: line-through;
}

.day-card--selected {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary-subtle);
}

@media (min-width: 1024px) {
  .tt-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
  }

  .week-strip,
  .tt-day,
  .tt-bar__attention {
    display: none;
  }

  .week-grid {
    display: block;
  }

  .jump__panel,
  .tt-filters__form {
    position: absolute;
    z-index: var(--z-sheet);
  }

  .tt-filters__form {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
    min-width: 560px;
  }
}

/* --- A-03 class detail --------------------------------------------------------------------------- */

.a03 {
  display: grid;
  gap: var(--space-4);
}

.a03__day {
  display: none;
}

.a03__day-head {
  margin: 0 0 var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
}

.a03__day-cards {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.a03__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}

@media (min-width: 1024px) {
  .a03 {
    grid-template-columns: minmax(0, 1fr) 420px;
    align-items: start;
  }

  .a03__day {
    display: block;
    padding: var(--space-2);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-card);
    background: var(--surface-bg);
  }
}

.panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  box-shadow: var(--elevation-1);
}

.panel--danger {
  border-color: var(--danger-border);
}

.panel__when {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0;
}

.panel__time {
  font-size: 24px;
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
}

.panel__date {
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.is-struck {
  text-decoration: line-through;
}

.panel__type {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: inherit;
}

.panel__who {
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
}

.panel__person {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: var(--space-2) 0 0;
}

.panel__name {
  display: block;
  font-size: var(--text-body-lg-size);
  font-weight: var(--weight-semibold);
}

.panel__sub {
  display: block;
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.panel__sub--danger {
  color: var(--danger-text);
}

.panel__note {
  margin: 0;
  padding: 10px 12px;
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.panel__slot {
  font-size: var(--text-caption-size);
}

.request-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--info-border);
  border-radius: var(--radius-card);
  background: var(--info-subtle);
  color: var(--info-text);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.request-link span {
  flex: 1;
}

/* The two trainer actions differ on every axis at once (design ActionCard): permanent is a solid
   primary border on the card surface, one-off a dashed border on the sunken surface. */
.action-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 14px;
  border-radius: var(--radius-card);
}

.action-card--permanent {
  border: 2px solid var(--color-primary);
  background: var(--surface-card);
}

.action-card--oneoff {
  border: 1px dashed var(--border-strong);
  background: var(--surface-sunken);
}

.action-card__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--text-body-lg-size);
  font-weight: var(--weight-semibold);
}

.action-card--permanent .action-card__title .icon {
  color: var(--color-primary);
}

.action-card__helper {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

.action-card--permanent .action-card__helper strong {
  color: var(--color-on-primary-subtle);
}

.action-card__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}

.action-card__link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

/* 11.4 A-03 Notes: Cancel this class is visually separate and destructive, never next to the
   primary action. */
.danger-zone {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-default);
}

/* --- Dialog (desktop) and BottomSheet (phone), as a page state ------------------------------- */

.dialog-layer {
  position: fixed;
  inset: 0;
  z-index: var(--z-dialog);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.dialog-layer__scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim);
}

.dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: 100%;
  max-height: 90vh;
  padding: var(--space-4) var(--space-4) calc(var(--space-4) + var(--safe-bottom, 0px));
  overflow-y: auto;
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  background: var(--surface-raised);
  box-shadow: var(--elevation-3);
}

.dialog form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.dialog__title {
  margin: 0;
  font-size: var(--text-title-size);
  font-weight: var(--weight-semibold);
}

.dialog__lead {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
}

.dialog__lead span {
  color: var(--text-tertiary);
  font-size: var(--text-caption-size);
}

.dialog__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

@media (min-width: 1024px) {
  .dialog-layer {
    align-items: center;
  }

  .dialog {
    max-width: 480px;
    border-radius: var(--radius-card);
  }

  .dialog__actions {
    flex-direction: row-reverse;
    justify-content: flex-start;
  }
}

/* UserPicker: the whole list renders; the dialog is the one scroll region. */
.user-picker {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
}

.user-picker__row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--border-subtle);
  cursor: pointer;
}

.user-picker__row:first-child {
  border-top: none;
}

.user-picker__row:has(input:checked) {
  background: var(--color-primary-subtle);
}

.user-picker__row--disabled {
  color: var(--text-disabled);
  cursor: not-allowed;
}

.user-picker__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.user-picker__name {
  font-weight: var(--weight-semibold);
}

.user-picker__why {
  color: var(--text-secondary);
  font-size: var(--text-caption-size);
}

.user-picker__warn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--warning-text);
  font-size: var(--text-caption-size);
}

.consequence {
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--color-primary-border);
  border-radius: var(--radius-control);
  background: var(--color-primary-subtle);
  color: var(--color-on-primary-subtle);
  font-size: var(--text-label-size);
}

.impact {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  background: var(--surface-sunken);
  list-style: none;
}

.impact li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-label-size);
}

.note-warning {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--warning-border);
  border-radius: var(--radius-control);
  background: var(--warning-subtle);
  color: var(--warning-text);
  font-size: var(--text-label-size);
}

/* Phase 3b: an information line (A-02, the admin's own crash-out, 9.14). */
.note-info {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--info-border);
  border-radius: var(--radius-control);
  background: var(--info-subtle);
  color: var(--info-text);
  font-size: var(--text-label-size);
}

/* Phase 3b: A-10's Send texts switch, a checkbox drawn as a switch (role="switch"). */
.switch-row {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap-min);
  cursor: pointer;
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

.switch {
  appearance: none;
  flex: none;
  position: relative;
  width: 44px;
  height: 26px;
  margin: 0;
  border-radius: 13px;
  background: var(--border-strong);
  cursor: pointer;
  transition: background var(--duration-fast);
}

.switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--surface-card);
  transition: transform var(--duration-fast);
}

.switch:checked {
  background: var(--color-primary);
}

.switch:checked::after {
  transform: translateX(18px);
}

.switch:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Phase 3b: this month's texts against the cap (FR-SET-02). Full at the cap (10.5). */
.usage-bar {
  display: block;
  width: 100%;
  height: 10px;
}

.usage-bar::-webkit-meter-bar {
  border: 0;
  border-radius: 5px;
  background: var(--surface-sunken);
}

.usage-bar::-webkit-meter-optimum-value,
.usage-bar::-webkit-meter-suboptimum-value {
  border-radius: 5px;
  background: var(--color-primary);
}

.usage-bar--full::-webkit-meter-optimum-value,
.usage-bar--full::-webkit-meter-suboptimum-value,
.usage-bar--full::-webkit-meter-even-less-good-value {
  background: var(--warning-text);
}

/* Phase 3b: A-01's delivery row, the failed count beside accepted against confirmed
   (FR-NOT-08, FR-NOT-10). */
.delivery-row {
  margin-top: var(--space-3);
}

.delivery-row .failed-count {
  margin-top: var(--space-1);
}

.delivery-row__pair {
  margin: var(--space-1) 0 0;
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
}

.delivery-row__caption {
  margin: var(--space-1) 0 0;
}

/* A checkbox with its label and hint beside it (A-03 Notify, T-06 Only mine). .checkbox is the
   box itself, 22px; this is the row it sits in. */
.check-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
}

.check-row > span {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.check__label {
  font-weight: var(--weight-semibold);
}

/* --- Phase 3e: offline, busy buttons, show/hide, the shared user picker, the admin lines ----- */

/* 11.1: the Offline banner is neutral: nothing is wrong with the app, the connection is gone. */
.banner--neutral {
  border-color: var(--neutral-border);
  background: var(--neutral-subtle);
}

/* 11.1 (25 Sep 2026): off A-01, Timetable stale and "Update PerfectGym" are one line each. */
.banner__text--line {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-1);
}

.banner__text--line .banner__link {
  flex: none;
}

/* Offline, a link that begins a write is greyed like a disabled button, and goes nowhere. */
a[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* S-01 Logging in, T-03 Sending: the button shows progress while the request is in flight. */
.button[aria-busy="true"] {
  cursor: progress;
}

.button[aria-busy="true"]::before {
  content: "";
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: busy-spin 0.8s linear infinite;
}

@keyframes busy-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .button[aria-busy="true"]::before {
    animation: none;
    border-right-color: currentColor;
    opacity: 0.6;
  }
}

/* S-01: the password field with its show/hide control inside it, on the right. */
.input-reveal {
  position: relative;
}

.input-reveal .input {
  width: 100%;
  padding-right: 8.5rem;
}

.input-reveal__toggle {
  position: absolute;
  top: 50%;
  right: var(--space-1);
  transform: translateY(-50%);
  min-height: 44px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  color: var(--text-link);
  font: inherit;
  font-size: var(--text-label-size);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.input-reveal__toggle[hidden] {
  display: none;
}

/* A-02 and A-03's picker: its search box, and what it says when nothing matches. */
.user-picker__search {
  margin-bottom: var(--space-2);
}

.user-picker__search[hidden],
.user-picker__row[hidden],
.user-picker__none[hidden] {
  display: none;
}

.user-picker__none {
  margin: var(--space-2) 0 0;
  color: var(--text-secondary);
  font-size: var(--text-label-size);
}

/* A-02's volunteers carry the same warning as the picker's rows. */
.user-row__body .user-picker__warn {
  display: flex;
}

/* T-06 desktop: the actual trainer's avatar on each week-grid card. */
.day-card__who {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
}

.day-card__avatar {
  flex: none;
}

/* The offline page (11.1; Design's OfflinePage, 25 Sep): wordmark, signal, sentence, centred. */
.offline-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  min-height: 100dvh;
  padding: var(--space-8) var(--space-4);
  text-align: center;
}

.offline-page__icon {
  color: var(--text-tertiary);
}

.offline-page__line {
  max-width: 300px;
  margin: 0;
  font-size: var(--text-body-lg-size);
  line-height: var(--text-body-lg-lh);
  font-weight: var(--weight-regular);
  text-wrap: pretty;
}
