/* Prompt Tilt — design system
   Paper/ink/oxblood. Square corners. Hairlines. No shadows. The beam wants space. */

/* Self-hosted fonts (latin subset) — no third-party requests.
   Space Grotesk is a variable-weight file covering 400–700. */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/space-grotesk-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/space-mono-400-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/space-mono-700-latin.woff2') format('woff2');
}

/* ---------- the palette ----------
   Ruled 2026-08-30: this is the project's design system and it overrides the
   CLAUDE.md baseline. Paper, ink, oxblood; nothing else earns a colour.
   The oxblood and the secondary grey are darker than they shipped because the
   values they shipped at did not measure up — 4.25:1 and 3.07:1 against a
   4.5:1 requirement. The hue is unchanged. Run `node checks/run.js` to re-run
   the arithmetic against these tokens; the checks read the values out of this
   file, so the numbers and the evidence cannot drift apart. */

:root {
  color-scheme: light dark;

  --paper: #F5F1EA;
  --paper-raised: #FBF9F4;
  --desk: #EBE7DE;
  --ink: #141414;
  --oxblood: #B93D2E;
  --muted: #63625E;
  --rule: #D8D2C6;

  /* No single grey clears 4.5:1 on both the paper and the reversed ink bar,
     so the bar carries its own three tokens. They also keep the bar from
     turning into a bright slab when the palette inverts. */
  --bar-bg: #141414;
  --bar-fg: #F5F1EA;
  --bar-muted: #9A968E;
  --on-oxblood: #F5F1EA;

  --scrim: rgba(20, 20, 20, .4);

  --font-display: 'Space Grotesk', sans-serif;
  --font-mono: 'Space Mono', monospace;

  --col-max: 680px;
  --gutter: 18px;
  --tap: 44px;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* Paper and ink, swapped — not a grey theme laid over the top. She is in bed
   at 10pm; the page becomes the ink and the type becomes the paper. The
   oxblood lifts on the same hue so it still reads as the accent rather than a
   stain, and the reversed bar drops to a quiet raised tone so card headers
   don't become the brightest thing in a dark room. Every pair here is held to
   the same thresholds as the light palette. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #141414;
    --paper-raised: #1E1E1C;
    --desk: #0B0B0A;
    --ink: #F5F1EA;
    --oxblood: #E4705F;
    --muted: #94918B;
    --rule: #3A3833;

    --bar-bg: #2A2A27;
    --bar-fg: #F5F1EA;
    --bar-muted: #B0AAA1;
    --on-oxblood: #141414;

    --scrim: rgba(0, 0, 0, .62);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--desk);
  color: var(--ink);
}

body {
  font-family: var(--font-mono);
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  justify-content: center;
}

h1, h2, h3, p { margin: 0; }

a { color: var(--ink); }
a:hover, a:focus-visible { color: var(--oxblood); }

button {
  font-family: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

input {
  font-family: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--oxblood);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- app shell ---------- */

#app {
  width: 100%;
  max-width: var(--col-max);
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--paper);
  color: var(--ink);
  display: flex;
  flex-direction: column;
}

@media (min-width: 720px) {
  body { padding: 32px 0; }
  #app { min-height: calc(100vh - 64px); min-height: calc(100dvh - 64px); border: 1px solid var(--rule); }
}

.screen {
  flex: 1;
  padding: 16px var(--gutter) 12px;
}

/* ---------- masthead + tabs ---------- */

.masthead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 2px solid var(--ink);
  padding: 0 var(--gutter) 8px;
  padding-top: calc(20px + var(--safe-top));
}

.masthead__mark {
  font-size: 11px;
  letter-spacing: .2em;
  font-weight: 700;
}

.masthead__date {
  font-size: 9px;
  letter-spacing: .15em;
  color: var(--muted);
}

.tabbar {
  display: flex;
  padding: 0 var(--gutter);
  border-bottom: 1px solid var(--rule);
  gap: 8px;
}

/* 44px tall and 8px apart, without costing the check-in the height: the
   tabbar's own padding comes out and the tap target provides it instead. */
.tab {
  flex: 1;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  letter-spacing: .18em;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.tab[aria-current="page"] {
  color: var(--ink);
  font-weight: 700;
  border-bottom-color: var(--ink);
}

/* ---------- eyebrow / labels ---------- */

.eyebrow {
  font-size: 10px;
  letter-spacing: .22em;
  color: var(--muted);
  text-transform: uppercase;
}

.eyebrow--oxblood { color: var(--oxblood); }

.field-label {
  font-size: 9px;
  letter-spacing: .18em;
  color: var(--muted);
  text-transform: uppercase;
}

/* ---------- prose ---------- */

.prose {
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink);
}

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

/* ---------- section spacing ---------- */

.section { margin-top: 16px; }
.section--lg { margin-top: 24px; }

/* ---------- notice (oxblood left accent) ---------- */

.notice {
  border-left: 3px solid var(--oxblood);
  background: var(--paper-raised);
  padding: 10px 12px;
}

.notice__eyebrow {
  font-size: 9px;
  letter-spacing: .22em;
  color: var(--oxblood);
}

.notice p {
  font-family: var(--font-display);
  font-size: 12px;
  line-height: 1.5;
  margin-top: 5px;
}

/* ---------- card (ink border, ink header bar) ---------- */

.card {
  border: 1px solid var(--ink);
  margin-top: 14px;
}

.card__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 9px 12px;
  background: var(--bar-bg);
  color: var(--bar-fg);
  font-size: 9px;
  letter-spacing: .2em;
}

.card__header span:last-child { color: var(--bar-muted); }

/* The import confirmation is the one bar that fills with oxblood. */
.card__header--alert { background: var(--oxblood); color: var(--on-oxblood); }
.card__header--alert span:last-child { color: var(--on-oxblood); }

/* quiet hairline table/list */

.list {
  border: 1px solid var(--rule);
  margin-top: 14px;
}

.list__header {
  display: flex;
  justify-content: space-between;
  padding: 8px 10px;
  font-size: 9px;
  letter-spacing: .2em;
  color: var(--muted);
  border-bottom: 1px solid var(--rule);
}

.list__row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  font-size: 11px;
  border-top: 1px solid var(--rule);
}

.list__header + .list__row { border-top: none; }
.list__row--muted { color: var(--muted); }
.list__row--live { color: var(--oxblood); font-weight: 700; }
.list__row--total { border-top: 2px solid var(--ink); font-weight: 700; }

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

.btn {
  display: block;
  text-align: center;
  padding: 15px 0;
  font-size: 12px;
  letter-spacing: .25em;
  font-weight: 700;
  width: 100%;
  border: 1px solid var(--ink);
}

.btn--primary { background: var(--ink); color: var(--paper); }
.btn--live { background: var(--oxblood); color: var(--on-oxblood); border-color: var(--oxblood); }
.btn--ghost { background: transparent; color: var(--ink); }
.btn--receipt { background: var(--paper); color: var(--ink); border: none; border-top: 2px solid var(--ink); }

/* However long the entry runs, the commit does not scroll away. Full-bleed
   across the gutter, pinned above the home indicator. */
.commit-bar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  margin: 12px calc(-1 * var(--gutter)) 0;
  padding-bottom: var(--safe-bottom);
  background: var(--paper);
  border-top: 2px solid var(--ink);
}

.commit-bar .btn { border: none; }

.btn-row { display: flex; gap: 10px; margin-top: 12px; }
.btn-row .btn { padding: 12px 0; font-size: 11px; }

.chip-row { display: flex; gap: 8px; }

.chip {
  flex: 1;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--muted);
  text-align: center;
  padding: 8px 4px;
  font-size: 12px;
}

.chip--quiet { border-color: var(--rule); color: var(--muted); }

/* ---------- stepper (cutoff etc.) ---------- */

.stepper { display: flex; align-items: center; gap: 10px; }

.stepper__btn {
  width: var(--tap); height: var(--tap);
  border: 1px solid var(--muted);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px;
}

.stepper__value {
  font-size: 20px;
  font-weight: 700;
  width: 68px;
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ---------- stamp marks (tap to stamp) ---------- */

.stamp-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  min-height: var(--tap);
  border-bottom: 1px solid var(--rule);
  width: 100%;
  text-align: left;
}

.stamp-row:last-child { border-bottom: none; }

.stamp-row__label {
  font-family: var(--font-display);
  font-size: 14px;
}

.stamp-box {
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700;
  border: 2px solid var(--muted);
  color: transparent;
  flex-shrink: 0;
}

.stamp-box--on {
  background: var(--oxblood);
  border-color: var(--oxblood);
  color: var(--on-oxblood);
}

/* ---------- minutes ruler ---------- */

.ruler {
  position: relative;
  height: var(--tap);
  margin-top: 8px;
  border-left: 2px solid var(--ink);
  border-right: 2px solid var(--ink);
  background:
    repeating-linear-gradient(to right, var(--rule) 0, var(--rule) 1px, transparent 1px, transparent 11px) 0 0/100% 16px repeat-x,
    repeating-linear-gradient(to right, var(--muted) 0, var(--muted) 1px, transparent 1px, transparent 33px) 0 16px/100% 28px repeat-x;
  touch-action: none;
}

/* The control is the grab point. This shipped as an opacity:0 range input
   behind a 3px needle that sat under the ruler's own border at value 0 —
   one-handed in the dark there was nothing to take hold of. The native thumb
   is now the indicator: visible, oxblood, and the full 44px of the track. */
.ruler__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

.ruler__input::-webkit-slider-runnable-track { height: 100%; background: transparent; }
.ruler__input::-moz-range-track { height: 100%; background: transparent; }

.ruler__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 26px;
  height: var(--tap);
  background: var(--oxblood);
  border: 2px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
}

.ruler__input::-moz-range-thumb {
  width: 26px;
  height: var(--tap);
  background: var(--oxblood);
  border: 2px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
}

.ruler-scale {
  display: flex;
  justify-content: space-between;
  font-size: 8px;
  letter-spacing: .15em;
  color: var(--muted);
  margin-top: 4px;
}

/* ---------- compare bars ---------- */

.bar-compare {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}

.bar-compare__label {
  font-size: 8px;
  letter-spacing: .1em;
  color: var(--muted);
  width: 44px;
  flex-shrink: 0;
}

.bar-compare__track {
  flex: 1;
  position: relative;
  height: 10px;
  background: var(--desk);
}

.bar-compare__fill {
  height: 100%;
  background: var(--ink);
}

.bar-compare__mean {
  position: absolute;
  top: -3px; bottom: -3px;
  width: 2px;
  background: var(--oxblood);
}

.bar-compare__value {
  font-size: 9px;
  color: var(--muted);
  width: 56px;
  text-align: right;
  flex-shrink: 0;
}

/* ---------- session rows ---------- */

.session-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 12px;
  font-size: 11px;
  border-top: 1px solid var(--rule);
}

.session-row__time { color: var(--muted); }
.session-row__min { font-weight: 700; white-space: nowrap; }
.session-row__edit {
  font-size: 9px;
  letter-spacing: .15em;
  color: var(--muted);
  min-width: var(--tap);
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.session-row__edit--active { color: var(--oxblood); font-weight: 700; }

.session-edit {
  display: flex;
  gap: 8px;
  padding: 0 12px 10px;
  border-top: 1px solid var(--rule);
}

.session-edit .chip { padding: 7px 0; font-size: 12px; }
.session-edit .chip--scratch { border-color: var(--oxblood); color: var(--oxblood); font-size: 11px; letter-spacing: .1em; }

/* ---------- form fields (subscription sheet) ---------- */

.field { margin-top: 16px; }

.field input[type="text"],
.field input[type="number"] {
  display: block;
  width: 100%;
  border: 1px solid var(--ink);
  background: var(--paper-raised);
  padding: 11px 12px;
  font-size: 16px; /* below 16px iOS zooms the page on focus */
  margin-top: 6px;
}

.field--money input, .field--number input {
  font-size: 20px;
  font-weight: 700;
}

.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; }

/* ---------- sheet overlay (add subscription) ---------- */

.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  display: flex;
  justify-content: center;
  align-items: flex-end;
  z-index: 20;
}

@media (min-width: 720px) {
  .sheet-backdrop { align-items: center; }
}

.sheet {
  width: 100%;
  max-width: var(--col-max);
  max-height: 92vh;
  max-height: 92dvh;
  overflow-y: auto;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--ink);
}

.sheet__body { padding: 20px; flex: 1; }

.sheet__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 8px;
}

.sheet__close {
  font-size: 18px;
  color: var(--muted);
  line-height: 1;
  min-width: var(--tap);
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.weigh-box {
  border: 2px solid var(--oxblood);
  margin-top: 20px;
  padding: 14px;
}

.weigh-box__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 6px;
}

.weigh-box__row:first-of-type { margin-top: 10px; }
.weigh-box__row span:first-child { font-size: 11px; color: var(--muted); }
.weigh-box__row span:last-child { font-size: 14px; font-weight: 700; }
.weigh-box__row--yr span:last-child { font-size: 22px; color: var(--oxblood); }
.weigh-box__row--total { padding-top: 8px; margin-top: 10px; border-top: 1px solid var(--rule); }
.weigh-box__row--total span:last-child { font-size: 12px; }
.weigh-box p { margin-top: 10px; }

.sheet-actions { display: flex; border-top: 1px solid var(--ink); padding-bottom: var(--safe-bottom); }
.sheet-actions__cancel {
  width: 110px;
  text-align: center;
  padding: 16px 0;
  font-size: 11px;
  letter-spacing: .2em;
  color: var(--muted);
  border-right: 1px solid var(--rule);
}
.sheet-actions__commit {
  flex: 1;
  background: var(--ink);
  color: var(--paper);
  text-align: center;
  padding: 16px 0;
  font-size: 12px;
  letter-spacing: .25em;
  font-weight: 700;
}

/* ---------- footer seal ---------- */

.seal {
  font-size: 9px;
  letter-spacing: .2em;
  color: var(--muted);
  margin-top: 16px;
  padding: 10px var(--gutter) calc(24px + var(--safe-bottom));
  border-top: 1px solid var(--rule);
}

/* ---------- threshold screen ---------- */

.threshold {
  flex: 1;
  padding: calc(20px + var(--safe-top)) var(--gutter) calc(12px + var(--safe-bottom));
  display: flex;
  flex-direction: column;
}

.threshold__brand {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.threshold__ai {
  font-size: 9px;
  letter-spacing: .15em;
  color: var(--muted);
}

.threshold__name {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -.02em;
  margin-top: 18px;
  line-height: 1.1;
}

.threshold__lede {
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--muted);
  margin-top: 10px;
  line-height: 1.55;
  max-width: 300px;
}

.principles {
  margin-top: 26px;
  border-top: 1px solid var(--rule);
}

.principle {
  display: flex;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--rule);
}

.principle__num { font-size: 10px; color: var(--muted); width: 16px; padding-top: 2px; flex-shrink: 0; }
.principle p { font-family: var(--font-display); font-size: 13px; line-height: 1.5; flex: 1; }

.threshold__cutoff {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 18px;
  border: 1px solid var(--ink);
  padding: 12px 14px;
}

.threshold__spacer { flex: 1; }

/* ---------- svg gauges ---------- */

.gauge-svg { width: 100%; display: block; }

/* Charts take their colours from the palette rather than from hard-coded hex,
   so the beam, the bars and the ribbon invert with everything else. Classes
   rather than var() in presentation attributes: a stylesheet rule is the one
   form guaranteed to apply on every engine. */
.s-ink { stroke: var(--ink); }
.s-muted { stroke: var(--muted); }
.s-ox { stroke: var(--oxblood); }
.s-rule { stroke: var(--rule); }
.f-ink { fill: var(--ink); }
.f-muted { fill: var(--muted); }
.f-ox { fill: var(--oxblood); }
.f-desk { fill: var(--desk); }

.beam-group {
  transform-origin: 60px 20px;
  transition: transform .5s ease;
}

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

/* ---------- data screen toggle ---------- */

.toggle {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  white-space: nowrap;
  border: 1px solid var(--muted);
  color: var(--muted);
  padding: 6px 12px;
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
}

.toggle--on { border-color: var(--ink); color: var(--ink); }

.currency-btn {
  font-size: 18px;
  font-weight: 700;
  border: 1px solid var(--muted);
  padding: 6px 16px;
  min-width: var(--tap);
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ---------- toast ---------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(80px + var(--safe-bottom));
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--paper);
  font-size: 11px;
  letter-spacing: .15em;
  padding: 10px 16px;
  z-index: 30;
}

/* ---------- first paint, and the screen that says what went wrong ----------
   `boot` is in index.html, so it is on screen before app.js has been round
   IndexedDB. Same masthead geometry as the real shell so nothing jumps. */

.boot, .failure {
  padding: calc(20px + var(--safe-top)) var(--gutter) calc(24px + var(--safe-bottom));
}

.boot__mark, .failure__mark {
  display: block;
  font-size: 11px;
  letter-spacing: .2em;
  font-weight: 700;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 8px;
}

.boot__note {
  display: block;
  margin-top: 20px;
  font-size: 11px;
  letter-spacing: .15em;
  color: var(--muted);
}

.failure p {
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1.55;
  margin-top: 16px;
}

.failure .btn { margin-top: 20px; }

/* ---------- small helpers ---------- */

.flex-between { display: flex; justify-content: space-between; align-items: baseline; }
.mt-header { margin-top: 16px; }
.small-note { font-size: 9px; color: var(--muted); margin-top: 6px; line-height: 1.6; }

/* ---------- phone readability ----------
   On a phone the smallest sizes fall below what an eye can settle on.
   Raise only the text that carries real words or figures; the chrome
   (eyebrows, seal, masthead) keeps its size. */

@media (max-width: 719px) {
  .tab { font-size: 10px; }
  .field-label { font-size: 10px; }
  .notice p { font-size: 13px; }
  .list__row { font-size: 12px; }
  .session-row { font-size: 12px; }
  .session-row__edit { font-size: 10px; }
  .bar-compare__label { font-size: 9px; }
  .bar-compare__value { font-size: 10px; }
  .ruler-scale { font-size: 9px; }
  .small-note { font-size: 11px; }
}
