/*
 * WisdomHub components.
 * Semantic classes that replace the Tailwind utility strings in trainermyhub.
 * Every value here maps to a token in styles.css. Nothing is invented.
 * Rule from the owner: no coloured vertical accent bars on cards, buttons, or boxes.
 */

/* ---------- Layout ---------- */

.container       { width: 100%; margin-inline: auto; padding-inline: 1.25rem; }
.container-md    { max-width: var(--w-md); }
.container-xl    { max-width: var(--w-xl); }
.container-2xl   { max-width: var(--w-2xl); }
.container-3xl   { max-width: var(--w-3xl); }
.container-4xl   { max-width: var(--w-4xl); }
.container-5xl   { max-width: var(--w-5xl); }
.container-6xl   { max-width: var(--w-6xl); }

.page            { min-height: 100vh; display: flex; flex-direction: column; }
.page > main     { flex: 1; }

.section         { padding-block: 4rem; }
@media (min-width: 640px) { .section { padding-block: 5rem; } }
.section + .section { padding-top: 0; }  /* stacked sections share one gap, not 80 + 80 (CP 17 Oct; every stacked pair shares its background, 17 Oct sweep) */

.stack > * + *   { margin-top: 1rem; }
.stack-sm > * + * { margin-top: 0.5rem; }
.stack-lg > * + * { margin-top: 1.5rem; }

.grid            { display: grid; gap: 1.5rem; }
.grid-2, .grid-3 { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 640px) {
  .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.row             { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.row-between     { justify-content: space-between; }
.row-start       { align-items: flex-start; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
[hidden] { display: none !important; }

/* ---------- Type helpers ---------- */

.eyebrow {
  font-size: var(--text-caption);                  /* sheet Label: 12px 700, 1px tracking, navy. Case as written: copy is frozen (CP 14 Sep) */
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--primary);
  text-transform: uppercase;                       /* sheet Label case; CP 15 Sep (copy session) */
}
.eyebrow-muted   { color: var(--muted-foreground); } /* reference-only blocks; also carries the prefix rule below */
/* Reference-only example blocks: Sean sees the state, ships nothing of this. */
[aria-label^="Example: "] { outline: 2px dashed var(--muted-foreground); outline-offset: 4px; }
[aria-label^="Example: "] > .eyebrow-muted::before { content: "Reference only \00b7\00a0"; }
/* Reference states are hidden until the reviewer flips "Show every state" (app.js block 22; ?states=1 also works).
   Sean: delete everything with aria-label="Example: ..." and [data-states-section]; they never ship. */
html:not(.show-states) [aria-label^="Example: "], html:not(.show-states) [data-states-section] { display: none !important; }
.states-toggle   { position: fixed; right: 1rem; bottom: 1rem; z-index: 60; opacity: 0.4; transition: opacity .15s; display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.875rem; border-radius: var(--radius-full); border: 1px dashed var(--muted-foreground); background: var(--card); color: var(--muted-foreground); font-size: var(--text-caption); font-weight: 600; cursor: pointer; box-shadow: var(--shadow-sm); }
.states-toggle[aria-pressed="true"] { border-style: solid; color: var(--foreground); }
.states-toggle:hover, .states-toggle:focus-visible, .states-toggle[aria-pressed="true"] { opacity: 1; } /* reviewer tool (CP 13 Sep): bottom-right, faded until wanted */
@media print, (max-width: 639px) { .states-toggle { display: none; } }
@media print { .qr { display: block; } } /* QR is print-only (T12): nobody scans a screen they are holding */
.eyebrow-light   { color: color-mix(in oklab, #fff 70%, transparent); }

/* Sheet heading rows as classes. Each carries face and weight, so any element can take a row. */
.display-lg      { font-family: var(--font-display); font-weight: 600; font-size: var(--text-display); line-height: 1.12; letter-spacing: -0.5px; }  /* H1; H2 size on mobile screens */
@media (min-width: 640px) { .display-lg { font-size: var(--text-display-lg); } }
.display         { font-family: var(--font-display); font-weight: 600; font-size: var(--text-display); line-height: 1.2; letter-spacing: -0.3px; }      /* H2 */
.heading         { font-family: var(--font-sans); font-weight: 700; font-size: var(--text-heading); line-height: 1.3; letter-spacing: -0.3px; }         /* H3 */
.subheading      { font-family: var(--font-sans); font-weight: 600; font-size: var(--text-subheading); line-height: 1.35; letter-spacing: -0.1px; }     /* H4 */
.body-lg         { font-size: var(--text-body-lg); }
.body-sm         { font-size: var(--text-body-sm); }
.caption         { font-size: var(--text-caption); }
.overline        { font-size: var(--text-overline); }

.text-muted      { color: var(--muted-foreground); }
.text-soft       { color: color-mix(in oklab, var(--foreground) 75%, transparent); }
.text-primary    { color: var(--primary); }
.text-coral      { color: var(--coral); }
.text-success    { color: var(--success); }
.text-destructive{ color: var(--destructive); }
.text-white      { color: #fff; }
.text-center     { text-align: center; }
.italic          { font-style: italic; }
.medium          { font-weight: 500; }
.semibold        { font-weight: 600; }
.tabular         { font-variant-numeric: tabular-nums; }
.prewrap         { white-space: pre-line; }
.break           { overflow-wrap: anywhere; }
.relaxed         { line-height: 1.65; }
.mt-1 { margin-top: 0.25rem; } .mt-2 { margin-top: 0.5rem; } .mt-3 { margin-top: 0.75rem; }
.mt-4 { margin-top: 1rem; }    .mt-5 { margin-top: 1.25rem; } .mt-6 { margin-top: 1.5rem; }
.mt-8 { margin-top: 2rem; }    .mt-10 { margin-top: 2.5rem; } .mt-12 { margin-top: 3rem; }
.mt-16 { margin-top: 4rem; }

/* Editorial prose (About, articles, legal). */
.prose > * + *   { margin-top: 1.25rem; }
.prose p         { font-size: var(--text-body-lg); line-height: 1.7; color: var(--grey-700); } /* sheet Body Large */
.prose h2        { margin-top: 2.5rem; }
/* Legal pages (rendered from the legal pack by build-legal.py): long documents, body size not body-lg. */
.prose--legal > * + *   { margin-top: 1rem; }
.prose--legal p, .prose--legal li, .prose--legal td, .prose--legal th, .prose--legal blockquote { font-size: var(--text-body); line-height: 1.65; }
.prose--legal h2        { font-family: var(--font-sans); font-size: var(--text-heading); font-weight: 700; letter-spacing: -0.3px; margin-top: 2rem; } /* H3 row */
.prose--legal h3        { font-size: var(--text-subheading); font-weight: 600; letter-spacing: -0.1px; margin-top: 1.5rem; } /* H4 row */
.prose--legal h4        { font-size: var(--text-body-lg); margin-top: 1.25rem; }
/* Collapsed legal sub-section (build-legal.py COLLAPSED). Summary reads as an h4 with a toggle. */
.prose-fold summary     { cursor: pointer; font-weight: 600; font-size: var(--text-body); margin-top: 1.25rem; list-style: none; }
.prose-fold summary::-webkit-details-marker { display: none; }
.prose-fold summary::after { content: " +"; color: var(--muted-foreground); }
.prose-fold[open] summary::after { content: " \2013"; }
.prose-fold > :not(summary) { margin-top: 1rem; }
/* Quiet fold (profile-setup, 23 Sep): sits under caption-size labels, so the
   summary matches the text around it instead of outweighing it. The fold holds
   detail nobody has to read; it should not pull the eye off the form. */
.prose-fold--quiet summary { margin-top: 0.5rem; font-size: var(--text-body-sm); font-weight: 400; color: var(--muted-foreground); }
.prose-fold--quiet > :not(summary) { margin-top: 0.5rem; }
.prose ul        { padding-left: 1.25rem; list-style: disc; }
.prose li + li   { margin-top: 0.5rem; }
.prose blockquote {
  margin: 2.5rem 0; padding: 0;
  font-family: var(--font-display); font-size: var(--text-heading); font-weight: 600;
  font-style: italic; line-height: 1.3; color: var(--coral);
}

/* ---------- Site chrome ---------- */

.site-header {
  border-bottom: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  background: color-mix(in oklab, var(--canvas) 70%, transparent);
  backdrop-filter: blur(8px);
  position: sticky; top: 0; z-index: 50; /* Menu stays reachable on long pages, phones especially (CP 6 Sep). */
}
.site-header__inner {
  max-width: var(--w-6xl); margin-inline: auto; padding: 1rem 1.25rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.site-brand {
  display: flex; align-items: center; gap: 0.625rem; text-decoration: none; white-space: nowrap; flex-shrink: 0;
}
.site-brand__logo { display: block; height: 2rem; width: auto; }
.site-brand__tag  { font-size: var(--text-caption); color: var(--muted-foreground); display: none; }
@media (min-width: 1024px) { .site-brand__tag { display: inline; } }

.site-nav        { display: none; align-items: center; gap: 0.25rem; font-size: var(--text-body); }
@media (min-width: 768px) { .site-nav { display: flex; } }
/* Admin header only: the selector keys on the untagged "Admin" brand tag (launch pages carry
   data-config="brand.tagline" on the same class). Eleven links do not fit one row at 1440, so the nav wraps.
   Orchestrator stop-gap, 23 Sep; the booked layout session may replace it. */
@media (min-width: 768px) { .site-header:has(.site-brand__tag:not([data-config])) .site-nav:not(.site-nav--mobile) { flex-wrap: wrap; justify-content: flex-end; row-gap: 0; } }
.site-nav a, .site-nav button {
  border: 0; background: none; cursor: pointer; text-decoration: none;
  padding: 0.5rem 0.75rem; border-radius: var(--radius-md); white-space: nowrap;
  color: color-mix(in oklab, var(--foreground) 80%, transparent);
  transition: background-color .15s, color .15s;
}
@media (hover: hover) { .site-nav a:hover, .site-nav button:hover { background: var(--accent); color: var(--foreground); } }
.site-nav a[aria-current="page"] { color: var(--foreground); font-weight: 500; }
.site-nav .btn   { margin-left: 0.5rem; }
/* ".site-nav a" outranks ".btn-primary", so restate the button's rest and hover states here. */
.site-nav a.btn-primary { background: var(--primary); color: var(--primary-foreground); }
@media (hover: hover) { .site-nav a.btn-primary:hover { background: var(--primary-hover); color: var(--primary-foreground); } }

.nav-toggle {
  display: grid; place-items: center; width: 2.5rem; height: 2.5rem; border: 0; background: none;
  border-radius: var(--radius-md); cursor: pointer; color: color-mix(in oklab, var(--foreground) 80%, transparent);
}
@media (hover: hover) { .nav-toggle:hover { background: var(--accent); } }
@media (min-width: 768px) { .nav-toggle { display: none; } }
/* CP 3 Nov (HANDOFF 286): the icon follows the state. Three lines closed, an X open; the button stays put so the
   thumb lands on the same spot. Until now only the hidden label changed, so a sighted user saw no way to close. */
.nav-toggle__close, .nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

.site-nav--mobile {
  /* ".site-nav" sets align-items:center; in a column that centres each row. Override to stretch
     so links are left-aligned and full-width tap targets. */
  display: none; flex-direction: column; align-items: stretch; gap: 0.25rem;
  border-top: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  background: var(--canvas); padding: 0.75rem 1.25rem; font-size: var(--text-body);
}
.site-nav--mobile.is-open { display: flex; }
/* CP 19 Sep (mobile): the drawer overlays the page instead of pushing it down. The header is the containing block.
   CP 20 Sep: position: relative removed here; it had overridden the sticky header (6 Sep) on every screen. Sticky is
   a positioned box too, so the drawer's top: 100% still hangs from the header. */
.site-header { z-index: 40; }
.site-nav--mobile.is-open { position: absolute; top: 100%; left: 0; right: 0; max-height: calc(100vh - 100%); overflow-y: auto; box-shadow: var(--shadow-lg, 0 12px 32px rgba(15, 23, 42, .18)); }
/* CP 19 Sep (mobile): the help page's "On this page" list repeats the accordion headings on a phone; desktop only. */
@media (max-width: 639px) { nav[aria-label="On this page"] { display: none; } }
@media (min-width: 768px) { .site-nav--mobile { display: none !important; } }
.site-nav--mobile a, .site-nav--mobile button { text-align: left; }
.site-nav--mobile .btn { margin: 0.5rem 0 0; align-self: flex-start; }

/* Resources dropdown (CP 7 Sep). Hover and keyboard focus open it; the button click
   toggles it for touch. Sean: a native <details> works too, this is markup-only on purpose. */
.nav-menu { position: relative; }
.nav-menu__btn { display: inline-flex; align-items: center; gap: 0.25rem; font: inherit; }
.nav-menu__btn svg { width: 1rem; height: 1rem; transition: transform .15s; }
.site-nav button[aria-current="page"] { color: var(--foreground); font-weight: 500; }
.nav-menu__panel {
  display: none; position: absolute; top: 100%; left: 0; z-index: 60; min-width: 11rem;
  margin-top: 0.25rem; padding: 0.375rem; flex-direction: column; gap: 0.125rem;
  background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow-menu);
}
.nav-menu__panel a { padding: 0.5625rem 0.75rem; border-radius: var(--radius-sm); font-size: var(--text-body-sm); font-weight: 500; color: var(--grey-700); } /* sheet menu item: 9 x 12, r8, 13/500 */
@media (hover: hover) { .site-nav .nav-menu__panel a:hover { background: var(--grey-50); color: var(--grey-700); } }
/* Invisible bridge so the pointer can cross the gap without closing the panel. */
.nav-menu__panel::before { content: ""; position: absolute; left: 0; right: 0; top: -0.375rem; height: 0.375rem; }
.nav-menu.is-open .nav-menu__panel { display: flex; }  /* one opener: app.js block 19 (focus-within fought the click toggle, CP 16 Sep) */
.nav-menu.is-open .nav-menu__btn svg { transform: rotate(180deg); }
/* Find programmes menu (CP 15 Sep, after Upwork): the 22 areas in three columns. Desktop; the drawer folds the same list in a <details> group. */
.site-nav:has(.nav-menu__panel--areas) { position: relative; }
.nav-menu:has(.nav-menu__panel--areas) { position: static; }  /* the wide panel anchors to the nav's right edge, not the button, so it never runs off the viewport */
.nav-menu__panel--areas { display: none; left: auto; right: 0; grid-template-columns: repeat(3, 13.5rem); grid-template-rows: repeat(8, auto); grid-auto-flow: column; column-gap: 0.75rem; padding: 0.75rem; }  /* reads down each column, taxonomy order */
.nav-menu.is-open .nav-menu__panel--areas { display: grid; }
.nav-menu__panel--areas a { white-space: normal; line-height: 1.3; }
.site-nav--mobile .site-nav__sub { padding-left: 1.75rem; font-size: var(--text-body-sm); }
/* Drawer groups (CP 14 Sep): identity row, then native <details> sections with a hairline between them. */
.site-nav__who { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0.75rem 0.75rem; }
.site-nav__group { border-top: 1px solid color-mix(in oklab, var(--border) 60%, transparent); padding-top: 0.25rem; margin-top: 0.25rem; }
.site-nav__group summary {
  display: flex; align-items: center; justify-content: space-between; list-style: none; cursor: pointer;
  padding: 0.5rem 0.75rem; border-radius: var(--radius-md); font-weight: 500; color: color-mix(in oklab, var(--foreground) 80%, transparent);
}
.site-nav__group summary::-webkit-details-marker { display: none; }
.site-nav__group summary svg { width: 1rem; height: 1rem; transition: transform .15s; }
.site-nav__group[open] summary svg { transform: rotate(180deg); }
.site-nav__group a { display: block; }
.site-nav__group[open] { padding-bottom: 0.25rem; }
.site-nav__group--first { border-top: 0; margin-top: 0; }  /* first fold sits flush under the drawer links */
.site-nav__sub--all { color: var(--primary); font-weight: 500; }  /* drawer: seven areas shown, this link opens the full list */
/* Why us menu (CP 15 Sep, after Upwork): each link carries a one-line description. Same markup in the desktop panel and the drawer fold. */
.nav-menu__panel:has(.nav-menu__item) { min-width: 19rem; }
.nav-menu__panel a.nav-menu__item, .site-nav a.site-nav__sub--desc { display: flex !important; flex-direction: column; align-items: flex-start; text-align: left; gap: 0.125rem; }
.site-nav--mobile .site-nav__sub--desc .nav-menu__title { font-weight: 600; color: var(--foreground); }  /* drawer: title bold so it reads apart from its description (CP 15 Sep) */
.nav-menu__desc { font-weight: 400; font-size: var(--text-caption); color: var(--muted-foreground); }

/* Header tools (CP 14 Sep): bell and help sit with the avatar, set apart from the text links. Icon button = sheet 40px, r10. */
.site-nav__tools { display: inline-flex; align-items: center; gap: 0.125rem; margin-left: 1.25rem; }
.site-nav a.site-nav__icon { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; padding: 0; }
.site-nav__icon .icon { width: 1.25rem; height: 1.25rem; }
/* Notifications dropdown (CP 14 Sep): bell button with an unread dot; rows = icon tile, title + due, one meta line. */
.nav-menu--notify .nav-menu__btn { position: relative; }
.nav-menu--notify.is-open .nav-menu__btn svg { transform: none; } /* the rotate rule is for chevrons */
.nav-menu--notify .nav-menu__btn[data-unread]::after { content: ""; position: absolute; top: 0.5rem; right: 0.625rem; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--coral); box-shadow: 0 0 0 2px var(--canvas); }
.nav-menu--notify .nav-menu__panel { left: auto; right: 0; width: 22rem; max-width: calc(100vw - 2.5rem); max-height: min(70vh, 32rem); overflow-y: auto; }
.nav-menu__panel a.notify__item { align-items: flex-start; gap: 0.75rem; padding: 0.625rem 0.75rem; white-space: normal; }
.notify__item .icon-tile { width: 2rem; height: 2rem; border-radius: var(--radius-sm); flex-shrink: 0; }
.notify__item .icon-tile svg { width: 1rem; height: 1rem; }
.notify__body  { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 0.125rem; }
.notify__title { display: flex; align-items: baseline; gap: 0.5rem; }
.notify__due   { margin-left: auto; font-size: var(--text-caption); font-weight: 600; white-space: nowrap; }
.notify__due--now  { color: var(--coral); }
.notify__due--soon { color: var(--amber-700); }
.notify__meta  { font-size: var(--text-caption); font-weight: 400; color: var(--muted-foreground); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Account menu (CP 14 Sep): the avatar opens the sheet Dropdown Menu, right-aligned, on every signed-in
   header. Same [data-menu] behaviour as Resources. Sheet values: 220 wide, item 9 x 12 r8 13/500 with a
   16px grey-500 icon, separator 1px grey-100, danger item red on a #FEF2F2 hover. */
.nav-menu--account .nav-menu__btn { padding: 0.125rem 0.25rem 0.125rem 0.125rem; border-radius: var(--radius-full); }
.nav-menu--account .avatar { width: 2.25rem; height: 2.25rem; font-size: var(--text-body-sm); }
.nav-menu--account .nav-menu__panel { left: auto; right: 0; width: 13.75rem; }
.nav-menu__head { padding: 0.5625rem 0.75rem 0.375rem; min-width: 0; }
.nav-menu__head span { display: block; }
.nav-menu__sep { height: 1px; background: var(--grey-100); margin: 0.375rem 0.25rem; }
.nav-menu__panel a { display: flex; align-items: center; gap: 0.6875rem; }
.nav-menu__panel a svg { width: 1rem; height: 1rem; flex-shrink: 0; color: var(--grey-500); }
.nav-menu__panel a .nav-menu__val { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
.nav-menu__panel a.is-danger, .nav-menu__panel a.is-danger svg { color: var(--destructive); }
@media (hover: hover) { .site-nav .nav-menu__panel a.is-danger:hover { background: #FEF2F2; color: #B91C1C; } /* sheet hover is #DC2626 on #FEF2F2 = 4.4:1; one step darker for AA */ }

.site-footer {
  margin-top: 6rem;
  border-top: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  background: color-mix(in oklab, var(--canvas) 40%, transparent);
}
.site-footer__inner {
  max-width: var(--w-6xl); margin-inline: auto; padding: 2rem 1.25rem;
  display: flex; flex-direction: column; gap: 1rem; font-size: var(--text-body-sm); color: var(--muted-foreground); /* footer one step under body (CP 13 Sep) */
}
@media (min-width: 640px) {
  .site-footer__inner { flex-direction: row; align-items: center; justify-content: space-between; }
}
.site-footer__brandline { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; }
.site-footer__logo  { display: block; height: 1.375rem; width: auto; }
.site-footer__links { display: flex; gap: 1rem; flex-wrap: wrap; }
.site-footer__links a { text-decoration: none; }
@media (hover: hover) { .site-footer__links a:hover { color: var(--foreground); } }
.site-footer__legal {
  max-width: var(--w-6xl); margin-inline: auto; padding: 0 1.25rem 2rem;
  font-size: var(--text-overline); color: var(--muted-foreground); /* legal line, 12px */
}

/* Launch footer: four link columns + bottom bar. Spec ../2026-09-16-launch-footer-design.md (16 Sep).
   Pre-launch pages keep the thin row above; these rules only fire on .site-footer--launch. */
.site-footer--launch { padding: 3rem 1.25rem 2rem; }
.site-footer__grid {
  max-width: var(--w-6xl); margin-inline: auto;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem 1.5rem;
}
@media (min-width: 768px) { .site-footer__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.site-footer__col .eyebrow { display: block; margin: 0 0 1rem; }
.site-footer__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.site-footer__col a { font-size: var(--text-body-sm); color: var(--muted-foreground); text-decoration: none; }
@media (hover: hover) { .site-footer__col a:hover { color: var(--foreground); } }
.site-footer__bar {
  max-width: var(--w-6xl); margin: 2.5rem auto 0; padding-top: 1.5rem;
  border-top: 1px solid color-mix(in oklab, var(--border) 60%, transparent);
  display: flex; flex-direction: column; gap: 1rem; color: var(--muted-foreground);
}
@media (min-width: 640px) { .site-footer__bar { flex-direction: row; align-items: center; justify-content: space-between; } }
.site-footer__copyright { font-size: var(--text-overline); }               /* legal line, 12px, same as the thin row */
.site-footer__social { display: flex; align-items: center; gap: 1rem; font-size: var(--text-body-sm); }
.site-footer__social a { display: inline-flex; color: var(--muted-foreground); }
.site-footer__social svg { width: 20px; height: 20px; }
@media (hover: hover) { .site-footer__social a:hover { color: var(--foreground); } }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.75rem 1.75rem;                                    /* sheet button: 12 x 28, 14/600, 2px border, r10 */
  border-radius: var(--radius-md); border: 2px solid transparent;
  font-size: var(--text-body); font-weight: 600; line-height: 1.5; letter-spacing: 0.1px;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color .15s, color .15s, border-color .15s, opacity .15s, transform .16s var(--ease-out);
}
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
/* S4: every pressable answers the press. Cards that are links keep the border change only. */
.btn:active:not(:disabled):not([aria-disabled="true"]), .chip:active, .pcard__save:active, .nav-toggle:active,
.states-toggle:active, .composer__attach:active, .demo__play:active, .cookie-banner__close:active { transform: scale(0.97); }
.pcard__save, .nav-toggle, .states-toggle, .composer__attach, .demo__play, .cookie-banner__close { transition: transform .16s var(--ease-out); }
.btn-primary     { background: var(--primary); color: var(--primary-foreground); }
@media (hover: hover) { .btn-primary:hover:not(:disabled) { background: var(--primary-hover); } }
/* Colour roles (design review 12 Sep, S1): green = HRDC accredited only, navy = action, amber = time,
   coral = the CTA. Coral button uses --coral-700 so white text passes AA (5.5:1; --coral-500 was 3.3:1). */
.btn-secondary   { background: var(--secondary-button); color: var(--secondary-foreground); }
@media (hover: hover) { .btn-secondary:hover:not(:disabled) { background: var(--secondary-button-hover); } }
.btn-outline     { background: transparent; color: var(--primary); border-color: var(--grey-300); }   /* sheet outlined: navy text, grey-300 border */
@media (hover: hover) { .btn-outline:hover:not(:disabled) { border-color: var(--primary); background: var(--accent); } }
.btn-inverted    { background: #fff; color: var(--primary); border-color: #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); } /* sheet inverted: for navy surfaces */
@media (hover: hover) { .btn-inverted:hover:not(:disabled) { background: var(--grey-50); } }
.btn-success     { background: var(--success); color: var(--success-foreground); }
.btn-destructive-outline { background: var(--background); color: var(--destructive); border-color: color-mix(in oklab, var(--destructive) 40%, transparent); }
@media (hover: hover) { .btn-destructive-outline:hover:not(:disabled) { background: color-mix(in oklab, var(--destructive) 10%, transparent); } }
.btn-ghost       { background: none; color: var(--muted-foreground); border-color: transparent; padding-inline: 0.5rem; }
@media (hover: hover) { .btn-ghost:hover:not(:disabled) { color: var(--foreground); } }
.btn-pill        { } /* step 4: the sheet has one button shape (r10); the round CTA is retired, class kept so no markup changes */
.btn-sm          { padding: 0.5rem 1.125rem; font-size: var(--text-body-sm); border-radius: var(--radius-sm); }   /* sheet 8 x 18, 13px, r8 */
.btn-lg          { padding: 0.875rem 2.25rem; font-size: 0.9375rem; border-radius: var(--radius); }              /* sheet 14 x 36, 15px, r12 */
.btn-block       { width: 100%; }
.btn-link {
  background: none; border: 0; padding: 0; min-height: 0; color: var(--primary);
  font-weight: 500; text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
@media (hover: hover) { .btn-link:hover  { opacity: 0.8; } }
.btn-dashed {
  width: 100%; padding: 0.75rem; border: 1px dashed var(--border); border-radius: var(--radius-lg);
  background: none; color: var(--primary); font-weight: 500; cursor: pointer;
}
@media (hover: hover) { .btn-dashed:hover { border-color: var(--primary); } }

/* ---------- Cards ---------- */

.card {
  background: var(--card); color: var(--card-foreground);
  border-radius: var(--radius-card);
  padding: 1.5rem; box-shadow: var(--shadow-card);
}
.card-tight      { padding: 1.25rem; }
.card-flat       { box-shadow: none; }
.card-xl         { border-radius: var(--radius-lg); padding: 1rem; }

/* Builder section card: title, hint, divider, body. */
.section-card    { padding: 1.5rem; }
@media (min-width: 640px) { .section-card { padding: 2rem; } }
.section-card__head { display: flex; align-items: center; gap: 0.5rem; }
.section-card__head h2, .section-card__head h3 { font-family: var(--font-sans); font-size: var(--text-heading); font-weight: 700; letter-spacing: -0.3px; } /* H3 row; a 31px Lora H2 is too heavy for a form section */
.section-card__action { margin-left: auto; }
.section-card__action [data-toggle][aria-expanded="true"],
.list-row__actions [data-toggle][aria-expanded="true"] { display: none; }   /* form open: Cancel sits beside Save, the top Edit steps back (CP 14 Sep) */
.section-card__hint { margin-top: 0.25rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.section-card__rule { margin-top: 0.75rem; height: 1px; background: var(--border); }
.section-card__body { margin-top: 1.5rem; }
/* Profile edit cards: while a section's form is open its saved view is hidden, so the reader never sees the text twice (CP 27 Sep). */
.section-card__body:has(> [id$="-edit"]:not([hidden])) > [id$="-view"] { display: none; }
.section-card__body:not(:has(> :not([hidden]))) { display: none; }

.divide > * + *  { border-top: 1px solid var(--border); padding-top: 1.25rem; margin-top: 1.25rem; }

/* ---------- Forms ---------- */

.field           { display: block; }
.field + .field, .field-group + .field, .field + .field-group, [data-role] + .field, [data-tp] + .field, .field + [data-tp], [data-launch] + .field, [data-prelaunch] + .field { margin-top: 1rem; } /* [data-launch]/[data-prelaunch]: a mode wrapper, hidden in the other mode, broke the chain above programme-edit Summary (17 Oct sweep). [data-role]: a role-switched block of fields is followed by a shared field (company-profile "How you found WisdomHub"), design review 20 Sep. [data-tp]: the provider-only block is hidden for companies, so the next field lost its gap (brief-new Requirements/Remarks, CP 16 Oct) */
/* Fields side by side in a grid row (Postcode | Town): the grid gap spaces them, so the second must not drop 1rem; the row keeps 1rem from the field above (CP 17 Oct) */
.grid-2 > .field + .field, .grid-3 > .field + .field { margin-top: 0; }
.field + .grid-2:has(> .field), .field + .grid-3:has(> .field),
.grid-2:has(> .field) + .field, .grid-3:has(> .field) + .field { margin-top: 1rem; }
.field__label    { display: block; font-size: var(--text-body); font-weight: 600; color: var(--grey-700); }         /* 14/600: CP 16 Oct type scale, question > guidance (sheet 13/600) */
.field__help     { display: block; margin-top: 0.375rem; font-size: var(--text-caption); color: var(--muted-foreground); } /* sheet helper 12px; grey-400 fails AA, muted token instead */
.field__error    { display: block; margin-top: 0.375rem; font-size: var(--text-caption); font-weight: 500; color: var(--destructive); }
.field__control, .input, .select, .textarea {
  display: block; width: 100%; margin-top: 0.375rem;
  padding: 0.6875rem 0.875rem; font-size: var(--text-body); line-height: 1.5; color: var(--foreground);
  background: var(--background); border: 1.5px solid var(--input); border-radius: var(--radius-md);   /* sheet input: 1.5px, r10, 11 x 14 */
  transition: border-color .15s, box-shadow .15s;
}
@media (max-width: 767px) { .field__control, .input, .select, .textarea { font-size: 1rem; } } /* Phones: under 16px, iOS Safari zooms the page when a field is tapped. */
.input::placeholder, .textarea::placeholder { color: var(--grey-400); font-size: var(--text-body-sm); } /* CP 16 Oct: example text 13px, light grey. Below AA on purpose: a sample, the instruction is .field__help (AA). Typed text keeps 14 (16 on phones) */
.input[type="search"]::placeholder { color: var(--muted-foreground); font-size: inherit; } /* search boxes have no label: the placeholder IS the instruction, so it keeps AA and full size */
.input:focus, .select:focus, .textarea:focus, .field__control:focus {
  outline: none; border-color: var(--primary);
  box-shadow: var(--ring-focus);                                                                       /* sheet: navy border + 3px ring at 8% */
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"], .select[aria-invalid="true"] { border-color: var(--destructive); }
.input[aria-invalid="true"]:focus, .textarea[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.08); }
.input:disabled, .select:disabled, .textarea:disabled { background: var(--grey-100); color: var(--grey-400); border-color: var(--grey-200); cursor: not-allowed; }
.select          { appearance: none; padding-right: 2.25rem;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='5'><path d='M0 0h10L5 5z' fill='%2364748B'/></svg>"); /* sheet: 5px triangle, grey-500 */
  background-repeat: no-repeat; background-position: right 0.875rem center; }
.textarea        { resize: vertical; min-height: 5.5rem; }
.counter-wrap    { display: block; }
.counter {
  display: block; margin-top: 0.25rem; text-align: right;
  font-size: var(--text-caption); color: var(--muted-foreground); font-variant-numeric: tabular-nums; /* 12px, CP 16 Oct (was 11) */
}
.counter.is-over { color: var(--destructive); font-weight: 500; }

.check           { display: flex; align-items: flex-start; gap: 0.625rem; font-size: var(--text-body); cursor: pointer; } /* 14, an answer like typed text (CP 16 Oct) */
.filters .check  { font-size: var(--text-body-sm); } /* search and board filter lists keep 13 */
.check input     { margin-top: 0; flex-shrink: 0; }
/* Sheet checkbox and radio: 20px, 1.5px grey-300, r6 or circle; checked = navy fill with a white tick or an 8px white dot. */
input[type="checkbox"], input[type="radio"] {
  appearance: none; width: 1.25rem; height: 1.25rem; margin: 0; flex-shrink: 0; cursor: pointer;
  border: 1.5px solid var(--grey-300); border-radius: 6px; background: var(--background) center / 0.75rem no-repeat;
  transition: border-color .15s, background-color .15s;
}
input[type="radio"] { border-radius: 50%; background-size: 0.5rem; }
input[type="checkbox"]:checked, input[type="radio"]:checked { border-color: var(--primary); background-color: var(--primary); }
input[type="checkbox"]:checked { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>"); }
input[type="radio"]:checked    { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><circle cx='4' cy='4' r='4' fill='%23fff'/></svg>"); }
input[type="checkbox"]:disabled, input[type="radio"]:disabled { opacity: 0.5; cursor: not-allowed; }
.check:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
.check--inline   { align-items: center; font-size: var(--text-body); }

.chips           { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
.chip {
  display: inline-flex; align-items: center;
  border: 1.5px solid var(--grey-200); background: var(--background); color: var(--grey-600);
  border-radius: var(--radius-full); padding: 0.4375rem 1rem; font-size: var(--text-caption); font-weight: 600; cursor: pointer;   /* sheet pill: 12/600, 7 x 16, 1.5px */
  transition: border-color .15s, background-color .15s, color .15s, transform .16s var(--ease-out);
}
@media (hover: hover) { .chip:hover      { border-color: var(--primary); color: var(--primary); } }
.chip[aria-pressed="true"] { background: var(--navy-50); border-color: var(--primary); color: var(--primary); }   /* tinted, not solid: a chip must not read as a primary button (CP 26 Sep) */
/* Radio chips: one click, one active, tinted not solid (CP 16 Sep). Board filters and the credits ledger filter. */
.chip-radios { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.375rem; }
.chip-radio { position: relative; }
.chip-radio input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.chip-radio input:checked + .chip { background: var(--navy-50); border-color: var(--primary); color: var(--primary); font-weight: 600; }
.chip-radio input:focus-visible + .chip { outline: 2px solid var(--ring); outline-offset: 2px; }
.chip-static     { cursor: default; border-color: transparent; border-radius: var(--radius-sm); padding: 0.375rem 0.75rem; font-weight: 500; background: var(--navy-50); color: var(--primary); } /* sheet tag: 12/500, 6 x 12, r8, tinted, no border */
@media (hover: hover) { .chip-static:hover { border-color: transparent; color: var(--primary); } }
.chip-selected {
  display: inline-flex; align-items: center; gap: 0.375rem; cursor: default;
  border-color: var(--primary); background: var(--navy-50); color: var(--primary);
}
.chip-selected button { border: 0; background: none; padding: 0; cursor: pointer; color: var(--muted-foreground); font-size: 1rem; line-height: 1; }
@media (hover: hover) { .chip-selected button:hover { color: var(--foreground); } }

/* .upload-box has no outline (CP 17 Oct): the dashed box made upload fields the only boxed field; they read label, help, button like the rest */
.upload-box + .upload-box { margin-top: 1.5rem; } /* stacked entries (certificates) stay apart without the outline */
.upload-box > * + * { margin-top: 0.75rem; }
.upload-box > p  { font-size: var(--text-caption); } /* upload help = field help, 12px (CP 16 Oct) */

.form-actions    { display: flex; align-items: center; gap: 0.75rem; margin-top: 1rem; flex-wrap: wrap; }

/* ---------- Pills, badges, status ---------- */

.pill {
  display: inline-flex; align-items: center; gap: 0.25rem;
  border-radius: var(--radius-full); padding: 0.25rem 0.75rem;
  font-size: var(--text-overline); font-weight: 600; line-height: 1.5; border: 0; white-space: nowrap;   /* sheet badge: 11/600, 4 x 12, tinted, no border */
}
.pill-muted      { background: var(--grey-100); color: var(--muted-foreground); }                /* sheet grey-500 text fails AA */
.pill-primary    { background: var(--navy-50); color: var(--primary); }
.pill-success    { background: #ECFDF5; color: #047857; }                                       /* sheet #059669 on this tint is 3.3:1; kept darker (S1, open for CP) */
.pill-warning    { background: #FFFBEB; color: #92400E; }
.pill-coral      { background: var(--coral-50); color: var(--coral-700); }                       /* sheet coral-500 text on coral-50 is 3.2:1; coral-700 kept */
.pill-outline    { box-shadow: inset 0 0 0 1px var(--border); color: var(--foreground); }        /* site-only variant, no sheet row */
.pill-upper      { }

/* ---------- Avatars ---------- */

.avatar {
  display: inline-grid; place-items: center; flex-shrink: 0; overflow: hidden;
  width: 4rem; height: 4rem; border-radius: var(--radius-full);
  background: var(--primary); color: #fff; font-weight: 600; font-size: 1.25rem;
}
.avatar img      { width: 100%; height: 100%; object-fit: cover; }
.avatar-sm       { width: 2.5rem; height: 2.5rem; font-size: var(--text-body); }
.avatar-lg       { width: 5rem; height: 5rem; font-size: 1.5rem; }
.avatar-xl       { width: 7rem; height: 7rem; font-size: 2rem; } /* profile header; circle like every other avatar (T8) */
.avatar-success  { background: var(--success); }

/* ---------- Hero (landing, about) ---------- */

.hero {
  position: relative; display: flex; align-items: center; overflow: hidden;
  min-height: 540px; border-radius: var(--radius-xl); background: var(--primary);
}
@media (min-width: 640px) { .hero { min-height: 600px; } }
.hero__img       { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero__img--top  { object-position: 50% 18%; }  /* faces sit high in the frame (search hero) */
.hero__scrim     { position: absolute; inset: 0; background: color-mix(in oklab, var(--navy-900) 72%, transparent); }
@media (min-width: 640px) {
  .hero__scrim { background: linear-gradient(to right,
    color-mix(in oklab, var(--navy-900) 92%, transparent),
    color-mix(in oklab, var(--navy-900) 60%, transparent) 55%,
    transparent); }
}
.hero__body      { position: relative; max-width: var(--w-xl); padding: 3rem 1.5rem; }
@media (min-width: 640px) { .hero__body { padding: 4rem 3rem; } }
.hero__title     { margin-top: 1.5rem; color: #fff; }  /* size from .display-lg on the element */

.hero__title em  { font-style: italic; color: var(--coral-300); }
.hero__lead      { margin-top: 1.25rem; max-width: var(--w-md); font-size: var(--text-body-lg); color: color-mix(in oklab, #fff 85%, transparent); }
.hero__note      { margin-top: 0.75rem; font-size: var(--text-body-sm); color: color-mix(in oklab, #fff 78%, transparent); }  /* the free-to-search fact, restored under the chips (copy session 15 Sep) */
.hero__hook      { margin-top: 2rem; max-width: var(--w-md); font-size: var(--text-body-lg); font-weight: 600; color: #fff; }
.hero__meta      { margin-top: 1.25rem; font-size: var(--text-body); color: color-mix(in oklab, #fff 80%, transparent); }
.hero__meta a    { color: #fff; font-weight: 500; text-underline-offset: 2px; }


/* Solid colour band (closing capture). */
.band            { background: var(--primary); color: #fff; }
.band__inner     { max-width: var(--w-md); margin-inline: auto; padding: 4rem 1.25rem; text-align: center; }
@media (min-width: 640px) { .band__inner { padding-block: 5rem; } }
.band h2         { color: #fff; font-size: var(--text-display); }
.band p          { color: color-mix(in oklab, #fff 80%, transparent); }
.band-wide .band__inner { max-width: var(--w-5xl); }
.band-cards      { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .band-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.band-card {
  padding: 1.5rem; border-radius: var(--radius-lg);
  background: color-mix(in oklab, #fff 8%, transparent);
  border: 1px solid color-mix(in oklab, #fff 12%, transparent);
}
.band-card h3    { color: #fff; font-size: var(--text-subheading); }
.band-card p     { margin-top: 0.5rem; color: color-mix(in oklab, #fff 80%, transparent); line-height: 1.6; }

.strip {
  border-top: 1px solid color-mix(in oklab, var(--border) 40%, transparent);
  background: var(--background); padding: 2rem 1.25rem; text-align: center;
  font-size: var(--text-caption); font-weight: 500;
  color: var(--muted-foreground);
}

/* ---------- Landing blocks ---------- */

.pillar          { overflow: hidden; border-radius: var(--radius-card); background: var(--card); box-shadow: var(--shadow-card); } /* one card fill (S3) */
.pillar img      { height: 16rem; width: 100%; object-fit: cover; }
.pillar__body    { padding: 1.75rem 1.75rem 2rem; }
.pillar__label   { display: flex; align-items: center; gap: 0.5rem; color: var(--muted-foreground); font-weight: 600; font-size: var(--text-body); } /* was violet; violet retired from labels (S1) */
.pillar__label svg { width: 1.25rem; height: 1.25rem; flex-shrink: 0; }
.pillar__body h3 { margin-top: 0.875rem; font-size: var(--text-heading); line-height: 1.3; }
.pillar__body p:not(.pillar__label) { margin-top: 0.75rem; font-size: var(--text-body-lg); color: color-mix(in oklab, var(--foreground) 75%, transparent); line-height: 1.6; }

.trainer-card {
  display: flex; align-items: center; gap: 1rem; padding: 1.25rem;
  border-radius: var(--radius-lg); background: var(--card); box-shadow: var(--shadow-card);
}
.trainer-card__name { font-weight: 600; }
.trainer-card__meta { margin-top: 0.125rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.trainer-card__meta span { display: block; }
.trainer-grid    { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px)  { .trainer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .trainer-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.faq             { border-top: 1px solid var(--border); }
.faq details     { border-bottom: 1px solid var(--border); }
.faq summary {
  cursor: pointer; list-style: none; position: relative; padding: 1.125rem 2rem 1.125rem 0;
  font-weight: 500; font-size: var(--text-body-lg);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; position: absolute; right: 0; top: 1.125rem; color: var(--muted-foreground); font-weight: 400; }
.faq details[open] summary::after { content: "\2013"; }
.faq details p   { padding-bottom: 1.125rem; color: color-mix(in oklab, var(--foreground) 75%, transparent); line-height: 1.65; max-width: var(--w-2xl); }

/* Help page folds (CP 14 Sep): each section is a native <details>, closed by default. Same +/– marker as .faq;
   body copy keeps its normal colour (AA ruling), so not .faq. app.js opens the fold a #anchor points at. */
.help-folds      { border-top: 1px solid var(--border); }
.help-fold       { border-bottom: 1px solid var(--border); scroll-margin-top: 9rem; } /* clears the sticky header (77px) + the sticky role heading (CP 20 Sep) */
.help-role       { scroll-margin-top: 5.5rem; }  /* role sections (CP 20 Sep): #trainers, #providers, #companies */
/* CP 21 Sep: each role is a white card on the canvas (option A of cards / numbered strip). The role heading is Lora at the
   H3 size (22px; CP: the 31px H2 shouted next to 22px fold titles) and sticks under the 77px site header while its card
   scrolls; the hairline under it makes the cut where rows pass beneath look intentional. */
.help-role       { background: var(--card); color: var(--card-foreground); border-radius: var(--radius-card); box-shadow: var(--shadow-card); padding: 0 1.25rem 0.25rem; margin-top: 1.5rem; }
.help-role > h2  { font-family: var(--font-display); font-weight: 600; font-size: var(--text-heading); line-height: 1.3; letter-spacing: -0.3px;
                   position: sticky; top: 4.5rem; z-index: 2; background: var(--card); padding: 1.25rem 0 0.875rem; border-bottom: 1px solid var(--border); }
.help-role > .text-muted { padding-top: 0.75rem; }
.help-role .help-folds { border-top: 0; }
.help-role .help-group { padding-top: 1.25rem; }  /* group label inside a card (providers: Hiring a trainer / On the roster, CP 21 Sep) */
.help-role .help-fold:last-child { border-bottom: 0; }
@media (min-width: 640px) { .help-role { padding-inline: 1.75rem; } }
.help-toc        { display: grid; gap: 1.25rem; }
.help-toc a.eyebrow { text-decoration: none; }
@media (min-width: 768px) { .help-toc { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.help-fold summary { cursor: pointer; list-style: none; position: relative; padding: 1.125rem 2rem 1.125rem 0; }
.help-fold summary::-webkit-details-marker { display: none; }
.help-fold summary .heading { font-size: var(--text-subheading); font-weight: 600; line-height: 1.35; letter-spacing: -0.1px; }  /* H4 size (CP 21 Sep): fold titles sit under the Lora 22px role heading, not level with it */
.help-fold summary::after { content: "+"; position: absolute; right: 0; top: 1.125rem; color: var(--muted-foreground); font-size: var(--text-body-lg); }
.help-fold[open] summary::after { content: "\2013"; }
.help-fold[open] summary { padding-bottom: 0; }
.help-fold[open] > :last-child { padding-bottom: 1.5rem; }
/* Card that folds (credits.html Buy credits, CP 16 Sep): a .card whose <summary> is the head row, chevron at the right. */
.card-fold       { border: 0; }
.card-fold summary { padding: 0 2rem 0 0; }
.card-fold summary::after { top: 0.125rem; }
.card-fold[open] summary { padding-bottom: 0; }
.card-fold[open] > :last-child { padding-bottom: 0; }
.card-fold > form { margin-top: 1.25rem; }

.counter-pill {
  display: inline-flex; align-items: center; gap: 0.5rem;
  border: 1px solid var(--border); background: var(--card); border-radius: var(--radius-full);
  padding: 0.25rem 0.75rem; font-size: var(--text-body); font-weight: 500; color: var(--muted-foreground);
}
.counter-pill::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--secondary); }
.counter-pill strong { color: var(--foreground); font-variant-numeric: tabular-nums; }

/* ---------- Build log: feature demos ---------- */

.demo            { display: block; margin: 0; border-radius: var(--radius-card); background: var(--card); box-shadow: var(--shadow-card); overflow: hidden; }
.demo__video     { position: relative; width: 100%; aspect-ratio: 16 / 9; overflow: hidden; background: var(--navy-900); }
.demo__video img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.85; }
.demo__play {
  position: absolute; inset: 0; margin: auto; width: 3.5rem; height: 3.5rem; border: 0; cursor: pointer;
  border-radius: 50%; background: var(--secondary); color: #fff; display: grid; place-items: center;
  box-shadow: var(--shadow-lg);
}
.demo__play svg  { width: 1.25rem; height: 1.25rem; margin-left: 0.125rem; }
.demo__len       { position: absolute; right: 0.75rem; bottom: 0.75rem; padding: 0.125rem 0.5rem; border-radius: var(--radius-sm); background: color-mix(in oklab, var(--navy-900) 70%, transparent); color: #fff; font-size: var(--text-caption); font-variant-numeric: tabular-nums; }
.demo__body      { padding: 1.25rem 1.5rem 1.5rem; }
.demo__body h3   { margin-top: 0.75rem; font-size: var(--text-subheading); line-height: 1.35; }
.demo__body p    { margin-top: 0.5rem; color: color-mix(in oklab, var(--foreground) 70%, transparent); line-height: 1.6; }
.demo--coming    { background: color-mix(in oklab, var(--muted) 50%, transparent); }
.demo--coming .demo__video { background: var(--muted); display: grid; place-items: center; color: var(--muted-foreground); font-size: var(--text-body-sm); }
.demo--coming .demo__body h3, .demo--coming .demo__body p { color: var(--muted-foreground); }
/* Phones: collapse unshipped demos to pill + title so Tools and FAQs are not four screens down. */
@media (max-width: 639px) {
  .demo--coming .demo__video, .demo--coming .demo__body p { display: none; }
  .demo--coming .demo__body { padding: 1rem 1.25rem; }
  .demo--coming .demo__body h3 { margin-top: 0.5rem; }
}

/* ---------- Article list ---------- */

.article-item    { padding: 1.5rem 0; border-bottom: 1px solid var(--border); }
.article-item h2 { margin-top: 0.5rem; font-family: var(--font-sans); font-size: var(--text-heading); font-weight: 700; letter-spacing: -0.3px; } /* H3 row */
.article-item h2 a { text-decoration: none; }
@media (hover: hover) { .article-item h2 a:hover { text-decoration: underline; text-underline-offset: 3px; } }
.article-item p  { margin-top: 0.5rem; color: color-mix(in oklab, var(--foreground) 75%, transparent); }
/* Article hero (CP 21 Sep): one 16:9 photo per article, assets/img/articles/<article id>.jpg,
   placed by place-articles.py. Same file is used for the card thumbnail on resources.html and
   articles/index.html, so there is one image to swap per article. Decorative: alt is empty,
   the headline carries the meaning. CREDITS.txt in that folder maps each file to its source. */
.article-hero      { margin-top: 2rem; overflow: hidden; border-radius: var(--radius-card); background: var(--muted); }
.article-hero img  { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }

.article-meta    { font-size: var(--text-caption); color: var(--muted-foreground); }
.back-link       { font-size: var(--text-body); font-weight: 500; color: var(--secondary); text-decoration: none; }
@media (hover: hover) { .back-link:hover { text-decoration: underline; } }

.area-grid       { margin-top: 3rem; display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .area-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.area-card       { border-radius: var(--radius-card); background: var(--card); box-shadow: var(--shadow-card); padding: 1.5rem; }
.area-card .eyebrow { color: var(--coral); display: block; margin-bottom: 0.5rem; }
.area-card h3    { line-height: 1.3; }
.area-card p     { margin-top: 0.625rem; color: color-mix(in oklab, var(--foreground) 75%, transparent); line-height: 1.6; }

.table-wrap      { margin-top: 2rem; overflow-x: auto; border-radius: var(--radius); border: 1px solid var(--grey-100); background: var(--card); }
table.table      { width: 100%; min-width: 36rem; border-collapse: collapse; text-align: left; font-size: var(--text-body-sm); }   /* sheet data table: 13px */
@media (max-width: 639px) { .table-wrap { mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent); } } /* Phones: fade says "more to the right". */
.table th        { padding: 0.8125rem 1.125rem; font-size: var(--text-overline); font-weight: 700; letter-spacing: 0.6px; color: var(--muted-foreground); background: var(--grey-50); border-bottom: 1px solid var(--grey-200); text-transform: uppercase; } /* sheet th: 11/700 uppercase; CP 15 Sep */
.table td        { padding: 0.875rem 1.125rem; vertical-align: top; line-height: 1.6; color: var(--grey-700); border-top: 1px solid var(--grey-100); }
.table tbody tr  { transition: background-color .12s; }
@media (hover: hover) { .table tbody tr:hover td { background: var(--grey-50); } }
.table td.choose { color: var(--coral); font-weight: 600; }
.table td.not    { color: var(--muted-foreground); }

/* ---------- Auth and registration ---------- */

.auth            { max-width: var(--w-xl); margin-inline: auto; padding: 4rem 1.25rem; } /* 576px: headings sit on one line on desktop (CP 15 Oct, HANDOFF 189); was --w-md 448 */
.auth h1         { font-size: var(--text-display); } /* 31px at every width, as account.html (.display); a form title, not a landing hero (CP 15 Oct, HANDOFF 188) */
.builder-title   { font-size: var(--text-display); } /* 31px at every width on the four Builder steps, a form title like .auth h1 (CP 15 Oct, HANDOFF 190) */
.auth form       { margin-top: 2rem; }
.auth .check     { font-size: var(--text-caption); } /* consent lines match the caption links under the button */
.auth .code      { letter-spacing: 0.3em; font-variant-numeric: tabular-nums; }
.auth__secondary { display: block; width: 100%; margin-top: 0.75rem; text-align: center; font-size: var(--text-caption); color: var(--muted-foreground); background: none; border: 0; cursor: pointer; }
.auth__secondary:disabled { opacity: 0.5; cursor: not-allowed; }

.steps           { display: flex; gap: 0.625rem; align-items: center; font-size: var(--text-body-sm); font-weight: 600; color: var(--muted-foreground); }  /* sheet stepper: label 13/600 */
.steps__dot      { width: 2.125rem; height: 2.125rem; border-radius: 50%; display: grid; place-items: center; border: 2px solid var(--grey-200); background: var(--background); color: var(--muted-foreground); font-weight: 700; font-size: var(--text-body-sm); transition: background-color .2s, border-color .2s, box-shadow .2s; }
.steps__dot.is-active, .steps__dot[data-state="current"] { border-color: var(--primary); color: var(--primary); box-shadow: 0 0 0 4px rgba(13, 59, 102, 0.10); }
.steps__dot.is-done, .steps__dot[data-state="done"] { background: var(--primary); border-color: var(--primary); color: #fff; }
.steps__dot.is-active + span, .steps__dot.is-done + span, .steps__dot[data-state="current"] + span, .steps__dot[data-state="done"] + span, .steps__dot[data-state="error"] + span { color: var(--foreground); }
.steps__line     { flex: 1; min-width: 1.25rem; height: 2px; border-radius: 2px; background: var(--grey-200); margin-inline: 0.125rem; }
.steps__line.is-done, .steps__line[data-state="done"] { background: var(--primary); }

/* ---------- Notices ---------- */

.notice          { border-radius: var(--radius-md); padding: 0.875rem 1.125rem; font-size: var(--text-body-sm); font-weight: 500; line-height: 1.5; display: flex; gap: 0.75rem; align-items: flex-start; } /* sheet alert: 13/500, 14 x 18, r10, no border */
.notice-info     { background: var(--navy-50); color: var(--primary); }
.notice-success  { background: #ECFDF5; color: #065F46; }
.notice-warning  { background: #FFFBEB; color: #92400E; }
.notice-error    { background: #FEF2F2; color: #991B1B; }
.notice-muted    { background: color-mix(in oklab, var(--muted) 40%, transparent); color: var(--muted-foreground); }
.notice-dashed   { border: 1px dashed var(--border); background: color-mix(in oklab, var(--muted) 30%, transparent); }
.notice__icon    { flex-shrink: 0; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--muted); color: var(--muted-foreground); }
.notice strong   { display: block; font-weight: 600; }
.notice small    { display: block; margin-top: 0.125rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }

.hint-empty {
  border: 1px dashed var(--border); border-radius: var(--radius-lg); padding: 0.625rem 0.875rem;
  font-size: var(--text-body); font-style: italic; color: color-mix(in oklab, var(--muted-foreground) 80%, transparent);
}
.launch-hint {
  display: flex; align-items: center; gap: 0.5rem; border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--muted) 40%, transparent); padding: 0.625rem 0.875rem;
  font-size: var(--text-body); color: var(--muted-foreground);
}

/* Auto-save indicator. States: idle, saving, saved, draft. */
.save-state      { font-size: var(--text-caption); font-weight: 500; color: var(--muted-foreground); }
.save-state[data-state="saving"] { color: var(--muted-foreground); }
.save-state[data-state="saved"]  { color: var(--success); }
.save-state[data-state="draft"]  { color: var(--warning-foreground); }
.save-state[data-state="error"]  { color: var(--destructive); }

/* ---------- Dashboard / builder ---------- */

.dash            { display: grid; gap: 2rem; grid-template-columns: 1fr; padding-block: 3rem; }
.dash > *        { min-width: 0; }
.dash--single    { grid-template-columns: 1fr !important; } /* no rail (credits.html, CP 16 Sep) */ /* 16 Sep: grid items default to min-width auto, so a scrolling strip inside (kanban, stage strip, packs) was widening the column past 375 instead of scrolling */
@media (min-width: 768px) { .dash { grid-template-columns: minmax(0, 1fr) 280px; } }
.builder         { display: grid; gap: 2rem; grid-template-columns: 1fr; padding-block: 2.5rem; }
@media (min-width: 1024px) { .builder { padding-block: 3.5rem; } } /* one column since 14 Sep: the Overview panel carries the meter and tasks */
.builder__main   { min-width: 0; }
/* Profile edit groups (B-03 spec, CP 28 Sep, option B): an H2 and one descriptor above ONE white panel per group; the
   sections inside the panel are divided by hairlines and keep their own title and Edit. Four panels on the grey page make
   the four groups countable at a glance (Fiverr / Upwork profile settings). More air above a group than inside it. */
.stack-lg > .builder__group { margin-top: 3rem; }
.stack-lg > .builder__group:first-child { margin-top: 0; }
.builder__group > div:first-child > p { margin-top: 0.375rem; } /* full panel width: the 62ch cap left the right side empty beside the panel (CP 17 Oct) */
.builder__group > div:first-child > .row > .pill { margin-left: auto; }
.builder__group > .panel { margin-top: 1.25rem; padding: 0; }
.panel > .section-card + .section-card { border-top: 1px solid var(--border); }
.panel > .section-card .section-card__rule { display: none; }        /* the panel's hairlines divide; no second rule under each hint */
.panel > .section-card .section-card__body { margin-top: 1.25rem; }
.panel > .section-card--bare > .section-card__body { margin-top: 0; }
#training-provider .list-row { padding: 0; }                          /* one row in its own panel: the section padding is the air */
#training-provider .cred-edit { padding-top: 1.25rem; }
.profile-head    { display: flex; gap: 1.25rem; align-items: flex-start; flex-wrap: wrap; }
.profile-head__who { flex: 1 1 16rem; min-width: 0; }
.profile-head__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: flex-end; }

.tick {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 1.25rem; height: 1.25rem; border-radius: 50%; border: 1px solid var(--border); background: var(--muted); margin-top: 0.125rem;
}
.tick.is-done    { background: var(--primary); border-color: var(--primary); color: #fff; }
.tick svg        { width: 0.75rem; height: 0.75rem; }

.checklist       { list-style: none; display: flex; flex-direction: column; gap: 0.625rem; margin-top: 0.75rem; }
.checklist li    { display: flex; align-items: flex-start; gap: 0.75rem; font-size: var(--text-body); color: var(--muted-foreground); }
/* Tap variant (profile-edit header, CP 16 Oct): each row is a 44px tap target, the link fills the row. No dividers. */
.checklist--tap  { gap: 0; }
.checklist--tap li { align-items: center; min-height: 2.75rem; }
.checklist--tap li > a { flex: 1; align-self: stretch; display: flex; align-items: center; }
.checklist li.is-done { color: var(--foreground); }
.checklist li li { display: list-item; } /* sub-points inside a checklist item (launch offer) keep their bullet */
.checklist .task { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.checklist .task .medium { color: var(--foreground); }   /* open task: title, benefit line, own button (copy pass 14 Sep) */
.checklist .task .btn { align-self: flex-start; margin-top: 0.375rem; }

.meter           { margin-top: 0.75rem; height: 0.5rem; width: 100%; overflow: hidden; border-radius: var(--radius-sm); background: var(--grey-200); display: flex; } /* sheet progress track */
.meter__req      { background: var(--primary); }
.meter__opt      { background: var(--secondary); }

.dot             { display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 50%; flex-shrink: 0; } /* meter legend dot (rail + dashboard) */
.ring__legend strong { color: var(--foreground); font-weight: 500; }

.locked          { pointer-events: none; user-select: none; opacity: 0.5; filter: blur(2px); }

/* Public profile */
.profile-head    { display: flex; flex-direction: column; gap: 1rem; }
@media (min-width: 640px) { .profile-head { flex-direction: row; align-items: flex-start; justify-content: space-between; } .profile-head > * + * { flex-shrink: 0; } } /* the action column keeps its width; the chips wrap instead */
@media (max-width: 639px) { .profile-head__who { flex-basis: auto; } } /* phones: in the column layout the 16rem flex-basis became a 256px minimum height, a blank band between the name and the button (design review 20 Sep) */
.profile-id      { display: flex; align-items: flex-start; gap: 1rem; }
@media (max-width: 639px) { .profile-id { flex-wrap: wrap; } .profile-id > div { flex-basis: 100%; } } /* phones: the name block sits under the photo at full width; four chips no longer stack in a 157px column (T8) */
.profile-cols    { display: grid; gap: 2rem; grid-template-columns: 1fr; }
@media (min-width: 1024px) { .profile-cols { grid-template-columns: 2fr 1fr; } }
.block + .block  { margin-top: 2rem; }
/* Public profile (CP 13 Sep, option B): the header and each main-column section are white panels on the canvas,
   no border, the resting shadow, one level deep. Navy Lora headings inside. Sidebar tiles keep their small labels. */
.profile-head, .profile-main .block { background: var(--card); border-radius: var(--radius-card); padding: 1.5rem; box-shadow: var(--shadow-card); }
.profile-main .block + .block { margin-top: 1rem; }
.profile-main .block__label { font-family: var(--font-sans); font-size: var(--text-heading); font-weight: 700; text-transform: none; color: var(--foreground); letter-spacing: -0.3px; margin-bottom: 1rem; } /* H3 row (was Lora navy 20px, 13 Sep) */
.profile-cols    { margin-top: 1rem; }
.profile-side .side-card { padding: 1.5rem; }
.profile-side .side-card + .side-card { margin-top: 1rem; }
.block__label    { margin-bottom: 0.75rem; font-family: var(--font-sans); font-size: var(--text-subheading); font-weight: 600; letter-spacing: -0.1px; color: var(--foreground); } /* H4 row, sentence case: card and block headers, not small grey caps (17 Oct sweep; was 11px uppercase muted, CP 15 Sep). Sans: the h2 rule would set Lora (S2) */
.side-card       { border-radius: var(--radius-lg); background: var(--card); box-shadow: var(--shadow-card); padding: 1rem; }
.side-card + .side-card { margin-top: 1.25rem; }
.qr-tile         { display: flex; gap: 0.875rem; align-items: flex-start; }
.qr              { display: none; width: 3.5rem; height: 3.5rem; flex-shrink: 0; color: var(--foreground); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.25rem; background: #fff; }
.quote           { padding: 0; } /* plain quote, no fill (T11); also the testimonial preview on profile-edit */
.quote p         { font-style: italic; color: color-mix(in oklab, var(--foreground) 80%, transparent); }
.quote small     { display: block; margin-top: 0.125rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.stars           { display: inline-flex; gap: 0.125rem; color: color-mix(in oklab, var(--muted-foreground) 40%, transparent); }
.stars svg       { width: 0.875rem; height: 0.875rem; }

/* Programme cards on a trainer profile (CP 13 Sep): a preview, not the search card. Title and a two-line summary,
   nothing else; modules, format, duration and language live on the programme page. Two columns, single column while there is one (T6). */
.pcard--preview  { padding: 1rem 1.25rem; }
.pcard--preview .pcard__title { margin-top: 0; font-size: 1.125rem; }
.pcard--preview .pcard__summary { font-size: var(--text-body-sm); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pcard--preview .prog-tags     { margin-top: 0.75rem; } /* programme industry tags on the trainer page card (27 Sep) */
.programme-grid  { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .programme-grid:not(:has(> :only-child)) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.media-list      { list-style: none; display: flex; flex-direction: column; gap: 0.5rem; }
.media-list button { display: flex; width: 100%; align-items: center; gap: 0.75rem; padding: 0.625rem 0.875rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card); color: inherit; font: inherit; text-align: left; cursor: pointer; transition: border-color .15s, transform .16s var(--ease-out); }
.media-list svg  { width: 1.25rem; height: 1.25rem; color: var(--primary); flex-shrink: 0; }
.media-list__label { display: block; font-weight: 500; }
@media (hover: hover) { .media-list button:hover { border-color: var(--primary); } }
.media-list button:active { transform: scale(0.99); }
/* Video pop-up: the dialog component, no padding, 16:9 frame, one close control. */
.dialog--video   { max-width: 56rem; padding: 0; overflow: hidden; background: var(--navy-900); }
.dialog--video::backdrop { background: color-mix(in oklab, var(--navy-900) 70%, transparent); }
.dialog__video   { aspect-ratio: 16 / 9; }
.dialog__video iframe { width: 100%; height: 100%; border: 0; display: block; }
.dialog__close   { position: absolute; top: 0.25rem; right: 0.25rem; z-index: 1; display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border: 0; padding: 0; background: color-mix(in oklab, var(--navy-900) 60%, transparent); color: #fff; font-size: 1.5rem; line-height: 1; border-radius: var(--radius-full); cursor: pointer; }
.dialog__close:focus-visible { outline-color: #fff; }
.block .article-item { padding: 0; border: 0; } /* on a profile the rows sit inside a block; the index page keeps its rules */
.block .article-item + .article-item { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.article-item h3 { margin-top: 0.375rem; font-size: var(--text-subheading); font-weight: 600; letter-spacing: -0.1px; } /* H4 row */
.article-item h3 a { text-decoration: none; }
@media (hover: hover) { .article-item h3 a:hover { text-decoration: underline; text-underline-offset: 3px; } }
@media (min-width: 1024px) { .profile-side { position: sticky; top: 5rem; align-self: start; } }
/* Launch action bar (phones and tablets). [data-launch] display is reverted by the switch, so the bar is a block with a flex row inside. */
.profile-bar     { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; padding: 0.75rem 1.25rem; background: var(--card); border-top: 1px solid var(--border); box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08); }
.profile-bar .row { flex-wrap: nowrap; max-width: var(--w-5xl); margin-inline: auto; }
.profile-bar .btn { flex: 1 1 0; }
body:has(.cookie-banner) .profile-bar { display: none !important; }
@media (max-width: 1023px) { .is-launch .profile-head .profile-head__launch { display: none !important; } html.is-launch body { padding-bottom: 5rem; } }
@media (min-width: 1024px) { html.is-launch .profile-bar { display: none !important; } } /* html. outranks the launch switch rule below */

.programme-card  { display: flex; flex-direction: column; border-radius: var(--radius-lg); background: var(--card); box-shadow: var(--shadow-card); padding: 1rem; }
.programme-card__title { font-weight: 600; }
.programme-card__meta { margin-top: 0.25rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.programme-card__summary { margin-top: 0.5rem; color: color-mix(in oklab, var(--foreground) 70%, transparent); line-height: 1.6;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.programme-card__foot { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border); display: flex; justify-content: space-between; align-items: flex-end; font-size: var(--text-body-sm); color: var(--muted-foreground); }

.list-row        { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: 1.25rem 0; }
.list-row + .list-row { border-top: 1px solid var(--border); }
.list-row__title { font-weight: 600; }
.list-row__meta  { margin-top: 0.25rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.list-row__actions { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }
.cred-edit       { padding-bottom: 1.25rem; }                       /* per-credential form under its row (profile-edit) */
.cred-edit + .list-row { border-top: 1px solid var(--border); }

/* Third-viewer marker (?as=tp, app.js 34): hidden unless the viewer is a training provider. Was engagement.css. */
[data-tp] { display: none !important; }
.as-tp main [data-tp] { display: revert !important; }

.kv              { display: grid; gap: 0.25rem 1rem; grid-template-columns: max-content 1fr; font-size: var(--text-body); }
.kv dt           { color: var(--muted-foreground); }
/* Supplier details box (CP(ETT)R 2024, 19 Sep): bilingual labels are long, so label above value, not a two-column grid. */
.supplier-box .kv, .prog-side .supplier-box .kv { display: block; font-size: var(--text-caption); }
.supplier-box .kv > div, .prog-side .supplier-box .kv > div { display: block; margin-top: 0.5rem; padding: 0; border: 0; }
.supplier-box .kv dt, .prog-side .supplier-box .kv dt { display: block; font-weight: 600; color: var(--muted-foreground); }
.supplier-box .kv dd, .prog-side .supplier-box .kv dd { display: block; margin: 0.125rem 0 0; text-align: left; font-weight: 400; color: var(--foreground); }
.kv dd           { margin: 0; }

.queue-item      { padding: 1.25rem; }
.queue-item + .queue-item { margin-top: 1rem; }
.queue-item__meta { margin-top: 0.125rem; font-size: var(--text-caption); color: var(--muted-foreground); }

.icon            { width: 1rem; height: 1rem; flex-shrink: 0; }
.icon-sm         { width: 0.875rem; height: 0.875rem; }
.icon-lg         { width: 1.25rem; height: 1.25rem; }
.pdf-icon {
  display: grid; place-items: center; width: 2.25rem; height: 2.25rem; flex-shrink: 0;
  border-radius: var(--radius-md); background: color-mix(in oklab, var(--primary) 10%, #fff);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--primary) 25%, transparent);
  font-size: var(--text-overline); font-weight: 600; letter-spacing: 0.05em; color: var(--primary);
}

/* Modal-less dialog (confirm). */
.dialog          { border: 0; border-radius: var(--radius-card); padding: 1.5rem; max-width: 26rem; width: calc(100% - 2rem); box-shadow: var(--shadow-modal); }
.dialog::backdrop { background: color-mix(in oklab, var(--navy-900) 50%, transparent); }
.dialog h2       { font-family: var(--font-sans); font-size: 1.125rem; font-weight: 700; letter-spacing: 0; } /* sheet modal header: Inter 18px 700 */
.dialog p        { margin-top: 0.5rem; color: var(--muted-foreground); }
.dialog .form-actions { justify-content: flex-end; margin-top: 1.5rem; }
/* Picker dialog (the Send brief picker, CP 4 Oct 2026 "follow this" on the AI Studio modal): navy band with an eyebrow,
   the title and a close X; a body of bordered rows, each with its own action; a footer with one full-width button. */
.dialog--picker  { padding: 0; max-width: 32rem; overflow: hidden; }
.dialog__band    { position: relative; padding: 1.25rem 3.5rem 1.25rem 1.5rem; background: var(--primary); color: #fff; }
.dialog__band h2 { margin-top: 0.25rem; color: #fff; }
.dialog__band .dialog__close { top: 0.75rem; right: 0.75rem; width: 2.25rem; height: 2.25rem; background: color-mix(in oklab, #fff 14%, transparent); }
.dialog--picker .dialog__body { padding: 1.5rem; }
.dialog--picker .dialog__foot { padding: 1rem 1.5rem 1.5rem; border-top: 1px solid var(--border); }
.picker__row     { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.25rem; border: 1px solid var(--border); border-radius: var(--radius-md); }
.picker__row + .picker__row { margin-top: 0.75rem; }
.picker__row > div { min-width: 0; }
.picker__row.is-current { border-color: var(--primary); }

/* ---------- About page ---------- */

.icon-tile {
  display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--coral) 12%, transparent); color: var(--coral);
}
.icon-tile svg   { width: 1.5rem; height: 1.5rem; }
.belief          { border-radius: var(--radius-card); background: var(--card); box-shadow: var(--shadow-card); padding: 1.5rem; }
.belief h3       { margin-top: 1rem; font-size: var(--text-subheading); line-height: 1.35; }
.belief p        { margin-top: 0.5rem; color: color-mix(in oklab, var(--foreground) 70%, transparent); line-height: 1.6; }
.link-card       { display: flex; flex-direction: column; text-decoration: none; }
@media (hover: hover) { .link-card:hover { box-shadow: var(--shadow-lg); } }  /* CP 15 Sep: darker lift, the card carries no "Browse" cue */
.link-card__go   { margin-top: 1rem; display: inline-flex; align-items: center; gap: 0.25rem; font-weight: 500; color: var(--primary); }
.link-card--coral { background: var(--coral); color: #fff; }  /* Browse all tile (CP 15 Sep): the one card that is an exit, not a subject */
.link-card--coral .icon-tile { background: color-mix(in oklab, #fff 18%, transparent); color: #fff; }
.link-card--coral .subheading, .link-card--coral p { color: #fff; }
/* Launch homepage categories (CP 15 Sep). Desktop: 8 full link cards, the eighth is Browse all. Phones: 3 x 2 icon tiles (Fiverr pattern), title only, then a Browse all link. */
.cat-grid__all { display: none; grid-column: 1 / -1; text-align: center; margin-top: 0.25rem; }
@media (max-width: 639px) {
  .grid-4.cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; } /* outranks the .grid-4 base rule further down */
  .cat-grid .link-card { align-items: center; text-align: center; padding: 1rem 0.5rem; }
  .cat-grid .link-card .text-muted, .cat-grid .link-card__go, .cat-grid .link-card__meta { display: none; }
  .cat-grid .subheading { margin-top: 0.625rem; font-size: 0.8125rem; line-height: 1.25; letter-spacing: 0; }
}
@media (max-width: 639px) { .cat-grid .cat-card--desktop-only { display: none; } .cat-grid__all { display: block; } }  /* phones: six tiles and the link; desktop: eight cards, no link */
/* Launch homepage featured programmes. Phones: one swipe row, card 82% wide so the next one peeks; bleeds to the section edge so the row is not clipped at the container padding. Same mechanics as .kanban. */
@media (max-width: 639px) {
  .grid-2.featured-row { grid-auto-flow: column; grid-auto-columns: 82%; gap: 0.75rem; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
    margin-inline: -1.25rem; padding-inline: 1.25rem; padding-bottom: 0.25rem; scroll-padding-inline: 1.25rem; }
  .featured-row::-webkit-scrollbar { display: none; }
  .featured-row > .pcard { scroll-snap-align: start; }
}
.split           { display: grid; gap: 3rem; align-items: center; grid-template-columns: 1fr; }
@media (min-width: 1024px) { .split { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.split__img      { overflow: hidden; border-radius: var(--radius-card); box-shadow: var(--shadow-card); }
.split__img img  { width: 100%; height: 100%; object-fit: cover; }
.flywheel        { width: 100%; max-width: 340px; }
.flywheel text   { font-family: var(--font-sans); font-size: 13px; font-weight: 600; fill: #FFFFFF; }
.capstone        { font-family: var(--font-display); font-size: var(--text-display); font-weight: 600; line-height: 1.2; letter-spacing: -0.3px; }
.capstone em     { color: var(--coral); }
.bg-canvas       { background: var(--canvas); }
.section-lead p  { font-size: var(--text-body-lg); line-height: 1.7; color: color-mix(in oklab, var(--foreground) 80%, transparent); }
.section-lead p + p { margin-top: 1rem; }

.tabs            { display: flex; gap: 0.25rem; border-bottom: 1.5px solid var(--grey-200); margin-top: 1.5rem; overflow-x: auto; scrollbar-width: none; } /* Phones: the row scrolls sideways instead of pushing the page wider. */
.tabs::-webkit-scrollbar { display: none; }
.tabs a          { white-space: nowrap; flex-shrink: 0; padding: 0.625rem 1rem; text-decoration: none; color: var(--muted-foreground); font-weight: 600; border-bottom: 2px solid transparent; margin-bottom: -1.5px; transition: color .15s, border-color .15s; } /* sheet tab: 14/600, 10 x 16 */
.tabs a[aria-current="page"] { color: var(--primary); border-bottom-color: var(--primary); }
@media (hover: hover) { .tabs a:hover    { color: var(--primary); } }
@media (max-width: 639px) { .tabs { mask-image: linear-gradient(to right, #000 calc(100% - 1.25rem), transparent); } .tabs a { padding-inline: 0.625rem; } } /* CP 17 Sep: four tabs whole, fifth peeks (the scroll cue) */

/* ---------- M2: programme search ---------- */

.search-bar      { position: relative; }
.search-bar svg  { position: absolute; left: 0.875rem; top: 50%; width: 1.125rem; height: 1.125rem; transform: translateY(-50%); color: var(--muted-foreground); pointer-events: none; }
.search-bar .input { margin-top: 0; padding: 0.75rem 1rem 0.75rem 2.5rem; border-radius: var(--radius); background: var(--grey-50); } /* sheet search bar: grey-50, 1.5px, r12, 12 x 16 */
.search-bar .input:focus { background: var(--card); }
.search-head     { display: grid; gap: 0.75rem; grid-template-columns: 1fr; }
@media (min-width: 768px) { .search-head { grid-template-columns: minmax(0, 1fr) 14rem; align-items: center; } }
.search-head .select { margin-top: 0; min-height: 3rem; background-color: var(--card); }

.search-layout   { display: grid; gap: 2rem; grid-template-columns: minmax(0, 1fr); margin-top: 2rem; }
@media (min-width: 1024px) { .search-layout { grid-template-columns: 17rem minmax(0, 1fr); } }

.filters         { align-self: start; }
@media (min-width: 1024px) and (min-height: 64rem) { .filters { position: sticky; top: 5rem; } } /* sticky only where the whole panel fits; shorter screens scroll it with the page (N1) */
.filters__head   { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.filters__head h2 { font-size: var(--text-body-lg); }
.filters__toggle { display: inline-flex; }
@media (min-width: 1024px) { .filters__toggle, .filters__done { display: none; } .filters__body[hidden] { display: block !important; } } /* Phones: filters fold behind the button; desktop always shows them. */
.filters__done   { position: sticky; bottom: 0.75rem; margin-top: 1.25rem; } /* phones: closes the fold from wherever the thumb is */
.filters__foot   { display: none; margin: 1.25rem 0 0; padding-top: 1rem; border-top: 1px solid var(--border); }
.filters__foot .btn-link { margin-left: 0.25rem; }
@media (min-width: 1024px) { .filters__foot { display: block; } } /* desktop: live count under the filters (CP 16 Sep); phones have the Show N button */
.filters__head .btn-link:disabled { color: var(--muted-foreground); opacity: 0.6; cursor: default; text-decoration: none; }
.applied         { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-bottom: 0.75rem; }
.applied .chip-selected button { min-width: 1.5rem; min-height: 1.5rem; }
.results__sort   { font-size: var(--text-body-sm); color: var(--muted-foreground); white-space: nowrap; }
.results__lead   { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 1rem; }
.results__lead a { font-size: var(--text-body-sm); }
.filters__body > .field + .field { margin-top: 1rem; }
.filters .field__label { font-size: var(--text-body-sm); }
.filters .select { min-height: 2.5rem; padding-block: 0.375rem; font-size: var(--text-body-sm); }
.filters .check  { margin-top: 0.5rem; }
.filters .check + .check { margin-top: 0.375rem; }
.filters__gated .select { opacity: 0.6; cursor: not-allowed; background-color: color-mix(in oklab, var(--muted) 40%, transparent); } /* S8: only the control dims; its help line stays readable */

.results__count  { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; font-size: var(--text-body); color: var(--muted-foreground); }
.results__count .select { width: auto; margin-top: 0; min-height: 2.25rem; padding-block: 0.25rem; font-size: var(--text-body-sm); } /* the board's two-option sort */
.results__count strong { color: var(--foreground); font-variant-numeric: tabular-nums; }
.results__list   { display: grid; gap: 1rem; margin-top: 1rem; }

.pagination      { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1.5rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }

/* Loading: three grey lines standing in for a card. Sean swaps in his own skeleton. */
.skeleton        { display: grid; gap: 0.625rem; padding: 1.25rem 1.5rem; border-radius: var(--radius-card); background: var(--card); box-shadow: var(--shadow-card); }
.skeleton span   { display: block; height: 0.875rem; border-radius: var(--radius-sm); background: color-mix(in oklab, var(--muted) 80%, var(--border)); animation: skeleton-pulse 1.1s ease-in-out infinite; }
@keyframes skeleton-pulse { 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .skeleton span { animation: none; } }
.skeleton span:nth-child(1) { width: 30%; } .skeleton span:nth-child(2) { width: 70%; height: 1.125rem; } .skeleton span:nth-child(3) { width: 90%; }

.empty-state     { padding: 3rem 1.5rem; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 0.75rem; } /* sheet empty state: open, centred, no box */
.empty-state h3  { font-size: var(--text-body-lg); font-weight: 600; color: var(--grey-700); letter-spacing: 0; }
.empty-state p   { margin-top: 0; max-width: 17.5rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.empty-state > svg { width: 3rem; height: 3rem; color: var(--grey-300); }
.empty-state .btn { margin-top: 0.25rem; }

/* ---------- M2: admin ranking and taxonomy ---------- */

.weights         { display: grid; gap: 0.75rem 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .weights { grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); } }
.weights .field  { margin: 0; }
.weights .input  { min-height: 2.5rem; font-variant-numeric: tabular-nums; }
.weights__total  { margin-top: 0.75rem; font-size: var(--text-body-sm); color: var(--success); font-weight: 500; font-variant-numeric: tabular-nums; }
.weights__total.is-invalid { color: var(--destructive); }
.admin-group + .admin-group { margin-top: 1.25rem; }
.admin-group h2  { font-family: var(--font-sans); font-size: var(--text-subheading); font-weight: 600; letter-spacing: -0.1px; } /* H4 row */
.admin-group__hint { margin-top: 0.25rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.table td .btn-link { font-size: var(--text-body-sm); }
.table td.num    { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.table th.num    { text-align: right; }
.table-wrap.mt-4 { margin-top: 1rem; }
.table td.nowrap { white-space: nowrap; }

/* Search hero (M2). The landing hero, shorter, with the search box inside. */
.hero--search    { min-height: 0; }
.hero--search .hero__body { max-width: var(--w-3xl); padding-block: 2.25rem; }
.hero--search .hero__title { margin-top: 0; } /* no eyebrow above it (S9, 13 Sep) */
.search-bar--hero { display: flex; align-items: center; gap: 0.5rem; padding: 0.375rem 0.375rem 0.375rem 0; background: var(--card); border-radius: var(--radius); max-width: 52rem; }
.search-bar--hero .input { border: 0; background: transparent; min-height: 2.75rem; }
.search-bar--hero .input { text-overflow: ellipsis; } /* the example list (copy sheet v3, 20 Sep) is longer than a phone field; clip with an ellipsis, not mid-word */
.search-bar--hero .input:focus-visible { box-shadow: none; }
.search-bar--hero:focus-within { box-shadow: 0 0 0 3px color-mix(in oklab, var(--coral) 45%, transparent); }
.search-bar--hero .btn { flex-shrink: 0; }
.try             { margin-top: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: var(--text-body-sm); color: color-mix(in oklab, #fff 80%, transparent); }
.try .chip       { background: color-mix(in oklab, #fff 12%, transparent); border-color: color-mix(in oklab, #fff 25%, transparent); color: #fff; }
@media (hover: hover) { .try .chip:hover { border-color: #fff; } }
.try a.chip      { text-decoration: none; }
@media (max-width: 639px) { .try .chip:nth-of-type(n + 4) { display: none; } } /* mobile screens: three suggestions, not four rows (CP 13 Sep) */
.search-bar .search-bar__submit svg { display: none; position: static; transform: none; width: 1.125rem; height: 1.125rem; color: inherit; pointer-events: auto; } /* not the bar's absolutely placed leading icon */
@media (max-width: 639px) { /* phones: the button carries the magnifier, the leading one goes, the input reclaims its left padding */
  .search-bar--hero .search-bar__submit { padding-inline: 0.75rem; min-width: 2.75rem; }
  .search-bar__submit span { display: none; }
  .search-bar .search-bar__submit svg { display: block; }
  .search-bar--hero > svg { display: none; }
  .search-bar--hero .input { padding-left: 1rem; }
}

/* Launch switch (reference only). Add ?launch=1 to any URL: [data-prelaunch] hides, [data-launch] shows.
   Sean ships one state or the other; this exists so reviewers can see both from one page. */
[data-launch]    { display: none !important; }
.is-launch [data-launch] { display: revert !important; }
.is-launch [data-prelaunch] { display: none !important; }
.is-launch .section + [data-prelaunch] + .section, html:not(.is-launch) .section + [data-launch] + .section { padding-top: 0; }  /* one gap when the block between two sections is hidden (about.html at launch, 17 Oct sweep) */

/* Launch homepage (M2). */
.grid-4          { display: grid; gap: 1.5rem; grid-template-columns: 1fr; }
@media (min-width: 640px)  { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.trainer-bar     { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.5rem; }
.steps-list      { list-style: none; padding: 0; margin: 0; }
.step__num       { display: inline-grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%; background: var(--primary); color: #fff; font-weight: 600; font-size: var(--text-body-sm); }

/* "Why us" on the launch home: lead left, four beliefs right (AI Studio HomePage, CP 14 Sep). */
.why-us          { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 1024px) { .why-us { grid-template-columns: 4fr 8fr; gap: 3rem; } }

/* Section head with nothing on the right sits centred (CP 14 Sep). */
.section-head--center { text-align: center; }

/* Connected step path (launch home "How it works", CP 14 Sep). One line runs through the numbers:
   down the left on narrow screens, across the top from 1024px. No cards; the canvas is the surface. */
.steps-path      { list-style: none; padding: 0; margin-bottom: 0; display: grid; gap: 2rem; }
.steps-path li   { position: relative; padding-left: 3rem; }
.steps-path .step__num { position: absolute; left: 0; top: 0; }
.steps-path li > h3 { margin-top: 0.25rem; }
.steps-path li::after { content: ""; position: absolute; left: calc(1rem - 1px); top: 2.5rem; bottom: -2rem; width: 2px; border-radius: 2px; background: var(--grey-200); }
.steps-path li:last-child::after { display: none; }
@media (min-width: 1024px) {
  .steps-path      { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2.5rem; }
  .steps-path li   { padding-left: 0; }
  .steps-path .step__num { position: static; }
  .steps-path li > h3 { margin-top: 1rem; }
  .steps-path li::after { left: 2.5rem; right: -2.5rem; top: calc(1rem - 1px); bottom: auto; width: auto; height: 2px; }
}

/* Launch home photos (21 Sep): the four sections below the featured cards were text only. One photo each, on the
   .split__img card treatment (radius-card + shadow-card), decorative, alt="". Files: assets/img/home/, place-home.py. */
.steps-photo, .why-us__img { margin-inline: 0; }  /* a bare figure carries the browser's 40px side margins; photos line up with the text edges (CP 27 Sep) */
.steps-photo     { margin-top: 2.5rem; overflow: hidden; border-radius: var(--radius-card); box-shadow: var(--shadow-card); aspect-ratio: 16 / 9; }
.steps-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (min-width: 768px) { .steps-photo { aspect-ratio: 16 / 7; } }
.why-us__img     { margin-top: 1.5rem; overflow: hidden; border-radius: var(--radius-card); box-shadow: var(--shadow-card); aspect-ratio: 16 / 9; }
.why-us__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (min-width: 1024px) { .why-us__img { margin-top: 2rem; aspect-ratio: 4 / 5; } }
.band-navy--photo { display: grid; padding: 0; overflow: hidden; }
.band-navy--photo > .band-navy__body { padding: 2rem; }
.band-navy--photo > .band-navy__img  { aspect-ratio: 16 / 9; }
.band-navy--photo > .band-navy__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (min-width: 1024px) {
  .band-navy--photo { grid-template-columns: 7fr 5fr; }
  .band-navy--photo > .band-navy__body { order: 1; }
  .band-navy--photo > .band-navy__img  { order: 2; aspect-ratio: auto; }
}

/* ---------- M3: credits, briefs, conversations ---------- */

/* Credit balance. One number (29 Aug ruling), navy card like the MVP plan card. */
.balance         { background: var(--primary); color: #fff; border-radius: var(--radius-card); padding: 1.5rem; }
.balance__label  { font-size: var(--text-caption); font-weight: 500; color: color-mix(in oklab, #fff 80%, transparent); }
.balance__value  { margin-top: 0.25rem; font-family: var(--font-display); font-size: var(--text-display-lg); font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; }
.balance__value small { font-family: var(--font-sans); font-size: var(--text-body); font-weight: 500; margin-left: 0.375rem; color: color-mix(in oklab, #fff 80%, transparent); }
.balance p       { color: color-mix(in oklab, #fff 80%, transparent); }
.balance a       { color: #fff; }
.balance .btn-outline, .hero .btn-outline { background: #fff; color: var(--primary); border-color: #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); } /* on navy the sheet uses the inverted button */
/* Balance card v2 (CP 16 Sep): figure left, labelled facts right. */
.balance__grid   { display: grid; gap: 1.5rem; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 640px) { .balance__grid { grid-template-columns: auto minmax(0, 1fr); gap: 3rem; } }
.balance__link   { display: inline-block; margin-top: 0.75rem; font-size: var(--text-body-sm); font-weight: 500; color: #fff; }
.balance__facts  { margin: 0; display: grid; gap: 0.625rem; align-self: center; }
.balance__facts > div { display: grid; grid-template-columns: minmax(8rem, 11rem) 1fr; gap: 1rem; font-size: var(--text-body-sm); }
.balance__facts dt { margin: 0; color: color-mix(in oklab, #fff 70%, transparent); font-weight: 500; }
.balance__facts dd { margin: 0; color: #fff; font-weight: 500; font-variant-numeric: tabular-nums; }
@media (min-width: 640px) { .balance__facts { justify-self: end; } }
@media (hover: hover) { .balance .btn-outline:hover:not(:disabled) { background: var(--grey-50); border-color: var(--grey-50); } }

/* Credit packs: radio cards. */
.packs           { display: grid; gap: 0.75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 1rem; }
@media (min-width: 768px) { .packs { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* CP 16 Sep pm: tiles are no longer radios. Each carries its own Buy button; the "Most chosen" tile wears the navy border. */
.pack            { position: relative; display: flex; flex-direction: column; border: 1px solid var(--grey-200); border-radius: var(--radius-lg); padding: 1rem; background: var(--card); } /* bordered option, not a card inside a card */
.pack--best      { border-color: var(--primary); }
.pack__credits   { font-family: var(--font-display); font-size: var(--text-heading); font-weight: 600; font-variant-numeric: tabular-nums; }
.pack__price     { margin-top: 0.25rem; font-weight: 500; }
.pack__per       { margin-top: 0.125rem; font-size: var(--text-caption); color: var(--muted-foreground); }
.pack__buy       { margin-top: 0.75rem; width: 100%; }
.pack__best      { position: absolute; top: -0.625rem; right: 0.75rem; }
.history td.change { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; font-weight: 500; }
.history td strong { font-weight: 600; }
.history .is-expired { color: #991B1B; } /* a loss, plain red text, no pill */
.history tr[hidden] { display: none; }
/* Under 640 the four-column table scrolled sideways and hid the Credits column. Each row stacks: date, then what beside the badge, balance under the badge. */
@media (max-width: 639px) {
  .history .table-wrap { overflow: visible; mask-image: none; }
  .history thead { display: none; }
  .history table.table, .history tbody { display: block; min-width: 0; }
  .history tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "date date" "what change" "what bal"; grid-template-rows: auto auto 1fr; column-gap: 0.75rem; align-items: start; padding: 0.875rem 1rem; border-top: 1px solid var(--grey-100); }
  .history tr:first-child { border-top: 0; }
  .history td { display: block; padding: 0; border: 0; }
  .history td.nowrap { white-space: normal; }
  .history td:nth-child(1) { grid-area: date; font-size: var(--text-caption); color: var(--muted-foreground); margin-bottom: 0.25rem; }
  .history td:nth-child(2) { grid-area: what; }
  .history td:nth-child(3) { grid-area: change; }
  .history td:nth-child(4) { grid-area: bal; font-size: var(--text-caption); color: var(--muted-foreground); text-align: right; margin-top: 0.25rem; }
  .history td:nth-child(4)::before { content: "Balance "; }
}

/* Invite slot meter (five dots, cap from config). */
.slots           { display: inline-flex; align-items: center; gap: 0.375rem; }
.slot            { width: 0.75rem; height: 0.75rem; border-radius: 50%; border: 1.5px dashed var(--border); background: transparent; }
.slot.is-responded { background: var(--success); border: 0; }
.slot.is-pending { border: 1.5px solid var(--warning); background: color-mix(in oklab, var(--warning) 30%, transparent); }
.slot.is-noreply { border: 1.5px solid var(--muted-foreground); background: repeating-linear-gradient(45deg, transparent 0 2px, var(--muted-foreground) 2px 3px); }
.slot.is-declined { border: 1.5px solid var(--border); background: var(--muted); }
.slots__label    { margin-left: 0.375rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }

/* Brief card in an inbox or list. */
.brief-card      { display: block; text-decoration: none; color: inherit; background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card); padding: 1.25rem 1.5rem; transition: box-shadow .15s; }
@media (hover: hover) { .brief-card:hover { box-shadow: var(--shadow-md); } }
.brief-card + .brief-card { margin-top: 1rem; }
.brief-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
@media (max-width: 639px) { .brief-card__top { flex-direction: column; gap: 0.5rem; } }
.brief-card__title { font-family: var(--font-display); font-size: 1.25rem; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.brief-card__meta { margin-top: 0.5rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.brief-card__desc { margin-top: 0.75rem; max-width: 65ch; color: color-mix(in oklab, var(--foreground) 75%, transparent); line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.brief-card__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; margin-top: 0.875rem; padding-top: 0.75rem; border-top: 1px solid var(--border); font-size: var(--text-body-sm); color: var(--muted-foreground); }
.brief-card.is-muted { background: var(--muted); } /* S8: surface dims, text keeps its contrast */

/* Trainer picker rows (choose up to 5). */
.pick            { display: flex; align-items: center; gap: 0.875rem; padding: 0.875rem 1rem; border: 1px solid transparent; border-radius: var(--radius-lg); background: var(--card); box-shadow: var(--shadow-card); cursor: pointer; }
.pick + .pick    { margin-top: 0.5rem; }
.pick:has(input:checked) { border-color: var(--primary); box-shadow: var(--ring-focus), var(--shadow-card); }
.pick:has(input:disabled) { opacity: 0.55; cursor: not-allowed; }
.pick__name      { font-weight: 500; }
.pick__meta      { font-size: var(--text-body-sm); color: var(--muted-foreground); }
.pick__count     { font-size: var(--text-body-sm); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.pick__count.is-full { color: var(--secondary); font-weight: 500; }

/* Conversation. Two columns on desktop: thread and the brief panel. */
.thread-layout   { display: grid; gap: 1.5rem; grid-template-columns: 1fr; margin-top: 1.5rem; }
@media (min-width: 1024px) { .thread-layout { grid-template-columns: minmax(0, 1fr) 20rem; align-items: start; } }
.thread          { display: flex; flex-direction: column; min-height: 32rem; background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card); overflow: hidden; }
.thread__head    { display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--border); }
.thread__body    { flex: 1; padding: 1.25rem; display: flex; flex-direction: column; gap: 0.875rem; overflow-y: auto; max-height: 36rem; }
.day-divider     { align-self: center; font-size: var(--text-caption); color: var(--muted-foreground); padding: 0.125rem 0.75rem; border-radius: var(--radius-full); background: var(--muted); }
.msg             { max-width: 80%; align-self: flex-start; }
.msg__bubble     { padding: 0.625rem 0.875rem; border-radius: var(--radius-card); border-bottom-left-radius: 5px; background: var(--muted); line-height: 1.55; }
.msg__meta       { margin-top: 0.25rem; font-size: var(--text-caption); color: var(--muted-foreground); }
/* "Me" is the viewer: the trainer by default, the company under ?as=company. Sean sets one class per message from the session. */
.msg--me, .msg[data-from="trainer"], .as-company .msg[data-from="company"] { align-self: flex-end; }
.as-company .msg[data-from="trainer"] { align-self: flex-start; }
.msg--me .msg__bubble, .msg[data-from="trainer"] .msg__bubble, .as-company .msg[data-from="company"] .msg__bubble { background: var(--primary); color: #fff; border-bottom-left-radius: var(--radius-card); border-bottom-right-radius: 5px; }
.as-company .msg[data-from="trainer"] .msg__bubble { background: var(--muted); color: inherit; }
.msg--me .msg__meta, .msg[data-from="trainer"] .msg__meta, .as-company .msg[data-from="company"] .msg__meta { text-align: right; }
.as-company .msg[data-from="trainer"] .msg__meta { text-align: left; }
.msg__file       { display: flex; align-items: center; gap: 0.75rem; padding: 0.625rem 0.875rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card); text-decoration: none; color: inherit; }
.msg--me .msg__file { border-color: color-mix(in oklab, var(--primary) 40%, var(--border)); }
.msg__file small { display: block; font-size: var(--text-caption); color: var(--muted-foreground); }
.msg--system     { align-self: center; max-width: 100%; text-align: center; font-size: var(--text-caption); color: var(--muted-foreground); }
.msg--system strong { color: var(--foreground); font-weight: 500; }
.composer        { border-top: 1px solid var(--border); padding: 0.875rem 1.25rem; display: flex; align-items: flex-end; gap: 0.5rem; }
.composer .textarea { margin-top: 0; min-height: 2.75rem; max-height: 10rem; }
.composer__attach { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; flex-shrink: 0; border: 1.5px solid var(--grey-200); border-radius: var(--radius-md); background: var(--card); cursor: pointer; color: var(--grey-600); transition: border-color .15s, color .15s, background-color .15s; } /* sheet icon button: 44, 1.5px, r10 */
@media (hover: hover) { .composer__attach:hover { color: var(--primary); border-color: var(--primary); background: var(--accent); } }
.composer__hint  { padding: 0 1.25rem 0.75rem; font-size: var(--text-caption); color: var(--muted-foreground); }
.thread-lock     { border-top: 1px solid var(--border); padding: 1.25rem; background: color-mix(in oklab, var(--muted) 40%, transparent); }
.thread-side .side-card { background: var(--card); }
.participants li { display: flex; align-items: center; gap: 0.625rem; }
.participants li + li { margin-top: 0.625rem; }

/* Viewer switch (reference only). ?as=company shows the company's side of a page. */
[data-company]   { display: none !important; }
.as-company [data-company] { display: revert !important; }
.as-company [data-trainer] { display: none !important; }
@media (max-width: 767px) { .as-company .site-header__inner .site-nav[data-company] { display: none !important; } } /* the revert above would show the desktop nav on mobile (thread.html) */
@media (min-width: 768px) { .as-company .site-header__inner .site-nav[data-company] { display: flex !important; } } /* revert gives block; the nav is a flex row (thread.html) */

/* Signed-in switch (reference only). ?signedin=1 on a public page: [data-signedout] hides, [data-signedin] shows. */
[data-signedin]  { display: none !important; }
.is-signedin [data-signedin] { display: revert !important; }
.is-signedin [data-signedout] { display: none !important; }

/* ---------- Cookie banner (js/app.js block 20) ---------- */
/* Sits above the sticky header (z-index 50) and the nav dropdown (60). app.js adds
   padding to the body while it is open, so it never covers a page's last button. */
.cookie-banner {
  position: fixed; z-index: 70; inset: auto 0 0 0;
  background: var(--card); color: var(--foreground);
  border-top: 1px solid var(--border);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08);
}
.cookie-banner:focus { outline: none; }
.cookie-banner__inner {
  max-width: var(--w-6xl); margin-inline: auto; padding: 1rem 1.25rem;
  display: flex; flex-direction: column; gap: 0.875rem;
}
.cookie-banner__title { font-family: inherit; font-size: var(--text-body); font-weight: 600; margin: 0; padding-right: 2.75rem; } /* keeps the heading clear of the close control */
.cookie-banner__text p { margin: 0.25rem 0 0; font-size: var(--text-body); }
.cookie-banner__text .cookie-banner__note { font-size: var(--text-caption); color: var(--muted-foreground); } /* specificity must beat the p rule above; it did not until 2 Nov, so the note rendered at 14px */
/* Phones (CP 2 Nov 2026, HANDOFF 285): the banner took 30% of a 390 screen. Body one step down, small buttons, tighter padding. Desktop row unchanged. */
@media (max-width: 899px) {
  .cookie-banner__inner { padding: 0.75rem 1.25rem 1rem; gap: 0.75rem; }
  .cookie-banner__text p { margin-top: 0.125rem; font-size: var(--text-body-sm); }
  .cookie-banner__text .cookie-banner__note { font-size: var(--text-caption); }
  .cookie-banner__actions .btn { padding: 0.5rem 1.125rem; font-size: var(--text-body-sm); border-radius: var(--radius-sm); }
}
/* Equal weight by design: the same button on both sides, so declining costs the
   reader nothing (Cookies Policy Cl. 5.1). Never promote one of these. */
.cookie-banner__actions { display: flex; gap: 0.75rem; }
.cookie-banner__actions .btn { flex: 1 1 0; }
@media (min-width: 900px) {
  .cookie-banner__inner { flex-direction: row; align-items: center; gap: 2rem; padding-block: 1.125rem; }
  .cookie-banner__text { flex: 1; }
  .cookie-banner__actions { flex: 0 0 auto; }
  .cookie-banner__actions .btn { flex: 0 0 auto; }
}

/* Dismiss control. Closing without choosing is a decline (CP ruling 8 Sep), so this
   is the touch equivalent of Escape. Hidden where a keyboard is present, because
   Escape already does it and a third way to decline unbalances the two choices. */
.cookie-banner__close {
  position: absolute; top: 0.25rem; right: 0.5rem;
  display: grid; place-items: center; width: 2.75rem; height: 2.75rem;
  background: none; border: 0; padding: 0; cursor: pointer;
  font-size: 1.375rem; line-height: 1; color: var(--muted-foreground);
}
@media (hover: hover) { .cookie-banner__close:hover { color: var(--foreground); } }
@media (hover: hover) and (pointer: fine) {
  .cookie-banner__close { display: none; }
  .cookie-banner__title { padding-right: 0; }
}


/* Sign-up role choice (launch). */
.role-card       { display: flex; flex-direction: column; padding: 1.75rem; }
.role-card .checklist { flex: 1; }
.role-card__cta  { margin-top: 1.5rem; }
.role-card .pill { white-space: normal; text-align: right; }
@media (min-width: 640px) { .role-grid > .role-card { display: grid; grid-row: span 5; grid-template-rows: subgrid; row-gap: 0; } } /* icon, title, line, ticks and button share rows across the three cards, so the tick lists start level (17 Oct sweep) */
.icon-tile--navy { background: color-mix(in oklab, var(--primary) 10%, transparent); color: var(--primary); }
.icon-tile--success { background: color-mix(in oklab, var(--success) 10%, transparent); color: var(--success); }

/* Open briefs board card: right rail for the three things a trainer scans for (budget, competition,
   deadline) plus the action, Freelancer-style. Additive modifier; the plain .brief-card on briefs.html
   is unchanged. Card stays one <a>, so the button is a styled span and the tags are static chips. */
.brief-card--rail { display: grid; grid-template-columns: minmax(0, 1fr) 13rem; gap: 0.75rem 1.5rem; }
.brief-card__main { min-width: 0; }
.brief-card__rail { display: flex; flex-direction: column; gap: 0.25rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.brief-card__rail-budget { font-family: var(--font-display); font-size: 1.125rem; font-weight: 600; color: var(--foreground); }
.brief-card__rail .btn { margin-top: 0.5rem; align-self: flex-start; }
.brief-card__rail .pill { margin-top: 0.75rem; align-self: flex-start; } /* status pill lives in the rail, under View brief (CP 13 Sep) */
.brief-card__rail .pill { margin-top: 0.75rem; align-self: flex-start; } /* status pill lives in the rail, under View brief (CP 13 Sep) */
.brief-card__tags { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.75rem; }
.brief-card--rail .brief-card__foot { grid-column: 1 / -1; }
@media (max-width: 639px) { .brief-card--rail { grid-template-columns: 1fr; } }

/* ---------- Pipeline kanban (12 Sep 2026; trainer briefs.html and company-dashboard.html) ----------
   One column per stage, horizontal scroll on narrow screens. Each column is a native <details open>
   so the collapse control (Trainer delta TD-11) costs no JS. Cards are links to the brief or thread. */
.kanban          { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(15rem, 1fr); gap: 1rem; overflow-x: auto; padding-bottom: 1rem; scroll-snap-type: x proximity; }
.kanban__col     { background: var(--muted); border-radius: var(--radius-lg); padding: 0.75rem; min-height: 6rem; scroll-snap-align: start; align-self: start; }
.kanban__col summary { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; cursor: pointer; list-style: none; padding: 0.25rem 0.25rem 0.5rem; font-weight: 600; font-size: var(--text-body-sm); }
.kanban__col summary::-webkit-details-marker { display: none; }
.kanban__count   { color: var(--muted-foreground); font-weight: 500; font-variant-numeric: tabular-nums; }
.kanban__card    { display: block; background: var(--card); border-radius: var(--radius-md); box-shadow: var(--shadow-card); padding: 0.75rem; text-decoration: none; color: inherit; transition: box-shadow .15s; }
.kanban__card + .kanban__card { margin-top: 0.5rem; }
@media (hover: hover) { .kanban__card:hover { box-shadow: var(--shadow-md); } }
.kanban__id      { font-size: var(--text-caption); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.kanban__title   { font-weight: 600; font-size: var(--text-body-sm); line-height: 1.35; margin-top: 0.125rem; }
.kanban__meta    { margin-top: 0.375rem; font-size: var(--text-caption); color: var(--muted-foreground); }
.kanban__empty   { font-size: var(--text-caption); color: var(--muted-foreground); padding: 0.5rem 0.25rem; }

/* ---------- Stat tiles (12 Sep 2026; business snapshot, trainer insights) ----------
   "Your number, platform average" side by side (Trainer Tasklist 1.3). No accent bars. */
.stat            { display: flex; flex-direction: column; gap: 0.875rem; align-items: stretch; container-type: inline-size; background: var(--card); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); padding: 1.375rem 1.5rem; } /* sheet stat card: icon row, then value; 22 x 24 */
.stat__label     { font-size: var(--text-body-sm); font-weight: 500; color: var(--muted-foreground); }
.stat__value     { font-family: var(--font-display); font-size: min(2.0625rem, 16cqi); font-weight: 700; line-height: 1; letter-spacing: -0.5px; color: var(--primary); margin-top: 0.375rem; font-variant-numeric: tabular-nums; } /* sheet stat value: Lora 33/700 navy */
.stat--lead .stat__value { font-size: min(2.75rem, 20cqi); } /* the total that the other cards add up to (credits.html Available credits; M4-007 to 009, CP 6 Oct): same row, visibly larger */
.stat__value.text-muted { font-family: var(--font-sans); font-size: var(--text-subheading); font-weight: 600; line-height: 1.35; letter-spacing: -0.1px; color: var(--muted-foreground); } /* a text state ("No rating yet") is not a number: H4 row, muted */
.stat__avg       { margin-top: 0.5rem; font-size: var(--text-caption); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.attention       { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .attention { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.attention__card { display: flex; align-items: flex-start; gap: 0.875rem; background: var(--card); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); padding: 1rem 1.25rem; text-decoration: none; color: inherit; transition: box-shadow .15s; }
@media (hover: hover) { .attention__card:hover { box-shadow: var(--shadow-md); } }
.attention__title { display: flex; align-items: baseline; gap: 0.5rem; font-weight: 600; }
.attention__meta { font-size: var(--text-body-sm); color: var(--muted-foreground); }

/* ---------- Pipeline v2 (12 Sep 2026, from the MVP PipelineBoard / TPDashboard) ----------
   Stage colours live on a dot, never on a card edge. Tokens are in styles.css (S12). */
.dot-stage       { display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--stage, var(--stage-invited)); flex-shrink: 0; }
[data-stage="interest"]   { --stage: var(--stage-interest); }
[data-stage="invited"]    { --stage: var(--stage-invited); }
[data-stage="discussion"] { --stage: var(--stage-discussion); }
[data-stage="confirmed"]  { --stage: var(--stage-confirmed); }
[data-stage="delivery"]   { --stage: var(--stage-delivery); }
[data-stage="invoiced"]   { --stage: var(--stage-invoiced); }
[data-stage="claim"]      { --stage: var(--stage-claim); }
[data-stage="closed"]     { --stage: var(--stage-closed); }
.mono            { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Stage strip: the funnel read left to right. */
.stage-strip     { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(7.5rem, 1fr); gap: 0.5rem; overflow-x: auto; padding-bottom: 0.5rem; }
.stage-tile      { position: relative; display: flex; flex-direction: column; background: var(--card); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); padding: 0.75rem 0.875rem; text-decoration: none; color: inherit; transition: box-shadow .15s; }
.stage-tile[aria-current="true"] { border-color: color-mix(in oklab, var(--stage, var(--primary)) 55%, var(--border)); }
@media (hover: hover) { .stage-tile:hover { box-shadow: var(--shadow-md); } }
.stage-tile__label { display: flex; align-items: center; gap: 0.375rem; font-size: var(--text-caption); font-weight: 600; color: var(--muted-foreground); }
.stage-tile__count { display: block; margin-top: auto; padding-top: 0.375rem; font-family: var(--font-display); font-size: 1.5rem; font-weight: 600; line-height: 1; }
.stage-tile__sum { display: block; margin-top: 0.375rem; font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted-foreground); }
.stage-tile + .stage-tile::before { content: ""; position: absolute; left: -0.45rem; top: 50%; width: 0.4rem; height: 0.4rem; border-right: 1.5px solid var(--border); border-bottom: 1.5px solid var(--border); transform: translateY(-50%) rotate(-45deg); }
.funnel-out      { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; font-size: var(--text-caption); }
.funnel-out__label { font-weight: 600; color: var(--muted-foreground); font-size: var(--text-caption); }
.funnel-out__item { display: inline-flex; align-items: center; gap: 0.375rem; color: var(--muted-foreground); } /* a count, plain text with its stage dot, not a pill (17 Oct sweep) */

/* Pipeline table. */
.pipe            { width: 100%; border-collapse: collapse; font-size: var(--text-body-sm); }
.pipe th         { text-align: left; font-size: var(--text-caption); font-weight: 600; color: var(--muted-foreground); padding: 0.75rem 1rem; background: var(--muted); }
.pipe td         { padding: 0.875rem 1rem; border-top: 1px solid var(--border); vertical-align: middle; }
@media (hover: hover) { .pipe tr:hover td { background: color-mix(in oklab, var(--muted) 50%, transparent); } }
.pipe__title     { font-weight: 600; color: var(--foreground); }
.pipe__title a   { color: inherit; text-decoration: none; }
@media (hover: hover) { .pipe__title a:hover { text-decoration: underline; } }
.pipe__ref       { margin-top: 0.125rem; font-family: var(--font-mono); font-size: var(--text-caption); color: var(--muted-foreground); }
.pipe__who       { display: flex; align-items: center; gap: 0.625rem; white-space: nowrap; }
.pipe__stage     { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 500; white-space: nowrap; }
.pipe .num       { text-align: right; font-family: var(--font-mono); font-weight: 600; white-space: nowrap; }
.pipe__next      { color: var(--muted-foreground); }
.avatar-xs       { width: 2rem; height: 2rem; font-size: var(--text-caption); }
.avatar img      { border-radius: inherit; }

/* Kanban v2: coloured head, meta line on cards. Sentence case since S2. */
.kanban__head    { display: inline-flex; align-items: center; gap: 0.5rem; font-size: var(--text-caption); }
.kanban__eyebrow { display: flex; align-items: center; gap: 0.375rem; font-size: var(--text-caption); font-weight: 600; color: var(--primary); }
.kanban__eyebrow .pill { margin-left: auto; padding: 0.125rem 0.5rem; font-size: var(--text-overline); }
.kanban__eyebrow--board { color: var(--muted-foreground); }
.kanban__eyebrow--claim { color: var(--success); }
.kanban__foot    { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.5rem; font-size: var(--text-caption); }
.kanban__money   { font-family: var(--font-mono); font-weight: 700; color: var(--success); white-space: nowrap; }
.kanban__next    { color: var(--muted-foreground); text-align: right; min-width: 0; }

/* Stat tile v2: icon tile + accent. */
.stat > .icon-tile { width: 2.625rem; height: 2.625rem; border-radius: 11px; align-self: flex-start; }   /* sheet stat icon 42, r11 */
.stat > .icon-tile svg { width: 1.25rem; height: 1.25rem; }
.stat__body      { min-width: 0; }
.icon-tile--warning { background: color-mix(in oklab, var(--warning) 15%, transparent); color: var(--amber-700); }
.icon-tile--violet  { background: color-mix(in oklab, var(--violet) 12%, transparent); color: var(--violet-700); }
.icon-tile--muted   { background: var(--muted); color: var(--muted-foreground); }

/* Attention card v2: icon + urgency. */
.attention__card > .icon-tile { width: 2.25rem; height: 2.25rem; border-radius: var(--radius-md); flex-shrink: 0; }
.attention__card > .icon-tile svg { width: 1.125rem; height: 1.125rem; }
.attention__body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 0.25rem; }
.attention__due  { margin-left: auto; font-size: var(--text-caption); font-weight: 600; white-space: nowrap; }
.attention__due--now { color: var(--coral); }
.attention__due--soon { color: var(--amber-700); }

/* Programme card v3 (CP 13 Sep 2026): trainer row, claim pill + Save, title (the link), two-line summary, one fact line.
   Modules, area, updated date and the trainer foot link moved to the programme page. Same card on search, launch home, saved. */
.pcard           { position: relative; display: flex; flex-direction: column; background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card); padding: 1.25rem 1.5rem; transition: box-shadow .15s; }
@media (hover: hover) { .pcard:hover     { box-shadow: var(--shadow-md); } }
.pcard[hidden]   { display: none; }
/* Programme first, trainer as supporting evidence (M2-001 / M2-003, 29 Sep): title, summary, facts, then one
   "Delivered by" line with the accredited pill. Save sits top-right of the card. */
.pcard__by       { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; margin-top: 0.875rem; padding-top: 0.875rem; border-top: 1px solid var(--border); }
.pcard__trainer  { display: flex; align-items: center; gap: 0.5rem; min-width: 0; text-decoration: none; color: inherit; }
.pcard__trainer .avatar { width: 2rem; height: 2rem; font-size: 0.75rem; }
.pcard__by-text  { min-width: 0; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.pcard__name     { font-weight: 600; color: var(--foreground); }
@media (hover: hover) { .pcard__trainer:hover .pcard__name { text-decoration: underline; } }
.pcard__save     { position: absolute; top: 1.25rem; right: 1.5rem; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border: 1.5px solid var(--grey-200); border-radius: var(--radius-md); background: var(--card); color: var(--grey-600); cursor: pointer; }
.pcard__save svg { width: 1.125rem; height: 1.125rem; }
@media (hover: hover) { .pcard__save:hover { border-color: var(--primary); color: var(--primary); background: var(--accent); } }
@media (pointer: coarse) { .pcard__save { width: 2.75rem; height: 2.75rem; } } /* 44px thumb target */
.pcard__save[aria-pressed="true"] { background: color-mix(in oklab, var(--warning) 18%, transparent); border-color: var(--warning); color: var(--amber-700); }
.pcard__title    { margin-top: 0; padding-right: 3rem; font-family: var(--font-display); font-size: 1.25rem; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.pcard__title a  { color: var(--primary); text-decoration: none; text-underline-offset: 3px; } /* the card's one visible link (Q1) */
.pcard__title a::after { content: ""; position: absolute; inset: 0; }
@media (hover: hover) { .pcard:hover .pcard__title a { text-decoration: underline; } }
.pcard__summary  { margin-top: 0.375rem; max-width: 65ch; color: color-mix(in oklab, var(--foreground) 75%, transparent); line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pcard__facts    { margin-top: 0.75rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.fact            { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; border-radius: var(--radius-sm); font-size: var(--text-body-sm); font-weight: 500; border: 1px solid transparent; }
.fact svg        { width: 0.875rem; height: 0.875rem; }
/* S1: facts are neutral. Colour on a chip is reserved for status pills. The two modifier classes stay in
   markup (60 uses) but render like .fact--plain, so Sean can drop them or keep them. */
.fact--navy      { border-color: var(--border); color: var(--foreground); }
.fact--violet    { border-color: var(--border); color: var(--foreground); }
.fact--plain     { border-color: var(--border); color: var(--foreground); }
.pcard__trainer { position: relative; }
.pcard__trainer, .pcard__save { z-index: 1; } /* sit above the title's stretched link */

/* Brief facts row (CP 15 to 16 Sep): icon + text pairs, no borders. Board, company briefs and my-briefs cards.
   A trailing claim pill (HRD Corp claim / Self-funded) rides as the last item. */
.brief-card__facts { display: flex; flex-wrap: wrap; gap: 0.375rem 1rem; margin: 0.5rem 0 0; padding: 0; list-style: none; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.brief-card__facts li { display: inline-flex; align-items: center; gap: 0.375rem; white-space: nowrap; }
.brief-card__facts svg { width: 0.875rem; height: 0.875rem; flex-shrink: 0; color: var(--grey-400); }
.brief-card__facts .pill { margin-left: 0.25rem; }
/* Trainer facts row (12 Sep; brief logistics moved to .brief-card__facts 16 Sep): the running "In-person · 2 days · 40 pax · ..." line as chips. Same .fact tokens as the programme card. */
.facts           { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.625rem; }
.facts .fact     { padding: 0.25rem 0.625rem; font-size: var(--text-caption); }
.facts .fact svg { width: 0.8rem; height: 0.8rem; }
.facts .pill     { align-self: center; }

/* Programme page modules (12 Sep): numbered because a programme runs in this order. */
.modules         { list-style: none; display: flex; flex-direction: column; gap: 0.5rem; }
.modules li      { display: flex; align-items: center; gap: 0.75rem; padding: 0.625rem 0.875rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card); }
.modules__n      { display: grid; place-items: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; background: color-mix(in oklab, var(--primary) 10%, transparent); color: var(--primary); font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 700; flex-shrink: 0; }

/* A trainer row with a photo (12 Sep): avatar, content, actions. */
.list-row > .avatar { margin-right: 0.875rem; }
.list-row > .avatar + div { flex: 1; min-width: 0; }

.list-row > .icon-tile { width: 2.5rem; height: 2.5rem; border-radius: var(--radius-md); margin-right: 0.875rem; flex-shrink: 0; }
.list-row > .icon-tile svg { width: 1.125rem; height: 1.125rem; }
.list-row > .icon-tile + div { flex: 1; min-width: 0; }

/* ---------- Programme page (CP 13 Sep): follows the AI Studio ProgramDetail layout as a full page, not a pop-up.
   One white sheet on the canvas: navy hero band (no trainer chip, CP 13 Sep), then a 2:1 body with a sticky rail. Copy unchanged. ---------- */
.prog             { background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card); overflow: clip; }
.prog-bar         { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; padding: 0.875rem 1.5rem; border-bottom: 1px solid var(--border); } /* 4 Oct: AI Studio top bar, no X */
.prog-bar .back-link { display: inline-flex; align-items: center; gap: 0.375rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.prog-bar .back-link svg { width: 1rem; height: 1rem; }
.prog-bar .pill   { grid-column: 2; }
.prog-hero        { position: relative; overflow: hidden; padding: 2rem 1.5rem 2.25rem; color: #fff;
                    background: linear-gradient(135deg, var(--navy-700) 0%, var(--navy-800) 45%, var(--navy-900) 100%); }
@media (min-width: 640px)  { .prog-hero { padding: 2.25rem 2rem 2.5rem; } }
@media (min-width: 1024px) { .prog-hero { padding: 2.5rem 2.5rem 2.75rem; } }
.prog-hero__deco  { position: absolute; inset: 0; pointer-events: none; }
.prog-hero__deco::before { content: ""; position: absolute; top: -4rem; right: -4rem; width: 16rem; height: 16rem; border-radius: 50%;
                    background: radial-gradient(circle, var(--coral-500) 0%, transparent 70%); opacity: 0.08; }
.prog-hero__deco::after  { content: ""; position: absolute; bottom: -3rem; left: 33%; width: 24rem; height: 12rem; border-radius: 50%;
                    background: radial-gradient(circle, #fff 0%, transparent 70%); opacity: 0.05; }
.prog-hero__grid  { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.04; }
.prog-hero > *:not(.prog-hero__deco):not(.prog-hero__grid) { position: relative; }
.prog-hero .facts { margin-top: 0; }
.prog-hero .fact  { background: color-mix(in oklab, #fff 12%, transparent); border-color: color-mix(in oklab, #fff 15%, transparent); color: var(--navy-100); font-weight: 600; }
.prog-hero .pill-success { background: color-mix(in oklab, var(--success) 18%, transparent); border-color: color-mix(in oklab, var(--success) 30%, transparent); color: #6EE7B7; font-weight: 600; }
.prog-hero__title { margin-top: 1rem; color: #fff; font-size: var(--text-display); line-height: 1.2; letter-spacing: -0.3px; }
@media (min-width: 640px)  { .prog-hero__title { font-size: var(--text-display-lg); line-height: 1.12; } } /* H1 row */
.prog-hero__area  { margin-top: 0.625rem; font-size: var(--text-body); font-weight: 500; color: var(--navy-200); }
.prog-hero :focus-visible { outline-color: #fff; }

.prog-body        { display: grid; gap: 2rem; grid-template-columns: 1fr; padding: 1.5rem; }
@media (min-width: 640px)  { .prog-body { padding: 2rem; } }
@media (min-width: 1024px) { .prog-body { grid-template-columns: 2fr 1fr; padding: 2rem 2.5rem 2.5rem; } }
.prog-main .block + .block { margin-top: 2rem; }
.prog-main .block__label { margin-bottom: 1rem; } /* site-wide H4 heading (HANDOFF 213); the 11px grey-400 caps and coral side bar are gone (CP 17 Oct, HANDOFF 229) */
.prog-main p      { max-width: 65ch; line-height: 1.65; color: var(--foreground); }
.prog-main .checklist { margin-top: 0; }
.prog-main .checklist li { color: var(--foreground); line-height: 1.45; }
.prog-main .tick.is-done { background: transparent; border: 1.5px solid var(--coral-500); color: var(--coral-500); }
.prog-main .modules li { padding: 0; border: 0; background: none; align-items: flex-start; }
.prog-main .modules__n { width: 1.5rem; height: 1.5rem; border-radius: var(--radius-sm); font-family: var(--font-sans); font-size: var(--text-overline); font-weight: 800; margin-top: 0.0625rem; background: var(--navy-100); color: var(--primary); } /* 4 Oct: navy numbers as in the AI Studio image */
.prog-main .modules li > span:last-child { padding-top: 0.125rem; line-height: 1.45; }
.prog-tags        { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.prog-tags .chip-static { display: inline-flex; align-items: center; gap: 0.375rem; border-radius: var(--radius-sm); font-weight: 600; font-size: var(--text-caption);
                    background: color-mix(in oklab, var(--primary) 6%, transparent); border-color: color-mix(in oklab, var(--primary) 20%, transparent); color: var(--navy-600); }
.prog-tags .chip-static svg { width: 0.75rem; height: 0.75rem; }
.prog-tags .chip-static--success { background: #ECFDF5; color: #047857; } /* Delivered in languages (4 Oct), the pill-success colours */

.prog-side        { align-self: start; }
@media (min-width: 1024px) { .prog-side { position: sticky; top: 1rem; } }
.prog-side .side-card { background: color-mix(in oklab, var(--canvas) 60%, var(--card)); border-radius: var(--radius-lg); padding: 1.25rem; }
.prog-side .side-card + .side-card { margin-top: 1rem; }
.prog-side .side-trainer { display: flex; align-items: center; gap: 0.75rem; }
.prog-side .side-trainer .avatar { width: 3rem; height: 3rem; border: 2px solid #fff; box-shadow: var(--shadow-card); }
.prog-side .side-trainer .medium { font-weight: 700; line-height: 1.3; }
.prog-side .side-trainer .loc { display: inline-flex; align-items: center; gap: 0.25rem; margin-top: 0.125rem; font-size: var(--text-caption); color: var(--muted-foreground); }
.prog-side .side-profile { display: flex; align-items: center; justify-content: space-between; margin-top: 1rem; font-size: var(--text-caption); font-weight: 600; color: var(--primary); text-decoration: none; }
.prog-side .side-profile svg { width: 0.875rem; height: 0.875rem; transition: transform .16s var(--ease-out); }
@media (hover: hover) { .prog-side .side-profile:hover { text-decoration: underline; text-underline-offset: 2px; } .prog-side .side-profile:hover svg { transform: translateX(2px); } }
.prog-side .stack-sm { margin-top: 1rem; }
.prog-side .btn svg { width: 1rem; height: 1rem; }
.prog-side .btn-secondary { font-weight: 700; }
.prog-side .btn-outline { min-height: 2.5rem; font-size: var(--text-caption); font-weight: 700; color: var(--muted-foreground); }
@media (hover: hover) { .prog-side .btn-outline:hover:not(:disabled) { border-color: var(--warning); color: var(--amber-700); background: color-mix(in oklab, var(--warning) 10%, transparent); } }
.prog-side .btn-outline[aria-pressed="true"] { background: color-mix(in oklab, var(--warning) 12%, transparent); border-color: color-mix(in oklab, var(--warning) 60%, transparent); color: var(--amber-700); }
.prog-side .overline { margin-top: 0.5rem; }
.prog-side .kv    { display: block; font-size: var(--text-caption); }
.prog-side .kv > div { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.625rem 0; border-top: 1px solid var(--border); }
.prog-side .kv > div:first-child { border-top: 0; padding-top: 0; }
.prog-side .kv > div:last-child  { padding-bottom: 0; }
.prog-side .kv dt { display: inline-flex; align-items: center; gap: 0.375rem; font-weight: 600; color: var(--muted-foreground); }
.prog-side .kv dt svg { width: 0.875rem; height: 0.875rem; }
.prog-side .kv dd { font-weight: 700; color: var(--foreground); text-align: right; }

/* Navy band (CP trial 15 Sep, after Fiverr's coloured closing block): the closing For-companies card painted navy so the last call to action reads apart from the white cards above. One per page. */
.band-navy { background: var(--primary); color: #fff; box-shadow: none; }
.band-navy .eyebrow { color: color-mix(in oklab, #fff 70%, transparent); }
.band-navy .display, .band-navy .checklist li { color: #fff; }
.band-navy .tick.is-done { background: #fff; border-color: #fff; color: var(--primary); }
.band-navy .btn-link { color: #fff; }
.band-navy .btn-secondary { background: #fff; color: var(--primary); }  /* coral-700 (the AA coral) reads dull on navy; white is the brightest thing on the band and keeps 11:1 */
.band-navy .btn-secondary:hover { background: var(--navy-50); }

/* Section panels (CP 16 Sep, Upwork model; resources.html and index-launch.html): alternate canvas / white full-bleed panel so each block reads as its own section.
   wash = soft navy glow off the top-left corner; hatch = faint diagonal lines fading out toward the centre. Pure CSS. */
.panel           { position: relative; background: var(--background); margin-top: 4rem; }
.panel > .rrow   { padding-bottom: 4rem; }
.panel .pcard, .panel .belief { border: 1px solid var(--border); }  /* ring shadow vanishes on white; same edge the resources cards carry */
.panel > section { position: relative; z-index: 1; }
.panel::before   { content: ""; position: absolute; inset: 0; pointer-events: none; }
.panel--wash::before  { background: radial-gradient(60rem 28rem at 0% 0%, var(--navy-50), transparent 70%); }
.panel--hatch::before { background: repeating-linear-gradient(-45deg, color-mix(in oklab, var(--navy-900) 11%, transparent) 0 1px, transparent 1px 12px);
  -webkit-mask-image: linear-gradient(to right, #000, transparent 35%, transparent 65%, #000); mask-image: linear-gradient(to right, #000, transparent 35%, transparent 65%, #000); }

/* Legal hub (pages/legal.html, CP 16 Sep 2026, Upwork legal centre model; rendered by build-legal.py).
   Sticky 280px rail headed "Terms of Service" on the left, one document after another in a 576px column (CP 19 Sep: 14px body, about 76 characters a line) on the right.
   Under 1024px the rail sits above the documents: the first two documents show, the rest sit behind Show more / Show less (app.js block 26, CP 16 Sep). */
.legal-hub         { display: grid; gap: 2rem; padding-top: 2.5rem; padding-bottom: 6rem; }
.legal-rail__title { font-family: var(--font-display); font-weight: 600; font-size: var(--text-heading); line-height: 1.3; letter-spacing: -0.3px; }
.legal-rail__list  { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.125rem; }
.legal-rail__list ul { list-style: none; margin: 0.125rem 0 0; padding-left: 1rem; }
.legal-rail__list a  { display: block; padding: 0.5rem 0.75rem; border-radius: var(--radius-md); color: var(--foreground); font-size: var(--text-body-sm); font-weight: 500; line-height: 1.4; text-decoration: none; }
.legal-rail__list a:hover { background: var(--muted); }
.legal-rail__list a[aria-current="true"] { background: var(--accent-active); color: var(--accent-foreground); font-weight: 600; }
.legal-main        { min-width: 0; }
.legal-doc         { scroll-margin-top: 5.5rem; } /* clears the sticky header on hash jumps */
.legal-doc + .legal-doc { margin-top: 4rem; padding-top: 3rem; border-top: 1px solid var(--border); }
.legal-doc [id]    { scroll-margin-top: 5.5rem; }
/* Documents render one heading level down inside the hub (title h2, sections h3, sub-sections h4; the Cookies block two down), so the sizes shift with them. */
.legal-doc .prose--legal h3 { font-family: var(--font-sans); font-size: var(--text-heading); font-weight: 700; letter-spacing: -0.3px; margin-top: 2rem; }
.legal-doc .prose--legal h4 { font-size: var(--text-subheading); font-weight: 600; letter-spacing: -0.1px; margin-top: 1.5rem; }
.legal-doc .prose--legal h5 { font-size: var(--text-body-lg); font-weight: 600; margin-top: 1.25rem; }
@media (min-width: 1024px) {
  .legal-hub { grid-template-columns: 280px minmax(0, 36rem); gap: 3.5rem; padding-top: 4rem; }
  .legal-rail { position: sticky; top: 5rem; align-self: start; max-height: calc(100vh - 6rem); overflow-y: auto; }
  .legal-rail__toggle { display: none; }
  .legal-rail__list > li[hidden] { display: list-item !important; }
}

/* ---------- Locked field (16 Sep, title lock on programme-edit.html) ----------
   A read-only value with a lock at the right end. Grey fill says "not yours to type in"; the help line under it
   says why and offers Request a change. */
.field--locked   { position: relative; display: block; }
.field--locked .input { padding-right: 2.5rem; background: var(--grey-50); color: var(--grey-700); cursor: default; }
.field--locked .input:focus { border-color: var(--input); box-shadow: none; }
.field__lock     { position: absolute; right: 0.875rem; top: 50%; width: 1rem; height: 1rem; margin-top: -0.5rem; color: var(--grey-400); pointer-events: none; }
.field__help .btn-link { font-size: inherit; }
.notice small .btn-link { font-size: inherit; color: inherit; font-weight: 600; }

/* Briefs waiting cards (CP 16 Sep): one primary button per card, so the card is a div with a stretched
   title link, not one big <a>. Button sits above the stretched link. Label flips to top-up when the
   balance is short; "N short" on the line is state, the why lives on help.html#credits. */
.brief-card--action { position: relative; }
.brief-card__link { color: inherit; text-decoration: none; }
.brief-card__link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.brief-card--action .btn { position: relative; z-index: 1; }
.brief-card__cta { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
@media (hover: hover) { .brief-card--action:hover { box-shadow: var(--shadow-md); } }

/* ---------- How it works: numbered steps with a phone-framed product screenshot (CP 19 Sep, Freelancer/Airbnb pattern) ---------- */
.hiw             { display: grid; gap: 2rem; align-items: center; }
@media (min-width: 1024px) {
  .hiw           { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4rem; }
  .hiw--flip > .hiw__shot { order: -1; }   /* phone on the left for every second step */
}
.hiw__shot       { margin: 0; width: min(100%, 17.5rem); margin-inline: auto; }
.phone           { padding: 0.625rem; border-radius: 2.5rem; background: var(--foreground); box-shadow: var(--shadow-lg, 0 12px 32px rgba(15, 23, 42, .18)); }
.phone img       { display: block; width: 100%; height: auto; border-radius: 1.9rem; }
.step__num--lg   { width: 3rem; height: 3rem; font-family: var(--font-display); font-size: var(--text-heading); }

/* ── Area pages: pages/areas.html + pages/areas/*.html, generated by build-areas.py (CP 20 Sep). ──
   .ph = photo slot. The <img> removes itself when the file is missing (onerror), so the dashed box and
   filename show until CP drops the photo in. Dashed border is the placeholder state only. */
.ph              { position: relative; overflow: hidden; margin: 0; aspect-ratio: 4 / 3; border-radius: var(--radius-lg); background: var(--muted); border: 1px dashed var(--border); }
.ph img          { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ph__label       { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; text-align: center; font-size: var(--text-body-sm); line-height: 1.5; color: var(--muted-foreground); }
.ph:has(img)     { border-style: solid; border-color: transparent; }
.ph:has(img) .ph__label { display: none; }                              /* the label sits above the photo in paint order; gone once the file loads */
.hiw__shot--photo { width: 100%; }                                      /* a landscape photo, not the phone frame */
.area-card       { padding: 0; }                                        /* index card: photo top, text below (Freelancer menu card) */
.area-card__img  { aspect-ratio: 3 / 2; border-radius: var(--radius-card) var(--radius-card) 0 0; border-width: 0 0 1px; }
.area-card__body { padding: 1.25rem; }
.chip--topic     { padding: 0.625rem 1.125rem; font-size: var(--text-body-sm); font-weight: 500; color: var(--foreground); text-decoration: none; }  /* area page sub-topic link, body size, not the 12px filter pill */
.chips--topics   { gap: 0.625rem; }
.hero__ph        { position: absolute; right: 1rem; bottom: 1rem; padding: 0.25rem 0.625rem; border: 1px dashed color-mix(in oklab, #fff 55%, transparent); border-radius: var(--radius-sm); color: color-mix(in oklab, #fff 75%, transparent); }  /* area hero photo slot label; gone once the photo exists */
.hero:has(.hero__img) .hero__ph { display: none; }

.ph--demo        { display: block; text-decoration: none; color: inherit; }                       /* the slot is a link to a trainer's demo video (Freelancer "Watch a demo") */
.ph__play        { position: absolute; left: 1.25rem; bottom: 1rem; display: inline-flex; align-items: center; gap: 0.5rem; font-family: var(--font-display); font-weight: 600; font-size: var(--text-heading); color: var(--foreground); }
.ph__play svg    { width: 2.5rem; height: 2.5rem; }
.ph--demo:has(img) .ph__play { color: #fff; text-shadow: 0 1px 8px rgba(15, 23, 42, .6); }        /* over a photo */
@media (hover: hover) { .ph--demo:hover .ph__play svg { transform: scale(1.08); transition: transform .16s var(--ease-out); } }
@media (max-width: 639px) { .hero__ph { display: none; } }                                       /* phones: the label collides with the hero buttons; the file name is in assets/img/areas/README.txt */

/* Programme card v4 (search.html, CP 4 Oct 2026): the AI Studio arrangement. Trainer row on top, pill and save on the
   right, module chips, coloured fact tags, one link at the foot. The save button leaves its absolute corner here. */
.results__list--cards { gap: 1.25rem; }
@media (min-width: 1024px) { .results__list--cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Programme cards side by side share six row tracks (head, title, summary, updated, modules, footer), so titles, module rows
   and the footer divider line up across a row (17 Oct sweep). Phones keep one card per row or the swipe row. */
@media (min-width: 640px)  { .grid-2 > .pcard:has(> .pcard__head) { display: grid; grid-row: span 6; grid-template-rows: subgrid; row-gap: 0; }
  .grid-2 > .pcard:has(> .pcard__head) > .pcard__modules { align-content: start; }
  .grid-2 > .pcard:has(> .pcard__head) > .pcard__tags { margin-top: 0; align-content: space-between; }
  .grid-2 > .pcard:has(> .pcard__head) .pcard__go { flex-basis: 100%; text-align: right; } }
@media (min-width: 1024px) { .results__list--cards > .pcard:has(> .pcard__head) { display: grid; grid-row: span 6; grid-template-rows: subgrid; row-gap: 0; }
  .results__list--cards > .pcard:has(> .pcard__head) > .pcard__modules { align-content: start; }
  .results__list--cards > .pcard:has(> .pcard__head) > .pcard__tags { margin-top: 0; align-content: space-between; }
  .results__list--cards > .pcard:has(> .pcard__head) .pcard__go { flex-basis: 100%; text-align: right; } }
.pcard__head     { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.pcard__head .pcard__trainer { align-items: flex-start; gap: 0.625rem; flex: 1 1 12rem; min-width: 0; } /* phone pass 4 Oct: the name keeps at least 12rem; the pill and Save wrap under it instead of squeezing it to one word a line */
.pcard__head .pcard__trainer .avatar { width: 2.25rem; height: 2.25rem; font-size: 0.8125rem; }
.pcard__head .pcard__by-text { display: flex; flex-direction: column; gap: 0.125rem; color: var(--foreground); }
.pcard__where    { display: inline-flex; align-items: center; gap: 0.25rem 0.5rem; flex-wrap: wrap; font-size: var(--text-caption); color: var(--muted-foreground); }
.pcard__where svg { width: 0.875rem; height: 0.875rem; }
.pcard__rating   { display: inline-flex; align-items: center; gap: 0.2rem; color: var(--amber-700); font-weight: 600; }
.pcard__head-right { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; margin-left: auto; position: relative; z-index: 1; }
.pcard__head-right .pcard__save { position: static; }
.pcard__head + .pcard__title { margin-top: 1rem; padding-right: 0; font-size: 1.125rem; }
.pcard__updated  { margin-top: 0.5rem; }
.pcard__modules  { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; margin-top: 0.75rem; margin-bottom: 0.875rem; }
.chip-outline    { cursor: default; border: 1px solid var(--grey-300); border-radius: var(--radius-sm); padding: 0.25rem 0.5rem; font-size: var(--text-caption); background: var(--card); color: var(--foreground); }
.pcard__tags     { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: auto; padding-top: 0.875rem; border-top: 1px solid var(--border); }
.tag             { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.3rem 0.625rem; border-radius: var(--radius-sm); font-size: var(--text-caption); font-weight: 600; border: 1px solid transparent; }
.tag svg         { width: 0.875rem; height: 0.875rem; }
.tag--navy       { background: var(--navy-50); color: var(--primary); border-color: color-mix(in oklab, var(--primary) 25%, transparent); }
.tag--violet     { background: color-mix(in oklab, var(--violet) 10%, var(--card)); color: var(--violet); border-color: color-mix(in oklab, var(--violet) 30%, transparent); }
.tag--muted      { background: var(--grey-100, var(--muted)); color: var(--muted-foreground); border-color: var(--grey-200); }
.pcard__go       { margin-left: auto; position: relative; z-index: 1; font-size: var(--text-body-sm); font-weight: 600; color: var(--primary); text-decoration: none; }

/* Saved trainers rows (4 Oct): three actions wrap under the name on phones instead of pushing the card wide. */
@media (max-width: 639px) { .list-wrap .list-row { flex-wrap: wrap; } .list-wrap .list-row__actions { width: 100%; justify-content: flex-start; } }

/* First-login walkthrough (js/tour.js, HANDOFF 259). The spot sits on the target; its shadow dims the rest of
   the page. pointer-events none: the page stays usable underneath, nothing is trapped. The bubble sits under
   the target (above it when there is no room); on phones it is pinned to the bottom. */
.tour-spot       { position: fixed; z-index: 70; pointer-events: none; border: 2px solid var(--coral); border-radius: var(--radius-md); box-shadow: 0 0 0 9999px color-mix(in oklab, var(--navy-900) 55%, transparent); transition: top .2s, left .2s, width .2s, height .2s; }
.tour-bubble     { position: fixed; z-index: 71; width: min(26rem, calc(100vw - 2rem)); padding: 1rem 1.25rem; background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-modal); outline: none; }
.tour-bubble .eyebrow { color: var(--coral); }
.tour-bubble h2  { margin-top: 0.25rem; font-family: var(--font-sans); font-size: 1rem; font-weight: 700; letter-spacing: 0; }
.tour-bubble p   { margin-top: 0.375rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.tour-bubble .eyebrow { margin: 0; }
.tour-bubble__actions { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-top: 0.875rem; }
.tour-bubble__actions .row { gap: 0.75rem; }
@media (max-width: 639px) { .tour-bubble { top: auto !important; left: 1rem !important; right: 1rem; bottom: 1rem; width: auto; } }

/* ---------- Pre-launch home, 2 Nov 2026 redo (William's mockup, CP rulings) ---------- */
.problem p + p          { margin-top: 1rem; }
.problem .closer        { color: var(--foreground); font-weight: 600; }
.band__rule             { margin-top: 2rem; padding-top: 2rem; border-top: 1px solid color-mix(in oklab, #fff 14%, transparent); }

/* Profile preview: what a company sees. Static, not a link. */
.preview                { max-width: var(--w-2xl); margin-inline: auto; }
.preview__head          { display: flex; align-items: center; gap: 1rem; }
.preview__head h3       { font-size: var(--text-heading); line-height: 1.3; }
.preview__meta          { margin-top: 0.25rem; font-size: var(--text-body-sm); color: var(--muted-foreground); line-height: 1.5; }
.preview__label         { margin-top: 1.5rem; font-weight: 600; color: var(--foreground); }
.preview__prog          { margin-top: 0.75rem; padding: 1rem 1.25rem; border-radius: var(--radius-lg); border: 1px solid var(--border); }
.preview__prog strong   { display: block; font-weight: 600; }
.preview__prog span     { display: block; margin-top: 0.125rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.preview__verified      { margin-top: 1.5rem; display: flex; align-items: center; gap: 0.5rem; font-size: var(--text-body-sm); color: var(--muted-foreground); }
.preview__verified svg  { width: 1rem; height: 1rem; flex-shrink: 0; color: var(--success); }
.preview__note          { margin-top: 1rem; text-align: center; font-size: var(--text-body-sm); }
.band .preview p        { color: inherit; }                      /* the band's white-80 rule must not reach into the white card */
.band .preview__meta, .band .preview__prog span, .band .preview__verified { color: var(--muted-foreground); }

/* One offer card on the navy band (design guide 16 Oct: header strip, perks, bonus footer, CTA inside). */
.offer                  { max-width: var(--w-2xl); margin-inline: auto; text-align: left; overflow: hidden; border-radius: var(--radius-lg);
                          background: var(--primary); color: color-mix(in oklab, #fff 82%, transparent); }
.offer p                { color: inherit; }
.offer__head            { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.75rem 1.5rem;
                          background: color-mix(in oklab, #fff 6%, transparent); border-bottom: 1px solid color-mix(in oklab, #fff 14%, transparent);
                          font-size: var(--text-caption); font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: #fff; }
.offer__head svg        { width: 1.25rem; height: 1.25rem; flex-shrink: 0; color: var(--coral-300); }
.offer__body            { padding: 1.5rem; }
.offer__title           { font-family: var(--font-display); font-weight: 600; font-size: var(--text-display); line-height: 1.15; color: #fff; }
.offer__sub             { margin-top: 0.25rem; }
.offer__list            { list-style: none; margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid color-mix(in oklab, #fff 14%, transparent);
                          display: flex; flex-direction: column; gap: 1rem; }
.offer__list li         { display: flex; gap: 0.75rem; align-items: flex-start; }
.offer__list svg        { width: 1.25rem; height: 1.25rem; flex-shrink: 0; margin-top: 0.125rem; color: var(--coral-300); }
.offer__list strong     { display: block; color: #fff; font-weight: 600; }
.offer__list svg        { color: var(--coral-300); }
.offer__list p          { margin-top: 0.125rem; font-size: var(--text-body); }
.offer__note            { max-width: var(--w-2xl); margin: 1rem auto 0; font-size: var(--text-body-sm); color: var(--muted-foreground); }
