
/* The two exported pages carry `min-height:100vh` as an inline style on their
   own root, so their ground covers the viewport. The athlete door is written
   by hand and had no such style — its background stopped at the end of the
   content and the console's ground showed through underneath, which reads as a
   half-rendered page. Set here rather than inline so the hand-written surface
   cannot drift from the exported ones again. */
.mk--door {
  min-height: 100vh;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}


/* The shell class for a public page. `.app` is the console's frame — it pins a
   min-width, a max-width and the console's own ground, all of which are wrong
   for a full-bleed marketing page: the min-width forces horizontal overflow
   that the design root's `overflow-x: clip` then clips, and the max-width
   letterboxes a layout that sets its own. `.app--gate` already does exactly
   this reset for the sign-in screens; this is the same reset for the site.

   Deliberately NOT scoped under .mk — it IS the app shell, not design-system
   content, and it has to win against .app's own rules. */
.app--public {
  display: block;
  min-width: 0;
  max-width: none;
  background: transparent;
}

/* Public marketing surfaces — home, about, athlete door.
 *
 * GENERATED from the approved Claude Design exports' own stylesheets, with one
 * transformation: every selector is scoped under `.mk`. That is not tidiness.
 * The design system ships bare `.btn`, `.card`, `.input`, `.nav` and `.tag`,
 * and this app already has its own `.btn` — unscoped, the marketing sheet
 * would silently restyle every button in the console. `:root`, `html` and
 * `body` rules collapse to `.mk` for the same reason: the design sets a page
 * background and a full token palette, and letting those escape would repaint
 * the app.
 *
 * Consequence worth knowing: these tokens exist ONLY inside `.mk`. A marketing
 * partial rendered outside a `.mk` root will lose its palette rather than
 * inherit the app's — which is the failure you want, because it is visible.
 */

/* Nocturne — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see readme.md. */
/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */

/* cyrillic-ext */

/* cyrillic */

/* greek-ext */

/* greek */

/* vietnamese */

/* latin-ext */

/* latin */



.mk{
  --color-bg: #161826;
  --color-surface: #232532;
  --color-text: #e9e9ed;
  --color-accent: #9184d9; /* review round 7 (Barron): the accent moves to
     the product's blurple — OKLCH hue 289.2, the hue of the app's own Pro
     accent (#9a8fe0, --om-accent-pro) — at the same lightness the steel
     accent held (L 0.660, so the documented ratios survive) and chroma
     in the product blurple's own range (its token sits at C 0.118; the
     accent takes 0.125, from the old steel's 0.030):
     the accent now reads as an accent rather than another neutral. */
  --color-accent-2: #a7a1db; /* the machine-derived stand-in follows: same
     hue, same L 0.734, chroma at the same 2:3 proportion it held */
  --color-divider: color-mix(in srgb, #e9e9ed 16%, transparent);

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. */
  --color-neutral-100: #f3f5fe;
  --color-neutral-200: #e4e7f5;
  --color-neutral-300: #cfd3e5;
  --color-neutral-400: #b2b6ca;
  --color-neutral-500: #9397ab;
  --color-neutral-600: #75798c;
  --color-neutral-700: #595d6c;
  --color-neutral-800: #3f424d;
  --color-neutral-900: #292b31;

  --color-accent-100: #f5f4ff;
  --color-accent-200: #e7e5fe;
  --color-accent-300: #d2cefd;
  --color-accent-400: #b5abfc;
  --color-accent-500: #968ae0;
  --color-accent-600: #796cbf;
  --color-accent-700: #5d5294;
  --color-accent-800: #423a6a;
  --color-accent-900: #2b2741;

  --color-accent-2-100: #f5f4ff;
  --color-accent-2-200: #e7e5fe;
  --color-accent-2-300: #d2cefd;
  --color-accent-2-400: #b5afe8;
  --color-accent-2-500: #9690c9;
  --color-accent-2-600: #7972a9;
  --color-accent-2-700: #5c5783;
  --color-accent-2-800: #423e5d;
  --color-accent-2-900: #2b293a;

  /* Deck section-divider ground — review round 3: saturation as presence.
     Dividers take a saturated deep indigo (hue 277, the neutral ramp's own
     family; C 0.094 — written when the accent held C 0.030, before the
     round-7 blurple raised it past the ground's) with a lighter bloom and
     a ghost tint of the same hue, while the slide grounds stay
     desaturated. Deck-scale fills only — not interface colors. */
  --color-section: #262a60;
  --color-section-glow: #353b80;
  --color-section-ghost: #4c5397;

  --font-heading: "Inter", system-ui, sans-serif;
  --font-heading-weight: 500;
  --font-body: "Inter", system-ui, sans-serif;

  --space-1: 2.8px;
  --space-2: 5.6px;
  --space-3: 8.4px;
  --space-4: 11.2px;
  --space-6: 16.8px;
  --space-8: 22.4px;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 0 0 1px #3f424d;
  --shadow-md: 0 0 0 1px #595d6c, 0 6px 18px rgba(0,0,0,0.55);
  --shadow-lg: 0 0 0 1px #9397ab, 0 16px 40px rgba(0,0,0,0.65);
}.mk{
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}.mk h1, .mk h2, .mk h3, .mk h4{ font-family: var(--font-heading); font-weight: var(--font-heading-weight); }.mk .lighten{mix-blend-mode:lighten;background-color:transparent}

/* ══════════════════════════════════════════════════════════════════════════
   Components — built with the tokens above. Plain CSS
   on plain HTML: no JavaScript, no build step. Each class is documented in
   readme.md and demonstrated in foundations/ and components/.
   ══════════════════════════════════════════════════════════════════════ */

.mk *, .mk *::before, .mk *::after{ box-sizing: border-box; }.mk{ margin: 0; font-size: 15px; line-height: 1.55; font-weight: 400; }.mk h1, .mk h2, .mk h3, .mk h4, .mk h5, .mk h6{
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.12; letter-spacing: -0.015em; margin: 0 0 var(--space-2);
}.mk h1{ font-size: 42px; }.mk h2{ font-size: 32px; }.mk h3{ font-size: 25px; }.mk h4{ font-size: 20px; }.mk h5{ font-size: 16px; }.mk h6{ font-size: 13px; }.mk h6{ letter-spacing: 0.08em; text-transform: uppercase; }.mk p{ margin: 0 0 var(--space-3); }.mk a{ color: var(--color-accent); text-underline-offset: 3px; }.mk img{ display: block; max-width: 100%; }.mk figure{ margin: 0; }.mk figcaption{
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}.mk .text-muted{ color: color-mix(in srgb, var(--color-text) 55%, transparent); }.mk :focus{ outline: none; }.mk :focus-visible{ outline: 2px solid var(--color-accent); outline-offset: 2px; }.mk ::selection{ background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* — rules — */
/* Rules fade to transparent at both ends instead of stopping cleanly — a
   Nocturne signature. The ramp is 48px an end (one deck baseline unit),
   painted from the same divider token. Freestanding rules fade; box
   outlines, in-control separators, and short accent marks stay solid. */
.mk .hr{
  height: 1px; border: 0; margin: var(--space-4) 0;
  background: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent);
}

/* — buttons — */
.mk .btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.2; color: var(--color-text); /* matches the .input's 14px —
     the pair sits side by side in sign-up rows */
  background: transparent; border: 1px solid transparent;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: var(--radius-md);
}.mk .btn svg{ display: block; }.mk .btn:disabled{ opacity: 0.45; cursor: not-allowed; }.mk .btn-primary{ color: var(--color-accent); border-color: var(--color-accent); }.mk .btn-primary:hover{ background: color-mix(in srgb, var(--color-accent) 12%, transparent); }.mk .btn-primary:active{ background: color-mix(in srgb, var(--color-accent) 22%, transparent); }.mk .btn-secondary{ border-color: var(--color-divider); }.mk .btn-secondary:hover{ background: color-mix(in srgb, var(--color-text) 7%, transparent); }.mk .btn-secondary:active{ background: color-mix(in srgb, var(--color-text) 14%, transparent); }.mk .btn-ghost{ color: var(--color-accent); padding-inline: var(--space-1); }.mk .btn-ghost:hover{ background: color-mix(in srgb, var(--color-accent) 10%, transparent); }.mk .btn-ghost:active{ background: color-mix(in srgb, var(--color-accent) 18%, transparent); }.mk .btn-icon{ width: 36px; height: 36px; padding: 0; }.mk .btn-block{ width: 100%; margin-top: var(--space-2); }

/* — forms — */
.mk .field > label{
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}.mk .input{
  width: 100%; min-height: 36px; padding: 6px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}.mk .input:hover{ border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }.mk .input:focus-visible{ border-color: var(--color-accent); outline-offset: 0; }.mk textarea.input{ min-height: 90px; resize: vertical; }.mk .radio{ display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }.mk .radio input, .mk .seg-opt input{
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}.mk .radio .dot{
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}.mk .radio:hover .dot{ border-color: var(--color-accent); }.mk .radio input:checked + .dot{
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}.mk .radio input:focus-visible + .dot{ outline: 2px solid var(--color-accent); outline-offset: 2px; }.mk .seg{
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}.mk .seg-opt{
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; font-size: 13px; cursor: pointer;
}.mk .seg-opt + .seg-opt{ border-left: 1px solid var(--color-divider); }.mk .seg-opt:has(input:checked){ color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }.mk .seg-opt:not(:has(input:checked)):hover{ background: color-mix(in srgb, var(--color-text) 7%, transparent); }.mk .seg-opt:has(input:focus-visible){ outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* — cards — */
.mk .card{
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}.mk .card-kicker{ font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }.mk .card-title{
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; line-height: 1.2;
}.mk .card-body{ margin: 0; font-size: 13px; opacity: 0.8; flex: 1; }.mk .card-meta{
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
}.mk .elev-sm{ box-shadow: var(--shadow-sm); }.mk .elev-md{ box-shadow: var(--shadow-md); }.mk .elev-lg{ box-shadow: var(--shadow-lg); }

/* — tags — */
.mk .tag{
  display: inline-flex; align-items: center; font-size: 11px;
  letter-spacing: 0.02em; padding: 3px 10px;
  border-radius: calc(var(--radius-md) * 0.75);
}.mk .tag-accent{ background: var(--color-accent-800); color: var(--color-accent-100); }.mk .tag-accent-2{ background: var(--color-accent-2-800); color: var(--color-accent-2-100); }.mk .tag-neutral{ background: var(--color-neutral-800); color: var(--color-neutral-100); }.mk .tag-outline{ border: 1px solid var(--color-accent); color: var(--color-accent); }

/* — navigation — */
.mk .nav{
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: none;
}.mk .nav-brand{
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; margin-right: auto;
}.mk .nav a{ color: inherit; text-decoration: none; font-size: 14px; }.mk .nav a:hover, .mk .nav a[aria-current='page']{ color: var(--color-accent); }

/* — tables — */
.mk .table{ width: 100%; border-collapse: collapse; font-size: 14px; }.mk .table th{
  text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  padding: var(--space-2); border-bottom: 1px solid transparent; /* keeps layout; the row paints the fading rule */
}.mk .table td{
  padding: var(--space-2);
  border-bottom: 1px solid transparent;
}
/* Row rules as row-level strips so the end-fade spans the row, not each cell. */
.mk .table thead tr{
  background: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}.mk .table tbody tr{
  background: linear-gradient(to right,
    transparent, color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
    color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}.mk .table tbody tr:hover{
  /* the hover tint layers over the row rule, which keeps painting */
  background:
    linear-gradient(color-mix(in srgb, var(--color-text) 4%, transparent),
                    color-mix(in srgb, var(--color-text) 4%, transparent)) no-repeat 0 0 / 100% 100%,
    linear-gradient(to right,
      transparent, color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
      color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}

/* — dialog — */
.mk .dialog-backdrop{
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}.mk .dialog{
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}.mk .dialog-title{
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px;
}.mk .dialog-body{ font-size: 14px; opacity: 0.85; }.mk .dialog-actions{ display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

/* TeleJACT app palette: warm paper ground, sage accent — retuned Nocturne tokens */
  .mk{
    --color-bg: #eae7dd;
    --color-surface: #f7f6f2;
    --color-text: #2e2f29;
    --color-accent: #7d9159;
    --color-accent-2: #7d9159;
    --color-divider: color-mix(in srgb, #2e2f29 14%, transparent);
    --color-neutral-100: #2e2f29;
    --color-neutral-200: #43443c;
    --color-neutral-300: #5b5c52;
    --color-neutral-600: #a9a89c;
    --color-neutral-800: #d8d5c9;
    --color-neutral-900: #eae7dd;
    --color-accent-100: #f2f5ec;
    --color-accent-300: #57683a;
    --color-accent-400: #6b7f4b;
    --color-accent-800: #e4ead9;
    --color-section: #dfdccf;
    --shadow-sm: 0 0 0 1px color-mix(in srgb, #2e2f29 10%, transparent);
    --shadow-md: 0 0 0 1px color-mix(in srgb, #2e2f29 12%, transparent), 0 6px 18px rgba(46,47,41,0.08);
    --shadow-lg: 0 0 0 1px color-mix(in srgb, #2e2f29 14%, transparent), 0 16px 40px rgba(46,47,41,0.12);
  }.mk{ scroll-behavior: smooth; }.mk{ margin: 0; background: var(--color-bg); }.mk a:hover{ color: var(--color-accent-400); }.mk .btn-primary{ background: var(--color-accent); border-color: var(--color-accent); color: #f7f6f2; }.mk .btn-primary:hover{ background: var(--color-accent-400); border-color: var(--color-accent-400); }.mk .btn-primary:active{ background: var(--color-accent-300); border-color: var(--color-accent-300); }.mk .btn-ghost{ color: var(--color-accent-300); }.mk .tag-outline{ color: var(--color-accent-300); border-color: color-mix(in srgb, var(--color-accent) 55%, transparent); }.mk .btn{ transition: background .18s ease, border-color .18s ease, transform .18s ease; }.mk .btn:hover{ transform: translateY(-1px); }
/* content is visible by default; reveals engage only once the logic class confirms JS is running */
  html[data-reveal-on] .mk [data-reveal]{ opacity: 0; transform: translateY(16px); transition: opacity .7s cubic-bezier(.22,.7,.2,1), transform .7s cubic-bezier(.22,.7,.2,1); }html[data-reveal-on] .mk [data-reveal][data-in]{ opacity: 1; transform: none; }html[data-reveal-on] .mk [data-reveal][data-delay="1"]{ transition-delay: .09s; }html[data-reveal-on] .mk [data-reveal][data-delay="2"]{ transition-delay: .18s; }html[data-reveal-on] .mk [data-reveal][data-delay="3"]{ transition-delay: .27s; }.mk .door{ transition: box-shadow .25s ease, transform .25s ease; }.mk .door:hover{ transform: translateY(-3px); box-shadow: var(--shadow-md); }.mk .feat{ transition: background .25s ease, box-shadow .25s ease; }.mk .feat:hover{ background: var(--color-surface); box-shadow: var(--shadow-md); }.mk .step{ opacity: .42; transition: opacity .45s ease, border-color .45s ease; border-left: 2px solid transparent; }.mk .step[data-active]{ opacity: 1; border-left-color: var(--color-accent); }.mk .step-num{ transition: color .45s ease; }.mk .step[data-active] .step-num{ color: var(--color-accent-300); }.mk .screen{ position: absolute; inset: 0; opacity: 0; transform: translateY(10px) scale(.99); transition: opacity .5s ease, transform .5s ease; pointer-events: none; }.mk .screen[data-active]{ opacity: 1; transform: none; }.mk .navlink{ position: relative; }.mk .navlink::after{ content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 1px; background: var(--color-accent); transform: scaleX(0); transform-origin: left; transition: transform .25s ease; }.mk .navlink:hover::after{ transform: scaleX(1); }@media (prefers-reduced-motion: reduce){html[data-reveal-on] .mk [data-reveal]{ opacity: 1; transform: none; transition: none; }.mk .step{ opacity: 1; }
  }.mk{
    --color-bg: #eae7dd;
    --color-surface: #f7f6f2;
    --color-text: #2e2f29;
    --color-accent: #7d9159;
    --color-accent-2: #7d9159;
    --color-divider: color-mix(in srgb, #2e2f29 14%, transparent);
    --color-neutral-100: #2e2f29;
    --color-neutral-200: #43443c;
    --color-neutral-300: #5b5c52;
    --color-neutral-600: #a9a89c;
    --color-neutral-800: #d8d5c9;
    --color-neutral-900: #eae7dd;
    --color-accent-100: #f2f5ec;
    --color-accent-300: #57683a;
    --color-accent-400: #6b7f4b;
    --color-accent-800: #e4ead9;
    --color-section: #dfdccf;
    --shadow-sm: 0 0 0 1px color-mix(in srgb, #2e2f29 10%, transparent);
    --shadow-md: 0 0 0 1px color-mix(in srgb, #2e2f29 12%, transparent), 0 6px 18px rgba(46,47,41,0.08);
    --shadow-lg: 0 0 0 1px color-mix(in srgb, #2e2f29 14%, transparent), 0 16px 40px rgba(46,47,41,0.12);
  }.mk .placeholder{ background: color-mix(in srgb, var(--color-accent) 14%, transparent); box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--color-accent) 55%, transparent); padding: 0 3px; border-radius: 3px; }


/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE LAYER
   ══════════════════════════════════════════════════════════════════════════

   Everything above this line was generated from the design export and had no
   width breakpoint of any kind — the whole stylesheet's only `@media` was a
   `prefers-reduced-motion` block. A phone got the desktop layout: a 58px hero
   on a 390px screen, the how-it-works mockup squeezed to ~120px beside its
   text, and /#/about overflowing to 528px of horizontal scroll inside a 320px
   viewport, because its 220px sidebar column left the prose about 20px.

   ── why these rules are `!important` ─────────────────────────────────────

   The exported markup carries its layout as inline styles and is kept
   verbatim so a redesign can be re-dropped (see the header comment in
   views/home.js). An inline style cannot be beaten by specificity — no
   selector, however long, outranks the style attribute. `!important` in an
   author stylesheet is the one thing that does. So the `!important` here is
   not a shortcut around a specificity fight; it is the only mechanism that
   overrides an inline style at all, and it is what lets the export stay
   untouched. Rules that override nothing inline are written without it.

   ── why min-width, when the base case is inline desktop values ───────────

   Mobile-first means the phone is the base case. But the base case is written
   into the markup as desktop inline styles, so a narrow override has to hold
   at every width unless something puts the desktop value back. Restating the
   desktop numbers in a `min-width` block would mean two copies of every value,
   drifting apart at the next export.

   Instead the breakpoints move only *tokens*, and each rule expresses its
   value in terms of a token such that the wide setting is the identity:
   `calc(96px * var(--mk-rhythm))` with `--mk-rhythm: 1` is exactly 96px,
   `max(13px, var(--mk-text-floor))` with the floor at `0px` is exactly 13px.
   Desktop therefore computes byte-identical to the export, provably, while
   the narrow case is a single token away.

   Breakpoints: 48rem (768px) is the layout breakpoint — below it the site is
   one column. 72rem (1152px) is where the 1120px container stops being
   gutter-constrained; the token layer is declared there so a future desktop
   step has a home, but it deliberately carries no rules today, because every
   candidate would have changed what 1024px already renders correctly.

   Scope: every selector below starts at `.mk`, and every custom property is
   declared on `.mk`. Nothing here can reach the console.
   ══════════════════════════════════════════════════════════════════════════ */

.mk {
  /* Layout */
  --mk-gutter: 20px;                          /* section side padding */
  --mk-rhythm: 0.62;                          /* vertical section rhythm */
  --mk-nav-wrap: wrap;
  --mk-cols-280: 1fr;                         /* the hero's two door cards */
  --mk-cols-side: minmax(0, 1fr);             /* about's label/prose split */
  --mk-side-gap: 12px;

  /* How it works */
  --mk-cols-hiw: minmax(0, 1fr);
  --mk-hiw-gap: 28px;
  --mk-hiw-order: -1;                         /* mockup ahead of the steps */
  --mk-hiw-mock-pos: static;
  --mk-hiw-step-gap-k: 0.27;                  /* × the export's 150px  → 40px */
  --mk-hiw-pad-t-k: 0.4;                      /* × the export's  40px  → 16px */
  --mk-hiw-pad-b-k: 0.09;                     /* × the export's 300px  → 27px */
  --mk-mock-margin: auto;                     /* centre the phone in its column */
  --mk-glow-display: none;
  --mk-step-opacity: 1;
  --mk-screen-base: 1;                        /* the mockup holds one screen  */
  --mk-screen-transform: none;
  --mk-screen-rest-display: none;

  /* Type floors. Reading text lands at 14px; uppercase tracked micro-labels
     land at 12px, because a 14px tracked kicker competes with the 20px title
     it is labelling. Both are 0 above the breakpoint, so `max()` returns the
     design's own size unchanged. */
  --mk-text-floor: 14px;
  --mk-label-floor: 12px;

  /* Touch. 44px is the floor; `auto`/`0px` above the breakpoint restore the
     export's own control sizes exactly. */
  --mk-tap: 44px;
  --mk-tap-pad: 12px;
  --mk-input-h: 44px;
  --mk-input-fs: 16px;                        /* <16px makes iOS Safari zoom on focus */

  /* Footer */
  --mk-stack: column;
  --mk-stack-align: flex-start;
  --mk-footer-links-align: stretch;           /* full-width rows, so a short
                                                 link like "About" is still a
                                                 44px-wide target */
  --mk-footer-link-gap: 0px;
}

@media (min-width: 48rem) {
  .mk {
    --mk-gutter: 32px;
    --mk-rhythm: 1;
    --mk-nav-wrap: nowrap;
    --mk-cols-280: repeat(auto-fit, minmax(280px, 1fr));
    --mk-cols-side: minmax(0, 220px) minmax(0, 1fr);
    --mk-side-gap: 40px;

    --mk-cols-hiw: minmax(0, 1fr) minmax(0, .8fr);
    --mk-hiw-gap: 56px;
    --mk-hiw-order: 0;
    --mk-hiw-mock-pos: sticky;
    --mk-hiw-step-gap-k: 1;
    --mk-hiw-pad-t-k: 1;
    --mk-hiw-pad-b-k: 1;
    --mk-mock-margin: 0px;
    --mk-glow-display: block;
    --mk-step-opacity: .42;
    --mk-screen-base: 0;
    --mk-screen-transform: translateY(10px) scale(.99);
    --mk-screen-rest-display: block;

    --mk-text-floor: 0px;
    --mk-label-floor: 0px;

    --mk-tap: auto;
    --mk-tap-pad: 0px;
    --mk-input-h: 36px;
    --mk-input-fs: 14px;

    --mk-stack: row;
    --mk-stack-align: center;
    --mk-footer-links-align: center;
    --mk-footer-link-gap: 16px;
  }
}

@media (min-width: 72rem) {
  /* The container reaches its 1120px cap here and stops being gutter-bound.
     No token moves: everything the 48rem step restores is already the
     design's own value, and lowering anything between 768px and 1152px would
     change a width that renders correctly today. Declared so the step exists
     when a desktop-only refinement needs one. */
  .mk { /* intentionally empty — see above */ }
}

/* The phone in "how it works" is an illustration of the app, drawn at a fixed
   300 × 370. Floors and tap targets applied to its interior would push its
   content past the frame's own `overflow:hidden` and clip it. Zeroing the
   tokens here rather than writing an exception into every rule means one
   place decides what "inside the illustration" means — and because each rule
   is written as `max(base, token)` / `calc(base * token)`, zeroing them makes
   every rule below a no-op inside the frame. */
.mk [style*="border-radius:34px"] {
  --mk-text-floor: 0px;
  --mk-label-floor: 0px;
  --mk-tap: auto;
  --mk-input-h: 36px;
  --mk-input-fs: 14px;
}

/* ── page frame ──────────────────────────────────────────────────────────
   One gutter for every top-level band, on all three public surfaces. */
.mk > header,
.mk > section,
.mk > main,
.mk > footer {
  padding-left: var(--mk-gutter) !important;
  padding-right: var(--mk-gutter) !important;
}

/* Vertical rhythm, keyed on the export's own padding declarations so the
   number being scaled is visible in the selector. */
.mk [style*="padding:64px 32px 0"]   { padding-top: calc(64px * var(--mk-rhythm)) !important; }
.mk [style*="padding:96px 32px 0"]   { padding-top: calc(96px * var(--mk-rhythm)) !important; }
.mk [style*="padding:88px 32px 0"]   { padding-top: calc(88px * var(--mk-rhythm)) !important; }
.mk [style*="padding:80px 32px 56px"]{ padding-top: calc(80px * var(--mk-rhythm)) !important;
                                       padding-bottom: calc(56px * var(--mk-rhythm)) !important; }
.mk [style*="padding:56px 32px 72px"]{ padding-top: calc(56px * var(--mk-rhythm)) !important;
                                       padding-bottom: calc(72px * var(--mk-rhythm)) !important; }

/* ── type scale ──────────────────────────────────────────────────────────
   Every clamp's upper bound is the export's own size and is reached below
   768px, so from the first breakpoint up the type is identical to today.
   Keyed on the inline declaration because the exported markup has no classes
   on its headings. */
.mk [style*="font-size:58px"] { font-size: clamp(2.2rem,  8.6vw, 3.625rem) !important; }
.mk [style*="font-size:52px"] { font-size: clamp(2rem,    7.6vw, 3.25rem)  !important; }
.mk [style*="font-size:38px"] { font-size: clamp(1.75rem, 5.6vw, 2.375rem) !important; }
.mk [style*="font-size:36px"] { font-size: clamp(1.6875rem, 5.3vw, 2.25rem) !important; }
.mk [style*="font-size:32px"] { font-size: clamp(1.5625rem, 4.7vw, 2rem)   !important; }
.mk [style*="font-size:30px"] { font-size: clamp(1.5rem,  4.4vw, 1.875rem) !important; }
.mk [style*="font-size:22px"] { font-size: clamp(1.125rem, 3.2vw, 1.375rem) !important; }
.mk [style*="font-size:19px"] { font-size: clamp(1rem,    2.8vw, 1.1875rem) !important; }
.mk [style*="font-size:18px"] { font-size: clamp(0.9375rem, 2.65vw, 1.125rem) !important; }
.mk [style*="font-size:17px"] { font-size: clamp(0.9375rem, 2.5vw, 1.0625rem) !important; }

/* The design system's own heading defaults, for any marketing markup that
   does not carry an inline size. Same rule: the clamp tops out at the value
   the sheet already sets, below the first breakpoint. */
.mk h1 { font-size: clamp(2rem,     7.6vw, 2.625rem); }
.mk h2 { font-size: clamp(1.75rem,  6vw,   2rem); }
.mk h3 { font-size: clamp(1.375rem, 4.8vw, 1.5625rem); }
.mk h4 { font-size: clamp(1.125rem, 3.8vw, 1.25rem); }

/* ── legibility floors ───────────────────────────────────────────────────
   Reading text to 14px. The `:not(…uppercase)` guard is what separates prose
   from the design's tracked micro-labels, which are handled below at 12px —
   both live at these same inline sizes. */
.mk [style*="font-size:13px"]:not([style*="text-transform:uppercase"]) { font-size: max(13px, var(--mk-text-floor)) !important; }
.mk [style*="font-size:12px"]:not([style*="text-transform:uppercase"]):not(.step-num) { font-size: max(12px, var(--mk-text-floor)) !important; }
.mk [style*="font-size:11px"]:not([style*="text-transform:uppercase"]) { font-size: max(11px, var(--mk-text-floor)) !important; }

.mk .card-body  { font-size: max(13px, var(--mk-text-floor)); }
.mk .card-meta  { font-size: max(11px, var(--mk-text-floor)); }
.mk figcaption  { font-size: max(11px, var(--mk-text-floor)); }
.mk .field > label { font-size: max(12px, var(--mk-text-floor)); }
.mk .radio, .mk .seg-opt { font-size: max(13px, var(--mk-text-floor)); }

/* Tracked uppercase labels: 12px, not 14px. */
.mk .card-kicker { font-size: max(10px, var(--mk-label-floor)); }
.mk .tag         { font-size: max(11px, var(--mk-label-floor)); }
.mk h6           { font-size: max(13px, var(--mk-label-floor)); }
.mk [style*="font-size:10px"] { font-size: max(10px, var(--mk-label-floor)) !important; }
.mk .step-num    { font-size: max(12px, var(--mk-label-floor)) !important; }

/* ── touch targets ───────────────────────────────────────────────────────
   `.btn` is `inline-flex; align-items:center` already, so a min-height
   centres its label rather than stranding it at the top of a taller box. */
.mk .btn   { min-height: var(--mk-tap); }
.mk .input { min-height: var(--mk-input-h); font-size: var(--mk-input-fs); }

/* Nav and footer links are flex items, so they are already blockified —
   vertical padding grows the hit box without changing `display`, which is
   what keeps the wide case identical. */
.mk > header .navlink,
.mk > header .nav-brand a,
.mk > footer a {
  padding-top: var(--mk-tap-pad);
  padding-bottom: var(--mk-tap-pad);
}
/* "Home" and "About" set 39px of text. Tall enough after the padding above,
   but a target is two-dimensional, so the box gets a floor on the short axis
   too. The label stays left-aligned inside it; only the hit area grows. */
.mk > header .navlink { min-width: var(--mk-tap); }

/* ── navigation ──────────────────────────────────────────────────────────
   Below the breakpoint the marketing header keeps the brand and the Sign in
   button; Athletes, Coaches and About come off the row. Nothing is lost:
   Athletes and Coaches are in-page jumps to the two door cards, which on one
   column are the next thing on screen, and About is already in the footer.

   The athlete door is excluded. Its nav is Home and About with no Sign in
   button beside them, so hiding those two would leave a header with no way
   back out of the page. */
.mk:not(.mk--door) > header .navlink { display: var(--mk-navlink-display, none); }
@media (min-width: 48rem) { .mk:not(.mk--door) > header .navlink { display: block; } }

.mk > header,
.mk > header nav { flex-wrap: var(--mk-nav-wrap); }

/* ── hero door cards ─────────────────────────────────────────────────────
   `auto-fit` with a 280px minimum fits a 320px viewport to the pixel, which
   is the kind of margin a scrollbar or a rounding difference eats. One
   column below the breakpoint is not a fit, it is a decision. */
.mk [style*="repeat(auto-fit, minmax(280px, 1fr))"] { grid-template-columns: var(--mk-cols-280) !important; }

/* ── about: label / prose split ──────────────────────────────────────────
   This is the 528px overflow. A fixed 220px label column plus a 40px gap
   inside a 320px viewport leaves the prose ~20px, and a `minmax(0,1fr)`
   track will not shrink text below its longest word — so the section pushed
   the document wider than the screen. */
.mk [style*="minmax(0,220px)"] {
  grid-template-columns: var(--mk-cols-side) !important;
  gap: var(--mk-side-gap) !important;
}

/* ── how it works ────────────────────────────────────────────────────────
   One column below the breakpoint, with the phone ordered ahead of the steps
   so the illustration reads before the list it illustrates.

   The mockup drops out of `position:sticky` there. In a single-column grid
   its row is only as tall as the mockup itself, so sticky has no travel and
   pinning it would do nothing anyway; leaving it sticky just costs a
   compositor layer. The consequence, stated plainly: the scroll-driven
   screen-switching is inert on a phone. The phone shows the invite screen
   above step 01, which is the pairing the section opens with.

   The phone keeps its designed 300px and centres rather than stretching —
   a 350px-wide, 370px-tall phone stops reading as a phone. */
.mk [style*="grid-template-columns:minmax(0,1fr) minmax(0,.8fr)"] {
  grid-template-columns: var(--mk-cols-hiw) !important;
  gap: var(--mk-hiw-gap) !important;
}
.mk [style*="grid-template-columns:minmax(0,1fr) minmax(0,.8fr)"] > div:nth-child(2) {
  order: var(--mk-hiw-order);
}
.mk [style*="position:sticky;top:96px"] { position: var(--mk-hiw-mock-pos) !important; }
.mk [style*="max-width:300px"] { margin-left: var(--mk-mock-margin) !important; margin-right: var(--mk-mock-margin) !important; }

/* The deck-scale rhythm the steps column carries — a 150px gap and 300px of
   trailing padding — exists to pace three steps against a pinned mockup. With
   nothing pinned it is just 490px of empty screen. The three base numbers are
   mirrored from the export; a re-export that retunes them should retune these. */
.mk [style*="gap:150px"] {
  gap: calc(150px * var(--mk-hiw-step-gap-k)) !important;
  padding-top: calc(40px * var(--mk-hiw-pad-t-k)) !important;
  padding-bottom: calc(300px * var(--mk-hiw-pad-b-k)) !important;
}

/* The accent bloom behind the phone is anchored to the mockup's left edge and
   drawn 360px wide. Against a centred phone in a 320px column it is neither
   behind it nor on screen. It is decoration; it sits out the narrow case. */
.mk [style*="radial-gradient(closest-side"] { display: var(--mk-glow-display) !important; }

/* Dimming the inactive steps to 42% signals "the mockup is showing a
   different one". With the mockup not tracking them, it signals nothing and
   costs contrast on the two steps out of three that are always inactive. The
   active step keeps its accent rule — that selector outranks this one. */
.mk .step { opacity: var(--mk-step-opacity); }

/* With the mockup no longer tracking the steps, the scroll handler still
   picks an active step and still switches the phone to match it — so the
   illustration sitting above step 01 was showing step 03's logged-sets
   screen. A picture that contradicts the words beside it is worse than a
   still one, so on one column the phone holds the invite screen, which is
   what step 01 describes and what the (inert, at every width) progress dots
   below it already claim.

   `--mk-screen-base` is the opacity `.mk .screen` already sets; the
   `[data-active]` rule above still wins at 1, so the wide case is untouched
   and the JS keeps driving it. The other two screens leave the box entirely
   rather than stacking transparently on top of the one being read. */
.mk .screen { opacity: var(--mk-screen-base); transform: var(--mk-screen-transform); }
.mk .screen:not([data-screen="0"]) { display: var(--mk-screen-rest-display); }

/* ── footer ──────────────────────────────────────────────────────────────
   Stacks, and takes the links the header gave up. */
.mk > footer > div {
  flex-direction: var(--mk-stack) !important;
  align-items: var(--mk-stack-align) !important;
}
.mk > footer > div > div {
  flex-direction: var(--mk-stack) !important;
  align-items: var(--mk-footer-links-align) !important;
  gap: var(--mk-footer-link-gap) !important;
}
