/*
 * One stylesheet for both pages, in the Sway app's wireframe language.
 *
 * The grammar, taken from `Sway/static/css/wire.css` and the tokens beside it:
 *
 *   - paper rather than a tinted card; a 1.5px ruled edge and a hard offset
 *     cast — never a blur, never a 16px radius
 *   - mono (Roboto Mono) for anything that labels; IBM Plex Sans speaks
 *   - ink plus one accent. The app stops there, and so does everything on these
 *     pages that is merely structural: the accent points at things and never
 *     labels them.
 *
 * Two functional exceptions, and only two. The app can refuse a danger colour
 * because weight and position tell a signed-in user which button is the
 * destructive one. Here they cannot, for two specific reasons:
 *
 *   - On the participant form the accent is already spoken for. A chosen answer
 *     is an accent-filled chip, so an accent-ruled error would be the same
 *     colour saying "this is your answer" and "this one is missing" on the same
 *     screen, eighteen inches from somebody's face, in a dark room.
 *   - On the organizer page one button deletes every answer an event collected.
 *     It is pressed once, under time pressure, next to a button that downloads
 *     them — and a rule in strong ink is not a different enough thing.
 *
 * So `--sw-danger` and `--sw-alert` exist, declared in both themes and used
 * only as an edge, a tint and a word — never as a filled button, which would
 * put a red block where the language expects paper. A test holds the palette to
 * the app's values plus exactly these two.
 *   - hover deepens the cast and lifts the sheet; pressed flattens it
 *   - heads are hatched, never filled; dividers inside a plate are dashed
 *
 * No hand-drawn ink, for the same reason the app has none: this is a live
 * surface whose boxes move under the reader, and an outline regenerated on
 * every change is not one anybody wants. Ruled edges throughout.
 *
 * The values are restated here rather than imported, which is how the family
 * works — but they are the same numbers. A sixth sheet is fine; a sixth sheet
 * with different numbers is not.
 *
 * Two departures from the app, both because this is a survey on a phone rather
 * than an application with chrome:
 *
 *   - The theme follows the operating system. The app has a toggle in its
 *     navigation bar; there is no navigation bar here to put one in, and a
 *     control that only changes the colours would be the second most prominent
 *     thing on a screen whose whole job is three questions.
 *   - The fluid root is expressed in rem rather than px, so it scales from
 *     whatever the reader has set as their browser's text size instead of
 *     overriding it. Same formula, same result at the default.
 */

/* ============================================================
   0. The two faces
   ============================================================ */
/*
 * Self-hosted rather than fetched from Google, which the app does. Two hundred
 * people on one venue's wifi should not each be waiting on a third party for
 * the type — and should not each be handing that third party their address, on
 * a survey whose first promise is that nothing identifying is collected.
 * Both are variable fonts, so the whole weight range is one file.
 */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-sans-latin.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/roboto-mono-latin.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================
   1. The language
   ============================================================ */
:root {
  color-scheme: light dark;

  --sw-page: #faf9f6;
  --sw-paper: #fffefb;
  --sw-sunken: #f0eeea;
  --sw-sunken-2: #e8e7e2;
  --sw-ink: #55555f;
  --sw-strong: #111118;
  --sw-text: #212529;
  --sw-soft: #3f3f46;
  --sw-muted: #6f6d68;
  --sw-faint: #bab7b0;
  --sw-cast: rgba(60, 50, 40, 0.16);
  --sw-hatch: rgba(60, 50, 40, 0.07);
  --sw-accent: #5a5ad1;
  --sw-accent-deep: #3a3ab1;
  --sw-accent-soft: rgba(90, 90, 209, 0.1);
  /* The accent as a hard cast: the guide's voice is a violet shadow, never a bar. */
  --sw-accent-cast: rgba(90, 90, 209, 0.35);
  /* Legible on an accent fill: paper in light, ink in dark. */
  --sw-on-accent: #fffefb;

  /* The two functional hues. See the note at the top of this file. */
  --sw-danger: #a8322a;
  --sw-danger-soft: rgba(168, 50, 42, 0.09);
  --sw-danger-cast: rgba(168, 50, 42, 0.3);
  --sw-alert: #96600f;
  --sw-alert-soft: rgba(150, 96, 15, 0.1);

  --sw-mono: 'Roboto Mono', ui-monospace, Menlo, Consolas, monospace;
  --sw-body: 'IBM Plex Sans', Roboto, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --radius: 5px;
  --gap: 1rem;
  /* Every control is at least this tall, because that is the size of a thumb. */
  --tap: 2.75rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* True black page, violet-ink — the app's dark values, unchanged. */
    --sw-page: #000000;
    --sw-paper: #15151e;
    --sw-sunken: #0e0e15;
    --sw-sunken-2: #07070c;
    --sw-ink: #a8a8b4;
    --sw-strong: #f1f1f5;
    --sw-text: #dcdce1;
    --sw-soft: #b3b3bc;
    --sw-muted: #8b8b92;
    --sw-faint: #4b4b5a;
    --sw-cast: rgba(226, 226, 255, 0.09);
    --sw-hatch: rgba(226, 226, 255, 0.05);
    --sw-accent: #8a8aff;
    --sw-accent-deep: #b3b3ff;
    --sw-accent-soft: rgba(138, 138, 255, 0.13);
    --sw-accent-cast: rgba(138, 138, 255, 0.4);
    --sw-on-accent: #15151e;

    /* Lifted for a black page, and desaturated so neither shouts. */
    --sw-danger: #f0938a;
    --sw-danger-soft: rgba(240, 147, 138, 0.12);
    --sw-danger-cast: rgba(240, 147, 138, 0.35);
    --sw-alert: #e8b25c;
    --sw-alert-soft: rgba(232, 178, 92, 0.13);
  }
}

* {
  box-sizing: border-box;
}

/*
 * The `hidden` attribute is how every screen here is shown and hidden, and the
 * user-agent rule behind it is only `display: none` at the lowest possible
 * specificity. Any class that sets `display` — `.option` and `.scale` are flex,
 * `.button` is inline-flex — silently beats it, and the element stays on screen
 * with `hidden` set. That is how a "Continue" link meant for the final screen
 * turned up on the waiting screen instead.
 */
[hidden] {
  display: none !important;
}

html {
  /* The page paints its own ground; a short body must not show the canvas. */
  background: var(--sw-page);
  /*
   * The app's fluid root, restated in rem: type grows with the window so a
   * large display reads without zooming, and the floor is whatever the reader
   * has set rather than a fixed 16px. 1rem here is the browser default, so at
   * the default setting this is the app's formula exactly.
   */
  font-size: clamp(1rem, 0.6875rem + 0.55vw, 1.34rem);
  -webkit-text-size-adjust: 100%;
}

body.page {
  margin: 0;
  /*
   * Even on all four sides. It used to carry extra at the bottom to keep the
   * submit button clear of a home indicator; now that the sheet is centred,
   * uneven padding simply shows as a sheet sitting off-centre. The insets add
   * back whatever a notch or an indicator actually needs, on the devices that
   * actually have one.
   */
  padding: max(1.25rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right))
    max(1.25rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
  background-color: var(--sw-page);
  color: var(--sw-text);
  font-family: var(--sw-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  /*
   * A column that fills the window, so a short sheet can sit in the middle of
   * it rather than clinging to the top of an otherwise empty page. `svh`
   * because the dynamic viewport unit moves as mobile browser chrome hides and
   * shows, which would nudge the sheet while somebody is reading it; `vh` first
   * for anything that has not heard of `svh`.
   */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
}

/* A thing you read: paper, ruled, cast. */
.card {
  position: relative;
  max-width: 34rem;
  width: 100%;
  /*
   * `auto` on all four sides rather than `justify-content: center` on the
   * column. Auto margins collapse to nothing once the sheet is taller than the
   * window, so a long form scrolls from its first line; centring the column
   * would push the top of an overflowing sheet above the scrollable area and
   * put the first statement out of reach.
   */
  margin: auto;
  padding: 1.5rem 1.6rem 1.4rem;
  background: var(--sw-paper);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 3px 3px 0 var(--sw-cast);
}

.page--wide .card {
  max-width: 48rem;
}

/* Headings label a screen, so mono. */
h1,
h2,
h3 {
  font-family: var(--sw-mono);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--sw-strong);
  text-wrap: balance;
}

h1 {
  margin: 0 0 0.75rem;
  font-size: 1.15rem;
  line-height: 1.35;
}

h2 {
  margin: 2rem 0 0.6rem;
  font-size: 0.92rem;
  /* A section head is separated by a dashed rule, never a second box. */
  border-top: 1px dashed var(--sw-faint);
  padding-top: 1.1rem;
}

h3 {
  margin: 0 0 0.3rem;
  font-size: 0.82rem;
}

p {
  margin: 0 0 var(--gap);
  color: var(--sw-soft);
}

.muted {
  color: var(--sw-muted);
  font-size: 0.86rem;
}

.privacy {
  margin-top: 1.4rem;
}

a,
.link {
  color: var(--sw-accent);
  overflow-wrap: anywhere;
}

a:hover {
  color: var(--sw-accent-deep);
}

a:focus-visible {
  outline: 2px solid var(--sw-accent);
  outline-offset: 2px;
  border-radius: 3px;
}

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

/*
 * The bridge message. The one paragraph a participant must actually read, and
 * the methodological content of the second stage — so it is set apart the way
 * the guide speaks in the app: a hatched sheet under a violet cast, rather than
 * a coloured bar. The accent points at it; it does not label it.
 */
.callout {
  padding: 1rem 1.1rem;
  background: var(--sw-hatch);
  color: var(--sw-strong);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 3px 3px 0 var(--sw-accent-cast);
  font-size: 0.95rem;
  line-height: 1.6;
}

/* Says what state something is in. Ruled and hatched, never coloured. */
.banner {
  max-width: 34rem;
  margin: 0 auto 0.85rem;
  padding: 0.6rem 0.85rem;
  background: var(--sw-alert-soft);
  color: var(--sw-strong);
  border: 1.5px solid var(--sw-alert);
  border-radius: var(--radius);
  font-family: var(--sw-mono);
  font-size: 0.74rem;
  line-height: 1.5;
}

/*
 * Something the organizer probably did not mean to do. Nothing is broken and
 * nothing is lost, so this is the alert hue rather than the danger one — a
 * tint and an edge, with the text left in ink so it stays legible in a room
 * with the lights down.
 */
.warning {
  padding: 0.8rem 0.95rem;
  background: var(--sw-alert-soft);
  color: var(--sw-strong);
  border: 1.5px solid var(--sw-alert);
  border-radius: var(--radius);
  font-size: 0.9rem;
  font-weight: 600;
}

.notice {
  padding: 0.65rem 0.9rem;
  background: var(--sw-sunken);
  color: var(--sw-strong);
  border: 1px dashed var(--sw-faint);
  border-radius: var(--radius);
  font-size: 0.88rem;
}

/*
 * Something is wrong and the reader has to act. Not the accent: on the
 * participant form the accent is the chosen answer, and one colour cannot mean
 * both "this is what you picked" and "this one is missing". Mono, because it
 * labels a state rather than saying anything.
 */
.error {
  padding: 0.65rem 0.9rem;
  background: var(--sw-danger-soft);
  color: var(--sw-strong);
  border: 1.5px solid var(--sw-danger);
  border-radius: var(--radius);
  box-shadow: 2px 2px 0 var(--sw-danger-cast);
  font-family: var(--sw-mono);
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.5;
}

/* ============================================================
   2. The questions
   ============================================================ */

/*
 * A fieldset is the wrong box to rule, twice over. Its own `border-top` is
 * carved into a notch for the legend, and a legend at `width: 100%` carves the
 * whole of it away — the rule is in the stylesheet, the element computes it,
 * and nothing is drawn. An absolutely positioned pseudo-element does not help
 * either: a fieldset resolves one against the anonymous box *below* its legend,
 * so the rule lands between the statement and its own options rather than
 * between one question and the next. (The same two faults are recorded in the
 * family's own notes on this.)
 *
 * So the divider belongs to the legend, which is an ordinary box and takes an
 * ordinary border. It also reads correctly: the rule introduces the statement.
 */
.question {
  margin: 0 0 1.4rem;
  padding: 0;
  border: 0;
}

/*
 * A statement speaks a sentence rather than labelling a region, so it takes the
 * body face at weight — mono is for labels.
 */
.question__text {
  display: block;
  width: 100%;
  padding: 1.1rem 0 0;
  margin-bottom: 0.9rem;
  /* A divider inside a plate is dashed. */
  border-top: 1px dashed var(--sw-faint);
  font-family: var(--sw-body);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--sw-strong);
  text-wrap: pretty;
}

/* Points at the statement that still needs an answer, in the same hue as the
   message under the button, so the two read as one thing. */
.question--missing .question__text {
  border-top: 1.5px solid var(--sw-danger);
}

/* A word about what a thing is: dashed, unfilled, never pressable. */
.badge {
  display: inline-block;
  border: 1px dashed var(--sw-faint);
  border-radius: 3px;
  background: none;
  color: var(--sw-muted);
  padding: 0.16em 0.55em;
  font-family: var(--sw-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}

.question__error {
  margin: 0.6rem 0 0;
  font-family: var(--sw-mono);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--sw-danger);
}

.scale {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

/*
 * An answer is a chip: paper, a ruled edge, a small cast, and mono because it
 * labels a position rather than saying anything.
 */
.option {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: var(--tap);
  padding: 0.45rem 0.85rem;
  background: var(--sw-paper);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 2px 2px 0 var(--sw-cast);
  color: var(--sw-strong);
  font-family: var(--sw-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.35;
  cursor: pointer;
  transition:
    box-shadow 0.18s ease,
    transform 0.18s ease;
}

/* Hover deepens the cast and lifts the sheet. */
@media (hover: hover) {
  .option:hover {
    box-shadow: 4px 4px 0 var(--sw-cast);
    transform: translate(-1px, -1px);
  }
}

/* Pressed, the sheet goes flat onto the page rather than lifting off it. */
.option:active {
  box-shadow: 1px 1px 0 var(--sw-cast);
  transform: translate(1px, 1px);
}

/* The chosen one takes the accent as its fill, as a selected item does in the app. */
.option:has(.option__input:checked) {
  background: var(--sw-accent);
  border-color: var(--sw-accent);
  color: var(--sw-on-accent);
  font-weight: 700;
}

.option:has(.option__input:focus-visible) {
  outline: 2px solid var(--sw-accent);
  outline-offset: 2px;
}

.option__input {
  width: 1.1rem;
  height: 1.1rem;
  margin: 0;
  flex: none;
  accent-color: var(--sw-accent);
}

/* On the accent fill the native control needs a ground of its own to sit on. */
.option:has(.option__input:checked) .option__input {
  accent-color: var(--sw-on-accent);
}

/* ============================================================
   3. Controls
   ============================================================ */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
  min-height: var(--tap);
  width: 100%;
  padding: 0.55rem 1.05rem;
  background: var(--sw-paper);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 2px 2px 0 var(--sw-cast);
  color: var(--sw-strong);
  font-family: var(--sw-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    box-shadow 0.18s ease,
    transform 0.18s ease;
}

.button + .button {
  margin-top: 0.5rem;
}

@media (hover: hover) {
  .button:not(:disabled):hover {
    box-shadow: 4px 4px 0 var(--sw-cast);
    transform: translate(-1px, -1px);
    text-decoration: none;
  }
}

.button:not(:disabled):active {
  box-shadow: 1px 1px 0 var(--sw-cast);
  transform: translate(1px, 1px);
}

/* The one ask on a screen takes the accent as its fill. */
.button--primary {
  background: var(--sw-accent);
  border-color: var(--sw-accent);
  color: var(--sw-on-accent);
  font-weight: 700;
}

/*
 * Destructive. Ruled and lettered in the danger hue, not filled with it: a red
 * block would put a shape on the page that the language has nowhere else, and
 * this button sits directly beneath one that merely downloads a file. Paper,
 * an unmistakable edge, and the weight.
 */
.button--danger {
  border-color: var(--sw-danger);
  border-width: 2px;
  color: var(--sw-danger);
  font-weight: 700;
}

@media (hover: hover) {
  .button--danger:not(:disabled):hover {
    box-shadow: 4px 4px 0 var(--sw-danger-cast);
  }
}

.button--danger:not(:disabled):active {
  box-shadow: 1px 1px 0 var(--sw-danger-cast);
}

.button--quiet {
  width: auto;
  min-height: 2.1rem;
  padding: 0.35rem 0.7rem;
  font-size: 0.7rem;
  box-shadow: none;
}

.button:disabled {
  border-color: var(--sw-faint);
  color: var(--sw-soft);
  opacity: 0.55;
  box-shadow: 2px 2px 0 var(--sw-cast);
  transform: none;
  cursor: default;
}

/*
 * In flight. The caption is left alone: it says what the button does, it is
 * derived from server state, and the moment a second thing writes to it the
 * two disagree — see `whileBusy` in `src/client/dom.ts`. So the wait is shown
 * beside the caption instead of on top of it. `gap` on `.button` spaces it.
 *
 * Static, not a spinner. Every one of these calls is a single round trip to
 * the same origin, and an animation would be the only moving thing on a page
 * whose whole language is drawn flat.
 */
.button[data-busy]::after {
  content: '···';
  letter-spacing: 0.1em;
}

.button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--sw-accent);
  outline-offset: 2px;
}

.field {
  display: block;
  margin: 0 0 0.9rem;
}

/* A field label is a label, so mono. */
.field__label {
  display: block;
  margin-bottom: 0.35rem;
  font-family: var(--sw-mono);
  font-weight: 700;
  font-size: 0.74rem;
  letter-spacing: 0.01em;
  color: var(--sw-strong);
}

input[type='text'],
input[type='password'],
input[type='url'],
textarea {
  width: 100%;
  min-height: var(--tap);
  padding: 0.5rem 0.7rem;
  background-color: var(--sw-paper);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 2px 2px 0 var(--sw-cast);
  color: var(--sw-strong);
  font-family: var(--sw-body);
  font-size: 0.95rem;
  resize: vertical;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

input:focus,
textarea:focus {
  border-color: var(--sw-accent);
  outline: 2px solid var(--sw-accent-soft);
  outline-offset: 1px;
}

input:disabled,
textarea:disabled {
  background-color: var(--sw-sunken);
  box-shadow: none;
  opacity: 0.7;
}

.fieldgroup {
  margin: 0 0 1.3rem;
  padding: 1rem;
  border: 1px dashed var(--sw-faint);
  border-radius: var(--radius);
}

/* A legend labels the region under it, so mono, tracked, in the accent. */
.fieldgroup legend {
  padding: 0 0.4rem;
  font-family: var(--sw-mono);
  font-weight: 500;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sw-accent);
}

/* ============================================================
   4. The organizer's dashboard
   ============================================================ */

.dashboard__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap);
}

.counts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.65rem;
  margin: 0 0 0.85rem;
}

.counts__item {
  padding: 0.7rem 0.8rem;
  background: var(--sw-paper);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 2px 2px 0 var(--sw-cast);
}

.counts dt {
  font-family: var(--sw-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sw-muted);
}

.counts dd {
  margin: 0.15rem 0 0;
  font-family: var(--sw-mono);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--sw-strong);
  font-variant-numeric: tabular-nums;
}

.stages {
  display: grid;
  gap: 0.75rem;
  margin-bottom: 0.85rem;
}

.stage {
  padding: 0.85rem;
  background: var(--sw-paper);
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 2px 2px 0 var(--sw-cast);
}

.stage__state {
  margin-bottom: 0.6rem;
  font-family: var(--sw-mono);
  font-size: 0.72rem;
  color: var(--sw-muted);
}

/* Open is the state that matters, so the accent points at it. */
.stage__state--open {
  color: var(--sw-accent);
  font-weight: 700;
}

.labels {
  display: grid;
  gap: 0.5rem;
  margin-bottom: 0.7rem;
}

.labels__row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.labels__index {
  flex: none;
  width: 1.5rem;
  text-align: right;
  font-family: var(--sw-mono);
  font-size: 0.78rem;
  color: var(--sw-muted);
  font-variant-numeric: tabular-nums;
}

.labels__remove {
  flex: none;
  width: var(--tap);
  min-height: var(--tap);
  padding: 0;
  font-size: 1rem;
}

/*
 * The code stays on white in both themes. It is read by a camera, and inverting
 * it for dark mode is the one change here that would stop the app working.
 */
.qr {
  display: flex;
  justify-content: center;
  padding: 1rem;
  background: #ffffff;
  border: 1.5px solid var(--sw-ink);
  border-radius: var(--radius);
  box-shadow: 3px 3px 0 var(--sw-cast);
}

.qr svg {
  width: 100%;
  max-width: 15rem;
  height: auto;
}

.activity {
  margin: 0 0 var(--gap);
  padding: 0;
  list-style: none;
  font-family: var(--sw-mono);
  font-size: 0.72rem;
  color: var(--sw-muted);
}

.activity li {
  display: flex;
  gap: 0.7rem;
  padding: 0.35rem 0;
  border-bottom: 1px dashed var(--sw-faint);
}

.activity time {
  flex: none;
  font-variant-numeric: tabular-nums;
}

.danger__heading {
  border-top-color: var(--sw-danger);
  color: var(--sw-danger);
}

.danger {
  padding: 1rem;
  background: var(--sw-paper);
  border: 2px solid var(--sw-danger);
  border-radius: var(--radius);
  box-shadow: 3px 3px 0 var(--sw-danger-cast);
}

code {
  padding: 0.1rem 0.35rem;
  background: var(--sw-sunken);
  border-radius: 3px;
  font-family: var(--sw-mono);
  font-size: 0.85em;
  color: var(--sw-strong);
}

/* ============================================================
   5. Wider than a phone
   ============================================================ */

@media (min-width: 40rem) {
  .counts {
    grid-template-columns: repeat(4, 1fr);
  }

  .stages {
    grid-template-columns: repeat(2, 1fr);
  }

  .button {
    width: auto;
  }

  .button + .button {
    margin-top: 0;
    margin-left: 0.5rem;
  }

  /* The participant's submit stays full width: it is the only thing on the
     screen at that moment and a thumb should not have to aim. */
  #submit,
  #handover {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }

  .option:hover,
  .option:active,
  .button:hover,
  .button:active {
    transform: none;
  }
}
