/*
 * LOCKEDTFIN Experience Layer (v5)
 *
 * The final cascade layer for the customer runtime. Earlier stylesheets own
 * structure, route geometry and the golden-composition grammar; this layer
 * owns finish: one calm type system, controls that never wrap or collide,
 * quieter truth labels, and the Mission Control / Workout / Nutrition /
 * Progress / Coach components. It never changes media truth: demo chips stay
 * present and live empty states keep their honest geometry.
 *
 * Sections
 *   1  Tokens            8  Mission Control (Today)
 *   2  Type              9  Workout
 *   3  Buttons           10 Nutrition
 *   4  Action rows       11 Check-in
 *   5  Truth chips       12 Progress
 *   6  Acquisition       13 Coach
 *   7  Navigation        14 Forms, focus, motion
 */

/* 1. Tokens ---------------------------------------------------------------- */
:root {
  --x-ease: cubic-bezier(.2, .8, .2, 1);
  --x-ease-spring: cubic-bezier(.34, 1.4, .64, 1);
  --x-fast: 160ms;
  --x-med: 280ms;
  --x-slow: 620ms;
  --x-hair: rgba(255, 214, 198, .12);
  --x-hair-strong: rgba(255, 214, 198, .22);
  --x-ink: var(--text);
  --x-ink-2: #cdbfb6;
  --x-ink-3: #978a83;
  --x-ring-track: rgba(255, 220, 205, .09);
  --x-eyebrow: color-mix(in srgb, var(--accent) 78%, #ffd9c9);
}

html[data-presentation="masculine"] {
  --x-hair: rgba(255, 190, 170, .1);
  --x-hair-strong: rgba(255, 190, 170, .2);
  --x-eyebrow: color-mix(in srgb, var(--accent) 70%, #ffc7b8);
}

@property --x-ring-value { syntax: "<number>"; inherits: true; initial-value: 0; }

/* Editorial serif fallback. Apple devices keep Iowan Old Style (matched first,
 * so this file is never fetched there); Android and Windows get Newsreader
 * (SIL OFL 1.1, assets/fonts/Newsreader-OFL.txt) instead of Times New Roman.
 * `optional` means a slow first load keeps the fallback rather than shifting
 * layout; later visits use the cached face. */
@font-face {
  font-family: "LOCKEDTFIN Serif";
  font-style: normal;
  font-weight: 200 800;
  font-display: optional;
  src: url("/lockedtfin/assets/fonts/newsreader-latin-wght.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root { --serif: "Iowan Old Style", "LOCKEDTFIN Serif", "Bodoni 72", Georgia, serif; }

/* 2. Type: one editorial voice, one functional voice ----------------------- */
.app-shell .eyebrow,
.public-shell .eyebrow,
.mode-gate .eyebrow,
.more-sheet .eyebrow {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--x-eyebrow);
}

.app-shell h1, .public-shell h1, .app-shell h2, .public-shell h2 { text-wrap: balance; }
.app-shell p, .public-shell p { text-wrap: pretty; }

.app-shell .metric-value,
.app-shell .gm-metric-band b,
.app-shell .progress-metrics b { font-variant-numeric: tabular-nums; }

.app-shell .metric-card { min-height: 0; }
.app-shell .metric-label { font-size: var(--label-fs); letter-spacing: var(--label-ls); font-weight: var(--label-fw); }
.app-shell .metric-value { margin-top: 12px; font-size: 30px; font-weight: 760; letter-spacing: -.035em; }

.app-shell .glass-card::before,
.public-shell .glass-card::before { opacity: .45; }

/* 3. Buttons: one icon, one line, one weight ------------------------------- */
.app-shell .button,
.public-shell .button,
.mode-gate .button,
.more-sheet .button {
  gap: 8px;
  font-weight: 720;
  letter-spacing: -.005em;
  white-space: nowrap;
  transition:
    transform var(--x-fast) var(--x-ease),
    box-shadow var(--x-fast) var(--x-ease),
    background-color var(--x-fast) var(--x-ease),
    border-color var(--x-fast) var(--x-ease),
    opacity var(--x-fast) var(--x-ease);
}

.button .icon { width: var(--icon-md); height: var(--icon-md); }

/* The inline SVG already carries the button's meaning. The decorative sparkle
 * pseudo-glyph doubled every primary icon and forced labels to wrap. */
.button--primary::after { content: none; display: none; }

.button--secondary { background: rgba(255, 236, 226, .055); border-color: var(--x-hair-strong); }
.app-shell .button--ghost, .public-shell .button--ghost { color: var(--x-ink-2); }
.app-shell .button--ghost:hover, .public-shell .button--ghost:hover { color: var(--x-ink); }
.button:disabled, .button[aria-disabled="true"] { opacity: .5; filter: saturate(.55); }

@media (max-width: 359px) {
  .app-shell .button, .public-shell .button { gap: 7px; }
  .app-shell .button .icon, .public-shell .button .icon { width: var(--icon-sm); height: var(--icon-sm); }
}

/* 4. Action rows: wrap into rows before any label can clip ---------------- */
/* `fit-content` resolves to min(max-content, available width): each button
 * holds its whole label, wraps to a new row first, and never exceeds the row.
 * !important is deliberate: older route rules zero this to force squeezing. */
.app-shell .action-row, .public-shell .action-row { flex-wrap: wrap; }
.app-shell .action-row > .button,
.public-shell .action-row > .button,
.context-action-tray__actions > .button {
  min-width: fit-content !important;
  max-width: 100%;
}

/* wrap-reverse keeps the primary commitment on the top row when a narrow
 * phone cannot fit both tray actions on one line. */
.context-action-tray__actions { flex-wrap: wrap-reverse; justify-content: flex-end; min-width: 0; }
.context-action-tray__actions .button { flex: 1 1 auto; }

@media (max-width: 760px) {
  .context-action-tray__actions { gap: 7px; }
  .context-action-tray__actions .button--primary { flex: 10 1 auto; }

  /* The tray wraps to two rows (119px) when the labels are long, as on
   * Norwegian Choose; 112px left the legal footer 13px under it at the end
   * of the scroll. */
  .public-shell:has([data-gm-concept="choose"]) .public-scroll,
  .public-shell:has([data-gm-concept="refine"]) .public-scroll,
  .public-shell:has([data-gm-concept="reveal"]) .public-scroll,
  .public-shell:has([data-gm-concept="paywall"]) .public-scroll,
  .public-shell:has([data-gm-concept="lock-in"]) .public-scroll,
  .public-shell[data-gm-concept="lock-in"] .public-scroll {
    padding-bottom: calc(150px + env(safe-area-inset-bottom));
  }

  /* Capture keeps its commitment in flow so it never covers the photo
   * source choices directly above it. */
  .public-shell [data-gm-concept="capture"] .context-action-tray { position: static; }

  /* Mission sheets: the primary grows, the secondary stays compact, and the
   * row stacks on the narrowest phones instead of wrapping a label. */
  .app-shell[data-gm-concept] .mission-card .action-row { display: flex; flex-wrap: wrap; gap: 8px; grid-template-columns: none; }
  .app-shell[data-gm-concept] .mission-card .action-row > .button {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    white-space: nowrap;
    line-height: 1;
  }
  .app-shell[data-gm-concept] .mission-card .action-row > .button--primary { flex-grow: 3; }
  .app-shell[data-gm-concept] .mission-card .action-row > .button--ghost { flex-grow: 0; min-height: var(--control-h-sm); padding-inline: var(--space-2); font-size: var(--control-fs-sm); gap: var(--space-1); }
  .app-shell[data-gm-concept] .mission-card .action-row > .button--ghost .icon { width: var(--icon-sm); height: var(--icon-sm); }
}

.roadmap-actions { margin-top: 4px; }
/* A tray that sits inside a card and stays in flow is the card's footer: a
   hairline divider, not a second floating container nested in the card. The
   phone acquisition trays that float over the page keep their tray chrome. */
@media (min-width: 761px) {
  .glass-card .context-action-tray { padding: var(--space-4) 0 0; border: 0; border-top: 1px solid var(--gm-hairline); border-radius: 0; background: none; box-shadow: none; }
}
@media (max-width: 760px) {
  .public-shell [data-gm-concept="paywall"] .glass-card .context-action-tray { padding: var(--space-4) 0 0; border: 0; border-top: 1px solid var(--gm-hairline); border-radius: 0; background: none; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* 5. Truth chips: present on every demo scene, but quiet ------------------ */
.demo-media-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px 5px 8px;
  border: 1px solid rgba(255, 232, 220, .2);
  border-radius: 999px;
  background: rgba(10, 7, 6, .62);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: #ffe6da;
  font: 700 10px/1 var(--sans);
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.demo-media-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--warn);
  box-shadow: 0 0 10px color-mix(in srgb, var(--warn) 70%, transparent);
}

/* One chip explains an entire triptych; the other panes keep a caption. */
.twin-grid > .glass-card:not(:first-child) .demo-media-badge { display: none; }
.twin-card .demo-media-badge { max-width: calc(100% - 14px); padding: 4px 7px; font-size: 9px; letter-spacing: .05em; gap: 5px; }
.twin-card .demo-media-badge::before { width: 5px; height: 5px; }

@media (max-width: 760px) {
  .app-screen--app-progress .twin-card .demo-media-badge { top: 8px; left: 8px; line-height: 1.15; }
  .app-screen--app-progress .twin-caption span { text-transform: none; letter-spacing: .01em; font-size: 11px; font-weight: 650; color: var(--x-ink-3); }
}

/* 6. Acquisition ------------------------------------------------------------ */
.flow-steps {
  position: absolute;
  z-index: 21;
  top: calc(72px + env(safe-area-inset-top));
  left: 0;
  right: 0;
  display: flex;
  gap: 6px;
  margin: 0;
  padding: 10px max(24px, env(safe-area-inset-left)) 0;
  pointer-events: none;
}

.flow-steps > li {
  flex: 1 1 0;
  min-width: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--x-ink-3);
  font: 700 10px/1.1 var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.flow-steps > li::before {
  content: "";
  display: block;
  height: 3px;
  border-radius: 3px;
  background: rgba(255, 230, 220, .1);
  transition: background var(--x-med) var(--x-ease);
}

.flow-steps > li[data-state="done"] { color: var(--x-ink-2); }
.flow-steps > li[data-state="done"]::before { background: color-mix(in srgb, var(--accent) 62%, transparent); }
.flow-steps > li[data-state="current"] { color: var(--x-ink); }
.flow-steps > li[data-state="current"]::before {
  background: linear-gradient(90deg, var(--accent), var(--warm));
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 60%, transparent);
}

.public-shell:has(.flow-steps) .flow-progress { display: none; }
.public-shell:has(.flow-steps) .public-surface { top: calc(104px + env(safe-area-inset-top)); }

@media (max-width: 760px) {
  .flow-steps { top: calc(58px + env(safe-area-inset-top)); padding-inline: 16px; gap: 4px; }
  .flow-steps > li { font-size: 9.5px; letter-spacing: .06em; }
  .public-shell:has(.flow-steps) .public-surface { top: calc(88px + env(safe-area-inset-top)); }
}

@media (display-mode: standalone) and (max-width: 760px) {
  .flow-steps { top: calc(60px + env(safe-area-inset-top)); }
  .public-shell:has(.flow-steps) .public-surface { top: calc(90px + env(safe-area-inset-top)); }
}

/* Hero: the loop callout sits in the clear upper edge of the stage so it can
 * never cover the Today / Future labels. */
.public-screen--feminine .stage-callout,
.public-screen--masculine .stage-callout {
  top: 16px;
  right: 16px;
  bottom: auto;
  left: auto;
  padding: 9px 12px;
  border-radius: var(--radius-inner);
  background: rgba(12, 8, 7, .7);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.public-screen--feminine .stage-callout span,
.public-screen--masculine .stage-callout span { font-size: var(--label-fs); letter-spacing: var(--label-ls); }
.public-screen--feminine .stage-callout b,
.public-screen--masculine .stage-callout b { font-size: 12px; font-weight: 700; }

.landing-actions .button--ghost { color: var(--x-ink-2); }

@media (max-width: 760px) {
  .public-shell [data-gm-concept="hero"] .stage-callout,
  .public-screen--feminine .stage-callout,
  .public-screen--masculine .stage-callout { top: 12px; right: 12px; bottom: auto; padding: 8px 10px; }
  .landing-actions { gap: 4px; }
  .trust-row { row-gap: 8px; }
}

/* Choose: three visual tiles instead of a clipped horizontal pager. */
@media (max-width: 760px) {
  .public-shell [data-gm-concept="choose"] .variant-list {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    overflow: visible;
    padding: 0;
    gap: 8px;
  }
  .public-shell [data-gm-concept="choose"] .variant {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 7px;
    min-height: 0;
    padding: 6px 6px 10px;
    text-align: left;
  }
  .public-shell [data-gm-concept="choose"] .variant-thumb { width: 100%; height: auto; aspect-ratio: 4 / 5; border-radius: max(4px, calc(var(--radius-inner) - 6px)); }
  .public-shell [data-gm-concept="choose"] .variant-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center 25%; }
  .public-shell [data-gm-concept="choose"] .variant > div:not(.variant-thumb) { padding-inline: 4px; min-width: 0; }
  .public-shell [data-gm-concept="choose"] .variant b { display: block; font-size: 13px; line-height: 1.15; overflow-wrap: anywhere; hyphens: auto; }
  .public-shell [data-gm-concept="choose"] .variant small { display: block; margin-top: 3px; font-size: 11px; line-height: 1.2; color: var(--x-ink-2); }
  .public-shell [data-gm-concept="choose"] .variant > .icon {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 26px;
    height: 26px;
    padding: 5px;
    border-radius: 50%;
    background: rgba(10, 7, 6, .7);
    opacity: 0;
    transform: scale(.7);
    transition: opacity var(--x-fast) var(--x-ease), transform var(--x-med) var(--x-ease-spring);
  }
  .public-shell [data-gm-concept="choose"] .variant.active > .icon { opacity: 1; transform: none; background: var(--accent); color: #fff; }
}

/* Plans: name over price, two equal choices at every width. */
.plan-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.plan-grid .choice-pill { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 3px; min-height: 60px; padding: 10px 16px; border-radius: var(--radius-inner); text-align: left; }
.plan-grid .choice-pill b { display: block; font-size: 15px; }
.plan-grid .choice-pill small { display: block; color: var(--x-ink-2); font-size: 12px; font-variant-numeric: tabular-nums; }
.plan-grid .choice-pill.active small { color: var(--x-ink); }

/* Lock-in: the two commitments read as a compact checklist at every width. */
.lock-what-you-lock { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-block: 4px; }
.lock-what-you-lock span { display: flex; align-items: center; gap: 8px; color: var(--x-ink); font-size: 13px; font-weight: 650; line-height: 1.25; }
.lock-what-you-lock .icon { width: var(--icon-sm); height: var(--icon-sm); flex: none; color: var(--accent); }

/* 7. Navigation ------------------------------------------------------------ */
.side-nav__group-label {
  margin: 10px 12px 2px;
  color: var(--x-ink-3);
  font: 700 10px/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
}

@media (min-width: 761px) {
  .side-nav { gap: 6px; padding-top: max(22px, env(safe-area-inset-top)); }
  .side-nav a { min-height: 38px; font-size: 13px; font-weight: 650; color: var(--x-ink-2); }
  .side-nav a .icon { width: 17px; height: 17px; opacity: .85; }
  .side-nav a.active { color: var(--x-ink); }
  .side-nav a.active .icon { color: var(--accent); opacity: 1; }
  .side-nav__lower { margin-top: 6px; gap: 2px; }
}

.more-sheet nav { display: block; }
.more-sheet__group { display: grid; gap: 6px; }
.more-sheet__group + .more-sheet__group { margin-top: 14px; }
.more-sheet__group > span { padding-inline: 4px; color: var(--x-ink-3); font: 700 10px/1 var(--sans); letter-spacing: .14em; text-transform: uppercase; }
.more-sheet__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.more-sheet nav a .icon { width: 18px; color: var(--accent); }

/* 8. Mission Control (Today) ---------------------------------------------- */
.x-ring {
  --x-ring-size: 64px;
  --x-ring-value: 0;
  position: relative;
  display: grid;
  place-items: center;
  width: var(--x-ring-size);
  height: var(--x-ring-size);
  flex: none;
  border-radius: 50%;
  background:
    radial-gradient(closest-side, var(--x-ring-hole, rgba(20, 12, 11, .96)) calc(100% - 6px), transparent calc(100% - 5px)),
    conic-gradient(from -90deg, var(--accent) calc(var(--x-ring-value) * 1%), var(--x-ring-track) 0);
  transition: --x-ring-value var(--x-slow) var(--x-ease);
}
.x-ring > b { font: 760 15px/1 var(--sans); letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--x-ink); }
.x-ring > b small { margin-left: 1px; font-size: 10px; font-weight: 700; color: var(--x-ink-3); }

.mission-progress { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.mission-progress__copy { display: grid; gap: 3px; min-width: 0; }
.mission-progress__copy b { font-size: 13px; font-weight: 720; color: var(--x-ink); }
.mission-progress__copy small { font-size: 12px; color: var(--x-ink-3); }

/* The mission sheet overlaps the Future scene by design; keep it opaque so
 * the scene's lower-third caption never bleeds through the commitment copy. */
.app-shell[data-gm-concept="home"] .hero-grid--media-first > .glass-card:first-child { background: linear-gradient(160deg, rgb(40, 25, 22), rgb(14, 9, 8)); }
html[data-presentation="masculine"] .app-shell[data-gm-concept="home"] .hero-grid--media-first > .glass-card:first-child { background: linear-gradient(160deg, rgb(32, 14, 13), rgb(10, 6, 6)); }

@media (max-width: 760px) {
  /* Progress reads as one quiet line inside the mission sheet. */
  .app-shell[data-gm-concept="home"] .mission-progress { gap: 9px; margin-top: 8px; }
  .app-shell[data-gm-concept="home"] .x-ring { --x-ring-size: 30px; --x-ring-hole: rgb(30, 19, 17); }
  .app-shell[data-gm-concept="home"] .x-ring > b { display: none; }
  .app-shell[data-gm-concept="home"] .mission-progress__copy { display: flex; align-items: baseline; gap: 6px; }
  .app-shell[data-gm-concept="home"] .mission-progress__copy small::before { content: "· "; }
}

@media (max-width: 359px) {
  .app-shell[data-gm-concept="home"] .app-header h1 { font-size: 38px; }
  .app-shell[data-gm-concept="home"] .mission-card h2 { font-size: 29px; }
  .app-shell[data-gm-concept="home"] .mission-card > p,
  .app-shell[data-gm-concept="program-ready"] .mission-card > p { display: none; }
}

/* Short phone viewports (Safari with toolbars ≈ 660px): the mission action
 * must stay above the dock even when the Future scene is present. */
@media (max-width: 760px) and (max-height: 760px) {
  .app-shell[data-gm-concept="home"] .app-header h1 { font-size: 38px; }
  .app-shell[data-gm-concept="home"] .app-header .button { min-height: 44px; }
  .app-shell[data-gm-concept="home"] .journey-rail { margin-block: 0 8px; padding-block: 4px; }
  .app-shell[data-gm-concept="home"] .journey-step__icon { width: 26px; height: 26px; }
  .app-shell[data-gm-concept="home"] .journey-step small { display: none; }
  .app-shell[data-gm-concept="home"] .hero-grid--media-first > .glass-card:last-child:not(.future-card--empty),
  .app-shell[data-gm-concept="home"] .hero-grid--media-first > .glass-card:last-child:not(.future-card--empty) .future-mini { height: 264px; min-height: 264px; }
  .app-shell[data-gm-concept="home"] .hero-grid--media-first > .glass-card:first-child { margin-top: -106px; }
  .app-shell[data-gm-concept="home"] .mission-card > p { display: none; }
  .app-shell[data-gm-concept="home"] .mission-card h2 { font-size: 30px; }
  .app-shell[data-gm-concept="home"] .mission-progress { margin-top: 4px; }
  .app-shell[data-gm-concept="home"] .mission-card .action-row { margin-top: 10px; }
}

/* Program Ready: the caption is a compact chip, not a bar across the face. */
.app-shell[data-gm-concept="program-ready"] .future-mini .demo-media-badge { top: 12px; left: 12px; }
.app-shell[data-gm-concept="program-ready"] .future-mini-overlay:has(> b:only-child) {
  top: 44px;
  right: auto;
  bottom: auto;
  left: 12px;
  width: auto;
  min-height: 0;
  padding: 6px 12px;
  border-radius: 999px;
}
.app-shell[data-gm-concept="program-ready"] .future-mini-overlay:has(> b:only-child) b { font: 650 13px/1.2 var(--sans); letter-spacing: 0; }

@media (max-width: 760px) {
  .app-shell[data-gm-concept="change-future"] .change-future-stage { min-height: 340px; max-height: 360px; }
}

/* 9. Workout ---------------------------------------------------------------- */
.rest-clock {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--accent-strong);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--x-ink);
  font: 720 15px/1 var(--sans);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.rest-clock::before { content: "Rest"; color: var(--x-ink-2); font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
html[lang="nb-NO"] .rest-clock::before { content: "Pause"; }
/* The timer appears only while it is counting; Start Rest is the idle cue. */
.rest-clock[data-running="false"] { display: none; }

.session-progress { grid-column: 1 / -1; width: 100%; display: flex; align-items: center; gap: 12px; }
.session-progress__bar { flex: 1; min-width: 120px; display: flex; gap: 4px; }
.session-progress__bar > i { flex: 1; height: 4px; border-radius: 4px; background: rgba(255, 230, 220, .1); }
.session-progress__bar > i[data-state="done"] { background: color-mix(in srgb, var(--accent) 70%, transparent); }
.session-progress__bar > i[data-state="current"] { background: linear-gradient(90deg, var(--accent), var(--warm)); }
.session-progress > span { color: var(--x-ink-2); font: 700 12px/1 var(--sans); white-space: nowrap; font-variant-numeric: tabular-nums; }

.set-check.done { background: var(--accent); border-color: transparent; color: #fff; animation: x-pop var(--x-med) var(--x-ease-spring); }
.set-row:has(.set-check.done) > span { color: var(--x-ink-3); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--accent) 60%, transparent); }
@keyframes x-pop { 0% { transform: scale(.82); } 100% { transform: none; } }

.workout-summary-card { grid-column: 1 / -1; }
.workout-summary { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 16px; align-items: center; padding: var(--card-pad); }
.workout-summary > .action-row { grid-column: 1 / -1; margin-top: 8px; }
.workout-summary h2 { margin: 4px 0 2px; font: 400 var(--type-h2)/1.02 var(--serif); letter-spacing: -.025em; }
.workout-summary p { margin: 0; }
.workout-summary__seal {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 88%, white), var(--accent2));
  color: #fff;
  box-shadow: 0 0 0 8px var(--accent-soft), 0 12px 36px var(--accent-soft);
  animation: x-pop var(--x-slow) var(--x-ease-spring);
}
.workout-summary__seal .icon { width: 26px; height: 26px; }

@media (max-width: 760px) {
  /* Focused Workout yields the dock only when validated form media earns the
   * poster layout; otherwise destinations stay one tap away. */
  .app-screen--app-workout .bottom-nav { display: grid; }
  .app-screen--app-workout:has(.exercise-media-slot img) .bottom-nav { display: none; }
  .app-screen--app-workout:has(.exercise-media-slot img) .session-progress { display: none; }
  .app-screen--app-workout .session-progress { margin-top: -4px; }

  /* Exercises are a chip stepper above the scene, never under the CTA. */
  .app-screen--app-workout .workout-layout .exercise-list,
  .app-screen--app-workout .workout-layout:has(.exercise-media-slot img) .exercise-list {
    order: -2;
    display: flex;
    flex-direction: row;
    gap: 6px;
    margin: 0 -2px;
    padding: 2px 2px 4px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .app-screen--app-workout .exercise-list::-webkit-scrollbar { display: none; }
  .app-screen--app-workout .exercise-row {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: auto;
    min-height: 44px;
    padding: 4px 14px 4px 5px;
    border-radius: 999px;
  }
  .app-screen--app-workout .exercise-row > div:not(.exercise-index) small { display: none; }
  .app-screen--app-workout .exercise-row b { font-size: 13px; white-space: nowrap; }
  .app-screen--app-workout .exercise-index { width: 34px; height: 34px; font-size: 12px; }
  .app-screen--app-workout .app-header { align-items: center; }
  .app-screen--app-workout .app-header h1 { font-size: 30px; }
}

/* 10. Nutrition: remaining-first macro rings ------------------------------- */
.macro-ring-card { padding: var(--card-pad-compact); }
.macro-ring-card .metric-label { justify-content: space-between; }
.macro-ring-body { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.macro-ring-body .x-ring { --x-ring-size: 58px; }
.macro-ring-copy { display: grid; gap: 3px; min-width: 0; }
.macro-ring-copy b { font: 760 22px/1 var(--sans); letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--x-ink); }
.macro-ring-copy small { color: var(--x-ink-3); font-size: 12px; white-space: nowrap; }
.macro-ring-card[data-over="true"] .x-ring {
  background:
    radial-gradient(closest-side, var(--x-ring-hole, rgba(20, 12, 11, .96)) calc(100% - 6px), transparent calc(100% - 5px)),
    conic-gradient(from -90deg, var(--warn) calc(var(--x-ring-value) * 1%), var(--x-ring-track) 0);
}
.meal-card-header > b small { margin-left: 3px; color: var(--x-ink-3); font-size: 12px; font-weight: 650; }

@media (max-width: 760px) {
  .macro-ring-body { gap: 10px; margin-top: 10px; }
  .macro-ring-body .x-ring { --x-ring-size: 50px; }
  .macro-ring-copy b { font-size: 19px; }
  .macro-ring-copy small:last-child { display: none; }
}

/* 11. Check-in: tappable energy scale -------------------------------------- */
.x-scale { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.x-scale button {
  min-height: 48px;
  border: 1px solid var(--x-hair-strong);
  border-radius: var(--radius-inner);
  background: rgba(255, 236, 226, .04);
  color: var(--x-ink-2);
  font: 720 15px/1 var(--sans);
  cursor: pointer;
  transition: background var(--x-fast), border-color var(--x-fast), color var(--x-fast), transform var(--x-fast);
}
.x-scale button[aria-pressed="true"] {
  border-color: transparent;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 88%, white), var(--accent2));
  color: #fff;
  box-shadow: 0 8px 24px var(--accent-soft);
}
.x-scale button:active { transform: scale(.96); }
.x-scale-hint { display: flex; justify-content: space-between; margin-top: 4px; color: var(--x-ink-3); font-size: 11px; }
.input--compact { max-width: 120px; margin-top: 8px; }

.checkin-stepper > span { white-space: nowrap; }
@media (max-width: 760px) {
  .checkin-stepper { gap: 6px; }
  .checkin-stepper > span { flex: 1 1 0; justify-content: center; padding-inline: 8px; min-width: 0; }
}

/* 12. Progress: measured trend --------------------------------------------- */
.x-trend { display: grid; gap: 10px; padding: var(--card-pad); }
.x-trend header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.x-trend header b { display: block; margin-top: 4px; font: 400 clamp(26px, 3vw, 34px)/1 var(--serif); letter-spacing: -.03em; color: var(--x-ink); }
.x-trend header small { color: var(--x-ink-3); font-size: 12px; }
.x-trend svg { width: 100%; height: 88px; overflow: visible; }
.x-trend .x-trend__line { fill: none; stroke: var(--accent); stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.x-trend .x-trend__area { fill: url(#x-trend-fill); }
.x-trend .x-trend__target { stroke: var(--x-hair-strong); stroke-dasharray: 4 5; vector-effect: non-scaling-stroke; }
.x-trend footer { display: flex; justify-content: space-between; gap: 8px; color: var(--x-ink-3); font-size: 11px; font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: no-preference) {
  .x-trend .x-trend__line { stroke-dasharray: 1200; stroke-dashoffset: 1200; animation: x-draw 1.1s var(--x-ease) .15s forwards; }
}
@keyframes x-draw { to { stroke-dashoffset: 0; } }

/* 13. Coach ------------------------------------------------------------------ */
.bubble { animation: x-bubble-in var(--x-med) var(--x-ease) both; }
.bubble.user { background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 80%, #fff 6%), var(--accent2)); border-color: transparent; color: #fff; }
.bubble.typing { display: inline-flex; align-items: center; gap: 5px; width: auto; padding-block: 14px; }
.bubble.typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--x-ink-2); animation: b 1.2s infinite ease-in-out; }
.bubble.typing i:nth-child(2) { animation-delay: .15s; }
.bubble.typing i:nth-child(3) { animation-delay: .3s; }
@keyframes x-bubble-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.coach-prompts button { transition: background var(--x-fast), border-color var(--x-fast); }
.coach-prompts button:hover { background: var(--accent-soft); border-color: var(--accent-strong); }

/* 14. Forms, focus, motion -------------------------------------------------- */
.app-shell .input, .app-shell .textarea, .app-shell .select,
.public-shell .input, .public-shell .textarea, .public-shell .select,
.mode-gate .input {
  transition: border-color var(--x-fast) var(--x-ease), box-shadow var(--x-fast) var(--x-ease), background var(--x-fast);
}

.app-shell .input:focus, .app-shell .textarea:focus, .app-shell .select:focus,
.public-shell .input:focus, .public-shell .textarea:focus, .public-shell .select:focus,
.mode-gate .input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}

.button:focus-visible, .choice-pill:focus-visible, .variant:focus-visible,
.bottom-nav a:focus-visible, .side-nav a:focus-visible, .x-scale button:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 80%, white);
  outline-offset: 3px;
}

/* Route changes move focus to the content landmark for screen readers; that
 * programmatic focus must not paint a 2px ring across the whole page. */
main[tabindex="-1"]:focus,
main[tabindex="-1"]:focus-visible,
.public-surface:focus-visible,
.app-surface:focus-visible { outline: none; }

.toast { border-radius: 16px; font-weight: 650; }

@media (prefers-reduced-motion: reduce) {
  .x-ring, .bubble, .set-check.done, .workout-summary__seal, .x-trend .x-trend__line {
    animation: none !important;
    transition: none !important;
    stroke-dashoffset: 0 !important;
  }
}

/* 15. Comparison slider ----------------------------------------------------- */
/* The comparison has always been draggable; the handle and cue make that
 * discoverable. Both stay hidden while either image is missing. */
.compare-card:not(.is-incomplete) .compare-divider { visibility: visible; }
.compare-knob {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(255, 236, 226, .5);
  border-radius: 50%;
  background: rgba(12, 8, 7, .62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .45), 0 0 0 6px color-mix(in srgb, var(--accent) 22%, transparent);
  transition: transform var(--x-med) var(--x-ease-spring), box-shadow var(--x-fast);
}
.compare-knob::before {
  content: "";
  width: 18px;
  height: 10px;
  background: #fff;
  clip-path: polygon(0 50%, 35% 0, 35% 100%, 0 50%, 100% 50%, 65% 0, 65% 100%, 100% 50%);
}
.compare-card:has(.compare-range:active) .compare-knob { transform: translate(-50%, -50%) scale(1.12); }
.compare-card:has(.compare-range:focus-visible) .compare-knob { box-shadow: 0 0 0 3px #fff, 0 0 0 7px var(--accent); }
.compare-hint {
  position: absolute;
  z-index: 5;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 11px;
  border-radius: 999px;
  background: rgba(12, 8, 7, .62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
  font: 650 11px/1 var(--sans);
  letter-spacing: .02em;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity var(--x-med) var(--x-ease);
}
.compare-card.is-incomplete .compare-hint,
.compare-card.is-explored .compare-hint { opacity: 0; }

/* 16. Empty measurements, utility layouts ---------------------------------- */
.app-shell .metric-value--empty { color: var(--x-ink-3); }
.app-shell .metric-value--empty small { display: block; margin: 6px 0 0; color: var(--x-ink-3); font-size: 12px; font-weight: 600; letter-spacing: 0; }

/* Preferences: the monogram is a circle at every width. */
.profile-avatar { aspect-ratio: 1; height: auto; align-self: start; }
@media (min-width: 761px) { .profile-avatar { width: 132px; } }

/* Future Mirror idle state: give the invitation room instead of clipping the
 * icon and footnote inside a fixed-height stage. */
@media (max-width: 760px) {
  .camera-stage:has(.camera-empty:not([hidden])) { min-height: 440px; }
  .camera-empty { padding: 58px 22px 24px; }
  .camera-empty .icon { width: 44px; height: 44px; }
  .camera-empty h2 { margin: 10px 0 6px; font-size: var(--type-h2); line-height: 1.02; }
  .camera-empty p { margin: 0 0 14px; font-size: 14px; line-height: 1.5; }
}

/* Change Future on desktop: the scene holds the left column; the decision
 * context and its actions stack in the right column. */
@media (min-width: 761px) {
  .app-shell[data-gm-concept="change-future"] .change-future-stage { grid-column: 1; grid-row: 2 / span 2; }
  .app-shell[data-gm-concept="change-future"] .member-screen > .glass-card { grid-column: 2; grid-row: 2; align-self: start; }
  .app-shell[data-gm-concept="change-future"] .member-screen > .context-action-tray { grid-column: 2; grid-row: 3; align-self: start; }
}

/* Desktop Workout: a compact exercise rail beside a generous active panel. */
@media (min-width: 1051px) {
  .app-screen--app-workout .workout-layout { grid-template-columns: minmax(220px, .62fr) minmax(0, 1.38fr); align-items: start; }
  .app-screen--app-workout .exercise-row { justify-items: start; text-align: left; min-height: 64px; }
  .app-screen--app-workout .exercise-row b { font-size: 15px; }
  .app-screen--app-workout .exercise-media-slot:has(img),
  .app-screen--app-workout .exercise-media-slot:has(img) img { height: 360px; min-height: 360px; }
}


/* 17. Review round 2 ---------------------------------------------------------- */
/* Pinned surfaces are solid enough that nothing reads through them. */
.bottom-nav { background: rgba(14, 10, 9, .96); backdrop-filter: blur(20px) saturate(120%); -webkit-backdrop-filter: blur(20px) saturate(120%); }
html[data-presentation="masculine"] .bottom-nav { background: rgba(12, 7, 7, .96); }
@media (max-width: 760px) {
  .public-shell .context-action-tray,
  .app-shell .context-action-tray {
    background: linear-gradient(125deg, rgba(40, 23, 20, .97), rgba(12, 8, 7, .98));
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
  }
  html[data-presentation="masculine"] .public-shell .context-action-tray,
  html[data-presentation="masculine"] .app-shell .context-action-tray { background: linear-gradient(125deg, rgba(34, 14, 13, .97), rgba(10, 6, 6, .98)); }
}

/* Choose: the drag cue sits under the handle, never on top of the truth chip. */
.compare-hint { top: calc(50% + 32px); }
.compare-card .demo-media-badge { flex-shrink: 0; }

/* Faces stay in frame: identity is the product promise. */
.app-shell[data-gm-concept="program-ready"] .future-mini img,
.app-shell[data-gm-concept="home"] .future-mini img,
.public-shell [data-gm-concept="refine"] .preview-tile img,
.public-shell [data-gm-concept="paywall"] .preview-tile img,
.public-shell [data-gm-concept="capture"] .capture-well img { object-position: center 14%; }
.app-shell[data-gm-concept="home"] .future-mini > img { width: 100%; height: 100%; object-fit: cover; }

/* Progress triptych chip: one compact line where it fits. */
.app-screen--app-progress .twin-card .demo-media-badge { white-space: nowrap; font-size: 8px; letter-spacing: .04em; padding: 4px 6px; }
.app-screen--app-progress .twin-card .demo-media-badge::before { display: none; }
@media (max-width: 359px) { .app-screen--app-progress .twin-card .demo-media-badge { white-space: normal; } }

/* Processing: the preview chip hugs its text instead of spanning the stage. */
.generation-demo-pair .demo-media-badge { left: 10px; right: auto; width: auto; }


/* Subtitles may use two lines on phones rather than truncating mid-thought. */
@media (max-width: 760px) {
  .app-shell[data-gm-concept] .app-header__subtitle,
  .app-screen--app-workout .app-header__subtitle,
  .app-screen--app-nutrition .app-header__subtitle,
  .app-screen--app-check-in .app-header__subtitle,
  .app-screen--app-progress .app-header__subtitle,
  .app-screen--app-history .app-header__subtitle,
  .app-screen--app-roadmap .app-header__subtitle,
  .app-screen--app-settings .app-header__subtitle,
  .app-screen--app-membership .app-header__subtitle,
  .app-screen--app-install .app-header__subtitle { -webkit-line-clamp: 2; line-clamp: 2; max-width: 36ch; }
}

/* Mirror: the camera glyph inside the CTA is a normal button icon. */
.camera-empty .button .icon { width: 18px; height: 18px; color: inherit; opacity: 1; }

/* Capture: the display title never touches its supporting line. */
.public-shell [data-gm-concept="capture"] .flow-screen h1 + .lead,
.public-shell [data-gm-concept="capture"] .lead { margin-top: 10px; }

/* Workout poster: the exercise card sits fully inside the scene, the scene
 * clears the first set row, and a validated-media caption moves to the
 * top-right (the demo chip already explains illustrative media). */
@media (max-width: 760px) {
  .app-screen--app-workout .exercise-panel:has(.exercise-media-slot img) > div:nth-of-type(1) { margin-top: -118px; margin-bottom: 14px; }
  .app-screen--app-workout .exercise-media-slot:has(img) figcaption { top: 12px; right: 12px; bottom: auto; left: auto; max-width: 55%; font-size: 10px; }
  .app-screen--app-workout .exercise-media-slot:has(.demo-media-badge) figcaption { display: none; }
  .app-screen--app-workout .app-header h1 { margin-left: 0; padding-left: 0; }
}

/* Desktop: images never take the whole screen. */
@media (min-width: 761px) {
  .app-shell[data-gm-concept="phase-complete"] .phase-demo-stage,
  .app-shell[data-gm-concept="phase-complete"] .gm-media-stage { max-height: min(60vh, 560px); }
}

/* Phase in progress: the same editorial card at every width. */
.app-shell[data-gm-concept="phase-complete"] .phase-in-progress { padding: var(--card-pad); }
.app-shell[data-gm-concept="phase-complete"] .phase-in-progress h2 { margin: 4px 0 8px; color: var(--gm-champagne, var(--x-ink)); font: 400 var(--type-h2)/1.02 var(--serif); letter-spacing: -.025em; }
.app-shell[data-gm-concept="phase-complete"] .phase-in-progress p { max-width: 60ch; margin: 0 0 16px; color: var(--muted); font-size: 14px; line-height: 1.5; }

/* 18. Real-data components ------------------------------------------------- */
.x-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--chip-h);
  padding: 0 var(--chip-pad);
  border: 1px solid var(--x-hair-strong);
  border-radius: var(--radius-pill);
  background: rgba(255, 236, 226, .05);
  color: var(--x-ink);
  font: var(--chip-fw) var(--chip-fs)/1 var(--sans);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--x-fast), border-color var(--x-fast), transform var(--x-fast);
}
.x-chip small { color: var(--x-ink-3); font-weight: 600; }
.x-chip:hover { background: var(--accent-soft); border-color: var(--accent-strong); }
.x-chip:active { transform: scale(.97); }
.x-chip:disabled { opacity: .5; }

/* Today's plan */
.today-plan { padding: var(--card-pad); }
.today-plan > header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.today-plan > header h2 { margin: 4px 0 0; font: 400 var(--type-h2)/1.02 var(--serif); letter-spacing: -.025em; }
.today-plan .x-ring { --x-ring-size: 48px; }
.today-plan .x-ring > b { font-size: 12px; }
.today-plan ul { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.today-plan__item { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 12px; min-height: 60px; padding: 8px 0; border-top: 1px solid var(--x-hair); }
.today-plan__icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: rgba(255, 236, 226, .06); color: var(--accent); }
.today-plan__icon .icon { width: var(--icon-sm); height: var(--icon-sm); }
.today-plan__item[data-done="true"] .today-plan__icon { background: var(--accent); color: #fff; }
.today-plan__copy { display: grid; gap: 2px; min-width: 0; }
.today-plan__copy b { font-size: 14px; font-weight: 700; color: var(--x-ink); }
.today-plan__copy small { font-size: 12px; color: var(--x-ink-3); }
.today-plan__item[data-done="true"] .today-plan__copy b { color: var(--x-ink-2); }
.today-plan__done { color: var(--x-ink-3); font: var(--label-fw) var(--label-fs)/1 var(--sans); letter-spacing: var(--label-ls); text-transform: uppercase; }
.today-plan .button--small { min-width: 72px; }

/* Recovery day and workout finish */
.recovery-day { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 16px; align-items: center; padding: var(--card-pad); }
.recovery-day > .action-row, .recovery-day > #workout-error { grid-column: 1 / -1; }
.recovery-day h2 { margin: 4px 0 6px; font: 400 var(--type-h2)/1.02 var(--serif); letter-spacing: -.025em; }
.recovery-day p { margin: 0; }
.recovery-day__seal { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); box-shadow: 0 0 0 8px rgba(255, 236, 226, .03); }
.recovery-day__seal .icon { width: 24px; height: 24px; }
.workout-finish { display: grid; gap: 14px; margin: 4px 0 0; padding: var(--card-pad-compact); border: 1px solid var(--accent-strong); border-radius: var(--radius-inner); background: var(--accent-soft); }
.workout-finish legend { padding: 0 6px; font: 400 var(--type-h3)/1.1 var(--serif); color: var(--x-ink); }
.x-scale--ten { grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 4px; }
.x-scale--ten button { min-height: 44px; font-size: 14px; }
.workout-summary__note { grid-column: 1 / -1; display: flex; gap: 8px; margin: 4px 0 0; padding: 10px 12px; border-radius: var(--radius-inner); background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--x-ink); font-size: 13px; line-height: 1.45; }
.workout-summary__note .icon { width: 16px; flex: none; color: var(--warn); }

/* Nutrition */
.water-quick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.water-quick > span { display: inline-flex; align-items: center; gap: 8px; margin-right: auto; color: var(--x-ink-2); font-size: 13px; }
.water-quick > span .icon { width: 16px; color: var(--accent); }
.macro-ring-card[data-met="true"] .x-ring { background:
    radial-gradient(closest-side, var(--x-ring-hole, rgba(20, 12, 11, .96)) calc(100% - 6px), transparent calc(100% - 5px)),
    conic-gradient(from -90deg, var(--good) calc(var(--x-ring-value) * 1%), var(--x-ring-track) 0); }
.meal-guidance { padding: var(--card-pad); }
.meal-guidance h3 { margin: 6px 0 8px; font: 400 var(--type-h3)/1.1 var(--serif); }
.meal-guidance p { margin: 0; line-height: 1.5; }
.recent-meals { display: grid; gap: 8px; }
.recent-meals > div { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.today-log { display: grid; gap: 0; margin: 4px 0 0; padding: 0; list-style: none; }
.today-log li { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px solid var(--x-hair); font-size: 13px; }
.today-log b { color: var(--x-ink-2); font-weight: 650; }

/* Lock In goal realism */
.goal-realism {
  --realism: 0;
  display: grid;
  grid-template-columns: 6px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 4px 0;
}
.goal-realism__meter { position: relative; align-self: stretch; width: 6px; min-height: 40px; border-radius: 6px; background: rgba(255, 230, 220, .1); overflow: hidden; }
.goal-realism__meter i { position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--realism) * 100%); border-radius: inherit; background: var(--good); transition: height var(--x-med) var(--x-ease), background var(--x-fast); }
.goal-realism b { display: block; font-size: 14px; color: var(--x-ink); }
.goal-realism small { display: block; margin-top: 3px; color: var(--x-ink-2); font-size: 12px; line-height: 1.4; }
.goal-realism[data-band="ambitious"] .goal-realism__meter i { background: var(--warn); }
.goal-realism[data-band="paced"] .goal-realism__meter i { background: var(--warn); height: 100%; }
.goal-realism[data-band="unsafe"] { padding: 12px 14px; border-radius: var(--radius-inner); background: color-mix(in srgb, var(--bad) 10%, transparent); }
.goal-realism[data-band="unsafe"] .goal-realism__meter i { background: var(--bad); height: 100%; }
.goal-realism.full { grid-column: 1 / -1; }
@media (max-width: 760px) { .goal-realism { grid-template-columns: 6px minmax(0, 1fr); } .goal-realism .button { grid-column: 2; justify-self: start; } }

/* 19. Trust & compliance components ---------------------------------------- */
/* AI label: visible on every generated Future Form, high contrast, never
 * dismissable. Sits top-right so it never collides with the demo chip. */
.ai-badge {
  position: absolute;
  z-index: 6;
  top: 12px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: 999px;
  background: rgba(8, 6, 5, .78);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
  font: 700 10px/1 var(--sans);
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
}
.ai-badge::before { content: "✦"; font-size: 9px; color: var(--accent); }
.ai-badge--mini { top: 6px; right: 6px; padding: 3px 6px; font-size: 9px; }
.ai-badge--mini::before { content: none; }
.variant-thumb { position: relative; }
.twin-card .ai-badge, .future-mini .ai-badge { top: 10px; right: 10px; }
.twin-card .ai-badge { max-width: calc(100% - 14px); font-size: 8px; padding: 4px 6px; letter-spacing: .04em; }
.twin-card .ai-badge::before { content: none; }
@media (max-width: 760px) { .app-screen--app-progress .twin-card .ai-badge { top: auto; bottom: 64px; right: 7px; white-space: normal; } }

/* Legal links */
.legal-links { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12px; }
.legal-links a { display: inline-flex; align-items: center; min-height: 32px; color: var(--x-ink-3); text-decoration: underline; text-decoration-color: rgba(255, 236, 226, .2); text-underline-offset: 3px; }
.legal-links a:hover { color: var(--x-ink); }
.legal-links--public { justify-content: center; margin: 28px auto 4px; max-width: 760px; }
.legal-links--sheet { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); }
.legal-links--settings { margin-top: 12px; }
.legal-links--rail { flex-direction: column; gap: 0; margin: 10px 12px 0; }
.legal-links--rail a { min-height: 26px; font-size: 11px; }

/* Consent capture */
.consent-block { display: grid; gap: 10px; margin: 0; padding: var(--card-pad-compact); border: 1px solid var(--x-hair-strong); border-radius: var(--radius-inner); background: rgba(255, 236, 226, .035); }
.consent-block legend { padding: 0 6px; color: var(--x-ink); font: 700 13px/1.2 var(--sans); }
.consent-check { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: start; color: var(--x-ink-2); font-size: 13px; line-height: 1.45; cursor: pointer; }
.consent-check input { width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--accent); }
.consent-check a { color: var(--x-ink); text-decoration: underline; text-underline-offset: 3px; }
/* Paywall pre-contract information (angrerettloven § 16) and in-app withdrawal. */
.checkout-terms { display: grid; gap: 10px; }
.checkout-terms[hidden] { display: none; }
.checkout-disclosure { margin: 0; color: var(--x-ink-2); font-size: 13px; line-height: 1.45; }
.checkout-disclosure a, .checkout-immediate a { color: var(--x-ink); text-decoration: underline; text-underline-offset: 3px; }
.checkout-immediate { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: start; color: var(--x-ink-2); font-size: 13px; line-height: 1.45; cursor: pointer; }
.checkout-immediate input { width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--accent); }
.membership-withdrawal { display: grid; gap: 8px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.membership-withdrawal p { margin: 0; }
/* The iOS container has no photo-library write permission; suppress the image save callout. */
html[data-platform="ios-native"] img { -webkit-touch-callout: none; }
.screening-question { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; padding: 10px 0; border-top: 1px solid var(--x-hair); }
.screening-question > span { flex: 1 1 100%; color: var(--x-ink); font-size: 13px; font-weight: 650; }
.screening-question label { display: inline-flex; align-items: center; gap: 6px; min-height: var(--chip-h); padding: 0 var(--chip-pad); border: 1px solid var(--x-hair-strong); border-radius: var(--radius-pill); font-size: var(--chip-fs); font-weight: var(--chip-fw); cursor: pointer; }
.screening-question label:has(input:checked) { border-color: var(--accent-strong); background: var(--accent-soft); color: var(--x-ink); }
.screening-question input { accent-color: var(--accent); }
.screening-referral { display: grid; gap: 8px; margin-top: 12px; padding: var(--card-pad-compact); border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); border-radius: var(--radius-inner); background: color-mix(in srgb, var(--warn) 10%, transparent); }
.screening-referral p { margin: 0; color: var(--x-ink-2); font-size: 13px; line-height: 1.5; }
.screening-referral .button { justify-self: start; }

/* Coach voice notice */
.voice-notice { display: grid; gap: 8px; margin: 10px 0; padding: var(--card-pad-compact); border: 1px solid var(--accent-strong); border-radius: var(--radius-inner); background: var(--accent-soft); }
.voice-notice p { margin: 0; color: var(--x-ink-2); font-size: 13px; line-height: 1.5; }

/* Settings privacy center */
.privacy-center { margin-bottom: 14px; }
.consent-list { display: grid; margin-top: 8px; }
.consent-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--x-hair); }
.consent-row b { display: block; font-size: 14px; }
.consent-row small { display: block; margin-top: 3px; color: var(--x-ink-3); font-size: 12px; line-height: 1.4; }
.consent-row__state { display: inline-block; margin-top: 6px; color: var(--x-ink-2); font: var(--label-fw) var(--label-fs)/1 var(--sans); letter-spacing: var(--label-ls); text-transform: uppercase; }
.consent-row[data-active="true"] .consent-row__state { color: var(--good); }
.consent-row__text { margin: 10px 0 0; padding: 10px 12px; border-radius: var(--radius-inner-min); background: var(--x-surface-2, rgba(255,255,255,.04)); color: var(--x-ink-2); font-size: 13px; line-height: 1.5; }
.error-banner__action { align-self: center; white-space: nowrap; color: var(--accent); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.export-status { min-height: 1em; margin: 8px 0 0; }

/* Guided progress-photo camera */
.ghost-camera { position: fixed; inset: 0; z-index: 200; display: grid; grid-template-rows: minmax(0, 1fr) auto auto; background: #000; color: #fff; }
.ghost-camera__stage { position: relative; overflow: hidden; }
.ghost-camera__video, .ghost-camera__still, .ghost-camera__ghost { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ghost-camera__video[data-facing="user"] { transform: scaleX(-1); }
.ghost-camera__ghost { opacity: .32; mix-blend-mode: screen; pointer-events: none; filter: grayscale(1) contrast(1.2); transition: opacity var(--x-med); }
.ghost-camera--ghost-off .ghost-camera__ghost { opacity: 0; }
.ghost-camera__guide { position: absolute; inset: 10% 26% 6%; border: 2px dashed rgba(255, 255, 255, .45); border-radius: 46% 46% 18% 18% / 20% 20% 10% 10%; pointer-events: none; }
.ghost-camera__count { position: absolute; inset: 0; display: grid; place-items: center; font: 400 120px/1 var(--serif); text-shadow: 0 4px 30px rgba(0, 0, 0, .6); }
.ghost-camera__tip { position: absolute; left: 16px; right: 16px; top: max(16px, env(safe-area-inset-top)); margin: 0; padding: 10px 14px; border-radius: 14px; background: rgba(0, 0, 0, .55); font-size: 13px; line-height: 1.4; text-align: center; }
.ghost-camera__status { position: absolute; left: 16px; right: 16px; bottom: 16px; font-size: 13px; text-align: center; }
.ghost-camera__bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 16px max(16px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); background: #000; }
.ghost-camera__icon, .ghost-camera__chip { min-width: 44px; min-height: 44px; border: 1px solid rgba(255, 255, 255, .25); border-radius: 999px; background: rgba(255, 255, 255, .08); color: #fff; font: 650 13px/1 var(--sans); }
.ghost-camera__icon { display: grid; place-items: center; width: 44px; padding: 0; }
.ghost-camera__chip { padding: 0 14px; }
.ghost-camera__chip[aria-pressed="false"] { opacity: .6; }
.ghost-camera__shutter { display: grid; place-items: center; width: 74px; height: 74px; border: 4px solid #fff; border-radius: 50%; background: transparent; }
.ghost-camera__shutter span { width: 58px; height: 58px; border-radius: 50%; background: #fff; transition: transform var(--x-fast); }
.ghost-camera__shutter:active span { transform: scale(.9); }
.ghost-camera__shutter:disabled { opacity: .4; }
.ghost-camera__review { display: flex; gap: 10px; justify-content: center; padding: 16px 16px max(20px, env(safe-area-inset-bottom)); background: #000; }
.ghost-camera__review[hidden], .ghost-camera__bar[hidden] { display: none; }

/* ==== Day one and completion moments (day-one.js) ========================== */
/* Program Ready: what the first session asks, in one calm line. */
.first-session-note { display: flex; align-items: center; gap: 8px; margin: 14px 0 0; color: var(--x-ink-2); font-size: 14px; font-weight: 600; line-height: 1.4; }
.first-session-note .icon { width: 16px; height: 16px; flex: none; color: var(--accent); }

/* Today on day 1: a compact welcome in the eyebrow slot, so the mission
 * action keeps its place above the dock. */
.day-one-welcome { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 22px; }
.day-one-welcome__badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px 3px 7px; border: 1px solid var(--accent-strong); border-radius: 999px; background: var(--accent-soft); color: var(--x-ink); font: 760 11px/1.2 var(--sans); letter-spacing: .1em; text-transform: uppercase; }
.day-one-welcome__badge .icon { width: 14px; height: 14px; color: var(--accent); }
/* One line, always: a wrapped welcome would push the mission action into the dock. */
.day-one-welcome__badge { flex: none; }
.day-one-welcome__line { min-width: 0; overflow: hidden; color: var(--x-ink-2); font-size: 13px; font-weight: 600; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 359px) { .day-one-welcome__line { display: none; } }

/* Completion: a ring fills, then a check draws. Paint-only (stroke offsets),
 * sized like the seal it replaces, so nothing around it moves. */
.x-celebrate { display: flex; align-items: center; gap: 10px; min-height: 22px; }
.x-celebrate__line { margin: 0; color: var(--x-ink); font-size: 14px; font-weight: 650; line-height: 1.35; }
.workout-summary .x-celebrate__line, .recovery-day .x-celebrate__line { margin-top: 6px; }
.x-celebrate-mark { --x-celebrate-size: 56px; display: grid; place-items: center; width: var(--x-celebrate-size); height: var(--x-celebrate-size); flex: none; }
.x-celebrate-mark--sm { --x-celebrate-size: 26px; }
.x-celebrate-mark svg { display: block; width: 100%; height: 100%; overflow: visible; }
.x-celebrate-mark__track { fill: color-mix(in srgb, var(--accent) 14%, transparent); stroke: rgba(255, 236, 226, .1); stroke-width: 3; }
.x-celebrate-mark__arc { fill: none; stroke: var(--accent); stroke-width: 3.5; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 0; transform: rotate(-90deg); transform-box: fill-box; transform-origin: center; }
.x-celebrate-mark__check { fill: none; stroke: var(--x-ink); stroke-width: 3.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 100; stroke-dashoffset: 0; }
.x-celebrate-mark--sm .x-celebrate-mark__track { stroke-width: 4; }
.x-celebrate-mark--sm .x-celebrate-mark__arc, .x-celebrate-mark--sm .x-celebrate-mark__check { stroke-width: 5; }
.x-celebrate-mark[data-animate="true"] .x-celebrate-mark__arc { animation: x-celebrate-draw 760ms var(--x-ease) both; }
.x-celebrate-mark[data-animate="true"] .x-celebrate-mark__check { animation: x-celebrate-draw 360ms var(--x-ease) 640ms both; }
.x-celebrate-mark[data-animate="true"] svg { animation: x-celebrate-settle 520ms var(--x-ease-spring) 820ms both; }
@keyframes x-celebrate-draw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@keyframes x-celebrate-settle { 0% { transform: scale(1); } 45% { transform: scale(1.06); } 100% { transform: scale(1); } }
/* The ring replaces the filled seal: keep the halo, drop the fill and pop. */
.x-celebrate-seal.workout-summary__seal, .x-celebrate-seal.recovery-day__seal { background: none; color: inherit; animation: none; box-shadow: 0 12px 36px var(--accent-soft); }
@media (prefers-reduced-motion: reduce) {
  .x-celebrate-mark svg, .x-celebrate-mark__arc, .x-celebrate-mark__check { animation: none !important; stroke-dashoffset: 0 !important; }
}
/* ==== End day one and completion moments ================================== */

/* ==== Continuity after in-place updates (src/motion.js) =================== */
/* A repaint used to make rings jump and new rows simply appear. motion.js
 * sets the previous ring value and marks what changed; the motion here is
 * paint-only (the ring's custom property) or compositor-only (opacity and
 * transform), and never moves anything around it. */
/* A row that was not there before: a warm wash that fades out behind it. */
.today-log li[data-fresh="true"], .today-plan__item[data-just-done="true"] { position: relative; isolation: isolate; }
.today-log li[data-fresh="true"]::before, .today-plan__item[data-just-done="true"]::before {
  /* Reaches 10px into the card padding (16px or more) so the text is not flush with the tint. */
  content: ""; position: absolute; inset: 0 -10px; z-index: -1; border-radius: 12px; background: var(--accent-soft); opacity: 0; pointer-events: none;
  animation: x-fresh-wash 1.8s var(--x-ease) 120ms both;
}
@keyframes x-fresh-wash { 0% { opacity: 0; } 18% { opacity: 1; } 100% { opacity: 0; } }
/* A target met by this log: the ring settles once its fill has landed. */
.macro-ring-card[data-just-met="true"] .x-ring { animation: x-celebrate-settle 560ms var(--x-ease-spring) var(--x-slow) both; }
/* Finished elsewhere since Today was last seen: the check pops in. */
.today-plan__item[data-just-done="true"] .today-plan__icon { animation: x-pop var(--x-med) var(--x-ease-spring) 280ms both; }
@media (prefers-reduced-motion: reduce) {
  .today-log li[data-fresh="true"]::before, .today-plan__item[data-just-done="true"]::before,
  .macro-ring-card[data-just-met="true"] .x-ring, .today-plan__item[data-just-done="true"] .today-plan__icon { animation: none !important; }
}
/* ==== End continuity ====================================================== */

/* Coach action proposals: nothing changes until the member confirms. */
.coach-proposal { align-self: flex-start; max-width: min(92%, 420px); margin: 4px 0 8px; padding: 12px 14px; border: 1px solid var(--x-hair); border-radius: var(--radius-inner); background: var(--x-surface-2, rgba(255,255,255,.05)); }
.coach-proposal p { margin: 0 0 10px; font-weight: 600; }
.coach-proposal .action-row { gap: 8px; }
.coach-proposal__done { margin: 0 !important; display: flex; align-items: center; gap: 8px; color: var(--good); }

/* ==========================================================================
   20. Type scale on phones and desktop composition (S+ round)
   One display size per role on narrow screens so headlines stop stacking
   into 3–4 line towers, and wide screens use the width for related content.
   ========================================================================== */
@media (max-width: 480px) {
  .mode-gate h1 { font-size: 34px; line-height: 1.04; max-width: min(100%, 11em); }
  .public-shell [data-gm-concept="choose"] .future-panel h1,
  .public-shell [data-gm-concept="paywall"] .acquisition-heading h1,
  .public-shell .future-panel h1,
  .public-shell .acquisition-heading h1,
  .public-shell .gm-composition--capture .flow-screen > div > h1 { font-size: 34px; line-height: 1.04; letter-spacing: -.02em; max-width: min(100%, 11em); }
  /* Home keeps its editorial headline (visual matrix: at least 42 px). */
}
@media (min-width: 1100px) {
  /* Progress: measured metrics and the trend read together. */
  .app-screen--app-progress .progress-metrics + .x-trend { margin-top: 0; }
  .app-screen--app-progress .member-screen > section {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 18px;
    align-items: start;
  }
  .app-screen--app-progress .member-screen > section > * { grid-column: 1 / -1; }
  .app-screen--app-progress .member-screen > section > .progress-metrics { grid-column: 1; }
  .app-screen--app-progress .member-screen > section > .x-trend { grid-column: 2; }
  /* Settings: privacy and account deletion side by side under the profile. */
  .app-screen--app-settings .member-screen {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    column-gap: 18px;
    align-items: start;
  }
  .app-screen--app-settings .member-screen > * { grid-column: 1 / -1; }
  .app-screen--app-settings .member-screen > .privacy-center { grid-column: 1; }
  .app-screen--app-settings .member-screen > .danger-zone { grid-column: 2; }
}
/* An AI badge belongs to its image: contain its z-index inside the media
   container so it can never paint above trays, docks or sheets. */
/* Explicit containers, not :has(): a universal :has() subject made WebKit
   re-check every element on each DOM mutation (route input ack regressed). */
.compare-card, .compare-layer, .variant-thumb, .preview-tile, .reveal-visual,
.commitment-pane, .gm-media-stage, .film-still, .film-still-divider, .twin-card,
.future-mini, [data-home-future-slot], .nutrition-visual-slot { isolation: isolate; }
/* Lock In: essentials first; plan preferences collapse behind a summary. */
.lock-tune { border-top: 1px solid var(--x-hair); border-bottom: 1px solid var(--x-hair); }
.lock-tune > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 10px 0; cursor: pointer; list-style: none; }
.lock-tune > summary::-webkit-details-marker { display: none; }
.lock-tune > summary span { display: grid; gap: 3px; }
.lock-tune > summary b { font-size: 14px; }
.lock-tune > summary small { color: var(--x-ink-2); font-size: 12px; line-height: 1.35; }
.lock-tune > summary .icon { flex: none; width: 18px; height: 18px; transition: transform .2s ease; }
.lock-tune[open] > summary .icon { transform: rotate(180deg); }
.lock-tune > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-inner-min); }
.lock-tune__fields { padding: 4px 0 16px; }
@media (prefers-reduced-motion: reduce) { .lock-tune > summary .icon { transition: none; } }
.profile-avatar .icon { width: 44%; height: 44%; opacity: .8; }
/* Exercises without validated media show a compact form cue, not an empty
   poster-sized box. */
.exercise-media-slot--cue { display: grid; gap: 6px; min-height: 0 !important; height: auto !important; aspect-ratio: auto; padding: 14px 16px !important; align-content: start; }
.exercise-media-slot--cue p { margin: 0; color: var(--x-ink); font-size: 14px; line-height: 1.45; }
/* A long exercise rail must scroll inside its track, not widen the grid
   (1fr resolves to minmax(auto, 1fr); with 4+ exercises the phone layout
   overflowed the viewport). */
.workout-layout { grid-template-columns: minmax(0, 1fr); min-width: 0; max-width: 100%; }
.workout-layout > * { min-width: 0; }
@media (min-width: 1100px) { .workout-layout { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); } }

/* ==========================================================================
   Nutrition food logging: search, portion picker, custom food, logged today.
   (Food search data and code load on demand; these rules only style them.)
   ========================================================================== */
.food-log-card { padding: var(--card-pad); scroll-margin-top: 16px; }
.food-log { display: grid; gap: 14px; min-width: 0; }
.food-search { display: grid; gap: 8px; }
.food-search__label { font: 400 var(--type-h3)/1.05 var(--serif); letter-spacing: -.02em; color: var(--x-ink); }
.food-search__row { display: flex; gap: 8px; align-items: stretch; }
.app-shell .food-search__input { flex: 1; min-width: 0; min-height: var(--input-h); font-size: 16px; padding-left: 44px; border-color: var(--accent-strong); background:
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b5aaa3' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") 14px 50% / 20px no-repeat, rgba(255, 255, 255, .05); }
.food-search__input::-webkit-search-cancel-button { filter: invert(.7); }
.food-search__scan { flex: none; display: grid; place-items: center; width: var(--input-h); height: var(--input-h); padding: 0; border: 1px solid var(--x-hair-strong); border-radius: var(--radius-inner); background: rgba(255, 236, 226, .06); color: var(--x-ink); cursor: pointer; }
.food-search__scan .icon { width: 22px; height: 22px; }
.food-search__scan[hidden] { display: none; }
.food-barcode-status:empty { display: none; }
.food-barcode-status { margin: -4px 0 0; color: var(--x-ink-2); font-size: 13px; line-height: 1.45; }
.food-results-host:empty, .food-portion-host:empty { display: none; }
.food-results { display: grid; margin: 0; padding: 0; list-style: none; border: 1px solid var(--x-hair); border-radius: var(--radius-inner); overflow: hidden; }
.food-results li + li { border-top: 1px solid var(--x-hair); }
.food-result { display: grid; gap: 4px; width: 100%; min-height: 56px; padding: 10px 14px; border: 0; background: transparent; color: var(--x-ink); text-align: left; cursor: pointer; }
.food-result:hover, .food-result:focus-visible { background: var(--accent-soft); outline: none; }
.food-result__name { font-size: 15px; font-weight: 650; line-height: 1.25; }
.food-result__meta { display: flex; flex-wrap: wrap; gap: 4px 12px; color: var(--x-ink-3); font-size: 12px; }
.food-result__meta b { color: var(--x-ink-2); font-weight: 700; font-variant-numeric: tabular-nums; }
.food-results__empty, .food-results__loading { margin: 0; color: var(--x-ink-2); font-size: 13px; line-height: 1.45; }
.food-source { margin: 8px 0 0; color: var(--x-ink-3); font-size: 11px; line-height: 1.4; }
.food-source a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.food-portion { display: grid; gap: 14px; padding: var(--card-pad-compact); border: 1px solid var(--accent-strong); border-radius: var(--radius-inner); background: var(--accent-soft); }
.food-portion__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.food-portion__head > div { flex: 1; min-width: 0; }
.food-portion__head h2 { margin: 4px 0 4px; font: 400 var(--type-h3)/1.08 var(--serif); letter-spacing: -.02em; color: var(--x-ink); }
.food-portion__head small { color: var(--x-ink-2); font-size: 12px; }
.food-portion__close { flex: none; width: 44px; height: 44px; border: 1px solid var(--x-hair-strong); border-radius: 50%; background: rgba(255, 236, 226, .05); color: var(--x-ink); font-size: 22px; line-height: 1; cursor: pointer; }
.food-portion__chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.food-portion__chips .x-chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #fff; }
.food-portion__amount { display: grid; grid-template-columns: var(--input-h) minmax(0, 1fr) var(--input-h); align-items: start; gap: 10px; }
.food-portion__amount > .food-step { margin-top: 25px; }
.food-step { width: var(--input-h); height: var(--input-h); border: 1px solid var(--x-hair-strong); border-radius: var(--radius-inner); background: rgba(255, 236, 226, .06); color: var(--x-ink); font: 600 24px/1 var(--sans); cursor: pointer; }
.food-step:active { transform: scale(.96); }
.food-portion__qty { display: grid; gap: 4px; justify-items: center; }
.app-shell .food-portion__qty .input { width: 100%; min-height: var(--input-h); text-align: center; font: 700 18px/1 var(--sans); font-variant-numeric: tabular-nums; }
.food-portion__amount .field > label { text-align: center; }
.food-portion__qty span { min-width: 0; color: var(--x-ink-2); font-size: 12px; line-height: 1.3; text-align: center; }
.food-portion__slider { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }
.food-portion__slider label { font-size: var(--label-fs); text-transform: uppercase; letter-spacing: var(--label-ls); color: var(--muted); font-weight: var(--label-fw); }
.food-portion__slider input[type="range"] { width: 100%; min-height: 44px; accent-color: var(--accent); }
.food-portion__slider output { min-width: 64px; text-align: right; font: 700 14px/1 var(--sans); font-variant-numeric: tabular-nums; color: var(--x-ink); }
.food-portion__macros { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin: 0; }
.food-portion__macros > div { display: grid; gap: 4px; padding: 10px 6px; border-radius: var(--radius-inner-min); background: rgba(0, 0, 0, .22); text-align: center; }
.food-portion__macros dt { color: var(--x-ink-3); font-size: 11px; font-weight: 650; line-height: 1.2; overflow-wrap: anywhere; hyphens: auto; }
.food-portion__macros dd { margin: 0; color: var(--x-ink-2); font-size: 11px; white-space: nowrap; }
.food-portion__macros dd b { color: var(--x-ink); font-size: 16px; font-variant-numeric: tabular-nums; }
.food-portion__macros [data-macro-cell="calories"] { grid-column: 1 / -1; display: flex; align-items: baseline; justify-content: space-between; padding: 10px 14px; background: rgba(0, 0, 0, .34); }
.food-portion__macros [data-macro-cell="calories"] dd b { font-size: 22px; }
.food-portion__limit { margin: 0; color: var(--warn); font-size: 13px; }
.food-portion__log { width: 100%; }
.food-portion .food-source { margin: 0; }
.food-custom { border-top: 1px solid var(--x-hair); border-bottom: 1px solid var(--x-hair); }
.food-custom > summary { display: flex; align-items: center; min-height: 48px; padding: 0; color: var(--x-ink-2); font-size: 14px; font-weight: 650; cursor: pointer; list-style: none; }
.food-custom > summary::-webkit-details-marker { display: none; }
.food-custom > summary::after { content: "+"; margin-left: auto; font-size: 20px; color: var(--x-ink-3); }
.food-custom[open] > summary::after { content: "–"; }
.food-custom__form { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; padding: 0 0 16px; }
.food-custom__name, .food-custom__submit { grid-column: 1 / -1; }
.food-undo { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 8px 8px 14px; border: 1px solid var(--x-hair-strong); border-radius: var(--radius-inner); background: rgba(255, 236, 226, .05); font-size: 13px; }
.today-log-groups { display: grid; gap: 12px; }
.today-log__title { margin: 4px 0 0; font: 400 var(--type-h3)/1.1 var(--serif); color: var(--x-ink); }
.today-log-group > header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.today-log-group > header small { color: var(--x-ink-3); font-size: 12px; font-variant-numeric: tabular-nums; }
.today-log-group .today-log li { display: grid; grid-template-columns: minmax(0, 1fr) auto 44px; align-items: center; gap: 10px; padding: 6px 0; }
.today-log__name { display: grid; gap: 2px; min-width: 0; }
.today-log__name b { overflow: hidden; color: var(--x-ink); font-size: 14px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
.today-log__name small { color: var(--x-ink-3); font-size: 12px; }
.today-log__kcal { color: var(--x-ink-2); font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.today-log__remove { width: 44px; height: 44px; border: 0; border-radius: 50%; background: transparent; color: var(--x-ink-3); font-size: 20px; line-height: 1; cursor: pointer; }
.today-log__remove:hover, .today-log__remove:focus-visible { background: rgba(255, 236, 226, .08); color: var(--x-ink); }
.today-log__empty { margin: 0; color: var(--x-ink-3); font-size: 13px; line-height: 1.45; }
.food-log .recent-meals .x-chip span { max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.macro-ring-card[data-calorie-state="in-range"] .x-ring { background:
    radial-gradient(closest-side, var(--x-ring-hole, rgba(20, 12, 11, .96)) calc(100% - 6px), transparent calc(100% - 5px)),
    conic-gradient(from -90deg, var(--good) calc(var(--x-ring-value) * 1%), var(--x-ring-track) 0); }
@media (max-width: 760px) {
  .food-custom__form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .food-portion__macros { gap: 4px; }
  .food-portion__macros > div { padding: 8px 4px; }
  .food-portion__macros dd b { font-size: 15px; }
}

/* ==========================================================================
 * 99. WCAG 2.2 AA layer — accessibility audit 2026-09-28
 * --------------------------------------------------------------------------
 * Every rule below closes a measured finding in
 * docs/product-truth/accessibility-audit-2026-09-28.md. It is deliberately
 * last so it overrides the legacy sheets (app/screens/responsive/golden)
 * without editing them. Contrast values are rendered measurements against the
 * painted background, not token guesses.
 * ========================================================================== */

/* 1.4.3 — tertiary ink measured 3.8–4.3:1 on the lighter glass cards
 * ("380 kcal", "40 min session", "Drained", flow-step labels). Tertiary ink
 * now shares the secondary muted tone (#b5aaa3, lighter than the #aa9d95 that
 * first cleared 4.5:1), so the text scale has three greys, not four. */
:root { --x-ink-3: var(--muted); }

/* 1.4.3 — white CTA text measured 2.4–3.2:1 on the light rose gradient
 * (every feminine primary button) and 3.7:1 at the light end of the
 * masculine red. Deepen the gradients so white text holds ≥4.6:1 end to end;
 * the glossy radial highlight sat behind the label and is dropped. */
html[data-presentation="feminine"] .button.button--primary,
html[data-presentation="feminine"] .bubble.user {
  background: linear-gradient(135deg, #c24a69, #8f2d4c);
  color: #fff;
}
html[data-presentation="masculine"] .button.button--primary,
html[data-presentation="masculine"] .bubble.user {
  background: linear-gradient(135deg, #c43333, #82191d);
  color: #fff;
}

/* 1.4.3 / 1.4.11 — selected states painted white on the flat accent measured
 * 2.7:1 (pressed portion chips, done set checks, selected variant tick, done
 * plan items). Dark ink on the accent reads ≥4.6:1 in both presentations; the
 * pressed effort/energy scale uses the deepened CTA gradient instead. */
html .food-portion__chips .x-chip[aria-pressed="true"],
html .set-check.done,
html .today-plan__item[data-done="true"] .today-plan__icon,
html .public-shell [data-gm-concept="choose"] .variant.active > .icon { color: #1b0a0c; }
html[data-presentation="feminine"] .x-scale button[aria-pressed="true"] { background: linear-gradient(135deg, #c24a69, #8f2d4c); color: #fff; }
html[data-presentation="masculine"] .x-scale button[aria-pressed="true"] { background: linear-gradient(135deg, #c43333, #82191d); color: #fff; }
.food-source { color: var(--x-ink-2); }

/* 1.4.3 — placeholders carry instructions ("Optional", "0–100") and measured
 * 4.2–4.4:1; the masculine "THE LOOP" kicker sat at 4.5:1 exactly. */
input::placeholder, textarea::placeholder { color: rgba(255, 244, 236, .64); opacity: 1; }
.public-screen--masculine .stage-callout span { color: var(--x-eyebrow); }

/* 1.4.3 — text over photography: the Home Future Form overlay faded to 35%
 * at the top, leaving "Future direction" at 3.4:1 over bright frames. */
.future-mini-overlay { background: linear-gradient(180deg, rgba(8, 7, 6, .74), rgba(8, 7, 6, .9)); }
.twin-caption { background: rgba(8, 7, 6, .86); }

/* 1.4.11 — text fields were bounded by a 10%-white hairline (1.5:1 against the
 * card). A 44% warm-white boundary measures ≥3:1 on every card surface. */
.app-shell .input, .app-shell .textarea, .app-shell .select,
.public-shell .input, .public-shell .textarea, .public-shell .select,
.mode-gate .input { border-color: rgba(255, 236, 226, .44); }

/* 2.4.7 / 1.4.11 — every keyboard focus gets a solid 2px ring. Inputs only
 * had a 17%-alpha glow; food results only a faint tint. */
.app-shell .input:focus-visible, .app-shell .textarea:focus-visible, .app-shell .select:focus-visible,
.public-shell .input:focus-visible, .public-shell .textarea:focus-visible, .public-shell .select:focus-visible,
.mode-gate .input:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 80%, white);
  outline-offset: 2px;
}
.food-result:focus-visible { outline: 2px solid color-mix(in srgb, var(--accent) 80%, white); outline-offset: -2px; }
.screening-referral:focus-visible, .workout-summary h2:focus-visible,
.exercise-panel h2:focus-visible, .recovery-day h2:focus-visible { outline: 2px solid color-mix(in srgb, var(--accent) 80%, white); outline-offset: 4px; border-radius: 6px; }
.screening-referral:focus:not(:focus-visible), .workout-summary h2:focus:not(:focus-visible),
.exercise-panel h2:focus:not(:focus-visible), .recovery-day h2:focus:not(:focus-visible) { outline: none; }

/* 2.5.8 / 2.4.11 — on short phones the sticky order tray floated over the
 * pre-contract disclosure and the immediate-start checkbox (target partly
 * obscured; required information hidden behind the order button). On the
 * paywall the tray stays in flow, directly after the disclosure. */
@media (max-width: 760px) { .public-shell [data-gm-concept="paywall"] .context-action-tray { position: static; } }

/* 2.2.2 Pause, Stop, Hide — the media-stage orbit drifted forever (12s,
 * infinite). It now drifts once, inside five seconds, and rests. */
@media (prefers-reduced-motion: no-preference) {
  .gm-media-stage::before { animation-duration: 4.8s; animation-iteration-count: 1; animation-fill-mode: both; }
}
/* 1.4.10 — at 320px the macro ring and its number cannot share a row in
 * WebKit; let the number wrap under the ring instead of being clipped. */
@media (max-width: 360px) { .macro-ring-body { flex-wrap: wrap; } }

/* 2.4.11 Focus Not Obscured — scrolling a focused control into view must
 * clear the sticky action tray and the dock. Browsers honour scroll-padding
 * for focus scrolling. */
@media (max-width: 760px) {
  .public-scroll { scroll-padding-top: 16px; scroll-padding-bottom: calc(var(--app-nav-reserved, 100px) + 96px); }
  /* Screens with a sticky action tray get .app-scroll--tray from the shell
     (a :has() on the route container was re-evaluated by WebKit on every
     route swap and cost the input-ack budget). */
  .app-scroll { scroll-padding-top: 68px; }
  .app-scroll--tray { scroll-padding-bottom: calc(var(--app-nav-reserved, 100px) + 96px); }
}

/* 2.5.8 Target Size — sliders were 16px tall; screening radios/checkboxes
 * 13–17px. */
input[type="range"] { min-height: 24px; }
.safety-screening input[type="checkbox"], .screening-question input[type="radio"] { width: 20px; height: 20px; margin-top: 0; }
/* Stand-alone consent checkboxes sit next to other controls: make the box
 * itself the full 24px target (axe target-size, WebKit layout). */
.consent-check, .checkout-immediate { grid-template-columns: 24px minmax(0, 1fr); }
.consent-check input, .checkout-immediate input[type="checkbox"] { width: 24px; height: 24px; flex: 0 0 24px; }
.safety-screening > label { min-height: 24px; align-items: center; }
.food-portion__close, .food-step { min-width: 44px; min-height: 44px; }
/* WebKit draws native selects 23px tall regardless of padding; draw our own
 * chevron so every select is a full-height target in both engines. */
.app-shell .select, .public-shell .select {
  -webkit-appearance: none;
  appearance: none;
  min-height: 48px;
  padding-right: 42px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f3e6de' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px;
}

/* 1.4.10 Reflow / 1.4.12 Text Spacing — informational copy must not be cut
 * off. Line clamps hid lead paragraphs and header subtitles on phones, and
 * logged meal names were ellipsised at 320px. */
html .public-shell [data-gm-concept="choose"] .future-panel > .lead,
html .public-shell [data-gm-concept="reveal"] .reveal-intro .lead,
html .app-shell[data-gm-concept] .app-header__subtitle,
html .app-shell .app-header__subtitle {
  display: block;
  overflow: visible;
  -webkit-line-clamp: unset;
  line-clamp: unset;
}
/* The phone quick-card carousel inherited a later `grid-template-columns: 1fr`
 * (responsive.css), so its first card — Workout — collapsed to 2px on every
 * phone. A column carousel has no explicit columns. */
@media (max-width: 760px) { .app-shell .quick-grid { grid-template-columns: none; } }
/* Long Bokmål compounds ("Konsolideringsblokk", "Midjeendring") overflowed
 * narrow cards at 320px; let words break only when they cannot fit. */
/* Wrap long words in text, not on the shells: an inherited overflow-wrap on
   the whole app changed line breaking for every text node on each route. */
:where(.app-shell, .public-shell, .mode-gate) :where(p, h1, h2, h3, h4, li, label, small, b, strong, dd, dt, figcaption, legend, summary) { overflow-wrap: break-word; }
.macro-ring-copy small { white-space: normal; }
.metric-label > span { min-width: 0; overflow-wrap: anywhere; }
/* "Log again" chips scroll horizontally; they never need to ellipsise a name. */
.food-log .recent-meals .x-chip span { max-width: none; overflow: visible; text-overflow: clip; }
.today-log__name b { overflow: visible; white-space: normal; overflow-wrap: anywhere; text-overflow: clip; }
.commitment-pane .ai-badge { max-width: calc(100% - 14px); white-space: normal; }

/* Screen-reader only text inside flex/grid chips stays out of layout. */
.bubble.typing .sr-only { position: absolute; }

/* ==========================================================================
 * 100. Desktop member experience (laptop and wider)
 * --------------------------------------------------------------------------
 * Owner: desktop composition pass (branch claude/desktop). Everything that
 * changes layout lives inside `@media (min-width: 1100px)`; phones and
 * tablets are pixel-identical (390/768/1024/1099 px diffed before/after).
 * The only rule outside the query makes the two Nutrition column wrappers
 * layout-transparent (`display: contents`) below 1100 px.
 *
 * Principles
 *  - Visual order follows DOM order: columns are filled left→right with
 *    DOM-contiguous runs, never with CSS `order` (legacy `order` swaps on the
 *    Today/Program Ready hero are reset here).
 *  - One gutter system: 20 px between cards, 24–28 px between columns.
 *  - Readable measure: running copy is capped at ~68ch.
 *  - Class selectors only; no :has() on containers, no universal subjects.
 * ========================================================================== */
.nutrition-summary,
.nutrition-main { display: contents; }

@media (min-width: 1100px) {
  /* -- Shell: one gutter, a wider canvas ---------------------------------- */
  .app-shell .app-scroll { padding: 34px clamp(32px, 3.4vw, 56px) 56px; }
  .app-shell .member-screen { width: min(1180px, 100%); padding: 0; gap: 20px; }
  .app-shell .member-composition { gap: 20px; }
  .app-shell .member-screen p { max-width: 68ch; }

  /* -- Today: mission | Future scene, then plan | metrics ----------------- */
  .app-screen--app .member-composition {
    display: grid;
    grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
    column-gap: 20px;
    align-content: start;
  }
  .app-screen--app .member-composition > * { grid-column: 1 / -1; min-width: 0; }
  .app-screen--app .member-composition > .today-plan { grid-column: 1; align-self: stretch; margin: 0; }
  .app-screen--app .member-composition > .metrics-grid {
    grid-column: 2;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: stretch;
    gap: 14px;
  }
  .app-screen--app .metrics-grid .metric-card { min-height: 0; }
  .app-screen--app .hero-grid--media-first,
  .app-screen--app-program-ready .hero-grid--media-first {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
    gap: 20px;
  }
  html[data-presentation] .app-screen--app .hero-grid--media-first > .glass-card:first-child,
  html[data-presentation] .app-screen--app .hero-grid--media-first > .glass-card:last-child,
  html[data-presentation] .app-screen--app-program-ready .hero-grid--media-first > .glass-card:first-child,
  html[data-presentation] .app-screen--app-program-ready .hero-grid--media-first > .glass-card:last-child { order: 0; }
  .app-screen--app .hero-grid--media-first > .glass-card:last-child:not(.future-card--empty),
  .app-screen--app .hero-grid--media-first > .glass-card:last-child:not(.future-card--empty) .future-mini,
  .app-screen--app .hero-grid--media-first > .glass-card:first-child .mission-card {
    min-height: clamp(340px, calc(100vh - 380px), 460px);
  }
  .app-screen--app .hero-grid--media-first .mission-card { padding: clamp(28px, 3vw, 40px); justify-content: center; }
  .app-screen--app .hero-grid--media-first .mission-card h2 { font-size: clamp(44px, 4.2vw, 60px); line-height: .98; }
  .app-screen--app .hero-grid--media-first .mission-card .mission-meta { margin-top: 22px; }
  .app-screen--app .quick-grid { gap: 14px; }
  .app-screen--app .quick-card { min-height: 0; gap: 12px; }

  /* -- Workout: exercise rail | active exercise (media | sets) ------------ */
  .app-screen--app-workout .workout-layout {
    grid-template-columns: minmax(200px, 23%) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
  }
  .app-screen--app-workout .exercise-list { position: sticky; top: 0; }
  .app-shell.app-screen--app-workout .exercise-panel {
    display: grid;
    /* The sets column gets the larger share: at 1280px an even split wrapped
       "Dumbbell Romanian deadlift" onto three lines beside the media. */
    grid-template-columns: minmax(200px, .85fr) minmax(300px, 1.15fr);
    grid-template-rows: repeat(6, auto) 1fr;
    column-gap: 26px;
    row-gap: 0;
    align-items: start;
  }
  .app-shell.app-screen--app-workout .exercise-panel > * { grid-column: 2; min-width: 0; margin: 0 0 14px; }
  .app-shell.app-screen--app-workout .exercise-panel > :last-child { margin-bottom: 0; }
  .app-shell.app-screen--app-workout .exercise-panel > #workout-error:empty { margin: 0; }
  .app-shell.app-screen--app-workout .exercise-panel > .exercise-media-slot {
    grid-column: 1;
    grid-row: 1 / -1;
    align-self: stretch;
    height: auto;
    min-height: 420px;
    margin: 0;
  }
  .app-shell.app-screen--app-workout .exercise-panel > .exercise-media-slot img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    min-height: 0;
  }
  .app-shell.app-screen--app-workout .exercise-panel > .exercise-media-slot--empty { align-self: start; min-height: 0; }
  /* The global 13ch heading measure would still wrap a long exercise name
     onto three lines inside the wider sets column. */
  .app-shell.app-screen--app-workout .exercise-panel h2 { max-width: none; font-size: clamp(28px, 2.3vw, 36px); line-height: 1.04; text-wrap: balance; }
  .app-shell.app-screen--app-workout .exercise-panel > #complete-exercise { width: 100%; }

  /* -- Nutrition: summary rail | log, portion panel, plan ----------------- */
  .app-screen--app-nutrition .member-composition {
    display: grid;
    grid-template-columns: minmax(280px, 320px) minmax(0, 1fr);
    gap: 20px 26px;
    align-content: start;
    align-items: start;
  }
  .app-screen--app-nutrition .member-composition > .app-header { grid-column: 1 / -1; }
  .nutrition-summary { display: grid; gap: 14px; position: sticky; top: 0; min-width: 0; }
  .nutrition-main { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
  .app-screen--app-nutrition .nutrition-summary .nutrition-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .app-screen--app-nutrition .nutrition-summary .macro-ring-card { padding: 14px; min-height: 0; }
  .app-screen--app-nutrition .nutrition-summary .macro-ring-body { flex-direction: column; align-items: flex-start; gap: 10px; margin-top: 10px; }
  .app-screen--app-nutrition .nutrition-summary .macro-ring-body .x-ring { --x-ring-size: 48px; }
  .app-screen--app-nutrition .nutrition-summary .water-quick { flex-wrap: wrap; }
  .app-screen--app-nutrition .nutrition-main .meal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Without a meal plan the grid holds only the daily-rhythm card; a lone
     card spans the column instead of leaving an empty half beside it. */
  .app-screen--app-nutrition .nutrition-main .meal-grid > :only-child { grid-column: 1 / -1; }

  /* -- Coach: readable conversation column, context beside, composer
        anchored to the bottom of the viewport ------------------------------ */
  .app-screen--app-coach .coach-layout {
    grid-template-columns: minmax(0, 720px) minmax(260px, 300px);
    align-items: start;
    min-height: 0;
    gap: 24px;
  }
  .app-screen--app-coach .coach-layout > .glass-card:first-child { height: max(460px, calc(100dvh - 190px)); }
  .app-screen--app-coach .chat-card { height: 100%; min-height: 0; grid-template-rows: auto minmax(0, 1fr) auto auto; }
  .app-screen--app-coach .chat-feed { padding: 22px 24px; }
  .app-screen--app-coach .bubble { max-width: min(86%, 62ch); font-size: 14px; }
  .app-screen--app-coach .coach-layout > .glass-card:last-child { position: sticky; top: 0; }

  /* -- Check-in: header and stepper share a row; photo | form ------------- */
  .app-screen--app-check-in .member-composition {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-content: start;
    column-gap: 24px;
  }
  .app-screen--app-check-in .member-composition > * { grid-column: 1 / -1; }
  .app-screen--app-check-in .member-composition > .app-header { grid-column: 1; }
  .app-screen--app-check-in .member-composition > .checkin-stepper { grid-column: 2; align-self: end; }
  .app-screen--app-check-in .checkin-layout { grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); gap: 24px; align-items: start; }
  .app-screen--app-check-in .checkin-photo { position: sticky; top: 0; min-height: 0; height: clamp(420px, calc(100vh - 230px), 620px); }

  /* -- Progress: triptych, then measured metrics | trend, then direction |
        film action ----------------------------------------------------------- */
  .app-screen--app-progress .member-screen > section { column-gap: 20px; }
  .app-shell[data-gm-concept="progress-twin"] .member-screen .progress-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .app-screen--app-progress .progress-metrics .metric-card { min-height: 0; }
  .app-screen--app-progress .member-screen > section > .progress-trend { grid-column: 1; align-self: stretch; margin: 0; }
  .app-screen--app-progress .member-screen > section > .context-action-tray { grid-column: 2; align-self: stretch; margin: 0; }

  /* -- History: metrics | check-in timeline, then the two ledgers --------- */
  .app-screen--app-history .member-screen {
    display: grid;
    grid-template-columns: minmax(220px, 260px) minmax(0, 1fr);
    gap: 20px;
    align-content: start;
  }
  .app-screen--app-history .member-screen > * { grid-column: 1 / -1; min-width: 0; }
  .app-shell[data-gm-concept="history"] .member-screen > .metrics-grid { grid-column: 1; grid-template-columns: minmax(0, 1fr); }
  .app-shell[data-gm-concept="history"] .member-screen > .metrics-grid .metric-card { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-height: 0; padding: 14px 16px; }
  .app-shell[data-gm-concept="history"] .member-screen > .metrics-grid .metric-value { margin: 0; text-align: right; }
  .app-screen--app-history .member-screen > #history-progress { grid-column: 2; }
  /* The check-in timeline wraps into chronological rows instead of a
     hidden-scrollbar pager. */
  .app-shell[data-gm-concept="history"] #history-progress .history-strip { flex-wrap: wrap; overflow: visible; }

  /* -- Roadmap: sticky north star | compact week timeline ----------------- */
  .app-shell[data-gm-concept="roadmap"] .member-screen { grid-template-columns: minmax(300px, .78fr) minmax(0, 1.22fr); gap: 20px 28px; }
  .app-shell[data-gm-concept="roadmap"] .roadmap-north-star {
    grid-row: span 2;
    align-self: start;
    position: sticky;
    top: 0;
    height: clamp(420px, calc(100vh - 110px), 700px);
    min-height: 0;
  }
  .app-shell[data-gm-concept="roadmap"] .timeline { gap: 8px; }
  .app-shell[data-gm-concept="roadmap"] .roadmap-actions { grid-column: 2; }

  /* -- Settings: identity (avatar + coach) | preferences; privacy | delete - */
  .app-shell[data-gm-concept="settings"] .profile-row {
    grid-template-columns: minmax(260px, .8fr) minmax(0, 1.2fr);
    grid-template-rows: auto 1fr;
    gap: 16px 24px;
    align-items: start;
  }
  .app-shell[data-gm-concept="settings"] .profile-details { display: contents; }
  .app-shell[data-gm-concept="settings"] .profile-avatar { grid-column: 1; grid-row: 1; justify-self: center; }
  .app-shell[data-gm-concept="settings"] .coach-preferences-card { grid-column: 1; grid-row: 2; }
  .app-shell[data-gm-concept="settings"] .profile-details > .glass-card { grid-column: 2; grid-row: 1 / span 2; }
  .app-screen--app-settings .member-screen { grid-template-columns: minmax(0, 1.28fr) minmax(0, .72fr); gap: 20px 24px; align-content: start; }

  /* -- Membership / Change Future: the scene holds the viewport ----------- */
  .app-shell[data-gm-concept="membership"] .member-screen,
  .app-shell[data-gm-concept="change-future"] .member-screen { gap: 20px 28px; }
  .app-shell[data-gm-concept="membership"] .membership-identity-stage,
  .app-shell[data-gm-concept="change-future"] .change-future-stage { height: clamp(420px, calc(100vh - 170px), 620px); min-height: 0; }
  .app-shell[data-gm-concept="membership"] .membership-grid { align-content: start; }

  /* -- Weekly review: two independent columns, no stretched empty card ---- */
  .app-shell[data-gm-concept="weekly-review"] .review-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 20px; align-items: start; }

  /* -- Phase: scene | status card ----------------------------------------- */
  .app-shell[data-gm-concept="phase-complete"] .member-screen {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
    gap: 20px 24px;
    align-content: start;
    align-items: start;
  }
  .app-shell[data-gm-concept="phase-complete"] .member-screen > * { grid-column: 1 / -1; min-width: 0; }
  .app-shell[data-gm-concept="phase-complete"] .member-screen > .phase-demo-stage { grid-column: 1; }
  .app-shell[data-gm-concept="phase-complete"] .member-screen > .phase-demo-stage + .glass-card { grid-column: 2; }

  /* -- Future Film: the film and its actions share the first fold -------- */
  .app-shell[data-gm-concept="future-film"] .film-player { max-height: calc(100vh - 260px); min-height: 380px; aspect-ratio: auto; }

  /* -- Stack: horizontal product cards in a responsive grid --------------- */
  .app-shell[data-gm-concept="stack"] .product-grid { grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); gap: 20px; max-width: 980px; }
  .app-shell[data-gm-concept="stack"] .product-card {
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    grid-template-rows: repeat(5, auto) 1fr;
    column-gap: 20px;
    align-content: start;
    min-height: 0;
  }
  .app-shell[data-gm-concept="stack"] .product-card > * { grid-column: 2; min-width: 0; }
  .app-shell[data-gm-concept="stack"] .product-card > .product-art { grid-column: 1; grid-row: 1 / -1; height: auto; min-height: 180px; margin: 0; }
  .app-shell[data-gm-concept="stack"] .product-card > .eyebrow { margin-top: 6px; }

  /* -- Install: device scene | instructions ------------------------------- */
  .app-shell[data-gm-concept="install"] .review-card {
    display: grid;
    grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
    grid-template-rows: repeat(5, auto) 1fr;
    column-gap: 32px;
    align-items: start;
  }
  .app-shell[data-gm-concept="install"] .review-card > * { grid-column: 2; }
  .app-shell[data-gm-concept="install"] .review-card > .install-device-scene { grid-column: 1; grid-row: 1 / -1; margin: 0; align-self: stretch; }
}

/* Nutrition portion picker as a two-column panel (inputs | result and its
 * commit action) once the main column is wide enough (≥1280px); between
 * 1100 and 1279px it keeps the stacked picker. */
@media (min-width: 1280px) {
  .app-shell .food-portion {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
    grid-template-areas:
      "head head"
      "chips macros"
      "amount macros"
      "slider log"
      "limit limit"
      "source source";
    column-gap: 22px;
    padding: 20px 22px;
  }
  .app-shell .food-portion__head { grid-area: head; }
  .app-shell .food-portion__chips { grid-area: chips; flex-wrap: wrap; overflow: visible; }
  .app-shell .food-portion__amount { grid-area: amount; }
  .app-shell .food-portion__slider { grid-area: slider; }
  .app-shell .food-portion__macros { grid-area: macros; align-self: start; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .app-shell .food-portion__limit { grid-area: limit; }
  .app-shell .food-portion__log { grid-area: log; align-self: center; }
  .app-shell .food-portion > .food-source { grid-area: source; }
}

@media (min-width: 1440px) {
  .app-shell .member-screen { gap: 24px; }
  .app-shell .member-composition { gap: 24px; }
  .app-screen--app .member-composition,
  .app-screen--app .hero-grid--media-first { column-gap: 24px; }
  .app-screen--app-workout .workout-layout { grid-template-columns: minmax(0, 280px) minmax(0, 1fr); gap: 24px; }
  .app-screen--app-nutrition .member-composition { grid-template-columns: 340px minmax(0, 1fr); column-gap: 32px; }
}
