/* KMB redesign — brand layer on top of Tailwind. Custom utilities + rich-text + chrome states. */

:root {
  --kmb-red:#ed1c24; --kmb-ink:#240708; --kmb-line:#e7ddd5;
  /* motion tokens */
  --kmb-ease-out: cubic-bezier(.2,.7,.2,1);
  --kmb-ease-spring: cubic-bezier(.34,1.3,.64,1);
  --kmb-dur-fast: .35s; --kmb-dur-base: .6s; --kmb-dur-slow: .9s;
  --kmb-stagger: 70ms;
  --kmb-reveal-dist: 24px;
  --kmb-kenburns: 20s;
}

html { scroll-behavior: smooth; }
body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
::selection { background: var(--kmb-red); color: #fff; }
:focus-visible { outline: 2px solid var(--kmb-red); outline-offset: 2px; }
img { -webkit-user-drag: none; }
/* display utilities (.flex/.grid) otherwise beat the preflight [hidden] rule in
   the cascade, so islands hiding their SSR fallback via the hidden attribute
   (e.g. carousel-3d's track) leave it visible */
[hidden]:not([hidden="until-found"]) { display: none !important; }

/* ---- typographic accents ---- */
.kmb-eyebrow {
  font-size: .72rem; letter-spacing: .22em; text-transform: uppercase;
  font-weight: 600; color: var(--kmb-red);
}
.kmb-display { font-family: "Unbounded", "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; }

/* animated underline for inline links */
.kmb-underline {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size .3s ease;
}
.kmb-underline:hover, a:hover > .kmb-underline { background-size: 100% 1px; }

/* ---- rich text (CMS rtf) ---- */
/* overflow-wrap: editor content may contain long unbreakable tokens (URLs,
   names at pasted font sizes) that would otherwise widen the phone layout */
.kmb-rtf { line-height: 1.75; color: #3b2b27; font-size: 1.0625rem; overflow-wrap: break-word; }
.kmb-rtf > :first-child { margin-top: 0; }
.kmb-rtf p { margin: 0 0 1.05rem; }
.kmb-rtf h2, .kmb-rtf h3, .kmb-rtf h4 { font-family: "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; line-height: 1.2; color: var(--kmb-ink); margin: 2rem 0 .75rem; }
.kmb-rtf h2 { font-size: 1.6rem; } .kmb-rtf h3 { font-size: 1.3rem; } .kmb-rtf h4 { font-size: 1.1rem; }
.kmb-rtf a { color: var(--kmb-red); text-decoration: underline; text-underline-offset: 3px; }
.kmb-rtf img { max-width: 100%; height: auto; border-radius: .3rem; margin: 1.25rem 0; }
.kmb-rtf ul { list-style: disc; padding-left: 1.3rem; margin: 0 0 1.05rem; }
.kmb-rtf ol { list-style: decimal; padding-left: 1.3rem; margin: 0 0 1.05rem; }
.kmb-rtf li { margin: .25rem 0; }
.kmb-rtf blockquote { border-left: 3px solid var(--kmb-red); padding-left: 1rem; font-style: italic; color: #5b4a45; margin: 1.25rem 0; }
.kmb-rtf iframe { max-width: 100%; }
/* auto-linked person names inside body text (link picker) — subtle until hover */
a.kmb-person-link, .kmb-rtf a.kmb-person-link { color: inherit; text-decoration: underline; text-decoration-color: rgba(237,28,36,.45); text-decoration-thickness: 1px; text-underline-offset: 2px; transition: color .2s, text-decoration-color .2s; }
a.kmb-person-link:hover, .kmb-rtf a.kmb-person-link:hover { color: var(--kmb-red); text-decoration-color: var(--kmb-red); }

/* ---- header states ---- */
.kmb-header { transition: background-color .3s, box-shadow .3s, border-color .3s; }
.kmb-header.is-scrolled { box-shadow: 0 1px 0 rgba(36,7,8,.08), 0 10px 30px -24px rgba(36,7,8,.5); }

/* ---- desktop dropdowns: CSS-only (JS enhances mobile) ---- */
@media (min-width: 1024px) {
  .kmb-nav-item > .kmb-dropdown { opacity: 0; visibility: hidden; transform: translateY(8px); transition: opacity .18s, transform .18s, visibility .18s; }
  .kmb-nav-item:hover > .kmb-dropdown,
  .kmb-nav-item:focus-within > .kmb-dropdown { opacity: 1; visibility: visible; transform: none; }
  /* micro-stagger of dropdown items on open */
  .kmb-nav-item > .kmb-dropdown li { opacity: 0; transform: translateY(4px); transition: opacity .18s ease, transform .18s ease; }
  .kmb-nav-item:hover > .kmb-dropdown li,
  .kmb-nav-item:focus-within > .kmb-dropdown li { opacity: 1; transform: none; }
  .kmb-dropdown li:nth-child(2) { transition-delay: .03s; }
  .kmb-dropdown li:nth-child(3) { transition-delay: .06s; }
  .kmb-dropdown li:nth-child(4) { transition-delay: .09s; }
  .kmb-dropdown li:nth-child(n+5) { transition-delay: .12s; }
}

/* ---- mobile nav drawer ----
   No-JS: drawer is visible (below lg) so navigation always works.
   With JS: collapsed until toggled. (.js is added by an inline script in <head>.) */
body.kmb-nav-open { overflow: hidden; }
.js [data-nav] { display: none; }
.js [data-nav].is-open { display: block; }

/* ============================ MOTION SYSTEM ============================
   Progressive enhancement. Hidden/animated states are gated behind `.js`
   (added inline in <head>) so NO-JS renders all content visible (SEO-safe).
   One IntersectionObserver + rAF live in app.js; reduced-motion neutralises all. */

/* page entrance — gentle "curtain up" on every SSR navigation */
.js .kmb-main { animation: kmb-page-in .4s ease both; }
@keyframes kmb-page-in { from { opacity: 0; } to { opacity: 1; } }

/* cross-document View Transitions (Chromium) — graceful no-op elsewhere; Layer A (page-in) covers the rest */
@view-transition { navigation: auto; }

/* reveal on scroll — legacy .kmb-reveal (now .js-gated → no-JS shows content) */
.js .kmb-reveal { opacity: 0; transform: translateY(16px); }
.kmb-reveal.is-in { opacity: 1; transform: none; transition: opacity var(--kmb-dur-base) ease, transform var(--kmb-dur-base) ease; }

/* reveal variants — data-reveal="fade-up|fade-in|slide-left|slide-right|scale-in|clip-reveal|wipe" */
.js [data-reveal] {
  opacity: 0;
  transition: opacity var(--kmb-dur-base) var(--kmb-ease-out),
              transform var(--kmb-dur-base) var(--kmb-ease-out),
              clip-path var(--kmb-dur-slow) var(--kmb-ease-out);
}
.js [data-reveal="fade-up"]     { transform: translateY(var(--kmb-reveal-dist)); }
.js [data-reveal="slide-left"]  { transform: translateX(var(--kmb-reveal-dist)); }
.js [data-reveal="slide-right"] { transform: translateX(calc(-1 * var(--kmb-reveal-dist))); }
.js [data-reveal="scale-in"]    { transform: scale(.94); }
.js [data-reveal="clip-reveal"] { clip-path: inset(0 0 100% 0); }
.js [data-reveal="wipe"]        { clip-path: inset(0 100% 0 0); }
[data-reveal].is-in { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }

/* staggered children of a revealed group (--i set by app.js, capped ~8) */
.js [data-reveal-stagger] > * { opacity: 0; }
[data-reveal-stagger].is-in > * {
  animation: kmb-rise var(--kmb-dur-base) var(--kmb-ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--kmb-stagger));
}
@keyframes kmb-rise { from { opacity: 0; transform: translateY(var(--kmb-reveal-dist)); } to { opacity: 1; transform: none; } }

/* hero typography entrance (above the fold → not observed) */
.js .kmb-in-1, .js .kmb-in-2, .js .kmb-in-3, .js .kmb-in-4 { opacity: 0; animation: kmb-rise var(--kmb-dur-base) var(--kmb-ease-out) both; }
.js .kmb-in-1 { animation-delay: .05s; } .js .kmb-in-2 { animation-delay: .16s; }
.js .kmb-in-3 { animation-delay: .27s; } .js .kmb-in-4 { animation-delay: .38s; }

/* parallax (app.js writes transform on the wrapper; reduced-motion → inert) */
.js [data-parallax] { will-change: transform; }

/* Ken-Burns slow drift for hero imagery (on the <img>, parallax sits on its wrapper) */
@media (prefers-reduced-motion: no-preference) {
  .kmb-kenburns { animation: kmb-kenburns var(--kmb-kenburns) ease-in-out infinite alternate; }
}
@keyframes kmb-kenburns { from { transform: scale(1); } to { transform: scale(1.12); } }

/* ---- hover-zoom image frame ---- */
.kmb-frame { overflow: hidden; }
.kmb-frame img { transition: transform var(--kmb-dur-slow) var(--kmb-ease-out); }
.kmb-frame:hover img { transform: scale(1.05); }

/* ---- hover-kinetics on cards (desktop, fine pointer only) ---- */
[data-kinetic] { transition: transform var(--kmb-dur-fast) var(--kmb-ease-spring), box-shadow var(--kmb-dur-fast) var(--kmb-ease-out); }
@media (hover: hover) and (pointer: fine) {
  [data-kinetic]:hover { transform: translateY(-6px); box-shadow: 0 18px 38px -22px rgba(36,7,8,.45); }
}

/* ---- reduced-motion: neutralise non-essential motion (hover keeps shadow, no move) ---- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .kmb-main,
  .js .kmb-reveal, .js [data-reveal],
  .js .kmb-in-1, .js .kmb-in-2, .js .kmb-in-3, .js .kmb-in-4,
  .js [data-reveal-stagger] > *, [data-reveal-stagger].is-in > *,
  .kmb-kenburns { animation: none !important; opacity: 1 !important; transform: none !important; clip-path: none !important; }
  [data-kinetic]:hover { transform: none !important; }
  /* HERO 2.0: no ambient video; letters/rule fully visible; grain/tilt inert
     (data-reveal="wipe" is already neutralised by the .js [data-reveal] line above) */
  .kmb-hero-video { display: none !important; }
  .js .kmb-hero-title .kmb-l, .js .kmb-hero-rule { animation: none !important; transform: none !important; opacity: 1 !important; }
  .kmb-hero-grain { animation: none !important; }
  [data-tilt] { transition: none !important; transform: none !important; }
  /* cinematic layer: overlays gone, magnets pinned, masked words visible (JS also bails) */
  .kmb-hv { display: none !important; }
  [data-magnetic] { transform: none !important; transition: none !important; }
  .js [data-spotlight]::after { display: none !important; }
  .js [data-reveal="mask"] .kmb-twi { transform: none !important; animation: none !important; }
  .kmb-marquee-cap { transform: none !important; }
}

/* ---- 3D coverflow carousel (island carousel-3d) ---- */
/* overflow-x: side slides poke past the container on narrow viewports and must
   not widen the document (= sideways pan on mobile); clip, not hidden, so the
   box never becomes a scroll container (hidden kept as fallback for old Safari) */
.kmb-c3d { position: relative; padding: 1rem 0 .25rem; overflow-x: hidden; overflow-x: clip; }
.kmb-c3d-stage { position: relative; height: 360px; perspective: 1500px; display: flex; align-items: center; justify-content: center; touch-action: pan-y; }
@media (min-width: 640px) { .kmb-c3d-stage { height: 440px; } }
.kmb-c3d-slide { position: absolute; width: 230px; height: 320px; border-radius: .85rem; overflow: hidden; background: #f1e9e2; box-shadow: 0 30px 60px -28px rgba(36,7,8,.65); transition: transform .55s var(--kmb-ease-out), opacity .55s var(--kmb-ease-out); cursor: pointer; text-decoration: none; will-change: transform; }
@media (min-width: 640px) { .kmb-c3d-slide { width: 290px; height: 400px; } }
.kmb-c3d-img { width: 100%; height: 100%; object-fit: cover; transition: filter .55s; }
.kmb-c3d-slide:not(.is-active) .kmb-c3d-img { filter: brightness(.55) saturate(.85); }
.kmb-c3d-grad { position: absolute; inset: 0; background: linear-gradient(to top, rgba(36,7,8,.85), transparent 55%); opacity: 0; transition: opacity .4s; }
.kmb-c3d-slide.is-active .kmb-c3d-grad { opacity: 1; }
.kmb-c3d-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 1rem; color: #fff; font-family: "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-weight: 700; font-size: 1.15rem; line-height: 1.15; opacity: 0; transform: translateY(8px); transition: opacity .4s, transform .4s; }
.kmb-c3d-slide.is-active .kmb-c3d-cap { opacity: 1; transform: none; }
.kmb-c3d-badge { position: absolute; top: .7rem; left: .7rem; background: var(--kmb-red); color: #fff; font-size: .6rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; padding: .2rem .5rem; border-radius: 999px; }
.kmb-c3d-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 200; width: 2.75rem; height: 2.75rem; border-radius: 999px; background: #fff; border: 1px solid var(--kmb-line); box-shadow: 0 10px 30px -12px rgba(36,7,8,.4); display: flex; align-items: center; justify-content: center; color: var(--kmb-ink); cursor: pointer; transition: color .2s; }
.kmb-c3d-arrow:hover { color: var(--kmb-red); }
.kmb-c3d-arrow:disabled { opacity: .35; cursor: default; }
.kmb-c3d-prev { left: 0; } .kmb-c3d-next { right: 0; }
@media (min-width: 640px) { .kmb-c3d-prev { left: 2%; } .kmb-c3d-next { right: 2%; } }
.kmb-c3d-dots { display: flex; gap: .4rem; justify-content: center; margin-top: 1.25rem; }
.kmb-c3d-dot { width: .5rem; height: .5rem; border-radius: 999px; background: var(--kmb-line); border: 0; cursor: pointer; padding: 0; transition: background .2s, transform .2s; }
.kmb-c3d-dot.is-on { background: var(--kmb-red); transform: scale(1.3); }
.kmb-c3d:focus-visible { outline: 2px solid var(--kmb-red); outline-offset: 4px; }

/* ===================== Radu Poklitaru — signature dark page =====================
   A deliberately distinct, cinematic dark treatment (vs the light editorial of the rest). */
.radu-body { background: #160405; }
.radu-body .kmb-main { background: #160405; color: #f1e9e2; }
.radu-spot { background: radial-gradient(72% 62% at 50% 0%, rgba(237,28,36,.14), transparent 70%); }
.radu-vignette { box-shadow: inset 0 -140px 180px -30px #160405, inset 0 0 240px 50px rgba(0,0,0,.55); }
.radu-hero-name { font-family: "Unbounded", "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; line-height: .95; letter-spacing: -.03em; }
.radu-quote { font-family: "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-style: italic; line-height: 1.1; letter-spacing: -.01em; }
.radu-quote::before { content: "\201C"; display: block; font-style: normal; font-size: 3.2em; line-height: .55; color: rgba(237,28,36,.45); margin-bottom: .08em; }
/* the lead RTF carries a pasted absolute font size (72px display name); on
   phones «Поклітару» at 72px is wider than the viewport — cap via vw */
@media (max-width: 520px) {
  .radu-lead .kmb-rtf span[style*="font-size"] { font-size: 14.5vw !important; }
}
.radu-num { position: absolute; top: -.35em; right: 0; z-index: 0; pointer-events: none; user-select: none;
  font-family: "Unbounded", "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-weight: 700; line-height: 1;
  font-size: clamp(4rem, 12vw, 9rem); color: rgba(237,28,36,.13); }
.radu-rule { height: 1px; background: linear-gradient(to right, rgba(237,28,36,.65), transparent); }
.radu-lead .kmb-rtf > p:first-of-type::first-letter,
.radu-lead::first-letter { float: left; font-family: "Unbounded", "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-weight: 700;
  font-size: 4.6rem; line-height: .72; margin: .08em .14em 0 0; color: var(--kmb-red); }
/* rich-text on the dark page */
.radu-body .kmb-rtf { color: rgba(241,233,226,.82); }
.radu-body .kmb-rtf h2, .radu-body .kmb-rtf h3, .radu-body .kmb-rtf h4, .radu-body .kmb-rtf strong { color: #fff; }
.radu-body .kmb-rtf a { color: var(--kmb-red); }
.radu-body .kmb-rtf blockquote { border-left-color: var(--kmb-red); color: rgba(241,233,226,.72); }
/* recognition timeline (red thread + nodes) */
.radu-timeline { position: relative; }
.radu-timeline::before { content: ""; position: absolute; left: .32rem; top: .6rem; bottom: .6rem; width: 2px;
  background: linear-gradient(rgba(237,28,36,.7), rgba(237,28,36,0)); }
.radu-timeline .kmb-rtf p { position: relative; padding-left: 2rem; margin-bottom: 1.5rem; }
.radu-timeline .kmb-rtf p::before { content: ""; position: absolute; left: 0; top: .5em; width: .7rem; height: .7rem;
  border-radius: 999px; background: var(--kmb-red); box-shadow: 0 0 0 4px rgba(237,28,36,.16); }
.radu-scroll { width: 1px; height: 2.5rem; background: linear-gradient(to bottom, rgba(255,255,255,.5), transparent); }
/* key-facts strip */
/* min() in the track floor: a hard 150px floor makes the grid's min-content
   3×150px, which blows the parent grid column past a 375px viewport */
.radu-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 28vw), 1fr)); gap: 1px; background: rgba(255,255,255,.08); border-block: 1px solid rgba(255,255,255,.1); }
.radu-stat { background: #160405; padding: 2.25rem 1.5rem; text-align: center; }
.radu-stat-n { font-family: "Unbounded", "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-weight: 700; font-size: clamp(2.2rem, 5vw, 3.4rem); line-height: 1; color: var(--kmb-red); }
.radu-stat-l { margin-top: .55rem; font-size: .76rem; letter-spacing: .14em; text-transform: uppercase; color: rgba(241,233,226,.6); }
/* structured achievements timeline */
.radu-tl { position: relative; }
.radu-tl::before { content: ""; position: absolute; left: .4rem; top: .5rem; bottom: .5rem; width: 2px; background: linear-gradient(rgba(237,28,36,.7), rgba(237,28,36,0)); }
.radu-tl-item { position: relative; padding-left: 2.25rem; padding-bottom: 2.25rem; }
.radu-tl-item:last-child { padding-bottom: 0; }
.radu-tl-item::before { content: ""; position: absolute; left: .05rem; top: .35rem; width: .75rem; height: .75rem; border-radius: 999px; background: var(--kmb-red); box-shadow: 0 0 0 4px rgba(237,28,36,.16); }
.radu-tl-year { font-family: "Unbounded", "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-weight: 700; font-size: 1.4rem; color: #fff; line-height: 1; }
.radu-tl-text { margin-top: .4rem; color: rgba(241,233,226,.78); line-height: 1.5; }
/* mouse-parallax smoothing (transform written by app.js) */
[data-mouseparallax] { transition: transform .25s cubic-bezier(.2,.7,.2,1); }

/* ---- reading-progress bar + back-to-top (added by app.js) ---- */
.kmb-progress { position: fixed; top: 0; left: 0; height: 3px; width: 0; background: var(--kmb-red); z-index: 60; transition: width .1s linear; pointer-events: none; }
.kmb-totop { position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 50; width: 2.75rem; height: 2.75rem; border: 0; border-radius: 999px; background: var(--kmb-ink); color: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 10px 30px -10px rgba(36,7,8,.5); cursor: pointer; opacity: 0; transform: translateY(12px); pointer-events: none; transition: opacity .3s var(--kmb-ease-out), transform .3s var(--kmb-ease-out), background-color .2s; }
.kmb-totop.is-on { opacity: 1; transform: none; pointer-events: auto; }
.kmb-totop:hover { background: var(--kmb-red); }
@media (prefers-reduced-motion: reduce) { .kmb-totop { transition: opacity .2s; transform: none; } .kmb-progress { transition: none; } }

/* ---- noscript hint for islands (hidden once an island is ready) ---- */
[data-island-ready] .kmb-island-fallback-note { display: none; }

/* ---- stage-photo marquee (island photo-marquee) ----
   No-JS / pre-boot: a normal horizontal scroll strip (every photo is a crawlable <a>).
   The island duplicates the track and drifts it; paused under reduced-motion + on hover/focus. */
.kmb-marquee { position: relative; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.kmb-marquee::-webkit-scrollbar { display: none; }
.kmb-marquee-track { display: flex; gap: 1rem; padding: 0 1.25rem; width: max-content; }
.kmb-marquee-item { flex: 0 0 auto; width: 16rem; height: 11rem; border-radius: .85rem; overflow: hidden; background: #f1e9e2; display: block; }
@media (min-width: 640px) { .kmb-marquee-item { width: 20rem; height: 13rem; } }
/* island mode: ONLY once the island is actually drifting the track (class added by the JS) do we
   hide overflow. Until then — no-JS, pre-boot, reduced-motion, or any early return — it stays a
   normal scrollable strip, so it can never get stuck "clipped and motionless". */
.kmb-marquee.is-animating { overflow: hidden; }
.kmb-marquee.is-animating .kmb-marquee-track { will-change: transform; }
/* spectacle-name caption on marquee tiles — hover-revealed (fine pointer), always-on for touch */
.kmb-marquee-item { position: relative; }
.kmb-marquee-cap {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 1.6rem .9rem .7rem;
  font-family: "Montserrat", "Fira Sans Condensed", system-ui, sans-serif; font-weight: 600;
  font-size: .82rem; letter-spacing: .04em; color: #fff;
  background: linear-gradient(to top, rgba(36,7,8,.78), transparent);
  opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity .35s var(--kmb-ease-out), transform .35s var(--kmb-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .kmb-marquee-item:hover .kmb-marquee-cap,
  .kmb-marquee-item:focus-visible .kmb-marquee-cap { opacity: 1; transform: none; }
}
@media (hover: none) { .kmb-marquee-cap { opacity: 1; transform: none; } }

/* ===== HERO 2.0 (island hero-fx) =====
   Ambient video + particle canvas + film grain + kinetic title. All layers are
   decorative (aria-hidden) and progressively enhanced; reduced-motion neutralises
   them in the block above. */

/* hero takes the full viewport (svh avoids the mobile URL-bar jump) */
.kmb-hero { min-height: 100vh; min-height: 100svh; }

/* ambient film stage — SSR'd <video data-hero-local> + promo layer <div data-hero-yt>;
   an inline picker script sets the src and .is-on fires on first 'playing' frame */
.kmb-hero-video { position: absolute; inset: 0; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity 1.2s var(--kmb-ease-out); }
.kmb-hero-video.is-on { opacity: 1; }
/* the local film is 2:1 (1920×960) — its own cover-crop math */
.kmb-hero-video video {
  position: absolute; top: 50%; left: 50%;
  width: max(100vw, 200vh); height: max(100vh, 50vw);
  transform: translate(-50%, -50%) scale(1.02);
  border: 0; pointer-events: none; object-fit: cover;
}
/* centered 16:9 cover-crop for promo iframes; the slight scale hides YouTube chrome */
.kmb-hero-video iframe {
  position: absolute; top: 50%; left: 50%;
  width: max(100vw, 177.78vh); height: max(100vh, 56.25vw);
  transform: translate(-50%, -50%) scale(1.15);
  border: 0; pointer-events: none;
}
/* promo crossfade layer above the looping film */
.kmb-hero-yt { position: absolute; inset: 0; opacity: 0; transition: opacity 1.2s var(--kmb-ease-out); }
.kmb-hero-yt.is-on { opacity: 1; }

/* particle canvas (drawn by the island; CSS size is mandatory — the island scales
   the backing store by devicePixelRatio, so the canvas must map onto this box) */
.kmb-hero-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* vignette + film grain (inline SVG feTurbulence tile, 128px, repeats) */
.kmb-hero-grain {
  position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image:
    radial-gradient(ellipse at center, transparent 0%, transparent 52%, rgba(22,4,5,.55) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23g)' opacity='.35'/%3E%3C/svg%3E");
  background-size: 100% 100%, 128px 128px;
  background-repeat: no-repeat, repeat;
}
@media (prefers-reduced-motion: no-preference) {
  .kmb-hero-grain { animation: kmb-grain 1.2s steps(6) infinite; }
}
/* only the grain tile jumps — the vignette layer stays put */
@keyframes kmb-grain {
  0%, 100% { background-position: 0 0, 0 0; }
  20% { background-position: 0 0, -28px 16px; }
  40% { background-position: 0 0, 14px -36px; }
  60% { background-position: 0 0, -42px -20px; }
  80% { background-position: 0 0, 34px 30px; }
}

/* kinetic title — real text stays in the DOM: word wrapper .kmb-w masks letter
   .kmb-l (--i = continuous letter index, set by PHP); no-JS shows the plain title */
.kmb-hero-title .kmb-w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .12em; margin-bottom: -.12em; } /* descender room for the display face */
.js .kmb-hero-title .kmb-l { display: inline-block; transform: translateY(115%); animation: kmb-letter-up .7s var(--kmb-ease-out) both; animation-delay: calc(.2s + var(--i, 0) * 35ms); }
@keyframes kmb-letter-up { to { transform: none; } }

/* red accent rule in the eyebrow line */
.kmb-hero-rule { display: inline-block; width: 3.5rem; height: 2px; background: var(--kmb-red); margin-left: .75rem; vertical-align: middle; }
.js .kmb-hero-rule { transform: scaleX(0); transform-origin: left; animation: kmb-rule-in .8s var(--kmb-ease-out) .9s both; }
@keyframes kmb-rule-in { to { transform: scaleX(1); } }

/* video pause/play toggle — ghost circle, 44px a11y target; unhidden by the island
   (lifted above the nearest-event strip) */
.kmb-hero-pause { position: absolute; right: 1.25rem; bottom: 4.75rem; z-index: 30; width: 2.75rem; height: 2.75rem; border-radius: 999px; background: transparent; border: 1px solid rgba(255,255,255,.4); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); transition: border-color .2s; }
.kmb-hero-pause:hover { border-color: #fff; }
.kmb-hero-pause[hidden] { display: none; }
/* pause glyph (two bars) ↔ play glyph (triangle), driven by aria-pressed */
.kmb-hero-pause span { width: 10px; height: 12px; background: linear-gradient(90deg, currentColor 0 3px, transparent 3px 7px, currentColor 7px 10px); }
.kmb-hero-pause[aria-pressed="true"] span { width: 11px; margin-left: 2px; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }

/* sound toggle (local film only — the desktop file carries the score) */
.kmb-hero-sound { position: absolute; right: 4.5rem; bottom: 4.75rem; z-index: 30; width: 2.75rem; height: 2.75rem; border-radius: 999px; background: transparent; border: 1px solid rgba(255,255,255,.4); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); transition: border-color .2s; }
.kmb-hero-sound:hover { border-color: #fff; }
.kmb-hero-sound[hidden] { display: none; }
/* speaker glyph; a slash overlays it while muted (aria-pressed=false) */
.kmb-hero-sound span { position: relative; width: 14px; height: 12px; background: currentColor; clip-path: polygon(0 35%, 35% 35%, 70% 0, 70% 100%, 35% 65%, 0 65%); }
.kmb-hero-sound[aria-pressed="false"]::after { content: ""; position: absolute; width: 1.4rem; height: 2px; background: currentColor; transform: rotate(-45deg); }

/* hero h1 — Unbounded is a wide face; the clamp keeps «Модерн-балет» on one line at 360px */
.kmb-hero-title { font-size: clamp(2.25rem, 1.1rem + 6.2vw, 6.5rem); line-height: 1.04; letter-spacing: -.02em; }

/* scroll-moment tilt (transform written by app.js, like [data-mouseparallax]) */
[data-tilt] { transition: transform .35s var(--kmb-ease-out); will-change: transform; transform-style: preserve-3d; }
/* keep the fast tilt timing when the element also carries a reveal
   (.js [data-reveal] sets the transition shorthand and wins on specificity) */
.js [data-reveal][data-tilt] {
  transition: opacity var(--kmb-dur-base) var(--kmb-ease-out),
              clip-path var(--kmb-dur-slow) var(--kmb-ease-out),
              transform .35s var(--kmb-ease-out);
}

/* ===== CINEMATIC LAYER (home upgrade) ===== */

/* ---- hover-video / living-poster overlay (app.js, data-hv-yt|data-hv-img) ----
   Overlay sits between the base <img> and the card's scrim/caption layers;
   nothing is fetched until the first hover intent. */
.kmb-hv { position: absolute; inset: 0; opacity: 0; transition: opacity .6s var(--kmb-ease-out); pointer-events: none; }
.kmb-hv.is-on { opacity: 1; }
/* centered 16:9 cover-crop (cards are taller than 16:9, so height:100% covers);
   slight scale hides YouTube edge chrome */
.kmb-hv iframe {
  position: absolute; top: 50%; left: 50%; border: 0;
  height: 100%; width: auto; aspect-ratio: 16 / 9;
  transform: translate(-50%, -50%) scale(1.06);
}
.kmb-hv-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.kmb-hv.is-on .kmb-hv-img { animation: kmb-hv-kb 8s var(--kmb-ease-out) both; }
@keyframes kmb-hv-kb { from { transform: scale(1.02); } to { transform: scale(1.12); } }

/* ---- curtain: scroll-driven stage-curtain lift on dark sections ----
   Progressive enhancement only (Chromium 115+/Safari 26): others keep the hard boundary. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .js .kmb-curtain { view-timeline: --kmb-curtain block; }
    .js .kmb-curtain::before {
      content: ""; position: absolute; inset: 0; z-index: 9; pointer-events: none;
      background: linear-gradient(to bottom, #0a0102, rgba(10,1,2,.93) 70%, rgba(10,1,2,.86));
      border-bottom: 2px solid rgba(237,28,36,.55);
      box-shadow: 0 6px 22px -4px rgba(237,28,36,.28); /* red hem glow riding the edge */
      animation: kmb-curtain-lift linear both;
      animation-timeline: --kmb-curtain;
      animation-range: entry 5% entry 90%;
    }
  }
}
@keyframes kmb-curtain-lift { from { transform: translateY(0); } to { transform: translateY(-101%); } }

/* ---- magnetic buttons (translate written by app.js pointer engine) ---- */
[data-magnetic] { will-change: transform; transition: transform .45s var(--kmb-ease-spring); }

/* ---- cursor spotlight on dark sections (--mx/--my written by app.js) ----
   A warm additive glow positioned via transform only (compositor-friendly). */
.js [data-spotlight]::after {
  content: ""; position: absolute; left: 0; top: 0; width: 68rem; height: 68rem; z-index: 10;
  pointer-events: none; opacity: 0; transition: opacity .6s var(--kmb-ease-out);
  background: radial-gradient(closest-side, rgba(255,235,220,.08), rgba(237,28,36,.05) 40%, transparent 70%);
  transform: translate(-50%, -50%) translate3d(var(--mx, 50vw), var(--my, 40vh), 0);
  will-change: transform, opacity;
}
.js [data-spotlight].is-spot-on::after { opacity: 1; }
@media (hover: none) { .js [data-spotlight]::after { display: none; } }

/* ---- static grain tile (same feTurbulence tile as the hero, no vignette/animation) ---- */
.kmb-grain-tile {
  position: absolute; inset: 0; pointer-events: none; opacity: .35;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23g)' opacity='.35'/%3E%3C/svg%3E");
  background-size: 128px 128px; background-repeat: repeat;
}

/* ---- masked word reveal for section titles (PHP emits .kmb-tw/.kmb-twi spans) ----
   Triggered by the shared IntersectionObserver via data-reveal="mask"; the container
   stays visible — words carry the motion (after the [data-reveal] base rules above). */
.kmb-tw { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .12em; margin-bottom: -.12em; }
.kmb-twi { display: inline-block; }
.js [data-reveal="mask"] { opacity: 1; transform: none; }
.js [data-reveal="mask"] .kmb-twi { transform: translateY(112%); }
[data-reveal="mask"].is-in .kmb-twi {
  animation: kmb-word-up .7s var(--kmb-ease-out) both;
  animation-delay: calc(var(--w, 0) * 70ms);
}
@keyframes kmb-word-up { to { transform: none; } }
