/* =========================================================================
   AMBSIENTE production shell — design tokens and navigation grammar.

   These values are the Gate 1 accepted system (Master §13.5 CANON), copied here
   as a PRODUCTION asset rather than imported from the Phase 1B prototype.
   The prototype must stay an isolated design reference with no build or runtime
   coupling to production (Phase 2 brief §4.3), so the tokens are duplicated
   deliberately. Both sides trace to Master §13.5.

   Scope: tokens, the authenticated shell chrome and the login surface. Feature
   screens belong to Phases 4-6 and are not built here.
   ========================================================================= */

:root {
  /* ---- surfaces: warm black through raised panel ---- */
  --bg-deep: #070605;
  --bg-base: #0c0a09;
  --bg-raised: #14100e;
  --bg-elevated: #1c1613;
  --bg-inset: #090706;

  /* ---- hairlines ---- */
  --line-faint: rgba(245, 239, 232, 0.065);
  --line: rgba(245, 239, 232, 0.115);
  --line-strong: rgba(245, 239, 232, 0.19);
  --line-accent: rgba(232, 161, 92, 0.3);

  /* ---- text. --text-tertiary is the AA-corrected value (amendment B-1) ---- */
  --text-primary: #f5efe8;
  --text-secondary: #a79e95;
  --text-tertiary: #8a8179;
  --text-inverse: #14100d;

  /* ---- copper accent family ---- */
  --accent: #e8a15c;
  --accent-bright: #f7c68a;
  --accent-deep: #c2703a;
  --accent-ember: #8a4a28;
  --accent-glow: rgba(232, 161, 92, 0.16);
  --accent-veil: rgba(232, 161, 92, 0.07);

  /* ---- status: muted, never traffic-light theatrics ---- */
  /* Athlete may use the restrained cyan digital-analysis accent (Phase 6 3.5). */
  --cyan: #74d7e8;
  --cyan-dim: #4f9fb4;
  --ok: #7fa37a;
  --caution: #d9a441;
  --caution-veil: rgba(217, 164, 65, 0.13);
  --alert: #c4614b;
  --alert-veil: rgba(196, 97, 75, 0.13);

  /* ---- radii / spacing ---- */
  --r-sm: 7px;
  --r-md: 11px;
  --r-lg: 15px;
  --r-xl: 19px;
  --r-pill: 999px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  /* ---- type ---- */
  --font-ui: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  --font-editorial: ui-serif, Georgia, 'Times New Roman', serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  --fs-tiny: 11px;
  --fs-xs: 12.5px;
  --fs-sm: 14px;
  --fs-base: 15.5px;
  --fs-lg: 18px;
  --fs-xl: 22px;
  --fs-2xl: 28px;
  --fs-3xl: 38px;
  --track-tight: -0.015em;

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --t-micro: 140ms;
}

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

html,
body {
  min-height: 100%;
}

body {
  margin: 0;
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--fs-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.num {
  font-variant-numeric: tabular-nums;
}

a {
  color: var(--accent);
}

/* =============================================================== login ==== */
.login {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--s-5);
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(46, 34, 26, 0.55), transparent 60%),
    var(--bg-base);
}
.login__card {
  width: min(420px, 100%);
  padding: var(--s-6);
  border-radius: var(--r-xl);
  background: var(--bg-raised);
  border: 1px solid var(--line-faint);
  box-shadow: 0 40px 90px -44px rgba(0, 0, 0, 0.95);
}
.login__brand {
  font-size: var(--fs-tiny);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--accent);
}
.login__title {
  font-family: var(--font-editorial);
  font-size: var(--fs-2xl);
  letter-spacing: var(--track-tight);
  margin: var(--s-3) 0 var(--s-2);
  font-weight: 400;
}
.login__sub {
  font-size: var(--fs-xs);
  color: var(--text-tertiary);
  margin: 0 0 var(--s-5);
}
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: var(--s-4);
}
.field > span {
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.field input {
  height: 40px;
  padding: 0 12px;
  border-radius: var(--r-sm);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
  color: var(--text-primary);
  font-size: var(--fs-sm);
  font-family: inherit;
}
.field input:focus {
  outline: none;
  border-color: var(--line-accent);
}
.btn {
  height: 40px;
  padding: 0 18px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text-primary);
  font-size: var(--fs-xs);
  font-family: inherit;
  cursor: pointer;
  transition: border-color var(--t-micro) var(--ease);
}
.btn:hover {
  border-color: var(--line-strong);
}
.btn--primary {
  width: 100%;
  border: none;
  color: var(--text-inverse);
  font-weight: 600;
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
}
.notice {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  margin-bottom: var(--s-4);
  border: 1px solid var(--alert);
  background: var(--alert-veil);
  color: var(--text-primary);
}
.notice--caution {
  border-color: rgba(217, 164, 65, 0.4);
  background: var(--caution-veil);
}

/* =============================================================== shell ==== */
.shell {
  display: grid;
  grid-template-columns: 68px 1fr;
  min-height: 100vh;
}
.rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-4) 0;
  background: var(--bg-deep);
  border-right: 1px solid var(--line-faint);
}
.rail__mark {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--accent);
  border: 1px solid var(--line-accent);
  background: var(--accent-veil);
  font-family: var(--font-editorial);
  font-size: 14px;
  margin-bottom: var(--s-4);
}
.rail__link {
  width: 52px;
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  border-radius: var(--r-sm);
  color: var(--text-tertiary);
  text-decoration: none;
  font-size: 8.5px;
  letter-spacing: 0.06em;
  text-align: center;
}
.rail__link:hover {
  color: var(--text-secondary);
  background: rgba(245, 239, 232, 0.03);
}
.rail__link.is-on {
  color: var(--accent);
  background: var(--accent-veil);
}
.rail__spacer {
  flex: 1;
}

.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.topbar {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding: var(--s-3) var(--s-5);
  border-bottom: 1px solid var(--line-faint);
  background: var(--bg-deep);
}
.topbar__title {
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--track-tight);
}
.topbar__spacer {
  flex: 1;
}
.topbar__who {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.topbar__form {
  display: inline;
}

.wrap {
  padding: var(--s-5);
  max-width: 1600px;
  width: 100%;
}
.panel {
  background: var(--bg-raised);
  border: 1px solid var(--line-faint);
  border-radius: var(--r-lg);
}
.panel__pad {
  padding: var(--s-5);
}
.label {
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Placeholder state for feature areas Phase 2 deliberately does not build. */
.placeholder__title {
  font-family: var(--font-editorial);
  font-size: var(--fs-3xl);
  letter-spacing: var(--track-tight);
  font-weight: 400;
  margin: var(--s-3) 0 var(--s-2);
}
.placeholder__lede {
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  max-width: 70ch;
  line-height: 1.62;
  margin: 0 0 var(--s-5);
}
.placeholder__tag {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--caution);
  background: var(--caution-veil);
  border: 1px solid rgba(217, 164, 65, 0.3);
}
.placeholder__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.placeholder__list li {
  position: relative;
  padding-left: 16px;
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  line-height: 1.6;
}
.placeholder__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 7px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--text-tertiary);
}

/* ============================================================== status ==== */
.status {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s-3);
  margin-top: var(--s-4);
}
.status__item {
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  border: 1px solid var(--line-faint);
  border-left: 2px solid var(--line);
}
.status__item.is-ok {
  border-left-color: var(--ok);
}
.status__item.is-bad {
  border-left-color: var(--alert);
}
.status__k {
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.status__v {
  font-size: var(--fs-lg);
  font-weight: 500;
  margin-top: 4px;
}
.status__detail {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  margin-top: 4px;
  font-family: var(--font-mono);
  word-break: break-word;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ====================================================== Daten & Importe ====
   The one production feature surface Phase 3 builds. Same tokens as the shell;
   no new colours, no new radii. A table and a chip are enough here — an import
   log is an operations view, and dressing it up would make it harder to scan.
   ========================================================================= */
.panel--gap {
  margin-top: var(--s-4);
}
.label--gap {
  display: block;
  margin: var(--s-5) 0 var(--s-3);
}
.backlink {
  font-size: var(--fs-xs);
  color: var(--text-tertiary);
  text-decoration: none;
}
.backlink:hover {
  color: var(--text-secondary);
}

.upload {
  display: flex;
  align-items: flex-end;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-top: var(--s-4);
}
.upload .field {
  flex: 1 1 320px;
  margin: 0;
}
.upload input[type='file'] {
  width: 100%;
  padding: 9px 12px;
  height: auto;
  line-height: 1.4;
  border-radius: var(--r-sm);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
  color: var(--text-secondary);
  font-size: var(--fs-xs);
  font-family: inherit;
}
.btn--upload {
  border: none;
  color: var(--text-inverse);
  font-weight: 600;
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
}
.btn--sm {
  height: 30px;
  padding: 0 12px;
  font-size: var(--fs-tiny);
  text-decoration: none;
  display: inline-flex;
  /* .btn--primary is full width for the login submit. A small button that
     inherits that stacks one per row instead of sitting in it. */
  width: auto;
  align-items: center;
}
.upload__hint {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  margin: var(--s-3) 0 0;
}
.reprocess {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-faint);
}
.reprocess .upload__hint {
  margin: 0;
  max-width: 46ch;
}

/* The base .notice is styled as an error; imports need both registers. */
.notice--ok {
  border-color: rgba(127, 163, 122, 0.4);
  background: rgba(127, 163, 122, 0.12);
  color: var(--text-primary);
}
.notice--bad {
  border-color: var(--alert);
  background: var(--alert-veil);
}

.chip {
  display: inline-block;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
  white-space: nowrap;
}
.chip.is-ok {
  color: var(--ok);
  border-color: rgba(127, 163, 122, 0.35);
}
.chip.is-warn {
  color: var(--caution);
  border-color: rgba(217, 164, 65, 0.35);
  background: var(--caution-veil);
}
.chip.is-bad {
  color: var(--alert);
  border-color: rgba(196, 97, 75, 0.4);
  background: var(--alert-veil);
}

/* Import tables can be wide; the page body must never scroll sideways. */
.tablewrap {
  overflow-x: auto;
  margin-top: var(--s-3);
}
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-xs);
}
.table th {
  text-align: left;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--text-tertiary);
  padding: 0 var(--s-3) var(--s-2) 0;
  border-bottom: 1px solid var(--line-faint);
  white-space: nowrap;
}
.table td {
  padding: var(--s-3) var(--s-3) var(--s-3) 0;
  border-bottom: 1px solid var(--line-faint);
  vertical-align: top;
  color: var(--text-primary);
}
.table tr:last-child td {
  border-bottom: none;
}
.table__sub {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  line-height: 1.5;
}
.table__mono {
  font-family: var(--font-mono);
  color: var(--text-secondary);
  white-space: nowrap;
}
.table__num {
  text-align: right;
  width: 1%;
}

/* ============================================================ Training ====
   The accepted Gate-1 Training information architecture against real data:
   week navigation, seven-day plan/actual grid, session detail, version
   history, sign-off and the weekly close. Same tokens as the rest of the
   shell -- no new colours, no new radii, no card wall.
   ========================================================================= */
.tnav {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
}
.tnav__title {
  font-family: var(--font-editorial);
  font-size: var(--fs-2xl);
  font-weight: 400;
  letter-spacing: var(--track-tight);
  margin: 0;
}
.tnav__spacer {
  flex: 1;
}
.tnav__dates {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  margin-top: 4px;
}
.texceptions {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-top: var(--s-3);
}

/* Seven columns on a wide screen; a readable stack on a phone. The grid is the
   week -- collapsing it into a single scrolling list would lose the shape the
   athlete actually plans in. */
.tgrid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--s-2);
  margin-top: var(--s-5);
}
@media (max-width: 1100px) {
  .tgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 620px) {
  .tgrid {
    grid-template-columns: 1fr;
  }
}
.tday {
  background: var(--bg-elevated);
  border: 1px solid var(--line-faint);
  border-radius: var(--r-md);
  padding: var(--s-3);
  min-height: 130px;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.tday.is-today {
  border-color: var(--line-accent);
}
.tday__head {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.tday__name {
  font-size: var(--fs-xs);
  font-weight: 500;
}
.tday__date {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.tday__now {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.tday__empty {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  margin-top: auto;
}

.tsession {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--bg-raised);
  border: 1px solid var(--line-faint);
  border-left: 2px solid var(--line);
  border-radius: var(--r-sm);
  padding: 10px;
  transition: border-color var(--t-micro) var(--ease);
}
.tsession:hover {
  border-color: var(--line-strong);
}
.tsession.is-key {
  border-left-color: var(--accent);
}
.tsession--unplanned {
  border-left-color: var(--caution);
  border-style: dashed;
}
.tsession__head {
  display: flex;
  align-items: center;
  gap: 6px;
}
.tsession__sport {
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.tsession__key,
.tsession__team {
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}
.tsession__team {
  color: var(--text-secondary);
}
.tsession__title {
  font-size: var(--fs-xs);
  margin: 4px 0 6px;
  line-height: 1.35;
}
.tsession__row {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-tiny);
  color: var(--text-secondary);
}
.tsession__k {
  color: var(--text-tertiary);
}
.tsession__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 8px;
}
.tsession__cta {
  font-size: var(--fs-tiny);
  color: var(--accent);
  white-space: nowrap;
}

.tversions {
  list-style: none;
  margin: var(--s-3) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.tversions__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--fs-xs);
}
.tversions__no {
  font-family: var(--font-mono);
  color: var(--text-secondary);
  min-width: 2.5em;
}
.tversions__meta {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}

.tplan,
.toutcome,
.tcheckin {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-3);
  margin-top: var(--s-3);
}
.field--inline {
  min-width: 150px;
}
.field--inline select,
.field--inline input {
  width: 100%;
  height: 36px;
  padding: 0 10px;
  border-radius: var(--r-sm);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
  color: var(--text-primary);
  font-size: var(--fs-xs);
  font-family: inherit;
}
.tplan textarea,
.toutcome textarea {
  width: 100%;
  min-width: 320px;
  padding: 10px;
  border-radius: var(--r-sm);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
  color: var(--text-primary);
  font-size: var(--fs-tiny);
  font-family: var(--font-mono);
}

.tcandidate {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-faint);
}
.tcandidate__what {
  flex: 1;
  font-size: var(--fs-xs);
  color: var(--text-secondary);
}

/* The Garmin-derived suggestion. Visually separate from the athlete's own
   field on purpose: Master 6.3 allows showing it, not merging it. */
.tsuggest {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
}
.tsuggest__text {
  flex: 1;
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  line-height: 1.55;
  min-width: 240px;
}
.tfuture {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-faint);
}
.tflash__where {
  display: block;
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-tiny);
  opacity: 0.85;
}

/* ======================================================== Performance ====
 *
 * Phase 5 §14.4: restraint over dashboard.
 *
 * There are no gauges, no rings, and no continuous confidence or priority
 * bars anywhere below. Priority and Aussagesicherheit are ordinal, so they get
 * discrete chips; a bar filled to 62% would draw the hidden magnitude that
 * §10 forbids storing.
 *
 * The only two marks that encode a quantity are the weekly volume bars and the
 * capability sparkline, both of which represent something actually measured in
 * a real unit. The sparkline is drawn as separate polylines per contiguous run
 * so a gap in the evidence stays visibly a gap.
 */

.perf-h1 {
  font-size: var(--fs-xl);
  font-weight: 300;
  letter-spacing: -0.015em;
  color: var(--text-primary);
  margin: 0;
}
.perf-h2 {
  font-size: var(--fs-base);
  font-weight: 400;
  color: var(--text-primary);
  margin: 0 0 var(--s-4);
  letter-spacing: -0.005em;
}
.perf-lede {
  margin: var(--s-2) 0 0;
  color: var(--text-secondary);
  font-size: var(--fs-sm);
  line-height: 1.6;
  max-width: 62ch;
}

/* ---- overview cards: a state and a finding, never a score --------------- */

.perf-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s-4);
  margin-top: var(--s-4);
}
.perf-card {
  display: block;
  padding: var(--s-5);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.18s ease, background 0.18s ease;
}
.perf-card:hover,
.perf-card:focus-visible {
  border-color: var(--line-accent);
  background: var(--bg-elevated);
}
.perf-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
}
.perf-card__name {
  font-size: var(--fs-lg);
  font-weight: 300;
  color: var(--text-primary);
}
.perf-card__state {
  font-size: var(--fs-tiny);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.perf-card__state--ok {
  color: var(--ok);
}
.perf-card__state--caution {
  color: var(--caution);
}
.perf-card__finding {
  margin-top: var(--s-4);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  line-height: 1.55;
}
.perf-card__finding p {
  margin: 0;
}
.perf-card__finding--none {
  color: var(--text-tertiary);
}
.perf-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: var(--s-3);
}

/* ---- ordinal chips ------------------------------------------------------ */

.perf-chip {
  display: inline-block;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font-size: var(--fs-tiny);
  letter-spacing: 0.02em;
  border: 1px solid var(--line);
  color: var(--text-tertiary);
  background: var(--bg-inset);
  white-space: nowrap;
}
.perf-chip--alert {
  color: var(--alert);
  background: var(--alert-veil);
  border-color: rgba(196, 97, 75, 0.3);
}
.perf-chip--caution {
  color: var(--caution);
  background: var(--caution-veil);
  border-color: rgba(217, 164, 65, 0.3);
}

/* ---- capabilities ------------------------------------------------------- */

.perf-cap {
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--line-faint);
}
.perf-cap:last-child {
  border-bottom: 0;
}
.perf-cap__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
}
.perf-cap__label {
  color: var(--text-primary);
  font-size: var(--fs-sm);
}
.perf-value {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.perf-value--none {
  color: var(--text-tertiary);
}
.perf-value__range {
  font-family: var(--font-mono);
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
  margin-left: var(--s-2);
}
.perf-cap__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: 6px;
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.perf-flag {
  color: var(--text-secondary);
  border: 1px solid var(--line-faint);
  border-radius: var(--r-sm);
  padding: 1px 6px;
}
.perf-flag--caution {
  color: var(--caution);
  border-color: rgba(217, 164, 65, 0.3);
}
.perf-cap__note,
.perf-cap__next,
.perf-cap__excl {
  margin: var(--s-2) 0 0;
  font-size: var(--fs-tiny);
  line-height: 1.6;
  max-width: 74ch;
}
.perf-cap__note {
  color: var(--text-secondary);
}
.perf-cap__next {
  color: var(--accent);
}
.perf-cap__excl {
  color: var(--text-tertiary);
}
.perf-missing {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-faint);
}

/* ---- timeline ----------------------------------------------------------- */

.perf-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 72px;
  margin-top: var(--s-3);
}
.perf-bar {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: flex-end;
  background: var(--bg-inset);
  border-radius: 2px;
}
.perf-bar__fill {
  width: 100%;
  background: var(--accent-ember);
  border-radius: 2px;
  min-height: 1px;
}
/* A key session is marked by hue, not by a second scale. */
.perf-bar__fill.is-key {
  background: var(--accent);
}
.perf-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.perf-blocks {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.perf-lane {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-faint);
}
.perf-lane__head {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  font-size: var(--fs-tiny);
  color: var(--text-secondary);
}
.perf-lane__gap {
  color: var(--text-tertiary);
}
.perf-lane__why {
  margin: 6px 0 0;
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.perf-spark {
  width: 100%;
  height: 46px;
  margin-top: 6px;
  overflow: visible;
}
.perf-spark polyline {
  fill: none;
  stroke: var(--accent);
  stroke-width: 0.7;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.perf-spark circle {
  fill: var(--accent);
}
.perf-spark circle.is-stale {
  fill: var(--caution);
}
.perf-narrative {
  list-style: none;
  margin: var(--s-5) 0 0;
  padding: 0;
}
.perf-narrative li {
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  line-height: 1.6;
  padding-left: var(--s-4);
  border-left: 1px solid var(--line-faint);
  margin-bottom: var(--s-3);
  max-width: 76ch;
}

/* ---- findings ----------------------------------------------------------- */

.perf-finding {
  padding: var(--s-5);
  background: var(--bg-inset);
  border: 1px solid var(--line-faint);
  border-radius: var(--r-md);
  margin-bottom: var(--s-4);
}
.perf-finding__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--s-3);
}
.perf-finding__cat {
  font-size: var(--fs-tiny);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-right: auto;
}
.perf-finding__statement {
  margin: 0;
  color: var(--text-primary);
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.perf-finding__matters {
  margin: var(--s-2) 0 0;
  color: var(--text-secondary);
  font-size: var(--fs-sm);
  line-height: 1.6;
  max-width: 78ch;
}
.perf-finding__grid {
  display: grid;
  grid-template-columns: minmax(120px, auto) 1fr;
  gap: 6px var(--s-4);
  margin: var(--s-4) 0 0;
  font-size: var(--fs-tiny);
  line-height: 1.6;
}
.perf-finding__grid dt {
  color: var(--text-tertiary);
}
.perf-finding__grid dd {
  margin: 0;
  color: var(--text-secondary);
}
.perf-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-4);
}

/* ---- load, recovery, adopted -------------------------------------------- */

.perf-bp {
  margin: var(--s-2) 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--text-primary);
}
.perf-recovery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s-4);
  margin-top: var(--s-3);
}
.perf-recovery__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perf-recovery__k {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.perf-recovery__v {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--text-primary);
}
.perf-recovery__n {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}
.perf-adopted {
  list-style: none;
  margin: var(--s-3) 0 0;
  padding: 0;
}
.perf-adopted li {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line-faint);
}
.perf-adopted li:last-child {
  border-bottom: 0;
}
.perf-adopted__what {
  color: var(--text-primary);
  font-size: var(--fs-sm);
}
.perf-adopted__why,
.perf-adopted__when {
  font-size: var(--fs-tiny);
  color: var(--text-tertiary);
}

/* Screen-reader text for the bar labels, which are otherwise title-only. */
.perf-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* ========================================================== Athlete =====
 *
 * The twin block below is the ACCEPTED Gate-1 styling, carried across from
 * prototype/src/styles/twin.css rather than reinvented. The asset is fixed
 * (Master 13.4); everything here is the stage it sits in or a layer above it.
 *
 * One deliberate change from the prototype: reduced motion is handled in CSS
 * instead of in JavaScript. The prototype decided in a hook and rendered fewer
 * elements; production renders the same DOM and stops it moving, because
 * reduced motion is a request to stop movement, not to see less data.
 */

.twinStage {
  position: relative; overflow: hidden; padding: var(--s-4) var(--s-4) var(--s-3);
  /* Tuned against the asset's own background, sampled from the file: its outer
     edges sit at rgb(2,7,11) and it lifts to about rgb(7,26,40) a third of the
     way in. The panel continues that same falloff outward, so the image has no
     brightness step at its border and stops reading as a pasted rectangle. */
  background:
    radial-gradient(46% 56% at 50% 45%,
      rgba(9,34,52,0.95) 0%, rgba(4,15,23,0.95) 58%, #02070B 100%),
    #02070B;
  border-color: rgba(116,215,232,0.14);
}
.twinStage__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-4); }
.twinStage__title { font-size: var(--fs-lg); font-weight: 500; margin-top: 5px; }
.twinStage__meta { font-size: 9.5px; color: var(--text-tertiary); }

/* The stage is locked to a fixed aspect ratio on purpose.
   The asset is `height:100%; width:auto`, so its width as a FRACTION of the
   stage depends only on this ratio — which is what lets image coordinates map
   to overlay anchors by a fixed formula. The asset is 1290x1928 (0.66908):
       image width = 0.66908 / (880/710) = 53.98% of the stage
       image left  = (100 - 53.98) / 2   = 23.01%
   Change this ratio and the anchors in screens/Athlete.tsx must change too. */
.twin {
  position: relative;
  width: min(100%, 880px);
  aspect-ratio: 880 / 710;
  margin: var(--s-3) auto;
}
.twin__img {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  height: 100%; width: auto; user-select: none; pointer-events: none;
  /* Feathered edges. The asset is opaque, so any mismatch between its border
     pixels and the panel reads as a seam. The horizontal fade stops at 7%,
     just clear of the projection platform, which reaches to about 8% in. */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 4%, #000 97%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 4%, #000 97%, transparent 100%);
  mask-composite: intersect;
}

/* ---------- ambient field: the only moving part of this screen ---------- */
.twin__field { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }

/* A very slow breath behind the figure. */
.twin__pulse {
  position: absolute; left: 50%; top: 46%; width: 62%; height: 74%;
  transform: translate(-50%, -50%);
  background: radial-gradient(50% 50% at 50% 50%, rgba(86,190,240,0.15), transparent 68%);
  animation: twinBreath 19s ease-in-out infinite alternate;
}
@keyframes twinBreath {
  from { opacity: 0.55; transform: translate(-50%, -50%) scale(0.96); }
  to   { opacity: 1;    transform: translate(-50%, -50%) scale(1.05); }
}

/* Orbits. The tilt wrapper rotates the whole ellipse; the orbit element fills
   the stage, so its translate percentages resolve against the stage rather than
   against the small sphere it carries. */
.twin__orbTilt { position: absolute; inset: 0; transform: rotate(var(--tilt, 0deg)); }
.twin__orbit {
  position: absolute; inset: 0; will-change: transform;
  transform: translate(var(--rx), 0);
  animation: twinOrbit var(--dur, 48s) linear infinite;
  animation-delay: var(--delay, 0s);
}
/* Twelve stops around the ellipse. One keyframe set serves every orbit, because
   the radii arrive as custom properties. */
@keyframes twinOrbit {
  0%    { transform: translate(calc(var(--rx) *  1),     calc(var(--ry) *  0)); }
  8.33% { transform: translate(calc(var(--rx) *  0.866), calc(var(--ry) *  0.5)); }
  16.7% { transform: translate(calc(var(--rx) *  0.5),   calc(var(--ry) *  0.866)); }
  25%   { transform: translate(calc(var(--rx) *  0),     calc(var(--ry) *  1)); }
  33.3% { transform: translate(calc(var(--rx) * -0.5),   calc(var(--ry) *  0.866)); }
  41.7% { transform: translate(calc(var(--rx) * -0.866), calc(var(--ry) *  0.5)); }
  50%   { transform: translate(calc(var(--rx) * -1),     calc(var(--ry) *  0)); }
  58.3% { transform: translate(calc(var(--rx) * -0.866), calc(var(--ry) * -0.5)); }
  66.7% { transform: translate(calc(var(--rx) * -0.5),   calc(var(--ry) * -0.866)); }
  75%   { transform: translate(calc(var(--rx) *  0),     calc(var(--ry) * -1)); }
  83.3% { transform: translate(calc(var(--rx) *  0.5),   calc(var(--ry) * -0.866)); }
  91.7% { transform: translate(calc(var(--rx) *  0.866), calc(var(--ry) * -0.5)); }
  100%  { transform: translate(calc(var(--rx) *  1),     calc(var(--ry) *  0)); }
}
.twin__sphere {
  position: absolute; left: 50%; top: 50%;
  width: var(--s, 13px); height: var(--s, 13px);
  margin: calc(var(--s, 13px) / -2) 0 0 calc(var(--s, 13px) / -2);
  border-radius: 50%;
  background: radial-gradient(circle at 34% 32%,
    #F2FCFF 0%, #A6E6FA 26%, #4FB6E4 56%, rgba(46,140,196,0.42) 78%, transparent 100%);
  box-shadow: 0 0 12px 3px rgba(110,205,245,0.40), 0 0 34px 10px rgba(64,160,215,0.14);
  opacity: var(--op, 0.9);
  animation: twinSphere calc(var(--dur, 48s) / 3) ease-in-out infinite alternate;
}
@keyframes twinSphere {
  from { opacity: calc(var(--op, 0.9) * 0.55); }
  to   { opacity: var(--op, 0.9); }
}

/* Drifting field particles. */
.twin__dust {
  position: absolute; width: 2px; height: 2px; border-radius: 50%;
  background: rgba(178,232,252,0.9); box-shadow: 0 0 6px 1px rgba(120,205,245,0.45);
  opacity: 0;
  animation: twinDrift var(--dur, 26s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes twinDrift {
  0%   { opacity: 0;    transform: translateY(12px); }
  22%  { opacity: 0.85; }
  74%  { opacity: 0.5; }
  100% { opacity: 0;    transform: translateY(-34px); }
}

/* Faint connector paths, drawn and undrawn rather than moved. */
.twin__links { position: absolute; inset: 0; width: 100%; height: 100%; }
.twin__link {
  fill: none; stroke: rgba(122,206,244,0.30); stroke-width: 1;
  stroke-dasharray: 5 210; stroke-dashoffset: 0;
  animation: twinTrace var(--dur, 30s) linear infinite;
  animation-delay: var(--delay, 0s);
  vector-effect: non-scaling-stroke;
}
@keyframes twinTrace { to { stroke-dashoffset: -430; } }

/* ---------- measurement overlay ---------- */
.twin__lines { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

.twin__dot {
  position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px;
  border-radius: 50%; background: rgba(226,250,255,0.95);
  box-shadow: 0 0 9px 3px rgba(120,210,248,0.5); cursor: pointer;
  transition: box-shadow var(--t-micro) var(--ease);
}
.twin__dot.is-on { background: #FFFFFF; box-shadow: 0 0 16px 5px rgba(160,232,252,0.72); }

/* Callouts float beside the figure, as in the target. */
.twin__cal {
  position: absolute; transform: translateY(-50%); cursor: pointer;
  display: flex; flex-direction: column; gap: 1px;
  padding: 6px 10px; border-radius: var(--r-sm);
  width: 17%; min-width: 116px;
  border: 1px solid transparent; transition: background var(--t-micro) var(--ease),
                                             border-color var(--t-micro) var(--ease);
}
.twin__cal--left { left: 3%; align-items: flex-end; text-align: right; }
.twin__cal--right { right: 3%; align-items: flex-start; }
.twin__cal.is-on { background: rgba(116,215,232,0.10); border-color: rgba(116,215,232,0.30); }
.twin__calK {
  font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--text-tertiary); font-weight: 600;
}
.twin__calV { font-size: var(--fs-xl); font-weight: 400; letter-spacing: var(--track-tight); color: var(--text-primary); }
.twin__cal.is-on .twin__calV { color: #CFF4FB; }
.twin__calU { font-size: var(--fs-xs); color: var(--text-tertiary); margin-left: 3px; }
.twin__calD { font-size: 9.5px; color: var(--ok); }
.twin__calD.is-down { color: var(--cyan-dim); }

.twinStage__foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding-top: var(--s-3); border-top: 1px solid rgba(116,215,232,0.10); flex-wrap: wrap;
}
.twinStage__detail { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.twinStage__detailK { font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--cyan-dim); font-weight: 600; }
.twinStage__detailHist { font-size: var(--fs-xs); color: var(--text-secondary); }
.twinStage__detailAge { font-size: 9.5px; color: var(--text-tertiary); }


/* Stage chrome that the production shell needs. */
.twinStage { border: 1px solid rgba(116,215,232,0.14); border-radius: var(--r-lg); }
.twin__calV--none {
  font-size: var(--fs-sm); color: var(--text-tertiary); font-weight: 400; letter-spacing: 0;
}
.twin__cal.is-empty .twin__calK { color: rgba(167,158,149,0.6); }
.twin__dot.is-empty { background: rgba(180,215,230,0.35); box-shadow: none; }

/* Reduced motion: the ambient field holds still, the data stays put. */
@media (prefers-reduced-motion: reduce) {
  .twin__pulse,
  .twin__orbit,
  .twin__sphere,
  .twin__dust,
  .twin__link {
    animation: none !important;
  }
  .twin__dust { opacity: 0.5; }
}

/* ---- tabs and page chrome ---- */
.at__tabs {
  display: flex; align-items: center; gap: var(--s-2);
  margin-bottom: var(--s-4); flex-wrap: wrap;
}
.at__tab {
  padding: 7px 13px; border-radius: var(--r-pill); font-size: var(--fs-sm);
  color: var(--text-secondary); text-decoration: none;
  border: 1px solid transparent; transition: color var(--t-micro) var(--ease);
}
.at__tab:hover { color: var(--text-primary); }
.at__tab.is-on {
  color: var(--cyan); background: rgba(116,215,232,0.09);
  border-color: rgba(116,215,232,0.28);
}
.at__tabSpacer { flex: 1; }
.at__vis {
  font-size: var(--fs-tiny); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-tertiary); border: 1px solid var(--line-faint);
  border-radius: var(--r-pill); padding: 3px 10px;
}
.at__h2 {
  font-size: var(--fs-base); font-weight: 400; color: var(--text-primary);
  margin: 0 0 var(--s-4);
}

/* ---- honest empty states ---- */
.at__empty { padding: var(--s-5) 0; }
.at__emptyTitle { font-size: var(--fs-sm); color: var(--text-primary); margin-bottom: 6px; }
.at__emptyLede {
  margin: 0; font-size: var(--fs-tiny); color: var(--text-tertiary);
  line-height: 1.65; max-width: 72ch;
}

/* ---- forms ---- */
.at__form { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: flex-end; }
.at__form .field { min-width: 150px; }
.at__hint, .at__note {
  font-size: var(--fs-tiny); color: var(--text-tertiary); line-height: 1.6; max-width: 76ch;
}
.at__note { margin: var(--s-4) 0 0; }
.at__hint { margin: var(--s-2) 0 0; }
.at__inlineForm {
  display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center;
  margin-top: var(--s-3); font-size: var(--fs-tiny);
}

/* ---- value cards (thresholds, strength records) ---- */
.at__cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--s-4);
}
.at__card {
  display: flex; flex-direction: column; gap: 3px;
  padding: var(--s-4); background: var(--bg-inset);
  border: 1px solid var(--line-faint); border-radius: var(--r-md);
}
.at__cardK { font-size: var(--fs-tiny); color: var(--text-tertiary); }
.at__cardV {
  font-family: var(--font-mono); font-size: var(--fs-lg); color: var(--cyan);
  font-variant-numeric: tabular-nums;
}
.at__cardM { font-size: var(--fs-tiny); color: var(--text-tertiary); }

.at__flag {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  font-size: var(--fs-tiny); border-radius: var(--r-sm);
  border: 1px solid var(--line-faint); color: var(--text-tertiary);
}
.at__flag--ok { color: var(--ok); border-color: rgba(127,163,122,0.35); }
.at__flag--care { color: var(--caution); border-color: rgba(217,164,65,0.35); }

/* ---- equipment ---- */
.at__equip {
  padding: var(--s-4) 0; border-bottom: 1px solid var(--line-faint);
}
.at__equip:last-child { border-bottom: 0; }
.at__equipHead {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s-3); flex-wrap: wrap;
}
.at__equipName { font-size: var(--fs-sm); color: var(--text-primary); }
.at__equipCat { font-size: var(--fs-tiny); color: var(--text-tertiary); margin-left: var(--s-3); }
.at__equipFlags { display: flex; gap: 6px; flex-wrap: wrap; }
.at__equipMeta {
  display: flex; gap: var(--s-3); flex-wrap: wrap;
  font-size: var(--fs-tiny); color: var(--text-tertiary); margin-top: 4px;
}
.at__usage { margin-top: var(--s-3); }
.at__usageV { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-primary); }
.at__cand {
  margin-top: var(--s-3); padding: var(--s-3);
  background: var(--bg-inset); border-radius: var(--r-sm);
}
.at__candRow {
  display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap;
  padding: 4px 0; font-size: var(--fs-tiny);
}
.at__equipDocs { margin-top: var(--s-3); display: flex; gap: var(--s-3); flex-wrap: wrap; align-items: center; }
.at__docLink { font-size: var(--fs-tiny); color: var(--cyan); text-decoration: none; }
.at__docLink:hover { text-decoration: underline; }

/* ---- bike fit ---- */
.at__fit { padding: var(--s-4) 0; border-bottom: 1px solid var(--line-faint); }
.at__fit:last-child { border-bottom: 0; }
.at__fitHead { display: flex; gap: var(--s-3); align-items: baseline; flex-wrap: wrap; }
.at__fitBike { font-size: var(--fs-sm); color: var(--text-primary); }
.at__fitBy { font-size: var(--fs-tiny); color: var(--text-tertiary); }
.at__fitValues {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s-3); margin-top: var(--s-3);
}
.at__fitVal { display: flex; flex-direction: column; gap: 2px; }
.at__fitK { font-size: var(--fs-tiny); color: var(--text-tertiary); }
.at__fitV { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-primary); }
.at__fitGrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--s-3); width: 100%;
}
tr.is-past td { opacity: 0.55; }

/* ============================================================= Team =====
 *
 * A workspace, not a feed: no avatars, no reactions, no activity stream.
 * The hero states the shared goal; everything else is a list someone has to
 * act on. Sharing is shown from both directions, because "what have I exposed"
 * is the question people forget to ask.
 */
.tm__hero {
  background:
    radial-gradient(70% 120% at 12% 0%, var(--accent-veil) 0%, transparent 62%),
    var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.tm__hero--empty { background: var(--bg-raised); }
.tm__heroTitle {
  font-family: var(--font-editorial);
  font-size: var(--fs-2xl); font-weight: 400; letter-spacing: -0.02em;
  color: var(--text-primary); margin: var(--s-2) 0 0;
}
.tm__heroLede, .tm__mission, .tm__logistics {
  margin: var(--s-3) 0 0; font-size: var(--fs-sm);
  color: var(--text-secondary); line-height: 1.65; max-width: 70ch;
}
.tm__logistics { color: var(--text-tertiary); font-size: var(--fs-tiny); }
.tm__heroMeta {
  display: flex; gap: var(--s-4); flex-wrap: wrap; align-items: baseline;
  margin-top: var(--s-3); font-size: var(--fs-tiny); color: var(--text-tertiary);
}
.tm__heroDate { font-family: var(--font-mono); color: var(--accent); }

.tm__confirm { border-color: rgba(217,164,65,0.35); }
.tm__confirmText {
  margin: var(--s-2) 0 var(--s-4); font-size: var(--fs-sm);
  color: var(--caution); line-height: 1.65; max-width: 74ch;
}

.tm__items { list-style: none; margin: 0; padding: 0; }
.tm__item {
  display: flex; gap: var(--s-3); align-items: baseline; flex-wrap: wrap;
  padding: var(--s-3) 0; border-bottom: 1px solid var(--line-faint);
}
.tm__item:last-child { border-bottom: 0; }
.tm__itemTitle { color: var(--text-primary); font-size: var(--fs-sm); }
.tm__itemBy { font-size: var(--fs-tiny); color: var(--text-tertiary); }
.tm__itemBody { font-size: var(--fs-tiny); color: var(--text-secondary); flex-basis: 100%; }
.tm__add { margin-top: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--line-faint); }

.tm__share {
  display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap;
  padding: var(--s-3) 0; border-bottom: 1px solid var(--line-faint);
}
.tm__share:last-of-type { border-bottom: 0; }
.tm__shareKind {
  font-size: var(--fs-tiny); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-tertiary); min-width: 110px;
}
.tm__shareLabel { color: var(--text-primary); font-size: var(--fs-sm); flex: 1; min-width: 140px; }
.tm__shareWho, .tm__shareWhen { font-size: var(--fs-tiny); color: var(--text-tertiary); }

.field--wide { flex: 1 1 320px; }
.field--check { flex-direction: row; align-items: center; gap: 6px; }

/* Amendment controls, folded away until wanted: correction is an occasional
   task and should not compete with the record it corrects. */
.at__amend, .tm__itemEdit { margin-top: var(--s-3); }
.at__amend > summary, .tm__itemEdit > summary {
  cursor: pointer; font-size: var(--fs-tiny); color: var(--text-tertiary);
  list-style: none; padding: 4px 0;
}
.at__amend > summary::-webkit-details-marker,
.tm__itemEdit > summary::-webkit-details-marker { display: none; }
.at__amend > summary::before, .tm__itemEdit > summary::before { content: '＋ '; }
.at__amend[open] > summary::before, .tm__itemEdit[open] > summary::before { content: '－ '; }
.at__amend > summary:hover, .tm__itemEdit > summary:hover { color: var(--text-secondary); }
.tm__itemEdit { flex-basis: 100%; }
.at__docActions { display: flex; gap: var(--s-2); align-items: center; }

/* Settings: the security state, stated plainly. */
.set__value { font-family: var(--font-ui); font-size: var(--fs-base); color: var(--text-primary); }
.set__enrol { margin-bottom: var(--s-4); }
.set__secret {
  margin: var(--s-3) 0; padding: var(--s-4);
  background: var(--bg-inset); border: 1px solid var(--line-accent);
  border-radius: var(--r-sm);
}
.set__secretValue {
  font-family: var(--font-mono); font-size: var(--fs-base);
  letter-spacing: 0.14em; color: var(--accent); word-break: break-all;
}

/* ====================================================== mobile layout ====
 *
 * Phase 7 §13: mobile is not the desktop squeezed narrower.
 *
 * The 68px vertical rail costs a fifth of a 375px viewport and pushes dense
 * Performance evidence into a ~240px column, where every capability row wraps
 * mid-value. On a phone the navigation becomes a horizontal bar pinned to the
 * bottom — where a thumb is — and the content gets the whole width.
 *
 * Touch targets go to 44px. The rail links were 52x29, and the navigation is
 * the most-tapped thing in the product.
 */
/* The measurement list is the phone's version of the callouts, so it is
   hidden wherever the callouts themselves are visible. */
.twin__list {
  display: none;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3) var(--s-4);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid rgba(116, 215, 232, 0.12);
}
.twin__listItem { display: flex; flex-direction: column; gap: 2px; }
.twin__listK {
  font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--text-tertiary); font-weight: 600;
}
.twin__listV {
  font-size: var(--fs-lg); font-weight: 400; color: var(--text-primary);
  letter-spacing: var(--track-tight);
}
.twin__listV--none { font-size: var(--fs-sm); color: var(--text-tertiary); }
.twin__listD { font-size: 9.5px; color: var(--cyan-dim); }

@media (max-width: 720px) {
  .shell {
    grid-template-columns: 1fr;
    /* Room for the fixed bar, plus the phone's own home indicator. */
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px));
  }

  .rail {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 20;
    flex-direction: row;
    justify-content: space-around;
    align-items: stretch;
    gap: 0;
    padding: 0 0 env(safe-area-inset-bottom, 0px);
    border-right: 0;
    border-top: 1px solid var(--line);
    background: var(--bg-deep);
  }
  /* The brand mark is decoration; the spacer only exists for the column. */
  .rail__mark,
  .rail__spacer {
    display: none;
  }
  .rail__link {
    width: auto;
    flex: 1 1 0;
    min-height: 44px;
    padding: 0 4px;
    justify-content: center;
    font-size: 10px;
    text-align: center;
  }

  .topbar {
    position: sticky;
    top: 0;
    z-index: 10;
  }
  .wrap {
    padding-left: var(--s-4);
    padding-right: var(--s-4);
  }

  /* Dense evidence: label above value rather than fighting it across a line. */
  .perf-cap__head,
  .at__equipHead,
  .twinStage__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  .at__form .field,
  .field--wide {
    flex: 1 1 100%;
    min-width: 0;
  }
  .btn {
    min-height: 44px;
  }
  .btn--sm {
    min-height: 40px;
  }
  /* Form controls are tap targets too. A 36px-tall `select` is a desktop
     control that happens to be on a phone -- the RPE picker on the training
     week was exactly that. Checkboxes and radios are excluded: the browser
     draws those at a fixed size and stretching the box does not enlarge the
     glyph, so their hit area comes from the surrounding label instead. */
  select,
  textarea,
  input:not([type='checkbox']):not([type='radio']):not([type='hidden']) {
    min-height: 44px;
  }
  /* The Athlete tab strip, the disclosure summaries and the document links are
     all comfortably clickable with a mouse and all too short for a thumb. */
  .at__tab,
  .at__docLink {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* Safe to make these flex: the native marker is already suppressed above and
     replaced with a `+`/`-` pseudo-element, so nothing is lost by changing the
     display type -- and a min-height is the only thing that reliably gets a
     one-line summary to a thumb-sized row. */
  .at__amend > summary,
  .tm__itemEdit > summary {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* A checkbox's tap target is its label -- the box itself is drawn at a fixed
     size the browser owns. The label wraps the input, so sizing the label is
     what actually enlarges the target. */
  .field--check {
    min-height: 44px;
  }

  /* A bare text link is the easiest tap target to miss on a phone. */
  .backlink {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 10px 0;
  }

  /* THE TWIN IS LEFT EXACTLY AS APPROVED.
   *
   * The stage's 880/710 ratio is load-bearing: the asset is
   * `height:100%; width:auto`, so its width as a fraction of the stage — and
   * therefore where the accepted anchor coordinates land on the body —
   * depends only on that ratio. An earlier attempt to reflow the stage for a
   * phone slid every callout onto the figure, and a second attempt using a
   * grid pulled the ambient field into its own row. Neither is worth it.
   *
   * So below 720px the figure keeps its geometry untouched and the flanking
   * callouts simply stand down: at 375px there is no room for two label
   * columns beside a body, and squeezing them there is exactly the "desktop
   * squeezed narrower" this breakpoint exists to avoid. The same measurements
   * appear underneath as a list, which is what a phone can actually read. */
  .twin__cal,
  .twin__lines {
    display: none;
  }
  .twin__list {
    display: grid;
  }

  .tablewrap {
    overflow-x: auto;
  }
}

/* The secondary navigation is not worth a third of a phone's bottom bar. */
@media (max-width: 480px) {
  .rail__link:nth-last-child(-n + 2) {
    display: none;
  }
}

/* CONTRAST ON THE TWIN STAGE.
 *
 * `--text-tertiary` is the AA-corrected grey (amendment B-1), and it passes
 * everywhere it sits on a panel. The twin stage is the exception: its backdrop
 * is a radial gradient that lifts to about rgb(9,33,51) through the middle,
 * and the labels sit across that lift rather than out on the dark edge. There
 * the same grey measures 4.26:1 -- under AA for text this small, where it is
 * 5.3:1 against the stage's outer colour.
 *
 * So on this stage only, the small labels step up to `--text-secondary`. This
 * extends amendment B-1 rather than contradicting it: same reasoning, a
 * background the amendment did not have to account for. Nothing else about the
 * accepted stage changes -- not the asset, not the anchors, not the ratio.
 */
.twinStage__meta,
.twin__calK,
.twin__calU,
.twin__calV--none,
.twin__listK,
.twin__listV--none {
  color: var(--text-secondary);
}

/* A name for assistive technology that the design does not need to show.
   Not `display: none` and not `visibility: hidden` -- both remove the element
   from the accessibility tree, which is the opposite of the point. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* =========================================================================
   KEYBOARD FOCUS

   Every gate before this one was proven with a pointer, and the app got away
   with the browser's default ring. Two things were wrong with that. The ring
   was never chosen, so on a near-black surface it was whatever the UA felt
   like; and `.field input:focus` above switches it off entirely and tints the
   border instead — a colour-only cue, which is the one kind of focus
   indicator that is not allowed to be the only one.

   So: one ring, from the accent family, drawn for :focus-visible only. A
   mouse click still does not light it up; a Tab key always does. The input
   keeps its border tint as well — two cues are better than one, and the
   tint is what makes the *field* look active rather than just outlined.
   ========================================================================= */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}
/* Same specificity as `.field input:focus`, and later, so it wins the
   `outline: none` back. */
.field input:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}
/* The rail sits against the panel edge on a phone, where a 2px offset ring
   would be clipped by the bar. Draw it inside instead. */
.rail__link:focus-visible {
  outline-offset: -3px;
}
