/* ================================================================
   TANTSUSTAAR THEME — assets/css/theme.css
   Ported from Design/v4/styles.css (v587+) into the @layer
   architecture defined in docs/wp-blueprint/component-inventory.md §9.

   Layer rules (do not break these):
   1. ALL @media rules live in `responsive` (the last layer) — nothing
      else goes there, and no @media anywhere else.
   2. Zero unlayered rules in this file. Only @font-face, @keyframes
      and @property may sit outside layers.
   3. !important is banned for ordering problems.
   4. Inside `responsive`: width queries desktop-first descending,
      then interaction-tier queries, then prefers-reduced-motion last.
   5. Canonical breakpoints: 900px + (hover:none) mobile/touch tier;
      grid collapses 980/940; small-phone 640/560. Do not invent new ones.
   ================================================================ */

/* ---------------------------------------------------------------
   FONTS — self-hosted Baumans + Exo (component-inventory §11)
   @font-face sits OUTSIDE all layers (unaffected by layer order).
   NOTE: Google ships Baumans in `latin` subset only (no latin-ext) —
   š/ž fall back to Exo in display type; ä ö ü õ are covered.
   --------------------------------------------------------------- */
@font-face {
  font-family: 'Baumans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/baumans-v18-latin-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/exo-v25-latin_latin-ext-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/exo-v25-latin_latin-ext-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/exo-v25-latin_latin-ext-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/exo-v25-latin_latin-ext-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/exo-v25-latin_latin-ext-700.woff2') format('woff2');
}

/* ---------------------------------------------------------------
   KEYFRAMES — outside layers
   --------------------------------------------------------------- */
@keyframes btnPulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,185,4,0.5); }
  70%  { box-shadow: 0 0 0 22px rgba(255,185,4,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,185,4,0); }
}
/* v5.3.1 — hero panel animates on load (no scroll-reveal dependency) */
@keyframes heroPanelIn {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes danceLine {
  0%   { left: -30%; }
  50%  { left: 100%; }
  100% { left: 100%; }
}
/* cta-band mesh drift (#36) */
@keyframes meshShift {
  0%   { background-position: 0% 0%, 100% 0%, 50% 100%, 0 0; }
  100% { background-position: 20% 10%, 80% 10%, 55% 90%, 0 0; }
}
/* v5.16 — content cutout float (#40) */
@keyframes cutoutFloat {
  from { transform: translateY(0) rotate(-0.6deg); }
  to   { transform: translateY(-10px) rotate(0.6deg); }
}
/* v5.15 — Ken Burns photo hero (pages awaiting real footage) */
@keyframes kenburns {
  from { transform: scale(1.04) translate(0.5%, 0.5%); }
  to   { transform: scale(1.14) translate(-1%, -1%); }
}

/* ---------------------------------------------------------------
   LAYER ORDER — declared once, structural override priority
   --------------------------------------------------------------- */
@layer reset, base, components, pages, integrations, utilities, responsive;

/* ================================================================
   LAYER: reset
   ================================================================ */
@layer reset {
  *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
  html { scroll-behavior: smooth; }
  img { max-width: 100%; display: block; }
  a { text-decoration: none; color: inherit; }
  button { font-family: inherit; }
}

/* ================================================================
   LAYER: base — design tokens, element defaults, container
   ================================================================ */
@layer base {
  :root {
    --color-yellow:  #FFB904;
    --color-orange:  #FF6500;
    --color-pink:    #F80086;
    --color-dark:    #1C1C1C;
    --color-dark-2:  #242424;
    --color-dark-3:  #2E2E2E;
    --color-light:   #FFFFFF;
    --color-light-2: #F5F5F5;
    --color-light-3: #EBEBEB;
    --text-on-dark:  #FFFFFF;
    --text-on-light: #1C1C1C;
    --text-muted:    #888888;

    --type-hero:   clamp(2rem, 5.2vw, 4rem);
    --type-h1:     clamp(2rem, 4vw, 3rem);
    --type-h2:     clamp(1.625rem, 3.2vw, 2.5rem);
    --type-h3:     clamp(1.125rem, 1.75vw, 1.5rem);
    --type-h4:     clamp(1rem, 1.35vw, 1.25rem);
    --type-body:   clamp(0.9rem, 1.1vw, 1rem);
    --type-small:  clamp(0.75rem, 0.9vw, 0.85rem);
    --type-nav:    clamp(0.76rem, 0.85vw, 0.85rem); /* v5.44: one step down — nav gained Tantsugrupid */

    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);

    --header-h: 88px;
  }

  body {
    font-family: 'Exo', sans-serif;
    font-weight: 300;
    line-height: 1.75;
    color: var(--text-on-light);
    background: var(--color-light);
    overflow-x: hidden;
  }

  .container {
    width: 100%;
    max-width: 1200px;
    margin-inline: auto;
    padding-inline: clamp(1.5rem, 5vw, 4rem);
  }

  /* Generic section rhythm (styles.css base rule) — sections without their
     own padding (team/story/studio-about/groups…) depend on it. Components
     with explicit padding beat this via layer order, same computed result
     as the prototype's specificity win. NOTE: the 640px tightening lives in
     `responsive`, where explicit section paddings are re-asserted (layer
     order would otherwise flip the prototype's specificity outcome). */
  section { padding-block: clamp(5rem, 10vw, 8rem); }

  /* Focus ring for accessibility */
  a:focus-visible, button:focus-visible {
    outline: 3px solid var(--color-yellow);
    outline-offset: 3px;
    border-radius: 4px;
  }
}

/* ================================================================
   LAYER: components — desktop values only, one block per component ID
   ================================================================ */
@layer components {

  /* ---------- #6 cursor-star ---------- */
  .cursor-feather {
    position: fixed;
    top: 0; left: 0;
    width: 20px; height: 20px;
    pointer-events: none;
    z-index: 9999;
    transform: translate3d(-100px, -100px, 0) rotate(0deg);
    will-change: transform;
    transition: width 0.3s var(--ease-spring), height 0.3s var(--ease-spring);
    color: var(--color-yellow);
    filter: drop-shadow(0 0 6px rgba(255,185,4,0.65)) drop-shadow(0 0 12px rgba(255,185,4,0.25));
  }
  .cursor-feather svg { width: 100%; height: 100%; display: block; }
  .cursor-feather.is-active {
    width: 30px; height: 30px;
    color: var(--color-pink);
    filter: drop-shadow(0 0 8px rgba(248,0,134,0.7)) drop-shadow(0 0 16px rgba(248,0,134,0.35));
  }
  .cursor-trail {
    position: fixed;
    top: 0; left: 0;
    pointer-events: none;
    z-index: 9998;
    transform: translate3d(-100px, -100px, 0) rotate(0deg);
    will-change: transform;
    color: var(--color-yellow);
  }
  .cursor-trail svg { width: 100%; height: 100%; display: block; }

  /* ---------- #1 site-header ---------- */
  .site-header {
    position: fixed; top: 0; left: 0; width: 100%;
    height: var(--header-h);
    background: var(--color-dark);
    z-index: 1000;
    transition: background 0.4s ease, backdrop-filter 0.4s ease, border-color 0.4s ease;
    border-bottom: 1px solid transparent;
  }
  .site-header.scrolled {
    background: rgba(28,28,28,0.8);
    backdrop-filter: saturate(1.4) blur(22px);
    -webkit-backdrop-filter: saturate(1.4) blur(22px);
    border-bottom-color: rgba(255,185,4,0.18);
  }
  .header-inner {
    display: flex; align-items: center; justify-content: space-between;
    height: var(--header-h);
  }
  .header-inner > nav { flex: 1; display: flex; justify-content: center; }
  .logo svg { height: 54px; width: auto; }

  .main-nav {
    display: flex; align-items: center; gap: clamp(1rem, 2vw, 2rem);
    list-style: none;
  }
  .main-nav > li { position: relative; }
  .main-nav a {
    color: rgba(255,255,255,0.85);
    font-size: var(--type-nav);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 0.5rem 0;
    position: relative;
    display: inline-flex;
    align-items: center;
    line-height: 1;
  }
  .main-nav > li > a::after {
    content: ''; position: absolute; bottom: -2px; left: 0;
    width: 0; height: 2px;
    background: linear-gradient(90deg, var(--color-yellow), var(--color-pink));
    transition: width 0.35s var(--ease-out);
  }
  .main-nav > li > a:hover::after { width: 100%; }
  .main-nav a:hover { color: #fff; }

  .nav-arrow {
    display: inline-block;
    width: 10px; height: 10px;
    margin-left: 0.45rem;
    background-color: var(--color-yellow);
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
    transition: transform 0.4s var(--ease-spring), background-color 0.3s ease;
  }
  .has-dropdown:hover .nav-arrow {
    transform: rotate(72deg) scale(1.15);
    background-color: var(--color-pink);
  }

  .nav-dropdown-panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 50%; transform: translateX(-50%) translateY(-8px);
    min-width: 240px;
    background: rgba(28,28,28,0.95);
    backdrop-filter: blur(20px);
    border: 1px solid rgba(255,185,4,0.2);
    border-radius: 14px;
    padding: 0.5rem;
    list-style: none;
    opacity: 0; visibility: hidden;
    transition: opacity 0.3s ease, transform 0.3s var(--ease-spring), visibility 0.3s;
  }
  .has-dropdown:hover .nav-dropdown-panel {
    opacity: 1; visibility: visible;
    transform: translateX(-50%) translateY(0);
  }
  .nav-dropdown-panel a {
    display: block;
    padding: 0.65rem 1rem;
    border-radius: 8px;
    text-transform: none;
    letter-spacing: 0.02em;
    font-size: 0.85rem;
    transition: background 0.2s, color 0.2s;
  }
  .nav-dropdown-panel a:hover {
    background: rgba(255,185,4,0.1);
    color: var(--color-yellow);
  }

  /* v5.45 — optical alignment: nav text centers on the logo WORDMARK */
  .main-nav { transform: translateY(-1.5px); }
  .header-cta { transform: translateY(-1px); } /* CTA joins the same optical line */
  /* v5.59 — header density: tighter nav gaps + guaranteed side margins */
  .main-nav { gap: clamp(0.9rem, 1.4vw, 1.5rem); }
  .header-inner > nav { margin: 0 clamp(1rem, 2vw, 2.2rem); }
  /* v5.59b — "E-pood" wrapped at its hyphen when the row tightened */
  .main-nav a { white-space: nowrap; }
  /* v5.59c — CTA pill wrapped to two lines under the same squeeze */
  .header-cta { white-space: nowrap; }

  .hamburger {
    display: none;
    width: 28px; height: 28px;
    background: transparent; border: 0;
    cursor: pointer;
    position: relative;
  }
  .hamburger span {
    position: absolute; left: 0; width: 100%; height: 2px;
    background: var(--color-yellow);
    transition: transform 0.3s ease, opacity 0.2s, top 0.3s ease;
  }
  .hamburger span:nth-child(1) { top: 6px; }
  .hamburger span:nth-child(2) { top: 13px; }
  .hamburger span:nth-child(3) { top: 20px; }
  .hamburger.active span:nth-child(1) { top: 13px; transform: rotate(45deg); }
  .hamburger.active span:nth-child(2) { opacity: 0; }
  .hamburger.active span:nth-child(3) { top: 13px; transform: rotate(-45deg); }

  /* ---------- #3 mobile-nav ---------- */
  .mobile-nav {
    position: fixed; inset: 0;
    background: var(--color-dark);
    z-index: 1001;
    display: flex; flex-direction: column;
    padding: clamp(4rem, 12vw, 5.5rem) 1.75rem 1.5rem;
    transform: translateX(100%);
    transition: transform 0.45s var(--ease-out);
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .mobile-nav.open { transform: translateX(0); }

  /* Decorative faded star in the corner for visual weight */
  .mobile-nav::before {
    content: '';
    position: absolute;
    top: -60px; right: -80px;
    width: 320px; height: 320px;
    background: var(--color-yellow);
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
    opacity: 0.06;
    pointer-events: none;
  }

  .mobile-nav-close {
    position: absolute; top: 1.25rem; right: 1.25rem;
    width: 44px; height: 44px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 50%;
    font-size: 1.4rem; color: var(--color-yellow);
    cursor: pointer;
    transition: background 0.3s ease, transform 0.3s var(--ease-spring);
    z-index: 2;
  }
  .mobile-nav-close:hover { background: var(--color-yellow); color: var(--color-dark); transform: rotate(90deg); }

  .mobile-nav-items {
    display: flex; flex-direction: column;
    gap: 0.3rem;
    position: relative;
    z-index: 1;
  }

  .mobile-nav-link {
    display: flex; align-items: center;
    gap: 0.9rem;
    padding: 0.65rem 0;
    color: #fff;
    font-family: 'Baumans', cursive;
    font-size: 1.55rem;
    letter-spacing: 0.03em;
    line-height: 1.1;
    position: relative;
  }
  .mobile-nav-star {
    display: inline-block;
    width: 13px; height: 13px;
    background-color: var(--star, var(--color-yellow));
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
    flex-shrink: 0;
    transition: transform 0.4s var(--ease-spring), background-color 0.3s ease;
  }
  .mobile-nav-link:active .mobile-nav-star,
  .mobile-nav-link:hover .mobile-nav-star {
    transform: rotate(72deg) scale(1.3);
  }
  .mobile-nav-link:hover { color: var(--color-yellow); }

  .mobile-nav-sub {
    display: flex; flex-direction: column;
    gap: 0.2rem;
    margin: 0.15rem 0 0.25rem 1.6rem;
    padding-left: 0.75rem;
    border-left: 1px solid rgba(255,255,255,0.12);
  }
  .mobile-nav-sub a {
    font-size: 0.92rem;
    font-family: 'Exo', sans-serif;
    color: rgba(255,255,255,0.6);
    padding: 0.35rem 0;
    transition: color 0.3s ease;
  }
  .mobile-nav-sub a:hover { color: var(--color-yellow); }

  .mobile-nav-bottom {
    margin-top: auto;
    padding-top: 1.75rem;
    border-top: 1px solid rgba(255,255,255,0.1);
    display: flex; flex-direction: column;
    gap: 1rem;
    position: relative; z-index: 1;
  }
  .mobile-nav-contact {
    display: flex; flex-direction: column;
    gap: 0.55rem;
  }
  .mobile-nav-contact a {
    display: flex; align-items: center;
    gap: 0.7rem;
    font-size: 0.88rem;
    color: rgba(255,255,255,0.75);
  }
  .mobile-nav-contact svg {
    width: 15px; height: 15px;
    color: var(--color-yellow);
    flex-shrink: 0;
  }
  .mobile-nav-social-row {
    display: flex;
    gap: 0.6rem;
  }
  .mobile-nav-social-row a {
    flex: 1;
    display: flex; align-items: center; justify-content: center;
    gap: 0.5rem;
    padding: 0.65rem 0.75rem;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 100px;
    color: #fff;
    font-size: 0.82rem;
    font-weight: 500;
    transition: background 0.3s ease, color 0.3s ease;
  }
  .mobile-nav-social-row a:hover {
    background: var(--color-yellow);
    color: var(--color-dark);
    border-color: var(--color-yellow);
  }
  .mobile-nav-social-row svg { width: 16px; height: 16px; }
  .mobile-nav-bottom > .btn-primary {
    justify-content: center;
    margin-top: 0.35rem;
  }

  /* ---------- #15 buttons ---------- */
  .btn-primary, .btn-ghost {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.85rem 2rem;
    border-radius: 100px;
    font-family: 'Exo', sans-serif;
    font-weight: 600;
    font-size: var(--type-small);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    border: 2px solid transparent;
    cursor: pointer;
    transition: background 0.3s ease, color 0.3s ease, box-shadow 0.4s ease, transform 0.3s var(--ease-spring);
    position: relative;
    will-change: transform;
  }
  .btn-primary {
    background: var(--color-yellow);
    color: var(--color-dark);
  }
  .btn-primary:hover {
    background: var(--color-orange);
    color: #fff;
    box-shadow: 0 10px 40px -10px rgba(255,101,0,0.7), 0 0 0 6px rgba(255,101,0,0.12);
  }
  .btn-primary.btn-sm { padding: 0.65rem 1.4rem; font-size: 0.72rem; }
  .btn-ghost {
    background: transparent;
    color: var(--color-yellow);
    border-color: var(--color-yellow);
  }
  .btn-ghost:hover { background: var(--color-yellow); color: var(--color-dark); }
  .btn-ghost--dark { color: var(--color-dark); border-color: var(--color-dark); }
  .btn-ghost--dark:hover { background: var(--color-dark); color: #fff; }

  .btn-group { display: inline-flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.5rem; }

  /* Pulse ring for signature CTA button */
  .btn-pulse {
    box-shadow: 0 0 0 0 rgba(255,185,4,0.5);
    animation: btnPulse 2.4s ease-out infinite;
  }

  /* ---------- #14 section-heading ---------- */
  .section-label {
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-size: var(--type-small);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--color-pink);
    margin-bottom: 1rem;
  }
  .section-label--pink { color: var(--color-pink); }
  /* v5.39 — class detail accent variants */
  .section-label--orange { color: var(--color-orange); }
  .section-label--yellow { color: #E09E00; }
  .section-label::before {
    content: '';
    display: inline-block;
    width: 14px; height: 14px;
    background: currentColor;
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  }
  .section-title {
    font-family: 'Baumans', cursive;
    font-size: var(--type-h2);
    color: var(--color-dark);
    letter-spacing: 0.01em;
    line-height: 1.15;
    margin-bottom: 1rem;
  }
  .section-subtitle {
    color: var(--text-muted);
    max-width: 560px;
    font-size: var(--type-body);
  }
  .section-subtitle--center { margin-inline: auto; }

  /* ---------- #11 page-header (compact dark band, non-video pages) ---------- */
  .page-header {
    position: relative;
    background: var(--color-dark);
    color: #fff;
    /* v5.81 (Edward 2026-07-08): trim wasted vertical space — the breathing
       padding above the label + below the sub was ~half the band. Cut the
       trimmable padding ~45% (the --header-h clearance for the fixed header
       stays). Site-wide (every .page-header page). */
    padding: calc(var(--header-h) + clamp(0.7rem, 1.6vh, 1.1rem)) 0 clamp(0.9rem, 2vh, 1.4rem);
    overflow: hidden;
  }
  /* v5.24 — tight header gap */
  .page-header { padding-bottom: clamp(0.9rem, 2vh, 1.4rem); } /* v5.81: trimmed with the base */
  /* v5.81: tighten the label→title→sub gaps too (part of the ~25% space saving) */
  .page-header .section-label { margin-bottom: 0.5rem; }
  .page-header-sub { margin-top: 0.1rem; }
  .page-header::before {
    content: '';
    position: absolute; inset: 0;
    background:
      radial-gradient(ellipse 60% 80% at 85% 10%, rgba(248,0,134,0.14) 0%, transparent 60%),
      radial-gradient(ellipse 50% 70% at 10% 90%, rgba(255,101,0,0.10) 0%, transparent 60%);
    pointer-events: none;
  }
  .page-header .container { position: relative; }
  .page-header .section-label { color: var(--color-yellow); }
  .page-header-title {
    font-family: 'Baumans', cursive;
    /* v6.2 (Edward 2026-07-08): unified header title — the e-pood "slim" size,
       bumped slightly. Applied site-wide via the base class so every page-header
       matches (was clamp(2.6rem,6vw,4.2rem); shop was clamp(1.6,2.8vw,2.3)). */
    font-size: clamp(2rem, 3.3vw, 2.7rem);
    line-height: 1.1;
    margin-block: 0.2rem 0.45rem; /* v5.81: tighter than 0.5/0.8 to reclaim band space */
  }
  .page-header-sub { max-width: 60ch; color: rgba(255,255,255,0.8); }
  .page-header-reveal { animation: heroPanelIn 0.8s var(--ease-out) 0.15s backwards; }

  /* ---------- #13 bottom-curve (hero-bottom-curve) ----------
     Base rules + the v4.1 review-fix override, in prototype cascade
     order. Net result since v4.1: the curve SVG is hidden and the
     divider renders as an absolutely-positioned 5px brand-gradient
     line at the bottom of the dark band (dark → light transition).
     Without these rules the in-flow SVG painted white/black strips. */
  .hero-bottom-curve {
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    line-height: 0;
    z-index: 3;
    pointer-events: none;
  }
  .hero-bottom-curve svg { width: 100%; height: 90px; display: block; }
  .hero-bottom-curve path { transition: d 7s ease-in-out; }
  /* v4.1 review fix 2 — curved separators → straight brand-gradient lines
     (panel-wave / panel-bottom-curve / cta-bottom-curve arrive with their pages) */
  .hero-bottom-curve svg { display: none; }
  .hero-bottom-curve {
    height: 5px;
    bottom: 0;
    background: linear-gradient(90deg, #F80086 0%, #FF6500 50%, #FFB904 100%);
  }

  /* ---------- #5 site-footer ---------- */
  .site-footer {
    background: var(--color-dark);
    color: rgba(255,255,255,0.75);
    padding-block: clamp(5rem, 8vw, 7rem) 2rem;
    position: relative;
    overflow: hidden;
  }
  .footer-grid {
    display: grid;
    grid-template-columns: 1.6fr 1fr 1fr;
    gap: clamp(3rem, 6vw, 5rem);
    align-items: start;
  }
  .footer-logo svg {
    height: clamp(70px, 8vw, 110px);
    width: auto;
  }
  .footer-brand p {
    margin-top: 1.5rem;
    font-size: 0.95rem;
    line-height: 1.7;
    max-width: 420px;
    color: rgba(255,255,255,0.7);
  }
  .footer-heading {
    font-family: 'Baumans', cursive;
    font-size: 1.1rem;
    color: var(--color-yellow);
    margin-bottom: 1.4rem;
    letter-spacing: 0.05em;
  }
  .footer-links { list-style: none; display: flex; flex-direction: column; gap: 0.7rem; }
  .footer-links a {
    font-size: 0.92rem;
    position: relative;
    display: inline-flex; align-items: center;
    transition: color 0.3s, padding-left 0.3s;
  }
  .footer-links a::before {
    content: '';
    width: 0; height: 1.5px;
    background: var(--color-yellow);
    margin-right: 0;
    transition: width 0.3s ease, margin-right 0.3s ease;
  }
  .footer-links a:hover { color: var(--color-yellow); }
  .footer-links a:hover::before { width: 14px; margin-right: 10px; }

  .footer-contact-item {
    display: flex; align-items: center; gap: 0.85rem;
    margin-bottom: 1rem;
    font-size: 0.92rem;
  }
  .footer-contact-icon {
    width: 36px; height: 36px;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(255,185,4,0.08);
    border: 1px solid rgba(255,185,4,0.2);
    border-radius: 50%;
    color: var(--color-yellow);
    flex-shrink: 0;
    transition: background 0.3s ease, transform 0.3s var(--ease-spring);
  }
  .footer-contact-icon svg { width: 16px; height: 16px; }
  .footer-contact-item:hover .footer-contact-icon { background: rgba(255,185,4,0.18); transform: scale(1.08); }
  .footer-contact-item a:hover { color: var(--color-yellow); }

  .footer-social {
    display: flex; flex-direction: column;
    gap: 0.75rem;
    margin-top: 2rem;
    max-width: 340px;
  }
  .footer-social a {
    display: inline-flex; align-items: center; gap: 0.8rem;
    padding: 0.7rem 1.1rem 0.7rem 0.7rem;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 100px;
    color: #fff;
    font-size: 0.88rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    transition: background 0.35s ease, border-color 0.35s ease, transform 0.35s var(--ease-spring), color 0.3s;
    position: relative;
    overflow: hidden;
  }
  .footer-social a::before {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(90deg, var(--color-pink), var(--color-orange), var(--color-yellow));
    opacity: 0;
    transition: opacity 0.4s ease;
    z-index: 0;
  }
  .footer-social a > * { position: relative; z-index: 1; }
  .footer-social a:hover {
    border-color: transparent;
    color: var(--color-dark);
    transform: translateX(4px);
  }
  .footer-social a:hover::before { opacity: 1; }
  .footer-social-icon {
    width: 36px; height: 36px;
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: #fff;
    border-radius: 50%;
    color: var(--color-dark);
    transition: background 0.35s ease;
  }
  .footer-social-icon svg { width: 18px; height: 18px; }
  .footer-social a:hover .footer-social-icon { background: var(--color-dark); color: #fff; }
  .footer-social-label { display: flex; flex-direction: column; line-height: 1.2; }
  .footer-social-label strong { font-weight: 600; color: #fff; transition: color 0.3s; }
  .footer-social-label span { font-size: 0.72rem; color: rgba(255,255,255,0.5); letter-spacing: 0.12em; text-transform: uppercase; transition: color 0.3s; }
  .footer-social a:hover .footer-social-label strong,
  .footer-social a:hover .footer-social-label span { color: var(--color-dark); }

  .footer-dance-line {
    position: relative;
    height: 2px;
    margin-top: 3rem;
    margin-bottom: 1.5rem;
    background: rgba(255,255,255,0.08);
    overflow: hidden;
    border-radius: 2px;
  }
  .footer-dance-line::after {
    content: '';
    position: absolute; top: 0; left: -30%;
    height: 100%; width: 30%;
    background: linear-gradient(90deg, transparent 0%, var(--color-pink) 30%, var(--color-orange) 55%, var(--color-yellow) 80%, transparent 100%);
    animation: danceLine 5s ease-in-out infinite;
    border-radius: 2px;
  }
  .footer-bottom {
    text-align: center;
    color: rgba(255,255,255,0.4);
    font-size: 0.8rem;
    letter-spacing: 0.05em;
  }

  /* ---------- #7 section-rail ----------
     Ported as the prototype's v-block cascade (v5.0 → v5.1.1) in source
     order — same-layer source order reproduces the exact computed values. */
  /* v5.0 — section rail (replaces scroll hint + back-to-top) */
  .section-rail {
    position: fixed;
    right: 26px; top: 50%;
    transform: translateY(-50%);
    z-index: 60;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
  }
  .rail-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: none;
    border: 0;
    padding: 5px 0;
    cursor: pointer;
    font: inherit;
  }
  .rail-line {
    display: block;
    width: 22px; height: 2px;
    border-radius: 2px;
    background: rgba(255,255,255,0.35);
    transition: width 0.35s var(--ease-out), background 0.3s ease, box-shadow 0.3s ease;
  }
  .rail-item:hover .rail-line { background: rgba(255,255,255,0.75); }
  .rail-item.is-active .rail-line {
    width: 38px; height: 3px;
    background: linear-gradient(90deg, #F80086 0%, #FF6500 50%, #FFB904 100%);
    box-shadow: 0 0 12px rgba(255,101,0,0.45);
  }
  .rail-label {
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    white-space: nowrap;
    color: rgba(255,255,255,0.88);
    opacity: 0;
    transform: translateX(6px);
    transition: opacity 0.3s ease, transform 0.3s var(--ease-out);
    pointer-events: none;
  }
  .rail-label em { font-style: normal; font-weight: 600; color: var(--color-yellow); }
  .rail-item.is-active .rail-label,
  .rail-item:hover .rail-label { opacity: 1; transform: translateX(0); }

  /* adaptive contrast when the active section is light */
  .section-rail.on-light .rail-line { background: rgba(28,28,28,0.3); }
  .section-rail.on-light .rail-item:hover .rail-line { background: rgba(28,28,28,0.6); }
  .section-rail.on-light .rail-label { color: rgba(28,28,28,0.88); }
  .section-rail.on-light .rail-label em { color: var(--color-orange); }

  /* v5.0.1 — compact rail + top/bottom arrows */
  .section-rail { gap: 2px; }
  .rail-item { padding: 3px 0; }
  .rail-arrow {
    background: none;
    border: 0;
    padding: 4px 0;
    cursor: pointer;
    color: rgba(255,255,255,0.55);
    display: flex;
    justify-content: flex-end;
    width: 100%;
    transition: color 0.3s ease, transform 0.3s var(--ease-out);
  }
  .rail-arrow svg { width: 15px; height: 15px; display: block; margin-right: 3px; }
  .rail-arrow--up { margin-bottom: 5px; }
  .rail-arrow--down { margin-top: 5px; }
  .rail-arrow--up:hover { color: var(--color-yellow); transform: translateY(-2px); }
  .rail-arrow--down:hover { color: var(--color-yellow); transform: translateY(2px); }
  .section-rail.on-light .rail-arrow { color: rgba(28,28,28,0.5); }
  .section-rail.on-light .rail-arrow--up:hover,
  .section-rail.on-light .rail-arrow--down:hover { color: var(--color-orange); }

  /* v5.0.2 — tighter rail, prominent clickable arrows */
  .section-rail { gap: 0; }
  .rail-item { padding: 2px 0; }
  .rail-arrow {
    width: 28px; height: 28px;
    padding: 0;
    border: 1px solid rgba(255,255,255,0.45);
    border-radius: 50%;
    background: rgba(28,28,28,0.35);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: #fff;
    display: grid;
    place-items: center;
    align-self: flex-end;
  }
  .rail-arrow svg { width: 14px; height: 14px; margin: 0; }
  .rail-arrow--up { margin-bottom: 9px; }
  .rail-arrow--down { margin-top: 9px; }
  .rail-arrow--up:hover,
  .rail-arrow--down:hover {
    background: var(--color-yellow);
    border-color: var(--color-yellow);
    color: var(--color-dark);
  }
  .section-rail.on-light .rail-arrow {
    border-color: rgba(28,28,28,0.45);
    background: rgba(255,255,255,0.5);
    color: var(--color-dark);
  }
  .section-rail.on-light .rail-arrow--up:hover,
  .section-rail.on-light .rail-arrow--down:hover {
    background: var(--color-orange);
    border-color: var(--color-orange);
    color: #fff;
  }

  /* v5.0.3 — align arrow circles to the line column axis */
  .rail-arrow {
    width: 26px; height: 26px;
    margin-right: -2px;
  }

  /* v5.0.4 — REAL rail compaction: labels out of flow */
  .rail-item {
    position: relative;
    padding: 4px 0 4px 18px; /* left padding = bigger hover/click area */
  }
  .rail-label {
    position: absolute;
    right: calc(100% + 12px);
    top: 50%;
    transform: translate(6px, -50%);
  }
  .rail-item.is-active .rail-label,
  .rail-item:hover .rail-label {
    opacity: 1;
    transform: translate(0, -50%);
  }

  /* v5.1 — rail as one glass pill */
  .section-rail {
    align-items: center;
    width: 46px;
    gap: 0;
    padding: 8px 0;
    background: rgba(28,28,28,0.34);
    border: 1px solid rgba(255,255,255,0.18);
    border-radius: 999px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }
  .rail-item {
    width: 100%;
    display: flex;
    justify-content: center;
    padding: 4px 0;
  }
  .rail-line { width: 18px; }
  .rail-item.is-active .rail-line { width: 30px; }
  .rail-arrow {
    width: 100%;
    height: 24px;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    color: rgba(255,255,255,0.75);
    display: grid;
    place-items: center;
    align-self: center;
  }
  .rail-arrow--up { margin-bottom: 3px; }
  .rail-arrow--down { margin-top: 3px; }
  .rail-arrow--up:hover, .rail-arrow--down:hover {
    background: none;
    border: 0;
    color: var(--color-yellow);
    transform: none;
  }
  .rail-label {
    right: calc(100% + 14px);
    background: rgba(28,28,28,0.62);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    padding: 5px 12px;
    border-radius: 10px;
    color: #fff;
  }
  /* pill is self-contrasting — neutralize the on-light variants */
  .section-rail.on-light .rail-line { background: rgba(255,255,255,0.35); }
  .section-rail.on-light .rail-item:hover .rail-line { background: rgba(255,255,255,0.75); }
  .section-rail.on-light .rail-label { color: #fff; }
  .section-rail.on-light .rail-label em { color: var(--color-yellow); }
  .section-rail.on-light .rail-arrow { border: 0; background: none; color: rgba(255,255,255,0.75); }
  .section-rail.on-light .rail-arrow--up:hover,
  .section-rail.on-light .rail-arrow--down:hover { background: none; color: var(--color-yellow); }

  /* v5.1.1 — arrow chevron centering */
  .rail-arrow {
    justify-content: center;
    justify-items: center;
    align-content: center;
  }

  /* ---------- #23 team-card (+ team-grid / team-section shell) ---------- */
  .team-section {
    background: var(--color-light);
    position: relative;
  }
  .team-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.25rem, 2.5vw, 2rem);
    margin-top: 3rem;
  }
  .team-card {
    position: relative;
    display: flex; flex-direction: column;
    background: var(--color-light);
    border-radius: 20px;
    overflow: hidden;
    transition: transform 0.45s var(--ease-spring), box-shadow 0.45s ease;
    cursor: default;
  }
  .team-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 28px 50px -18px rgba(28,28,28,0.2);
  }
  /* Portrait photo fills the top — taller than wide (4/5 aspect) */
  .team-card-photo {
    position: relative;
    /* 2026-08-03: 4/5 -> 3/4 to match the v2 greet clips (834x1112 = exactly
       3:4). object-fit: cover crops whatever is narrower than the frame, so a
       mismatched frame cropped the video and its poster by DIFFERENT amounts
       and the portrait visibly jumped the moment playback started. At 3/4 the
       v2 clips and their frame-0 posters both fill with zero crop, so the
       handoff is pixel-identical. This is also strictly better for the members
       still on v1: the 547x833 photos now crop 12% instead of 18%, and the old
       9:16 clips 25% instead of 30%. */
    aspect-ratio: 3/4;
    overflow: hidden;
    background: linear-gradient(135deg, var(--color-pink) 0%, var(--color-orange) 50%, var(--color-yellow) 100%);
    display: flex; align-items: center; justify-content: center;
    color: #fff;
    font-family: 'Baumans', cursive;
    font-size: clamp(3rem, 5vw, 4.5rem);
    letter-spacing: 0.04em;
  }
  .team-card-photo img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: center 20%;
    display: block;
    transition: transform 0.8s var(--ease-out);
  }
  .team-card:hover .team-card-photo img { transform: scale(1.04); }
  /* Subtle gradient overlay at bottom of photo for text legibility */
  .team-card-photo::after {
    content: '';
    position: absolute; inset: auto 0 0 0;
    height: 40%;
    background: linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.08) 100%);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.4s ease;
  }
  .team-card:hover .team-card-photo::after { opacity: 1; }
  /* Info block below photo */
  .team-card-info {
    padding: 1.1rem 1.1rem 1.25rem;
    display: flex; flex-direction: column;
    gap: 0.35rem;
  }
  .team-card-name {
    font-family: 'Exo', sans-serif;
    font-weight: 600;
    font-size: clamp(1.05rem, 1.4vw, 1.2rem);
    color: var(--color-dark);
    line-height: 1.2;
    letter-spacing: 0.005em;
  }
  .team-card-role {
    font-family: 'Exo', sans-serif;
    font-weight: 500;
    font-size: 0.82rem;
    color: var(--color-pink);
    line-height: 1.4;
    min-height: 2.3em;
  }
  .team-card-email {
    font-family: 'Exo', sans-serif;
    font-weight: 400;
    font-size: 0.78rem;
    color: var(--text-muted);
    word-break: break-all;
    margin-top: 0.15rem;
    transition: color 0.3s ease;
  }
  .team-card-email:hover { color: var(--color-orange); }
  /* Leadership: brand-colour ring appears on hover + role colour shifts */
  .team-card--lead .team-card-role { color: var(--color-orange); }
  .team-card--lead::after {
    content: '';
    position: absolute; inset: 0;
    border-radius: inherit;
    pointer-events: none;
    box-shadow: inset 0 0 0 0 transparent;
    transition: box-shadow 0.45s ease;
  }
  .team-card--lead:hover::after {
    box-shadow: inset 0 0 0 2px rgba(255,101,0,0.8);
  }
  /* Star badge in top-right for leadership */
  .team-card-badge {
    position: absolute;
    top: 0.85rem; right: 0.85rem;
    width: 18px; height: 18px;
    background: var(--color-pink);
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
    z-index: 3;
    filter: drop-shadow(0 2px 6px rgba(0,0,0,0.3));
  }
  /* v5.2 — living team portraits: video behaves exactly like the img */
  .team-card-photo video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  /* v5.40 (generalized from .class-teacher-card to all team cards) —
     media must FILL the 4/5 frame: the v5.2 sizing leaves the video a
     flex-centered child with intrinsic size, so on hover-play (and
     during the network fetch gap) the brand-gradient fallback peeks
     through as bands. Absolute inset-0 fill + neutral white fallback
     matches the portrait background — worst case is a white flash on
     a white card. MUST stay AFTER the base .team-card-photo + v5.2
     rules (same layer + specificity → source order decides).
     Scoped to photo boxes that actually CONTAIN media (about page has
     initials-only cards — "LT"/"BT" — that need the base brand-gradient;
     the prototype kept it via .class-teacher-card scoping, our
     generalization must not flood them white). */
  .team-card-photo:has(img, video) { background: #fff; }
  .team-card-photo video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 20%;
  }
  /* poster-overlay — theme improvement over the (disk-served) prototype:
     on play() the browser drops the video's poster attribute BEFORE the
     first frame decodes, so a network-served video blinks white once per
     session. A separate overlay <img> sits above the video and fades out
     on 'playing' / back in on pause (JS toggles .is-video-live on the
     card). THE standard for all hover-video cards (component #23). */
  .team-card-poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 20%;
    transition: opacity 0.28s ease;
    pointer-events: none;
  }
  .team-card.is-video-live .team-card-poster { opacity: 0; }

  /* ---------- #10 page-hero-video (+ hero copy atoms) ----------
     Family port in prototype append order (porting lesson #1): index
     hero atoms (.hero-eyebrow/-title/-subtitle/-buttons/-slide-overlay,
     .hero-media) → v5.2 (.page-hero-video) → v5.5 (classes-hero) →
     v5.15 (kenburns variant). @media rules → `responsive`.
     Skipped as dead since v5.4 "pure cinema" (no markup references
     them on any of the 18 pages): .page-hero-scrim, .page-hero-content,
     .page-hero-eyebrow/-title, .page-hero-panel. Swiper-scoped reveal
     rules (.swiper-slide-active …) ship with the index port. */
  .hero-slide-overlay { position: absolute; inset: 0; }
  .hero-eyebrow {
    font-size: var(--type-small);
    font-weight: 300;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--color-yellow);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.8s ease, transform 0.8s var(--ease-out);
    transition-delay: 0.15s;
  }
  .hero-title {
    font-family: 'Baumans', cursive;
    font-size: var(--type-hero);
    line-height: 1.1;
    letter-spacing: 0.02em;
    color: var(--color-yellow);
    clip-path: inset(0 100% 0 0);
    transition: clip-path 1s var(--ease-out);
    transition-delay: 0.35s;
  }
  .hero-subtitle {
    color: #fff;
    max-width: 480px;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.8s ease, transform 0.8s var(--ease-out);
    transition-delay: 0.55s;
  }
  .hero-buttons {
    display: flex; flex-wrap: wrap; gap: 0.75rem;
    margin-top: 0.5rem;
    opacity: 0; transform: translateY(12px);
    transition: opacity 0.8s ease, transform 0.8s var(--ease-out);
    transition-delay: 0.75s;
  }
  /* hero mixed media (img/video fills the hero) */
  .hero-media {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    transform: scale(1.05);
    transition: transform 6s ease;
    background: var(--color-dark);
  }

  /* ---------- optional 9:16 phone asset ----------
     Images pick themselves via <picture><source media>, so nothing is needed
     for them here. Video cannot: browsers ignore a media attribute on <source>
     inside <video>, so ts_hero_media_markup() emits two <video> elements and
     this hides one.

     Hiding is what keeps it cheap. Both elements are preload="none", and the
     IntersectionObserver in main.js starts playback — a display:none element
     never intersects, so the hidden variant is never played and its file is
     never fetched. The wide default below means a browser with no support for
     the portrait query still gets exactly one video. ---------- */
  .hero-media--tall { display: none; }
  @media (max-width: 900px) and (orientation: portrait) {
    .hero-media--wide { display: none; }
    .hero-media--tall { display: block; }
    /* Stands in for the poster attribute. Declared only inside this query so a
       desktop never fetches it — measured: Chrome pulls a poster="" even for a
       display:none <video>, which cost 119 KB per desktop view. */
    .hero-media--tall {
      background-image: var(--tall-poster);
      background-size: cover;
      background-position: center;
      background-repeat: no-repeat;
    }
  }
  /* v5.2 — cinematic page hero (about + all video-hero subpages) */
  .page-hero-video {
    position: relative;
    height: 100vh;
    height: 100svh;
    min-height: 560px;
    overflow: hidden;
    background: var(--color-dark);
    display: flex;
    align-items: flex-end;
  }
  /* v5.5 — classes-hero: homepage-style left copy over directional scrim */
  .classes-hero { align-items: center; }
  .classes-hero-scrim {
    position: absolute; inset: 0;
    background: linear-gradient(90deg, rgba(28,28,28,0.88) 0%, rgba(28,28,28,0.55) 45%, rgba(28,28,28,0.15) 100%);
  }
  .classes-hero-content {
    position: relative; z-index: 2;
    display: flex; flex-direction: column; gap: 1rem;
  }
  .classes-hero-content > * { max-width: 580px; }

  /* ---------- page/post hero schemes (.page-hero--*) ----------
     Picked per hero in the admin ("Skeem") to suit its image. The class is
     stamped by ts_render_hero(); the rule above is the shared default, and each
     scheme below replaces only what it needs to.

     The left-to-right gradient assumes a quiet left edge. That holds for the
     curated page photography but not for a news featured image — the event
     posters carry their own large type right where the copy sits, and no
     gradient strength makes yellow text safe over one. `panel` and `bottom`
     exist for those. ---------- */

  /* Tume — the shared default; named so the admin choice is explicit. */
  .page-hero--dark .classes-hero-scrim {
    background: linear-gradient(90deg, rgba(28,28,28,0.88) 0%, rgba(28,28,28,0.55) 45%, rgba(28,28,28,0.15) 100%);
  }

  /* Hele — for images that are already dark; copy flips to the dark ink. */
  .page-hero--light .classes-hero-scrim {
    background: linear-gradient(90deg, rgba(255,255,255,0.86) 0%, rgba(255,255,255,0.5) 45%, rgba(255,255,255,0.06) 100%);
  }
  .page-hero--light .hero-title,
  .page-hero--light .hero-subtitle { color: var(--color-dark); }
  .page-hero--light .hero-eyebrow { color: var(--color-pink); }
  .page-hero--light .post-date { color: rgba(28,28,28,0.75); }
  .page-hero--light .post-back { color: var(--color-dark); border-color: rgba(28,28,28,0.3); }

  .page-hero--red .classes-hero-scrim {
    background: linear-gradient(90deg, rgba(100,0,20,0.85) 0%, rgba(100,0,20,0.45) 45%, rgba(100,0,20,0.1) 100%);
  }

  /* Tume paneel — the copy gets its own contained ground instead of relying on
     the image behind it, so contrast is fixed rather than a gamble. The image
     stays visible around it, which a full-width heavy scrim would deny. The
     scrim drops to a light overall dim purely to seat the panel. */
  .page-hero--panel .classes-hero-scrim {
    background: linear-gradient(90deg, rgba(28,28,28,0.55) 0%, rgba(28,28,28,0.3) 55%, rgba(28,28,28,0.12) 100%);
  }
  .page-hero--panel .classes-hero-content {
    background: rgba(20, 14, 22, 0.9);
    backdrop-filter: blur(3px);
    border-radius: 20px;
    padding: clamp(1.5rem, 3vw, 2.4rem) clamp(1.5rem, 3vw, 2.6rem);
    max-width: min(760px, 100%);
    box-shadow: 0 24px 60px -24px rgba(0,0,0,0.55);
  }
  /* The panel is the measure now — an inner cap would double-constrain and
     leave the ragging tighter than the box it sits in. */
  .page-hero--panel .classes-hero-content > * { max-width: none; }

  /* ---------- match the front-page slider exactly ----------
     The same image is often used for a front-page slide and for the post it
     links to, so these three reproduce the slide look on a post hero. They read
     --scrim-slide-* (declared with the slider rules further down) instead of
     repeating the gradients, so the two stay identical by construction — the
     hand-written page versions above had already drifted from the slide values
     they were meant to echo (0.88 vs 0.9, and a tail that never clears).

     Kept alongside rather than replacing dark/light/red: those are tuned
     stronger, and all four page heroes run video behind them where the scrim
     was judged against real footage. ---------- */
  .page-hero--slide-dark .classes-hero-scrim  { background: var(--scrim-slide-dark); }
  .page-hero--slide-light .classes-hero-scrim { background: var(--scrim-slide-light); }
  .page-hero--slide-red .classes-hero-scrim   { background: var(--scrim-slide-red); }
  /* Same ink flip the slider applies on its light slides. */
  .page-hero--slide-light .hero-title,
  .page-hero--slide-light .hero-subtitle { color: var(--color-dark); }
  .page-hero--slide-light .hero-eyebrow { color: var(--color-pink); }
  .page-hero--slide-light .post-date { color: rgba(28,28,28,0.75); }
  .page-hero--slide-light .post-back { color: var(--color-dark); border-color: rgba(28,28,28,0.3); }

  /* Alt üles — copy at the bottom under a vertical scrim, for images whose
     subject sits high in the frame. */
  .page-hero--bottom { align-items: flex-end; }
  .page-hero--bottom .classes-hero-scrim {
    background: linear-gradient(0deg, rgba(28,28,28,0.92) 0%, rgba(28,28,28,0.72) 30%, rgba(28,28,28,0.28) 62%, rgba(28,28,28,0.05) 100%);
  }
  .page-hero--bottom .classes-hero-content { padding-bottom: clamp(1rem, 3vh, 2.5rem); }

  /* hero copy reveals on load, not on scroll-IO (prototype-original
     !important — overrides the atoms' initial hidden states) */
  .classes-hero-reveal { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .classes-hero-content .hero-eyebrow { animation: heroPanelIn 0.8s var(--ease-out) 0.15s backwards; }
  .classes-hero-content .hero-title { animation: heroPanelIn 0.9s var(--ease-out) 0.3s backwards; }
  .classes-hero-content .hero-subtitle { animation: heroPanelIn 0.9s var(--ease-out) 0.45s backwards; }
  .classes-hero-content .hero-buttons { animation: heroPanelIn 0.9s var(--ease-out) 0.6s backwards; }
  /* v5.15 — Ken Burns photo hero (img variant, lastetants) */
  .kenburns-hero .hero-media {
    animation: kenburns 20s ease-in-out infinite alternate;
    transition: none;
  }

  /* ---------- #36 cta-band — "Liitu Tantsustaari perega!" ----------
     Family port in prototype append order: base band → v4 blended-video
     upgrade → v4 text-shadow polish → v4.1 straight gradient line →
     v4.3 full-height. Touch/640px rules → `responsive`. */
  .cta-section {
    position: relative;
    overflow: hidden;
    padding-top: clamp(5rem, 9vw, 7rem);
    padding-bottom: clamp(6rem, 10vw, 9rem); /* lifts content above the wave */
    background: var(--color-light);
    text-align: center;
    isolation: isolate;
  }
  /* Wave baked into the CTA bottom — mirrors the hero pattern */
  .cta-bottom-curve {
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    line-height: 0;
    z-index: 2;
    pointer-events: none;
  }
  .cta-bottom-curve svg { width: 100%; height: 90px; display: block; }
  .cta-bottom-curve path { transition: d 7s ease-in-out; }
  .cta-mesh {
    position: absolute; inset: 0;
    z-index: -1;
    background:
      radial-gradient(ellipse 60% 50% at 20% 30%, rgba(248,0,134,0.22) 0%, transparent 55%),
      radial-gradient(ellipse 55% 45% at 80% 20%, rgba(255,101,0,0.22) 0%, transparent 55%),
      radial-gradient(ellipse 70% 55% at 60% 85%, rgba(255,185,4,0.28) 0%, transparent 55%),
      linear-gradient(180deg, #fff 0%, #FFF7E3 100%);
    animation: meshShift 18s ease-in-out infinite alternate;
  }
  .cta-section .cta-star {
    position: absolute;
    top: 42%; left: 50%;
    width: clamp(160px, 22vw, 300px);
    aspect-ratio: 1;
    transform: translate(-50%, -50%) scale(0) rotate(-30deg);
    opacity: 0.3;
    transition: transform 1.4s var(--ease-spring), opacity 1s ease;
    pointer-events: none;
    z-index: -1;
  }
  .cta-section.visible .cta-star { transform: translate(-50%, -50%) scale(1) rotate(15deg); opacity: 0.22; }
  .cta-section h2 {
    font-family: 'Baumans', cursive;
    font-size: clamp(2.25rem, 5vw, 3.75rem);
    line-height: 1.1;
    letter-spacing: 0.02em;
    color: var(--color-dark);
    margin-bottom: 1rem;
  }
  .cta-section p {
    max-width: 560px;
    margin-inline: auto;
    color: var(--color-dark);
    opacity: 0.8;
  }
  .cta-section .btn-group { justify-content: center; }
  /* v4 — CTA: blended video band */
  .cta-media-wrap { position: absolute; inset: 0; z-index: -2; }
  .cta-media {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    /* darker + punchier footage so the video reads through the brand tint */
    filter: brightness(0.82) contrast(1.18) saturate(1.05);
  }
  .cta-media-tint {
    position: absolute; inset: 0;
    /* Dark base grounds the footage; the brand gradient sits on top as a lighter accent
       (not a full wash), so the video reads through with contrast instead of drowning in
       bright colour. */
    background:
      linear-gradient(120deg, rgba(248,0,134,0.40) 0%, rgba(255,101,0,0.34) 55%, rgba(255,185,4,0.26) 100%),
      linear-gradient(180deg, rgba(18,16,22,0.50) 0%, rgba(18,16,22,0.62) 100%);
  }
  .cta-section { color: #fff; }
  .cta-section .section-label { color: #FFE9A8; }
  .cta-section h2 { color: #fff; }
  .cta-section > .container > p { color: rgba(255,255,255,0.92); }
  .cta-section .cta-mesh {
    background:
      radial-gradient(ellipse 60% 50% at 20% 30%, rgba(255,255,255,0.06) 0%, transparent 55%),
      radial-gradient(ellipse 55% 45% at 80% 20%, rgba(255,255,255,0.04) 0%, transparent 55%),
      radial-gradient(ellipse 70% 55% at 60% 85%, rgba(28,28,28,0.30) 0%, transparent 60%);
  }
  .cta-section .cta-star { opacity: 0.5; }
  .cta-section .btn-ghost--dark {
    border-color: rgba(255,255,255,0.85);
    color: #fff;
  }
  .cta-section .btn-ghost--dark:hover {
    background: rgba(255,255,255,0.12);
    border-color: #fff;
  }
  /* v4 polish: keep CTA copy readable over busy video footage */
  .cta-section h2,
  .cta-section > .container > p,
  .cta-section .section-label { text-shadow: 0 1px 14px rgba(28,28,28,0.45); }
  /* v4.1 review fix 2 — curved separator → straight brand-gradient line */
  .cta-bottom-curve svg { display: none; }
  .cta-bottom-curve {
    height: 5px;
    bottom: 0;
    background: linear-gradient(90deg, #F80086 0%, #FF6500 50%, #FFB904 100%);
  }
  .cta-section { padding-bottom: clamp(4.5rem, 7vw, 6rem); }
  /* v4.3 — full-height section system (mobile reset in `responsive`) */
  .cta-section {
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* ---------- #39 studio-about (story + side panel) + #17 star-list ----------
     v5.5 block; 820px collapse → responsive. */
  .studio-about { background: var(--color-light-2); }
  .studio-about-grid {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
    margin-bottom: clamp(3rem, 6vw, 5rem);
  }
  .studio-about-text p { margin-block: 1rem; }
  /* THEME FIX (2026-07-06, Edward's review) — wide-viewport balance:
     verified pixel-identical to the prototype, which ALSO leaves a big
     white gap under the shorter text column at ≥1200px (measured 1440px:
     text col 389px vs side col 804px on lastetants). Centering the
     columns distributes the difference symmetrically so the rhythm stays
     tight; at ≤1100px the columns are near-equal and this is a no-op.
     Deviation from prototype v5.5 `align-items: start` — flagged for
     Edward's side-by-side review. */
  .studio-about-grid { align-items: center; }
  .curriculum-card {
    background: #fff;
    border-radius: 24px;
    padding: clamp(1.8rem, 4vw, 2.6rem);
    box-shadow: 0 24px 48px -18px rgba(28,28,28,0.16);
  }
  .curriculum-card h3 {
    font-family: 'Baumans', cursive;
    font-size: 1.5rem;
    margin-bottom: 1.2rem;
  }
  .star-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.8rem; }
  .star-list li {
    position: relative;
    padding-left: 1.7rem;
    line-height: 1.55;
  }
  .star-list li::before {
    content: '';
    position: absolute;
    left: 0; top: 0.32em;
    width: 0.85em; height: 0.85em;
    background: linear-gradient(135deg, #F80086, #FF6500 55%, #FFB904);
    clip-path: polygon(50% 0%, 60% 38%, 100% 50%, 60% 62%, 50% 100%, 40% 62%, 0% 50%, 40% 38%);
  }
  .curriculum-note {
    margin-top: 1.4rem;
    padding-top: 1.2rem;
    border-top: 1px solid var(--color-light-3);
    font-weight: 600;
    color: var(--color-orange);
  }

  /* ---------- #22 style-card + styles-grid ----------
     v5.5 base → v5.66 minmax fix, append order. Width queries → responsive. */
  .styles-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: clamp(1rem, 2vw, 1.5rem);
  }
  .style-card {
    background: #fff;
    border-radius: 20px;
    padding: 1.6rem 1.5rem;
    box-shadow: 0 18px 36px -16px rgba(28,28,28,0.14);
    border-top: 4px solid var(--color-pink);
    transition: transform 0.4s var(--ease-out), box-shadow 0.4s ease;
  }
  .style-card--orange { border-top-color: var(--color-orange); }
  .style-card--yellow { border-top-color: var(--color-yellow); }
  .style-card:hover { box-shadow: 0 26px 48px -16px rgba(28,28,28,0.22); }
  .style-card-star { width: 22px; height: 22px; margin-bottom: 0.8rem; }
  .style-card--pink .style-card-star { fill: var(--color-pink); }
  .style-card--orange .style-card-star { fill: var(--color-orange); }
  .style-card--yellow .style-card-star { fill: var(--color-yellow); }
  .style-card h3 { font-family: 'Baumans', cursive; font-size: 1.25rem; margin-bottom: 0.5rem; }
  .style-card p { font-size: 0.92rem; color: var(--text-muted); line-height: 1.6; }
  /* v5.16 grid variant */
  .styles-grid--2col { grid-template-columns: repeat(2, 1fr); }
  /* v5.42 grid variant (voistlused/klass pages) */
  .styles-grid--3col { grid-template-columns: repeat(3, 1fr); }
  /* v5.66 — TRULY equal tracks (1fr's auto minimum let long Estonian
     words widen a column) */
  .styles-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .styles-grid--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .styles-grid--3col { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* v5.61 grid variant (voistlused #miks — 3-card stack beside the text).
     THEME FIX (2026-07-06): placed AFTER the v5.66 re-assertions on
     purpose. In the prototype this rule (styles.css:5268) is beaten by
     the later unscoped v5.66 `.styles-grid` re-assertion (:5442) — the
     benefits grid computes 4×108px squished tracks at 1440px (verified
     headless). That is the exact "unscoped late rule" regression class
     v5.66 itself fixed for --2col/--3col, so we restore the v5.61
     design intent here. Mobile parity is untouched: the responsive
     layer's 1000px/560px `.styles-grid` rules still beat this rule
     (later layer), giving the prototype's 2-col → 1-col collapse. */
  .styles-grid--benefits { grid-template-columns: 1fr; gap: 1rem; }

  /* ---------- #21 group-card (+ groups shell, #18 filter-pill, #16 type-chip) ----------
     v5.5 base → v5.8 (semantic colors + filter bar) → v5.13 (arrow
     affordance) → v5.14 (gradient-flood hover), append order. */
  .groups-section { background: var(--color-light); }
  .groups-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.2rem, 2.5vw, 1.8rem);
    margin-top: clamp(2.5rem, 5vw, 4rem);
  }
  .group-card {
    background: var(--color-light-2);
    border-radius: 20px;
    padding: 1.6rem 1.6rem 1.5rem;
    border-left: 5px solid var(--color-pink);
    transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease;
  }
  .group-card--orange { border-left-color: var(--color-orange); }
  .group-card--yellow { border-left-color: var(--color-yellow); }
  .group-card:hover { transform: translateY(-5px); box-shadow: 0 22px 44px -18px rgba(28,28,28,0.2); }
  .group-card-tag {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
  }
  .group-card-name {
    font-family: 'Baumans', cursive;
    font-size: 1.35rem;
    margin-bottom: 0.6rem;
  }
  .group-card-teacher {
    display: flex; align-items: center; gap: 0.5rem;
    font-size: 0.9rem;
    margin-bottom: 0.8rem;
  }
  .group-card-teacher svg { width: 13px; height: 13px; flex-shrink: 0; }
  .group-card--pink .group-card-teacher svg { fill: var(--color-pink); }
  .group-card--orange .group-card-teacher svg { fill: var(--color-orange); }
  .group-card--yellow .group-card-teacher svg { fill: var(--color-yellow); }
  .group-card-times { list-style: none; padding: 0; margin: 0; }
  .group-card-times li {
    font-size: 0.88rem;
    color: var(--text-muted);
    padding-block: 0.3rem;
    border-top: 1px solid var(--color-light-3);
  }
  .group-card-times li:first-child { border-top: 0; }
  /* v5.6 — #34 fullband-video (full-height video band; touch reset in
     responsive) */
  .fullband-video {
    position: relative;
    overflow: hidden;
    background: var(--color-dark);
    color: #fff;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
  }
  .fullband-content {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.1rem;
    max-width: 640px;
  }
  .fullband-video .section-title { color: #fff; font-size: clamp(2.2rem, 4.5vw, 3.4rem); }
  .fullband-video .section-label { color: var(--color-yellow); }
  .fullband-text { color: rgba(255,255,255,0.88); font-size: 1.05rem; line-height: 1.7; }

  /* v5.8 — group type system: semantic colors + filter bar */
  .group-filter {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.7rem;
    margin-top: clamp(2rem, 4vw, 3rem);
  }
  .filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.65rem 1.3rem;
    background: #fff;
    border: 1.5px solid var(--color-light-3);
    border-radius: 999px;
    font: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s var(--ease-out);
  }
  .filter-pill:hover { transform: translateY(-2px); }
  .filter-dot { width: 10px; height: 10px; border-radius: 50%; }
  .filter-pill--orange .filter-dot { background: var(--color-orange); }
  .filter-pill--pink .filter-dot { background: var(--color-pink); }
  .filter-pill--yellow .filter-dot { background: var(--color-yellow); }
  .filter-pill.is-active { background: var(--color-dark); border-color: var(--color-dark); color: #fff; }
  .filter-pill--orange.is-active { background: var(--color-orange); border-color: var(--color-orange); }
  .filter-pill--pink.is-active { background: var(--color-pink); border-color: var(--color-pink); }
  .filter-pill--yellow.is-active { background: var(--color-yellow); border-color: var(--color-yellow); color: var(--color-dark); }
  .type-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.32rem 0.8rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 0.8rem;
  }
  .type-chip svg { width: 11px; height: 11px; }
  .type-chip--orange { background: rgba(255,101,0,0.12); color: #C24E00; }
  .type-chip--orange svg { fill: var(--color-orange); }
  .type-chip--pink { background: rgba(248,0,134,0.10); color: #C2006B; }
  .type-chip--pink svg { fill: var(--color-pink); }
  .type-chip--yellow { background: rgba(255,185,4,0.16); color: #8A6400; }
  .type-chip--yellow svg { fill: var(--color-yellow); }
  .group-card-tag { margin-bottom: 0.7rem; }
  .group-card .group-card-name { margin-bottom: 0.3rem; }
  .group-card.is-filtered { display: none; }
  /* v5.13 — clickability affordance: type-colored slide-in arrow */
  .group-card {
    cursor: pointer;
    position: relative;
  }
  .group-card::after {
    content: '→';
    position: absolute;
    top: 1.4rem;
    right: 1.5rem;
    font-size: 1.25rem;
    font-weight: 600;
    opacity: 0;
    transform: translateX(-8px);
    transition: opacity 0.3s ease, transform 0.35s var(--ease-out);
    pointer-events: none;
  }
  .group-card--pink::after { color: var(--color-pink); }
  .group-card--orange::after { color: var(--color-orange); }
  .group-card--yellow::after { color: #C99200; }
  .group-card:hover::after {
    opacity: 1;
    transform: translateX(0);
  }
  .group-card-name { transition: color 0.3s ease; }
  .group-card--pink:hover .group-card-name { color: var(--color-pink); }
  .group-card--orange:hover .group-card-name { color: var(--color-orange); }
  .group-card--yellow:hover .group-card-name { color: #C99200; }
  /* v5.14 — BOLD gradient-flood hover; cards are real links */
  a.group-card {
    display: block;
    text-decoration: none;
    color: inherit;
  }
  .group-card { overflow: hidden; }
  .group-card::before {
    content: '';
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 0.4s ease;
    pointer-events: none;
  }
  .group-card--pink::before {
    background:
      radial-gradient(ellipse 80% 60% at 70% 12%, rgba(255,255,255,0.18) 0%, transparent 55%),
      linear-gradient(155deg, #FF4FA8 0%, #F80086 58%, #A80059 100%);
  }
  .group-card--orange::before {
    background:
      radial-gradient(ellipse 80% 60% at 70% 12%, rgba(255,255,255,0.2) 0%, transparent 55%),
      linear-gradient(155deg, #FFA050 0%, #FF6500 58%, #B04500 100%);
  }
  .group-card--yellow::before {
    background:
      radial-gradient(ellipse 80% 60% at 70% 12%, rgba(255,255,255,0.25) 0%, transparent 55%),
      linear-gradient(155deg, #FFE066 0%, #FFB904 58%, #B58000 100%);
  }
  .group-card:hover::before { opacity: 1; }
  .group-card > * { position: relative; z-index: 1; }
  /* text flips to white on flood (overrides v5.13 tints) */
  .group-card:hover .group-card-name,
  .group-card--pink:hover .group-card-name,
  .group-card--orange:hover .group-card-name,
  .group-card--yellow:hover .group-card-name { color: #fff; }
  .group-card:hover .group-card-tag { color: rgba(255,255,255,0.85); }
  .group-card:hover .group-card-teacher { color: #fff; }
  .group-card:hover .group-card-teacher svg { fill: #fff !important; }
  .group-card:hover .group-card-times li { color: rgba(255,255,255,0.92); border-top-color: rgba(255,255,255,0.28); }
  .group-card:hover .type-chip { background: rgba(255,255,255,0.22); color: #fff; }
  .group-card:hover .type-chip svg { fill: #fff; }
  /* big circle-arrow replaces the small slide-in arrow */
  .group-card::after {
    content: '→';
    top: auto;
    bottom: 1.2rem;
    right: 1.3rem;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: rgba(255,255,255,0.2);
    border: 1.5px solid rgba(255,255,255,0.65);
    color: #fff;
    font-size: 1.2rem;
    line-height: 39px;
    text-align: center;
    opacity: 0;
    transform: translateX(-8px) scale(0.85);
    transition: opacity 0.3s ease, transform 0.4s var(--ease-spring, var(--ease-out));
  }
  .group-card--pink::after, .group-card--orange::after, .group-card--yellow::after { color: #fff; }
  .group-card:hover::after {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
  /* extra lift on flood */
  .group-card:hover { transform: translateY(-7px); box-shadow: 0 30px 56px -16px rgba(28,28,28,0.35); }

  /* ---------- #40 content-cutout + extras-split + oppest-side ----------
     v5.16 block; 900px sizing + v5.65 touch reset + reduced → responsive. */
  .content-cutout {
    pointer-events: none;
    filter: drop-shadow(0 24px 36px rgba(28,28,28,0.18));
    will-change: transform;
  }
  .content-cutout img { width: 100%; height: auto; display: block; }
  .oppest-side { display: flex; flex-direction: column; gap: 1rem; }
  .content-cutout--side {
    max-width: 330px;
    align-self: center;
    margin-top: 0.5rem;
    animation: cutoutFloat 7s ease-in-out infinite alternate;
  }
  .extras-split {
    display: grid;
    grid-template-columns: 1fr 1.45fr;
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: center;
  }
  .content-cutout--wide { max-width: 560px; }

  /* ---------- #38 theatre-cinema ----------
     Full v-series in prototype append order: v5.12 (cinema shell +
     sound button) → v5.12.1 → v5.17 (theatre room) → v5.18 → v5.19 →
     v5.20 → v5.21 → v5.22 (each re-measures the screen; final values
     come from the cascade exactly like the prototype) → v5.66 (zoom
     wrappers). @media rules → responsive (v5.18/v5.19 900px, v5.64b,
     v5.65 mobile zoom). Only ONE theatre per page (IDs). */
  .cinema-section {
    background: #141416;
    color: #fff;
    position: relative;
    overflow: hidden;
  }
  .cinema-section::before {
    content: '';
    position: absolute; inset: 0;
    background:
      radial-gradient(ellipse 70% 50% at 50% 10%, rgba(248,0,134,0.10) 0%, transparent 60%),
      radial-gradient(ellipse 60% 45% at 50% 100%, rgba(255,101,0,0.08) 0%, transparent 60%);
    pointer-events: none;
  }
  .cinema-inner {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(1.5rem, 3vw, 2.5rem);
  }
  .cinema-section .section-title { color: #fff; }
  .cinema-section .section-label { color: var(--color-yellow); }
  .cinema-sound {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.8rem 1.6rem;
    border-radius: 999px;
    border: 1px solid rgba(255,255,255,0.3);
    background: rgba(28,28,28,0.5);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s var(--ease-out);
  }
  .cinema-sound:hover { border-color: var(--color-yellow); transform: translateY(-2px); }
  .cinema-sound svg { width: 18px; height: 18px; }
  .cinema-sound .ico-off { display: none; }
  .cinema-sound.is-on .ico-on { display: none; }
  .cinema-sound.is-on .ico-off { display: block; }
  .cinema-sound.is-on { border-color: var(--color-yellow); color: var(--color-yellow); }
  /* v5.12.1 — muted feature video invites a click */
  .cinema-frame video.is-muted { cursor: pointer; }
  /* v5.17 — movie theatre screen */
  .theatre-wrap {
    position: relative;
    width: 100%;
    margin: 0;
    border-radius: 26px;
    overflow: hidden;
    box-shadow: 0 40px 90px -30px rgba(0,0,0,0.8);
  }
  .theatre-room { width: 100%; display: block; }
  .theatre-screen {
    position: absolute;
    left: 20.24%;
    top: 25.13%;
    width: 59.15%;
    height: 44.61%;
    background: #000;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
  }
  .theatre-screen video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    cursor: pointer;
  }
  .theatre-vignette {
    position: absolute;
    inset: 0;
    pointer-events: none;
    box-shadow: inset 0 0 90px 30px #141416;
    border-radius: 26px;
  }
  /* old frame class kept for safety; theatre replaces it */
  .cinema-frame { display: none; }
  /* v5.18 — true 16:9 screen, breaks out of the container */
  .cinema-section { padding-block: clamp(3rem, 5vh, 4.5rem) clamp(2rem, 4vh, 3.5rem); }
  .cinema-inner { gap: 0.4rem; }
  .cinema-inner .text-center { position: relative; z-index: 2; }
  .theatre-wrap {
    width: min(94vw, 1560px);
    margin-left: calc(50% - min(47vw, 780px));
    margin-top: -2.2rem;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
    -webkit-mask-image: radial-gradient(ellipse 88% 82% at 50% 50%, #000 58%, transparent 97%);
    mask-image: radial-gradient(ellipse 88% 82% at 50% 50%, #000 58%, transparent 97%);
  }
  .theatre-vignette { display: none; }
  .theatre-screen {
    top: auto;
    bottom: 30.26%;
    height: 58.82%;
    background: #000;
    border: 3px solid #161616;
    border-radius: 6px;
    box-shadow:
      0 0 90px 8px rgba(255,228,180,0.16),
      0 0 26px 2px rgba(255,228,180,0.22);
  }
  .theatre-wrap .cinema-sound {
    position: absolute;
    bottom: 5%;
    left: 50%;
    transform: translateX(-50%);
    z-index: 3;
  }
  .theatre-wrap .cinema-sound:hover {
    transform: translateX(-50%) translateY(-2px);
  }
  /* v5.19 — theatre v3: user-approved room */
  .theatre-wrap {
    width: min(82vw, 1180px);
    margin-left: calc(50% - min(41vw, 590px));
    margin-top: -1.2rem;
    -webkit-mask-image: radial-gradient(ellipse 94% 92% at 50% 48%, #000 55%, transparent 99%);
    mask-image: radial-gradient(ellipse 94% 92% at 50% 48%, #000 55%, transparent 99%);
  }
  .theatre-screen {
    left: 19.97%;
    top: 18.33%;
    bottom: auto;
    width: 60.06%;
    height: 55.23%;
    background: #000;
    border: 0;
    border-radius: 4px;
    box-shadow: none;
  }
  .theatre-screen video { object-fit: cover; }
  /* v5.20 — theatre final: premium room, exact 16:9 screen band */
  .theatre-wrap {
    width: min(92vw, 1480px);
    margin-left: calc(50% - min(46vw, 740px));
    margin-top: -1.6rem;
    -webkit-mask-image: radial-gradient(ellipse 96% 94% at 50% 48%, #000 56%, transparent 99%);
    mask-image: radial-gradient(ellipse 96% 94% at 50% 48%, #000 56%, transparent 99%);
  }
  .theatre-screen {
    left: 26.29%;
    top: 21.12%;
    bottom: auto;
    width: 47.56%;
    height: 51.53%;
    border: 0;
    border-radius: 10px;
    box-shadow: none;
    background: #000;
  }
  .theatre-screen video { object-fit: cover; }
  /* v5.21 — theatre depth pass: room emerges from darkness */
  .cinema-section {
    background: #0a0a0b;
  }
  .cinema-section::before {
    background:
      radial-gradient(ellipse 60% 40% at 50% 0%, rgba(248,0,134,0.05) 0%, transparent 60%);
  }
  .theatre-wrap {
    width: min(96vw, 1680px);
    margin-left: 0;
    align-self: center;
    margin-top: -1.6rem;
    -webkit-mask-image:
      linear-gradient(to right, transparent 0%, #000 9%, #000 91%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 8%, #000 90%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, transparent 0%, #000 9%, #000 91%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 8%, #000 90%, transparent 100%);
    mask-composite: intersect;
  }
  .theatre-screen {
    left: 25.94%;
    top: 20.32%;
    width: 48.26%;
    height: 53.13%;
    border-radius: 6px;
  }
  .cinema-sound { z-index: 4; }
  /* v5.22 — theatre fit pass: whole section fits one viewport */
  .cinema-section {
    min-height: 100svh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-block: clamp(1.5rem, 3vh, 2.5rem);
  }
  .cinema-inner { gap: 1.2rem; width: 100%; }
  .theatre-wrap {
    margin-top: 0;
    width: min(96vw, 1680px, calc((100svh - 250px) * 1.925));
  }
  .theatre-screen {
    top: 19.5%;
    height: 53.95%;
  }
  /* v5.66 — theatre zoom wrappers (base; mobile zoom in responsive) */
  .theatre-clip { position: relative; }
  .theatre-scale { position: relative; }
  /* THEME FIX (2026-07-06, Edward's review) — poster-overlay for the
     theatre screen: on play() the browser drops the video's poster
     BEFORE the first frame of the 55–61MB network-served file decodes
     → long BLACK screen (frame 0 of both theatre videos is near-black,
     YAVG 16/19). Same defect mechanism as the team-card overlay
     (porting lesson: the disk-served prototype never exposed it). The
     overlay <img> fades only when frames actually flow ('playing') and
     returns on 'pause'; featureVideo JS toggles .is-live. */
  .theatre-poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
    transition: opacity 0.35s ease;
  }
  .theatre-screen.is-live .theatre-poster { opacity: 0; }

  /* ---------- #38b theatre YouTube facade (blog posts, Phase 3) ----------
     Privacy-friendly, lazy YouTube inside the SAME cinema frame as the MP4
     theatre. Renders the video's thumbnail as poster + a play button; the
     click-to-load handler (main.js youtubeFacade) swaps in a
     youtube-nocookie.com iframe with sound on first click. NO autoplay
     (YouTube blocks muted-less autoplay). Reuses .cinema-section /
     .theatre-room / .theatre-screen geometry verbatim — only the screen
     contents differ (facade/iframe instead of <video>). */
  .yt-facade {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    padding: 0;
    margin: 0;
    display: block;
    cursor: pointer;
    background: #000;
    overflow: hidden;
  }
  .yt-facade img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s var(--ease-out, ease), filter 0.35s ease;
  }
  .yt-facade:hover img { transform: scale(1.04); filter: brightness(1.05); }
  .yt-facade::after {
    /* soft scrim so the play button reads on bright thumbnails */
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 60% 60% at 50% 50%, rgba(0,0,0,0.15), rgba(0,0,0,0.45));
    pointer-events: none;
    transition: opacity 0.35s ease;
  }
  .yt-facade:hover::after { opacity: 0.75; }
  .yt-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: clamp(58px, 7vw, 84px);
    height: clamp(58px, 7vw, 84px);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(229, 0, 114, 0.92); /* brand pink */
    box-shadow: 0 10px 34px -6px rgba(0,0,0,0.6), 0 0 0 0 rgba(229,0,114,0.5);
    transition: transform 0.35s var(--ease-out, ease), background 0.3s ease, box-shadow 0.3s ease;
    pointer-events: none; /* the whole facade is the click target */
  }
  .yt-facade:hover .yt-play {
    transform: translate(-50%, -50%) scale(1.08);
    background: rgba(229, 0, 114, 1);
    box-shadow: 0 14px 40px -6px rgba(0,0,0,0.7), 0 0 0 10px rgba(229,0,114,0.14);
  }
  .yt-play svg { width: 42%; height: 42%; margin-left: 8%; fill: #fff; }
  /* iframe (post-click) fills the screen identically to the facade/video */
  .theatre-screen iframe,
  .theatre-screen .yt-facade { width: 100%; height: 100%; }
  .theatre-screen iframe { border: 0; display: block; }

  /* ---------- #33 media-blend (video + tint + scrim) ----------
     Used by stage-section (panel-media), fullband-video, program panels. */
  .media-blend { position: absolute; inset: 0; overflow: hidden; }
  .panel-media {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
  }
  .media-tint { position: absolute; inset: 0; mix-blend-mode: normal; }
  .media-blend--orange .media-tint {
    background: linear-gradient(160deg, rgba(255,101,0,0.42) 0%, rgba(176,69,0,0.34) 100%);
  }
  .media-blend--pink .media-tint {
    background: linear-gradient(160deg, rgba(248,0,134,0.38) 0%, rgba(110,0,62,0.36) 100%);
  }
  .media-blend--yellow .media-tint {
    background: linear-gradient(160deg, rgba(255,185,4,0.32) 0%, rgba(150,105,0,0.34) 100%);
  }
  .media-scrim {
    position: absolute; inset: 0;
    background: linear-gradient(90deg, rgba(28,28,28,0.88) 0%, rgba(28,28,28,0.62) 45%, rgba(28,28,28,0.28) 100%);
  }

  /* ---------- #33b media-blend--clean (2026-08-03) ----------
     "Premium studio" treatment: show the footage's TRUE colours instead of
     washing them in a brand tint. The --orange/--pink/--yellow tints sit at
     ~0.33–0.42 across the whole frame, which turns the studio's magenta
     shirts brown and its teal/purple lighting grey — no amount of grading
     survives that, so the tint is dropped entirely here.

     Legibility is paid for two other ways instead:
     1. the scrim gets STEEPER, not lighter — heavier than the base at the
        left edge (0.92 vs 0.88) where the copy sits, then clearing to fully
        transparent by 88% so the right half of the frame stays pristine;
     2. a small contrast/saturation/brightness lift on the media itself,
        which is what "more contrast, brighter, truer colours" actually asks
        for — brand feeling now comes from what is IN the footage (magenta
        tops, purple LED wash) plus the yellow label/CTA, not from a glaze.

     Opt-in per section — add .media-blend--clean next to the tint class.
     The tint element stays in the DOM so the markup is identical either way. */
  .media-blend--clean .media-tint { background: none; }
  /* Falloff is tuned to MEASURED copy geometry, not guessed: at 1280px the
     .fullband-content column reaches 74.4% of the viewport, and the widest
     title/body lines end at ~68%. So the scrim has to still carry ~0.4 at 68%
     and only go fully clear past ~94%. Net vs the old treatment at that same
     68% mark: 0.43 clean here versus ~0.48 scrim PLUS a 0.33 mustard tint
     before — lighter AND uncast, while the far right goes to zero instead of
     0.28+tint, which is where the "premium studio" actually shows. */
  .media-blend--clean .media-scrim {
    background: linear-gradient(95deg,
      rgba(18,16,22,0.90) 0%,
      rgba(18,16,22,0.78) 28%,
      rgba(18,16,22,0.60) 52%,
      rgba(18,16,22,0.40) 70%,
      rgba(18,16,22,0.16) 84%,
      rgba(18,16,22,0) 94%);
  }
  /* Colour is pushed, luminance is NOT: saturation + contrast make the magenta
     tops / teal / purple LED wash read true and rich, while brightness stays
     at ~1.0 so the oak floor never blows out under the white copy. Lifting
     brightness instead was tried and it fought the text for no colour gain. */
  .media-blend--clean .panel-media {
    filter: contrast(1.16) saturate(1.22) brightness(0.99);
  }

  /* ---------- #35 stage-section — "Lava ootab" theatrical band ----------
     v5.9 block; touch padding reset → responsive. */
  .stage-section {
    position: relative;
    overflow: hidden;
    background: #0E0E10;
    color: #fff;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
    text-align: center;
  }
  .stage-media { position: absolute; inset: 0; }
  .stage-vignette {
    position: absolute; inset: 0;
    background:
      radial-gradient(ellipse 75% 65% at 50% 42%, rgba(14,14,16,0) 0%, rgba(14,14,16,0.55) 62%, rgba(14,14,16,0.92) 100%),
      linear-gradient(180deg, rgba(14,14,16,0.55) 0%, rgba(14,14,16,0.15) 30%, rgba(14,14,16,0.65) 100%);
  }
  .stage-content {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.1rem;
  }
  .stage-section .section-label { color: var(--color-yellow); }
  .stage-title {
    font-family: 'Baumans', cursive;
    font-size: clamp(2.8rem, 7vw, 5rem);
    line-height: 1.05;
    color: #fff;
    text-shadow: 0 2px 30px rgba(0,0,0,0.6);
  }
  .stage-lead {
    max-width: 56ch;
    color: rgba(255,255,255,0.85);
    font-size: 1.05rem;
    line-height: 1.7;
  }
  .stage-lineup {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: clamp(0.8rem, 1.6vw, 1.2rem);
    margin-top: clamp(1.5rem, 3vh, 2.5rem);
  }
  .stage-chip {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 1rem 1.5rem;
    background: rgba(28,28,28,0.45);
    border: 1px solid rgba(255,255,255,0.22);
    border-radius: 16px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transition: border-color 0.3s ease, transform 0.35s var(--ease-out), background 0.3s ease;
  }
  .stage-chip:hover {
    transform: translateY(-4px);
    border-color: var(--color-yellow);
    background: rgba(28,28,28,0.65);
  }
  .stage-chip em {
    font-style: normal;
    font-family: 'Baumans', cursive;
    font-size: 1.5rem;
    color: var(--color-yellow);
    line-height: 1;
  }
  .stage-chip span { font-weight: 600; white-space: nowrap; }
  .stage-extras {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin-top: clamp(1.5rem, 3.5vh, 2.8rem);
  }
  .stage-extras-label {
    font-size: var(--type-small);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: rgba(255,255,255,0.6);
    margin-right: 0.4rem;
  }
  .stage-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.45rem 1rem;
    border: 1px solid rgba(255,255,255,0.18);
    border-radius: 999px;
    background: rgba(28,28,28,0.35);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    font-size: 0.85rem;
    color: rgba(255,255,255,0.85);
  }
  .stage-pill::before {
    content: '';
    width: 0.6em; height: 0.6em;
    background: linear-gradient(135deg, #F80086, #FF6500 55%, #FFB904);
    clip-path: polygon(50% 0%, 60% 38%, 100% 50%, 60% 62%, 50% 100%, 40% 62%, 0% 50%, 40% 38%);
  }

  /* ---------- #24 event-card (+ events-grid shell) ----------
     News cards: uudised loop, index 3-latest (Phase: front page),
     post-related (single.php). The index-only nth-child stagger +
     hover offsets are (min-width: 981px) medias → `responsive`
     (with the news-grid neutralizers re-asserted there — layer trap). */
  .events-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.5rem, 2.5vw, 2rem);
    margin-top: 3rem;
  }
  .event-card {
    background: #fff;
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 6px 24px rgba(0,0,0,0.06);
    transition: transform 0.4s var(--ease-spring), box-shadow 0.4s ease;
    display: flex; flex-direction: column;
  }
  .event-card:hover {
    box-shadow: 0 30px 60px -20px rgba(28,28,28,0.25);
  }
  .event-card-image {
    position: relative;
    /* v5.76: 16:9 matches the event promo banners (~1.78–1.9, text baked to
       edges). 3:2 was narrower than every image → cover cropped the sides,
       clipping the date/character. 16:9 = near-zero crop; matches the
       responsive breakpoints (already 16/9) for one consistent grid. */
    aspect-ratio: 16/9;
    overflow: hidden;
  }
  .event-badge {
    position: absolute;
    top: 1rem; left: 1rem;
    background: var(--color-pink);
    color: #fff;
    padding: 0.35rem 0.9rem;
    border-radius: 100px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    z-index: 2;
    box-shadow: 0 6px 20px rgba(248,0,134,0.35);
  }
  .event-card-body {
    padding: 1.75rem;
    display: flex; flex-direction: column; gap: 0.65rem;
    flex: 1;
  }
  .event-card-date {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--text-muted);
    font-weight: 500;
  }
  .event-card-title {
    font-family: 'Exo', sans-serif;
    font-weight: 500;
    font-size: 1.1rem;
    line-height: 1.35;
    color: var(--color-dark);
  }
  .event-card-excerpt {
    color: var(--text-muted);
    font-size: 0.9rem;
    line-height: 1.65;
    flex: 1;
  }
  .event-card-link {
    display: inline-flex; align-items: center; gap: 0.5rem;
    color: var(--color-dark);
    font-weight: 600;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    margin-top: 0.5rem;
    transition: color 0.3s ease;
  }
  .event-card-link:hover { color: var(--color-orange); }
  .event-card-link span { transition: transform 0.3s ease; display: inline-block; }
  .event-card-link:hover span { transform: translateX(6px); }
  /* real photos with hover zoom */
  .event-img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.8s var(--ease-out);
  }
  .event-card:hover .event-img { transform: scale(1.06); }
  /* newsList filter state (matches .group-card.is-filtered) */
  .event-card.is-filtered { display: none; }

  /* ---------- #20 pagination (v5.24 — JS-rendered: newsList,
     groupsDirectory) ---------- */
  .pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.5rem;
    margin-top: clamp(2.5rem, 5vw, 4rem);
  }
  .page-btn {
    min-width: 44px;
    height: 44px;
    padding: 0 0.9rem;
    border-radius: 999px;
    border: 1.5px solid var(--color-light-3);
    background: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s var(--ease-out);
  }
  .page-btn:hover { transform: translateY(-2px); border-color: var(--color-orange); }
  .page-btn.is-active {
    background: var(--color-dark);
    border-color: var(--color-dark);
    color: #fff;
  }
  .page-btn[disabled] { opacity: 0.35; cursor: default; transform: none; }

  /* ---------- #19 category-tabs (v5.33 — liitu data-jfilter; reused by
     tantsugrupid data-gfilter in Phase 3; region-pill arrives with it) ---------- */
  .category-tabs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(0.8rem, 1.6vw, 1.2rem);
  }
  .cat-tab {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: clamp(1.4rem, 3vw, 2rem) 1.2rem;
    background: #fff;
    border: 0;
    border-top: 5px solid var(--color-light-3);
    border-radius: 20px;
    box-shadow: 0 16px 32px -16px rgba(28,28,28,0.14);
    font: inherit;
    cursor: pointer;
    overflow: hidden;
    transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease;
  }
  .cat-tab:hover { transform: translateY(-4px); box-shadow: 0 24px 44px -16px rgba(28,28,28,0.22); }
  .cat-tab--orange { border-top-color: var(--color-orange); }
  .cat-tab--pink { border-top-color: var(--color-pink); }
  .cat-tab--yellow { border-top-color: var(--color-yellow); }
  .cat-tab-star { width: 26px; height: 26px; }
  .cat-tab--orange .cat-tab-star { fill: var(--color-orange); }
  .cat-tab--pink .cat-tab-star { fill: var(--color-pink); }
  .cat-tab--yellow .cat-tab-star { fill: var(--color-yellow); }
  .cat-tab strong {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.3rem, 2.4vw, 1.7rem);
    font-weight: 400;
  }
  .cat-tab span { font-size: 0.85rem; color: var(--text-muted); }
  /* active: flooded with the type gradient */
  .cat-tab.is-active { color: #fff; }
  .cat-tab.is-active span { color: rgba(255,255,255,0.85); }
  .cat-tab.is-active .cat-tab-star { fill: #fff; }
  .cat-tab--orange.is-active {
    background: linear-gradient(155deg, #FFA050 0%, #FF6500 58%, #B04500 100%);
    border-top-color: #B04500;
  }
  .cat-tab--pink.is-active {
    background: linear-gradient(155deg, #FF4FA8 0%, #F80086 58%, #A80059 100%);
    border-top-color: #A80059;
  }
  .cat-tab--yellow.is-active {
    background: linear-gradient(155deg, #FFE066 0%, #FFB904 58%, #B58000 100%);
    border-top-color: #B58000;
    color: var(--color-dark);
  }
  .cat-tab--yellow.is-active span { color: rgba(28,28,28,0.75); }
  .cat-tab--yellow.is-active .cat-tab-star { fill: var(--color-dark); }

  /* ---------- #49 join-panes (v5.51 — registreeri tab content) ----------
     The Sportlyzer frame chrome (.join-form-frame) lives in
     `integrations`; iframe mobile heights (v5.67b) in `responsive`. */
  .join-pane[hidden] { display: none; }
  .join-pane { margin-top: clamp(2rem, 4vh, 3rem); }
  .join-pane-intro { max-width: 720px; margin: 0 auto; text-align: center; }
  .join-pane-intro h2 {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.6rem, 2.6vw, 2.1rem);
    margin-bottom: 0.7rem;
  }
  .join-pane-intro p { color: var(--text-muted, #555); line-height: 1.7; margin-bottom: 0.9rem; }
  .join-pane-link { color: var(--color-orange); font-weight: 600; text-decoration: none; font-size: 0.95rem; }
  .join-pane-link:hover { text-decoration: underline; }
  /* v5.52 — registration terms row */
  .join-pane-meta { margin-top: 1.3rem; }
  .join-terms {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.6rem 1.3rem;
    border: 1.5px solid rgba(28,28,28,0.22);
    border-radius: 100px;
    color: var(--color-dark, #1C1C1C);
    text-decoration: none;
    font-size: 0.88rem;
    font-weight: 600;
    transition: border-color 0.25s ease, color 0.25s ease;
  }
  .join-terms svg { width: 17px; height: 17px; }
  .join-terms:hover { border-color: var(--color-orange); color: var(--color-orange); }
  .join-tax {
    margin: 0.9rem auto 0;
    max-width: 56ch;
    color: #9a9a9a;
    font-size: 0.84rem;
    line-height: 1.55;
  }

  /* ---------- #50 join-how — "Kolm lihtsat sammu" (v5.49) ----------
     Section padding is page rhythm → `pages`; steps grid is component. */
  .join-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.2rem, 2.5vw, 2rem);
    margin-top: 2.6rem;
  }
  .join-step {
    background: #fff;
    border: 1px solid rgba(28,28,28,0.06);
    border-radius: 20px;
    padding: clamp(1.6rem, 2.5vw, 2.2rem);
    text-align: center;
    box-shadow: 0 12px 32px -14px rgba(28,28,28,0.12);
  }
  .join-step-num {
    display: inline-grid;
    place-items: center;
    width: 46px; height: 46px;
    border-radius: 50%;
    background: linear-gradient(135deg, #F80086, #FF6500 60%, #FFB904);
    color: #fff;
    font-weight: 700;
    font-size: 1.15rem;
    margin-bottom: 1rem;
  }
  .join-step h3 { font-family: 'Baumans', cursive; font-size: 1.25rem; margin-bottom: 0.5rem; }
  .join-step p { color: var(--text-muted, #6b6b6b); font-size: 0.94rem; line-height: 1.6; margin: 0; }

  /* ---------- #27 class-note (icon + strong + text info row) ----------
     Base family (styles.css:4062). Reused as venues-note (voistlused),
     product-note + shop trust strip (Phase 4), klass notes (Phase 3).
     Color variants (.class-facts--pink/--yellow) arrive with the klass
     template. */
  .class-notes { margin-top: 2.2rem; display: flex; flex-direction: column; gap: 0.9rem; }
  .class-note {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 1.05rem 1.25rem;
    border-radius: 14px;
    background: rgba(255,101,0,0.06);
    border: 1px solid rgba(255,101,0,0.14);
  }
  .class-note > svg { width: 22px; height: 22px; flex: 0 0 auto; color: var(--color-orange, #FF6500); margin-top: 0.1rem; }
  .class-note strong { display: block; font-size: 0.95rem; margin-bottom: 0.15rem; }
  .class-note span { color: var(--text-muted, #6b6b6b); font-size: 0.9rem; line-height: 1.5; }
  /* v5.61 — venues variant (voistlused; AFTER base, within-layer order) */
  .venues-note {
    max-width: 860px;
    margin: clamp(2rem, 4vw, 3rem) auto 0;
    background: #fff;
    border: 1px solid rgba(28,28,28,0.05);
    box-shadow: 0 10px 30px -12px rgba(28,28,28,0.10);
  }
  .venues-note > svg { color: var(--color-pink); }

  /* ---------- #37 quote-band (v5.61 — voistlused; blog pattern later) ---------- */
  .quote-band {
    max-width: 780px;
    margin: clamp(3rem, 6vw, 5rem) auto 0;
    text-align: center;
  }
  .quote-band svg { width: 40px; height: 40px; margin-bottom: 1.1rem; }
  .quote-band p {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.5rem, 3vw, 2.3rem);
    line-height: 1.35;
    color: var(--color-dark, #1C1C1C);
    margin: 0;
  }

  /* ---------- #39 side panel: costume-card (v5.61 — voistlused #kavad) ---------- */
  .costume-card {
    position: relative;
    background: #fff;
    border: 1px solid rgba(28,28,28,0.07);
    border-radius: 22px;
    padding: clamp(1.8rem, 3vw, 2.4rem);
    box-shadow: 0 24px 48px -22px rgba(28,28,28,0.16);
    overflow: hidden;
  }
  .costume-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: linear-gradient(90deg, #F80086, #FF6500, #FFB904);
  }
  .costume-star { width: 26px; height: 26px; fill: var(--color-orange); margin-bottom: 0.8rem; }
  .costume-card h3 { font-family: 'Baumans', cursive; font-size: 1.35rem; margin-bottom: 0.7rem; }
  .costume-card > p { color: #555; line-height: 1.65; margin-bottom: 1.1rem; }

  /* ---------- #12 class-header + #26 price-card + #28 sched-list +
     class-styles/-season/-electives — KLASS DETAIL template family
     (Phase 2 batch 4). Prototype v-block append order preserved:
     v5.35 base → v5.36 header grid + teacher card → v5.38 tonal cards
     → v5.39 accent variants (kool=pink, stuudio=yellow) → v5.40
     centered style cards → v5.41 white-surface unification → v5.42
     fixes. Day badges compute as Exo 700 (no font-family on
     .sched-day — inherits body Exo; the Baumans-badge look was a
     prototype-era bug, long fixed).
     NOT ported (dead in the final prototype markup, lesson #12b):
     v5.35 .class-teacher pill family (replaced by the v5.36 teacher
     team-card), v5.35 .class-register-section/.reg-steps + v5.36
     .reg-cta (v5.37 removed the registration section — price-card CTA
     is the single entry), .class-links (no klass page ships it).
     Already ported elsewhere: v5.39 .section-label--orange/--yellow
     (components #14), v5.40 teacher video media-fill + white photo bg
     (generalized to all team cards, components #23), v5.42
     .styles-grid--3col tracks (components #22 + responsive layer).
     @media rules (940/860/520/640 re-assertions) → responsive. ---------- */

  /* v5.35 — header: meta chips, subtle type glow */
  .class-header { position: relative; overflow: hidden; }
  /* v6.3 (Edward 2026-07-08): class detail pages (lasteaed/kool/stuudio groups)
     keep the larger v4 title — the group name is the key element here, more
     important than on ordinary headers (which stay at the unified slim size). */
  .class-header .page-header-title { font-size: clamp(2.6rem, 6vw, 4.2rem); line-height: 1.08; margin-block: 0.3rem 0.6rem; }
  .class-header--orange::before {
    content: '';
    position: absolute;
    top: -30%; right: -10%;
    width: 55vw; height: 120%;
    background: radial-gradient(ellipse at center, rgba(255,101,0,0.22), transparent 65%);
    pointer-events: none;
  }
  .class-header .container { position: relative; z-index: 1; }
  .class-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.1rem; margin-bottom: 0.9rem; }
  .class-meta .type-chip { margin-bottom: 0; }
  /* dark-header chip recolor — the base #16 chips are tuned for light
     surfaces; scoped to .class-meta (the prototype-era unscoped-chip
     bug was fixed by exactly this scoping) */
  .class-meta .type-chip--orange { background: rgba(255,101,0,0.18); color: #FFB27A; }
  .class-meta .type-chip--pink { background: rgba(248,0,134,0.20); color: #FF7AC4; }
  .class-meta .type-chip--pink svg { fill: #FF7AC4; }
  .class-meta .type-chip--yellow { background: rgba(255,185,4,0.16); color: #FFD25E; }
  .class-meta .type-chip--yellow svg { fill: #FFD25E; }
  .class-meta-item {
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: rgba(255,255,255,0.55);
  }
  .class-meta-item + .class-meta-item { position: relative; padding-left: 1.1rem; }
  .class-meta-item + .class-meta-item::before {
    content: '·';
    position: absolute; left: 0.25rem;
    color: rgba(255,255,255,0.35);
  }

  /* v5.35 — facts: schedule + sticky price card */
  .class-facts { padding: clamp(3.5rem, 8vh, 5.5rem) 0; }
  .class-facts-grid {
    display: grid;
    grid-template-columns: 1.25fr 0.8fr;
    gap: clamp(2rem, 4.5vw, 4.5rem);
    align-items: start;
  }
  .sched-list { list-style: none; margin: 1.9rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.9rem; }
  .sched-row {
    display: flex;
    align-items: center;
    gap: 1.15rem;
    background: #fff;
    border: 1px solid rgba(28,28,28,0.05);
    border-radius: 16px;
    padding: 1rem 1.4rem;
    box-shadow: 0 10px 30px -12px rgba(28,28,28,0.10);
    transition: transform 0.35s ease, box-shadow 0.35s ease;
  }
  .sched-row:hover {
    transform: translateX(6px);
    box-shadow: 0 16px 36px -12px rgba(255,101,0,0.22);
  }
  .sched-day {
    flex: 0 0 auto;
    width: 50px; height: 50px;
    border-radius: 50%;
    display: grid; place-items: center;
    background: linear-gradient(135deg, #FF6500, #FFB904);
    color: #fff;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
  }
  .sched-info { display: flex; flex-direction: column; gap: 0.12rem; min-width: 0; }
  .sched-info strong { font-size: 1.06rem; }
  .sched-info span { color: var(--text-muted, #6b6b6b); font-size: 0.92rem; }
  .sched-dow {
    margin-left: auto;
    flex: 0 0 auto;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: rgba(28,28,28,0.38);
  }
  .price-card {
    position: sticky;
    top: 110px;
    background: #1C1C1C;
    color: #fff;
    border-radius: 22px;
    padding: clamp(1.9rem, 3vw, 2.5rem);
    overflow: hidden;
    isolation: isolate;
  }
  .price-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: linear-gradient(90deg, #FF6500, #FFB904);
  }
  .price-card::after {
    content: '';
    position: absolute;
    top: -35%; right: -30%;
    width: 75%; height: 80%;
    background: radial-gradient(ellipse at center, rgba(255,101,0,0.28), transparent 68%);
    pointer-events: none;
    z-index: -1;
  }
  .price-card-label {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: rgba(255,255,255,0.55);
    margin-bottom: 0.7rem;
  }
  .price-card-price { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 1.5rem; }
  .price-card-price em {
    font-style: normal;
    font-family: 'Baumans', cursive;
    font-size: clamp(2.7rem, 4vw, 3.4rem);
    line-height: 1;
    background: linear-gradient(100deg, #FFB904, #FF6500);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
  .price-card-price span { color: rgba(255,255,255,0.6); font-size: 0.98rem; }
  .price-card .star-list li { color: rgba(255,255,255,0.85); font-size: 0.95rem; }
  .price-card .btn-primary { display: block; text-align: center; margin-top: 1.7rem; }
  .price-card-terms {
    display: block;
    text-align: center;
    margin-top: 0.95rem;
    color: rgba(255,255,255,0.6);
    font-size: 0.86rem;
    text-decoration: none;
    transition: color 0.3s ease;
  }
  .price-card-terms:hover { color: var(--color-yellow, #FFB904); }

  /* v5.36 — hero teacher card (per-teacher portrait video) */
  .class-header-grid {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: clamp(2rem, 5vw, 5rem);
    align-items: center;
  }
  .class-teacher-card {
    width: clamp(230px, 21vw, 300px);
    box-shadow: 0 34px 64px -22px rgba(0,0,0,0.6);
    cursor: pointer;
  }
  .class-teacher-card .team-card-role { color: var(--color-orange); }

  /* v5.38 — tonal cards: teacher = dark glass on dark hero; price =
     warm cream (v5.41 below re-unifies price surfaces to white —
     append order preserved, lesson #2) */
  .class-teacher-card {
    background: rgba(255,255,255,0.07);
    border: 1px solid rgba(255,255,255,0.14);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 30px 60px -28px rgba(0,0,0,0.55);
  }
  .class-teacher-card .team-card-photo {
    margin: 10px 10px 0;
    border-radius: 14px;
    overflow: hidden;
  }
  .class-teacher-card .team-card-name { color: #fff; }
  .price-card {
    background: linear-gradient(150deg, #FFF9F0 0%, #FFF0DF 55%, #FFE9D3 100%);
    color: var(--color-dark, #1C1C1C);
    border: 1px solid rgba(255,101,0,0.16);
    box-shadow: 0 26px 50px -22px rgba(255,101,0,0.28);
  }
  .price-card::after {
    background: radial-gradient(ellipse at center, rgba(255,185,4,0.30), transparent 68%);
  }
  .price-card-label { color: rgba(28,28,28,0.5); }
  .price-card-price span { color: rgba(28,28,28,0.55); }
  .price-card .star-list li { color: rgba(28,28,28,0.82); }
  .price-card-terms { color: rgba(28,28,28,0.55); }
  .price-card-terms:hover { color: var(--color-orange, #FF6500); }

  /* v5.39 — accent variants (kool=pink, stuudio=yellow) */
  .class-header--pink::before {
    content: '';
    position: absolute;
    top: -30%; right: -10%;
    width: 55vw; height: 120%;
    background: radial-gradient(ellipse at center, rgba(248,0,134,0.20), transparent 65%);
    pointer-events: none;
  }
  .class-header--yellow::before {
    content: '';
    position: absolute;
    top: -30%; right: -10%;
    width: 55vw; height: 120%;
    background: radial-gradient(ellipse at center, rgba(255,185,4,0.16), transparent 65%);
    pointer-events: none;
  }
  .class-header--pink .team-card-role { color: #FF5FB5; }
  .class-header--yellow .team-card-role { color: var(--color-yellow); }
  .class-teacher-card .team-card-email { color: rgba(255,255,255,0.55); }
  .class-teacher-card .team-card-email:hover { color: var(--color-yellow); }
  .class-facts--pink .sched-day { background: linear-gradient(135deg, #F80086, #FF6500); }
  .class-facts--pink .sched-row:hover { box-shadow: 0 16px 36px -12px rgba(248,0,134,0.20); }
  .class-facts--yellow .sched-day { background: linear-gradient(135deg, #FFB904, #FF6500); }
  .class-facts--yellow .sched-row:hover { box-shadow: 0 16px 36px -12px rgba(255,185,4,0.30); }
  .sched-day--multi { font-size: 0.78rem; letter-spacing: 0.03em; }
  .sched-full {
    display: inline-flex;
    margin-top: 0.4rem;
    padding: 0.28rem 0.7rem;
    border-radius: 999px;
    background: rgba(248,0,134,0.10);
    color: #C2006B;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }
  .class-facts--pink .class-note { background: rgba(248,0,134,0.05); border-color: rgba(248,0,134,0.13); }
  .class-facts--pink .class-note > svg { color: var(--color-pink); }
  .class-facts--yellow .class-note { background: rgba(255,185,4,0.09); border-color: rgba(255,185,4,0.25); }
  .class-facts--yellow .class-note > svg { color: #E09E00; }
  .price-card--pink {
    background: linear-gradient(150deg, #FFF6FA 0%, #FFECF4 55%, #FFE4EF 100%);
    border-color: rgba(248,0,134,0.15);
    box-shadow: 0 26px 50px -22px rgba(248,0,134,0.25);
  }
  .price-card--pink::before { background: linear-gradient(90deg, #F80086, #FF6500); }
  .price-card--pink::after { background: radial-gradient(ellipse at center, rgba(248,0,134,0.14), transparent 68%); }
  .price-card--pink .price-card-price em { background: linear-gradient(100deg, #F80086, #FF6500); -webkit-background-clip: text; background-clip: text; }
  .price-card--yellow {
    background: linear-gradient(150deg, #FFFBEE 0%, #FFF4D8 55%, #FFEEC6 100%);
    border-color: rgba(255,185,4,0.30);
    box-shadow: 0 26px 50px -22px rgba(255,185,4,0.35);
  }
  .price-card--yellow::before { background: linear-gradient(90deg, #FFB904, #FF6500); }
  .price-card--yellow::after { background: radial-gradient(ellipse at center, rgba(255,185,4,0.35), transparent 68%); }
  .price-card--yellow .price-card-price em { background: linear-gradient(100deg, #E09E00, #FF6500); -webkit-background-clip: text; background-clip: text; }

  /* v5.39 — styles / tutvustus section furniture */
  .class-styles { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(3rem, 7vh, 5rem); }
  .class-styles .styles-grid { margin-top: 2.4rem; }
  .class-season {
    display: flex;
    gap: 1.1rem;
    align-items: flex-start;
    max-width: 860px;
    margin: clamp(2rem, 4vw, 3rem) auto 0;
    padding: 1.4rem 1.6rem;
    border-radius: 16px;
    background: rgba(255,185,4,0.09);
    border: 1px solid rgba(255,185,4,0.25);
  }
  .class-season svg { width: 24px; height: 24px; flex: 0 0 auto; color: #E09E00; margin-top: 0.15rem; }
  .class-season p { margin: 0; font-size: 0.97rem; line-height: 1.65; }
  .class-electives { margin-top: clamp(3rem, 6vw, 4.5rem); }
  .soon-chip {
    display: inline-block;
    vertical-align: middle;
    margin-left: 0.5rem;
    padding: 0.22rem 0.65rem;
    border-radius: 999px;
    background: rgba(255,101,0,0.12);
    color: #C24E00;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  /* v5.40 — style cards on class detail pages read better centered */
  .class-styles .style-card { text-align: center; }

  /* v5.41 — UNIFIED COLOR PRINCIPLE: neutral white surfaces; the type
     color lives ONLY in small details (day badge, icons, price
     numeral, top bar, chips, hover shadows) */
  .price-card,
  .price-card--pink,
  .price-card--yellow {
    background: #fff;
    border: 1px solid rgba(28,28,28,0.07);
    box-shadow: 0 24px 48px -22px rgba(28,28,28,0.16);
  }
  .price-card::after { content: none; }
  .class-facts .class-note {
    background: #fff;
    border: 1px solid rgba(28,28,28,0.05);
    box-shadow: 0 10px 30px -12px rgba(28,28,28,0.10);
  }
  /* "Grupp on täis" — quiet status line instead of a loud pill */
  .sched-full {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.4rem;
    padding: 0;
    border-radius: 0;
    background: none;
    color: var(--text-muted, #8a8a8a);
    font-size: 0.82rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
  }
  .sched-full::before {
    content: '';
    width: 7px;
    height: 7px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--color-pink, #F80086);
  }

  /* v5.42 — teacher photo overlay artifacts: the base team-card
     ::after is a hover-in legibility gradient; on the white-bg
     portrait it read as a "box" — removed entirely (v5.42 → v5.42b
     final word: content none) */
  .class-teacher-card .team-card-photo::after { content: none; }
  /* v5.42 — status line: dot anchors to first text line on wrap */
  .sched-full { align-items: flex-start; }
  .sched-full::before { margin-top: 0.42em; }

  /* ---------- #19 tantsugrupid directory furniture (v5.32/v5.34) ----------
     Region pills + count + empty state; category-tabs (#19) and
     pagination (#20) already ported above. Hard category separation
     (v5.33) is JS behavior (groupsDirectory, main.js). ---------- */
  .region-filter {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1rem;
  }
  .region-pill {
    padding: 0.5rem 1.1rem;
    border-radius: 999px;
    border: 1.5px solid var(--color-light-3);
    background: #fff;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s var(--ease-out);
  }
  .region-pill:hover { transform: translateY(-2px); border-color: var(--color-orange); }
  .region-pill.is-active {
    background: var(--color-orange);
    border-color: var(--color-orange);
    color: #fff;
  }
  .directory-count {
    text-align: center;
    color: var(--text-muted);
    font-size: 0.9rem;
    margin-top: 1.4rem;
  }
  .directory-section .groups-grid { margin-top: 1.6rem; }
  .directory-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 3rem 1rem;
    color: var(--text-muted);
  }
  /* v5.34 — hidden must actually hide (class display beat the [hidden]
     UA rule), tighter hero gap */
  .region-filter[hidden] { display: none; }
  .directory-section { padding-top: clamp(2.5rem, 5vh, 3.5rem); }

  /* ---------- #42 post-meta (back-link + chips + date) ----------
     Blog post headers, both layouts; back-link reused by the klass
     header (Phase 3). Base blocks then the v5.68 chip restyle,
     prototype append order. */
  .post-back {
    display: inline-block;
    color: rgba(255,255,255,0.65);
    text-decoration: none;
    font-size: 0.9rem;
    margin-bottom: 1.2rem;
    transition: color 0.3s ease;
  }
  .post-back:hover { color: var(--color-yellow); }
  .post-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-bottom: 0.8rem; }
  .post-chip {
    display: inline-block;
    padding: 0.3rem 0.9rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }
  .post-chip--pink { background: rgba(248,0,134,0.2); color: #FF8FC8; }
  .post-chip--yellow { background: rgba(255,185,4,0.18); color: var(--color-yellow); }
  /* THEME ADDITION: Esinemised=orange per the page-map chip color map
     (§14a.3) — the prototype demonstrates only pink/yellow chips. */
  .post-chip--orange { background: rgba(255,101,0,0.2); color: #FFB380; }
  .post-date { color: rgba(255,255,255,0.6); font-size: 0.9rem; }

  /* ---------- chips over a photo ----------
     The translucent fills above are sound where they were designed to sit: on
     the flat dark band of the standard header they composite to 8.7–9.7:1
     against their tinted text (measured). In the big hero there is no known
     backdrop — the fill mixes with whatever the featured image happens to be
     under it — so the ratio is whatever the photo decides, which on the event
     posters is close to nothing. Opaque fills are the only treatment that
     holds regardless of image.

     Text colour per fill is measured, not matched to the brand by eye:
       #FFB904 + #1C1C1C = 9.90:1   #FF6500 + #1C1C1C = 5.77:1
     Pink is the awkward one — #F80086 reaches only 3.94:1 on white and 4.33:1
     on the dark ink, failing 4.5:1 both ways at this size, so the chip fill
     alone is darkened to #D4006F (5.21:1 with white). The lighter brand pink
     stays in use everywhere else. ---------- */
  .post-big-hero .post-chip {
    background: #D4006F;
    color: #fff;
  }
  .post-big-hero .post-chip--yellow {
    background: var(--color-yellow);
    color: var(--color-dark);
  }
  .post-big-hero .post-chip--orange {
    background: var(--color-orange);
    color: var(--color-dark);
  }
  /* The date was 60% white — legible on the dark band it was built for, thin
     over a photo. Full white, and a hairline pill so it reads as part of the
     same row without competing with the coloured chips for attention. */
  .post-big-hero .post-date {
    color: #fff;
    padding: 0.3rem 0.75rem;
    border-radius: 999px;
    background: rgba(20, 14, 22, 0.55);
    border: 1px solid rgba(255,255,255,0.22);
    font-size: 0.8rem;
  }
  /* On the panel scheme the copy already has an opaque ground, so the pill
     would be a box inside a box. */
  .page-hero--panel .post-date {
    background: none;
    border: 0;
    padding-inline: 0;
  }
  /* Light schemes flip the ink; the chips keep their own measured pairings.
     Both classes land on the SAME element (ts_render_hero stamps post-big-hero
     and page-hero--* together), so this is a compound selector, not a
     descendant one — the descendant form silently matched nothing. */
  .post-big-hero.page-hero--light .post-date,
  .post-big-hero.page-hero--slide-light .post-date {
    color: var(--color-dark);
    background: rgba(255,255,255,0.6);
    border-color: rgba(28,28,28,0.2);
  }
  /* Post titles are sentences, so this measure decides how many lines the dark
     header band runs to. 20ch capped it at 511px inside a 1140px container —
     565px of the row sat unused while a 72-character title broke to 3 lines
     (4 at narrower widths). A character measure is the wrong unit here: it
     shrinks with the font size, so the narrower the viewport the tighter the
     column, exactly when lines are already scarce.
     960px fits a typical news headline on two lines (~38 characters per line
     at the 2.7rem cap) and holds the longest ones — the 103-character
     tantsuetendus titles — to three. The container caps it below that on
     smaller screens, so no separate breakpoint is needed. */
  .post-title { max-width: 960px; }
  /* v5.26 — Template A: index-style event hero (post-big-hero) */
  .post-big-hero .post-back { margin-bottom: 0.4rem; }
  .post-big-hero .post-meta { margin-bottom: 0.2rem; }
  .post-big-hero .post-date { color: rgba(255,255,255,0.75); }
  .post-big-hero .hero-title { max-width: 16ch; }
  /* Long news headlines in the hero slot.
     A page hero's title is a short crafted line (18ch on /tantsuope-stuudios/,
     one line, 70px tall). A post hero gets the post title — 94ch on the
     linnalaager post — which at the shared --type-hero set 6 lines and 422px,
     47% of the 900px hero, leaving the CTA stranded at the bottom.
     The bare 16ch above was making it worse rather than better: as a character
     measure it shrinks with the font size, so every step down narrowed the
     column and put the lines back. Size and measure therefore step TOGETHER,
     in px so the column stays put, keyed on the bucket that
     ts_hero_title_length_class() stamps on the element.
     These win over .classes-hero-content > * { max-width: 580px } on
     specificity (0,2,0 vs 0,1,0), which is why the wider measures apply. */
  /* Measured while tuning: 2.6rem at 620px put a 66-character title on three
     lines — worse than the --long step below would have managed for the same
     text, because the larger type at the narrower measure fits fewer
     characters per line. Both numbers move together or the step is pointless. */
  .post-big-hero .hero-title--medium {
    font-size: clamp(1.8rem, 3.1vw, 2.4rem);
    max-width: 700px;
  }
  .post-big-hero .hero-title--long {
    font-size: clamp(1.6rem, 2.9vw, 2.2rem);
    max-width: 680px;
    letter-spacing: 0.01em;
  }
  /* v5.68 #4 — back-links read as LINKS: chip style (all dark headers) */
  .post-back {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 1.05rem;
    border: 1px solid rgba(255,255,255,0.28);
    border-radius: 999px;
    font-size: 0.85rem;
    color: rgba(255,255,255,0.82);
    transition: border-color 0.25s ease, color 0.25s ease;
  }
  .post-back:hover { border-color: var(--color-yellow); color: var(--color-yellow); }

  /* ---------- #43 post-content typography ----------
     Base blocks then v5.26/v5.27/v5.28/v5.29 fixes, append order.
     Targets block-editor output (.post-content wraps the_content()). */
  .post-hero-img {
    margin: 0 0 clamp(2rem, 4vw, 3rem);
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 30px 60px -20px rgba(28,28,28,0.25);
    margin-top: calc(-1 * clamp(5rem, 10vh, 8rem));
    position: relative;
    z-index: 2;
    /* v5.78: desktop base needs the aspect box too — was relying on the
       img's height="1080" attribute (no CSS height) → object-fit:fill
       stretched the 16:9 image to 1080px tall (portrait) on desktop.
       16:9 + cover here matches the mobile rule = correct at every width. */
    aspect-ratio: 16 / 9;
  }
  .post-hero-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .post-lead { font-size: 1.15rem; line-height: 1.75; margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
  .post-content h2 {
    font-family: 'Baumans', cursive;
    font-size: 1.6rem;
    margin: 0 0 1rem;
  }
  /* #44 post-cols — two-column block ("Kaks veergu tärnidega" pattern) */
  .post-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(1.5rem, 4vw, 3rem);
    margin-bottom: clamp(2rem, 4vw, 3rem);
  }
  /* v5.26 — the seam line must pass BEHIND the straddling image */
  .post-hero-img { z-index: 5; }
  /* v5.27 — body title on the hero template */
  .post-body-title {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.8rem, 3.5vw, 2.4rem);
    margin-bottom: 1rem;
  }
  /* v5.80 (Edward 2026-07-08) — blog content spans the FULL post column
     (≈1012px), matching the content pages + the "Loe veel" 3-card grid
     directly below, so text + image + cards all share one width/left edge.
     (Supersedes the earlier 78ch readable-measure cap + the image cap.) */
  .post-lead, .post-content > p { max-width: none; }
  .post-hero-img { max-width: none; }
  /* v5.29 — heading hierarchy + component rhythm */
  .post-body-title {
    font-size: clamp(2.2rem, 4.2vw, 3.2rem);
    line-height: 1.12;
    margin-bottom: 1.4rem;
    max-width: 26ch;
  }
  .post-content h2 { font-size: 1.45rem; letter-spacing: 0.01em; }
  .post-lead { margin-bottom: clamp(2rem, 4vw, 3rem); }
  .post-cols { margin-block: 0 clamp(2.5rem, 5vw, 3.5rem); }

  /* ---------- #45 post-register (camp registration block) ----------
     Content-pattern furniture (Phase 3 wraps a Fluent Forms embed);
     CSS ported now with the family. v5.27 base → v5.28 340px widen,
     append order; the 860px stack lives in `responsive` (v5.67 note:
     the 340px upgrade beat the old 860px rule in the prototype — the
     responsive layer restores stacking structurally). */
  .post-price { text-align: center; }
  .post-price em {
    display: block;
    font-style: normal;
    font-family: 'Baumans', cursive;
    font-size: 3rem;
    line-height: 1;
    background: linear-gradient(135deg, #F80086, #FF6500 55%, #FFB904);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
  .post-price span { font-size: 0.8rem; color: var(--text-muted); }
  .post-register {
    background: #fff;
    border-radius: 24px;
    box-shadow: 0 24px 48px -18px rgba(28,28,28,0.16);
    margin-top: clamp(2rem, 4vw, 3rem);
    display: grid;
    grid-template-columns: 300px 1fr;
    overflow: hidden;
  }
  .post-register-info {
    background: linear-gradient(165deg, #FFF7E3 0%, #FFEFEF 100%);
    padding: clamp(1.8rem, 4vw, 2.4rem);
    display: flex;
    flex-direction: column;
    gap: 1.2rem;
  }
  .post-register-info .post-price { text-align: left; }
  .post-register-form { padding: clamp(1.8rem, 4vw, 2.6rem); }
  .post-register-form h2 {
    font-family: 'Baumans', cursive;
    font-size: 1.7rem;
    margin-bottom: 0.3rem;
  }
  /* v5.28 — generous sizing */
  .post-register { grid-template-columns: 340px 1fr; }
  .post-register-form { padding: clamp(2.2rem, 4vw, 3.2rem); }
  .post-register-info { padding: clamp(2.2rem, 4vw, 3rem); }
  /* v5.29 — rhythm */
  .post-register { margin-top: clamp(2.5rem, 5vw, 4rem); }
  /* v5.31 — structured payment info */
  /* Registration closed / sold out, in place of the .post-register block.
     Same card language as .post-register above — 24px radius, same shadow, same
     warm gradient as .post-register-info — so an event that has filled up reads
     as the same component in a later state rather than a different box. */
  .post-closed {
    background: linear-gradient(165deg, #FFF7E3 0%, #FFEFEF 100%);
    border-radius: 24px;
    box-shadow: 0 24px 48px -18px rgba(28,28,28,0.16);
    margin-top: clamp(2rem, 4vw, 3rem);
    padding: clamp(1.7rem, 4vw, 2.6rem);
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    align-items: flex-start;
  }
  .post-closed-badge {
    display: inline-block;
    background: var(--color-orange);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 0.35rem 0.8rem;
    border-radius: 999px;
  }
  .post-closed h2 {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.4rem, 3vw, 1.8rem);
    margin: 0;
  }
  .post-closed p { margin: 0; max-width: 60ch; }

  .reg-deadline {
    background: #fff;
    border-left: 4px solid var(--color-orange);
    border-radius: 12px;
    padding: 0.9rem 1.1rem;
    font-size: 0.95rem;
    box-shadow: 0 8px 20px -10px rgba(28,28,28,0.12);
  }
  .reg-deadline strong {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-orange);
    margin-bottom: 0.25rem;
  }
  .reg-bank h3 {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-muted);
    margin-bottom: 0.8rem;
  }
  .reg-bank dl { margin: 0; }
  .reg-bank dt {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
  }
  .reg-bank dd {
    margin: 0.1rem 0 0.75rem;
    font-weight: 600;
    overflow-wrap: anywhere;
  }

  /* ---------- #47 post-related — "Loe veel" ----------
     Base + v5.27 no-stagger cleanup, append order. (The related grid
     also carries .news-grid, whose flat re-assertions in the ≥981px
     responsive block cover the same trap.) */
  .post-related { margin-top: clamp(3rem, 6vw, 5rem); }
  .post-related .section-title { margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
  .post-related .event-card,
  .post-related .event-card:nth-child(2),
  .post-related .event-card:nth-child(3) { transform: none; }
  .post-related .event-card:hover { transform: translateY(-8px) rotate(-0.5deg); }

  /* ---------- #46 post-gallery (photo mosaic — voistlused #galerii, blog) ----------
     Base block (styles.css:3749) then the v5.29 fix block, prototype
     append order preserved. The prototype's inline 900px @media moved
     to `responsive` (columns only — see the dead-rows note there). */
  .post-gallery-block { margin-top: clamp(3rem, 6vw, 5rem); }
  .post-gallery-block .section-title { margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
  .post-gallery {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 220px;
    gap: clamp(0.8rem, 1.5vw, 1.2rem);
  }
  .pg-item {
    margin: 0;
    border-radius: 18px;
    overflow: hidden;
    position: relative;
  }
  .pg-item--big { grid-column: span 2; grid-row: span 2; }
  .pg-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.6s var(--ease-out);
  }
  .pg-item:hover img { transform: scale(1.05); }
  /* v5.29 — real-world gallery gaps: tight 12px, taller 240px rows.
     Unscoped-late in the prototype → wins at EVERY width (incl. over the
     900px media's 180px rows). Keep after the base block. */
  .post-gallery { gap: 12px; grid-auto-rows: 240px; }
  .post-gallery-block { margin-bottom: clamp(2rem, 4vw, 3rem); }

  /* ---------- #47 page-prose — generic page content (2026-08-03) ----------
     page.php renders the_content() raw, and the stylesheet carries no base
     rules for h2/p/table (everything is component-scoped), so long-form pages
     — Müügitingimused, Privaatsustingimused — came out as unstyled HTML flow:
     numbered headings sitting flush against the preceding paragraph and
     borderless tables.

     Deliberately restrained: reading measure, heading rhythm, and a table that
     matches the site's card language. No new colours beyond the existing
     tokens. Scoped to .page-prose so the designed page templates, which own
     their own typography, are untouched. */
  .page-body { padding-block: clamp(3rem, 6vh, 5rem); }

  .page-prose {
    max-width: 68ch;                 /* keeps legal text readable on wide screens */
    font-size: var(--type-body);
    line-height: 1.8;
    color: var(--text-on-light);
  }
  .page-prose > * + * { margin-top: 1.15em; }

  .page-prose h2,
  .page-prose h3 {
    font-family: 'Baumans', cursive;
    color: var(--color-dark);
    line-height: 1.2;
    letter-spacing: 0.01em;
    text-wrap: balance;
  }
  /* The spacing that was missing: headings need room above, less below, so a
     section reads as attached to its own text rather than the previous one. */
  .page-prose > h2 { font-size: var(--type-h3); margin-top: 2.6em; margin-bottom: 0.65em; }
  .page-prose > h3 { font-size: var(--type-h4); margin-top: 2em;   margin-bottom: 0.5em; }
  .page-prose > h2:first-child,
  .page-prose > h3:first-child { margin-top: 0; }
  /* Hairline above each top-level section — cheap way to make a long legal
     document scannable without numbering it twice. */
  .page-prose > h2 { padding-top: 1.1em; border-top: 1px solid var(--color-light-3); }
  .page-prose > h2:first-child { padding-top: 0; border-top: 0; }

  .page-prose strong { font-weight: 600; color: var(--color-dark); }

  .page-prose a {
    color: var(--color-pink);
    text-decoration: underline;
    text-underline-offset: 0.18em;
    text-decoration-thickness: 1px;
  }
  .page-prose a:hover { text-decoration-thickness: 2px; }

  .page-prose ul,
  .page-prose ol { padding-left: 1.35em; }
  .page-prose li + li { margin-top: 0.4em; }
  .page-prose ul { list-style: none; padding-left: 1.1em; }
  .page-prose ul > li { position: relative; padding-left: 0.9em; }
  .page-prose ul > li::before {
    content: '';
    position: absolute; left: 0; top: 0.72em;
    width: 5px; height: 5px; border-radius: 50%;
    background: var(--color-pink);
  }

  /* Tables: the source blocks are wp:table, so style the block wrapper too.
     Full-bleed of the prose measure, since a 3-column table needs the room. */
  .page-prose figure.wp-block-table { margin-top: 1.8em; overflow-x: auto; }
  .page-prose table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95em;
    background: var(--color-light);
    border: 1px solid var(--color-light-3);
    border-radius: 10px;
    overflow: hidden;
  }
  .page-prose thead th {
    text-align: left;
    font-weight: 600;
    font-size: 0.86em;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-dark);
    background: var(--color-light-2);
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--color-light-3);
  }
  .page-prose tbody td {
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--color-light-3);
    vertical-align: top;
  }
  .page-prose tbody tr:last-child td { border-bottom: 0; }
  .page-prose tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--color-light-2) 55%, transparent); }
  /* No per-column alignment rules. An earlier version right-aligned and
     nowrap'd the last column on the assumption it always holds a price — true
     for the delivery and retention tables, false for the recipients table in
     Privaatsustingimused, where that column is a full sentence. The result was
     a horizontal scrollbar with the text cut off. Left-aligned throughout is
     both safer and fine to read; tabular-nums still lines up any digits. */
  .page-prose table { font-variant-numeric: tabular-nums; }
  .page-prose :is(th, td) { text-align: left; }

}

/* ================================================================
   LAYER: pages — page-specific one-off rules
   ================================================================ */
@layer pages {

  /* ============================================
     v5.47 — KONTAKT PAGE (desktop values; @media rules → responsive)
     ============================================ */
  .contact-section { padding: clamp(3.5rem, 8vh, 5.5rem) 0; }
  .contact-grid {
    display: grid;
    grid-template-columns: 0.9fr 1.1fr;
    gap: clamp(2rem, 4vw, 4rem);
    align-items: start;
  }
  .contact-channels { display: flex; flex-direction: column; gap: 1rem; }
  .contact-channels > .animate-in:first-child { margin-bottom: 0.8rem; }
  .contact-card {
    display: flex;
    gap: 1.1rem;
    align-items: flex-start;
    background: #fff;
    border: 1px solid rgba(28,28,28,0.05);
    border-radius: 16px;
    padding: 1.25rem 1.4rem;
    box-shadow: 0 10px 30px -12px rgba(28,28,28,0.10);
  }
  .contact-card > svg { width: 24px; height: 24px; flex: 0 0 auto; color: var(--color-orange); margin-top: 0.15rem; }
  .contact-card strong { display: block; margin-bottom: 0.35rem; font-size: 0.98rem; }
  .contact-card a {
    display: block;
    color: var(--text-muted, #6b6b6b);
    text-decoration: none;
    font-size: 0.95rem;
    line-height: 1.7;
    transition: color 0.25s ease;
  }
  .contact-card a:hover { color: var(--color-orange); }
  .contact-reg { font-size: 0.82rem; color: #9a9a9a; margin-top: 0.4rem; }

  .contact-form-card {
    background: #fff;
    border: 1px solid rgba(28,28,28,0.07);
    border-radius: 22px;
    padding: clamp(1.8rem, 3vw, 2.6rem);
    box-shadow: 0 24px 48px -22px rgba(28,28,28,0.16);
    position: relative;
    overflow: hidden;
  }
  .contact-form-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: linear-gradient(90deg, #F80086, #FF6500, #FFB904);
  }
  .contact-form-card h2 {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.5rem, 2.4vw, 1.9rem);
    margin-bottom: 0.4rem;
  }

  .studio-map-section { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(3.5rem, 8vh, 5.5rem); }

  /* 6 cards: 3 + 3 (6-track grid, span 2 each) */
  .contact-team-grid { grid-template-columns: repeat(6, 1fr); }
  .contact-team-grid .team-card { grid-column: span 2; }
  .contact-team-grid .team-card-role { color: var(--color-orange); }

  /* v5.48 — org identity card (kontakt) */
  .contact-org {
    display: flex;
    gap: 1.1rem;
    align-items: flex-start;
    background: #fff;
    border: 1px solid rgba(28,28,28,0.07);
    border-radius: 16px;
    padding: 1.4rem 1.5rem;
    box-shadow: 0 10px 30px -12px rgba(28,28,28,0.10);
    position: relative;
    overflow: hidden;
  }
  .contact-org::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: linear-gradient(90deg, #F80086, #FF6500, #FFB904);
  }
  .contact-org > svg {
    width: 26px; height: 26px;
    flex: 0 0 auto;
    fill: var(--color-orange);
    margin-top: 0.15rem;
  }
  .contact-org strong {
    display: block;
    font-family: 'Baumans', cursive;
    font-size: 1.25rem;
    margin-bottom: 0.3rem;
  }
  .contact-org span { display: block; color: var(--text-muted, #6b6b6b); font-size: 0.93rem; line-height: 1.65; }

  /* ============================================
     SAAME-TUTTAVAKS (about) — story grid + kinetic title (#41)
     Desktop values; 820px collapse + reduced-motion → responsive.
     ============================================ */
  .kinetic-title { font-family: 'Baumans', cursive; font-size: var(--type-h2); line-height: 1.15; }
  .kinetic-title .word {
    display: inline-block;
    transform: translateY(24px) rotate(3deg);
    opacity: 0;
    transition: opacity 0.6s ease, transform 0.7s var(--ease-spring);
  }
  .animate-in.visible .kinetic-title .word { opacity: 1; transform: translateY(0) rotate(0); }
  .kinetic-title .word:nth-child(1) { transition-delay: 0.05s; }
  .kinetic-title .word:nth-child(2) { transition-delay: 0.12s; }
  .kinetic-title .word:nth-child(3) { transition-delay: 0.19s; }
  .kinetic-title .word:nth-child(4) { transition-delay: 0.26s; }
  .kinetic-title .word:nth-child(5) { transition-delay: 0.33s; }

  .story-section {
    background: var(--color-light-2);
    position: relative;
    overflow: hidden;
  }
  .story-grid {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    gap: clamp(2.5rem, 5vw, 4rem);
    align-items: center;
  }
  .story-text h2.section-title { margin-bottom: 1.25rem; }
  .story-text p {
    margin-block: 1rem;
    line-height: 1.8;
    color: var(--color-dark);
  }
  .story-image {
    aspect-ratio: 1;
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 30px 60px -20px rgba(28,28,28,0.25);
    position: relative;
  }
  .story-image img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
  }
  /* v5.2 — story image joins the collage language + parallax hint
     (MUST stay after the base block — same layer, source order) */
  .story-image { border-radius: 24px; overflow: hidden; box-shadow: 0 30px 60px -20px rgba(28,28,28,0.25); will-change: transform; }
  .story-image img { width: 100%; height: 100%; object-fit: cover; display: block; }

  /* ============================================
     v5.61 — TANTSUVÕISTLUSED page (section rhythm one-offs;
     ≤640px re-assertions live in the responsive LAYER-TRAP block)
     ============================================ */
  .venues-section { padding: clamp(3rem, 7vh, 5rem) 0; }
  .venues-section .styles-grid { margin-top: 2.4rem; }
  .solos-section { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(3rem, 7vh, 5rem); }
  .solos-section .styles-grid { margin-top: 2.4rem; }
  .voistlused-gallery { padding-bottom: clamp(3.5rem, 8vh, 5.5rem); }
  .voistlused-gallery .post-gallery-block { margin-top: 0; }

  /* ============================================
     v5.49/v5.51 — REGISTREERI page (liitu.html) section rhythm
     (≤640px re-assertions in the responsive LAYER-TRAP block)
     ============================================ */
  .join-section { padding: clamp(3rem, 7vh, 5rem) 0; }
  .join-how { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(4rem, 9vh, 6rem); }

  /* ============================================
     UUDISED listing (news-section) — base block + v5.24 fixes,
     prototype append order. Also used by category.php archives.
     ============================================ */
  .news-section { background: var(--color-light-2); }
  .news-section .group-filter { margin-top: 0; margin-bottom: clamp(2rem, 4vw, 3rem); }
  a.event-card { display: block; text-decoration: none; color: inherit; }
  .news-grid { grid-template-rows: auto; }
  /* v5.24 — uudised listing fixes: tight header gap, flat multi-row
     grid (index stagger neutralized — desktop stagger lives in a
     (min-width: 981px) responsive block, its neutralizers re-asserted
     THERE; these unqualified ones keep parity at every other width),
     equal-height cards. (page-header padding-bottom part of this
     v-block is already in components #11.) */
  section.news-section { padding-block: clamp(2rem, 4vh, 3rem) clamp(4rem, 7vw, 6rem); }
  .news-grid .event-card,
  .news-grid .event-card:nth-child(2),
  .news-grid .event-card:nth-child(3) { transform: none; }
  .news-grid .event-card:hover,
  .news-grid .event-card:nth-child(2):hover,
  .news-grid .event-card:nth-child(3):hover { transform: translateY(-8px) rotate(-0.5deg); }
  .news-grid { align-items: stretch; row-gap: clamp(1.5rem, 3vw, 2.5rem); }
  .news-grid .event-card { display: flex; flex-direction: column; }
  .news-grid .event-card-body { flex: 1; display: flex; flex-direction: column; }
  .news-grid .event-card-link { margin-top: auto; }
  /* category.php empty state (theme addition — no prototype equivalent) */
  .news-empty { grid-column: 1 / -1; text-align: center; color: var(--text-muted); padding: 3rem 0; }

  /* ============================================
     BLOG POST pages (single.php — both layouts).
     Prototype append order kept; the dead `section.post-section`
     padding rules (v5.24/v5.27/v5.29 — post bodies are <article>, they
     never matched, v5.30.1's comment) are NOT ported, and v5.30.1's
     prototype-original !importants are dropped: in @layer an
     !important would invert layer priority, and plain rules here
     already express the final computed values.
     ============================================ */
  .post-header { padding-bottom: clamp(3rem, 6vh, 4.5rem); }
  .post-section { background: var(--color-light-2); }
  .post-container { max-width: 900px; }
  /* v5.25 — header column aligns with the post body; the pulled-up
     hero image must clear the title */
  .post-header-inner { max-width: 900px; }
  .post-header { padding-bottom: clamp(8rem, 14vh, 11rem); }
  /* v5.26 */
  .post-section { position: relative; }
  /* v5.27 */
  .post-big-hero + .post-section .post-content { padding-top: 0; }
  /* v5.28 — wider article column (900px was cramped) */
  .post-container { max-width: 1140px; }
  /* v5.30.1 final values (element-agnostic — see note above) */
  .post-section { padding-block: clamp(3rem, 6vh, 4.5rem) clamp(5rem, 8vw, 7rem); }
  .post-section--related { padding-block: clamp(3.5rem, 7vh, 5rem) clamp(6.5rem, 10vw, 9rem); }
  /* v5.31 — spacing dialed back (final hero→body clearance) */
  .post-big-hero + .post-section { padding-top: clamp(3.5rem, 6vh, 4.5rem); }
  /* THEME FIX (2026-07-06, Edward's review) — the standard post header
     is measurably identical to the prototype (padding-bottom 128px at
     1440×~810, headless-verified) but reads as a dead dark void below
     the title: the straddling image only claws back ~32px of it.
     Compacted deliberately from v5.25's clamp(8rem,14vh,11rem); the
     image pull-up (-clamp(5rem,10vh,8rem)) minus the body's top
     padding stays inside this at every viewport, leaving ~3rem of
     breathing room between title and image. Mobile untouched (v5.68
     responsive override still wins). */
  .post-header { padding-bottom: clamp(5rem, 9vh, 7rem); }
}

/* ================================================================
   LAYER: integrations — v4 skins for third-party markup
   ================================================================ */
@layer integrations {

  /* ---------- #48 reg-form — canonical form skin ----------
     Prototype .field system (kontakt v5.47, blog v5.25/v5.28) kept as the
     source of truth; Fluent Forms markup is mapped onto it below.
     FF's own stylesheets are dequeued (functions.php, §9 rule 3). */
  .post-form-sub { color: var(--text-muted); margin-bottom: 1.5rem; }

  /* Placeholder shipped inside the "Ürituse registreerimine" pattern where
     the form shortcode goes. Styled to read as an unfinished editor note,
     not as page content — see the pattern comment in functions.php. */
  .reg-form-placeholder {
    border: 2px dashed var(--color-yellow);
    border-radius: 12px;
    background: color-mix(in srgb, var(--color-yellow) 12%, transparent);
    padding: 1.1rem 1.2rem;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text-on-light);
  }
  .reg-form-placeholder code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    background: color-mix(in srgb, var(--color-dark) 8%, transparent);
    padding: 0.1em 0.35em;
    border-radius: 3px;
  }

  .reg-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.1rem 1.4rem;
  }
  .field { display: flex; flex-direction: column; gap: 0.35rem; }
  .field--full { grid-column: 1 / -1; }
  .field span {
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.04em;
  }
  .field input, .field select {
    font: inherit;
    padding: 0.75rem 1rem;
    border: 1.5px solid var(--color-light-3);
    border-radius: 12px;
    background: var(--color-light-2);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
  }
  .field input:focus, .field select:focus {
    outline: none;
    border-color: var(--color-orange);
    box-shadow: 0 0 0 3px rgba(255,101,0,0.15);
  }
  .consent {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-size: 0.88rem;
    color: var(--text-muted);
    cursor: pointer;
  }
  .consent input { accent-color: var(--color-orange); margin-top: 0.2rem; }
  .reg-success {
    background: rgba(255,185,4,0.12);
    border: 1px solid rgba(255,185,4,0.4);
    border-radius: 12px;
    padding: 0.9rem 1.2rem;
    font-weight: 600;
  }
  /* v5.26 — custom select chevron (native arrow looked off) */
  .field select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF6500' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 16px;
    padding-right: 2.8rem;
  }
  /* v5.47 — textarea joins the field family */
  .field textarea {
    font: inherit;
    padding: 0.75rem 1rem;
    border: 1.5px solid var(--color-light-3);
    border-radius: 12px;
    background: var(--color-light-2);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
    resize: vertical;
    min-height: 120px;
    width: 100%;
    min-width: 0;
  }
  .field textarea:focus {
    outline: none;
    border-color: var(--color-orange);
    box-shadow: 0 0 0 3px rgba(255,101,0,0.15);
  }
  /* v5.28 — form overflow fix + generous spacing */
  .field { min-width: 0; }
  .field input, .field select {
    width: 100%;
    box-sizing: border-box;
    padding: 0.9rem 1.1rem;
  }
  .reg-form { gap: 1.3rem 1.6rem; }

  /* ---------- Fluent Forms → reg-form skin mapping ----------
     FF wraps fields in <form><fieldset>…; the grid lives on the fieldset.
     Field containers carry `field--full` via FF container_class settings. */
  .frm-fluent-form fieldset {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.3rem 1.6rem; /* v5.28 spacing */
  }
  .frm-fluent-form legend { grid-column: 1 / -1; } /* 0-height a11y title — must not eat a grid cell */
  .ff-el-group {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 0;
    min-width: 0;
  }
  .ff-el-input--label label {
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.04em;
  }
  /* FF's dequeued CSS normally renders the required asterisk — replicate */
  .ff-el-is-required.asterisk-right label::after { content: ' *'; }
  .ff-el-form-control {
    font: inherit;
    width: 100%;
    box-sizing: border-box;
    padding: 0.9rem 1.1rem;
    border: 1.5px solid var(--color-light-3);
    border-radius: 12px;
    background: var(--color-light-2);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
  }
  .ff-el-form-control:focus {
    outline: none;
    border-color: var(--color-orange);
    box-shadow: 0 0 0 3px rgba(255,101,0,0.15);
  }
  textarea.ff-el-form-control {
    resize: vertical;
    min-height: 120px;
  }
  /* submit button = .btn-primary look (components #15) */
  .ff-btn-submit {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.85rem 2rem;
    border-radius: 100px;
    font-family: 'Exo', sans-serif;
    font-weight: 600;
    font-size: var(--type-small);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    border: 2px solid transparent;
    cursor: pointer;
    transition: background 0.3s ease, color 0.3s ease, box-shadow 0.4s ease, transform 0.3s var(--ease-spring);
    background: var(--color-yellow);
    color: var(--color-dark);
    justify-self: start;
  }
  .ff-btn-submit:hover {
    background: var(--color-orange);
    color: #fff;
    box-shadow: 0 10px 40px -10px rgba(255,101,0,0.7), 0 0 0 6px rgba(255,101,0,0.12);
  }
  .ff-btn-submit[disabled] { opacity: 0.6; cursor: wait; }
  /* validation + confirmation states (keep .reg-success styling per JS table §10) */
  .ff-el-is-error .ff-el-form-control { border-color: var(--color-pink); }
  .ff-el-group .error, .ff-el-group .text-danger {
    color: var(--color-pink);
    font-size: 0.78rem;
    font-weight: 500;
  }
  .ff-message-success {
    background: rgba(255,185,4,0.12);
    border: 1px solid rgba(255,185,4,0.4);
    border-radius: 12px;
    padding: 0.9rem 1.2rem;
    font-weight: 600;
  }

  /* ---------- FF skin: elements first used by the registration form
     (form 4, "Üritusele registreerimine" — 2026-07-06 review round) ---------- */
  /* select → the v5.26 chevron look (FF markup ≠ .field select) */
  select.ff-el-form-control {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF6500' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 16px;
    padding-right: 2.8rem;
  }
  /* terms/consent checkbox → prototype .consent look
     (FF markup: .ff-el-tc > label > input.ff-el-form-check-input + .ff_t_c) */
  .ff-el-tc label {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-size: 0.88rem;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--text-muted);
    cursor: pointer;
  }
  .ff-el-tc input { accent-color: var(--color-orange); margin-top: 0.2rem; flex: 0 0 auto; }
  .ff_t_c p { margin: 0; display: inline; }

  /* ---------- #43 post editor content FLOW (THEME ADDITION,
     2026-07-06 review round) ----------
     The prototype has NO vertical-flow margins inside .post-content —
     its universal reset zeroes everything and its content is always
     classed blocks (post-lead / post-cols / post-register /
     post-gallery), so bare-tag flow (p after list, heading after list)
     was never designed and crams (measured 0px gaps). These rules give
     editor-written Phase 3 content a sane rhythm WITHOUT touching the
     prototype-classed blocks:
     - DIRECT children only (`>`): Gutenberg emits flow blocks as
       direct .post-content children, while every prototype pattern
       (post-cols / post-register / post-gallery wp:html blocks) nests
       its elements one level down — so pattern internals (reg-deadline,
       register h2, cols star-lists…) can never match. This matters
       because integrations is a LATER layer than components: a generic
       rule here would beat ported family rules regardless of
       specificity (probe caught .post-lead's 48px margin-bottom
       collapsing to 16.8px before the :not exclusions were added);
     - `* + h2/h3` only hits headings that FOLLOW content (first-child
       headings — post-cols columns etc. — untouched). */
  :where(.post-content) > p:not(.post-lead):not(.post-body-title) { margin-block: 1.05rem; }
  :where(.post-content) > ul:not([class]),
  :where(.post-content) > ol:not([class]) { margin-block: 1.05rem; padding-left: 1.3rem; }
  .post-content > * + h2,
  .post-content > * + h3 { margin-top: clamp(2rem, 3.5vw, 2.75rem); }
  .post-content > ul.star-list { margin-block: 1.2rem 1.7rem; }

  /* ---------- #52 map-embed — OSM iframe + glass overlay card ----------
     OSM kept: Google output=embed blanks in the EU (consent redirect
     blocks framing) — prototype comment, kontakt.html. */
  .map-wrap {
    position: relative;
    margin-top: 2.4rem;
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 30px 60px -25px rgba(28,28,28,0.30);
  }
  .map-wrap iframe {
    display: block;
    width: 100%;
    height: clamp(360px, 48vh, 480px);
    border: 0;
    filter: grayscale(0.85) contrast(1.02);
  }
  .map-card {
    position: absolute;
    top: clamp(1rem, 3vw, 2rem);
    left: clamp(1rem, 3vw, 2rem);
    max-width: 300px;
    background: rgba(28,28,28,0.88);
    color: #fff;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 18px;
    padding: 1.4rem 1.6rem;
  }
  .map-card > svg { width: 20px; height: 20px; fill: var(--color-yellow); margin-bottom: 0.6rem; }
  .map-card strong { display: block; font-family: 'Baumans', cursive; font-size: 1.15rem; margin-bottom: 0.3rem; }
  .map-card p { margin: 0 0 0.8rem; color: rgba(255,255,255,0.75); font-size: 0.92rem; line-height: 1.5; }
  .map-directions { color: var(--color-yellow); text-decoration: none; font-size: 0.88rem; font-weight: 600; transition: color 0.25s ease; }
  .map-directions:hover { color: #fff; }

  /* ---------- #49 Sportlyzer frame chrome (v5.51 base → v5.52 widen,
     append order kept). Desktop iframe heights are HTML attributes
     (1850/1900/1900); mobile heights (v5.67b) live in `responsive`. ---------- */
  .join-form-frame {
    max-width: 680px;
    margin: clamp(1.8rem, 3.5vh, 2.6rem) auto 0;
    background: #fff;
    border: 1px solid rgba(28,28,28,0.07);
    border-radius: 22px;
    padding: clamp(1.4rem, 2.5vw, 2.4rem);
    box-shadow: 0 24px 48px -22px rgba(28,28,28,0.16);
    position: relative;
    overflow: hidden;
  }
  .join-form-frame::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
  }
  .join-form-frame--orange::before { background: linear-gradient(90deg, #FF6500, #FFB904); }
  .join-form-frame--pink::before { background: linear-gradient(90deg, #F80086, #FF6500); }
  .join-form-frame--yellow::before { background: linear-gradient(90deg, #FFB904, #FF6500); }
  .join-form-frame iframe { display: block; width: 100%; border: 0; }
  /* v5.52 — wider frame */
  .join-form-frame { max-width: 880px; }
}

/* ================================================================
   LAYER: utilities
   ================================================================ */
@layer utilities {
  .visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .text-center { text-align: center; }

  /* Scroll animations */
  .animate-in {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.8s ease, transform 0.8s var(--ease-out);
  }
  .animate-in.visible {
    opacity: 1;
    transform: translateY(0);
  }
  .stagger .animate-in:nth-child(1) { transition-delay: 0s; }
  .stagger .animate-in:nth-child(2) { transition-delay: 0.12s; }
  .stagger .animate-in:nth-child(3) { transition-delay: 0.24s; }
  .stagger .animate-in:nth-child(4) { transition-delay: 0.36s; }

  /* v4 — no-JS gate: initial hidden states only apply once JS adds .js-anim */
  html:not(.js-anim) .animate-in,
  html:not(.js-anim) .hero-eyebrow,
  html:not(.js-anim) .hero-subtitle,
  html:not(.js-anim) .hero-buttons { opacity: 1 !important; transform: none !important; }
  html:not(.js-anim) .hero-title { clip-path: none !important; }
  html:not(.js-anim) .kinetic-title .word { opacity: 1 !important; transform: none !important; }
}

/* ================================================================
   LAYER: responsive — ALL @media rules live here, nothing else.
   Order: width queries desktop-first descending → interaction-tier
   → prefers-reduced-motion last (motion-off always wins).
   ================================================================ */
@layer responsive {

  /* ----- desktop tier: blog back-link is mobile furniture ----------
     THEME FIX (2026-07-06, Edward's review): the prototype ships
     "← Kõik uudised" in BOTH post headers at every width; Edward
     removed it from desktop ("the link Kõik uudised on the desktop
     not needed") — the header nav covers it there. The v5.68 chip
     stays on the touch tier, where it is the only visible way back.
     Scoped to the blog headers so the klass header's back-link
     (Phase 3) is unaffected. ----- */
  @media (min-width: 901px) and (hover: hover) {
    .post-header .post-back,
    .post-big-hero .post-back { display: none; }
  }

  /* ----- ≥981px: index events stagger + hover offsets (#24) ----------
     LAYER-TRAP NOTE: in the unlayered prototype the v5.24 news-grid
     neutralizers (pages block) beat these by source order; in @layer
     this responsive block would beat `pages`, re-staggering the uudised
     grid — so the neutralizers are re-asserted HERE, after the stagger
     rules, in prototype computed values. ----- */
  @media (min-width: 981px) {
    .events-grid .event-card:nth-child(2) { transform: translateY(2.5rem); }
    .events-grid .event-card:nth-child(3) { transform: translateY(5rem); }
    .events-grid .event-card:hover { transform: translateY(calc(var(--baseOffset, 0px) - 8px)) rotate(-0.5deg); }
    .events-grid .event-card:nth-child(1):hover { --baseOffset: 0rem; }
    .events-grid .event-card:nth-child(2):hover { --baseOffset: 2.5rem; }
    .events-grid .event-card:nth-child(3):hover { --baseOffset: 5rem; }
    /* re-assertions (v5.24, see note): flat news grid at every width */
    .news-grid .event-card,
    .news-grid .event-card:nth-child(2),
    .news-grid .event-card:nth-child(3) { transform: none; }
    .news-grid .event-card:hover,
    .news-grid .event-card:nth-child(2):hover,
    .news-grid .event-card:nth-child(3):hover { transform: translateY(-8px) rotate(-0.5deg); }
  }

  /* ----- 1000px: style + group grids drop to 2 columns ----- */
  @media (max-width: 1000px) {
    .styles-grid { grid-template-columns: repeat(2, 1fr); }
    .groups-grid { grid-template-columns: repeat(2, 1fr); }
    /* v5.42 */
    .styles-grid--3col { grid-template-columns: repeat(2, 1fr); }
    /* v5.66 — minmax(0,1fr) re-declare, append order preserved */
    .styles-grid, .styles-grid--3col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  /* ----- 980px: events grid drops to 2 columns (#24) ----- */
  @media (max-width: 980px) {
    .events-grid { grid-template-columns: repeat(2, 1fr); }
  }

  /* ----- 940px: kontakt contact grid collapses (v5.47) ----- */
  @media (max-width: 940px) {
    .contact-grid { grid-template-columns: 1fr; }
    /* v5.35 — klass facts: schedule + price card stack */
    .class-facts-grid { grid-template-columns: 1fr; }
  }

  /* ----- 900px: mobile/touch tier — header collapses to hamburger ----- */
  @media (max-width: 900px) {
    .main-nav, .header-cta { display: none; }
    .hamburger { display: block; }
    .logo svg { height: 44px; }
    .header-inner > nav { display: none; }
    /* v5.16 — lastetants extras split stacks, cutouts shrink */
    .extras-split { grid-template-columns: 1fr; }
    .content-cutout--wide { max-width: 420px; margin-inline: auto; }
    .content-cutout--side { max-width: 260px; }
    /* v5.18 — theatre */
    .theatre-wrap { margin-top: -0.5rem; }
    .theatre-wrap .cinema-sound { bottom: 2%; }
    /* v5.19 — theatre v3 */
    .theatre-wrap { width: 94vw; margin-left: calc(50% - 47vw); }
    /* #46 post-gallery → 2 columns (prototype inline media,
       styles.css:3757). Columns ONLY: that media's 180px grid-auto-rows
       is dead code in the prototype — the later unscoped v5.29 rule
       (gap 12px / rows 240px, ported to `components`) beats it by source
       order at every width, so 240px is the prototype's computed value
       on mobile too. */
    .post-gallery { grid-template-columns: repeat(2, 1fr); }
    /* v5.67b — Sportlyzer stacks single-column at phone width → much
       taller; the desktop-tuned iframe heights clipped the submit area */
    [data-jpane="lasteaed"] .join-form-frame iframe { height: 2020px; }
    [data-jpane="kool"] .join-form-frame iframe,
    [data-jpane="stuudio"] .join-form-frame iframe { height: 2300px; }
  }

  /* ----- 860px: join steps stack (v5.49); post-register stacks
     (v5.27 media + v5.67 restore — the responsive layer beats the
     components-layer 340px upgrade structurally, no repeat needed) ----- */
  @media (max-width: 860px) {
    .join-steps { grid-template-columns: 1fr; }
    .post-register { grid-template-columns: 1fr; }
    /* v5.36 — klass header: teacher card drops under the title copy */
    .class-header-grid { grid-template-columns: 1fr; }
    .class-teacher-card { width: min(260px, 72vw); }
  }

  /* ----- 820px: footer grid + team grids collapse ----- */
  @media (max-width: 820px) {
    .footer-grid { grid-template-columns: 1fr; gap: 2.5rem; }
    .team-grid { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
    /* v5.47 — kontakt 6-track grid back to plain 2-col */
    .contact-team-grid { grid-template-columns: repeat(2, 1fr); }
    .contact-team-grid .team-card { grid-column: auto; }
    /* about story goes single-column */
    .story-grid { grid-template-columns: 1fr; gap: 2rem; }
    .story-image { aspect-ratio: 4/5; }
    /* v5.5 — studio-about story stacks */
    .studio-about-grid { grid-template-columns: 1fr; }
  }

  /* ----- 760px: category-tabs — v5.33 stack, then the v5.68 compact
     segmented control (same query, later source wins = prototype order;
     the full cards pushed the actual content below the fold) ----- */
  @media (max-width: 760px) {
    .category-tabs { grid-template-columns: 1fr; }
  }
  @media (max-width: 760px) {
    .category-tabs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; }
    .cat-tab { padding: 0.75rem 0.3rem 0.7rem; border-radius: 14px; }
    .cat-tab strong { font-size: 0.82rem; letter-spacing: 0; }
    .cat-tab span { display: none; }
    .cat-tab-star { width: 15px; height: 15px; margin-bottom: 0.3rem; }
    .cat-tab:hover { transform: none; }
  }

  /* ----- 700px: post columns stack (#44 — prototype inline media) ----- */
  @media (max-width: 700px) {
    .post-cols { grid-template-columns: 1fr; }
  }

  /* ----- 640px: form goes single-column (v5.25; FF fieldset mapping) ----- */
  @media (max-width: 640px) {
    .reg-form { grid-template-columns: 1fr; }
    .frm-fluent-form fieldset { grid-template-columns: 1fr; }
  }

  /* ----- 640px: mobile section rhythm + hero copy + CTA (index base
     block). LAYER-TRAP NOTE: in the unlayered prototype the generic
     `section` rule lost to every explicit section padding (specificity);
     in @layer the responsive layer beats them all, so sections whose
     explicit padding must survive ≤640px are re-asserted here, in
     prototype computed values, AFTER the generic rule. ----- */
  @media (max-width: 640px) {
    /* Tighter section rhythm on mobile — no wasted vertical space */
    section { padding-block: clamp(2.5rem, 7vw, 4rem); }
    /* re-assertions (see note): components/pages paddings ≤640px */
    .page-header { padding: calc(var(--header-h) + clamp(0.8rem, 2vh, 1.2rem)) 0 clamp(1rem, 2.5vh, 1.6rem); }
    .contact-section { padding: clamp(3.5rem, 8vh, 5.5rem) 0; }
    .studio-map-section { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(3.5rem, 8vh, 5.5rem); }
    /* voistlused (v5.61 pages rules — prototype computed values) */
    .venues-section { padding: clamp(3rem, 7vh, 5rem) 0; }
    .solos-section { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(3rem, 7vh, 5rem); }
    .voistlused-gallery { padding-bottom: clamp(3.5rem, 8vh, 5.5rem); }
    /* registreeri (v5.49/v5.51 pages rules — prototype computed values) */
    .join-section { padding: clamp(3rem, 7vh, 5rem) 0; }
    .join-how { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(4rem, 9vh, 6rem); }
    /* uudised (v5.24 pages rule — prototype computed values) */
    section.news-section { padding-block: clamp(2rem, 4vh, 3rem) clamp(4rem, 7vw, 6rem); }
    /* klass detail + tantsugrupid (v5.35/v5.39/v5.34 — prototype
       computed values; .directory-section only classes the TOP
       padding, its bottom keeps the generic mobile value) */
    .class-facts { padding: clamp(3.5rem, 8vh, 5.5rem) 0; }
    .class-styles { padding: clamp(1.5rem, 4vh, 3rem) 0 clamp(3rem, 7vh, 5rem); }
    .directory-section { padding-top: clamp(2.5rem, 5vh, 3.5rem); }

    /* events grid single-column (#24 — prototype inline 640px media) */
    .events-grid { grid-template-columns: 1fr; }

    /* hero copy compacts (shared atoms — classes-hero pages) */
    .hero-title { font-size: clamp(1.6rem, 7.5vw, 2.1rem); }
    .hero-subtitle { font-size: 0.88rem; line-height: 1.5; max-width: none; }
    .hero-eyebrow { font-size: 0.68rem; letter-spacing: 0.2em; }
    /* Buttons: stack full-width — compact sizing */
    .hero-buttons {
      flex-direction: column;
      align-items: stretch;
      gap: 0.45rem;
      margin-top: 0.25rem;
    }
    .hero-buttons .btn-primary,
    .hero-buttons .btn-ghost {
      width: 100%;
      justify-content: center;
      padding: 0.58rem 1rem;
      font-size: 0.68rem;
      letter-spacing: 0.08em;
    }
    /* Ghost button on mobile — always white border/text over media */
    .hero-buttons .btn-ghost {
      color: #fff;
      border-color: rgba(255,255,255,0.5);
    }
    .hero-buttons .btn-ghost:hover {
      background: #fff;
      color: var(--color-dark);
    }
    /* The post hero's subtitle is a trimmed excerpt (135 chars), which runs to
       three lines on a phone. With a five-line title above it the copy block
       reached 93% of the 520px hero — it fits, but a longer manually-set
       _ts_hero_subtitle would push the CTA out. Two lines keeps the headroom.
       Placed in the responsive layer deliberately: per the LAYER-TRAP note
       above, this layer wins, so a components-layer rule would not apply. */
    .post-big-hero .hero-subtitle {
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    /* CTA gets tighter too (its own padding overrides generic) */
    .cta-section {
      padding-top: clamp(3rem, 10vw, 5rem);
      padding-bottom: clamp(4rem, 10vw, 6rem);
    }
    /* Smaller star in CTA on mobile */
    .cta-section .cta-star {
      width: clamp(140px, 40vw, 220px);
    }
  }

  /* ----- 620px: group cards single-column ----- */
  @media (max-width: 620px) {
    .groups-grid { grid-template-columns: 1fr; }
  }

  /* ----- 560px: style grids single-column ----- */
  @media (max-width: 560px) {
    .styles-grid { grid-template-columns: 1fr; }
    /* v5.66 — variants defined late beat the base rule; phone = 1 col, final word */
    .styles-grid, .styles-grid--2col, .styles-grid--3col { grid-template-columns: 1fr; }
  }

  /* ----- 560px: v5.63b — team card emails wrapped mid-TLD in 2-col grid ----- */
  @media (max-width: 560px) {
    .team-card-email {
      font-size: 0.68rem;
      letter-spacing: 0;
      display: block;
      max-width: 100%;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .team-card-info { padding: 0.9rem 0.8rem 1rem; }
    .team-card-name { font-size: 0.98rem; }
    .team-card-role { font-size: 0.78rem; }
  }

  /* ----- 560px: v5.68 #6 — Sportlyzer breathing room on phones:
     frame goes near full-bleed ----- */
  @media (max-width: 560px) {
    .join-form-frame {
      margin-inline: -14px;
      padding: 0.75rem 0.6rem;
      border-radius: 16px;
    }
  }

  /* ----- 520px: v5.35 — weekday label is desktop furniture on the
     sched rows (prototype inline media, styles.css:4060) ----- */
  @media (max-width: 520px) {
    .sched-dow { display: none; }
  }

  /* ----- touch tier: section rail is desktop furniture (v5.0) ----- */
  @media (max-width: 900px), (hover: none) {
    .section-rail { display: none; }
  }

  /* ----- touch tier: heroes + CTA back to natural flow ----- */
  @media (max-width: 900px), (hover: none) {
    /* v5.2 — page hero compacts */
    .page-hero-video { height: max(64vh, 480px); min-height: 0; }
    /* …unless it has a portrait asset, which is the point of adding one: the
       compaction exists because a wide asset cover-cropped into a tall viewport
       loses most of the frame. Per-hero, unlike the slider, so no all-or-nothing
       condition. Portrait-only: a phone in landscape is on the wide asset and
       keeps the compacted height.

       The height comes from the ASSET's ratio, not the viewport, because 9:16
       (0.5625) is no longer the shape of a phone — an iPhone 14/15 is 390x844 =
       0.462. Measured on the Minnie poster: forcing 100svh cover-cropped 17.9%
       of its width away, 42px off each side, cutting the date and the URL baked
       into the artwork. Letting the ratio decide gives 693px here — 82% of the
       screen, nothing lost — while an asset that IS phone-shaped (1080x2340)
       hits max-height and fills the screen edge to edge. So a taller asset
       upgrades the layout on its own.

       min-height keeps a wide-ish tablet in portrait from collapsing the hero
       below what the compacted rule would have given it. */
    @media (orientation: portrait) {
      .page-hero-video.hero-has-portrait {
        /* Height is computed, NOT expressed as aspect-ratio.
           aspect-ratio looked equivalent and was not: with width:auto, the
           moment a height clamp made the height definite, Chrome resolved the
           WIDTH from that height through the ratio and the hero stopped filling
           the screen. Measured at 393x620 (a phone whose browser chrome eats
           enough svh for max-height to bind): width collapsed 393 -> 299px,
           23.9% short, leaving a white column down the right — 532 * 0.5625 =
           299.25, exactly the computed width. Doing the same arithmetic in
           calc() keeps width at 100% no matter which term wins.
           --hero-pw / --hero-ph are the asset's real pixel dimensions, set
           inline by ts_render_hero.

           Clears the header rather than running under it, so the cap is the
           screen MINUS the header. Measured on the Minnie poster at 430x932:
           starting at top 0 beneath the fixed opaque 88px header lost 107px of
           artwork — 13% — including the headroom the poster was composed with
           above its logo. 88px was the header; the rest came from the base
           scale(1.05), neutralised below.

           No min-height: it could only ever exceed the asset's own height,
           which would crop the very asset this exists to show whole. */
        width: 100%;
        margin-top: var(--header-h);
        height: min(
          calc(100vw * var(--hero-ph, 16) / var(--hero-pw, 9)),
          calc(100svh - var(--header-h))
        );
        max-height: none;
        min-height: 0;
      }
      /* (The matching header-clearance reset lives with the clearance rule
         further down — equal specificity means source order decides, so it has
         to come after it, not here.) */
      /* scale(1.05) on .hero-media is a safety margin so panning footage never
         shows an edge. A purpose-made portrait asset has no margin to spare —
         every pixel of it is composed. */
      .hero-has-portrait .hero-media { transform: none; }
    }
    /* v4.3 — full-height is a desktop staging choice */
    .cta-section { min-height: 0; display: block; }
    /* ---------- phone copy treatments (hero-mobile--*) ----------
       v5.63c drew the glass panel for every hero, which was right when the
       background was unpredictable footage: raw text over bright frames was
       unreadable. It is the wrong default over a 9:16 asset made for this
       screen — the panel covers the artwork that is the reason for the asset.
       The treatment is now chosen per hero; `glass` keeps the old behaviour.

       Shared: the phone drops the chips and the subtitle in every treatment.
       The category pills repeat what the headline says and cost the artwork a
       whole row; the subtitle is the auto-excerpt, which on a phone is a
       truncated first sentence carrying no information the title lacks. Both
       stay on desktop, where there is room for the hierarchy. ---------- */
    .post-big-hero .post-meta .post-chip,
    .post-big-hero .hero-subtitle { display: none; }
    /* Date keeps its place but loses the pill — the row is now one small line,
       set like the hero eyebrow it sits in for. */
    .post-big-hero .post-date {
      background: none;
      border: 0;
      padding: 0;
      font-size: 0.7rem;
      font-weight: 600;
      text-transform: uppercase;
      letter-spacing: 0.16em;
      color: rgba(255,255,255,0.82);
    }
    .post-big-hero .post-meta { margin-bottom: 0.15rem; }

    /* 1. Klaas — the original blurred card. */
    .page-hero-video.hero-mobile--glass .classes-hero-content {
      margin: 0 1rem;
      padding: 1.25rem 1.15rem 1.4rem;
      background: rgba(18, 8, 20, 0.55);
      -webkit-backdrop-filter: blur(16px) saturate(1.25);
      backdrop-filter: blur(16px) saturate(1.25);
      border: 1px solid rgba(255,255,255,0.10);
      border-radius: 18px;
    }
    @supports not (backdrop-filter: blur(1px)) {
      .page-hero-video.hero-mobile--glass .classes-hero-content { background: rgba(18, 8, 20, 0.82); }
    }

    /* 2. Varjund — no card at all. The copy drops to the bottom and the scheme's
       scrim is swapped for a bottom-up wash, so the top two thirds of the image
       are untouched. Same swap the fullband scrim already makes on phones (see
       .media-blend--clean below): a left-to-right gradient cannot support
       full-width lines. */
    .page-hero-video.hero-mobile--scrim { align-items: flex-end; }
    .page-hero-video.hero-mobile--scrim .classes-hero-scrim {
      background: linear-gradient(180deg, rgba(14,10,18,0) 34%, rgba(14,10,18,0.42) 62%, rgba(14,10,18,0.86) 100%);
    }
    .page-hero-video.hero-mobile--scrim .classes-hero-content {
      margin: 0 1.15rem 1.6rem;
      padding: 0;
      background: none;
      /* Panel scheme's box is not viewport scoped — its shadow would still
         draw around invisible copy. */
      border: 0;
      border-radius: 0;
      box-shadow: none;
      max-width: none;
      text-shadow: 0 1px 14px rgba(0,0,0,0.55);
    }

    /* 3. Riba — a band across the bottom, flush to the edges. Reads as a
       caption rather than a card, and leaves a clean rectangle of image above
       it with a hard edge instead of a soft blur. */
    .page-hero-video.hero-mobile--bar { align-items: flex-end; }
    .page-hero-video.hero-mobile--bar .classes-hero-scrim {
      background: linear-gradient(180deg, rgba(14,10,18,0) 55%, rgba(14,10,18,0.28) 100%);
    }
    .page-hero-video.hero-mobile--bar .classes-hero-content {
      margin: 0;
      width: 100%;
      max-width: none;
      padding: 1.1rem 1.15rem 1.3rem;
      background: rgba(14, 10, 18, 0.78);
      -webkit-backdrop-filter: blur(10px);
      backdrop-filter: blur(10px);
      border: 0;
      border-top: 1px solid rgba(255,255,255,0.12);
      /* The panel scheme styles .classes-hero-content and is not viewport
         scoped, so its rounded corners and drop shadow reached the band and made
         it read as a floating card again. */
      border-radius: 0;
      box-shadow: none;
    }

    /* 4. Minimaalne — title and button only, sitting on the image. Nothing
       between the reader and the artwork; the date goes too, since a bare date
       with no other chrome reads as a stray line. */
    .page-hero-video.hero-mobile--bare { align-items: flex-end; }
    .page-hero-video.hero-mobile--bare .classes-hero-scrim {
      background: linear-gradient(180deg, rgba(14,10,18,0) 46%, rgba(14,10,18,0.30) 72%, rgba(14,10,18,0.74) 100%);
    }
    .page-hero-video.hero-mobile--bare .classes-hero-content {
      margin: 0 1.15rem 1.7rem;
      padding: 0;
      background: none;
      gap: 0.85rem;
      /* Panel scheme's box is not viewport scoped — its shadow would still
         draw around invisible copy. */
      border: 0;
      border-radius: 0;
      box-shadow: none;
      max-width: none;
      text-shadow: 0 1px 16px rgba(0,0,0,0.6);
    }
    .page-hero-video.hero-mobile--bare .post-meta,
    .page-hero-video.hero-mobile--bare .post-back { display: none; }
    /* THEME FIX (2026-07-06, Edward's phone review) — the centered glass
       panel lands 2px under the fixed header at 375×812 and SLIDES BEHIND
       it on shorter viewports (480px hero, 340px panel → top 70px < 88px
       header) — measured identical in the prototype, which shipped this
       clearance only for blogpost-hero (v5.68). Extends the same
       treatment to every classes-hero page (about's hero has no panel —
       unaffected). Flex-centering uses the margin box, so the panel stays
       visually centered in the remaining space. (The v5.68 .post-big-hero
       clearance rule is therefore already covered by this one.)

       Scoped to the centred treatments. The other three sit at the bottom, so
       there is nothing to clear — and a top margin on a flex-end item still
       counts toward its margin box, which would push the copy off the bottom
       edge. */
    .page-hero-video.hero-mobile--glass .classes-hero-content,
    .page-hero-video:not([class*="hero-mobile--"]) .classes-hero-content {
      margin-top: calc(var(--header-h) + 0.9rem);
    }
    /* A portrait hero starts BELOW the header (margin-top: var(--header-h)
       above), so clearing it again here would push the panel down by a second
       header's worth. Must follow the rule it overrides: both are (0,3,0), so
       source order is what decides. */
    @media (orientation: portrait) {
      .page-hero-video.hero-has-portrait .classes-hero-content { margin-top: 0; }
    }

    /* v5.68 #1 — blogpost: 2.56:1 slider image became a thin
       heads-cropping strip; dark gap between title and image too tall */
    .post-header { padding-bottom: clamp(2.2rem, 5vh, 3rem); }
    /* v5.76: match the container to the 16:9 featured images (event promo
       banners have text baked to the edges — a 16:10 cover-crop clipped it
       on phones). 16:9 container + cover = zero crop, full poster shown. */
    .post-hero-img { margin-top: -1.4rem; aspect-ratio: 16 / 9; }
    .post-hero-img img { height: 100%; object-fit: cover; }
  }

  /* ----- touch tier: theatre + cutouts + tilt safety (v5.64b/v5.65) ----- */
  @media (max-width: 900px), (hover: none) {
    /* v5.6 — fullband back to natural height */
    .fullband-video { min-height: 0; padding-block: clamp(4rem, 10vw, 6rem); }
    /* #33b (2026-08-03): the --clean scrim is directional for desktop, where
       the copy is a 640px column on the left. On phones .fullband-content
       spans the full width, so a gradient that clears by 88% would leave the
       right end of every line unsupported. Swap to a vertical wash that still
       reads far truer than the old 0.33 tint (0.52–0.72 vs 0.88 flat). */
    .media-blend--clean .media-scrim {
      background: linear-gradient(180deg, rgba(18,16,22,0.52) 0%, rgba(18,16,22,0.62) 45%, rgba(18,16,22,0.72) 100%);
    }
    /* v5.9 — stage band back to natural height */
    .stage-section { min-height: 0; padding-block: clamp(4.5rem, 10vw, 6rem); }
    /* v5.64b — cinema full-height is a desktop staging choice */
    .cinema-section { min-height: 0; padding-block: clamp(2.5rem, 6vh, 4rem); }

    /* v5.65 — cutout photos: full content width, no float/rotate */
    .content-cutout--side,
    .content-cutout--wide {
      max-width: none;
      width: 100%;
      margin-inline: 0;
      align-self: stretch;
      animation: none;
      transform: none !important;
    }

    /* v5.65 — tilt safety net: no 3D transforms on touch cards
       (prototype-original !important — beats the JS inline transform) */
    .style-card { transform: none !important; }

    /* v5.65 — theatre: zoom the whole stage as ONE layer (.theatre-scale);
       clip aspect = room aspect (1.925) ÷ zoom (1.45) → full room height
       fits, only the sides crop away */
    .theatre-clip { overflow: hidden; border-radius: 14px; aspect-ratio: 1.328; }
    /* the desktop edge-fade mask swallowed the enlarged screen's top —
       the clip's rounded rectangle is the mobile edge treatment */
    .theatre-wrap {
      -webkit-mask-image: none;
      mask-image: none;
    }
    .theatre-wrap .cinema-sound:hover { transform: none; }
    .theatre-scale {
      position: absolute;
      top: 50%; left: 0; right: 0;
      transform: translateY(-50%) scale(1.45);
      transform-origin: 50% 50%;
    }
    .theatre-wrap .cinema-sound {
      position: static;
      display: flex;
      width: fit-content;
      max-width: 100%;
      margin: 1.2rem auto 0;
      padding: 0.5rem 1rem;
      font-size: 0.78rem;
      white-space: normal;
      text-align: center;
      transform: none;
      left: auto;
      bottom: auto;
    }
    .cinema-sound svg { width: 16px; height: 16px; }
  }

  /* ----- interaction tier: no custom cursor on touch ----- */
  @media (hover: none), (pointer: coarse) {
    .cursor-feather, .cursor-trail { display: none; }
  }

  /* ----- height tier: short laptop screens tighten event cards ----
     (v4.3 fit tuning — unscoped to .events-section in the prototype,
     so uudised/category grids get the same treatment; ported family-
     wide. The .events-section index-only rules of these v-blocks
     arrive with the front page.) ----- */
  @media (max-height: 960px) and (min-width: 901px) {
    .events-grid { gap: 1.25rem; }
    .event-card-image { aspect-ratio: 16/9; }
    .event-card-title,
    .event-card-excerpt {
      display: -webkit-box;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    .event-card-title { -webkit-line-clamp: 2; }
    .event-card-excerpt { -webkit-line-clamp: 2; }
  }

  /* ----- prefers-reduced-motion — always last ----- */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
    .marquee-track { animation: none; }
    .cursor-dot { display: none; }
    .program-card-bg,
    .hero-orbit-star,
    .cta-mesh { animation: none !important; }
    .kinetic-title .word { transform: none; opacity: 1; }
    /* v4 layer */
    .hero-media { transform: none; transition: none; }
    /* v5.15 */
    .kenburns-hero .hero-media { animation: none; }
    /* v5.16 */
    .content-cutout--side { animation: none; }
  }
}

/* ============================================================
   v5.71 (2026-07-06) — lastetants Lastetantsust three-row rhythm
   Row 1 text + curriculum card · Row 2 photo-band two-up ·
   Row 3 styles-grid--4col. Replaces extras-split/cutouts on
   this page (cutout CSS retained for reuse).
   ============================================================ */
@layer components {
  .photo-band {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.6rem;
    margin-top: 3.6rem;
  }
  .photo-band-item {
    margin: 0;
    border-radius: 22px;
    overflow: hidden;
    aspect-ratio: 3 / 2;
    background: #fff;
    box-shadow: 0 18px 44px rgba(15, 15, 20, 0.10);
  }
  .photo-band-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .styles-grid--4col {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-top: 3.6rem;
  }
}

@layer responsive {
  @media (max-width: 1100px) {
    .styles-grid--4col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (max-width: 760px) {
    .photo-band { gap: 1rem; margin-top: 2.6rem; }
    .styles-grid--4col { margin-top: 2.6rem; }
  }
  @media (max-width: 560px) {
    .photo-band { grid-template-columns: 1fr; }
    .styles-grid--4col { grid-template-columns: 1fr; }
  }
}

/* ============================================================
   v5.72 (2026-07-06) — gallery lightbox: click .post-gallery
   image → modal, prev/next, counter, swipe, ESC. Brand glass.
   ============================================================ */
@layer components {
  .post-gallery .pg-item img { cursor: zoom-in; }
  .lightbox {
    position: fixed;
    inset: 0;
    z-index: 300;
    display: grid;
    place-items: center;
    background: rgba(10, 10, 14, 0.92);
    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
  }
  .lightbox.is-open { opacity: 1; pointer-events: auto; }
  .lightbox-img {
    max-width: 88vw;
    max-height: 82vh;
    border-radius: 14px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
    transform: scale(0.96);
    transition: transform 0.25s ease;
    user-select: none;
  }
  .lightbox.is-open .lightbox-img { transform: scale(1); }
  .lightbox-btn {
    position: absolute;
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.22);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.2s ease, transform 0.2s ease;
  }
  .lightbox-btn:hover { background: rgba(255, 255, 255, 0.18); transform: scale(1.06); }
  .lightbox-close { top: 1.2rem; right: 1.2rem; }
  .lightbox-prev { left: 1.2rem; top: 50%; translate: 0 -50%; }
  .lightbox-next { right: 1.2rem; top: 50%; translate: 0 -50%; }
  .lightbox-counter {
    position: absolute;
    bottom: 1.4rem;
    left: 50%;
    translate: -50% 0;
    padding: 0.35rem 0.95rem;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-family: 'Exo', sans-serif;
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.06em;
  }
}

@layer responsive {
  @media (max-width: 640px) {
    .lightbox-img { max-width: 94vw; max-height: 76vh; border-radius: 10px; }
    .lightbox-btn { width: 44px; height: 44px; }
    .lightbox-prev { left: 0.5rem; }
    .lightbox-next { right: 0.5rem; }
    .lightbox-close { top: 0.7rem; right: 0.7rem; }
  }
}

/* v5.73 (2026-07-06) — post-content star-lists match body size
   (16px was the card-context size; inconsistent in article flow) */
@layer integrations {
  .post-content .star-list li { font-size: 1.05rem; }
}

/* v5.74 (2026-07-06) — lead paragraph aligned with body text
   (Edward: uniform paragraph scale in posts) */
@layer integrations {
  .post-lead { font-size: 1.05rem; line-height: 1.7; }
}

/* v5.75 (2026-07-06) — post bottom rhythm rule: content end → "Loe veel"
   = article pb (80) + related mt (48) = 128px, nothing else.
   WP autop generates empty <p> around HTML blocks (~86px of ghost
   space measured on naidis-uudis-1); last content block keeps its
   own bottom margin out of the equation. */
@layer integrations {
  .post-content > p:empty { display: none; }
  .post-content > :last-child { margin-bottom: 0; }
}

/* v5.75b — content→"Loe veel" gap rule: content article pb (80) +
   related wrapper pt (48) = 128px. The 48 lives as PADDING inside the
   related wrapper — as a child margin it collapses through the section
   edge and exposes a white body strip between the two grey articles. */
@layer integrations {
  .post-section--related { padding-top: 48px; }
  .post-section--related .post-related { margin-top: 0; }
}

/* ================================================================
   FRONT PAGE (avaleht) — index-only components (2026-07-07)
   Ported from Design/v4/index.html + styles.css. The prototype is
   flat CSS with interspersed @media; here desktop rules → components
   / pages, ALL @media → responsive (component-inventory §9). Shared
   families already ported (hero atoms, .hero-media, .hero-bottom-curve,
   .section-rail both modes, .cta-section, .media-blend/.panel-media,
   .event-card/.events-grid, .panel-wave/.panel-bottom-curve) are NOT
   repeated — only the index-only pieces live here.

   Program panels are ported in their FINAL computed state: the v4.1
   review fix (styles.css ~2014-2058) dropped the wave-clip masks for
   clean straight edges + straight gradient panel-wave lines, so the
   earlier wave-mask complexity is intentionally NOT ported (porting
   lessons #2, #11 — port the intent/final value, not a superseded
   cascade state; matches how the theme already handles hero-bottom-curve).
   ================================================================ */

/* @keyframes sit OUTSIDE @layer (unaffected by layer order — §9 rule 2).
   btnPulse/heroPanelIn/kenburns already exist; add the index-only three. */
@keyframes orbit {
  from { transform: translateY(-50%) rotate(0deg); }
  to   { transform: translateY(-50%) rotate(360deg); }
}
@keyframes hintFloat {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 7px); }
}
@keyframes hintPulse {
  0%   { transform: scale(1); opacity: 0.8; }
  70%  { transform: scale(1.6); opacity: 0; }
  100% { transform: scale(1.6); opacity: 0; }
}
/* #about kinetic-title decorative star (styles.css ~583) — WITHOUT this,
   the <svg class="sparkle" viewBox="0 0 24 24"> has no CSS size and
   expands to fill its grid column (~528px) with fill=currentColor
   inheriting the dark heading colour → a giant black star (Edward's
   2026-07-07 review). The rule sizes it to 0.8em, tints it brand pink,
   and spins it. */
@keyframes sparkleSpin {
  0%,100% { transform: rotate(0deg) scale(1); opacity: 1; }
  50%     { transform: rotate(180deg) scale(1.15); opacity: 0.7; }
}

@layer components {
  /* ---------- #14 section-heading: kinetic-title decorative star ---------- */
  .sparkle {
    display: inline-block;
    vertical-align: middle;
    width: 0.8em; height: 0.8em;
    color: var(--color-pink);
    margin-left: 0.15em;
    animation: sparkleSpin 6s linear infinite;
  }
  /* ---------- #9 hero-swiper (index-only) ----------
     Base .hero shell + swiper slider chrome. Hero copy atoms
     (.hero-eyebrow/-title/-subtitle/-buttons) + .hero-media already
     ported with #10; the .swiper-slide-active reveal rules + slider
     chrome ship here (component-inventory §9 note). Height is the v4.3
     full-viewport value (100svh); the mobile height override → responsive. */
  .hero {
    position: relative;
    background: var(--color-dark);
    overflow: hidden;
    padding: 0; /* override generic section padding */
  }
  .hero-swiper {
    height: 100vh;
    height: 100svh;
    min-height: 620px;
  }
  .hero-slide { position: relative; overflow: hidden; }
  /* The three front-page slide scrims, defined once. The post-hero schemes
     .page-hero--slide-* read these same custom properties rather than copying
     the values, so "täpselt nagu esilehe hero" is structurally true: a change
     here moves the slider and the matching post scheme together, and the two
     cannot drift apart the way the hand-copied versions already had. */
  :root {
    /* Strong on the left for legible text, then clears fast so the footage /
       products keep full contrast on the right (kills the mid veil). */
    --scrim-slide-dark:  linear-gradient(90deg, rgba(28,28,28,0.9) 0%, rgba(28,28,28,0.52) 30%, rgba(28,28,28,0.14) 60%, rgba(28,28,28,0) 84%);
    --scrim-slide-light: linear-gradient(90deg, rgba(255,255,255,0.75) 0%, rgba(255,255,255,0.35) 45%, rgba(255,255,255,0.05) 100%);
    --scrim-slide-red:   linear-gradient(90deg, rgba(100,0,20,0.75) 0%, rgba(100,0,20,0.4) 45%, rgba(100,0,20,0.1) 100%);
  }
  .hero-slide--dark .hero-slide-overlay  { background: var(--scrim-slide-dark); }
  .hero-slide--light .hero-slide-overlay { background: var(--scrim-slide-light); }
  .hero-slide--red .hero-slide-overlay   { background: var(--scrim-slide-red); }

  /* panel + bottom are offered on the same Skeem dropdown as the slides, so a
     slider hero can be set to either. Without these the overlay would fall
     back to no background at all — .hero-slide-overlay only sets position —
     leaving copy on raw footage with no scrim. */
  .hero-slide--panel .hero-slide-overlay {
    background: linear-gradient(90deg, rgba(28,28,28,0.55) 0%, rgba(28,28,28,0.3) 55%, rgba(28,28,28,0.12) 100%);
  }
  .hero-slide--panel .hero-content > * { max-width: none; }
  .hero-slide--panel .hero-content {
    max-width: min(760px, 100%);
    margin-inline: 0;
    align-self: center;
    background: rgba(20, 14, 22, 0.9);
    backdrop-filter: blur(3px);
    border-radius: 20px;
    padding: clamp(1.5rem, 3vw, 2.4rem) clamp(1.5rem, 3vw, 2.6rem);
    box-shadow: 0 24px 60px -24px rgba(0,0,0,0.55);
  }
  .hero-slide--bottom .hero-slide-overlay {
    background: linear-gradient(0deg, rgba(28,28,28,0.92) 0%, rgba(28,28,28,0.72) 30%, rgba(28,28,28,0.28) 62%, rgba(28,28,28,0.05) 100%);
  }
  .hero-slide--bottom .hero-content { justify-content: flex-end; }
  /* hero content block spans the container; text stays narrow inside
     (v4.1 review fix — matches .container max-width 1200px) */
  .hero-content {
    position: relative; z-index: 2;
    width: 100%;
    max-width: 1200px;
    margin-inline: auto;
    padding: calc(var(--header-h) + 1rem) clamp(1.5rem, 5vw, 4rem) clamp(2rem, 6vw, 4rem);
    height: 100%;
    display: flex; flex-direction: column; justify-content: center;
    gap: 1rem;
  }
  .hero-content > * { max-width: 580px; }
  .hero-slide--light .hero-eyebrow { color: var(--color-pink); }
  .hero-slide--light .hero-title { color: var(--color-dark); }
  .hero-slide--light .hero-subtitle { color: var(--color-dark); }
  /* Swiper slide-active reveals (index only — the atoms rest hidden,
     the active slide plays them in) */
  .swiper-slide-active .hero-eyebrow,
  .swiper-slide-active .hero-subtitle,
  .swiper-slide-active .hero-buttons { opacity: 1; transform: translateY(0); }
  .swiper-slide-active .hero-title { clip-path: inset(0 0 0 0); }
  .swiper-slide-active .hero-media { transform: scale(1); }
  /* Orbiting decorative star behind hero content */
  .hero-orbit-star {
    position: absolute;
    top: 50%; left: -4%;
    transform: translateY(-50%);
    width: clamp(320px, 34vw, 520px);
    height: auto;
    opacity: 0.14;
    pointer-events: none;
    z-index: 1;
    animation: orbit 40s linear infinite;
    mix-blend-mode: screen;
  }
  /* Swiper pagination: dash/pill style, lifted above the wave curve */
  .hero-swiper .swiper-pagination {
    bottom: 6.5rem !important;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.6rem;
  }
  .hero-swiper .swiper-pagination-bullet {
    width: 22px;
    height: 3px;
    border-radius: 2px;
    background: rgba(255,255,255,0.45);
    opacity: 1;
    margin: 0 !important;
    transition: width 0.45s var(--ease-spring), background 0.3s ease, box-shadow 0.3s ease;
    cursor: pointer;
  }
  .hero-swiper .swiper-pagination-bullet:hover {
    background: rgba(255,255,255,0.75);
  }
  .hero-swiper .swiper-pagination-bullet-active {
    width: 48px;
    background: var(--color-yellow);
    box-shadow: 0 0 12px rgba(255,185,4,0.55);
  }

  /* ---------- #29 about-collage (index) ---------- */
  .about-collage {
    position: relative;
    aspect-ratio: 4/5;
    max-height: 560px;
  }
  .collage-tile {
    position: absolute;
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 30px 60px -20px rgba(28,28,28,0.3);
    will-change: transform;
  }
  .collage-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .collage-tile--main { top: 0; right: 0; width: 86%; height: 78%; }
  .collage-tile--accent {
    left: 0; bottom: 4%;
    width: 48%; height: 52%;
    border: 6px solid #fff;
    border-radius: 20px;
  }
  .collage-star {
    position: absolute;
    top: -26px; left: 58%;
    width: 52px; height: 52px;
    transform: rotate(-12deg);
  }

  /* ---------- #30 stats-band (index) ---------- */
  .dark-section-waves { position: absolute; inset: 0; opacity: 0.8; pointer-events: none; z-index: 1; }
  .dark-section-waves svg { width: 100%; height: 100%; }
  /* ---------- #30–#32 → programme cards (index, 6 Aug 2026) ----------
     Three blocks lived here: #30 stats-band KPIs, #31 program-shortcut jump
     pills, #32 the 300vh sticky programme showcase. All three staged the
     section-locked scroll that was removed on launch day, and free-scrolled
     sticky panels could rest half-covered. Replaced by one row of three
     cards inside #programsIntro — the framed-media treatment the mobile
     tier already used, on every tier (prototype:
     Design/v4/index-programs-cards.html). The KPI row was dropped on
     Edward's call the same evening — it crowded the merged screen.

     .panel-progress and .panel-index survive from the panels: the cards
     kept the star row, and its geometry never depended on the showcase.
     .media-blend--* tints (#33) are shared with two subpages and live on. */
  .panel-progress { display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.4rem; }
  .panel-progress svg { width: 13px; height: 13px; fill: rgba(255,255,255,0.32); transition: fill 0.4s ease; }
  .panel-progress svg.is-active { width: 19px; height: 19px; }
  .panel-index {
    margin-left: 0.6rem;
    font-size: 0.78rem;
    letter-spacing: 0.28em;
    color: rgba(255,255,255,0.55);
  }

  .pcards-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 3rem;
    max-width: 560px;
    margin-inline: auto;
    position: relative; z-index: 2; /* above .dark-section-waves, like the copy */
  }
  @media (min-width: 1024px) {
    .pcards-grid {
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: clamp(1.5rem, 2.6vw, 2.5rem);
      max-width: none;
      margin-inline: 0;
    }
  }
  .pcard { display: flex; flex-direction: column; }
  .pcard-media {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: 18px;
    overflow: hidden;
    margin-bottom: 1.35rem;
    transform: translateZ(0); /* keep the radius clipping the video on WebKit */
  }
  .pcard-media .panel-media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  /* softer scrim than the panels had: the media is framed and the text sits
     below it, so the video only needs settling at its foot, not legibility
     cover — .media-scrim's heavy left gradient existed for text-over-video */
  .pcard-scrim {
    position: absolute; inset: 0;
    background: linear-gradient(180deg, transparent 55%, rgba(28,28,28,0.45) 100%);
  }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .pcard-media { transition: transform 0.45s cubic-bezier(0.22, 0.8, 0.3, 1), box-shadow 0.45s ease; }
    .pcard:hover .pcard-media {
      transform: translateY(-6px);
      box-shadow: 0 22px 44px -20px rgba(0, 0, 0, 0.6);
    }
  }
  .pcard-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.7rem;
    color: #fff;
    flex: 1; /* with the auto margin below, the three CTAs share a baseline
                even though the descriptions run different lengths */
  }
  .pcard .panel-progress { margin-bottom: 0; }
  .pcard .panel-progress svg { fill: rgba(255, 255, 255, 0.28); }
  .pcard--orange .panel-progress svg.is-active { fill: var(--color-orange); }
  .pcard--pink   .panel-progress svg.is-active { fill: var(--color-pink); }
  .pcard--yellow .panel-progress svg.is-active { fill: var(--color-yellow); }
  .pcard-label {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
  }
  /* same accent tones the panel labels used (yellow follows the join-chip tone) */
  .pcard--orange .pcard-label { color: #FFB370; }
  .pcard--pink   .pcard-label { color: #FF8FC8; }
  .pcard--yellow .pcard-label { color: #FFDD87; }
  .pcard-title {
    font-family: 'Baumans', cursive;
    font-size: clamp(1.5rem, 1.75vw, 1.85rem);
    line-height: 1.12;
    letter-spacing: 0.02em;
    color: #fff;
    margin: 0;
  }
  .pcard-text {
    font-size: 0.95rem;
    line-height: 1.65;
    color: rgba(255, 255, 255, 0.78);
    /* fixed floor between text and CTA — the auto margin below only ever ADDS
       to this on the shorter cards */
    margin: 0 0 0.9rem;
  }
  .pcard .btn-primary { margin-top: auto; }
  /* straight gradient seam into the light Events section — the separator
     language that replaced the wave curves; the showcase's bottom curve
     carried this job before */
  .pcards-sep {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 5px;
    background: linear-gradient(90deg, #F80086 0%, #FF6500 50%, #FFB904 100%);
    z-index: 3;
  }

  /* ---------- #8 scroll-hint (index only) ---------- */
  .scroll-hint {
    position: fixed;
    left: 50%; bottom: 26px;
    z-index: 60;
    width: 48px; height: 48px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.35);
    background: rgba(28,28,28,0.35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    cursor: pointer;
    display: grid;
    place-items: center;
    padding: 0;
    transition: opacity 0.4s ease, border-color 0.3s ease, background 0.3s ease;
    animation: hintFloat 2.6s ease-in-out infinite;
  }
  .scroll-hint::before {
    content: '';
    position: absolute; inset: -1px;
    border-radius: 50%;
    border: 1px solid rgba(255,185,4,0.65);
    animation: hintPulse 2.6s ease-out infinite;
    pointer-events: none;
  }
  .scroll-hint svg { width: 18px; height: 18px; display: block; }
  .scroll-hint:hover {
    border-color: var(--color-yellow);
    background: rgba(28,28,28,0.6);
    color: var(--color-yellow);
  }
  .scroll-hint.is-hidden { opacity: 0; pointer-events: none; }

  /* ---------- events header row (index): title left, "Kõik uudised" right ---------- */
  .events-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2rem;
  }
  .events-head .section-subtitle { margin-bottom: 0; }
  .events-all-link { flex-shrink: 0; margin-bottom: 0.4rem; }
}

@layer pages {
  /* ---------- About section (index) — base + v4.3 full-height ---------- */
  .about-section {
    background: var(--color-light-2);
    position: relative;
    overflow: hidden;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
  }
  .about-section::before {
    content: '';
    position: absolute;
    top: -120px; right: -120px;
    width: 380px; height: 380px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(248,0,134,0.1) 0%, transparent 70%);
    pointer-events: none;
  }
  .about-section > .container { width: 100%; }
  .about-grid {
    display: grid; gap: clamp(2rem, 5vw, 4rem);
    grid-template-columns: 1.1fr 1fr;
    align-items: center;
  }
  .about-text p { margin-block: 1rem; }

  /* ---------- Stats + programs intro (index) — v4.3 full-height dark ---------- */
  .stats-intro-section {
    background: var(--color-dark);
    color: #fff;
    position: relative;
    overflow: hidden;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
    /* 6 Aug 2026 — the programme cards moved into this section, and the
       one-screen fit is measured, not hoped for: 963px against an 860px
       viewport before these two changes, ~848px after. Padding trimmed the
       way About and Events already were, and the subtitle runs wider so it
       wraps to 2 lines instead of 4. */
    padding-block: clamp(2.25rem, 4.5vh, 3.5rem);
  }
  .stats-intro-inner {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* was clamp(3.5rem, 10vh, 8rem) — rhythm for three sparse blocks (KPIs,
       copy, shortcut pills) spread down a screen. With the copy sitting
       directly above the card row, that much air read as two strangers. */
    gap: clamp(2.25rem, 5vh, 3.5rem);
    position: relative;
    z-index: 2;
  }
  .stats-intro-section .section-title { color: #fff; }
  .stats-intro-section .section-subtitle { color: rgba(255,255,255,0.72); }
  .stats-intro-section .section-subtitle--center { max-width: 56rem; margin-bottom: 0; }

  /* ---------- Events section (index) — v4.3 full-height ---------- */
  .events-section {
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
  }
  .events-section > .container { width: 100%; }
}

@layer responsive {
  /* ===== FRONT PAGE @media — prototype source order (§9 rule 4) ===== */

  /* about-grid collapse (820) */
  @media (max-width: 820px) {
    .about-grid { grid-template-columns: 1fr; }
    .about-collage { aspect-ratio: 4/3; max-height: 420px; }
  }

  /* events-grid staggered offsets (desktop) + collapses */
  @media (min-width: 981px) {
    .events-grid .event-card:nth-child(2) { transform: translateY(2.5rem); }
    .events-grid .event-card:nth-child(3) { transform: translateY(5rem); }
  }
  @media (max-width: 980px) { .events-grid { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 640px) { .events-grid { grid-template-columns: 1fr; } }

  /* The stats-grid 2-col collapse and the sticky-panel → stacked-card mobile
     restyles stood here until 6 Aug 2026 — their DOM (KPI row, programme
     panels) left with the card-row rework. The pcards-grid is mobile-first,
     so it needs no collapse rule at all. */

  /* v4.3 full-height system — mobile/touch: natural scroll, no forced heights */
  @media (max-width: 900px), (hover: none) {
    .hero-swiper { height: max(72vh, 620px); }
    /* A slider whose every slide carries a 9:16 asset gets the same treatment as
       a portrait post hero: height from the asset, capped at the screen minus
       the header, never from aspect-ratio — see the note on the post hero rule
       for why that shrank the width. front-page.php decides the all-slides
       condition and picks the binding asset, since the container sizes every
       slide together. Scoped to portrait so a phone held sideways — a wide
       viewport on the wide asset — keeps the compacted height.

       margin-top clears the fixed opaque header. Measured on the live front page
       at 375x667: the slide media sat 64px behind it. That costs nothing while a
       wide asset is being cover-cropped, but hides the top of a composed 9:16
       frame — the same 88px that was cutting the Minnie poster.

       The selector is doubled for specificity, not for looks: a later
       `.hero-swiper` height lives in the 640px block further down, and at equal
       specificity source order hands it the win. It did — 620px instead of
       699px, and the number looked plausible because its `max(68vh, 560px)`
       resolves against the LARGE viewport (912px here) rather than the 852px
       visual one. (0,2,0) settles it wherever the rule sits in the file. */
    @media (orientation: portrait) {
      .hero-swiper.hero-swiper--portrait {
        width: 100%;
        margin-top: var(--header-h);
        height: min(
          calc(100vw * var(--hero-ph, 16) / var(--hero-pw, 9)),
          calc(100svh - var(--header-h))
        );
      }
      .hero-swiper--portrait .hero-media { transform: none; }
      /* The slide's own copy padding assumes the media runs under the header. */
      .hero-swiper--portrait .hero-content { padding-top: 1rem; }
    }
    .about-section,
    .stats-intro-section,
    .events-section,
    .cta-section { min-height: 0; display: block; }
    .stats-intro-inner { gap: 3rem; }
  }

  /* v4.3 fit tuning — make About + Events genuinely fit one viewport (desktop) */
  @media (min-width: 901px) and (hover: hover) {
    .about-section, .events-section { padding-block: clamp(2.5rem, 5vh, 5rem); }
    .about-collage { max-height: min(58vh, 560px); }
    .events-section .section-subtitle { margin-bottom: 0.5rem; }
    .events-grid { margin-top: clamp(1.5rem, 3.5vh, 3rem); }
  }
  /* v4.3 fit #3 — top-anchored full-height sections clear the fixed header */
  @media (min-width: 901px) and (hover: hover) {
    .events-section { padding-block: calc(var(--header-h) + 0.5rem) clamp(1.5rem, 3vh, 3rem); }
    .events-section .section-subtitle { margin-bottom: 0; }
  }
  /* Short laptop screens: tighten Events so it fits one viewport */
  @media (max-height: 960px) and (min-width: 901px) {
    .events-grid { gap: 1.25rem; }
    .event-card-image { aspect-ratio: 16/9; }
    .events-section .section-subtitle { margin-bottom: 0; }
    .events-section { padding-block: clamp(4rem, 6vh, 5rem); }
    .event-card-title,
    .event-card-excerpt {
      display: -webkit-box;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    .event-card-title { -webkit-line-clamp: 2; }
    .event-card-excerpt { -webkit-line-clamp: 2; }
    .events-section .section-title { font-size: clamp(1.8rem, 3.2vw, 2.4rem); }
  }

  /* v4.4 — footer as full-height section (index/.fullpage only) */
  @media (min-width: 901px) and (hover: hover) {
    .fullpage .site-footer {
      min-height: 100vh;
      min-height: 100svh;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    .fullpage .site-footer > .container { width: 100%; }
  }

  /* 6 Aug 2026 — CSS scroll-snap was shipped here to replace the JS wheel
     hijack, and REVERTED minutes later. Do not restore it in that form.

     What was tried: `scroll-snap-type: y mandatory` on html (via :has(), since
     `fullpage` is a body class and snap must sit on the scroll container), with
     `scroll-snap-align: start` on the index's nine viewport-height screens —
     hero, about, programsIntro, the three programme panels, events, cta,
     footer. Nine × 860px against a 7740px document, so no snap area exceeded
     the viewport, which is normally the one thing that makes `mandatory` unsafe.

     Why it failed: three of those nine screens are the `position: sticky`
     panels, and a stuck sticky element's snap area travels with the viewport.
     `mandatory` therefore reads any position inside the track as already
     snapped and refuses to leave it. The live index froze at the top of the
     track — no scrolling up or down.

     Why the probe missed it: it only ever scrolled *into* the track, where the
     next panel is not yet stuck, so snapping looked correct. It never tried
     scrolling back out, which is the case that hangs.

     If this is attempted again: snap targets must be elements that do not move,
     e.g. non-sticky markers at each panel's flow position inside the track, and
     it must be tested in both directions — including scrolling out of the track
     and back to the top — before shipping. */

  /* scroll-hint + events-head mobile (the program-shortcuts collapse that
     shared this block left with the pills, 6 Aug 2026) */
  @media (max-width: 900px), (hover: none) { .scroll-hint { display: none; } }
  @media (max-width: 900px), (hover: none) {
    .events-head { flex-direction: column; align-items: flex-start; }
    .events-all-link { margin-bottom: 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .scroll-hint, .scroll-hint::before { animation: none; }
    .hero-orbit-star { animation: none; }
    .collage-tile { will-change: auto; }
  }

  /* ---- Mobile hero glass panel (640) — heavily tuned mobile round ---- */
  @media (max-width: 640px) {
    .hero-swiper { height: max(68vh, 560px); }
    /* Soft bottom scrim helps the glass panel sit cleanly.
       SCOPED to .hero-slide (2026-08-04). Page and post heroes put
       .hero-slide-overlay and .classes-hero-scrim on the SAME element, so this
       unscoped !important was repainting their scrim too — every Skeem choice
       (dark / panel / bottom / slide-*) was silently inert below 640px, which is
       most phones. Only the panel scheme still looked right there, and only
       because its opaque box lives on .classes-hero-content rather than the
       scrim. The !important is dropped with the scoping: this sits in @layer
       responsive, which already beats the components-layer .hero-slide--*
       rules regardless of specificity (§9 rule 3 bans !important for ordering). */
    .hero-slide .hero-slide-overlay {
      background: linear-gradient(180deg,
        rgba(28,28,28,0.2) 0%,
        transparent 30%,
        transparent 50%,
        rgba(28,28,28,0.35) 100%);
    }
    /* Space the bottom-anchored treatments must leave clear: the 90px bottom
       curve plus the pagination strip, which sits ~112px above the slide's
       bottom edge (measured at 393x852; it is positioned independently of the
       curve, so the curve height alone is not enough — 90px + 0.4rem left the
       buttons 16px into the dots). Named once so the three treatments cannot
       drift apart. */
    .hero-slide .hero-content { --hero-copy-reserve: calc(90px + 2.25rem); }

    /* Content becomes a positioned glass panel at the bottom.
       The four hero-mobile--* treatments the post heroes gained now apply here
       too, chosen per SLIDE (only the height is shared — see the swiper rule).
       This one is `glass`, the original; the :not() keeps a slide rendered
       before the class existed looking exactly as it did. All four share the
       absolute positioning, so it stays on the base selector below. */
    .hero-content {
      position: absolute;
      left: 1rem;
      right: 1rem;
      bottom: calc(90px + 0.75rem);
      top: auto;
      height: auto;
      max-width: none;
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }
    .hero-slide.hero-mobile--glass .hero-content,
    .hero-slide:not([class*="hero-mobile--"]) .hero-content {
      padding: 1rem 1.1rem 1.1rem;
      background: rgba(18, 8, 20, 0.55);
      -webkit-backdrop-filter: blur(16px) saturate(1.25);
      backdrop-filter: blur(16px) saturate(1.25);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 18px;
      box-shadow: 0 12px 32px rgba(0,0,0,0.35);
    }
    @supports not (backdrop-filter: blur(1px)) {
      .hero-slide.hero-mobile--glass .hero-content,
      .hero-slide:not([class*="hero-mobile--"]) .hero-content { background: rgba(18, 8, 20, 0.82); }
    }

    /* Varjund — no card; a bottom-up wash on the slide's own overlay carries the
       copy instead. Overrides the shared mobile slider scrim above, so it has to
       come after it. */
    .hero-slide.hero-mobile--scrim .hero-slide-overlay {
      background: linear-gradient(180deg, rgba(14,10,18,0) 34%, rgba(14,10,18,0.42) 62%, rgba(14,10,18,0.86) 100%);
    }
    /* Anchored at the bottom with the pagination strip RESERVED in the padding,
       the way the bar treatment does it. Offsetting `bottom` instead left the
       buttons 26px into the dots: with padding:0 the box hugs the copy, and the
       reveal transform on .hero-buttons pushes the last button past the box's
       own edge, so any offset tuned to the box is short by that much. */
    .hero-slide.hero-mobile--scrim .hero-content {
      left: 1.15rem;
      right: 1.15rem;
      bottom: 0;
      padding: 0 0 var(--hero-copy-reserve);
      background: none;
      border: 0;
      box-shadow: none;
      text-shadow: 0 1px 14px rgba(0,0,0,0.55);
    }

    /* Riba — a band flush to the edges. Sits above the pagination rather than
       floating clear of it, so the image keeps a clean rectangle. */
    .hero-slide.hero-mobile--bar .hero-slide-overlay {
      background: linear-gradient(180deg, rgba(14,10,18,0) 55%, rgba(14,10,18,0.28) 100%);
    }
    .hero-slide.hero-mobile--bar .hero-content {
      left: 0;
      right: 0;
      bottom: 0;
      padding: 1.1rem 1.15rem var(--hero-copy-reserve);
      background: rgba(14, 10, 18, 0.78);
      -webkit-backdrop-filter: blur(10px);
      backdrop-filter: blur(10px);
      border: 0;
      border-top: 1px solid rgba(255,255,255,0.12);
      border-radius: 0;
      box-shadow: none;
    }

    /* Minimaalne — title and buttons on the image, nothing between. */
    .hero-slide.hero-mobile--bare .hero-slide-overlay {
      background: linear-gradient(180deg, rgba(14,10,18,0) 46%, rgba(14,10,18,0.30) 72%, rgba(14,10,18,0.74) 100%);
    }
    .hero-slide.hero-mobile--bare .hero-content {
      left: 1.15rem;
      right: 1.15rem;
      bottom: 0;
      padding: 0 0 var(--hero-copy-reserve);
      background: none;
      border: 0;
      box-shadow: none;
      gap: 0.85rem;
      text-shadow: 0 1px 16px rgba(0,0,0,0.6);
    }
    .hero-slide.hero-mobile--bare .hero-eyebrow,
    .hero-slide.hero-mobile--bare .hero-subtitle { display: none; }
    /* Light-slide text override: always white-on-glass for consistency */
    .hero-slide--light .hero-eyebrow { color: var(--color-yellow); }
    .hero-slide--light .hero-title { color: var(--color-yellow); }
    .hero-slide--light .hero-subtitle { color: #fff; }
    /* Buttons stack full-width inside the glass panel */
    .hero-buttons {
      flex-direction: column;
      align-items: stretch;
      gap: 0.45rem;
      margin-top: 0.25rem;
    }
    .hero-buttons .btn-primary,
    .hero-buttons .btn-ghost {
      width: 100%;
      justify-content: center;
      padding: 0.58rem 1rem;
      font-size: 0.68rem;
      letter-spacing: 0.08em;
    }
    .hero-buttons .btn-ghost {
      color: #fff;
      border-color: rgba(255,255,255,0.5);
    }
    .hero-buttons .btn-ghost:hover {
      background: #fff;
      color: var(--color-dark);
    }
    /* Pagination at top (under header) since text now sits in the panel */
    .hero-swiper .swiper-pagination {
      bottom: auto !important;
      top: calc(var(--header-h) + 1rem) !important;
    }
    /* Hide oversized decorative blob on narrow viewports */
    .about-section::before { display: none; }
  }

  /* ---- v5.63 MOBILE ROUND: index fixes (later source order wins) ---- */
  @media (max-width: 900px), (hover: none) {
    /* 1. hero glass panel: symmetric 1rem insets (a later width:100%
       rule pushed it past the right edge) */
    .hero-content { width: auto; }
    /* 2. video slide 16:9 footage framing nudge (portrait 9:16 cut later) */
    .hero-media--pos-left { object-position: 26% center; }
    /* 4. (retired 6 Aug 2026) the program-panel framed-media mobile restyle
       stood here — it is the treatment the .pcard block now applies on every
       tier, so when the panels became cards this became the whole design
       rather than a mobile override. */
  }
}

/* ============================================================
   v5.77 (2026-07-08) — /uudised/ listing: two within-cascade
   order-traps (porting lesson #2/#11). Placed last in the
   responsive layer + compound specificity → wins both ways.
   1) Filtered/paginated cards must hide: `.news-grid .event-card
      {display:flex}` (pages layer) was beating `.event-card
      .is-filtered{display:none}` (components layer) by LAYER order.
   2) The listing must NOT inherit the homepage .events-grid
      diagonal stagger (nth-child translateY) — it pushed card 3
      down 5rem into row 2 (the overlap Edward saw).
   ============================================================ */
@layer responsive {
  .news-grid .event-card.is-filtered { display: none; }
  .news-grid.events-grid .event-card,
  .news-grid.events-grid .event-card:nth-child(2),
  .news-grid.events-grid .event-card:nth-child(3) { transform: none; }
  .news-grid.events-grid .event-card:hover,
  .news-grid.events-grid .event-card:nth-child(2):hover,
  .news-grid.events-grid .event-card:nth-child(3):hover { transform: translateY(-8px) rotate(-0.5deg); }
}

/* ============================================================
   Phase 4 (v6.0) — E-POOD / shop system
   Ported from Design/v4/styles.css v592 (shop grid, product detail,
   cart drawer, checkout). Reuses existing filter-pill / type-chip /
   class-note / star-list (already in theme). Base rules -> pages layer,
   media queries -> responsive layer (per @layer architecture).
   ============================================================ */
@layer pages {
  /* --- Header cart button (shop pages) --- */
  .header-cart {
    position: relative; display: inline-grid; place-items: center;
    flex: 0 0 42px; width: 42px; height: 42px; aspect-ratio: 1; box-sizing: border-box;
    align-self: center; border: none; border-radius: 50%;
    background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.85);
    cursor: pointer; transition: background 0.3s ease, color 0.3s ease;
    margin-right: 0.6rem;
  }
  .header-cart:hover { background: rgba(255,255,255,0.16); color: #fff; }
  .header-cart svg { width: 20px; height: 20px; }
  .header-cart-badge {
    position: absolute; top: -3px; right: -4px; min-width: 18px; height: 18px;
    padding: 0 4px; border-radius: 999px; background: var(--color-yellow);
    color: var(--color-dark); font-size: 0.68rem; font-weight: 700;
    display: grid; place-items: center;
  }
  .header-cart-badge:empty, .header-cart-badge[data-count="0"] { display: none; }
  /* header density so the cart button fits without spilling the nav */
  .main-nav a { white-space: nowrap; }
  .header-cta { white-space: nowrap; }

  /* --- Shop listing (epood) --- */
  .shop-section { padding: clamp(2.5rem, 5vh, 3.5rem) 0 clamp(2rem, 4vh, 3rem); }
  .shop-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.2rem, 2.5vw, 2rem); margin-top: 2.2rem; }
  .shop-card {
    position: relative; display: flex; flex-direction: column; background: #fff;
    border: 1px solid rgba(28,28,28,0.05); border-radius: 20px; overflow: hidden;
    text-decoration: none; color: inherit; box-shadow: 0 10px 30px -14px rgba(28,28,28,0.10);
    transition: transform 0.45s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)), box-shadow 0.45s ease;
  }
  .shop-card:hover { transform: translateY(-6px); box-shadow: 0 28px 50px -18px rgba(28,28,28,0.20); }
  .shop-card.is-filtered { display: none; }
  .shop-sale {
    position: absolute; top: 14px; left: 14px; z-index: 2; padding: 0.3rem 0.7rem;
    border-radius: 999px; background: var(--color-pink); color: #fff; font-size: 0.75rem;
    font-weight: 700; letter-spacing: 0.04em;
  }
  .shop-card-img { position: relative; aspect-ratio: 4 / 5; background: #fff; overflow: hidden; }
  .shop-card-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease-out, ease); }
  .shop-card:hover .shop-card-img img { transform: scale(1.05); }
  .shop-card-body { padding: 1.15rem 1.3rem 1.3rem; }
  .shop-card-body h3 { font-size: 1.02rem; font-weight: 600; line-height: 1.35; margin-bottom: 0.4rem; }
  .shop-card-price { display: flex; align-items: baseline; gap: 0.55rem; margin-bottom: 0.55rem; }
  .shop-price { font-weight: 700; font-size: 1.12rem; }
  .shop-card-price s { color: #a5a5a5; font-size: 0.9rem; }
  .shop-card-link { color: var(--color-orange); font-size: 0.86rem; font-weight: 600; opacity: 0; transform: translateY(4px); transition: opacity 0.3s ease, transform 0.3s ease; }
  .shop-card:hover .shop-card-link { opacity: 1; transform: translateY(0); }

  /* --- Trust strip (reuses class-note) --- */
  .shop-info { padding: clamp(1rem, 3vh, 2rem) 0 clamp(3.5rem, 8vh, 5.5rem); }
  .shop-info-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  .shop-info .class-note { background: #fff; border: 1px solid rgba(28,28,28,0.05); box-shadow: 0 10px 30px -12px rgba(28,28,28,0.10); }
  .shop-info .class-note > svg { color: var(--color-orange); }

  /* --- Cart drawer (dark glass, right slide) --- */
  .cart-backdrop { position: fixed; inset: 0; z-index: 210; background: rgba(15,15,15,0.5); opacity: 0; transition: opacity 0.35s ease; }
  .cart-backdrop.is-open { opacity: 1; }
  .cart-backdrop[hidden] { display: none; }
  .cart-drawer {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 220; width: min(420px, 100vw);
    display: flex; flex-direction: column; background: rgba(28,28,28,0.94);
    backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
    border-left: 1px solid rgba(255,255,255,0.10); color: #fff;
    transform: translateX(100%); transition: transform 0.4s var(--ease-out, ease);
  }
  .cart-drawer.is-open { transform: translateX(0); }
  .cart-drawer[hidden] { display: none; }
  .cart-drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 1.5rem 1.6rem 1.2rem; border-bottom: 1px solid rgba(255,255,255,0.10); }
  .cart-drawer-head h2 { font-family: 'Baumans', cursive; font-size: 1.35rem; }
  .cart-count { color: var(--color-yellow); }
  .cart-close { width: 38px; height: 38px; border: none; border-radius: 50%; background: rgba(255,255,255,0.08); color: #fff; font-size: 1.4rem; line-height: 1; cursor: pointer; transition: background 0.25s ease; }
  .cart-close:hover { background: rgba(255,255,255,0.18); }
  .cart-items { list-style: none; margin: 0; padding: 0.4rem 0; flex: 1; overflow-y: auto; }
  .cart-item { display: flex; align-items: center; gap: 1rem; padding: 1rem 1.6rem; border-bottom: 1px solid rgba(255,255,255,0.06); }
  .cart-item img { width: 60px; height: 74px; object-fit: cover; border-radius: 10px; background: #fff; }
  .cart-item-info { flex: 1; min-width: 0; }
  .cart-item-info strong { display: block; font-size: 0.93rem; line-height: 1.35; margin-bottom: 0.2rem; }
  .cart-item-info span { color: rgba(255,255,255,0.55); font-size: 0.82rem; }
  .cart-item-side { display: flex; flex-direction: column; align-items: flex-end; gap: 0.35rem; }
  .cart-item-side em { font-style: normal; font-weight: 700; font-size: 0.95rem; }
  .cart-item-remove { border: none; background: none; color: rgba(255,255,255,0.4); font-size: 1.1rem; cursor: pointer; transition: color 0.25s ease; text-decoration: none; }
  .cart-item-remove:hover { color: var(--color-pink); }
  .cart-empty { padding: 2.5rem 1.6rem; text-align: center; color: rgba(255,255,255,0.6); font-size: 0.95rem; }
  .cart-foot { padding: 1.3rem 1.6rem 1.6rem; border-top: 1px solid rgba(255,255,255,0.10); }
  .cart-subtotal { display: flex; justify-content: space-between; font-size: 1rem; margin-bottom: 0.4rem; }
  .cart-subtotal em { font-style: normal; font-weight: 700; font-size: 1.15rem; }
  .cart-note { color: rgba(255,255,255,0.5); font-size: 0.82rem; margin-bottom: 1.1rem; }
  .cart-foot .btn-primary { display: block; text-align: center; }
  .cart-continue { display: block; width: 100%; margin-top: 0.8rem; border: none; background: none; color: rgba(255,255,255,0.6); font: inherit; font-size: 0.88rem; cursor: pointer; transition: color 0.25s ease; }
  .cart-continue:hover { color: var(--color-yellow); }

  /* --- Product detail (toode) --- */
  .product-section { padding: clamp(2.5rem, 5vh, 3.5rem) 0 clamp(3.5rem, 8vh, 5.5rem); }
  .shop-back { display: inline-block; color: var(--text-muted, #777); text-decoration: none; font-size: 0.9rem; margin-bottom: 1.4rem; transition: color 0.25s ease; }
  .shop-back:hover { color: var(--color-orange); }
  .product-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 4vw, 4rem); align-items: start; }
  .product-stage { position: relative; aspect-ratio: 4 / 5; border-radius: 22px; overflow: hidden; background: #fff; border: 1px solid rgba(28,28,28,0.05); box-shadow: 0 24px 48px -22px rgba(28,28,28,0.18); }
  .product-stage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
  .product-stage img[hidden], .product-stage video[hidden] { display: none; }
  .product-stage video { position: absolute; inset: 0; width: 100%; height: 100%; display: block; background: #101010; }
  .stage-video--vertical { object-fit: contain; }
  .product-thumbs { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 0.9rem; }
  .product-thumb { position: relative; width: 68px; height: 84px; border: 2px solid transparent; border-radius: 12px; overflow: hidden; padding: 0; background: #fff; cursor: pointer; transition: border-color 0.25s ease; }
  .product-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .product-thumb.is-active { border-color: var(--color-orange); }
  .thumb-play { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(28,28,28,0.45); color: #fff; font-size: 0.9rem; }
  .product-panel h1 { font-family: 'Baumans', cursive; font-size: clamp(1.7rem, 2.8vw, 2.3rem); margin: 0.7rem 0 0.4rem; }
  .product-price { margin-bottom: 1.2rem; }
  .product-price em { font-style: normal; font-size: clamp(1.6rem, 2.4vw, 2rem); font-weight: 700; background: linear-gradient(100deg, #FFB904, #FF6500); -webkit-background-clip: text; background-clip: text; color: transparent; }
  .product-price s { color: #a5a5a5; font-size: 1.05rem; margin-left: 0.6rem; }
  .product-note { margin-bottom: 1.4rem; }
  .product-label { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: #8a8a8a; margin: 1.2rem 0 0.6rem; }
  .size-pills { display: flex; flex-wrap: wrap; gap: 0.5rem; }
  .size-pill { padding: 0.5rem 0.95rem; border: 1.5px solid rgba(28,28,28,0.18); border-radius: 999px; background: #fff; font: inherit; font-size: 0.85rem; cursor: pointer; transition: all 0.25s ease; }
  .size-pill:hover { border-color: var(--color-orange); }
  .size-pill.is-active { background: var(--color-dark, #1C1C1C); border-color: var(--color-dark, #1C1C1C); color: #fff; }
  .size-pill.is-unavailable { text-decoration: line-through; color: #b5b5b5; cursor: not-allowed; border-style: dashed; }
  .product-buyrow { display: flex; gap: 0.9rem; align-items: stretch; margin-top: 0.2rem; }
  .qty-stepper { display: flex; align-items: center; border: 1.5px solid rgba(28,28,28,0.18); border-radius: 999px; overflow: hidden; }
  .qty-btn { width: 42px; height: 100%; min-height: 48px; border: none; background: none; font-size: 1.2rem; cursor: pointer; transition: background 0.2s ease; }
  .qty-btn:hover { background: rgba(28,28,28,0.06); }
  .qty-value { min-width: 34px; text-align: center; font-weight: 700; }
  .product-add { flex: 1; }
  .product-meta { display: flex; align-items: center; gap: 0.4rem; margin-top: 1.1rem; color: #8a8a8a; font-size: 0.84rem; }
  .pm-ico { width: 17px; height: 17px; }
  .product-desc { max-width: 820px; margin-top: clamp(3rem, 6vw, 4.5rem); }
  .product-desc h2 { font-family: 'Baumans', cursive; font-size: clamp(1.4rem, 2.2vw, 1.8rem); margin-bottom: 0.9rem; }
  .product-desc p { line-height: 1.75; color: #444; margin-bottom: 1rem; }
  .product-desc-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; margin-top: 1.6rem; }
  .product-desc-cols h3 { font-size: 1.02rem; margin-bottom: 0.8rem; }
  .product-badges { display: flex; flex-direction: column; gap: 0.8rem; }
  .product-badge { background: #fff; border: 1px solid rgba(28,28,28,0.06); border-radius: 14px; padding: 0.95rem 1.2rem; box-shadow: 0 8px 22px -12px rgba(28,28,28,0.10); }
  .product-badge strong { display: block; font-size: 0.92rem; }
  .product-badge span { color: #8a8a8a; font-size: 0.84rem; }
  .product-related { margin-top: clamp(3rem, 6vw, 4.5rem); }
  .product-related .section-title { margin-bottom: 0.4rem; }

  /* --- Checkout (kassa) --- */
  .kassa-section { padding: clamp(2.5rem, 5vh, 3.5rem) 0 clamp(4rem, 9vh, 6rem); }
  .kassa-grid { display: grid; grid-template-columns: 1.25fr 0.75fr; gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
  .kassa-block { background: #fff; border: 1px solid rgba(28,28,28,0.06); border-radius: 22px; padding: clamp(1.15rem, 3vw, 2.4rem); box-shadow: 0 16px 40px -20px rgba(28,28,28,0.14); margin-bottom: 1.4rem; }
  .kassa-block h2 { display: flex; align-items: center; gap: 0.8rem; font-family: 'Baumans', cursive; font-size: 1.35rem; margin-bottom: 1.3rem; }
  .kassa-num { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: linear-gradient(135deg, #F80086, #FF6500 60%, #FFB904); color: #fff; font-family: 'Exo', sans-serif; font-weight: 700; font-size: 0.95rem; }
  .delivery-cards { display: flex; flex-direction: column; gap: 0.8rem; }
  .delivery-card { display: flex; align-items: center; gap: 1rem; width: 100%; padding: 1.05rem 1.3rem; border: 1.5px solid rgba(28,28,28,0.12); border-radius: 16px; background: #fff; font: inherit; text-align: left; cursor: pointer; transition: border-color 0.25s ease, box-shadow 0.25s ease; }
  .delivery-card:hover { border-color: rgba(28,28,28,0.35); }
  .delivery-card.is-active { border-color: var(--color-orange); box-shadow: 0 0 0 3px rgba(255,101,0,0.14); }
  .delivery-dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; }
  .delivery-dot--orange { background: var(--color-orange); }
  .delivery-dot--pink { background: var(--color-pink); }
  .delivery-dot--yellow { background: var(--color-yellow); }
  .delivery-info { flex: 1; display: flex; flex-direction: column; }
  .delivery-info strong { font-size: 0.97rem; }
  .delivery-info span { color: #8a8a8a; font-size: 0.83rem; }
  .delivery-card em { font-style: normal; font-weight: 700; }
  .kassa-terminal { margin-top: 1rem; display: flex; }
  .kassa-terminal[hidden] { display: none; }
  .wallet-row { display: flex; gap: 0.8rem; }
  .wallet-btn { flex: 1; padding: 0.85rem; border: none; border-radius: 12px; background: var(--color-dark, #1C1C1C); color: #fff; font: inherit; font-weight: 600; cursor: pointer; }
  .wallet-or { text-align: center; color: #9a9a9a; font-size: 0.82rem; margin: 0.9rem 0; }
  .pay-error { margin-top: 1rem; padding: 0.95rem 1.2rem; border-radius: 12px; background: rgba(248,0,134,0.07); border: 1.5px solid rgba(248,0,134,0.35); color: #C2006B; font-size: 0.92rem; }
  .pay-error[hidden] { display: none; }
  .kassa-pay { display: block; width: 100%; margin-top: 1.2rem; text-align: center; }
  .kassa-secure { display: flex; align-items: center; justify-content: center; gap: 0.45rem; margin-top: 0.9rem; color: #9a9a9a; font-size: 0.82rem; }
  .kassa-secure svg { width: 15px; height: 15px; }
  .kassa-terms-link { color: var(--color-orange); }
  .kassa-summary { position: sticky; top: 110px; background: #fff; border: 1px solid rgba(28,28,28,0.07); border-radius: 22px; padding: clamp(1.6rem, 3vw, 2.2rem); box-shadow: 0 24px 48px -22px rgba(28,28,28,0.16); }
  .summary-items { list-style: none; margin: 0.8rem 0 1.2rem; padding: 0; display: flex; flex-direction: column; gap: 0.9rem; }
  .summary-items li { display: flex; align-items: center; gap: 0.8rem; font-size: 0.9rem; }
  .summary-items img { width: 44px; height: 54px; object-fit: cover; border-radius: 8px; }
  .summary-items span { flex: 1; color: #555; }
  .summary-items em { font-style: normal; font-weight: 600; }
  .summary-row { display: flex; justify-content: space-between; padding: 0.5rem 0; font-size: 0.95rem; border-top: 1px solid rgba(28,28,28,0.06); }
  .summary-row em { font-style: normal; font-weight: 600; }
  .summary-row--total { font-size: 1.05rem; }
  .summary-row--total em { font-weight: 700; font-size: 1.25rem; }

  /* --- Slim dark header band (shared listing + product) --- */
  /* v6.2: slim band now matches the (reduced) base .page-header height so all
     headers are identical — shop + non-shop. Was taller (1.4-2.2 / 2.2-3). */
  .page-header--slim { padding: calc(var(--header-h) + clamp(0.7rem, 1.6vh, 1.1rem)) 0 clamp(0.9rem, 2vh, 1.4rem); }
  .page-header-title--sm { font-size: clamp(2rem, 3.3vw, 2.7rem); margin-bottom: 0; } /* v6.2: matches unified base title */
  .page-header-sub--slim { font-size: 0.95rem; margin-top: 0.6rem; max-width: 78ch; color: rgba(255,255,255,0.65); }
  .crumb-link { color: inherit; text-decoration: none; transition: color 0.25s ease; }
  .crumb-link:hover { color: var(--color-yellow); }
}

@layer responsive {
  /* Phase 4 — shop responsive */
  @media (max-width: 940px) {
    .shop-grid { grid-template-columns: repeat(2, 1fr); }
    .kassa-grid { grid-template-columns: 1fr; }
    .kassa-summary { position: static; top: auto; order: -1; }
  }
  @media (max-width: 900px) { .product-grid { grid-template-columns: 1fr; } }
  @media (max-width: 860px) { .shop-info-grid { grid-template-columns: 1fr; } }
  @media (max-width: 700px) { .product-desc-cols { grid-template-columns: 1fr; } }
  @media (max-width: 560px) { .shop-grid { grid-template-columns: 1fr; } }
  @media (max-width: 480px) { .cart-drawer { width: 100vw; } }
}

/* ============================================================
   Phase 4 (v6.1) — KASSA / checkout: style WooCommerce's form,
   payment box, terms + place-order to match the prototype.
   Base kassa layout (kassa-grid/block/summary/delivery-card) is in v6.0.
   ============================================================ */
@layer pages {
  /* delivery radios hidden — the whole label IS the card */
  .delivery-card { position: relative; }
  .delivery-card input.ts-ship-radio { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
}

@layer integrations {
  /* --- Kontakt fields (Woo .form-row markup) --- */
  .woocommerce-checkout .kassa-block .form-row { display: block; margin: 0 0 0.9rem; padding: 0; }
  .woocommerce-checkout #customer_details { display: flex; flex-wrap: wrap; gap: 0 4%; }
  .woocommerce-checkout #customer_details .form-row-first,
  .woocommerce-checkout #customer_details .form-row-last { width: 48%; }
  .woocommerce-checkout #customer_details .form-row-wide { width: 100%; }
  .woocommerce-checkout .kassa-block label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 0.35rem; color: var(--color-dark); }
  .woocommerce-checkout .kassa-block .required { color: var(--color-pink); border: 0; text-decoration: none; }
  .woocommerce-checkout .kassa-block input.input-text,
  .woocommerce-checkout .kassa-block .woocommerce-input-wrapper input {
    width: 100%; padding: 0.8rem 1rem; border: 1.5px solid rgba(28,28,28,0.15);
    border-radius: 12px; font: inherit; background: #fff; color: var(--color-dark);
  }
  .woocommerce-checkout .kassa-block input.input-text:focus { outline: none; border-color: var(--color-orange); }

  /* --- Makse: payment methods + Stripe element --- */
  .woocommerce-checkout .wc_payment_methods { list-style: none; margin: 0; padding: 0; }
  .woocommerce-checkout .wc_payment_methods > li { list-style: none; margin: 0; }
  .woocommerce-checkout .wc_payment_method > label { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; }
  .woocommerce-checkout .wc_payment_method > input[type=radio] { display: none; }
  .woocommerce-checkout .payment_box { background: rgba(28,28,28,0.02); border: 1px solid rgba(28,28,28,0.06); border-radius: 12px; padding: 1.1rem 1.2rem; margin-top: 0.8rem; }
  .woocommerce-checkout .payment_box::before { display: none; }

  /* terms checkbox → .consent look */
  .woocommerce-checkout .woocommerce-terms-and-conditions-wrapper { margin: 1.2rem 0 0; }
  .woocommerce-checkout .woocommerce-terms-and-conditions-wrapper .woocommerce-form__label-for-checkbox { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.9rem; color: #555; }
  .woocommerce-checkout .woocommerce-terms-and-conditions-wrapper input[type=checkbox] { accent-color: var(--color-orange); margin-top: 0.15rem; flex: 0 0 auto; }
  .woocommerce-checkout .woocommerce-terms-and-conditions-link { color: var(--color-orange); }

  /* place order → brand gradient pill */
  .woocommerce-checkout #place_order {
    display: block; width: 100%; margin-top: 1.2rem; cursor: pointer;
    padding: 1rem 1.5rem; border: none; border-radius: 999px;
    font: inherit; font-weight: 700; color: var(--color-dark);
    background: linear-gradient(100deg, #FFB904, #FF6500);
    transition: transform 0.3s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)), box-shadow 0.3s ease;
  }
  .woocommerce-checkout #place_order:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -12px rgba(255,101,0,0.5); }

  /* Woo error/notice inside checkout → brand-styled */
  .woocommerce-checkout .woocommerce-error,
  .woocommerce-checkout .woocommerce-NoticeGroup ul {
    list-style: none; margin: 0 0 1rem; padding: 0.9rem 1.2rem; border-radius: 12px;
    background: rgba(248,0,134,0.07); border: 1.5px solid rgba(248,0,134,0.35); color: #C2006B; font-size: 0.92rem;
  }
}

/* ============================================================
   Phase 4 (v6.4) — mobile polish (Edward 2026-07-08)
   ============================================================ */
@layer responsive {
  /* Class detail header: more breathing between keywords → title → description
     on phones (the class page is the key mobile view). Small, for readability. */
  @media (max-width: 640px) {
    .class-header .class-meta { margin-bottom: 1.3rem; row-gap: 0.55rem; }
    .class-header .page-header-sub { margin-top: 0.8rem; line-height: 1.6; }
  }

  /* Hero pagination dots were centered mid-hero on mobile: the base rule sets
     bottom:6.5rem and the mobile override adds top — both applied, so the
     absolutely-positioned container stretched top↔bottom and flex-centred the
     bullets. Force a single bottom anchor + auto height so they hug the bottom. */
  @media (max-width: 900px), (hover: none) {
    .hero-swiper .swiper-pagination {
      top: auto !important;
      bottom: clamp(1.25rem, 4vh, 2rem) !important;
      height: auto !important;
    }
  }
}
