/* S.K.I.F. Ruše: components. Values come from tokens.css only (generated from Figma variables).
   Breakpoints: Desktop >= 1200, Tablet 768-1199, Mobile <= 767. */

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--layout-nav-height) + var(--spacing-16)); }
body { margin: 0; font-family: var(--typography-font-family-primary); font-size: var(--typography-body-size); line-height: var(--typography-body-line-height); color: var(--color-text-primary); background: var(--color-bg-primary); -webkit-font-smoothing: antialiased; }
img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }
[hidden] { display: none !important; }
.wp-site-blocks > * + * { margin-block-start: 0; }
.wp-site-blocks { padding: 0; }
.site-main { display: block; }

.screen-reader-text { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: var(--spacing-16); top: -100px; z-index: 200; padding: var(--spacing-12) var(--spacing-16); background: var(--color-bg-inverse); color: var(--color-text-inverse); border-radius: var(--radius-small); text-decoration: none; }
.skip-link:focus { top: var(--spacing-16); }
.on-dark :focus-visible { outline-color: var(--color-border-focus-inverse); }

/* ---------- buttons (Figma: Button) ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-12); min-height: 52px; padding: var(--spacing-16) var(--spacing-32); border-radius: var(--radius-small); font-size: var(--typography-button-size); line-height: var(--typography-button-line-height); letter-spacing: var(--typography-button-letter-spacing); font-weight: 500; text-decoration: none; white-space: nowrap; transition: background-color .15s ease, color .15s ease, box-shadow .15s ease; }
.btn .icon { flex: none; transition: transform var(--motion-duration, .2s) ease; } /* CP12B: transition added (was declared on .text-link .icon only); inert until a hover rule below actually changes transform. */
.btn--primary { background: var(--color-action-primary); color: var(--color-text-on-action); }
.btn--primary:hover { background: var(--color-action-primary-hover); }
/* Figma Button / Primary + Secondary / Focus: 2 px ring drawn inside the button (light: border-focus; on dark surfaces border-focus-inverse). */
.btn--primary:focus-visible, .btn--secondary:focus-visible { outline: 2px solid var(--color-border-focus); outline-offset: -2px; }
.on-dark .btn--primary:focus-visible, .on-dark .btn--secondary:focus-visible { outline-color: var(--color-border-focus-inverse); }
/* Secondary: 1 px border drawn inside, so it is 52 px high like Primary. */
.btn--secondary { background: transparent; color: var(--color-text-primary); box-shadow: inset 0 0 0 1px var(--color-border-strong); }
.btn--secondary:hover { background: var(--color-bg-inverse); box-shadow: inset 0 0 0 1px var(--color-bg-inverse); } /* Figma Secondary / Light / Hover: filled dark, white text (colour set below) */
.on-dark .btn--secondary { color: var(--color-text-inverse); box-shadow: inset 0 0 0 1px var(--color-border-strong-inverse); }
.on-dark .btn--secondary:hover { background: var(--color-bg-secondary); box-shadow: inset 0 0 0 1px var(--color-bg-secondary); } /* Figma Secondary / Dark / Hover: filled white, dark text */
.btn--text { min-height: 44px; padding: var(--spacing-12) 0; background: none; color: inherit; }
.btn--text:hover span { text-decoration: underline; text-underline-offset: 4px; }

/* ---------- logo ---------- */
.logo { display: inline-flex; align-items: center; gap: var(--spacing-12); text-decoration: none; color: var(--color-text-primary); flex: none; }
.logo__mark { width: 48px; height: 48px; }
/* Uploaded logo only (Nastavitve kluba → Znak kluba): white circle (Figma "Mark") with the emblem inset
   and object-fit: contain, so it is never distorted or cropped. The theme's own placeholder logo.svg
   already draws its own circle and stays a plain <img class="logo__mark"> — this rule never touches it. */
.logo__mark--custom { display: flex; align-items: center; justify-content: center; flex: none; background: var(--color-bg-secondary); border-radius: 50%; padding: 4px; box-sizing: border-box; overflow: hidden; }
.logo__emblem { display: block; width: 100%; height: 100%; object-fit: contain; }
.logo__name { display: flex; flex-direction: column; }
.logo__line1 { font-size: var(--typography-small-size); line-height: 22px; }
.logo__line2 { font-size: var(--typography-caption-size); line-height: 16px; color: var(--color-text-secondary); }
.logo--dark { color: var(--color-text-inverse); }
.logo--dark .logo__line2 { color: var(--color-text-inverse); }

/* ---------- header (Figma: Navbar Light / Overlay / Scrolled) ---------- */
/* WordPress wraps each <!-- wp:template-part --> in its own div ("site-header-part", set via the block's
   className attribute in templates/*.html) which contains only the header — so, unstyled, that wrapper is
   exactly the header's own height. position:sticky's usable "stuck" range is bounded by its containing
   block (here, that wrapper): with zero extra height in it, sticky had zero range and the header simply
   scrolled away with the page instead of sticking (confirmed live: header tracked scrollY 1:1, never
   clamping at top:0). display:contents removes the wrapper from the box tree so .site-header's containing
   block becomes .wp-site-blocks/<body> (the full page height) instead — the standard fix for this template
   -part-wrapper-breaks-sticky-header gotcha. Scoped to this one wrapper class; nothing else styles it. */
.site-header-part.wp-block-template-part { display: contents; }
.site-header { position: sticky; top: var(--wp-admin-bar-h, 0px); z-index: 50; background: var(--color-bg-primary); color: var(--color-text-primary); transition: background-color .2s ease, box-shadow .2s ease, color .2s ease; }
.site-header__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-32); height: var(--layout-nav-height); padding-inline: var(--layout-margin); max-width: calc(var(--layout-container-width) + 2 * var(--layout-margin)); margin-inline: auto; transition: height .2s ease; }
.site-header__actions { display: flex; align-items: center; gap: var(--spacing-48); }
/* --wp-admin-bar-h (both header variants — an overlay-page header carries BOTH "site-header" and
   "site-header--overlay" classes, so it reads the same property) is set by site.js from #wpadminbar's own
   live getBoundingClientRect(), every scroll/resize/orientationchange frame — not from a WP-version/
   viewport-width assumption about whether the admin bar is position:fixed or position:absolute at a given
   breakpoint (that assumption did not hold: a real logged-in mobile Safari test showed the admin bar still
   on screen, and still needing an offset, after scrolling — see assets/js/site.js for the measurement).
   Falls back to 0px for a logged-out visitor (#wpadminbar absent — see 0px default and site.js's own
   early-out) or before JS runs, matching the original no-admin-bar behavior exactly. */

/* Overlay: only on the front page, over the hero. Must stay position:fixed, NOT sticky: sticky still
   reserves its own box's height in normal document flow (like static/relative), which pushed .hero down
   by the header's height and broke the whole transparent-over-hero effect (confirmed live: with sticky,
   .hero's rect.top was 64–80px instead of 0, so the still-correctly-transparent header sat over the plain
   page background instead of the hero image — a white-on-white regression, not a color/cascade bug).
   fixed removes it from flow entirely, which is what "floats over the hero, hero starts at y:0" requires;
   the explicit top: (after inset, which itself only sets a top:0 fallback) reads the same live
   --wp-admin-bar-h property as the base .site-header rule above. */
.site-header--overlay { position: fixed; inset: 0 0 auto 0; top: var(--wp-admin-bar-h, 0px); background: transparent; color: var(--color-text-inverse); }
.site-header--overlay .logo { color: var(--color-text-inverse); }
.site-header--overlay .logo__line2 { color: var(--color-text-inverse); }

/* Scrolled (after 80 px): solid, lower, soft shadow. */
.site-header.is-scrolled { background: var(--color-bg-primary); color: var(--color-text-primary); box-shadow: 0 2px 12px rgba(0,0,0,.08); }
.site-header.is-scrolled .site-header__inner { height: 64px; }
.site-header.is-scrolled .logo { color: var(--color-text-primary); }
.site-header.is-scrolled .logo__line2 { color: var(--color-text-secondary); }
.site-header.is-scrolled .logo__mark { width: 40px; height: 40px; }

/* Desktop navigation */
.nav--desktop .nav__list { display: flex; align-items: center; gap: var(--spacing-32); }
.nav__item { position: relative; }
.nav__row { display: flex; align-items: center; gap: var(--spacing-4); }
.nav__link { display: block; padding: var(--spacing-8) var(--spacing-4); font-size: var(--typography-navigation-size); line-height: var(--typography-navigation-line-height); font-weight: 500; text-decoration: none; position: relative; }
/* Figma NavLink: 8 + 20 (label) + 4 + 2 (underline) + 8 = 42 px tall; the label sits 3 px above the bar centre. */
.nav--desktop .nav__link { padding-bottom: 14px; }
.nav--desktop .nav__link::after { content: ""; position: absolute; left: var(--spacing-4); right: var(--spacing-4); bottom: var(--spacing-8); height: 2px; background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform .2s ease; }
.nav--desktop .nav__link:hover::after, .nav--desktop .is-current > .nav__row .nav__link::after { transform: scaleX(1); }
.nav--desktop .is-current > .nav__row .nav__link::after { background: var(--color-action-primary); }
.nav__toggle { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: calc(-1 * var(--spacing-4)); border-radius: var(--radius-small); }
.nav__toggle .icon { width: 16px; height: 16px; transition: transform .2s ease; }
.nav__toggle[aria-expanded="true"] .icon { transform: rotate(180deg); }
/* Desktop: Figma shows no chevrons. The toggle stays in the DOM and keyboard-focusable (disclosure pattern),
   it is only visually hidden; on keyboard focus it appears next to its link without moving the layout. */
.nav--desktop .nav__toggle { position: absolute; top: 50%; left: 100%; margin: 0; width: 24px; height: 24px; transform: translateY(-50%); opacity: 0; }
.nav--desktop .nav__toggle:focus-visible { opacity: 1; background: var(--color-surface-primary); color: var(--color-text-primary); }

/* Desktop dropdown (Figma: Nav Dropdown) */
.nav--desktop .nav__submenu { position: absolute; top: calc(100% + 5px); left: calc(-1 * var(--spacing-16)); min-width: 280px; padding: var(--spacing-8); background: var(--color-surface-primary); color: var(--color-text-primary); border-radius: var(--radius-medium); box-shadow: 0 8px 24px rgba(0,0,0,.10); z-index: 60; }
.nav--desktop .nav__item--parent::before { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 5px; } /* hover bridge */
.nav--desktop .nav__item--parent:hover > .nav__submenu[hidden] { display: block !important; }
.nav--desktop .nav__sub-link { display: flex; flex-direction: column; gap: var(--spacing-4); padding: var(--spacing-12) var(--spacing-16); border-radius: var(--radius-small); text-decoration: none; }
.nav--desktop .nav__sub-link:hover { background: var(--color-bg-primary); }
.nav__sub-title { font-size: var(--typography-navigation-size); line-height: var(--typography-navigation-line-height); font-weight: 500; }
.nav__sub-desc { font-size: var(--typography-small-size); line-height: var(--typography-small-line-height); color: var(--color-text-secondary); }

/* Language switcher (Figma: Caption typography, 12px/16px — identical at every breakpoint's token set,
   unlike Navigation's 15/17px, so one base declaration covers desktop/tablet/mobile with no duplication). */
.lang { display: flex; align-items: center; gap: var(--spacing-8); font-size: var(--typography-caption-size); line-height: var(--typography-caption-line-height); font-weight: 500; }
.lang__item { text-decoration: none; opacity: .72; padding: var(--spacing-8) 0; }
.lang__item.is-current { opacity: 1; text-decoration: underline; text-underline-position: from-font; text-decoration-thickness: from-font; }
.lang__item:hover { opacity: 1; }
.lang__sep { opacity: .72; }
/* Overlay header (Figma Surface=Dark): inactive language and separator are solid border-strong-inverse, no opacity. */
.site-header--overlay:not(.is-scrolled) .lang__item:not(.is-current), .site-header--overlay:not(.is-scrolled) .lang__sep { opacity: 1; color: var(--color-border-strong-inverse); }
.site-header--overlay:not(.is-scrolled) .lang__item:not(.is-current):hover { color: var(--color-text-inverse); }

/* Menu button (Figma: Mobile Menu Button, 48 x 48) */
.menu-button { display: none; align-items: center; justify-content: center; width: 48px; height: 48px; border-radius: var(--radius-small); box-shadow: inset 0 0 0 1px var(--color-border-strong); }
.site-header--overlay:not(.is-scrolled) .menu-button { box-shadow: inset 0 0 0 1px var(--color-border-strong-inverse); }

@media (max-width: 1199px) {
	.nav--desktop, .site-header__cta { display: none; }
	.menu-button { display: inline-flex; }
	.site-header__actions { gap: var(--spacing-24); }
	.site-header.is-scrolled .site-header__inner { height: 56px; }
	.site-header.is-scrolled .menu-button { width: 44px; height: 44px; }
}
/* Figma Tablet (115:29412;37:401 metadata): Navbar Overlay is Fill width (left:0/right:0), not capped —
   .site-header__inner duplicated .container's max-width formula without its matching max-width:none
   override, so above 768px it stayed a fixed 768px box centred in the viewport instead of stretching
   full-width like every other section. 16px gap between the language switcher and the menu button, same
   as Figma's Nav Right. Scoped to 768-1199 only — mobile (≤767) is unaudited and must stay untouched. */
@media (min-width: 768px) and (max-width: 1199px) {
	.site-header__inner { max-width: none; }
	.site-header__actions { gap: var(--spacing-16); }
}
/* Figma Mobile (115:29901, Navbar Overlay I115:29902;37:446): Logo (194px) + Nav Right (131px) leave only
   ~17px of natural space-between slack in the 342px content box — the 32px .site-header__inner gap above
   is a wider-breakpoint value that isn't scoped down, so it becomes a forced minimum and pushes the whole
   actions group past the right margin. Dropping the gap to 0 here lets space-between alone govern the
   spacing, fluidly, at any mobile width. Fluid-sanity testing above 390px also reproduced the same
   fixed-centred-box bug the tablet fix (768-1199px block above) already solved for .site-header__inner's
   own max-width formula — it was scoped to 768-1199 only, so ≤767 never got it and the header sat as a
   centred 390px box at any mobile viewport wider than 390 (e.g. 430, 767). Reusing that exact same,
   already-proven max-width:none fix here closes the same gap for mobile. */
@media (max-width: 767px) {
	.site-header__inner { gap: 0; max-width: none; }
	.site-header__actions { gap: var(--spacing-16); }
	.logo__line1 { font-size: 14px; }
}

/* ---------- mobile menu (Figma: Mobile Menu, Tablet 768 x 1024, Mobile 390 x 844) ---------- */
.mobile-menu { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; background: var(--color-bg-primary); color: var(--color-text-primary); overflow-y: auto; overscroll-behavior: contain; padding-bottom: env(safe-area-inset-bottom, 0); }
body.admin-bar .mobile-menu { top: 46px; }
.mobile-menu__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-16); min-height: var(--layout-nav-height); padding-inline: var(--layout-margin); }
.mobile-menu__bar .menu-button { display: inline-flex; }
.mobile-menu__bar-actions { display: flex; align-items: center; gap: var(--spacing-16); }
.nav--mobile { padding: var(--spacing-24) var(--layout-margin) var(--spacing-32); }
.nav--mobile .nav__item { border-bottom: 1px solid var(--color-border-default); }
.nav--mobile .nav__row { justify-content: space-between; }
.nav--mobile .nav__link { flex: 1; padding: var(--spacing-16) 0; font-size: var(--typography-h4-size); line-height: var(--typography-h4-line-height); letter-spacing: var(--typography-h4-letter-spacing); font-weight: 700; }
.nav--mobile .nav__toggle { width: 48px; height: 48px; margin-right: calc(-1 * var(--spacing-12)); }
.nav--mobile .nav__toggle .icon { width: 20px; height: 20px; }
.nav--mobile .nav__submenu { padding: 0 0 var(--spacing-16) var(--spacing-12); }
.nav--mobile .nav__sub-link { display: block; padding: var(--spacing-8) 0; font-size: var(--typography-body-size); line-height: var(--typography-body-line-height); color: var(--color-text-secondary); text-decoration: none; }
.nav--mobile .nav__sub-link:hover, .nav--mobile .nav__sub-link[aria-current] { color: var(--color-text-primary); }
.nav--mobile .nav__sub-title { font-size: inherit; font-weight: 400; }
.mobile-menu__cta { margin-top: auto; padding: var(--spacing-24) var(--layout-margin); }
.mobile-menu__cta .btn { width: 100%; }
@media (min-width: 768px) { .mobile-menu__cta .btn { width: auto; min-width: 50%; } }
html.menu-open { overflow: hidden; }

/* ---------- hero (Figma: Hero — desktop 187:19877, tablet 187:17662, mobile 187:17807) ---------- */
/* Figma Desktop Hero frame is 958px tall — clamp() lets it fill the viewport on real (shorter or taller)
   windows while capping at that design height, rather than hard-coding 958px. Bottom padding is 32px on
   Tablet and Mobile (both instances read identically) but 160px on Desktop — a real per-breakpoint jump,
   not a token-scale value, see the ≥1200px override below. */
.hero { position: relative; display: flex; flex-direction: column; justify-content: flex-end; min-height: clamp(640px, 100svh, 958px); padding: calc(var(--layout-nav-height) + var(--spacing-64)) var(--layout-margin) var(--spacing-32); background: var(--color-bg-inverse); color: var(--color-text-inverse); overflow: hidden; isolation: isolate; }
.hero__media { position: absolute; inset: 0; z-index: -1; }
.hero__media picture, .hero__img { width: 100%; height: 100%; }
.hero__img { object-fit: cover; object-position: var(--hero-focal-desktop-x, 50%) var(--hero-focal-desktop-y, 50%); max-width: none; }
/* Focal point (CP7, inc/render/hero.php): the custom properties are only ever printed inline when a stored
   value differs from center, so with no CMS override every var() falls back to 50% and this is byte-for-byte
   the old object-position: center — same image breakpoints as the <picture> art direction above (599/600,
   899/900), not the layout breakpoints, and no geometry/crop/object-fit here changes. */
@media (min-width: 600px) and (max-width: 899px) {
	.hero__img { object-position: var(--hero-focal-tablet-x, 50%) var(--hero-focal-tablet-y, 50%); }
}
@media (max-width: 599px) {
	.hero__img { object-position: var(--hero-focal-mobile-x, 50%) var(--hero-focal-mobile-y, 50%); }
}
/* Scrim: Tablet and Mobile both carry all three gradients (top for the navbar, a lighter left wash, a
   stronger bottom wash under the buttons); the Desktop instance (node 187:19879) has the left and bottom
   gradient slots zeroed out (fully transparent) — only the top gradient is active there. Confirmed on two
   independent get_design_context reads per breakpoint, not inferred. */
.hero__scrim { position: absolute; inset: 0; background:
	linear-gradient(to bottom, rgba(0,0,0,.5) 0%, rgba(0,0,0,0) 28%),
	linear-gradient(to right, rgba(0,0,0,.25) 0%, rgba(0,0,0,0) 70%),
	linear-gradient(to top, rgba(0,0,0,.82) 0%, rgba(0,0,0,.4) 45%, rgba(0,0,0,0) 80%); }
@media (min-width: 1200px) {
	.hero { padding-bottom: var(--spacing-160); }
	.hero__scrim { background: linear-gradient(to bottom, rgba(0,0,0,.5) 0%, rgba(0,0,0,0) 28%); }
}
.hero__content { display: flex; flex-direction: column; gap: var(--spacing-24); width: 100%; max-width: calc(var(--layout-container-width)); margin-inline: auto; }
.hero__content > * { max-width: 900px; }
.hero__eyebrow { color: var(--color-text-accent-inverse); }
.hero__copy { max-width: 560px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--spacing-16); padding-top: var(--spacing-8); }
/* Figma Tablet (115:29412 metadata): uniform 24px gap throughout Hero Content, same as desktop below.
   Content is bottom-anchored (justify-content:flex-end), so removing the base 8px padding-top shifts the
   content block's top edge down by 8px without changing Hero's own height (governed by min-height, not
   content). */
@media (min-width: 768px) and (max-width: 1199px) {
	.hero__actions { padding-top: 0; }
}
@media (min-width: 1200px) { .hero__actions { padding-top: 0; } } /* Figma Desktop: 24 px between copy and buttons */
/* Scroll cue: visible on Tablet (its own Hero instance carries this node); Desktop's own instance has it
   explicitly hidden (get_design_context omits it entirely for that frame); Mobile's Hero has no such node
   at all. Content/position stay CMS-driven (hero_scroll) — only Desktop visibility is forced off here. */
.hero__scroll { position: absolute; right: var(--layout-margin); bottom: var(--spacing-48); display: inline-flex; align-items: center; gap: var(--spacing-8); color: var(--color-text-inverse); text-decoration: none; }
.hero__scroll:hover { text-decoration: underline; text-underline-offset: 4px; }
@media (min-width: 1200px) {
	.hero__scroll { display: none; }
}
@media (min-width: 1441px) { .hero__scroll { right: calc((100vw - var(--layout-container-width)) / 2); } }
/* Figma Tablet Hero frame is 900px tall — the ≤767 rule below overrides this again for Mobile (780px). */
@media (max-width: 1199px) { .hero { min-height: clamp(640px, 100svh, 900px); } }
@media (max-width: 767px) {
	.hero { min-height: clamp(560px, 100svh, 780px); padding-bottom: var(--spacing-32); }
	/* Figma Mobile (115:29901, Hero I115:29902;37:424): Hero Actions sits flush after Copy (24px gap, same
	   as every other gap in Hero Content), no extra top padding — the base 8px was a pre-mobile-Figma
	   assumption, already corrected for tablet/desktop above but never for ≤767. */
	.hero__actions { flex-direction: column; gap: var(--spacing-12); padding-top: 0; }
	.hero__actions .btn { width: 100%; }
	.hero__scroll { display: none; }
}
#vsebina { display: block; height: 0; outline: 0; }

/* ---------- footer (Figma: Footer) ---------- */
.site-footer { background: var(--color-bg-inverse); color: var(--color-text-inverse); padding: var(--layout-section-padding-y) 0 var(--spacing-32); }
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { text-decoration: underline; text-underline-offset: 4px; }
.site-footer__top { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--layout-gutter); row-gap: var(--spacing-48); }
.site-footer__brand { grid-column: 1 / 6; display: flex; flex-direction: column; gap: 40px; align-items: flex-start; }
.site-footer__about { display: flex; flex-direction: column; gap: var(--spacing-24); align-items: flex-start; }
.site-footer__about > p { margin: 0; }
/* Figma: white brand glyphs (FB 24.3, IG 24.3, YT 31.4 px, 34.5 px apart) under the statement — separate from the
   plain-text "Sledi nam" column further right; both use the same facebook/instagram/youtube options. */
.site-footer__social-icons { display: flex; align-items: center; gap: 34.463px; margin: 0; padding: 0; list-style: none; }
.site-footer__social-icons li { margin: 0; }
.site-footer__social-icon { display: flex; align-items: center; justify-content: center; height: 31.42px; opacity: 1; transition: opacity .15s ease; }
.site-footer__social-icon img { display: block; height: auto; }
.site-footer__social-icon:hover { opacity: .7; text-decoration: none; }
.site-footer__cols { grid-column: 6 / 13; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); column-gap: var(--layout-gutter); row-gap: var(--spacing-32); }
.site-footer__col { grid-column: span 2; }
.site-footer .site-footer__heading { color: var(--color-text-accent-inverse); margin-bottom: var(--spacing-12); }
.site-footer__list { display: flex; flex-direction: column; gap: var(--spacing-12); font-size: var(--typography-small-size); line-height: var(--typography-small-line-height); }
.site-footer__list li { margin: 0; }
.site-footer__bottom { display: flex; justify-content: space-between; gap: var(--spacing-24); margin-top: var(--spacing-64); padding-top: var(--spacing-64); border-top: 1px solid color-mix(in srgb, var(--color-border-strong-inverse) 20%, transparent); }
.site-footer__bottom p { line-height: var(--typography-caption-line-height); }
.site-footer__legal, .site-footer__legal-list { display: flex; flex-wrap: wrap; gap: var(--spacing-8); align-items: center; }
.site-footer__legal > * + *::before, .site-footer__legal-list li + li::before { content: "·"; margin-right: var(--spacing-8); }
@media (max-width: 1199px) {
	.site-footer__brand { gap: var(--spacing-24); } /* Figma Tablet/Mobile: 24 px statement → icons (40 px on Desktop) */
	.site-footer__brand, .site-footer__cols { grid-column: 1 / -1; }
	.site-footer__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.site-footer__col { grid-column: auto; }
}
/* Figma Tablet (115:29536 metadata): 32px column-gap (a third value, distinct from mobile's stacked layout
   and desktop's own 24px gutter reuse), 48px both sides of the divider, and the same caption line-height
   fix already applied to the bottom paragraph at desktop. */
@media (min-width: 768px) and (max-width: 1199px) {
	.site-footer__cols { column-gap: var(--spacing-32); }
	.site-footer__bottom { margin-top: var(--spacing-48); padding-top: var(--spacing-48); }
	.site-footer__bottom p { line-height: var(--typography-caption-line-height); }
}
/* Figma Mobile (115:29901, Footer 115:30013): 48px both sides of the divider here too (Footer Top content
   end → 48 → divider → 48 → Copyright) — the 64/64 base pair above was assumed to be mobile's own value
   when the tablet fix was written, before this mobile frame existed to confirm otherwise. */
@media (max-width: 767px) {
	.site-footer__cols { grid-template-columns: 1fr; }
	.site-footer__bottom { flex-direction: column; gap: var(--spacing-12); margin-top: var(--spacing-48); padding-top: var(--spacing-48); }
}

/* ---------- simple page (until each page gets its Hi-Fi template) ---------- */
.site-main--page { padding-bottom: var(--layout-section-padding-y); }
.page-intro { padding-top: var(--spacing-64); padding-bottom: var(--spacing-48); display: flex; flex-direction: column; gap: var(--spacing-16); }
.page-intro__note { color: var(--color-text-secondary); }
.reading > * { max-width: 735px; }
.reading > * + * { margin-top: var(--spacing-24); }

/* Headings on dark surfaces take the surface text colour (theme.json sets headings to text-primary). */
.on-dark :is(h1, h2, h3, h4) { color: inherit; }

/* Links in header, menus and footer keep their colour on hover (theme.json turns content links red). */
.site-header a:hover, .mobile-menu a:hover, .site-footer a:hover, .hero a.hero__scroll:hover { color: inherit; }
.btn:hover { color: inherit; }
.btn--primary:hover { color: var(--color-text-on-action); }
.btn--secondary:hover { color: var(--color-text-inverse); }
.on-dark .btn--secondary:hover { color: var(--color-text-primary); }
/* Mobile menu: dividers only between top-level items. */
.nav--mobile .nav__submenu .nav__item { border-bottom: 0; }

/* =====================================================================
   Sections (home). Surfaces alternate as in Figma Hi-Fi v1.
   ===================================================================== */
.section { padding-block: var(--layout-section-padding-y); }
.section--compact { padding-block: var(--spacing-64); }
.section--white { background: var(--color-bg-secondary); }
.section--primary { background: var(--color-bg-primary); }
.section--dark { background: var(--color-bg-inverse); color: var(--color-text-inverse); }
.section__more { margin-top: var(--spacing-64); }
.section__actions { margin-top: var(--spacing-64); }

/* Reusable optional section background (opt-in per section — see skif_section_bg()/skif_section_bg_class()
   in inc/helpers.php; V1 wires up only .cta). Purely decorative and absolutely positioned: cannot affect
   section height, padding, grid or content position. .has-bg is the only rule touching .section itself,
   and only on the sections that opt in — .section's own geometry (padding-block above) is untouched. */
.has-bg { position: relative; overflow: hidden; }
.has-bg > .container { position: relative; z-index: 1; }
.section__bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.section__bg::after { content: ''; position: absolute; inset: 0; background: var(--color-bg-inverse); opacity: var(--bg-overlay, 0); }
.section__bg__img { width: 100%; height: 100%; object-fit: cover; object-position: center; max-width: none; }
/* Parallax (opt-in per section via "Ozadje, parallax" — skif_bg_fields()/skif_section_bg() in
   inc/helpers.php add the "section__bg--parallax" class to .section__bg, never to .has-bg/.section, so
   layout/padding/grid stay untouched). Only the image itself moves: .section__bg::after (the overlay)
   lives on the wrapper above, not on this element, so it never shifts with the image. The image is
   absolutely positioned and overscanned 32px on each edge — more than assets/js/site.js's ±24px max
   travel — so translateY can never reveal .has-bg's edge (.has-bg's own overflow:hidden clips it besides).
   With no JS running (var() fallback = 0px) the image sits centered in that overscanned box, i.e. this
   rule alone, with zero active parallax, is the same crop as the non-parallax rule above. */
.section__bg--parallax .section__bg__img {
	position: absolute;
	top: -32px;
	left: 0;
	width: 100%;
	height: calc(100% + 64px);
	transform: translateY(var(--bg-parallax-y, 0px));
	will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
	.section__bg--parallax .section__bg__img { transform: none; }
}
/* Generic content-color pairing for any has-bg section (skif_section_bg_class()): reuses the existing
   .on-dark convention (see .hero/.section--dark/.site-footer) rather than a parallel class — every
   .on-dark component override (buttons, links, section-header) below already applies for free. Only the
   base text color is generic here; a section's own two-tone elements need their own override, same as
   every other .on-dark consumer in this file (e.g. .section-header__eyebrow/__desc further down). */
.has-bg.on-dark { color: var(--color-text-inverse); }

/* Section header (Left / Split) */
.section-header { display: flex; flex-direction: column; gap: var(--spacing-16); margin-bottom: var(--layout-section-header-gap); max-width: 735px; }
.section-header__heading { display: flex; flex-direction: column; gap: var(--spacing-16); }
.section-header__eyebrow { color: var(--color-text-accent); }
.on-dark .section-header__eyebrow { color: var(--color-text-accent-inverse); }
.section-header__desc { color: var(--color-text-secondary); }
.on-dark .section-header__desc { color: var(--color-neutral-300); }
@media (min-width: 1200px) {
	.section-header--split { flex-direction: row; justify-content: space-between; align-items: flex-end; max-width: none; }
	.section-header--split .section-header__heading { width: calc(6 * (100% - 11 * var(--layout-gutter)) / 12 + 5 * var(--layout-gutter)); }
	.section-header--split .section-header__desc { width: calc(4 * (100% - 11 * var(--layout-gutter)) / 12 + 3 * var(--layout-gutter)); }
	/* Figma (Inštruktorji, Novice): a thin vertical rule separates the heading from the side note. */
	.section-header--split .section-header__desc { border-left: 1px solid var(--color-border-strong-inverse); padding-left: var(--spacing-48); }
	.on-dark .section-header--split .section-header__desc { border-left-color: var(--color-border-inverse); }
}

/* Text link (Figma: CTA Text) */
.text-link { display: inline-flex; align-items: center; gap: var(--spacing-12); min-height: 44px; font-size: var(--typography-button-size); line-height: var(--typography-button-line-height); font-weight: 500; text-decoration: none; color: inherit; }
.text-link { position: relative; }
/* Figma Text / Light / Hover: label and arrow in the accent colour, no underline. Dark hover is not compared yet: unchanged. */
.text-link:hover { color: var(--color-text-accent); }
.on-dark .text-link:hover { color: inherit; }
.on-dark .text-link:hover span:first-child { text-decoration: underline; text-underline-offset: 4px; }
.text-link .icon { transition: transform var(--motion-duration, .2s) ease; } /* CP12B: var() with the exact prior literal as fallback — byte-identical .2s when --motion-duration is unset (motion off). */
.on-dark .text-link:hover .icon--arrow-right { transform: translateX(3px); }
/* Figma Text / Focus (Light and Dark): 2 px ring 4 px above/below and 6 px left/right of the link box. */
.text-link:focus-visible { outline: none; }
.text-link:focus-visible::after { content: ""; position: absolute; inset: -4px -6px; border: 2px solid var(--color-border-focus); border-radius: var(--radius-small); pointer-events: none; }
.on-dark .text-link:focus-visible::after { border-color: var(--color-border-focus-inverse); }

/* Two columns: text 1-6, aside 8-12 (Heritage, Tradition) */
.grid-2 { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--layout-gutter); row-gap: var(--spacing-48); }
.grid-2__main { grid-column: 1 / 7; display: flex; flex-direction: column; align-items: flex-start; }
.grid-2__aside { grid-column: 8 / 13; }
@media (max-width: 1199px) { .grid-2__main, .grid-2__aside { grid-column: 1 / -1; } }

/* Media block */
.media { margin: 0; }
.media__frame { position: relative; overflow: hidden; border-radius: var(--radius-small); background: var(--color-neutral-100); }
.media--4-5 .media__frame { aspect-ratio: 4 / 5; }
.media--16-9 .media__frame { aspect-ratio: 16 / 9; }
.media--3-4 .media__frame { aspect-ratio: 3 / 4; }
.media--1-1 .media__frame { aspect-ratio: 1; }
.media__img { width: 100%; height: 100%; object-fit: cover; }
.media--natural .media__img { height: auto; }
@media (min-width: 1200px) { .media--natural .media__frame { aspect-ratio: 4 / 5; } .media--natural .media__img { height: 100%; } }
.media__fallback { position: absolute; inset: 0; display: grid; place-items: center; }
.media__fallback img { width: 48px; height: 48px; opacity: .35; filter: grayscale(1); }
.on-dark .media__frame { background: var(--color-surface-dark); }
.media__caption { margin-top: var(--spacing-12); color: var(--color-text-secondary); }
.on-dark .media__caption { color: var(--color-neutral-300); }
.media--natural:not(:has(.media__img)) .media__frame { aspect-ratio: 4 / 5; }

/* Stats (Heritage, Competitions) */
.stats { margin: 0; display: grid; gap: var(--spacing-32); }
.stat { margin: 0; }
.stat__num { margin: 0; font-variant-numeric: tabular-nums; }
.stat__cap { margin: var(--spacing-8) 0 0; color: var(--color-text-secondary); }
.on-dark .stat__cap { color: var(--color-text-inverse); }
.stats--stack { margin-bottom: var(--spacing-48); }
.stats--row { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--layout-gutter); margin-bottom: var(--spacing-80); }
@media (max-width: 767px) { .stats--row { grid-template-columns: 1fr; margin-bottom: var(--spacing-64); } }

/* Heritage (Figma: Section / Heritage 1975 — desktop 187:20079, tablet 192:51873, mobile 193:52670). Single
   vertical column at every breakpoint, no photo (the archive photo was dropped from this design; her_image
   stays registered — see inc/render/heritage.php). All spacing below reuses existing tokens because their
   own responsive values already match each Figma frame exactly (verified per breakpoint):
   --layout-section-header-gap (64/48/48), --spacing-48/32/16/8. */
.heritage__inner, .heritage__layout, .heritage__content, .heritage__header {
	display: flex; flex-direction: column; align-items: flex-start; width: 100%;
}
.heritage__inner { gap: var(--layout-section-header-gap); }
.heritage__layout { gap: 45px; }
.heritage__content { gap: var(--spacing-48); }
.heritage__header { gap: var(--spacing-16); }
.heritage__eyebrow, .heritage__title, .heritage__intro, .heritage__stats { width: 100%; }
/* Figma Mobile: the eyebrow stays 13px (matches desktop/tablet), not t-eyebrow's global mobile size (12px). */
@media (max-width: 767px) {
	.heritage__eyebrow { font-size: 13px; }
}
/* Section padding: Desktop uses the generic --layout-section-padding-y (120px, via .section); Tablet and
   Mobile both override to a literal 60px (get_design_context on both 192:51873 and 193:52670 confirms
   "py-[60px]" — not the generic 96px/64px section tokens). */
@media (max-width: 1199px) { .heritage { padding-block: 60px; } }
/* Stats: Desktop only puts the 3 stats in one row (183px column gap, 32px padding around the whole block —
   node 187:20084). Tablet and Mobile both STACK them in a single column (gap 24px) instead — confirmed on
   both 192:51881 (Tablet, no divider) and 193:52678 (Mobile, with a 100px divider line between stats,
   node 193:52693/93694). This replaces an earlier "always one row" assumption that did not match either
   frame. .stat__num keeps the plain .t-display class at every breakpoint — Figma uses the Display token
   directly (80/60/44), not a fixed literal size — so no separate stat__num override is needed. */
.heritage .stats--row { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 183px; padding: var(--spacing-32); margin-bottom: 0; }
@media (max-width: 1199px) {
	.heritage .stats--row { grid-template-columns: 1fr; row-gap: var(--spacing-24); padding: 0; }
}
@media (max-width: 767px) {
	.heritage .stat + .stat { position: relative; padding-top: var(--spacing-24); }
	.heritage .stat + .stat::before { content: ""; position: absolute; top: 0; left: 0; width: 100px; height: 1px; background: var(--color-border-default); }
	.heritage .stats--row { row-gap: 0; }
}
/* Generations (Figma: Karate za vsako generacije — desktop 187:20930, tablet 192:52021, mobile 193:52695).
   4 fixed cards reusing the same "Getting Started Card" component as Treningi's .growth-card (identical
   values, including the scaled decimals — see .growth-card in the Treningi section below), 2 per row at
   every breakpoint down to Mobile. .generation-card only overrides what differs from that shared card: a
   taller, fixed-height photo (315px, constant across breakpoints per Figma) instead of growth-card's own
   254.143px. */
/* Section padding: Desktop 80px (node 187:20930 "py-[80px]" — not the generic 120px section token),
   Tablet 64px, Mobile 32px (both derived from the header's own top offset within their frames). */
.generations { padding-block: var(--spacing-80); }
@media (max-width: 1199px) { .generations { padding-block: var(--spacing-64); } }
@media (max-width: 767px) { .generations { padding-block: var(--spacing-32); } }
.generations__head { display: flex; gap: var(--spacing-48); align-items: flex-start; margin-bottom: var(--spacing-48); }
.generations__intro { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 12px; color: var(--color-text-primary); }
.generations__lead { flex: 0 0 409px; max-width: 409px; padding-top: 12px; margin: 0; color: var(--color-text-accent); }
@media (max-width: 1199px) {
	.generations__head { flex-direction: column; gap: 36px; margin-bottom: var(--spacing-32); }
	.generations__lead { flex-basis: auto; max-width: none; width: 100%; padding-top: 0; }
}
/* Card gap is a constant 53px in both directions at every breakpoint (confirmed on Desktop, Tablet and
   Mobile metadata — Mobile stacks to 1 column but keeps the same 53px vertical gap, not a smaller one). */
.generation-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 53px; }
@media (max-width: 767px) { .generation-grid { grid-template-columns: 1fr; } }
.generation-card .growth-card__image { height: 315px; }
/* Focal point (CP8, inc/render/generations.php): X/Y custom properties on .growth-card__image, defaulting to
   50%/100% — the same value as the old literal "bottom" — so with no CMS override this is byte-for-byte the
   previous rule. Separate from Treningi's own --growth-card-position (shared .growth-card__img rule above,
   left untouched); scoped to .generation-card only, so Treningi's growth cards are unaffected either way. */
.generation-card .growth-card__img { object-position: var(--generation-card-focal-x, 50%) var(--generation-card-focal-y, 100%); }
/* Figma: the card eyebrow ("ZAČETNIKI" etc.) is the Eyebrow text style (13px bold, uppercase, letter-spaced)
   — scoped to Generations only, .growth-card__eyebrow itself (shared with Treningi's own cards) is untouched. */
.generation-card .growth-card__eyebrow { text-transform: uppercase; font-size: var(--typography-eyebrow-size); line-height: var(--typography-eyebrow-line-height); letter-spacing: var(--typography-eyebrow-letter-spacing); font-weight: 700; }

.stretched { text-decoration: none; color: inherit; }
.stretched::after { content: ""; position: absolute; inset: 0; z-index: 1; }

/* Tradition (Figma: Section / Tradition SKIF — desktop 187:17590, tablet 192:52153, mobile 193:52814).
   All numbers below are measured from those three nodes' get_design_context/get_metadata. */
.tradition { padding-block: 72px; }
.tradition__inner { display: grid; grid-template-columns: 720px minmax(0, 1fr); }
/* Text column: rule → Display title → eyebrow → Body Large copy → CTA. 720 px on desktop, 431 px on tablet,
   the full 342 px container on mobile. Gaps: 24 / 24 / 32 / 32; the copy's blank Figma paragraphs are one
   28 px line each, so the paragraph gap is 28. */
.tradition__text { display: flex; flex-direction: column; align-items: flex-start; }
.accent-line { display: block; width: 48px; height: 2px; background: var(--color-action-primary); margin-bottom: var(--spacing-24); }
.tradition__statement { margin: 0; }
.tradition__attr { margin-top: var(--spacing-24); color: var(--color-text-accent); }
.tradition__copy { margin-top: var(--spacing-32); display: flex; flex-direction: column; gap: 28px; }
.tradition__copy p { margin: 0; line-height: inherit; }
.tradition__copy + .text-link { margin-top: var(--spacing-32); }
/* Logos: 87 px, 32 px apart — bottom-right of the content box on desktop (bottom edge = CTA's bottom edge). */
.tradition__logos { display: flex; gap: 32px; align-self: end; justify-self: end; }
.tradition__logo { width: 87px; height: 87px; object-fit: cover; }
/* Background: Figma's photo (1282×705) is drawn ~2× and cropped by the section, not cover-fitted.
   Desktop: 2580 px wide at x -487 / y -228 of the 1440×934 section, expressed relative to the section. */
.tradition__bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; container-type: size; }
.tradition__bg-img { position: absolute; max-width: none; height: auto; width: 179.16%; left: -33.79%; top: -24.38%; }
/* Scrim: linear-gradient(to left, black 30% → black 78% at 63.244%) on a box wider than the section
   (desktop 1602 px at x -81 on 1440 px), so the right edge sits at ~34 % darkness, not 30 %. */
.tradition__scrim { position: absolute; top: 0; bottom: 0; left: -5.625%; right: -5.625%; background: linear-gradient(to left, rgba(0,0,0,.3), rgba(0,0,0,.78) 63.244%); }
/* Tablet (768): photo is section-height, right-anchored 712 px past the edge; text column 431 px; logos
   left-aligned 36 px under the CTA (+36 px below); eyebrow is accent-inverse on this frame only. */
@media (max-width: 1199px) {
	.tradition__inner { grid-template-columns: minmax(0, 1fr); }
	.tradition__text { max-width: 431px; }
	.tradition__attr { color: var(--color-text-accent-inverse); }
	.tradition__logos { justify-self: start; margin-block: 36px; }
	.tradition__bg-img { width: auto; height: 100cqh; left: auto; right: -57.96cqh; top: 0; }
	.tradition__scrim { left: -19.4%; right: -62.5%; }
}
/* Mobile (390): section padding is 24 px (not the 96/64 of other sections), text column = full container,
   logos centered; photo right-anchored 730 px past the edge. */
@media (max-width: 767px) {
	.tradition { padding-block: 24px; }
	.tradition__text { max-width: none; }
	.tradition__attr { color: var(--color-text-accent); }
	.tradition__logos { justify-self: center; }
	.tradition__bg-img { right: -61.01cqh; }
	.tradition__scrim { left: -38.2%; right: -89%; }
}

/* Instructors (Figma: Inštruktorji — desktop 187:21256, tablet 192:52184, mobile 193:52841). Cards reuse the
   .growth-card shell (background, radius, shadow — see Treningi section below).
   All three Figma frames use the DESKTOP type values (H1 60/66, H3 32/40, Small 14/22, Eyebrow 13/16 — metadata
   heights confirm it at 768/390 too), except the card title on Tablet (24/32) and the rank on Mobile (Eyebrow
   style) — so the values below are explicit rather than the mode-switching tokens.
   Section padding: 96 px desktop/tablet, 32 px on all four sides on mobile (container inset 32, not 24). */
.instructors { padding-block: 96px; }
.instructors__header { display: flex; flex-direction: column; gap: 48px; margin-bottom: 48px; }
.instructors__heading { display: flex; flex-direction: column; gap: 12px; }
.instructors__eyebrow { margin: 0; color: var(--color-text-accent); font-size: 13px; line-height: 16px; letter-spacing: 1.8px; }
.instructors__title { margin: 0; color: var(--color-text-primary); font-size: 60px; line-height: 66px; font-weight: 700; letter-spacing: -1.2px; }
.instructors__intro { display: flex; align-items: center; gap: 48px; }
.instructors__lead { flex: 1 1 0; min-width: 0; margin: 0; color: var(--color-text-primary); font-size: var(--typography-body-large-size); line-height: var(--typography-body-large-line-height); }
.instructors__statement { display: flex; align-items: center; gap: 48px; flex: none; }
.instructors__divider { flex: none; width: 0; height: 92px; border-left: 1px solid var(--color-text-accent); margin-right: -1px; }
.instructors__accent { width: 409px; margin: 0; color: var(--color-text-accent); font-size: var(--typography-body-large-size); line-height: var(--typography-body-large-line-height); }
.instructor-card { gap: 8.591px; }
.instructor-card__photo { position: relative; height: 391px; flex: none; background: var(--color-bg-secondary); padding: 12px; box-sizing: border-box; }
.instructor-card__img { display: block; width: 100%; height: 100%; object-fit: contain; }
.instructor-card__photo .media__fallback { position: static; display: grid; place-items: center; width: 100%; height: 100%; }
.instructor-card .growth-card__body { flex: 1 1 auto; padding-bottom: 34.363px; } /* Figma: card padding-bottom 22.909 + text-block padding 11.454 */
.instructor-card .growth-card__title { color: #000; font-size: 32px; line-height: 40px; letter-spacing: -.3px; }
.instructor-card__rank { color: var(--color-text-accent); margin: 0; font-size: 15px; line-height: 20px; font-weight: 500; letter-spacing: .1px; }
.instructor-card__rule { margin: 0; height: .5px; }
.instructor-card__desc { color: #000; margin: 0; font-size: 14px; line-height: 22px; }
/* CTA block (separator + link) is pushed to the bottom of the card so all three cards line up whatever their bio length; absent entirely without link_url. */
.instructor-card__cta { margin-top: auto; display: flex; flex-direction: column; gap: 24.34px; }
.instructor-card__sep { height: 0; margin: 0 0 -.5px; border: 0; border-top: .5px solid var(--color-text-accent); }
.instructor-card__link { font-size: 12px; line-height: 16px; }
@media (min-width: 768px) and (max-width: 1199px) {
	.instructor-grid { gap: 24px; }
	.instructors__intro { align-items: center; }
	.instructors__lead { flex: none; width: 399px; }
	.instructors__statement { flex: 1 1 0; min-width: 0; }
	.instructors__divider { height: 200px; border-left-color: #231f20; }
	.instructors__accent { width: auto; flex: 1 1 0; min-width: 0; }
	.instructor-card .growth-card__title { font-size: 24px; line-height: 32px; letter-spacing: -.1px; }
}
@media (max-width: 767px) {
	.instructors { padding-block: 32px; }
	.instructors > .container { padding-inline: 32px; }
	.instructors__intro { flex-direction: column; align-items: stretch; }
	.instructors__lead { flex: none; }
	.instructors__statement { align-self: stretch; }
	.instructors__divider { height: 200px; border-left-color: #231f20; }
	.instructors__accent { width: auto; flex: 1 1 0; min-width: 0; }
	.instructor-card__rank { font-size: 13px; line-height: 16px; font-weight: 700; letter-spacing: 1.8px; text-transform: uppercase; }
}

/* Trainings (Figma: Section / Trainings — desktop 190:21429, tablet 192:52245, mobile 193:52902). All numbers
   below are read from those three nodes. Blocks are 64 px apart on Desktop, 60 px on Tablet/Mobile. */
.trainings { position: relative; overflow: hidden; }
.trainings__inner { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 64px; }
@media (max-width: 1199px) { .trainings__inner { gap: 60px; } }

.trainings__header { display: flex; flex-direction: column; gap: 16px; max-width: 628px; }
.trainings__header > * { margin: 0; }
.trainings__eyebrow { color: var(--color-text-accent); }
.trainings__desc { color: var(--color-text-secondary); }
@media (max-width: 767px) { .trainings__header { max-width: none; } }

/* Shared white card chrome (schedule, Honbu, contact — Figma "Getting Started Card", radius 2.864). */
.trainings-card { position: relative; background: var(--color-bg-secondary); border-radius: 2.864px; box-shadow: 0 5.727px 17.181px -4.295px rgba(0, 0, 0, .08); overflow: hidden; }
/* Plain white panel (still used by other sections). */
.panel { background: var(--color-bg-secondary); border-radius: var(--radius-small); box-shadow: 0 8px 24px -6px rgba(0,0,0,.08); }

/* Schedule cards (training_group CPT: time/title/audience/location). Card = 32 px padding + 22.9 px bottom. */
.schedule-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 53px; }
.schedule-card { padding: 32px 32px 54.909px; display: flex; flex-direction: column; gap: 24.34px; }
.schedule-card__text { display: flex; flex-direction: column; gap: 11.454px; }
.schedule-card__text > * { margin: 0; }
.schedule-card__eyebrow { color: var(--color-text-accent); }
.schedule-card__name, .schedule-card__audience { color: #000; }
.schedule-card__sep { height: .5px; border: 0; margin: 0 0 -.5px; background: var(--color-text-accent); }
.schedule-card__location { display: flex; align-items: center; gap: 12px; margin: 0; color: var(--color-text-accent); font-size: var(--typography-caption-size); line-height: var(--typography-caption-line-height); }
.schedule-card__pin { flex: none; width: 31px; height: 31px; }
@media (max-width: 767px) { .schedule-grid { grid-template-columns: 1fr; } }

/* Honbu Dojo banner: white card, dojo photo (object-cover) faded in from the right by a gradient alpha mask
   — Desktop/Tablet: banner is 1280 px wide (card clips it), photo 100 % at the right edge → 0 at 66.3 % from
   the right; Mobile: 502×658 banner, mask 60 % → 20 %. */
.honbu-card { display: flex; flex-direction: column; align-items: flex-start; gap: 56px; padding: 32px; }
.honbu-card__bg { position: absolute; left: 0; top: 0; width: 1280px; height: 100%; z-index: 0; -webkit-mask-image: linear-gradient(to left, #fff 0, rgba(255,255,255,0) 66.3462%); mask-image: linear-gradient(to left, #fff 0, rgba(255,255,255,0) 66.3462%); }
.honbu-card__img { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.honbu-card__content, .honbu-card__actions { position: relative; z-index: 1; }
.honbu-card__content { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 578px; }
.honbu-card__copy { display: flex; flex-direction: column; gap: 16px; color: var(--color-text-primary); }
.honbu-card__copy > * { margin: 0; }
.honbu-card__eyebrow { margin: 0; color: var(--color-text-accent); }
@media (max-width: 767px) {
	.honbu-card__bg { left: -1px; top: -2px; width: 502px; height: calc(100% + 4px); -webkit-mask-image: linear-gradient(to left, rgba(255,255,255,.6) 18.0742%, rgba(255,255,255,.2) 70.0522%); mask-image: linear-gradient(to left, rgba(255,255,255,.6) 18.0742%, rgba(255,255,255,.2) 70.0522%); }
}

/* Kje treniramo: 573 px map (345 px on Mobile). The location card overlaps the map's bottom-left on Desktop
   (left 68, top 305.4, hanging 127 px below the map, into the 120 px above the contact card) and on Tablet
   (23 px inset, 658 wide, top 433.4). On Mobile Figma puts it in normal flow BELOW the map. */
.trainings-where { display: flex; flex-direction: column; gap: 24px; }
.trainings-where__head { display: flex; flex-direction: column; gap: 24px; }
.trainings-where__head > * { margin: 0; }
.trainings-where__map { position: relative; }
.trainings-where__embed { border-radius: 4px; overflow: hidden; height: 573px; }
.trainings-where__embed iframe { display: block; width: 100%; height: 100%; border: 0; }
.location-card { position: absolute; z-index: 2; left: 68px; top: 305.42px; width: 438px; box-sizing: border-box; padding: 32px; display: flex; flex-direction: column; align-items: flex-start; background: var(--color-bg-secondary); border-radius: 4px; box-shadow: 0 12px 32px rgba(0, 0, 0, .14); }
.location-card__body { display: flex; flex-direction: column; gap: 11.454px; width: 100%; }
.location-card__place { display: flex; flex-direction: column; gap: 11px; }
.location-card__place > * { margin: 0; }
.location-card__label { color: var(--color-text-accent); }
.location-card__address { color: #000; }
.location-card__sep { flex: none; height: .5px; border: 0; margin: 0 0 -.5px; background: var(--color-text-accent); }
.location-card__term { display: flex; align-items: center; gap: 20px; }
.location-card__clock { flex: none; width: 81px; height: 81px; }
.location-card__term-text { display: flex; flex-direction: column; gap: 4px; flex: 1 1 0; min-width: 0; }
.location-card__term-text > * { margin: 0; }
.location-card__term-title { color: var(--color-text-primary); }
.location-card__term-text .t-body, .location-card__time { color: #000; }
.location-card__cta { margin-top: 42px; }
.location-card__cta img { flex: none; }
@media (max-width: 1199px) {
	.location-card { left: 23px; right: 23px; top: 433.42px; width: auto; padding: 32px 30px; }
	.location-card__body { flex-direction: row; align-items: center; gap: 11px; }
	.location-card__place { flex: none; width: 300px; }
	.location-card__sep { width: .5px; height: 106px; margin: 0; }
	.location-card__term { gap: 0; }
	.location-card__clock { margin-right: -4px; }
	.location-card__term-text { flex: none; width: 184px; }
	.location-card__cta { margin-top: 24px; }
}
@media (max-width: 767px) {
	.trainings-where__embed { height: 345px; }
	.location-card { position: static; left: auto; right: auto; top: auto; margin-top: 60px; }
	.location-card__body { flex-direction: column; align-items: stretch; gap: 24px; }
	.location-card__place { width: 100%; padding-block: 10px; }
	.location-card__sep { width: 100%; height: 1px; margin: 0; background: #000; }
	.location-card__term { justify-content: space-between; }
	.location-card__term-text { flex: none; }
	.location-card__cta { width: 100%; max-width: 342px; box-sizing: border-box; }
}

/* Contact card (Figma "INFO"): Desktop = intro (596) | 201 px black divider | contacts; Tablet = 280 | divider | 280;
   Mobile = stacked with a horizontal divider. 120 px of air above it on Desktop/Tablet (where the location card hangs). */
.trainings-info { padding-top: 120px; }
.contact-cta-card { display: flex; align-items: flex-start; gap: 44px; padding: 32px; }
.contact-cta-card__intro { flex: none; width: 596px; display: flex; flex-direction: column; gap: 11.454px; margin: 3.05px 16px 0 0; /* Figma: text block centered in the 201 px divider height */ }
.contact-cta-card__intro > * { margin: 0; }
.contact-cta-card__eyebrow { color: var(--color-text-accent); }
.contact-cta-card__desc { color: #000; }
.contact-cta-card__sep { flex: none; width: 1px; height: 201px; margin-right: -1px; background: #000; }
.contact-cta-card__actions { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 24px; padding-top: 30px; }
.contact-cta-card__row { display: flex; align-items: center; gap: 24px; width: 100%; margin: 0; }
.contact-cta-card__row img { flex: none; }
.contact-cta-card__row a { color: var(--color-text-accent); text-decoration: none; }
.contact-cta-card__row a:hover { text-decoration: underline; }
@media (max-width: 1199px) {
	.contact-cta-card { gap: 40px; }
	.contact-cta-card__intro { width: 280px; margin: 0; }
	.contact-cta-card__sep { align-self: center; margin: 0 -1px 0 0; }
}
@media (max-width: 767px) {
	.trainings-info { padding-top: 0; margin-top: -32px; }
	.contact-cta-card { flex-direction: column; align-items: stretch; gap: 20px; }
	.contact-cta-card__intro { width: 100%; }
	.contact-cta-card__sep { align-self: stretch; width: auto; height: 1px; margin: 9.5px 0; }
	.contact-cta-card__actions { flex: none; padding-top: 10px; }
}

/* Tags (Figma: Tag) */
.tag { display: inline-flex; align-items: center; padding: var(--spacing-4) var(--spacing-12); border: 1px solid currentColor; border-radius: var(--radius-small); font-size: var(--typography-eyebrow-size); line-height: var(--typography-eyebrow-line-height); letter-spacing: var(--typography-eyebrow-letter-spacing); font-weight: 700; text-transform: uppercase; }
.tag--accent { color: var(--color-text-accent); }

/* Competitions: latest result (date 1-2, content 3-8, placement 9-10, download right) */
.result-list { border-bottom: 1px solid var(--color-border-inverse); }
/* A thin divider between rows (list now shows up to 5 results, was 1), same colour as the list's existing
   closing border-bottom above. First row unaffected, so a 1-result list still looks exactly as before. */
.result + .result { border-top: 1px solid var(--color-border-inverse); }
.result { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--layout-gutter); row-gap: var(--spacing-12); align-items: center; padding-block: var(--spacing-32); }
.result__date { grid-column: 1 / 3; }
.result__content { grid-column: 3 / 9; display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-8); }
.result__meta { color: var(--color-text-inverse); white-space: pre-wrap; } /* Figma: white, the double spaces around the dots are kept */
.competitions .tag { border-color: var(--color-border-strong-inverse); }
.result__placement { grid-column: 9 / 11; color: var(--color-text-accent-inverse); }
.result__download { grid-column: 11 / 13; justify-self: end; }
@media (max-width: 1199px) {
	.result { grid-template-columns: 1fr; align-items: start; }
	.result__date, .result__content, .result__placement, .result__download { grid-column: 1; justify-self: start; }
}
/* Figma Tablet (115:29488/98 metadata): 48 px below the stats (a third value, distinct from mobile/desktop's
   64), 24 px row padding, 48 px before "Vsi rezultati" — confirmed independently on the tablet frame.
   .result is scoped to .competitions on purpose even though it's the only current user, so this rule stays
   inert if .result is ever reused elsewhere without a tablet audit of its own. */
@media (min-width: 768px) and (max-width: 1199px) {
	.competitions .stats--row { margin-bottom: var(--spacing-48); }
	.competitions .result { padding-block: var(--spacing-24); }
	.competitions .section__more { margin-top: var(--spacing-48); }
}
/* Figma Mobile (115:29901, Competitions 115:29967): confirmed distinct from the shared ≤1199px rule above
   and the tablet/desktop overrides — those are wider-breakpoint values never scoped down for ≤767.
   Stats→List 48px (the generic ≤767 .stats--row rule above is a different, wider value, so this stays
   scoped to .competitions like tablet/desktop already do). Result Item padding-block is 24px top / 25px
   bottom, read directly off 115:29978 (Date starts at y=24; item ends 25px after the Download CTA) — an
   asymmetric Figma value, not a rounding artifact to normalize away. List→CTA 48px. The Download CTA
   itself is a known CMS gap (result_doc has no file attached) and is intentionally left untouched here. */
@media (max-width: 767px) {
	.competitions .stats--row { margin-bottom: var(--spacing-48); }
	.competitions .result { padding-block: 24px 25px; }
	.competitions .section__more { margin-top: var(--spacing-48); }
}
/* Figma Desktop 1440: 64 px below the numbers, row padding 24 px, and the row as in Figma (gap 48 px: date = 2 columns,
   flexible content, placement 200 px, download link). Only this row; the 12-column grid is not touched. */
@media (min-width: 1200px) {
	.competitions .stats--row { margin-bottom: var(--spacing-64); }
	.result { padding-block: var(--spacing-24); column-gap: var(--spacing-48); grid-template-columns: calc((100% - 11 * var(--layout-gutter)) / 6) minmax(0, 1fr) 200px minmax(155px, auto); }
	.result__date { grid-column: 1; }
	.result__content { grid-column: 2; }
	.result__placement { grid-column: 3; }
	.result__download { grid-column: 4; }
	/* Compact "archive list" density (5 rows instead of 3), desktop only. Local font-size/line-height
	   overrides, not tokens.css — every value stays a scoped override on .competitions' own elements, same
	   technique already used for Heritage's desktop-only type overrides elsewhere in this file. */
	.result { padding-block: var(--spacing-16); }
	.competitions .result__date { font-size: 16px; line-height: 1.3; }
	.competitions .result__content { gap: var(--spacing-4); }
	.competitions .result__content .tag { font-size: 11px; padding: 2px var(--spacing-8); }
	.competitions .result__title { font-size: 20px; line-height: 26px; }
	.competitions .result__meta { line-height: 18px; }
	.competitions .result__placement { font-size: 12px; }
}

/* Club life: tall photo left spans both rows, bottoms aligned */
.club-life__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto; column-gap: var(--layout-gutter); row-gap: var(--spacing-48); }
.club-life__a { grid-row: 1 / 3; display: flex; flex-direction: column; }
.club-life__a .media__frame { flex: 1; min-height: 320px; }
.club-life__c { align-self: end; }
@media (max-width: 1199px) {
	.club-life__grid { row-gap: var(--spacing-24); }
	.club-life__a { grid-column: 1 / -1; grid-row: auto; }
	.club-life__a .media__frame { aspect-ratio: 16 / 9; flex: none; min-height: 0; }
	.club-life__c { align-self: start; }
}
/* Figma Mobile (115:29901, Club Life Grid 115:29983): items A/B/C (115:29984-86) are all identical
   342 x 220.375 (16:9) — item A no longer gets its own taller ratio here, so it falls back to the shared
   ≤1199px rule above (aspect-ratio: 16/9), matching B and C exactly. Desktop's own 4:5 tall-photo
   masonry (≥1200px block below) is untouched. */
@media (max-width: 767px) { .club-life__grid { grid-template-columns: 1fr; } }
/* Figma Desktop 1440: everything top-aligned (no bottom alignment), 24 px between the two right photos,
   tall photo 4:5. The second row takes the leftover height so the right photos keep their natural size. */
@media (min-width: 1200px) {
	.club-life__grid { row-gap: var(--spacing-24); grid-template-rows: auto 1fr; align-items: start; }
	.club-life__a .media__frame { flex: none; aspect-ratio: 4 / 5; min-height: 0; }
	.club-life__c { align-self: start; }
}

/* Events (date 1-2, content 3-10, tag right) */
.event-list { border-top: 1px solid var(--color-border-default); }
.event { position: relative; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--layout-gutter); align-items: center; padding-block: var(--spacing-32); border-bottom: 1px solid var(--color-border-default); }
.event__date { grid-column: 1 / 3; margin: 0; }
.event__date time { display: flex; flex-direction: column; gap: var(--spacing-4); }
.event__month { color: var(--color-text-accent); }
.event__content { grid-column: 3 / 11; display: flex; flex-direction: column; gap: var(--spacing-8); }
.event__place { display: flex; align-items: center; gap: var(--spacing-8); color: var(--color-text-secondary); }
/* Wraps 1-N .tag.tag--accent badges (an event can have more than one event_category term — see
   inc/render/events.php). A single tag looks exactly as before: this is just a flex box around it. */
.event__tags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-16); grid-column: 11 / 13; justify-self: end; justify-content: flex-end; }
.event:hover .event__title a { text-decoration: underline; text-underline-offset: 4px; }
/* Figma Mobile (115:29901, Event Item 115:29998): Date stacks above Content, Tag below, 16px gaps between
   all three — confirmed distinct from the side-by-side Date+Content grid this block used before mobile had
   its own Figma frame. Day/Month sit side by side within Date (Figma: Day 35px, 12px gap, Month 30px,
   vertically centred), not stacked. Content keeps its own base gap:8 (Title→Location, already matched
   Figma) and is stretched full-width; Date and Tag keep their natural (non-stretched) width.
   .event-list's border-top and .section__more's margin-top are both base/wider-breakpoint values already
   zeroed/reduced for tablet (768-1199px block below) and desktop (≥1200px block below) but never scoped
   down for ≤767 — confirmed via Figma 115:29994 (Event List 454px, no extra border; List→CTA gap 48px). */
@media (max-width: 767px) {
	.event { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-16); padding-block: var(--spacing-24); }
	.event__date time { flex-direction: row; align-items: center; gap: var(--spacing-12); }
	.event__content { align-self: stretch; }
	.event-list { border-top: 0; }
	.events .section__more { margin-top: var(--spacing-48); }
}
/* Figma Tablet (115:29521/22 metadata): Date/Content/Tag as a single flex row with 48 px gaps (not the
   desktop 12-column grid's 24 px gutter reused, which overlapped Content and Tag at this width). Date is
   169.33px in BOTH event items despite different date text, so it's Figma's Fixed sizing, not Hug — no
   matching token exists, so the literal value is used rather than a rounded guess. No border-top; 24 px
   row padding, same as desktop. */
@media (min-width: 768px) and (max-width: 1199px) {
	.event-list { border-top: 0; }
	.event { display: flex; align-items: center; gap: var(--spacing-48); padding-block: var(--spacing-24); }
	.event__date { flex: 0 0 169.33px; }
	.event__content { flex: 1 1 auto; min-width: 0; }
	.event__tags { flex: none; }
	.events .section__more { margin-top: var(--spacing-48); }
}

/* Figma Desktop 1440: event rows 24 px padding, no line above the first row, tag border in the action red. */
@media (min-width: 1200px) {
	.event-list { border-top: 0; }
	.event { padding-block: var(--spacing-24); }
	.events .tag--accent { border-color: var(--color-action-primary); }
}

/* News (Figma: Section / News — desktop 191:22087, tablet 192:52423, mobile 193:53170). Cards reuse the
   .growth-card shell. Desktop/Tablet: 3 equal columns (gap 53 / 16), Mobile: 1 column (gap 16). Header→grid gap
   96 px (Desktop/Tablet), 44 px (Mobile). */
.news__inner { display: flex; flex-direction: column; gap: 96px; }
.news__header { display: flex; align-items: flex-start; gap: 48px; }
.news__heading { display: flex; flex: 1 1 0; min-width: 0; flex-direction: column; gap: 12px; }
.news__heading > * { margin: 0; }
.news__eyebrow { color: var(--color-text-accent); }
.news__title { color: var(--color-text-primary); }
.news__intro { display: flex; flex: 1 1 0; min-width: 0; align-items: center; gap: 48px; }
.news__divider { flex: none; width: 0; height: 92px; margin-right: -1px; border-left: 1px solid #231f20; }
.news__desc { flex: 1 1 0; min-width: 0; margin: 0; color: var(--color-text-accent); }
.news-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 53px; align-items: stretch; }
.news-card { position: relative; gap: 8.591px; }
.news-card__photo { position: relative; aspect-ratio: 391 / 307; background: var(--color-bg-secondary); padding: 12px; box-sizing: border-box; overflow: hidden; }
.news-card__img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease, filter .25s ease; } /* CP12A: filter transition added here, not in the shared photography block below, so it doesn't clobber this existing hover-zoom transition. */
.news-card:hover .news-card__img { transform: scale(1.03); }
.news-card .growth-card__body { flex: 1 1 auto; padding-bottom: 34.363px; }
.news-card__meta { display: flex; align-items: flex-start; gap: 12px; margin: 0; }
.news-card__tag { flex: none; padding: var(--spacing-4) var(--spacing-12); border: 1px solid var(--color-action-primary); border-radius: var(--radius-small); color: var(--color-text-accent); font-size: var(--typography-small-size); line-height: var(--typography-small-line-height); text-transform: uppercase; white-space: nowrap; }
.news-card__date { flex: 1 1 0; min-width: 0; color: #000; font-size: 11.454px; line-height: 18.613px; text-align: right; }
.news-card .growth-card__title { color: #000; }
.news-card__excerpt { margin: 0; color: #000; }
.news-card:hover .growth-card__title a { text-decoration: underline; text-underline-offset: 4px; }
/* Separator + CTA are pushed to the card bottom so every card lines up whatever the title/excerpt length. */
.news-card__cta { margin-top: auto; display: flex; flex-direction: column; gap: 24.34px; }
.news-card__sep { height: 0; margin: 0 0 -.5px; border: 0; border-top: .5px solid var(--color-text-accent); }
.news-card__link { display: flex; align-items: center; gap: 12px; color: var(--color-text-accent); font-size: var(--typography-caption-size); line-height: var(--typography-caption-line-height); }
.news-card__link img { flex: none; }
@media (max-width: 1199px) {
	.news__header { gap: 48px; }
	.news__divider { height: 92px; }
	.news__intro { align-items: center; }
	.news-grid { gap: 16px; }
	.news-card__photo { aspect-ratio: 224 / 175; }
}
@media (max-width: 767px) {
	.news__inner { gap: 44px; }
	.news__header { flex-direction: column; align-items: stretch; gap: 48px; }
	.news__intro { align-self: stretch; }
	.news__divider { height: 148px; }
	.news-grid { grid-template-columns: 1fr; }
	.news-card__photo { aspect-ratio: 342 / 237; }
}

/* Partners (Figma: Section / Partners — desktop 187:17656, tablet 192:52501, mobile 193:53248). Content-driven
   grid (any number of partner posts): 4 columns × 24 px gap on Desktop (compact horizontal cards 302×96, rows
   64 px apart) and Tablet (vertical cards 158×177, rows 24 px), 2 columns on Mobile (159×177). Logos are
   max-size + contain — never cropped or stretched. Section padding is the compact 64 px; 24 px eyebrow→grid. */
.partners__title { margin: 0 0 var(--spacing-24); color: var(--color-text-accent); }
.partner-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 64px 24px; list-style: none; margin: 0; padding: 0; }
.partner { box-sizing: border-box; display: flex; min-width: 0; min-height: 96px; border: 1px solid var(--color-border-default); border-radius: var(--radius-small); overflow: hidden; }
.partner a { display: flex; align-items: stretch; width: 100%; min-width: 0; color: inherit; text-decoration: none; }
.partner__logo-box { flex: none; width: 139px; display: flex; align-items: center; justify-content: center; padding: 12px 12px 10px; box-sizing: border-box; }
.partner__logo { max-width: 100%; max-height: 72px; width: auto; height: auto; object-fit: contain; }
.partner__info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: var(--spacing-8); padding: 12px; color: #000; overflow-wrap: anywhere; }
.partner__site { color: #000; }
@media (max-width: 1199px) {
	.partner-strip { row-gap: 24px; }
	.partner { min-height: 177px; }
	.partner a { flex-direction: column; }
	.partner__logo-box { width: 100%; height: 87.5px; padding: 12px 12px 3.5px; }
	.partner__info { flex: 1 1 0; justify-content: center; }
}
@media (max-width: 767px) { .partner-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Final CTA (Figma: CTA Section — desktop 191:23311, tablet 192:52654, mobile 193:53343). Light section, dark
   text; type is Display 80/84 at ALL breakpoints (Figma keeps it — 3 lines on Mobile), 24 px between eyebrow,
   title and text, 64 px before the button. Padding 120 / 120 / 80 px (Desktop / Tablet / Mobile). */
.cta { padding-block: 120px; }
.cta__inner { display: flex; flex-direction: column; align-items: flex-start; gap: 64px; }
.cta__content { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-24); width: 100%; }
.cta__content > * { margin: 0; }
.cta__eyebrow { color: var(--color-text-accent); }
.cta__title { color: var(--color-text-primary); font-size: 80px; line-height: 84px; font-weight: 700; letter-spacing: -2px; }
.cta__desc { color: var(--color-text-secondary); }
.cta__actions { padding: 0; }
/* Light content colour (only when a CMS photo is set, skif_section_bg_class()): colour-only overrides. */
.cta.on-dark .cta__eyebrow { color: var(--color-text-accent-inverse); }
.cta.on-dark .cta__title { color: var(--color-text-inverse); }
.cta.on-dark .cta__desc { color: var(--color-neutral-300); }
/* Theme photo. Desktop: image stretched to 1637×637 at y −76.6 of the 1440×560 section, alpha mask on the
   section box (right 70 % → left 0). Tablet: 1440 px wide, section height, left-anchored, mask on the image.
   Mobile: 2200.8×855.9 at x −639. All from the Figma "Background Image" nodes. */
.cta--figma { position: relative; overflow: hidden; }
.cta--figma > .container { position: relative; z-index: 1; }
/* Light-fade mask (CP10 design_cta_scrim, inc/design.php): the two alpha stops are CSS custom properties so
   the Design tab can weaken the fade without touching direction/geometry — unset, they resolve to the exact
   committed baseline (.7 → 0), byte-identical to before. Same two properties feed every mask-image below
   (both the theme's own fallback photo and a CMS photo share this — see .cta__photo-img--cms), so the scrim
   control affects both identically. */
.cta__photo { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; -webkit-mask-image: linear-gradient(to left, rgba(255,255,255,var(--cta-scrim-a1,.7)), rgba(255,255,255,var(--cta-scrim-a0,0))); mask-image: linear-gradient(to left, rgba(255,255,255,var(--cta-scrim-a1,.7)), rgba(255,255,255,var(--cta-scrim-a0,0))); }
.cta__photo picture { display: contents; }
.cta__photo-img { position: absolute; left: 0; top: -13.675%; width: 113.68%; height: 113.75%; max-width: none; object-fit: fill; }
/* CMS photo only (CP10, inc/render/cta.php): unlike the theme's two pre-cut fallback assets — correctly
   stretched with object-fit:fill above — an arbitrary uploaded photo must be cropped, not distorted, so this
   modifier swaps in object-fit:cover with a focal point. Box geometry (left/top/width/height) is untouched;
   only fit + position change. Desktop/Tablet use the Desktop focal; the ≤767px rule below switches to the
   (already breakpoint-resolved) Mobile focal. */
.cta__photo-img--cms { object-fit: cover; object-position: var(--cta-focal-desktop-x, 50%) var(--cta-focal-desktop-y, 50%); }
@media (max-width: 1199px) {
	.cta { padding-block: 120px; }
	.cta > .container { padding-inline: 80px; }
	.cta__photo { -webkit-mask-image: none; mask-image: none; }
	.cta__photo-img { top: .14px; width: 1440px; height: 100%; -webkit-mask-image: linear-gradient(to left, rgba(255,255,255,var(--cta-scrim-a1,.7)), rgba(255,255,255,var(--cta-scrim-a0,0))); mask-image: linear-gradient(to left, rgba(255,255,255,var(--cta-scrim-a1,.7)), rgba(255,255,255,var(--cta-scrim-a0,0))); }
}
@media (max-width: 767px) {
	.cta { padding-block: 80px; }
	.cta > .container { padding-inline: var(--layout-margin); }
	.cta__desc { color: var(--color-text-primary); }
	.cta__photo-img { left: -639px; width: 2200.77px; height: 855.85px; }
	.cta__photo-img--cms { object-position: var(--cta-focal-mobile-x, 50%) var(--cta-focal-mobile-y, 50%); }
}

/* Footer social links */
.site-footer__social a { display: inline-flex; align-items: center; gap: var(--spacing-8); }
/* Figma Desktop 1440: the bottom row is 16 px high (caption line-height also on the paragraph); "Sledi nam" shows text links only (22 px lines, 34 px pitch). */
@media (min-width: 1200px) {
	.site-footer__bottom p { line-height: var(--typography-caption-line-height); }
	.site-footer__nowrap { white-space: nowrap; } /* e-mail and phone lines stay on one line; a long value may reach into the 24 px column gap */
}

/* Koledar page (Figma: "10 Koledar"). Scoped to this page only — .cal-event etc. are deliberately not the
   Home .event/.event-list classes (theme.css:719-761): same visual family, different grid needs (a fixed
   169.33px date column + a flexible tag row of 1-N tags, vs. Home's fixed 3-item 12-col grid), so Home's
   finished layout stays untouched. */
.koledar-hero { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; min-height: 420px; padding: 0 var(--spacing-80) var(--spacing-48); background: var(--color-bg-primary); }
.koledar-hero__image { position: absolute; inset: 0; z-index: 0; }
.koledar-hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: right center; }
.koledar-hero__header { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--spacing-24); color: var(--color-text-primary); max-width: 720px; }
.koledar-hero__breadcrumb a { color: inherit; }
.koledar-hero__breadcrumb a:hover { text-decoration: underline; }
@media (max-width: 1199px) { .koledar-hero { min-height: 300px; padding-left: var(--spacing-32); } }
@media (max-width: 767px) {
	.koledar-hero { min-height: 270px; }
	.koledar-hero__intro { font-size: var(--typography-small-size); line-height: var(--typography-small-line-height); }
}

.cal-section { padding: var(--spacing-32) 0 var(--layout-section-padding-y); }
.cal-container { display: flex; flex-direction: column; gap: var(--spacing-64); }
@media (max-width: 1199px) { .cal-container { gap: var(--spacing-48); } }

.filter-chips { display: flex; flex-wrap: wrap; gap: var(--spacing-12); }
.chip { display: inline-flex; align-items: center; padding: var(--spacing-12) var(--spacing-16); border: 1px solid var(--color-border-strong); border-radius: var(--radius-small); color: var(--color-text-primary); font-size: var(--typography-small-size); line-height: var(--typography-small-line-height); text-decoration: none; }
.chip.is-active { background: var(--color-bg-inverse); border-color: var(--color-bg-inverse); color: var(--color-text-inverse); }

.cal-month { display: flex; flex-direction: column; gap: var(--spacing-16); }
.cal-events { border-top: 1px solid var(--color-border-default); }
.cal-event { position: relative; display: flex; align-items: center; gap: var(--spacing-48); padding-block: var(--spacing-24); border-bottom: 1px solid var(--color-border-default); }
.cal-event__date { flex: 0 0 169.33px; }
.cal-event__date time { display: flex; flex-direction: column; gap: var(--spacing-4); }
.cal-event__day { color: var(--color-text-primary); }
.cal-event__month { color: var(--color-text-accent); }
.cal-event__content { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--spacing-8); }
.cal-event__place { display: flex; align-items: center; gap: var(--spacing-8); color: var(--color-text-secondary); }
.cal-event__tags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-16); flex: none; }
.cal-event:hover .cal-event__title a { text-decoration: underline; text-underline-offset: 4px; }
@media (max-width: 767px) {
	.cal-event { flex-direction: column; align-items: flex-start; gap: var(--spacing-16); }
	.cal-event__date { flex: none; }
	.cal-event__date time { flex-direction: row; align-items: center; gap: var(--spacing-12); }
}

.cal-empty { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-16); padding-block: var(--spacing-32); }

/* Momiji (maple leaf) hero overlay — off by default, see inc/render/hero.php (hero_leaves_enabled).
   Sits between .hero__media (z-index: -1) and .hero__content in the DOM: .hero already has its own
   isolated stacking context (isolation: isolate) and overflow: hidden, so this layer paints above the
   background/scrim and below the in-flow .hero__content that follows it, without touching either rule. */
.hero__leaves { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.leaf { position: absolute; left: var(--leaf-left); top: var(--leaf-top); width: var(--leaf-w); height: auto; opacity: 0; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-duration: var(--leaf-dur); animation-delay: var(--leaf-delay); will-change: transform, opacity; }
.leaf--bg { animation-name: momiji-fall-bg; filter: blur(var(--leaf-blur, 2px)); }
.leaf--mid { animation-name: momiji-fall-mid; }
.leaf--fg { animation-name: momiji-fall-fg; filter: blur(var(--leaf-blur, 4px)); }

@keyframes momiji-fall-bg {
	0%   { transform: translate3d(0, -8vh, 0) rotate(0deg); opacity: 0; }
	12%  { opacity: var(--leaf-op); }
	45%  { transform: translate3d(-25px, 25vh, 0) rotate(100deg); }
	75%  { transform: translate3d(15px, 48vh, 0) rotate(190deg); }
	90%  { opacity: var(--leaf-op); }
	100% { transform: translate3d(-10px, 65vh, 0) rotate(250deg); opacity: 0; }
}
@keyframes momiji-fall-mid {
	0%   { transform: translate3d(8px, -10vh, 0) rotate(-12deg); opacity: 0; }
	8%   { opacity: var(--leaf-op); }
	38%  { transform: translate3d(-40px, 22vh, 0) rotate(90deg); }
	68%  { transform: translate3d(30px, 45vh, 0) rotate(200deg); }
	88%  { opacity: var(--leaf-op); }
	100% { transform: translate3d(-20px, 68vh, 0) rotate(300deg); opacity: 0; }
}
@keyframes momiji-fall-fg {
	0%   { transform: translate3d(15px, -12vh, 0) rotate(10deg); opacity: 0; }
	6%   { opacity: var(--leaf-op); }
	42%  { transform: translate3d(-60px, 28vh, 0) rotate(130deg); }
	80%  { transform: translate3d(-30px, 55vh, 0) rotate(260deg); }
	88%  { opacity: var(--leaf-op); }
	100% { transform: translate3d(-90px, 78vh, 0) rotate(340deg); opacity: 0; }
}
/* Tablet: drop the background tier, plus the two leaves whose desktop start position (left: 40%/60%) sits
   close enough to the copy column that at tablet width they visibly near the title text — a minimal,
   targeted fix (2 of 10 leaves), not a tablet redesign; the rest keep their desktop positions/timing. */
@media (max-width: 1199px) {
	.hero__leaves .leaf--bg, .hero__leaves .leaf--near-text { display: none; }
}
/* Mobile: off entirely for this first POC — smallest hero height, least room to spare for a decorative
   layer without risking copy legibility (the brief's other allowed option was "3-4 small leaves"; this
   picks the safer of the two for a first pass). */
@media (max-width: 767px) {
	.hero__leaves { display: none; }
}
@media (prefers-reduced-motion: reduce) {
	.hero__leaves { display: none; }
}

/* Sections touch each other (no block gap between top-level blocks in <main>). */
.site-main > * { margin-block: 0 !important; }
/* Links on dark surfaces keep the surface colour (theme.json sets links to text-primary). */
.on-dark a:not(.btn) { color: inherit; }

/* Treningi page (Figma: "05 Treningi"). Scoped to this page's own sections — new components below, not
   reused from Koledar's .koledar-hero (different content: no CTA button there, fixed min-height + bottom-
   aligned text here vs. this hero's content-driven height) or from Home's .hero (different anchoring: this
   header is top-anchored, not bottom-anchored, so its scrim below is its own gradient recipe, not a shared
   rule with .hero__scrim). */
.trainings-hero { position: relative; overflow: hidden; display: flex; flex-direction: column; color: var(--color-text-inverse); background: var(--color-bg-inverse); padding: var(--spacing-96) var(--layout-margin) var(--spacing-64); }
.trainings-hero__image { position: absolute; inset: 0; z-index: 0; }
.trainings-hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Legibility fix (not a Figma element): same "media wrapper + absolute scrim sibling" pattern as
   .hero__scrim (layered linear-gradients, no text-shadow), re-tuned for top-anchored content — a left-side
   fade behind the text column, plus mild top/bottom fades for the breadcrumb and button. Percentage-based
   stops scale with the box at every breakpoint, so Mobile/Tablet (where the source photo's bright area
   sits directly behind the text) get the same proportional protection as Desktop without a media query,
   and the opacities stay low enough that Desktop (already legible) isn't darkened beyond "subtle". */
.trainings-hero__scrim { position: absolute; inset: 0; background:
	linear-gradient(to bottom, rgba(0, 0, 0, .4) 0%, rgba(0, 0, 0, 0) 35%),
	linear-gradient(to top, rgba(0, 0, 0, .45) 0%, rgba(0, 0, 0, 0) 45%),
	linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .15) 65%, rgba(0, 0, 0, 0) 100%); }
.trainings-hero__header { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--spacing-24); max-width: 630px; }
.trainings-hero__breadcrumb a { color: inherit; }
.trainings-hero__breadcrumb a:hover { text-decoration: underline; }

/* Treningi: Program Cards (Figma: "Section / Groups" -> Začetniki + Nadaljevalci in tekmovalci). Card width
   is fixed (653px, per Figma at Desktop AND Tablet) rather than fluid: centered via .container + flex
   justify-content, it naturally reproduces Figma's measured margins at every breakpoint (55px Desktop /
   57.5px Tablet, both wider than --layout-margin because the two fixed cards overflow the nominal content
   box and center within it) without any bespoke non-token spacing value. Only Mobile switches the card to
   the fluid container width (342px, matching --layout-margin there exactly), per Figma. */
.program-cards { display: flex; flex-direction: row; gap: var(--spacing-24); justify-content: center; }
/* background: white (not --color-surface-dark, its pre-opacity value) — .program-card__media now renders at
   a CMS opacity < 1, and whatever sits behind it on .program-card is what that opacity blends toward. A
   dark surface color made a low-opacity photo blend toward black/grey instead of the intended "photo
   fades toward white" look; white is also the correct "no photo uploaded at all" fallback for this
   section's light background, unlike the previous dark-tile fallback. */
.program-card { position: relative; overflow: hidden; border-radius: var(--radius-small); width: 653px; max-width: 100%; min-height: 426px; padding: var(--spacing-24); background: var(--color-neutral-0); }
/* Opacity (Nastavitve kluba -> Treningi -> Začetniki/Nadaljevalci, tr_g{1,2}_image_opacity) is set inline
   per-card on this wrapper only — it never touches .program-card, so the gradient and content layers above
   it stay fully opaque regardless of the photo's own opacity. */
.program-card__media, .program-card__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.program-card__media { pointer-events: none; }
/* Same left-to-right white fade recipe (23.558% / 82.692%) as the Figma "Gradient mask" component reused
   on the Tekmovanja CTA hero (checkpoint 2) — kept as literal Figma values, not rounded. */
.program-card__gradient { position: absolute; inset: 0; background: linear-gradient(to right, var(--color-neutral-0) 23.558%, rgba(255, 255, 255, 0) 82.692%); }
.program-card__content { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--spacing-16); max-width: 330px; color: var(--color-text-primary); }
.program-card__eyebrow { color: var(--color-text-accent); }
.program-card__audience { display: flex; flex-direction: column; gap: var(--spacing-16); }
.program-card__audience-list { display: flex; flex-direction: column; gap: var(--spacing-12); }
.program-card__audience-list li { display: flex; align-items: center; gap: var(--spacing-8); }
.program-card__audience-list .icon { color: var(--color-status-success); flex-shrink: 0; }
@media (max-width: 1199px) { .program-cards { flex-direction: column; align-items: center; } }
/* Mobile-only legibility fix: Figma's own mobile "Gradient mask" layer is wider (491px/534px) than the
   card itself (342px there), so its 23.558%/82.692% stops land at different effective positions relative
   to the card than at Desktop/Tablet (where the mask matches the card 1:1) — the white zone reads further
   right than the flat desktop/tablet stops would give. Kept moderate on purpose: per-card legibility is
   now primarily tuned via the photo's own CMS opacity (tr_g{1,2}_image_opacity, see .program-card__media),
   not by pushing this mask toward fully opaque. Desktop/Tablet keep the base rule untouched. */
@media (max-width: 767px) {
	.program-card { width: 100%; }
	.program-card__gradient { background: linear-gradient(to right,
		rgba(255, 255, 255, 0.98) 0%,
		rgba(255, 255, 255, 0.96) 42%,
		rgba(255, 255, 255, 0.82) 58%,
		rgba(255, 255, 255, 0.40) 76%,
		rgba(255, 255, 255, 0) 100%); }
}

/* Treningi: Vrednote (Figma: "Values"). Vertical padding is a fixed var(--spacing-80) at every breakpoint
   (Figma measures 80px top/bottom on Desktop, Tablet AND Mobile alike — a spacing token, not a layout one,
   so it doesn't respond to viewport). Horizontal padding instead matches the rest of the page's content
   inset (--layout-margin, same as .container: 80/32/24 at Desktop/Tablet/Mobile) rather than Figma's own
   flat 80px-on-Tablet-too reading — confirmed against "En trening" (.container) as the reference for a
   consistent Tablet inset across the page. .container itself doesn't fit here because its vertical spacing
   comes from a separate .section, whose --layout-section-padding-y doesn't match this 80px-constant value. */
.trainings-values__inner { display: flex; flex-direction: column; gap: var(--spacing-48); padding: var(--spacing-80); }
@media (max-width: 1199px) { .trainings-values__inner { padding-inline: var(--layout-margin); } }
.trainings-values__copy { display: flex; flex-direction: column; gap: var(--spacing-16); }
.trainings-values__lead { color: var(--color-text-primary); }
/* 5 values, Desktop/Tablet in one row (5 equal columns, 0 gap — matches Figma exactly at both), Mobile in
   Figma's own 2+2+1 grouping with its own order (Družina+Načelnost / Čast+Pogum / Spoštovanje alone,
   centered) — grid-area names decouple visual placement from DOM order (see trainings-values.php), so DOM
   stays in the Desktop reading order at every breakpoint. The Desktop/Tablet 5-column row is the base rule
   (applies everywhere by default); only Mobile (<=767px) gets its own bounded override below, so there is
   no wider "not-mobile" range whose correctness depends on this rule coming first in the cascade. */
.value-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); grid-template-areas: "family principle respect courage honor"; }
.value-item--family { grid-area: family; }
.value-item--principle { grid-area: principle; }
.value-item--respect { grid-area: respect; }
.value-item--courage { grid-area: courage; }
.value-item--honor { grid-area: honor; }
.value-item { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--spacing-8); text-align: center; }
/* Kanji/sumi-e crop ratio (Figma "Value Symbol" frame, ~256x228 at every breakpoint): object-fit: cover on
   a fixed-ratio box, not a plain <img>, so the export's square canvas keeps the same crop Figma shows. */
.value-item__symbol { display: block; width: 100%; aspect-ratio: 256 / 228; overflow: hidden; }
.value-item__symbol img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.value-item__label { color: var(--color-text-accent); }
/* Figma: the value label is Small Bold (14px) on Tablet AND Mobile — not the Desktop H4 (24px) the markup
   carries by default — so a same-width column with an unbreakable word ("SPOŠTOVANJE"/"NAČELNOST") sizes
   identically to the other four instead of forcing its track wider. Checkpoint 2 full-page-QA correction
   (final Figma node 183:15228): an earlier pass had marked Mobile as "already correct" at 24px, but a
   fresh get_design_context read of the FINAL Mobile Values frame confirms Small Bold 14/22 at Mobile too,
   identical to Tablet — so this is now one shared <=1199px rule instead of a Tablet-only range. */
@media (max-width: 1199px) {
	.value-item__label { font-size: var(--typography-small-size); line-height: var(--typography-small-line-height); letter-spacing: var(--typography-small-letter-spacing); }
}
@media (max-width: 767px) {
	.value-grid { grid-template-columns: repeat(2, 1fr); column-gap: 64px; row-gap: 20px; grid-template-areas:
		"family principle"
		"honor courage"
		"respect respect"; }
	.value-item--respect { justify-self: center; width: 121px; }
}

/* Treningi: En trening. Več kot samo tehnika. (Figma: "Proces treninga"). One CSS Grid with per-phase named
   areas reproduces all three Figma layouts (Desktop: 1 image row + 1 text row; Tablet: 2 image+text
   row-pairs of 2 phases each; Mobile: fully sequential image-then-text per phase) from a single DOM order
   — see trainings-process.php. Column/row gaps are unified to --spacing-24 (Figma has 18px between images
   specifically; kept as one token rather than a second one-off value — see Checkpoint 2 report). */
.trainings-process__title { margin-bottom: var(--spacing-24); }
.trainings-process__intro { margin-bottom: var(--spacing-24); color: var(--color-text-primary); }
/* Checkpoint 3 full-page-QA correction (final Figma, all 3 breakpoints read directly): vertical padding is
   NOT the flat 64px/64px .section--compact previously assumed. Desktop is asymmetric (16px top / 64px
   bottom); Tablet reads 0px top / 64px bottom; Mobile is the already-correct symmetric 24px/24px. */
.trainings-process { padding-top: 16px; padding-bottom: var(--spacing-64); }
@media (max-width: 1199px) { .trainings-process { padding-top: 0; } }
@media (max-width: 767px) { .trainings-process { padding-block: var(--spacing-24); } }
/* Figma: Mobile's title explicitly switches to the H3 type scale (32px), not H1's own mobile-shrunk value
   (38px per the global --typography-h1-size token) — a deliberate smaller-scale swap, same idea as the
   Growth Cards section's subtitle using Body Large Bold instead of a shrunk H4. */
@media (max-width: 767px) {
	.trainings-process__title { font-size: var(--typography-h3-size); line-height: var(--typography-h3-line-height); letter-spacing: var(--typography-h3-letter-spacing); }
}
.phase-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--spacing-24); grid-template-areas:
	"img1 img2 img3 img4"
	"txt1 txt2 txt3 txt4"; }
.phase-grid__img--1 { grid-area: img1; } .phase-grid__text--1 { grid-area: txt1; }
.phase-grid__img--2 { grid-area: img2; } .phase-grid__text--2 { grid-area: txt2; }
.phase-grid__img--3 { grid-area: img3; } .phase-grid__text--3 { grid-area: txt3; }
.phase-grid__img--4 { grid-area: img4; } .phase-grid__text--4 { grid-area: txt4; }
.phase-grid__img { position: relative; height: 200px; border-radius: var(--radius-small); overflow: hidden; background: var(--color-bg-primary); }
.phase-grid__photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.phase-grid__text { display: flex; flex-direction: column; gap: var(--spacing-16); max-width: 300px; }
.phase-grid__eyebrow { color: var(--color-text-accent); }
.phase-grid__phase-title, .phase-grid__desc { color: var(--color-text-primary); }
/* Bounded on both ends (not a bare max-width:1199px that relied on the Mobile rule below to override it
   back out by cascade order): Tablet now owns its own non-overlapping range, so this rule's correctness
   at 768px no longer depends on source order relative to the Mobile rule. */
@media (min-width: 768px) and (max-width: 1199px) {
	.phase-grid { grid-template-columns: repeat(2, 1fr); grid-template-areas:
		"img1 img2"
		"txt1 txt2"
		"img3 img4"
		"txt3 txt4"; }
}
@media (max-width: 767px) {
	.phase-grid { grid-template-columns: 1fr; grid-template-areas:
		"img1"
		"txt1"
		"img2"
		"txt2"
		"img3"
		"txt3"
		"img4"
		"txt4"; }
	.phase-grid__text { max-width: none; }
}

/* Treningi: Več kot šport (Figma: "04 · KAJ KARATE RAZVIJA"). Background/overlay reuse the existing
   skif_section_bg() system (skif_bg_fields('ben', ...) in inc/options.php) — same mechanism as Home's
   cta/competitions sections, .has-bg/.section--dark classes unchanged here. Vertical padding lives only on
   the section (var(--spacing-96) top / var(--spacing-64) bottom, constant at every breakpoint per Figma);
   horizontal inset comes entirely from .container to avoid double-padding, with one Tablet-only override
   below (Figma measures 80px there too, not the site's usual 32px --layout-margin — same kind of flat-token
   reading Checkpoint 2's Vrednote had before its Tablet-inset fix; kept as literal Figma value here since
   the metadata pixel position confirms it, not just the codegen fallback — flag for visual confirmation). */
.trainings-benefits { position: relative; padding-block: var(--spacing-96) var(--spacing-64); }
/* Checkpoint 4 correction (final Figma, all 3 breakpoints): Mobile's own top padding is 32px, not the
   96px used everywhere else — a further Mobile-only reduction on top of the base rule. */
@media (max-width: 767px) { .trainings-benefits { padding-top: var(--spacing-32); } }
@media (min-width: 768px) and (max-width: 1199px) {
	.trainings-benefits .container { padding-inline: var(--spacing-80); }
}

/* Desktop = 2 columns (intro+CTA stacked in the left column, benefits in the right column); Tablet AND
   Mobile = single column, CTA AFTER the benefits (Checkpoint 4 correction — an earlier pass had Tablet's
   CTA appear right after the intro, before the benefits; a fresh get_design_context read of the final
   Tablet frame confirms the CTA sits after the benefit list there too, identical to Mobile's own already-
   correct order, not a Tablet-only in-between state) — grid-area names place intro/cta/list independently
   of DOM order (DOM stays intro, cta, list — the Desktop reading order — at every breakpoint; see
   trainings-benefits.php). */
.trainings-benefits__inner { display: grid; grid-template-columns: 1fr; gap: var(--spacing-48); grid-template-areas:
	"intro"
	"list"
	"cta"; }
.trainings-benefits__intro { grid-area: intro; display: flex; flex-direction: column; gap: var(--spacing-24); }
.trainings-benefits__eyebrow { color: var(--color-text-accent); }
.trainings-benefits__title, .trainings-benefits__desc { color: var(--color-text-inverse); }
.trainings-benefits__actions { grid-area: cta; }
/* Each benefit is its own translucent red block (rgba(181,29,38,.45), 16px padding, 4px radius) with a
   backdrop-blur wrapper — Checkpoint 4 correction: the earlier pass rendered benefits as plain list rows
   directly on the dark section background, with no block/blur at all (that treatment didn't exist in this
   final Figma read). */
.benefit-list { grid-area: list; display: flex; flex-direction: column; gap: var(--spacing-24); backdrop-filter: blur(2.5px); -webkit-backdrop-filter: blur(2.5px); }
.benefit { display: flex; align-items: flex-start; gap: 43px; background: rgba(181, 29, 38, .45); border-radius: var(--radius-small); padding: 16px; }
.benefit__icon-tile { position: relative; width: 51px; height: 51px; border-radius: var(--radius-small); overflow: hidden; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
/* Each icon's native SVG size/offset inside this shared 61x61 box is set inline per instance (see
   trainings-benefits.php $benefits config) — ion/reicon/emojione each export at a different natural size. */
.benefit__icon { position: relative; width: 61px; height: 61px; flex-shrink: 0; }
/* max-width: none overrides the global "img,svg,video{max-width:100%}" reset (theme.css:8): meditation.svg
   is 86x86, wider than this 61x61 wrapper, and would otherwise be downscaled to 61x61 by that reset —
   fitness (61x61) and dharma (53x53) never hit that cap, which is why only meditation was affected. */
/* Checkpoint 4 visual-QA correction: the source SVGs (assets/img/benefits/*.svg) hardcode fill="#B51D26"
   (the red used everywhere ELSE these icons sit, e.g. on the plain dark background this section used
   before the red-block treatment) — the final Figma card treatment needs them white. Recolored with a
   filter scoped to this exact selector (brightness(0) then invert(1) turns any opaque fill white) rather
   than editing the shared SVG files or touching skif_icon()/any global icon rule — nothing else references
   these 3 files, but the recolor still lives in CSS, not the asset, in case that changes later. */
.benefit__icon img { position: absolute; display: block; max-width: none; filter: brightness(0) invert(1); }
.benefit__text { display: flex; flex-direction: column; gap: var(--spacing-12); flex: 1 1 0; min-width: 0; }
/* Checkpoint 4 visual-QA correction: Figma's card eyebrow is white (--color-text-inverse), not the site's
   usual red accent eyebrow color — scoped to .benefit__eyebrow only, .t-eyebrow's shared font-metric rule
   and every other section's own eyebrow color (still red there) are untouched. */
.benefit__eyebrow { color: var(--color-text-inverse); }
.benefit__title, .benefit__desc { color: var(--color-text-inverse); }

@media (min-width: 768px) and (max-width: 1199px) { .trainings-benefits__inner { gap: var(--spacing-64); } }
@media (min-width: 1200px) {
	/* row-gap is the intro-to-CTA distance in column 1 only ("list" spans both rows as one cell, so the
	   row track gap never touches it) — Figma's Desktop "Hero content" wrapper measures 136px there. */
	.trainings-benefits__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 126px; row-gap: 136px; grid-template-areas:
		"intro list"
		"cta list"; }
	/* Figma: the benefit description text is a fixed 528px on Desktop only (not fluid) — kept as a
	   max-width cap rather than forcing the flex column itself to stop growing. */
	.benefit__text { max-width: 528px; }
}

/* Treningi: Prvič v doju? (Figma: "Prvič v doju?", final page assembly — Checkpoint 5 rebuild from an
   icon+text row layout to photo cards, see trainings-visit.php). Vertical padding: Desktop/Tablet are a
   symmetric 64px/64px; Mobile is 32px top / 64px bottom (an earlier pass had 96px top at every breakpoint —
   that no longer matches this final Figma read). Horizontal inset uses .container — Figma's own Tablet
   frame measures a flat 80px here too (same "codegen/metadata reads 80" situation noted throughout this
   page), "En trening" remains this page's confirmed reference for correct Tablet inset (32px). */
.trainings-visit { padding-block: var(--spacing-64); }
@media (max-width: 767px) { .trainings-visit { padding-top: var(--spacing-32); } }
.trainings-visit__inner { display: flex; flex-direction: column; gap: var(--spacing-48); }
.trainings-visit__intro { display: flex; flex-direction: column; gap: var(--spacing-12); color: var(--color-text-primary); }
/* Figma: Mobile's title explicitly swaps to H2 (not H1's own mobile-shrink) — same deliberate smaller-scale
   swap as Growth Cards' subtitle and En trening's Mobile title. */
@media (max-width: 767px) {
	.trainings-visit__title { font-size: var(--typography-h2-size); line-height: var(--typography-h2-line-height); letter-spacing: var(--typography-h2-letter-spacing); }
}

/* Desktop = 3 cards in one row (fluid 1fr columns — a fixed px width here would hit the exact same
   "fits Desktop's own 80px inset, underfills Tablet's corrected 32px inset" bug the Growth Cards section
   had at Checkpoint 1); Tablet AND Mobile = single column, one card per row (no 2-up Tablet state, unlike
   Growth Cards — confirmed from both frames independently, not inferred). */
.visit-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 53px; list-style: none; margin: 0; padding: 0; }
@media (max-width: 1199px) { .visit-steps { grid-template-columns: 1fr; gap: 53px; } }
.visit-step { display: flex; flex-direction: column; background: #f5f4f1; border-radius: var(--radius-small); box-shadow: 0 8px 24px -6px rgba(0, 0, 0, .08); overflow: hidden; }
.visit-step__image { position: relative; height: 355px; flex: none; background: var(--color-bg-primary); }
.visit-step__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* Figma: the "Poskusi" card's photo is bottom-anchored on Mobile only (Desktop/Tablet stay centered). */
@media (max-width: 767px) { .visit-step:nth-child(2) .visit-step__img { object-position: center bottom; } }
/* "Pridi" card photo (a portrait 3024x4032 source in a landscape box): Desktop uses plain object-fit:cover
   (Figma's own Desktop frame has no custom transform on it), but Tablet and Mobile each apply their own
   deliberate scale+offset crop that goes beyond what object-position alone can express — Tablet still
   matches a plain cover *scale* (100% width, so only a vertical pan), but Mobile zooms in further still
   (121.05% width / 155.49% height, both above the 100%/128.5% a plain cover would give). Reproduced here
   with the exact width/height/left/top percentages Figma computed (verified: at each breakpoint the
   resulting box aspect ratio matches the source photo's own 3024:4032 ratio exactly, so no distortion) —
   same asset, no new cropped copy, pure CSS. */
@media (min-width: 768px) and (max-width: 1199px) {
	.visit-step:nth-child(1) .visit-step__img { inset: auto; width: 100%; height: 228.36%; left: -0.07%; top: -32.76%; }
}
@media (max-width: 767px) {
	.visit-step:nth-child(1) .visit-step__img { inset: auto; width: 121.05%; max-width: none; height: 155.49%; left: -6.59%; top: -16.99%; }
}
.visit-step__body { display: flex; flex-direction: column; gap: 16px; padding: 16px; padding-bottom: 32px; }
.visit-step__label { color: var(--color-text-accent); }
.visit-step__desc, .visit-step__highlight { color: var(--color-text-primary); }

/* Treningi: FAQ ("Kaj pričakovati") + Telovadnica OŠ Ruše (Figma: "FAQ"). Desktop = FAQ column (fixed
   ~500px) beside Šola column, 80px gap; Tablet AND Mobile = stacked, 36px gap (identical at both, per
   Figma — not a Tablet-only override, same pattern as .visit-steps above). Horizontal inset/vertical
   rhythm use .container (80/32/24) + .section (--layout-section-padding-y: 120/96/64), not Figma's own
   flat 92/92/24 frame padding (same decoupled-padding situation as every earlier Treningi section). */
.trainings-faq__inner { display: flex; align-items: flex-start; gap: var(--spacing-80); }
.trainings-faq__column { flex: 0 0 500px; max-width: 500px; }
.trainings-faq__title { margin-bottom: var(--spacing-24); }
.trainings-faq__school { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 34px; }
.trainings-faq__school-text { display: flex; flex-direction: column; gap: var(--spacing-12); }
@media (max-width: 1199px) {
	.trainings-faq__inner { flex-direction: column; gap: 36px; }
	.trainings-faq__column { flex-basis: auto; max-width: none; width: 100%; }
	.trainings-faq__school { width: 100%; }
}

/* Each FAQ item is a native <details>/<summary> — no JS. Border/padding are uniform on every item
   (including first and last), matching Figma's FaqItem component exactly. */
.faq-item { border-bottom: 1px solid var(--color-border-default); padding-block: var(--spacing-24); }
.faq-item__row { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-24); cursor: pointer; list-style: none; }
.faq-item__row::-webkit-details-marker { display: none; }
.faq-item__row::marker { content: ""; }
.faq-item__question { flex: 1 1 auto; }
.faq-item__answer { margin-top: var(--spacing-16); color: var(--color-text-secondary); }
/* Plus/minus glyph via two pseudo-elements (a horizontal + a rotated vertical bar) instead of a new
   skif_icon()/SVG asset: rotating the vertical bar back to 0deg on [open] turns the "+" into a "−" with no
   JS and no icon swap. Sized to match Figma's Icon/plus /Icon/minus glyph (24px box, ~14px bar). */
.faq-item__icon { position: relative; width: 24px; height: 24px; flex: none; color: var(--color-text-primary); }
.faq-item__icon::before, .faq-item__icon::after {
	content: ""; position: absolute; top: 50%; left: 50%; width: 14px; height: 2px; background: currentColor;
	transform: translate(-50%, -50%); transition: transform .15s ease;
}
.faq-item__icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq-item[open] .faq-item__icon::after { transform: translate(-50%, -50%) rotate(0deg); }

/* Gallery: NOT a symmetric 2x2 — Checkpoint 7 visual-QA correction against the FINAL page-assembly FAQ
   node (183:14951/186:17218/186:17486, not the earlier standalone FAQ node this was first built from,
   which the final assembly does not reuse verbatim). Figma is one full-width "hero" photo (fixed 285px
   tall, fluid width) followed by a row of 2 half-width photos (339/285 aspect ratio, matching this
   section's own photo box). Reproduced with a plain 2-column grid whose first item spans both columns —
   the same technique that already made this grid robust to an arbitrary CPT count, so a gallery of 1, 2,
   4, 5... photos still degrades sensibly (1 = hero only, 2 = hero + one pair item, etc). Gap is 34px on
   both axes at every breakpoint (Figma's Mobile frame gives an exact 447.818 - 285 - 128.818 = 34px row
   gap, not the ~19px estimate an earlier, different FAQ node reading had produced; Mobile's own row-2
   column gap computes to a very close 36px — accepted as the same 34px rather than a third one-off value). */
.faq-gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: 34px; }
.faq-gallery__photo { position: relative; aspect-ratio: 339 / 285; border-radius: var(--radius-small); overflow: hidden; background: var(--color-bg-primary); }
.faq-gallery__photo:first-child { grid-column: 1 / -1; aspect-ratio: auto; height: 285px; }
.faq-gallery__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* skif_school_photo CPT post with no featured image of its own — same neutral-tile idiom as
   .media__fallback, not a Figma default photo (those only apply to the seeded/fixed-slot fallback paths). */
.faq-gallery__fallback { position: absolute; inset: 0; display: grid; place-items: center; }
.faq-gallery__fallback img { width: 48px; height: 48px; opacity: .35; filter: grayscale(1); }

/* Treningi: "Karate raste skupaj s tabo." (final Figma page assembly, node 183:14792). Vertical padding is
   asymmetric on Desktop (96px top / 64px bottom, both real Figma spacing tokens, not a --section-padding-y
   pair) but collapses to a plain symmetric value on Tablet (64px) and Mobile (32px). Horizontal inset is
   the confirmed .container system (80/32/24), matching every earlier Treningi section. */
.trainings-growth { padding-block: var(--spacing-96) var(--spacing-64); }
@media (min-width: 768px) and (max-width: 1199px) { .trainings-growth { padding-block: var(--spacing-64); } }
@media (max-width: 767px) { .trainings-growth { padding-block: var(--spacing-32); } }
.trainings-growth__inner { display: flex; flex-direction: column; gap: var(--spacing-48); }
.trainings-growth__head { display: flex; align-items: flex-start; gap: var(--spacing-48); }
.trainings-growth__intro { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 12px; color: var(--color-text-primary); }
.trainings-growth__title {
	font-family: var(--typography-font-family-primary); font-weight: 700; margin: 0;
	font-size: var(--typography-h1-size); line-height: var(--typography-h1-line-height); letter-spacing: var(--typography-h1-letter-spacing);
}
.trainings-growth__subtitle {
	font-family: var(--typography-font-family-primary); font-weight: 700; margin: 0;
	font-size: var(--typography-h4-size); line-height: var(--typography-h4-line-height); letter-spacing: var(--typography-h4-letter-spacing);
}
.trainings-growth__lead { flex: 0 0 409px; max-width: 409px; padding-top: 12px; margin: 0; color: var(--color-text-primary); }
/* Tablet AND Mobile share the same stacked order (lead paragraph above the title, via `order`, so the DOM
   itself keeps the heading first for a sane reading/AT order) and the same smaller intro typography (H2 +
   Body Large Bold, not Desktop's H1 + H4) — identical at both, per Figma, so one shared bounded range. */
@media (max-width: 1199px) {
	.trainings-growth__head { flex-direction: column; gap: 36px; }
	.trainings-growth__lead { order: -1; flex-basis: auto; max-width: none; width: 100%; }
	.trainings-growth__title { font-size: var(--typography-h2-size); line-height: var(--typography-h2-line-height); letter-spacing: var(--typography-h2-letter-spacing); }
	.trainings-growth__subtitle { font-size: var(--typography-body-large-size); line-height: var(--typography-body-large-line-height); letter-spacing: var(--typography-body-large-letter-spacing); }
}
/* Cards: a fixed ~280px width (flex-wrap) was tried first since Desktop's own Figma frame happens to have
   4 x 280px + 3 x 53px gaps ~= its 1280px content width almost exactly — but Tablet's Figma frame reads a
   flat 80px inset (608px content width) where 2 x 280px + 53px gap ALSO fills edge-to-edge, not the
   confirmed 32px-inset .container width (704px) this page actually uses. A fixed card width sized for
   Figma's own (uncorrected) 608px tablet content left ~91px of unfilled space on the right at the real
   32px inset — cards must instead be fluid grid columns that fill whatever the corrected container width
   actually is, at every width in the Tablet/Desktop ranges, not just one exact breakpoint value. */
.growth-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 53px; }
@media (min-width: 768px) and (max-width: 1199px) { .growth-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) { .growth-cards { grid-template-columns: 1fr; } }
.growth-card { display: flex; flex-direction: column; min-width: 0; background: #f5f4f1; border-radius: 2.864px; box-shadow: 0 5.727px 17.181px -4.295px rgba(0, 0, 0, .08); overflow: hidden; }
.growth-card__image { position: relative; height: 254.143px; flex: none; background: var(--color-bg-primary); }
.growth-card__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: var(--growth-card-position, center); }
.growth-card__body { display: flex; flex-direction: column; gap: 24.34px; padding: 11.454px; padding-bottom: 22.909px; }
.growth-card__text { display: flex; flex-direction: column; gap: 11.454px; }
.growth-card__eyebrow { color: var(--color-text-accent); margin: 0; }
.growth-card__title { color: var(--color-text-primary); margin: 0; }
.growth-card__desc { color: var(--color-text-primary); margin: 0; font-size: 11.454px; line-height: 18.613px; }
.growth-card__sep { border: 0; border-top: 1px solid var(--color-border-default); margin: 0; }
.growth-card__chips { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.growth-card__chip { background: #d9d9d9; color: var(--color-text-primary); height: 21px; display: flex; align-items: center; padding-inline: 10px; border-radius: 999px; font-size: 8px; line-height: 13.071px; white-space: nowrap; }
.growth-card__link { display: flex; align-items: center; gap: 12px; color: var(--color-text-accent); text-decoration: none; }
.growth-card__link:hover { text-decoration: underline; }
.growth-card__link .icon { flex: none; }

/* Treningi: zaključni CTA (Figma: "Hero section" / "Tekmovanja", final page assembly — last section before
   the footer, identical at all 3 breakpoints: zero outer margin, so this section carries no section-level
   padding-block of its own, unlike every other Treningi section — its own 24px inner padding + min-height
   are the only vertical rhythm). Horizontal inset is the standard .container (80/32/24) — Figma's own flat
   80px Tablet reading is the same "codegen vs. corrected 32px inset" situation noted throughout this page,
   so it is not special-cased here. */
.trainings-cta { position: relative; padding-block: var(--spacing-24); min-height: 400px; }
@media (max-width: 767px) { .trainings-cta { min-height: 380px; } }
/* Fixed design detail, not CMS-adjustable (separate from the admin's own optional "Ozadje, zatemnitev"
   darkening, applied via skif_section_bg()'s own ::after on this same .section__bg wrapper): the photo
   itself always renders at 40% opacity, under the white gradient below. */
.trainings-cta .section__bg__img { opacity: .4; }
/* White gradient mask: solid white through ~23.6% of the section width, fading to fully transparent by
   ~82.7% — Figma reads identically at all 3 breakpoints (the mask box itself is wider than the mobile
   viewport and offset, but its own internal stops are the same percentages), so one rule covers every
   breakpoint with no override needed. */
.trainings-cta__fade { position: absolute; inset: 0; z-index: 0; pointer-events: none; background: linear-gradient(to right, var(--color-bg-secondary) 0%, var(--color-bg-secondary) 23.558%, rgba(255, 255, 255, 0) 82.692%); }
.trainings-cta__inner { position: relative; z-index: 1; }
.trainings-cta__content { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-24); color: var(--color-text-primary); }
.trainings-cta__eyebrow { color: var(--color-text-accent); }
@media (min-width: 1200px) { .trainings-cta__content { max-width: 600px; } }

/* =====================================================================
   CMS v2.1 CP12A — Image treatment (Nastavitve kluba → Design → Interakcije & fotografije, inc/motion.php).
   One :root custom property toggles every photography selector at once instead of duplicating `filter`
   per component. Logos/emblems/icons/social icons/placeholder glyphs (.logo__mark, .logo__emblem,
   .tradition__logo, .partner__logo, .site-footer__social-icon img, .benefit__icon img,
   .value-item__symbol img, schedule/location/contact SVG icons, skif_icon() SVGs, .media__fallback img,
   .faq-gallery__fallback img) are deliberately NOT in this selector list — see CP12A discovery §3/§7.
   Default (no class on <body>) is byte-for-byte the pre-CP12A frontend: every selector below is a leaf
   <img> with no descendants of its own, so filter:grayscale(0) creates no visible stacking/paint side
   effect (an inert stacking context on a childless element) and is safe to apply unconditionally, rather
   than gating the declaration itself behind a class (see CP12A discovery §8/§13 — no existing `filter` or
   `mask-image` on any of these selectors: .honbu-card__bg/.cta__photo carry mask-image on the WRAPPER,
   never on the .honbu-card__img/.cta__photo-img child itself, so there is no collision). */
:root { --photo-grayscale: 0; }
.motion-photo-bw { --photo-grayscale: 1; }

.hero__img, .tradition__bg-img, .cta__photo-img, .section__bg__img, .trainings-hero__img,
.koledar-hero__img, .honbu-card__img, .growth-card__img, .instructor-card__img, .news-card__img,
.visit-step__img, .phase-grid__photo, .faq-gallery__img, .media__img {
	filter: grayscale(var(--photo-grayscale, 0));
}
/* .news-card__img's own filter transition is declared alongside its existing transform transition further
   above (theme.css .news-card__img rule) so this shared list doesn't overwrite that hover-zoom transition. */
.hero__img, .tradition__bg-img, .cta__photo-img, .section__bg__img, .trainings-hero__img,
.koledar-hero__img, .honbu-card__img, .growth-card__img, .instructor-card__img,
.visit-step__img, .phase-grid__photo, .faq-gallery__img, .media__img {
	transition: filter .25s ease;
}

/* Image hover (design_image_hover): card photography only. Generations, Treningi growth cards,
   Instructors and News cards all carry the shared ".growth-card" base class already (see
   inc/render/generations.php, trainings-growth.php, instructors.php, news.php), so one hover trigger
   covers all four families with no renderer changes. Hero/Tradition/Final CTA/section backgrounds/Honbu/
   visit-steps/phase-grid/faq-gallery are full-bleed or static, non-card photography and intentionally get
   no hover state (see CP12A discovery §5/§9: they have no natural, discrete hover target, and constant
   filter-swapping while the pointer crosses a large background would read as glitchy, not premium). */
@media (hover: hover) and (pointer: fine) {
	.motion-hover-color .growth-card:hover .growth-card__img,
	.motion-hover-color .growth-card:hover .instructor-card__img,
	.motion-hover-color .growth-card:hover .news-card__img { --photo-grayscale: 0; }

	.motion-hover-bw .growth-card:hover .growth-card__img,
	.motion-hover-bw .growth-card:hover .instructor-card__img,
	.motion-hover-bw .growth-card:hover .news-card__img { --photo-grayscale: 1; }
}
/* Touch/no-hover fallback (confirmed UX decision, CP12A discovery §11/§14): only "default Black & White +
   hover Color" needs an override — without a fine-pointer hover, that pairing would otherwise leave card
   photography permanently Black & White with the intended Color state unreachable. Every other pairing
   already resolves correctly from the default treatment alone (Color-default stays Color regardless of
   hover; hover:none never adds a hover class to begin with). Full-bleed/static photography is untouched
   here and simply keeps following the default treatment on touch, as specified. */
@media not all and (hover: hover) and (pointer: fine) {
	.motion-photo-bw.motion-hover-color .growth-card__img,
	.motion-photo-bw.motion-hover-color .instructor-card__img,
	.motion-photo-bw.motion-hover-color .news-card__img { --photo-grayscale: 0; }
}

/* CP12A.4 — per-card hover/touch override (currently used by Generations, inc/render/generations.php;
   generic and reusable for any future .growth-card-family component). A card's OWN resolved hover state can
   differ from every OTHER card's on the same page (multi-card independence — see CP12A.4 discovery §14), so
   this can't be driven by the global .motion-hover-* body classes above: those two rules and these two are
   the same specificity (4 classes each: e.g. ".motion-hover-color .growth-card:hover .growth-card__img" vs
   ".growth-card.has-local-hover-color:hover .growth-card__img"), so — same as any two equal-specificity
   rules — SOURCE ORDER decides, which is exactly why this block is appended after the global one: a card
   that opts in with .has-local-hover-color/-bw always wins over the page-wide global hover, regardless of
   what design_image_hover currently is. Printed by the renderer only when the resolved hover state actually
   differs from the resting state (skif_resolve_image_state()'s own has_hover_change) — a card with no
   override gets neither class and this block is inert for it, unchanged from before this checkpoint. */
@media (hover: hover) and (pointer: fine) {
	.growth-card.has-local-hover-color:hover .growth-card__img,
	.growth-card.has-local-hover-color:hover .instructor-card__img,
	.growth-card.has-local-hover-color:hover .news-card__img { --photo-grayscale: 0; }

	.growth-card.has-local-hover-bw:hover .growth-card__img,
	.growth-card.has-local-hover-bw:hover .instructor-card__img,
	.growth-card.has-local-hover-bw:hover .news-card__img { --photo-grayscale: 1; }
}
/* Per-card touch fallback — same "bw resting + color hover would otherwise be permanently unreachable on
   touch" rule as the global one above, just scoped to one card: the renderer only ever prints
   .has-local-touch-color (skif_touch_image_treatment() only ever returns a value different from the
   resolved resting treatment in that one pairing), so no .has-local-touch-bw variant exists or is needed. */
@media not all and (hover: hover) and (pointer: fine) {
	.growth-card.has-local-touch-color .growth-card__img,
	.growth-card.has-local-touch-color .instructor-card__img,
	.growth-card.has-local-touch-color .news-card__img { --photo-grayscale: 0; }
}

/* =====================================================================
   CP12B — Card hover motion (News, Partners only — design_card_hover, inc/motion.php) and button/text-link
   arrow motion (design_button_motion), both driven by a minimal 3-token intensity system
   (design_motion_intensity). Strictly scoped: NOT applied to .growth-card/.generation-card/.instructor-card
   (not .stretched — only a small inline link is clickable there; a card-level lift would read as a false
   affordance, see CP12B discovery §6) or to any other section/card. No image zoom is added anywhere by this
   checkpoint — the existing News .news-card__img scale(1.03) (theme.css, CP12A block above) is untouched and
   composes safely with the new PARENT-level .news-card translateY below (different elements, different
   properties' computed transforms — a child's own transform is never affected by a transform on its parent).
   ===================================================================== */
.motion-intensity-subtle     { --motion-card-y: -2px; --motion-arrow-x: 3px; --motion-duration: .2s; --reveal-y: 16px; --reveal-duration: .5s; --reveal-stagger: 70ms; }
.motion-intensity-expressive { --motion-card-y: -4px; --motion-arrow-x: 5px; --motion-duration: .28s; --reveal-y: 24px; --reveal-duration: .65s; --reveal-stagger: 100ms; }

/* Card motion base (transition only — inert until a hover/focus rule below actually changes transform/
   box-shadow). Resting box-shadow (.growth-card's own rule, .news-card inherits it structurally; .partner
   has none today) is untouched; only the :hover/:focus-within shadow further down is new. */
.motion-card-hover .news-card,
.motion-card-hover .partner {
	transition: transform var(--motion-duration, .2s) ease, box-shadow var(--motion-duration, .2s) ease;
}
/* Mouse/trackpad only — never on touch (no fine pointer), so no sticky/fake hover state. */
@media (hover: hover) and (pointer: fine) {
	.motion-card-hover.motion-intensity-subtle .news-card:hover,
	.motion-card-hover.motion-intensity-subtle .partner:hover {
		transform: translateY(var(--motion-card-y));
		box-shadow: 0 8px 20px -6px rgba(0, 0, 0, .12);
	}
	.motion-card-hover.motion-intensity-expressive .news-card:hover,
	.motion-card-hover.motion-intensity-expressive .partner:hover {
		transform: translateY(var(--motion-card-y));
		box-shadow: 0 14px 28px -8px rgba(0, 0, 0, .16);
	}
}
/* Keyboard focus — equivalent feedback on any device (not gated by pointer capability): the focusable
   element is the card's own nested <a> (News: the .stretched title link; Partner: the link wrapping the
   whole tile), so :focus-within on the card reacts the same way :hover does above. Never added to any card
   that isn't actually a link (see CP12B discovery §6/§9) — .growth-card family is untouched. */
.motion-card-hover.motion-intensity-subtle .news-card:focus-within,
.motion-card-hover.motion-intensity-subtle .partner:focus-within {
	transform: translateY(var(--motion-card-y));
	box-shadow: 0 8px 20px -6px rgba(0, 0, 0, .12);
}
.motion-card-hover.motion-intensity-expressive .news-card:focus-within,
.motion-card-hover.motion-intensity-expressive .partner:focus-within {
	transform: translateY(var(--motion-card-y));
	box-shadow: 0 14px 28px -8px rgba(0, 0, 0, .16);
}

/* Button/text-link arrow motion — targets only genuine directional arrows (.icon--arrow-right) inside .btn
   or .text-link; never .icon--dots-grid (card inline links), raster <img> icons (external-link/mail/phone),
   nav chevrons, or social icons — none of those match this selector at all. Equal specificity (4 classes) to
   the existing ".on-dark .text-link:hover .icon--arrow-right" rule (theme.css, base buttons section) — this
   block is appended AFTER it, so source order lets this win once motion is on (giving 5px in Expressive even
   on dark surfaces), while leaving that rule's own 3px fully intact and unreachable-by-this-block when
   motion is off (no .motion-button-motion class exists on <body> then). */
@media (hover: hover) and (pointer: fine) {
	.motion-button-motion .btn:hover .icon--arrow-right,
	.motion-button-motion .text-link:hover .icon--arrow-right {
		transform: translateX(var(--motion-arrow-x));
	}
}
.motion-button-motion .btn:focus-visible .icon--arrow-right,
.motion-button-motion .text-link:focus-visible .icon--arrow-right {
	transform: translateX(var(--motion-arrow-x));
}

/* Reduced motion: card TRANSLATE and arrow TRANSLATE are the real "motion" this spec cares about (per
   CP12B discovery §14 — only these two, not the hover shadow, which is a depth/color cue rather than
   movement, the same reasoning that already lets the photography filter/color system stay active here).
   Same targeted-override idiom already used for parallax and the momiji leaves elsewhere in this file,
   applied to the new CP12B selectors only. The global catch-all (tokens.css) already collapses the
   transition to near-zero; this additionally removes the transform end-state itself, so nothing moves at
   all, while the hover shadow may still (instantly, per the global catch-all) appear. */
@media (prefers-reduced-motion: reduce) {
	.motion-card-hover .news-card:hover,
	.motion-card-hover .news-card:focus-within,
	.motion-card-hover .partner:hover,
	.motion-card-hover .partner:focus-within {
		transform: none;
	}
	.motion-button-motion .btn:hover .icon--arrow-right,
	.motion-button-motion .btn:focus-visible .icon--arrow-right,
	.motion-button-motion .text-link:hover .icon--arrow-right,
	.motion-button-motion .text-link:focus-visible .icon--arrow-right {
		transform: none;
	}
}

/* =====================================================================
   CP12C — Scroll reveal (Home only — design_scroll_reveal, inc/motion.php). Native IntersectionObserver
   (assets/js/site.js), one shared observer, one-shot (unobserve after first reveal, never replayed on
   scroll-up). Reuses the CP12B intensity tokens above (--reveal-y/--reveal-duration/--reveal-stagger), no
   separate intensity control.

   Progressive enhancement (see inc/motion.php's wp_head hook for the full reasoning): the hidden pre-reveal
   state below is gated behind `html.skif-reveal-js` alone — an early, synchronous, non-deferred inline
   <head> script, printed only when design_scroll_reveal is on (the same option the deferred body_class
   `.motion-scroll-reveal` reflects; both are always in sync for a given request, so requiring both here
   would be redundant — see below for why that redundancy specifically matters for specificity).
   `[data-reveal]`/`[data-reveal-item]` attributes are printed unconditionally by the Home renderers
   regardless of the toggle — they are inert without this gate, so the toggle being off (or JS never running)
   leaves the frontend exactly at its normal, fully visible resting state: no rule anywhere sets
   opacity/transform on these attributes outside this gated block. `.is-visible` (added by assets/js/site.js
   on intersection) then transitions back to the resting, fully-visible values.

   `data-reveal-item` additionally reads an inline `--reveal-index` (the element's position within its own
   grid — Generations, News cards) to derive a per-card transition-delay from the shared --reveal-stagger
   token; `data-reveal` (plain section-level reveal) never sets --reveal-index, so it defaults to 0 (no
   delay) — one rule serves both without duplication.

   CRITICAL specificity note (News/Partners, CP12C spec §9): the selector below is deliberately kept to ONE
   gating class (`.skif-reveal-js`) plus the attribute, not two — `html.skif-reveal-js [data-reveal-item]`
   sits at (0,2,1)/(0,3,1 with .is-visible), safely BELOW CP12B's `.motion-card-hover.motion-intensity-*
   .news-card:hover`/`:focus-within` (0,4,0) in the second specificity tier, so CP12B's hover/focus transform
   always wins regardless of source order or whether `.is-visible` is present. Adding the redundant
   `.motion-scroll-reveal` class here (as an earlier draft of this rule did) pushes `.is-visible`'s specificity
   to (0,4,1) — tying, then beating, CP12B's hover rule on the *third* tier — which would silently cancel the
   News/Partners hover lift after reveal. Do not add that class back without re-deriving this comparison. */
html.skif-reveal-js [data-reveal],
html.skif-reveal-js [data-reveal-item] {
	opacity: 0;
	transform: translateY(var(--reveal-y, 16px));
	transition: opacity var(--reveal-duration, .5s) ease-out, transform var(--reveal-duration, .5s) ease-out;
	transition-delay: calc(var(--reveal-index, 0) * var(--reveal-stagger, 0ms));
}
html.skif-reveal-js [data-reveal].is-visible,
html.skif-reveal-js [data-reveal-item].is-visible {
	opacity: 1;
	transform: none;
}

/* Reduced motion: content must be visible immediately, never waiting on IntersectionObserver to fire (a
   above-the-fold reveal target must not depend on the user scrolling first) — a stronger requirement than
   the global tokens.css catch-all alone provides (that only speeds up the transition once it runs, it
   doesn't skip the initial hidden state). !important mirrors tokens.css's own global reduced-motion
   mechanism, the same idiom already used at that one other spot in this codebase. Independent of, and
   without touching, the CP12B/parallax/momiji reduced-motion blocks elsewhere in this file. */
@media (prefers-reduced-motion: reduce) {
	[data-reveal], [data-reveal-item] { opacity: 1 !important; transform: none !important; }
}
