:root {
  --bg: #000;
  --surface: #121212;
  --surface-2: #1c1c1e;
  --line: #2c2c2e;
  --text: #fff;
  --muted: #8e8e93;
  --accent: #2f7cf6;
  --green: #34c759;
  --green-bg: #14320f;
  --red: #ff453a;
  --gold: #ffd60a;
  --radius: 12px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  overscroll-behavior-y: contain;
}

body { padding-bottom: calc(64px + var(--safe-b)); }

button, input, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
input { -webkit-appearance: none; }

/* ---------- layout ---------- */

.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 12px;
  padding: calc(10px + var(--safe-t)) 16px 10px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.topbar h1 { font-size: 20px; font-weight: 600; margin: 0; flex: 1; }
.topbar .sub { font-size: 12px; color: var(--muted); font-weight: 400; display: block; }

main { padding: 16px; max-width: 640px; margin: 0 auto; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 14px;
}
.card h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }

.row { display: flex; align-items: center; gap: 10px; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.muted { color: var(--muted); }
.small { font-size: 13px; }
.tiny { font-size: 11px; }
.center { text-align: center; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--surface-2); color: var(--text);
  border-radius: 10px; padding: 13px 16px; font-weight: 600; font-size: 15px;
  min-height: 46px; width: 100%;
}
.btn:active { opacity: .6; }
.btn.primary { background: var(--accent); }
.btn.danger { color: var(--red); }
.btn.green { background: var(--green); }
.btn.sm { min-height: 36px; padding: 8px 14px; font-size: 14px; width: auto; }
.btn.ghost { border: 1px solid var(--line); background: transparent; }
.btn-row { display: flex; gap: 10px; }

/* ---------- bottom nav ---------- */

nav.tabs {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; background: #0a0a0aee; backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  padding-bottom: var(--safe-b);
}
nav.tabs a {
  flex: 1; text-align: center; padding: 9px 0 8px; font-size: 10px;
  color: var(--muted); text-decoration: none; letter-spacing: .2px;
}
nav.tabs a .ico { display: block; font-size: 20px; line-height: 1.3; }
nav.tabs a.on { color: var(--accent); }

/* ---------- bodyweight ---------- */

.bw-now { font-size: 44px; font-weight: 700; letter-spacing: -1px; line-height: 1; }
.bw-now span { font-size: 18px; font-weight: 500; color: var(--muted); }
.bw-entry { display: flex; gap: 10px; align-items: stretch; margin-top: 14px; }
.bw-entry input {
  flex: 1; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 12px 14px; font-size: 26px; font-weight: 600;
  text-align: center; min-width: 0;
}
.bw-entry input:focus { outline: none; border-color: var(--accent); }
.step {
  width: 52px; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 10px; font-size: 20px; font-weight: 600; flex: none;
}
.step:active { background: var(--accent); }
.delta { font-size: 13px; font-weight: 600; padding: 3px 8px; border-radius: 20px; background: var(--surface-2); }
.delta.up { color: var(--red); }
.delta.down { color: var(--green); }

.spark { width: 100%; height: 124px; display: block; margin-top: 8px; }
.spark path.line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.spark path.area { fill: rgba(47,124,246,.14); stroke: none; }
.spark circle { fill: var(--accent); }
.spark text { fill: var(--muted); font-size: 9px; }
.spark line.grid { stroke: var(--line); stroke-width: 1; }

.chips { display: flex; gap: 8px; margin-top: 10px; }
.chips button {
  flex: 1; padding: 7px; font-size: 13px; border-radius: 8px;
  background: var(--surface-2); color: var(--muted);
}
.chips button.on { background: var(--accent); color: #fff; }

/* ---------- muscle bars ---------- */

.mg { padding: 11px 0; border-bottom: 1px solid var(--line); }
.mg:last-child { border-bottom: 0; }
.mg-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 7px; }
.mg-name { font-size: 15px; font-weight: 500; }
.mg-num { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.mg-num b { color: var(--text); font-size: 15px; }
.bar { height: 8px; background: var(--surface-2); border-radius: 4px; overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 4px; background: var(--accent); transition: width .25s; }
.bar i.done { background: var(--green); }
.bar i.low { background: #ff9f0a; }
.bar i.none { background: var(--red); }

.legend { display: flex; gap: 12px; flex-wrap: wrap; font-size: 11px; color: var(--muted); margin-top: 12px; }
.legend i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 4px; }

/* ---------- log workout ---------- */

.stats { display: flex; gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.stats div { flex: 1; }
.stats .k { font-size: 12px; color: var(--muted); }
.stats .v { font-size: 19px; font-weight: 600; font-variant-numeric: tabular-nums; }
.stats .v.accent { color: var(--accent); }

.ex { margin-bottom: 22px; }
.ex-head { display: flex; align-items: center; gap: 8px; }
.ex-name { color: var(--accent); font-size: 17px; font-weight: 600; flex: 1; }
.ex-menu { color: var(--muted); font-size: 20px; padding: 4px 8px; }
.ex-note {
  width: 100%; background: transparent; border: 0; color: var(--text);
  padding: 6px 0; font-size: 14px;
}
.ex-note::placeholder { color: #5a5a5e; }
.ex-muscles { font-size: 11px; color: var(--muted); margin: 2px 0 8px; }

table.sets { width: 100%; border-collapse: collapse; }
table.sets th {
  font-size: 11px; color: var(--muted); font-weight: 600; text-transform: uppercase;
  letter-spacing: .6px; padding: 6px 2px; text-align: center;
}
table.sets th:nth-child(2) { text-align: left; }
table.sets td { padding: 4px 2px; text-align: center; }
table.sets tr.on td { background: var(--green-bg); }
table.sets tr.on td:first-child { border-radius: 8px 0 0 8px; }
table.sets tr.on td:last-child { border-radius: 0 8px 8px 0; }

.set-n {
  width: 34px; height: 34px; margin: 0 auto; border-radius: 8px; background: var(--surface-2);
  display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 600;
}
.prev { color: var(--muted); font-size: 13px; text-align: left; white-space: nowrap; }
.cell {
  width: 100%; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 9px 4px; text-align: center; font-size: 16px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.cell:focus { outline: none; border-color: var(--accent); background: #000; }
tr.on .cell { background: transparent; border-color: transparent; }
.tick {
  width: 40px; height: 34px; border-radius: 8px; background: var(--surface-2);
  color: var(--muted); font-size: 17px; display: flex; align-items: center; justify-content: center;
}
.tick.on { background: var(--green); color: #fff; }
col.c-set { width: 46px; }
col.c-prev { width: 30%; }
col.c-tick { width: 50px; }

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

.rest-bar {
  position: fixed; left: 0; right: 0; bottom: calc(56px + var(--safe-b)); z-index: 25;
  background: var(--surface); border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
}
.rest-bar .t { flex: 1; text-align: center; font-size: 30px; font-weight: 600; font-variant-numeric: tabular-nums; }
.rest-bar .adj { background: var(--surface-2); border-radius: 8px; padding: 10px 12px; font-size: 14px; font-weight: 600; }
.rest-progress { position: absolute; top: 0; left: 0; height: 2px; background: var(--accent); transition: width 1s linear; }

/* ---------- search / modal ---------- */

.sheet {
  position: fixed; inset: 0; z-index: 50; background: var(--bg);
  display: flex; flex-direction: column;
}
.sheet header {
  display: flex; align-items: center; gap: 10px; padding: calc(12px + var(--safe-t)) 16px 12px;
  border-bottom: 1px solid var(--line);
}
.sheet header h2 { flex: 1; margin: 0; font-size: 17px; }
.sheet .body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: 40px; }
.search {
  width: 100%; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 12px 14px; font-size: 16px;
}
.search:focus { outline: none; border-color: var(--accent); }
/* The ranking rides at the top of the picker's list, inside the scroll: open,
   it pushes the catalog down rather than squeezing it against the keyboard. */
.pick-coach { padding: 12px 16px 4px; }
.pick-coach .coach { margin-bottom: 8px; }
.pick { display: block; width: 100%; text-align: left; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.pick:active { background: var(--surface-2); }
.pick .n { font-size: 16px; }
.pick .m { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ---------- history ---------- */

.hist { display: block; width: 100%; text-align: left; }
.hist .t { font-size: 16px; font-weight: 600; }
.hist .d { font-size: 12px; color: var(--muted); margin: 2px 0 8px; }
.hist .l { font-size: 13px; color: var(--muted); }

/* Every past session is one line - date, size, duration - inside a single
   card, so months of training scroll as a list. The breakdown lives behind the
   caret. */
.hist-list { padding: 4px 14px; }
.h-item { border-bottom: 1px solid var(--line); }
.h-item:last-child { border-bottom: 0; }

.h-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; padding: 13px 0;
}
.h-row:active { opacity: .6; }
.h-day {
  flex: 1; min-width: 0; font-size: 15px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.h-meta {
  flex: none; font-size: 13px; color: var(--muted);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.h-meta i { font-style: normal; padding: 0 5px; color: #5a5a5e; }
.h-caret { flex: none; font-size: 10px; color: var(--muted); }
.h-item.open .h-day { color: var(--accent); }

.h-open { padding: 2px 0 14px; }
.h-sub { font-size: 12px; color: var(--muted); margin-bottom: 10px; }

.h-ex { padding: 9px 0; border-top: 1px solid var(--line); }
.h-ex-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.h-ex-name {
  font-size: 14px; font-weight: 500; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.h-ex-n { flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.h-sets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.h-set {
  font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums;
  background: var(--surface-2); border-radius: 7px; padding: 4px 8px;
}
.h-set i { font-style: normal; font-weight: 500; font-size: 10.5px; color: var(--muted); }
.h-set b { font-weight: 700; color: var(--accent); margin-left: 5px; }
.h-note { font-size: 12px; color: var(--muted); margin-top: 7px; }

.empty { text-align: center; color: var(--muted); padding: 36px 20px; font-size: 14px; }

.pill { font-size: 11px; background: var(--surface-2); border-radius: 20px; padding: 3px 9px; color: var(--muted); }

/* Pills used as controls need a real tap target. */
button.pill { padding: 9px 12px; min-height: 34px; }
.topbar h1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .sub { overflow: hidden; text-overflow: ellipsis; }

/* Phone-first app viewed on a desktop screen: hold it in a centred column
   instead of stretching a bottom tab bar across 1400px. */
@media (min-width: 700px) {
  body { background: #0a0a0b; }
  #app {
    max-width: 430px; margin: 0 auto; min-height: 100vh;
    background: var(--bg); border-inline: 1px solid var(--line);
  }
  nav.tabs { left: 50%; transform: translateX(-50%); width: 430px; border-inline: 1px solid var(--line); }
  .rest-bar { left: 50%; transform: translateX(-50%); width: 430px; }
  .sheet { max-width: 430px; left: 50%; transform: translateX(-50%); border-inline: 1px solid var(--line); }
}

/* A muscle at zero still needs to read as "nothing yet" rather than as an
   empty track, so the red state stays visible at 0%. */
.bar i.none { min-width: 4px; }

/* Build stamp. Small and out of the way, but present so "did the update land?"
   is answerable by looking. */
.version {
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  padding: 4px 0 24px;
  font-variant-numeric: tabular-nums;
}
.version b { color: #6b6b70; font-weight: 600; }

/* A session left open for hours. It has to read as a question to answer, not
   as a stat, so it sits above everything with the two ways out on it. */
.stale {
  background: #23180a;
  border: 1px solid #5a4420;
  border-radius: var(--radius);
  padding: 13px 14px;
  margin-bottom: 14px;
}
.stale-t { font-size: 14px; font-weight: 600; color: #ffd60a; }
.stale-b { font-size: 12.5px; line-height: 1.45; color: var(--muted); margin-top: 4px; }
.stale-acts { display: flex; gap: 8px; margin-top: 11px; }
.stale-acts .btn { flex: 1; }

/* ---------- what to train next ---------- */

.coach {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 18px;
  overflow: hidden;
}
.coach.open { border-color: #34405a; }

.coach-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  padding: 13px 14px;
}
.coach-head:active { background: var(--surface-2); }
.coach-txt { flex: 1; min-width: 0; }
.coach-k {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .7px;
  color: var(--muted);
}
.coach-v {
  font-size: 16px;
  font-weight: 600;
  color: var(--accent);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.coach-s { font-size: 12px; color: var(--muted); margin-top: 3px; }
.coach-caret { color: var(--muted); font-size: 11px; flex: none; }

.coach-body { border-top: 1px solid var(--line); }

.sug {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
}
.sug:active { background: var(--surface-2); }
.sug-rank {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sug-main { flex: 1; min-width: 0; }
.sug-name {
  display: block;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sug-parts { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }
.sug-parts b { color: #a8a8ad; font-weight: 600; }
.sug-gain {
  flex: none;
  font-size: 14px;
  font-weight: 700;
  color: var(--green);
  font-variant-numeric: tabular-nums;
}

.coach-note {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
  padding: 11px 14px;
  background: #1a1608;
  border-bottom: 1px solid var(--line);
}
.coach-note b { color: #ffd60a; font-weight: 600; }

.coach-foot { font-size: 11px; color: #6b6b70; padding: 10px 14px; }
.coach-empty { font-size: 13px; color: var(--muted); padding: 14px; line-height: 1.5; }

/* A gap nothing in rotation can close - needs to read as a prompt, not a stat. */
.coach-gap {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
  padding: 11px 14px;
  background: #1c0f0f;
  border-bottom: 1px solid var(--line);
}
.coach-gap b { color: #ff9f8a; font-weight: 600; }

/* Closed, the panel is a single label. */
.coach-head { justify-content: space-between; }
.coach-head .coach-v { font-size: 15px; font-weight: 600; color: var(--accent); }
.coach-sum {
  font-size: 12px;
  color: var(--muted);
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
}
.coach-sum b { color: var(--text); font-weight: 600; }

/* ---------- weekly goal ---------- */

/* One row: percent, bar, sets, caret. It stays a single line at phone widths -
   the bar is the only part that flexes. */
.wk-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 2px 0;
}
.wk-row:active { opacity: .6; }
.wk-pct {
  flex: none;
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -1px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.wk-pct span { font-size: 15px; font-weight: 500; color: var(--muted); }
.wk-bar { display: block; flex: 1; min-width: 40px; }
.wk-sets {
  flex: none;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.wk-caret { flex: none; font-size: 10px; color: var(--muted); }

.wk-past { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 4px; }
.wk-hist { display: flex; align-items: center; gap: 10px; padding: 7px 0; }
.wk-hist-lbl {
  flex: none;
  width: 92px;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wk-hist-pct {
  flex: none;
  width: 38px;
  text-align: right;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.wk-foot { font-size: 11px; line-height: 1.45; color: #6b6b70; padding: 8px 0 2px; }

/* ---------- exercise name as a way in ---------- */

.ex-name { text-align: left; padding: 0; }
.ex-name::after { content: ' ›'; color: var(--muted); font-weight: 400; }
.ex-name:active { opacity: .6; }

/* The block a suggestion just landed on, so the jump is visible rather than
   leaving you to work out what moved. */
.ex.flash { animation: flash 1.1s ease-out; }
@keyframes flash {
  from { background: rgba(47,124,246,.20); box-shadow: 0 0 0 8px rgba(47,124,246,.20); }
  to { background: transparent; box-shadow: 0 0 0 8px transparent; }
}

/* ---------- swipe a set away ---------- */

/* pan-y keeps vertical scrolling with the browser and gives us the sideways
   drag; without it the browser claims the gesture and cancels the pointer
   mid-swipe. It has to go on the cells and their contents, not just the row:
   Blink does not honour touch-action on a table row, so a rule on <tr> alone
   leaves the effective value at auto and the swipe dies on the second move. */
table.sets, table.sets td, table.sets td * { touch-action: pan-y; }
table.sets tbody td { transform: translateX(var(--dx, 0px)); transition: transform .18s ease; }
table.sets tbody tr.swiping td { transition: none; background: var(--bg); }
table.sets tbody tr.swiping.on td { background: var(--green-bg); }
/* Revealed behind the row as it moves: dark red while dragging, full red once
   letting go would actually delete. */
table.sets tbody tr.swiping { background: #3a100c; }
table.sets tbody tr.swiping.armed { background: var(--red); }

.swipe-hint { font-size: 11px; color: #6b6b70; padding: 7px 2px 0; }

/* ---------- one exercise's history ---------- */

.xh { padding: 12px 16px; border-bottom: 1px solid var(--line); }
.xh-d { font-size: 14px; font-weight: 500; }
.xh-k { font-size: 12px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.xh-sets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.xh-set {
  font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums;
  background: var(--surface-2); border-radius: 7px; padding: 5px 8px;
}
.xh-set i { font-style: normal; font-weight: 500; font-size: 11px; color: var(--muted); }
.xh-set.best { background: #2a2408; color: var(--gold); }
.xh-set.best i { color: #b9a233; }
.xh-note { font-size: 12px; color: var(--muted); margin-top: 7px; }

/* ---------- rest alerts ---------- */

.alert-row {
  display: flex; align-items: center; gap: 12px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
.alert-txt { flex: 1; min-width: 0; }

/* ---------- log header ---------- */

/* Time / Exercises / Sets is the running state of the session, so it travels
   with the bar above it rather than scrolling away behind the first exercise.
   Sticking the wrapper rather than the two rows separately means the stats
   never need to know how tall the bar is - which changes with the safe-area
   inset and with the length of the workout title. */
.stickyhead {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
}
.stickyhead .topbar { position: static; }
