/* One stylesheet. The app has a handful of screens and a single job — be
   readable at arm's length, one-handed, in bad light, with chalk on your
   fingers. Everything here serves that.

   Targets are 56px minimum because the user is often holding something.
   Contrast is checked against WCAG 2.2 AA on both themes. */

:root {
  --bg: #fbfaf8;
  --ink: #16181d;
  --muted: #5b6472;
  --line: #e2e0dc;
  /* Blue, deliberately: the accent is "go", and it must never share a hue
     with --danger. A red primary button reads as a warning (Paul, 2026-07-28).
     Both themes hold ≥4.5:1 ink-on-accent (WCAG AA). */
  --accent: #2a5da8;
  --accent-ink: #ffffff;
  --surface: #ffffff;
  --danger: #a3241a;
  --tap: 3.5rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #12131a;
    --ink: #f0f1f5;
    --muted: #9aa6b8;
    --line: #2a2d38;
    --accent: #8fb8f2;
    --accent-ink: #0c1626;
    --surface: #1a1c25;
    --danger: #f08b7f;
  }
}

* {
  box-sizing: border-box;
  margin: 0;
}

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

body {
  background: var(--bg);
  color: var(--ink);
  font: 400 1.0625rem/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}

.app {
  max-width: 32rem;
  margin: 0 auto;
  padding: max(1.5rem, env(safe-area-inset-top)) 1.25rem
    max(1.5rem, env(safe-area-inset-bottom));
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.screen {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  flex: 1;
  padding-block: 1rem;
}

.screen.centred {
  justify-content: center;
  text-align: center;
  align-items: stretch;
}

h1 {
  font-size: 1.9rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-weight: 650;
}

.session-name {
  font-size: 3rem;
  letter-spacing: -0.03em;
}

.exercise-name {
  font-size: 2.1rem;
}

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted);
}

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

.small {
  font-size: 0.9rem;
}

.reason {
  font-size: 0.95rem;
}

.error {
  color: var(--danger);
  font-size: 0.95rem;
}

.or {
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
}

/* --- the weight, which is the point of the screen --- */

.load {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-block: 0.5rem;
}

.load-value {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.35rem;
  flex: 1;
}

.load-input {
  font-size: clamp(3.5rem, 22vw, 5.5rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  width: 100%;
  max-width: 6em;
  text-align: right;
  border: none;
  background: none;
  color: inherit;
  font-family: inherit;
  padding: 0;
  font-variant-numeric: tabular-nums;
}

.load-input:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 4px;
  border-radius: 0.25rem;
}

.load .unit {
  font-size: 1.25rem;
  color: var(--muted);
  font-weight: 500;
}

.load.bodyweight .load-value {
  font-size: 2rem;
  font-weight: 650;
  justify-content: center;
}

.nudge {
  width: var(--tap);
  height: var(--tap);
  flex: none;
  /* Flex-centred, with the base button's padding cleared — a fixed height plus
     inherited vertical padding squeezes the content box. The mark inside is
     drawn rather than typed (see .nudge-icon), so this centres a box whose
     contents are already centred, instead of hoping a font agrees. */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}

/* Two bars, centred by geometry rather than by font metrics. */
.nudge-icon {
  position: relative;
  display: block;
  width: 1.15rem;
  height: 1.15rem;
}

.nudge-bar {
  position: absolute;
  inset: 50% 0 auto 0;
  height: 2px;
  margin-top: -1px;
  background: currentColor;
  border-radius: 1px;
}

.nudge-bar.upright {
  inset: 0 50% auto auto;
  width: 2px;
  height: 100%;
  margin: 0 -1px 0 0;
}

.set-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  font-size: 1.05rem;
}

.set-label {
  color: var(--muted);
}

.reps-input {
  width: 3.5rem;
  height: var(--tap);
  font-size: 1.5rem;
  font-weight: 650;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
  background: var(--surface);
  color: inherit;
  font-family: inherit;
}

.set-target {
  color: var(--muted);
}

/* --- buttons --- */

button {
  font: inherit;
  min-height: var(--tap);
  border-radius: 0.75rem;
  cursor: pointer;
  padding: 0.75rem 1.25rem;
  border: 1px solid transparent;
}

button:disabled {
  opacity: 0.55;
  cursor: default;
}

button:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.primary {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 650;
  border: none;
}

.primary.big {
  min-height: 4rem;
  font-size: 1.2rem;
}

/* The big action never moves. Done, Next set, End session, Start: one spot,
   pinned to the bottom, so mid-session the thumb learns a single position and
   keeps it between clicks (Paul, 2026-07-28). Fixed to the viewport, sized to
   the app column; the screen pads itself so nothing hides underneath. */
.screen .primary.big {
  position: fixed;
  bottom: max(1rem, env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  width: min(100vw - 2.5rem, 29.5rem);
  z-index: 1;
}

.screen:has(.primary.big) {
  padding-bottom: 5.5rem;
}

.secondary {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--line);
  font-weight: 550;
}

.quiet {
  background: none;
  color: var(--muted);
  border: none;
  min-height: 2.75rem;
  font-size: 0.95rem;
}

.choices {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.choice {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  align-items: flex-start;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 1.1rem 1.25rem;
  font-weight: 550;
}

.choice .muted {
  font-size: 0.9rem;
  font-weight: 400;
}

/* --- forms --- */

.stack,
.field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.stack {
  gap: 1rem;
}

label {
  font-weight: 550;
  font-size: 0.95rem;
}

input[type="email"],
input[type="text"]:not(.load-input) {
  min-height: var(--tap);
  border: 1px solid var(--line);
  border-radius: 0.6rem;
  padding: 0 0.9rem;
  font: inherit;
  background: var(--surface);
  color: inherit;
  width: 100%;
}

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

.with-unit .unit {
  color: var(--muted);
}

/* --- rest timer --- */

.timer {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: stretch;
}

.timer-track {
  height: 0.4rem;
  background: var(--line);
  border-radius: 0.2rem;
  overflow: hidden;
}

.timer-bar {
  height: 100%;
  background: var(--accent);
  transition: width 1s linear;
}

.timer-readout {
  font-size: clamp(3rem, 18vw, 4.5rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  text-align: center;
}

.timer-readout.over {
  color: var(--muted);
}

.timer-controls {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
}

.adjust {
  background: var(--surface);
  border-color: var(--line);
  color: var(--ink);
  flex: 1;
  font-variant-numeric: tabular-nums;
}

.up-next {
  font-size: 1.5rem;
}

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

/* --- coaching --- */

.lift-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.lift {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.15rem 1rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.lift-name {
  font-weight: 600;
}

.lift-load {
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  text-align: right;
}

.lift .muted {
  grid-column: 1 / -1;
}

.choice.waiting {
  opacity: 0.7;
  cursor: default;
}

.invite-link {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
}

/* --- the rest of the session, folded --- */

.upcoming {
  border-top: 1px solid var(--line);
  padding-top: 0.9rem;
  margin-top: auto;
}

.upcoming summary {
  color: var(--muted);
  font-size: 0.95rem;
  cursor: pointer;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
}

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

.upcoming-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding-bottom: 0.5rem;
}

.upcoming-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.95rem;
}

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

/* --- a rest day: the session demoted, never locked --- */

.rest-line {
  font-size: 2.2rem;
  letter-spacing: -0.03em;
}

.next-card {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  text-align: left;
}

/* The same name, a size down: the harness and screen readers see one
   .session-name either way, only the emphasis moves. */
.next-card .session-name {
  font-size: 1.5rem;
}

.preview summary {
  color: var(--muted);
  font-size: 0.95rem;
  cursor: pointer;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
}

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

.quiet-row {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
}

/* --- history --- */

.history {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.session {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.session-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.session-day {
  font-weight: 650;
}

.session-lift {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.95rem;
}

/* --- personal bests --- */

/* Screen-reader-only text. The trophy is an emoji, which announces as "trophy"
   or as nothing at all depending on the platform; the sentence is what carries
   the meaning, so it is always there whether or not it is on screen. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.trophies {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 100%;
  padding: 0.9rem 1rem;
  margin: 0.25rem 0 0.5rem;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.trophy-label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  color: var(--accent);
}

/* Emoji ignore currentColor, and are the one thing on the screen that should
   not be tuned for contrast — it is decoration sitting beside real text. */
.trophy {
  font-size: 1.1em;
  line-height: 1;
}

.trophy-row {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.trophy-headline {
  font-weight: 650;
}

.trophy-chip {
  display: inline-flex;
  align-items: center;
  margin-left: 0.4rem;
}

/* --- progress --- */

.progress-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.progress-list > .eyebrow {
  margin: 0;
}

.progress {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.progress-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.progress-name {
  font-weight: 650;
}

.progress-now {
  font-variant-numeric: tabular-nums;
}

/* Scales to the width it is given; the stroke does not scale with it, so a
   line drawn on a phone is the same weight as one drawn on a laptop. */
.spark {
  width: 100%;
  height: auto;
  overflow: visible;
}

.spark-line {
  stroke: var(--ink);
  stroke-width: 1.5;
  stroke-linejoin: round;
  opacity: 0.75;
}

.spark-now {
  fill: var(--ink);
}

/* A best is a diamond as well as a colour: it still reads as a marker in bad
   light, on a bad screen, and to anyone who does not see the accent at all. */
.spark-best {
  fill: var(--accent);
}

.progress p {
  margin: 0;
}
