/* Snusee — components and screens.
 * Every value comes from tokens.css. Mobile-first; target 390x844, must also
 * survive 360x800 and 430x932.
 */

/* ------------------------------------------------------------- reset ---- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html, body { height: 100%; }

body {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;               /* the page body never scrolls sideways */
  -webkit-tap-highlight-color: transparent;
}

button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; padding: 0; }
a { color: var(--pink-deep); text-decoration: none; }
svg { display: block; flex: none; }

h1, h2, h3 { font-family: var(--font-display); font-weight: 700; line-height: 1.25; }

:focus-visible {
  outline: 2px solid var(--pink-deep);
  outline-offset: 3px;
  border-radius: 6px;
}

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

/* ------------------------------------------------------------ layout ---- */
#app { position: relative; z-index: var(--z-content); min-height: 100%; }

.screen {
  min-height: 100dvh;
  /* Bottom padding clears the tab bar AND the floating SOS button. Without
   * the SOS allowance the last card sits under it and is unreadable. */
  padding:
    calc(var(--sp-4) + env(safe-area-inset-top))
    var(--screen-pad)
    calc(var(--tabbar-h) + var(--sos-size) + var(--sp-6) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--card-gap);
}
.screen--plain {   /* no tab bar: onboarding, auth, SOS */
  padding-bottom: calc(var(--sp-6) + env(safe-area-inset-bottom));
}

/* Background motifs sit behind everything and mean nothing.
 *
 * V3 adds two soft colour blooms under the tiled motif. The page was a flat
 * cream wash, and against a flat wash a cream card has nothing to be lighter
 * than -- the blooms give the cards something to sit on. Fixed, so they do
 * not scroll and never read as content. */
.motif {
  position: fixed; inset: 0;
  z-index: var(--z-motif);
  pointer-events: none;
  background: var(--grad-page-lit);
}
.motif::after {
  content: ''; position: absolute; inset: 0;
  background-image: var(--motif-image, none);
  background-size: 320px;
  opacity: .14;
}

.screen-head { margin-bottom: var(--sp-1); }
.screen-head h1 { font-size: 22px; }
.screen-head p  { font-size: 13px; color: var(--ink-soft); line-height: 1.4; }
.screen-head--center { text-align: center; }

.topbar {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}
.topbar .screen-head { flex: 1; }

/* -------------------------------------------------------------- card ---- */
/* Raised surfaces all wear the same three-part treatment: a gradient for the
 * light across the face, --shadow-edge for the lit top rim and hairline ring,
 * and a drop shadow for the lift. Defined once here and reused, so nothing in
 * the app can end up half-lit. */
.card {
  background: var(--grad-card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft), var(--shadow-edge);
  padding: var(--card-pad);
}
.card__title {
  font-family: var(--font-display);
  font-size: 16px; font-weight: 600;
  display: flex; align-items: center; gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
.card__note { font-size: 12px; color: var(--ink-soft); margin-top: var(--sp-2); }

.zdroj {
  font-size: 12px; color: var(--ink-soft);
  margin-top: var(--sp-3); line-height: 1.45;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--card-sunk);
}

/* ------------------------------------------------------------ button ---- */
.btn {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  width: 100%; min-height: 52px; padding: 0 var(--sp-5);
  font-family: var(--font-display); font-size: 17px; font-weight: 600;
  border-radius: var(--radius-btn);
  transition: transform var(--dur-fast) var(--ease-spring),
              box-shadow var(--dur-fast) var(--ease-soft);
}
.btn:active { transform: scale(.96); }

.btn--primary {
  background: var(--grad-primary); color: var(--on-pink);
  box-shadow: var(--shadow-btn);
}
.btn--primary:active { box-shadow: var(--shadow-press); }

.btn--secondary {
  background: transparent; color: var(--pink-deep);
  border: 1.5px solid var(--pink);
}
.btn--ghost { color: var(--ink-soft); font-size: 15px; min-height: 44px; }

.btn[disabled] { opacity: .5; pointer-events: none; }

.btn-icon {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--radius-chip);
  color: var(--ink);
  background: var(--grad-card);
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.btn-icon:active { transform: scale(.92); }

/* ------------------------------------------------------------- input ---- */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field > label { font-size: 13px; color: var(--ink-soft); padding-left: var(--sp-2); }

.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap > svg:first-child {
  position: absolute; left: var(--sp-4); color: var(--ink-faint);
}
.input-wrap:has(> svg:first-child) .input { padding-left: calc(var(--sp-4) * 2 + 20px); }

.input {
  width: 100%; min-height: 52px;
  padding: 0 var(--sp-4);
  background: var(--grad-sunk);
  border: 1.5px solid transparent;
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-well);
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.input::placeholder { color: var(--ink-faint); }
.input:focus { outline: none; border-color: var(--pink); }

textarea.input { min-height: 110px; padding: var(--sp-4); line-height: 1.5; resize: vertical; }

.input-toggle {
  position: absolute; right: var(--sp-4);
  color: var(--ink-faint); display: grid; place-items: center;
}

/* Errors never use red -- a peach accent and plain words instead. */
.form-error {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3) var(--sp-4);
  background: var(--peach-wash);
  border-left: 3px solid var(--peach);
  border-radius: var(--radius-input);
  font-size: 14px;
}

/* -------------------------------------------------------------- chip ---- */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 38px; padding: 0 var(--sp-4);
  background: var(--grad-card);
  border: 1.5px solid transparent;
  border-radius: var(--radius-chip);
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  font-size: 14px;
  transition: transform var(--dur-fast) var(--ease-spring),
              background-color var(--dur-fast) var(--ease-soft);
}
.chip:active { transform: scale(.94); }
.chip[aria-pressed="true"] {
  background: var(--pink-wash);
  border-color: var(--pink);
  color: var(--pink-deep);
  font-weight: 700;
}

.pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--pink-wash); color: var(--pink-deep);
  border-radius: var(--radius-chip);
  font-size: 12px; font-weight: 700;
}

/* ------------------------------------------------------------- timer ---- */
.timer { display: flex; align-items: center; gap: var(--sp-1); }

.timer__tile {
  flex: 1;
  display: flex; flex-direction: column; align-items: center;
  gap: 2px; padding: var(--sp-3) var(--sp-1);
  border-radius: var(--radius-tile);
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  min-width: 0;
  /* The tint is the tile's own accent; this overlay is the same light every
   * other raised surface gets, so the four tiles read as a row of objects
   * rather than four flat swatches. */
  background-image: linear-gradient(168deg,
    rgba(255, 255, 255, .85) 0%, rgba(255, 255, 255, 0) 62%);
}
.timer__value {
  font-family: var(--font-display);
  font-size: 30px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.timer__label {
  font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-soft);
}
.timer__sep {
  font-family: var(--font-display); font-size: 22px; font-weight: 700;
  color: var(--ink-faint); padding-bottom: 14px;
}

.timer__tile--days    { background: var(--pink-wash); }
.timer__tile--days    .timer__value { color: var(--pink-deep); }
.timer__tile--hours   { background: var(--lavender-wash); }
.timer__tile--hours   .timer__value { color: var(--lavender-ink); }
.timer__tile--minutes { background: var(--mint-wash); }
.timer__tile--minutes .timer__value { color: var(--mint-ink); }
.timer__tile--seconds { background: var(--peach-wash); }
.timer__tile--seconds .timer__value { color: var(--peach-ink); }

/* Transform-only so the tick never reflows the row. */
@keyframes tick { 0% { transform: scale(1); } 40% { transform: scale(1.06); } 100% { transform: scale(1); } }
.timer__tile--seconds .timer__value.is-ticking {
  animation: tick var(--dur-fast) var(--ease-spring);
}

/* -------------------------------------------------------------- stats --- */
.stat-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--card-gap); }

.stat {
  background: var(--grad-card); border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft), var(--shadow-edge); padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-1);
}
.stat__label {
  font-size: 12px; color: var(--ink-soft);
  display: flex; align-items: center; gap: var(--sp-2);
}
.stat__value {
  font-family: var(--font-display); font-size: 26px; font-weight: 700;
  line-height: 1.1; overflow-wrap: anywhere;
}
.stat__note { font-size: 11px; color: var(--ink-faint); }

/* ----------------------------------------------------------- progress --- */
.progress { display: flex; flex-direction: column; gap: var(--sp-2); }
.progress__track {
  position: relative; height: 10px;
  background: var(--card-sunk); box-shadow: var(--shadow-well);
  border-radius: var(--radius-chip);
}
.progress__fill {
  height: 100%; border-radius: var(--radius-chip);
  background: var(--grad-progress);
  transition: width var(--dur-slow) var(--ease-soft);
}
.progress__knob {
  position: absolute; top: 50%; translate: -50% -50%;
  width: 26px; height: 26px;
  transition: left var(--dur-slow) var(--ease-soft);
}
.progress__meta {
  display: flex; justify-content: space-between;
  font-size: 12px; color: var(--ink-soft);
}

/* ------------------------------------------------------------ tabbar ---- */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--z-tabbar);
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: linear-gradient(180deg, var(--white) 0%, var(--card) 100%);
  box-shadow: 0 -6px 20px rgba(214, 164, 178, .16),
              inset 0 1px 0 rgba(255, 255, 255, .95);
  padding-bottom: env(safe-area-inset-bottom);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
}
.tabbar__item {
  height: var(--tabbar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; font-size: 11px; color: var(--ink-soft);
  transition: color var(--dur-fast) var(--ease-soft);
}
.tabbar__item[aria-current="page"] { color: var(--pink-deep); font-weight: 700; }

/* SOS sits above the tab bar and is never scrolled away -- a craving does not
 * wait for you to find the button. */
.sos-fab {
  position: fixed; right: var(--screen-pad);
  bottom: calc(var(--tabbar-h) + var(--sp-4) + env(safe-area-inset-bottom));
  z-index: var(--z-sos);
  display: flex; align-items: center; gap: var(--sp-2);
  height: var(--sos-size); padding: 0 var(--sp-5);
  background: var(--grad-primary); color: var(--on-pink);
  border-radius: var(--radius-btn);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-display); font-size: 16px; font-weight: 700;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.sos-fab:active { transform: scale(.94); }

/* ----------------------------------------------------------- journey ---- */
.journey { position: relative; padding: var(--sp-4) 0 var(--sp-10); }
.journey__path { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.journey__stops { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--sp-6); }

.stop { display: flex; align-items: center; gap: var(--sp-3); max-width: 78%; }
.stop--right { align-self: flex-end; flex-direction: row-reverse; text-align: right; }

.stop__bubble {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--grad-card); border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft), var(--shadow-edge);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.stop__bubble:active { transform: scale(.97); }
.stop__when { font-size: 12px; color: var(--ink-soft); }
.stop__title { font-family: var(--font-display); font-size: 15px; font-weight: 600; }

.stop--locked .stop__bubble { background: var(--locked-bg); box-shadow: none; }
.stop--locked .stop__title  { color: var(--ink-faint); }
.stop--locked .stop__when   { color: var(--ink-faint); }

.stop__icon {
  width: 42px; height: 42px; flex: none;
  border-radius: var(--radius-chip);
  display: grid; place-items: center;
  background: var(--pink-wash);
  box-shadow: var(--shadow-edge);
}
.stop--locked .stop__icon { background: var(--locked); opacity: .55; }

.you-are-here {
  align-self: center;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  background: var(--grad-primary); color: var(--on-pink);
  border-radius: var(--radius-chip);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-display); font-size: 12px; font-weight: 700;
  letter-spacing: .06em;
}

.journey__segment {
  font-family: var(--font-display); font-size: 13px; font-weight: 700;
  color: var(--ink-soft); text-align: center;
  margin-top: var(--sp-4);
}

/* --------------------------------------------------------------- log ---- */
.tabs { display: flex; gap: var(--sp-2); background: var(--card-sunk);
        padding: var(--sp-1); border-radius: var(--radius-chip);
        box-shadow: var(--shadow-well); }
.tabs__item {
  flex: 1; min-height: 40px; border-radius: var(--radius-chip);
  font-size: 14px; color: var(--ink-soft);
  transition: background-color var(--dur-fast) var(--ease-soft);
}
.tabs__item[aria-selected="true"] {
  background: var(--card); color: var(--ink); font-weight: 700;
  box-shadow: var(--shadow-lift);
}

.faces { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--sp-2); }
.face {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) 0;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.face:active { transform: scale(.92); }
.face__dot {
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  transition: transform var(--dur-base) var(--ease-spring),
              box-shadow var(--dur-base) var(--ease-soft);
}
.face__label { font-size: 10px; color: var(--ink-soft); text-align: center; line-height: 1.2; }
.face[aria-pressed="true"] .face__dot { transform: scale(1.16); box-shadow: var(--shadow-btn); }
.face[aria-pressed="true"] .face__label { color: var(--ink); font-weight: 700; }

.face--1 .face__dot { background: var(--scale-1); }
.face--2 .face__dot { background: var(--scale-2); }
.face--3 .face__dot { background: var(--scale-3); }
.face--4 .face__dot { background: var(--scale-4); }
.face--5 .face__dot { background: var(--scale-5); }

.severity { display: flex; align-items: center; gap: var(--sp-3); }

/* The range input is styled explicitly rather than left to accent-color.
 * accent-color only tints the filled portion and the thumb -- the unfilled
 * track keeps the platform default, which is near-black here and is the one
 * dark bar in an app that has no dark bars. At severity 0 the whole track is
 * unfilled, so the default was ALL the user saw. */
.severity input[type="range"] {
  flex: 1;
  -webkit-appearance: none; appearance: none;
  height: 24px; background: transparent; cursor: pointer;
}
.severity input[type="range"]::-webkit-slider-runnable-track {
  height: 8px; border-radius: var(--radius-chip);
  background: var(--card-sunk); box-shadow: var(--shadow-well);
}
.severity input[type="range"]::-moz-range-track {
  height: 8px; border-radius: var(--radius-chip);
  background: var(--card-sunk); box-shadow: var(--shadow-well);
}
.severity input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; margin-top: -6px;
  border-radius: 50%; border: 2px solid var(--card);
  background: var(--pink); box-shadow: var(--shadow-lift);
}
.severity input[type="range"]::-moz-range-thumb {
  width: 20px; height: 20px;
  border-radius: 50%; border: 2px solid var(--card);
  background: var(--pink); box-shadow: var(--shadow-lift);
}
.severity input[type="range"]::-moz-range-progress {
  height: 8px; border-radius: var(--radius-chip); background: var(--pink);
}
.severity input[type="range"]:focus-visible { outline: 2px solid var(--pink-deep); outline-offset: 4px; }

.symptom-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--card-sunk);
}
.symptom-row:last-child { border-bottom: 0; }

/* ------------------------------------------------------------ badges ---- */
.badge-hero { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); }
.badge-hero__art { position: relative; width: 190px; height: 150px; display: grid; place-items: center; }
.badge-hero__medal { width: 96px; height: 96px; }
.badge-hero__wreath { position: absolute; inset: 0; width: 100%; height: 100%; }

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

.badge {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-1);
  background: var(--grad-card); border-radius: var(--radius-tile);
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.badge:active { transform: scale(.94); }
.badge__art { width: 46px; height: 46px; }
.badge__name { font-size: 9.5px; text-align: center; line-height: 1.2; color: var(--ink-soft); }

/* One art asset per badge: the locked state is CSS, not a second image. */
.badge--locked { background: var(--locked-bg); box-shadow: none; }
.badge--locked .badge__art { filter: grayscale(1) opacity(.45); }
.badge--locked .badge__name { color: var(--ink-faint); }
.badge__lock { position: absolute; color: var(--locked); }
.badge__wrap { position: relative; display: grid; place-items: center; }

/* ------------------------------------------------------------- sheet ---- */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: var(--z-sheet);
  background: rgba(107, 90, 94, .32);
  display: flex; align-items: flex-end;
  animation: fade var(--dur-base) var(--ease-soft);
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.sheet {
  width: 100%; max-height: 86dvh; overflow-y: auto;
  background: var(--grad-card);
  border-radius: 32px 32px 0 0;
  box-shadow: var(--shadow-deep), inset 0 1px 0 rgba(255, 255, 255, .95);
  padding: var(--sp-5) var(--screen-pad)
           calc(var(--sp-6) + env(safe-area-inset-bottom));
  animation: rise var(--dur-base) var(--ease-soft);
}
@keyframes rise { from { transform: translateY(6%); } to { transform: translateY(0); } }

.sheet__grab {
  width: 42px; height: 5px; border-radius: 3px;
  background: var(--card-sunk); margin: 0 auto var(--sp-4);
}

/* ------------------------------------------------------------- toast ---- */
.toast {
  position: fixed; left: 50%; translate: -50% 0;
  bottom: calc(var(--tabbar-h) + var(--sos-size) + env(safe-area-inset-bottom));
  z-index: var(--z-takeover);
  max-width: calc(100vw - var(--sp-8));
  padding: var(--sp-3) var(--sp-5);
  background: var(--grad-card); border-radius: var(--radius-chip);
  box-shadow: var(--shadow-deep), var(--shadow-edge);
  font-size: 14px; text-align: center;
  animation: rise var(--dur-base) var(--ease-spring);
}

/* -------------------------------------------------------- onboarding ---- */
.wizard { flex: 1; display: flex; flex-direction: column; gap: var(--card-gap); }
.wizard__body { flex: 1; display: flex; flex-direction: column; gap: var(--card-gap); }

.dots { display: flex; gap: var(--sp-2); justify-content: center; }
.dots span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink-faint);
  transition: width var(--dur-base) var(--ease-spring),
              background-color var(--dur-base) var(--ease-soft);
}
.dots span.is-on { width: 20px; border-radius: 4px; background: var(--pink); }

.stepper { display: flex; align-items: center; justify-content: center; gap: var(--sp-5); }
.stepper__btn {
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--grad-card); box-shadow: var(--shadow-lift), var(--shadow-edge);
  display: grid; place-items: center; color: var(--pink-deep);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.stepper__btn:active { transform: scale(.9); }
.stepper__value {
  font-family: var(--font-display); font-size: 46px; font-weight: 700;
  min-width: 92px; text-align: center; font-variant-numeric: tabular-nums;
}

.option {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; padding: var(--sp-4);
  background: var(--grad-card); border-radius: var(--radius-card);
  border: 1.5px solid transparent;
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  text-align: left;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.option:active { transform: scale(.98); }
.option[aria-pressed="true"] { border-color: var(--pink); background: var(--pink-wash); }
.option__title { font-family: var(--font-display); font-size: 16px; font-weight: 600; }
.option__sub { font-size: 12px; color: var(--ink-soft); }

/* --------------------------------------------------------------- sos ---- */
.sos {
  position: fixed; inset: 0; z-index: var(--z-takeover);
  /* Lit like the rest: this screen covers .motif completely, so with the plain
   * page gradient it was the one flat surface in the app -- and it is the one
   * screen somebody opens at their worst moment. */
  background: var(--grad-page-lit);
  display: flex; flex-direction: column;
  padding:
    calc(var(--sp-5) + env(safe-area-inset-top))
    var(--screen-pad)
    calc(var(--sp-5) + env(safe-area-inset-bottom));
  gap: var(--card-gap);
  overflow-y: auto;
}
.sos__lead {
  font-family: var(--font-display); font-size: 20px; font-weight: 700;
  text-align: center; line-height: 1.35;
}

.breath { position: relative; display: grid; place-items: center; height: 220px; flex: none; }
.breath__circle {
  width: 150px; height: 150px; border-radius: 50%;
  background: var(--grad-primary); opacity: .22;
  animation: breathe 10s var(--ease-soft) infinite;
}
.breath__inner {
  position: absolute; display: grid; place-items: center; gap: var(--sp-1);
  text-align: center;
}
.breath__phase { font-family: var(--font-display); font-size: 19px; font-weight: 700; }
.breath__count { font-size: 13px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

/* 4s in, 6s out. */
@keyframes breathe {
  0%   { transform: scale(.72); }
  40%  { transform: scale(1.12); }
  100% { transform: scale(.72); }
}

/* With reduced motion the circle holds still; the phase label and countdown
 * keep updating, so the guide still works. */
@media (prefers-reduced-motion: reduce) {
  .breath__circle { transform: scale(1); opacity: .18; }
}

.ring { --p: 0; width: 74px; height: 74px; flex: none; }
.ring circle { fill: none; stroke-width: 7; stroke-linecap: round; }
.ring__track { stroke: var(--card-sunk); }
.ring__fill  { stroke: var(--pink); transition: stroke-dashoffset 1s linear; }

.reason {
  background: var(--pink-wash);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-edge);
  padding: var(--card-pad);
}
.reason__label {
  font-size: 12px; color: var(--pink-deep); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; margin-bottom: var(--sp-2);
}
.reason__text { font-family: var(--font-display); font-size: 17px; line-height: 1.45; }

/* ----------------------------------------------------------- relapse ---- */
.kept {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--card-gap);
}
.kept__item {
  background: var(--pink-wash); border-radius: var(--radius-tile);
  box-shadow: var(--shadow-edge);
  padding: var(--sp-4); text-align: center;
}
.kept__value {
  font-family: var(--font-display); font-size: 24px; font-weight: 700;
  color: var(--pink-deep);
}
.kept__label { font-size: 11px; color: var(--ink-soft); }

/* ------------------------------------------------------ knowledge base -- */
.kb-item {
  width: 100%; display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4);
  background: var(--grad-card); border-radius: var(--radius-card);
  box-shadow: var(--shadow-lift), var(--shadow-edge); text-align: left;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.kb-item:active { transform: scale(.98); }
.kb-item__title { flex: 1; font-family: var(--font-display); font-size: 15px; font-weight: 600; }

.prose h3 {
  font-size: 15px; margin: var(--sp-4) 0 var(--sp-2);
  color: var(--pink-deep);
}
.prose p { margin-bottom: var(--sp-3); }
.prose strong { font-weight: 700; }

.callout {
  background: var(--mint-wash); border-radius: var(--radius-card);
  box-shadow: var(--shadow-edge);
  padding: var(--card-pad); display: flex; flex-direction: column; gap: var(--sp-2);
}
.callout--urgent { background: var(--pink-wash); }
.callout__title { font-family: var(--font-display); font-size: 16px; font-weight: 700; }

.tel {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-3) var(--sp-4);
  background: var(--grad-card); border-radius: var(--radius-input);
  box-shadow: var(--shadow-lift), var(--shadow-edge);
}
.tel__number { font-family: var(--font-display); font-size: 18px; font-weight: 700; }
.tel__meta { font-size: 11px; color: var(--ink-soft); }

/* ------------------------------------------------------------ splash ---- */
.splash {
  min-height: 100dvh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--sp-5);
  padding: calc(var(--sp-6) + env(safe-area-inset-top)) var(--screen-pad)
           calc(var(--sp-6) + env(safe-area-inset-bottom));
  text-align: center;
}
.splash__mascot { width: 128px; height: 128px; }
.splash__wordmark { width: 210px; max-width: 60vw; }
.splash__tagline { font-family: var(--font-display); font-size: 17px; color: var(--ink-soft); }
.splash__actions { width: 100%; display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-4); }

/* ------------------------------------------------------------ states ---- */
.empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-3);
  padding: var(--sp-8) var(--sp-4); text-align: center; color: var(--ink-soft);
}
.offline-bar {
  position: fixed; top: env(safe-area-inset-top); left: 50%; translate: -50% 0;
  z-index: var(--z-takeover);
  padding: var(--sp-2) var(--sp-4); margin-top: var(--sp-2);
  background: var(--peach-wash); color: var(--ink);
  border-radius: var(--radius-chip); box-shadow: var(--shadow-lift);
  font-size: 12px;
}

.skeleton {
  background: var(--card-sunk); border-radius: var(--radius-tile);
  animation: pulse 1.4s var(--ease-soft) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* ============================================================== V2: sea === */
/* The Cesta tab. The only screen in the app that is not on cream -- it is the
 * open sea, so it gets its own ground and the page motif is hidden behind it.
 *
 * Motion here is decoration in the strict sense: with prefers-reduced-motion
 * every animation below stops (tokens.css), and the screen still says exactly
 * where the boat is, because that comes from the transform JS sets, never from
 * an animation. */

/* V3: the sea is water, not blue paper.
 *
 * The depth gradient REPEATS every --sea-band-h instead of being stretched
 * over the whole map. Stretched over four thousand pixels it resolves to one
 * unchanging blue -- which is exactly what the old screen looked like. Repeated,
 * the eye gets a horizon rhythm no matter how far down the map you are.
 *
 * The sun bloom is a single non-repeating layer pinned to the top, because
 * light comes from one place. */
.screen--sea {
  background-color: var(--sea);
  background-image: var(--sea-sun), var(--sea-band);
  background-size: 100% 620px, 100% var(--sea-band-h);
  background-repeat: no-repeat, repeat-y;
  padding-bottom: calc(var(--tabbar-h) + var(--sp-8) + env(safe-area-inset-bottom));
}
.screen--sea .screen-head h1,
.screen--sea .screen-head p { color: var(--ink); }

.sea-status {
  position: sticky; top: var(--sp-2); z-index: 3;
  background: color-mix(in srgb, var(--card) 88%, transparent);
  backdrop-filter: blur(6px);
  border-radius: var(--radius-tile);
  padding: var(--sp-3) var(--sp-4);
  box-shadow: var(--shadow-lift);
  margin-bottom: var(--sp-4);
}
.sea-status__line {
  display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-display); font-size: 15px; font-weight: 600;
}
.sea-status__line svg { flex: none; color: var(--pink-deep); }
.sea-status__meta { font-size: 12px; color: var(--ink-soft); margin-top: var(--sp-1); }

.sea-progress {
  height: 6px; border-radius: var(--radius-chip); background: var(--card-sunk);
  box-shadow: var(--shadow-well);
  overflow: hidden; margin-top: var(--sp-2);
}
.sea-progress__fill {
  height: 100%; border-radius: var(--radius-chip);
  background: var(--grad-progress);
  transition: width var(--dur-slow) var(--ease-soft);
}

.sea-map { position: relative; margin: 0 calc(var(--screen-pad) * -1); }

/* ---- water surface ----
 * Crests, troughs and foam glints, on their own layer so the whole thing can
 * drift by TRANSFORM. Animating background-position instead would repaint a
 * four-thousand-pixel element sixty times a second on a phone; a transform on
 * a composited layer costs nothing. Inset negatively so the drift never
 * exposes an unpainted edge. */
.sea-water {
  position: absolute; inset: -80px -60px;
  z-index: 0; pointer-events: none;
  background-image: var(--sea-glint), var(--sea-swell);
  background-size: 74px 62px, 100% 67px;
  animation: sea-drift 14s var(--ease-soft) infinite alternate;
  will-change: transform;
}
@keyframes sea-drift {
  from { transform: translate3d(-16px, 0, 0); }
  to   { transform: translate3d(16px, 6px, 0); }
}

/* ---- route ---- */
.sea-route { position: absolute; inset: 0; width: 100%; z-index: 1; pointer-events: none; }
/* The route ahead: a dashed line, clearly visible but plainly "not yet". */
.sea-route__line {
  fill: none; stroke: var(--sea-route); stroke-width: 4;
  stroke-linecap: round; stroke-dasharray: 2 11; opacity: .9;
}
/* The wake behind: solid, warm, and wider. The contrast between the two IS
 * the progress indicator on this screen, so they must not look alike. */
.sea-route__wake {
  fill: none; stroke: var(--wake); stroke-width: 6;
  stroke-linecap: round; opacity: 1;
  filter: drop-shadow(0 1px 2px rgba(120, 150, 175, .25));
  transition: stroke-dashoffset var(--dur-slow) linear;
}

/* ---- islands ---- */
.sea-islands { position: absolute; inset: 0; z-index: 2; }

/* The button is exactly the artwork, so translate(-50%,-50%) centres the
 * ISLAND on its route point. The text hangs off the side absolutely and does
 * not affect that centring. */
.sea-island {
  position: absolute; translate: -50% -50%;
  width: var(--island-size);
  display: grid; place-items: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  transition: transform var(--dur-base) var(--ease-spring);
}
.sea-island:active { transform: scale(.95); }

/* ---- the label ----
 * V3 rebuild. The old label was a 12px word on a 82%-opaque pill, which on
 * open water read as a caption that had come loose from its island: too small
 * to be a title, too transparent to be an object, and unattached to anything.
 *
 * It is now a card in its own right -- the same lit-rim treatment every raised
 * surface in the app wears, plus a short connector to the island so the pairing
 * is stated rather than implied. */
.sea-island__text {
  position: absolute; top: 50%; translate: 0 -50%;
  left: calc(100% + 14px);
  width: 132px; text-align: left;
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-1);
}
.sea-island--flip .sea-island__text {
  left: auto; right: calc(100% + 14px);
  text-align: right; align-items: flex-end;
}

/* The connector. Sits in the 14px gap, vertically centred on the label. */
.sea-island__text::before {
  content: ''; position: absolute; top: 50%; translate: 0 -50%;
  left: -14px; width: 14px; height: 2px;
  background: var(--sea-foam); opacity: .8;
  border-radius: var(--radius-chip);
}
.sea-island--flip .sea-island__text::before { left: auto; right: -14px; }

.sea-island__art {
  /* Not yet reached: hazy and pale, like something on the horizon. Not
   * greyscale -- a grey island in a colour sea reads as broken, and locking
   * the user out of looking ahead is not the point.
   *
   * V3 pulled the haze back from .62 to .78. At .62, against a sea that now
   * has visible texture running behind it, a distant island stopped reading as
   * distant and started reading as a half-loaded image -- which is exactly the
   * complaint that turned out to be a real bug in the ART for the boat. Once
   * one thing on the screen is transparent by mistake, everything transparent
   * on purpose becomes suspect, so the deliberate version has to be
   * unmistakably deliberate. */
  filter: saturate(.6) brightness(1.04) blur(.3px);
  opacity: .78;
  transition: filter var(--dur-slow) var(--ease-soft), opacity var(--dur-slow) var(--ease-soft);
}
.sea-island.is-reached .sea-island__art { filter: none; opacity: 1; }

/* Labels sit on open water, so they get their own surface rather than relying
 * on a text-shadow to survive whatever passes behind them. */
.sea-island__label {
  font-family: var(--font-display);
  font-size: 13px; font-weight: 700;
  color: var(--ink); line-height: 1.25;
  text-wrap: balance;                 /* "Hladina nikotínu začína klesať" */
  padding: 7px 11px;
  border-radius: 15px;
  background: var(--grad-card);
  box-shadow: var(--shadow-label);
  /* A left accent bar carries the state, so reached / not reached is legible
   * without relying on a colour difference in the text itself. */
  border-left: 3px solid var(--sea-deep);
}
.sea-island--flip .sea-island__label {
  border-left: 0; border-right: 3px solid var(--sea-deep);
}

.sea-island:not(.is-reached) .sea-island__label {
  color: var(--ink-soft);
  background: color-mix(in srgb, var(--card) 76%, transparent);
  box-shadow: 0 2px 8px rgba(84, 132, 166, .18);
  border-left-color: var(--ink-faint);
}
.sea-island--flip:not(.is-reached) .sea-island__label { border-right-color: var(--ink-faint); }

.sea-island.is-reached .sea-island__label { border-left-color: var(--mint); }
.sea-island--flip.is-reached .sea-island__label { border-right-color: var(--mint); }

/* The countdown is a chip, not a second line of label: it is a different kind
 * of fact and it changes every second. */
.sea-island__when {
  font-size: 10.5px; font-weight: 700; letter-spacing: .01em;
  color: var(--pink-deep);
  padding: 2px 9px; border-radius: var(--radius-chip);
  background: var(--pink-wash);
  box-shadow: var(--shadow-lift);
  white-space: nowrap;
}
.sea-island__when:empty { display: none; }

/* The island the cat is at right now: lifted, with a soft halo, and the one
 * label in the app that inverts -- it is the answer to "where am I". */
.sea-island.is-current { z-index: 3; }
.sea-island.is-current .sea-island__art {
  animation: island-bob 4.5s var(--ease-soft) infinite;
  filter: drop-shadow(0 6px 14px rgba(214, 164, 178, .45));
}
.sea-island.is-current .sea-island__label {
  font-size: 14px;
  background: var(--grad-primary);
  color: var(--on-pink);
  border-left-color: var(--white);
  box-shadow: var(--shadow-btn), inset 0 1px 0 rgba(255, 255, 255, .35);
}
.sea-island--flip.is-current .sea-island__label { border-right-color: var(--white); }
.sea-island.is-current .sea-island__text::before { background: var(--pink); opacity: 1; }

@keyframes island-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}

/* ---- the boat ---- */
.sea-boat-wrap {
  position: absolute; left: 0; top: 0; z-index: 4;
  width: 64px; height: 64px;
  display: grid; place-items: center;
  pointer-events: none;
  /* No transition on transform: JS sets an absolute position derived from the
   * clock, and easing between two truths would put the boat somewhere it is
   * not. The bob below supplies the movement instead. */
  animation: boat-bob 3.2s var(--ease-soft) infinite;
}
.sea-boat-wrap.is-docked { animation-duration: 5s; }
.sea-boat { width: 64px; height: auto; transition: transform var(--dur-slow) var(--ease-soft); }

@keyframes boat-bob {
  0%, 100% { margin-top: 0; }
  50%      { margin-top: -6px; }
}

/* ---- dressing ---- */
.sea-deco-layer { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.sea-deco { position: absolute; opacity: .75; }
.sea-deco--cloud { animation: deco-drift 26s linear infinite; opacity: .8; }
.sea-deco--bird  { animation: deco-drift 19s linear infinite; opacity: .7; }
.sea-deco--wave  { animation: deco-swell 5.5s var(--ease-soft) infinite; opacity: .55; }
.sea-deco--fish  { animation: deco-jump 7s var(--ease-soft) infinite; opacity: .8; }

@keyframes deco-drift {
  0%   { transform: translateX(-14px); }
  50%  { transform: translateX(14px); }
  100% { transform: translateX(-14px); }
}
@keyframes deco-swell {
  0%, 100% { transform: translateY(0) scaleX(1); }
  50%      { transform: translateY(-4px) scaleX(1.06); }
}
@keyframes deco-jump {
  0%, 70%, 100% { transform: translateY(0) rotate(0); }
  80%           { transform: translateY(-12px) rotate(-12deg); }
  90%           { transform: translateY(-4px) rotate(6deg); }
}

/* ======================================================= V2: records ===== */
.records { display: flex; flex-direction: column; }

.record {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  width: 100%; padding: var(--sp-3) 0; text-align: left;
  background: none; border: 0; border-bottom: 1px solid var(--card-sunk);
  cursor: pointer; font: inherit; color: inherit;
}
.record:last-child { border-bottom: 0; }
.record:active { opacity: .7; }

.record__face {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; color: var(--ink);
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
}
.record__face--1 { background: var(--scale-1); }
.record__face--2 { background: var(--scale-2); }
.record__face--3 { background: var(--scale-3); }
.record__face--4 { background: var(--scale-4); }
.record__face--5 { background: var(--scale-5); }

.record__body { flex: 1; min-width: 0; }
.record__when  { font-size: 11px; color: var(--ink-soft); }
.record__title { font-family: var(--font-display); font-size: 14px; font-weight: 600; }
.record__tags  { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.record__tag {
  font-size: 10px; padding: 2px var(--sp-2); border-radius: var(--radius-chip);
  background: var(--card-sunk); color: var(--ink-soft);
}
.record__note {
  font-size: 12px; color: var(--ink-soft); margin-top: 4px;
  overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
.record__side {
  flex: none; display: flex; align-items: center; gap: var(--sp-2);
  color: var(--ink-faint); align-self: center;
}
.record__flag {
  font-size: 10px; padding: 2px var(--sp-2); border-radius: var(--radius-chip);
  background: var(--peach-wash); color: var(--peach-ink); font-weight: 700;
}

/* The fail button. Distinct from the primary action and never beside it: this
 * is the one button on the screen with a consequence, and it sits alone. */
.btn--fail {
  background: var(--card); color: var(--peach-ink);
  border: 1.5px solid var(--peach); box-shadow: var(--shadow-lift);
}
.btn--fail:active { background: var(--peach-wash); }

/* ==================================================== V2: statistics ===== */
/* Marks follow one spec: thin bars, 4px rounded data-ends anchored to the
 * baseline, a 2px surface gap between neighbours, recessive axis text, and a
 * value printed only on the peak. Every chart here is a SINGLE series, so
 * every bar in it is the same colour -- identity comes from the label. */

.chart {
  display: flex; align-items: flex-end; gap: 2px;
  height: 108px; margin-top: var(--sp-2);
  padding-top: 18px;                 /* room for the peak's value label */
  border-bottom: 1px solid var(--chart-grid);
}
.chart__col {
  flex: 1; min-width: 0; height: 100%;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
  position: relative;
}
.chart__bar {
  width: 100%; border-radius: 4px 4px 0 0;
  background: var(--chart-bar); opacity: .55;
  transition: opacity var(--dur-base) var(--ease-soft);
}
.chart__bar.is-peak { opacity: 1; }
.chart__col:hover .chart__bar { opacity: .85; }

.chart__value {
  position: absolute; top: -18px; left: 50%; translate: -50% 0;
  font-family: var(--font-display); font-size: 11px; font-weight: 700;
  color: var(--ink); white-space: nowrap;
}
.chart__tick {
  font-size: 9px; color: var(--ink-faint); margin-top: 3px;
  white-space: nowrap; line-height: 1;
}

/* Ranked horizontal bars, where the label is a word. */
.hbars { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-2); }
.hbar { display: flex; align-items: center; gap: var(--sp-3); }
.hbar__label {
  flex: 0 0 34%; font-size: 12px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hbar__track {
  flex: 1; height: 12px; background: var(--card-sunk);
  box-shadow: var(--shadow-well); border-radius: var(--radius-chip);
}
.hbar__fill  { height: 100%; border-radius: var(--radius-chip); background: var(--chart-bar); }
.hbar__value {
  flex: none; font-size: 11px; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* The one categorical pair in the app. Both halves carry a word and a number,
 * so the colour is never the only thing telling them apart. */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-top: var(--sp-2); }
.split__part {
  padding: var(--sp-3); border-radius: var(--radius-tile); text-align: center;
  box-shadow: var(--shadow-edge);
  border-top: 3px solid transparent;
}
.split__part--good { background: var(--mint-wash);  border-top-color: var(--chart-good); }
.split__part--bad  { background: var(--peach-wash); border-top-color: var(--chart-bad); }
.split__value { font-family: var(--font-display); font-size: 24px; font-weight: 700; color: var(--ink); }
.split__label { font-size: 11px; color: var(--ink-soft); }

.stat-line {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: 13px; color: var(--ink); margin-bottom: var(--sp-2);
}
.stat-line svg { flex: none; color: var(--pink-deep); }

/* ============================================================ V3: hero === */
/* The first thing on the home screen. It used to be the word "Dobrý deň" and
 * nothing else -- a greeting is not a reason to keep going, and the reason to
 * keep going is what someone opening this at 2am is looking for.
 *
 * The sentence changes with elapsed time (see BANDS in home.js): what it says
 * in hour two and what it says on day two hundred are about different
 * situations, because the person reading them is in a different one. */
.hero {
  background: var(--grad-hero);
  box-shadow: var(--shadow-soft), var(--shadow-edge);
}
.hero__greet {
  font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--pink-deep);
  padding-top: var(--sp-2);
}
.hero__line {
  font-family: var(--font-display);
  font-size: 25px; font-weight: 700; line-height: 1.24;
  color: var(--ink);
  text-wrap: balance;
  margin-top: var(--sp-3);
}
/* Only on a change, never on first paint -- see paint() in home.js. */
@keyframes hero-in {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}
.hero__line.is-new { animation: hero-in var(--dur-slow) var(--ease-soft); }

/* ---------------------------------------------- home: island closeup ---- */
.home-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-3);
}
.home-head .screen-head,
.home-head .hero__greet { flex: 1; }

.closeup {
  display: block; width: 100%; text-align: left;
  border: 0; cursor: pointer; font: inherit; color: inherit;
}
.closeup:active { transform: scale(.99); }

.closeup__scene {
  position: relative; height: 180px; overflow: hidden;
  border-radius: var(--radius-tile);
  background: var(--grad-sea);
  box-shadow: var(--shadow-well);
  margin-bottom: var(--sp-3);
}

/* The same crest-and-glint layer the map uses, so the little scene and the
 * full map are recognisably the same ocean. Confined to the water half. */
.closeup__scene::after {
  content: ''; position: absolute; inset: 42% -30px 0 -30px;
  pointer-events: none;
  background-image: var(--sea-glint), var(--sea-swell);
  background-size: 58px 48px, 100% 50px;
  opacity: .9;
  animation: sea-drift 11s var(--ease-soft) infinite alternate;
}

.closeup__sky {
  position: absolute; inset: 0 0 55% 0;
  background:
    var(--sea-sun),
    linear-gradient(180deg, var(--peach-wash) 0%, var(--sea-far) 100%);
}

/* The island the cat is on, and the next one small on the horizon. */
.closeup__island { position: absolute; left: 10px; bottom: 4px; z-index: 2; }
.closeup__next {
  position: absolute; right: 12px; bottom: 62px; z-index: 1;
  opacity: .5; filter: saturate(.5) blur(.6px);
}

.closeup__cat {
  position: absolute; z-index: 3;
  left: 85px; bottom: 66px; translate: -50% 0;
  animation: boat-bob 3.4s var(--ease-soft) infinite;
}
/* Sailing: crosses the gap between the two islands. `--sail` is the real leg
 * progress, set by home.js from the same voyage maths the map uses, so this
 * little scene cannot claim different progress from the Cesta tab. */
.closeup__cat.is-sailing {
  bottom: 20px;
  left: calc(30% + var(--sail, 0) * 48%);
}

/* A row of foam bumps along the shoreline.
 *
 * The stops fade to rgba(255,255,255,0), NOT to `transparent`. The keyword
 * interpolates through rgba(0,0,0,0), which paints a grey halo around every
 * bump -- which is exactly what it did here: four dirty grey semicircles
 * instead of white foam. */
.closeup__waves {
  position: absolute; inset: auto 0 0 0; height: 20px; z-index: 4;
  background: radial-gradient(circle at 50% 100%,
    rgba(255, 255, 255, .9) 0 9px, rgba(255, 255, 255, 0) 10px);
  background-size: 32px 20px;
  background-repeat: repeat-x;
  background-position: bottom center;
  animation: deco-swell 4.5s var(--ease-soft) infinite;
}

.closeup__label {
  font-family: var(--font-display); font-size: 15px; font-weight: 600; color: var(--ink);
}
.closeup__meta { font-size: 12px; color: var(--ink-soft); margin-top: 2px; margin-bottom: var(--sp-2); }

/* ========================================================== V3: health === */
/* Twenty-one symptoms, each shown against its own clock.
 *
 * THE TRACK IS THE WHOLE IDEA. A plain progress bar answers "how far through",
 * which is not what anybody wants to know at hour seventy-one. The question is
 * "is this as bad as it gets", so the track is the symptom's ENTIRE lifetime
 * end to end, with the peak marked on it and the user's own position marked
 * against that peak. Whether the worst is ahead or behind is then readable
 * without reading a word -- which matters, because the people most in need of
 * this screen are the least able to concentrate on it. */

.health__lead { font-size: 13px; color: var(--ink-soft); line-height: 1.45; }
.health { display: flex; flex-direction: column; gap: var(--sp-5); margin-top: var(--sp-4); }
.health__group { display: flex; flex-direction: column; gap: var(--sp-2); }

.health__heading {
  display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-display); font-size: 14px; font-weight: 700;
}
.health__heading::before {
  content: ''; width: 9px; height: 9px; flex: none;
  border-radius: 50%; background: var(--ink-faint);
  box-shadow: var(--shadow-edge);
}
.health__group--now   .health__heading::before { background: var(--sym-peak); }
.health__group--ahead .health__heading::before { background: var(--sym-ahead); }
.health__group--past  .health__heading::before { background: var(--sym-done); }

.health__hint {
  font-size: 11.5px; color: var(--ink-faint); line-height: 1.4;
  margin-bottom: var(--sp-1);
}

/* ---- one symptom ---- */
.sym {
  display: block; width: 100%; text-align: left;
  padding: var(--sp-3) var(--sp-4);
  border: 0; font: inherit; color: inherit;
  border-radius: var(--radius-tile);
  background: var(--grad-card);
  box-shadow: var(--shadow-lift), var(--shadow-edge);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.sym:active { transform: scale(.985); }

.sym__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-2);
}
.sym__name { font-family: var(--font-display); font-size: 14.5px; font-weight: 600; }

.sym__phase {
  flex: none;
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; white-space: nowrap;
  padding: 3px 9px; border-radius: var(--radius-chip);
  background: var(--card-sunk); color: var(--ink-soft);
}

/* The rail holds the peak marker above the track, so the two never collide.
 * They collide on precisely the day the marker matters most. */
.sym__rail { position: relative; margin: var(--sp-4) 0 var(--sp-2); }

.sym__track {
  position: relative; height: 10px;
  border-radius: var(--radius-chip);
  /* The gradient is set inline per row -- it encodes where THAT symptom peaks,
   * which is the one thing about it CSS cannot know. */
  box-shadow: var(--shadow-well);
}

/* Everything still ahead of them, greyed over the curve. Not transparent:
 * the point is that the shape underneath is visible but plainly not yet. */
.sym__veil {
  position: absolute; top: 0; right: 0; bottom: 0;
  border-radius: 0 var(--radius-chip) var(--radius-chip) 0;
  background: var(--card-sunk);
  opacity: .88;
  transition: left var(--dur-slow) var(--ease-soft);
}

/* Where the worst of it is: a notch above the track, pointing at the spot.
 * Above rather than on, because at the peak the position knob sits exactly
 * here and would hide it. */
.sym__peak {
  position: absolute; bottom: 12px; translate: -50% 0;
  width: 0; height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--sym-peak);
}

/* Where they are. The only round thing on the row, so the eye finds it first. */
.sym__here {
  position: absolute; top: 50%; translate: -50% -50%;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--white);
  border: 3.5px solid var(--pink-deep);
  box-shadow: var(--shadow-lift);
  transition: left var(--dur-slow) var(--ease-soft);
}

.sym__meta { font-size: 11.5px; color: var(--ink-soft); line-height: 1.4; }

/* ---- per phase ----
 * The curve runs through the craving scale's own hues and stops before red,
 * for the reason that scale stops: a body doing exactly what the literature
 * says it will do on day three is not an error state. */

/* Not started: the whole curve is under the veil anyway, so the marker and the
 * notch are what carry the state. */
.sym--ahead .sym__peak { border-top-color: var(--sym-ahead); }
.sym--past  .sym__peak { opacity: .45; }

.sym--rising  .sym__phase { background: var(--peach-wash);    color: var(--peach-ink); }
.sym--peak    .sym__phase { background: var(--pink-wash);     color: var(--pink-deep); }
.sym--easing  .sym__phase { background: var(--mint-wash);     color: var(--mint-ink); }
.sym--ongoing .sym__phase { background: var(--lavender-wash); color: var(--lavender-ink); }
.sym--past    .sym__phase { background: var(--mint-wash);     color: var(--mint-ink); }
.sym--ahead   .sym__phase { background: var(--locked-bg);     color: var(--ink-faint); }

/* At its worst, a symptom gets a ring. It is the row that explains how the
 * person feels at the moment they are reading, so it stops being a list item. */
.sym--peak {
  box-shadow: var(--shadow-soft),
              inset 0 0 0 1.5px var(--pink),
              inset 0 1px 0 rgba(255, 255, 255, .92);
}

/* Not yet, and already done: recessed rather than raised. Same information,
 * plainly not the part that is about right now. */
.sym--ahead, .sym--past {
  background: var(--grad-sunk);
  box-shadow: var(--shadow-edge);
}
.sym--ahead .sym__name, .sym--past .sym__name { color: var(--ink-soft); }
.sym--ahead .sym__here { border-color: var(--ink-faint); }
.sym--past  .sym__here { border-color: var(--sym-done); }
/* Nothing left ahead, so nothing to veil -- and a zero-width veil still paints
 * its rounded right cap over the end of the curve. */
.sym--past .sym__veil, .sym--ongoing .sym__veil { display: none; }

/* ---- the detail sheet ---- */
.sym-sheet__head {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--sp-2); margin-bottom: var(--sp-4);
}
.sym__phase--lg { font-size: 10.5px; padding: 4px 12px; }

/* ---------------------------------------------------------- narrow ------ */
@media (max-width: 370px) {
  :root { --screen-pad: 16px; --card-pad: 16px; }
  .timer__value { font-size: 26px; }
  .stat__value  { font-size: 22px; }
  .badge-grid   { grid-template-columns: repeat(3, 1fr); }
  .hero__line   { font-size: 22px; }
  .sea-island__text { width: 112px; }
}
