/* ==========================================================================
   Fit Việt — "giấy & mực" (paper & ink)
   Warm editorial worksheet. Light-only on purpose: this reads like a coach's
   printed sheet, not a dashboard. No dark mode, no glow, no neon gradients.
   Fonts are self-hosted (assets/fonts) so the page works offline and fast on
   Vietnamese mobile networks.
   ========================================================================== */

/* ---------- fonts ------------------------------------------------------- */

@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-400-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-500-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-600-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-700-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Be Vietnam Pro';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/be-vietnam-pro-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/fraunces-400-700-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329,
    U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/fraunces-400-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

/* ---------- tokens ------------------------------------------------------ */

:root {
  color-scheme: light;

  /* hex fallbacks first; OKLCH below for browsers that support it */
  --paper: #faf6ef;
  --paper-2: #f3ece0;
  --paper-3: #eae0cf;
  --ink: #2e211a;
  --ink-2: #5c4a3d;
  --ink-3: #8a7666;
  --rule: #ddd0bb;
  --lantern: #c2452c;
  --lantern-ink: #9c3521;
  --leaf: #4a7c48;
  --amber: #c98a17;
  --olive: #8a7a2f;
  --brick: #b1503a;

  --shadow-sheet: 0 1px 0 var(--rule), 0 10px 24px -18px rgba(46, 33, 26, 0.5);

  /* type: fluid but bounded, 62ch measure */
  --step--1: clamp(0.83rem, 0.8rem + 0.15vw, 0.9rem);
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.08rem);
  --step-1: clamp(1.2rem, 1.12rem + 0.4vw, 1.4rem);
  --step-2: clamp(1.45rem, 1.3rem + 0.7vw, 1.85rem);
  --step-3: clamp(1.8rem, 1.5rem + 1.4vw, 2.6rem);
  --step-4: clamp(2.4rem, 1.8rem + 3vw, 4rem);

  /* spacing on a 4px grid */
  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;
  --s8: 4rem;

  --measure: 62ch;
  --radius: 3px;
  --ease: cubic-bezier(0.2, 0.6, 0.2, 1);
}

@supports (color: oklch(50% 0.1 20)) {
  :root {
    --paper: oklch(97.5% 0.012 75);
    --paper-2: oklch(95% 0.018 78);
    --paper-3: oklch(91.5% 0.026 78);
    --ink: oklch(26% 0.035 45);
    --ink-2: oklch(42% 0.03 48);
    --ink-3: oklch(58% 0.028 55);
    --rule: oklch(86% 0.025 75);
    --lantern: oklch(55% 0.19 28);
    --lantern-ink: oklch(46% 0.17 28);
    --leaf: oklch(54% 0.11 145);
    --amber: oklch(68% 0.13 75);
    --olive: oklch(58% 0.09 100);
    --brick: oklch(53% 0.14 34);
  }
}

/* ---------- reset ------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--paper);
  /* faint paper tooth: two very low-contrast washes, no image request */
  background-image: radial-gradient(
      circle at 15% -10%,
      color-mix(in oklab, var(--paper-2) 70%, transparent),
      transparent 55%
    ),
    radial-gradient(circle at 100% 0%, color-mix(in oklab, var(--paper-3) 45%, transparent), transparent 40%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: 'Be Vietnam Pro', ui-sans-serif, sans-serif;
  font-size: var(--step-0);
  line-height: 1.6;
  font-feature-settings: 'kern' 1;
  text-rendering: optimizeLegibility;
}

img,
svg {
  display: block;
  max-width: 100%;
}

h1,
h2,
h3 {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0;
  text-wrap: balance;
}

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

a {
  color: var(--lantern-ink);
  text-underline-offset: 0.18em;
  text-decoration-thickness: from-font;
}

:where(a, button, input, select, summary):focus-visible {
  outline: 2px solid var(--lantern);
  outline-offset: 2px;
  border-radius: 2px;
}

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

.wrap {
  width: 100%;
  max-width: 68rem;
  margin-inline: auto;
  padding-inline: var(--s4);
}

.prose {
  max-width: var(--measure);
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  position: static;
  display: inline-block;
  margin: var(--s2);
  padding: var(--s2) var(--s3);
  background: var(--ink);
  color: var(--paper);
}

/* ---------- masthead ---------------------------------------------------- */

.masthead {
  border-bottom: 1px solid var(--rule);
  background: color-mix(in oklab, var(--paper) 85%, white);
}

.masthead-in {
  display: flex;
  /* Centre, not baseline: the brand carries a 1.4em icon and the nav links a
     smaller type size, so baseline alignment left them ~10px out of visual
     alignment on every page. */
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding-block: var(--s3);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  /* "Gym Việt" broke onto two lines on phones, which pushed the nav into the
     gap between them and doubled the header height. */
  white-space: nowrap;
}

.brand-mark {
  width: 1.4em;
  height: 1.4em;
  flex: none;
}

.masthead-tag {
  font-size: var(--step--1);
  color: var(--ink-3);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ---------- hero: editorial, left-aligned, no big-number card ----------- */

.hero {
  padding-block: var(--s7) var(--s6);
  border-bottom: 1px solid var(--rule);
}

.hero h1 {
  font-size: var(--step-4);
  max-width: 24ch;
}

.hero h1 .mark {
  /* hand-highlighted word, not a gradient */
  background: linear-gradient(
    to bottom,
    transparent 62%,
    color-mix(in oklab, var(--amber) 45%, transparent) 62%,
    color-mix(in oklab, var(--amber) 45%, transparent) 94%,
    transparent 94%
  );
  padding-inline: 0.06em;
}

.hero-lede {
  margin-top: var(--s4);
  max-width: 48ch;
  font-size: var(--step-1);
  color: var(--ink-2);
  line-height: 1.5;
}

.hero-meta {
  margin-top: var(--s5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s5);
  font-size: var(--step--1);
  color: var(--ink-3);
}

.hero-meta li {
  list-style: none;
}
.hero-meta {
  padding: 0;
}

/* ---------- tool tabs (notebook dividers) ------------------------------ */

.tabs {
  display: flex;
  gap: var(--s1);
  margin-top: var(--s6);
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar {
  display: none;
}

.tab {
  appearance: none;
  border: 1px solid transparent;
  border-bottom: none;
  background: none;
  font: inherit;
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--ink-3);
  padding: var(--s2) var(--s4);
  white-space: nowrap;
  cursor: pointer;
  border-radius: var(--radius) var(--radius) 0 0;
  transition: color 0.15s var(--ease), background-color 0.15s var(--ease);
}

.tab:hover {
  color: var(--ink);
  background: color-mix(in oklab, var(--paper-2) 60%, transparent);
}

.tab[aria-selected='true'] {
  color: var(--ink);
  font-weight: 600;
  background: var(--paper);
  border-color: var(--rule);
  box-shadow: 0 1px 0 0 var(--paper);
}

.panel[hidden] {
  display: none;
}

/* ---------- worksheet (the form) --------------------------------------- */

.cols {
  display: grid;
  /* minmax(0, 1fr), not the default auto: a single-column grid sizes to the
     widest item's min-content, so a wide result table stretched the column
     past the page container and dragged the *form* out with it — 5px of
     horizontal scroll at 320px that looked like a form bug. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s6);
  padding-block: var(--s6);
  align-items: start;
}

@media (min-width: 60rem) {
  .cols {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: var(--s7);
  }
  .cols > .sheet-col {
    position: sticky;
    top: var(--s4);
  }
}

.step-label {
  display: flex;
  align-items: center;
  gap: var(--s3);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s4);
}

/* A later step needs air above it or it reads as a caption belonging to the
   block before it. Measured 0px between step 02 and the note above it on the
   progression form; the first label keeps its flush top. */
.step-label:not(:first-child) {
  margin-top: var(--s6);
}

.step-label::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.field {
  margin-bottom: var(--s5);
}

.field > label,
.legend {
  display: block;
  font-weight: 600;
  font-size: var(--step-0);
  margin-bottom: var(--s2);
}

.hint {
  display: block;
  font-size: var(--step--1);
  color: var(--ink-3);
  margin-bottom: var(--s2);
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--s4);
}

input[type='number'],
select {
  width: 100%;
  font: inherit;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: color-mix(in oklab, white 65%, var(--paper));
  border: 1px solid var(--rule);
  border-bottom-width: 2px;
  border-radius: var(--radius);
  padding: 0.7em 0.75em;
  min-height: 44px;
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease);
}

input[type='number']:hover,
select:hover {
  border-color: var(--ink-3);
}

input[type='number']:focus,
select:focus {
  border-color: var(--lantern);
  background: white;
}

input[aria-invalid='true'] {
  border-color: var(--lantern);
  background: color-mix(in oklab, var(--lantern) 6%, white);
}

.err {
  display: block;
  min-height: 1.2em;
  margin-top: var(--s1);
  font-size: var(--step--1);
  color: var(--lantern-ink);
  font-weight: 500;
}

/* segmented choice: ticket stubs, not pills */
fieldset {
  border: 0;
  margin: 0 0 var(--s5);
  padding: 0;
}

.seg {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.seg label {
  flex: 1 1 auto;
  min-width: 7rem;
  position: relative;
}

.seg input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  margin: 0;
}

.seg span {
  display: block;
  text-align: center;
  padding: 0.65em 0.9em;
  min-height: 44px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: color-mix(in oklab, white 55%, var(--paper));
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--ink-2);
  transition: all 0.15s var(--ease);
}

.seg label:hover span {
  border-color: var(--ink-3);
  color: var(--ink);
}

.seg input:checked + span {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
  font-weight: 600;
}

.seg input:focus-visible + span {
  outline: 2px solid var(--lantern);
  outline-offset: 2px;
}

.seg-note {
  font-size: var(--step--1);
  color: var(--ink-3);
  margin-top: var(--s2);
}

/* primary action: stamped, full-width on mobile */
.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  width: 100%;
  font: inherit;
  font-weight: 600;
  font-size: var(--step-0);
  letter-spacing: 0.01em;
  color: #fff;
  background: var(--lantern);
  border: 1px solid var(--lantern-ink);
  border-radius: var(--radius);
  padding: 0.85em 1.2em;
  min-height: 48px;
  cursor: pointer;
  box-shadow: 0 2px 0 0 var(--lantern-ink);
  transition: transform 0.1s var(--ease), box-shadow 0.1s var(--ease),
    background-color 0.15s var(--ease);
}

.btn:hover {
  background: var(--lantern-ink);
}

.btn:active {
  transform: translateY(2px);
  box-shadow: 0 0 0 0 var(--lantern-ink);
}

.btn-ghost {
  color: var(--ink-2);
  background: none;
  border-color: var(--rule);
  box-shadow: none;
  width: auto;
  font-size: var(--step--1);
  padding: 0.5em 0.9em;
  min-height: 40px;
}
.btn-ghost:hover {
  background: var(--paper-2);
  color: var(--ink);
}

.share-btn {
  margin-top: var(--s5);
}
.share-btn:disabled {
  opacity: 0.7;
  cursor: default;
}

/* ---------- result sheet (phiếu kết quả) ------------------------------- */

.sheet {
  position: relative;
  background: color-mix(in oklab, white 70%, var(--paper));
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sheet);
  padding: var(--s5) var(--s5) var(--s6);
}

.sheet::before {
  /* torn-edge tick marks along the top, like a tear-off pad */
  content: '';
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 4px;
  background: repeating-linear-gradient(
    90deg,
    var(--rule) 0 6px,
    transparent 6px 12px
  );
  border-radius: var(--radius) var(--radius) 0 0;
}

.sheet-head {
  display: flex;
  /* Centre, not flex-start: the title is uppercase small-caps and the stamp a
     different size, so flex-start left their optical centres 5.6px apart on
     every tool page. Same defect as the masthead had. */
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--rule);
}

.sheet-title {
  /* Must be allowed to shrink and wrap: with flex:none defaults the title plus
     the rotated stamp measured 293px inside a 238px sheet at 320px viewport,
     which pushed the whole page into horizontal scroll. */
  flex: 0 1 auto;
  min-width: 0;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.stamp {
  flex: none;
  transform: rotate(-4deg);
  border: 2px solid var(--lantern);
  color: var(--lantern-ink);
  border-radius: var(--radius);
  padding: 0.25em 0.6em;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.9;
}

.headline-kcal {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin-top: var(--s5);
}

.headline-kcal b {
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-4);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  line-height: 0.95;
}

.headline-kcal .unit {
  font-size: var(--step-1);
  color: var(--ink-3);
}

.headline-sub {
  margin-top: var(--s2);
  color: var(--ink-2);
  max-width: 42ch;
}

/* macro proportion bar */
.macrobar {
  display: flex;
  height: 0.85rem;
  margin-top: var(--s5);
  border: 1px solid var(--rule);
  border-radius: 99px;
  overflow: hidden;
  background: var(--paper-2);
}

.macrobar span {
  display: block;
  transition: flex-basis 0.5s var(--ease);
  flex-grow: 0;
  flex-shrink: 1;
}

.mb-p {
  background: var(--brick);
}
.mb-c {
  background: var(--amber);
}
.mb-f {
  background: var(--olive);
}

.macros {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s3);
  margin-top: var(--s4);
  padding: 0;
  list-style: none;
}

.macro {
  border-top: 3px solid var(--rule);
  padding-top: var(--s2);
}
.macro.is-p {
  border-top-color: var(--brick);
}
.macro.is-c {
  border-top-color: var(--amber);
}
.macro.is-f {
  border-top-color: var(--olive);
}

.macro dt {
  font-size: var(--step--1);
  color: var(--ink-3);
  font-weight: 500;
}

.macro dd {
  margin: var(--s1) 0 0;
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.macro dd small {
  display: block;
  margin-top: var(--s1);
  font-family: 'Be Vietnam Pro', sans-serif;
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--ink-3);
}

/* ---------- ledger rows (dotted leaders) ------------------------------- */

.ledger {
  margin: var(--s6) 0 0;
  padding: 0;
}

.ledger div {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding-block: var(--s2);
}

.ledger div + div {
  border-top: 1px dotted var(--rule);
}

.ledger dt {
  /* Shrinkable, unlike the value: a long label such as "Bánh tạ (cả hai bên)"
     with flex:none overflowed the sheet by 140px at a 320px viewport. The
     number keeps flex:none so it never wraps mid-figure. */
  flex: 0 1 auto;
  min-width: 0;
  overflow-wrap: break-word;
  color: var(--ink-2);
  font-size: var(--step--1);
}

.ledger .lead {
  flex: 1 1 var(--s4);
  min-width: var(--s3);
  height: 0;
  border-bottom: 1px dotted var(--rule);
  transform: translateY(-0.25em);
}

.ledger dd {
  flex: none;
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tone-good {
  color: var(--leaf);
}
.tone-neutral {
  color: var(--ink);
}
.tone-warn {
  color: var(--amber);
}
.tone-bad {
  color: var(--lantern-ink);
}

.sub-note {
  display: block;
  margin-top: var(--s2);
  font-size: var(--step--1);
  color: var(--ink-2);
  line-height: 1.5;
  max-width: 52ch;
}

/* ---------- notices ----------------------------------------------------- */

.notice {
  margin-top: var(--s5);
  /* Extra left padding: with symmetric 16px the text sat visually crowded
     against the new 4px rule, since the rule reads as part of the panel edge. */
  padding: var(--s3) var(--s4) var(--s3) var(--s5);
  /* At a 9% tint the panel measured 1.14:1 against the result sheet, i.e.
     effectively invisible, so the caveats inside it were skippable. 18% plus a
     4px rule reads as a distinct panel while staying on the paper palette. */
  border-left: 4px solid var(--amber);
  background: color-mix(in oklab, var(--amber) 18%, var(--paper));
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-2);
  border-radius: 0 var(--radius) var(--radius) 0;
}

.notice[hidden] {
  display: none;
}

.notice strong {
  color: var(--ink);
}

/* ---------- food equivalents (disclosure) ------------------------------ */

details.foods {
  margin-top: var(--s6);
  border-top: 1px solid var(--rule);
  padding-top: var(--s4);
}

details.foods summary {
  cursor: pointer;
  font-weight: 600;
  font-size: var(--step-0);
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--s2);
}

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

details.foods summary::before {
  content: '+';
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4em;
  height: 1.4em;
  flex: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  font-family: 'Fraunces', serif;
  color: var(--ink-3);
}

details.foods[open] summary::before {
  content: '–';
}

.food-cols {
  display: grid;
  gap: var(--s5);
  margin-top: var(--s4);
}

@media (min-width: 30rem) {
  .food-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.food-cols h3 {
  font-size: var(--step-0);
  font-family: 'Be Vietnam Pro', sans-serif;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: var(--s2);
}

.food-cols ul {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--step--1);
}

.food-cols li {
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  padding-block: 0.35em;
  border-bottom: 1px dotted var(--rule);
  color: var(--ink-2);
}

.serv {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  flex: none;
}

/* ---------- editorial sections ----------------------------------------- */

.section {
  padding-block: var(--s7);
  border-top: 1px solid var(--rule);
}

.section h2 {
  font-size: var(--step-3);
  max-width: 30ch;
}

.section h2 + p {
  margin-top: var(--s4);
  color: var(--ink-2);
}

.faq {
  margin-top: var(--s5);
  display: grid;
  gap: var(--s2);
  max-width: var(--measure);
}

.faq details {
  border-bottom: 1px solid var(--rule);
  padding-block: var(--s3);
}

.faq summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}

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

.faq summary::after {
  content: '↓';
  float: right;
  color: var(--ink-3);
  transition: transform 0.2s var(--ease);
}

.faq details[open] summary::after {
  content: '↑';
}

.faq p {
  margin-top: var(--s2);
  color: var(--ink-2);
  font-size: var(--step--1);
  line-height: 1.6;
  max-width: 56ch;
}

.disclaimer {
  margin-top: var(--s5);
  font-size: var(--step--1);
  color: var(--ink-3);
  max-width: 60ch;
  line-height: 1.6;
}

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

.site-foot {
  border-top: 1px solid var(--rule);
  background: color-mix(in oklab, var(--paper-2) 60%, var(--paper));
  padding-block: var(--s6);
  font-size: var(--step--1);
  color: var(--ink-3);
}

.site-foot p + p {
  margin-top: var(--s2);
}

/* ---------- masthead nav (shared across the tool pages) ---------------- */

.masthead-nav {
  display: flex;
  gap: var(--s2);
  overflow-x: auto;
  scrollbar-width: none;
  margin-inline: calc(-1 * var(--s2));
  padding-inline: var(--s2);
}

.masthead-nav::-webkit-scrollbar {
  display: none;
}

.masthead-nav a {
  flex: none;
  padding: 0.35em 0.6em;
  border-radius: var(--radius);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
}

.masthead-nav a:hover {
  background: var(--paper-2);
  color: var(--ink);
}

.masthead-nav a[aria-current='page'] {
  color: var(--ink);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 0 var(--lantern);
}

/* Phones: give the nav its own full-width row instead of squeezing it beside
   the brand, where the fourth tool was cut off with no scroll affordance.
   Wrapping beats scrolling here: with only four items a second row costs ~20px,
   while a hidden tool costs a visit. */
@media (max-width: 40rem) {
  .masthead-in {
    flex-wrap: wrap;
    row-gap: var(--s2);
  }

  .masthead-nav {
    width: 100%;
    gap: var(--s2);
    flex-wrap: wrap;
    overflow-x: visible;
  }

  /* Thumb targets. Measured 31px tall with 4px gaps before this rule, which
     clears the WCAG 2.5.8 floor of 24px but is tight for four adjacent links
     on a phone. */
  .masthead-nav a {
    padding-block: 0.55em;
    padding-inline: 0.5em;
  }
}

/* The home page stacks two identical .tool-index lists — tools, then guides.
   Same styling made them read as one long list, so the guides band gets a
   tinted ground: same design language, clearly a different kind of thing. */
.band {
  background: color-mix(in oklab, var(--paper-2) 55%, var(--paper));
}

/* ---------- tool index (cross-links, editorial list not cards) --------- */

.tool-index {
  margin: var(--s5) 0 0;
  padding: 0;
  list-style: none;
  max-width: var(--measure);
  border-top: 1px solid var(--rule);
}

.tool-index li {
  border-bottom: 1px solid var(--rule);
}

.tool-index a {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  padding-block: var(--s3);
  text-decoration: none;
  color: var(--ink);
}

.tool-index a:hover .ti-name {
  color: var(--lantern-ink);
}

.ti-num {
  flex: none;
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}

.ti-name {
  font-weight: 600;
}

.ti-desc {
  display: block;
  margin-top: var(--s1);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--ink-3);
}

.tool-index a::after {
  content: '→';
  margin-left: auto;
  flex: none;
  color: var(--ink-3);
}

/* ---------- checkbox row (which plates the gym owns) ------------------- */

.checks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.checks label {
  position: relative;
  flex: none;
}

.checks input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  margin: 0;
}

.checks span {
  display: block;
  min-width: 3.6rem;
  text-align: center;
  padding: 0.5em 0.6em;
  min-height: 40px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: color-mix(in oklab, white 55%, var(--paper));
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  transition: all 0.15s var(--ease);
}

.checks input:checked + span {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
  font-weight: 600;
}

.checks input:focus-visible + span {
  outline: 2px solid var(--lantern);
  outline-offset: 2px;
}

/* ---------- loaded barbell diagram ------------------------------------- */

.bar-view {
  margin-top: var(--s5);
  padding: var(--s4) var(--s3);
  border: 1px dashed var(--rule);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--paper-2) 45%, transparent);
  overflow-x: auto;
}

.bar-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 8.5rem;
}

.sleeve {
  display: flex;
  align-items: center;
  gap: 2px;
  min-height: 8.5rem;
}

.sleeve.is-right {
  flex-direction: row-reverse;
}

.bar-mid {
  flex: none;
  width: clamp(2rem, 12vw, 5rem);
  height: 0.6rem;
  border-radius: 99px;
  background: var(--ink-3);
}

.collar {
  flex: none;
  width: 0.5rem;
  height: 1.6rem;
  border-radius: 2px;
  background: var(--ink-2);
}

.plate {
  flex: none;
  width: 1.05rem;
  border-radius: 3px;
  border: 1px solid color-mix(in oklab, var(--ink) 35%, transparent);
  display: grid;
  place-items: center;
  font-size: 0.62rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #fff;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  letter-spacing: 0.02em;
}

/* Plate colours follow the IWF competition convention where it exists, warmed
   slightly to sit on cream paper. Height encodes diameter, so the stack reads
   like a real bar at a glance. */
.plate-25 {
  height: 8.5rem;
  background: #b1503a;
}
.plate-20 {
  height: 8rem;
  background: #2f5d8a;
}
.plate-15 {
  height: 7rem;
  background: #c98a17;
}
.plate-10 {
  height: 6rem;
  background: #4a7c48;
}
.plate-5 {
  height: 4.6rem;
  background: #6f6357;
  color: #fff;
}
.plate-2-5 {
  height: 3.6rem;
  background: #2e211a;
}
.plate-1-25 {
  height: 2.8rem;
  background: #8a7666;
}
.plate-other {
  height: 3.2rem;
  background: var(--ink-2);
}

.bar-caption {
  margin-top: var(--s3);
  text-align: center;
  font-size: var(--step--1);
  color: var(--ink-3);
}

/* ---------- data rows (rep-max, warm-up, per-side list) --------------- */

.rows {
  width: 100%;
  margin-top: var(--s4);
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.rows caption {
  text-align: left;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: var(--s2);
}

.rows th,
.rows td {
  text-align: left;
  padding: 0.45em 0.5em 0.45em 0;
  border-bottom: 1px dotted var(--rule);
  font-size: var(--step--1);
}

.rows thead th {
  font-weight: 500;
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule);
}

.rows td:last-child,
.rows th:last-child {
  text-align: right;
  padding-right: 0;
}

.rows .num {
  font-weight: 600;
  color: var(--ink);
}

.rows tbody tr:hover {
  background: color-mix(in oklab, var(--paper-2) 55%, transparent);
}

/* ---------- band scale (waist ratio, body fat) ------------------------- */

.scale {
  margin-top: var(--s5);
}

.scale-track {
  display: flex;
  height: 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 99px;
  overflow: hidden;
  background: var(--paper-2);
}

.scale-track span {
  display: block;
  flex: 1;
}

.scale-track .s-good {
  background: color-mix(in oklab, var(--leaf) 70%, white);
}
.scale-track .s-neutral {
  background: color-mix(in oklab, var(--ink-3) 45%, white);
}
.scale-track .s-warn {
  background: color-mix(in oklab, var(--amber) 70%, white);
}
.scale-track .s-bad {
  background: color-mix(in oklab, var(--lantern) 60%, white);
}

.scale-marks {
  display: flex;
  margin-top: var(--s1);
  font-size: 0.7rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.scale-marks span {
  flex: 1;
  text-align: center;
}

.scale-here {
  position: relative;
  height: 1.1rem;
  margin-bottom: var(--s1);
}

.scale-here b {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--lantern-ink);
  white-space: nowrap;
  transition: left 0.4s var(--ease);
}

.scale-here b::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -0.35rem;
  width: 1px;
  height: 0.35rem;
  background: var(--lantern);
}

/* ---------- motion ------------------------------------------------------ */

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.sheet:not([hidden]) {
  animation: rise 0.45s var(--ease) both;
}

.sheet:not([hidden]) .headline-kcal {
  animation: rise 0.5s var(--ease) 0.08s both;
}

.sheet:not([hidden]) .macros {
  animation: rise 0.5s var(--ease) 0.16s both;
}

.sheet:not([hidden]) .ledger {
  animation: rise 0.5s var(--ease) 0.24s both;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- print: it is a worksheet, let people print it -------------- */

@media print {
  body {
    background: white;
  }
  .masthead,
  .masthead-nav,
  .tabs,
  .btn,
  .site-foot,
  .hero-meta,
  .tool-index {
    display: none !important;
  }
  .sheet {
    box-shadow: none;
    border-color: #999;
  }
  .bar-view {
    border-color: #999;
    background: none;
  }
}

/* ---------- guide articles ---------------------------------------------- */
/* Long-form "cách làm" pages. Same paper, narrower measure, generous rhythm:
   these are read start to finish, unlike the tool pages which are scanned. */

.article {
  max-width: var(--measure);
  padding-block: var(--s6) var(--s8);
}

.crumbs {
  font-size: var(--step--1);
  color: var(--ink-3);
  margin-bottom: var(--s4);
}

.crumbs a {
  color: var(--ink-3);
}

.crumbs a:hover {
  color: var(--lantern-ink);
}

.article > h1 {
  font-size: var(--step-3);
}

.article-meta {
  margin-top: var(--s3);
  font-size: var(--step--1);
  color: var(--ink-3);
}

.article-lede {
  margin-top: var(--s4);
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--ink-2);
}

.article h2 {
  font-size: var(--step-2);
  margin-top: var(--s7);
  padding-top: var(--s4);
  border-top: 1px solid var(--rule);
}

.article h3 {
  font-size: var(--step-1);
  margin-top: var(--s5);
}

.article p,
.article ul,
.article ol {
  margin-top: var(--s4);
  line-height: 1.65;
}

.article ul,
.article ol {
  padding-left: var(--s5);
  display: grid;
  gap: var(--s2);
}

.article li {
  padding-left: var(--s1);
}

.article strong {
  font-weight: 600;
}

/* Numbered how-to steps: the number sits in the margin, like a worksheet. */
.steps {
  margin-top: var(--s5);
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s5);
  counter-reset: step;
}

.steps > li {
  counter-increment: step;
  position: relative;
  padding-left: var(--s7);
}

.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -0.1em;
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-0);
  color: var(--paper);
  background: var(--lantern);
  border-radius: 50%;
}

.steps > li > strong {
  display: block;
  margin-bottom: var(--s1);
}

/* Pull-aside for the one thing worth remembering. */
.keypoint {
  margin-top: var(--s5);
  padding: var(--s4) var(--s5);
  border-left: 3px solid var(--lantern);
  background: color-mix(in oklab, var(--paper) 88%, var(--lantern));
}

.keypoint p {
  margin-top: 0;
}

.keypoint p + p {
  margin-top: var(--s3);
}

/* Inline call-to-action back to the matching tool. */
.tool-cta {
  margin-top: var(--s6);
  padding: var(--s5);
  border: 1px solid var(--rule);
  background: color-mix(in oklab, var(--paper) 85%, white);
  display: grid;
  gap: var(--s3);
  justify-items: start;
}

.tool-cta h2,
.tool-cta h3 {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: var(--step-1);
}

.tool-cta p {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--step--1);
}

.article .faq {
  margin-top: var(--s5);
}

.article table {
  margin-top: var(--s5);
}

@media print {
  .crumbs,
  .tool-cta {
    display: none;
  }
}

/* ---------- progression schedule (lịch tăng tạ) -------------------------- */
/* A printable sheet read at the gym, one small table per week. Weeks are
   separated rather than run together because "which row am I on" matters more
   than compactness when you are holding a phone with chalk on your hands. */

.sheet-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s5);
}
.sheet-actions .share-btn {
  margin-top: 0;
}

.week-list {
  margin-top: var(--s5);
  display: grid;
  gap: var(--s5);
}

.week-title {
  /* h3 already carries Fraunces from the base rules. */
  font-size: var(--step-0);
  font-weight: 700;
  letter-spacing: 0.02em;
  margin-bottom: var(--s2);
  padding-bottom: var(--s1);
  border-bottom: 1px solid var(--rule);
}

.week .rows {
  margin-top: 0;
}

/* Repeated weight is a real answer, not a bug — but it has to say so.
   --ink-3 measured 4.23:1 here, under the 4.5:1 AA floor for text this small.
   Filled rather than outlined: a hairline rule on the near-white sheet read as
   ghost text instead of a stamp. */
.tag-same {
  display: inline-block;
  font-family: 'Be Vietnam Pro', ui-sans-serif, sans-serif;
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.1em 0.35em;
  vertical-align: middle;
  white-space: nowrap;
}

/* The dots must never be the reason a row overflows: they are decorative and
   the text beside them carries the same information. Letting the cell wrap is
   a better guard than hiding them below a viewport width, which broke the
   phone/desktop consistency for no real gain. */
.plates-cell {
  white-space: normal;
}

.plates-cell .plate-dot:first-of-type {
  margin-left: 0;
}

/* Small colour dots echo the plate diagram on /lap-ta, so a lifter who has
   used that page recognises the loading at a glance. Decorative only: the
   text beside them carries the same information. */
.plate-dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.85rem;
  border-radius: 2px;
  border: 1px solid color-mix(in oklab, var(--ink) 30%, transparent);
  margin-right: 0.15rem;
  vertical-align: middle;
}

.plates-text {
  margin-left: var(--s2);
  font-variant-numeric: tabular-nums;
  font-size: var(--step--1);
  color: var(--ink-2);
  white-space: nowrap;
}

@media print {
  .sheet-actions,
  .week-list .plate-dot {
    display: none !important;
  }
  .week {
    break-inside: avoid;
  }
  .week-title {
    border-bottom-color: #999;
  }
}
