/* Per-surface layout. Each block maps to one artboard in the design canvas:
   2A roster · 2B client · 2C program builder · 2D profile · 3A admin. */

.view {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.view__head {
  padding: 20px 28px 0;
  display: flex;
  align-items: flex-start;
  gap: 16px;
}
.view__title { font-size: 30px; }
.view__sub { font-size: 14px; color: var(--ink-50); margin-top: 3px; }
.view__actions { margin-left: auto; display: flex; gap: 8px; }

.filters {
  padding: 16px 28px 12px;
  display: flex;
  gap: 8px;
  align-items: center;
}
.filters__note { margin-left: auto; font-size: 13px; color: var(--ink-40); }

.scroll {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.scroll::-webkit-scrollbar { width: 10px; }
.scroll::-webkit-scrollbar-thumb {
  background: rgba(62, 58, 47, 0.16);
  border-radius: 10px;
  border: 3px solid transparent;
  background-clip: content-box;
}
.scroll::-webkit-scrollbar-thumb:hover { background: rgba(62, 58, 47, 0.3); background-clip: content-box; }

/* ───────────────────────────  2A · roster  ───────────────────────────── */

.roster { padding: 0 28px 20px; display: flex; flex-direction: column; min-height: 0; flex: 1; }
/* Fluid rather than fixed: fixed pixel columns meant the table could not use
   a wide window and could not fit a narrow one. */
.roster__cols,
.roster__row {
  grid-template-columns:
    minmax(200px, 1.5fr) minmax(120px, 0.9fr) minmax(115px, 0.9fr)
    minmax(175px, 1.6fr) minmax(125px, 1fr) minmax(80px, 0.6fr);
  gap: 14px;
}

.roster__row {
  display: grid;
  align-items: center;
  padding: 13px 14px;
  border-bottom: 1px solid var(--line-soft);
  width: 100%;
  text-align: left;
  background: transparent;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: background .18s ease;
}
.roster__row:hover { background: rgba(62, 58, 47, 0.03); }
.roster__row.is-flagged { background: var(--accent-softer); }
.roster__row.is-flagged:hover { background: rgba(126, 146, 105, 0.11); }
.roster__row.is-paused { opacity: 0.55; }
.roster__client { display: flex; align-items: center; gap: 11px; }
.roster__name { font-size: 15px; }
.roster__meta { font-size: 13px; color: var(--ink-45); }
.roster__pct { font-size: 15px; }
.roster__pct.is-low { color: var(--warn); }
.roster__bar { width: 92px; margin-top: 5px; }
.roster__cell { font-size: 14px; color: var(--ink-75); }
.roster__cell--soft { font-size: 14px; color: var(--ink-40); }
.roster__cell--prog {
  font-size: 14px;
  color: var(--ink-60);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.roster__signals { display: flex; gap: 6px; flex-wrap: wrap; }
.roster__thread { font-size: 13px; color: var(--accent-deep); }
.roster__thread--none { color: var(--ink-45); }

/* ───────────────────────────  2B · client  ───────────────────────────── */

.client__head {
  padding: 18px 28px 0;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.client__id { display: flex; align-items: center; gap: 14px; }
.client__name { font-size: 23px; letter-spacing: -0.015em; }
.client__facts { font-size: 13px; color: var(--ink-50); }
.client__body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  overflow: hidden;
}
.client__main {
  padding: 20px 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
}
.client__stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.stat { background: var(--surface); border-radius: var(--r-card); padding: 13px; box-shadow: var(--edge-ring); }
.stat--flag { box-shadow: var(--edge-ring-accent); }
.stat__val { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; margin-top: 5px; }
.stat__val u { font-size: 14px; color: var(--ink-50); text-decoration: none; font-weight: 400; }
.stat__val.is-warn { color: var(--warn); }
.stat__foot { font-size: 13px; color: var(--ink-45); }
.stat__foot.is-good { color: var(--accent-deep); }

.chart__head { display: flex; align-items: baseline; gap: 12px; }
.chart__title { font-size: 17px; }
.chart__legend { display: flex; gap: 12px; margin-left: 8px; font-size: 13px; }
.chart__legend button {
  background: transparent;
  border: 0;
  font: inherit;
  padding: 0;
  cursor: pointer;
  color: var(--ink-45);
}
.chart__legend button.is-on { color: var(--accent-deep); }
.chart__legend button:hover { color: var(--ink); }
.chart__note { margin-left: auto; font-size: 13px; color: var(--ink-45); }
.chart__svg { width: 100%; height: 220px; display: block; }

.reasons { display: flex; gap: 26px; }
.reasons__list { flex: 1; display: flex; flex-direction: column; gap: 9px; }
.reasons__title { font-size: 17px; }
.reason { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.reason i { font-size: 8px; color: var(--accent); }
.reason span:first-of-type { flex: 1; }
.reason__w { color: var(--ink-50); }
.reason.is-off { opacity: 0.5; }
.reason.is-off i { color: var(--ink-45); }
.reasons__act {
  width: 220px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-left: 1px solid var(--line);
  padding-left: 22px;
}
.reasons__act p { font-size: 13px; color: var(--ink-60); line-height: 1.5; }

.thread {
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.thread__head {
  padding: 15px 18px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 8px;
}
.thread__head div { font-size: 16px; }
.thread__head span { font-size: 13px; color: var(--ink-45); }
.thread__log {
  flex: 1;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 11px;
  overflow-y: auto;
}
.msg {
  max-width: 84%;
  padding: 9px 12px;
  font-size: 14px;
  line-height: 1.5;
}
.msg--them {
  align-self: flex-start;
  background: var(--surface);
  border-radius: var(--r-bubble) var(--r-bubble) var(--r-bubble) 4px;
}
.msg--me {
  align-self: flex-end;
  background: var(--accent-wash);
  color: var(--accent-ink);
  border-radius: var(--r-bubble) var(--r-bubble) 4px var(--r-bubble);
}
.msg--sys {
  align-self: center;
  font-size: 13px;
  color: var(--ink-35);
  max-width: 100%;
}
.thread__compose {
  padding: 12px 18px 16px;
  border-top: 1px solid var(--line);
  display: flex;
  gap: 8px;
}
.thread__compose .input { height: 42px; font-size: 14px; }

/* Client with data sharing off — the whole analytics column collapses. */
.locked {
  margin: auto;
  max-width: 420px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.locked i { font-size: 30px; color: var(--ink-35); }
.locked h3 { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.locked p { font-size: 14px; color: var(--ink-60); line-height: 1.6; }

.sessions { display: flex; flex-direction: column; }
.session {
  display: grid;
  grid-template-columns: 120px 1fr 90px 80px;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 14px;
}
.session:last-child { border-bottom: 0; }
.session__date { color: var(--ink-60); }
.session__meta { color: var(--ink-45); font-size: 13px; }

/* ─────────────────────  2C · program builder  ────────────────────────── */

.builder__bar {
  height: 64px;
  flex: none;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
}
.builder__name { font-size: 17px; }
.builder__saved { font-size: 13px; color: var(--ink-40); }
.builder__right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.stack { display: flex; align-items: center; }
.stack .avatar { width: 26px; height: 26px; font-size: 11px; border: 1px solid var(--ground); }
.stack .avatar + .avatar { margin-left: -7px; }

.builder__body {
  flex: 1;
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr) 320px;
  overflow: hidden;
}

.weeks {
  border-right: 1px solid var(--line);
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow-y: auto;
}
.weeks__item {
  padding: 9px 10px;
  border-radius: var(--r-lg);
  background: var(--surface);
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 0;
  font-family: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.weeks__item i { font-size: 15px; color: var(--ink-35); }
.weeks__item:hover { background: #fff; }
.weeks__item.is-on {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--accent-deeper);
}
.weeks__item.is-deload { background: var(--surface-sunk); color: var(--ink-60); }
.weeks__item.is-deload.is-on { background: var(--accent-soft); color: var(--accent-deeper); }
.weeks__days { margin-left: auto; font-size: 13px; color: var(--ink-40); }
.weeks__foot { margin-top: auto; padding-top: 10px; font-size: 13px; color: var(--ink-40); line-height: 1.5; }

.days { overflow: hidden; display: flex; flex-direction: column; }
.days__head { padding: 14px 20px 10px; display: flex; align-items: center; gap: 12px; }
.days__title { font-size: 21px; letter-spacing: -0.015em; }
.days__meta { font-size: 13px; color: var(--ink-45); }
.days__acts { margin-left: auto; display: flex; gap: 8px; }
.days__list {
  flex: 1;
  overflow-y: auto;
  padding: 0 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.day {
  border-radius: var(--r-card);
  box-shadow: var(--edge-ring);
  background: var(--surface-sunk);
  overflow: hidden;
  flex: none;
}
.day__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  cursor: pointer;
}
.day.is-open .day__head { background: var(--surface); }
.day__grip { font-size: 16px; color: var(--ink-35); }
.day__name { font-size: 15px; }
.day__meta { font-size: 13px; color: var(--ink-45); }
.day__acts { margin-left: auto; display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--ink-45); }
.day__acts button {
  background: transparent;
  border: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  padding: 0;
}
.day__acts button:hover { color: var(--ink); }

.ex__cols,
.ex__row { grid-template-columns: 26px minmax(0, 1fr) 74px 74px 74px 96px 108px 30px; }
.ex__cols {
  display: grid;
  padding: 8px 14px;
  font-size: 11px;
  font-family: var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-40);
  border-bottom: 1px solid var(--line-soft);
}
.ex__row {
  display: grid;
  align-items: center;
  padding: 9px 14px;
  border-bottom: 1px solid rgba(62, 58, 47, 0.05);
  font-size: 14px;
  width: 100%;
  text-align: left;
  background: transparent;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  font-family: inherit;
  color: inherit;
  cursor: pointer;
  transition: background .18s ease, box-shadow .25s ease;
}
.ex__row:last-of-type { border-bottom: 0; }
.ex__row:hover { background: rgba(62, 58, 47, 0.03); }
.ex__row.is-on {
  background: var(--accent-softer);
  box-shadow: inset 0 0 0 1px rgba(126, 146, 105, 0.35);
}
.ex__row i { font-size: 15px; color: rgba(62, 58, 47, 0.25); }
/* The row's delete trigger (.admin__menu — remove-exercise, and the same
   markup reused by nutrition.js for remove-target/remove-item) is an <i>
   inside .ex__row, so the rule above colours it too — identical grey, same
   15px, as the drag grip at the row's other end. It also means
   .admin__menu:hover (:554) never reaches the glyph: that rule sets the
   button's own color, but an element with its own explicit color (set here)
   never falls back to an inherited one, whatever darkens around it. Fixed by
   giving the icon its own explicit color and its own explicit hover, both
   more specific than the rule above — no !important needed since specificity
   alone decides it (2 classes + a type beats 1 class + a type).
 *
   .ex__row's trigger is a trash can now, not the dots-menu note-item still
   uses, so it no longer needs a muted tint to read as "the odd one out" —
   the glyph already says what it does. Full-strength --danger at rest,
   darkening on hover the same ratio .btn--danger already darkens by.
   note-item keeps the original muted-tint-to-full-opacity treatment, since
   its glyph is still the ambiguous three dots. */
.ex__row .admin__menu i {
  color: var(--danger);
  transition: color .18s ease;
}
.ex__row .admin__menu:hover i {
  color: color-mix(in srgb, var(--danger) 68%, black);
}
.note-item .admin__menu i {
  color: var(--danger);
  opacity: 0.55;
  transition: opacity .18s ease;
}
.note-item .admin__menu:hover i {
  opacity: 1;
}
.ex__row .num { color: var(--ink-85); }
.ex__row .load { color: var(--ink-60); }
.ex__row .load.is-pct { color: var(--accent-deep); }
.ex__row .rest { color: var(--ink-75); }
.ex__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 10px; }
.day__add { padding: 9px 14px 12px 40px; }

.inspector {
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.inspector__head {
  padding: 14px 16px 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid var(--line);
}
.inspector__head div { font-size: 15px; }
.inspector__head span { margin-left: auto; font-size: 13px; color: var(--ink-40); }
.inspector__body {
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
}
.inspector__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.inspector .input--on { border-color: var(--accent); color: var(--accent-deeper); }
.swap {
  padding: 8px 10px;
  border-radius: var(--r-md);
  background: var(--surface-sunk);
  font-size: 14px;
  display: flex;
  align-items: center;
  width: 100%;
  border: 0;
  font-family: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.swap:hover { background: var(--surface); box-shadow: var(--edge-ring); }
.swap span { margin-left: auto; font-size: 13px; color: var(--ink-40); }

.picker { display: flex; flex-direction: column; gap: 6px; }
.picker__list {
  max-height: 210px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* The search/browse-one-pattern results view flows in the inspector's own
   scroll instead of capping its own height — unlike the "used elsewhere"
   box below, it is not sitting inside a bordered card competing for room. */
.picker__list--flow { max-height: none; overflow: visible; }

/* ── exercise picker: browse root ────────────────────────────────────────
   "Used elsewhere in this program" and "Browse by <taxonomy>" — the two
   boxes state.builder.picker's root view shows before anything is typed. */
.picker__box {
  border-radius: var(--r-lg);
  box-shadow: var(--edge-ring);
  padding: 10px;
}
.picker__box + .picker__box { margin-top: 12px; }
.picker__box-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 2px 2px 8px;
}
.picker__box-head .kicker { margin: 0; }
.picker__box-count { font-size: 13px; color: var(--ink-40); }
.picker__box-note { font-size: 13px; color: var(--ink-45); padding: 8px 2px 0; }

/* Plain divided rows, not individually boxed — "Browse by" is a list of
   categories to drill into, not something to add directly, so it reads
   lighter than the quick-add rows below. */
.picker__rows { display: flex; flex-direction: column; }
.pgroup {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 2px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  font-family: inherit;
  font-size: 14px;
  color: var(--ink-85);
  text-align: left;
  cursor: pointer;
  transition: background .18s ease;
}
.pgroup:last-child { border-bottom: 0; }
.pgroup:hover { background: var(--surface-sunk); }
.pgroup__name { flex: 1; }
.pgroup__count { font-size: 13px; color: var(--ink-40); }
.pgroup > i { font-size: 13px; color: var(--ink-35); flex: none; }

/* A subheading inside the search-results list — same visual language as
   .picker__box-head's kicker + count, just without the card around it. */
.picker__group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 10px 2px 6px;
}
.picker__group-head:first-child { padding-top: 2px; }
.picker__group-head span:first-child {
  font-size: 11px;
  font-family: var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-45);
}
.picker__group-head span:last-child { font-size: 13px; color: var(--ink-40); }

/* A quick-add row — "used elsewhere" and search-result rows both use this:
   a movement a single click prescribes, as opposed to .pgroup's drill-in. */
.pquick {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--r-md);
  background: var(--surface-sunk);
  border: 0;
  font-family: inherit;
  font-size: 14px;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .18s ease, box-shadow .25s ease;
}
.pquick:hover { background: var(--surface); box-shadow: var(--edge-ring); }
.pquick i { font-size: 13px; color: var(--accent-deep); flex: none; }
.pquick__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pquick__name b { font-weight: 700; color: var(--ink); }
.pquick__count { font-size: 13px; color: var(--ink-40); flex: none; }

/* "to Upper A", ahead of Close in the picker's root-view header. */
.inspector__context { margin-right: 8px; }

/* ───────────────────────  2D · public profile  ───────────────────────── */

.profile__bar {
  height: 64px;
  flex: none;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 24px;
}
.profile__bar > div:first-child { font-size: 17px; }
.profile__body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 470px;
  overflow: hidden;
}
.profile__form {
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  overflow-y: auto;
}
.profile__avatar { display: flex; align-items: center; gap: 16px; }
.profile__avatar .btn i { font-size: 15px; }
.profile__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.profile__triple { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
.profile__tags { display: flex; gap: 8px; flex-wrap: wrap; }
.profile__tags .tag--lg { border: 0; font-family: inherit; }
.profile__tags button.tag--lg { cursor: pointer; }
.profile__tags button.tag--lg[disabled] { cursor: not-allowed; opacity: 0.5; }
.spec { background: var(--surface); color: var(--ink-50); }
.spec.is-on { background: var(--accent); color: var(--surface); }

/* ── settings ────────────────────────────────────────────────────────── */

.settings {
  padding: 20px 28px 32px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 720px;
  overflow-y: auto;
}
.settings__section { display: flex; flex-direction: column; gap: 2px; }
.settings__title { font-size: 15px; font-weight: 600; margin-bottom: 12px; }
.settings__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.settings__grid .field__label { margin-bottom: 3px; }
.settings__grid > .field > div:last-child { font-size: 14px; }
.settings__section--danger .settings__title { color: var(--danger); }
.settings__impact {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 14px;
  color: var(--ink-75);
}

.preview {
  border-left: 1px solid var(--line);
  padding: 24px;
  background: var(--rail);
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
}
.pcard {
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--edge-ring);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pcard.is-unpublished { opacity: 0.72; }
.pcard__name { font-size: 20px; letter-spacing: -0.015em; }
.pcard__where { font-size: 13px; color: var(--ink-50); display: flex; align-items: center; gap: 5px; }
.pcard__where i { font-size: 14px; color: var(--accent-deep); }
.pcard__bio { font-size: 14px; line-height: 1.55; color: var(--ink-75); }
.pcard__tags { display: flex; gap: 6px; flex-wrap: wrap; }
.pcard__foot { display: flex; align-items: center; gap: 10px; padding-top: 4px; }
.pcard__rate { font-size: 18px; }
.pcard__rate u { font-size: 13px; color: var(--ink-50); text-decoration: none; }

/* ────────────────────────────  3A · admin  ───────────────────────────── */

.admin { display: grid; grid-template-columns: minmax(0, 1fr) 400px; height: 100vh; overflow: hidden; }
.admin__main { display: flex; flex-direction: column; overflow: hidden; }
.admin__table { padding: 0 26px 20px; display: flex; flex-direction: column; flex: 1; min-height: 0; }
.admin__cols,
.admin__row {
  grid-template-columns:
    minmax(220px, 1.6fr) minmax(90px, 0.6fr) minmax(140px, 1fr)
    minmax(140px, 1fr) minmax(110px, 0.8fr) 38px;
  gap: 12px;
}
/* The coach roster is the same table furniture with a different question, so
   it reuses .admin__row and overrides only the track list: six columns, no
   entitlement or billing, a narrow gutter for the attention marker and one
   for the message link. */
.admin__cols--coach,
.admin__row--coach {
  grid-template-columns:
    minmax(220px, 1.8fr) minmax(120px, 0.7fr) minmax(140px, 1fr)
    minmax(150px, 1fr) 30px 30px;
}
.admin__flag {
  justify-self: center;
  color: var(--warn);
  font-size: 16px;
  line-height: 1;
}
.admin__row--coach.is-flagged { background: var(--warn-bg); }
.admin__mail {
  justify-self: center;
  color: var(--ink-35);
  font-size: 16px;
  line-height: 1;
  transition: color .18s ease;
}
.admin__mail:hover { color: var(--accent-deep); }

.admin__cols { padding: 0 12px 9px; }
.admin__row {
  display: grid;
  align-items: center;
  padding: 12px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 14px;
  transition: background .18s ease;
}
.admin__row.is-suspended { opacity: 0.6; }
/* :not(--coach) — the coach-activity table reuses .admin__row for its own,
   non-clickable rows (coachActivityRow() never got the whole-row toggle
   userRow() did), so the "this opens" affordance has to stop at the
   modifier, not the base class, or a static row would read as clickable. */
.admin__row:not(.admin__row--coach) { cursor: pointer; }
.admin__row:not(.admin__row--coach):hover { background: rgba(62, 58, 47, 0.03); }
.admin__row .tag { justify-self: start; }
.admin__who div:last-child { font-size: 13px; color: var(--ink-45); }
.admin__role { color: var(--ink-75); }
.admin__billing { color: var(--ink-75); }
.admin__billing.is-late { color: var(--danger); }
.admin__seen { color: var(--ink-60); }
.admin__menu {
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--ink-35);
  font-size: 17px;
  justify-self: center;
  transition: color .18s ease;
}
.admin__menu:hover { color: var(--ink); }
/* This darkening never reaches the icon in .ex__row or .note-item — see the
   .ex__row .admin__menu i rule near :381, which is where those destructive
   uses (remove-exercise, remove-target, remove-item, delete-note) are given
   their own color and hover instead. Every current .admin__menu is one of
   those two, so this base rule is dormant rather than dead: it is what a
   future non-destructive .admin__menu — one not sitting inside .ex__row or
   .note-item — would actually render through. admin.js's own audit trigger
   used to be that case; it is a whole-row click now (userRow(), matching
   .roster__row's accordion convention), not an .admin__menu at all. */

.admin__side {
  border-left: 1px solid var(--line);
  background: var(--rail);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.admin__side-head { padding: 20px 20px 12px; display: flex; align-items: center; gap: 8px; }
.admin__side-head div { font-size: 17px; }
.admin__side-body {
  padding: 0 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
}
.vet {
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--edge-ring);
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  border: 0;
  font-family: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: box-shadow .25s ease;
}
.vet:hover { box-shadow: var(--edge-ring-accent); }
.vet div:last-of-type { font-size: 13px; color: var(--ink-45); }
.vet__name { font-size: 15px; }
.vet--open {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 14px;
  box-shadow: var(--edge-ring-accent);
  cursor: default;
}
.vet--open:hover { box-shadow: var(--edge-ring-accent); }
.vet__id { display: flex; align-items: center; gap: 10px; }
.vet__id > div > div:first-child { font-size: 16px; }
.vet__checks { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.vet__check { display: flex; align-items: center; gap: 8px; color: var(--ink-60); }
.vet__check i { font-size: 15px; }
.vet__check.is-ok { color: var(--ink); }
.vet__check.is-ok i { color: var(--accent-deep); }
.vet__acts { display: flex; gap: 8px; }
.vet__acts .btn { flex: 1; }

.billing { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.billing__tile { border-radius: var(--r-card); background: var(--surface); padding: 12px; }
.billing__val { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.billing__val.is-late { color: var(--danger); }
.billing__lbl { font-size: 13px; color: var(--ink-50); }
.billing__out {
  border-radius: var(--r-lg);
  background: var(--surface);
  padding: 16px;
  font-size: 14px;
  color: var(--ink-60);
  line-height: 1.55;
}

/* The assignment panel needs more room than the row inspector; the weeks and
   sessions columns keep their widths so nothing behind it reflows. */
.builder__body--wide { grid-template-columns: 216px minmax(0, 1fr) 400px; }

.pick {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--surface-sunk);
  font-family: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.pick:hover { background: var(--surface); box-shadow: var(--edge-ring); }
.pick > i { font-size: 18px; color: var(--ink-35); flex: none; }
.pick.is-on { background: var(--accent-softer); box-shadow: inset 0 0 0 1px rgba(126, 146, 105, 0.35); }
.pick.is-on > i { color: var(--accent); }
.pick__body { flex: 1; min-width: 0; display: block; }
.pick__name { display: block; font-size: 14px; }
.pick__meta { display: block; font-size: 13px; color: var(--ink-45); }

/* Per-set loads: what one row per prescribed set buys you — a ramp inside one
   exercise, editable set by set. */
.perset { display: flex; flex-direction: column; gap: 6px; }
.perset__row { display: flex; align-items: center; gap: 10px; }
.perset__n {
  width: 46px;
  flex: none;
  font-size: 13px;
  font-family: var(--mono);
  color: var(--ink-45);
}
.perset__row .input { flex: 1; }
.perset__row .numfield { flex: 1; }

/* A number you can type, with a nudge on either side. The field is the
   primary input and takes the space; the steppers are for ±1, which is what
   the native spin buttons were for before they turned out to be a hairline
   tall and the only way in. `tabindex="-1"` on them keeps tabbing between
   fields, not through six buttons. */
.numfield { display: flex; align-items: stretch; gap: 4px; }
.numfield__input {
  flex: 1;
  min-width: 0;
  text-align: center;
  font-family: var(--mono);
}
.numfield__step {
  flex: none;
  width: 30px;
  border: 1px solid rgba(62, 58, 47, 0.16);
  border-radius: var(--r-sm);
  background: var(--surface-sunk);
  color: var(--ink-45);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  user-select: none;
}
.numfield__step:hover { background: rgba(62, 58, 47, 0.09); color: var(--ink); }
.numfield__step:active { background: rgba(62, 58, 47, 0.14); }
.numfield__step:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── diet plan builder ─────────────────────────────────────────────────────
   Same three-column skeleton as the program builder; only the column
   contents differ, so a coach who knows one knows the other. */

.target__cols,
.target__row { grid-template-columns: 26px minmax(0, 1fr) 110px 110px 150px 30px; }
.target__row .resolved { color: var(--accent-deep); }
.target__row:last-of-type { border-bottom: 0; }

.meal__cols,
.meal__row { grid-template-columns: minmax(0, 1fr) 92px 64px 52px 52px 52px 30px; }
.meal__row { cursor: default; }
.meal__row:hover { background: transparent; }

.seg--wrap { flex-wrap: wrap; }
.seg--wrap button { border-left: 1px solid rgba(62, 58, 47, 0.14); }

.check {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  font-size: 13px;
  color: var(--ink-60);
  line-height: 1.45;
  cursor: pointer;
}
.check input { margin-top: 2px; accent-color: var(--accent); }

/* ── client nutrition tab ────────────────────────────────────────────────── */

.macro {
  display: grid;
  grid-template-columns: 90px 1fr 130px;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 14px;
}
.macro:last-child { border-bottom: 0; }
.macro__name { color: var(--ink-75); }
.macro__track {
  position: relative;
  height: 6px;
  background: var(--track);
  border-radius: 3px;
  overflow: hidden;
}
.macro__fill { height: 6px; background: var(--accent); border-radius: 3px; }
.macro__fill.is-over { background: var(--warn); }
.macro__fill.is-under { background: var(--accent-2, var(--accent)); opacity: 0.6; }
.macro__num { text-align: right; color: var(--ink-60); font-size: 13px; }
.macro__num b { color: var(--ink); font-weight: 500; }

.nutriday {
  display: grid;
  grid-template-columns: 110px 90px 1fr 70px;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 14px;
}
.nutriday:last-child { border-bottom: 0; }
.nutriday__date { color: var(--ink-60); }
.nutriday__type { font-size: 13px; color: var(--ink-45); }
.nutriday__meta { color: var(--ink-45); font-size: 13px; }

/* A target that does not resolve shows why, never a number. */
.target__row .resolved.is-problem { color: var(--warn-ink); }

/* ── plan library ─────────────────────────────────────────────────────────
   Programs and diet plans share a card: both are something the coach wrote
   that some number of clients are on. */

.library { flex: 1; display: flex; flex-direction: column; padding: 0 28px 20px; min-height: 0; }
.library .scroll { display: flex; flex-direction: column; gap: 12px; padding-right: 4px; }

.plan {
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--edge-ring);
  overflow: hidden;
  flex: none;
}
.plan__open {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 16px 18px;
  background: transparent;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.plan__open:hover { background: var(--accent-softer); }
.plan__icon {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: var(--r-lg);
  background: var(--accent-wash);
  color: var(--accent-deeper);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
}
.plan__body { flex: 1; min-width: 0; display: block; }
.plan__name { display: block; font-size: 17px; }
.plan__meta { display: block; font-size: 13px; color: var(--ink-45); margin-top: 2px; }
.plan__who {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--line-soft);
  background: var(--surface-sunk);
}
.plan__acts { margin-left: auto; display: flex; gap: 8px; }

.picker-panel {
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--edge-ring-accent);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}
.picker-panel__head { display: flex; align-items: center; gap: 10px; font-size: 16px; }
.picker-panel__head .backlink { margin-left: auto; }

/* ── Today ────────────────────────────────────────────────────────────────
   Grouped by what the coach would do about it, not by which table the data
   came from. */

.today { flex: 1; display: flex; flex-direction: column; padding: 0 28px 20px; min-height: 0; }
.today__strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  padding-bottom: 18px;
}
.today__list { display: flex; flex-direction: column; gap: 14px; padding-right: 4px; }

.todo {
  flex: none;
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--edge-ring);
  overflow: hidden;
}
.todo--accent { box-shadow: var(--edge-ring-accent); }
.todo--warn { box-shadow: 0 0 0 1px var(--warn-bg); }

.todo__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px 12px;
}
.todo__icon {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: var(--r-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  background: var(--surface-sunk);
  color: var(--ink-60);
}
.todo--accent .todo__icon { background: var(--accent-wash); color: var(--accent-deeper); }
.todo--warn .todo__icon { background: var(--warn-bg); color: var(--warn-ink); }
.todo__title { font-size: 17px; }
.todo__why { font-size: 13px; color: var(--ink-45); margin-top: 2px; }
.todo__count {
  margin-left: auto;
  font-size: 23px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink-40);
}
.todo--accent .todo__count { color: var(--accent-deep); }
.todo--warn .todo__count { color: var(--warn-ink); }

.todo__rows { display: flex; flex-direction: column; }
.todo__row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 18px;
  border-top: 1px solid var(--line-soft);
}
.todo__row:hover { background: var(--accent-softer); }
.todo__who {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 11px;
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.todo__name { font-size: 15px; }
.todo__detail {
  margin-left: auto;
  font-size: 13px;
  color: var(--ink-50);
  padding-right: 6px;
  white-space: nowrap;
}
.todo__more {
  width: 100%;
  padding: 10px;
  border: 0;
  border-top: 1px solid var(--line-soft);
  background: var(--surface-sunk);
  font: inherit;
  font-size: 13px;
  color: var(--accent-deep);
  cursor: pointer;
}
.todo__more:hover { background: var(--accent-soft); }

/* ── coach notes ─────────────────────────────────────────────────────────── */

.note-compose { display: flex; flex-direction: column; gap: 10px; }
.note-compose__foot { display: flex; align-items: center; gap: 12px; }
.note-compose__foot .btn { margin-left: auto; }

.notes { display: flex; flex-direction: column; }
.note-item {
  display: grid;
  grid-template-columns: 110px 1fr 34px;
  align-items: start;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line-soft);
}
.note-item:last-child { border-bottom: 0; }
.note-item__when { font-size: 13px; color: var(--ink-45); font-family: var(--mono); }
.note-item__body { font-size: 14px; line-height: 1.6; white-space: pre-wrap; }

/* Never signed in is a fact, not a gap — it reads as absence, not as data. */
.admin__seen.is-never { color: var(--ink-35); font-style: italic; }

/* ── loading / error / empty ─────────────────────────────────────────────── */

.state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
  padding: 56px 24px;
  margin: 24px 28px;
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--edge-ring);
}
.state > i { font-size: 26px; color: var(--ink-35); }
.state__title { font-size: 17px; }
.state__detail { font-size: 14px; color: var(--ink-60); max-width: 52ch; line-height: 1.6; }
.state__note { font-size: 13px; color: var(--ink-45); }
.state .btn { margin-top: 6px; }

.state--error { box-shadow: 0 0 0 1px var(--warn-bg); }
.state--error > i { color: var(--warn-ink); }

.state--loading > i {
  color: var(--accent);
  animation: state-spin 900ms linear infinite;
}
@keyframes state-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .state--loading > i { animation: none; }
}

/* Sample-data warning for the surfaces that have no rail to carry it. Fixed
   rather than in flow: the builder is three fixed columns that must not reflow
   mid-edit, and a bar that pushes the page down would be its own bug report. */
.samplebar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 5px 14px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: 12px;
  line-height: 1.4;
}
.samplebar i { font-size: 14px; flex: none; }

/* ── sign in ─────────────────────────────────────────────────────────────── */

.gatekeeper {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
}
.gatekeeper .state { margin: 0; max-width: 520px; }

.signin {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 32px;
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--lift);
}
.signin__brand { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; }
.signin__brand span { color: var(--ink-40); font-size: 15px; font-weight: 400; }
.signin__lead { font-size: 14px; color: var(--ink-60); margin-bottom: 4px; }
.signin__dev {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border-radius: var(--r-lg);
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: 13px;
  line-height: 1.55;
}
.signin__hints { display: flex; flex-wrap: wrap; gap: 6px; }
.signin__hints .chip { font-size: 12px; }

/* The three ways off the sign-in form: make an account, make a coach account,
   recover a password. Stacked rather than in a row — they are three separate
   errands, and a row of three links reads as one breadcrumb trail. The rule
   above them separates "ways out" from the form's own submit. */
.signin__alts {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 9px;
  margin-top: 2px;
  padding-top: 15px;
  border-top: 1px solid var(--line-field);
}
.signin__alts .linkish { font-size: 13px; text-align: left; }

/* ── applying to coach ────────────────────────────────────────────────────
   An athlete has no rail and no coach surface, but the profile editor doubles
   as the application form (§7, migration 0019). It needs room to breathe that
   the narrow gatekeeper column does not give it. */
.gatekeeper--wide {
  max-width: 1100px;
  width: 100%;
  align-items: stretch;
}
.applybar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 4px 12px;
  font-size: 15px;
}
.applybar .linkish { margin-left: auto; }
