/* The room's older buttons and fields, still used by its scripts and some of its React (spec 0025 step 8c moved them here
   from theme.css, which is gone). */
[hidden] {
  display: none !important;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-4);
  border: var(--border-width) solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}

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

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

.btn-quiet {
  border-color: var(--board-line);
  background: transparent;
  color: var(--board-text);
}

.btn-quiet:hover {
  border-color: var(--board-accent);
  background: var(--board-glass-faint);
  color: var(--board-text);
}

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


.input {
  width: 100%;
  min-height: var(--control-height);
  padding: 0 var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-md);
}

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

/* The controls that sit over the 3D board, shared by admin and guest. */
.room-page {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--board-scene);
  color: var(--board-text);
  /* Native checkboxes, selects and their lists draw dark, on the night glass. */
  color-scheme: dark;
  --control-height: var(--room-control-height);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.35;
}

.glass {
  border: 1px solid var(--board-line);
  background: var(--board-glass);
  box-shadow: var(--board-highlight);
  -webkit-backdrop-filter: var(--board-blur);
  backdrop-filter: var(--board-blur);
}

.room-page :focus-visible {
  outline: 2px solid var(--board-focus);
  outline-offset: 2px;
}

.panel-heading {
  color: var(--board-text-muted);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.icon {
  flex: none;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-3);
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-control);
  background: var(--board-sunk);
  color: var(--board-text);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: background-color var(--duration-fast) ease, border-color var(--duration-fast) ease;
}

.tool:hover {
  background: var(--board-press);
}

.tool:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.tool[aria-pressed="true"],
.view-fold[aria-expanded="true"] {
  border-color: var(--board-accent);
  background: var(--board-chosen);
  color: var(--board-accent);
}

.tool-square {
  width: 44px;
  padding: 0;
}

/* The shelf of pieces (spec 0025 step 3) opens above the bar at the bottom centre; its content is the room's React's. */
.tray {
  position: absolute;
  inset-inline: var(--room-tools-reach);
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 5;
  max-inline-size: 46rem;
  margin-inline: auto;
  max-height: calc(100% - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--radius-xl);
  transition: width var(--duration-base) ease;
}

.tray.is-collapsed {
  display: none;
}

.room-toast {
  position: absolute;
  left: 50%;
  top: max(16px, env(safe-area-inset-top));
  z-index: var(--z-toast);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-width: calc(100vw - 32px);
  transform: translateX(-50%);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-control);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

.room-toast > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.toast-action {
  flex: none;
  min-height: 28px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--board-accent);
  font: inherit;
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.toast-action:hover {
  text-decoration: underline;
}

@media (min-width: 721px) {
  .admin-page:not(.panel-closed) .room-toast {
    left: calc(50% - 220px);
    max-width: calc(100vw - 472px);
  }
}

/* A column of square tools on a glass panel: the view tools on the right and the left-hand tools share it. */
.tool-group {
  position: absolute;
  bottom: max(16px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-1-5);
  border-radius: var(--radius-lg);
}

.tool-icon {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
}

/* Zoom controls, bottom right on every screen. */
.view-tools {
  inset-inline-end: 16px;
}

/* Names floating above figures. */
.tag {
  position: absolute;
  transform: translate(-50%, -100%);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-75) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--board-glass-strong);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  pointer-events: none;
}

.tag-hidden {
  border: 1px dashed var(--board-line-bright);
  background: var(--board-glass-label);
  color: var(--board-text-muted);
  font-weight: var(--weight-medium);
}

.tag .icon {
  width: 13px;
  height: 13px;
}

.board-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* What's set on a bar button: how many, or a dot for something unread. */
.bar-badge {
  position: absolute;
  top: 1px;
  inset-inline-end: 1px;
  min-inline-size: 16px;
  block-size: 16px;
  padding: 0 var(--room-badge-pad);
  border-radius: var(--radius-full);
  background: var(--board-fill);
  color: var(--board-on-fill);
  font-size: var(--room-badge-text);
  font-weight: var(--weight-semibold);
  line-height: 16px;
  text-align: center;
}

.admin-panel {
  position: absolute;
  top: var(--room-top-space);
  inset-inline-end: 84px;
  bottom: 16px;
  display: flex;
  flex-direction: column;
  width: 340px;
  overflow: hidden;
  border-radius: var(--radius-xl);
}

.admin-panel-head {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2);
  border-bottom: 1px solid var(--board-line);
}

.admin-panel-head .tool-square {
  flex: none;
  width: 30px;
  min-height: 30px;
  height: 30px;
  padding: 0;
}

.admin-panel.is-collapsed {
  display: none;
}

.admin-panel-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* A second panel (spec 0013): docked, the two share the column by the rail under the room's row, the first above and
   the second below, 8px apart. */
.admin-panel-second {
  z-index: 1;
}

.admin-panel.is-top {
  bottom: calc(50% - var(--room-top-space) / 2 + 12px);
}

.admin-panel-second.is-bottom {
  top: calc(50% + var(--room-top-space) / 2 - 4px);
}

/* A folded panel is just its header, so the other takes the rest of the column. */
.top-folded .admin-panel-second.is-bottom {
  top: calc(var(--room-top-space) + 60px);
}

.bottom-folded .admin-panel.is-top {
  bottom: 76px;
}

.bottom-folded .admin-panel-second.is-bottom {
  top: auto;
  bottom: 16px;
}

.panel-title {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding-inline-start: var(--space-1-5);
  overflow: hidden;
  color: var(--board-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A panel's header already names it, so its first heading isn't repeated (its controls stay). */
.admin-panel .panel-pane > .panel-section:first-child > .section-head > .panel-heading:not(:has(label)) {
  visibility: hidden;
}

/* With no control but a link, that row takes no room of its own: the link sits at the end of the line below. */
.admin-panel .panel-pane > .panel-section:first-child > .section-head:has(> .panel-heading):not(:has(label)) {
  float: inline-end;
  margin: 0;
  margin-inline-start: var(--space-2);
}

.admin-panel .panel-pane > .panel-section:first-child > .section-head:has(> .panel-heading):not(:has(label)) > .panel-heading {
  display: none;
}

.admin-panel .panel-pane > .panel-section:first-child > .section-head:has(> .panel-heading):not(:has(label)) > .link-button {
  margin-block: calc((var(--text-xs) * 1.5 - var(--space-8)) / 2);
}

/* Dragged by its header to float over the board, or folded down to its header. */
.panel-drag {
  cursor: grab;
  touch-action: none;
}

.panel-drag button,
.panel-drag a,
.panel-drag input {
  cursor: pointer;
}

.admin-panel.is-floating {
  inset-inline-end: auto;
  bottom: auto;
  z-index: 2;
  height: min(70vh, 560px);
  min-width: 280px;
  min-height: 160px;
  max-width: calc(100vw - 16px);
  max-height: calc(100vh - 16px);
  resize: both;
  box-shadow: var(--board-shadow);
}

.admin-panel.is-floating.is-folded {
  height: auto;
  min-height: 0;
  resize: none;
}

.admin-panel.is-dragging {
  cursor: grabbing;
  user-select: none;
}

.admin-panel.is-folded {
  bottom: auto;
  height: auto;
}

.admin-panel.is-folded .admin-panel-body {
  display: none;
}

.panel-fold .icon {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.panel-section {
  padding: var(--space-4);
  border-bottom: 1px solid var(--board-line);
}

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.link-button {
  min-height: 32px;
  padding: 0 var(--space-1);
  border: 0;
  background: none;
  text-decoration: none;
  color: var(--board-accent);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

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

.row {
  display: grid;
  align-items: center;
  gap: var(--space-2);
  border-radius: var(--radius-control);
}

.person-row {
  grid-template-columns: 14px 1fr auto;
  padding: var(--space-0-5) 0;
}

.figure-row {
  grid-template-columns: 26px 1fr 44px;
  padding: var(--space-0-75) var(--space-1-5);
  margin: 0 calc(var(--space-1-5) * -1);
}

.swatch {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

.figure-swatch {
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  cursor: pointer;
}

.name-input {
  width: 100%;
  min-width: 0;
  min-height: 40px;
  padding: 0 var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--board-text);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
}

@media (min-width: 721px) {
  .name-input {
    font-size: var(--text-base);
  }
}

.name-input::placeholder {
  color: var(--board-text-faint);
  font-weight: var(--weight-regular);
}

.name-input:hover {
  background: var(--board-sunk);
}

.name-input:focus {
  border-color: var(--board-accent);
  background: var(--board-hover);
  outline: none;
}

.panel-add {
  width: 100%;
  margin-bottom: var(--space-2);
}

.person-permissions {
  display: flex;
  gap: 2px;
}

.everyone-label {
  padding-inline-start: var(--space-2);
  color: var(--board-text-muted);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
}

.everyone-row {
  margin-bottom: var(--space-1);
  padding-bottom: var(--space-1-5);
  border-bottom: 1px solid var(--board-line);
  border-radius: 0;
}

.permission-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--board-text-faint);
  cursor: pointer;
}

.permission-toggle .icon {
  width: 16px;
  height: 16px;
}

.permission-toggle:hover {
  background: var(--board-hover);
}

.permission-toggle[aria-pressed="true"] {
  color: var(--board-accent);
}

/* Off isn't only a colour change, so it's clear without colour vision. */
.permission-toggle[aria-pressed="false"]::after {
  content: "";
  position: absolute;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transform: rotate(-45deg);
}

@media (pointer: coarse) {
  .permission-toggle {
    width: 40px;
    height: 40px;
  }
}

.row-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--board-text-muted);
  cursor: pointer;
}

.row-toggle:hover {
  background: var(--board-hover);
  color: var(--board-text);
}

.row-toggle[aria-pressed="true"] {
  color: var(--board-accent);
}

/* Guest screen. */
.guest-people {
  position: absolute;
  top: max(16px, env(safe-area-inset-top));
  right: 16px;
  min-width: 170px;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
}

.guest-people ul {
  display: grid;
  gap: var(--space-1-5);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
}

.guest-people li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.you {
  color: var(--board-text-muted);
  font-weight: var(--weight-regular);
}

.guest-bar {
  position: absolute;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1-5);
  border-radius: var(--radius-lg);
}

.notice {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-3);
  color: var(--board-accent);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .admin-panel {
    top: auto;
    inset-inline: 0;
    bottom: calc(54px + env(safe-area-inset-bottom));
    width: auto;
    max-height: 62dvh;
    border-width: 1px 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  }

  /* A sheet opens at about half the screen, its top edge just under the board's centre, and its handle drags it up
     to the full height above (David, 2026-11-15). The pull is the drag so far, from room-controls.js. */
  .admin-panel.is-half {
    max-height: min(62dvh, calc(46dvh - 54px - env(safe-area-inset-bottom) + var(--sheet-pull, 0px)));
  }

  .admin-page .view-tools {
    top: max(16px, env(safe-area-inset-top));
    right: 12px;
    bottom: auto;
  }

  .guest-page .view-tools {
    top: max(16px, env(safe-area-inset-top));
    right: 12px;
    bottom: auto;
  }

  .guest-people {
    top: max(16px, env(safe-area-inset-top));
    left: 12px;
    right: auto;
    min-width: 0;
  }

  .guest-bar {
    left: auto;
    right: 12px;
    transform: none;
    max-width: calc(100vw - 24px);
  }

  .tray:not(.is-collapsed) {
    inset-inline: 0;
    bottom: 0;
    max-inline-size: none;
    max-height: 72dvh;
    border-width: 1px 0 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .admin-page:not(.panel-closed) .view-tools,
  .admin-page:not(.panel-closed) .top-stack {
    display: none;
  }

  .notice {
    white-space: normal;
  }
}

.figure-row .figure-icon {
  display: grid;
  place-items: center;
  width: 26px;
  height: 32px;
}

.figure-icon svg {
  width: 24px;
  height: 30px;
}

.figure-row {
  grid-template-columns: 26px 1fr auto;
}

.visibility {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 32px;
  min-height: 32px;
  padding: 0;
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--board-text-muted);
  font-family: var(--font-sans);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.visibility:hover {
  background: var(--board-hover);
}

.visibility[data-state="all"] {
  border-color: var(--board-accent);
  color: var(--board-accent);
}

.visibility[data-state="none"] {
  color: var(--board-text-faint);
}

.panel-empty {
  color: var(--board-text-muted);
  font-size: var(--text-sm);
}

.room-notice {
  position: absolute;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: calc(100vw - 180px);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  color: var(--board-accent);
  font-weight: var(--weight-medium);
}

/* With the host's panel open beside the board, the notice sits centred between the tools on one side (80px) and the
   panel and its rail on the other (440px), not under either. Narrower windows keep it centred over everything. */
@media (min-width: 960px) {
  .admin-page:not(.panel-closed) .room-notice:not(.room-notice-top) {
    left: auto;
    inset-inline-start: 80px;
    inset-inline-end: 440px;
    inline-size: fit-content;
    max-inline-size: none;
    margin-inline: auto;
    transform: none;
  }
}

.room-notice-top {
  top: 0;
  right: 0;
  bottom: auto;
  left: 0;
  z-index: 6;
  transform: none;
  justify-content: center;
  max-width: none;
  padding: calc(env(safe-area-inset-top) + var(--space-2)) var(--space-4) var(--space-2);
  border-width: 0 0 1px;
  border-radius: 0;
}

/* A message instead of the board, such as waiting for the facilitator or a session that ended: a card over the room's
   world, so it still feels like the room rather than an error page. */
.room-message {
  position: absolute;
  inset: 0;
  z-index: 9;
  display: grid;
  place-items: center;
  padding: var(--space-6);
  background: radial-gradient(ellipse at center, color-mix(in srgb, var(--night-950) 30%, transparent) 0%, color-mix(in srgb, var(--night-950) 88%, transparent) 75%),
    var(--world-backdrop, url("worlds/relief/nebula-half.jpg")) center / cover no-repeat,
    var(--board-scene);
  text-align: center;
}

.room-message-card {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  inline-size: min(28rem, 100%);
  padding: var(--space-8) var(--space-6);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
}

.room-message h1 {
  margin: 0;
  color: var(--board-text);
  font-family: var(--font-sans);
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
}

.room-message p {
  max-width: 24rem;
  margin: 0;
  color: var(--board-text-muted);
  font-size: var(--text-md);
  line-height: 1.5;
}

.room-message-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
}

/* While waiting, a slow ring keeps breathing out from a point, so the page reads as listening, not stuck. */
.room-message-ring {
  position: relative;
  inline-size: 56px;
  block-size: 56px;
  margin-block-end: var(--space-2);
  border-radius: 50%;
  background: radial-gradient(circle, var(--board-accent) 0 5px, transparent 6px);
}

.room-message-ring::before,
.room-message-ring::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--board-accent);
  border-radius: 50%;
  animation: room-message-breathe var(--duration-message-breathe) ease-out infinite;
}

.room-message-ring::after {
  animation-delay: calc(var(--duration-message-breathe) / 2);
}

@keyframes room-message-breathe {
  from {
    opacity: 0.9;
    transform: scale(0.35);
  }
  to {
    opacity: 0;
    transform: scale(1.4);
  }
}

/* Still, for anyone who asked for less motion (the room's setting, which follows the device unless they chose): one
   quiet ring. */
.reduce-motion .room-message-ring::before,
.reduce-motion .room-message-ring::after {
  animation: none;
  opacity: 0.5;
  transform: none;
}

/* Only exists on this Mac. */
.dev-console {
  position: absolute;
  top: 10px;
  left: 50%;
  z-index: 8;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
  padding: var(--space-1) var(--space-1-5) var(--space-1) var(--space-3);
  border: 1px dashed var(--board-accent);
  border-radius: var(--radius-control);
  background: var(--board-glass-strong);
  color: var(--board-accent);
  font-family: var(--font-sans);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.dev-console button {
  min-height: 30px;
  padding: 0 var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--board-text-muted);
  font: inherit;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}

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

.size-value {
  font-weight: var(--weight-semibold);
}

.size-slider {
  display: block;
  width: 100%;
  height: 32px;
  margin: 0;
  accent-color: var(--board-accent);
  cursor: pointer;
}

/* Options replaces the panel's lists while it's open. The panel's body scrolls it, as it does every pane; a scroller of
   its own here kept the wheel from reaching the body once panels stacked. */
.options-pane {
  flex: 1;
  min-height: 0;
}

.admin-panel.is-collapsed .options-pane {
  display: none;
}

.theme-list {
  display: grid;
  gap: var(--space-2);
}

.theme-choice {
  position: relative;
  display: flex;
  align-items: flex-end;
  width: 100%;
  /* The same shape as the clip, so it shows a real piece of the art and never squashes it. */
  aspect-ratio: 4 / 1;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-control);
  background-position: center;
  background-size: cover;
  color: var(--board-text);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  text-align: left;
  cursor: pointer;
}

/* Night rising from the tile's foot, so its name reads on any picture. */
.theme-choice::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--board-picture-shade);
}

.theme-choice span {
  position: relative;
  width: 100%;
  padding: var(--space-4) var(--space-3) var(--space-2);
  text-shadow: var(--board-picture-text-shadow);
}

.theme-choice:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.theme-choice:hover {
  border-color: var(--board-line-bright);
}

.theme-choice[aria-pressed="true"] {
  border-color: var(--board-accent);
  box-shadow: 0 0 0 1px var(--board-accent);
}

.option-check {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--board-text);
  cursor: pointer;
}

/* At least 24px, as every target is (WCAG 2.5.8), and easier for older hands. */
.option-check input {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  accent-color: var(--board-accent);
}

/* An empty box's own edge barely shows on a panel (WCAG 1.4.11). */
.option-check input:not(:checked) {
  appearance: none;
  border: 1px solid var(--board-line-bright);
  border-radius: var(--radius-xs);
  background: transparent;
}

#people:not([hidden]) {
  margin-top: var(--space-1);
}

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--board-text-muted);
  cursor: pointer;
}

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

@media (pointer: coarse) {
  .admin-panel-head .tool-square {
    width: 36px;
    min-height: 36px;
    height: 36px;
  }
}

.figure-icon {
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  cursor: pointer;
}

.figure-icon:hover {
  background: var(--board-press);
}

.figure-row.is-pointed-out {
  background: var(--board-chosen);
  box-shadow: inset 0 0 0 1px var(--board-accent);
}

#clear-selected {
  flex: none;
  white-space: nowrap;
}

.person-row {
  grid-template-columns: 14px 1fr auto;
}

/* Another host in the room: their name and role, and for the room's owner a way to remove a co-host. */
.host-row {
  grid-template-columns: 14px minmax(0, 1fr) auto auto;
  column-gap: var(--space-2);
  min-height: 36px;
}

.host-name {
  overflow: hidden;
  color: var(--board-text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cohost-remove.is-armed {
  padding: 0 var(--space-2);
  border-radius: var(--radius-md);
  background: var(--board-danger);
  color: var(--board-text);
}

.person-row .swatch {
  justify-self: center;
  width: 8px;
  height: 8px;
}

/* Each world's backdrop behind the shelf and the waiting screens, and the sky its board clears to. Every world wears
   the same night glass (spec 0025 item 25, 2026-11-13). See docs/THEMES.md. */
/* Before a room's world is known, the join and waiting screens wear the default, Navy Relief (to-do 10d). */
.room-page:not([data-theme]) {
  --board-scene: var(--scene-relief);
}

.room-page[data-theme="forest"] {
  --world-backdrop: url("worlds/forest/nebula-half.jpg");
  --board-scene: var(--scene-forest);
}

.room-page[data-theme="aurora"] {
  --world-backdrop: url("worlds/aurora/nebula-half.jpg");
  --board-scene: var(--scene-aurora);
}

.room-page[data-theme="universe"] {
  --world-backdrop: url("worlds/universe/nebula-half.jpg");
  --board-scene: var(--scene-universe);
}

.room-page[data-theme="relief"] {
  --world-backdrop: url("worlds/relief/nebula-half.jpg");
  --board-scene: var(--scene-relief);
}

.room-page[data-theme="sea"] {
  --world-backdrop: url("worlds/sea/nebula-half.jpg");
  --board-scene: var(--scene-sea);
}

.room-page[data-theme="autumn"] {
  --world-backdrop: url("worlds/autumn/nebula-half.jpg");
  --board-scene: var(--scene-autumn);
}

.room-page[data-theme="study"] {
  --world-backdrop: url("worlds/study/nebula-half.jpg");
  --board-scene: var(--scene-study);
}

/* The loading screen (to-do 4s): over the board, its controls and any message until the room's world is drawn, so
   the page hides it when it shows a message (showMessage in room-start.js). */
#loading {
  position: absolute;
  inset: 0;
  /* Over the room's controls, which arrive while the world is still being set out. */
  z-index: var(--z-nav);
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--board-scene);
  color: var(--board-text);
  font: var(--text-base)/1.4 var(--font-sans);
  text-align: center;
  transition: opacity var(--duration-view-cut) ease;
}

#loading.is-done {
  opacity: 0;
  pointer-events: none;
}

/* Wider than the screen, so the blur has no pale edge. */
.room-loader-art {
  position: absolute;
  inset: calc(var(--space-6) * -1);
  background: center / cover no-repeat;
  filter: blur(14px) brightness(0.55);
  opacity: 0;
  transition: opacity var(--duration-slow) ease;
}

.room-loader-art.is-shown {
  opacity: 1;
}

.room-loader-shade {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, transparent 0%, color-mix(in srgb, var(--night-950) 70%, transparent) 80%);
}

.room-loader-body {
  position: relative;
  width: min(420px, 100% - 2rem);
}

.room-loader-lead {
  margin: 0;
  color: var(--board-text-muted);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
}

.room-loader-world {
  min-height: 1.3em;
  margin: var(--space-3) 0 0;
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1.3;
}

.room-loader-track {
  width: min(300px, 100%);
  height: 4px;
  margin: var(--space-5) auto var(--space-4);
  border-radius: var(--radius-full);
  background: var(--board-line);
}

#bar {
  width: 0;
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--board-fill);
  box-shadow: var(--board-bar-glow);
}

.room-loader-percent {
  margin: 0;
  font-size: var(--text-3xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1;
}

.room-loader-percent small {
  margin-left: 2px;
  color: var(--board-text-muted);
  font-size: var(--text-xl);
  font-weight: 500;
}

.room-loader-step {
  min-height: 1.4em;
  margin: var(--space-3) 0 0;
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
}

.room-loader-marks {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
  color: var(--board-text-faint);
  font-size: var(--text-sm);
}

.room-loader-marks li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.room-loader-marks li::before {
  content: "";
  display: inline-grid;
  place-items: center;
  box-sizing: border-box;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--board-line-strong);
  border-radius: var(--radius-full);
  font-size: var(--text-2xs);
  line-height: 1;
}

.room-loader-marks .is-done {
  color: var(--board-text-muted);
}

.room-loader-marks .is-done::before {
  content: "\2713";
  border-color: var(--board-fill);
  background: var(--board-fill);
  color: var(--board-on-fill);
}

.room-loader-marks .is-now {
  color: var(--board-text);
}

.room-loader-marks .is-now::before {
  border-color: var(--board-fill);
  box-shadow: var(--board-step-ring);
}

/* Its line is kept while it's hidden, so nothing moves when it appears. */
.room-loader-slow {
  visibility: hidden;
  margin: var(--space-4) 0 0;
  color: var(--board-text-faint);
  font-size: var(--text-sm);
}

.room-loader-slow.is-shown {
  visibility: visible;
}

.person-remove {
  flex: none;
  padding: 0 var(--space-1);
  border: 0;
  background: none;
  color: inherit;
  opacity: 0.75;
  cursor: pointer;
}

.person-remove:hover {
  opacity: 1;
}

/* Everyone who could represent a figure, as choices like the gestures'. */
.rep-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* What's set, in one line at the top of the People and Figures flyouts. */
.pane-summary {
  margin: 0 0 var(--space-3);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
  line-height: 1.5;
}

/* Representatives on or off for the room, who chooses them, and the chosen guest's card. */
.reps-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.reps-chooser-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

.choose-list {
  display: grid;
  gap: var(--space-2);
  max-height: min(50vh, 420px);
  overflow-y: auto;
}

.choose-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

/* Chat (spec 0011), the same list and box in a host's flyout and a guest's panel. A small line with the writer, a
   crown for facilitators, a lock and who sees it for private messages, and the time, over a run of their messages. */
.chat-view {
  display: grid;
  gap: var(--space-3);
}

.chat-list {
  display: grid;
  align-content: start;
  gap: 2px;
  min-height: 120px;
  max-height: min(52vh, 460px);
  margin-inline: calc(var(--space-2) * -1);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.chat-empty,
.chat-note {
  margin: 0;
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

.chat-empty {
  padding: var(--space-4) var(--space-2);
  text-align: center;
}

.chat-message {
  position: relative;
  padding: 2px var(--space-2);
  border-inline-start: 2px solid transparent;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--board-text);
  font-size: var(--text-sm);
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.chat-message:not(.is-continued) {
  margin-block-start: var(--space-2);
}

.chat-message:hover {
  background: var(--board-sunk);
}

/* Private: a thin edge, rather than a box, so it reads as the same conversation. */
.chat-message.is-private {
  border-inline-start-color: var(--board-accent);
}

.chat-message.is-removed {
  color: var(--board-text-muted);
  font-size: var(--text-xs);
  font-style: italic;
}

.chat-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--space-2);
  margin-block-end: 1px;
  padding-inline-end: calc(var(--space-6) + var(--space-0-5));
  font-size: var(--text-xs);
}

.chat-name {
  font-weight: var(--weight-semibold);
}

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

.chat-text {
  white-space: pre-wrap;
}

/* The remove button, on the message under the pointer or in focus, and always on touch screens. */
.chat-remove {
  position: absolute;
  top: 2px;
  inset-inline-end: 2px;
  display: none;
  inline-size: 24px;
  block-size: 24px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--board-glass-strong);
  color: var(--board-text-muted);
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

.chat-message:hover .chat-remove,
.chat-message:focus-within .chat-remove {
  display: block;
}

.chat-remove:hover {
  color: var(--board-text);
}

@media (pointer: coarse) {
  .chat-remove {
    display: block;
  }
}

.crown {
  inline-size: 13px;
  block-size: 10px;
  margin-inline-end: var(--space-1);
  fill: currentColor;
  vertical-align: baseline;
}

/* A co-host's crown: the same shape, as an outline. */
.crown.is-outline,
.person-mark svg.is-outline {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linejoin: round;
}

.role-mark {
  display: inline-flex;
  align-items: center;
}

/* The crown comes from the room's React wrapped in this, which mustn't change the layout (spec 0020). */
.role-mark-icon {
  display: contents;
}

.role-mark .crown {
  inline-size: 11px;
  block-size: 9px;
  margin-inline-end: var(--space-0-75);
}

.chat-private-mark {
  color: var(--board-text-muted);
}

.chat-private-mark .icon {
  inline-size: 11px;
  block-size: 11px;
  margin-inline-end: var(--space-0-75);
  vertical-align: -1px;
}

/* Who it goes to, as a quiet line above the box, and the box with its send button inside. */
.chat-form {
  display: grid;
  gap: var(--space-1);
}

.chat-to-row {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

.chat-to {
  min-height: 26px;
  padding: 0 var(--space-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--board-text);
  font: inherit;
  font-weight: var(--weight-semibold);
  cursor: pointer;
}

.chat-to:hover,
.chat-to:focus-visible {
  background: var(--board-hover);
}

.chat-box {
  position: relative;
}

.chat-input {
  display: block;
  inline-size: 100%;
  min-height: 42px;
  max-height: 120px;
  padding: calc(var(--space-2) + var(--space-0-5)) calc(var(--space-10) + var(--space-1-5)) calc(var(--space-2) + var(--space-0-5)) var(--space-3);
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-control);
  background: var(--board-sunk);
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-sm);
  line-height: 1.45;
  resize: none;
}

.chat-input:focus {
  border-color: var(--board-accent);
  outline: none;
}

.chat-input:focus-visible {
  box-shadow: 0 0 0 2px var(--board-focus);
}

.chat-send {
  position: absolute;
  inset-inline-end: 5px;
  bottom: 5px;
  display: grid;
  place-items: center;
  inline-size: 32px;
  block-size: 32px;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--board-fill);
  color: var(--board-on-fill);
  cursor: pointer;
}

.chat-send:hover {
  background: var(--board-fill-hover);
}

.chat-send .icon {
  inline-size: 16px;
  block-size: 16px;
}

.chat-button {
  position: relative;
}

.chat-button .icon {
  width: 20px;
  height: 20px;
}

.chat-count {
  position: absolute;
  top: 0;
  inset-inline-end: 0;
  min-inline-size: 18px;
  block-size: 18px;
  padding: 0 var(--room-badge-pad);
  border-radius: var(--radius-full);
  background: var(--board-fill);
  color: var(--board-on-fill);
  font-size: var(--room-count-text);
  font-weight: var(--weight-semibold);
  line-height: 18px;
  text-align: center;
}

/* In a host's flyout the chat fills the height, its box at the bottom, as a messaging app's does. */
.chat-pane:not([hidden]) {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.chat-pane .panel-section {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.chat-pane .chat-slot {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.chat-pane .chat-view {
  flex: 1;
  grid-template-rows: 1fr auto auto;
  min-height: 0;
}

.chat-pane .chat-list {
  max-height: none;
  min-height: 0;
}

.chat-panel,
.settings-panel {
  position: absolute;
  inset-inline-start: 84px;
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 7;
  display: grid;
  gap: var(--space-3);
  inline-size: min(380px, calc(100vw - 100px));
  padding: var(--space-3) var(--space-4) var(--space-4);
  border-radius: var(--radius-lg);
  color: var(--board-text);
}

.chat-panel .feeling-card-head,
.settings-panel .feeling-card-head {
  padding-block-end: var(--space-2);
  border-block-end: 1px solid var(--board-line);
}

.figure-details {
  position: fixed;
  z-index: 60;
  display: grid;
  /* Its column is the card's width, so no wide piece, such as a long word in Geist, can push the card's edge out. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2);
  width: 260px;
  max-height: calc(100dvh - 16px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  padding: var(--space-3);
  border-radius: var(--radius-control);
  color: var(--board-text);
  background: var(--board-glass-strong);
  font-size: var(--text-base);
}

/* The name takes whatever the row has left, up to the marks, which take only what they need. */
.figure-row {
  grid-template-columns: 26px minmax(0, 1fr) auto 32px;
  column-gap: var(--space-1-5);
}

/* What's set on a figure, as small marks beside its name: lying down, who represents it, how many lines. */
.figure-marks {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.figure-mark {
  display: inline-grid;
  place-items: center;
  min-inline-size: 18px;
  block-size: 18px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-full);
  background: var(--board-hover);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
}

.figure-mark svg {
  inline-size: 12px;
  block-size: 12px;
  fill: currentColor;
}

.rep-mark {
  background: var(--board-chosen);
  color: var(--board-text);
}

/* Words for screen readers and tests that sit behind an icon. */
.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.figure-card-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--board-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: grab;
  touch-action: none;
}

.figure-card-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-fold {
  display: grid;
  flex: none;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--board-text-muted);
  cursor: pointer;
}

.card-fold:hover {
  background: var(--board-hover);
  color: var(--board-text);
}

.card-fold .icon {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.figure-details.is-folded > :not(.figure-card-title) {
  display: none;
}

.figure-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
}

.figure-card-actions .link-button {
  padding: 0;
}

/* Each part of a figure's card under its own thin rule, so a long card still reads as sections. */
/* What's inside a card is drawn by the room's React into this, which mustn't change the card's layout (spec 0020). */
.card-body {
  display: contents;
}

.figure-details > .card-body > .figure-detail-label {
  padding-block-start: var(--space-2);
  border-block-start: 1px solid var(--board-line);
}

.figure-lay {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.figure-lay svg {
  inline-size: 18px;
  block-size: 18px;
  fill: currentColor;
}

.figure-detail-label {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-0-75);
}

.figure-tie,
.rep-moves,
.line-kind,
.line-to,
.show-who,
.show-look,
.face-pick,
.feel-who,
.see-as select,
.chat-mode,
.chat-to,
.reps-chooser,
.choose-person {
  max-width: 100%;
  padding: var(--space-1);
  color: inherit;
  background: var(--board-sunk);
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-sm);
}

/* A figure's lines in its menu: each one with a way to remove it, then a row to add another. */
.figure-lines {
  display: grid;
  gap: var(--space-1);
}

.figure-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  color: var(--board-text);
}

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

.saved-state {
  font-size: var(--text-base);
}

#template-name {
  width: 100%;
}

.person-row {
  grid-template-columns: 14px minmax(0, 1fr) auto auto;
}

.person-remove {
  min-width: 32px;
  min-height: 32px;
  border-radius: var(--radius-md);
  font-size: var(--text-md);
}

.person-remove.is-armed {
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--board-text);
  background: var(--board-danger);
}

.let-back {
  display: block;
  margin-block: var(--space-1) 0;
  margin-inline: var(--space-6) 0;
}

.visibility-menu {
  width: 240px;
  gap: var(--space-1);
  padding: var(--space-1-5);
}

.visibility-choice {
  display: grid;
  gap: var(--space-0-5);
  padding: var(--space-2) var(--space-2);
  border: 0;
  border-radius: var(--radius-md);
  text-align: left;
  color: inherit;
  background: transparent;
  cursor: pointer;
}

.visibility-choice span {
  font-size: var(--text-xs);
  opacity: 0.75;
}

.visibility-choice:hover,
.visibility-choice:focus-visible,
.visibility-choice[aria-checked="true"] {
  background: var(--board-hover);
}

/* Its own layer, so no label, however it's raised among the others, comes up over a panel or a sheet. */
.board-overlay {
  position: absolute;
  z-index: 0;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

/* One figure's actions, floating just above it. */
.figure-bar {
  position: absolute;
  inset-block: 0 auto;
  inset-inline-start: 0;
  flex-direction: row;
  font-size: var(--text-lg);
  animation: figure-bar-in var(--duration-fast) ease-out;
}

.figure-bar svg {
  inline-size: 20px;
  block-size: 20px;
}

.figure-bar .bar-feel path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linejoin: round;
}

.figure-bar .bar-lay svg {
  fill: currentColor;
}

/* Text size from the Accessibility settings (spec 0014): everything sized in rem grows with it. */
html[data-text="large"] {
  font-size: 112.5%;
}

html[data-text="larger"] {
  font-size: 125%;
}

/* Reduce motion chosen in the settings: nothing animates or slides, it just changes. */
.reduce-motion *,
.reduce-motion *::before,
.reduce-motion *::after {
  animation-duration: var(--duration-instant) !important;
  animation-iteration-count: 1 !important;
  transition-duration: var(--duration-instant) !important;
  scroll-behavior: auto !important;
}

/* Accessibility settings (spec 0014 step 2), in a host's Options and a guest's card. */
.settings-list {
  display: grid;
  gap: var(--space-3);
}

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

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

.settings-panel {
  inline-size: min(320px, calc(100vw - 100px));
}

/* The board as a list (spec 0015): wider than the settings, and scrolling within the screen. */
.settings-panel.board-list {
  inline-size: min(440px, calc(100vw - 100px));
  max-block-size: calc(100vh - 32px);
  grid-template-rows: auto minmax(0, 1fr);
}

.board-list-body {
  display: grid;
  gap: var(--space-3);
  overflow-y: auto;
  outline: none;
}

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

.board-list-items {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.board-list-row {
  display: grid;
  gap: var(--space-1);
  padding-block: var(--space-2);
  border-block-start: 1px solid var(--board-line);
}

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

.board-list-open {
  justify-self: start;
}

/* The two choosers sit in a row of chips, at their size and weight. */
.board-list-pick .chat-to {
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
}

/* High contrast: solid panels and tags, and edges that show. */
.high-contrast .glass {
  border-color: var(--board-line-bright);
  background: var(--board-glass-strong);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.high-contrast .board-tag,
.high-contrast .board-tag.is-faint {
  background: var(--board-glass-label);
  outline: 1px solid var(--board-line-bright);
}

.high-contrast :is(.tool, .bar-button, .feeling-choice, .gesture-choice, .rep-choice, .feeling-strength, .setting-choice, .chat-to):not(.bar-add):not([aria-pressed="true"]) {
  border-color: var(--board-line-bright);
  color: var(--board-text);
}

.high-contrast :is(.tool, .bar-button, .feeling-choice, .gesture-choice, .rep-choice, .feeling-strength, .setting-choice, .chat-to)[aria-pressed="true"]:not(.bar-add) {
  border-color: var(--board-accent);
  color: var(--board-accent);
}

/* Simple view, for a guest: the board, their own figure, the chat and these settings, and nothing else. */
.simple-view.is-guest #view,
.simple-view.is-guest #tray-toggle,
.simple-view.is-guest #shot,
.simple-view.is-guest .people-list {
  display: none;
}

/* An icon button's name, shown on keyboard focus or a long press (spec 0014 step 1.4). Placed from the page. */
.control-tip {
  position: fixed;
  z-index: var(--z-toast);
  max-inline-size: min(280px, calc(100vw - 12px));
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--board-glass-strong);
  color: var(--board-text);
  font-size: var(--text-sm);
  line-height: 1.35;
  pointer-events: none;
}

/* A long press on a button shows its name, so the phone's own text selection and menu stay out of the way. */
button[title],
a[title] {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* The pointed-at button's name, just above the bar. */
.figure-bar-caption {
  position: absolute;
  inset-block-end: calc(100% + 4px);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--board-glass-strong);
  color: var(--board-text);
  font-size: var(--text-xs);
  white-space: nowrap;
  pointer-events: none;
}

@keyframes figure-bar-in {
  from {
    opacity: 0;
  }
}

.reduce-motion .figure-bar {
  animation: none;
}

.board-tag {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-1-5);
  border-radius: var(--radius-xs);
  white-space: nowrap;
  font: var(--weight-medium) var(--text-sm)/1.3 var(--font-sans);
  background: var(--board-glass-label);
  will-change: transform;
}

.board-tag.is-below {
  font-size: var(--text-2xs);
  opacity: 0.9;
}

.board-tag.is-faint {
  background: var(--board-glass-faint);
}

/* A label without room shrinks to a dot in its feeling's colour, keeping its words for screen readers. */
/* Shown labels sit above dots, so a dot that couldn't move clear never covers words. */
.board-tag {
  z-index: 1;
}

.board-tag.is-dot {
  z-index: 0;
  --feel: 255, 255, 255;
  inline-size: 10px;
  block-size: 10px;
  padding: 0;
  overflow: hidden;
  border: 1.5px solid var(--board-glass);
  border-radius: 50%;
  background: rgb(var(--feel));
}

.board-tag.is-dot > * {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.board-tag.is-dot[data-family="ease"] { --feel: var(--feel-ease-rgb); }
.board-tag.is-dot[data-family="pull"] { --feel: var(--feel-pull-rgb); }
.board-tag.is-dot[data-family="low"] { --feel: var(--feel-low-rgb); }
.board-tag.is-dot[data-family="fear"] { --feel: var(--feel-fear-rgb); }
.board-tag.is-dot[data-family="anger"] { --feel: var(--feel-anger-rgb); }
.board-tag.is-dot[data-family="withdrawn"] { --feel: var(--feel-withdrawn-rgb); }
.board-tag.is-dot[data-family="unsure"] { --feel: var(--feel-unsure-rgb); }

.high-contrast .board-tag.is-dot {
  background: rgb(var(--feel));
}

.person-mark {
  display: inline-flex;
  width: 11px;
  justify-content: center;
}

.person-mark svg {
  width: 11px;
  height: 9px;
  fill: currentColor;
}

.people-list {
  position: absolute;
  top: max(8px, env(safe-area-inset-top));
  left: max(12px, env(safe-area-inset-left));
  display: grid;
  gap: 2px;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  font: var(--weight-medium) var(--text-sm)/1.45 var(--font-sans);
  color: var(--board-text);
  background: var(--board-glass-label);
  pointer-events: auto;
}

.people-list.is-following {
  top: 46px;
}

.people-status {
  opacity: 0.75;
}

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

.people-chip {
  min-height: 32px;
  padding: 0;
  border: 0;
  font: inherit;
  color: inherit;
  background: none;
  cursor: pointer;
}

/* Weak devices, as the board itself detects, give up the glass blur everywhere, with stronger glass in its place.
   Capable ones keep it. */
.quality-low {
  --board-blur: none;
  --board-glass: var(--board-glass-strong);
}

@media (pointer: coarse) {
  .tool,
  .figure-lay,
  .visibility,
  .permission-toggle,
  .person-remove {
    min-width: 40px;
    min-height: 40px;
  }
}

.reduce-motion #flash {
  transition: none !important;
}

.reduce-motion #flash {
  display: none;
}


/* A representative's figures, at the top of their screen, and who represents what in the facilitator's lists. */
.top-stack {
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  left: 50%;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  max-width: calc(100vw - 32px);
  transform: translateX(-50%);
  pointer-events: none;
}

.top-stack > * {
  pointer-events: auto;
}

.point-bar {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  color: var(--board-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

/* A host seeing the names as one guest sees them. */
.see-as {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-2);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

.seeas-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  border: var(--border-width) solid var(--board-accent);
}

.point-bar.is-yours {
  border: var(--border-width) solid var(--board-accent);
  color: var(--board-accent);
}

.rep-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-lg);
  color: var(--board-text);
  overflow-x: auto;
}

.rep-label {
  color: var(--board-text-muted);
  font-size: var(--text-sm);
  white-space: nowrap;
}

.rep-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-height-sm);
  padding: 0 var(--space-3) 0 var(--space-2);
  border: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--board-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
}

.rep-chip svg {
  width: 20px;
  height: 20px;
}

.rep-chip:hover {
  background: var(--board-hover);
}

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

.rep-step {
  width: var(--control-height-sm);
  height: var(--control-height-sm);
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--board-text);
  font-size: var(--text-lg);
  cursor: pointer;
}

.rep-step:hover {
  background: var(--board-hover);
}

.row-note {
  grid-column: 1 / -1;
  padding-inline-start: calc(var(--space-8) + var(--space-1));
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

/* What the other hosts changed, newest first, under the people. */
.host-activity {
  display: grid;
  gap: var(--space-1);
  margin-block-start: var(--space-3);
  padding-block-start: var(--space-2);
  border-block-start: 1px solid var(--board-line);
}

.activity-line {
  margin: 0;
  padding-inline-start: 0;
}

.activity-line time {
  color: var(--board-text-muted);
  font-variant-numeric: tabular-nums;
}

.row-action {
  min-height: 28px;
  margin-inline-start: var(--space-2);
}

.row-action[aria-pressed="true"] {
  color: var(--board-text);
}

/* How representatives move, under Everyone: a choice, and in When invited, inviting or stopping all at once. */
.rep-moves-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: var(--space-1) var(--space-2);
}

.rep-moves-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--board-text-muted);
  font-size: var(--text-xs);
}

.rep-status {
  color: var(--board-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

.rep-bar.is-waiting .rep-status {
  color: var(--board-text-muted);
}

/* Seeing through a figure's eyes: a way back, the figure's name with previous and next, and a thumb-sized pad. */
.room-page.is-seeing .view-tools [data-view] {
  display: none;
}

.room-page.is-seeing .top-stack {
  top: var(--stack-top, calc(max(12px, env(safe-area-inset-top)) + 56px));
}

.eyes-ui {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}

.eyes-ui > * {
  pointer-events: auto;
}

.eyes-top {
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  inset-inline: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  pointer-events: none;
}

.eyes-top > * {
  pointer-events: auto;
}

/* Feelings (spec 0009): choices in their family's colour, a guest's own card, and the edges of the screen from inside
   a figure that feels something. */
.feeling-picker {
  display: grid;
  gap: var(--space-2);
}

.feeling-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.feeling-choice,
.feeling-edge {
  --feel: var(--feel-unsure-rgb);
}

.feeling-choice[data-family="ease"],
.feeling-edge[data-family="ease"] {
  --feel: var(--feel-ease-rgb);
}

.feeling-choice[data-family="pull"],
.feeling-edge[data-family="pull"] {
  --feel: var(--feel-pull-rgb);
}

.feeling-choice[data-family="low"],
.feeling-edge[data-family="low"] {
  --feel: var(--feel-low-rgb);
}

.feeling-choice[data-family="fear"],
.feeling-edge[data-family="fear"] {
  --feel: var(--feel-fear-rgb);
}

.feeling-choice[data-family="anger"],
.feeling-edge[data-family="anger"] {
  --feel: var(--feel-anger-rgb);
}

.feeling-choice[data-family="withdrawn"],
.feeling-edge[data-family="withdrawn"] {
  --feel: var(--feel-withdrawn-rgb);
}

.feeling-choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  min-height: 30px;
  padding: 0 var(--space-2);
  border: 1px solid rgba(var(--feel), 0.35);
  border-radius: var(--radius-full);
  background: rgba(var(--feel), 0.08);
  color: var(--board-text);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.feeling-choice::before {
  content: "";
  inline-size: 8px;
  block-size: 8px;
  border-radius: 50%;
  background: rgb(var(--feel));
}

.feeling-choice:hover {
  background: rgba(var(--feel), 0.18);
}

.feeling-choice[aria-pressed="true"] {
  border-color: rgb(var(--feel));
  background: rgba(var(--feel), 0.28);
}

.feeling-strengths {
  display: flex;
  gap: var(--space-1);
}

.figure-feeling-gesture {
  display: grid;
  gap: var(--space-3);
}

.gesture-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.gesture-choice {
  min-height: 30px;
  padding: 0 var(--space-2);
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-full);
  background: none;
  color: var(--board-text-muted);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.gesture-choice:hover {
  border-color: var(--board-line-bright);
  color: var(--board-text);
}

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

.feeling-strength,
.setting-choice {
  flex: 1;
  min-height: 28px;
  border: 1px solid var(--board-line-strong);
  border-radius: var(--radius-md);
  background: none;
  color: var(--board-text-muted);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.feeling-strength[aria-pressed="true"],
.setting-choice[aria-pressed="true"] {
  border-color: var(--board-accent);
  background: var(--board-chosen);
  color: var(--board-text);
}

.feeling-card {
  position: absolute;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 7;
  display: grid;
  gap: var(--space-3);
  inline-size: min(440px, calc(100vw - 32px));
  padding: var(--space-4);
  border-radius: var(--radius-xl);
  transform: translateX(-50%);
  color: var(--board-text);
}

.feeling-done {
  justify-self: end;
}

/* The figure's close-up, a tab on top of its card: a glass frame whose middle is left empty for the board to draw into,
   softened towards the edges, with the figure's name along the bottom. No backdrop blur, which would blur the figure. */
.feeling-portrait {
  position: absolute;
  z-index: 7;
  overflow: hidden;
  inline-size: var(--board-portrait-size);
  block-size: var(--board-portrait-size);
  border: 6px solid var(--board-glass-strong);
  border-block-end-width: 0;
  border-start-start-radius: var(--radius-xl);
  border-start-end-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  box-sizing: content-box;
  pointer-events: none;
}

.feeling-portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 72% 70% at 50% 42%, transparent 58%, color-mix(in srgb, var(--night-950) 75%, transparent) 100%);
}

.feeling-portrait-name {
  position: absolute;
  z-index: 1;
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--space-3) var(--space-2) var(--space-1);
  background: linear-gradient(transparent, var(--board-glass-strong));
  color: var(--board-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.feeling-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.feeling-edge {
  position: absolute;
  inset: 0;
  z-index: 3;
  box-shadow: inset 0 0 var(--feel-edge-reach) var(--feel-edge-spread) rgba(var(--feel), 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-feel-fade) ease;
}

.feeling-edge.is-on {
  opacity: var(--feel-strength, 0.6);
  animation: feel-breathe var(--duration-feel-breathe) ease-in-out var(--duration-feel-fade) infinite;
}

@keyframes feel-breathe {
  50% {
    opacity: calc(0.7 * var(--feel-strength, 0.6));
  }
}

.reduce-motion .feeling-edge.is-on {
  animation: none;
}

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

.figure-show-note {
  color: var(--board-text-muted);
}

/* In a figure's eyes the title says whose eyes and whether they're yours, so the representative's bar and the list of
   who's here step aside. The host still has People in the panel. */
.room-page.is-seeing .rep-bar,
.room-page.is-seeing .people-list {
  display: none;
}

/* The title in full, or on a phone just the figure's name. */
.eyes-name-short {
  display: none;
}

/* The bar never runs past the screen: the figure's name shortens instead. */
.eyes-title {
  max-inline-size: 100%;
}

.eyes-name {
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.eyes-yours {
  align-self: center;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--board-chosen);
  color: var(--board-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  pointer-events: none;
}

/* Below the "Following the facilitator's view" bar, with only the figure's name to show. */
.eyes-ui.is-led .eyes-top {
  top: calc(max(12px, env(safe-area-inset-top)) + 48px);
}

.eyes-back {
  margin-inline-end: var(--space-1);
  border-inline-end: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-full) 0 0 var(--radius-full);
}

.eyes-feel .icon,
.eyes-show .icon,
.eyes-show svg {
  width: 18px;
  height: 18px;
}

.eyes-ahead {
  margin-inline-start: var(--space-1);
  border-inline-start: var(--border-width) solid var(--board-line);
  border-radius: 0 var(--radius-full) var(--radius-full) 0;
}

.eyes-title {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--control-height);
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  color: var(--board-text);
  font-weight: var(--weight-semibold);
}

.eyes-name {
  padding: 0 var(--space-2);
  white-space: nowrap;
}

.eyes-hop,
.eyes-back,
.eyes-ahead,
.eyes-feel,
.eyes-show {
  display: inline-grid;
  place-items: center;
  width: var(--control-height);
  height: var(--control-height);
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--board-text);
  font-size: var(--text-xl);
  cursor: pointer;
}

.eyes-hop:hover,
.eyes-back:hover,
.eyes-ahead:hover,
.eyes-feel:hover,
.eyes-show:hover {
  background: var(--board-hover);
}

/* Going back is spelled out, so it isn't mistaken for the arrows that step between figures. */
.eyes-back {
  display: inline-flex;
  gap: var(--space-2);
  align-items: center;
  width: auto;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.eyes-back > span:first-child {
  font-size: var(--text-lg);
}

.eyes-hint {
  position: absolute;
  bottom: calc(max(24px, env(safe-area-inset-bottom)) + 156px);
  left: 50%;
  max-width: min(90vw, 28rem);
  margin: 0;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-lg);
  transform: translateX(-50%);
  color: var(--board-text);
  font-size: var(--text-sm);
  text-align: center;
  transition: opacity var(--duration-slow) var(--ease-out);
}

.eyes-hint.is-faded {
  opacity: 0;
  pointer-events: none;
}

/* Turn left, forward and turn right across the top, back below forward: where a thumb rests on a phone. */
.eyes-pad {
  position: absolute;
  bottom: max(24px, env(safe-area-inset-bottom));
  left: 50%;
  display: grid;
  grid-template-columns: repeat(3, 64px);
  grid-template-rows: repeat(2, 64px);
  gap: var(--space-2);
  transform: translateX(-50%);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.eyes-pad-button {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border: var(--border-width) solid var(--board-line);
  border-radius: var(--radius-full);
  background: var(--board-glass);
  -webkit-backdrop-filter: var(--board-blur);
  backdrop-filter: var(--board-blur);
  color: var(--board-text);
  font-size: var(--room-pad-arrow);
  cursor: pointer;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}

.eyes-pad-button[data-dir="b"] {
  grid-column: 2;
}

.eyes-pad-button.is-held {
  border-color: var(--board-accent);
  background: linear-gradient(var(--board-chosen), var(--board-chosen)), var(--board-glass);
}

/* The eyes' controls keep clear of the facilitator's panel, open or folded, and of the guests' list. */
@media (min-width: 721px) {
  .admin-page:not(.panel-closed) .eyes-ui {
    inset-inline-end: 440px;
  }

  .admin-page:not(.panel-closed) .top-stack {
    left: calc(50% - 220px);
    max-width: calc(100vw - 472px);
  }

}

.room-page.is-seeing .guest-people {
  display: none;
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .room-page.is-seeing .view-tools {
    display: none;
  }

  /* On a phone the corners hold who's here and the view tools, so the representative's and the pointing bars sit at
     the bottom, clear of the add and picture buttons. */
  .top-stack {
    top: auto;
    bottom: max(16px, env(safe-area-inset-bottom));
    left: var(--space-3);
    right: 12px;
    max-width: none;
    transform: none;
  }

  .top-stack .rep-bar,
  .top-stack .point-bar {
    flex-wrap: wrap;
    justify-content: center;
  }

  /* Above the bar along the bottom edge, a host's or a guest's. */
  .room-page .top-stack {
    bottom: calc(var(--room-bar-space) + env(safe-area-inset-bottom));
  }

  /* In a figure's eyes the corners are clear, so the bars go just under the first-person bar. */
  .room-page.is-seeing .top-stack {
    top: var(--stack-top, calc(max(12px, env(safe-area-inset-top)) + 60px));
    bottom: auto;
    left: 12px;
  }

  .eyes-title {
    font-size: var(--text-sm);
  }

  .eyes-name-long {
    display: none;
  }

  .eyes-name-short {
    display: inline;
  }

  .admin-page .eyes-pad {
    bottom: calc(max(24px, env(safe-area-inset-bottom)) + 64px);
  }
}

/* Targets (WCAG 2.5.8, spec 0014): nothing under 24px. What guests use, the feelings and representative cards and the
   chat, is 36px tall with a mouse and 44px on a touch screen, as Apple's and Google's guidance give for touch. */

.feeling-choice,
.gesture-choice,
.rep-choice,
.feeling-strength,
.setting-choice,
.chat-to,
.feeling-card .face-pick {
  min-height: 36px;
}

.feeling-close,
.chat-close,
.chat-send,
.feeling-done {
  min-inline-size: 36px;
  min-block-size: 36px;
}

@media (pointer: coarse) {
  .feeling-choice,
  .gesture-choice,
  .rep-choice,
  .feeling-strength,
  .setting-choice,
  .chat-to,
  .feeling-card .face-pick {
    min-height: 44px;
  }

  .feeling-close,
  .chat-close,
  .chat-send,
  .feeling-done {
    min-inline-size: 44px;
    min-block-size: 44px;
  }
}

/* The host's row along the top (spec 0025 step 1): what sat at the top moves under it, and who's here under the follow
   switch. Until step 2 rebuilds the frame. */
.admin-page .eyes-top {
  top: var(--room-top-space);
}

.admin-page .people-list {
  top: calc(var(--room-top-space) + var(--control-height) + var(--space-3));
}

/* Hosts see who's here at the top right (step 1b); only the quality line stays in the list, when asked for. */
.admin-page .people-line,
.admin-page .people-chip {
  display: none;
}

.admin-page .people-list:not(:has(.people-status)) {
  display: none;
}

.admin-page .top-stack {
  top: calc(var(--room-top-space) + var(--space-2));
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .admin-page .people-list {
    top: var(--room-top-space);
  }

  .admin-page .view-tools {
    top: var(--room-top-space);
  }

  .admin-page .top-stack {
    top: auto;
  }

  .room-top__time,
  .room-top__code {
    display: none;
  }
}

/* The host's bar (spec 0025 step 2a): the left-hand tools' buttons are in it, the bar keeps to the board's half beside
   an open panel, notices sit above it, and in a figure's eyes the pad takes its place. Until step 2b and the look. */
/* Beside an open panel the bar centres on the board's part of the screen; on a narrow window it centres on the whole
   width, and the panel ends above it. */
.admin-page:not(.panel-closed) .room-bar {
  inset-inline-start: calc(50% - var(--room-panel-reach) / 2);
}

/* On a narrow window it starts at the left edge instead, where the board's part is narrower than the bar. */
@media (max-width: 1000px) {
  .admin-page:not(.panel-closed) .room-bar {
    inset-inline-start: var(--space-4);
    transform: none;
  }
}

/* What opens at the bottom sits above the bar, a host's or a guest's (step 4): notices, the shelf, a figure's feeling
   and lines cards, and a guest's chat and settings. */
.room-page .room-notice:not(.room-notice-top),
.room-page .tray,
.room-page .feeling-card,
.room-page .settings-panel,
.room-page .chat-panel {
  bottom: calc(var(--room-bar-space) + env(safe-area-inset-bottom, 0px));
}

/* A guest's chat and settings open above their bar, in the middle, clear of the view tools. */
.guest-page .chat-panel,
.guest-page .settings-panel {
  inset-inline: var(--room-tools-reach);
  margin-inline: auto;
}

/* On a phone they take the width, above the bar. */
@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .guest-page .chat-panel,
  .guest-page .settings-panel {
    inset-inline: var(--space-3);
    inline-size: auto;
  }
}

/* And they stop below what's at the top: the room's row, who's here and the follow switch. */
.room-page .tray,
.room-page .settings-panel.board-list {
  max-height: calc(100% - var(--room-bar-space) - var(--room-top-space) - var(--control-height) * 2 - var(--space-6));
}

/* In a figure's eyes a host's pad takes the bar's place; a guest keeps theirs, with Chat and Settings. */
.admin-page.is-seeing .room-bar {
  display: none;
}

.guest-page .eyes-pad {
  bottom: calc(var(--room-bar-space) + env(safe-area-inset-bottom, 0px));
}

/* The hint keeps its place above the pad, as it does over the bottom edge. */
.guest-page .eyes-hint {
  bottom: calc(var(--room-bar-space) + env(safe-area-inset-bottom, 0px) + 140px);
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .admin-page:not(.panel-closed) .room-bar {
    inset-inline-start: 0;
  }

  /* The bars and an open sheet sit at the bottom on a phone, so a notice there goes above them, never on them, and a
     short message above the notice, never over the name row. room-controls.js measures both (layoutBottomStack). */
  .room-page:not(.is-seeing) .room-notice:not(.room-notice-top) {
    bottom: var(--notice-bottom, calc(var(--room-bar-space) + env(safe-area-inset-bottom, 0px)));
  }

  .room-page:not(.is-seeing) .room-toast {
    top: auto;
    bottom: var(--toast-bottom, calc(var(--room-bar-space) + env(safe-area-inset-bottom, 0px)));
  }

  /* An open tray is a sheet on a phone, as a panel is: the view tools and the top bars step aside. */
  .admin-page:has(.tray:not(.is-collapsed)) .view-tools,
  .admin-page:has(.tray:not(.is-collapsed)) .top-stack {
    display: none;
  }
}

/* A host's phone held upright: the view tools fold into one button, which opens them where they were. The shape is
   the one the board's first view goes by (CameraRig's PhoneAspect), and FOLD_QUERY in room-controls.js is this rule. */
.view-fold {
  display: none;
}

@media (max-aspect-ratio: 13/20) and (max-width: 560px), (max-aspect-ratio: 13/20) and (max-width: 720px) and (pointer: coarse) {
  .admin-page .view-fold {
    display: inline-flex;
  }

  .admin-page:not(.view-unfolded) .view-tools > :not(.view-fold) {
    display: none;
  }
}

/* A host's sound is in the Room panel (spec 0025 step 2b); a guest keeps it with their view tools until step 4. */
.admin-page .sound-tool {
  display: none;
}

/* A narrow upright window with a mouse keeps more of the board beside a docked panel. A touch tablet held upright has
   its panels as sheets instead (below). */
@media (min-width: 721px) and (max-width: 900px) and (orientation: portrait) and (pointer: fine), (min-width: 561px) and (max-width: 720px) and (orientation: portrait) and (pointer: fine) {
  .admin-page .admin-panel {
    width: min(340px, 36vw);
  }
}

/* Beside a host's open panel the shelf centres on the board's part of the screen, clear of the panel. */
.admin-page:not(.panel-closed) .tray {
  inset-inline-end: var(--room-panel-reach);
  inset-inline-start: var(--space-4);
}

/* The figure card (spec 0025 step 5): Remove from board is its last action, in danger's colour. */
.figure-details .figure-remove {
  color: var(--board-danger-text);
}


/* A guest on a phone (spec 0025 items 22 to 24): their line along the top, View in the bar opening the view tools as a
   small sheet with the picture, and Add figure the large button. Elsewhere the view tools stay at the right edge. */
.guest-top,
.room-bar .bar-view,
.view-picture {
  display: none;
}

@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .guest-page .guest-top {
    position: absolute;
    inset-block-start: max(var(--space-3), env(safe-area-inset-top));
    inset-inline: var(--space-3);
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    min-block-size: var(--control-height);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-lg);
    color: var(--board-text);
    font-size: var(--text-sm);
  }

  .room-page.is-seeing .guest-top {
    display: none;
  }

  .guest-top__state {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--weight-medium);
  }

  .guest-top__dot {
    inline-size: 8px;
    block-size: 8px;
    border-radius: var(--radius-full);
    background: var(--board-accent);
  }

  .guest-top.is-waiting .guest-top__dot {
    background: var(--board-text-muted);
  }

  .guest-top__holds {
    min-inline-size: 0;
    overflow: hidden;
    color: var(--board-text-muted);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .guest-top__figure {
    color: var(--board-text);
    font-weight: var(--weight-semibold);
  }

  .guest-page .people-list {
    top: calc(max(var(--space-3), env(safe-area-inset-top)) + var(--control-height) + var(--space-4));
  }

  .room-bar.is-tabs .bar-view:not([hidden]) {
    display: flex;
  }

  .guest-page .guest-room-bar.is-tabs .bar-add {
    flex: 2 1 0;
    flex-direction: row;
    gap: var(--space-2);
    font-size: var(--text-sm);
  }

  .guest-page .guest-room-bar.keeps-picture #shot {
    display: flex;
  }

  .guest-page:not(.view-open) .view-tools {
    display: none;
  }

  .guest-page.view-open .view-tools {
    inset-block: auto calc(var(--room-bar-space) + env(safe-area-inset-bottom));
    inset-inline: var(--space-3);
    flex-flow: row wrap;
    justify-content: center;
  }

  .guest-page.view-open .view-picture {
    display: inline-flex;
    flex-basis: 100%;
    justify-content: center;
  }
}

/* A representative on a phone: the top line names their figure, and the feelings and See as replace the icons. */
@media (max-width: 560px), (max-width: 720px) and (pointer: coarse) {
  .guest-page .rep-label,
  .guest-page .rep-bar.is-single .rep-chip,
  .guest-page .rep-eyes,
  .guest-page .rep-feel {
    display: none;
  }
}

/* A host's figure card as a sheet (spec 0025 item 22): on a phone, and on a tablet held upright when it won't fit beside
   its figure, a sheet over the lower part, as the panels are, standing in for the panel's sheet while it's open. Its
   title is the grabber. */
.figure-details.is-sheet {
  inset: auto 0 calc(54px + env(safe-area-inset-bottom)) 0;
  width: auto;
  max-height: 62dvh;
  padding-block-start: var(--space-4);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
}

.figure-details.is-sheet .figure-card-title {
  position: relative;
  touch-action: none;
}

.figure-details.is-sheet .figure-card-title::before {
  content: "";
  position: absolute;
  inset-block-start: calc(var(--space-2) * -1 - 4px);
  inset-inline: 0;
  inline-size: 36px;
  block-size: 4px;
  margin-inline: auto;
  border-radius: var(--radius-full);
  background: var(--board-text-muted);
}

.room-page.card-sheet .admin-panel {
  visibility: hidden;
}

/* The same on the room's older controls: a finger's width to hit, the look unchanged (spec 0025 item 24). Each sits a
   layer up with its wider area, and a figure's name box above its icon's, so the name box keeps its own edge. Text boxes, selects and the
   slider can't grow a hit area past their box, and keep their size. */
@media (pointer: coarse) {
  .room-page :is(.link-button, .figure-icon, .people-chip, .permission-toggle, .person-remove, .tool-square, .visibility,
    .option-check, .reps-toggle, .card-fold, .chat-close, .feeling-close, .board-list-open, .panel-add, .view-picture) {
    position: relative;
    z-index: 1;
  }

  /* A figure's name box comes after its icon, so it keeps its own edge from the icon's wider area. */
  .room-page .name-input {
    position: relative;
    z-index: 1;
  }

  .room-page :is(.link-button, .figure-icon, .people-chip, .permission-toggle, .person-remove, .tool-square, .visibility,
    .option-check, .reps-toggle, .card-fold, .chat-close, .feeling-close, .board-list-open, .panel-add, .view-picture)::before {
    content: "";
    position: absolute;
    inset: min(0px, calc((100% - var(--touch-target)) / 2));
  }
}

/* A host's panels as sheets: on a phone, and on a touch tablet held upright, where a docked panel would take a third of
   the width (the UI/UX session, 2026-11-13). The rest of a tablet keeps its computer form. */
/* The sheet's head is its grabber: dragged down, the sheet closes. */
.panel-sheets .admin-panel-head {
  position: relative;
  padding-block-start: var(--space-4);
  touch-action: none;
}

.panel-sheets .admin-panel-head::before {
  content: "";
  position: absolute;
  inset-block-start: var(--space-1-5);
  inset-inline: 0;
  inline-size: 36px;
  block-size: 4px;
  margin-inline: auto;
  border-radius: var(--radius-full);
  background: var(--board-text-muted);
}

/* Above the bar and clear of the view tools' column, one at a time. */
.tablet-sheets .admin-panel,
.tablet-sheets .figure-details.is-sheet {
  top: auto;
  inset-inline: var(--space-4) 84px;
  bottom: calc(var(--room-bar-space) + env(safe-area-inset-bottom));
  width: auto;
  max-height: 50dvh;
  border-radius: var(--radius-xl);
}
