/* ==========================================================================
   seo-hub.css — the three hub pages only:
     /training-plans/                          trainingPlansIndex.mjs
     /training-plans/<sport>/                  sportHub.mjs
     /training-plans/<sport>/<distance>/       distanceHub.mjs

   Loaded AFTER tokens.css and seo.css. It extends, never redefines: every
   selector here is namespaced `hub-`, so nothing in this file can outrank or
   silently change a class the event template owns in seo.css. Shared
   primitives (.wrap .section .card .card-tint .card-dashed .chip .kicker
   .lede .prose .fine .data .btn .rule .hairline-list .ico) come from
   tokens.css and are used as-is.

   No colour is written as a literal — every value is a token, so the dark
   theme comes for free and the ramp stays the single source of truth.
   No box-shadows: elevation is a step on the ramp plus a hairline.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. BREADCRUMBS
   Mono, spaced, uppercase. This is the ONE place the site uses
   text-transform instead of typing caps at the call site: unlike a kicker,
   these are real navigation links, and the DOM text has to stay natural case
   for crawlers and for screen readers that spell out all-caps words.
   -------------------------------------------------------------------------- */

.hub-crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 8px;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 11px;
  line-height: 1.6;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.hub-crumbs li { display: flex; align-items: center; gap: 8px; }
.hub-crumbs li + li::before {
  content: "/";
  color: var(--text-faint);     /* a separator glyph, not content — decorative */
}
/* 44px hit area on a 11px line: the padding is invisible but the target is
   real, and it doubles as the gap between the trail and the h1. */
.hub-crumbs a,
.hub-crumbs [aria-current="page"] { display: inline-flex; align-items: center; min-height: 44px; }
.hub-crumbs a { color: var(--text-secondary); text-decoration: none; }
.hub-crumbs a:hover { color: var(--accent-strong); }
.hub-crumbs [aria-current="page"] { color: var(--text); }


/* --------------------------------------------------------------------------
   2. HERO — copy left, one card right. Stacks under the copy below 980px.
   -------------------------------------------------------------------------- */

/* The crumb trail's own 44px hit area supplies part of the top space, and the
   hero closes tighter than a standard .section so the rule under it does not
   float in the middle of nowhere. */
.hub-hero {
  padding-block-start: clamp(12px, 1.8vw, 24px);
  padding-block-end: clamp(40px, 5vw, 64px);
}

.hub-head {
  display: flex;
  gap: clamp(28px, 4vw, 56px);
  align-items: flex-start;
}
.hub-head-main { flex: 1 1 auto; min-width: 0; }
.hub-head h1 { max-width: 15ch; }
.hub-lede { margin-top: 20px; max-width: 60ch; }
.hub-custom { margin-top: 16px; max-width: 60ch; }
.hub-custom-line { margin-top: 10px; color: var(--text-secondary); }
.hub-custom-h { margin-top: 24px; font-size: var(--fs-h3, 1.25rem); }

.hub-aside { width: 300px; flex: none; }
.hub-aside .kicker { display: block; margin-bottom: 14px; }

@media (max-width: 980px) {
  .hub-head { flex-direction: column; gap: 32px; }
  .hub-aside { width: 100%; max-width: 480px; }
  .hub-head h1 { max-width: none; }
}

/* Disciplines list (sport hub) */
.hub-disciplines { display: flex; flex-direction: column; gap: 10px; font-size: 14.5px; }
.hub-disciplines li { display: flex; align-items: flex-start; gap: 11px; color: var(--text); }
.hub-disciplines .ico { margin-top: 3px; }

/* At-a-glance facts (distance hub) */
.hub-facts { font-size: 14.5px; }
.hub-facts li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.hub-fact-k { color: var(--text-secondary); }
.hub-fact-v { font-weight: 600; text-align: right; min-width: 0; overflow-wrap: anywhere; }

/* A value too long to sit beside its label takes the line below it, rather
   than squeezing the label until "Race months" breaks in half. Set per row by
   distanceHub.mjs, on the length of the value. */
.hub-facts li.is-stacked { flex-direction: column; align-items: flex-start; gap: 2px; }
.hub-facts li.is-stacked .hub-fact-v { text-align: left; }

/* CTA pair + the fine print underneath it */
.hub-cta-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.hub-cta-note { margin-top: 14px; }


/* --------------------------------------------------------------------------
   3. SECTION HEADS
   -------------------------------------------------------------------------- */

.hub-section-h { margin-top: 16px; font-size: var(--fs-h2); }

/* The derived sentence that reconciles a count with what is on screen. Sits
   under an h2, above the grid it is describing. */
.hub-section-note { margin-top: 14px; max-width: 68ch; font-size: 15px; }

.hub-grid-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  margin-bottom: 30px;
}
.hub-grid-head h2 { margin-top: 14px; font-size: clamp(30px, 2.9vw, 40px); }
.hub-grid-note { max-width: 330px; font-size: 14.5px; margin-bottom: 4px; }

@media (max-width: 860px) {
  .hub-grid-head { flex-direction: column; align-items: flex-start; gap: 16px; }
  .hub-grid-note { max-width: none; margin-bottom: 0; }
}


/* --------------------------------------------------------------------------
   4. DISTANCE CARDS
   -------------------------------------------------------------------------- */

.hub-distances,
.hub-sports {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 232px), 1fr));
}
.hub-distances-section .kicker { display: block; margin-bottom: 22px; }

.hub-distance h3 { font-size: 26px; }
.hub-distance-meta {
  margin-top: 6px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-copy);
}

.hub-sport { display: flex; flex-direction: column; gap: 14px; min-height: 124px; }
.hub-sport h3 { font-size: 21px; line-height: 1.1; }
.hub-sport-blurb { margin-top: 4px; font-size: 13.5px; color: var(--text-copy); }
.hub-sport-meta { margin-top: 10px; color: var(--text-secondary); }


/* --------------------------------------------------------------------------
   5. THE EVENT GRID
   Below the fold, below the pitch. Every chip is a link; the grid is an
   internal-linking device first and a browse UI second.
   -------------------------------------------------------------------------- */

.hub-group + .hub-group { margin-top: 30px; }
.hub-group-title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}

/* The count that makes the heading true at one race and at seventeen. It is
   content, not decoration — a reader uses it to check the list under it. */
.hub-group-count {
  color: var(--text-secondary);   /* content (a count), not decoration: --text-faint is 3.15:1 in light */
  font-size: 11px;
  letter-spacing: .08em;
}

/* A merged distance is a section of this page rather than a page of its own,
   so the group is a link target. Clear the sticky-free header and the rule. */
.hub-group[id] { scroll-margin-top: 24px; }

.hub-chips {
  display: grid;
  gap: 10px;
  /* min() keeps a single column at 360px instead of forcing an overflow. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 196px), 1fr));
}
.hub-chips-lg { grid-template-columns: repeat(auto-fill, minmax(min(100%, 262px), 1fr)); }

.hub-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;          /* touch target */
  padding: 11px 14px;
  border: 1px solid var(--divider);
  border-radius: var(--r-chip);
  background: transparent;
  color: var(--text);
  text-decoration: none;
  font-size: 14.5px;
  line-height: 1.3;
}
.hub-chip:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }
.hub-chip-lg { padding: 13px 15px; }

/* Static chips (sports with no hub page) must not look clickable. */
.hub-chip.is-static { border-style: dashed; color: var(--text-copy); cursor: default; }
.hub-chip.is-static:hover { border-color: var(--divider); background: transparent; }

.hub-chip-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.hub-chip-when { flex: none; color: var(--text-secondary); }
.hub-chip-chev { flex: none; color: var(--text-secondary); }
.hub-chip:hover .hub-chip-chev { color: var(--accent-strong); }


/* --------------------------------------------------------------------------
   5b. THE DISTANCE PROFILE (distance hub only)

   Derived notes, then the race table. The notes are a plain multi-column
   flow of short blocks; the table is the substantive part of the page and is
   the one place on the hubs where content can exceed the viewport width.
   -------------------------------------------------------------------------- */

.hub-notes {
  display: grid;
  gap: 26px 34px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}
.hub-note > .kicker { display: block; margin-bottom: 10px; }
.hub-note .prose { font-size: 15px; max-width: 46ch; }
.hub-note .prose + .prose { margin-top: 10px; }

/* The table can be wider than a phone. It scrolls INSIDE this box; the page
   body never scrolls sideways. tabindex + role make the scroll container
   reachable from the keyboard, which is the accessibility cost of doing it. */
.hub-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--divider);
  border-radius: var(--r-surface);
}

.hub-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14.5px;
  line-height: 1.35;
}
.hub-table th,
.hub-table td {
  text-align: left;
  padding: 13px 16px;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  white-space: nowrap;
}
.hub-table thead th {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-secondary);
  border-bottom-color: var(--divider);
  background: var(--surface);
}
.hub-table tbody tr:last-child th,
.hub-table tbody tr:last-child td { border-bottom: 0; }
.hub-table tbody th {
  font-weight: 600;
  white-space: normal;
  min-width: 200px;
}
.hub-table tbody th a { color: var(--text); text-decoration: none; }
.hub-table tbody th a:hover { color: var(--accent-strong); text-decoration: underline; }
.hub-table tbody tr:hover td,
.hub-table tbody tr:hover th { background: var(--accent-soft); }

.hub-t-sub {
  display: block;
  margin-top: 3px;
  font-weight: 400;
  font-size: 13px;
  color: var(--text-secondary);
}
/* An em dash for a figure we do not hold. Never a 0, never "flat". */
.hub-t-none { color: var(--text-secondary); }   /* content (a missing figure), not decoration */
.hub-table .is-num { text-align: right; font-variant-numeric: tabular-nums; }


/* --------------------------------------------------------------------------
   6. STRIPS + TAIL
   -------------------------------------------------------------------------- */

.hub-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px 20px;
  border: 1px solid var(--divider);
  border-radius: var(--r-surface);
  padding: 20px 24px;
}
.hub-strip > .kicker { flex: none; }
.hub-strip-list { display: flex; flex-wrap: wrap; gap: 10px; flex: 1 1 320px; min-width: 0; }
.hub-strip-list .hub-chip { min-width: 0; }

.hub-empty { max-width: 720px; }

/* Phase 19, Theme 5: the authored guide of a sport with no race library (hiking). Cards reuse .hub-distances / .hub-distance;
   the text sections are a single readable column. */
.hub-guide > .kicker { display: block; margin-bottom: 22px; }
.hub-guide-text { max-width: 720px; }
.hub-guide-item + .hub-guide-item { margin-top: 26px; }
.hub-guide-item h3 { font-size: 21px; line-height: 1.2; }
.hub-guide-item .prose { margin-top: 8px; }

/* Phase 19, Theme 5: the blog. The list is one card per post; the body is the owner's Markdown subset (h2, h3, p, ul, strong, a)
   in a single readable column. */
.blog-list { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); list-style: none; padding: 0; margin: 22px 0 0; }
.blog-card { display: block; height: 100%; text-decoration: none; color: inherit; }
.blog-card h3 { font-size: 24px; line-height: 1.15; }
.blog-meta { margin-top: 14px; }
.blog-body { max-width: 680px; margin-top: 28px; }
.blog-body h2 { margin-top: 36px; font-size: clamp(24px, 2.2vw, 30px); }
.blog-body h3 { margin-top: 28px; font-size: 21px; }
.blog-body p, .blog-body ul { margin-top: 14px; color: var(--text-copy); line-height: 1.65; }
.blog-body ul { padding-left: 1.25em; }
.blog-body li + li { margin-top: 6px; }
.blog-body a { color: var(--accent-strong); }

.hub-also-list {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
  margin-top: 14px;
}
.hub-also-note { margin-top: 16px; max-width: 720px; }

.hub-distance-groups > .hub-group + .hub-group { margin-top: 26px; }

.hub-tail { display: flex; flex-direction: column; gap: 24px; }
.hub-close {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  max-width: 620px;
}
.hub-close h2 { font-size: clamp(24px, 2.2vw, 28px); }
.hub-close .prose { font-size: 14.5px; }


/* --------------------------------------------------------------------------
   7. MOTION
   Two durations, both from tokens, both inside the reduced-motion guard.
   .hub-chip is an <a>, so tokens.css already transitions its colour, border
   and background; only the chevron needs adding.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .hub-chip-chev { transition: color var(--dur-state) var(--ease-out); }
}


/* --------------------------------------------------------------------------
   8. PRINT — the grid is the useful part; the CTAs are not.
   -------------------------------------------------------------------------- */

@media print {
  .hub-cta-row, .hub-cta-note, .hub-close { display: none; }
  .hub-chip { border-color: #767676; }
  /* Nothing scrolls on paper; let the table wrap instead of clipping. */
  .hub-table-wrap { overflow: visible; border-color: #767676; }
  .hub-table th, .hub-table td { white-space: normal; }
}
