/* ==========================================================================
   fitness-2026 — assets/css/main.css
   The theme's ONE enqueued stylesheet (functions.php::fitness_2026_assets(),
   cache-busted by FITNESS_2026_VERSION). style.css only carries the required
   WP theme-identity header (C1) — every rule lives here.

   Source of truth: docs/partnerships/fitness-ee/redesign-2026/variant-a.html
   ("Variant A — Kaasaegne ajakiri"). Design tokens (C2), fonts, and
   reset/base are transcribed 1:1 from the mock. The section-banner comments
   below mirror the mock's own map 1:1 (minus the demo-only sections — see
   note at the bottom) so later work packages (D/E/F/G/H) each have exactly
   one predictable place to add their component CSS. WP-C (this file's
   author) owns ONLY the fonts / :root tokens / reset+base blocks; every
   other banner below is an intentionally EMPTY placeholder.

   C9 (Zone.ee/ZoneOS): no native CSS nesting, no @import — this file and
   every file merged into it must survive WP-Optimize/ZoneOS minification.
   C5: every later `.entry-content` selector MUST be wrapped in :where()
   (specificity 0) so turg-embed inline styles + pipeline HTML always win —
   marker left at the bottom of the "article" section below.
   ========================================================================== */

/* ---------- fonts ---------- */
/* Self-hosted Red Hat Display 400/700/900, latin + latin-ext (C2, C9 — no
   CDN). Transcribed verbatim from variant-a.html:7-24, paths adjusted for
   this file's location (assets/css/ -> ../fonts/). */
@font-face { font-family:'Red Hat Display'; font-style:normal; font-weight:400; font-display:swap;
  src:url(../fonts/redhat-400-normal-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Red Hat Display'; font-style:normal; font-weight:400; font-display:swap;
  src:url(../fonts/redhat-400-normal-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Red Hat Display'; font-style:normal; font-weight:700; font-display:swap;
  src:url(../fonts/redhat-700-normal-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Red Hat Display'; font-style:normal; font-weight:700; font-display:swap;
  src:url(../fonts/redhat-700-normal-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Red Hat Display'; font-style:normal; font-weight:900; font-display:swap;
  src:url(../fonts/redhat-900-normal-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Red Hat Display'; font-style:normal; font-weight:900; font-display:swap;
  src:url(../fonts/redhat-900-normal-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* Metric-adjusted local fallback (WP-C step 2 — keeps font-swap CLS < 0.02).
   Values computed from the ACTUAL Red Hat Display OS/2 + hhea tables
   (unitsPerEm 1000, ascent 1018, descent -305, lineGap 0, xAvgCharWidth 539
   — read directly from redhat-{400,700,900}-normal-latin.woff2 with
   fontTools; identical across weights) against Arial's published OS/2
   metrics (unitsPerEm 2048, ascent 1854, descent -434, lineGap 67,
   xAvgCharWidth 904), using the standard Fontaine/next-font formula:
     size-adjust      = (webXAvg/webUPM) / (fallbackXAvg/fallbackUPM)
     ascent-override   = (webAscent/webUPM)  / size-adjust
     descent-override  = (webDescent/webUPM) / size-adjust
     line-gap-override = (webLineGap/webUPM) / size-adjust
   This makes the LOCAL fallback occupy the same line-box + average glyph
   width as Red Hat Display, so the FOUT swap doesn't reflow the page. */
@font-face {
  font-family:'Red Hat Display Fallback';
  src:local('Arial'), local('Helvetica'), local('Liberation Sans'), local('Arimo');
  ascent-override:83.37%;
  descent-override:24.98%;
  line-gap-override:0%;
  size-adjust:122.11%;
}

/* ---------- tokens ---------- */
/* Transcribed 1:1 from variant-a.html:25-31 (C2). --font gains the metric-
   adjusted fallback family (above) inserted right after the webfont — the
   mock has no local-fallback story since it's a static demo page. */
:root {
  --blue:#005DB9; --blue-deep:#174b80; --red:#E02020; --gold:#f0b32e;
  --ink:#131a22; --muted:#5b6572; --paper:#ffffff; --mist:#f2f5f9; --line:#dfe5ec;
  --navy:#0c1f3a; --navy-2:#12325c;
  --radius:14px; --shadow:0 1px 2px rgba(19,26,34,.05),0 8px 28px rgba(19,26,34,.08);
  --font:'Red Hat Display','Red Hat Display Fallback',system-ui,-apple-system,'Segoe UI',sans-serif;
}

/* color-scheme: light — dark mode is out of scope v1 (00-implementation-overview.md). */
:root { color-scheme: light; }

/* ---------- reset / base ---------- */
/* Transcribed 1:1 from variant-a.html:32-41. */
* { box-sizing:border-box; margin:0; padding:0; }
html { scroll-behavior:smooth; }
body { font-family:var(--font); background:var(--paper); color:var(--ink); font-size:17px; line-height:1.65; -webkit-font-smoothing:antialiased; }
img { max-width:100%; display:block; }
/* Editorial thumbnails crop from the UPPER third, not the centre.
   Every card/rail/hero slot below fills a fixed aspect box with
   `object-fit:cover`; the CSS default anchor is `50% 50%`, which beheads any
   source taller than its slot. That is not an edge case here — 32% of the
   archive's featured images are portrait or square (measured over 600 posts:
   192 under 1.25 aspect, only 37 at 16:9 or wider), a legacy of the pre-2026
   site, whose theme never cropped at all. A 2:3 portrait in the 3:2 hero loses
   56% of its height dead-centre, i.e. exactly the face.
   20% (not 0/top) is deliberate: sampled against 10 real portrait heroes it
   recovered the head in every people-photo, while `top` started clipping
   bottom-anchored subjects (a shoes-and-laces shot). Scoped to editorial
   photography ONLY — `.mural` and every `.ad-banner__img` are artwork composed
   for their exact slot and must stay centred. */
.feature .ph img,
.side-item img,
.card img,
.rcard img,
.sponsored-item img { object-position:50% 20%; }
a { color:var(--blue); text-decoration:none; }
a:hover { text-decoration:underline; }
:focus-visible { outline:3px solid var(--blue); outline-offset:2px; border-radius:4px; }
button { font-family:inherit; cursor:pointer; }
.wrap { max-width:1160px; margin:0 auto; padding:0 20px; }
.wrap .wrap { max-width:none; padding:0; } /* partials that carry their own .wrap section (coach/turg strips) stay reusable inside a .wrap main (search.php) without double side-padding */
.eyebrow { font-size:12px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; }

/* Accessibility base — transcribed from variant-a.html's standalone
   prefers-reduced-motion rule (sits just above its "responsive" banner in
   the mock; grouped here with reset/base since it applies globally, not to
   one component). */
@media (prefers-reduced-motion:reduce) {
  *, *::before, *::after { animation:none!important; transition:none!important; }
  html { scroll-behavior:auto; }
}

/* ==========================================================================
   Section map (mirrors variant-a.html's own comment-banner structure 1:1 —
   the file's map for every later WP). Each banner below is an EMPTY
   placeholder; WP-C does not style any component. Two mock sections are
   deliberately NOT mapped here:
     - "coach bubble" (.coach-fab) — NOT theme-owned in v1 (implementation
       overview, "Coach bubble" decision row); no placeholder needed.
     - "demo toolbar" (.demo-bar) — the mock's own dev-only view-switcher
       UI, never ported to any WP (03-wp-C-scaffold.md gotchas).
   ========================================================================== */

/* ---------- header ---------- */
/* Transcribed from variant-a.html:43-67 (header + mobile sheet), tokens
   only, C9-clean (no nesting, no @import, no inline styles). WP-D
   (04-wp-D-chrome.md). Two additions beyond the mock, both documented in
   the doc's operator notes: the top-notice bar (C8 `widget-area_topnotice`,
   audit.md §4) and the .no-js/.burger-fallback no-JS mobile-menu fallback. */

/* WP-D addition, not in the mock (the mock is a static demo with no a11y
   skip link). `.screen-reader-text` is also reused by the newsletter-form
   <label> (footer.php) and the topnotice widget-title span (functions.php)
   — those never carry `.skip-link` so they stay hidden even on focus; only
   the skip link (header.php's first element) becomes visible here. */
.screen-reader-text { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0,0,0,0); clip-path:inset(50%); border:0; white-space:nowrap; }
.skip-link.screen-reader-text:focus { position:fixed; top:10px; left:10px; z-index:100000; width:auto; height:auto; margin:0; padding:10px 18px; overflow:visible; clip:auto; clip-path:none; white-space:normal; background:var(--paper); color:var(--ink); font-weight:700; font-size:14px; border-radius:var(--radius); box-shadow:var(--shadow); }

/* top notice — NOT in the mock. header.php only prints the wrapper when
   the sidebar has real content (fitness_2026_render_sidebar()), so today's
   known-empty `block-7` widget (audit.md §4) renders nothing — no blank
   bar/gap above the header. */
.top-notice { background:var(--navy); color:#dce6f2; font-size:13px; line-height:1.5; text-align:center; }
.top-notice .wrap { padding:7px 20px; }
.top-notice a { color:#fff; font-weight:700; }
.top-notice p { margin:0; }

.hdr { position:sticky; top:0; z-index:50; background:var(--paper); border-bottom:1px solid var(--line); }
/* Solid fallback above (older Safari / no backdrop-filter support) — MUST
   stay before the @supports enhancement below (04-wp-D-chrome.md gotchas). */
@supports ( (backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px)) ) {
  .hdr { background:rgba(255,255,255,.94); -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px); }
}
.hdr::before { content:""; display:block; height:3px; background:linear-gradient(90deg,var(--blue) 0 70%,var(--red) 70% 85%,var(--gold) 85% 100%); }
.hdr-in { display:flex; align-items:center; gap:26px; height:62px; }
.hdr-logo { display:inline-flex; align-items:center; }
.hdr-logo img { height:34px; width:auto; }
.hdr-nav { display:flex; align-items:center; gap:2px; flex:1; min-width:0; }
.hdr-nav a { color:var(--ink); font-size:13.5px; font-weight:700; padding:8px 11px; border-radius:8px; white-space:nowrap; }
.hdr-nav a:hover { background:var(--mist); text-decoration:none; }
.hdr-nav a[aria-current], .hdr-nav a.is-current { color:var(--blue); box-shadow:inset 0 -3px 0 var(--blue); border-radius:8px 8px 0 0; }
.hdr-nav .nav-turg { color:#fff; background:var(--blue); margin-left:6px; }
.hdr-nav .nav-turg:hover { background:var(--blue-deep); }
.hdr-nav .nav-ai { color:var(--navy); background:linear-gradient(100deg,#fdf6e3,#faeccb); border:1px solid #f1dda5; }
/* Mock parity: the mock's AI-treener label is "✦ AI-treener" (variant-a.html:364,391).
   The glyph is presentation, so it lives HERE, not in the shared wp-admin menu title —
   turg's header-sync mirrors that menu and must never inherit a decorative glyph. */
.hdr-nav .nav-ai::before, .sheet-panel .nav-ai::before { content:"✦ "; }
/* Honor the legacy menu's UIkit hide utility: the live menu-9 "Main" carries
   `uk-hidden` on the Yanku.eu item (audit menu, verified on the WP-B replica).
   The legacy theme hid it via UIkit; the new (non-UIkit) theme must reproduce
   that intent or a deliberately-hidden item reappears at cutover. Scoped to
   the nav so it can't hide content elsewhere. Applies to the mobile sheet too
   via the same class. (Turg's header-sync already skips uk-hidden items.) */
.hdr-nav .uk-hidden, .sheet-panel .uk-hidden { display:none; }
.hdr-actions { display:flex; align-items:center; gap:8px; margin-left:auto; }
.icon-btn { display:grid; place-items:center; width:38px; height:38px; border:1px solid var(--line); background:var(--paper); border-radius:10px; color:var(--ink); }
.icon-btn:hover { background:var(--mist); text-decoration:none; }

/* Inline header search dropdown (UAT 2026-07-16 round 2 — the magnifier opens
   this with the input focused; main.js). Anchored under the header's right
   edge; [hidden] keeps it out of the no-JS flow entirely. */
.hdr-in { position:relative; }
.hdr-search { position:absolute; right:0; top:calc(100% + 8px); z-index:60; display:flex; gap:8px; background:var(--paper); border:1px solid var(--line); border-radius:12px; padding:10px; box-shadow:0 10px 34px rgba(12,31,58,.16); width:min(380px, calc(100vw - 40px)); }
.hdr-search[hidden] { display:none; }
.hdr-search .search-field { flex:1; min-width:0; padding:9px 12px; border:1px solid var(--line); border-radius:8px; font:inherit; color:var(--ink); background:var(--mist); }
.hdr-search .search-submit { border:0; border-radius:8px; background:var(--blue); color:#fff; font-weight:700; font-size:14px; padding:9px 16px; cursor:pointer; }
.hdr-search .search-submit:hover { background:var(--blue-deep); }

/* Typeahead suggestion panel (main.js appends .search-suggest into any form
   carrying data-suggest — the header dropdown AND the /?s= landing form).
   Absolutely positioned under the form so opening it never shifts layout. */
.search-suggest { position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:61; background:var(--paper); border:1px solid var(--line); border-radius:12px; box-shadow:0 10px 34px rgba(12,31,58,.16); overflow:hidden; }
.search-suggest[hidden] { display:none; }
.suggest-item { display:block; padding:10px 14px; font-size:14px; line-height:1.4; color:var(--ink); border-bottom:1px solid var(--mist); }
.suggest-item:last-child { border-bottom:0; }
.suggest-item:hover, .suggest-item.is-active { background:var(--mist); color:var(--blue); text-decoration:none; }
.suggest-turg { font-weight:700; color:var(--blue); }
.suggest-all { font-weight:700; }
.burger { display:none; }
.burger-fallback { display:none; } /* WP-D addition, not in the mock — see the .no-js rules below */

@media (max-width:1020px) {
  .hdr-nav { display:none; }
  .burger { display:grid; }
  /* Lighter chrome: on the burger layout the search + menu icons drop their
     bordered/filled box (that chunky-card look read as "big & ugly") and become
     borderless icons — the modern news-app pattern (cf. delfi.ee). The 44px
     touch target is KEPT (transparent hit area); only the visual weight goes.
     A tinted round press-state gives feedback. */
  .icon-btn { width:44px; height:44px; border-color:transparent; background:transparent; border-radius:50%; color:var(--ink); }
  .icon-btn:hover, .icon-btn:focus-visible { background:var(--mist); }
  /* With the nav gone the bar carries only logo + 2 light icons, so it can be
     much shorter than the desktop 62px — reclaim that space (the header is
     sticky, so every px is paid on every scroll). */
  .hdr-in { height:52px; gap:12px; }
  .hdr-logo img { height:29px; }
}

/* no-JS / JS swap (WP-D addition, not in the mock). assets/js/main.js flips
   <html> from .no-js to .js as its first statement. Under .no-js the
   burger toggle is inert (no JS to open the sheet), so it's hidden and a
   real jump link to the footer's "Sisu" content-links column is shown
   instead — 04-wp-D-chrome.md step 2. */
.no-js .burger { display:none; }
.no-js .burger-fallback { display:grid; }

/* mobile sheet (variant-a.html:378-398) */
.sheet { display:none; }
.sheet.open { display:block; position:fixed; inset:0; z-index:60; }
.sheet-bg { position:absolute; inset:0; background:rgba(12,20,30,.45); }
.sheet-panel { position:absolute; top:0; right:0; bottom:0; width:min(340px,88vw); background:var(--paper); padding:22px; overflow:auto; box-shadow:-12px 0 40px rgba(0,0,0,.18); }
.sheet-panel h3 { font-size:12px; letter-spacing:.09em; text-transform:uppercase; color:var(--muted); margin:18px 0 6px; }
.sheet-panel a { display:block; padding:10px 8px; font-weight:700; color:var(--ink); border-radius:8px; }
.sheet-panel a:hover { background:var(--mist); text-decoration:none; }
/* Same walker as .hdr-nav → same current-page signals (aria-current exact,
   .is-current section) so the drawer also shows where you are. */
.sheet-panel a[aria-current], .sheet-panel a.is-current { color:var(--blue); background:var(--mist); }
.sheet-close { float:right; border:0; background:var(--mist); width:44px; height:44px; border-radius:50%; font-size:17px; } /* 44px touch target (mobile-2026) */

/* ---------- masthead / graffiti ---------- */
/* WP-E (home). Transcribed from variant-a.html:70-77. The masthead partial
   ships from WP-D (template-parts/masthead.php); these are its rules. */
.masthead { padding:18px 0 6px; }
.mural { position:relative; border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); }
.mural img { display:block; width:100%; aspect-ratio:1200/172; object-fit:cover; height:auto; }
/* Caption + credit OVERLAY the mural bottom on a dark scrim (a plain
   half-opacity would be illegible on the bright graffiti) — so the tagline and
   @simkares credit claim zero vertical height of their own; the masthead is
   just the image band. Clipped to the rounded box by .mural's overflow:hidden. */
.mural-row { position:absolute; left:0; right:0; bottom:0; display:flex; align-items:baseline; justify-content:space-between; gap:4px 14px; padding:30px 16px 10px; background:linear-gradient(to top, rgba(9,17,29,.82), rgba(9,17,29,.28) 62%, transparent); flex-wrap:wrap; }
.mural-tag { font-size:12.5px; color:rgba(255,255,255,.94); font-weight:600; text-shadow:0 1px 2px rgba(0,0,0,.55); }
.credit-chip { font-size:11.5px; font-weight:500; color:rgba(255,255,255,.82); text-shadow:0 1px 2px rgba(0,0,0,.55); }
.credit-chip a { color:#fff; font-weight:700; }
.credit-chip a:hover { color:#fff; text-decoration:underline; }

/* ---------- hero ---------- */
/* WP-E (home). Transcribed from variant-a.html:80-98. The mock made the whole
   .feature/.side-item clickable via onclick; the theme links the image + the
   heading instead (one strong anchor set, crawlable), so cursor:pointer is
   dropped and heading links inherit ink (base a{color:blue} reset below). */
.hero { padding:26px 0 8px; }
.chip { display:inline-block; font-size:11.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--blue); background:#e8f1fb; border-radius:6px; padding:3px 9px; }
.hero-grid { display:grid; grid-template-columns:7fr 5fr; gap:28px; }
.feature .ph { display:block; border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); }
.feature .ph img { aspect-ratio:16/9; object-fit:cover; width:100%; transition:transform .5s ease; height:auto; }
.feature:hover .ph img { transform:scale(1.02); }
.feature h2 { font-size:clamp(26px,3.2vw,38px); font-weight:900; line-height:1.12; letter-spacing:-.015em; margin:16px 0 10px; text-wrap:balance; }
.feature h2 a { color:inherit; text-decoration:none; }
.feature:hover h2 a { color:var(--blue); }
.feature p { color:var(--muted); max-width:56ch; }
.meta { display:flex; align-items:center; gap:10px; font-size:13px; color:var(--muted); margin-top:12px; flex-wrap:wrap; }
.meta b { color:var(--ink); font-weight:700; }
.meta .sep::before { content:"\00B7"; }
.side-list { display:flex; flex-direction:column; }
.side-item { display:grid; grid-template-columns:110px 1fr; gap:14px; padding:14px 0; border-top:1px solid var(--line); align-items:center; }
.side-item:first-child { border-top:0; padding-top:2px; }
.side-item img { border-radius:10px; aspect-ratio:4/3; object-fit:cover; height:auto; }
.side-item h3 { font-size:16.5px; font-weight:700; line-height:1.3; }
.side-item h3 a { color:inherit; text-decoration:none; }
.side-item:hover h3 a { color:var(--blue); }
.side-item .meta { margin-top:6px; }

/* ---------- sections ---------- */
/* WP-E (home) / WP-G (secondary templates). Transcribed from variant-a.html:
   101-117 (.sect/.cards/.card) + 250-262 (.turg-box strip). `.sect-head--tight`
   replaces the mock's inline `style="margin-bottom:…"` (C9 — no inline styles).
   Card heading links inherit ink; the .card also styles index.php's fallback
   cards for free. */
.sect { padding:34px 0 6px; }
.sect-head { display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-bottom:18px; }
.sect-head--tight { margin-bottom:8px; }
.sect-head h2 { font-size:24px; font-weight:900; letter-spacing:-.01em; }
.sect-head a { font-size:13.5px; font-weight:700; }
.cards { display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }
/* `.cards.cards-4` (0-2-0), NOT `.cards-4` (0-1-0): `.cards` is re-declared in
   later sections of this file (WP-E/G) with repeat(3,1fr), which — same
   specificity, later wins — clobbered a bare `.cards-4` back to 3 cols and
   wrapped the 4th "Värsked artiklid" card. The compound selector wins over any
   single-class `.cards` rule regardless of order. The responsive overrides
   below are compounded to match so the breakpoint cascade stays consistent. */
.cards.cards-4 { grid-template-columns:repeat(4,1fr); gap:18px; }
.card { background:#fff; border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; transition:box-shadow .25s ease, transform .25s ease; }
.card:hover { box-shadow:var(--shadow); transform:translateY(-2px); }
.card .card-media { display:block; }
.card img { aspect-ratio:16/10; object-fit:cover; width:100%; height:auto; }
.card-body { padding:16px 18px 18px; }
.card h2, .card h3 { font-size:18px; font-weight:700; line-height:1.3; margin:9px 0 7px; }
.card h2 a, .card h3 a { color:inherit; text-decoration:none; }
.card:hover h2 a, .card:hover h3 a { color:var(--blue); }
.card p { font-size:14.5px; color:var(--muted); }
.card .meta { margin-top:10px; }
.cards-4 .card img { height:150px; aspect-ratio:auto; }
.cards-4 .card-body { padding:13px 15px 15px; }
.cards-4 .card h2, .cards-4 .card h3 { font-size:15.5px; margin:8px 0 0; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.cards-4 .card .meta { margin-top:8px; font-size:12px; }

/* turg product strip ("Populaarne Turul", variant-a.html:250-262). The whole
   .pcard is one anchor (crawlable, one link per product); the mock's inner
   `a.buy` becomes a visual `.buy` span. */
.turg-box { border:1px solid var(--line); border-radius:16px; padding:22px; margin:30px 0; background:linear-gradient(180deg,#fbfcfe,#f4f7fb); }
.turg-head { display:flex; justify-content:space-between; align-items:baseline; gap:14px; margin-bottom:16px; }
.turg-head h2 { font-size:19px; font-weight:900; }
.turg-head a { font-size:13px; font-weight:700; }
.turg-track { display:grid; grid-auto-flow:column; grid-auto-columns:200px; gap:14px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:6px; scrollbar-width:thin; }
.pcard { background:#fff; border:1px solid var(--line); border-radius:12px; padding:12px; display:flex; flex-direction:column; gap:8px; color:var(--ink); text-decoration:none; }
.pcard:hover { text-decoration:none; box-shadow:var(--shadow); }
.pcard img { height:120px; object-fit:contain; margin:0 auto; }
.pcard .brand { font-size:10.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); }
.pcard .nm { font-size:13px; font-weight:700; line-height:1.3; min-height:51px; }
.pcard .pr { font-size:15px; font-weight:900; }
.pcard .buy { margin-top:auto; text-align:center; font-size:12.5px; font-weight:700; color:#fff; background:var(--blue); border-radius:8px; padding:8px 10px; }
.pcard:hover .buy { background:var(--blue-deep); }
.pcard-more { display:flex; flex-direction:column; justify-content:center; gap:6px; background:var(--navy); border:1px solid var(--navy); border-radius:12px; padding:14px; color:#eef3fa; text-decoration:none; }
.pcard-more:hover { text-decoration:none; filter:brightness(1.12); }
.pcard-more b { font-size:15px; }
.pcard-more span { font-size:12px; color:#b9c6d8; }
.pcard-more .go { color:var(--gold); font-weight:900; font-size:13px; margin-top:4px; }

/* secondary templates (WP-G) — archive.php / search.php / 404.php /
   page.php (07-wp-G-secondary.md). Per this WP's explicit CSS scope: every
   rule WP-G needs lives in THIS "sections" sub-banner only — including the
   4 ported calculator/training-plan page templates' minimal wrapper
   styling further down (scoped to #calculator-page so the "tools" banner
   above stays untouched, even though its own placeholder comment
   anticipated WP-G landing there instead).

   .cards / .cards-list / .card / .card-body are transcribed verbatim from
   variant-a.html:105-117 — that's the mock's OWN "sections" banner, so this
   mirrors the mock 1:1. They are SHARED infrastructure: WP-C's index.php
   fallback already emits this exact markup unstyled, and WP-E's home rails
   are expected to reuse the same classes for its own card grids — first
   WP to land the rules owns them; a later WP should extend, not duplicate.
   template-parts/card.php (WP-E, not yet landed as of this commit) owns the
   markup INSIDE .card/.card-body; archive.php/search.php/404.php only own
   the grid container + the empty-state/pagination/search-form chrome
   around it. */
.page-header { padding:34px 0 22px; }
.page-header .page-title { font-size:28px; font-weight:900; letter-spacing:-.01em; line-height:1.25; }
.page-header .page-title span { color:var(--blue); }
.page-header .archive-description { margin-top:10px; color:var(--muted); font-size:15.5px; line-height:1.6; }

.cards { display:grid; grid-template-columns:repeat(3,1fr); gap:22px; margin:22px 0 34px; }
.cards.cards-list { grid-template-columns:1fr; gap:14px; max-width:760px; }
.card { background:#fff; border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; transition:box-shadow .25s ease, transform .25s ease; }
.card:hover { box-shadow:var(--shadow); transform:translateY(-2px); }
.card img { aspect-ratio:16/10; object-fit:cover; width:100%; height:auto; }
.card-body { padding:16px 18px 18px; }
.card h2, .card h3 { font-size:18px; font-weight:700; line-height:1.3; margin:9px 0 7px; }
.card p, .card .entry-summary { font-size:14.5px; color:var(--muted); }
.card .meta { margin-top:10px; font-size:13px; color:var(--muted); }

.empty-state { padding:12px 0 40px; color:var(--muted); font-size:15.5px; }

.search-form-page { display:flex; gap:8px; margin:18px 0 8px; max-width:480px; position:relative; } /* position anchors the .search-suggest typeahead panel */
.search-turg { margin:6px 0 26px; } /* the search page's "Turult" upsell strip */
.search-form-page .search-field { flex:1; padding:10px 14px; border:1px solid var(--line); border-radius:var(--radius); font:inherit; color:var(--ink); }
.search-form-page .search-submit { padding:10px 18px; border:0; border-radius:var(--radius); background:var(--blue); color:#fff; font-weight:700; }
.search-form-page .search-submit:hover { background:var(--blue-deep); }

/* the_posts_pagination() output (archive.php/search.php) — Google walks
   .nav-links, so it must be real markup, not JS-only. */
.nav-links { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:10px; margin:24px 0 40px; font-size:14px; }
.nav-links .page-numbers { padding:8px 14px; border:1px solid var(--line); border-radius:10px; color:var(--ink); font-weight:700; }
.nav-links a.page-numbers:hover { background:var(--mist); text-decoration:none; }
.nav-links .page-numbers.current { background:var(--blue); color:#fff; border-color:var(--blue); }
.nav-links .page-numbers.dots { border-color:transparent; }

/* 404 recent-articles heading (404.php). Deliberately NOT named .sect-head
   — that class belongs to the mock's flex div-wrapper shape
   (div.sect-head > h2 + a, variant-a.html:100-102), which this bare <h2>
   doesn't match; WP-E's home page is expected to own the real .sect-head
   wrapper for its rail headings. */
.related-heading { font-size:20px; font-weight:900; letter-spacing:-.01em; margin:6px 0 14px; }

/* generic page (page.php) — the article thumbnail + wp_link_pages() output;
   the prose itself is entirely WP-H's .entry-content contract (main.css
   "article" banner below), this only positions the two elements around it. */
.page-article .page-thumbnail { margin:18px 0 26px; }
.page-article .page-thumbnail img { width:100%; border-radius:var(--radius); }
.page-article .page-links { margin:26px 0; font-size:14px; font-weight:700; }

/* 4 ported legacy calculator/training-plan page templates
   (template-repmax.php, template-bav.php, template-calculator.php,
   template-trainingplans.php — 07-wp-G-secondary.md step 5). These pages
   load the vendored legacy UIkit 3.5.13 stylesheet in full
   (assets/legacy/css/uikit.min.css, enqueued only on these 4 templates by
   functions.php::fitness_2026_calculator_assets()) for their own
   forms/tabs/accordion/spinner styling — porting that framework wholesale
   is a functional necessity (uk-tab/uk-switcher/uk-accordion are JS-driven
   UIkit components, not just decoration), not a restyle. This is the ONLY
   integration layer WP-G adds on top of it, so these 4 pages sit inside
   the new chrome (header.php/footer.php) without looking like a jump cut.
   Full re-theming to the Variant A token system is an explicit post-1.0
   task (functional survival > visual purity at cutover). */
#calculator-page { padding:34px 0 60px; font-family:var(--font); color:var(--ink); }
#calculator-page > .uk-container { max-width:1160px; margin:0 auto; padding:0 20px; }
#calculator-page h1 { font-size:26px; font-weight:900; letter-spacing:-.01em; margin-bottom:16px; }

/* ---------- tools ---------- */
/* WP-E (home) / WP-G (calculator tool templates). Transcribed from
   variant-a.html:120-126. `.tools-lede` replaces the mock's inline
   `style="color:…"` paragraph (C9). */
.tools-band { background:var(--mist); border-radius:18px; padding:28px; margin:38px 0 8px; }
.tools-lede { color:var(--muted); font-size:14.5px; }
.tools-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:16px; margin-top:18px; }
.tool { display:flex; gap:13px; align-items:flex-start; background:#fff; border:1px solid var(--line); border-radius:12px; padding:16px; color:var(--ink); }
.tool:hover { text-decoration:none; border-color:var(--blue); box-shadow:var(--shadow); }
.tool-ic { flex:0 0 38px; height:38px; border-radius:10px; background:#e8f1fb; color:var(--blue); display:grid; place-items:center; font-weight:900; font-size:15px; }
.tool-txt b { display:block; font-size:15px; line-height:1.25; }
.tool-txt span { font-size:12.5px; color:var(--muted); }

/* ---------- interests: topic chips + rails ---------- */
/* WP-E (home). Transcribed from variant-a.html:129-169 (+ the railflash
   keyframe :136 and the hover-arrow rule :149). The chip +/✓ mark is CSS-driven
   off aria-pressed (home.js only flips the attribute — no text slicing). */
.topics { display:flex; flex-wrap:wrap; gap:8px; margin:6px 0 8px; }
.topics-hint { font-size:13px; color:var(--muted); margin:2px 0 0; }
.topic-chip { display:inline-flex; align-items:center; gap:6px; font-size:13px; font-weight:700; border:1px solid var(--line); background:#fff; color:var(--ink); border-radius:999px; padding:8px 15px; cursor:pointer; }
.topic-chip:hover { border-color:var(--blue); color:var(--blue); text-decoration:none; }
.topic-chip[aria-pressed="true"] { background:var(--blue); border-color:var(--blue); color:#fff; }
.topic-chip__mark::before { content:"+"; font-weight:900; }
.topic-chip[aria-pressed="true"] .topic-chip__mark::before { content:"\2713"; }
.rail-sect { padding:22px 0 2px; position:relative; border-radius:14px; }
.rail-sect.flash { animation:railflash 1.2s ease; }
@keyframes railflash { 0% { background:#e8f1fb; box-shadow:0 0 0 8px #e8f1fb; } 100% { background:transparent; box-shadow:0 0 0 8px transparent; } }
.rail-head { display:flex; align-items:center; gap:12px; margin-bottom:12px; }
.rail-head h3 { font-size:19px; font-weight:900; letter-spacing:-.01em; }
.rail-head .count { font-size:12.5px; color:var(--muted); }
.rail-state { margin-left:auto; font-size:11.5px; font-weight:700; letter-spacing:.04em; border-radius:999px; padding:4px 12px; }
.rail-sect[data-followed="true"] .rail-state { background:#e8f6ec; color:#1d7a3f; }
.rail-sect[data-followed="true"] .rail-state::before { content:"\2713 J\00E4lgid"; }
.rail-sect[data-followed="false"] .rail-state { background:var(--mist); color:var(--muted); }
.rail-sect[data-followed="false"] .rail-state::before { content:"Avasta"; }
.rail-arrow { position:absolute; top:55%; z-index:5; width:38px; height:38px; border-radius:50%; border:1px solid var(--line); background:rgba(255,255,255,.95); color:var(--ink); font-size:17px; box-shadow:var(--shadow); display:none; }
.rail-arrow:hover { color:var(--blue); border-color:var(--blue); }
.rail-arrow.prev { left:-14px; }
.rail-arrow.next { right:-14px; }
@media (hover:hover) { .rail-sect:hover .rail-arrow { display:grid; place-items:center; } }
.rail-track { display:grid; grid-auto-flow:column; grid-auto-columns:216px; gap:14px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding:4px 2px 10px; scroll-snap-type:x proximity; scrollbar-width:thin; }
.rcard { scroll-snap-align:start; background:#fff; border:1px solid var(--line); border-radius:12px; overflow:hidden; transition:box-shadow .2s ease, transform .2s ease; }
.rcard:hover { box-shadow:var(--shadow); transform:translateY(-2px); }
.rcard img { width:100%; aspect-ratio:16/10; object-fit:cover; height:auto; }
.rcard-body { padding:11px 13px 13px; }
.rcard h4 { font-size:14px; font-weight:700; line-height:1.3; }
.rcard h4 a { color:inherit; text-decoration:none; }
.rcard:hover h4 a { color:var(--blue); }
.rcard .meta { margin-top:7px; font-size:11.5px; }
.rcard-cta { scroll-snap-align:start; display:flex; flex-direction:column; justify-content:center; gap:8px; background:radial-gradient(120% 160% at 85% 0%,#1d4471 0%,var(--navy-2) 45%,var(--navy) 100%); border:0; border-radius:12px; padding:18px; color:#eef3fa; text-decoration:none; }
.rcard-cta:hover { text-decoration:none; filter:brightness(1.1); }
.rcard-cta .eyebrow { color:var(--gold); }
.rcard-cta b { font-size:16px; line-height:1.3; }
.rcard-cta span.d { font-size:12.5px; color:#b9c6d8; }
.rcard-cta .go { font-weight:900; font-size:13px; color:#fff; margin-top:4px; }

/* ---------- bottom feed (load-more) ---------- */
/* WP-E (home) — C12 crawlable /page/N/ + JS fragment enhancement. Transcribed
   from variant-a.html:172-181. `.load-more` ships hidden and home.js reveals it
   (hiding `.feed-pagination`); if JS never runs, the crawlable pagination nav is
   the fallback. Feed rows are single anchors (mock `.feedrow` was a div). */
.feedlist { border-top:1px solid var(--line); }
.feedrow { display:flex; align-items:baseline; gap:14px; padding:14px 4px; border-bottom:1px solid var(--line); }
.feedrow .chip { flex:0 0 auto; }
.feedrow h3 { font-size:16px; font-weight:700; line-height:1.35; color:var(--ink); }
.feedrow:hover { text-decoration:none; } /* block anchor (mock's .feedrow was a div): the global a:hover underline would streak chip+title+date — the blue title IS the hover signal (UAT 2026-07-16) */
.feedrow:hover h3 { color:var(--blue); }
.feedrow .when { margin-left:auto; flex:0 0 auto; font-size:12.5px; color:var(--muted); white-space:nowrap; }
.load-more { display:block; margin:20px auto 0; border:1.5px solid var(--line); background:#fff; color:var(--ink); font-weight:700; font-size:14px; border-radius:999px; padding:11px 26px; }
.load-more:hover { border-color:var(--blue); color:var(--blue); }
.load-more[disabled] { opacity:.55; cursor:default; }
.load-more[hidden] { display:none; }
.feed-pagination { margin:22px 0 6px; }
.feed-pagination[hidden] { display:none; }
.feed-pagination .nav-links { display:flex; flex-wrap:wrap; gap:8px; justify-content:center; align-items:center; }
.feed-pagination .page-numbers { display:inline-flex; align-items:center; justify-content:center; min-width:38px; height:38px; padding:0 10px; border:1px solid var(--line); border-radius:10px; font-size:14px; font-weight:700; color:var(--ink); }
.feed-pagination a.page-numbers:hover { border-color:var(--blue); color:var(--blue); text-decoration:none; }
.feed-pagination .page-numbers.current { background:var(--blue); border-color:var(--blue); color:#fff; }
.feed-pagination .page-numbers.dots { border-color:transparent; }

/* ---------- ad slots ---------- */
/* WP-E (home) / WP-F (article) — C11 banner render contract. Slot chrome
   (.ad-slot/.ad-lbl) from variant-a.html:184-190; the inner .ad-banner markup
   is inc/banners.php's (WP-D), so the aspect-ratio/crop rules target its
   .ad-banner__link/.ad-banner__img (not the mock's bare `.ad-slot a`). */
.ad-slot { margin:30px auto 6px; }
.ad-slot .ad-lbl { display:block; font-size:10.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:#a7afba; margin-bottom:5px; }
.ad-slot .ad-banner { border-radius:12px; overflow:hidden; border:1px solid var(--line); }
.ad-slot .ad-banner__link { display:block; }
.ad-slot .ad-banner__img { width:100%; display:block; }
.ad-slot .ad-banner:hover { box-shadow:var(--shadow); }
.ad-wide .ad-banner__link { aspect-ratio:1200/270; }
.ad-wide .ad-banner__img { height:100%; object-fit:cover; }

/* ---------- AI coach band ---------- */
/* WP-E (home) / WP-H (components). Transcribed from variant-a.html:196-204.
   Static band only — the mock's floating .coach-fab is not theme-owned (C
   decision). */
.coach-band { display:flex; align-items:center; gap:26px; background:radial-gradient(120% 180% at 88% 0%,#1d4471 0%,var(--navy-2) 38%,var(--navy) 100%); color:#eef3fa; border-radius:18px; padding:30px 32px; margin:38px 0 8px; flex-wrap:wrap; }
.coach-spark { flex:0 0 58px; height:58px; border-radius:16px; background:rgba(240,179,46,.14); display:grid; place-items:center; box-shadow:0 0 34px rgba(240,179,46,.35); }
.coach-band .grow { flex:1 1 320px; }
.coach-band .eyebrow { color:var(--gold); }
.coach-band h2 { font-size:clamp(20px,2.6vw,27px); font-weight:900; margin:4px 0 5px; }
.coach-band h2 em { font-style:normal; color:var(--gold); }
.coach-band p { color:#b9c6d8; font-size:15px; max-width:52ch; }
.coach-cta { display:inline-flex; align-items:center; gap:9px; background:var(--gold); color:#20180a; font-weight:900; font-size:15px; border-radius:999px; padding:13px 22px; }
.coach-cta:hover { text-decoration:none; filter:brightness(1.06); }

/* ---------- community ---------- */
/* WP-E (home). Transcribed from variant-a.html:207-212. */
.comm { display:grid; grid-template-columns:repeat(3,1fr); gap:22px; margin:36px 0 8px; }
.comm a { border:1px solid var(--line); border-radius:var(--radius); padding:20px; color:var(--ink); }
.comm a:hover { text-decoration:none; box-shadow:var(--shadow); border-color:var(--blue); }
.comm b { display:block; font-size:17px; margin-bottom:4px; }
.comm span { font-size:14px; color:var(--muted); }
.comm .go { display:inline-block; margin-top:10px; color:var(--blue); font-weight:700; font-size:13.5px; }

/* ---------- article ---------- */
/* WP-F (article) adds the article *chrome* selectors here later — .crumbs,
   .art-head, .byline, .art-grid, .art-hero, .rail (mock variant-a.html:214-…).
   WP-F MUST wrap the_content() in a container carrying the class
   `entry-content` — that is the boundary the contract block below is scoped to
   (shared C5 contract between WP-F and WP-H). WP-H owns everything from the
   "content-component contract v1" banner down. */

/* article page (WP-F) — 06-wp-F-article.md.
   The article *chrome* (variant-a.html:754-1013 markup / :82-286 styles):
   breadcrumb, header/byline, two-column grid, hero figure, sticky TOC rail +
   tool card + vertical ad slot, related section, comments, the two C11 ad
   slots, print styles.

   SCOPE DISCIPLINE (C5): the CHROME classes below (.crumbs/.art-head/.rail/…)
   are the theme's own layout — they never wrap post content, so they use
   plain class selectors like the rest of the theme chrome (.hdr/.ft/…),
   matching the mock (blanket :where()-wrapping them would drop them to the
   base tag rules' specificity and rely on source order — fragile). ONLY rules
   that reach INSIDE .entry-content — the two mock "prose extras" .callout/.refs
   that WP-H's frozen contract block does NOT own — are :where(.entry-content)-
   wrapped so specificity stays low and pipeline HTML + turg-embed inline styles
   always win. NOTHING here selects inside .turg-embed. The WP-H
   "content-component contract v1" sub-block below is untouched — the base prose
   tags / .tldr / .faq / .wp-block-* are ITS job, not duplicated here. */

/* -- shared primitives also used by WP-E home (transcribed verbatim from the
      mock; if WP-E declares the same classes, the values are identical —
      dedupe at merge). The related section's individual .card styling is WP-E's
      card component (template-parts/card.php); this owns only .related + the
      .cards grid + .chip + .sect-head. -- */
.chip { display:inline-block; font-size:11.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--blue); background:#e8f1fb; border-radius:6px; padding:3px 9px; }
.sect-head { display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-bottom:18px; }
.sect-head h2 { font-size:24px; font-weight:900; letter-spacing:-.01em; }
.cards { display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }

/* -- breadcrumb (mock :215-216 + :756-758). Theme-owned, schema-free trail
      (C6 — Yoast keeps emitting BreadcrumbList JSON-LD via wp_head()
      independently; header.php 2026-07-16 note). Real titles run long where
      the mock hand-shortened its own, so the current crumb ellipsizes on one
      line instead of wrapping under the header. -- */
.crumbs { display:flex; align-items:baseline; font-size:13px; color:var(--muted); padding:22px 0 0; white-space:nowrap; }
.crumbs a { color:var(--muted); flex:0 0 auto; }
.crumbs a:hover { color:var(--blue); }
.crumbs .sep { margin:0 6px; color:var(--line); flex:0 0 auto; }
.crumbs .crumb-current { overflow:hidden; text-overflow:ellipsis; min-width:0; }

/* -- article header (mock :217-221) -- */
.art-head { max-width:780px; padding:14px 0 6px; }
.art-head h1 { font-size:clamp(29px,4vw,42px); font-weight:900; line-height:1.1; letter-spacing:-.015em; margin:12px 0 14px; text-wrap:balance; }
.art-head .standfirst { font-size:19px; color:var(--muted); line-height:1.55; }
.byline { display:flex; align-items:center; gap:12px; margin:18px 0 8px; font-size:13.5px; color:var(--muted); flex-wrap:wrap; }
.byline b { color:var(--ink); font-weight:700; }
.ava { width:38px; height:38px; border-radius:50%; background:var(--red); color:#fff; display:grid; place-items:center; font-weight:900; text-transform:uppercase; } /* brand red (owner ask, wt/chips-byline) */

/* -- two-column grid + hero (mock :222-225) -- */
.art-grid { display:grid; grid-template-columns:minmax(0,720px) 280px; gap:48px; padding:10px 0 30px; justify-content:start; }
.prose { min-width:0; } /* grid child: lets wide content (tables/embeds) scroll instead of blowing the column out */
.art-hero { border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); margin:8px 0 6px; }
/* The hero NEVER crops. A fixed `aspect-ratio:3/2` + `cover` here discarded
   more than half of every portrait source (see the crop note by the base `img`
   reset) — on a trainer profile it rendered a headless torso. Instead the box
   takes its height from the image's own intrinsic ratio (the width/height
   attrs wp_get_attachment_image() emits still reserve it, so this costs no
   CLS), capped at 560px so a 2:3 or 9:16 source can't push the article off the
   fold. `contain` is a NO-OP for anything landscape enough to fit under the cap
   — those render whole, edge to edge, exactly as before; only taller-than-cap
   sources letterbox onto --mist, showing the full photo instead of its middle.
   The hero is deliberately absent from the 20% crop-anchor list above: nothing
   is being cropped away here, so a centred letterbox is the correct framing. */
.art-hero img { width:100%; height:auto; max-height:560px; object-fit:contain; background:var(--mist); }
.art-hero figcaption { font-size:12.5px; color:var(--muted); padding:8px 4px; background:#fff; }

/* -- prose extras NOT in WP-H's frozen contract (mock-only decorative
      elements; :where(.entry-content)-scoped so content HTML always wins) -- */
:where(.entry-content) .callout { display:flex; gap:16px; align-items:center; background:#fff8ea; border:1px solid #f3e2b8; border-radius:12px; padding:18px 20px; margin:24px 0; }
:where(.entry-content) .callout .num { font-size:34px; font-weight:900; color:#b07908; line-height:1; white-space:nowrap; }
:where(.entry-content) .callout p { font-size:14.5px; color:#6b5613; margin:0; }
:where(.entry-content) .refs { margin:26px 0; }
:where(.entry-content) .refs summary { font-weight:700; font-size:14px; color:var(--muted); cursor:pointer; list-style:none; }
:where(.entry-content) .refs summary::-webkit-details-marker { display:none; }
:where(.entry-content) .refs summary::before { content:"▸"; margin-right:7px; font-size:11px; }
:where(.entry-content) .refs[open] summary::before { content:"▾"; }
:where(.entry-content) .refs summary:hover { color:var(--blue); }
/* Genesis emits a <ul> of citations (json_to_wp.py corpus), the mock wrote <ol>
   — style both identically; article.js moves the list inside the <details>. */
:where(.entry-content) .refs ol, :where(.entry-content) .refs ul { margin:10px 0 0 20px; font-size:13.5px; color:var(--muted); display:grid; gap:5px; }

/* -- article footer: tag pills (the_tags(), theme chrome — mock .tags :245-247,
      named .art-tags to stay clear of any in-content .tags) -- */
.art-tags { display:flex; flex-wrap:wrap; gap:8px; margin:26px 0; }
.art-tags a { font-size:12.5px; font-weight:700; background:var(--mist); border:1px solid var(--line); color:var(--ink); border-radius:999px; padding:5px 12px; }
.art-tags a:hover { border-color:var(--blue); color:var(--blue); text-decoration:none; }

/* -- sticky rail: TOC + tool card + vertical ad (mock :268-278) -- */
.rail { position:sticky; top:86px; align-self:start; display:grid; gap:22px; }
.rail-box { border:1px solid var(--line); border-radius:14px; padding:18px; }
.rail-box h4 { font-size:12px; letter-spacing:.09em; text-transform:uppercase; color:var(--muted); margin-bottom:10px; }
.toc { display:grid; gap:2px; font-size:13.5px; }
.toc a { color:var(--ink); padding:6px 9px; border-radius:7px; border-left:2px solid transparent; }
.toc a:hover { background:var(--mist); text-decoration:none; color:var(--blue); }
.rail-tool { display:block; background:var(--navy); color:#eaf1fa; border-radius:14px; padding:18px; }
.rail-tool:hover { text-decoration:none; filter:brightness(1.08); }
.rail-tool .eyebrow { color:var(--gold); }
.rail-tool b { display:block; font-size:16px; margin:5px 0 3px; }
.rail-tool span { font-size:13px; color:#b9c6d8; }

/* -- C11 ad slots (mock :184-193). The shared renderer inc/banners.php emits
      .ad-banner > .ad-banner__link(a|span) > .ad-banner__img + the offscreen
      _special_html pixel; single.php/rail.php wrap that in .ad-slot(.ad-wide|
      .ad-vert) with a visible "Reklaam" .ad-lbl (banners.php emits no label).
      Never style ._special_html — it carries its own inline style. -- */
.ad-slot { margin:30px auto 6px; }
.ad-slot .ad-lbl { display:block; font-size:10.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:#a7afba; margin-bottom:5px; }
.ad-banner__link { display:block; border-radius:12px; overflow:hidden; border:1px solid var(--line); }
.ad-banner__link:hover { box-shadow:var(--shadow); }
.ad-banner__img { width:100%; display:block; }
.ad-wide .ad-banner__link { aspect-ratio:1200/270; }
.ad-wide .ad-banner__img { height:100%; object-fit:cover; }
.ad-vert { margin:0; }
.ad-vert .ad-banner__link { aspect-ratio:260/520; }
.ad-vert .ad-banner__img { height:100%; object-fit:cover; }

/* -- related "Loe järgmisena" (mock :281 + :975-1003) -- */
.related { padding:8px 0 20px; }

/* -- comments (mock :282-286). DEFAULT WP comment markup, CSS-only restyle —
      comment_form()/wp_list_comments() defaults; spam plugins hook the standard
      fields, never restructured (06-wp-F-article.md step 8). -- */
.comments { max-width:720px; border:1px solid var(--line); border-radius:16px; padding:24px; margin:10px 0 40px; }
.comments .comments-title, .comments .comment-reply-title { font-size:19px; font-weight:900; margin-bottom:6px; }
.comments .comment-list { list-style:none; margin:0 0 18px; padding:0; display:grid; gap:16px; }
.comments .comment-list ol.children { list-style:none; margin:14px 0 0 22px; padding:0; display:grid; gap:14px; }
.comments .comment-body { border:1px solid var(--line); border-radius:12px; padding:14px 16px; }
.comments .comment-author { font-size:14px; font-weight:700; }
.comments .comment-author .avatar { border-radius:50%; margin-right:8px; vertical-align:middle; }
.comments .comment-metadata, .comments .comment-awaiting-moderation { font-size:12.5px; color:var(--muted); }
.comments .comment-metadata a { color:var(--muted); }
.comments .comment-content { margin-top:8px; font-size:15px; }
.comments .reply { margin-top:8px; font-size:13px; font-weight:700; }
.comments .comment-form { display:grid; gap:12px; }
.comments .comment-notes, .comments .logged-in-as { font-size:14px; color:var(--muted); margin:0; }
.comments textarea { width:100%; min-height:96px; border:1px solid var(--line); border-radius:10px; padding:12px 14px; font-family:inherit; font-size:15px; resize:vertical; background:var(--mist); }
.comments .comment-form input[type=text], .comments .comment-form input[type=email], .comments .comment-form input[type=url] { width:100%; max-width:340px; border:1px solid var(--line); border-radius:10px; padding:10px 12px; font-family:inherit; font-size:15px; background:var(--mist); }
.comments .comment-form label { display:block; font-size:13px; font-weight:700; margin-bottom:5px; }
.comments .form-submit { margin:0; }
.comments .submit, .comments .form-submit input[type=submit] { background:var(--ink); color:#fff; border:0; border-radius:999px; font-weight:700; font-size:14px; padding:11px 22px; cursor:pointer; }
.comments .no-comments { font-size:14px; color:var(--muted); }

/* -- responsive (mock :326-337) — the rail (TOC + tool + vertical ad) drops
      below 1020px exactly like the mock; the article becomes single-column. -- */
@media (max-width:1020px) {
  .art-grid { grid-template-columns:minmax(0,1fr); }
  .rail { display:none; }
}
@media (max-width:760px) {
  .cards { grid-template-columns:1fr; }
  .art-head h1 { margin:10px 0 12px; }
}

/* -- print: a clean, readable article — chrome/ads/rail/related/comments
      hidden, single column, ink on white (workout/recipe articles get printed) -- */
@media print {
  .hdr, .top-notice, .sheet, .skip-link, #site-footer, .crumbs, .rail, .ad-slot, .art-tags, .related, .comments, .burger, .burger-fallback { display:none !important; }
  .art-grid { display:block; padding:0; }
  .prose { max-width:100%; }
  .art-hero { box-shadow:none; border:1px solid #ccc; }
  body { font-size:12pt; color:#000; background:#fff; }
  .art-head h1 { font-size:22pt; }
  a, :where(.entry-content) a { color:#000; text-decoration:underline; }
}

/* ======================================================================
   content-component contract v1  (WP-H — owns C5; 00-implementation-overview.md)
   ----------------------------------------------------------------------
   The Genesis pipeline (scripts/fitness-ee/genesis/json_to_wp.py — the SAME
   emitter the book-grounded variant reuses) and this theme co-own these
   classnames PERMANENTLY. The frozen surface:
     .tldr   <div class="tldr"><p><strong>Lühidalt:</strong></p><ul>…</ul></div>
              (_tldr_block, json_to_wp.py:92-97)
     .faq    <div class="faq"><h2>…</h2><h3>Q</h3><p>A</p>…</div>
              (_faq_block, json_to_wp.py:100-110). The mock uses <details>; the
              pipeline emits h3/p, styled below as static bordered cards. Do NOT
              "fix" the pipeline — a <details> migration is a separate contract
              v2 task (pipeline + backfill + CSS in one change).
     ArtGym  <p>Tule trenni! <a …>ArtGym</a></p>  (ensure_artgym_cta, :180-183)
              — NO class by design; inherits the prose rules below.
     turg    [turg_products] → <aside class="turg-embed"> … </aside>, ALL children
              inline-styled (mu-plugins/turg-embed.php:1089-1190).
              *** THE THEME NEVER STYLES INSIDE .turg-embed *** — its inline
              styles ARE the API (C5). No selector below names `turg-embed`. The
              only bare elements that ALSO occur inside .turg-embed (<a>, <img>,
              its <h3 class="turg-embed__h">, <span>) are pinned by turg-embed's
              own inline styles; the bare a/img/h2/h3 rules below set no
              decorative BOX property turg-embed doesn't already pin, so nothing
              leaks in. ALL decorative/box styling here lives on component/block
              classes (.tldr / .faq / figure.wp-block-image / .wp-block-table /
              blockquote / …) that never occur inside .turg-embed.

   Every selector is :where()-wrapped → specificity 0 (C5) so turg-embed inline
   styles + Genesis pipeline HTML always win. C9 (ZoneOS): no native nesting,
   no @import — flat rules only.

   CHANGE CONTROL: renaming a selector here OR in json_to_wp.py is a contract
   change — bump v1→v2 and update BOTH in the same commit (change-control note:
   docs/seo/genesis-content-engine.md + .claude/skills/genesis/SKILL.md).

   ORCHESTRATOR DECISION (2026-07-15): there is NO runtime assets/css/_components.css
   — C3 forbids a build step and the dev loop bind-mounts the theme, so a
   "compiled-in" sheet would only drift. This is the one enqueued stylesheet; the
   contract CSS lives HERE. Deviation recorded in 08-wp-H-components.md.
   ====================================================================== */

/* -- body typography (Genesis markdown → bare tags; legacy → .wp-block-*
      classes sit ON the same tags, so tag selectors cover both) -- */
:where(.entry-content) h2 { font-size:24px; font-weight:900; letter-spacing:-.01em; line-height:1.25; margin:34px 0 12px; scroll-margin-top:86px; }
:where(.entry-content) h3 { font-size:19px; font-weight:900; letter-spacing:-.01em; line-height:1.3; margin:26px 0 10px; }
:where(.entry-content) h4 { font-size:16px; font-weight:700; margin:22px 0 8px; }
:where(.entry-content) p { margin:0 0 15px; }
:where(.entry-content) ul, :where(.entry-content) ol { margin:0 0 15px 22px; display:grid; gap:6px; }
:where(.entry-content) li { margin:0; }
:where(.entry-content) a { color:var(--blue); text-decoration:underline; text-underline-offset:2px; }
:where(.entry-content) img { max-width:100%; height:auto; }

/* -- TL;DR card (.tldr) — mock variant-a.html:226-228. The pipeline emits a
      label <p><strong>Lühidalt:</strong></p> where the mock had <b class="lbl">,
      so the label look is mapped onto .tldr's <p>/<strong>. -- */
:where(.entry-content) .tldr { background:var(--mist); border-left:4px solid var(--blue); border-radius:0 12px 12px 0; padding:18px 22px; margin:22px 0; }
:where(.entry-content) .tldr p { margin:0 0 8px; }
:where(.entry-content) .tldr strong { display:block; font-size:12px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--blue); }
:where(.entry-content) .tldr ul { margin:0; padding-left:19px; display:grid; gap:7px; font-size:15.5px; }

/* -- FAQ (.faq) — pipeline emits <h2> then repeating <h3>question / <p>answer.
      Mock (variant-a.html:235-241) uses <details>; approximated as static
      bordered cards. Q & A are siblings, so header/body borders stitch into one
      card via a shared radius. -- */
:where(.entry-content) .faq { margin:34px 0 8px; }
:where(.entry-content) .faq h2 { font-size:22px; font-weight:900; letter-spacing:-.01em; margin:0 0 14px; }
:where(.entry-content) .faq h3 { margin:12px 0 0; padding:15px 18px; font-size:15.5px; font-weight:700; line-height:1.35; color:var(--ink); background:#fff; border:1px solid var(--line); border-radius:12px 12px 0 0; }
:where(.entry-content) .faq p { margin:0; padding:0 18px 16px; font-size:15px; color:var(--muted); background:#fff; border:1px solid var(--line); border-top:0; border-radius:0 0 12px 12px; }

/* -- FAQ accordion upgrade (.faq-details — added by article.js when it
      rewraps the h3/p pairs into native <details>/<summary>; mock :236-241).
      The h3/p card rules above stay as the no-JS fallback; these override the
      answer-<p> chrome once it lives INSIDE a <details>. Contract v1 markup
      unchanged — the pipeline still emits h3/p. -- */
:where(.entry-content) .faq-details details { border:1px solid var(--line); border-radius:12px; margin-bottom:10px; background:#fff; overflow:hidden; }
:where(.entry-content) .faq-details summary { list-style:none; display:flex; justify-content:space-between; gap:14px; align-items:center; padding:15px 18px; font-weight:700; font-size:15.5px; line-height:1.35; cursor:pointer; }
:where(.entry-content) .faq-details summary::-webkit-details-marker { display:none; }
:where(.entry-content) .faq-details summary::after { content:"+"; font-size:20px; color:var(--blue); font-weight:400; flex:0 0 auto; }
:where(.entry-content) .faq-details details[open] summary::after { content:"–"; }
:where(.entry-content) .faq-details details p { border:0; border-radius:0; background:none; padding:0 18px 16px; }

/* -- ArtGym closing CTA (.artgym — class added by article.js to the
      pipeline's `<p>Tule trenni! <a>ArtGym</a></p>`; mock :263-265). No-JS
      visitors see the plain prose paragraph — nothing is lost. -- */
:where(.entry-content) .artgym { text-align:center; border:1px dashed #e5b5b5; background:#fdf6f6; border-radius:14px; padding:22px; margin:30px 0; }
:where(.entry-content) .artgym a { font-weight:900; color:var(--red); text-decoration:underline; }

/* -- legacy Gutenberg blocks (live corpus census: wp-block-heading ×720,
      -image ×143, -separator ×57, -embed ×36, -table ×30, -quote ×14) + classic
      fallbacks (audit §13). Headings/lists already covered by the tag rules. -- */
:where(.entry-content) figure { margin:22px 0; }
:where(.entry-content) figure.wp-block-image img { border-radius:12px; }
:where(.entry-content) figcaption, :where(.entry-content) .wp-element-caption, :where(.entry-content) .wp-caption-text { margin-top:8px; font-size:13px; line-height:1.5; color:var(--muted); text-align:center; }
:where(.entry-content) blockquote, :where(.entry-content) .wp-block-quote { margin:24px 0; padding:8px 20px; border-left:4px solid var(--blue); font-size:18px; }
:where(.entry-content) blockquote cite, :where(.entry-content) .wp-block-quote cite { display:block; margin-top:8px; font-size:13.5px; font-style:normal; color:var(--muted); }
:where(.entry-content) hr, :where(.entry-content) .wp-block-separator { height:0; margin:30px auto; border:0; border-top:1px solid var(--line); }
:where(.entry-content) .wp-block-table, :where(.entry-content) figure.wp-block-table { margin:24px 0; overflow-x:auto; }
:where(.entry-content) table { width:100%; border-collapse:collapse; font-size:14.5px; }
:where(.entry-content) th, :where(.entry-content) td { padding:9px 12px; border:1px solid var(--line); text-align:left; vertical-align:top; }
:where(.entry-content) thead th { background:var(--mist); font-weight:700; }
:where(.entry-content) .wp-block-embed { margin:24px 0; }
:where(.entry-content) .wp-block-embed__wrapper { position:relative; }
:where(.entry-content) iframe { max-width:100%; border:0; }

/* -- classic image alignments (audit §13; near-zero in the live corpus — 0
      wp-caption / 0 [gallery] / 0 classic alignleft-right — but cheap + robust
      for the oldest imported posts and block align variants) -- */
:where(.entry-content) .aligncenter { display:block; margin-left:auto; margin-right:auto; }
:where(.entry-content) .alignleft { float:left; margin:6px 20px 12px 0; }
:where(.entry-content) .alignright { float:right; margin:6px 0 12px 20px; }
:where(.entry-content) .alignnone { margin:12px 0; }
:where(.entry-content) .alignwide, :where(.entry-content) .alignfull { margin-left:auto; margin-right:auto; }
:where(.entry-content) .wp-caption { max-width:100%; margin:22px 0; }

/* -- responsive (component-scoped, mirrors the mock's own responsive banner) -- */
@media (max-width:640px) {
  :where(.entry-content) h2 { font-size:21px; }
  :where(.entry-content) .tldr { padding:16px 18px; }
  :where(.entry-content) .faq h3 { padding:13px 15px; }
  :where(.entry-content) .faq p { padding:0 15px 14px; }
  :where(.entry-content) .faq-details summary { padding:13px 15px; }
  :where(.entry-content) .faq-details details p { padding:0 15px 14px; }
}

/* ---------- footer ---------- */
/* Transcribed from variant-a.html:288-301 (footer) + :1050 (.ft-legal),
   tokens only, C9-clean. Deliberately NOT ported: `.demo-bar` (mock's own
   dev-only view-switcher — never ported to any WP, 03-wp-C-scaffold.md
   gotchas). WP-D (04-wp-D-chrome.md). `.coach-fab` (below the footer rules)
   joined the theme 2026-07-16 — UAT reversed the "not in v1" lock. */
footer { background:var(--ink); color:#c6cdd6; margin-top:44px; }
/* .ft/.ft-legal sit ON the same element as .wrap — their padding shorthand
   used to zero .wrap's 20px side gutter (later rule, same specificity), so
   footer text sat flush against the screen edge at every viewport ≤1200px.
   Keep the gutter explicit here (mobile-2026 fix). */
.ft { display:grid; grid-template-columns:2fr 1fr 1fr 1.4fr; gap:34px; padding:44px 20px 30px; }
.ft h4 { color:#fff; font-size:12.5px; letter-spacing:.09em; text-transform:uppercase; margin-bottom:12px; }
.ft a { display:block; color:#c6cdd6; font-size:14.5px; padding:4px 0; }
.ft a:hover { color:#fff; }
.ft .brand img { height:30px; width:auto; margin-bottom:12px; filter:drop-shadow(0 1px 1px rgba(0,0,0,.4)); } /* width:auto is a WP-D addition: fitness_2026_the_logo() emits width/height attrs (CLS), and without it the attr width (100) would win over the height-constrained scale -> ~20% horizontal stretch (caught in the 2026-07-15 headless-Chrome parity check) */
.ft .brand p { font-size:14px; max-width:34ch; }
.ft-badge-row { margin-top:10px; } /* WP-D addition: replaces the mock's inline style="margin-top:10px" on the badge <p> (C9 — no inline styles) */
.news input { width:100%; background:#20232b; border:1px solid #3a3f49; color:#fff; border-radius:10px; padding:11px 14px; font-family:inherit; font-size:14px; }
.news button { margin-top:9px; width:100%; background:var(--blue); color:#fff; border:0; border-radius:10px; padding:11px; font-weight:700; font-size:14px; }
.ft-links-secondary { margin-top:14px; } /* WP-D addition: replaces the mock's inline style="margin-top:14px" (C9) */
.ft-legal { border-top:1px solid #262b33; padding:18px 20px 26px; display:flex; justify-content:space-between; gap:14px; flex-wrap:wrap; font-size:12.5px; color:#8b93a0; align-items:center; }
.ft-legal-credit { color:#aab2be; } /* WP-D addition: replaces the mock's inline style="color:#aab2be" on the @simkares credit link (C9) */
.badge-tv { display:inline-flex; align-items:center; gap:7px; border:1px solid #3a3f49; border-radius:999px; padding:4px 12px; font-size:11.5px; color:#aab2be; }
.badge-tv i { width:8px; height:8px; border-radius:50%; background:#57c26a; }

/* WP-D addition, not in the mock — the `widget-area_forum-latest-posts`
   sidebar (audit.md §4) renders here, inside the "Sisu" column; only
   prints when it has real content (fitness_2026_render_sidebar()). Its
   links inherit `.ft a` above for free. */
.ft-forum-latest { margin-top:10px; }

/* ---------- AI coach bubble ---------- */
/* Transcribed from variant-a.html:302-312 (+ the :347 mobile offset).
   footer.php renders it; the teaser ships display:none and main.js adds
   .show after a delay (dismissal remembered per-session). The .coach-btn
   link needs no JS at all. z-index 70 sits under the fe-shared-state
   consent banner by design — consent always wins the corner. */
.coach-fab { position:fixed; right:18px; bottom:18px; z-index:70; display:flex; flex-direction:column; align-items:flex-end; gap:10px; }
.coach-teaser { background:#fff; border:1px solid var(--line); box-shadow:0 10px 34px rgba(12,31,58,.2); border-radius:16px 16px 4px 16px; padding:13px 15px; max-width:250px; font-size:13.5px; line-height:1.45; display:none; }
.coach-teaser.show { display:block; animation:coach-pop .35s ease; }
.coach-teaser b { display:block; margin-bottom:2px; }
.coach-teaser a { font-weight:700; }
.coach-teaser .x { float:right; border:0; background:none; color:var(--muted); font-size:15px; margin:-4px -4px 0 6px; cursor:pointer; }
.coach-btn { display:flex; align-items:center; gap:9px; background:#fff; border:1px solid var(--line); border-radius:999px; padding:9px 18px 9px 10px; font-weight:900; font-size:14px; color:var(--navy); box-shadow:0 8px 28px rgba(12,31,58,.22); }
.coach-btn:hover { text-decoration:none; transform:translateY(-1px); }
.spark { width:30px; height:30px; border-radius:50%; background:radial-gradient(circle at 35% 30%,#173861,#0c1f3a); display:grid; place-items:center; box-shadow:0 0 14px rgba(240,179,46,.55); }
@keyframes coach-pop { from { opacity:0; transform:translateY(8px) scale(.96); } to { opacity:1; transform:none; } }
@media (max-width:760px) {
  .coach-fab { bottom:64px; }
}
@media print {
  .coach-fab { display:none !important; }
}

@media (max-width:760px) {
  .ft { grid-template-columns:1fr 1fr; }
}

/* ---------- responsive ---------- */
/* Each WP adds its own component's media queries alongside that component's
   rules above (or in this banner, mirroring the mock). WP-E's home breakpoints
   are grouped here, transcribed from variant-a.html:323-347 — ONLY the home
   components' rules (the mock's header `.hdr-nav`/`.burger` are WP-D's and its
   `.art-grid`/`.rail` are WP-F's; not repeated here). */
@media (max-width:1020px) {
  .cards.cards-4 { grid-template-columns:repeat(2,1fr); }
  .tools-grid { grid-template-columns:repeat(2,1fr); }
}
@media (max-width:760px) {
  .hero-grid { grid-template-columns:1fr; }
  .cards { grid-template-columns:1fr; }
  .cards.cards-4 { grid-template-columns:1fr 1fr; gap:12px; }
  .cards-4 .card img { height:108px; }
  .cards-4 .card h2, .cards-4 .card h3 { font-size:14px; -webkit-line-clamp:3; }
  .comm { grid-template-columns:1fr; }
  .tools-grid { grid-template-columns:1fr; }
  .tools-band { padding:20px; }
  .coach-band { padding:24px 20px; }
  /* Header: a touch shorter still on phones (borderless 44px icons clear 48px). */
  .hdr-in { height:48px; }
  .hdr-logo img { height:26px; }
  /* Masthead: the mural IMAGE stays (it's the brand), but on a phone it's a
     slim ~82px band, and the caption OVERLAYS it (see base .mural-row) so the
     "Body · Spirit · Mind" line and credit take no height of their own — the
     lead story rises up the fold. The tagline tail is dropped for a clean
     single overlaid line. @simkares credit kept (locked constraint). */
  .masthead { padding:10px 0 6px; }
  .mural img { aspect-ratio:auto; height:82px; object-fit:cover; }
  .mural-tag-tail { display:none; }
  .mural-row { padding:24px 12px 8px; gap:2px 10px; }
  .mural-tag { font-size:11.5px; }
  .credit-chip { font-size:11px; }
}

/* ===== sponsored (wt/home-sponsored) ===== */
/* Delfi-style "Sisuturundus": 2 compact cards under the hero side items
   (template-parts/home/hero.php) + one interleaved feed row (feed.php).
   The chip is AMBER on purpose — paid placement must never read as the
   editorial blue chip — and the label is visible text, never colour-only.
   Same specificity as .chip (0,1,0); this section is last in the file, so
   the override wins by order. Fallback filler cards render the normal
   editorial .chip, so no rule here may restyle .sponsored-item .chip as a
   whole — only .chip-sponsored. */
.chip-sponsored { color:#7a5200; background:#faf0d5; }
.sponsored-rail { margin-top:16px; border-top:2px solid var(--gold); padding-top:2px; }
.sponsored-item { display:grid; grid-template-columns:84px 1fr; gap:12px; padding:12px 0; border-top:1px solid var(--line); align-items:center; }
.sponsored-item:first-child { border-top:0; } /* the rail's gold rule already separates */
.sponsored-item img { border-radius:8px; aspect-ratio:4/3; object-fit:cover; height:auto; }
.sponsored-item h3 { font-size:14.5px; font-weight:700; line-height:1.35; margin-top:5px; }
.sponsored-item h3 a { color:inherit; text-decoration:none; }
.sponsored-item:hover h3 a { color:var(--blue); }
/* Compact horizontal card holds its shape down to 390px (84px thumb + fluid
   text column); just tighten the gutter a notch on small screens. */
@media (max-width:760px) {
  .sponsored-item { grid-template-columns:76px 1fr; gap:10px; }
}
/* ^ mobile-2026 fix: this closing brace was MISSING (bad parallel-branch
   merge) — the un-closed @media swallowed every rule below it (the whole
   archive-ux section + the red-byline rules), so none of them applied on
   desktop. Browsers auto-close at EOF, which is why mobile looked right. */

/* ===== archive-ux (wt/archive-ux) ===== */
/* Archive listing usability (archive.php + functions.php archive-ux block).
   Parallel-branch CSS discipline: this appended section is the ONLY main.css
   change on wt/archive-ux — no rule above is edited. Everything here is
   scoped under the archive-ux wrapper classes (.archive-head / .archive-
   chips / .archive-pagenav), so search.php's shared .search-form-page and
   .nav-links chrome and the home feed's .feed-pagination keep their existing
   look untouched. Specificity note (the .cards-4 lesson at the "sections"
   banner applies here too): the pagination overrides deliberately ride the
   3-class chain .archive-pagenav .nav-links .page-numbers (0-3-0) so they
   beat the base 0-2-0 rules regardless of any future re-ordering. */

/* -- header bar: title + description left, compact search right; the form
      itself is the stock searchform.php (.search-form-page) so the field/
      button skin + typeahead anchor are inherited, only layout is scoped. -- */
.archive-head { display:flex; flex-wrap:wrap; align-items:flex-start; justify-content:space-between; gap:12px 24px; }
.archive-head__main { flex:1 1 340px; min-width:0; }
.archive-search { flex:0 1 320px; }
.archive-search .search-form-page { margin:4px 0 0; max-width:none; }

/* -- category filter chips: same pill language as .topic-chip (border,
      radius 999, blue active state) but LINKS in a single horizontally
      scrollable row — no wrap, so 20 chips at 390px stay one clean swipe.
      Own classes per the parallel-branch contract; .topic-chip stays the
      home page's button-chip. Bottom padding gives the focus ring and the
      thin scrollbar room so neither clips against the row edge. -- */
.archive-chips { margin:16px 0 0; }
.archive-chips__track { display:flex; flex-wrap:nowrap; gap:8px; overflow-x:auto; padding:2px 2px 8px; -webkit-overflow-scrolling:touch; scrollbar-width:thin; }
.archive-chip { flex:0 0 auto; display:inline-flex; align-items:center; white-space:nowrap; min-height:36px; font-size:13px; font-weight:700; border:1px solid var(--line); background:#fff; color:var(--ink); border-radius:999px; padding:7px 15px; }
.archive-chip:hover { border-color:var(--blue); color:var(--blue); text-decoration:none; }
.archive-chip[aria-current] { background:var(--blue); border-color:var(--blue); color:#fff; }
.archive-chip[aria-current]:hover { color:#fff; }

/* -- pagination: centered page window (mid_size=2 -> 1 2 3 … 131) with a
      small "Lehekülg X / Y" line above it. Mirrors .feed-pagination's
      centered boxed-number look but with >=44px touch targets throughout
      (they wrap cleanly at 390px, so no mobile-only downsizing needed).
      .dots is core's ellipsis <span> — inert: no border, muted, unclickable. -- */
.archive-pagenav { margin:6px 0 40px; }
.archive-pageinfo { text-align:center; font-size:13px; color:var(--muted); margin:0 0 10px; }
.archive-pagenav .nav-links { justify-content:center; gap:8px; margin:0; }
.archive-pagenav .nav-links .page-numbers { display:inline-flex; align-items:center; justify-content:center; min-width:44px; min-height:44px; padding:0 13px; border-radius:10px; }
.archive-pagenav .nav-links .page-numbers.dots { border-color:transparent; color:var(--muted); pointer-events:none; }

@media (max-width:760px) {
  /* search drops below the title, full width; chips keep scrolling in-row */
  .archive-search { flex:1 1 100%; }
  .archive-search .search-form-page { margin-top:6px; }
}
/* ===== chips-byline (wt/chips-byline) ===== */
/* Author byline in the brand's red (owner ask): the .ava circle flips to
   var(--red) at its base rule above; the author NAME picks up the matching
   accent here. Same specificity as the base .byline b rule — this section is
   appended, so it wins by order. The rest of the byline meta stays muted.
   .feature .meta b = the home-hero author name (the only <b> inside any .meta)
   so hero and article byline read as one brand treatment. */
.byline b { color:var(--red); }
.feature .meta b { color:var(--red); }

/* ===== mobile-2026 (mobile-friendliness overhaul) ===== */
/* Delfi-informed mobile ergonomics pass (owner ask, 2026-07-21): compact
   horizontal list rows, swipeable chip rows, news-scale mobile type, 44px
   tap targets. Appended LAST on purpose — every override here wins by order
   over the base rules above at equal specificity; the only specificity it
   adds is .cards:not(.cards-4) (0-2-0), which must beat the 0-1-0/0-2-0
   .cards/.card rules regardless of future re-ordering while leaving the home
   "Värsked" showcase grid (.cards.cards-4) untouched. C9-clean: no nesting,
   no @import, no inline styles. Nothing here styles inside .turg-embed. */

/* -- content-safety guards (all widths). :where() keeps specificity 0 (C5)
      so pipeline/turg-embed inline styles still win every OTHER property;
      max-width merely caps what an inline `style="width:NNNpx"` on a
      resized figure/embed can force — the class of bug behind the reported
      "hero image overflows below ~480px" report (an img-only max-width
      guard existed; figures and embed wrappers had none). -- */
:where(.entry-content) figure,
:where(.entry-content) video,
:where(.entry-content) .wp-block-embed__wrapper { max-width:100%; }
:where(.entry-content) pre { max-width:100%; overflow-x:auto; }

/* -- .wrap gutter restoration (all widths). .masthead/.hero/.sect sit ON the
      same element as .wrap (e.g. `<section class="sect wrap">`) and their
      `padding:X 0 Y` shorthand — later in the file, same specificity —
      zeroed .wrap's 20px side gutter: every home section ran flush against
      the screen edge at any viewport ≤1200px (and sat 40px wider than the
      header/footer/article column above 1200). Same shorthand bug family as
      the .ft footer fix above. The compound selectors (0-2-0) win over both
      the single-class section rules and `.wrap .wrap`; the nested-wrap
      exception (turg/coach strips inside search.php's main.wrap) is then
      re-asserted so those keep relying on their parent's gutter. -- */
.masthead.wrap, .hero.wrap, .sect.wrap { padding-left:20px; padding-right:20px; }
.wrap .masthead.wrap, .wrap .hero.wrap, .wrap .sect.wrap { padding-left:0; padding-right:0; }

@media (max-width:760px) {
  /* -- delfi-style full-bleed lead imagery: the text column keeps its 20px
        gutter, the hero/masthead image runs edge-to-edge (-20px cancels the
        .wrap gutter restored above). Radius dropped — a full-bleed image
        with rounded corners reads as a mistake. -- */
  .feature .ph { margin-left:-20px; margin-right:-20px; border-radius:0; }
  .masthead .mural { margin-left:-20px; margin-right:-20px; border-radius:0; }
  .art-hero { margin-left:-20px; margin-right:-20px; border-radius:0; }

  /* -- interest topic chips: one swipeable line instead of a 3-row wrap
        pile. Full-bleed (-20px cancels .wrap's gutter) so the clipped next
        chip peeks at the true screen edge — that peek is the scroll
        affordance; the scrollbar itself is hidden like every news app. -- */
  .topics { flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; margin-left:-20px; margin-right:-20px; padding:2px 20px 10px; }
  .topics::-webkit-scrollbar { display:none; }
  .topic-chip { flex:0 0 auto; }

  /* -- archive filter chips: same full-bleed peek treatment (the track
        already scrolls horizontally with momentum at its base rule). -- */
  .archive-chips__track { margin-left:-20px; margin-right:-20px; padding-left:20px; padding-right:20px; scrollbar-width:none; }
  .archive-chips__track::-webkit-scrollbar { display:none; }

  /* -- interest rails: bleed to the screen edge so the next card peeks; the
        muted "värsked lood / populaarsed lood" count label makes the rail
        head wrap to three ragged lines at 390px — drop it, keep the state
        pill. -- */
  .rail-track { margin-left:-20px; margin-right:-20px; padding-left:20px; padding-right:20px; scroll-padding-left:20px; }
  .rail-head .count { display:none; }

  /* -- turg strip: tighter box so 2 product cards + a peek fit at 390px. -- */
  .turg-box { padding:16px 14px; margin:24px 0; }

  /* -- "Rohkem lugusid" feed rows, delfi-style: small rubric+date line on
        top, then the headline FULL WIDTH below it (was: chip + title + date
        side by side on one baseline — the date column squeezed titles to
        ~55% width). The whole row stays one big anchor. -- */
  .feedrow { display:grid; grid-template-columns:minmax(0,1fr) auto; row-gap:5px; column-gap:10px; align-items:center; padding:13px 2px; }
  .feedrow .chip { grid-row:1; grid-column:1; justify-self:start; }
  .feedrow .when { grid-row:1; grid-column:2; margin-left:0; }
  .feedrow h3 { grid-row:2; grid-column:1 / -1; font-size:16.5px; line-height:1.4; }

  /* -- secondary article lists (archive / search / related / 404): compact
        horizontal rows — text left, thumb right, hairline separators — in
        place of full-width vertical cards (~700px tall each; a delfi-length
        scroll for 12 results). .cards-4 (home "Värsked" showcase) keeps its
        2-col mini-card grid. -- */
  .cards:not(.cards-4) { grid-template-columns:1fr; gap:0; margin:14px 0 30px; border-top:1px solid var(--line); }
  .cards:not(.cards-4) .card { display:grid; grid-template-columns:minmax(0,1fr) 104px; column-gap:14px; align-items:center; background:none; border:0; border-bottom:1px solid var(--line); border-radius:0; padding:14px 2px; transition:none; }
  .cards:not(.cards-4) .card:hover { box-shadow:none; transform:none; }
  .cards:not(.cards-4) .card .card-media { grid-column:2; grid-row:1; margin:0; }
  .cards:not(.cards-4) .card img { aspect-ratio:4/3; border-radius:10px; }
  .cards:not(.cards-4) .card-body { grid-column:1; grid-row:1; padding:0; }
  .cards:not(.cards-4) .card h2, .cards:not(.cards-4) .card h3 { font-size:16.5px; line-height:1.35; margin:6px 0 0; }
  .cards:not(.cards-4) .card p, .cards:not(.cards-4) .card .entry-summary { display:none; }
  .cards:not(.cards-4) .card .meta { margin-top:6px; font-size:12px; }

  /* -- hero side items + sponsored rail: flip to text-left / thumb-right so
        every compact row on the page reads the same direction. -- */
  .side-item { grid-template-columns:minmax(0,1fr) 104px; }
  .side-item > a { grid-column:2; grid-row:1; }
  .side-item > div { grid-column:1; grid-row:1; }
  .sponsored-item { grid-template-columns:minmax(0,1fr) 84px; gap:12px; }
  .sponsored-item > a { grid-column:2; grid-row:1; }
  .sponsored-item > div { grid-column:1; grid-row:1; }

  /* -- mobile type ramp: news-site scale at 390px (desktop sizes read
        oversized once single-column). Body stays 17px. -- */
  .sect-head h2 { font-size:21px; }
  .page-header .page-title { font-size:24px; }
  .art-head h1 { font-size:clamp(26px,7vw,32px); }
  .art-head .standfirst { font-size:17px; }
  .feature p { font-size:15.5px; }
  .related-heading { font-size:19px; }

  /* -- tap targets ≥44px: feed pagination boxes, generic pagination links,
        load-more, footer link rows, drawer links. -- */
  .feed-pagination .page-numbers { min-width:44px; height:44px; }
  .nav-links .page-numbers { display:inline-flex; align-items:center; min-height:44px; }
  .load-more { padding:13px 30px; }
  .ft a { padding:9px 0; }
  .sheet-panel a { padding:12px 10px; }
}

/* ===== pagenav v2 (unified pagination — archive + search + home feed) =====
   Owner feedback 2026-07-21: paginate_links()'s first/last + ellipsis shape
   read as noise, and base .nav-links' space-between spread scattered the
   pills across the full row. One compact centred cluster instead; the
   "Lehekülg X / Y" line carries the total, so there are no first/last jump
   pills and no dots. Markup: inc/pagination.php. Base .nav-links styles stay
   untouched for any remaining core-generated pagination. */
.pagenav { margin:26px 0 44px; }
.pagenav-info { text-align:center; font-size:13px; color:var(--muted); margin:0 0 10px; }
.pagenav-row { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:8px; }
.pagenav-pill { display:inline-flex; align-items:center; justify-content:center; min-width:44px; min-height:44px; padding:0 14px; border:1px solid var(--line); border-radius:12px; font-size:14px; font-weight:700; color:var(--ink); }
a.pagenav-pill:hover { border-color:var(--blue); color:var(--blue); text-decoration:none; }
.pagenav-pill.is-current { background:var(--blue); border-color:var(--blue); color:#fff; }
.pagenav-step { padding:0 16px; }

/* ===== coach-fab-v2 (wt/coach-fab) =====
   Owner mobile feedback 2026-07-21: the teaser + labeled pill covered too
   much of a 390px viewport and the teaser reappeared after closing (v1
   dismissal was sessionStorage-only; main.js now persists it 30 days and
   gates the mobile show on engagement). Overrides of the earlier .coach-*
   rules live HERE by source order — do not edit the originals in place
   (shared file across parallel branches).
   - .is-leaving: slide-away used by main.js's 10s mobile auto-hide (the
     global prefers-reduced-motion rule at the top of this file already
     nukes the animation; main.js clears .show on a timeout, not
     animationend, so reduce-motion just hides it without the slide).
   - ≤760px: the .coach-btn pill collapses to a 56px icon-only circle
     (font-size:0 hides the "AI-treener" text node; the anchor's aria-label
     keeps the full accessible name) and the teaser is capped at 85vw. */
.coach-teaser.is-leaving { animation:coach-fab-v2-out .3s ease forwards; }
@keyframes coach-fab-v2-out { to { opacity:0; transform:translateY(10px) scale(.96); } }
@media (max-width:760px) {
  .coach-btn { width:56px; height:56px; padding:0; border-radius:50%; justify-content:center; gap:0; font-size:0; }
  .coach-teaser { max-width:min(250px, 85vw); }
}
/* ===== responsive-ad (wt/mobile-banner) =====
   Wide ad slots (home ad-wide.php + single.php in-content) now render BOTH
   creatives as inert <template>s (inc/banners.php::
   fitness_2026_render_banner_responsive); main.js's responsive-ad-swap block
   imports exactly one at boot. When it picks the vertical (<=760px viewport,
   sidebar-1 creative live) it adds .ad-wide--vert to the slot: the 260x520
   vertical renders centred at ~300px instead of the 1200x270 leaderboard
   squashed to ~86px tall on phones. These rules are NOT media-queried on
   purpose — the swap never re-runs on resize, so the modifier class must
   keep styling the vertical creative after an orientation change. Same
   specificity as the base .ad-wide rules; this block wins by source order
   (append-only, shared file — do not fold into the blocks above). */
template.ad-tpl { display:none; } /* inert by spec; belt-and-braces for ancient parsers */
.ad-wide--vert .ad-banner { max-width:300px; margin-left:auto; margin-right:auto; }
.ad-wide--vert .ad-banner__link { aspect-ratio:260/520; }
.ad-wide--vert .ad-banner__img { height:100%; object-fit:cover; }
/* ===== sponsored-rotation (wt/sponsored-rotation) ===== */
/* The rail now renders EVERY sponsored candidate (up to 6) and rotation
   shows/hides them via the `hidden` attribute. The base .sponsored-item rule
   sets display:grid, which overrides the UA stylesheet's [hidden] default —
   so hidden cards must be forced off explicitly. */
.sponsored-item[hidden] { display:none; }
/* Separator borders between VISIBLE cards only: with rotation the first
   rendered card may be hidden, so :first-child no longer means "first shown".
   A visible card gets a top border iff some visible card precedes it — the
   first shown card stays flush under the rail's gold rule, exactly the old
   look when everything is visible. */
.sponsored-rail .sponsored-item { border-top:0; }
.sponsored-rail .sponsored-item:not([hidden]) ~ .sponsored-item:not([hidden]) { border-top:1px solid var(--line); }

/* ===== mobile hero header — home banner overlay (v1.2.4) =====
   On the HOME page at phone widths the graffiti mural becomes a hero banner and
   the header floats over its top: the mural is pulled up under the sticky header
   (JS makes it transparent via .hdr--overlay), the search/menu icons become
   highlighted solid white circles so they pop over the busy graffiti, and the
   caption still overlays the bottom. The banner is NOT pinned — it scrolls away;
   once it does, JS adds .is-solid and the header becomes the normal slim white
   bar, staying pinned so the menu is always one tap away. No-JS and desktop fall
   back to the plain solid header (safe — the header just sits opaque over the
   mural top, ~= the previous look). Home-only (keyed on the WP .home body class)
   + phone-only. */
@media (max-width:760px) {
  .home .masthead { margin-top:-52px; padding-top:0; }
  .home .mural img { height:134px; }
  /* soft top scrim so the (transparent-header) logo stays legible on the mural */
  .home .mural::before { content:""; position:absolute; left:0; right:0; top:0; height:66px; background:linear-gradient(to bottom, rgba(9,17,29,.42), transparent); z-index:1; pointer-events:none; }

  /* transparent header while overlaying the hero (JS class, pre-scroll) */
  .hdr--overlay:not(.is-solid) { background:transparent; border-bottom-color:transparent; box-shadow:none; -webkit-backdrop-filter:none; backdrop-filter:none; }
  .hdr--overlay:not(.is-solid) .hdr-logo img { filter:drop-shadow(0 1px 3px rgba(0,0,0,.55)); }
  /* highlighted icons over the graffiti: solid white circles with a soft lift */
  .hdr--overlay:not(.is-solid) .icon-btn { background:#fff; border-color:#fff; box-shadow:0 2px 9px rgba(0,0,0,.30); color:var(--ink); }
  /* once scrolled past the banner (.is-solid) the header uses its normal slim
     white-bar styling + borderless icons — nothing extra needed here. */
}

/* ===== interest-rail + turg scroll affordance (2026-07-22) ===== */
/* Desktop had no at-rest cue that these strips scroll horizontally (the rail
   arrows are hover-only). Edge fades signal it: home.js toggles
   .can-scroll-prev/next on each track's positioned parent (.rail-sect /
   .turg-box) when the track actually overflows that way, and the gradient fades
   the peeking card into the section background. Scoped to fine-pointer (mouse)
   devices — touch already reveals scroll via the peeking card + momentum, and a
   fade there would only obscure content. .rail-sect is already position:relative
   (line 437); .turg-box needs it to anchor the pseudo-elements. */
.turg-box { position:relative; }
@media (hover:hover) and (pointer:fine) {
  .rail-sect::before,
  .rail-sect::after,
  .turg-box::before,
  .turg-box::after {
    content:""; position:absolute; z-index:4; width:52px;
    pointer-events:none; opacity:0; transition:opacity .18s ease;
  }
  .rail-sect::before, .rail-sect::after { top:46px; bottom:14px; }
  .rail-sect::before { left:0;  background:linear-gradient(90deg,  var(--paper), rgba(255,255,255,0)); }
  .rail-sect::after  { right:0; background:linear-gradient(270deg, var(--paper), rgba(255,255,255,0)); }
  .turg-box::before, .turg-box::after { top:64px; bottom:22px; }
  .turg-box::before { left:1px;  background:linear-gradient(90deg,  #f4f7fb, rgba(244,247,251,0)); }
  .turg-box::after  { right:1px; background:linear-gradient(270deg, #f4f7fb, rgba(244,247,251,0)); }
  .rail-sect.can-scroll-prev::before,
  .rail-sect.can-scroll-next::after,
  .turg-box.can-scroll-prev::before,
  .turg-box.can-scroll-next::after { opacity:1; }
  /* Surface the directional rail arrow whenever there IS more to scroll (not
     only on :hover, line 452) so the cue is explicit, not just the soft fade —
     the peeking-card fade alone read as "not obvious" on desktop. */
  .rail-sect.can-scroll-prev .rail-arrow.prev,
  .rail-sect.can-scroll-next .rail-arrow.next { display:grid; place-items:center; }
}
