/* ===========================================================================
   Sloth design tokens.
   Rule of colour: BLUE means "do this" (one primary action per screen).
   HONEY means "people are free here" (the availability heat). Everything else is
   warm neutrals that sit quietly around the grid.
   =========================================================================== */
:root {
  color-scheme: light;

  /* Neutrals (warm, to sit with the mascot's cream and honey) */
  --bg: #fffcf7;
  --surface: #ffffff;
  --surface-2: #fbf6ee;
  --line: #eee6da;
  --line-strong: #d8ccbb;
  --text: #3c4043;          /* soft charcoal, 10.2:1 on --bg (Calendar-style) */
  --muted: #5f6368;         /* 5.9:1 on --bg, 5.6:1 on --surface-2 */
  --text-on-heat: #2b2622;  /* deep ink kept only for counts on --heat-4 (6.5:1) */

  /* Action blue (the branch, deepened for contrast: 6.3:1 with white) */
  --accent: #2f5fa7;
  --accent-hover: #244c88;
  --accent-soft: #eef3fb;
  --focus: 0 0 0 3px rgba(47, 95, 167, 0.32);

  /* Data honey (the fur). Text passes on every step (6.3:1 or better; heat-4 uses --text-on-heat). */
  --heat-0: #ffffff;
  --heat-1: #fff4de;
  --heat-2: #fbe1b0;
  --heat-3: #f2c27a;
  --heat-4: #de9f55;
  --peach: #f4c5b3;

  /* Sloth brown: big numbers and results (the "answer" ink). 8.2:1 on --bg. */
  --sloth: #7a4a24;

  /* Top tabs: real buttons. Active = solid sloth brown (white 7.4:1), inactive =
     honey-cream pill with brown text (6.2:1), hover = a deeper tint (6.7:1).
     Milestones mirrors these exactly. */
  --tab-bg: #f6ead8;
  --tab-line: #e8d5b9;
  --tab-fg: #7a4a24;
  --tab-hover-bg: #efdcc0;
  --tab-hover-fg: #6a3f1e;
  --tab-active-bg: #7a4a24;
  --tab-active-hover-bg: #6a3f1e;
  --tab-active-fg: #ffffff;

  /* Status */
  --warn: #8a5a12;
  --warn-soft: #fff4de;
  --danger: #b4432f;
  --danger-soft: #fdeeea;

  /* Legacy aliases kept so older selectors resolve while passes land. */
  --accent-dark: var(--accent-hover);
  --surface-3: var(--surface-2);
  --blue: var(--accent);
  --amber: var(--heat-4);

  /* Type */
  --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: "Figtree", "Inter", system-ui, sans-serif;
  --fs-caption: 0.75rem;   /* 12 */
  --fs-ui: 0.875rem;       /* 14 */
  --fs-body: 1rem;         /* 16 */
  --fs-card: 1.25rem;      /* 20 */
  --fs-title: 1.75rem;     /* 28 */

  /* Space (4px base) */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  /* Shape */
  --r-input: 10px;
  --r-button: 12px;
  --r-card: 20px;
  --r-pill: 999px;
  --shadow-1: 0 1px 2px rgba(43, 38, 34, 0.06);
  --shadow-2: 0 6px 20px rgba(43, 38, 34, 0.07);
  --shadow-3: 0 12px 32px rgba(43, 38, 34, 0.12);
  --shadow: var(--shadow-2);
}

* {
  box-sizing: border-box;
}

/* The hidden attribute must always win over a class's display rule. */
[hidden] {
  display: none !important;
}

html,
body {
  min-height: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* Calendar-style restraint: nothing above 600. Headings are Figtree 500,
   emphasis is Inter 500; hierarchy comes from size, not weight. */
strong,
b {
  font-weight: 500;
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  cursor: pointer;
}

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

:focus-visible {
  outline: none;
  box-shadow: var(--focus);
}

.app-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ---------------------------------------------------------------------------
   Header: mascot + wordmark + tagline, text tabs, one quiet secondary button.
   --------------------------------------------------------------------------- */
.topbar {
  min-height: 68px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-3) var(--s-5);
  background: rgba(255, 252, 247, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 220px;
}

.brand-mark {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  object-fit: contain;
}

.brand h1,
.brand p,
.section-head h2,
.section-head p,
.panel-title h2 {
  margin: 0;
}

.brand h1 {
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.05;
  color: var(--text);
}

.brand-tagline {
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--fs-caption);
  font-weight: 500;
  white-space: nowrap;
}

.mode-tabs {
  display: inline-flex;
  align-items: stretch;
  gap: 6px;
}

.tab {
  position: relative;
  min-height: 44px;
  padding: 0 var(--s-4);
  border: 1px solid var(--tab-line);
  border-radius: var(--r-pill);
  color: var(--tab-fg);
  background: var(--tab-bg);
  font-size: var(--fs-ui);
  font-weight: 600;
  white-space: nowrap;
  transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

/* The Milestones link sits in the same tab bar and must look like the buttons. */
a.tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.tab:hover {
  color: var(--tab-hover-fg);
  background: var(--tab-hover-bg);
}

.tab.is-active {
  border-color: var(--tab-active-bg);
  color: var(--tab-active-fg);
  background: var(--tab-active-bg);
}

.tab.is-active:hover {
  border-color: var(--tab-active-hover-bg);
  background: var(--tab-active-hover-bg);
}

.tab:focus-visible {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);
}

.guide-button {
  min-height: 40px;
  padding: 0 var(--s-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-ui);
  font-weight: 500;
  white-space: nowrap;
}

.guide-button:hover,
.guide-button.is-active {
  border-color: var(--accent);
  color: var(--accent);
}

/* Off phones the header is three equal tracks: brand pinned left, tabs truly
   centred, actions pinned right. Milestones mirrors this exactly. */
@media (min-width: 761px) {
  .topbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  }

  .topbar > .guide-button {
    justify-self: end;
  }
}

/* ---------------------------------------------------------------------------
   Workspace: setup column + main area.
   --------------------------------------------------------------------------- */
.workspace {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(300px, 360px) minmax(0, 1fr);
  gap: var(--s-5);
  padding: var(--s-5);
  min-height: 0;
  width: 100%;
  max-width: 1600px;
  margin: 0 auto;
}

.sidebar {
  display: grid;
  align-content: start;
  gap: var(--s-4);
  min-width: 0;
}

.tool-panel {
  min-width: 0;
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-2);
}

.panel-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}

#searchStatus {
  text-align: right;
  line-height: 1.3;
}

.panel-title.inline {
  margin-bottom: var(--s-3);
}

.panel-title h2 {
  font-size: var(--fs-card);
  font-weight: 500;
  line-height: 1.2;
  color: var(--text);
}

.panel-title span {
  color: var(--muted);
  font-size: var(--fs-caption);
}

/* ---------------------------------------------------------------------------
   Form controls
   --------------------------------------------------------------------------- */
.field {
  display: grid;
  gap: 6px;
  margin-bottom: var(--s-3);
}

.field > span {
  color: var(--text);
  font-size: var(--fs-ui);
  font-weight: 500;
}

.field input,
.field select,
textarea {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-input);
  background: var(--surface);
  color: var(--text);
  padding: 10px 12px;
  font-size: var(--fs-ui);
  box-shadow: var(--shadow-1);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input:hover,
.field select:hover {
  border-color: #c4b7a4;
}

.field input:focus,
.field select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--focus);
}

.field input:disabled,
.field select:disabled {
  background: var(--surface-2);
  color: var(--muted);
  cursor: not-allowed;
}

.field input.has-error,
.field select.has-error {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(180, 67, 47, 0.18);
}

.field-note {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

.day-field {
  margin-top: 0;
}

.lesson-note {
  margin: -6px 0 var(--s-3);
}

/* Start/end ranges (event dates, hours): always ONE line, two shrinking
   inputs with a small "to" between, at every width. */
.range-inputs {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--s-2);
}

.field .range-inputs input {
  min-width: 0;
  width: 100%;
}

@media (max-width: 420px) {
  .range-inputs {
    gap: 6px;
  }

  .field .range-inputs input {
    min-height: 40px;
    padding: 8px 6px;
    font-size: 0.8125rem;
  }

  .field .range-inputs input::-webkit-calendar-picker-indicator {
    width: 12px;
    height: 12px;
    margin: 0;
    padding: 0;
  }
}

/* iOS Safari zooms the page when a focused input is under 16px. */
@supports (-webkit-touch-callout: none) {
  .field input,
  .field select,
  .field .range-inputs input {
    font-size: 16px;
  }
}

.date-range-sep {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: var(--fs-caption);
}

.day-toggles {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--s-1);
}

.day-chip {
  position: relative;
  display: block;
  cursor: pointer;
}

.day-chip input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
}

.field .day-chip span {
  display: grid;
  place-items: center;
  min-height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-input);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--fs-caption);
  font-weight: 500;
  text-align: center;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.field .day-chip:hover span {
  border-color: var(--accent);
  color: var(--accent);
}

.field .day-chip input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 500;
}

.field .day-chip input:focus-visible + span {
  box-shadow: var(--focus);
}

.day-chip input:disabled + span {
  cursor: not-allowed;
}

.event-dates-label {
  margin: 0 0 4px;
  color: var(--text);
  font-size: var(--fs-ui);
  font-weight: 500;
}

/* ---------------------------------------------------------------------------
   Buttons. Primary = filled blue, at most one per screen. Secondary = outline.
   Small = compact outline. Dismiss = quiet text-style.
   --------------------------------------------------------------------------- */
.primary-button {
  min-height: 48px;
  padding: 0 var(--s-5);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: #ffffff;
  font-size: var(--fs-body);
  font-weight: 600;
  box-shadow: 0 4px 14px rgba(47, 95, 167, 0.25);
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.primary-button:hover {
  background: var(--accent-hover);
}

.primary-button:active {
  transform: translateY(1px);
}

.primary-button:disabled {
  opacity: 0.6;
  cursor: progress;
}

.small-button,
.secondary-button {
  min-height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  font-weight: 500;
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.small-button {
  min-height: 36px;
  padding: 0 var(--s-3);
  color: var(--accent);
  white-space: nowrap;
  font-size: var(--fs-ui);
}

.small-button:hover,
.secondary-button:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

.secondary-button {
  flex: 1;
  padding: 0 var(--s-3);
  font-size: var(--fs-ui);
}

.secondary-button.danger {
  color: var(--danger);
}

.secondary-button.danger:hover {
  border-color: var(--danger);
  color: var(--danger);
  background: var(--danger-soft);
}

.secondary-button:disabled,
.small-button:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

.button-row {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
}

/* Tertiary: text-only actions (destructive ones in brick, never filled). */
.text-button {
  min-height: 36px;
  padding: 0 var(--s-2);
  border: 0;
  border-radius: var(--r-input);
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-ui);
  font-weight: 500;
}

.text-button:hover {
  color: var(--text);
  background: var(--surface-2);
}

.text-button.danger:hover {
  color: var(--danger);
  background: var(--danger-soft);
}

.text-button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.quiet-row {
  justify-content: space-between;
  margin-top: var(--s-1);
}

/* ---------------------------------------------------------------------------
   Setup steps (1 When, 2 Who, 3 Share) and progressive disclosure
   --------------------------------------------------------------------------- */
.step-num {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-right: var(--s-2);
  border-radius: 50%;
  background: var(--heat-1);
  color: var(--warn);
  font-family: var(--font-display);
  font-size: var(--fs-ui);
  font-weight: 500;
  vertical-align: 2px;
}

.field-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}

.disclosure {
  margin-top: var(--s-2);
  border-top: 1px solid var(--line);
}

.disclosure > summary {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  color: var(--muted);
  font-size: var(--fs-ui);
  font-weight: 500;
  list-style: none;
  cursor: pointer;
  border-radius: var(--r-input);
}

.disclosure > summary::-webkit-details-marker {
  display: none;
}

.disclosure > summary::before {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}

.disclosure[open] > summary::before {
  transform: rotate(45deg);
}

.disclosure > summary:hover {
  color: var(--text);
}

.disclosure-body {
  padding: var(--s-1) 0 var(--s-2);
}

.disclosure-body > .field-note {
  margin: -4px 0 var(--s-3);
}

.empty-hint {
  margin: 0;
  padding: var(--s-4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-button);
  color: var(--muted);
  font-size: var(--fs-ui);
  line-height: 1.5;
  text-align: center;
}

/* Session length matters only to Clean Schedule: shown on that tab alone. */
.lesson-field,
.lesson-note {
  display: none;
}

body.mode-scheduler .lesson-field {
  display: grid;
}

body.mode-scheduler .lesson-note {
  display: block;
}

.share-step .primary-button {
  width: 100%;
}

/* ---------------------------------------------------------------------------
   People
   --------------------------------------------------------------------------- */
.person-list {
  display: grid;
  gap: var(--s-1);
  margin-bottom: var(--s-4);
}

.person-button {
  width: 100%;
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr);
  gap: var(--s-3);
  align-items: center;
  min-height: 48px;
  padding: var(--s-2) var(--s-3);
  border: 1px solid transparent;
  border-radius: var(--r-button);
  background: transparent;
  color: var(--text);
  text-align: left;
}

.person-button:hover {
  background: var(--surface-2);
}

.person-button.is-active {
  background: var(--accent-soft);
  border-color: rgba(47, 95, 167, 0.35);
}

.person-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--line-strong);
  box-shadow: 0 0 0 2px var(--surface);
}

.person-copy {
  min-width: 0;
  display: grid;
  gap: 1px;
}

.person-copy strong,
.assignment-row strong,
.best-copy strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.person-copy strong {
  font-size: var(--fs-ui);
  font-weight: 500;
}

.person-copy small,
.assignment-row small,
.best-copy small {
  color: var(--muted);
  font-size: var(--fs-caption);
}

.editor {
  padding-top: var(--s-1);
}

textarea {
  min-height: 110px;
  margin-top: var(--s-3);
  resize: vertical;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: var(--fs-caption);
}

textarea.has-error {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(180, 67, 47, 0.18);
}

/* ---------------------------------------------------------------------------
   Main area, guide card, section heads
   --------------------------------------------------------------------------- */
.main-area {
  min-width: 0;
}

.dismiss-button {
  min-height: 40px;
  padding: 0 var(--s-3);
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-ui);
  font-weight: 500;
  white-space: nowrap;
}

.dismiss-button:hover {
  color: var(--text);
  background: var(--surface-2);
}

.mode-panel {
  display: none;
}

.mode-panel.is-active {
  display: block;
}

.section-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-4);
}

.eyebrow,
.section-intro {
  margin: 0;
  color: var(--accent);
  font-size: var(--fs-ui);
  font-weight: 500;
}

.section-head h2 {
  margin-top: 2px;
  font-size: var(--fs-title);
  font-weight: 500;
  line-height: 1.15;
}

.section-note {
  max-width: 600px;
  margin: var(--s-2) 0 0;
  color: var(--muted);
  font-size: var(--fs-ui);
  line-height: 1.5;
}

.score-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--s-2);
}

.score-strip span {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 var(--s-3);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-caption);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.split-layout,
.schedule-layout {
  display: grid;
  grid-template-columns: minmax(440px, 1fr) minmax(260px, 340px);
  gap: var(--s-5);
  align-items: start;
}

.calendar-panel,
.results-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-2);
}

.calendar-panel {
  overflow: auto;
}

.results-panel {
  padding: var(--s-5);
}

/* ---------------------------------------------------------------------------
   Grids (shared skeleton for availability + schedule)
   --------------------------------------------------------------------------- */
.availability-grid,
.schedule-grid {
  --day-count: 5;
  display: grid;
  grid-template-columns: 76px repeat(var(--day-count), minmax(88px, 1fr));
  min-width: 600px;
  background: var(--line);
  gap: 1px;
  font-variant-numeric: tabular-nums;
}

.availability-grid {
  grid-template-columns: 76px repeat(var(--day-count), minmax(60px, 1fr));
  min-width: 0;
  user-select: none;
  -webkit-user-select: none;
}

.grid-corner,
.day-header,
.time-label,
.availability-cell,
.schedule-cell {
  background: var(--surface);
}

.grid-corner,
.day-header {
  min-height: 38px;
  position: sticky;
  top: 0;
  z-index: 5;
}

.grid-corner {
  left: 0;
  z-index: 6;
}

.day-header {
  display: grid;
  place-items: center;
  color: var(--text);
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.time-label {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 var(--s-3);
  color: var(--muted);
  font-size: var(--fs-caption);
  white-space: nowrap;
  position: sticky;
  left: 0;
  z-index: 4;
}

/* Compact zone row (8b): groups the reference-zone control with its single S5
   caption caption, matching the Meeting Duration field's structure. The .field
   inside keeps the shared field layout; the group just tightens the caption gap. */
.zone-row {
  display: grid;
  gap: 2px;
}

.zone-row .field {
  margin-bottom: 4px;
}

.zone-row .field-note {
  margin-top: 0;
}

/* S5 disclosure above the grid: whose clock the times are on, always named. */
.tz-disclosure {
  display: grid;
  gap: var(--s-1);
  margin-bottom: var(--s-3);
}

.tz-line {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-ui);
}

.tz-name {
  color: var(--text);
  font-weight: 500;
}

.tz-change {
  border: 0;
  background: none;
  padding: 0 2px;
  color: var(--accent);
  font: inherit;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  border-radius: 4px;
}

.tz-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-1);
  font-size: var(--fs-ui);
  color: var(--muted);
}

.tz-picker input,
.tz-picker select {
  min-height: 40px;
  min-width: 0;
  max-width: 100%;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-input);
  background: var(--surface);
  color: var(--text);
  padding: 6px 10px;
  font-size: var(--fs-ui);
}

.tz-picker select {
  max-width: 340px;
}

.tz-picker input:focus,
.tz-picker select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--focus);
}

.tz-picker input.has-error,
.tz-picker select.has-error {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(180, 67, 47, 0.18);
}

.tz-caveat {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

/* ---------------------------------------------------------------------------
   Availability cells.
   Honey = how many people can attend a full meeting starting here (O5).
   Solid blue + check = the selected person's own marks. Hatched blue = marked,
   but their full meeting can't start here (item 4). Ink ring + star = everyone.
   Hue AND lightness both change, and the count is printed: never colour alone.
   Decorations are pseudo-elements with pointer-events: none (touch painting
   hit-tests the cell itself).
   --------------------------------------------------------------------------- */
.availability-cell {
  position: relative;
  min-width: 0;
  min-height: 34px;
  border: 0;
  padding: 0;
  color: var(--text);
  background: var(--heat-0);
  font-size: var(--fs-caption);
  font-weight: 400;
  transition: background-color 0.08s ease;
}

.availability-cell[data-heat="1"] { background: var(--heat-1); }
.availability-cell[data-heat="2"] { background: var(--heat-2); }
.availability-cell[data-heat="3"] { background: var(--heat-3); }
.availability-cell[data-heat="4"] { background: var(--heat-4); color: var(--text-on-heat); }

.availability-cell:hover {
  box-shadow: inset 0 0 0 2px rgba(47, 95, 167, 0.45);
}

.availability-cell:focus-visible {
  box-shadow: inset 0 0 0 3px var(--accent);
}

.availability-cell.is-everyone {
  box-shadow: inset 0 0 0 2px var(--text);
  font-weight: 500;
}

.availability-cell.is-everyone::before {
  content: "\2605";
  position: absolute;
  top: 2px;
  left: 4px;
  font-size: 9px;
  line-height: 1;
  pointer-events: none;
}

.availability-cell.is-selected {
  color: #ffffff;
  background: var(--accent);
  font-weight: 500;
}

.availability-cell.is-selected::after {
  content: "";
  position: absolute;
  top: 5px;
  right: 6px;
  width: 4px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.9;
  pointer-events: none;
}

.availability-cell.is-selected.is-everyone {
  box-shadow: inset 0 0 0 2px var(--text), inset 0 0 0 4px #ffffff;
}

.availability-cell.is-tail {
  color: var(--accent-hover);
  background: repeating-linear-gradient(
    135deg,
    var(--accent-soft) 0 5px,
    rgba(47, 95, 167, 0.3) 5px 8px
  );
  box-shadow: inset 0 0 0 2px var(--accent);
}

/* A viewer-grid bucket with no reference-window cell (spillover hole). Inert. */
.availability-cell.is-empty {
  background: repeating-linear-gradient(
    45deg,
    rgba(43, 38, 34, 0.04),
    rgba(43, 38, 34, 0.04) 4px,
    transparent 4px,
    transparent 8px
  );
  pointer-events: none;
}

/* A cell that maps outside the reference window (S6 out-of-window = not paintable). */
.availability-cell.is-unpaintable {
  background: var(--surface-2);
  color: var(--muted);
  cursor: not-allowed;
}

/* Legend: one quiet line of swatches above the grid. */
.grid-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin-bottom: var(--s-3);
  color: var(--muted);
  font-size: var(--fs-caption);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

.swatch,
.swatch-ramp b {
  display: inline-block;
  width: 16px;
  height: 16px;
  border-radius: 4px;
}

.swatch-mine {
  background: var(--accent);
}

.swatch-tail {
  background: repeating-linear-gradient(135deg, var(--accent-soft) 0 3px, rgba(47, 95, 167, 0.35) 3px 5px);
  box-shadow: inset 0 0 0 2px var(--accent);
}

.swatch-all {
  background: var(--heat-4);
  box-shadow: inset 0 0 0 2px var(--text);
}

.swatch-ramp {
  display: inline-flex;
  gap: 2px;
}

.swatch-ramp b[data-heat="1"] { background: var(--heat-1); box-shadow: inset 0 0 0 1px var(--line-strong); }
.swatch-ramp b[data-heat="2"] { background: var(--heat-2); }
.swatch-ramp b[data-heat="3"] { background: var(--heat-3); }

.schedule-grid {
  position: relative;
}

.schedule-grid .day-header,
.schedule-grid .grid-corner {
  min-height: 40px;
}

.schedule-cell {
  min-height: 44px;
}

/* One session block: a soft tint of the person's colour, a solid edge in it,
   and the name always printed (colour is never the only cue). */
.schedule-assignment {
  --person: var(--accent);
  z-index: 2;
  min-width: 0;
  margin: 2px 3px;
  padding: 5px 8px;
  border-left: 4px solid var(--person);
  border-radius: var(--r-input);
  background: var(--surface);
  background: color-mix(in srgb, var(--person) 12%, var(--surface));
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.schedule-assignment strong,
.schedule-assignment span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.schedule-assignment strong {
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.2;
}

.schedule-assignment span {
  margin-top: 1px;
  color: var(--muted);
  font-size: 0.6875rem;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
}

/* ROADMAP 10: a one-block session (e.g. 30 min) keeps both lines inside 40px. */
.schedule-assignment.is-short {
  padding-top: 4px;
  padding-bottom: 4px;
}

/* The payoff line: one sentence about the result, with the mascot. */
.schedule-hero {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-card);
  background: var(--surface-2);
  border: 1px solid var(--line);
}

.schedule-hero.is-complete {
  background: var(--heat-1);
  border-color: var(--heat-2);
}

.schedule-hero-art {
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  pointer-events: none;
}

.schedule-hero p {
  margin: 0;
}

.schedule-hero-title {
  font-family: var(--font-display);
  font-size: var(--fs-card);
  font-weight: 500;
  line-height: 1.25;
}

.schedule-hero-sub {
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--fs-ui);
}

#scheduleZoneLine {
  margin-bottom: var(--s-3);
}

#searchStatus {
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-caption);
  font-weight: 500;
}

.best-zone-note {
  margin: -4px 0 var(--s-2);
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

.best-list,
.assignment-list {
  display: grid;
  gap: 8px;
}

.best-row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  grid-template-areas: "rank copy count" "rank meter count";
  align-items: center;
  gap: 6px var(--s-3);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}

.best-row .rank { grid-area: rank; align-self: start; }
.best-row .best-copy { grid-area: copy; }
.best-row .fit-meter { grid-area: meter; }
.best-row .fit-count { grid-area: count; }

.best-copy strong {
  white-space: normal;
  font-size: var(--fs-ui);
  font-weight: 500;
}

.best-row:last-child {
  border-bottom: 0;
}

.rank {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--heat-1);
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 500;
}

.best-copy,
.assignment-row > div {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.fit-meter {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  overflow: hidden;
}

.fit-meter span {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--heat-4);
}

.fit-count {
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 500;
  text-align: right;
}

.assignment-row {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  min-height: 46px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.assignment-row:last-child {
  border-bottom: 0;
}

.assignment-row .student-local {
  display: block;
  color: var(--muted);
  font-size: var(--fs-caption);
}

.assignment-row.is-missed {
  margin-top: var(--s-2);
  padding: var(--s-3);
  border: 1px dashed rgba(180, 67, 47, 0.4);
  border-radius: var(--r-button);
  background: var(--danger-soft);
}

.assignment-row.is-missed small {
  color: var(--danger);
  font-weight: 500;
}

.assignment-row.is-missed .person-dot {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--danger);
}

.empty-state {
  padding: var(--s-5) var(--s-4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-button);
  color: var(--muted);
  font-size: var(--fs-ui);
  text-align: center;
}

@media (max-width: 1100px) {
  .workspace {
    grid-template-columns: minmax(0, 1fr);
  }

  .sidebar {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    align-items: start;
  }

  .split-layout,
  .schedule-layout {
    grid-template-columns: minmax(0, 1fr);
  }

}

@media (max-width: 760px) {
  .topbar {
    flex-wrap: wrap;
    gap: var(--s-2) var(--s-3);
    padding: var(--s-3) var(--s-4) var(--s-2);
  }

  .brand {
    min-width: 0;
    flex: 1 1 auto;
  }

  .brand-mark {
    width: 36px;
    height: 36px;
  }

  .guide-button {
    min-height: 36px;
    padding: 0 var(--s-3);
  }

  .mode-tabs {
    order: 3;
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .tab {
    flex: 1 0 auto;
    min-height: 40px;
    padding: 0 var(--s-3);
  }

  .workspace {
    padding: var(--s-4);
    gap: var(--s-4);
  }

  .sidebar {
    grid-template-columns: minmax(0, 1fr);
  }

  .tool-panel,
  .results-panel {
    padding: var(--s-4);
  }

  .section-head {
    align-items: start;
    flex-direction: column;
  }

  .section-head h2 {
    font-size: 1.5rem;
  }

  .score-strip {
    justify-content: flex-start;
  }

  .availability-grid {
    grid-template-columns: 58px repeat(var(--day-count), minmax(40px, 1fr));
    min-width: 0;
  }

  .schedule-grid {
    grid-template-columns: 58px repeat(var(--day-count), minmax(76px, 1fr));
    min-width: 0;
  }

  .availability-grid .time-label {
    padding: 0 var(--s-2);
    font-size: 0.6875rem;
  }

  .availability-grid .day-header {
    font-size: 0.6875rem;
  }


}

/* "Exit sample" bar (local mode, sample session only). Minimal; polish pending. */
.sample-bar {
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin: 0 0 var(--s-4);
  padding: var(--s-2) var(--s-2) var(--s-2) 56px;
  min-height: 56px;
  border: 1px solid var(--heat-2);
  border-radius: var(--r-card);
  background: var(--heat-1) url("assets/sloth-96.png") 14px center / 30px no-repeat;
  color: var(--warn);
  font-size: var(--fs-ui);
  font-weight: 500;
}

.sample-bar .small-button {
  flex: 0 0 auto;
  border-color: var(--heat-3);
  background: var(--surface);
  color: var(--text);
}

.sample-bar .small-button:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--surface);
}

/* "Start a new empty event": quiet, separated, brick only as a hint. */
#newEventBtn {
  display: block;
  margin-top: var(--s-3);
  padding-left: 0;
  color: var(--danger);
  font-weight: 500;
}

#newEventBtn:hover {
  padding-left: var(--s-2);
  background: var(--danger-soft);
}

/* Locked time zone: say it calmly, right under the (disabled) select. */
.zone-row:has(#eventZone:disabled) #eventZoneNote {
  margin-top: var(--s-1);
  padding: var(--s-2) var(--s-3) var(--s-2) 30px;
  border-radius: var(--r-input);
  background: var(--warn-soft);
  color: var(--warn);
  position: relative;
}

.zone-row:has(#eventZone:disabled) #eventZoneNote::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 12px;
  width: 9px;
  height: 7px;
  border-radius: 2px;
  background: currentColor;
}

.zone-row:has(#eventZone:disabled) #eventZoneNote::after {
  content: "";
  position: absolute;
  left: 12px;
  top: 7px;
  width: 7px;
  height: 7px;
  border: 1.5px solid currentColor;
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
}

#eventZone:disabled {
  cursor: not-allowed;
  opacity: 0.85;
}

/* ---------------------------------------------------------------------------
   Share-link (online) modes. Local mode never carries these body classes, so
   none of the online-only blocks show there. Panels are hidden, never removed:
   app.js attaches listeners to every element.
   --------------------------------------------------------------------------- */
.net-banner {
  margin: 0 0 var(--s-4);
  padding: var(--s-3) var(--s-4);
  border: 1px solid rgba(180, 67, 47, 0.3);
  border-radius: var(--r-button);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 0.9rem;
  line-height: 1.4;
}

.net-banner[hidden],
.share-notice[hidden] {
  display: none;
}

.share-notice {
  max-width: 560px;
  margin: var(--s-7) auto;
  padding: var(--s-6) var(--s-5) var(--s-5);
  padding-top: 128px;
  background: var(--surface) url("assets/sloth-96.png") center 28px / 80px no-repeat;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-2);
  text-align: center;
}

.share-notice h2 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 500;
}

.share-notice p {
  margin: 0;
  color: var(--muted);
}

.student-panel,
.student-actions {
  display: none;
}

.field-error {
  margin: -6px 0 10px;
  color: var(--danger);
  font-size: 0.82rem;
}

.field-error[hidden] {
  display: none;
}

.link-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.link-row input {
  flex: 1;
  min-width: 0;
  min-height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-input);
  background: var(--surface-2);
  color: var(--text);
  padding: 6px 8px;
  font-size: 0.82rem;
}

/* Student mode: one person's grid, nothing else of the organizer UI. */
body.is-student .sidebar,
body.is-student .mode-tabs,
body.is-student .guide-button,
body.is-student .guide-panel,
body.is-student .section-head,
body.is-student .results-panel,
body.is-student #schedulerPanel,
body.is-student #eventDatesLabel {
  display: none !important;
}

/* One calm centred column for the participant. */
body.is-student .workspace {
  grid-template-columns: minmax(0, 1fr);
  max-width: 820px;
}

body.is-student .split-layout {
  grid-template-columns: minmax(0, 1fr);
}

body.is-student .student-panel {
  display: block;
  margin-bottom: var(--s-4);
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-2);
}

body.is-student .student-panel .eyebrow {
  color: var(--accent);
}

body.is-student .student-panel h2 {
  margin: 2px 0 var(--s-2);
  font-size: clamp(1.5rem, 4vw, var(--fs-title));
  font-weight: 500;
  line-height: 1.15;
}

body.is-student .student-panel .section-note {
  margin-top: var(--s-3);
}

.student-dates,
.student-zone {
  margin: 0 0 var(--s-1);
  color: var(--muted);
  font-size: var(--fs-ui);
  line-height: 1.5;
}

.student-name {
  max-width: 360px;
  margin-top: var(--s-4);
}

/* Send bar: sticky at the bottom while the participant paints, so the one
   primary action is always in reach. It is sticky (in flow), not fixed, so at
   the end of the page it sits below the grid and never covers the last row.
   Once saved, the edit-link card shows and the bar returns to normal flow. */
body.is-student .student-actions {
  display: grid;
  gap: var(--s-3);
  margin-top: var(--s-4);
}

body.is-student .student-actions:has(.student-saved[hidden]) {
  position: sticky;
  bottom: var(--s-3);
  z-index: 10;
  padding: var(--s-3) var(--s-4);
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-3);
}

.student-submit-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
}

.student-status {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-ui);
}

.student-saved {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-5);
  background: var(--heat-1);
  border: 1px solid var(--heat-2);
  border-radius: var(--r-card);
}

.student-saved p {
  margin: 0;
  font-size: var(--fs-ui);
  line-height: 1.5;
}

.student-saved-title strong {
  display: block;
  margin-bottom: 2px;
  font-family: var(--font-display);
  font-size: var(--fs-card);
  font-weight: 500;
}

.student-summary {
  color: var(--muted);
}

@media (max-width: 760px) {
  body.is-student .student-panel {
    padding: var(--s-4);
  }

  body.is-student .student-submit-row .primary-button {
    width: 100%;
  }
}

/* Online modes: hold the planner until the event has loaded; hide it entirely
   when the link is invalid. */
body.share-loading .mode-panel,
body.share-invalid .mode-panel,
body.share-invalid .student-panel,
body.share-invalid .sidebar {
  visibility: hidden;
}

body.share-invalid .mode-panel,
body.share-invalid .student-panel,
body.share-invalid .sidebar {
  display: none !important;
}

body.share-invalid .workspace {
  grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 760px) {
  body.is-student .availability-grid {
    grid-template-columns: 58px repeat(var(--day-count), minmax(46px, 1fr));
    min-width: 0;
  }

  body.is-student .time-label {
    padding: 0 6px;
    font-size: 0.7rem;
  }

  body.is-student .day-header {
    font-size: 0.68rem;
    text-align: center;
  }
}

/* Teacher-online: the shared event's links and status in the Data panel. */
.share-online {
  display: none;
}

body.is-teacher-online .share-online {
  display: grid;
  gap: 4px;
  margin-bottom: 14px;
}

body.is-online #loadSampleBtn,
body.is-online #guideLoadSampleBtn,
body.is-online #importBtn {
  display: none;
}

.share-event-title {
  margin: 0;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.share-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.share-status {
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
}

.share-warning {
  margin: 0 0 6px;
  padding: var(--s-3);
  border-radius: var(--r-input);
  background: var(--warn-soft);
  color: var(--warn);
  font-size: var(--fs-caption);
  line-height: 1.4;
}

/* Local mode: "Create share link" (hidden once the page is an online event). */
.share-local {
  display: grid;
  gap: var(--s-2);
  margin-bottom: var(--s-2);
}

body.is-online .share-local {
  display: none;
}

.share-local .field-note {
  margin: 0;
}

.share-created {
  display: grid;
  gap: var(--s-1);
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}

.share-created[hidden] {
  display: none;
}

/* Click/tap-only painting: a finger sliding over the cells scrolls the page.
   manipulation keeps pan + pinch-zoom but drops double-tap zoom, so tapping two
   cells in quick succession toggles both instead of zooming. */
.availability-cell {
  touch-action: manipulation;
}

/* Three tabs (Best Times / Clean Schedule / Milestones) on a 375px phone. */
@media (max-width: 420px) {
  .tab {
    padding: 0 var(--s-2);
    font-size: 0.8125rem;
  }

  .brand-tagline {
    white-space: normal;
  }
}

/* ---------------------------------------------------------------------------
   How it works: a CSS-only, looping 10s story (no JS, decorative, aria-hidden).
   1 the board appears -> 2 a finger taps four cells (blue + check) -> 3 they
   settle into honey heat as others join and one cell earns the star.
   Fixed-size board, so nothing around it ever shifts. Reduced motion shows the
   final frame. Per-cell keyframes below are generated. The dialog shell, the
   steps and the Clean Schedule story live in the "How it works" section below.
   --------------------------------------------------------------------------- */
.demo-board {
  animation: demo-board var(--demo-loop) ease-in-out infinite;
}

@keyframes demo-board {
  0% { opacity: 0; transform: translateY(6px); }
  5%, 94% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(-4px); }
}

.demo-head {
  display: grid;
  grid-template-columns: repeat(5, 28px);
  gap: 4px;
  margin-bottom: 6px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 500;
  text-align: center;
}

.demo-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 28px);
  grid-auto-rows: 28px;
  gap: 4px;
}

.demo-cell {
  --final: var(--surface);
  position: relative;
  display: block;
  border-radius: 7px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  animation-duration: var(--demo-loop);
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-fill-mode: both;
}

.demo-cell.h1 { --final: var(--heat-1); }
.demo-cell.h2 { --final: var(--heat-2); }
.demo-cell.h3 { --final: var(--heat-3); }

/* The check on a tapped cell. */
.demo-cell.is-tap::after {
  content: "";
  position: absolute;
  left: 10px;
  top: 6px;
  width: 6px;
  height: 11px;
  border-right: 2px solid #ffffff;
  border-bottom: 2px solid #ffffff;
  transform: rotate(45deg);
  opacity: 0;
  animation-duration: var(--demo-loop);
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}

/* The star on the everyone-can-meet cell. */
.demo-cell.is-star::before {
  content: "\2605";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--text);
  font-size: 13px;
  opacity: 0;
  animation: demo-star var(--demo-loop) ease-in-out infinite;
}

@keyframes demo-star {
  0%, 79% { opacity: 0; transform: scale(0.4); }
  83% { opacity: 1; transform: scale(1.25); }
  86%, 100% { opacity: 1; transform: scale(1); }
}

.demo-bubble {
  position: absolute;
  z-index: 3;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--text);
  color: #ffffff;
  font-size: 10px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  translate: -50% 0;
  animation: demo-bubble var(--demo-loop) ease-in-out infinite;
}

@keyframes demo-bubble {
  0%, 81% { opacity: 0; transform: translateY(6px); }
  85%, 100% { opacity: 1; transform: none; }
}

/* A soft fingertip with a ripple on each tap. */
.demo-finger {
  position: absolute;
  z-index: 4;
  left: 0;
  top: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(168, 123, 87, 0.55);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 4px 10px rgba(43, 38, 34, 0.2);
  opacity: 0;
  animation: demo-finger var(--demo-loop) ease-in-out infinite;
}

.demo-finger::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  opacity: 0;
  animation: demo-ripple var(--demo-loop) ease-out infinite;
}

/* Reduced motion: no movement, show the finished story. */
@media (prefers-reduced-motion: reduce) {
  .demo-board,
  .demo-cell,
  .demo-cell::after,
  .demo-cell::before,
  .demo-bubble,
  .demo-finger,
  .demo-finger::after,
  .guide-steps li {
    animation: none !important;
  }

  .demo-cell { background: var(--final); }
  .demo-cell.is-star { background: var(--heat-4); box-shadow: inset 0 0 0 2px var(--text); }
  .demo-cell.is-star::before,
  .demo-bubble { opacity: 1; }
  .demo-finger { display: none; }
}
@keyframes demo-tap-10 {
  0%, 25.5% { background: var(--surface); transform: scale(1); }
  26% { background: var(--accent); transform: scale(0.82); }
  28% { transform: scale(1.08); }
  30% { transform: scale(1); }
  57% { background: var(--accent); }
  62% { background: var(--final); }
  100% { background: var(--final); }
}
.demo-cell.is-tap[data-k="10"] { animation-name: demo-tap-10; }
@keyframes demo-tap-10-check {
  0%, 26% { opacity: 0; }
  28%, 56% { opacity: 1; }
  60%, 100% { opacity: 0; }
}
.demo-cell.is-tap[data-k="10"]::after { animation-name: demo-tap-10-check; }
@keyframes demo-tap-21 {
  0%, 33.5% { background: var(--surface); transform: scale(1); }
  34% { background: var(--accent); transform: scale(0.82); }
  36% { transform: scale(1.08); }
  38% { transform: scale(1); }
  57% { background: var(--accent); }
  62% { background: var(--final); }
  79% { background: var(--final); box-shadow: none; }
  82%, 100% { background: var(--heat-4); box-shadow: inset 0 0 0 2px var(--text); }
}
.demo-cell.is-tap[data-k="21"] { animation-name: demo-tap-21; }
@keyframes demo-tap-21-check {
  0%, 34% { opacity: 0; }
  36%, 56% { opacity: 1; }
  60%, 100% { opacity: 0; }
}
.demo-cell.is-tap[data-k="21"]::after { animation-name: demo-tap-21-check; }
@keyframes demo-tap-31 {
  0%, 41.5% { background: var(--surface); transform: scale(1); }
  42% { background: var(--accent); transform: scale(0.82); }
  44% { transform: scale(1.08); }
  46% { transform: scale(1); }
  57% { background: var(--accent); }
  62% { background: var(--final); }
  100% { background: var(--final); }
}
.demo-cell.is-tap[data-k="31"] { animation-name: demo-tap-31; }
@keyframes demo-tap-31-check {
  0%, 42% { opacity: 0; }
  44%, 56% { opacity: 1; }
  60%, 100% { opacity: 0; }
}
.demo-cell.is-tap[data-k="31"]::after { animation-name: demo-tap-31-check; }
@keyframes demo-tap-32 {
  0%, 49.5% { background: var(--surface); transform: scale(1); }
  50% { background: var(--accent); transform: scale(0.82); }
  52% { transform: scale(1.08); }
  54% { transform: scale(1); }
  57% { background: var(--accent); }
  62% { background: var(--final); }
  100% { background: var(--final); }
}
.demo-cell.is-tap[data-k="32"] { animation-name: demo-tap-32; }
@keyframes demo-tap-32-check {
  0%, 50% { opacity: 0; }
  52%, 56% { opacity: 1; }
  60%, 100% { opacity: 0; }
}
.demo-cell.is-tap[data-k="32"]::after { animation-name: demo-tap-32-check; }
@keyframes demo-heat-1 {
  0%, 60% { background: var(--surface); }
  65%, 100% { background: var(--final); }
}
.demo-cell.g1 { animation-name: demo-heat-1; }
@keyframes demo-heat-2 {
  0%, 66% { background: var(--surface); }
  71%, 100% { background: var(--final); }
}
.demo-cell.g2 { animation-name: demo-heat-2; }
@keyframes demo-heat-3 {
  0%, 72% { background: var(--surface); }
  77%, 100% { background: var(--final); }
}
.demo-cell.g3 { animation-name: demo-heat-3; }
@keyframes demo-finger {
  0%, 18% { opacity: 0; transform: translate(170px, 124px) scale(1); }
  21% { opacity: 1; transform: translate(158px, 116px) scale(1); }
  24.5% { opacity: 1; transform: translate(35.0px, 3.0px) scale(1); }
  26% { transform: translate(35.0px, 3.0px) scale(0.78); }
  27.5% { transform: translate(35.0px, 3.0px) scale(1); }
  32.5% { opacity: 1; transform: translate(67.0px, 35.0px) scale(1); }
  34% { transform: translate(67.0px, 35.0px) scale(0.78); }
  35.5% { transform: translate(67.0px, 35.0px) scale(1); }
  40.5% { opacity: 1; transform: translate(99.0px, 35.0px) scale(1); }
  42% { transform: translate(99.0px, 35.0px) scale(0.78); }
  43.5% { transform: translate(99.0px, 35.0px) scale(1); }
  48.5% { opacity: 1; transform: translate(99.0px, 67.0px) scale(1); }
  50% { transform: translate(99.0px, 67.0px) scale(0.78); }
  51.5% { transform: translate(99.0px, 67.0px) scale(1); }
  54% { opacity: 0; transform: translate(129.0px, 91.0px) scale(1); }
  100% { opacity: 0; transform: translate(170px, 124px) scale(1); }
}
@keyframes demo-ripple {
  0% { opacity: 0; transform: scale(0.4); }
  25.8% { opacity: 0; transform: scale(0.4); }
  26% { opacity: 0.7; transform: scale(0.6); }
  29% { opacity: 0; transform: scale(1.7); }
  33.8% { opacity: 0; transform: scale(0.4); }
  34% { opacity: 0.7; transform: scale(0.6); }
  37% { opacity: 0; transform: scale(1.7); }
  41.8% { opacity: 0; transform: scale(0.4); }
  42% { opacity: 0.7; transform: scale(0.6); }
  45% { opacity: 0; transform: scale(1.7); }
  49.8% { opacity: 0; transform: scale(0.4); }
  50% { opacity: 0.7; transform: scale(0.6); }
  53% { opacity: 0; transform: scale(1.7); }
  100% { opacity: 0; transform: scale(0.4); }
}
.demo-bubble { left: 78.0px; top: 2px; }
.demo-finger { transform: translate(170px, 124px); }

/* ===========================================================================
   How it works: a native modal <dialog>. Desktop: one centred ~580px card
   (story board beside the three steps). Phone: a sheet tucked under the header
   and tab bar with an obvious round X. Step 3 and the board follow the tab
   (body.mode-scheduler). The story itself is CSS-only and decorative.
   =========================================================================== */
.guide-dialog {
  width: min(580px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 0;
  border-radius: var(--r-card);
  background: transparent;
  color: var(--text);
  overflow: auto;
  box-shadow: var(--shadow-3);
}

.guide-dialog[open] {
  animation: guide-in 0.22s ease-out;
}

.guide-dialog::backdrop {
  background: rgba(43, 38, 34, 0.38);
}

@keyframes guide-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to { opacity: 1; transform: none; }
}

.guide-panel {
  --demo-loop: 10s;
  position: relative;
  display: grid;
  grid-template-columns: 196px minmax(0, 1fr);
  grid-template-areas:
    "intro intro"
    "demo steps"
    "actions actions";
  align-items: center;
  gap: var(--s-4) var(--s-5);
  margin: 0;
  padding: var(--s-5);
  background: var(--surface);
  border: 0;
  border-radius: inherit;
  box-shadow: none;
}

.guide-intro {
  grid-area: intro;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-right: var(--s-7);
}

.guide-art {
  width: 56px;
  height: 56px;
  flex: 0 0 auto;
  border-radius: 16px;
  pointer-events: none;
}

.guide-panel .section-intro {
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.guide-panel h2 {
  margin: 2px 0 0;
  font-size: var(--fs-card);
  font-weight: 500;
  line-height: 1.25;
}

.guide-close {
  position: absolute;
  z-index: 2;
  top: var(--s-4);
  right: var(--s-4);
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
  transition: background-color 0.15s ease;
}

.guide-close:hover {
  background: var(--line);
}

/* The three steps: compact rows that light up in turn with the board. */
.guide-steps {
  grid-area: steps;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-self: center;
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.guide-steps li {
  min-width: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--s-3);
  align-items: baseline;
  padding: 10px var(--s-3);
  border-radius: var(--r-button);
  background: var(--surface-2);
  box-shadow: inset 0 0 0 2px transparent;
  animation: var(--demo-loop) ease-in-out infinite both;
}

.guide-steps li > strong {
  display: contents;
  font-size: var(--fs-ui);
}

.guide-steps li > strong .step-num {
  grid-row: span 2;
  align-self: center;
  width: 24px;
  height: 24px;
  margin: 0;
  font-size: var(--fs-caption);
}

.guide-steps li > span {
  grid-column: 2;
  display: block;
  margin-top: 1px;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

.guide-steps li:nth-child(1) { animation-name: demo-step-1; }
.guide-steps li:nth-child(2) { animation-name: demo-step-2; }
.guide-steps li:nth-child(3) { animation-name: demo-step-3; }

@keyframes demo-step-1 {
  0%, 18% { background: var(--surface); box-shadow: inset 0 0 0 2px rgba(47, 95, 167, 0.35); }
  22%, 100% { background: var(--surface-2); box-shadow: inset 0 0 0 2px transparent; }
}

@keyframes demo-step-2 {
  0%, 18% { background: var(--surface-2); box-shadow: inset 0 0 0 2px transparent; }
  22%, 54% { background: var(--surface); box-shadow: inset 0 0 0 2px rgba(47, 95, 167, 0.35); }
  58%, 100% { background: var(--surface-2); box-shadow: inset 0 0 0 2px transparent; }
}

@keyframes demo-step-3 {
  0%, 54% { background: var(--surface-2); box-shadow: inset 0 0 0 2px transparent; }
  58%, 94% { background: var(--surface); box-shadow: inset 0 0 0 2px rgba(47, 95, 167, 0.35); }
  100% { background: var(--surface-2); box-shadow: inset 0 0 0 2px transparent; }
}

/* Actions: "Got it" is the dialog's one filled action; the sample stays outline. */
.guide-actions {
  grid-area: actions;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-2);
  flex-wrap: wrap;
  padding-top: var(--s-1);
}

.guide-actions .dismiss-button {
  min-height: 40px;
  padding: 0 var(--s-5);
  background: var(--accent);
  color: #ffffff;
  font-weight: 500;
}

.guide-actions .dismiss-button:hover {
  background: var(--accent-hover);
  color: #ffffff;
}

.guide-actions .small-button {
  min-height: 40px;
  padding: 0 var(--s-4);
}

/* ---------------------------------------------------------------------------
   The story board (shared by both variants). A fixed-size board, so nothing
   around it shifts while it plays.
   --------------------------------------------------------------------------- */
.guide-demo {
  grid-area: demo;
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--s-2);
  height: 196px;
  padding: var(--s-3);
  border-radius: var(--r-card);
  background: var(--surface-2);
  pointer-events: none;
}

/* Step 3 and the board follow the active tab (after .guide-demo, so it wins). */
.guide-steps li > .guide-step3-scheduler,
.guide-demo-scheduler,
body.mode-scheduler .guide-steps li > .guide-step3-poll,
body.mode-scheduler .guide-demo-poll {
  display: none;
}

body.mode-scheduler .guide-steps li > .guide-step3-scheduler {
  display: block;
}

body.mode-scheduler .guide-demo-scheduler {
  display: grid;
}

/* ---------------------------------------------------------------------------
   Clean Schedule story (10 s loop, in step with the step highlights):
   step 2 (22-54%) three people tap their free cells, each in their own colour;
   step 3 (58-94%) the taps settle, one after another, into three separate,
   non-overlapping blocks with initials; then "Everyone gets their own slot."
   Cells are addressed by position: AC = cells 1 + 6 (Mon, rows 1-2),
   BO = 8 + 13 (Wed, rows 2-3), CR = 15 + 20 (Fri, rows 3-4).
   --------------------------------------------------------------------------- */
.demo-sched-grid .demo-cell {
  --tint: var(--surface);
}

.demo-sched-grid .demo-cell:nth-child(1),
.demo-sched-grid .demo-cell:nth-child(6) { --tint: #cfe3f2; }
.demo-sched-grid .demo-cell:nth-child(8),
.demo-sched-grid .demo-cell:nth-child(13) { --tint: #f3dcb8; }
.demo-sched-grid .demo-cell:nth-child(15),
.demo-sched-grid .demo-cell:nth-child(20) { --tint: #c6e8dc; }

.demo-sched-grid .demo-cell:nth-child(1) { animation-name: demo-stap-a; }
.demo-sched-grid .demo-cell:nth-child(6) { animation-name: demo-stap-b; }
.demo-sched-grid .demo-cell:nth-child(8) { animation-name: demo-stap-c; }
.demo-sched-grid .demo-cell:nth-child(13) { animation-name: demo-stap-d; }
.demo-sched-grid .demo-cell:nth-child(15) { animation-name: demo-stap-e; }
.demo-sched-grid .demo-cell:nth-child(20) { animation-name: demo-stap-f; }

@keyframes demo-stap-a {
  0%, 24% { background: var(--surface); transform: scale(1); }
  25% { background: var(--tint); transform: scale(0.82); }
  27%, 95% { background: var(--tint); transform: scale(1); }
  100% { background: var(--surface); }
}
@keyframes demo-stap-b {
  0%, 28% { background: var(--surface); transform: scale(1); }
  29% { background: var(--tint); transform: scale(0.82); }
  31%, 95% { background: var(--tint); transform: scale(1); }
  100% { background: var(--surface); }
}
@keyframes demo-stap-c {
  0%, 34% { background: var(--surface); transform: scale(1); }
  35% { background: var(--tint); transform: scale(0.82); }
  37%, 95% { background: var(--tint); transform: scale(1); }
  100% { background: var(--surface); }
}
@keyframes demo-stap-d {
  0%, 38% { background: var(--surface); transform: scale(1); }
  39% { background: var(--tint); transform: scale(0.82); }
  41%, 95% { background: var(--tint); transform: scale(1); }
  100% { background: var(--surface); }
}
@keyframes demo-stap-e {
  0%, 44% { background: var(--surface); transform: scale(1); }
  45% { background: var(--tint); transform: scale(0.82); }
  47%, 95% { background: var(--tint); transform: scale(1); }
  100% { background: var(--surface); }
}
@keyframes demo-stap-f {
  0%, 48% { background: var(--surface); transform: scale(1); }
  49% { background: var(--tint); transform: scale(0.82); }
  51%, 95% { background: var(--tint); transform: scale(1); }
  100% { background: var(--surface); }
}

.demo-block {
  position: absolute;
  z-index: 2;
  width: 28px;
  height: 60px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  color: #ffffff;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.02em;
  box-shadow: 0 3px 8px rgba(43, 38, 34, 0.18);
  opacity: 0;
  animation: var(--demo-loop) ease-out infinite both;
}

.demo-block-1 { left: 0; top: 0; background: #0b6aa8; animation-name: demo-settle-1; }
.demo-block-2 { left: 64px; top: 32px; background: #9a5a00; animation-name: demo-settle-2; }
.demo-block-3 { left: 128px; top: 64px; background: #00805c; animation-name: demo-settle-3; }

@keyframes demo-settle-1 {
  0%, 59% { opacity: 0; transform: scale(0.6); }
  62% { opacity: 1; transform: scale(1.08); }
  64%, 95% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: none; }
}
@keyframes demo-settle-2 {
  0%, 66% { opacity: 0; transform: scale(0.6); }
  69% { opacity: 1; transform: scale(1.08); }
  71%, 95% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: none; }
}
@keyframes demo-settle-3 {
  0%, 73% { opacity: 0; transform: scale(0.6); }
  76% { opacity: 1; transform: scale(1.08); }
  78%, 95% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: none; }
}

/* The bubble sits under the board here, so it never covers a block. */
.demo-sched-grid .demo-bubble {
  top: calc(100% + 8px);
}

/* Reduced motion: no movement, each variant shows its final frame, and a small
   caption says why nothing moves (Windows "Animation effects" off, etc.). */
@media (prefers-reduced-motion: reduce) {
  .guide-dialog[open],
  .demo-block,
  .demo-sched-grid .demo-cell {
    animation: none !important;
  }

  .demo-block { opacity: 1; }
  .demo-sched-grid .demo-cell { background: var(--tint); }

  .guide-demo::after {
    content: "Reduced motion is on \2014\00a0showing the result.";
    color: var(--muted);
    font-size: 11px;
    line-height: 1.3;
    text-align: center;
  }

  .guide-demo { height: auto; min-height: 196px; }
  .demo-sched-grid { margin-bottom: 28px; }
}

/* ---------------------------------------------------------------------------
   Phones: a sheet under the header + tab bar, full width, round X in reach.
   --------------------------------------------------------------------------- */
@media (max-width: 640px) {
  .guide-dialog {
    width: 100%;
    max-width: 100%;
    margin: var(--topbar-h, 112px) 0 0;
    max-height: calc(100dvh - var(--topbar-h, 112px));
    border-radius: var(--r-card) var(--r-card) 0 0;
  }

  .guide-dialog[open] {
    animation-name: guide-sheet-in;
  }

  @keyframes guide-sheet-in {
    from { transform: translateY(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
  }

  .guide-dialog::backdrop {
    top: var(--topbar-h, 112px);
  }

  .guide-panel {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "intro" "demo" "steps" "actions";
    gap: var(--s-3);
    padding: var(--s-4) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
  }

  .guide-close {
    top: var(--s-3);
    right: var(--s-3);
    width: 44px;
    height: 44px;
  }

  .guide-art {
    width: 48px;
    height: 48px;
    border-radius: 14px;
  }

  .guide-panel h2 {
    font-size: 1.125rem;
  }

  .guide-demo {
    height: 200px;
  }

  .guide-actions {
    justify-content: stretch;
  }

  .guide-actions > * {
    flex: 1;
  }
}

/* ===========================================================================
   Calendar layout (Round 7): a quiet Google-Calendar rail on the left, the
   When2meet-style grid pair on the right. The rail is flat (no cards): hairline
   dividers, one line per setting, soft filled controls. The grids are the only
   cards on the page, so the eye lands there.
   Widths: >= 1100 rail 272px + two grids side by side; 760-1100 rail 248px +
   the two grids stacked full width; < 760 the phone layout further below.
   =========================================================================== */
.workspace {
  grid-template-columns: 272px minmax(0, 1fr);
  gap: var(--s-6);
}

.rail {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  align-self: start;
  gap: 0;
  max-width: none;
}

.rail-sheet-head {
  display: none;
}

.rail-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-3);
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--line);
}

.rail-section:first-of-type {
  padding-top: 0;
}

.rail-section:last-child {
  border-bottom: 0;
}

.rail-section > *,
.rail-row > *,
.mini-cal-grid > *,
.zone-row > * {
  min-width: 0;
}

.rail .field {
  margin-bottom: 0;
}

.rail .field > span {
  color: var(--muted);
  font-size: var(--fs-ui);
  font-weight: 500;
}

/* One line per setting: a muted label, then the control. */
.rail-row {
  grid-template-columns: 56px minmax(0, 1fr);
  align-items: center;
  column-gap: var(--s-2);
}

.rail-row > span {
  margin: 0;
}

/* Rail controls: soft filled, no shadow, the same height and shape for the
   Hours chip, Length and Zone, so the column reads as one calm list. */
.rail select,
.rail .field select,
.hours-chip {
  width: 100%;
  min-width: 0;
  min-height: 38px;
  padding: 0 32px 0 12px;
  border: 1px solid transparent;
  border-radius: var(--r-input);
  background: var(--surface-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b625a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right 12px center / 10px 6px no-repeat;
  color: var(--text);
  font-size: var(--fs-ui);
  font-weight: 500;
  text-align: left;
  box-shadow: none;
  -webkit-appearance: none;
  appearance: none;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.rail select:hover,
.rail .field select:hover,
.hours-chip:hover {
  border-color: var(--line-strong);
  background-color: var(--surface);
}

.rail select:focus,
.rail .field select:focus,
.hours-chip:focus-visible,
.hours-chip[aria-expanded="true"] {
  outline: none;
  border-color: var(--accent);
  background-color: var(--surface);
  box-shadow: var(--focus);
}

.rail .field select:disabled {
  background-color: var(--surface-2);
  border-color: transparent;
  color: var(--muted);
}

/* The editor's name / label inputs and the more-menu select keep the field look,
   just compact. */
.rail .field input {
  min-height: 38px;
  padding: 8px 12px;
  box-shadow: none;
}

/* ---------------------------------------------------------------------------
   Mini month calendar (dates are a label only; weekday chips own the days).
   Monday first, a muted ISO week column, today ringed, the picked range as one
   continuous soft band with filled ends.
   --------------------------------------------------------------------------- */
.mini-cal {
  display: grid;
  gap: var(--s-2);
}

.mini-cal-head {
  display: flex;
  align-items: center;
  gap: var(--s-1);
}

.mini-cal-title {
  order: -1;
  flex: 1;
  padding-left: 4px;
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: 500;
}

.mini-cal-nav {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0 0 2px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 1.375rem;
  line-height: 1;
}

.mini-cal-nav:hover {
  background: var(--surface-2);
  color: var(--text);
}

.mini-cal-grid {
  display: grid;
  grid-template-columns: 24px repeat(7, minmax(0, 1fr));
  row-gap: 2px;
  column-gap: 0;
  text-align: center;
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
}

.mini-cal-label {
  padding-bottom: 2px;
  color: var(--muted);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 20px;
}

.mini-cal-wk {
  display: grid;
  place-items: center;
  color: #a39789;
  font-size: 0.625rem;
  font-weight: 400;
}

.mini-cal-label.mini-cal-wk {
  display: block;
}

.mini-cal-day {
  position: relative;
  isolation: isolate;
  min-width: 0;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-caption);
  font-weight: 400;
}

/* The round "chip" is a pseudo-element, so the range band can run edge to edge
   on the button itself. */
.mini-cal-day::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 1px;
  left: 50%;
  width: 28px;
  height: 28px;
  margin-left: -14px;
  border-radius: 50%;
  pointer-events: none;
}

.mini-cal-day:hover::before {
  background: var(--surface-2);
}

.mini-cal-day:focus-visible {
  box-shadow: none;
}

.mini-cal-day:focus-visible::before {
  box-shadow: var(--focus);
}

.mini-cal-day.is-other-month {
  color: #a39789;
}

.mini-cal-label.is-undeclared,
.mini-cal-day.is-undeclared {
  opacity: 0.45;
}

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

.mini-cal-day.is-today::before {
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

.mini-cal-day.is-in-range {
  background: var(--accent-soft);
  opacity: 1;
}

.mini-cal-day.is-range-start {
  background: linear-gradient(90deg, transparent 50%, var(--accent-soft) 50%);
}

.mini-cal-day.is-range-end {
  background: linear-gradient(90deg, var(--accent-soft) 50%, transparent 50%);
}

.mini-cal-day.is-range-start.is-range-end {
  background: transparent;
}

.mini-cal-day.is-range-start,
.mini-cal-day.is-range-end,
.mini-cal-day.is-pending {
  color: #ffffff;
  font-weight: 500;
  opacity: 1;
}

.mini-cal-day.is-range-start::before,
.mini-cal-day.is-range-end::before,
.mini-cal-day.is-pending::before {
  background: var(--accent);
}

.mini-cal-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  min-height: 28px;
}

.mini-cal-status {
  margin: 0;
  padding-left: 4px;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.4;
}

.mini-cal-foot .text-button {
  min-height: 28px;
  padding: 0 var(--s-2);
  color: var(--accent);
  font-size: var(--fs-caption);
}

/* "Range includes Sat — add Saturday?": one soft honey line, one tap. */
.day-prompt {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  padding: 4px 4px 4px var(--s-1);
  border-radius: var(--r-button);
  background: var(--heat-1);
}

.day-prompt .small-button {
  flex: 1;
  min-width: 0;
  min-height: 32px;
  padding: 4px var(--s-2);
  border: 0;
  border-radius: var(--r-input);
  background: transparent;
  color: var(--warn);
  white-space: normal;
  line-height: 1.3;
  text-align: left;
  font-size: var(--fs-caption);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.day-prompt .small-button:hover {
  background: var(--heat-2);
  color: var(--text);
}

.day-prompt .text-button {
  min-height: 32px;
  color: var(--warn);
}

/* ---------------------------------------------------------------------------
   Days: label above, seven equal chips (the only source of settings.days).
   --------------------------------------------------------------------------- */
.rail .day-field {
  grid-template-columns: minmax(0, 1fr);
  row-gap: 6px;
}

.rail .day-toggles {
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}

.rail .field .day-chip span {
  min-width: 0;
  width: auto;
  min-height: 32px;
  padding: 0;
  border-color: transparent;
  border-radius: var(--r-input);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 0.6875rem;
  font-weight: 500;
}

.rail .field .day-chip:hover span {
  border-color: var(--line-strong);
  color: var(--text);
}

.rail .field .day-chip input:checked + span {
  border-color: transparent;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 500;
  box-shadow: inset 0 0 0 1px rgba(47, 95, 167, 0.35);
}

.rail .field .day-chip input:checked:focus-visible + span,
.rail .field .day-chip input:focus-visible + span {
  box-shadow: var(--focus);
}

/* ---------------------------------------------------------------------------
   Hours: chip + Start / End listboxes, styled like Google Calendar's time
   dropdown (white card, airy rows, the chosen time in blue).
   --------------------------------------------------------------------------- */
.hours-field {
  position: relative;
}

.hours-chip {
  justify-self: stretch;
  font-variant-numeric: tabular-nums;
}

.hours-popover {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  width: max-content;
  max-width: calc(100vw - 32px);
  display: flex;
  gap: var(--s-2);
  padding: var(--s-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-button);
  box-shadow: var(--shadow-3);
}

.hours-col {
  display: grid;
  gap: var(--s-1);
}

.hours-col-label {
  padding: 4px 12px 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  font-weight: 500;
}

.time-listbox {
  position: relative;
  max-height: 264px;
  min-width: 128px;
  margin: 0;
  padding: 4px 0;
  overflow-x: hidden;
  overflow-y: auto;
  list-style: none;
  border: 0;
  border-radius: var(--r-input);
  scrollbar-width: thin;
}

.time-listbox:focus-visible {
  box-shadow: var(--focus);
}

.time-listbox [role="option"] {
  padding: 7px 12px;
  border-radius: 0;
  color: var(--text);
  font-size: var(--fs-ui);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
}

.time-listbox [role="option"]:hover {
  background: var(--surface-2);
}

.time-listbox [role="option"].is-active {
  background: var(--surface-2);
  box-shadow: inset 3px 0 0 var(--line-strong);
}

.time-listbox [role="option"][aria-selected="true"] {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 500;
}

.time-listbox [role="option"][aria-selected="true"].is-active {
  box-shadow: inset 3px 0 0 var(--accent);
}

.hours-dur {
  color: var(--muted);
  font-weight: 400;
}

/* Zone: the caption only shows when the zone is locked (it says why). */
.zone-row {
  gap: 0;
}

.zone-row .field {
  margin-bottom: 0;
}

.zone-row #eventZoneNote {
  display: none;
}

.zone-row:has(#eventZone:disabled) #eventZoneNote {
  display: block;
  margin-top: var(--s-2);
}

#eventZoneOtherField {
  margin-top: var(--s-2);
}

/* ---------------------------------------------------------------------------
   People in the rail: a light list; the selected person's details sit in one
   soft card right under it.
   --------------------------------------------------------------------------- */
.people-panel .panel-title {
  margin-bottom: 0;
}

.people-panel .panel-title h2 {
  font-size: var(--fs-body);
}

.people-panel .person-list {
  gap: 2px;
  margin-bottom: 0;
}

.people-panel .person-button {
  min-height: 44px;
  padding: 6px var(--s-3);
  gap: var(--s-3);
}

.people-panel .person-copy strong {
  font-size: var(--fs-ui);
}

.people-panel .empty-hint {
  padding: var(--s-3);
  font-size: var(--fs-caption);
}

.people-panel .editor {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-3);
  border-radius: var(--r-button);
  background: var(--surface-2);
}

.people-panel .editor .field input,
.people-panel .editor .field select {
  background-color: var(--surface);
}

.people-panel .editor .disclosure {
  margin-top: 0;
  border-top: 0;
}

.people-panel .editor .disclosure > summary {
  min-height: 32px;
  font-size: var(--fs-caption);
}

.people-panel .lesson-note {
  margin: -4px 0 0;
}

.people-panel .quiet-row {
  margin-top: 0;
}

.people-panel .quiet-row {
  flex-wrap: nowrap;
  gap: var(--s-1);
}

.people-panel .quiet-row .text-button {
  min-height: 32px;
  padding: 0 6px;
  font-size: var(--fs-caption);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Share row: the page's one primary action + a round "more" menu.
   --------------------------------------------------------------------------- */
.share-step {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: var(--s-2);
}

.share-step > .share-local,
.share-step > .share-online {
  grid-column: 1;
  min-width: 0;
}

.share-step > .rail-more {
  grid-column: 2;
  grid-row: 1;
}

.share-local {
  margin-bottom: 0;
}

.share-local .primary-button,
.share-step .primary-button {
  width: 100%;
}

.more-menu {
  position: relative;
}

.more-menu-button {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  font-size: 1.25rem;
  line-height: 1;
  list-style: none;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.more-menu-button::-webkit-details-marker {
  display: none;
}

.more-menu-button:hover,
.more-menu[open] > .more-menu-button {
  border-color: var(--accent);
  color: var(--accent);
}

.more-menu-body {
  position: absolute;
  z-index: 30;
  right: 0;
  bottom: calc(100% + var(--s-2));
  width: 264px;
  display: grid;
  gap: var(--s-2);
  padding: var(--s-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-button);
  box-shadow: var(--shadow-3);
}

.more-menu-body .field {
  margin-bottom: var(--s-1);
}

.more-menu-body .small-button {
  justify-self: start;
}

.more-menu-body #newEventBtn {
  margin-top: 0;
}

/* ---------------------------------------------------------------------------
   Context line: what the grids show and whose clock (S5), above both tabs.
   --------------------------------------------------------------------------- */
.context-bar {
  margin-bottom: var(--s-4);
}

.context-line {
  margin: 0 0 2px;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.3;
}

.context-bar .tz-disclosure {
  margin-bottom: 0;
}

body.is-student .context-line {
  display: none;
}

/* ---------------------------------------------------------------------------
   The grid pair: [Name]'s times | Group (Best Times) or Schedule (Clean).
   Two equal cards, equal height, the same head structure.
   --------------------------------------------------------------------------- */
.grid-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-4);
  align-items: stretch;
  margin-bottom: var(--s-5);
}

/* Remote organizer: the grids are on different clocks, so stack them. */
.grid-pair.is-cross-zone {
  grid-template-columns: minmax(0, 1fr);
}

.pair-slot {
  display: grid;
  min-width: 0;
}

.grid-pair .calendar-panel {
  min-width: 0;
  overflow: visible;
  padding: var(--s-4);
  box-shadow: var(--shadow-1);
}

.grid-head {
  display: grid;
  gap: 2px;
  min-height: 48px;
  margin-bottom: var(--s-3);
}

.grid-head h2 {
  margin: 0;
  font-size: var(--fs-card);
  font-weight: 500;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.grid-zone {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-caption);
  line-height: 1.45;
}

.grid-head .section-note {
  margin-top: 2px;
  font-size: var(--fs-caption);
}

.grid-scroll {
  overflow: auto;
  border-radius: var(--r-input);
}

/* Legends: one quiet caption line UNDER the grid, so both grids start at the
   same height. The marking grid's "[Name]'s times" swatch repeats its title, so
   the organizer view drops it (students keep theirs). */
.grid-pair .calendar-panel {
  display: flex;
  flex-direction: column;
}

.grid-pair .grid-legend {
  order: 3;
  gap: var(--s-1) var(--s-3);
  margin: var(--s-3) 0 0;
}

.grid-pair .legend-item {
  gap: 6px;
}

.grid-pair .swatch,
.grid-pair .swatch-ramp b {
  width: 12px;
  height: 12px;
  border-radius: 3px;
}

body:not(.is-student) .mark-panel .legend-item:has(.swatch-mine) {
  display: none;
}

body:not(.is-student) .mark-panel .grid-legend:not(:has(.swatch-tail)) {
  display: none;
}

/* Grid skeleton inside the pair: hairlines, compact time column. */
.grid-pair .availability-grid {
  grid-template-columns: 60px repeat(var(--day-count), minmax(36px, 1fr));
}

.grid-pair .schedule-grid {
  min-width: 0;
  grid-template-columns: 60px repeat(var(--day-count), minmax(52px, 1fr));
}

.grid-pair .grid-corner,
.grid-pair .day-header {
  min-height: 32px;
}

.grid-pair .day-header {
  min-width: 0;
  overflow: hidden;
  padding: 0 2px;
  font-size: var(--fs-caption);
  color: var(--muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.grid-pair .schedule-grid .day-header {
  display: block;
  line-height: 40px;
  text-align: center;
  font-size: 0.6875rem;
}

.grid-pair .time-label {
  padding: 0 var(--s-2) 0 0;
  font-size: 0.6875rem;
}

.grid-pair .availability-cell {
  min-height: 30px;
}

.grid-pair .schedule-cell {
  min-height: 40px;
}

/* Group grid = the answer on Best Times: honey heat, the count printed, and the
   everyone-can-meet cells ringed in ink with a star. Read only. */
.group-cell {
  display: grid;
  place-items: center;
  cursor: default;
}

.group-cell:hover {
  box-shadow: none;
}

.group-cell.is-everyone,
.group-cell.is-everyone:hover {
  box-shadow: inset 0 0 0 2px var(--text);
  font-weight: 500;
}

.group-cell.is-everyone::before {
  top: 3px;
  left: 4px;
  font-size: 10px;
}

/* Schedule = the answer on Clean Schedule. Blocks fit narrow day columns. */
.grid-pair .schedule-assignment {
  margin: 2px;
  padding: 3px 6px 3px 5px;
  border-left-width: 3px;
  border-radius: 7px;
}

.grid-pair .schedule-assignment strong {
  font-size: var(--fs-caption);
}

.grid-pair .schedule-assignment span {
  font-size: 0.625rem;
}

#scheduleZoneLine {
  margin-bottom: 0;
}

/* The payoff line: mascot + one sentence, the count in sloth brown. */
.grid-pair .schedule-hero {
  gap: var(--s-3);
  margin-bottom: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-button);
}

.grid-pair .schedule-hero-art {
  width: 44px;
  height: 44px;
}

.grid-pair .schedule-hero-title {
  font-size: 1.125rem;
}

.schedule-hero-sub {
  font-size: var(--fs-caption);
}

.hero-num {
  color: var(--sloth);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.schedule-hero.is-complete .hero-num {
  font-size: 1.15em;
}

.grid-pair .score-strip {
  justify-content: flex-start;
  margin-bottom: var(--s-3);
}

.grid-pair .score-strip span {
  min-height: 26px;
  padding: 0 10px;
}

/* ---------------------------------------------------------------------------
   Result lists under the pair (Best Times, Assignments): two columns when wide,
   so the page stays short and calm.
   --------------------------------------------------------------------------- */
.mode-panel > .results-panel {
  margin-bottom: var(--s-4);
  box-shadow: var(--shadow-1);
}

.best-panel .panel-title,
.mode-panel > .results-panel .panel-title {
  flex-wrap: wrap;
}

.best-panel .score-strip {
  justify-content: flex-start;
  margin-bottom: var(--s-2);
}

.best-list,
.assignment-list {
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  column-gap: var(--s-6);
  row-gap: 0;
}

.best-list > .empty-state,
.assignment-list > .empty-state {
  grid-column: 1 / -1;
}

.best-row:last-child,
.assignment-row:last-child {
  border-bottom: 1px solid var(--line);
}

.assignment-row.is-missed {
  grid-column: 1 / -1;
}

/* Participant view keeps one grid. */
body.is-student .group-panel {
  display: none !important;
}

body.is-student .grid-pair {
  grid-template-columns: minmax(0, 1fr);
}

/* ---------------------------------------------------------------------------
   760-1100: a narrower rail, the two grids stacked full width (each still
   comfortable for five days), lists in one column.
   --------------------------------------------------------------------------- */
@media (max-width: 1100px) {
  .workspace {
    grid-template-columns: 248px minmax(0, 1fr);
    gap: var(--s-5);
  }

  .sidebar.rail {
    grid-template-columns: minmax(0, 1fr);
  }

  .grid-pair {
    grid-template-columns: minmax(0, 1fr);
  }

  .rail-row {
    grid-template-columns: 52px minmax(0, 1fr);
  }

  .hours-popover {
    left: auto;
    right: 0;
  }
}

/* Phone-only pieces are hidden on wider screens. */
.pane-toggle,
.summary-bar,
.person-chips,
.share-bar,
.rail-scrim {
  display: none;
}

@media (max-width: 760px) {
  .workspace {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The rail becomes a bottom sheet opened from the summary bar. */
  .rail {
    position: fixed;
    z-index: 40;
    left: 0;
    right: 0;
    bottom: 0;
    max-width: none;
    max-height: 85dvh;
    overflow-y: auto;
    padding: 0 var(--s-4) var(--s-4);
    background: var(--surface);
    border-radius: var(--r-card) var(--r-card) 0 0;
    box-shadow: var(--shadow-3);
    transform: translateY(100%);
    visibility: hidden;
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
  }

  body.rail-open .rail {
    transform: none;
    visibility: visible;
    transition: transform 0.2s ease, visibility 0s;
  }

  .rail-sheet-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--s-3) 0;
    background: var(--surface);
  }

  .rail-sheet-head h2 {
    margin: 0;
    font-size: var(--fs-card);
  }

  .rail-close {
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    font-size: 1.1rem;
  }

  body.rail-open .rail-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 39;
    border: 0;
    background: rgba(43, 38, 34, 0.4);
  }

  /* Menus inside the scrolling sheet open in place (no clipping). */
  .more-menu-body {
    position: static;
    width: auto;
    margin-top: var(--s-2);
  }

  .summary-bar {
    display: block;
    width: 100%;
    min-height: 44px;
    margin-bottom: var(--s-2);
    padding: 0 var(--s-4);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--text);
    font-size: var(--fs-ui);
    font-weight: 500;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .person-chips {
    display: flex;
    gap: var(--s-2);
    margin: 0 calc(-1 * var(--s-4)) var(--s-3);
    padding: 2px var(--s-4);
    overflow-x: auto;
    scrollbar-width: none;
  }

  .person-chip {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 36px;
    padding: 0 var(--s-3);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--text);
    font-size: var(--fs-caption);
    font-weight: 500;
    white-space: nowrap;
  }

  .person-chip[aria-pressed="true"] {
    border-color: var(--accent);
    background: var(--accent-soft);
  }

  .person-chip .person-dot {
    width: 10px;
    height: 10px;
  }

  /* Segmented toggle: one half of the pair at a time. */
  .pane-toggle {
    display: flex;
    margin-bottom: var(--s-3);
    padding: 3px;
    border-radius: var(--r-pill);
    background: var(--surface-2);
  }

  .pane-button {
    flex: 1;
    min-height: 36px;
    border: 0;
    border-radius: var(--r-pill);
    background: transparent;
    color: var(--muted);
    font-size: var(--fs-ui);
    font-weight: 500;
  }

  .pane-button[aria-pressed="true"] {
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-2);
  }

  .grid-pair,
  .grid-pair.is-cross-zone {
    grid-template-columns: minmax(0, 1fr);
  }

  body[data-pane="mark"] .grid-pair > .pair-result,
  body[data-pane="result"] .grid-pair > .pair-slot {
    display: none;
  }

  .grid-pair .calendar-panel {
    padding: var(--s-2);
  }

  .grid-pair .availability-grid {
    grid-template-columns: 54px repeat(var(--day-count), minmax(0, 1fr));
  }

  .grid-pair .schedule-grid {
    grid-template-columns: 54px repeat(var(--day-count), minmax(52px, 1fr));
  }

  /* Sticky Share bar: in flow at the end of the page, so it never covers the
     last grid row once you scroll there. */
  .share-bar {
    display: block;
    position: sticky;
    bottom: 0;
    z-index: 10;
    margin: var(--s-4) calc(-1 * var(--s-4)) calc(-1 * var(--s-4));
    padding: var(--s-3) var(--s-4);
    background: rgba(255, 252, 247, 0.96);
    border-top: 1px solid var(--line);
  }

  .share-bar .primary-button {
    width: 100%;
  }

  /* Participant view keeps its own structure: no toggle, chips, sheet or share bar. */
  body.is-student .pane-toggle,
  body.is-student .summary-bar,
  body.is-student .person-chips,
  body.is-student .share-bar {
    display: none !important;
  }

  body.is-student .grid-pair > .pair-slot {
    display: block !important;
  }

  body.share-invalid .summary-bar,
  body.share-invalid .person-chips,
  body.share-invalid .share-bar {
    display: none !important;
  }
}

/* ---------------------------------------------------------------------------
   Phone polish (< 760px): one calm column. Summary bar -> setup sheet, people
   chips, the Mark | Result toggle, then the grid; Share waits at the bottom.
   --------------------------------------------------------------------------- */
@media (max-width: 760px) {
  /* clip, not hidden, on body: overflow-x: hidden would make body a scroll
     container, and then the sticky header and the sticky Share bar never stick. */
  html {
    overflow-x: hidden;
  }

  body {
    overflow-x: clip;
  }

  .workspace {
    gap: var(--s-3);
  }

  /* The summary bar already says days / hours / length / zone here; the
     "Times in ..." clock line below it stays (S5). */
  .context-line {
    display: none;
  }

  .context-bar {
    margin-bottom: var(--s-3);
  }

  .context-bar .tz-line {
    font-size: var(--fs-caption);
    line-height: 1.5;
  }

  /* Sample bar: one compact line. */
  .sample-bar {
    flex-wrap: nowrap;
    min-height: 48px;
    margin-bottom: var(--s-3);
    padding: 6px 6px 6px 44px;
    background-position: 10px center;
    background-size: 24px;
    border-radius: var(--r-button);
    font-size: var(--fs-caption);
    line-height: 1.35;
  }

  .sample-bar > span {
    flex: 1;
    min-width: 0;
  }

  .sample-bar .small-button {
    min-height: 36px;
  }

  /* Summary bar: a calm card-like button (its own text ends in a caret). */
  .summary-bar {
    min-height: 44px;
    margin-bottom: var(--s-2);
    padding: 0 var(--s-4);
    border: 1px solid var(--line);
    border-radius: var(--r-button);
    background: var(--surface);
    box-shadow: var(--shadow-1);
    font-variant-numeric: tabular-nums;
  }

  .summary-bar:hover,
  .summary-bar[aria-expanded="true"] {
    border-color: var(--accent);
  }

  /* People chips: the selected person in blue (their marks are blue). */
  .person-chips {
    gap: 6px;
    margin-bottom: var(--s-3);
  }

  .person-chip {
    min-height: 36px;
    border-color: var(--line);
    font-size: var(--fs-caption);
  }

  .person-chip[aria-pressed="true"] {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 500;
  }

  .person-chip-add {
    border-style: dashed;
    border-color: var(--line-strong);
    color: var(--accent);
  }

  .person-chip-add:disabled {
    opacity: 0.45;
  }

  /* Segmented toggle. */
  .pane-toggle {
    margin-bottom: var(--s-3);
    padding: 3px;
    background: var(--line);
  }

  .pane-button {
    min-height: 38px;
  }

  .pane-button[aria-pressed="true"] {
    color: var(--accent);
    box-shadow: var(--shadow-1);
  }

  /* Grid cards: tighter frame, smaller titles, still the same structure. */
  .grid-pair {
    margin-bottom: var(--s-3);
  }

  .grid-pair .calendar-panel {
    padding: var(--s-3) var(--s-2) var(--s-2);
    border-radius: var(--r-button);
  }

  .grid-head {
    min-height: 0;
    margin-bottom: var(--s-2);
    padding: 0 var(--s-1);
  }

  .grid-head h2 {
    font-size: 1.125rem;
  }

  .grid-pair .schedule-hero {
    padding: var(--s-3);
  }

  .grid-pair .score-strip {
    padding: 0 var(--s-1);
  }

  .mode-panel > .results-panel {
    border-radius: var(--r-button);
  }

  /* Setup sheet: a grab handle, roomier touch targets. */
  .rail {
    padding: 0 var(--s-4) calc(var(--s-5) + env(safe-area-inset-bottom, 0px));
  }

  .rail-sheet-head {
    padding: var(--s-4) 0 var(--s-3);
  }

  .rail-sheet-head::before {
    content: "";
    position: absolute;
    top: 6px;
    left: 50%;
    width: 36px;
    height: 4px;
    margin-left: -18px;
    border-radius: var(--r-pill);
    background: var(--line-strong);
  }

  .rail-close {
    width: 44px;
    height: 44px;
    background: var(--surface-2);
    color: var(--text);
  }

  .rail select,
  .rail .field select,
  .hours-chip,
  .rail .field input {
    min-height: 44px;
  }

  .rail .field .day-chip span {
    min-height: 40px;
  }

  .mini-cal-day {
    height: 36px;
  }

  .mini-cal-day::before {
    top: 2px;
    width: 32px;
    height: 32px;
    margin-left: -16px;
  }

  .hours-popover {
    left: 0;
    right: 0;
    width: auto;
  }

  .hours-col {
    flex: 1;
    min-width: 0;
  }

  .time-listbox {
    min-width: 0;
  }

  /* Share bar: sticky in flow. It sits after the last result, so at the end of
     the page it never covers anything; while scrolling it floats compactly. */
  .share-bar {
    margin: var(--s-3) calc(-1 * var(--s-4)) calc(-1 * var(--s-4));
    padding: var(--s-2) var(--s-4) calc(var(--s-2) + env(safe-area-inset-bottom, 0px));
    background: rgba(255, 252, 247, 0.94);
    backdrop-filter: blur(8px);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 16px rgba(43, 38, 34, 0.05);
  }

  .share-bar .primary-button {
    min-height: 44px;
  }

  body.rail-open .share-bar {
    visibility: hidden;
  }
}

@media (max-width: 380px) {
  .person-chip {
    padding: 0 10px;
  }

  .grid-pair .availability-grid {
    grid-template-columns: 50px repeat(var(--day-count), minmax(0, 1fr));
  }

  .grid-pair .time-label {
    padding-right: 6px;
    font-size: 0.625rem;
  }
}

/* ===========================================================================
   One screen on desktop (Round 8), like Google Calendar: the header is fixed,
   the workspace is exactly the rest of the viewport, and nothing scrolls the
   document. Each panel that can outgrow its space scrolls inside itself:
   the rail, each grid body (day names stay pinned), and the results list.
   Phones, 760-1100, short windows, the participant view and the invalid-link
   notice keep normal page scrolling.
   =========================================================================== */
@media (min-width: 1100px) and (min-height: 600px) {
  body:not(.is-student, .share-invalid) .app-shell {
    height: 100vh;
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }

  body:not(.is-student, .share-invalid) .topbar {
    flex: none;
  }

  body:not(.is-student, .share-invalid) .workspace {
    flex: 1 1 0;
    min-height: 0;
    max-width: none;
    grid-template-rows: minmax(0, 1fr);
    padding: var(--s-4) var(--s-5);
    overflow: hidden;
  }

  /* Rail: its own scroll, the thin bar parked in the gutter beside it. */
  body:not(.is-student, .share-invalid) .rail {
    align-self: stretch;
    min-height: 0;
    margin-right: calc(-1 * var(--s-4));
    padding: var(--s-1) var(--s-4) var(--s-4) 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* The Hours popover must not be clipped by the scrolling rail. Where CSS
     anchor positioning exists it floats above everything, tied to the chip;
     elsewhere it opens in flow inside the rail (the rail just gets longer). */
  body:not(.is-student, .share-invalid) .hours-popover {
    position: static;
    grid-column: 1 / -1;
    width: auto;
    max-width: none;
    margin-top: var(--s-1);
    box-shadow: var(--shadow-1);
  }

  body:not(.is-student, .share-invalid) .hours-popover .hours-col {
    flex: 1 1 0;
    min-width: 0;
  }

  body:not(.is-student, .share-invalid) .hours-popover .time-listbox {
    min-width: 0;
  }

  body:not(.is-student, .share-invalid) .hours-popover .time-listbox [role="option"] {
    white-space: normal;
  }

  @supports (anchor-name: --a) and (position-try-fallbacks: flip-block) {
    body:not(.is-student, .share-invalid) .hours-chip {
      anchor-name: --sloth-hours-chip;
    }

    body:not(.is-student, .share-invalid) .hours-popover {
      position: fixed;
      position-anchor: --sloth-hours-chip;
      top: calc(anchor(bottom) + 6px);
      left: anchor(left);
      position-try-fallbacks: flip-block;
      width: max-content;
      margin: 0;
      box-shadow: var(--shadow-3);
    }

    body:not(.is-student, .share-invalid) .hours-popover .time-listbox {
      min-width: 128px;
    }

    body:not(.is-student, .share-invalid) .hours-popover .time-listbox [role="option"] {
      white-space: nowrap;
    }
  }

  /* Main stage: banners and the S5 clock line on top, the panel fills the rest.
     If a short window can't hold the panel's minimum, the stage itself scrolls
     (never the page). */
  body:not(.is-student, .share-invalid) .main-area {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  body:not(.is-student, .share-invalid) .main-area > * {
    flex: none;
  }

  body:not(.is-student, .share-invalid) .context-bar {
    margin-bottom: var(--s-3);
  }

  /* Marking grid | answer grid on top, the results list as a strip below. The
     pair wrapper dissolves so its two cards and the list share one grid. */
  body:not(.is-student, .share-invalid) .mode-panel.is-active {
    flex: 1 1 0;
    min-height: 440px;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas:
      "mark answer"
      "list list";
    gap: var(--s-4);
  }

  body:not(.is-student, .share-invalid) .mode-panel .grid-pair {
    display: contents;
  }

  body:not(.is-student, .share-invalid) .mode-panel .pair-slot {
    grid-area: mark;
    min-height: 0;
  }

  body:not(.is-student, .share-invalid) .mode-panel .pair-result {
    grid-area: answer;
  }

  /* A card scrolls as a whole only as a last resort (a very short window). */
  body:not(.is-student, .share-invalid) .grid-pair .calendar-panel {
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* Only the grid body gives up height; titles, the S5 zone line, the payoff
     line and the stats never get squeezed. */
  body:not(.is-student, .share-invalid) .grid-pair .calendar-panel > * {
    flex-shrink: 0;
  }

  body:not(.is-student, .share-invalid) .grid-pair .grid-scroll {
    flex: 0 1 auto;
    min-height: 96px;
    overflow: auto;
    overscroll-behavior: contain;
  }

  /* Results strip: capped height, its title pinned while the rows scroll. */
  body:not(.is-student, .share-invalid) .mode-panel > .results-panel {
    grid-area: list;
    min-height: 0;
    max-height: clamp(132px, 20vh, 260px);
    margin: 0;
    padding-top: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  body:not(.is-student, .share-invalid) .mode-panel > .results-panel > .panel-title {
    position: sticky;
    top: 0;
    z-index: 3;
    margin-bottom: 0;
    padding: var(--s-4) 0 var(--s-3);
    background: var(--surface);
  }

  /* One calm scrollbar style for every inner scroller. */
  body:not(.is-student, .share-invalid) :is(.rail, .main-area, .grid-scroll, .results-panel, .calendar-panel) {
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
  }
}

/* Wide screens: the list gets its own full-height column beside the grids. */
@media (min-width: 1600px) and (min-height: 600px) {
  body:not(.is-student, .share-invalid) .mode-panel.is-active {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(280px, 340px);
    grid-template-rows: minmax(0, 1fr);
    grid-template-areas: "mark answer list";
  }

  body:not(.is-student, .share-invalid) .mode-panel > .results-panel {
    max-height: none;
  }

  body:not(.is-student, .share-invalid) .mode-panel :is(.best-list, .assignment-list) {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Remote organizer (grids on different clocks, stacked): the cards keep their
   natural height and the panel scrolls as one column instead. */
@media (min-width: 1100px) and (min-height: 600px) {
  body:not(.is-student, .share-invalid) .mode-panel.is-active:has(.grid-pair.is-cross-zone) {
    flex: none;
    min-height: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-template-areas: "mark" "answer" "list";
  }

  /* Each grid body still scrolls under its pinned day row. */
  body:not(.is-student, .share-invalid) .mode-panel.is-active:has(.grid-pair.is-cross-zone) .grid-scroll {
    max-height: 70vh;
  }

  body:not(.is-student, .share-invalid) .mode-panel.is-active:has(.grid-pair.is-cross-zone) > .results-panel {
    max-height: none;
    overflow: visible;
  }
}
