/* # Every style in the app: auth screen, tracker, session list, and the tour
   replay. — one design system, one dark theme, DM Sans/Manrope typography.

   THE DESIGN SYSTEM
   Three colours, two fonts, and a handful of scales. Every rule below reads
   from these tokens; nothing carries its own hex value, radius, or font size.

   - --bg       the one background colour
   - --primary  the one primary colour: text, primary buttons, selected states
   - --accent   the one accent colour: focus rings, progress, emphasis, the mark
   - surfaces, borders, and muted text are mixed from --bg and --primary so the
     whole grey ramp follows those two colours
   - --danger is the only extra colour and only ever marks a destructive confirm

   Buttons, cards, inputs, chips, and segmented controls each have exactly one
   recipe, declared once in the "Shared recipes" section and reused everywhere. */

/* Tokens */
:root {
  /* Colours */
  --bg: #080808;
  --primary: #f5f5f7;
  --accent: #c8f04c;
  --danger: #ff7a70;

  /* Derived greys: cards, controls, and hover states step up from the
     background toward the primary colour in even increments. */
  --surface: color-mix(in srgb, var(--bg) 95%, var(--primary));
  --surface-2: color-mix(in srgb, var(--bg) 89%, var(--primary));
  --surface-3: color-mix(in srgb, var(--bg) 82%, var(--primary));
  --line: color-mix(in srgb, var(--bg) 87%, var(--primary));
  --line-strong: color-mix(in srgb, var(--bg) 78%, var(--primary));
  --text: var(--primary);
  --muted: color-mix(in srgb, var(--primary) 64%, var(--bg));
  --on-primary: var(--bg);
  --accent-soft: color-mix(in srgb, var(--accent) 18%, transparent);
  --danger-soft: color-mix(in srgb, var(--danger) 16%, var(--bg));
  --danger-line: color-mix(in srgb, var(--danger) 35%, var(--bg));

  /* Fonts */
  --font-body: "DM Sans", Arial, sans-serif;
  --font-heading: "Manrope", Arial, sans-serif;

  /* Type scale */
  --text-xs: 11px;
  --text-sm: 12px;
  --text-md: 13px;
  --text-base: 14px;
  --text-lg: 16px;
  --text-xl: 20px;
  --text-2xl: 24px;
  --text-3xl: 32px;
  --text-4xl: 40px;
  --text-h1: clamp(34px, 4.5vw, 50px);
  --text-display: clamp(44px, 5.5vw, 76px);

  /* Radius scale: chips, controls, segmented containers, cards, circles. */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-full: 999px;

  /* Spacing scale */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;

  /* Component metrics */
  --control-h: 48px;
  --card-pad: var(--space-6);

  /* Depth: cards sit on the base, controls on cards, floating cards throw a
     layered shadow tinted with the background. */
  --shadow-lift: 0 1px 2px rgb(8 8 8 / .45), 0 8px 20px -8px rgb(8 8 8 / .7);
  --shadow-float: 0 1px 2px rgb(8 8 8 / .5), 0 24px 64px -16px rgb(8 8 8 / .85);

  /* Motion: transform and opacity only, spring-style easing. */
  --dur: 160ms;
  --ease: cubic-bezier(.2, .8, .2, 1);

  color-scheme: dark;
  font-family: var(--font-body);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  background: var(--bg);
  color: var(--text);
}
/* Every element: include padding and borders in its width and height. */
* {
  box-sizing: border-box;
}
/* Browser-drawn surfaces: selection, caret, scrollbars, and native control
   accents default to the platform's own colours. Pull them onto the system. */
::selection {
  background: var(--surface-3);
  color: var(--text);
}
html {
  caret-color: var(--text);
  accent-color: var(--accent);
  scrollbar-color: var(--line-strong) var(--bg);
}
/* Whole page: remove the browser's default outer spacing. */
body {
  margin: 0;
}

/* Startup skeleton: visibility also keeps unfinished controls out of keyboard
   navigation and the accessibility tree. No artificial minimum loading delay. */
.loading-screen {
  display: none;
}
html[data-loading] body > :not(.loading-screen):not(noscript) {
  visibility: hidden;
}
html[data-loading] .loading-screen {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 1000;
  overflow: auto;
  background: var(--bg);
}
.loading-layout {
  max-width: 1180px;
  margin: 0 auto;
  padding: var(--space-8) clamp(20px, 5vw, 64px);
}
.loading-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--line);
}
/* A finite, gentle pulse signals activity without continuous animation. */
.skeleton {
  display: block;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  animation: skeleton-pulse 1.6s ease-in-out 8;
}
.loading-logo { width: 112px; height: 28px; }
.loading-nav { width: 35%; height: 18px; }
.loading-avatar { width: 40px; height: 40px; border-radius: var(--radius-full); }
.loading-intro { padding: var(--space-12) 0 var(--space-8); }
.loading-kicker { width: 160px; height: 10px; margin-bottom: var(--space-5); }
.loading-title { width: min(380px, 90%); height: 44px; margin-bottom: var(--space-4); }
.loading-subtitle { width: min(280px, 75%); height: 14px; }
.loading-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.loading-label { width: min(120px, 80%); height: 12px; margin-bottom: var(--space-6); }
.loading-value { width: 58px; height: 34px; }
.loading-panel { margin-top: var(--space-6); }
.loading-row { height: 54px; margin-top: var(--space-4); }
@keyframes skeleton-pulse {
  50% { opacity: .55; }
}
/* Stack cards on small phones and honor the user's motion preference. */
@media (max-width: 540px) {
  .loading-intro { padding-top: var(--space-10); }
  .loading-nav { display: none; }
  .loading-cards { grid-template-columns: 1fr; gap: var(--space-3); }
  .loading-card { display: flex; align-items: center; justify-content: space-between; }
  .loading-card .loading-label { margin: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

/* Base elements */
/* Buttons and text fields: use the surrounding text's font settings. */
button, input, textarea {
  font: inherit;
}
/* Page and form controls: use the body font. */
body, button, input, textarea, select {
  font-family: var(--font-body);
}
/* Buttons, links, and text fields: remove the coloured flash when tapped. */
button, a, input, textarea {
  -webkit-tap-highlight-color: transparent;
}
/* Buttons and links: make touch taps work smoothly. */
button, a {
  touch-action: manipulation;
}
/* All links: use the surrounding text colour and remove underlines. */
a {
  color: inherit;
  text-decoration: none;
}
/* All buttons: show a hand cursor when hovered. */
button {
  cursor: pointer;
}
/* Unavailable buttons: fade them and use the normal cursor. */
button:disabled {
  opacity: .35;
  cursor: default;
}
/* Keyboard navigation: one accent ring on every focused control. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* Headings and the replay logo: use the heading font. */
h1, h2, h3, .logo {
  font-family: var(--font-heading);
  font-weight: 600;
}
/* Main page titles: size, line spacing, tight tracking, and outer spacing. */
h1 {
  font-size: var(--text-h1);
  line-height: 1.07;
  letter-spacing: -.03em;
  margin: var(--space-4) 0;
}
/* Emphasised words in the main title, such as "Your progress.": the accent colour, same font. */
h1 em {
  font-style: normal;
  color: var(--accent);
}
/* Section titles: size and spacing. */
h2 {
  font-size: var(--text-xl);
  letter-spacing: -.02em;
  margin: 0;
}
/* Subsection titles: size and spacing. */
h3 {
  font-size: var(--text-lg);
  margin: 0 0 var(--space-2);
}
/* Supporting text and helpful instructions: size and generous line spacing. */
.muted, .hint {
  font-size: var(--text-base);
  line-height: 1.7;
}
/* Supporting text across forms, history, sign-in, and dialogs: the muted colour. */
.muted, .hint, .eyebrow, .date-row, .counter-foot, legend, .notes-label,
.count-wrap > span, .stats span, .session time, .session-total small,
.local-note, .empty p, .history-filter label, .metric-fields label,
.auth-box label, .profile-panel label, .auth-disclosure, dialog p,
.ace-note p, .ace-welcome p, .session-note {
  color: var(--muted);
}
/* Small labels above headings, such as "A NOTE FROM ACE": compact, spaced lettering. */
.eyebrow {
  font-size: var(--text-xs);
  letter-spacing: .1em;
  font-weight: 600;
}
/* Hidden screens and controls: keep them out of the page layout. */
[hidden] {
  display: none !important;
}
/* "Skip to content" link: keep it above the visible page until focused. */
.skip {
  position: absolute;
  top: -80px;
  background: var(--primary);
  color: var(--on-primary);
  padding: var(--space-4);
  border-radius: var(--radius-md);
}
/* "Skip to content" link: show it when selected with the keyboard. */
.skip:focus {
  top: var(--space-3);
  left: var(--space-3);
}

/* Shared recipes */
/* Cards: panels, the next-session banner, Ace's notes, dialogs, and the
   loading skeleton all share one surface, border, radius, and padding. */
.panel, .dashboard-actions, .ace-note, .ace-welcome, dialog,
.loading-card, .loading-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  padding: var(--card-pad);
}
/* Buttons: every button shares one height, radius, type, and motion. */
.save, .secondary, .text-button, .guest-button, .dialog-actions button,
.adjust, .avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: 0 var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  font-size: var(--text-md);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
}
/* Primary buttons: Continue, Save session, Save profile, Log a session, tour Next. */
.save {
  width: 100%;
  justify-content: space-between;
  margin-top: var(--space-5);
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
/* Secondary buttons: Resend code, Download sessions, Show me around, Log out,
   Continue without login, tour Back, and dialog choices. */
.secondary, .guest-button, .dialog-actions button {
  background: var(--surface-2);
  border-color: var(--line-strong);
}
/* Ghost buttons: Reset count, Show more sessions, Delete, and Skip tour. */
.text-button {
  min-height: 40px;
  padding: 0 var(--space-2);
  color: var(--muted);
}
/* Destructive confirm: the only place the danger colour appears. */
.dialog-actions .confirm-delete {
  background: var(--danger-soft);
  border-color: var(--danger-line);
  color: var(--danger);
}
/* Round buttons: the counter's minus and plus, and the profile avatar. */
.adjust, .avatar {
  padding: 0;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
/* Segmented controls: the app navigation and the Log in / Create profile switch. */
.app-nav, .auth-tabs {
  display: flex;
  gap: var(--space-1);
  padding: var(--space-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
}
.app-nav a, .auth-tabs button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--muted);
  font-size: var(--text-md);
  font-weight: 500;
}
.app-nav a[aria-current="page"], .auth-tabs button[aria-pressed="true"] {
  background: var(--surface-3);
  color: var(--text);
}
/* Inputs: date, notes, sign-in, profile, dropdowns, and sport stats. */
input[type="date"], textarea, .auth-box input, select, .profile-panel input,
.metric-fields input {
  width: 100%;
  min-height: var(--control-h);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  color: var(--text);
  font-size: var(--text-base);
}
::placeholder {
  color: var(--muted);
  opacity: 1;
}
/* Chips: the session count badge and saved sport stats. */
.badge, .session-metrics span {
  display: inline-block;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--muted);
  font-size: var(--text-sm);
}
/* Pill label, such as "MANUAL ENTRY": a bordered chip with an accent dot. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--muted);
  font-size: var(--text-xs);
  letter-spacing: .1em;
  white-space: nowrap;
}
.pill span {
  width: 5px;
  height: 5px;
  border-radius: var(--radius-full);
  background: var(--accent);
}

/* Shell, header, navigation */
/* Main app container: center the content and limit its width. */
.shell {
  max-width: 1120px;
  padding: 0 var(--space-10);
  margin: auto;
}
/* Top header: arrange the logo, navigation links, and profile button. */
header {
  height: 88px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
}
/* The "replay." logo: size and bold lettering. */
.logo {
  display: inline-flex;
  align-items: center;
  font-weight: 800;
  font-size: 28px;
  letter-spacing: -.05em;
}
/* Rewind symbol beside the replay logo: the accent colour. */
.mark {
  font-size: 18px;
  letter-spacing: -7px;
  margin-right: var(--space-4);
  color: var(--accent);
}
/* Round profile shortcut button in the header: fixed size. */
.avatar {
  width: 44px;
  height: 44px;
  min-height: 44px;
  font-weight: 700;
}
/* Symbols beside navigation link labels: size. */
.nav-icon {
  font-size: 18px;
  line-height: 1;
}
/* Bottom footer: arrange the replay name and closing messages. */
footer {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  border-top: 1px solid var(--line);
  padding: var(--space-6) 0;
  font-size: var(--text-sm);
}
/* Small supporting text in the footer: spacing and size. */
footer .muted {
  margin-left: var(--space-3);
  font-size: var(--text-xs);
}

/* Intro and Ace */
/* Page introduction: arrange the title and the note from Ace. */
.intro {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-10) 0 var(--space-8);
}
/* "A NOTE FROM ACE" card: arrange Ace and the encouragement text. */
.ace-note {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
/* Encouragement text inside the Ace note: size and spacing. */
.ace-note p {
  font-size: var(--text-sm);
  line-height: 1.7;
  margin: var(--space-1) 0 0;
}
/* Log session and History pages: hide the introductory Ace note. */
body[data-screen="practice"] .ace-note, body[data-screen="history"] .ace-note {
  display: none;
}
/* Ace character: the face shape, shading, and tilt, drawn from the primary colour. */
.ace {
  position: relative;
  width: 58px;
  height: 64px;
  flex-shrink: 0;
  border-radius: 45% 45% 39% 39%;
  background: radial-gradient(
    circle at 30% 20%,
    var(--primary) 5%,
    color-mix(in srgb, var(--primary) 90%, var(--bg)) 55%,
    color-mix(in srgb, var(--primary) 58%, var(--bg)) 100%
  );
  transform: rotate(-9deg);
  box-shadow: inset -6px -8px 12px rgb(8 8 8 / .15);
}
/* Ace's eyes: place the two eyes next to each other. */
.eyes {
  display: flex;
  justify-content: center;
  gap: 10px;
  padding-top: 24px;
}
/* Each of Ace's eyes: the small dark oval. */
.eyes i {
  width: 5px;
  height: 9px;
  border-radius: 50%;
  background: var(--bg);
}
/* Ace's smile: the curved mouth. */
.smile {
  width: 17px;
  height: 10px;
  border-bottom: 2px solid var(--surface-3);
  border-radius: 50%;
  margin: var(--space-1) auto;
}
/* Robot version of Ace: rounded corners and a slight tilt. */
.robot {
  border-radius: var(--radius-xl);
  transform: rotate(-6deg);
}
/* Robot Ace's antenna: the small piece above the head. */
.robot::before {
  content: "";
  position: absolute;
  top: -9px;
  left: calc(50% - 3px);
  width: 6px;
  height: 12px;
  border-radius: var(--space-1);
  background: color-mix(in srgb, var(--primary) 90%, var(--bg));
}
/* Robot Ace's side pieces: the details on both sides of the head. */
.robot::after {
  content: "";
  position: absolute;
  left: -5px;
  right: -5px;
  top: 25px;
  height: 15px;
  border-left: 5px solid color-mix(in srgb, var(--primary) 72%, var(--bg));
  border-right: 5px solid color-mix(in srgb, var(--primary) 72%, var(--bg));
  border-radius: var(--space-1);
}

/* Panels and shared controls */
/* Main practice area: the practice form and history column side by side. */
.workspace {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: var(--space-6);
  align-items: start;
}
/* Main practice area in single-column mode: one column. */
.workspace.single-column {
  grid-template-columns: 1fr;
}
/* Top row of each card: align its title with its label or count. */
.section-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
/* Practice and profile feedback messages: reserve space and style the text. */
#status {
  min-height: var(--space-6);
  margin: var(--space-4) 0 0;
  font-size: var(--text-md);
  color: var(--muted);
}
/* A message only exists after something happened, so give it a surface then.
   Empty it stays a reserved gap and draws nothing. */
#status:not(:empty) {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--text);
}

/* Log-a-session form */
/* Grouped practice form fields: remove default borders and spacing. */
fieldset {
  padding: 0;
  margin: 0;
  border: 0;
  min-width: 0;
}
/* Numbered practice steps and the notes label: size and spacing. */
legend, .notes-label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: .06em;
  margin-bottom: var(--space-3);
}
/* Text beside the practice step numbers: colour, size, and spacing. */
legend span, .notes-label span {
  color: var(--text);
  font-size: var(--text-md);
  font-weight: 500;
  letter-spacing: 0;
  margin-left: var(--space-2);
}
/* "Something to work on" label: place it on its own line. */
.notes-label {
  display: block;
}
/* "OPTIONAL" beside the notes label: small, spaced lettering. */
.notes-label small {
  font-size: var(--text-xs);
  margin-left: var(--space-2);
  letter-spacing: .1em;
}
/* Sport choices: Basketball, Tennis, Football, and Running in four columns. */
.sports {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
}
/* Each sport choice: a clickable area for its radio input. */
.sports label {
  position: relative;
  cursor: pointer;
}
/* Sport radio inputs: keep them clickable while hiding their default appearance. */
.sports input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}
/* Visible sport choice cards: the secondary control recipe, stacked. */
.sports label > span {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-1);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  font-size: var(--text-md);
  font-weight: 500;
  color: var(--muted);
  background: var(--surface-2);
}
/* Symbols inside sport choice cards: size and weight. */
.sports b {
  font-size: var(--text-2xl);
  font-weight: 400;
  line-height: 1;
}
/* Selected sport card: the primary colour, like a pressed primary button. */
.sports input:checked + span {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
/* Sport card selected with the keyboard: the same accent ring as everything else. */
.sports input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* Session date row: align the label with the date input. */
.date-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-5) 0 var(--space-6);
  font-size: var(--text-sm);
}
/* Session date input: maximum width. */
input[type="date"] {
  max-width: 190px;
}
/* "Count your mistakes" section: a dividing line and top spacing. */
.count-field {
  border-top: 1px solid var(--line);
  padding-top: var(--space-5);
}
/* "Count your mistakes" heading: leave room beside its text. */
.count-field legend {
  padding-right: var(--space-3);
  margin: 0;
}
/* Short instructions under form headings: small text with no outer spacing. */
.hint {
  font-size: var(--text-sm);
  margin: 0;
}
/* Mistake counter row: the minus button, number, and plus button. */
.counter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-3);
}
/* Minus and plus buttons: large round targets. */
.adjust {
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  font-size: 28px;
  font-weight: 400;
}
/* Plus button: the primary colour. */
.add {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
/* Mistake number and its caption: center the content. */
.count-wrap {
  text-align: center;
  min-width: 0;
}
/* Editable mistake total: a large centered number. */
#mistakes {
  width: 100%;
  max-width: 215px;
  border: 0;
  background: transparent;
  color: var(--text);
  text-align: center;
  font-family: var(--font-heading);
  font-size: clamp(48px, 6vw, 76px);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.04em;
  appearance: textfield;
  padding: 0;
}
/* Long mistake totals: reduce the font size so the number fits. */
#mistakes.large-count {
  font-size: clamp(28px, 7vw, 46px);
  letter-spacing: -.02em;
}
/* Mistake number input: hide the browser's built-in up and down arrows. */
#mistakes::-webkit-inner-spin-button, #mistakes::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* "mistakes this session" caption: below the number. */
.count-wrap > span {
  display: block;
  font-size: var(--text-xs);
}
/* Row below the counter: the Reset count button. */
.counter-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  font-size: var(--text-sm);
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-6);
}
/* Optional sport stats section: space before the notes field. */
.sport-metrics {
  margin-bottom: var(--space-6);
}
/* Sport stat input area: fields in two columns. */
.metric-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin: var(--space-4) 0;
}
/* Labels above sport stat inputs: text and bottom spacing. */
.metric-fields label {
  display: block;
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
}
/* "Something to work on" notes box: vertical resizing and text spacing. */
textarea {
  resize: vertical;
  line-height: 1.6;
}
/* "Saved on this browser" message: centered below Save session. */
.local-note {
  text-align: center;
  font-size: var(--text-sm);
  margin: var(--space-3) 0 0;
}

/* Overview and history */
/* Overview and recent sessions column: stack cards with space between them. */
.history-column {
  display: grid;
  gap: var(--space-6);
}
/* "Ready for your next session?" card: the message and Log a session link. */
.dashboard-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-6);
}
/* "Log a session" link inside the overview action card: width and spacing. */
.dashboard-actions .save {
  width: 180px;
  flex-shrink: 0;
  margin: 0;
}
/* Overview cards: two columns. */
.dashboard-grid {
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
}
/* Total sessions and mistakes: the two statistics side by side. */
.stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-bottom: var(--space-6);
}
/* Second overview statistic: a divider and space to its left. */
.stats > div + div {
  border-left: 1px solid var(--line);
  padding-left: var(--space-6);
}
/* Large overview totals: heading font, scaled down on narrow screens instead of
   wrapping, so a total like 10,000 never splits across two lines mid-digit. */
.stats strong {
  display: block;
  font-family: var(--font-heading);
  font-size: clamp(var(--text-2xl), 7.5vw, var(--text-4xl));
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
}
/* Labels under overview totals: small text. */
.stats span {
  font-size: var(--text-xs);
}
/* History sport filter row: align its label and dropdown. */
.history-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin: 0 0 var(--space-5);
}
/* "Filter by sport" label: text size. */
.history-filter label {
  font-size: var(--text-sm);
}
/* History sport filter dropdown: width. */
.history-filter select {
  width: 150px;
}
/* History with no matching sessions: center the empty-state message. */
.empty {
  text-align: center;
  padding: var(--space-8) var(--space-3) var(--space-10);
}
/* Symbol above the empty history message: a rounded square on the control surface. */
.empty-symbol {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  margin: 0 auto var(--space-5);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--text-2xl);
}
/* Empty history heading: size and weight. */
.empty h3 {
  font-size: var(--text-lg);
}
/* Empty history explanation: size and line spacing. */
.empty p {
  font-size: var(--text-sm);
  line-height: 1.7;
}
/* Each saved session: separated from other sessions with a line and spacing. */
.session {
  border-top: 1px solid var(--line);
  padding: var(--space-5) 0;
}
/* Top row of a saved session: align its details and mistake total. */
.session-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
/* Sport name in a saved session: the heading. */
.session h3 {
  margin: 0 0 var(--space-1);
  font-size: var(--text-base);
  font-weight: 600;
}
/* Date shown in a saved session: small text. */
.session time {
  font-size: var(--text-sm);
}
/* Mistake total in a saved session: larger and aligned to the right. */
.session-total {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 600;
  letter-spacing: -.02em;
  text-align: right;
}
/* Small caption below a saved session's mistake total: on its own line. */
.session-total small {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0;
}
/* Saved session sport stats: stat chips that wrap. */
.session-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-3) 0;
}
/* Saved session notes: preserve the user's line breaks and space the text. */
.session-note {
  font-size: var(--text-sm);
  line-height: 1.6;
  white-space: pre-wrap;
}
/* Delete text button in a saved session: align it with the session content. */
.session .text-button {
  padding-left: 0;
}

/* Profile */
/* Profile card: limit its width and center it. */
.profile-panel {
  max-width: 620px;
  margin: var(--space-8) auto;
}
/* "Your profile" heading: page-level size and top spacing. */
.profile-panel h2 {
  font-size: var(--text-3xl);
  letter-spacing: -.03em;
  margin-top: var(--space-4);
}
/* Profile sections for practice data, Ace, and version details: dividers and spacing. */
.settings-section {
  border-top: 1px solid var(--line);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
}
/* Supporting text inside profile sections: spacing before the button. */
.settings-section .muted {
  margin: 0 0 var(--space-4);
}

/* Sign-in screen */
/* Sign-in screen: the story and login area in two full-height columns. */
.auth-screen {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100svh;
}
/* Story side of sign-in: the logo, welcome message, and closing label. */
.auth-story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-12) max(40px, 8vw);
  border-right: 1px solid var(--line);
}
/* "Your game. Your pace. Your progress." heading: display size and line spacing. */
.auth-story h1 {
  font-size: var(--text-display);
  line-height: 1.1;
}
/* Ace below the sign-in story: space above the character. */
.auth-ace {
  margin-top: var(--space-8);
}
/* Login side of sign-in: center the form area. */
.auth-content {
  display: grid;
  place-items: center;
  padding: var(--space-12);
}
/* Login form container: limit the width of its contents. */
.auth-box {
  width: 100%;
  max-width: 370px;
}
/* "Welcome to your next chapter" heading: page-level size and spacing. */
.auth-box h2 {
  font-size: var(--text-3xl);
  line-height: 1.15;
  letter-spacing: -.03em;
  margin-top: var(--space-6);
}
/* Ace's welcome card above login: the robot and greeting. */
.ace-welcome {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
/* "Hey, I am Ace" greeting: size and weight. */
.ace-welcome strong {
  font-size: var(--text-md);
  font-weight: 600;
}
/* Instructions inside Ace's welcome card: size and spacing. */
.ace-welcome p {
  font-size: var(--text-sm);
  line-height: 1.7;
  margin: var(--space-1) 0 0;
}
/* Log in and Create profile switch: two equal choices. */
.auth-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: var(--space-6) 0;
}
/* Labels for sign-in and profile fields: above the inputs. */
.auth-box label, .profile-panel label {
  display: block;
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-sm);
}
/* "Continue without login" button: full width with the arrow on the right. */
.guest-button {
  width: 100%;
  justify-content: space-between;
  margin-top: var(--space-3);
}
/* Sign-in and local history explanation below the forms: size and spacing. */
.auth-disclosure {
  font-size: var(--text-xs);
  line-height: 1.7;
  margin-top: var(--space-6);
}
/* Login and verification feedback messages: size and line spacing. */
#auth-status {
  font-size: var(--text-sm);
  line-height: 1.7;
}
/* Sign-in form: stack the secondary buttons with even spacing. */
#otp-form .secondary {
  width: 100%;
  margin-top: var(--space-3);
}

/* Dialogs */
/* Popup dialogs: the card recipe plus a floating shadow. */
dialog {
  width: min(400px, calc(100% - 32px));
  max-width: calc(100% - 32px);
  color: var(--text);
  box-shadow: var(--shadow-float);
}
/* Area behind a popup dialog: dim the page with the background colour.
   (::backdrop cannot read the tokens in every browser, so this is the
   background colour written out.) */
dialog::backdrop {
  background: rgb(8 8 8 / .72);
}
/* Explanatory text inside popup dialogs: size. */
dialog p {
  font-size: var(--text-md);
  line-height: 1.6;
  margin: var(--space-2) 0 0;
}
/* Dialog actions: side by side. */
.dialog-actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-6);
}
.dialog-actions button {
  flex: 1;
  white-space: nowrap;
}

/* Ace tour: a floating card, plus a clear window over the control it describes. */
/* Ace's guided tour card: above the page, scrolling inside. */
.ace-tour {
  position: fixed;
  inset: auto var(--space-5) var(--space-6) auto;
  margin: 0;
  width: 390px;
  max-width: calc(100vw - 40px);
  height: min(400px, 48dvh);
  max-height: min(440px, 48dvh);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Area behind the Ace tour dialog: keep its background transparent. */
.ace-tour::backdrop {
  background: transparent;
}
.ace-tour[open] {
  display: flex;
  flex-direction: column;
}
#tour-announcement {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.tour-heading, .tour-track, .tour-actions {
  flex-shrink: 0;
}
/* Top of the Ace tour card: the robot, progress label, and Skip tour button. */
.tour-heading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
/* Ace character inside the tour heading: a smaller size. */
.tour-heading .ace {
  width: 48px;
  height: 54px;
}
/* Eyes inside the tour heading: vertical position. */
.tour-heading .eyes {
  padding-top: 20px;
}
/* Tour step counter: size and spacing. */
#tour-progress {
  font-size: var(--text-xs);
  color: var(--muted);
  margin: var(--space-1) 0 0;
}
/* "Skip tour" button: push it to the right and keep its text on one line. */
#tour-skip {
  margin-left: auto;
  white-space: nowrap;
}
/* Current tour step title: line spacing. */
#tour-title {
  line-height: 1.25;
}
/* Current tour step instructions: size and spacing. */
#tour-description {
  font-size: var(--text-md);
  line-height: 1.7;
  color: var(--muted);
  margin: var(--space-3) 0 var(--space-5);
}
/* Tour progress bar background: a thin rounded track. */
.tour-track {
  height: 3px;
  background: var(--surface-3);
  border-radius: var(--radius-full);
}
/* Filled part of the tour progress bar: the accent colour. */
#tour-bar {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: inherit;
  transition: width 260ms var(--ease);
}
/* Back and Next button row in the tour: visible while the card scrolls. */
.tour-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  position: sticky;
  bottom: -1px;
  background: var(--surface);
  padding-top: var(--space-2);
}
/* Main Next or finish button in the tour: fill available space, centered label. */
.tour-actions .save {
  margin: 0;
  width: auto;
  flex: 1;
  justify-content: center;
}
/* Control highlighted by the tour: remove its normal outline. */
.tour-target {
  outline: none !important;
}
/* Tour spotlight: dim the surrounding page and ring the highlighted control in the accent. */
#tour-spotlight {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 30;
  pointer-events: none;
  border-radius: 0;
  box-shadow:
    0 0 0 200vmax rgb(8 8 8 / .66),
    inset 0 0 0 2px var(--accent),
    0 0 0 6px var(--accent-soft);
}
/* Page during the tour: scroll space so top and bottom controls can be centered. */
body.tour-running {
  padding-top: 50vh;
  padding-bottom: 50vh;
  overflow-anchor: none;
}

/* Keep lengthy user content and large counts inside narrow layouts. */
.intro > div, .ace-welcome > div, .workspace > *, .history-column,
.section-top > *, .tour-heading > div {
  min-width: 0;
}
#greeting, .session-note, .session-metrics span {
  overflow-wrap: anywhere;
}

/* Ace moves using small transform and opacity animations. */
@keyframes ace-greeting {
  0% { transform: translateY(8px) rotate(-12deg); }
  45% { transform: translateY(-4px) rotate(8deg); }
  75% { transform: translateY(0) rotate(-9deg); }
  100% { transform: translateY(0) rotate(-6deg); }
}
@keyframes ace-float {
  0%, 100% { transform: translateY(0) rotate(-6deg); }
  50% { transform: translateY(-4px) rotate(-3deg); }
}
@keyframes ace-blink {
  0%, 42%, 47%, 100% { transform: scaleY(1); }
  44%, 45% { transform: scaleY(.12); }
}
@keyframes tour-arrive {
  from { opacity: 0; transform: translateY(16px) scale(.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* Ace in the welcome card: the greeting, then three floats. */
.ace-welcome .robot {
  animation: ace-greeting 850ms var(--ease), ace-float 4s ease-in-out 850ms 3;
}
/* Tour card when open: its entrance animation. */
.ace-tour[open] {
  animation: tour-arrive 240ms var(--ease);
}
/* Robot inside the open tour: float three times. */
.ace-tour[open] .robot {
  animation: ace-float 4s ease-in-out 3;
}
/* Ace's eyes in the welcome card and tour: blink three times. */
.ace-welcome .eyes i, .ace-tour[open] .eyes i {
  transform-origin: center;
  animation: ace-blink 4.5s linear 3;
}
/* Page content: fade in while moving upward a small distance. */
@keyframes content-arrive {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
/* New history entries and form fields: fade in without moving the layout. */
@keyframes content-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Interactive states: every clickable control has hover, focus, and press. */
/* Press: every button settles down slightly. */
.save:active:not(:disabled), .secondary:active:not(:disabled),
.text-button:active:not(:disabled), .guest-button:active:not(:disabled),
.dialog-actions button:active:not(:disabled), .adjust:active:not(:disabled),
.avatar:active, .auth-tabs button:active:not(:disabled), .app-nav a:active,
.sports label:active > span {
  transform: scale(.97);
}

/* Motion effects: run only when the user allows animation. */
@media (prefers-reduced-motion: no-preference) {
  .auth-story > div {
    animation: content-arrive 500ms var(--ease) both;
  }
  .auth-box {
    animation: content-arrive 500ms var(--ease) 90ms both;
  }
  #signup-fields, #otp-form {
    animation: content-fade 220ms var(--ease);
  }
  .session, .empty, .metric-fields > div {
    animation: content-fade 260ms var(--ease);
  }
  #delete-dialog[open], #empty-session-dialog[open] {
    animation: content-arrive 220ms var(--ease);
  }
  /* Buttons, navigation, and sport cards: transform and opacity only. */
  .save, .secondary, .text-button, .guest-button, .dialog-actions button,
  .adjust, .avatar, .app-nav a, .auth-tabs button, .sports label > span {
    transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
  }
}

/* Mouse and trackpad users: hover states for every clickable control. */
@media (hover: hover) and (pointer: fine) {
  /* Primary buttons and the plus button: lift with a tinted shadow. */
  .save:hover:not(:disabled), .add:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lift);
  }
  /* Secondary, round, and dialog buttons: step up one surface. */
  .secondary:hover:not(:disabled), .guest-button:hover:not(:disabled),
  .dialog-actions button:hover:not(:disabled), .adjust:hover:not(:disabled),
  .avatar:hover {
    background: var(--surface-3);
    border-color: var(--line-strong);
  }
  .add:hover:not(:disabled) {
    background: var(--primary);
    border-color: var(--primary);
  }
  .dialog-actions .confirm-delete:hover:not(:disabled) {
    background: color-mix(in srgb, var(--danger) 24%, var(--bg));
    border-color: var(--danger);
  }
  /* Ghost buttons: brighten the text. */
  .text-button:hover:not(:disabled) {
    color: var(--text);
    background: var(--surface-2);
  }
  /* Segmented controls: brighten inactive items. */
  .app-nav a:hover:not([aria-current="page"]),
  .auth-tabs button:hover:not([aria-pressed="true"]) {
    background: var(--surface-3);
    color: var(--text);
  }
  /* Sport choices: lift the card under the pointer. */
  .sports label:hover > span {
    transform: translateY(-2px);
  }
  .sports label:hover > input:not(:checked) + span {
    border-color: var(--line-strong);
    color: var(--text);
  }
  /* Hovered buttons settle back down while pressed. */
  .save:hover:active:not(:disabled), .add:hover:active:not(:disabled) {
    transform: scale(.97);
    box-shadow: none;
  }
}

/* Reduced-motion settings: no animation, no press or hover movement. */
@media (prefers-reduced-motion: reduce) {
  .ace-welcome .robot, .ace-tour[open], .ace-tour[open] .robot,
  .ace-welcome .eyes i, .ace-tour[open] .eyes i {
    animation: none;
  }
  #tour-bar {
    transition: none;
  }
  .save:active, .secondary:active, .text-button:active, .guest-button:active,
  .dialog-actions button:active, .adjust:active, .avatar:active,
  .auth-tabs button:active, .app-nav a:active, .sports label:active > span,
  .save:hover, .add:hover, .sports label:hover > span {
    transform: none;
  }
}

/* Screens up to 760px wide: adapt the app for phones and narrow windows. */
@media (max-width: 760px) {
  :root {
    --card-pad: var(--space-5);
  }
  .shell {
    padding: 0 var(--space-5) calc(90px + env(safe-area-inset-bottom));
  }
  header {
    height: 76px;
    padding: 0;
    flex-wrap: nowrap;
    gap: var(--space-3);
  }
  /* Small screens: the navigation becomes a bar fixed to the bottom of the screen. */
  .app-nav {
    position: fixed;
    z-index: 10;
    order: 3;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    gap: 0;
    justify-content: space-between;
    padding: var(--space-2) var(--space-3) calc(8px + env(safe-area-inset-bottom));
    border: 0;
    border-top: 1px solid var(--line);
    border-radius: 0;
    background: var(--surface);
  }
  .app-nav a {
    flex: 1;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-1);
    min-height: 52px;
    padding: var(--space-1);
    font-size: var(--text-sm);
  }
  .nav-icon {
    font-size: var(--text-2xl);
  }
  .intro {
    padding: var(--space-6) 0;
    align-items: flex-start;
    flex-direction: column;
    gap: var(--space-4);
  }
  .intro h1 {
    margin: var(--space-3) 0 var(--space-2);
    font-size: 34px;
  }
  .intro .muted {
    margin: 0;
    max-width: 290px;
  }
  .ace-note {
    width: 100%;
    gap: var(--space-4);
  }
  .workspace, .dashboard-grid {
    grid-template-columns: 1fr;
  }
  .dashboard-actions {
    align-items: stretch;
    flex-direction: column;
    gap: var(--space-4);
  }
  .dashboard-actions .save {
    width: 100%;
  }
  .profile-panel {
    margin: var(--space-6) 0;
  }
  #mistakes {
    font-size: 66px;
  }
  footer {
    flex-wrap: wrap;
  }
  .auth-screen {
    grid-template-columns: 1fr;
  }
  .auth-story {
    padding: var(--space-6);
    gap: var(--space-5);
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .auth-story h1 {
    font-size: 38px;
  }
  .auth-story > .eyebrow, .auth-ace, .auth-story > div > .muted {
    display: none;
  }
  .auth-content {
    padding: var(--space-6);
  }
  .auth-box h2 {
    margin-top: var(--space-4);
    font-size: 28px;
  }
  .auth-tabs {
    margin: var(--space-5) 0;
  }
  .ace-tour {
    inset: auto var(--space-3) calc(12px + env(safe-area-inset-bottom)) var(--space-3);
    width: auto;
    max-width: none;
  }
}

/* Screens up to 640px tall: make the tour more compact. */
@media (max-height: 640px) {
  .ace-tour {
    padding: var(--space-4);
  }
  .tour-heading {
    margin-bottom: var(--space-3);
  }
  .tour-heading .robot {
    width: 32px;
    height: 38px;
    border-radius: var(--radius-md);
  }
  .tour-heading .robot .eyes {
    padding-top: 12px;
    gap: 6px;
  }
  .tour-heading .robot::after {
    top: 14px;
  }
  #tour-title {
    font-size: var(--text-lg);
  }
  #tour-description {
    margin: var(--space-2) 0;
    font-size: var(--text-sm);
    line-height: 1.5;
  }
  .tour-actions {
    margin-top: var(--space-3);
  }
}
