/* ============================================================================
   trainlog — design system & application styles
   ----------------------------------------------------------------------------
   Structure
     01. Tokens
     02. Reset & base
     03. Primitives (buttons, inputs, steppers, sheets, pills)
     04. App shell (header, view, bottom tab bar, rest bar)
     05. Auth
     06. Today (logging)
     07. History
     08. Routines
     09. Body
     10. More / settings
     11. Toasts & empty states

   Conventions
     - BEM-ish. Tokens only: no raw hex outside section 01.
     - Mobile first. The only media query widens things for tablets/desktop.
     - Minimum tap target 48px, primary actions 56px. This is used one-handed,
       standing up, sometimes with chalk on your hands.
   ========================================================================== */

/* ══ 01. TOKENS ══════════════════════════════════════════════════════════ */
:root {
  color-scheme: dark;

  /* Surfaces */
  --bg:        #0B0D11;
  --bg-1:      #12151C;
  --bg-2:      #191D26;
  --bg-3:      #222733;
  --bg-hover:  rgba(255,255,255,.05);
  --bg-active: rgba(255,255,255,.09);

  /* Strokes */
  --stroke:   rgba(255,255,255,.08);
  --stroke-2: rgba(255,255,255,.15);

  /* Type */
  --text:   #ECEFF4;
  --text-2: #98A1B2;
  --text-3: #626A7A;

  /* Brand + semantics */
  --primary:      #4B8DF8;
  --primary-2:    #6FA5FA;
  --primary-soft: rgba(75,141,248,.16);
  --pr:           #FFC53D;
  --pr-soft:      rgba(255,197,61,.15);
  --up:           #3DD68C;
  --up-soft:      rgba(61,214,140,.14);
  --down:         #FF5D73;
  --down-soft:    rgba(255,93,115,.14);
  --warm:         #FF9F45;

  /* Geometry */
  --r-sm: 8px;
  --r:    12px;
  --r-lg: 18px;
  --r-xl: 26px;

  --tap:     48px;   /* minimum interactive height */
  --tap-lg:  56px;   /* primary actions */
  --tabbar:  60px;
  --restbar: 46px;

  /* Safe areas — iPhone home indicator and notch. */
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);

  --shadow: 0 8px 28px rgba(0,0,0,.45);

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

:root[data-theme="light"] {
  color-scheme: light;
  --bg:        #F6F7F9;
  --bg-1:      #FFFFFF;
  --bg-2:      #F0F2F5;
  --bg-3:      #E4E8ED;
  --bg-hover:  rgba(0,0,0,.04);
  --bg-active: rgba(0,0,0,.07);
  --stroke:    rgba(0,0,0,.09);
  --stroke-2:  rgba(0,0,0,.17);
  --text:      #131720;
  --text-2:    #59616F;
  --text-3:    #8A92A0;
  --shadow:    0 8px 28px rgba(0,0,0,.14);
}

/* ══ 02. RESET & BASE ════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overscroll-behavior-y: none;  /* no pull-to-refresh eating a logged set */
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  /* 16px minimum throughout: smaller also makes iOS zoom on focus, which
     yanks the layout sideways mid-workout. */
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.01em; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p  { margin: 0 0 .6em; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; border: none; background: none; }

/* Links are navigation chrome here (the tab bar), not prose. The one place a
   link should look like a link -- the sign-in/register switch -- re-enables
   the underline itself via .auth__link. */
a { color: inherit; text-decoration: none; }

/* Every weight and rep count. Tabular figures stop numbers jittering
   horizontally as they tick up and down in a stepper. */
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ══ 03. PRIMITIVES ══════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  min-height: var(--tap);
  padding: 0 1.1em;
  border-radius: var(--r);
  background: var(--bg-2);
  border: 1px solid var(--stroke);
  color: var(--text);
  font-weight: 600;
  transition: background .12s ease, transform .06s ease;
}
.btn:active { transform: scale(.985); background: var(--bg-active); }
.btn[disabled] { opacity: .45; pointer-events: none; }

.btn--primary { background: var(--primary); border-color: transparent; color: #fff; }
.btn--primary:active { background: var(--primary-2); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn--danger { background: var(--down-soft); border-color: transparent; color: var(--down); }
.btn--lg { min-height: var(--tap-lg); font-size: 1.05rem; border-radius: var(--r-lg); }
.btn--block { display: flex; width: 100%; }

.input, .select {
  width: 100%;
  min-height: var(--tap);
  padding: 0 .85em;
  background: var(--bg-2);
  border: 1px solid var(--stroke);
  border-radius: var(--r);
  color: var(--text);
}
.input::placeholder { color: var(--text-3); }
textarea.input { min-height: 88px; padding: .7em .85em; resize: vertical; }

.field { display: block; margin-bottom: .85rem; }
.field__label {
  display: block; margin-bottom: .35rem;
  font-size: .85rem; font-weight: 600; color: var(--text-2);
}
.field__hint { margin-top: .3rem; font-size: .82rem; color: var(--text-3); }

/* --- Stepper -------------------------------------------------------------
   The core input of the app. Big +/- either side of the value so a set can
   be adjusted without the OS keyboard ever appearing; the value itself is
   still a real input for the rare case you need to type an exact number. */
.stepper { display: flex; flex-direction: column; gap: .3rem; }
.stepper__label {
  font-size: .78rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-3);
}
.stepper__row {
  display: grid;
  grid-template-columns: var(--tap) 1fr var(--tap);
  align-items: stretch;
  background: var(--bg-2);
  border: 1px solid var(--stroke);
  border-radius: var(--r);
  overflow: hidden;
}
.stepper__btn {
  display: flex; align-items: center; justify-content: center;
  min-height: var(--tap);
  font-size: 1.4rem; font-weight: 500; color: var(--text-2);
  background: var(--bg-3);
}
.stepper__btn:active { background: var(--bg-active); color: var(--text); }
.stepper__value {
  width: 100%; min-width: 0;
  border: none; background: transparent; text-align: center;
  font-size: 1.35rem; font-weight: 650;
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.stepper__value::-webkit-outer-spin-button,
.stepper__value::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper__value:focus { outline: none; background: var(--bg-3); }

/* --- Cards & rows --- */
.card {
  background: var(--bg-1);
  border: 1px solid var(--stroke);
  border-radius: var(--r-lg);
  padding: 1rem;
  margin-bottom: .8rem;
}
.card__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; margin-bottom: .7rem;
}

.row {
  display: flex; align-items: center; gap: .75rem;
  width: 100%;
  min-height: var(--tap);
  padding: .55rem .8rem;
  background: var(--bg-1);
  border: 1px solid var(--stroke);
  border-radius: var(--r);
  margin-bottom: .45rem;
  text-align: left;
}
.row:active { background: var(--bg-hover); }
.row__main { flex: 1; min-width: 0; }
.row__title { font-weight: 600; }
.row__sub { font-size: .87rem; color: var(--text-2); }
.row__meta { color: var(--text-2); font-size: .9rem; white-space: nowrap; }

/* --- Pills / badges --- */
.pill {
  display: inline-flex; align-items: center; gap: .35em;
  padding: .2em .6em;
  border-radius: 999px;
  font-size: .78rem; font-weight: 650;
  background: var(--bg-3); color: var(--text-2);
  white-space: nowrap;
}
.pill--pr { background: var(--pr-soft); color: var(--pr); }
.pill--warm { background: var(--bg-3); color: var(--warm); }
.pill--ok { background: var(--up-soft); color: var(--up); }
.pill__dot { width: .5em; height: .5em; border-radius: 50%; background: currentColor; }

/* --- Sheet (full-width bottom modal) ---
   Sheets rather than centred dialogs: the controls land under the thumb
   instead of in the middle of the screen. */
.scrim {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(0,0,0,.55);
  animation: fade .15s ease;
}
.sheet {
  position: fixed; z-index: 41;
  left: 0; right: 0; bottom: 0;
  max-height: 88vh;
  display: flex; flex-direction: column;
  background: var(--bg-1);
  border-top-left-radius: var(--r-xl);
  border-top-right-radius: var(--r-xl);
  border-top: 1px solid var(--stroke);
  box-shadow: var(--shadow);
  padding: .6rem 1rem calc(1rem + var(--safe-b));
  animation: rise .2s cubic-bezier(.2,.8,.3,1);
}
.sheet__grip {
  width: 40px; height: 4px; border-radius: 2px;
  background: var(--stroke-2); margin: .2rem auto .8rem;
}
.sheet__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; margin-bottom: .8rem;
}
.sheet__body { overflow-y: auto; -webkit-overflow-scrolling: touch; }
.sheet__foot { padding-top: .8rem; }

@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes rise { from { transform: translateY(14px); opacity: .6 } to { transform: none; opacity: 1 } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ══ 04. APP SHELL ═══════════════════════════════════════════════════════ */
.app { display: flex; flex-direction: column; min-height: 100%; }

.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: .6rem;
  padding: calc(.55rem + var(--safe-t)) 1rem .55rem;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--stroke);
}
.topbar__title { flex: 1; font-size: 1.2rem; font-weight: 700; }

/* Sync state. Deliberately quiet: losing signal in a basement gym is normal,
   not an error, and the UI should read as calm about it. */
.syncpill { font-size: .76rem; }
.syncpill[data-state="synced"]  { color: var(--text-3); }
.syncpill[data-state="pending"] { color: var(--warm); }
.syncpill[data-state="offline"] { color: var(--text-2); }
.syncpill[data-state="syncing"] { color: var(--primary); }

.view {
  flex: 1;
  padding: 1rem 1rem calc(var(--tabbar) + var(--safe-b) + 1.5rem);
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
}
.view--has-rest { padding-bottom: calc(var(--tabbar) + var(--restbar) + var(--safe-b) + 1.5rem); }

/* --- Bottom tab bar: thumb reach. Never a top nav or hamburger here. --- */
.tabbar {
  position: fixed; z-index: 30;
  left: 0; right: 0; bottom: 0;
  display: grid; grid-template-columns: repeat(5, 1fr);
  height: calc(var(--tabbar) + var(--safe-b));
  padding-bottom: var(--safe-b);
  background: color-mix(in srgb, var(--bg-1) 94%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--stroke);
}
.tabbar__item {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  color: var(--text-3);
  font-size: .68rem; font-weight: 600;
}
.tabbar__item[aria-current="page"] { color: var(--primary); }
.tabbar__ico { width: 24px; height: 24px; display: block; }

/* --- Rest timer: sits directly above the tab bar, never over the log button --- */
.restbar {
  position: fixed; z-index: 29;
  left: 0; right: 0;
  bottom: calc(var(--tabbar) + var(--safe-b));
  height: var(--restbar);
  display: flex; align-items: center; gap: .75rem;
  padding: 0 1rem;
  background: var(--bg-2);
  border-top: 1px solid var(--stroke);
}
.restbar__time {
  font-size: 1.15rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 4.2ch;
}
.restbar__bar { flex: 1; height: 4px; border-radius: 2px; background: var(--bg-3); overflow: hidden; }
.restbar__fill { height: 100%; background: var(--primary); transition: width .95s linear; }
.restbar__done { color: var(--up); }

/* ══ 05. AUTH ════════════════════════════════════════════════════════════ */
.auth {
  min-height: 100dvh;
  display: flex; flex-direction: column; justify-content: center;
  padding: 2rem 1.25rem calc(2rem + var(--safe-b));
  max-width: 420px; margin: 0 auto;
}
.auth__brand { text-align: center; margin-bottom: 1.75rem; }
.auth__mark {
  width: 56px; height: 56px; margin: 0 auto .7rem;
  border-radius: 16px;
  background: linear-gradient(150deg, var(--primary), #2E6BD4);
  display: grid; place-items: center;
}
.auth__tag { color: var(--text-2); font-size: .95rem; }
.auth__switch { margin-top: 1.1rem; text-align: center; color: var(--text-2); font-size: .92rem; }
.auth__link { color: var(--primary); font-weight: 600; text-decoration: underline; }

.alert {
  padding: .7rem .85rem;
  border-radius: var(--r);
  font-size: .92rem;
  margin-bottom: .9rem;
}
.alert--error { background: var(--down-soft); color: var(--down); }
.alert--info  { background: var(--primary-soft); color: var(--primary-2); }

/* ══ 06. TODAY ═══════════════════════════════════════════════════════════ */
.session__meta {
  display: flex; align-items: baseline; gap: .8rem;
  color: var(--text-2); font-size: .9rem; margin-bottom: 1rem;
}
.session__elapsed { font-variant-numeric: tabular-nums; }

.exblock { margin-bottom: 1.1rem; }
.exblock__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .5rem;
}
.exblock__name { font-size: 1.05rem; font-weight: 650; }

/* "Last time: 80 kg x 8, 80 x 7" — kept on screen because progressive
   overload is the point, and hiding it behind a History tap is the single
   most common design failure in this kind of app. */
.lasttime {
  display: flex; flex-wrap: wrap; gap: .35rem .5rem;
  align-items: center;
  padding: .5rem .7rem;
  background: var(--bg-2);
  border-radius: var(--r);
  margin-bottom: .6rem;
  font-size: .9rem;
  color: var(--text-2);
}
.lasttime__label { font-weight: 650; color: var(--text-3); }
.lasttime__set { font-variant-numeric: tabular-nums; }

.setlist { list-style: none; margin: 0 0 .6rem; padding: 0; }
.setrow {
  display: flex; align-items: center; gap: .7rem;
  width: 100%;
  min-height: var(--tap);
  padding: .4rem .7rem;
  background: var(--bg-1);
  border: 1px solid var(--stroke);
  border-radius: var(--r);
  margin-bottom: .35rem;
  text-align: left;
}
.setrow--warmup { opacity: .72; border-style: dashed; }
.setrow__idx {
  width: 1.9rem; height: 1.9rem; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg-3); color: var(--text-2);
  font-size: .82rem; font-weight: 700;
}
.setrow__val { flex: 1; font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.setrow__tag { flex: none; }

.logbar { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-bottom: .6rem; }
.logbar--single { grid-template-columns: 1fr; }

/* ══ 07. HISTORY ═════════════════════════════════════════════════════════ */
.daygroup__label {
  font-size: .8rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-3);
  margin: 1.2rem 0 .5rem;
}
.wsummary__title { display: flex; align-items: center; gap: .5rem; }
.wsummary__stats { display: flex; gap: 1rem; color: var(--text-2); font-size: .88rem; }

/* ══ 08. ROUTINES ════════════════════════════════════════════════════════ */
.routine__items { color: var(--text-2); font-size: .88rem; }

/* ══ 09. BODY ════════════════════════════════════════════════════════════ */
.chart { width: 100%; height: auto; display: block; }
.chart__empty { color: var(--text-3); font-size: .9rem; text-align: center; padding: 2rem 0; }

.statgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; margin-bottom: 1rem; }
.stat {
  background: var(--bg-1); border: 1px solid var(--stroke);
  border-radius: var(--r); padding: .8rem;
}
.stat__label { font-size: .78rem; font-weight: 650; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em; }
.stat__value { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat__delta { font-size: .85rem; font-weight: 600; }
.stat__delta--up { color: var(--up); }
.stat__delta--down { color: var(--down); }

/* ══ 10. MORE ════════════════════════════════════════════════════════════ */
.seg {
  display: inline-flex; padding: 3px; gap: 3px;
  background: var(--bg-2); border: 1px solid var(--stroke);
  border-radius: var(--r);
}
.seg__btn {
  min-height: 40px; padding: 0 1em;
  border-radius: calc(var(--r) - 4px);
  color: var(--text-2); font-weight: 650;
}
.seg__btn.is-active { background: var(--primary); color: #fff; }

/* ══ 10b. UTILITIES ══════════════════════════════════════════════════════
   A deliberately tiny set, and the reason they exist rather than inline
   style="" attributes: the Content-Security-Policy is `style-src 'self'` with
   no unsafe-inline, which silently DROPS style attributes. Markup keeps
   rendering, the rule just never applies -- so an inline margin looks correct
   in the source and is simply absent on screen. Classes are the only way to
   style anything here. */
.mt-xs { margin-top: .4rem; }
.mt-sm { margin-top: .6rem; }
.mt-md { margin-top: .8rem; }
.mt-1  { margin-top: 1rem; }
.mt-lg { margin-top: 1.2rem; }
.mt-xl { margin-top: 1.5rem; }

.t-center { text-align: center; }
.t-muted  { color: var(--text-2); }
.t-faint  { color: var(--text-3); }

.section-title { margin: 1.5rem 0 .6rem; }

/* Checkbox + label on one line, sized for a thumb. */
.checkline {
  display: flex; align-items: center; gap: .5rem;
  margin-top: .6rem;
  min-height: var(--tap);
  color: var(--text-2); font-size: .9rem;
}
.checkline__box { width: 22px; height: 22px; accent-color: var(--primary); }

/* ══ 10c. EXERCISE IMAGES ════════════════════════════════════════════════
   Source photos vary in aspect ratio -- most are landscape, a few portrait --
   so every thumbnail is a fixed box with object-fit: cover. Letting the image
   set its own height would make list rows different heights and the list would
   visibly jolt while typing in the search field. */
.exthumb {
  flex: none;
  width: 56px; height: 56px;
  border-radius: 10px;
  object-fit: cover;
  background: var(--surface-2);
  /* Photos are on a bright gym background; this keeps them from glaring out
     of a dark UI without washing out the figure. */
  filter: brightness(.92) saturate(.9);
}
.exthumb--none {
  display: inline-block;
  border: 1px dashed var(--stroke);
  background: transparent;
}

/* On the logging screen the thumbnail sits inline in the header rather than as
   a banner above it. A full-width figure there would push the steppers below
   the fold, and the two-tap logging flow is the one thing that must not move.
   Tap it for the full illustration. */
.exthumb-btn {
  flex: none;
  padding: 0;
  border-radius: 10px;
  line-height: 0;
}
.exthumb-btn:active { opacity: .7; }

/* Full-size view: the two frames side by side are what actually communicate
   the movement -- a single still of a squat is ambiguous about direction. */
.exframes { display: grid; gap: .6rem; }
.exframes img {
  width: 100%;
  border-radius: var(--radius);
  background: var(--surface-2);
}
.exframes__cap {
  font-size: .8rem; color: var(--text-3);
  margin-top: -.35rem;
}
@media (min-width: 520px) {
  .exframes { grid-template-columns: 1fr 1fr; }
}

/* ══ 10d. CATEGORIES, SESSION DETAIL, HEART RATE ═════════════════════════ */

/* Category chips. Colour is never the only signal -- each carries its label. */
.pill--cat { font-size: .68rem; letter-spacing: .02em; }
.pill--gym { background: rgba(75,141,248,.16); color: #9dbcfb; }
.pill--calisthenics { background: rgba(52,199,123,.16); color: #7fdcab; }

.row__tags { display: flex; gap: .3rem; flex: none; }

/* Filter chips. Horizontally scrollable: twelve muscle groups will not wrap
   onto a 375px screen without eating half the sheet, and a scrolling strip
   keeps the list itself above the fold. */
.chips {
  display: flex; gap: .4rem;
  margin-bottom: .5rem;
  padding-bottom: .2rem;
  overflow-x: auto;
  scrollbar-width: none;
  /* Lets a chip settle flush rather than half-cut at the edge. */
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.chips::-webkit-scrollbar { display: none; }
.chips--sub { margin-bottom: .7rem; }

.chip {
  display: inline-flex; align-items: center; gap: .3rem;
  flex: none;
  min-height: 36px;
  padding: 0 .7rem;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--text-2);
  font-size: .82rem; font-weight: 600;
  white-space: nowrap;
  scroll-snap-align: start;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.chip:active { transform: scale(.97); }
.chip.is-active {
  background: var(--primary-soft);
  border-color: transparent;
  color: var(--primary-2);
}
.chip__count {
  font-size: .72rem; font-weight: 500;
  color: var(--text-3);
}
.chip.is-active .chip__count { color: var(--primary-2); opacity: .8; }

/* Sectioned exercise picker. */
.exgroup + .exgroup { margin-top: 1rem; }
.exgroup__label {
  display: flex; align-items: center; gap: .45rem;
  margin: 0 .1rem .4rem;
  font-size: .74rem; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-3);
}
.exgroup__count {
  padding: 0 .35rem;
  border-radius: 6px;
  background: var(--surface-2);
  font-size: .7rem;
}

/* A card that behaves as a button needs the button reset undone. */
.card--tappable {
  display: block; width: 100%;
  text-align: left;
  cursor: pointer;
}
.card--tappable:active { opacity: .75; }
.card__cta {
  margin-top: .5rem;
  font-size: .8rem; color: var(--primary);
}
.card__head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }

.catrow { display: flex; gap: .35rem; flex-wrap: wrap; }

.exblock__foot {
  margin-top: .35rem;
  font-size: .8rem; color: var(--text-3);
}

/* Heart-rate zones. */
.zones { display: grid; gap: .55rem; }
.zone__head {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: .82rem;
}
.zone__name { font-weight: 700; }
.zone__desc { font-weight: 400; color: var(--text-3); }
.zone__bpm { color: var(--text-3); font-size: .76rem; }
.zone__bar {
  height: 8px; margin: .25rem 0 .15rem;
  border-radius: 4px;
  background: var(--surface-2);
  overflow: hidden;
}
/* Width is set from JS (session.js): the CSP drops inline style attributes,
   so a percentage in the markup would render as an empty bar. */
.zone__fill { height: 100%; border-radius: 4px; background: var(--primary); }
.zone__time { font-size: .76rem; color: var(--text-2); }
.zone__pct { color: var(--text-3); }

/* Warmer as intensity rises, matching what a sports watch shows. */
.zone[data-zone="Z1"] .zone__fill { background: #6fa8ff; }
.zone[data-zone="Z2"] .zone__fill { background: #46c37b; }
.zone[data-zone="Z3"] .zone__fill { background: #e0b23c; }
.zone[data-zone="Z4"] .zone__fill { background: #e8863c; }
.zone[data-zone="Z5"] .zone__fill { background: #e2544e; }

/* Token shown in Settings for the Apple Health Shortcut. */
.token {
  display: block; width: 100%;
  padding: .6rem .7rem;
  border: 1px solid var(--stroke); border-radius: 10px;
  background: var(--surface-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .78rem; word-break: break-all;
  color: var(--text);
}

.steps {
  margin: .5rem 0 0;
  padding-left: 1.15rem;
  font-size: .86rem; color: var(--text-2);
}
.steps li + li { margin-top: .45rem; }
.steps code {
  padding: .05rem .25rem;
  border-radius: 5px;
  background: var(--surface-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8em; word-break: break-all;
}

/* ══ 11. TOASTS & EMPTY STATES ═══════════════════════════════════════════ */
.toasts {
  position: fixed; z-index: 60;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--tabbar) + var(--safe-b) + 1rem);
  display: flex; flex-direction: column; gap: .5rem;
  width: min(92vw, 420px);
  pointer-events: none;
}
.toast {
  padding: .7rem .9rem;
  border-radius: var(--r);
  background: var(--bg-3);
  border: 1px solid var(--stroke-2);
  box-shadow: var(--shadow);
  font-size: .92rem;
  animation: rise .18s ease;
}
.toast--error { background: var(--down-soft); border-color: transparent; color: var(--down); }
.toast--ok { background: var(--up-soft); border-color: transparent; color: var(--up); }

.empty { text-align: center; padding: 2.5rem 1rem; color: var(--text-2); }
.empty__title { font-weight: 650; color: var(--text); margin-bottom: .3rem; }
.empty__hint { font-size: .92rem; }

.skeleton {
  height: 64px; border-radius: var(--r);
  background: linear-gradient(90deg, var(--bg-1), var(--bg-2), var(--bg-1));
  background-size: 200% 100%;
  animation: shimmer 1.2s infinite;
  margin-bottom: .5rem;
}
@keyframes shimmer { to { background-position: -200% 0 } }

/* ══ RESPONSIVE ══════════════════════════════════════════════════════════
   The layout is designed for a phone. Above 720px it simply centres and
   gains breathing room -- no separate desktop design, because there is no
   desktop use case for logging a set at a rack. */
@media (min-width: 720px) {
  .view { padding-left: 1.5rem; padding-right: 1.5rem; }
  .sheet {
    left: 50%; transform: translateX(-50%);
    width: min(560px, 100%);
    border-radius: var(--r-xl);
    bottom: 2rem;
  }
  .statgrid { grid-template-columns: repeat(4, 1fr); }
}
