/* ── Layout ─────────────────────────────────────────────────────────────── */

.wrap { max-width: var(--page); margin: 0 auto; padding: 0 var(--s-4); }

.bar {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.bar__in { display: flex; align-items: center; gap: var(--s-5); height: var(--bar-h); }

.mark { display: flex; align-items: center; gap: 9px; text-decoration: none; color: var(--ink); padding: 7px 4px; margin-left: -4px; border-radius: var(--r-1); }
.mark svg { display: block; width: 22px; height: 22px; flex: none; }
/* The stroke lives here rather than on the element, because style-src is
   'self' with no 'unsafe-inline' and a style attribute in the markup is
   refused on the deployment — and only there. */
.mark svg path { stroke: var(--accent); }
.mark b { font: 400 var(--t-4)/1 var(--serif); letter-spacing: 0.01em; }

/* min-width:0 and the scroll are the safety valve: whatever happens to the
   labels, the nav can never be the thing that makes the *page* scroll
   sideways. scrollbar-width:none because a visible scrollbar under five words
   reads as a fault. */
.nav {
  display: flex; gap: 2px; margin-left: auto;
  min-width: 0; overflow-x: auto; scrollbar-width: none;
}
.nav::-webkit-scrollbar { display: none; }
.nav button {
  font: 500 var(--t-1)/1 var(--mono);
  letter-spacing: 0.04em;
  padding: 11px 13px;
  min-height: 36px;
  border-radius: var(--r-pill);
  color: var(--ink-3);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.nav button:hover { color: var(--ink); background: var(--shade); }
.nav button[aria-current='page'] { color: var(--ink); background: var(--shade); }

/* A prompt is waiting on a screen you are not looking at. */
.nav button[data-due='1'] { color: var(--accent-ink); }
.nav button[data-due='1']::after {
  content: '';
  display: inline-block;
  width: 6px; height: 6px; margin-left: 6px;
  border-radius: 50%; background: var(--accent);
  vertical-align: 1px;
}
@media (prefers-reduced-motion: no-preference) {
  .nav button[data-due='1']::after { animation: pulse 2.4s var(--ease) infinite; }
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

.view { padding: var(--s-6) 0 var(--s-7); }
.view[hidden] { display: none; }

/* ── Cards and sections ─────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  box-shadow: var(--lift-1);
}
.card--pad { padding: var(--s-5); }

.sec { margin-top: var(--s-6); }
.sec > .k { margin-bottom: var(--s-3); }
.sec:first-child { margin-top: 0; }

.grid { display: grid; gap: var(--s-4); }
.grid--2 { grid-template-columns: 1fr 1fr; }
.grid--3 { grid-template-columns: repeat(3, 1fr); }

.prose { color: var(--ink-2); max-width: 68ch; }
.prose p + p { margin-top: var(--s-3); }
.muted { color: var(--ink-3); }
.small { font-size: var(--t-2); }

/* ── The hero: the one number this app is about ─────────────────────────── */

.hero {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  box-shadow: var(--lift-2);
  padding: var(--s-6) var(--s-5) var(--s-5);
  position: relative;
  overflow: hidden;
}
.hero__k { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }

.big {
  font: 400 var(--t-8)/0.92 var(--serif);
  letter-spacing: -0.02em;
  margin: var(--s-3) 0 0;
  display: flex; align-items: baseline; gap: 10px;
  transition: color var(--t-med) var(--ease);
}
.big small { font: 500 var(--t-4)/1 var(--mono); letter-spacing: 0.02em; color: var(--ink-3); }

/* The bout ramp. Neutral under thirty minutes — colour appears only when
   there is something to say — then the family ochre, then the rust. There is
   no green rung and no red one: nothing here is a pass, and nothing is a
   telling-off. */
.big[data-ramp='0'] { color: var(--ink); }
.big[data-ramp='1'] { color: var(--accent-ink); }
.big[data-ramp='2'] { color: var(--alert); }

.hero__sub { margin-top: var(--s-2); color: var(--ink-3); font-size: var(--t-2); }

/* Time to the next prompt, as a line rather than a ring. A ring would be a
   second drawing of the same fact as the number above it. */
.meter { margin-top: var(--s-5); }
.meter__track {
  height: 5px; border-radius: var(--r-pill);
  background: var(--sunk); overflow: hidden;
}
.meter__fill {
  height: 100%; border-radius: var(--r-pill);
  background: var(--accent);
  transition: width 1s linear;
}
.meter__lab { display: flex; justify-content: space-between; margin-top: var(--s-2); gap: var(--s-3); }

/* ── The prompt ─────────────────────────────────────────────────────────── */

.prompt { border-color: var(--accent); box-shadow: var(--lift-2); }
.prompt__head { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-bottom: var(--s-4); }
.prompt h2 { font-size: var(--t-6); margin-bottom: var(--s-2); }
.prompt__cue { font-size: var(--t-4); line-height: 1.45; color: var(--ink); max-width: 46ch; }
.prompt__why { margin-top: var(--s-3); color: var(--ink-3); font-size: var(--t-2); max-width: 58ch; }

.detail { margin-top: var(--s-4); padding-left: var(--s-4); border-left: 2px solid var(--line-firm); }
.detail li { list-style: none; color: var(--ink-2); font-size: var(--t-2); }
.detail li + li { margin-top: var(--s-2); }

.count {
  font: 400 var(--t-7)/1 var(--serif);
  color: var(--accent-ink);
  margin: var(--s-4) 0 0;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */

.row { display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }
.row--end { justify-content: flex-end; }
.spread { margin-top: var(--s-5); }

.btn {
  font: 500 var(--t-2)/1 var(--mono);
  letter-spacing: 0.03em;
  padding: 12px 18px;
  /* Every control clears 36px in its short dimension. tools/check-ui.mjs
     measures it at 420px on all five screens, because a settings row that is
     comfortable with a mouse is a 31px target on the phone this also runs on. */
  min-height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-firm);
  color: var(--ink);
  background: var(--surface);
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  white-space: nowrap;
}
.btn:hover { background: var(--sunk); border-color: var(--ink-3); }
.btn:active { transform: translateY(1px); }
.btn[aria-pressed='true'] { background: var(--accent); border-color: var(--accent); color: #fff; }
:root[data-theme='dark'] .btn[aria-pressed='true'] { color: #17130c; }

.btn--go { background: var(--accent); border-color: var(--accent); color: #fff; }
:root[data-theme='dark'] .btn--go { color: #17130c; }
.btn--go:hover { background: var(--accent-ink); border-color: var(--accent-ink); color: #fff; }
:root[data-theme='dark'] .btn--go:hover { background: var(--ink); border-color: var(--ink); color: #17130c; }

.btn--quiet { border-color: transparent; color: var(--ink-3); }
.btn--quiet:hover { color: var(--ink); background: var(--shade); border-color: transparent; }
.btn--sm { padding: 8px 13px; font-size: var(--t-1); min-height: 36px; }
.btn[disabled] { opacity: 0.45; cursor: default; }
.btn[disabled]:hover { background: var(--surface); border-color: var(--line-firm); }

.pill {
  font: 500 var(--t-0)/1 var(--mono);
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 6px 10px; border-radius: var(--r-pill);
  border: 1px solid var(--line-firm); color: var(--ink-3);
  white-space: nowrap;
}
.pill--accent { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.pill--alert { color: var(--alert); border-color: color-mix(in srgb, var(--alert) 45%, transparent); }
.pill--solid { background: var(--accent); border-color: var(--accent); color: #fff; }
:root[data-theme='dark'] .pill--solid { color: #17130c; }

/* ── The day strip ──────────────────────────────────────────────────────── */

.strip { margin-top: var(--s-3); }
.strip__track {
  position: relative;
  height: 46px;
  background: var(--sunk);
  border-radius: var(--r-2);
  overflow: hidden;
  border: 1px solid var(--line);
}
.strip__b {
  position: absolute; top: 0; bottom: 0;
  border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 22%, transparent);
}
.strip__b[data-ramp='1'] { background: color-mix(in srgb, var(--accent) 62%, transparent); }
.strip__b[data-ramp='2'] { background: color-mix(in srgb, var(--alert) 70%, transparent); }
.strip__b[data-open='1'] { border-right: 2px solid var(--ink); }
/* An interruption that got you out of the chair. A tick rather than a block,
   because at this scale five minutes is four pixels and a block that thin
   reads as a rendering artefact. */
.strip__cut { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--surface); }
.strip__cut::after {
  content: ''; position: absolute; left: -2px; top: 50%; transform: translateY(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}
/* The app was not running. Drawn as absence rather than filled in, because
   nothing is known about it. */
.strip__gap {
  position: absolute; top: 0; bottom: 0;
  background: repeating-linear-gradient(-45deg, transparent 0 4px, var(--line) 4px 5px);
}
.strip__axis { display: flex; justify-content: space-between; margin-top: 6px; }
.strip__now { position: absolute; top: -2px; bottom: -2px; width: 1px; background: var(--alert); }

/* ── Stat tiles ─────────────────────────────────────────────────────────── */

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s-3); margin-top: var(--s-4); }
.tile {
  background: var(--sunk);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  padding: var(--s-4);
}
.tile__v { font: 400 var(--t-6)/1 var(--serif); margin-top: 6px; display: block; }
.tile__v[data-ramp='1'] { color: var(--accent-ink); }
.tile__v[data-ramp='2'] { color: var(--alert); }
.tile__n { margin-top: 6px; color: var(--ink-3); font-size: var(--t-1); line-height: 1.45; }

/* ── Lists: plan, log, evidence ─────────────────────────────────────────── */

summary.k { min-height: 36px; display: flex; align-items: center; }
summary.k::marker { color: var(--ink-3); }

.list { border-top: 1px solid var(--line); }
.item {
  display: grid; grid-template-columns: 74px 1fr auto;
  gap: var(--s-3); align-items: baseline;
  padding: var(--s-3) 0; border-bottom: 1px solid var(--line);
}
.item__t { font: 500 var(--t-1)/1.5 var(--mono); color: var(--ink-3); }
.item__n { font-size: var(--t-2); color: var(--ink); }
.item__n span { color: var(--ink-3); display: block; font-size: var(--t-1); margin-top: 2px; }
.item[data-state='skip'] .item__n,
.item[data-state='missed'] .item__n { color: var(--ink-3); text-decoration: line-through; text-decoration-thickness: 1px; }
.item[data-state='ahead'] { opacity: 0.62; }

.ev { padding: var(--s-5) 0; border-bottom: 1px solid var(--line); }
.ev:last-child { border-bottom: 0; }
.ev h3 { font-size: var(--t-4); margin-bottom: var(--s-2); }
.ev__cite { font: 400 var(--t-1)/1.55 var(--mono); color: var(--ink-3); margin-top: var(--s-3); }
.ev__cite a { color: var(--ink-3); }

/* The file input is visually hidden rather than display:none, because
   display:none takes it out of the tab order and its label is not focusable —
   so the only way to import a log was with a mouse. */
.btn input[type='file'] {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}
.btn:focus-within { outline: 2px solid var(--accent-ink); outline-offset: 2px; }

.strength { display: inline-flex; gap: 3px; vertical-align: middle; margin-right: 8px; }
.strength i { width: 7px; height: 7px; border-radius: 50%; background: var(--line-firm); display: block; }
.strength i[data-on='1'] { background: var(--accent); }

/* ── Week grid ──────────────────────────────────────────────────────────── */

.week { display: grid; gap: var(--s-2); }
.week__row { display: grid; grid-template-columns: 92px 1fr 76px 54px; gap: var(--s-3); align-items: center; }
/* A day with something in it opens that day, so the row is a real button —
   reset to look like the plain row it replaced. */
button.week__row {
  width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer;
  background: none; border: 0; padding: var(--s-1) var(--s-2); border-radius: var(--r-1);
  min-height: 36px;
}
button.week__row:hover { background: var(--sunk); }
button.week__row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.week__row .k { text-align: right; }
.week__bar { height: 26px; background: var(--sunk); border-radius: var(--r-1); position: relative; overflow: hidden; border: 1px solid var(--line); }
.week__fill { position: absolute; inset: 0 auto 0 0; background: color-mix(in srgb, var(--accent) 55%, transparent); }
.week__fill[data-ramp='2'] { background: color-mix(in srgb, var(--alert) 60%, transparent); }
.week__fill[data-ramp='0'] { background: color-mix(in srgb, var(--ink) 25%, transparent); }
.week__v { font: 400 var(--t-3)/1 var(--serif); text-align: right; }

/* ── Settings ───────────────────────────────────────────────────────────── */

.field { display: grid; grid-template-columns: 1fr auto; gap: var(--s-4); align-items: center; padding: var(--s-4) 0; border-bottom: 1px solid var(--line); }
.field:last-child { border-bottom: 0; }
.field__l { font-size: var(--t-2); }
.field__l span { display: block; color: var(--ink-3); font-size: var(--t-1); margin-top: 3px; line-height: 1.5; max-width: 54ch; }
select, input[type='time'], input[type='number'] {
  background: var(--sunk); border: 1px solid var(--line-firm); color: var(--ink);
  border-radius: var(--r-1); padding: 9px 10px; min-height: 38px;
  font: 500 var(--t-2)/1 var(--mono);
}
.days { display: flex; gap: 4px; }
.days button {
  width: 38px; height: 38px; border-radius: var(--r-1);
  border: 1px solid var(--line-firm); font: 500 var(--t-1)/1 var(--mono);
  color: var(--ink-3);
}
.days button[aria-pressed='true'] { background: var(--accent); border-color: var(--accent); color: #fff; }
:root[data-theme='dark'] .days button[aria-pressed='true'] { color: #17130c; }

/* ── Notices ────────────────────────────────────────────────────────────── */

.note {
  display: flex; gap: var(--s-3); align-items: flex-start;
  background: var(--sunk); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-2); padding: var(--s-4);
  font-size: var(--t-2); color: var(--ink-2);
  margin-top: var(--s-4);
}
.note .k { flex: none; padding-top: 3px; }
.note--alert { border-left-color: var(--alert); }

.empty { padding: var(--s-6) 0; color: var(--ink-3); font-size: var(--t-2); text-align: center; }

/* ── Narrow ─────────────────────────────────────────────────────────────── */

@media (max-width: 760px) {
  :root { --t-8: 58px; --t-7: 34px; --t-6: 25px; }
  .wrap { padding: 0 var(--s-3); }
  .bar__in { gap: var(--s-3); }
  .mark b { font-size: var(--t-3); }
  .nav { gap: 0; }
  .nav button { padding: 11px 9px; font-size: var(--t-0); letter-spacing: 0.02em; }
  .grid--2, .grid--3 { grid-template-columns: 1fr; }
  .week__row { grid-template-columns: 62px 1fr 62px; }
  /* `.week__v` is the third of four children, so `:last-child` matched nothing
     and the fourth cell wrapped to a second row instead — every populated
     History row was two lines tall on a phone, with "3 over" right-aligned
     under the weekday. Target the cell that is genuinely last. */
  .week__row > :last-child { display: none; }
  .field { grid-template-columns: 1fr; gap: var(--s-3); }
  .item { grid-template-columns: 62px 1fr; }
  .item > :last-child { grid-column: 1 / -1; }
}

/* Below about 400px the five labels and the wordmark cannot share a row.
   The nav takes its own instead of scrolling: a scrolling nav on a five-item
   app hides two of them, and nobody scrolls a row that does not look
   scrollable. Two rows of header on a phone is the cheaper cost. */
@media (max-width: 400px) {
  /* padding-block, not the shorthand: this element carries the .wrap class
     too, and `padding: 8px 0 6px` zeroes the horizontal padding that keeps
     the row off the edge of the screen. The nav then spans the full viewport
     and the first and last tabs sit hard against both edges — legible, and it
     reads as a rendering fault rather than as a layout. */
  .bar__in { flex-wrap: wrap; height: auto; padding-top: 8px; padding-bottom: 6px; gap: var(--s-2); }
  .nav { width: 100%; margin-left: 0; justify-content: space-between; }
  .nav button { padding: 10px 6px; letter-spacing: 0; }
  .card--pad { padding: var(--s-4); }
  .note { flex-wrap: wrap; }
  /* Seven fixed 38px squares plus their gaps need 290px, which is more than a
     320px phone has left after the padding. A grid shrinks instead. */
  .days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
  .days button { width: 100%; }
}
