/* Toastmasters Timekeeper
   Brand palette: Loyal Blue #004165, True Maroon #772432,
                  Cool Gray #A9B2B1, Happy Yellow #F2DF74.
   The timing card uses true signal colours - a pale brand yellow is not
   readable as a warning from the back of a room. */

:root {
  --tm-blue:   #004165;
  --tm-blue-d: #002b43;
  --tm-maroon: #772432;
  --tm-gray:   #A9B2B1;
  --tm-yellow: #F2DF74;

  --sig-white:  #FFFFFF;
  --sig-green:  #00843D;
  --sig-yellow: #FFD100;
  --sig-red:    #C8102E;

  --ink:      #12242e;
  --ink-soft: #4a5c66;
  --paper:    #f4f6f7;
  --card:     #ffffff;
  --line:     #dbe1e4;
  --radius:   14px;
  --shadow:   0 1px 2px rgba(0,65,101,.08), 0 8px 24px rgba(0,65,101,.08);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

/* Any author `display` beats the browser's own [hidden] rule, so elements we
   toggle with el.hidden need this or they stay on screen. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
}

a { color: var(--tm-blue); }

/* ------------------------------------------------------------------ chrome */

.topbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .7rem 1rem;
  background: var(--tm-blue);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 20;
  padding-top: max(.7rem, env(safe-area-inset-top));
}
.topbar h1 { font-size: 1rem; margin: 0; font-weight: 650; letter-spacing: .01em; }
.topbar .sub { font-size: .78rem; opacity: .75; }
.topbar .sub a { color: #fff; text-decoration: underline; }

/* Which meeting you are running, chosen in the header so it costs no vertical
   space and is impossible to miss. */
.mtg-pick {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  margin: 0;
  max-width: 100%;
  border-radius: 6px;
  background: rgba(255,255,255,.14);
  padding: .05rem .35rem .05rem .15rem;
}
.mtg-pick select {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  color: #fff;
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  padding: .1rem .1rem;
  width: auto;
  max-width: 15rem;
  text-overflow: ellipsis;
  cursor: pointer;
}
.mtg-pick select:focus { outline: 2px solid rgba(255,255,255,.6); border-radius: 4px; }
.mtg-pick select option { color: var(--ink); background: #fff; }
.mtg-pick .caret { font-size: .6rem; opacity: .8; pointer-events: none; }
.topbar .spacer { margin-left: auto; }
.topbar a { color: #fff; text-decoration: none; opacity: .9; font-size: .85rem; }
.topbar a:hover { opacity: 1; text-decoration: underline; }
.topbar nav { display: flex; gap: .9rem; align-items: center; }

.wrap { max-width: 60rem; margin: 0 auto; padding: 1rem; }
.wrap.narrow { max-width: 32rem; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1rem;
  margin-bottom: 1rem;
}
.card h2 {
  margin: 0 0 .75rem;
  font-size: .95rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--tm-blue);
}
.card h2 .count { color: var(--ink-soft); text-transform: none; letter-spacing: 0; font-weight: 400; }

.muted { color: var(--ink-soft); }
.small { font-size: .84rem; }
.mono  { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.center { text-align: center; }
.row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }

/* ------------------------------------------------------------------ forms */

label { display: block; font-size: .8rem; font-weight: 600; color: var(--ink-soft); margin-bottom: .25rem; }

input[type=text], input[type=password], input[type=date], input[type=number], select, textarea {
  width: 100%;
  padding: .6rem .7rem;
  font: inherit;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
}
input:focus, select:focus, textarea:focus {
  outline: 3px solid rgba(0,65,101,.18);
  border-color: var(--tm-blue);
}
.field { margin-bottom: .8rem; }
.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr)); gap: .6rem; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  padding: .6rem 1rem;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: var(--tm-blue);
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  text-decoration: none;
  line-height: 1.2;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { background: var(--tm-blue-d); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.ghost { background: #fff; color: var(--tm-blue); border-color: var(--line); }
.btn.ghost:hover { background: #eef2f4; }
.btn.maroon { background: var(--tm-maroon); }
.btn.maroon:hover { background: #5d1c27; }
.btn.danger { background: #fff; color: var(--tm-maroon); border-color: #e3c8cd; }
.btn.danger:hover { background: #fbeff1; }
.btn.sm { padding: .35rem .6rem; font-size: .8rem; border-radius: 8px; }

/* Admin section tabs. An inline grid with equal automatic columns sizes every
   tab to the widest label, so the row reads as one control instead of four
   odd-sized buttons - and stays right if the labels are ever translated. */
.tabs {
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: .5rem;
  max-width: 100%;
}
.tabs .btn { justify-content: center; }

/* Four equal tabs need about 324px, which a phone in portrait (320-390px
   wide, less the page and card padding) cannot give. Squeezed, the grid would
   keep the longest label at full width and shrink the rest - unequal again -
   so below 400px go two by two, where all four stay equal. */
@media (max-width: 25rem) {
  .tabs { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr); }
}

.pill {
  display: inline-block;
  padding: .12rem .5rem;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}
.pill.white  { background: #eceff1; color: #46555e; }
.pill.green  { background: var(--sig-green);  color: #fff; }
.pill.yellow { background: var(--sig-yellow); color: #4a3b00; }
.pill.red    { background: var(--sig-red);    color: #fff; }
.pill.over   { background: var(--tm-maroon);  color: #fff; }
.pill.idle   { background: var(--tm-gray);    color: #1e2c33; }

.logo-preview {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 5.5rem;
  height: 4rem;
  padding: .4rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }

.notice {
  padding: .7rem .9rem;
  border-radius: 10px;
  border: 1px solid;
  margin-bottom: 1rem;
  font-size: .9rem;
}
.notice.err  { background: #fbeff1; border-color: #e3c8cd; color: #6d1f2b; }
.notice.ok   { background: #eaf6ef; border-color: #b9dcc7; color: #12572f; }
.notice.info { background: #eef4f8; border-color: #c5d8e4; color: var(--tm-blue); }

/* ------------------------------------------------------------------ table */

table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th, td { text-align: left; padding: .55rem .5rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
th { font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); font-weight: 700; }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.center, th.center { text-align: center; }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Rows for agenda steps that carry no green-amber-red. */
tr.row-untimed > td { background: #fafbfb; }
tr.row-untimed input[type=text] { color: var(--ink-soft); }
input[type=checkbox] { width: auto; accent-color: var(--tm-blue); }

/* ==================================================== the display screen == */

body.display {
  background: var(--sig-white);
  height: 100dvh;
  overflow: hidden;
}

.stage {
  height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  text-align: center;
  padding: 2.5dvh 3vw;
  position: relative;
}

/* The club name sits in the top strip and inherits the phase's text colour,
   so it stays legible on white, green, yellow and red.
   The session timer is NOT shown here - it is the timekeeper's own running
   total for the report, and lives only on the control page. */
.stage-top {
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 1.6em;
}
.stage-top .club {
  font-size: clamp(.85rem, 2.1vw, 1.7rem);
  font-weight: 700;
  letter-spacing: .04em;
  opacity: .78;
  text-align: left;
}

/* The logo sits on its own white chip so a blue-and-maroon mark stays correct
   and readable when the screen behind it turns green, yellow or red. */
.stage-top .club-logo {
  height: clamp(1.6rem, 4vw, 3.2rem);
  width: auto;
  max-width: 30vw;
  object-fit: contain;
  background: #fff;
  border-radius: 8px;
  padding: .28rem .4rem;
  box-shadow: 0 0 0 1px rgba(0, 65, 101, .10);
  flex: 0 0 auto;
}

.stage-mid {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5dvh;
  min-height: 0;
}

.stage .who {
  font-size: clamp(1.4rem, 5.5vw, 4.5rem);
  font-weight: 700;
  line-height: 1.1;
  max-width: 92vw;
  overflow-wrap: break-word;
}
.stage .role {
  font-size: clamp(.9rem, 2.6vw, 2rem);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  opacity: .72;
}
.stage .clock {
  font-size: clamp(4rem, 22vw, 18rem);
  font-weight: 800;
  line-height: .95;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: -.02em;
}
.stage .target {
  font-size: clamp(.85rem, 2.2vw, 1.6rem);
  opacity: .62;
  font-variant-numeric: tabular-nums;
}
.stage .hint {
  font-size: clamp(.7rem, 1.6vw, 1rem);
  opacity: .5;
  padding-bottom: env(safe-area-inset-bottom);
  min-height: 1.2em;
  /* Its opacity makes it a stacking context spanning the full width, which
     would otherwise swallow clicks aimed at the full-screen button. */
  pointer-events: none;
}
.stage .demo-flag, .stage .stale-flag { pointer-events: none; }

/* Signal states. Text colour flips for contrast on each ground. */
body.display[data-phase="white"]  { background: var(--sig-white);  color: var(--tm-blue); }
body.display[data-phase="green"]  { background: var(--sig-green);  color: #fff; }
body.display[data-phase="yellow"] { background: var(--sig-yellow); color: #3d3100; }
body.display[data-phase="red"]    { background: var(--sig-red);    color: #fff; }
body.display[data-phase="over"]   { background: var(--sig-red);    color: #fff; animation: overpulse 1s steps(1, end) infinite; }
body.display[data-phase="idle"]   { background: var(--sig-white);  color: var(--tm-gray); }

@keyframes overpulse {
  0%, 100% { background-color: var(--sig-red); }
  50%      { background-color: var(--tm-maroon); }
}
@media (prefers-reduced-motion: reduce) {
  body.display[data-phase="over"] { animation: none; }
}

/* Quiet "the clock is running" marker. Inherits the phase's text colour, so it
   stays legible on white, green, amber and red without drawing the eye. */
.run-flag {
  position: absolute;
  top: max(1.2dvh, env(safe-area-inset-top));
  right: 1.5vw;
  display: flex;
  align-items: center;
  gap: .45em;
  font-size: clamp(.65rem, 1.5vw, 1.05rem);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: .5;
  pointer-events: none;
}
.run-flag svg { width: 1.5em; height: 1.5em; display: block; }
.run-dot {
  width: .5em;
  height: .5em;
  border-radius: 50%;
  background: currentColor;
  animation: runpulse 1.6s ease-in-out infinite;
}
@keyframes runpulse { 0%, 100% { opacity: 1; } 50% { opacity: .1; } }

.run-flag[data-state="paused"] { opacity: .32; }
.run-flag[data-state="paused"] .run-dot { animation: none; opacity: .45; }

@media (prefers-reduced-motion: reduce) { .run-dot { animation: none; } }

/* On a phone-sized display the word would crowd the corner. */
@media (max-width: 30rem) { .run-flag .run-label { display: none; } }

/* Marks a held colour as a demonstration, so nobody walking in mistakes it
   for a speaker who is genuinely over time. */
.demo-flag {
  position: absolute;
  top: max(1.2dvh, env(safe-area-inset-top));
  right: 1.5vw;
  font-size: clamp(.7rem, 1.5vw, 1rem);
  font-weight: 800;
  letter-spacing: .18em;
  padding: .2rem .7rem;
  border-radius: 999px;
  background: rgba(255,255,255,.9);
  color: var(--tm-blue);
}

/* ------------------------------------------------ voting on the display -- */

.vote-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(.8rem, 2.5vw, 2rem);
  background: #fff;
  color: var(--tm-blue);
  border-radius: 16px;
  padding: clamp(.7rem, 1.8vw, 1.4rem);
  box-shadow: 0 6px 30px rgba(0,0,0,.18);
}
.vote-panel .vote-qr { line-height: 0; }
.vote-panel .vote-qr svg { display: block; width: 100%; height: 100%; }
.vote-panel .vote-title {
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.vote-panel .vote-link { font-variant-numeric: tabular-nums; opacity: .8; word-break: break-all; }

/* Nothing being timed: the vote takes the middle of the screen. */
body.display[data-voting="full"] .stage-mid { display: none; }
body.display[data-voting="full"] .vote-panel {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  flex-direction: column;
  text-align: center;
}
body.display[data-voting="full"] .vote-qr { width: min(42vh, 42vw); height: min(42vh, 42vw); }
body.display[data-voting="full"] .vote-title { font-size: clamp(1rem, 3vw, 2.4rem); }
body.display[data-voting="full"] .vote-link  { font-size: clamp(.85rem, 2.2vw, 1.8rem); }

/* A speech is running: the signal colour keeps the room, the vote steps aside. */
body.display[data-voting="compact"] .vote-panel {
  position: absolute;
  right: 1.5vw;
  bottom: max(1.5dvh, env(safe-area-inset-bottom));
  max-width: 34vw;
}
body.display[data-voting="compact"] .vote-qr { width: clamp(4rem, 11vh, 8rem); height: clamp(4rem, 11vh, 8rem); }
body.display[data-voting="compact"] .vote-title { font-size: clamp(.65rem, 1.3vw, 1rem); }
body.display[data-voting="compact"] .vote-link  { font-size: clamp(.6rem, 1.1vw, .9rem); }
body.display[data-voting="compact"] .stale-flag { display: none; }

/* ------------------------------------------------- voting on the phone --- */

.vote-card { border-left: 4px solid var(--tm-blue); }
.poll-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--line);
}
.poll-row:last-of-type { border-bottom: 0; }
.poll-row .poll-name { font-weight: 700; }
.poll-row .poll-meta { font-size: .76rem; color: var(--ink-soft); }
.poll-row[data-status="open"] { background: #eaf6ef; border-radius: 8px; padding-left: .5rem; padding-right: .5rem; }
.pill.white { background: #eceff1; color: #46555e; }

/* ------------------------------------------------------ the vote page ---- */

body.votepage .topbar { gap: .6rem; }
body.votepage .vote-logo {
  height: 1.9rem; width: auto; background: #fff;
  border-radius: 6px; padding: .2rem .3rem;
}
.poll .poll-label { margin-bottom: .8rem; }
.poll-choices { display: grid; gap: .55rem; }

/* Choosing is a radio, so it is reversible and keyboard-navigable; the vote is
   only cast by the submit button below. */
.choice {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  text-align: left;
  font: inherit;
  padding: .95rem 1rem .95rem 2.9rem;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.choice .choice-name   { font-weight: 700; font-size: 1.02rem; }
.choice .choice-detail { font-size: .8rem; color: var(--ink-soft); }

/* The radio itself, drawn rather than hidden so its state is always visible. */
.choice-radio {
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.25rem;
  height: 1.25rem;
  margin: 0;
  accent-color: var(--tm-blue);
}
.choice:hover { border-color: var(--tm-blue); }
.choice:has(.choice-radio:focus-visible) { outline: 3px solid rgba(0,65,101,.25); }

.choice.is-picked { border-color: var(--tm-blue); background: #eef4f8; }

.choice.is-mine {
  border-color: var(--sig-green);
  background: #eaf6ef;
}
.choice.is-mine .choice-name::after { content: " ✓"; color: var(--sig-green); }
.choice:has(.choice-radio:disabled) { cursor: default; }
.choice:has(.choice-radio:disabled):not(.is-mine) { opacity: .55; }

.poll-submit { width: 100%; margin-top: .9rem; padding: .85rem 1rem; font-size: 1.02rem; }

/* Full-screen toggle. Inherits the phase's text colour so it stays readable on
   white, green, amber and red, and fades away when the screen is left alone. */
.fs-btn {
  position: absolute;
  z-index: 2;              /* above the decorative strips sharing this corner */
  bottom: max(1.5dvh, env(safe-area-inset-bottom));
  left: 1.5vw;
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: 0;
  transition: opacity .25s ease;
  -webkit-tap-highlight-color: transparent;
  /* Invisible must also mean untouchable: a hidden button you can still hit
     would put the surprise fullscreen straight back. A tap there wakes it
     instead, and a second tap activates it. */
  pointer-events: none;
}
.fs-btn.is-awake { opacity: .45; pointer-events: auto; }
.fs-btn:hover,
.fs-btn:focus-visible { opacity: .9; outline: none; }
.fs-btn svg { width: 1.2rem; height: 1.2rem; display: block; }

/* Keyboard users should always be able to find it, awake or not. */
.fs-btn:focus-visible {
  opacity: 1;
  pointer-events: auto;
  box-shadow: 0 0 0 3px rgba(127,127,127,.35);
}

@media (prefers-reduced-motion: reduce) { .fs-btn { transition: none; } }

.stale-flag {
  position: absolute;
  bottom: max(1.5dvh, env(safe-area-inset-bottom));
  right: 1.5vw;
  font-size: .8rem;
  font-weight: 700;
  padding: .25rem .6rem;
  border-radius: 999px;
  background: rgba(0,0,0,.28);
  color: #fff;
}
body.display[data-phase="white"] .stale-flag,
body.display[data-phase="idle"] .stale-flag { background: rgba(0,65,101,.15); color: var(--tm-blue); }

/* ==================================================== the phone control == */

body.control { background: var(--paper); }

.ctrl-status {
  border-radius: var(--radius);
  padding: 1rem;
  text-align: center;
  color: #fff;
  margin-bottom: 1rem;
  border: 1px solid transparent;
}
.ctrl-status[data-phase="white"]  { background: #fff; color: var(--tm-blue); border-color: var(--line); }
.ctrl-status[data-phase="idle"]   { background: #fff; color: var(--ink-soft); border-color: var(--line); }
.ctrl-status[data-phase="green"]  { background: var(--sig-green); }
.ctrl-status[data-phase="yellow"] { background: var(--sig-yellow); color: #3d3100; }
.ctrl-status[data-phase="red"]    { background: var(--sig-red); }
.ctrl-status[data-phase="over"]   { background: var(--tm-maroon); }

.ctrl-status .who   { font-size: 1.1rem; font-weight: 700; }
.ctrl-status .role  { font-size: .75rem; text-transform: uppercase; letter-spacing: .08em; opacity: .8; }
.ctrl-status .clock { font-size: 3.4rem; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.05; margin: .3rem 0; }
.ctrl-status .target { font-size: .8rem; opacity: .8; font-variant-numeric: tabular-nums; }

/* The session timer sits visually apart from the speaker transport so the two
   are never confused mid-meeting. */
.sess-card { border-left: 4px solid var(--tm-maroon); }

.sess-status {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem .75rem;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: #fff;
}
.sess-status .sess-name   { font-weight: 700; }
.sess-status .sess-target { font-size: .75rem; color: var(--ink-soft); }
.sess-status .sess-clock  { font-size: 1.9rem; font-weight: 800; font-variant-numeric: tabular-nums; }

.sess-status[data-phase="green"]  { border-color: var(--sig-green); }
.sess-status[data-phase="yellow"] { border-color: var(--sig-yellow); }
.sess-status[data-phase="red"],
.sess-status[data-phase="over"] {
  border-color: var(--sig-red);
  background: #fbeff1;
}
.sess-status[data-phase="red"] .sess-clock,
.sess-status[data-phase="over"] .sess-clock { color: var(--sig-red); }

/* ------------------------------------------------ demo the signals ------ */

.demo-card > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
}
.demo-card > summary::-webkit-details-marker { display: none; }
.demo-card > summary::before {
  content: "▸";
  color: var(--tm-blue);
  font-size: .9rem;
}
.demo-card[open] > summary::before { content: "▾"; }
.demo-card.demo-on { border-color: var(--sig-red); box-shadow: 0 0 0 2px rgba(200,16,46,.16), var(--shadow); }
.demo-live { margin-left: auto; }

.demo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr)); gap: .5rem; }

.demo-swatch {
  font: inherit;
  font-weight: 700;
  border: 2px solid transparent;
  border-radius: 12px;
  padding: 1.1rem .5rem;
  cursor: pointer;
  color: #fff;
  -webkit-tap-highlight-color: transparent;
}
.demo-swatch[data-phase="white"]  { background: #fff; color: var(--tm-blue); border-color: var(--line); }
.demo-swatch[data-phase="green"]  { background: var(--sig-green); }
.demo-swatch[data-phase="yellow"] { background: var(--sig-yellow); color: #3d3100; }
.demo-swatch[data-phase="red"]    { background: var(--sig-red); }
.demo-swatch[data-phase="over"]   { background: var(--tm-maroon); }
.demo-swatch.demo-end { background: #fff; color: var(--ink-soft); border-color: var(--line); }

/* The colour currently held on the display. */
.demo-swatch.is-on {
  border-color: var(--tm-blue);
  box-shadow: 0 0 0 3px rgba(0,65,101,.22);
}
.demo-swatch.is-on span::after { content: " ●"; font-size: .7em; vertical-align: middle; }

.bigbtns { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.bigbtns .btn { padding: 1.1rem .8rem; font-size: 1.05rem; border-radius: 12px; }
.bigbtns .span2 { grid-column: 1 / -1; }

.agenda-list { list-style: none; margin: 0; padding: 0; }
.agenda-list li {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .6rem .5rem;
  border-bottom: 1px solid var(--line);
}
.agenda-list li:last-child { border-bottom: 0; }
/* The armed row is the transport now, so it needs to be obvious. */
.agenda-list li.active {
  background: #eef4f8;
  border-radius: 8px;
  box-shadow: inset 3px 0 0 var(--tm-blue);
  padding-left: .7rem;
}
/* Fixed width stops the row shuffling as the label cycles Arm/Start/Stop. */
.agenda-list .js-row-go { min-width: 4.6rem; padding-top: .5rem; padding-bottom: .5rem; }
.agenda-list .idx {
  flex: 0 0 1.6rem; height: 1.6rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--tm-blue); color: #fff;
  font-size: .75rem; font-weight: 700;
}
.agenda-list li.done .idx { background: var(--tm-gray); color: #1e2c33; }
/* The name doubles as its own edit field: tap it and type. */
.agenda-list .nm { font-weight: 600; cursor: text; min-height: 1.3em; }
.agenda-list .nm:hover { text-decoration: underline dotted; text-underline-offset: 3px; }
.agenda-list .nm[data-editing] { text-decoration: none; }
.agenda-list .meta { font-size: .76rem; color: var(--ink-soft); }

input.nm-input {
  width: 100%;
  font: inherit;
  font-weight: 600;
  padding: .2rem .45rem;
  border: 2px solid var(--tm-blue);
  border-radius: 8px;
  background: #fff;
}
input.nm-input:focus { outline: 3px solid rgba(0,65,101,.18); }

.agenda-list .item-actions { display: flex; gap: .3rem; flex-shrink: 0; align-items: center; }

/* Remove-from-agenda. Quiet by design, and furthest from the Arm/Start button
   so a thumb reaching for the primary action cannot catch it. */
.btn-x {
  flex: 0 0 auto;
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  padding: 0;
  font: inherit;
  font-size: 1.15rem;
  line-height: 1;
  color: var(--tm-gray);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.btn-x:hover, .btn-x:focus-visible {
  color: var(--tm-maroon);
  border-color: #e3c8cd;
  background: #fbeff1;
  outline: none;
}

/* Agenda steps with no green-amber-red sit quieter in the list. */
.agenda-list li.untimed .idx { background: #fff; color: var(--ink-soft); border: 1px dashed var(--tm-gray); }
.agenda-list li.untimed .nm  { font-weight: 500; }
.nosig { font-style: italic; opacity: .8; }

.conn {
  font-size: .74rem;
  padding: .1rem .5rem;
  border-radius: 999px;
  background: rgba(255,255,255,.18);
}
.conn[data-state="down"] { background: var(--tm-maroon); }

/* Live clock in the sticky header, so the agenda can be driven from anywhere
   on the page without scrolling back to the status card. */
.topclock {
  font-size: 1rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  padding: .12rem .5rem;
  border-radius: 8px;
  background: rgba(255,255,255,.18);
  color: #fff;
  line-height: 1.35;
}
.topclock[data-phase="white"],
.topclock[data-phase="idle"]   { background: #fff; color: var(--tm-blue); }
.topclock[data-phase="green"]  { background: var(--sig-green);  color: #fff; }
.topclock[data-phase="yellow"] { background: var(--sig-yellow); color: #3d3100; }
.topclock[data-phase="red"]    { background: var(--sig-red);    color: #fff; }
.topclock[data-phase="over"]   { background: var(--sig-red); color: #fff; animation: overpulse 1s steps(1, end) infinite; }

/* ------------------------------------------------------------------ print */

@media print {
  .topbar, .btn, .noprint { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; border: 0; padding: 0; }
  .wrap { max-width: none; padding: 0; }
  table { font-size: 11pt; }
  th, td { border-bottom: 1px solid #999; }
}
