/* Public sign-up page (signup.html) — plain signups and class picks.

   Built to be read by seniors, often from across a room while the page is on a
   projector, then finished on a phone held at arm's length: 60px+ tap targets,
   thick selection borders, and no hover-only affordances. Font sizes are em
   multiples of `--cl-base`. The A- / A / A+ control writes `--cl-scale` onto
   the class list only — the title and the lead under it stay put, so enlarging
   text does not shove the classes down the screen. Padding, radii, and the QR
   still do not scale. Warm amber accent keeps it distinct from the board purple and
   reservation teal. */

:root {
  --cl-bg: #fbf7f0;
  --cl-bg-wash: #fce9c8;
  --cl-surface: #ffffff;
  --cl-surface-alt: #f6f0e6;
  --cl-text: #241d12;
  --cl-muted: #6b5f4d;
  --cl-accent: #a15c07;
  --cl-accent-soft: #fdf0d8;
  --cl-border: #e2d7c5;
  --cl-border-strong: #cbbba0;
  --cl-danger: #a3231a;
  --cl-ok: #1f7a3d;
  --cl-ok-soft: #e4f3e9;
  --cl-solid-from: #d98314;
  --cl-solid-to: #a15c07;
  --cl-solid-ink: #ffffff;
  /* Text scale. `--cl-scale` is what the A- / A / A+ control writes. Applied
     only on `#clGroups` so the hero title and lead do not grow with it. */
  --cl-base: 16px;
  --cl-scale: 1;
  --cl-radius: 22px;
  --cl-radius-sm: 16px;
  --cl-shadow: 0 1px 2px rgba(36, 29, 18, 0.04), 0 18px 40px -22px rgba(36, 29, 18, 0.32);
  --cl-shadow-lift: 0 2px 6px rgba(36, 29, 18, 0.06), 0 22px 44px -20px rgba(36, 29, 18, 0.38);
  --cl-ring: rgba(36, 29, 18, 0.08);
  --cl-solid-shadow: 0 10px 22px -10px rgba(161, 92, 7, 0.55);
  --cl-ease: 180ms cubic-bezier(0.22, 0.7, 0.25, 1);
  --cl-font: 'Figtree', 'Segoe UI', sans-serif;
  --cl-display: 'Outfit', 'Figtree', sans-serif;
  --cl-group-color: var(--cl-accent);
}

[data-theme="dark"] {
  --cl-bg: #14110c;
  --cl-bg-wash: #2c2214;
  --cl-surface: #1c1811;
  --cl-surface-alt: #251f16;
  --cl-text: #f5efe4;
  --cl-muted: #b3a68f;
  --cl-accent: #f0b45a;
  --cl-accent-soft: #382a15;
  --cl-border: #322a1e;
  --cl-border-strong: #55452c;
  --cl-danger: #f2b8b5;
  --cl-ok: #6ee7a0;
  --cl-ok-soft: #16301f;
  --cl-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 18px 40px -18px rgba(0, 0, 0, 0.65);
  --cl-shadow-lift: 0 2px 8px rgba(0, 0, 0, 0.45), 0 24px 48px -20px rgba(0, 0, 0, 0.8);
  --cl-ring: rgba(255, 255, 255, 0.08);
  --cl-solid-shadow: 0 10px 22px -10px rgba(0, 0, 0, 0.7);
}

/* `[hidden]` is specificity 0-1-0 — the same as a class — so any rule here that
   sets `display` (the expand button's inline-flex, the confirmation tick's grid)
   silently beats the UA's `[hidden] { display: none }` and the element stays on
   screen while the code believes it is hidden. This puts that back, once, for
   every element on the page. */
body.event-classes-page [hidden] {
  display: none !important;
}

body.event-classes-page {
  margin: 0;
  background:
    radial-gradient(920px 420px at 8% -12%, var(--cl-bg-wash) 0%, transparent 58%),
    radial-gradient(720px 380px at 100% 0%, color-mix(in srgb, var(--cl-bg-wash) 70%, #f4d9a8) 0%, transparent 52%),
    radial-gradient(520px 280px at 78% 100%, color-mix(in srgb, var(--cl-bg-wash) 50%, transparent) 0%, transparent 62%),
    var(--cl-bg);
  background-attachment: fixed;
  color: var(--cl-text);
  font-family: var(--cl-font);
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  padding-bottom: calc(24px + var(--mobile-nav-h, 60px));
}

.cl-wrap {
  max-width: 1040px;
  margin: 0 auto;
  padding: 28px 20px 64px;
  font-size: var(--cl-base);
}

/* Class choices only. The hero title and the sentence under it stay at
   `--cl-base`, so A+ does not drift the list down the page. */
#clGroups {
  font-size: calc(var(--cl-base) * var(--cl-scale));
}

/* ── Hero ─────────────────────────────────────────────────────────────── */

.cl-hero {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 22px 32px;
  flex-wrap: wrap;
  margin: 4px 0 28px;
  padding: 4px 2px 2px;
}

.cl-hero-copy { flex: 1 1 18rem; min-width: 0; }

.cl-hero-kicker {
  margin: 0 0 10px;
  font-family: var(--cl-display);
  font-size: 0.74em;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cl-accent);
}

.cl-page-title {
  font-family: var(--cl-display);
  font-size: clamp(1.85em, 4.6vw, 2.55em);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.08;
  margin: 0 0 10px;
}

.cl-page-lead {
  margin: 0;
  max-width: 38ch;
  font-size: 1.05em;
  line-height: 1.5;
  color: var(--cl-muted);
}

.cl-hero-tools {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  flex: 0 1 auto;
}

/* Text size control. Sits with the hero tools so someone who needs it larger
   finds it before reading the list. The buttons show their own effect:
   a small A, a medium A, a large A. */
.cl-textsize {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px;
  background: var(--cl-surface);
  border: 1px solid var(--cl-border);
  border-radius: 999px;
  box-shadow: var(--cl-shadow);
}

.cl-textsize-label {
  padding: 0 8px 0 10px;
  font-size: 0.82em;
  font-weight: 600;
  color: var(--cl-muted);
}

.cl-textsize-btn {
  min-width: 44px;
  min-height: 40px;
  padding: 0 12px;
  font-family: var(--cl-display);
  font-weight: 700;
  line-height: 1;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  transition: filter 140ms ease;
}

/* Fixed px, not em: these must not resize themselves as they resize the page. */
#clTextSmaller { font-size: 13px; }
#clTextReset   { font-size: 16px; }
#clTextBigger  { font-size: 21px; }

.cl-textsize-btn:hover { filter: brightness(0.97); }
.cl-textsize-btn:focus-visible { outline: 3px solid var(--cl-accent); outline-offset: 2px; }
.cl-textsize-btn:disabled { opacity: 0.4; cursor: default; }

/* ── Cards ────────────────────────────────────────────────────────────── */

.cl-card {
  background: var(--cl-surface);
  border: 1px solid var(--cl-ring);
  border-radius: var(--cl-radius);
  box-shadow: var(--cl-shadow);
  padding: 22px;
  margin-bottom: 18px;
}

.cl-status {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 140px;
  text-align: center;
}

.cl-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--cl-border);
  border-top-color: var(--cl-accent);
  border-radius: 50%;
  animation: cl-spin 0.7s linear infinite;
}

@keyframes cl-spin { to { transform: rotate(360deg); } }

.cl-empty-mark {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  font-family: var(--cl-display);
  font-size: 1.4em;
  font-weight: 800;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border-radius: 50%;
}

.cl-empty { margin: 0; color: var(--cl-muted); text-align: center; }
.cl-empty-title { font-family: var(--cl-display); font-size: 1.2em; margin: 0 0 4px; text-align: center; }
.cl-note { margin: 10px 0 0; font-size: 0.88em; color: var(--cl-muted); }

/* Closed window — muted amber pill, not green "ok" and not red danger. */
.cl-closed-tag {
  display: inline-block;
  margin: 0 0 8px;
  padding: 4px 12px;
  font-size: 0.78em;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border: 1px solid var(--cl-border-strong);
  border-radius: 999px;
  white-space: nowrap;
}

.cl-status .cl-closed-tag { margin-top: 2px; }

.cl-status #clRecentShow {
  margin-top: 16px;
}

.cl-board-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin: 0 0 18px;
  padding: 12px 14px;
  background: var(--cl-accent-soft);
  border: 1px solid var(--cl-border);
  border-radius: var(--cl-radius-sm);
}

.cl-board-banner[hidden] { display: none !important; }

.cl-board-banner .cl-closed-tag { margin: 0; }

.cl-board-banner-text {
  margin: 0;
  flex: 1 1 12rem;
  font-size: 0.9em;
  color: var(--cl-muted);
}

/* ── How-to steps ─────────────────────────────────────────────────────── */

.cl-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  margin: 0 0 18px;
  padding: 0;
  list-style: none;
}

.cl-step {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.92em;
  font-weight: 600;
  color: var(--cl-muted);
}

.cl-step-num {
  display: inline-grid;
  place-items: center;
  width: 1.7em;
  height: 1.7em;
  flex: none;
  font-family: var(--cl-display);
  font-size: 0.85em;
  font-weight: 800;
  color: var(--cl-solid-ink);
  background: linear-gradient(180deg, var(--cl-solid-from), var(--cl-solid-to));
  border-radius: 50%;
  box-shadow: 0 2px 8px -2px color-mix(in srgb, var(--cl-accent) 55%, transparent);
}

/* ── Group of classes ─────────────────────────────────────────────────── */

.cl-group {
  border-top: none;
  box-shadow: inset 6px 0 0 var(--cl-group-color), var(--cl-shadow);
}

.cl-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.cl-group-title {
  font-family: var(--cl-display);
  font-size: 1.25em;
  font-weight: 700;
  margin: 0;
}

.cl-group-badge {
  flex: none;
  font-size: 0.8em;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border-radius: 999px;
  padding: 4px 12px;
}

.cl-opts { display: flex; flex-direction: column; gap: 12px; }

/* One choice. The whole block is the tap target — a senior should never have
   to hit a small circle. */
.cl-opt {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  min-height: 62px;
  padding: 16px;
  border: 2px solid var(--cl-border);
  border-radius: var(--cl-radius-sm);
  background: var(--cl-surface);
  cursor: pointer;
  transition: border-color var(--cl-ease), background var(--cl-ease), box-shadow var(--cl-ease), transform var(--cl-ease);
}

/* The visible control is `.cl-opt-mark`; the input itself is only for state and
   keyboard. Not scoped to a type — a type-specific selector is how a native
   control leaked through once already. */
.cl-opt input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.cl-opt-mark {
  flex: none;
  width: 28px;
  height: 28px;
  margin-top: 2px;
  border: 3px solid var(--cl-border-strong);
  border-radius: 50%;
  background: var(--cl-surface);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

.cl-opt.is-picked {
  border-color: var(--cl-accent);
  background: var(--cl-accent-soft);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--cl-accent) 35%, transparent);
}

.cl-opt.is-picked .cl-opt-mark {
  border-color: var(--cl-accent);
  box-shadow: inset 0 0 0 6px var(--cl-accent);
}

.cl-opt:focus-within {
  outline: 3px solid var(--cl-accent);
  outline-offset: 2px;
}

.cl-opt-body { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.cl-opt-name { font-size: 1.15em; font-weight: 700; line-height: 1.35; }

/* Two lines, then "See more". The clamp is unconditional; the control that
   undoes it is revealed only where text is actually cut off (measured in JS). */
.cl-opt-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  font-size: 0.95em;
  line-height: 1.5;
  color: var(--cl-muted);
}

.cl-opt-desc.is-expanded {
  display: block;
  overflow: visible;
  -webkit-line-clamp: unset;
  line-clamp: unset;
}

.cl-opt-desc :is(p, ul, ol, h1, h2, h3, h4, h5, h6) { margin: 0 0 0.35em; }
.cl-opt-desc :is(p, ul, ol, h1, h2, h3, h4, h5, h6):last-child { margin-bottom: 0; }
.cl-opt-desc :is(h1, h2, h3, h4, h5, h6) { font-size: 1em; font-weight: 700; }
.cl-opt-desc ul, .cl-opt-desc ol { padding-left: 1.2em; }
.cl-opt-desc a { color: var(--cl-accent); }

.cl-opt-more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  /* Generous hit area: this sits inside the label, and a senior aiming for it
     with a fingertip must not land on the class row behind it. */
  padding: 6px 10px 6px 0;
  font-family: inherit;
  font-size: 0.92em;
  font-weight: 700;
  color: var(--cl-accent);
  background: none;
  border: none;
  cursor: pointer;
}

.cl-opt-more:focus-visible { outline: 3px solid var(--cl-accent); outline-offset: 2px; border-radius: 6px; }

.cl-chevron {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid currentColor;
  transition: transform 140ms ease;
}

.cl-opt-more.is-expanded .cl-chevron { transform: rotate(180deg); }


/* The tag flows as part of the title's own text, not as a second flex item:
   flex-wrap would drop it onto a line of its own the moment the name got long,
   which on a phone is exactly the wasted line this replaced. Inline, it sits
   after the last word and only moves down if that word leaves no room. */
.cl-opt-head {
  display: block;
  align-self: stretch;
}

.cl-opt-name { display: inline; }

.cl-count-tag {
  display: inline-block;
  margin-left: 8px;
  vertical-align: baseline;
  padding: 2px 9px;
  font-size: 0.78em;
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--cl-ok);
  background: var(--cl-ok-soft);
  border-radius: 999px;
}

.cl-count-short { display: none; }

.cl-count-tag.is-zero {
  color: var(--cl-muted);
  background: var(--cl-surface-alt);
}

/* Sits in the title line beside the count tag, so it never costs a row. */
.cl-opt-doc {
  display: inline-block;
  margin-left: 8px;
  vertical-align: baseline;
  padding: 2px 10px;
  font-size: 0.78em;
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border-radius: 999px;
  text-decoration: none;
}

.cl-opt-doc:hover { text-decoration: underline; }
.cl-opt-doc:focus-visible { outline: 3px solid var(--cl-accent); outline-offset: 2px; }
.cl-doc-arrow { margin-left: 4px; font-size: 0.9em; }

.cl-opt-closes {
  margin-top: 2px;
  font-size: 0.88em;
  font-weight: 700;
  color: var(--cl-accent);
}

.cl-opt--none { background: var(--cl-surface-alt); }
.cl-opt--none .cl-opt-name { font-size: 1em; font-weight: 600; color: var(--cl-muted); }
.cl-opt--none.is-picked .cl-opt-name { color: var(--cl-text); }

/* ── Name + submit ────────────────────────────────────────────────────── */

.cl-name-card { text-align: left; }

.cl-form-side { min-width: 0; }

.cl-name-label {
  display: block;
  font-family: var(--cl-display);
  font-size: 1.15em;
  font-weight: 700;
  margin-bottom: 10px;
}

.cl-name-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 1.15em;
  padding: 14px 16px;
  color: var(--cl-text);
  background: var(--cl-surface-alt);
  border: 2px solid var(--cl-border-strong);
  border-radius: var(--cl-radius-sm);
}

.cl-name-input:focus {
  outline: 3px solid var(--cl-accent);
  outline-offset: 2px;
  background: var(--cl-surface);
}

.cl-contact-fields {
  display: grid;
  gap: 4px;
  margin-top: 14px;
}

.cl-contact-label {
  margin-top: 10px;
  margin-bottom: 8px;
  font-size: 1em;
}

.cl-optional {
  font-weight: 500;
  color: var(--cl-muted, #6b7280);
}

.cl-roster-person[title],
.cl-confirm-person[title] {
  cursor: help;
  text-decoration: underline dotted currentColor;
  text-underline-offset: 3px;
}

.cl-btn {
  font-family: var(--cl-display);
  font-size: 1.05em;
  font-weight: 700;
  color: var(--cl-solid-ink);
  background: linear-gradient(180deg, var(--cl-solid-from), var(--cl-solid-to));
  border: none;
  border-radius: 999px;
  padding: 14px 30px;
  cursor: pointer;
  box-shadow: var(--cl-solid-shadow);
  transition: filter var(--cl-ease), transform var(--cl-ease);
}

.cl-btn:hover { filter: brightness(1.05); }
.cl-btn:active { transform: translateY(1px); }
.cl-btn:disabled { opacity: 0.6; cursor: default; }
.cl-btn:focus-visible { outline: 3px solid var(--cl-accent); outline-offset: 3px; }

.cl-btn--big {
  display: block;
  width: 100%;
  margin-top: 18px;
  font-size: 1.2em;
  padding: 20px 24px;
}

.cl-btn--sm { font-size: 0.92em; padding: 12px 22px; }

.cl-btn--ghost {
  color: var(--cl-accent);
  background: transparent;
  border: 2px solid var(--cl-border-strong);
  box-shadow: none;
}

.cl-error {
  margin: 14px 0 0;
  padding: 12px 14px;
  font-weight: 600;
  color: var(--cl-danger);
  background: rgba(163, 35, 26, 0.08);
  border-radius: var(--cl-radius-sm);
  white-space: pre-line;
}

/* ── Confirmation (my sign-ups, in the right column) ──────────────────── */

.cl-mine { text-align: left; padding: 16px 16px 14px; margin-bottom: 12px; }

.cl-mine .cl-confirm-title {
  font-family: var(--cl-display);
  font-size: 1em;
  font-weight: 700;
  margin: 0 0 6px;
}

.cl-mine .cl-confirm-people { margin: 0 0 8px; }

.cl-mine .cl-confirm-line {
  margin: 4px 0 0;
  font-size: 0.88em;
  line-height: 1.65;
}

.cl-mine .cl-roster {
  padding: 8px 10px;
  margin-bottom: 6px;
}

.cl-mine .cl-roster-class { font-size: 0.92em; }

.cl-mine .cl-roster-group-title {
  font-size: 0.88em;
  margin: 10px 0 4px;
}

.cl-mine .cl-confirm-unsign {
  width: 1.45em;
  height: 1.45em;
  font-size: 0.85em;
}

.cl-mine .cl-note { margin: 0; font-size: 0.82em; }
.cl-mine .cl-pin-clear { margin-top: 8px; }

.cl-confirm-icon {
  width: 62px;
  height: 62px;
  margin: 0 auto 12px;
  display: grid;
  place-items: center;
  font-size: 1.6em;
  color: var(--cl-solid-ink);
  background: linear-gradient(180deg, var(--cl-solid-from), var(--cl-solid-to));
  border-radius: 50%;
}

.cl-confirm-title { font-family: var(--cl-display); font-size: 1.35em; margin: 0 0 4px; }
.cl-confirm-who { margin: 0 0 14px; font-size: 1em; color: var(--cl-muted); }

.cl-confirm-people { text-align: left; margin: 0 0 18px; }

.cl-confirm-line {
  margin: 6px 0 0;
  font-size: 0.98em;
  line-height: 2;
}

.cl-confirm-person { white-space: nowrap; }

.cl-confirm-unsign {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7em;
  height: 1.7em;
  margin: 0 0 0 0.05em;
  padding: 0;
  vertical-align: -0.15em;
  border: 1px solid var(--cl-border-strong);
  border-radius: 50%;
  background: var(--cl-surface);
  color: var(--cl-muted);
  font-size: 0.95em;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.cl-confirm-unsign:disabled { opacity: 0.45; }

.cl-person + .cl-person { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--cl-border); }

.cl-person-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}

.cl-person-name { font-family: var(--cl-display); font-size: 1.1em; font-weight: 700; }

/* Who the open form is for — only appears once a second person is possible. */
.cl-who-for {
  margin: 0 0 12px;
  padding: 10px 14px;
  font-size: 0.92em;
  font-weight: 700;
  color: var(--cl-accent);
  text-align: left;
  background: var(--cl-accent-soft);
  border-radius: var(--cl-radius-sm);
}

.cl-confirm-list { list-style: none; margin: 0; padding: 0; text-align: left; }

.cl-confirm-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  margin-bottom: 10px;
  background: var(--cl-accent-soft);
  border-radius: var(--cl-radius-sm);
}

.cl-confirm-item--none { background: var(--cl-surface-alt); color: var(--cl-muted); text-align: center; }
.cl-confirm-group { font-size: 0.8em; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--cl-accent); }
.cl-confirm-name { font-size: 1.1em; font-weight: 700; }

/* ── Name list (PIN) ──────────────────────────────────────────────────── */

.cl-names-title { font-family: var(--cl-display); font-size: 1.2em; margin: 0 0 4px; }

.cl-board-toggle-wrap {
  display: flex;
  justify-content: center;
  margin: 4px 0 8px;
}

.cl-board-toggle-wrap[hidden] { display: none !important; }

.cl-board-split { display: grid; gap: 28px; }

.cl-pin-form { display: flex; gap: 10px; align-items: center; margin-top: 12px; flex-wrap: wrap; }

.cl-pin-input {
  box-sizing: border-box;
  width: 6.5ch;
  height: 2.7em;
  font-family: var(--cl-display);
  font-size: 0.92em;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-align: center;
  padding: 0 10px;
  line-height: 1;
  color: var(--cl-text);
  background: var(--cl-surface-alt);
  border: 1px solid var(--cl-border-strong);
  border-radius: var(--cl-radius-sm);
  -webkit-text-security: disc;
}

.cl-pin-remember { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 0.88em; color: var(--cl-muted); }
.cl-pin-remember input { width: 20px; height: 20px; }

.cl-pin-clear {
  display: inline-block;
  margin-top: 12px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.88em;
  color: var(--cl-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.cl-pin-clear[hidden] { display: none; }

.cl-pin-status { margin: 10px 0 0; font-size: 0.92em; color: var(--cl-muted); }
.cl-pin-status.is-error { color: var(--cl-danger); font-weight: 600; }

.cl-stats-title { font-family: var(--cl-display); font-size: 1.05em; margin: 0 0 8px; }
.cl-stats-table { width: 100%; border-collapse: collapse; margin-top: 10px; }

.cl-stats-table th,
.cl-stats-table td {
  padding: 5px 0;
  font-size: 0.95em;
  font-weight: 500;
  text-align: left;
}

.cl-stats-table td { width: 4em; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

.cl-stats-total th,
.cl-stats-total td {
  padding-top: 9px;
  border-top: 2px solid var(--cl-border-strong);
  font-weight: 700;
}

.cl-stats-recent {
  margin-top: 14px;
}

.cl-board-banner .cl-btn {
  margin-top: 10px;
}

.cl-roster-wrap:not(:empty) { margin-top: 18px; }
.cl-roster-group-title { font-family: var(--cl-display); font-size: 1.05em; margin: 18px 0 8px; color: var(--cl-accent); }

.cl-roster {
  padding: 14px 16px;
  margin-bottom: 10px;
  background: var(--cl-surface-alt);
  border-radius: var(--cl-radius-sm);
}

.cl-roster-head { display: block; margin-bottom: 6px; }
.cl-roster-class { display: inline; font-size: 1em; font-weight: 700; }
.cl-roster-count { font-size: 0.88em; color: var(--cl-muted); }
.cl-roster-empty { margin: 0; color: var(--cl-muted); }

.cl-roster-names {
  margin: 6px 0 0;
  padding-left: 1.6em;
  columns: 2;
  column-gap: 26px;
  font-size: 0.98em;
}

.cl-roster-names li { break-inside: avoid; }

.cl-names-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 14px;
}

/* ── QR ───────────────────────────────────────────────────────────────── */

/* The note at the top exists because the code is at the foot of the page: on a
   projected screen the list is what people read, and nothing about it says a way
   to sign up is further down. */
.cl-qr-note {
  display: inline-flex;
  align-items: center;
  max-width: 28ch;
  margin: 0;
  padding: 8px 14px;
  font-size: 0.88em;
  font-weight: 600;
  line-height: 1.35;
  text-align: right;
  text-decoration: none;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border: 1px solid color-mix(in srgb, var(--cl-accent) 22%, var(--cl-border));
  border-radius: 999px;
}

.cl-qr-note:hover { text-decoration: underline; }
.cl-qr-note:focus-visible { outline: 3px solid var(--cl-accent); outline-offset: 2px; }

.cl-qr {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px 28px;
  flex-wrap: wrap;
  margin-top: 12px;
  scroll-margin-top: 88px;
  text-align: left;
}

.cl-qr-copy { min-width: 12rem; max-width: 28ch; }

/* Small and dimmed at rest: on a projected page the code sits under everything
   else and a bright white block competes with the classes for attention. It
   still scans from a phone held close; tapping it gives the full-size, full
   brightness version for the room.

   qrcodejs paints black on white, so the plate stays light in both themes —
   dimming is done with opacity over that plate, never by inverting it. */
.cl-qr-box {
  display: inline-block;
  flex: none;
  padding: 12px;
  background: #ffffff;
  border: none;
  border-radius: var(--cl-radius-sm);
  box-shadow: var(--cl-shadow);
  cursor: pointer;
  line-height: 0;
  opacity: 0.62;
  transition: opacity 160ms ease, transform var(--cl-ease);
}

.cl-qr-box:hover,
.cl-qr-box:focus-visible { opacity: 1; transform: translateY(-1px); }

.cl-qr-box:focus-visible { outline: 3px solid var(--cl-accent); outline-offset: 3px; }
.cl-qr-box img, .cl-qr-box canvas { display: block; }

.cl-qr-hint { margin: 0 0 6px; font-size: 1.05em; font-weight: 700; }
.cl-qr-enlarge { margin: 0; font-size: 0.88em; color: var(--cl-muted); }
.cl-qr-url { margin: 0 0 14px; font-size: 0.8em; color: var(--cl-muted); word-break: break-all; }

.cl-qr-modal .cl-qr-hint { margin: 14px 0 4px; text-align: center; }

/* Same shape as the home board's footer, in this page's palette. */
.cl-footer {
  padding: 1.5rem;
  text-align: center;
  font-size: 0.85em;
  color: var(--cl-muted);
  border-top: 1px solid var(--cl-border);
}

.cl-footer-meta { opacity: 0.6; }

body.cl-qr-open { overflow: hidden; }

.cl-qr-overlay {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(20, 17, 12, 0.78);
}

.cl-qr-modal {
  max-width: 100%;
  padding: 22px;
  text-align: center;
  background: var(--cl-surface);
  border-radius: var(--cl-radius);
  box-shadow: var(--cl-shadow);
}

.cl-qr-big {
  display: inline-block;
  padding: 16px;
  background: #ffffff;
  border-radius: var(--cl-radius-sm);
  line-height: 0;
}

/* Generated larger than it is shown, then scaled down — so it stays sharp on a
   projector at any of these sizes. */
.cl-qr-big img, .cl-qr-big canvas {
  display: block;
  width: min(64vh, 74vw, 560px);
  height: auto;
}

.cl-qr-modal .cl-qr-hint { margin: 14px 0 4px; font-size: 0.98em; font-weight: 600; }

/* Wide screens: classes on the left; my sign-ups + name + Sign Up sticky on
   the right so the action stays in view while scrolling a long term list. */
@media (min-width: 900px) {
  body.event-classes-page #clForm:not([hidden]) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
    column-gap: 22px;
    align-items: start;
  }

  .cl-steps { grid-column: 1 / -1; }

  .cl-who-for,
  #clGroups { grid-column: 1; }

  .cl-form-side {
    grid-column: 2;
    grid-row: 2 / span 8;
    position: sticky;
    top: 80px;
    margin-bottom: 0;
  }

  .cl-name-card { margin-bottom: 0; }

  .cl-board-split {
    grid-template-columns: minmax(180px, 0.4fr) minmax(0, 1fr);
    gap: 0 36px;
    align-items: start;
  }

  .cl-board-counts {
    position: sticky;
    top: 88px;
    padding-right: 28px;
  }

  .cl-board-names {
    padding-left: 36px;
    border-left: 1px solid var(--cl-border);
  }
}

@media (max-width: 899px) {
  .cl-hero { align-items: flex-start; }
  .cl-hero-tools { align-items: flex-start; width: 100%; }
  .cl-qr-note { text-align: left; max-width: none; }
}

@media (max-width: 520px) {
  .cl-wrap { --cl-base: 15px; }
  /* Tighter so a normal class name and its count still share one line on a
     phone — the whole point of the tag. A genuinely long name still wraps, and
     costs its own line only for that class. */
  .cl-count-tag { margin-left: 6px; padding: 1px 8px; font-size: 0.78em; }
  .cl-count-full { display: none; }
  .cl-count-short { display: inline; }
  .cl-opt-doc { margin-left: 6px; padding: 1px 8px; }
  .cl-wrap { padding: 18px 12px 48px; }
  .cl-card { padding: 18px 16px; }
  .cl-roster-names { columns: 1; }
  .cl-hero { margin-bottom: 18px; }
  .cl-steps { gap: 8px 12px; }
  .cl-qr { justify-content: flex-start; }
}


/* ---------------------------------------------------------------------------
   Bulk sign-up (desk tool)

   Two panels: classes on the left as drop targets, an unassigned name pool on
   the right. Drag-and-drop for a mouse, tap-then-tap for a tablet — the page is
   often driven from a laptop at a table, but not always, and HTML5 drag events
   never fire on touch.
   --------------------------------------------------------------------------- */

.cl-bulk-overlay {
  position: fixed;
  inset: 0;
  /* Above the sticky site nav (z-index 1050), same as the QR overlay — at 60
     the nav painted straight over the modal's header. */
  z-index: 1200;
  background: rgba(20, 17, 12, 0.55);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: cl-bulk-fade 160ms ease-out;
}

@keyframes cl-bulk-fade { from { opacity: 0; } to { opacity: 1; } }

.cl-bulk-modal {
  background: var(--cl-bg);
  border: 1px solid var(--cl-border);
  border-radius: var(--cl-radius);
  box-shadow: var(--cl-shadow-lift);
  width: min(1100px, 100%);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.cl-bulk-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--cl-border);
  background: var(--cl-surface);
}

.cl-bulk-title {
  margin: 0 0 4px;
  font-family: var(--cl-display);
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--cl-text);
}

.cl-bulk-hint {
  margin: 0;
  color: var(--cl-muted);
  font-size: 0.9rem;
  line-height: 1.5;
  max-width: 68ch;
}

.cl-bulk-body {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);
  gap: 0;
  overflow: hidden;
  flex: 1;
  min-height: 0;
}

.cl-bulk-classes {
  padding: 16px;
  overflow-y: auto;
  /* Grid items are min-height:auto by default, so without this a long class
     list refuses to shrink, pushes the row past .cl-bulk-body, and gets clipped
     by its overflow:hidden — tall content and no scrollbar anywhere. */
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
  align-content: start;
}

.cl-bulk-side {
  padding: 16px;
  border-left: 1px solid var(--cl-border);
  background: var(--cl-surface-alt);
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* The pool inside scrolls, not this — the paste box has to stay reachable
     however many names are waiting. */
  overflow: hidden;
}

/* Everything except the pool keeps its natural height. */
.cl-bulk-side-title,
.cl-bulk-empty,
.cl-bulk-input-label,
.cl-bulk-input,
.cl-bulk-input-hint,
.cl-bulk-side-actions { flex: none; }

.cl-bulk-side-title,
.cl-bulk-card-title {
  margin: 0 0 8px;
  font-family: var(--cl-display);
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--cl-text);
}

/* ---------- class cards (drop targets) ---------- */

.cl-bulk-card {
  background: var(--cl-surface);
  border: 2px dashed var(--cl-border);
  border-radius: var(--cl-radius-sm);
  padding: 12px;
  transition: border-color var(--cl-ease), background var(--cl-ease), transform var(--cl-ease), box-shadow var(--cl-ease);
}

.cl-bulk-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.cl-bulk-card-count {
  color: var(--cl-muted);
  font-size: 0.8rem;
  white-space: nowrap;
}

/* The landing cue: the card under the pointer lifts and turns solid-accent. */
.cl-bulk-card.is-drop-target {
  border-color: var(--cl-accent);
  border-style: solid;
  background: var(--cl-accent-soft);
  transform: translateY(-2px) scale(1.015);
  box-shadow: var(--cl-solid-shadow);
}

/* While a name is picked up, every card advertises that it can take it. */
.cl-bulk-modal.is-dragging .cl-bulk-card:not(.is-drop-target) {
  border-color: var(--cl-border-strong);
}

.cl-bulk-card-drop {
  margin: 8px 0 0;
  color: var(--cl-muted);
  font-size: 0.82rem;
  text-align: center;
  padding: 8px 4px;
  border-radius: 10px;
  background: var(--cl-surface-alt);
}

.cl-bulk-card-names {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  min-height: 34px;
}

/* ---------- name chips ---------- */

.cl-bulk-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--cl-surface-alt);
  border: 1px solid var(--cl-border);
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 0.9rem;
  color: var(--cl-text);
  max-width: 100%;
}

.cl-bulk-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cl-bulk-card .cl-bulk-chip {
  background: var(--cl-ok-soft);
  border-color: transparent;
  animation: cl-bulk-pop 220ms cubic-bezier(0.22, 1.2, 0.36, 1);
}

@keyframes cl-bulk-pop {
  from { transform: scale(0.72); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.cl-bulk-chip-x {
  border: none;
  background: none;
  color: var(--cl-muted);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  padding: 0 2px;
  border-radius: 6px;
}

.cl-bulk-chip-x:hover { color: var(--cl-danger); }
.cl-bulk-chip-x:focus-visible { outline: 2px solid var(--cl-accent); outline-offset: 1px; }

/* ---------- pool ---------- */

.cl-bulk-pool {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-content: start;
  /* Takes whatever height is left and scrolls inside it: forty pasted names
     must not push the paste box out of the panel. */
  flex: 1 1 auto;
  min-height: 64px;
  overflow-y: auto;
  margin-bottom: 6px;
  padding-right: 2px;
}

.cl-bulk-pool .cl-bulk-chip {
  cursor: grab;
  background: var(--cl-surface);
  transition: transform var(--cl-ease), box-shadow var(--cl-ease), background var(--cl-ease);
}

.cl-bulk-pool .cl-bulk-chip:hover { box-shadow: var(--cl-shadow); }
.cl-bulk-pool .cl-bulk-chip:active { cursor: grabbing; }
.cl-bulk-pool .cl-bulk-chip.is-dragging { opacity: 0.4; }

/* Tap-to-pick, for touch where dragging never fires. */
.cl-bulk-pool .cl-bulk-chip.is-selected {
  background: linear-gradient(140deg, var(--cl-solid-from), var(--cl-solid-to));
  color: var(--cl-solid-ink);
  border-color: transparent;
  box-shadow: var(--cl-solid-shadow);
  transform: translateY(-1px);
}

.cl-bulk-empty,
.cl-bulk-input-hint {
  margin: 4px 0 10px;
  color: var(--cl-muted);
  font-size: 0.84rem;
  line-height: 1.5;
}

.cl-bulk-input-label {
  display: block;
  padding-top: 12px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--cl-muted);
}

.cl-bulk-input {
  width: 100%;
  box-sizing: border-box;
  margin-top: 6px;
  background: var(--cl-surface);
  border: 1px solid var(--cl-border);
  border-radius: 12px;
  padding: 9px 10px;
  font: inherit;
  font-size: 0.9rem;
  color: var(--cl-text);
  resize: vertical;
}

.cl-bulk-input:focus {
  outline: none;
  border-color: var(--cl-accent);
  box-shadow: 0 0 0 3px var(--cl-ring);
}

.cl-bulk-side-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.cl-bulk-status {
  margin: 0;
  padding: 10px 20px 14px;
  border-top: 1px solid var(--cl-border);
  background: var(--cl-surface);
  color: var(--cl-muted);
  font-size: 0.88rem;
  min-height: 1.2em;
}

.cl-bulk-status.is-error { color: var(--cl-danger); }
.cl-bulk-status.is-ok { color: var(--cl-ok); }

@media (max-width: 860px) {
  .cl-bulk-body { grid-template-columns: 1fr; overflow-y: auto; }
  /* `min-height: 0` is what lets these columns scroll independently on a wide
     screen. Stacked in one column it is actively harmful: the grid row shrinks
     below its content, and because nothing here scrolls internally the class
     cards spill out and paint *on top of* the panel below — so taps aimed at a
     card were landing on the names panel instead. Let the rows grow and let the
     modal body do the scrolling. */
  .cl-bulk-classes,
  .cl-bulk-side { min-height: auto; overflow: visible; }
  .cl-bulk-side { border-left: none; border-top: 1px solid var(--cl-border); }
  .cl-bulk-pool { flex: none; overflow: visible; max-height: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cl-bulk-overlay { animation: none; }
  .cl-bulk-card,
  .cl-bulk-card .cl-bulk-chip,
  .cl-bulk-pool .cl-bulk-chip { transition: none; animation: none; }
  .cl-bulk-card.is-drop-target { transform: none; }
}

/* Sort A–Z, on the pool heading and on each card. A text label, not an icon:
   this page ships no icon font, and it is read by people using the large-text
   control. Display-only — see compareNamesAlpha. */
.cl-bulk-sort {
  border: 1px solid var(--cl-border);
  background: var(--cl-surface);
  color: var(--cl-muted);
  border-radius: 999px;
  padding: 2px 9px;
  font: inherit;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.6;
  cursor: pointer;
  white-space: nowrap;
  flex: none;
  transition: background var(--cl-ease), color var(--cl-ease), border-color var(--cl-ease);
}

.cl-bulk-sort:hover { border-color: var(--cl-border-strong); color: var(--cl-text); }
.cl-bulk-sort:focus-visible { outline: 2px solid var(--cl-accent); outline-offset: 1px; }

.cl-bulk-sort.is-active {
  background: var(--cl-accent);
  border-color: transparent;
  color: var(--cl-solid-ink);
}

.cl-bulk-side-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex: none;
}

.cl-bulk-side-head .cl-bulk-side-title { margin-bottom: 8px; }

/* The card head now carries title, count and sort; keep them on one line with
   the title taking the slack. */
.cl-bulk-card-head { flex-wrap: wrap; }
.cl-bulk-card-head .cl-bulk-card-title { flex: 1 1 auto; min-width: 0; }

/* ---------- share row (under the QR) ---------- */

.cl-share-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}

.cl-share-status {
  margin: 8px 0 0;
  min-height: 1.2em;
  font-size: 0.86rem;
  text-align: center;
  color: var(--cl-muted);
}

.cl-share-status.is-ok { color: var(--cl-ok); }
.cl-share-status.is-error { color: var(--cl-danger); }

/* Roster A–Z toggle: sits with Copy, and lights up while the sort is on so it
   is obvious that Copy will follow it rather than sign-up order. */
#clNamesSort.is-active {
  background: var(--cl-accent-soft);
  border-color: var(--cl-accent);
  color: var(--cl-accent);
}

/* Copy / sort feedback, inline with the buttons that cause it. */
.cl-names-actions-status {
  font-size: 0.85rem;
  color: var(--cl-muted);
  align-self: center;
  min-height: 1em;
}

.cl-names-actions-status.is-ok { color: var(--cl-ok); }
.cl-names-actions-status.is-error { color: var(--cl-danger); }


/* ── Slice 1 additions (event-level signup, 2026-10) ─────────────────────── */

/* The event's own description under the lead — same type as the lead, muted. */
.cl-event-desc {
  margin: 10px 0 0;
  font-size: 0.98em;
  color: var(--cl-muted);
}
.cl-event-desc p { margin: 0 0 6px; }

/* No ?event=: one row per open signup. Whole row is the link. */
.cl-list-items { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.cl-list-link {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  padding: 16px 18px;
  color: var(--cl-text);
  text-decoration: none;
  background: var(--cl-surface-alt);
  border: 1px solid var(--cl-border);
  border-radius: var(--cl-radius-sm);
  transition: border-color var(--cl-ease), box-shadow var(--cl-ease);
}
.cl-list-link:hover,
.cl-list-link:focus-visible { border-color: var(--cl-accent); box-shadow: var(--cl-shadow); }
.cl-list-name { font-family: var(--cl-display); font-weight: 700; font-size: 1.15em; }
.cl-list-when { color: var(--cl-muted); font-size: 0.92em; }
.cl-list-link .cl-closed-tag { margin: 0; }

/* Room under the class name: what a senior needs to find it on Sunday. */
.cl-opt-room {
  display: block;
  margin-top: 2px;
  font-size: 0.92em;
  font-weight: 600;
  color: var(--cl-muted);
}

/* A full class: the count turns amber; picking it shows the not-guaranteed
   note right under it. Never red — nothing is refused (design D21). */
.cl-count-tag.is-full {
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  outline: 1px solid var(--cl-accent);
}
.cl-opt-full-note,
.cl-warn,
.cl-roster-full {
  display: block;
  margin-top: 8px;
  padding: 10px 12px;
  font-size: 0.9em;
  font-weight: 600;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border-radius: var(--cl-radius-sm);
}
.cl-opt-full-note[hidden],
.cl-warn[hidden] { display: none; }
.cl-warn { margin: 0 0 10px; }
.cl-roster-full { margin: 4px 0 8px; padding: 6px 10px; font-size: 0.85em; }

.cl-bulk-card-over {
  margin-left: 6px;
  padding: 1px 8px;
  font-size: 0.78em;
  font-weight: 700;
  color: var(--cl-accent);
  background: var(--cl-accent-soft);
  border-radius: 999px;
}

.cl-note-input { min-height: 3.2em; resize: vertical; font-family: inherit; }

/* A plain signup has no classes column: one centred column, name card first. */
@media (min-width: 900px) {
  body.event-classes-page #clForm.is-plain:not([hidden]) {
    grid-template-columns: minmax(0, 520px);
    justify-content: center;
  }
  body.event-classes-page #clForm.is-plain .cl-form-side {
    grid-column: 1;
    grid-row: auto;
    position: static;
  }
}
