/* LineAstra's classes. Every page and React component styles itself only with these, and these use only the
   variables in tokens.css. Directions are logical (start and end) so right-to-left languages need no redesign. */

/* Base */

*, *::before, *::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, p, ul, ol, figure {
  margin: 0;
}

ul[class], ol[class] {
  padding: 0;
  list-style: none;
}

img, svg {
  display: block;
  max-inline-size: 100%;
}

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

[hidden] {
  display: none !important;
}

:focus-visible {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: var(--focus-offset);
}

::selection {
  background: var(--color-accent-soft);
}

/* Numbers that line up, on every figure. */
.num {
  font-variant-numeric: tabular-nums;
}

.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Layout */

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.stack--xs { gap: var(--space-1); }
.stack--sm { gap: var(--space-2); }
.stack--md { gap: var(--space-3); }
.stack--lg { gap: var(--space-6); }
.stack--xl { gap: var(--space-8); }

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

.cluster--lg { gap: var(--space-4); }
.cluster--between { justify-content: space-between; }
.cluster--end { justify-content: flex-end; }
.cluster--nowrap { flex-wrap: nowrap; }

.grow {
  flex: 1 1 auto;
  min-inline-size: 0;
}

.divider {
  block-size: var(--border-width);
  margin: 0;
  border: 0;
  background: var(--color-border);
}

/* Text */

.heading-1 {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
}

.heading-2 {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
}

.heading-3 {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
}

.text-muted { color: var(--color-text-muted); }
.text-subtle { color: var(--color-text-subtle); }
.text-sm { font-size: var(--text-sm); }
.text-xs { font-size: var(--text-xs); }
.text-danger { color: var(--color-danger); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }

.text-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mono {
  font-family: var(--font-mono);
  overflow-wrap: anywhere;
}

.eyebrow {
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-accent-text);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
}

.link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.link--muted {
  color: var(--color-text-muted);
}

.link--danger {
  color: var(--color-danger);
}

.prose {
  max-inline-size: var(--content-narrow);
  font-size: var(--text-md);
}

.prose > * + * {
  margin-block-start: var(--space-4);
}

.prose h2 {
  margin-block-start: var(--space-8);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.prose ul, .prose ol {
  padding-inline-start: var(--space-6);
}

.prose li + li {
  margin-block-start: var(--space-2);
}

.prose a {
  color: var(--color-accent-text);
}

/* Brand */

/* The wordmark is the whole logo (decision 0027): set by its height, never stretched, never under 18px tall. */
.brand {
  display: inline-flex;
  flex: none;
  align-items: center;
  text-decoration: none;
}

.brand__logo {
  display: block;
  inline-size: auto;
  max-inline-size: none;
  block-size: var(--logo-height);
}

.brand--large .brand__logo {
  block-size: var(--logo-height-lg);
}

/* Buttons */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-block-size: var(--control-height);
  padding: 0 var(--space-4);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-control);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}

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

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

.button:disabled, .button[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

.button--primary {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-on-accent);
}

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

.button--danger {
  border-color: var(--color-danger);
  background: var(--color-danger);
  color: var(--color-on-accent);
}

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

.button--ghost {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--color-text-muted);
}

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

/* An action that can't be undone, offered plainly rather than as the page's main action, such as deleting an account. */
.button--danger-outline {
  border-color: var(--color-danger);
  background: var(--color-surface);
  color: var(--color-danger);
}

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

.button--danger-ghost {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--color-danger);
}

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

.button--sm {
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
}

.button--lg {
  min-block-size: var(--control-height-lg);
  padding: 0 var(--space-6);
  font-size: var(--text-md);
}

.button--block {
  inline-size: 100%;
}

.icon-button {
  display: inline-grid;
  place-items: center;
  inline-size: var(--control-height);
  block-size: var(--control-height);
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

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

.icon {
  inline-size: 1.125rem;
  block-size: 1.125rem;
  flex: none;
}

.icon--sm {
  inline-size: 1rem;
  block-size: 1rem;
}

.icon--lg {
  inline-size: 1.5rem;
  block-size: 1.5rem;
}

.spinner {
  display: inline-block;
  vertical-align: middle;
  inline-size: 1rem;
  block-size: 1rem;
  border: 2px solid currentColor;
  border-inline-end-color: transparent;
  border-radius: var(--radius-full);
  animation: spin var(--duration-spin) linear infinite;
}

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

/* Forms */

.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.field__label {
  color: var(--color-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.field__hint {
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

.field__error {
  color: var(--color-danger);
  font-size: var(--text-sm);
}

.input, .select {
  inline-size: 100%;
  min-block-size: var(--control-height);
  padding: var(--space-2) var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-control);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-base);
  transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}

/* Fields stay at 16px on touch screens, where anything smaller makes iOS zoom in. */
@media (pointer: coarse) {
  .input, .select {
    font-size: var(--text-md);
  }
}

.input::placeholder {
  color: var(--color-text-subtle);
}

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

.input[aria-invalid="true"] {
  border-color: var(--color-danger);
}

.input--code {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  letter-spacing: var(--tracking-code);
  text-align: center;
  text-transform: uppercase;
}

.select {
  appearance: none;
  padding-inline-end: var(--space-8);
  background-image: linear-gradient(45deg, transparent 50%, var(--color-text-subtle) 50%),
    linear-gradient(135deg, var(--color-text-subtle) 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 50%, calc(100% - 0.8rem) 50%;
  background-size: 0.3rem 0.3rem;
  background-repeat: no-repeat;
}

.select:dir(rtl) {
  background-position: 1.1rem 50%, 0.8rem 50%;
}

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--text-base);
  cursor: pointer;
}

.checkbox input {
  flex: none;
  inline-size: 1.125rem;
  block-size: 1.125rem;
  margin: var(--space-0-5) 0 0;
  accent-color: var(--color-accent);
}

/* A whole row to tick, such as a person in a list: centred, with room for a picture and two lines. */
.checkbox--row {
  align-items: center;
  inline-size: 100%;
}

.checkbox--row input {
  margin: 0;
}

/* A choice with a short name and a quiet line saying what it covers. */
.checkbox__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.checkbox__title {
  color: var(--color-text);
  font-weight: var(--weight-medium);
}

.checkbox__hint {
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

/* Messages */

.alert {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: var(--color-text);
  font-size: var(--text-sm);
}

.alert--danger {
  border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
  background: var(--color-danger-soft);
  color: var(--color-danger-text);
}

.alert--success {
  border-color: color-mix(in srgb, var(--color-success) 30%, transparent);
  background: var(--color-success-soft);
  color: var(--color-success);
}

.alert--warning {
  border-color: color-mix(in srgb, var(--color-warning) 30%, transparent);
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.alert--info {
  border-color: color-mix(in srgb, var(--color-accent) 25%, transparent);
  background: var(--color-accent-soft);
  color: var(--color-accent-text);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

.badge--accent { background: var(--color-accent-soft); color: var(--color-accent-text); }
.badge--success { background: var(--color-success-soft); color: var(--color-success); }
.badge--warning { background: var(--color-warning-soft); color: var(--color-warning); }
.badge--danger { background: var(--color-danger-soft); color: var(--color-danger-text); }

.status-dot {
  inline-size: 0.5rem;
  block-size: 0.5rem;
  flex: none;
  border-radius: var(--radius-full);
  background: var(--color-text-subtle);
}

.status-dot--live {
  background: var(--color-success-mark);
  box-shadow: 0 0 0 var(--halo-width) var(--color-success-soft);
}

/* Surfaces */

.card {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}

.card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-5) var(--space-6) 0;
}

.card__body {
  padding: var(--space-5) var(--space-6);
}

.card__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  border-block-start: var(--border-width) solid var(--color-border);
}

.card__footer--start {
  justify-content: space-between;
}

.card--highlight {
  border-inline-start: var(--highlight-edge) solid var(--color-highlight);
  animation: arrive var(--duration-slow) var(--ease-out);
}

@keyframes arrive {
  from { opacity: 0; transform: translateY(-6px); }
}

.code-chip {
  display: inline-flex;
  align-items: center;
  padding: var(--space-0-5) var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-code);
}

.qr {
  inline-size: var(--qr-size);
  block-size: var(--qr-size);
  padding: var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-qr-paper);
}

.avatar {
  display: inline-grid;
  place-items: center;
  inline-size: 2rem;
  block-size: 2rem;
  flex: none;
  border-radius: var(--radius-full);
  background: var(--color-accent-soft);
  color: var(--color-accent-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
}

/* Lists of things, such as rooms and templates */

.item-list {
  container: items / inline-size;
  display: flex;
  flex-direction: column;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
}

/* Inside a card, a list is the card's own rows under a divider, not a second panel. */
.card > .item-list {
  margin-block-start: var(--space-4);
  border: 0;
  border-block-start: var(--border-width) solid var(--color-border);
  border-radius: 0;
  border-end-start-radius: var(--radius-lg);
  border-end-end-radius: var(--radius-lg);
  background: transparent;
  box-shadow: none;
}

.card > .item-list .item {
  padding-inline: var(--space-6);
}

/* Rows in a card stack their actions only at phone widths, as a card's rows have few actions. */
.card > .item-list {
  container: card-items / inline-size;
}

@container card-items (max-width: 520px) {
  .card > .item-list .item {
    grid-template-columns: minmax(0, 1fr);
    padding: var(--space-4);
  }

  .card > .item-list .item__actions {
    justify-content: flex-start;
    margin-inline-start: calc(var(--space-3) * -1);
  }
}

.item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3) var(--space-6);
  padding: var(--space-4) var(--space-5);
}

.item + .item {
  border-block-start: var(--border-width) solid var(--color-border);
}

.item--new {
  background: var(--color-surface-selected);
  animation: arrive var(--duration-slow) var(--ease-out);
}

.item__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-inline-size: 0;
}

.item__title {
  color: var(--color-text);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

.item__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

.item__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* Rows stack their buttons under the details when the list itself is narrow, whatever the screen. */
@container items (max-width: 760px) {
  .item {
    grid-template-columns: minmax(0, 1fr);
    padding: var(--space-4);
  }

  .item__actions {
    justify-content: flex-start;
    margin-inline-start: calc(var(--space-3) * -1);
  }
}

.item__confirm {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-danger-soft);
  color: var(--color-danger);
  font-size: var(--text-sm);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-12) var(--space-6);
  border: var(--border-width) dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  text-align: center;
}

.empty-state__icon {
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 3rem;
  border-radius: var(--radius-full);
  background: var(--color-accent-soft);
  color: var(--color-accent-text);
}

.empty-state__title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}

.empty-state__text {
  max-inline-size: 28rem;
  color: var(--color-text-muted);
}

/* App shell: a sidebar of sections, and the page beside it */

.shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  min-block-size: 100vh;
  min-block-size: 100dvh;
}

/* The star blue stripe down the far edge. */
.shell::before {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  z-index: var(--z-nav);
  inline-size: var(--stripe-width);
  background: linear-gradient(var(--color-highlight), var(--color-highlight-tint));
  content: "";
}

.shell__sidebar {
  position: sticky;
  inset-block-start: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  block-size: 100vh;
  block-size: 100dvh;
  padding: var(--space-4) var(--space-3);
  border-inline-end: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  overflow-y: auto;
}

.shell__brand {
  padding: var(--space-1) var(--space-2);
}

.shell__workspace {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  inline-size: 100%;
  padding: var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.shell__workspace:hover,
.shell__workspace[aria-expanded="true"] {
  background: var(--color-surface-hover);
}

.shell__workspace-mark {
  display: grid;
  flex: none;
  place-items: center;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  border-radius: var(--radius-md);
  background: var(--color-info-soft);
  color: var(--color-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

/* Placed by code on its own layer, under or over its button (ui/Menu.tsx), so no scrolling box clips it. */
.menu {
  position: fixed;
  z-index: var(--z-overlay);
  min-inline-size: 12rem;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-1);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  box-shadow: var(--shadow-lg);
}

.menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--control-height-sm);
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-sm);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}

.menu__item:hover,
.menu__item:focus-visible {
  background: var(--color-surface-hover);
}

.menu__item[aria-current="true"] {
  font-weight: var(--weight-semibold);
}

.menu__divider {
  block-size: var(--border-width);
  margin-block: var(--space-1);
  background: var(--color-border);
}

.shell__workspace-name {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
}

.shell__workspace-plan {
  display: block;
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

.shell__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.shell__nav-heading {
  padding: var(--space-3) var(--space-3) var(--space-1);
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--control-height);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}

.nav-item .icon {
  color: var(--color-text-subtle);
}

.nav-item:hover {
  background: var(--color-surface-hover);
  color: var(--color-text);
}

.nav-item[aria-current="page"] {
  background: var(--color-highlight-soft);
  color: var(--color-text);
  font-weight: var(--weight-semibold);
}

.nav-item[aria-current="page"] .icon {
  color: var(--color-highlight);
}

.nav-item__count {
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

.nav-item__live {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-success);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

.nav-item__live .status-dot {
  box-shadow: none;
}

/* The foot of the sidebar: this month's hours, then the account. */
.shell__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-block-start: auto;
}

.shell__help {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  text-decoration: none;
}

.shell__help:hover {
  color: var(--color-text);
}

.shell__usage {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  text-decoration: none;
}

.shell__usage:hover {
  border-color: var(--color-border-strong);
}

.shell__usage[aria-current="page"] {
  border-color: transparent;
  background: var(--color-highlight-soft);
}

.shell__usage-text strong {
  color: var(--color-text);
  font-weight: var(--weight-semibold);
}


.shell__account {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  inline-size: 100%;
  padding: var(--space-2);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.shell__account:hover,
.shell__account[aria-expanded="true"] {
  background: var(--color-surface-hover);
}

.shell__account-name {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.shell__account-email {
  display: block;
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

/* The bar above each page: the page's tabs, then search and its main action. */
.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-block-end: var(--space-6);
}

.topbar__start {
  display: flex;
  align-items: center;
  min-inline-size: 0;
}

.topbar__end {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: auto;
}

.search-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  inline-size: 13.75rem;
  min-block-size: var(--control-height);
  padding: 0 var(--space-2) 0 var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-control);
  background: var(--color-surface);
  color: var(--color-text-subtle);
  font: inherit;
  font-size: var(--text-sm);
  text-align: start;
  cursor: pointer;
}

.search-button:hover {
  border-color: var(--color-border-strong);
}

.kbd {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-1);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  line-height: var(--leading-normal);
}

/* The command palette, near the top of the screen like a search box, with no animation. */
.palette {
  inline-size: min(100% - 2rem, var(--palette-width));
  max-block-size: min(70vh, 32rem);
  margin-block-start: 12vh;
  padding: 0;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
  overflow: hidden;
}

.palette[open] {
  display: flex;
  flex-direction: column;
}

.palette::backdrop {
  background: var(--color-backdrop);
}

.palette__search {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-block-end: var(--border-width) solid var(--color-border);
  color: var(--color-text-subtle);
}

.palette__input {
  flex: 1;
  min-inline-size: 0;
  border: 0;
  background: none;
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-md);
  outline: none;
}

.palette__list {
  padding: var(--space-2);
  overflow-y: auto;
}

.palette__group {
  padding: var(--space-2) var(--space-2) var(--space-1);
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

.palette__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--control-height);
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  cursor: pointer;
}

.palette__item .icon {
  color: var(--color-text-subtle);
}

.palette__item--active {
  background: var(--color-highlight-soft);
}

.palette__item--active .icon {
  color: var(--color-highlight);
}

.palette__hint {
  color: var(--color-text-subtle);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

.palette__empty {
  padding: var(--space-6) var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  text-align: center;
}

.shortcuts {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
}

.shortcuts__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-sm);
}

.shortcuts__keys {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
}

.shortcuts__key {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.shell__topbar {
  display: none;
}

.shell__main {
  container: content / inline-size;
  min-inline-size: 0;
}

.shell__content {
  inline-size: 100%;
  max-inline-size: var(--content-max);
  margin: 0 auto;
  padding: var(--space-8) var(--space-8) var(--space-16);
}

.shell__scrim {
  display: none;
}

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

  .shell::before,
  .topbar .search-button {
    display: none;
  }

  .shell__topbar {
    position: sticky;
    inset-block-start: 0;
    z-index: var(--z-sticky);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    block-size: var(--topbar-height);
    padding: 0 var(--space-3);
    border-block-end: var(--border-width) solid var(--color-border);
    background: var(--color-surface);
  }

  .shell__sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: var(--z-nav);
    inline-size: min(85vw, var(--sidebar-width));
    transform: translateX(-100%);
    /* Closed, it's hidden from the keyboard and screen readers too, once it has slid away; opening, it's visible at
       once (the open rule has no visibility transition), so the focus can move into it. */
    visibility: hidden;
    transition: transform var(--duration-base) var(--ease-out), visibility var(--duration-base);
  }

  .shell__sidebar:dir(rtl) {
    transform: translateX(100%);
  }

  .shell--nav-open .shell__sidebar {
    box-shadow: var(--shadow-lg);
    transform: none;
    visibility: visible;
    transition: transform var(--duration-base) var(--ease-out);
  }

  .shell--nav-open .shell__scrim {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-nav) - 1);
    display: block;
    background: var(--color-backdrop);
  }

  .shell__content {
    padding: var(--space-6) var(--space-4) var(--space-12);
  }
}

/* Page heading */

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--space-6);
}

.page-header__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-inline-size: 0;
}

.page-header__description {
  max-inline-size: 40rem;
  color: var(--color-text-muted);
}

.page-header__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.page-note {
  margin-block-start: var(--space-4);
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

/* Settings: a section per topic */

.settings {
  container: settings / inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  max-inline-size: 48rem;
}

/* Settings' sections (spec 0021 B13): a column beside them from 1024px that stays in view, and a list to jump with on
   a phone. A section scrolled to stops a little below the top. */
.settings-layout {
  display: grid;
  gap: var(--space-6);
}

.settings-nav {
  display: none;
}

.settings-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-block-end: var(--space-6);
  border-block-end: var(--border-width) solid var(--color-border);
  scroll-margin-block-start: calc(var(--topbar-height) + var(--space-4));
}

.settings-group:last-child {
  border-block-end: 0;
}

.settings-group .settings-section {
  padding-block-end: 0;
  border-block-end: 0;
}

.settings-nav__heading {
  margin: 0;
  padding-inline: var(--space-3);
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

/* By the width the page has, not the window's: the column only once the sections still have room for their fields. */
@container content (min-width: 60rem) {
  .settings-layout {
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: var(--space-10);
  }

  .settings-nav {
    position: sticky;
    inset-block-start: var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    align-self: start;
  }

  .settings-jump {
    display: none;
  }
}

.settings-section {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: var(--space-4) var(--space-8);
  padding-block-end: var(--space-6);
  border-block-end: var(--border-width) solid var(--color-border);
}

.settings-section:last-child {
  border-block-end: 0;
}

.settings-section__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* A section's words above its fields once the sections' own column is too narrow for both side by side. */
@container settings (max-width: 40rem) {
  .settings-section {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Sign-in and other pages before the app: a centred card */

.auth {
  display: flex;
  flex-direction: column;
  min-block-size: 100vh;
  min-block-size: 100dvh;
  background: var(--color-bg);
}

.auth__panel {
  display: flex;
  flex: 1;
  flex-direction: column;
}

/* The board in a world: a strip above the form on a phone, a column of its own from 1024px. */
.auth__showcase {
  position: relative;
  order: -1;
  block-size: 7.5rem;
  margin: 0;
  background: var(--ink-900);
  overflow: hidden;
}

.auth__tagline {
  display: none;
}

/* Cropped a little above centre, so a phone's strip keeps the tops of the pieces. */
.auth__world {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}

@media (min-width: 1024px) {
  .auth--split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  .auth__showcase {
    position: sticky;
    inset-block-start: 0;
    order: 0;
    block-size: 100vh;
    block-size: 100dvh;
  }

  .auth__tagline {
    display: block;
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    padding: var(--space-16) var(--space-10) var(--space-10);
    background: linear-gradient(to top, color-mix(in srgb, var(--ink-900) 85%, transparent), transparent);
    color: var(--gray-0);
    font-size: var(--text-lg);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
  }
}

/* The guests' join page: often older people, often on phones, so everything a step larger (spec 0021 B4). */
.auth__card--guest,
.auth__card--guest .field__label,
.auth__card--guest .field__hint,
.auth__card--guest .field__error,
.auth__card--guest .input,
.auth__card--guest .checkbox {
  font-size: var(--text-lg);
}

/* The room code as six boxes, one character each, in reading order whatever the page's direction. They're .input--code
   too; one character needs no spacing after it. */
.code-boxes__row {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-2);
  direction: ltr;
}

.auth__card--guest .code-boxes__box {
  min-block-size: var(--control-height-lg);
  padding: 0;
  font-size: var(--text-xl);
  letter-spacing: normal;
}

.auth__divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

.auth__divider::before,
.auth__divider::after {
  content: "";
  flex: 1;
  border-block-start: var(--border-width) solid var(--color-border);
}

/* A password and its Show button, inside the one box. */
.password-field {
  position: relative;
}

.password-field__input {
  padding-inline-end: var(--space-16);
}

.password-field__toggle {
  position: absolute;
  inset-block: var(--space-1);
  inset-inline-end: var(--space-1);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.password-field__toggle:hover {
  background: var(--color-surface-hover);
  color: var(--color-text);
}

.password-field__toggle:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.field__warning {
  color: var(--status-warning-text);
  font-size: var(--text-sm);
}

/* A rule a value must meet, ticked as it's typed, such as a password's length. */
.field__rule {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

.field__rule .icon {
  opacity: 0.35;
}

.field__rule--met {
  color: var(--status-success-text);
}

.field__rule--met .icon {
  opacity: 1;
}

.auth__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5) var(--space-6);
}

.auth__main {
  display: grid;
  flex: 1;
  place-items: center;
  padding: var(--space-6) var(--space-4) var(--space-16);
}

/* On a phone the card starts right under the logo, not centred down the screen. */
@media (max-width: 640px) {
  .auth__main {
    place-items: start center;
    padding-block-start: var(--space-2);
  }
}

.auth__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  inline-size: 100%;
  max-inline-size: var(--auth-card-width);
  padding: var(--space-8);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}

/* An auth page's card with tiles to choose from, such as first-run setup's ways of working and worlds. */
.auth__card--wide {
  max-inline-size: var(--auth-card-width-wide);
}

.auth__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
}

.auth__intro {
  color: var(--color-text-muted);
}

.auth__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

.auth__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-5);
  padding: var(--space-4) var(--space-6);
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  text-align: center;
}

@media (max-width: 480px) {
  .auth__card {
    padding: var(--space-6) var(--space-5);
    border-radius: var(--radius-lg);
  }
}

/* Dialogs */

.dialog {
  inline-size: min(100% - 2rem, 30rem);
  padding: 0;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
}

.dialog::backdrop {
  background: var(--color-backdrop);
}

/* The header and footer stay in view; only the body scrolls. */
.dialog[open] {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: arrive var(--duration-base) var(--ease-out);
}

.dialog > form {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-block-size: 0;
}

.dialog__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-6) 0;
}

.dialog__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.dialog__close {
  display: none;
}

@media (max-width: 760px) {
  .dialog__close {
    display: inline-flex;
  }
}

.dialog__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.dialog__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-4);
  min-block-size: 0;
  padding: var(--space-5) var(--space-6);
  overflow-y: auto;
}

.dialog__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-block-start: var(--border-width) solid var(--color-border);
  background: var(--color-surface-sunken);
}

/* Loading */

.loading {
  display: grid;
  place-items: center;
  min-block-size: 50vh;
  color: var(--color-text-subtle);
}

.skeleton {
  border-radius: var(--radius-md);
  background: linear-gradient(90deg, var(--color-surface-sunken), var(--color-surface-hover), var(--color-surface-sunken));
  background-size: 200% 100%;
  animation: shimmer var(--duration-shimmer) ease-in-out infinite;
}

.skeleton--row {
  block-size: 4.5rem;
}

@keyframes shimmer {
  to { background-position: -200% 0; }
}

/* Reading pages, such as the guide */

.doc {
  min-block-size: 100vh;
  background: var(--color-surface);
}

.doc__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-block-end: var(--border-width) solid var(--color-border);
}

.doc__main {
  margin: 0 auto;
  padding: var(--space-10) var(--space-5) var(--space-16);
}

/* Section headings inside a page */

.section-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  margin-block-end: var(--space-3);
}

.section-heading__title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}

/* Figures at a glance */

.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
}

/* Four across when there's room, otherwise two by two, never three and one. */
@container content (max-width: 760px) {
  .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.stat__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.stat__value {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  font-variant-numeric: tabular-nums;
}

.stat__note {
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

/* How much of a limit is used */

.meter {
  display: block;
  inline-size: 100%;
  block-size: 0.5rem;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  appearance: none;
  overflow: hidden;
}

.meter::-webkit-progress-bar {
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
}

/* Every meter is the one look: the highlight, turning warning near a limit and danger at it. */
.meter::-webkit-progress-value {
  border-radius: var(--radius-full);
  background: var(--color-highlight);
}

.meter::-moz-progress-bar {
  border-radius: var(--radius-full);
  background: var(--color-highlight);
}

.meter.meter--warning::-webkit-progress-value { background: var(--color-warning); }
.meter.meter--warning::-moz-progress-bar { background: var(--color-warning); }
.meter.meter--full::-webkit-progress-value { background: var(--color-danger); }
.meter.meter--full::-moz-progress-bar { background: var(--color-danger); }

.usage {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* On its own on a page, rather than in a column of them. */
.usage--narrow {
  max-inline-size: 26rem;
}

.usage__line {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
}

.usage__value {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Two columns on wide screens, one on narrow */

.columns {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}

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

/* Tabs and filter chips */

.tabs {
  display: flex;
  gap: var(--space-1);
  margin-block-end: var(--space-5);
  border-block-end: var(--border-width) solid var(--color-border);
  overflow-x: auto;
}

.tab {
  margin-block-end: calc(var(--border-width) * -1);
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-block-end: 2px solid transparent;
  background: none;
  color: var(--color-text-muted);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
}

.tab:hover {
  color: var(--color-text);
}

.tab[aria-selected="true"] {
  border-block-end-color: var(--color-accent);
  color: var(--color-accent-text);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chip {
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.chip:hover {
  color: var(--color-text);
}

/* A word shown as a tag, not a control. */
.chip--tag {
  display: inline-flex;
  align-items: center;
  min-block-size: 1.5rem;
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  cursor: default;
}

.chip--tag:hover {
  color: var(--color-text-muted);
}

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

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-block-end: var(--space-5);
}

.toolbar__search {
  flex: 1 1 16rem;
  max-inline-size: 22rem;
}

.toolbar__end {
  margin-inline-start: auto;
}

/* Cards in a grid: rooms, templates, worlds */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: var(--space-4);
}

/* Under a long list shown a page at a time. */
.list-more {
  display: flex;
  justify-content: center;
  margin-block-start: var(--space-5);
}

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  overflow: hidden;
  transition: border-color var(--duration-fast) var(--ease-out);
}

.tile:hover {
  border-color: var(--color-border-strong);
}

.tile--new {
  border-inline-start: var(--highlight-edge) solid var(--color-highlight);
  animation: arrive var(--duration-slow) var(--ease-out);
}

.tile--selected {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
}

.tile--locked .tile__media {
  opacity: 0.55;
}

.tile__media {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  border-block-end: var(--border-width) solid var(--color-border);
  background: var(--color-surface-sunken);
  overflow: hidden;
}

.tile__image {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.tile__badges {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.tile__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
}

.tile__title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

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

.tile__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

.tile__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-block-start: var(--border-width) solid var(--color-border);
}

.tile__footer-end {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-1);
  margin-inline-start: auto;
}

/* A room's board on its card covers the picture area, under the card's badges. */
.board-picture.board-picture--tile {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  aspect-ratio: auto;
}

/* Smaller cards, four across on a wide screen, and larger ones, two across. */
.card-grid--dense {
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}

.card-grid--wide {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 28rem), 1fr));
}

/* A card that opens its item: the title is the button, stretched over the whole card under its other controls. */
/* Its size and weight are its title class's. */
.tile__open {
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font-family: inherit;
  line-height: inherit;
  text-align: start;
  cursor: pointer;
}

/* On a touch screen, where nothing shows on hover, a card says it opens. */
.tile__touch-hint {
  display: none;
}

@media (hover: none) {
  .tile__touch-hint {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
  }
}

.tile__open::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.tile__open:focus-visible {
  outline: none;
}

.tile:has(.tile__open:focus-visible) {
  border-color: var(--color-focus);
  box-shadow: var(--focus-ring);
}

/* Over the card's stretched button, so a card's own controls stay clickable. */
.tile__above {
  position: relative;
  z-index: 1;
}

/* A card's main action, over the corner of its picture. */
.tile__media-action {
  position: absolute;
  inset-block-end: var(--space-2);
  inset-inline-end: var(--space-2);
  z-index: 1;
}

/* An action shown on hover and focus only, so a page of cards isn't a wall of buttons. Always shown on touch screens. */
.tile__hover-action {
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-out);
}

.tile:hover .tile__hover-action,
.tile:focus-within .tile__hover-action {
  opacity: 1;
}

@media (hover: none) {
  .tile__hover-action {
    opacity: 1;
  }
}

/* A lock over a format's picture when the plan doesn't include it. */
.tile__lock {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--card);
  background: color-mix(in srgb, var(--ink-900) 35%, transparent);
}

/* A short list of what something gives, each line with a tick. */
.check-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-block-end: var(--space-4);
}

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

.check-list__item .icon {
  color: var(--color-success);
}

/* Two columns, one on a phone: a narrow list and the chosen item in full (Ways of working), or a wide form and its
   preview (New room). A sticky column stays in view while the other scrolls, on a computer only. */
.split {
  display: grid;
  grid-template-columns: minmax(14rem, 18rem) minmax(0, 1fr);
  align-items: start;
  gap: var(--space-6);
}

.split--wide-start {
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
}

.split--middle {
  align-items: center;
}

.split__sticky {
  position: sticky;
  inset-block-start: 0;
}

.split__detail {
  padding: var(--space-6);
}

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

  .split__sticky {
    position: static;
  }
}

/* The list of a list and detail page: menu items, a little larger, the chosen one marked. */
.side-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.side-list__item {
  inline-size: 100%;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-base);
}

.side-list__item[aria-current="true"] {
  background: var(--color-highlight-soft);
}

.side-list__item[aria-current="true"] .icon {
  color: var(--color-highlight);
}

/* Three stills of a kind side by side in a card, overlapping a little: each is a square, mostly clear around the figure. */
.still-row {
  position: absolute;
  inset: 8% 0 4%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.figure-picture {
  block-size: 100%;
  inline-size: auto;
}

/* A rendered figure standing on a soft shadow, drawn by the page so every still sits on the same ground. */
.figure-still {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  flex: 0 0 auto;
  block-size: 100%;
  min-inline-size: 0;
  aspect-ratio: 1;
  margin-inline: -9%;
}

/* The middle still in front, its neighbours a little smaller behind it, so each figure reads on its own (wings too). */
.figure-still:nth-child(2) {
  z-index: 1;
}

.figure-still:not(:nth-child(2)) {
  transform: scale(0.86);
  transform-origin: bottom;
  opacity: 0.92;
}

.figure-still::before {
  content: "";
  position: absolute;
  inset-block-end: 6%;
  inset-inline: 22%;
  block-size: 9%;
  border-radius: var(--radius-full);
  background: radial-gradient(closest-side, color-mix(in srgb, var(--ink-900) 30%, transparent), transparent);
}

.figure-still__image {
  position: relative;
  inline-size: 100%;
  block-size: 100%;
  min-inline-size: 0;
}

/* The drawn shape standing in while a still is on its way. It waits a moment first, so a still that arrives at once
   never flickers through it. */
.figure-still__waiting {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: still-waiting var(--duration-fast) var(--duration-base) both;
}

@keyframes still-waiting {
  from { opacity: 0; }
}

/* A still cropped to its piece and drawn to fill its place (FigureStill's frame), as on the room's shelf. */
.figure-still.figure-still--framed {
  overflow: hidden;
  inline-size: 100%;
  aspect-ratio: auto;
  margin-inline: 0;
  opacity: 1;
  transform: none;
}

.figure-still--framed .figure-still__image {
  position: absolute;
  inline-size: auto;
  block-size: auto;
  max-inline-size: none;
}

/* A figure's colour beside its kind, in a list. */
.figure-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.figure-list__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.figure-list__swatch {
  inline-size: var(--space-3);
  block-size: var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-full);
}

.drawer {
  position: fixed;
  inset-block: 0;
  inset-inline: auto 0;
  display: none;
  flex-direction: column;
  inline-size: min(100%, 32rem);
  block-size: 100%;
  max-block-size: none;
  margin: 0;
  padding: 0;
  border: none;
  border-inline-start: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
}

.drawer[open] {
  display: flex;
  animation: drawer-in var(--duration-base) var(--ease-out);
}

.drawer::backdrop {
  background: var(--color-backdrop);
}

/* From its own edge, in either direction of writing. */
@keyframes drawer-in {
  from {
    margin-inline-end: calc(-1 * var(--space-6));
    opacity: 0;
  }
}

.drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
  border-block-end: var(--border-width) solid var(--color-border);
}

.drawer__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.drawer__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-6);
  overflow-y: auto;
}

.drawer__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-block-start: var(--border-width) solid var(--color-border);
  background: var(--color-surface-sunken);
}

/* A world shown whole, for its preview. */
.world-preview {
  display: block;
  inline-size: 100%;
  border-radius: var(--radius-lg);
}

/* A board seen from above */

.board-preview {
  inline-size: 72%;
  block-size: auto;
  max-block-size: 92%;
}

.board-preview--small {
  inline-size: 3.5rem;
  block-size: 3.5rem;
}

.board-preview__platform {
  fill: var(--color-surface);
  stroke: var(--color-border-strong);
  stroke-width: 0.12;
}

.board-preview__ring {
  fill: none;
  stroke: var(--color-border);
  stroke-width: 0.06;
}

.board-preview__figure {
  stroke: var(--color-surface);
  stroke-width: 0.12;
}

.board-preview__facing {
  stroke: var(--color-text-subtle);
  stroke-width: 0.14;
  stroke-linecap: round;
}

/* Lists of things to do */

/* Plans side by side */

.table-wrap {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow-x: auto;
}

.table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--text-base);
}

.table th, .table td {
  padding: var(--space-3) var(--space-4);
  border-block-end: var(--border-width) solid var(--color-border);
  text-align: start;
  white-space: nowrap;
}

.table tr:last-child th, .table tr:last-child td {
  border-block-end: 0;
}

.table thead th {
  background: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.table tbody th {
  color: var(--color-text-muted);
  font-weight: var(--weight-medium);
}

.table__current {
  background: var(--color-accent-soft);
}

/* A comparison wider than a phone scrolls sideways under its row names, which stay put, with a hint above it. */
.table--compare tbody th {
  position: sticky;
  inset-inline-start: 0;
  z-index: 1;
  background: var(--color-surface);
  box-shadow: 1px 0 0 var(--color-border);
}

.table--compare thead th:first-child {
  position: sticky;
  inset-inline-start: 0;
  z-index: 2;
}

.table-hint {
  display: none;
  margin-block: 0 var(--space-2);
  font-size: var(--text-sm);
}

@media (max-width: 40rem) {
  .table-hint {
    display: block;
  }

  /* Row names wrap, so two plans fit beside them. */
  .table--compare tbody th {
    min-inline-size: 7rem;
    max-inline-size: 8.5rem;
    white-space: normal;
  }
}

/* Choosing one picture among several, such as a world */

.choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: var(--space-2);
}

/* Worlds large enough to see, in New room. */
/* Worlds to pick from, where the picture is the choice: larger tiles in their 16:9. */
.choice-grid--worlds {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr));
}

.choice-grid--worlds .choice__image {
  aspect-ratio: 16 / 9;
}

.choice-grid--wide {
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}

.choice {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  overflow: hidden;
  cursor: pointer;
}

.choice:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--color-choice-selected);
}

.choice:has(input:focus-visible) {
  box-shadow: var(--focus-ring);
}

.choice:has(input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}

.choice input {
  position: absolute;
  opacity: 0;
}

.choice__image {
  inline-size: 100%;
  aspect-ratio: 4 / 1;
  object-fit: cover;
}

.choice__label {
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

/* Short confirmations in a corner */

.toasts {
  position: fixed;
  inset-block-end: var(--space-5);
  inset-inline-end: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-text);
  box-shadow: var(--shadow-lg);
  color: var(--color-text-inverse);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  animation: arrive var(--duration-base) var(--ease-out);
  pointer-events: auto;
}

@media (max-width: 640px) {
  .toasts {
    inset-inline: var(--space-4);
  }
}

.greeting {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

fieldset {
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

legend {
  padding: 0;
  margin-block-end: var(--space-2);
}

.tile__footer > .item__confirm {
  flex: 1 1 100%;
}

/* The style guide (spec 0021 A4): its layout and the token specimens. */

.styleguide {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
  max-inline-size: var(--content-max);
  margin-inline: auto;
  padding: var(--space-8) var(--space-6) var(--space-16);
}

.styleguide__part {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.styleguide__state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.styleguide__label {
  inline-size: var(--space-16);
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

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

.styleguide__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: var(--space-4);
}

.styleguide__board {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-6);
}

/* At the size a room's tile shows it. */
.styleguide__board > .board-preview:not(.board-preview--small) {
  inline-size: 13rem;
}

.specimens {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  gap: var(--space-3) var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.specimens--icons {
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
}

.specimen {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-inline-size: 0;
}

.specimen__name,
.specimen__value {
  overflow-wrap: anywhere;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

.specimen__value {
  color: var(--color-text-subtle);
}

.specimen__swatch {
  display: block;
  block-size: var(--space-10);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
}

.specimen__swatch--plain {
  border-color: transparent;
  background: var(--color-surface);
}

.specimen__swatch--outline {
  inline-size: var(--space-12);
  background: var(--color-highlight-soft);
  border-color: var(--color-highlight);
}

.specimen__bar {
  display: block;
  block-size: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-info);
}

.specimen__text {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Home (spec 0021 B1): headline numbers, pills, tags, the live card, the rooms table, follow-ups and the week chart. */

.home-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  align-items: start;
  gap: var(--space-5);
}

/* A wide table scrolls inside its card rather than widening the page. */
.home-columns > * {
  min-inline-size: 0;
}

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

.kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}

.kpi-strip__cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
}

.kpi-strip__cell + .kpi-strip__cell {
  border-inline-start: var(--border-width) solid var(--color-border);
}

.kpi-strip__label {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* The number and its change each on one line, side by side while they fit, the change under the number when not. */
.kpi-strip__value {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0;
  color: var(--color-text);
  font-size: var(--text-kpi);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
}

.kpi-strip__value > * {
  white-space: nowrap;
}

/* A headline value that's a state in words, not a number: a step smaller, and free to wrap. */
.value-word {
  font-size: var(--text-lg);
  white-space: normal;
}

.kpi-strip__suffix {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
}

@media (max-width: 860px) {
  .kpi-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .kpi-strip__cell:nth-child(3) {
    border-inline-start: 0;
  }

  .kpi-strip__cell:nth-child(n + 3) {
    border-block-start: var(--border-width) solid var(--color-border);
  }
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
}

.status-pill__dot {
  inline-size: 0.375rem;
  block-size: 0.375rem;
  border-radius: var(--radius-full);
  background: currentColor;
}

.status-pill--live {
  background: var(--color-success-soft);
  color: var(--color-success);
}

.status-pill--live .status-pill__dot {
  background: var(--color-success-mark);
}

.status-pill--warning {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.status-pill--danger {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}

.way-dot {
  display: inline-flex;
}

.way-dots {
  gap: var(--space-0-5);
}

.tag__dot {
  inline-size: 0.375rem;
  block-size: 0.375rem;
  border-radius: var(--radius-full);
  background: var(--way-free);
}

.tag--coaching .tag__dot { background: var(--way-coaching); }
.tag--organisation .tag__dot { background: var(--way-organisations); }
.tag--parts .tag__dot { background: var(--way-parts); }
.tag--family .tag__dot { background: var(--way-family); }
.tag--group .tag__dot { background: var(--way-groups); }
.tag--free .tag__dot { background: var(--way-free); }

.segmented {
  display: inline-flex;
  max-inline-size: 100%;
  overflow-x: auto;
  gap: var(--space-1);
  padding: var(--space-1);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.segmented__item {
  display: inline-flex;
  flex: none;
  white-space: nowrap;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.segmented__item:hover {
  color: var(--color-text);
}

.segmented__item[aria-selected="true"],
.segmented__item[aria-checked="true"] {
  background: var(--color-surface-sunken);
  color: var(--color-text);
  font-weight: var(--weight-semibold);
}

.segmented__count {
  color: var(--color-highlight-text);
  font-weight: var(--weight-semibold);
}

.follow-up {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.follow-up__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
}

.follow-up__item + .follow-up__item {
  border-block-start: var(--border-width) solid var(--color-border);
}

.follow-up__icon {
  display: grid;
  flex: none;
  place-items: center;
  inline-size: var(--space-8);
  block-size: var(--space-8);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
}

.follow-up__icon--urgent {
  border-color: transparent;
  background: var(--color-highlight-soft);
  color: var(--color-highlight);
}

.follow-up__text {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-inline-size: 0;
}

.follow-up__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.follow-up__line {
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

/* Positioned, so screen-reader-only text inside stays inside and doesn't widen the page. */
.data-table__scroll {
  position: relative;
  overflow-x: auto;
}

.data-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.data-table th {
  padding: var(--space-2) var(--space-4);
  border-block: var(--border-width) solid var(--color-border);
  background: var(--color-surface-header);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-align: start;
}

/* Numbers line up on their last digit, their heading with them. */
.data-table .num {
  text-align: end;
}

/* A choice inside a row, such as a member's role, wide enough to read. */
.data-table .select {
  min-inline-size: 9rem;
}

.data-table td {
  padding: var(--space-3) var(--space-4);
  border-block-end: var(--border-width) solid var(--color-border);
  vertical-align: middle;
}

.data-table tbody tr:last-child td {
  border-block-end: 0;
}

.data-table--compact th,
.data-table--compact td {
  padding: var(--space-1) var(--space-2);
}

.data-table__room {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.data-table__thumb {
  flex: none;
  inline-size: var(--space-10);
  block-size: var(--space-10);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  object-fit: cover;
}

.data-table__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-1);
}

.data-table__name {
  display: block;
  font-weight: var(--weight-semibold);
}

.data-table__sub {
  display: block;
  color: var(--color-text-muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

/* A table whose cells keep to one line, scrolling sideways when it must; long text ends with an ellipsis. */
.data-table--nowrap th,
.data-table--nowrap td {
  white-space: nowrap;
}

.data-table--nowrap .data-table__name,
.data-table--nowrap .data-table__sub {
  max-inline-size: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The Team page's members: the person's name and email give way first, and the actions column stays in view at the
   right edge even when the table scrolls, so Remove is always there to find. */
.data-table--members .data-table__name,
.data-table--members .data-table__sub {
  max-inline-size: 12rem;
}

.data-table--members th,
.data-table--members td {
  padding-inline: var(--space-3);
}

/* Separate borders, so the sticky column keeps its own, with an edge where the rest slides under it. */
.data-table--members {
  border-collapse: separate;
  border-spacing: 0;
}

.data-table--members td:last-child,
.data-table--members th:last-child {
  position: sticky;
  inset-inline-end: 0;
  background: var(--color-surface);
  box-shadow: inset var(--border-width) 0 0 var(--color-border);
}

.data-table--members th:last-child {
  background: var(--color-surface-header);
}

/* On a phone, each member stacked: who they are, then their role and Save role, then their numbers on one line, each
   with its heading, then the menu. */
@media (max-width: 640px) {
  .data-table.data-table--members thead {
    display: none;
  }

  .data-table.data-table--members,
  .data-table.data-table--members tbody {
    display: block;
  }

  .data-table.data-table--members tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-block-end: var(--border-width) solid var(--color-border);
  }

  .data-table.data-table--members td {
    position: static;
    padding: 0;
    border: 0;
    white-space: normal;
  }

  .data-table.data-table--members tbody tr:last-child {
    border-block-end: 0;
  }

  .data-table.data-table--members td:last-child {
    box-shadow: none;
  }

  /* Shrinks to the screen, so a long email wraps rather than pushing the row wider. */
  .data-table.data-table--members td:first-child,
  .data-table.data-table--members td[data-member-role] {
    flex-basis: 100%;
    min-inline-size: 0;
  }

  .data-table.data-table--members .data-table__sub {
    overflow-wrap: anywhere;
  }

  .data-table.data-table--members td[data-label]::before {
    content: attr(data-label) " ";
    color: var(--color-text-muted);
  }

  .data-table.data-table--members .data-table__name,
  .data-table.data-table--members .data-table__sub {
    max-inline-size: none;
  }
}

.live-card {
  overflow: hidden;
}

.live-card__board {
  position: relative;
  margin: var(--space-4) var(--space-4) 0;
  border-radius: var(--radius-lg);
  background: var(--ink-900);
  overflow: hidden;
}

.board-picture {
  display: block;
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 5 / 2;
}

/* The board: a dark, half-clear platform with a fine rim and a fainter inner ring, at real pixel widths. */
.board-picture__platform {
  fill: color-mix(in srgb, var(--ink-900) 55%, transparent);
  stroke: color-mix(in srgb, var(--card) 55%, transparent);
  stroke-width: var(--board-rim);
  vector-effect: non-scaling-stroke;
}

.board-picture__ring {
  fill: none;
  stroke: color-mix(in srgb, var(--card) 18%, transparent);
  stroke-width: var(--border-width);
  vector-effect: non-scaling-stroke;
}

/* Open land: no edge, a soft fill. */
.board-picture__ground {
  fill: color-mix(in srgb, var(--ink-900) 35%, transparent);
}

.board-picture__shadow {
  fill: color-mix(in srgb, var(--ink-900) 60%, transparent);
}

.live-card__overlay {
  position: absolute;
  inset-inline: var(--space-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.live-card__overlay--top {
  inset-block-start: var(--space-3);
}

.board-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

.live-card__strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-8);
  padding: var(--space-4) var(--space-5);
}

.live-card__strip .button {
  margin-inline-start: auto;
}

.live-card__cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.week-bars {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.week-bars__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--text-xs);
}

.week-bars__legend {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  color: var(--color-text-muted);
}

.week-bars__key {
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border-radius: var(--radius-full);
}

.week-bars__key--now { background: var(--chart-now); }
.week-bars__key--before { background: var(--chart-before); }
.week-bars__key--highlight { background: var(--chart-highlight); }

.week-bars__plot {
  border-radius: var(--radius-md);
}

.week-bars__svg {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

.week-bars__base {
  stroke: var(--color-border-strong);
  stroke-width: var(--border-width);
  vector-effect: non-scaling-stroke;
}

.week-bars__bar--now { fill: var(--chart-now); }
.week-bars__bar--before { fill: var(--chart-before); }
.week-bars__bar--highlight { fill: var(--chart-highlight); }

.week-bars__week--active .week-bars__bar {
  stroke: var(--color-text);
  stroke-width: var(--border-width);
  vector-effect: non-scaling-stroke;
}

/* Week labels in HTML, so they stay at their real size whatever the chart's width. */
.week-bars__axis {
  display: flex;
  color: var(--color-text-subtle);
  font-size: var(--text-2xs);
}

.week-bars__axis > span {
  flex: 1;
  min-inline-size: 0;
  white-space: nowrap;
}

.week-bars__hit {
  fill: transparent;
}

.week-bars__tip {
  min-block-size: var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  visibility: hidden;
}

.week-bars__tip--shown {
  visibility: visible;
}

.skeleton--chart {
  block-size: var(--space-16);
}

/* Home's rooms table: the room takes about 40%, and short columns stay on one line. */
.data-table--stack th:first-child {
  inline-size: 40%;
}

.data-table--stack th,
.data-table--stack td:nth-child(n + 2) {
  white-space: nowrap;
}

/* On a phone, each room in two lines: the room and its actions, then one run of way of working, last use and status. */
@media (max-width: 760px) {
  .data-table.data-table--stack thead {
    display: none;
  }

  .data-table.data-table--stack,
  .data-table.data-table--stack tbody {
    display: block;
  }

  .data-table.data-table--stack tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-block-end: var(--border-width) solid var(--color-border);
  }

  .data-table.data-table--stack tbody tr:last-child {
    border-block-end: 0;
  }

  .data-table.data-table--stack td {
    padding: 0;
    border: 0;
    font-size: var(--text-xs);
  }

  /* The room and its actions fill the first line together; the rest wraps onto the second. */
  .data-table.data-table--stack td:nth-child(1) { flex: 1 0 calc(100% - var(--row-actions) - var(--space-2)); order: 1; min-inline-size: 0; }
  .data-table.data-table--stack td:nth-child(5) { flex: 0 0 var(--row-actions); order: 2; }
  .data-table.data-table--stack td:nth-child(2) { order: 3; }
  .data-table.data-table--stack td:nth-child(3) { order: 4; }
  .data-table.data-table--stack td:nth-child(4) { order: 5; }

  .data-table.data-table--stack td:nth-child(3)::before,
  .data-table.data-table--stack td:nth-child(4)::before {
    margin-inline-end: var(--space-2);
    color: var(--color-text-subtle);
    content: "·";
  }

  .data-table--stack .data-table__thumb {
    inline-size: var(--space-8);
    block-size: var(--space-8);
  }

  .data-table--stack .data-table__name,
  .data-table--stack .data-table__sub {
    display: inline;
  }

  .data-table--stack .data-table__sub {
    margin-inline-start: var(--space-2);
  }

  .data-table--stack .icon-button {
    inline-size: var(--control-height-sm);
    block-size: var(--control-height-sm);
  }
}

/* The Room page (spec 0021 B2): its title with a status, the session chart, the room's facts, and who hosts it. */

.page-header__title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.tile__title--link {
  color: inherit;
  text-decoration: none;
}

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

.data-table a.data-table__name {
  color: inherit;
  text-decoration: none;
}

.data-table a.data-table__name:hover {
  text-decoration: underline;
}

.line-chart {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.line-chart__grid {
  stroke: var(--color-border);
  stroke-width: var(--border-width);
  stroke-dasharray: 3 3;
  vector-effect: non-scaling-stroke;
}

/* One measure is a series, so it's the "now" colour (ocean); the highlight marks only the newest point. */
.line-chart__area {
  fill: color-mix(in srgb, var(--chart-now) 14%, transparent);
}

/* A limit across the chart, such as the plan's hours: dashed, in the text's colour, as a threshold isn't a series. */
.line-chart__limit {
  stroke: var(--color-text-muted);
  stroke-width: var(--border-width);
  stroke-dasharray: 6 4;
  vector-effect: non-scaling-stroke;
}

.week-bars__key--limit {
  block-size: 0;
  border-radius: 0;
  border-block-start: calc(var(--border-width) * 2) dashed var(--color-text-muted);
}

.line-chart__line {
  fill: none;
  stroke: var(--chart-now);
  stroke-width: var(--chart-line);
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.line-chart__point {
  fill: var(--color-surface);
  stroke: var(--chart-now);
  stroke-width: var(--chart-line);
  vector-effect: non-scaling-stroke;
}

.line-chart__point--active {
  fill: var(--chart-now);
}

.line-chart__point--newest {
  fill: var(--chart-highlight);
  stroke: var(--chart-highlight);
}

.line-chart__axis {
  justify-content: space-between;
}

.line-chart__axis > span {
  flex: none;
}

.key-values {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 8rem), 1fr));
  gap: var(--space-4) var(--space-5);
  margin: 0;
}

.key-values__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.key-values__label {
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

.key-values__value {
  margin: 0;
  color: var(--color-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.privacy-note {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

.person-list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  border-block-start: var(--border-width) solid var(--color-border);
  list-style: none;
}

.person-list__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-block-end: var(--border-width) solid var(--color-border);
}

.person-list__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.person-list__role {
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

/* Home's setup strip (spec 0021, chosen by David): progress, a chip a step, and the chosen step's action. */
.setup {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}

.setup__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.setup__title {
  margin: 0;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}

.meter.setup__progress {
  flex: 1 1 8rem;
  max-inline-size: 16rem;
  block-size: calc(var(--space-1) * 1.5);
}

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

.setup__dismiss {
  margin-inline-start: auto;
}

.setup__steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.setup__step {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}

.setup__step[aria-pressed="true"] {
  border-color: var(--color-text);
}

.setup__step--done {
  border-color: var(--color-border);
  color: var(--color-text-muted);
}

.setup__step--done .icon {
  color: var(--color-success-mark);
}

.setup__step--current {
  border-color: transparent;
  background: var(--color-highlight-soft);
}

.setup__dot {
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-full);
}

.setup__step--current .setup__dot {
  border-color: var(--color-highlight);
  background: var(--color-highlight);
}

.setup__action {
  padding-block-start: var(--space-1);
}

.setup__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

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

.setup__input {
  inline-size: 12rem;
  min-block-size: var(--control-height-sm);
}

@media (max-width: 760px) {
  .meter.setup__progress {
    flex-basis: 100%;
    max-inline-size: none;
    order: 3;
  }

  .setup__row {
    flex-direction: column;
    align-items: stretch;
  }

  .setup__input {
    inline-size: 100%;
  }
}

/* Room page review: the breadcrumb, a table under a card's title, an empty board, and the line chart's scale. */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-block-end: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.breadcrumb a {
  color: inherit;
}

.breadcrumb__sep {
  color: var(--color-text-subtle);
}

.card__table {
  margin-block-start: var(--space-4);
}

.live-card__empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

.line-chart__plot {
  position: relative;
  padding-inline-start: var(--space-8);
}

.line-chart__tick {
  position: absolute;
  inset-inline-start: 0;
  color: var(--color-text-subtle);
  font-size: var(--text-2xs);
  line-height: 1;
  transform: translateY(-50%);
}

/* Level with the chart's top line, its half line and its baseline (8 and 152 of its 160 pixels). */
.line-chart__tick--top { top: 5%; }
.line-chart__tick--half { top: 50%; }
.line-chart__tick--zero { top: 95%; }

/* The Rooms page (spec 0021 B5): its filter bar, the new room's mark in the list, and the row menu. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-block-end: var(--space-4);
}

.filter-bar__search {
  flex: 1 1 14rem;
  min-inline-size: 0;
}

.filter-bar__end {
  margin-inline-start: auto;
}

.data-table__row--new td {
  background: var(--color-highlight-soft);
}

.menu-holder {
  position: relative;
}

.menu__item--danger {
  color: var(--color-danger-text);
}

/* New room (spec 0021 B6): a wide dialog in two columns, way-of-working tiles, the folded guests line, the preview,
   and the made room's invitation with its QR code. */
.dialog--wide {
  inline-size: min(100% - 2rem, 60rem);
}

@media (max-width: 760px) {
  .dialog--wide {
    inline-size: 100%;
    max-inline-size: 100%;
    block-size: 100%;
    max-block-size: 100%;
    border-radius: 0;
  }
}

.create__preview {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.create__preview .live-card__board {
  margin: 0;
}

.create__code {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
}

.copy-field {
  display: flex;
  gap: var(--space-2);
}

.copy-field__value {
  flex: 1;
  min-inline-size: 0;
}

.way-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr));
  gap: var(--space-2);
}

.way-tile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-control);
  cursor: pointer;
}

/* Chosen, as every choice is: the accent's border, two hairlines wide without moving anything, over its tint. */
.way-tile:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--color-choice-selected);
  box-shadow: inset 0 0 0 var(--border-width) var(--color-accent);
}

.way-tile:has(input:disabled) {
  cursor: not-allowed;
  opacity: 0.6;
}

.way-tile__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
}

.way-tile__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.way-tile__hint {
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

.guests-line {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-control);
}

.guests-line__summary {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3);
  font-size: var(--text-sm);
  cursor: pointer;
}

.guests-line[open] > :not(summary) {
  padding: 0 var(--space-3) var(--space-3);
}

.qr-code {
  display: block;
  inline-size: 12rem;
  block-size: 12rem;
  border-radius: var(--radius-md);
}

.qr-code--loading {
  border-radius: var(--radius-md);
}

.qr-code--failed {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border: var(--border-width) dashed var(--color-border);
  text-align: center;
}

.qr-code__ground {
  fill: var(--card);
}

.qr-code__modules {
  fill: var(--ink-900);
}

/* Insights (spec 0021 B11): the charts two across from 1100px, wide ones across both; the heatmap of when sessions
   start; and bars ranked or in order, each with its number. */
.insights-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
}

.insights-grid__wide {
  grid-column: 1 / -1;
}

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

.heatmap {
  display: grid;
  grid-template-columns: auto repeat(24, minmax(0, 1fr));
  gap: var(--space-0-5);
  align-items: center;
  border-radius: var(--radius-md);
  font-size: var(--text-2xs);
}

.heatmap__day {
  padding-inline-end: var(--space-2);
  color: var(--color-text-subtle);
  white-space: nowrap;
}

.heatmap__hour {
  color: var(--color-text-subtle);
  white-space: nowrap;
}

.heatmap__cell {
  block-size: 1.25rem;
  border-radius: var(--radius-xs);
  background: var(--color-surface-sunken);
}

.heatmap__cell--1 { background: var(--heat-1); }
.heatmap__cell--2 { background: var(--heat-2); }
.heatmap__cell--3 { background: var(--heat-3); }
.heatmap__cell--4 { background: var(--heat-4); }
.heatmap__cell--5 { background: var(--heat-5); }
.heatmap__cell--busiest { background: var(--chart-highlight); }

.heatmap__cell--active {
  outline: calc(var(--border-width) * 2) solid var(--color-text);
  outline-offset: 1px;
}

.heatmap__scale {
  display: inline-flex;
  align-items: center;
  gap: var(--space-0-5);
}

.heatmap__scale .heatmap__cell {
  inline-size: 0.75rem;
  block-size: 0.75rem;
}

.bar-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.bar-list__item {
  display: grid;
  grid-template-columns: minmax(6rem, 11rem) minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
  font-size: var(--text-sm);
}

.bar-list__label {
  overflow: hidden;
  color: var(--color-text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bar-list__track {
  display: block;
  block-size: 0.625rem;
}

.bar-list__bar {
  display: block;
  inline-size: 0;
  min-inline-size: 2px;
  block-size: 100%;
  border-start-end-radius: var(--radius-xs);
  border-end-end-radius: var(--radius-xs);
  background: var(--chart-now);
}

.bar-list__item--muted .bar-list__bar {
  background: var(--color-border-strong);
}

.bar-list__item--empty .bar-list__bar {
  min-inline-size: 0;
}

.bar-list__value {
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* The room's row along the top (spec 0025 step 1), over the board: the room at the left, ending it at the right. */

.room-top {
  position: absolute;
  inset-block-start: var(--room-edge);
  inset-inline: var(--room-edge);
  z-index: var(--z-sticky);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  pointer-events: none;
}

.room-top__start,
.room-top__end-group {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-inline-size: 0;
  min-block-size: var(--control-height);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-1);
  border-radius: var(--radius-full);
  color: var(--board-text);
  font-size: var(--text-sm);
  pointer-events: auto;
}

.room-top__end-group {
  flex: none;
  padding: var(--space-1);
}

.room-top__back,
.room-top__copy {
  display: grid;
  flex: none;
  place-items: center;
  inline-size: var(--control-height-sm);
  block-size: var(--control-height-sm);
  padding: 0;
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-full);
  background: none;
  color: var(--board-text);
  cursor: pointer;
}

.room-top__back:hover,
.room-top__copy:hover {
  border-color: var(--board-line);
}

.room-top__back:focus-visible,
.room-top__copy:focus-visible,
.room-top__end:focus-visible,
.follow-switch:focus-visible {
  outline: var(--focus-width) solid var(--board-focus);
  outline-offset: var(--focus-offset);
}

.room-top__name {
  overflow: hidden;
  flex: 1 1 auto;
  min-inline-size: var(--space-16);
  max-inline-size: var(--room-top-name);
  margin: 0;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.room-top__name > button {
  display: block;
  overflow: hidden;
  inline-size: 100%;
  min-block-size: var(--control-height-sm);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.room-top__name--full {
  max-inline-size: none;
}

.room-top__name--full > button {
  white-space: normal;
}

.room-top__live {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--space-1);
  font-weight: var(--weight-medium);
}

.room-top__live::before {
  inline-size: var(--space-2);
  block-size: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-success-mark);
  content: "";
}

/* On a phone the dot says Live, so the room's name keeps its room; screen readers still hear the word. */
@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .room-top__start {
    flex: 1 1 auto;
  }

  .room-top__name {
    min-inline-size: var(--space-8);
  }

  .room-top__live-word {
    position: absolute;
    overflow: hidden;
    inline-size: 1px;
    block-size: 1px;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

.room-top__time {
  flex: none;
  color: var(--board-text-muted);
  font-variant-numeric: tabular-nums;
}

/* In Geist with even-width figures, so the room page never downloads Geist Mono for six characters. Codes have no
   I, L, O, 0 or 1, so no two look alike in a sans face (the UI/UX session, 2026-11-13). */
.room-top__code {
  flex: none;
  padding-inline-start: var(--space-2);
  border-inline-start: var(--border-width) solid var(--board-line);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-code);
  text-transform: uppercase;
}

/* Ending the session is the room's most final action, so it wears the danger colour. */
.room-top__end {
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: var(--border-width) solid var(--board-danger);
  border-radius: var(--radius-full);
  background: none;
  color: var(--board-text);
  font: inherit;
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.room-top__end:hover {
  background: var(--board-danger);
}

.room-top__end:disabled {
  opacity: 0.55;
  cursor: progress;
}

/* The host's switch sits first in the stack at the top centre, and gives way to any status line there. */
.top-stack:has(> :not(.follow-slot)) > .follow-slot {
  display: none;
}

.follow-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}

.follow-switch[aria-pressed="true"] {
  border-color: var(--board-accent);
  background: var(--board-chosen);
}

.card-body > .follow-switch {
  inline-size: 100%;
  margin-block-end: var(--space-2);
}

/* Who's here, at the top right: initials ringed in each person's colour, hosts crowned. */
.room-top__people {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-1);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-full);
  background: none;
  color: var(--board-text);
  font: inherit;
  cursor: pointer;
}

.room-top__people:hover {
  border-color: var(--board-line);
}

.room-top__people:focus-visible {
  outline: var(--focus-width) solid var(--board-focus);
  outline-offset: var(--focus-offset);
}

.room-top__avatar {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: var(--control-height-sm);
  block-size: var(--control-height-sm);
  margin-inline-start: calc(var(--space-2) * -1);
  border: var(--focus-width) solid var(--board-line);
  border-radius: var(--radius-full);
  background: var(--board-glass-strong);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

.room-top__avatar:first-child {
  margin-inline-start: 0;
}

.room-top__crown {
  position: absolute;
  z-index: 1;
  inset-block-start: calc(var(--space-2) * -1);
  inset-inline-end: calc(var(--space-1) * -1);
  inline-size: var(--space-3);
  color: var(--board-accent);
}

.room-top__more {
  margin-inline-start: var(--space-1);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

/* The host's bar at the bottom centre (spec 0025 step 2): Add figure filled, each panel's button with its word and what's
   set on it, then Undo, Redo and the picture as icons. */
.room-bar {
  position: absolute;
  inset-block-end: var(--space-4);
  inset-inline-start: 50%;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-lg);
  transform: translateX(-50%);
}

.bar-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-inline-size: var(--control-height);
  block-size: var(--control-height);
  padding: 0 var(--space-3);
  border: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-control);
  background: none;
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
}

.room-bar .bar-icon {
  inline-size: var(--control-height);
  min-height: var(--control-height);
  padding: 0;
}

.bar-button:hover {
  border-color: var(--board-text-muted);
}

.bar-button:focus-visible {
  outline: var(--focus-width) solid var(--board-focus);
  outline-offset: var(--focus-offset);
}

.bar-tab[aria-pressed="true"] {
  border-color: var(--board-accent);
  background: var(--board-chosen);
}

/* Add figure is the one filled button; what's written on star blue is ink. */
.room-bar .bar-add {
  inline-size: auto;
  padding: 0 var(--space-3);
  border-color: var(--board-fill);
  background: var(--board-fill);
  color: var(--board-on-fill);
}

.room-bar .bar-add:hover {
  border-color: var(--board-fill-hover);
  background: var(--board-fill-hover);
}

/* A count sits beside its word on the bar (room.css places it on an icon's corner); that's part of the bar's width, so
   of when it turns to icons. */
.room-bar:not(.is-compact) .bar-badge {
  position: static;
}

.bar-rule {
  inline-size: var(--border-width);
  block-size: var(--space-6);
  margin-inline: var(--space-1);
  background: var(--board-line);
}

/* Where the bar with its words doesn't fit beside the panels, room-controls.js keeps the words for screen readers only
   (sr-only), so a button's name still starts with its word. */
.room-bar.is-compact .bar-button,
.room-bar.is-compact .bar-add {
  padding: 0;
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .room-bar {
    inset-block-end: 0;
    inset-inline: 0;
    justify-content: space-around;
    gap: 0;
    padding: var(--space-1) var(--space-2) calc(var(--space-1) + env(safe-area-inset-bottom));
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    transform: none;
  }

  .bar-rule {
    display: none;
  }

  /* Each button takes an equal share of the edge, at least a thumb's height. */
  .room-bar .bar-button {
    flex: 1 1 0;
    min-inline-size: 0;
    block-size: var(--control-height-lg);
  }

  /* A host's five named tabs (spec 0025 item 21): the word under the icon; Undo, Redo and the picture, icons only,
     step aside, Undo and Redo staying in the messages that offer them and the picture in the Room sheet. */
  .room-bar.is-tabs .bar-button {
    flex-direction: column;
    gap: var(--space-0-5);
    block-size: auto;
    min-block-size: var(--control-height-lg);
    padding-block: var(--space-1);
    font-size: var(--text-2xs);
    position: relative;
  }

  .room-bar.is-tabs .bar-icon {
    display: none;
  }

  .room-bar.is-tabs .bar-badge {
    position: absolute;
    inset-block-start: var(--space-0-5);
    inset-inline-end: 22%;
  }

  .panel-links .panel-picture {
    display: inline-flex;
  }
}

/* The picture is in the bar except on a phone. */
.panel-picture {
  display: none;
}

/* The Room panel's utility links, one under another (a stack) and alike, each as wide as its words (spec 0025 step 2b). */
.panel-links {
  align-items: flex-start;
}

/* The guide is a link and the others are buttons; the same box keeps the gaps between them equal. */
.panel-links > * {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--control-height-sm);
}

/* On the narrowest phones End session says just End, so the room's name keeps about ten characters. */
.room-top__end-short {
  display: none;
}

@media (max-width: 400px) {
  .room-top__end-short {
    display: inline;
  }

  .room-top__name {
    min-inline-size: calc(var(--space-16) + var(--space-6));
  }
}

/* The shelf of pieces (spec 0025 step 3): the sets as tabs, the pieces as they look, then the colour and an optional
   name for the next piece. */
.shelf {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  color: var(--board-text);
}

.shelf__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.shelf__sets {
  display: inline-flex;
  max-inline-size: 100%;
  overflow-x: auto;
  padding: var(--space-0-5);
  border: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-control);
}

.shelf__set {
  flex: none;
  white-space: nowrap;
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.shelf__set[aria-expanded="true"] {
  background: var(--board-chosen);
}

/* "Sets in this room": the sets a host turns on and off, in place of the pieces while it is open. */
.shelf__choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.shelf__choices legend {
  padding: 0;
  margin-block-end: var(--space-2);
}

.shelf__set[aria-pressed="true"] {
  background: var(--board-chosen);
  box-shadow: inset 0 0 0 var(--border-width) var(--board-accent);
  color: var(--board-accent);
}

.shelf__hint {
  flex: 1 1 auto;
  color: var(--board-text-muted);
  font-size: var(--text-sm);
}

.shelf__done,
.shelf__retry {
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-4);
  border: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-control);
  background: none;
  color: var(--board-text);
  font: inherit;
  font-weight: var(--weight-medium);
  cursor: pointer;
}

/* The room's sets couldn't be read: said on a line of its own under the tabs, with its way to try again. */
.shelf__unread {
  display: flex;
  flex-basis: 100%;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.shelf__retry:disabled {
  opacity: 0.55;
  cursor: progress;
}

.shelf__body {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4);
}

.shelf__pieces {
  display: flex;
  flex: 1 1 18rem;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.shelf__piece {
  display: grid;
  justify-items: center;
  gap: var(--space-1);
  inline-size: calc(var(--space-16) + var(--space-4));
  padding: var(--space-1);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-md);
  background: none;
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-xs);
  cursor: grab;
  /* A swipe scrolls the shelf; a held press drags the piece (Shelf.tsx). No text selection or long-press menu. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* The piece's picture is part of the press, never an image of its own to drag. */
.shelf__piece img {
  -webkit-user-drag: none;
  pointer-events: none;
}

/* A piece being dragged onto the board, under the pointer. Placed from the pointer's own x and y, so its origin is the
   physical top left in either direction. */
.shelf__ghost {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-toast);
  opacity: 0.92;
  pointer-events: none;
}

.shelf__piece:hover:not([aria-disabled="true"]) {
  border-color: var(--board-line);
}

.shelf__piece[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
}

.shelf__picture {
  display: flex;
  inline-size: var(--space-16);
  block-size: var(--space-16);
}

.shelf__locked {
  color: var(--board-text-muted);
  font-size: var(--text-2xs);
}

.shelf__side {
  display: grid;
  flex: 0 1 15rem;
  gap: var(--space-2);
  padding-inline-start: var(--space-4);
  border-inline-start: var(--border-width) solid var(--board-line);
}

.shelf__label {
  color: var(--board-text-muted);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.shelf__colours {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1-5);
}

.shelf__colour {
  inline-size: var(--space-6);
  block-size: var(--space-6);
  padding: 0;
  border: var(--focus-width) solid transparent;
  border-radius: var(--radius-full);
  cursor: pointer;
}

.shelf__colour[aria-pressed="true"] {
  outline: var(--focus-width) solid var(--board-text);
  outline-offset: var(--focus-offset);
}

.shelf__name {
  display: grid;
  gap: var(--space-1);
}

/* On the board's dark glass the field is dark too. */
.shelf__name .input {
  border-color: var(--board-line);
  background: color-mix(in srgb, var(--board-glass-strong) 60%, transparent);
  color: var(--board-text);
}


.shelf__note {
  margin: 0;
  color: var(--board-text-muted);
  font-size: var(--text-sm);
}

.shelf__note:empty {
  display: none;
}

.shelf__set:focus-visible,
.shelf__done:focus-visible,
.shelf__retry:focus-visible,
.shelf__piece:focus-visible,
.shelf__colour:focus-visible {
  outline: var(--focus-width) solid var(--board-focus);
  outline-offset: var(--focus-offset);
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .shelf__side {
    padding-inline-start: 0;
    border-inline-start: 0;
  }

  .shelf__piece {
    inline-size: var(--space-16);
  }

  .shelf__picture {
    inline-size: var(--space-12);
    block-size: calc(var(--space-12) + var(--space-2));
  }
}

/* The figure card's name and who sees it, at its top (spec 0025 step 5). */
/* The pill moves under the name when both won't fit, so the name field always shows its whole hint. */
.figure-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Two classes, so the room's older .input rule, loaded later, doesn't paint it white. */
.input.figure-card-rename {
  flex: 1 1 auto;
  min-inline-size: 12rem;
  border-color: var(--board-line);
  background: color-mix(in srgb, var(--board-glass-strong) 60%, transparent);
  color: var(--board-text);
}

.figure-card-vis {
  flex: none;
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-full);
  background: none;
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.figure-card-vis:focus-visible {
  outline: var(--focus-width) solid var(--board-focus);
  outline-offset: var(--focus-offset);
}

/* Its own pill, not a feeling's, so it never reads as one more choice. */
.choice-more {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-3);
  border: var(--border-width) dashed var(--board-line);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--board-text-muted);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.choice-more:hover {
  color: var(--board-text);
}


/* A room control whose change is saving: dimmed and held until the database answers. One that didn't save says so
   beside itself (the UI/UX session, 2026-11-12). */
.room-page [aria-busy="true"] {
  opacity: 0.55;
  cursor: progress;
}

.save-note {
  font-size: var(--text-xs);
  color: var(--board-danger-text);
}

/* In a person's row, the note has a line of its own under the name, so the row keeps its shape. */
.save-note--line {
  grid-column: 2 / -1;
}

/* A representative on a phone (spec 0025 item 23): the top line says who they represent, their figure's feelings are on
   screen, and seeing as it is the main button. Elsewhere the bar keeps its chips and icons (room.css). */
.rep-feelings,
.rep-see {
  display: none;
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .guest-page .rep-feelings {
    display: block;
    flex-basis: 100%;
  }

  .guest-page .rep-see {
    display: inline-flex;
    flex-basis: 100%;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-block-size: var(--control-height-lg);
    border: var(--border-width) solid var(--board-accent);
    border-radius: var(--radius-lg);
    background: var(--board-glass-strong);
    color: var(--board-text);
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
  }

  .guest-page .rep-see .icon {
    inline-size: 20px;
    block-size: 20px;
  }
}

/* On a touch screen every control in the room takes at least a finger's width (spec 0025 item 24), looking as it did:
   the hit area grows past the box, never the box itself. The room's name clips its words, so its
   button can't grow past its box. */
@media (pointer: coarse) {
  .room-top__back,
  .room-top__copy,
  .room-top__people,
  .room-top__end,
  .follow-switch,
  .room-bar .bar-button {
    position: relative;
    z-index: 1;
  }

  .room-top__back::before,
  .room-top__copy::before,
  .room-top__people::before,
  .room-top__end::before,
  .follow-switch::before,
  .room-bar .bar-button::before {
    content: "";
    position: absolute;
    inset: min(0px, calc((100% - var(--touch-target)) / 2));
  }
}
