/* Hierro y placa: a training logbook in chalk, iron and plate red.
   Red is the plate: bands, the main action and "done". It never carries meaning alone: errors
   and destructive actions always carry an icon or a word. Only white text sits on red (ink on
   red is 2.73:1). Iron marks a selection (segmented control, filter chips) and the dock.
   Depth comes from layered shadows; lines are kept for structure (rows, tables, fields). */

@font-face {
  font-family: "Barlow";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/barlow-400.woff2") format("woff2");
}

@font-face {
  font-family: "Barlow";
  font-weight: 600;
  font-display: swap;
  src: url("fonts/barlow-600.woff2") format("woff2");
}

@font-face {
  font-family: "Barlow Condensed";
  font-weight: 600;
  font-display: swap;
  src: url("fonts/barlow-condensed-600.woff2") format("woff2");
}

@font-face {
  font-family: "Barlow Condensed";
  font-weight: 700;
  font-display: swap;
  src: url("fonts/barlow-condensed-700.woff2") format("woff2");
}

:root {
  color-scheme: light dark;

  /* Surfaces */
  --bg: #eef0eb; /* chalk */
  --sheet: #ffffff; /* paper */
  --sunken: #e4e7e1; /* tracks, segmented control, tags */
  --field: #ffffff;

  /* Text and lines */
  --ink: #1f2226;
  --muted: #5e645c; /* 5.3:1 on chalk, 6.1:1 on paper, 4.9:1 on sunken */
  --rule: rgb(31 34 38 / 0.1);
  --line: #7a8077; /* control borders: 3.5:1 on chalk, 4:1 on paper */
  --blue: #2f5fd0; /* links and the focus ring */

  /* Plate red */
  --brand: #c8281c;
  --brand-deep: #a11e14;
  --on-brand: #ffffff; /* 5.56:1 on --brand */
  --on-brand-soft: #fbe9e6; /* 4.75:1 on --brand */
  --red-text: #c8281c; /* red as text: 4.85:1 on chalk, 5.56:1 on paper */
  --plate-past: #ecb4b0; /* 3.1:1 on --brand */
  --fill: linear-gradient(90deg, var(--brand-deep), var(--brand)); /* progress bars */

  /* Iron */
  --iron: #1d2024;
  --on-iron: #eef0eb;
  --iron-muted: #aeb4ac; /* 7.7:1 on --iron */
  --iron-track: #3d4248;
  --dock: rgb(29 32 36 / 0.94);
  --select-bg: var(--iron);
  --select-ink: var(--on-iron);
  --tile: var(--iron);

  /* Elevation (better-ui): a 1px ring, lift and ambient depth */
  --shadow-sheet:
    0 0 0 1px oklch(0 0 0 / 0.06),
    0 1px 2px -1px oklch(0 0 0 / 0.06),
    0 2px 4px 0 oklch(0 0 0 / 0.04);
  --shadow-lift:
    0 0 0 1px oklch(0 0 0 / 0.05),
    0 2px 4px -2px oklch(0 0 0 / 0.1),
    0 16px 32px -16px oklch(0 0 0 / 0.35);
  --shadow-brand:
    inset 0 1px 0 rgb(255 255 255 / 0.18),
    0 1px 2px rgb(110 16 10 / 0.35),
    0 8px 18px -10px rgb(200 40 28 / 0.7);
  --shadow-band: 0 18px 36px -28px rgb(161 30 20 / 0.55);

  /* Shape: controls 10, sheets 26 (10 + 16 of padding), bands 32, pills round */
  --radius-control: 10px;
  --radius-sheet: 26px;
  --radius-band: 32px;

  --ease: cubic-bezier(0.2, 0, 0, 1);
  --display: "Barlow Condensed", "Arial Narrow", sans-serif;
  --text: "Barlow", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Chalk dust: a faint speckle so the page reads as a surface, not a flat fill. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%231f2226' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111315; /* cast iron */
    --sheet: #1a1d21;
    --sunken: #25292e;
    --field: #1a1d21;
    --ink: #eceee9;
    --muted: #9da39c; /* 5.7:1 on sunken */
    --rule: rgb(236 238 233 / 0.1);
    --line: #7b828a; /* 4.3:1 on fields */
    --blue: #7fa0f2;
    --red-text: #e5604f; /* 4.9:1 on sheets */
    --fill: linear-gradient(90deg, var(--brand), #e5604f); /* the end of a bar stays 3:1 on dark tracks */
    --iron: #22262b;
    --iron-track: #3a3f46;
    --dock: rgb(34 38 43 / 0.94);
    --select-bg: #eceee9;
    --select-ink: #111315;
    --tile: #2c3137;
    --shadow-sheet: 0 0 0 1px oklch(1 0 0 / 0.08);
    --shadow-lift: 0 0 0 1px oklch(1 0 0 / 0.1), 0 16px 32px -16px oklch(0 0 0 / 0.8);
    --shadow-brand: inset 0 1px 0 rgb(255 255 255 / 0.16), 0 8px 20px -10px rgb(229 96 79 / 0.55);
    --shadow-band: 0 24px 48px -32px rgb(200 40 28 / 0.75);
    --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
    --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23eceee9' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  }
}

/* --- Base --------------------------------------------------------------------- */

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  /* The floating dock and the sticky save bar must never cover a focused field. */
  scroll-padding-bottom: 120px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The page is as tall as the large viewport (100lvh), not the small one (100svh). On the iPhone
   home-screen app 100svh is 59 px short of the screen; a document that short makes the browser
   place everything pinned to the bottom (the dock, the background) 59 px too high. */
body {
  margin: 0;
  min-height: 100lvh;
  background: var(--grain) var(--bg);
  background-color: var(--bg);
  color: var(--ink);
  font: 400 1.0625rem/1.5 var(--text);
  -webkit-text-size-adjust: 100%;
}

a,
button,
summary {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

main {
  max-width: 560px;
  margin: 0 auto;
  padding: calc(20px + env(safe-area-inset-top)) 20px calc(100px + env(safe-area-inset-bottom));
}

::selection {
  background: rgb(200 40 28 / 0.22);
}

/* --- Type --------------------------------------------------------------------- */

h1,
h2,
h3 {
  font-family: var(--display);
  text-wrap: balance;
}

h1 {
  margin: 0;
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
}

h2 {
  margin: 28px 0 10px;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
}

p {
  margin: 0 0 12px;
  text-wrap: pretty;
}

a {
  color: var(--blue);
  text-decoration-thickness: from-font;
  text-underline-offset: 0.15em;
}

[tabindex="-1"]:focus {
  outline: none;
}

.eyebrow {
  margin: 0;
  color: var(--muted);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
}

.num {
  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.num.big {
  font-size: 2.75rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.muted,
.hint {
  color: var(--muted);
}

.hint {
  font-size: 0.9375rem;
  line-height: 1.45;
}

/* Facts about one record, set apart by hairlines instead of a run of middle dots. Each fact
   draws its hairline on its left; the box is widened by 10 px and clipped, so the hairline
   of whichever fact starts a line falls outside and only the ones between facts show. */
.facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 4px;
  overflow: hidden;
  margin-inline: -10px;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.4;
}

p.facts {
  margin-block: 0 14px;
}

.facts > span {
  margin-left: -1px;
  padding-inline: 10px;
  border-left: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}

/* A state written as a word, with a small plate when it is the live one. */
.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink);
  font-weight: 600;
}

.status.live::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand);
}

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  margin-bottom: 4px;
  color: var(--muted);
  font-weight: 600;
  text-decoration: none;
}

.back svg {
  transform: rotate(180deg);
}

.row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

/* --- The band: top-level screens open with a red plate ------------------------- */

.band,
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin: calc(-1 * (20px + env(safe-area-inset-top))) -20px 22px;
  padding: calc(24px + env(safe-area-inset-top)) 20px 24px;
  border-radius: 0 0 var(--radius-band) var(--radius-band);
  background-color: var(--brand);
  background-image: linear-gradient(172deg, var(--brand) 30%, var(--brand-deep));
  box-shadow: var(--shadow-band);
  color: var(--on-brand);
}

/* Knurling, like the grip of a barbell: a fine diamond texture that fades out upward. */
.band::before,
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(45deg, rgb(0 0 0 / 0.08) 0 1px, transparent 1px 6px),
    repeating-linear-gradient(-45deg, rgb(0 0 0 / 0.08) 0 1px, transparent 1px 6px);
  -webkit-mask-image: linear-gradient(to top, #000, transparent 75%);
  mask-image: linear-gradient(to top, #000, transparent 75%);
}

.band h1,
.hero h1 {
  font-size: 3rem;
  letter-spacing: -0.02em;
}

.page-head.band {
  flex-wrap: wrap;
  row-gap: 10px;
}

.band .btn {
  background: var(--on-brand);
  box-shadow: 0 1px 2px rgb(60 8 4 / 0.3), 0 6px 14px -8px rgb(60 8 4 / 0.5);
  color: var(--brand);
}

.band .btn:not(:disabled):active {
  background-color: var(--on-brand-soft);
}

.band :focus-visible,
.hero :focus-visible {
  outline-color: var(--on-brand);
}

/* One line under a band's title: what the screen holds right now. */
.band-status {
  flex-basis: 100%;
  margin: 0;
  color: var(--on-brand-soft);
  font-size: 1.0625rem;
  line-height: 1.35;
}

.band-status strong {
  color: var(--on-brand);
  font-family: var(--display);
  font-size: 1.375rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* --- Inicio: the week at a glance ---------------------------------------------- */

.hero .eyebrow {
  color: var(--on-brand-soft);
}

.hero h1 {
  margin-bottom: 18px;
}

.hero-row {
  display: flex;
  align-items: flex-end;
  gap: 16px;
}

.hero-number {
  font: 700 7.5rem/0.82 var(--display);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
}

.hero-notes {
  display: flex;
  flex-direction: column;
  padding-bottom: 6px;
  line-height: 1.35;
}

.hero-notes span {
  color: var(--on-brand-soft);
}

.weekly {
  margin: 18px 0 0;
}

/* The week's plate trees: one post per week, one plate loaded on it per workout. Past weeks
   are pale plates (3.1:1 on red), this week's are white; an empty post reads as zero. */
.rack {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  min-height: 76px;
  padding-top: 4px;
  border-bottom: 2px solid rgb(255 255 255 / 0.45);
}

.stack {
  position: relative;
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-start;
  align-items: center;
  gap: 3px;
  width: 30px;
}

/* The post, behind the plates (the band is the stacking context). */
.stack::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  z-index: -1;
  width: 4px;
  margin-left: -2px;
  border-radius: 2px 2px 0 0;
  background: rgb(255 255 255 / 0.22);
}

.plate {
  width: 100%;
  height: 10px;
  border-radius: 3px;
  /* The post shows through the plate's hub. */
  background: linear-gradient(90deg, transparent 43%, rgb(0 0 0 / 0.16) 43% 57%, transparent 57%), var(--plate-past);
  box-shadow: inset 0 -2px 0 rgb(0 0 0 / 0.12);
}

.stack.current .plate {
  background: linear-gradient(90deg, transparent 43%, rgb(161 30 20 / 0.28) 43% 57%, transparent 57%), var(--on-brand);
}

.stack .more {
  color: var(--on-brand);
  font: 700 0.8125rem/1 var(--display);
  font-variant-numeric: tabular-nums;
}

.weekly figcaption {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  color: var(--on-brand-soft);
  font-size: 0.8125rem;
}

.weekly figcaption strong {
  color: var(--on-brand);
}

/* --- Sheets: paper surfaces that group a section ------------------------------- */

.panel,
.sheet {
  margin: 0 0 16px;
  border: 1px solid transparent; /* forced-colors mode drops the shadow and paints this */
  border-radius: var(--radius-sheet);
  background: var(--sheet);
  box-shadow: var(--shadow-sheet);
}

.panel {
  padding: 4px 16px 16px;
}

.panel > h2,
.panel-head > h2 {
  margin: 16px 0 8px;
  font-size: 1.25rem;
}

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.panel-count {
  color: var(--red-text);
  font: 700 1.125rem/1 var(--display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.panel-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 4px;
  font-weight: 600;
}

/* A list on a sheet: rows run edge to edge, split by hairlines inset like the text. */
.panel.list,
.sheet.list {
  padding: 0;
  overflow: hidden;
}

.panel.list > *,
.sheet.list > * {
  padding-inline: 16px;
}

.panel.list > * + *,
.sheet.list > * + * {
  background-image: linear-gradient(var(--rule), var(--rule));
  background-position: 16px 0;
  background-repeat: no-repeat;
  background-size: calc(100% - 16px) 1px;
}

.panel.list > a,
.sheet.list > a,
.sheet.list > article {
  transition-property: background-color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

.panel.list > a:active,
.sheet.list > a:active {
  background-color: var(--sunken);
}

.sheet.list > .empty {
  margin: 0;
  padding-block: 20px;
  border: 0;
  border-radius: 0;
  text-align: start;
}

.module-row {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  padding-block: 12px;
  color: var(--ink);
  text-decoration: none;
}

.tile {
  display: grid;
  flex: none;
  width: 44px;
  height: 44px;
  place-items: center;
  border-radius: 12px;
  background: var(--tile);
  color: var(--on-iron);
}

.module-name {
  display: flex;
  flex: 1;
  flex-direction: column;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.25;
}

.module-stat {
  color: var(--muted);
  font-size: 0.9375rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.chevron {
  display: grid;
  color: var(--muted);
}

/* A segmented control: the sections of one module. */
.sections {
  display: flex;
  gap: 4px;
  margin: 0 0 18px;
  padding: 4px;
  border-radius: 14px;
  background: var(--sunken);
}

.sections a {
  display: grid;
  flex: 1;
  min-height: 44px;
  place-items: center;
  border-radius: var(--radius-control);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  transition-property: background-color, color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

.sections a.active {
  background: var(--select-bg);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.2);
  color: var(--select-ink);
}

/* --- Buttons ------------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: var(--brand);
  box-shadow: var(--shadow-brand);
  color: var(--on-brand);
  font: 600 1.0625rem/1.2 var(--text);
  text-decoration: none;
  cursor: pointer;
  transition-property: scale, background-color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

.btn:not(:disabled):active {
  background-color: var(--brand-deep);
}

.btn:disabled {
  box-shadow: none;
  cursor: default;
  opacity: 0.5;
}

.btn.block {
  display: flex;
  width: 100%;
  margin: 12px 0;
}

.btn.small {
  min-height: 44px;
  padding: 0 16px;
  font-size: 1rem;
}

/* Destructive buttons use this too: they say "Eliminar" and ask first, color is not the signal. */
.btn.ghost {
  border: 1.5px solid var(--ink);
  background: transparent;
  box-shadow: none;
  color: var(--ink);
}

.btn.ghost:not(:disabled):active {
  background-color: var(--sunken);
}

.btn.text {
  min-height: 44px;
  padding-left: 0;
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--muted);
}

.icon-btn {
  display: grid;
  flex: none;
  width: 44px;
  height: 44px;
  place-items: center;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition-property: background-color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

.icon-btn:active {
  background-color: var(--sunken);
}

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

/* --- Forms -------------------------------------------------------------------- */

label {
  display: block;
  margin-bottom: 16px;
  color: var(--muted);
  font-size: 0.9375rem;
  font-weight: 600;
}

input,
select,
textarea {
  display: block;
  width: 100%;
  min-height: 52px;
  margin-top: 6px;
  padding: 12px 14px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-control);
  background: var(--field);
  color: var(--ink);
  font: 400 1.0625rem/1.4 var(--text);
  transition-property: border-color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--ink);
}

select {
  padding-right: 42px;
  background-image: var(--select-arrow);
  background-position: right 14px center;
  background-repeat: no-repeat;
  -webkit-appearance: none;
  appearance: none;
}

input::placeholder,
textarea::placeholder {
  color: var(--muted);
  opacity: 1;
}

/* A rejected field gets a heavier border; the error box above names it in words. */
[aria-invalid="true"] {
  border: 3px solid var(--ink);
}

textarea {
  min-height: 88px;
  resize: vertical;
}

.fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
}

.fields.two {
  gap: 12px;
}

.check {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  color: var(--ink);
  font-size: 1.0625rem;
  font-weight: 400;
}

.check input {
  flex: none;
  width: 24px;
  height: 24px;
  min-height: 0;
  margin: 0;
  accent-color: var(--brand);
}

.login {
  padding-top: 12vh;
}

.login h1 {
  margin-bottom: 24px;
  font-size: 3rem;
}

/* --- Rows and lists ----------------------------------------------------------- */

/* The logbook: tabular rows under a heavy rule (sets, history). */
.ledger {
  margin: 0 0 20px;
  padding: 0;
  border-top: 2px solid var(--ink);
  list-style: none;
}

.ledger > li {
  padding-block: 12px;
  border-bottom: 1px solid var(--rule);
}

.ledger > li.row {
  align-items: center;
}

.ledger > li.row .num {
  margin-left: auto;
}

.block-link {
  display: block;
  margin-bottom: 8px;
  color: inherit;
  text-decoration: none;
}

.block-link > .row {
  margin-bottom: 8px;
}

.block-link .ledger {
  margin-bottom: 0;
}

.entry {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 16px;
  padding-block: 14px;
  color: inherit;
  text-decoration: none;
}

.panel .entry {
  border-top: 1px solid var(--rule);
}

.entry-date {
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
}

.entry-date svg {
  margin-right: 6px;
  vertical-align: -2px;
}

.entry-type {
  justify-self: end;
  align-self: center;
  color: var(--muted);
  font-size: 0.9375rem;
  text-align: end;
}

.entry-type.num {
  color: var(--ink);
  font-size: 1.125rem;
}

.entry-type.num.big {
  font-size: 1.75rem;
}

.entry-body,
.entry-meta {
  grid-column: 1 / -1;
}

/* A bar inside a row needs a block; a clamped summary keeps its own box (see .clamp). */
.entry > .entry-body:not(.clamp) {
  display: block;
}

.entry-meta {
  color: var(--muted);
  font-size: 0.9375rem;
}

.note-entry .entry {
  padding-bottom: 8px;
}

.note-entry .chips {
  margin-bottom: 14px;
}

.clamp {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow-wrap: anywhere; /* a long word or link wraps instead of being cut at the side */
  color: var(--muted);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 20px 0 8px;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 20px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 18px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: 600 1rem/1.2 var(--text);
  text-decoration: none;
  transition-property: background-color, border-color, color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

button.chip {
  cursor: pointer;
}

.chip[aria-pressed="true"] {
  border-color: var(--select-bg);
  background: var(--select-bg);
  color: var(--select-ink);
}

.chip.tag {
  min-height: 32px;
  padding: 0 12px;
  border-color: transparent;
  background: var(--sunken);
  color: var(--muted);
  font-size: 0.9375rem;
  font-weight: 400;
}

/* A tag that can be tapped (it filters) gets the same 44 px target as every control. */
button.chip.tag,
a.chip.tag {
  min-height: 44px;
}

/* Plain multi-line text written by the user (a description). */
.prose {
  margin: 0 0 20px;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

blockquote {
  margin: 0 0 12px;
  padding: 4px 0 4px 16px;
  border-left: 3px solid var(--brand);
  white-space: pre-wrap;
}

.empty {
  margin: 0 0 16px;
  padding: 24px 20px;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-sheet);
  color: var(--muted);
  text-align: center;
  text-wrap: balance;
}

.panel .empty {
  margin: 0;
  padding: 12px 0 4px;
  border: 0;
  text-align: start;
}

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

/* Folded content: completed, archived or converted records. */
.panel.archived {
  padding-block: 4px;
}

.panel.archived[open] {
  padding-bottom: 12px;
}

.archived summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 52px;
  padding: 12px 0;
  font-weight: 600;
  list-style: none;
  cursor: pointer;
}

.archived summary::-webkit-details-marker {
  display: none;
}

.archived summary::after {
  content: "";
  width: 9px;
  height: 9px;
  margin-right: 6px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg);
}

.archived[open] summary::after {
  transform: rotate(-135deg);
}

/* --- Habits ------------------------------------------------------------------- */

.habit-row {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  column-gap: 8px;
  align-items: center;
  padding-block: 10px;
  border-top: 1px solid var(--rule);
}

.habit-row:first-child {
  border-top: 0;
}

.habit-check {
  display: grid;
  width: 44px;
  height: 44px;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--on-brand);
  cursor: pointer;
}

.habit-check .box {
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border: 2px solid var(--line);
  border-radius: 9px;
  background: var(--field);
  transition-property: scale, background-color, border-color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

.habit-check[aria-checked="true"] .box {
  border-color: var(--brand);
  background: var(--brand);
  box-shadow: 0 4px 10px -4px rgb(200 40 28 / 0.65);
}

.habit-check svg {
  stroke-width: 2.6;
}

.habit-main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 44px;
  color: inherit;
  text-decoration: none;
}

.habit-name {
  font-size: 1.0625rem;
  font-weight: 600;
}

.habit-sub {
  color: var(--muted);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.habit-streak {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.habit-streak svg {
  color: var(--red-text);
}

.habit-streak.muted {
  font-weight: 400;
}

.habit-extra {
  display: flex;
  flex-wrap: wrap;
  grid-column: 2 / -1;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding-bottom: 4px;
}

.habit-error {
  grid-column: 1 / -1;
}

.dots {
  display: inline-flex;
  gap: 6px;
}

.dot {
  width: 10px;
  height: 10px;
  border: 1.5px solid var(--line);
  border-radius: 50%;
}

.dot.met {
  border-color: var(--brand);
  background: var(--brand);
}

.habit-value {
  display: flex;
  align-items: center;
  gap: 8px;
}

.habit-value input {
  width: 96px;
  min-height: 44px;
  margin: 0;
}

.habit-value .btn {
  min-height: 44px;
}

.stats {
  display: flex;
  gap: 32px;
  margin: 16px 0;
}

.stats > div {
  display: flex;
  flex-direction: column;
}

.backfill {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 12px;
}

.backfill label {
  flex: 1 1 140px;
}

.backfill .btn {
  margin-bottom: 16px;
}

/* --- Notes -------------------------------------------------------------------- */

.markdown {
  margin-bottom: 8px;
  overflow-wrap: anywhere;
}

.markdown > :first-child {
  margin-top: 0;
}

.markdown h2,
.markdown h3,
.markdown h4 {
  margin: 20px 0 8px;
}

.markdown h3 {
  font-size: 1.2rem;
}

.markdown h4 {
  font-size: 1.05rem;
}

.markdown ul,
.markdown ol {
  margin: 0 0 12px;
  padding-left: 22px;
}

.markdown code {
  padding: 1px 5px;
  border-radius: 6px;
  background: var(--sunken);
  font: 0.95em ui-monospace, "Cascadia Code", Consolas, monospace;
}

.markdown pre {
  margin: 0 0 12px;
  padding: 12px 14px;
  overflow-x: auto;
  border-radius: 14px;
  background: var(--sunken);
}

.markdown pre code {
  padding: 0;
  background: none;
}

/* --- Workouts ----------------------------------------------------------------- */

.sets-table {
  width: 100%;
  margin-bottom: 8px;
  border-collapse: collapse;
}

.sets-table th,
.sets-table td {
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
  text-align: left;
}

.sets-table thead th {
  border-bottom: 2px solid var(--ink);
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
}

.progress-table {
  margin-top: 20px;
}

/* The date is the link to that workout: the whole cell is the touch target. */
.progress-table td a {
  display: flex;
  align-items: center;
  min-height: 44px;
}

fieldset.exercise {
  min-width: 0;
  margin: 0 0 20px;
  padding: 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-sheet);
  background: var(--sheet);
  box-shadow: var(--shadow-sheet);
}

.exercise-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.exercise-head input {
  margin-top: 0;
  font: 700 1.4rem var(--display);
}

.exercise .hint {
  min-height: 1.4em;
  margin: 6px 0 4px;
}

.set,
.set-head,
.other {
  display: grid;
  grid-template-columns: 1.6rem 1fr 1fr 1fr 44px;
  align-items: center;
  gap: 8px;
}

.other {
  grid-template-columns: 2fr 1fr 44px;
  margin-bottom: 8px;
}

.set {
  margin-bottom: 8px;
}

.set input,
.other input {
  margin-top: 0;
  font: 600 1.25rem var(--display);
  font-variant-numeric: tabular-nums;
}

.other input:first-child {
  font: 400 1.0625rem var(--text);
}

.set-head {
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
}

.set-index {
  color: var(--muted);
}

.exercise > .btn {
  margin-top: 4px;
}

.savebar {
  position: sticky;
  bottom: 0;
  margin: 16px -20px 0;
  padding: 10px 20px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--rule);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.savebar .btn {
  margin: 0;
}

/* A form has no dock, so its save bar closes the page instead of leaving the dock's room under it. */
main:has(.savebar) {
  padding-bottom: 0;
}

.measurement p {
  margin: 4px 0 0;
}

/* --- Feedback: never color alone ---------------------------------------------- */

.error,
.notice {
  display: flex;
  gap: 12px;
  margin: 12px 0 20px;
  padding: 14px 16px;
  border: 2px solid var(--ink);
  border-radius: 14px;
  background: var(--sheet);
}

.error {
  margin-bottom: 12px;
}

.error svg,
.notice svg {
  flex: none;
  margin-top: 2px;
}

.error p,
.notice p {
  margin: 0;
}

.error ul {
  margin: 8px 0 0;
  padding-left: 20px;
}

.error-screen .actions {
  margin-top: 20px;
}

/* --- Charts (app/web/chart.js) ------------------------------------------------ */

.chart {
  margin: 0 0 16px;
  padding: 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-sheet);
  background: var(--sheet);
  box-shadow: var(--shadow-sheet);
}

.chart.empty {
  border: 1.5px dashed var(--line);
  background: transparent;
  box-shadow: none;
  color: var(--muted);
}

.chart svg {
  display: block;
  width: 100%;
  height: auto;
}

.chart text {
  fill: var(--muted);
  font: 400 11px var(--text);
}

.chart .grid {
  stroke: var(--rule);
}

.chart .line {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chart .line.primary {
  stroke: var(--red-text);
}

.chart .line.secondary {
  stroke: var(--ink);
  stroke-dasharray: 6 4;
}

.chart .dot.primary {
  fill: var(--red-text);
}

.chart .dot.secondary {
  fill: var(--ink);
}

.chart figcaption {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin-top: 10px;
  color: var(--muted);
  font-size: 0.9375rem;
}

.legend::before {
  content: "";
  display: inline-block;
  width: 18px;
  margin-right: 8px;
  border-top: 3px solid var(--red-text);
  vertical-align: middle;
}

.legend.secondary::before {
  border-top: 3px dashed var(--ink);
}

/* --- Progress: goals, learning, expenses -------------------------------------- */

.meter {
  height: 8px;
  overflow: hidden;
  border-radius: 4px;
  background: var(--sunken);
}

.meter > span {
  display: block;
  height: 100%;
  border-radius: 4px;
  background: var(--fill);
  transform-origin: left;
  animation: fill 600ms var(--ease) both;
}

.entry .meter {
  margin: 8px 0 4px;
}

.goal-summary {
  margin-bottom: 20px;
}

.goal-summary .row {
  margin-bottom: 10px;
}

/* A big number with its caption: on a narrow phone the caption drops below as a whole line. */
.panel > .row,
.goal-summary .row {
  flex-wrap: wrap;
  row-gap: 2px;
}

.shares {
  margin: 12px 0 4px;
  padding: 0;
  list-style: none;
}

.shares > li {
  padding-block: 8px;
}

.shares .row {
  margin-bottom: 6px;
}

/* The iron panel on Inicio: the goals, cast in the second material. */
.panel.iron {
  background: var(--iron);
  box-shadow: var(--shadow-lift);
  color: var(--on-iron);
}

.panel.iron > h2 {
  color: var(--on-iron);
}

.panel.iron :focus-visible {
  outline-color: var(--on-iron);
}

.iron-goal {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px 12px;
  padding-block: 14px;
  border-bottom: 1px solid var(--iron-track);
  color: inherit;
  text-decoration: none;
}

.iron-title {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.iron-percent {
  font: 700 1.375rem/1.1 var(--display);
  font-variant-numeric: tabular-nums;
}

.iron-goal .meter {
  grid-column: 1 / -1;
  background: var(--iron-track);
}

.iron-goal .meter > span {
  background: var(--on-iron);
}

.iron-sub {
  grid-column: 1 / -1;
  color: var(--iron-muted);
  font-size: 0.9375rem;
}

.panel.iron .panel-link {
  color: var(--on-iron);
}

/* --- Meals and expenses: one day or one month at a time ------------------------ */

.day-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.day-nav .step {
  display: grid;
  flex: none;
  width: 44px;
  height: 44px;
  place-items: center;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--ink);
  transition-property: scale, background-color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

.day-nav .step:disabled {
  opacity: 0.4;
}

.day-nav .flip svg {
  transform: rotate(180deg);
}

.day-label {
  flex: 1;
  margin: 0;
  font: 600 1.25rem/1.2 var(--display);
  text-align: center;
}

/* --- The dock: a floating iron bar ------------------------------------------- */

#tabs {
  position: fixed;
  z-index: 10;
  inset: auto 12px calc(10px + env(safe-area-inset-bottom));
  display: flex;
  gap: 2px;
  max-width: 536px;
  margin-inline: auto;
  padding: 6px;
  border: 1px solid transparent;
  border-radius: 28px;
  background: var(--dock);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: var(--shadow-lift);
}

#tabs a {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 52px;
  border-radius: 22px; /* 28 - 6 of padding */
  color: var(--iron-muted);
  font-size: 0.75rem;
  line-height: 1.2;
  text-decoration: none;
  transition-property: background-color, color;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}

#tabs .pill {
  display: grid;
  place-items: center;
}

#tabs a.active {
  background: var(--brand);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.18), 0 6px 14px -8px rgb(200 40 28 / 0.9);
  color: var(--on-brand);
  font-weight: 600;
}

#tabs :focus-visible {
  outline-color: var(--on-iron);
}

/* --- Motion ------------------------------------------------------------------- */

@keyframes grow {
  from {
    transform: scaleY(0);
  }
}

@keyframes fill {
  from {
    transform: scaleX(0);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

/* Press feedback: 0.96 over 150 ms, never on a disabled control. */
@media (prefers-reduced-motion: no-preference) {
  .btn:not(:disabled):active,
  .module-row:active,
  .day-nav .step:not(:disabled):active,
  .habit-check:active .box {
    scale: 0.96;
  }
}

/* Inicio's first load, once per visit: the heading groups rise 100 ms apart, then the week's
   plates drop onto their stacks, left to right. Every other screen only moves on an action. */
@media (prefers-reduced-motion: no-preference) {
  .hero.enter > * {
    animation: rise 300ms ease-out both;
  }

  .hero.enter > :nth-child(2) {
    animation-delay: 100ms;
  }

  .hero.enter > :nth-child(3) {
    animation-delay: 200ms;
  }

  .hero.enter > :nth-child(4) {
    animation-delay: 300ms;
  }

  .hero.enter .plate {
    animation: drop 300ms var(--ease) both;
    animation-delay: calc(400ms + min(var(--i, 0), 24) * 35ms);
  }

  /* A habit ticked by hand: the check grows in (better-ui icon cross-fade values). */
  .habit-check.just-done svg {
    animation: tick 300ms var(--ease) both;
  }
}

/* Reduced motion keeps an opacity fade instead of movement. */
@media (prefers-reduced-motion: reduce) {
  .meter > span,
  .hero.enter > *,
  .hero.enter .plate,
  .habit-check.just-done svg {
    animation: fade-in 300ms ease-out both;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
    filter: blur(4px);
  }
}

@keyframes drop {
  from {
    opacity: 0;
    transform: translateY(-16px);
  }
}

@keyframes tick {
  from {
    opacity: 0;
    scale: 0.25;
    filter: blur(4px);
  }
}

@media (hover: hover) {
  .panel.list > a:hover,
  .sheet.list > a:hover {
    background-color: var(--sunken);
  }

  .btn.ghost:hover {
    background-color: var(--sunken);
  }
}

/* --- Pieces that live inside lists ------------------------------------------- */

ul.sheet {
  list-style: none;
}

.measurement {
  padding-block: 12px;
}

.facts.num {
  color: var(--ink);
  font-size: 1.0625rem;
}

.panel.archived .module-row {
  border-top: 1px solid var(--rule);
}

/* --- Signature pieces ---------------------------------------------------------- */

/* The trend of the body weight on Inicio: one red line with a ringed end point. */
.sparkline {
  display: block;
  width: 100%;
  height: auto;
  margin: 12px 0 6px;
  overflow: visible;
}

.spark-area {
  fill: var(--brand);
  opacity: 0.08;
}

.spark-line {
  fill: none;
  stroke: var(--red-text);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.spark-dot {
  fill: var(--red-text);
  stroke: var(--sheet);
  stroke-width: 2;
}

/* Hábitos band: one standing plate per habit, white when it is done today. */
.habit-plates {
  display: inline-flex;
  align-items: flex-end;
  gap: 4px;
  margin-right: 12px;
  vertical-align: -4px;
}

.habit-plates .plate {
  width: 7px;
  height: 24px;
  border-radius: 3px;
  background: rgb(255 255 255 / 0.3);
  box-shadow: none;
}

.habit-plates .plate.done {
  background: var(--on-brand);
}

/* The day or month navigator lives in the band of Comidas and Gastos. */
.band .day-nav {
  flex-basis: 100%;
  margin: 2px 0 0;
}

.band .day-nav .step {
  border-color: rgb(255 255 255 / 0.55);
  color: var(--on-brand);
}

.band .day-nav .step:not(:disabled):active {
  background-color: rgb(0 0 0 / 0.12);
}

.day-label strong {
  display: block;
  font: 700 1.5rem/1.1 var(--display);
  letter-spacing: -0.01em;
}

.day-label span {
  display: block;
  font: 400 0.9375rem/1.4 var(--text);
}

.band .day-label span {
  color: var(--on-brand-soft);
}

/* The way in: the whole screen is the red plate. */
.login {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 100lvh;
  margin: calc(-1 * (20px + env(safe-area-inset-top))) -20px calc(-1 * (100px + env(safe-area-inset-bottom)));
  padding: calc(18vh + env(safe-area-inset-top)) 20px 40px;
  background-color: var(--brand);
  background-image: linear-gradient(172deg, var(--brand) 30%, var(--brand-deep));
  color: var(--on-brand);
}

.login::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(45deg, rgb(0 0 0 / 0.08) 0 1px, transparent 1px 6px),
    repeating-linear-gradient(-45deg, rgb(0 0 0 / 0.08) 0 1px, transparent 1px 6px);
  -webkit-mask-image: linear-gradient(to top, #000, transparent 60%);
  mask-image: linear-gradient(to top, #000, transparent 60%);
}

.login h1 {
  font-size: 3.5rem;
  letter-spacing: -0.02em;
}

.login label,
.login .hint {
  color: var(--on-brand-soft);
}

.login input {
  border-color: transparent;
}

.login .btn {
  background: var(--on-brand);
  box-shadow: 0 1px 2px rgb(60 8 4 / 0.3), 0 8px 18px -10px rgb(60 8 4 / 0.6);
  color: var(--brand);
}

.login :focus-visible {
  outline-color: var(--on-brand);
}

.login .error {
  color: var(--ink);
}

/* --- The mix: glass header, frosted sheets, a warm page ------------------------- */
/* Appended last on purpose: it restyles the base above through its own tokens and rules, so a
   screen only has to use .band, .panel and .sheet to get the new look. */

:root {
  --wash: linear-gradient(180deg, #f7e3dc 0%, #f1e9e4 38%, #eef0eb 70%, #f3ddd6 100%);
  --wash-end: #f3ddd6;
  --sheet-glass: rgb(255 255 255 / 0.78);
  --band-glow: rgb(205 40 26 / 0.5);
  --band-flare: rgb(227 39 27 / 0.55);
}

@media (prefers-color-scheme: dark) {
  :root {
    --wash: linear-gradient(180deg, #2a0f0d 0%, #17120f 38%, #111315 70%, #28100d 100%);
    --wash-end: #28100d;
    --sheet-glass: rgb(26 29 33 / 0.8);
  }
}

body {
  background: var(--grain);
  background-color: var(--wash-end, var(--bg));
}

/* The wash is a fixed layer of its own. `background-attachment: fixed` is not honoured by iOS: it
   painted the wash only over the body box and left a flat strip under the dock. */
html::before {
  content: "";
  position: fixed;
  inset: 0 0 auto;
  z-index: -2;
  height: calc(100lvh + env(safe-area-inset-bottom));
  pointer-events: none;
  background: var(--wash);
}

/* Home-screen app: the page runs under the status bar (black-translucent, white clock and
   battery). A band already carries its own material under the notch, so there is nothing to add
   at the top of those screens. Where white text would land on chalk (a screen without a band, or
   content scrolled up under the clock) a strip of the same material (near-black with the red
   glow) fades in and out below. It is 0 high where there is no notch. */
html::after {
  content: "";
  position: fixed;
  inset: 0 0 auto;
  z-index: 30;
  height: env(safe-area-inset-top);
  pointer-events: none;
  background:
    radial-gradient(70% 140% at 100% 0%, var(--band-flare), transparent 70%),
    #190706;
  -webkit-mask-image: linear-gradient(#000 70%, transparent);
  mask-image: linear-gradient(#000 70%, transparent);
  opacity: 0;
  transition: opacity 200ms var(--ease);
}

html.under-bar::after,
html:not(:has(.band, .hero))::after {
  opacity: 1;
}


/* Slow red lights behind the page. Fixed, so they stay while the content scrolls. */
body::before {
  content: "";
  position: fixed;
  inset: -10% -10% calc(-10% - env(safe-area-inset-bottom));
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(42% 30% at 100% 38%, rgb(255 122 92 / 0.5), transparent 70%),
    radial-gradient(40% 28% at 0% 72%, rgb(227 39 27 / 0.26), transparent 70%),
    radial-gradient(40% 26% at 100% 100%, rgb(255 176 138 / 0.5), transparent 70%);
}

@media (prefers-color-scheme: dark) {
  body::before {
    background:
      radial-gradient(42% 30% at 100% 38%, rgb(200 40 28 / 0.5), transparent 70%),
      radial-gradient(40% 28% at 0% 72%, rgb(142 18 11 / 0.6), transparent 70%),
      radial-gradient(40% 26% at 100% 100%, rgb(227 39 27 / 0.35), transparent 70%);
  }
}

@media (prefers-reduced-motion: no-preference) {
  body::before {
    animation: lights 24s ease-in-out infinite alternate;
  }

  @keyframes lights {
    to {
      transform: translate(-3%, 2%) scale(1.06);
    }
  }
}

/* Sheets are frosted: the page's color shows through, the text sits on an almost solid layer. */
.panel,
.sheet {
  background: var(--sheet-glass);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
}

/* The header is near-black with a red glow behind its content, like the rings of Inicio. */
.band,
.hero {
  background-color: #190706;
  background-image:
    radial-gradient(85% 70% at 16% 45%, var(--band-glow), transparent 72%),
    radial-gradient(70% 90% at 100% 0%, var(--band-flare), transparent 70%),
    linear-gradient(170deg, rgb(38 9 7 / 0), #1e0807);
}

@media (prefers-reduced-motion: no-preference) {
  .band::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: -50%;
    right: 0;
    width: 70%;
    aspect-ratio: 1;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(closest-side, rgb(242 69 46 / 0.55), transparent);
    animation: flare 18s ease-in-out infinite alternate;
  }

  @keyframes flare {
    to {
      transform: translate(-30%, 40%) scale(1.2);
    }
  }
}

/* A short notice above the bottom bar: what just happened, with an undo when there is one. */
#toast {
  position: fixed;
  z-index: 20;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 28px);
  min-height: 44px;
  padding: 6px 18px 6px 18px;
  border-radius: 999px;
  background: var(--iron);
  box-shadow: var(--shadow-lift);
  color: var(--on-iron);
  font-weight: 600;
  opacity: 0;
  visibility: hidden;
  translate: -50% 16px;
  transition:
    opacity 200ms var(--ease),
    translate 280ms var(--ease),
    visibility 0s linear 280ms;
}

#toast.show {
  opacity: 1;
  visibility: visible;
  translate: -50% 0;
  transition-delay: 0s;
}

#toast span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#toast button {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  margin-right: -12px;
  padding: 8px 14px;
  border: 0;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.12);
  color: #ffa59a;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: scale 150ms var(--ease);
}

#toast button:not(:disabled):active {
  scale: 0.96;
}

#toast :focus-visible {
  outline: 2px solid var(--on-iron);
  outline-offset: 2px;
}

/* Loading shows the shape of the screen, not a word. */
.skeleton .sk-band {
  height: 168px;
  margin: calc(-1 * (20px + env(safe-area-inset-top))) -20px 22px;
  border-radius: 0 0 var(--radius-band) var(--radius-band);
  background: #190706;
}

.skeleton .sk-sheet {
  height: 148px;
  margin-bottom: 16px;
  border-radius: var(--radius-sheet);
  background: var(--sheet-glass);
  box-shadow: var(--shadow-sheet);
}

.skeleton .sk-sheet.short {
  height: 96px;
}

@media (prefers-reduced-motion: no-preference) {
  .skeleton .sk-band,
  .skeleton .sk-sheet {
    animation: pulse 1.1s ease-in-out infinite alternate;
  }

  @keyframes pulse {
    from {
      opacity: 0.55;
    }
  }

  /* A new screen rises into place, block by block. Redrawing in place does not repeat it. */
  #view.entering > * > :not(.hero) {
    animation: screen-in 420ms var(--ease) both;
  }

  #view.entering > * > :nth-child(2) { animation-delay: 60ms; }
  #view.entering > * > :nth-child(3) { animation-delay: 120ms; }
  #view.entering > * > :nth-child(4) { animation-delay: 180ms; }
  #view.entering > * > :nth-child(5) { animation-delay: 240ms; }
  #view.entering > * > :nth-child(n + 6) { animation-delay: 300ms; }

  @keyframes screen-in {
    from {
      opacity: 0;
      translate: 0 12px;
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  #view.entering > * {
    animation: fade-in 200ms ease-out both;
  }
}

/* --- Inicio and the bottom bar of the mix ---------------------------------------- */

/* The bar: glass, with the "+" raised in the middle. */
#tabs {
  max-width: 536px;
  align-items: center;
  padding: 5px 6px;
  background: var(--sheet-glass);
  border-color: var(--rule);
  box-shadow: 0 16px 34px -16px rgb(0 0 0 / 0.45);
  -webkit-backdrop-filter: blur(22px) saturate(170%);
  backdrop-filter: blur(22px) saturate(170%);
}

#tabs a {
  color: var(--muted);
  font-weight: 600;
}

#tabs a.active {
  background: color-mix(in srgb, var(--brand) 14%, transparent);
  box-shadow: none;
  color: var(--red-text);
}

#tabs :focus-visible {
  outline-color: var(--ink);
}

#tabs .plus {
  flex: none;
  align-self: flex-start;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin: -30px 4px 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 26%, #e5503f, var(--brand) 55%, #8e120b);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.3),
    0 0 0 6px var(--sheet),
    0 16px 28px -8px rgb(161 30 20 / 0.9);
  color: var(--on-brand);
  cursor: pointer;
  transition: scale 150ms var(--ease);
}

#tabs .plus:active {
  scale: 0.94;
}

#tabs .plus:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

/* The sheet the "+" opens */
dialog.quick {
  width: min(100% - 24px, 520px);
  max-width: none;
  margin: auto auto calc(104px + env(safe-area-inset-bottom));
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 28px;
  background: var(--sheet-glass);
  box-shadow: 0 24px 60px -24px rgb(0 0 0 / 0.6);
  color: var(--ink);
  -webkit-backdrop-filter: blur(26px) saturate(170%);
  backdrop-filter: blur(26px) saturate(170%);
}

dialog.quick::backdrop {
  background: rgb(20 8 6 / 0.45);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
}

.quick-body {
  display: grid;
  gap: 14px;
  padding: 16px;
}

.quick-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.quick-head h2 {
  margin: 0;
  font-size: 1.5rem;
}

.quick-close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--sunken);
  color: var(--ink);
  cursor: pointer;
}

.quick-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.quick-grid a {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 14px 6px 12px;
  border-radius: 18px;
  background: var(--sunken);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  transition: scale 150ms var(--ease);
}

.quick-grid a:active {
  scale: 0.96;
}

.quick-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 16px;
  background: linear-gradient(140deg, var(--brand-deep), var(--brand));
  box-shadow: 0 8px 16px -8px rgb(161 30 20 / 0.8);
  color: var(--on-brand);
}

dialog.quick :focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: no-preference) {
  dialog.quick[open] {
    animation: sheet-in 380ms cubic-bezier(0.34, 1.3, 0.64, 1) both;
  }

  dialog.quick[open]::backdrop {
    animation: fade-in 220ms ease-out both;
  }

  dialog.quick[open] .quick-grid a {
    animation: screen-in 300ms var(--ease) both;
    animation-delay: calc(60ms + var(--j, 0) * 35ms);
  }

  @keyframes sheet-in {
    from {
      opacity: 0;
      translate: 0 24px;
      scale: 0.94;
    }
  }
}

/* Inicio: the glass header with the three rings */
.home-hero {
  display: grid;
  gap: 4px;
}

.home-hero h1 {
  margin: 0 0 14px;
  font-size: 2.5rem;
}

.hero-date {
  margin: 0;
  color: var(--on-brand-soft);
  font-size: 0.9375rem;
  font-weight: 500;
}

.rings-row {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  align-items: center;
  gap: 18px;
}

.rings-wrap {
  position: relative;
  width: 150px;
  aspect-ratio: 1;
}

.rings-wrap::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(24 2 2 / 0.55), transparent);
}

.rings {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 0 10px rgb(255 90 50 / 0.35));
}

.ring-track {
  fill: none;
  stroke: rgb(255 255 255 / 0.12);
  stroke-width: 17;
}

.ring-value {
  fill: none;
  stroke-width: 17;
  stroke-linecap: round;
  stroke-dashoffset: var(--off);
  transition: stroke-dashoffset 800ms var(--ease);
}

@media (prefers-reduced-motion: no-preference) {
  .home-hero.enter .ring-value {
    animation: ring-draw 1400ms var(--ease) both;
    animation-delay: calc(420ms + var(--k, 0) * 170ms);
  }

  @keyframes ring-draw {
    from {
      stroke-dashoffset: var(--c);
    }
  }
}

.rings-legend {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.legend-label {
  display: block;
  color: var(--on-brand-soft);
  font-size: 0.875rem;
  font-weight: 600;
}

.rings-legend b {
  font-family: var(--display);
  font-size: 2.125rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.rings-legend small {
  font-size: 1.0625rem;
  font-weight: 600;
  opacity: 0.85;
}

.legend-workouts b {
  color: #ff8f73;
}

.legend-habits b {
  color: #ffb45e;
}

.legend-protein b {
  color: #ffe08a;
}

/* Cards: the clean sheets under the header */
.card {
  display: grid;
  gap: 10px;
  margin: 0 0 14px;
  padding: 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-sheet);
  background: var(--sheet-glass);
  box-shadow: var(--shadow-sheet);
  color: var(--ink);
  text-decoration: none;
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
}

.card h2 {
  margin: 0;
  font-size: 1.25rem;
}

.card p {
  margin: 0;
}

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.card-title {
  font: 700 1.875rem/1.05 var(--display);
  letter-spacing: -0.01em;
}

.card-link {
  transition: scale 150ms var(--ease);
}

.card-link:not(.btn):active {
  scale: 0.985;
}

.card-action {
  color: var(--red-text);
  font-weight: 700;
}

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

p.small {
  color: var(--muted);
  font-size: 0.875rem;
}

.big {
  font: 700 2.25rem/1 var(--display);
  font-variant-numeric: tabular-nums;
}

.big small {
  color: var(--muted);
  font: 600 0.9375rem var(--text);
}

.last-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 0;
}

.last-stats dt {
  color: var(--muted);
  font-size: 0.8125rem;
}

.last-stats dd {
  margin: 0;
  font: 700 1.5rem/1.1 var(--display);
  font-variant-numeric: tabular-nums;
}

.last-stats dd small {
  color: var(--muted);
  font: 600 0.8125rem var(--text);
}

.record-note {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  color: var(--red-text);
  font-size: 0.9375rem;
}

.record-note b {
  color: var(--ink);
}

/* Habits as tiles */
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 8px 0 10px;
}

.section-head h2 {
  margin: 0;
  font-size: 1.25rem;
}

.count {
  margin: 0;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.count b {
  color: var(--ink);
}

.habits-block {
  margin-bottom: 14px;
}

.tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.habit-tile {
  position: relative;
  display: grid;
  align-content: space-between;
  gap: 10px;
  min-height: 120px;
  padding: 12px;
  overflow: hidden;
  isolation: isolate;
  border: 1px solid transparent;
  border-radius: 22px;
  background: var(--sheet-glass);
  box-shadow: var(--shadow-sheet);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  transition: scale 150ms var(--ease);
}

.habit-tile:active {
  scale: 0.96;
}

.tile-fill {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(160deg, var(--brand), var(--brand-deep));
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 620ms var(--ease);
}

.habit-tile.is-done .tile-fill {
  transform: scaleY(1);
}

.tile-mark {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--sunken);
  font: 700 1.125rem var(--display);
  transition: background-color 250ms ease-out, color 250ms ease-out;
}

.tile-text {
  display: grid;
  gap: 2px;
  padding-bottom: 6px;
}

.tile-name {
  font-weight: 700;
  line-height: 1.2;
}

.tile-detail,
.tile-streak {
  color: var(--muted);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  transition: color 250ms ease-out 120ms;
}

.tile-streak {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.tile-check {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #ffffff;
  color: var(--brand-deep);
  scale: 0;
  opacity: 0;
  transition: scale 320ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 200ms ease-out;
}

.tile-bar {
  position: absolute;
  right: 12px;
  bottom: 8px;
  left: 12px;
  height: 4px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--sunken);
  transition: opacity 200ms ease-out;
}

.tile-bar i {
  display: block;
  width: calc(var(--p) * 100%);
  height: 100%;
  border-radius: inherit;
  background: var(--fill);
}

.habit-tile.is-done .tile-check {
  scale: 1;
  opacity: 1;
}

.habit-tile.is-done .tile-bar {
  opacity: 0;
}

.habit-tile.is-done,
.habit-tile.is-done .tile-detail,
.habit-tile.is-done .tile-streak {
  color: var(--on-brand);
}

.habit-tile.is-done .tile-mark {
  background: rgb(60 8 4 / 0.4);
  color: var(--on-brand);
}

/* Starting from nothing */
.starters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.starter {
  position: relative;
  display: grid;
  gap: 2px;
  min-height: 62px;
  padding: 10px 34px 10px 12px;
  border: 1.5px solid transparent;
  border-radius: 16px;
  background: var(--sunken);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 200ms ease-out, border-color 200ms ease-out, scale 150ms var(--ease);
}

.starter:active {
  scale: 0.96;
}

.starter[aria-pressed="true"] {
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 10%, var(--sheet));
}

.starter-name {
  font-weight: 700;
  line-height: 1.2;
}

.starter-note {
  color: var(--muted);
  font-size: 0.8125rem;
}

.starter-check {
  position: absolute;
  top: 8px;
  right: 8px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--brand);
  color: var(--on-brand);
  scale: 0;
  transition: scale 280ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.starter[aria-pressed="true"] .starter-check {
  scale: 1;
}

/* Weight and goal side by side */
.pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.pair .card {
  align-content: start;
  margin: 0;
}

.pair .sparkline {
  height: 44px;
  margin: 0;
}

.goal-name {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.25;
}

.goal-bar {
  height: 10px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--sunken);
}

.goal-bar i {
  display: block;
  width: calc(var(--g) * 100%);
  height: 100%;
  border-radius: inherit;
  background: var(--fill);
}

@media (prefers-reduced-motion: no-preference) {
  .goal-bar i {
    animation: grow-x 1000ms var(--ease) 600ms both;
    transform-origin: left;
  }

  @keyframes grow-x {
    from {
      transform: scaleX(0);
    }
  }

  .habit-tile.just-done .tile-check {
    animation: tick-pop 520ms var(--ease);
  }

  @keyframes tick-pop {
    50% {
      transform: scale(1.3);
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .tile-fill,
  .ring-value,
  .tile-check {
    transition-property: opacity, background-color;
  }
}

.habits-block .panel-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 6px;
  color: var(--red-text);
  font-weight: 700;
  text-decoration: none;
}

/* The tile's own surface turns red once the fill has covered it, so what is under the text is
   always its real color (and tools that read backgrounds see it). */
.habit-tile {
  transition:
    scale 150ms var(--ease),
    background-color 0s linear 620ms;
}

.habit-tile.is-done {
  background: var(--brand);
}

/* Quick weight form: a figure between a minus and a plus */
.stepper {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) 56px;
  align-items: center;
  gap: 12px;
}

.stepper .stepper-input {
  min-height: 56px;
  margin: 0;
  padding: 0 8px;
  text-align: center;
  font-family: var(--display);
  font-size: 2.75rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stepper-btn {
  width: 56px;
  height: 56px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--field);
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}

.stepper-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.stepper-unit {
  margin: 4px 0 0;
  text-align: center;
}

/* Routines */
.routine-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-right: 12px;
}

.routine-item .entry {
  flex: 1;
  min-width: 0;
}

.routine-rows {
  display: grid;
  gap: 8px;
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
}

.routine-row {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  align-items: center;
  gap: 2px 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
}

.routine-actions {
  grid-column: 2;
  display: flex;
  justify-content: flex-end;
  gap: 4px;
}

.routine-row .set-index {
  text-align: center;
  color: var(--muted);
}

.routine-row .exercise-name {
  margin: 0;
}

.icon-btn.up svg {
  transform: rotate(-90deg);
}

.icon-btn.down svg {
  transform: rotate(90deg);
}

.icon-btn:disabled {
  opacity: 0.35;
}

/* A draft found when the log screen opens */
.recovered {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 16px;
  padding: 10px 14px;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: color-mix(in srgb, var(--brand) 10%, var(--sheet));
}
.habit-value { flex-wrap: wrap; }

/* One row of chips that scrolls sideways instead of wrapping into several rows */
.chips.scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: none;
  /* The fade on the right says there is more to slide; the padding lets the last chip clear it. */
  padding-inline-end: 28px;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}

.chips.scroll::-webkit-scrollbar {
  display: none;
}

.chips.scroll .chip {
  flex: none;
}

/* --- Grouped lists (Hábitos first) --------------------------------------------- */

/* One surface per group and rows split by hairlines inset to the text: no borders, shadows or
   glass around each thing. It is how iOS lays out Settings, Reminders and Fitness. */
.group-section {
  margin: 0 0 24px;
}

.group-title {
  margin: 0 16px 8px;
  color: var(--muted);
  font: 600 0.8125rem/1.3 var(--text);
  letter-spacing: 0.02em;
}

.panel.group {
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 22px;
  background: var(--sheet);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.group > .empty {
  padding: 18px 16px;
}

.group .habit-row {
  position: relative;
  grid-template-columns: 44px 1fr auto;
  column-gap: 10px;
  min-height: 64px;
  padding: 10px 16px 10px 8px;
  border-top: 0;
}

.group .habit-row + .habit-row::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 62px;
  height: 1px;
  background: var(--rule);
}

.group .habit-check .box {
  width: 28px;
  height: 28px;
  border-width: 1.5px;
  border-radius: 50%;
}

.group .habit-check[aria-checked="true"] .box {
  box-shadow: none;
}

.group .habit-sub {
  font-size: 0.875rem;
}

.group .dot {
  width: 8px;
  height: 8px;
  border-width: 1px;
}

.group.archived summary {
  min-height: 56px;
  padding: 0 16px;
}

.group.archived .module-row {
  margin-inline: 16px;
  padding-inline: 0;
  border-top: 1px solid var(--rule);
}

/* The value of a numeric habit: a filled field and a text action instead of two outlined boxes. */
.group .habit-value input {
  width: 88px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--sunken);
  text-align: center;
}

.group .habit-value .btn.ghost {
  min-width: 44px;
  padding-inline: 10px;
  border: 0;
  background: none;
  color: var(--red-text);
  box-shadow: none;
}

.group .habit-streak.muted {
  color: var(--muted);
  font-size: 0.875rem;
}

/* --- Confirmation sheet (confirm.js) ------------------------------------------- */

/* A sheet from the bottom, like an iOS action sheet: the question and its destructive action in
   one surface, and Cancel in a surface of its own below. */
dialog.confirm {
  width: min(100% - 24px, 440px);
  max-width: none;
  margin: auto auto calc(12px + env(safe-area-inset-bottom));
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  overscroll-behavior: contain;
}

dialog.confirm::backdrop {
  background: rgb(10 4 3 / 0.5);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

dialog.confirm[open] {
  display: grid;
  gap: 8px;
}

.confirm-sheet {
  display: grid;
  gap: 6px;
  padding: 20px 20px 8px;
  border-radius: 22px;
  background: var(--sheet);
  text-align: center;
}

.confirm-sheet h2 {
  margin: 0;
  font: 600 1.0625rem/1.3 var(--text);
  text-wrap: balance;
}

.confirm-sheet p {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.4;
  text-wrap: pretty;
}

.confirm-action,
.confirm-cancel {
  min-height: 56px;
  border: 0;
  font: 600 1.0625rem/1 var(--text);
  cursor: pointer;
}

.confirm-action {
  margin: 0 -20px;
  border-top: 1px solid var(--rule);
  background: none;
  color: var(--red-text);
}

.confirm-cancel {
  border-radius: 22px;
  background: var(--sheet);
  color: var(--ink);
}

@media (prefers-reduced-motion: no-preference) {
  dialog.confirm[open] {
    animation: confirm-in 220ms var(--ease);
  }

  @keyframes confirm-in {
    from {
      opacity: 0;
      transform: translateY(24px);
    }
  }
}

/* --- Inicio (ux-polish T1) ------------------------------------------------------ */

/* Cards and tiles are solid surfaces: the page behind them is not blurred through. */
.card,
.habit-tile {
  background: var(--sheet);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.meal-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0;
}

.meal-stats dt {
  color: var(--muted);
  font-size: 0.8125rem;
}

.meal-stats dd {
  margin: 0;
  font: 700 1.5rem/1.1 var(--display);
  font-variant-numeric: tabular-nums;
}

.meal-stats dd small {
  color: var(--muted);
  font: 600 0.8125rem var(--text);
}

.shortcuts-block {
  margin-top: 22px;
}

.shortcuts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.shortcut {
  display: grid;
  align-content: space-between;
  gap: 14px;
  min-height: 104px;
  padding: 14px;
  border-radius: 22px;
  background: var(--sheet);
  color: var(--ink);
  text-decoration: none;
  transition: scale 150ms var(--ease);
}

.shortcut:active {
  scale: 0.97;
}

.shortcut-icon {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border-radius: 12px;
  background: var(--brand);
  color: var(--on-brand);
}

.shortcut-text {
  display: grid;
  gap: 2px;
  line-height: 1.2;
}

.shortcut-name {
  font-size: 1.0625rem;
  font-weight: 600;
}

.shortcut-stat {
  color: var(--muted);
  font-size: 0.8125rem;
}

/* --- Más and the "+" sheet (ux-polish T2) ----------------------------------------- */

/* A menu: the icon is a red rounded square, as in the Settings of iOS with one accent. */
.group.menu {
  margin-bottom: 24px;
}

.group.menu .module-row {
  position: relative;
  min-height: 64px;
  padding: 10px 16px;
}

.group.menu .module-row + .module-row::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 66px;
  height: 1px;
  background: var(--rule);
}

.group.menu .module-row:active {
  background: var(--sunken);
}

.group.menu .tile {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--brand);
  color: var(--on-brand);
}

.group.menu .module-name {
  font-size: 1.0625rem;
}

.group.padded {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.group.padded > * {
  margin: 0;
}

/* The sheet of the "+": one solid surface at the bottom, like the confirmation sheet. */
dialog.quick {
  margin: auto auto calc(12px + env(safe-area-inset-bottom));
  border: 0;
  background: var(--sheet);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.quick-body {
  gap: 18px;
  padding: 18px 16px 16px;
}

.quick-grid {
  gap: 4px;
}

.quick-grid a {
  gap: 10px;
  padding: 12px 4px;
  background: none;
  font-size: 0.9375rem;
}

.quick-grid a:active {
  background: var(--sunken);
}

.quick-icon {
  width: 56px;
  height: 56px;
  border-radius: 17px;
  box-shadow: none;
}

/* --- Completing a habit (ux-polish T3) ---------------------------------------------- */

/* A habit done: the red grows from the touch, the check draws itself, the mark gives a beat.
   The redrawn tile starts already done, so these are keyframes, not transitions. */
@media (prefers-reduced-motion: no-preference) {
  .habit-tile.just-done .tile-fill {
    animation: tile-reveal 700ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
  }

  .habit-tile.just-done .tile-check svg path {
    stroke-dasharray: 22;
    animation: check-draw 380ms ease-out 220ms both;
  }

  .habit-tile.just-done .tile-mark {
    animation: mark-beat 520ms var(--ease) 80ms both;
  }

  @keyframes tile-reveal {
    from {
      clip-path: circle(0 at var(--ox, 50%) var(--oy, 50%));
    }
    to {
      clip-path: circle(160% at var(--ox, 50%) var(--oy, 50%));
    }
  }

  @keyframes check-draw {
    from {
      stroke-dashoffset: 22;
    }
    to {
      stroke-dashoffset: 0;
    }
  }

  @keyframes mark-beat {
    40% {
      scale: 1.18;
    }
  }

  /* The habits ring answers every change; the last habit of the day closes it with a flash. */
  .rings-wrap.pulse .rings {
    animation: ring-pulse 520ms var(--ease);
  }

  .rings-wrap.flash .rings {
    animation: ring-pulse 700ms var(--ease);
  }

  .rings-wrap.flash::after {
    content: "";
    position: absolute;
    inset: -14px;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(closest-side, rgb(255 190 150 / 0.85), rgb(255 90 50 / 0.35) 55%, transparent);
    animation: ring-flash 1100ms ease-out both;
  }

  @keyframes ring-pulse {
    40% {
      scale: 1.07;
    }
  }

  @keyframes ring-flash {
    from {
      opacity: 1;
      scale: 0.6;
    }
    to {
      opacity: 0;
      scale: 1.35;
    }
  }
}

/* The day is complete: the ring keeps a warm glow. */
.rings-wrap.complete .rings {
  filter: drop-shadow(0 0 14px rgb(255 120 70 / 0.65));
}

.habits-block .count b {
  font-variant-numeric: tabular-nums;
}

/* --- Surfaces everywhere (ux-polish T4) ------------------------------------------------ */

/* Every panel and sheet is one solid surface, like the grouped lists: no glass, no ring of
   shadow. The border stays transparent so forced-colors mode still draws an edge. */
.panel,
.sheet {
  border-radius: 22px;
  background: var(--sheet);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* A form that is shorter than the screen still ends with its save bar at the bottom of it: the
   form takes the height that is left and the bar goes to the end of it. */
main:has(.savebar) {
  display: flex;
  min-height: 100lvh;
  flex-direction: column;
}

main:has(.savebar) > div {
  display: flex;
  flex: 1;
  flex-direction: column;
}

main > div > form:has(> .savebar) {
  display: flex;
  flex: 1;
  flex-direction: column;
}

form > .savebar {
  margin-top: auto;
}

/* --- One colour per module (ux-polish T7) ------------------------------------------ */

/* The hue tells one module from another and is the same wherever the module appears. The
   tile is a faint wash of the hue and the icon carries it; in light mode the icon is darker so
   it keeps 3:1 against its tile. Colour never carries the meaning alone: names are always there. */
.hue-training { --hue: #ff6b57; }
.hue-meals { --hue: #ff9a3d; }
.hue-body { --hue: #4da3ff; }
.hue-money { --hue: #2fc4b2; }
.hue-notes { --hue: #a78bfa; }
.hue-projects { --hue: #e879f9; }
.hue-learning { --hue: #7c8cff; }
.hue-goals { --hue: #ffd23f; }

.hued,
.group.menu .tile.hued {
  background: color-mix(in srgb, var(--hue) 14%, var(--sheet));
  color: color-mix(in srgb, var(--hue) 60%, #000);
  box-shadow: none;
}

@media (prefers-color-scheme: dark) {
  .hued,
  .group.menu .tile.hued {
    background: color-mix(in srgb, var(--hue) 18%, var(--sheet));
    color: var(--hue);
  }
}

.group-title.caps {
  margin-inline: 16px;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- Better UI: the screens of Direction A (odd/tasks/better-ui.md) ------------------ */

.group-section > .chips {
  margin-inline: 0;
}

.chip.lead {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-color: transparent;
  background: color-mix(in srgb, var(--brand) 18%, var(--sheet));
  color: var(--red-text);
}

/* Workouts: the day is the anchor of a row. */
.workout-months {
  margin-top: 4px;
}

.workout-row {
  position: relative;
  display: flex;
  gap: 14px;
  padding: 14px 16px;
  color: inherit;
  text-decoration: none;
  transition: background-color 150ms ease-out;
}

.workout-row:active {
  background-color: var(--sunken);
}

.workout-row + .workout-row::before {
  position: absolute;
  inset: 0 0 auto 74px;
  height: 1px;
  background: var(--rule);
  content: "";
}

.workout-day {
  display: flex;
  width: 44px;
  flex: none;
  flex-direction: column;
  align-items: center;
}

.workout-num {
  font: 700 1.875rem/1 var(--display);
  font-variant-numeric: tabular-nums;
}

.workout-wd {
  margin-top: 2px;
  color: var(--muted);
  font: 600 0.75rem/1.3 var(--text);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.workout-main {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
  gap: 2px;
}

.workout-title {
  font: 700 1.0625rem/1.3 var(--text);
}

.workout-names {
  color: var(--ink);
  font-size: 0.875rem;
  line-height: 1.4;
  opacity: 0.82;
}

.workout-figures {
  color: var(--muted);
  font-size: 0.8125rem;
}

/* Detail screens of a band: the way back sits inside it. */
.detail-head {
  align-items: flex-end;
}

.detail-head .back {
  flex-basis: 100%;
  margin: 0;
  color: color-mix(in srgb, var(--on-brand) 88%, transparent);
}

.detail-head h1 {
  margin: 0;
}

.band-sub {
  margin: 4px 0 0;
  color: color-mix(in srgb, var(--on-brand) 86%, transparent);
  font-size: 0.9375rem;
}

.panel.group.stat-strip {
  display: flex;
  margin-bottom: 18px;
  padding: 14px 8px;
}

.stat-strip > div {
  flex: 1;
  text-align: center;
}

.stat-strip > div + div {
  border-left: 1px solid var(--rule);
}

.stat-strip b {
  display: block;
  font: 700 1.75rem/1.1 var(--display);
  font-variant-numeric: tabular-nums;
}

.stat-strip span {
  color: var(--muted);
  font-size: 0.8125rem;
}

.panel.group.exercise-card {
  margin-bottom: 14px;
}

.stat-strip + blockquote {
  margin-top: 0;
  margin-bottom: 18px;
}

.exercise-card > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px 6px;
}

.exercise-card h2 {
  margin: 0;
  font: 700 1.125rem/1.3 var(--text);
}

.record-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 0 10px;
  border-radius: 13px;
  background: color-mix(in srgb, var(--brand) 18%, var(--sheet));
  color: var(--red-text);
  font: 700 0.75rem/1 var(--text);
}

.set-row {
  position: relative;
  display: grid;
  grid-template-columns: 36px 1fr 1fr auto;
  gap: 8px;
  padding: 9px 16px;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.set-row + .set-row::before {
  position: absolute;
  inset: 0 0 auto 52px;
  height: 1px;
  background: var(--rule);
  content: "";
}

.exercise-card > .set-row:last-child {
  padding-bottom: 13px;
}

.set-num,
.set-rpe {
  color: var(--muted);
}

.set-weight {
  font-weight: 600;
}

.exercise-card > .hint {
  margin: 0;
  padding: 8px 16px 14px;
}

/* Comidas */
.panel.meal-total {
  margin-bottom: 22px;
  padding: 18px 16px 16px;
  --hue-fill: linear-gradient(90deg, #d97a1f, #ff9a3d);
}

.meal-total .meter {
  margin-bottom: 10px;
}

.meal-total .facts {
  margin-block: 0;
}

.meal-figures {
  display: flex;
  align-items: flex-end;
  gap: 28px;
  margin-bottom: 14px;
}

.meal-figures > div {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.meal-figures b {
  font: 700 2.75rem/1 var(--display);
  font-variant-numeric: tabular-nums;
}

.meal-figures span {
  margin-top: 4px;
  color: var(--muted);
  font-size: 0.8125rem;
}

.meal-total .meter > span {
  background: var(--hue-fill, var(--fill));
}

.line-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 12px 16px;
  color: inherit;
  text-decoration: none;
  transition: background-color 150ms ease-out;
}

.line-row:active {
  background-color: var(--sunken);
}

.line-row + .line-row::before {
  position: absolute;
  inset: 0 0 auto 64px;
  height: 1px;
  background: var(--rule);
  content: "";
}

.line-icon {
  display: grid;
  width: 36px;
  height: 36px;
  flex: none;
  place-items: center;
  border-radius: 10px;
}

.line-main {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
}

.line-name {
  font: 600 1rem/1.3 var(--text);
}

.line-meta {
  color: var(--muted);
  font-size: 0.8125rem;
}

.line-figure {
  flex: none;
  font: 700 1.125rem/1 var(--display);
  font-variant-numeric: tabular-nums;
}

/* Two things on the right of a band's title (Gastos: "Privado" and its add button). */
.head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.add-form > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* Hábitos: the value field opens from "Cargar". */
.habit-manual {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Gastos: a reminder that the module is private. */
.private-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 12px;
  border-radius: 16px;
  background: rgb(0 0 0 / 0.28);
  color: var(--on-brand);
  font: 600 0.8125rem/1 var(--text);
}

/* Notas */
.note-row {
  position: relative;
  padding: 12px 16px 12px;
}

.note-row + .note-row::before {
  position: absolute;
  inset: 0 0 auto 16px;
  height: 1px;
  background: var(--rule);
  content: "";
}

.note-link {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: inherit;
  text-decoration: none;
}

.note-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.note-title {
  font: 700 1.0625rem/1.3 var(--text);
}

.note-type {
  flex: none;
  color: var(--muted);
  font-size: 0.8125rem;
}

.note-snippet {
  color: var(--ink);
  font-size: 0.875rem;
  line-height: 1.4;
  opacity: 0.82;
}

.note-row .chips {
  margin-top: 8px;
}

.group-title svg {
  margin-right: 6px;
  vertical-align: -2px;
}

/* Proyectos */
.project-row {
  align-items: flex-start;
}

.project-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.project-row .chips {
  margin-top: 6px;
}

.group.archived > div > .line-row {
  margin-inline: 0;
  border-top: 0;
}

/* Aprendizaje */
.learn-row {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 16px;
  color: inherit;
  text-decoration: none;
  transition: background-color 150ms ease-out;
}

.learn-row:active {
  background-color: var(--sunken);
}

.learn-row + .learn-row::before {
  position: absolute;
  inset: 0 0 auto 16px;
  height: 1px;
  background: var(--rule);
  content: "";
}

.group.archived > div > .learn-row:first-child::before {
  display: none;
}

.learn-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.learn-progress {
  display: flex;
  align-items: center;
  gap: 12px;
}

.learn-progress .meter {
  flex: 1;
}

.learn-progress b {
  min-width: 40px;
  font: 700 0.9375rem/1 var(--text);
  font-variant-numeric: tabular-nums;
  text-align: end;
}

/* Metas */
.goal-row {
  gap: 14px;
}

.goal-ring {
  position: relative;
  display: grid;
  width: 48px;
  height: 48px;
  flex: none;
  place-items: center;
  color: var(--ink);
}

.goal-ring svg {
  position: absolute;
  inset: 0;
}

.goal-ring .goal-ring-track {
  stroke: var(--sunken);
}

.goal-ring .goal-ring-value {
  stroke: var(--hue-goal, #c8921b);
}

.goal-ring b {
  font: 700 0.9375rem/1 var(--display);
  font-variant-numeric: tabular-nums;
}

.goal-reached {
  color: var(--red-text);
  font-weight: 600;
}

@media (prefers-color-scheme: dark) {
  .goal-ring .goal-ring-value {
    stroke: #ffd23f;
  }
}

.panel.group + .panel.group {
  margin-top: 14px;
}

.goal-row + .goal-row::before {
  left: 78px;
}

/* Cuerpo */
.history {
  margin-top: 24px;
}

.panel.group > .measurement {
  position: relative;
  padding: 12px 16px;
}

.panel.group > .measurement + .measurement::before {
  position: absolute;
  inset: 0 0 auto 16px;
  height: 1px;
  background: var(--rule);
  content: "";
}

.measurement p {
  margin: 2px 0 0;
}

/* Comidas: repeat what was eaten lately, and the add flow (search, describe, by hand). */
.recent-meals .chips {
  margin-bottom: 0;
}

.recent-meals .chip {
  max-width: 100%;
  text-align: left;
}

.meal-add .chips {
  margin: 12px 0;
}

.meal-mode[hidden] {
  display: none;
}

.meal-search {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 8px 12px;
}

.meal-search label {
  margin: 0;
}

button.line-row {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.meal-mode .panel.group {
  margin-bottom: 8px;
}

.meal-mode .group-title {
  margin: 16px 0 8px;
}

.ai-notice {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.ai-notice svg {
  flex: none;
  margin-top: 2px;
}

.portion h3 {
  margin: 12px 0 0;
  font: 700 1.25rem/1.2 var(--display);
}

.portion-figures {
  margin: 12px 0;
}

/* iOS Safari draws a date field with its own width and height and centres its value, so in a
   two-column row it spilled over its neighbour. It has to fill its cell like the other fields. */
.fields > * {
  min-width: 0;
}

input[type="date"],
input[type="time"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
  height: 52px;
  text-align: start;
}

input[type="date"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value {
  min-height: 1.4em;
  text-align: start;
}

/* The open add form's header: the title and Cancelar sit on one line. */
.add-form > header h2,
.add-form > header .btn {
  margin: 0;
}

/* Text without spaces (a pasted link, a very long word) wraps inside its row instead of being cut
   or running under the amount next to it. */
.line-name,
.line-meta,
.note-title,
.note-snippet,
.tile-name,
.module-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

.line-figure {
  max-width: 45%;
  text-align: end;
  overflow-wrap: anywhere;
}

/* A link inside a sentence is 20 px tall; this gives the finger 44 px without moving the text. */
.empty a {
  display: inline-block;
  margin: -12px -6px;
  padding: 12px 6px;
}
