/* ==========================================================================
   Balerina Ballet School — design tokens & base
   ========================================================================== */
:root {
  --color-primary: #d81b6b;
  --color-primary-dark: #a81254;
  --color-primary-light: #f4a6c6;
  --color-blush: #fdf1f5;
  --color-blush-deep: #f8dce6;
  --color-ink: #2a1f27;
  --color-ink-soft: #6e5a66;
  --color-white: #ffffff;
  --color-gold: #cf9a52;
  --color-line: #f0d9e3;

  /* Playfair Display + Inter is the single most reached-for "elegant" pairing
     in template/generated design right now — swapped the display face for
     Cormorant Garamond: a real garamond-cut serif with proper Cyrillic
     support (unlike most contemporary display faces — Fraunces and Bodoni
     Moda, tried first, both drop Cyrillic entirely, which would have quietly
     fallen back to the browser default serif on every RU headline). Self-
     hosted the same way Inter/Caveat/Playfair already were, weight 600 only
     (its 700 shares Playfair's exact glyph outlines — Google just maps the
     request to the nearest weight it has, so a distinct 700 file doesn't
     exist to fetch). */
  --font-display: "Cormorant Garamond", "Georgia", serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-script: "Caveat", cursive;

  --container: 1240px;
  --radius-lg: 28px;
  --radius-md: 18px;
  --radius-sm: 12px;
  --shadow-soft: 0 20px 45px -20px rgba(168, 18, 84, 0.25);
  --shadow-card: 0 12px 30px -14px rgba(42, 31, 39, 0.18);
  --transition: 280ms cubic-bezier(0.4, 0, 0.2, 1);

  /* Purpose-matched easing: hover/color changes keep --transition above;
     these cover entrances, on-screen movement, and the drawer specifically —
     using one curve for everything is what makes motion feel generic. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
}

* , *::before, *::after { box-sizing: border-box; }
/* overflow-x:hidden was briefly added here too (alongside body's, below) to
   chase a reported horizontal-drag bug on phone — CONFIRMED here to be
   wrong and reverted: setting overflow-x on an element with overflow-y left
   as its default forces the UA to give overflow-y a real (non-visible)
   value too ("auto"), turning <html> into an actual scroll container. With
   BOTH <html> and <body> then acting as scroll containers, the site
   header's `position: sticky` no longer had an unambiguous single scroll
   box to stick against — verified live (Chromium, not just suspected on
   iOS): the header scrolled away with the page instead of staying pinned.
   body's own overflow-x:hidden below is enough on its own.

   UPDATE: `overflow-x: clip` is the right tool and does NOT have that
   problem — unlike `hidden`, `clip` never turns the element into a scroll
   container, so <html> stays a non-scroller and the sticky header keeps its
   single unambiguous scroll box. Guarded behind @supports so an older
   Safari without `clip` simply keeps today's behaviour instead of
   regressing. This is the belt-and-braces layer under the real fixes
   (min-width:0 on the actual offenders); the founder reported being able to
   drag the whole site sideways on her iPhone, which body-only clipping
   evidently did not prevent there even though Chromium honoured it. */
html { scroll-behavior: smooth; scroll-padding-top: 104px; }
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-ink);
  background: var(--color-white);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  max-width: 100%;
  overscroll-behavior-x: none;
}

/* Must come AFTER body's own overflow-x above (same specificity, later wins)
   and must set BOTH html and body — verified live that setting it on <html>
   alone leaves <body> as the only scroll container, which breaks the sticky
   header exactly the way the reverted `hidden` attempt did (header scrolled
   away instead of pinning). With `clip` on both, neither becomes a scroll
   container, the header stays pinned, and there is nothing to drag sideways. */
@supports (overflow: clip) {
  html, body { overflow-x: clip; }
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
button { font-family: inherit; cursor: pointer; }
h1, h2, h3, h4 { font-family: var(--font-display); margin: 0; line-height: 1.15; font-weight: 600; }
p { margin: 0; }

/* ==========================================================================
   Preloader — a line-drawn arabesque, not a generic spinner. Each stroke
   animates in with pathLength="100" on the SVG elements themselves, so the
   dash math stays a flat 0→100 regardless of each path's real geometry
   (no JS length-measuring needed). Draws once, then holds with a slow
   breathing loop in case the page is still loading. main.js adds
   .is-hidden on window load (with a minimum display floor so a fast load
   doesn't just flash it) and removes the element after the fade. */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: var(--color-blush);
  transition: opacity 500ms ease, visibility 500ms ease;
}
.preloader.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }

.preloader__figure {
  width: 84px;
  height: 84px;
  overflow: visible;
  animation: preloader-breathe 2.4s ease-in-out 1.7s infinite;
}
.preloader__path {
  stroke: var(--color-primary);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: preloader-draw 1.1s ease forwards;
}
.preloader__path--tutu {
  stroke: var(--color-primary-light);
  fill: var(--color-primary-light);
  fill-opacity: 0;
  animation: preloader-draw 1.1s ease forwards, preloader-tutu-fill 0.5s ease 0.6s forwards;
}
.preloader__path--head { animation-delay: 0.3s; }
.preloader__path--torso { animation-delay: 0.45s; }
.preloader__path--leg-standing { animation-delay: 0.65s; }
.preloader__path--leg-back { animation-delay: 0.8s; }
.preloader__path--arm-front { animation-delay: 0.9s; }
.preloader__path--arm-back { animation-delay: 1s; }

.preloader__word {
  font-family: var(--font-script);
  font-size: 26px;
  color: var(--color-primary-dark);
  opacity: 0;
  transform: translateY(4px);
  animation: preloader-word-in 0.6s ease 1.3s forwards;
}

@keyframes preloader-draw { to { stroke-dashoffset: 0; } }
@keyframes preloader-tutu-fill { to { fill-opacity: 0.85; } }
@keyframes preloader-word-in { to { opacity: 1; transform: translateY(0); } }
@keyframes preloader-breathe {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.04); opacity: 0.82; }
}

@media (prefers-reduced-motion: reduce) {
  .preloader__path, .preloader__path--tutu { animation: none; stroke-dashoffset: 0; }
  .preloader__path--tutu { fill-opacity: 0.85; }
  .preloader__figure { animation: none; }
  .preloader__word { animation: none; opacity: 1; transform: none; }
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 20px;
}

@media (min-width: 768px) {
  .container { padding-inline: 32px; }
}

/* The header carries more inline content (logo, phone, 7 nav links, lang
   switch, CTA) than a body section ever does, so it gets extra breathing
   room beyond the standard 1240px content width — otherwise the nav has
   nowhere to grow into no matter how wide the actual browser window is. */
.site-header .container { max-width: 1520px; }

.section { padding-block: 72px; position: relative; }
.section--tight { padding-block: 48px; }
.section--blush { background: var(--color-blush); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-primary);
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--color-primary);
  border-radius: 2px;
}

.section-head { max-width: 640px; margin-bottom: 40px; }
.section-head--center { margin-inline: auto; text-align: center; }
.section-title { font-size: clamp(28px, 4vw, 40px); margin-top: 10px; }
.section-lede { margin-top: 14px; color: var(--color-ink-soft); font-size: 16px; line-height: 1.7; }

.script-text {
  font-family: var(--font-script);
  font-size: clamp(24px, 3vw, 32px);
  color: var(--color-primary-dark);
  line-height: 1.25;
}

/* Soft blurred color blobs — a section otherwise made of plain text/cards
   gets a little depth and warmth without a full photo or a flat color
   swap. Purely decorative (aria-hidden), each section picks 1-2 of these
   in different corners so the effect reads as intentional, not repeated. */
.section--decorated { position: relative; overflow: hidden; }
.section-blob {
  position: absolute; z-index: 0; border-radius: 50%; filter: blur(70px);
  opacity: 0.5; pointer-events: none;
  animation: blob-drift 14s ease-in-out infinite;
}
.section-blob--a { top: -80px; right: -60px; width: 320px; height: 320px; background: var(--color-blush-deep); }
.section-blob--b { bottom: -100px; left: -80px; width: 280px; height: 280px; background: rgba(207, 154, 82, 0.25); animation-delay: -6s; }
.section-blob--c { top: -60px; left: 10%; width: 360px; height: 360px; background: var(--color-primary-light); opacity: 0.28; animation-delay: -3s; }
.section--decorated > .container { position: relative; z-index: 1; }
@keyframes blob-drift {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(18px, -14px) scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .section-blob { animation: none; }
}

/* Buttons ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 26px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 15px;
  border: 1px solid transparent;
  transition: transform 150ms var(--ease-out), box-shadow var(--transition), background var(--transition), color var(--transition);
  white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn--light:active, .btn--ghost:active { transform: scale(0.96); }
.btn-icon { width: 18px; height: 18px; flex-shrink: 0; transition: transform var(--transition); }
.btn:hover .btn-icon { transform: translateX(3px); }

.btn--primary {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
  color: var(--color-white);
  box-shadow: 0 14px 28px -12px rgba(216, 27, 107, 0.55);
}
.btn--primary:hover { box-shadow: 0 18px 34px -12px rgba(216, 27, 107, 0.65); transform: translateY(-2px); }

.btn--ghost {
  background: transparent;
  border-color: var(--color-line);
  color: var(--color-ink);
}
.btn--ghost:hover { border-color: var(--color-primary); color: var(--color-primary); }

.btn--light {
  background: var(--color-white);
  color: var(--color-primary-dark);
}
.btn--light:hover { transform: translateY(-2px); box-shadow: var(--shadow-card); }

.btn--block { width: 100%; justify-content: center; }
.btn--sm { padding: 11px 18px; font-size: 14px; }

.play-btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  color: var(--color-ink);
  font-weight: 600;
  font-size: 14px;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.play-btn__circle {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--color-white);
  color: var(--color-primary);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-card);
  transition: transform var(--transition);
}
.play-btn:hover .play-btn__circle { transform: scale(1.08); }

.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 3px;
  z-index: 200;
  background: linear-gradient(90deg, var(--color-primary), var(--color-gold));
  transform: scaleX(0);
  transform-origin: left;
}

/* ==========================================================================
   Header / Navigation
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.site-header.is-scrolled {
  border-color: var(--color-line);
  box-shadow: 0 8px 24px -18px rgba(42, 31, 39, 0.3);
}

/* margin-bottom depends ONLY on .is-home (set once, server-side, per page —
   see header.php) and NEVER on .is-scrolled. That used to not be true: it
   transitioned 20px→0 the instant .is-scrolled landed, and animating a
   margin on a position:sticky element sitting right at the scroll boundary
   is exactly what triggers Chrome's scroll anchoring — the layout shift
   nudges scrollY, which crosses the 8px is-scrolled threshold the OTHER
   way, which un-shifts it, forever, as long as you keep scrolling slowly
   through that zone ("небольшой скролл... дрожит туда-сюда... на телефоне
   тоже"). Fixed per page load now, so scrolling never moves it — the small
   trade-off is that the reserved gap below the header stays exactly the
   same size whether or not the mark is currently overflowing into it, but
   a fixed few extra pixels of breathing room is a much smaller cost than a
   header that shakes. */
.site-header.is-home { margin-bottom: 20px; }

@media (min-width: 768px) {
  .site-header.is-home { margin-bottom: 36px; }
}

/* Height is likewise fixed regardless of scroll — ONLY the mark and text
   inside change size on .is-scrolled (see below), never anything that
   would resize this bar itself. overflow:visible (the default) still lets
   the big-mode mark spill past this fixed box exactly as before; a
   fixed-size ancestor just never reacts to an overflowing child's size, so
   there's nothing here for scroll anchoring to notice or compensate for. */
.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
  height: 64px;
}

/* Shared layout only here — .brand is reused in both the header (sized
   below) and the footer (kept modest, see .footer-brand further down);
   neither the base rule nor .brand__name span's type styling should differ
   between the two. */
.brand { display: flex; align-items: center; gap: 12px; }
.brand__mark { flex-shrink: 0; object-fit: contain; }
.brand__name {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1.1;
}
.brand__name span { display: block; margin-top: 3px; font-family: var(--font-body); letter-spacing: 0.2em; color: var(--color-ink-soft); font-weight: 600; }

/* This compact size is the header's size EVERYWHERE — every page except the
   home page, and the home page too once scrolled. At 34px/17px it read as
   fine print next to the menu ("очень маленькая надпись"); this is the
   later, still-modest correction ("максимально увеличить" landed on the
   home-page-only treatment below instead — putting a dramatically bigger,
   animating mark on every single page turned out to cause its own bugs on
   scroll: "деспре ной и чуть-чуть скролю — вижу как бегает логотип", and
   the overflow spilling into page-hero content it, on pages far narrower
   than the home page's hero ever needed to allow for). */
.site-header .brand__mark {
  width: 40px;
  height: 40px;
  transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1), height 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-header .brand__name {
  font-size: 18px;
  transition: font-size 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-header .brand__name span { font-size: 9.5px; transition: font-size 320ms cubic-bezier(0.4, 0, 0.2, 1); }

/* The home page ONLY, and only before any scrolling — a genuinely large
   mark, deliberately taller than the (fixed-height) bar around it so it
   spills past the header's own frame top and bottom ("выезжает за рамки"),
   easing back down to the same compact size the moment .is-scrolled lands
   (toggled in main.js past 8px of scroll) or the visitor is on any other
   page. Only width/height/font-size change here — properties that affect
   just these elements' own boxes, never their fixed-size ancestors', so
   there's nothing for scroll anchoring to react to (see the .site-header
   and .site-header__bar comments above for the property that USED to
   cause that). */
.site-header.is-home:not(.is-scrolled) .brand__mark {
  width: 92px;
  height: 92px;
}
.site-header.is-home:not(.is-scrolled) .brand__name {
  font-size: 24px;
}
.site-header.is-home:not(.is-scrolled) .brand__name span {
  font-size: 10.5px;
}

@media (min-width: 768px) {
  .site-header .brand { gap: 14px; }
  .site-header__bar { height: 72px; }
  .site-header .brand__mark { width: 50px; height: 50px; }
  .site-header .brand__name { font-size: 21px; }
  .site-header .brand__name span { font-size: 11px; }

  .site-header.is-home:not(.is-scrolled) .brand { gap: 16px; }
  .site-header.is-home:not(.is-scrolled) .brand__mark { width: 130px; height: 130px; }
  .site-header.is-home:not(.is-scrolled) .brand__name { font-size: 34px; }
  .site-header.is-home:not(.is-scrolled) .brand__name span { font-size: 13px; }
}

@media (prefers-reduced-motion: reduce) {
  .site-header, .site-header__bar, .site-header .brand__mark, .site-header .brand__name, .site-header .brand__name span { transition: none; }
}

/* Footer's brand mark — unaffected by the header's scroll animation, kept
   at the original compact size (it sits in dark footer copy, not a hero
   moment). */
.footer-brand .brand__mark { width: 34px; height: 34px; }
.footer-brand .brand__name { font-size: 17px; }
.footer-brand .brand__name span { font-size: 10px; }

.main-nav { display: none; }
.main-nav__list { display: flex; align-items: center; gap: 2px; }
/* Was 13.5px/weight 500/muted ink-soft — genuinely low-contrast against a
   white header, and the "active" state was just a 3px dot easy to miss
   entirely among 8 items. Bolder weight + real size, and active/hover get
   an actual pill background instead of a dot, so "where am I" reads at a
   glance instead of requiring a close look. Font-size/padding trimmed back
   down from an earlier pass (14.5px/14px) that pushed the whole row past
   1600px wide on the RU site — a real desktop width, not just a phone —
   causing the nav to fall back to the hamburger button on an ordinary
   (non-maximized) laptop window. This size still reads fine at arm's length. */
.main-nav__list a {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-ink);
  opacity: 0.72;
  position: relative;
  padding: 8px 10px;
  border-radius: 999px;
  white-space: nowrap;
  transition: opacity var(--transition), background-color var(--transition), color var(--transition);
}
/* An underline draw on hover reads more boutique/editorial than a filled
   pill — the pill stays reserved for the is-active state, so "where am I"
   and "what's under my cursor" don't look like the same affordance. */
.main-nav__list a::after {
  content: '';
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 3px;
  height: 1px;
  background: var(--color-primary);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--transition);
}
.main-nav__list a:hover { opacity: 1; }
.main-nav__list a:hover::after { transform: scaleX(1); }
.main-nav__list a.is-active { opacity: 1; color: var(--color-primary-dark); background: var(--color-blush-deep); }
.main-nav__list a.is-active::after { display: none; }

.header-actions { display: flex; align-items: center; gap: 16px; }
.header-divider { display: none; width: 1px; height: 22px; background: var(--color-line); }

.header-phone {
  display: none;
  align-items: center;
  gap: 10px;
}
/* Bordered blush pill — was plain text, easy to skim past even at a larger
   size ("важен чтобы им звонили"). Same blush+primary-border language as
   .trust-badge and the mobile drawer's own .mobile-nav__phone-block, so the
   number reads as the one thing in the header worth a second look. */
.header-phone__number {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px 7px 12px;
  border: 1.5px solid var(--color-primary);
  border-radius: 999px;
  background: var(--color-blush);
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--color-ink);
  white-space: nowrap;
  transition: color var(--transition), background-color var(--transition), border-color var(--transition);
}
.header-phone__number svg { width: 17px; height: 17px; color: var(--color-primary); flex-shrink: 0; }
.header-phone__number:hover { color: var(--color-primary-dark); background: var(--color-blush-deep); border-color: var(--color-primary-dark); }
/* Was plain underlined text — read as a caption next to the phone number,
   not a clickable action, easy to mistake for part of "Înscrie-te acum"
   right beside it ("не видно что заказать звонок это кнопка а не запись").
   A real outlined pill (icon + border) reads as its own tappable button at
   a glance, while staying visually secondary to the filled primary CTA. */
.header-phone__callback {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--color-line);
  border-radius: 999px;
  padding: 7px 14px 7px 12px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--transition), border-color var(--transition), background-color var(--transition);
}
.header-phone__callback svg { width: 14px; height: 14px; flex-shrink: 0; }
.header-phone__callback:hover { color: var(--color-primary); border-color: var(--color-primary); background: var(--color-blush); }

.lang-switch {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.lang-switch i { font-style: normal; color: var(--color-line); }
.lang-switch a { color: var(--color-ink-soft); transition: color var(--transition); }
.lang-switch a.is-active { color: var(--color-primary); }
.lang-switch a:not(.is-active):hover { color: var(--color-ink); }
.header-actions .btn--primary { display: none; }

.nav-toggle {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  color: var(--color-ink);
}
.nav-toggle svg { width: 22px; height: 22px; }

/* Below 768px the header stays down to logo + lang switch + menu button —
   phone/CTA move to the floating mobile buttons and the drawer instead (see
   .mobile-fab, .mobile-nav__phone), so nothing crowds the row. The language
   switch is small enough to stay put at every width. */
@media (min-width: 768px) {
  .header-phone { display: inline-flex; }
  .header-divider { display: block; }
  .header-actions .btn--primary { display: inline-flex; }
}

/* Full inline nav needs logo + phone + 8 links + lang switch + CTA in one row.
   Russian labels ("Педагоги", "Расписание"...) run noticeably longer than
   Romanian, so the breakpoint has margin for the longer language, not just
   the shorter one — tuned tight for RO would wrap on the RU site.
   This breakpoint (and the nav's own font-size/padding just above) went
   through two real rounds of live measurement in the same sitting: 1460px
   measurably wrapped the RU header onto two rows, so it was first raised to
   1640px — which then showed the mobile hamburger on an ordinary
   (non-maximized) desktop window, a worse regression than the wrap it
   fixed. The nav's own size was trimmed down instead (14.5px/14px padding
   → 13.5px/10px), which brought the real no-wrap threshold back down to
   ~1460-1480px — 1500 is confirmed wrap-free with a small margin. The
   .site-header .container max-width above must stay >= this value. */
@media (min-width: 1500px) {
  .main-nav { display: block; }
  .nav-toggle { display: none; }
}

/* Mobile drawer */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 200;
  visibility: hidden;
}
.mobile-nav__backdrop {
  position: absolute; inset: 0;
  background: rgba(42, 31, 39, 0.45);
  opacity: 0;
  transition: opacity var(--transition);
}
.mobile-nav__panel {
  position: absolute;
  top: 0; right: 0;
  height: 100%;
  width: min(84vw, 360px);
  background: var(--color-white);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  transform: translateX(100%);
  transition: transform 320ms var(--ease-drawer);
}
.mobile-nav.is-open { visibility: visible; }
.mobile-nav.is-open .mobile-nav__backdrop { opacity: 1; }
.mobile-nav.is-open .mobile-nav__panel { transform: translateX(0); }
.mobile-nav__top { display: flex; align-items: center; justify-content: space-between; }
.mobile-nav__close { width: 38px; height: 38px; border-radius: 10px; border: 1px solid var(--color-line); display: grid; place-items: center; background: none; }
.mobile-nav__close svg { width: 18px; height: 18px; }

.mobile-nav__phone-block {
  margin-top: -12px;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: var(--color-blush);
}
.mobile-nav__phone { display: flex; align-items: center; gap: 12px; }
.mobile-nav__phone svg { width: 21px; height: 21px; color: var(--color-primary); flex-shrink: 0; }
.mobile-nav__phone span { display: flex; flex-direction: column; font-size: 21px; font-weight: 700; color: var(--color-ink); }
.mobile-nav__phone small { font-size: 11px; font-weight: 600; color: var(--color-ink-soft); text-transform: uppercase; letter-spacing: 0.04em; }
/* Was plain text with a 10px arrow, easy to miss/mistake for a caption next
   to the phone number rather than its own action ("не видно что заказать
   звонок это кнопка"). A small outlined pill reads as tappable at a glance. */
.mobile-nav__callback {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 10px 0 0 30px;
  background: none;
  border: 1px solid var(--color-line);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-primary-dark);
  cursor: pointer;
}
.mobile-nav__callback svg { width: 13px; height: 13px; }

.mobile-nav__list { display: flex; flex-direction: column; gap: 4px; }
.mobile-nav__list a {
  display: block;
  padding: 14px 6px;
  font-size: 18.5px;
  font-weight: 600;
  border-bottom: 1px solid var(--color-line);
}

.mobile-nav__lang { display: flex; gap: 8px; margin: 4px 0 6px; }
.mobile-nav__lang a {
  flex: 1;
  text-align: center;
  padding: 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-line);
  font-size: 13px;
  font-weight: 700;
  color: var(--color-ink-soft);
}
.mobile-nav__lang a.is-active { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-white); }

/* ==========================================================================
   Hero
   ========================================================================== */
/* Sixth pass. Full-bleed dark-scrim overlays got rejected three times
   running; the plain hairline-framed photo that replaced them (modelled
   on Berkeley Ballet's homepage) then read as "just a photo dropped in a
   box, no design intent". The actual fix was never "plain" vs "overlay" —
   it's that a photo needs SOME deliberate relationship to the rest of the
   page to read as designed rather than dropped in. Here that's a blush
   mat: the photo sits inset on a soft brand-colored panel (like a print
   mounted on colored card), tying it to the palette without darkening it
   or putting text on top of it, plus the small pinned handwritten note —
   from the original design, never one of the things that got rejected —
   back in the corner as the one extra detail. */
.hero { padding-block: 56px 40px; background: var(--color-white); }
.hero__grid {
  display: grid;
  gap: 40px;
  align-items: center;
}
.hero__copy { max-width: 560px; }
.hero .eyebrow { text-transform: none; letter-spacing: normal; font-size: 15px; font-weight: 600; }
.hero .eyebrow::before { display: none; }
.hero__title {
  font-size: clamp(36px, 6vw, 56px);
  margin-top: 16px;
  letter-spacing: -0.01em;
  color: var(--color-ink);
}
.hero__title em { font-style: normal; color: inherit; }
.hero__title .line { display: block; overflow: hidden; }
.hero__title .line-inner { display: block; }
.hero__text { margin-top: 20px; font-size: 17px; line-height: 1.75; color: var(--color-ink-soft); max-width: 460px; }
.hero__actions { margin-top: 28px; display: flex; flex-wrap: wrap; align-items: center; gap: 26px; }
.hero__meta { margin-top: 18px; font-size: 13.5px; color: var(--color-ink-soft); }

/* Free-trial trust pill — the one thing the founder specifically asked
   back after it went missing in the previous pass. */
.trust-badge {
  display: inline-flex; align-items: flex-start; gap: 9px; margin-top: 22px;
  padding: 10px 18px 10px 14px; border-radius: 18px; max-width: 440px;
  background: var(--color-blush-deep); color: var(--color-primary-dark);
  font-size: 13.5px; font-weight: 700; line-height: 1.5;
}
.trust-badge svg { width: 18px; height: 18px; flex-shrink: 0; }
.trust-badge__emoji { font-size: 16px; line-height: 1.3; flex-shrink: 0; }
.trust-badge strong { color: var(--color-primary); }

/* Eighth pass. Every version until now was some variant of "one photo,
   held in some frame" — a blur, an arch, a mask, a dark scrim, a curtain,
   a hairline border, a colored mat, an ink mat — and each one drew the
   same complaint back regardless of the frame, because the FRAME was
   never the axis that needed to change. This drops the single-photo-in-
   a-box format entirely: two photographs, different sizes, offset from
   each other, floating directly on the page with nothing behind them —
   no mat, no border, no dark panel. The pairing tells an actual story
   (backstage before the show, then the stage itself) instead of being
   one static image, and the offset overlap is what makes it read as
   composed rather than "a photo dropped in" — the thing that was
   missing from the plain version — without needing a frame to do it. */
.hero__media {
  position: relative;
  margin-bottom: 12%;
}
.hero__photo {
  display: block;
  object-fit: cover;
  border-radius: 14px;
  box-shadow: 0 24px 48px -20px rgba(42, 31, 39, 0.35);
}
.hero__photo--main {
  width: 76%;
  aspect-ratio: 4 / 5;
  object-position: 50% 30%;
}
/* Positioned past the main photo's own bottom edge (not just bottom:0,
   which would tuck it fully inside the main photo's height) so it visibly
   overhangs — that overhang is what reads as two separate photographs
   arranged on the page, not one image with a small inset corner. The
   container's own margin-bottom above reserves room for the overhang so
   it never collides with the marquee strip below. */
.hero__photo--accent {
  position: absolute;
  right: 0;
  bottom: -12%;
  width: 50%;
  aspect-ratio: 4 / 3;
  object-position: 50% 45%;
  border: 5px solid var(--color-white);
  transform: rotate(3deg);
  z-index: 2;
}

.hero__achievement {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 200px;
  background: var(--color-white);
  border-radius: 999px;
  padding: 9px 16px 9px 11px;
  box-shadow: var(--shadow-card);
  animation: hero-achievement-float 4.5s ease-in-out infinite;
}
.hero__achievement svg { width: 22px; height: 22px; color: var(--color-gold); flex-shrink: 0; }
.hero__achievement strong { display: block; font-family: var(--font-display); font-size: 12.5px; line-height: 1.25; color: var(--color-ink); }
.hero__achievement span > span { display: block; font-size: 10.5px; color: var(--color-ink-soft); margin-top: 2px; }
@keyframes hero-achievement-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__achievement { animation: none; }
}

@media (min-width: 1024px) {
  .hero { padding-block: 64px 48px; }
  .hero__grid { grid-template-columns: 1fr 1fr; gap: 64px; }
}

/* Infinite marquee strip — length-agnostic, so it never breaks across languages */
.marquee {
  margin-top: 64px;
  padding-block: 18px;
  background: var(--color-ink);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee__track {
  display: flex;
  width: max-content;
  gap: 28px;
  animation: marquee-scroll 32s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.88);
  font-size: 14px;
  font-weight: 500;
}
.marquee__item svg { width: 18px; height: 18px; color: var(--color-primary-light); flex-shrink: 0; }
.marquee__item::after {
  content: "";
  width: 5px; height: 5px;
  margin-left: 28px;
  border-radius: 50%;
  background: var(--color-primary);
  flex-shrink: 0;
  display: inline-block;
}

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* ==========================================================================
   Directions / Cursuri
   ========================================================================== */
.section-head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 36px;
  flex-wrap: wrap;
}
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--color-primary-dark);
  font-size: 15px;
}
.link-arrow svg { width: 16px; height: 16px; transition: transform var(--transition); }
.link-arrow:hover svg { transform: translateX(4px); }

/* "Нужно как-то сделать чтоб в ряд были" — a fixed 2/4-column grid left a
   5-card section (hobby, once "Balet pentru adulți" was added) with one
   card alone on its own row, and would do the same to any section whose
   count isn't a clean multiple of the column count (the 3-card professional
   section too, at 4 columns). auto-fit sizes columns to how many actually
   fit AND collapses any left over for the item count present — a 5-card
   row gets 5 even columns, a 3-card row gets 3 wider ones, never a lonely
   leftover, at any width including mobile (same idiom already used for
   this exact problem on the admin dashboard's own panel grid). */
.direction-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
@media (min-width: 900px) {
  .direction-grid { grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr)); }
}

.direction-card {
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 3 / 4;
  color: var(--color-white);
  box-shadow: var(--shadow-card);
}
.direction-card img { width: 100%; height: 100%; object-fit: cover; transition: transform 500ms ease; }
.direction-card__scrim {
  position: absolute; inset: 0;
  /* Darkens from the very top (not just the lower third) so title/age text
     stays legible no matter how bright the underlying photo is in that spot. */
  background: linear-gradient(180deg, rgba(42, 31, 39, 0.15) 0%, rgba(42, 31, 39, 0.35) 45%, rgba(42, 31, 39, 0.92) 100%);
}
.direction-card__body { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.45); }
.direction-card__age { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; color: var(--color-primary-light); text-transform: uppercase; }
.direction-card__title { font-family: var(--font-display); font-size: 19px; margin-top: 6px; }
.direction-card__sub { font-size: 12px; opacity: 0.9; margin-top: 4px; }
.direction-card__go {
  position: absolute;
  top: 14px; right: 14px;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,0.92);
  color: var(--color-primary-dark);
  display: grid; place-items: center;
  transition: transform var(--transition), background var(--transition);
}
.direction-card__go svg { width: 15px; height: 15px; }

/* ==========================================================================
   How it works (3-step process)
   ========================================================================== */
.steps-grid { display: grid; gap: 24px; margin-top: 44px; }
@media (min-width: 760px) { .steps-grid { grid-template-columns: repeat(3, 1fr); } }
.step-card { position: relative; padding: 8px 8px 0; }
.step-card__num {
  display: flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 50%;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
  color: var(--color-white); font-family: var(--font-display); font-size: 22px;
  margin-bottom: 18px;
}
.step-card h3 { font-family: var(--font-display); font-size: 20px; margin-bottom: 8px; }
.step-card p { color: var(--color-ink-soft); font-size: 14.5px; line-height: 1.6; }
.steps-grid__cta { display: flex; justify-content: center; margin-top: 40px; }

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq-list { max-width: 720px; margin: 40px auto 0; display: flex; flex-direction: column; gap: 12px; }
.faq-item {
  background: var(--color-white); border: 1px solid var(--color-blush-deep);
  border-radius: var(--radius-md); padding: 4px 22px;
}
.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 0; font-weight: 700; font-size: 15.5px; cursor: pointer;
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item__chevron { width: 20px; height: 20px; color: var(--color-primary); flex-shrink: 0; transition: transform var(--transition); }
.faq-item[open] .faq-item__chevron { transform: rotate(180deg); }
.faq-item p { padding-bottom: 20px; margin: 0; color: var(--color-ink-soft); font-size: 14.5px; line-height: 1.7; }

/* ==========================================================================
   About
   ========================================================================== */
.about__grid { display: grid; gap: 40px; align-items: center; }
@media (min-width: 960px) { .about__grid { grid-template-columns: 0.9fr 1.1fr; gap: 60px; } }

.about__media { position: relative; }
.about__media img { border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); width: 100%; aspect-ratio: 5/4; object-fit: cover; }
.about__badge {
  position: absolute;
  left: -18px; bottom: -18px;
  background: var(--color-white);
  padding: 16px 20px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 240px;
}
.about__badge svg { width: 26px; height: 26px; color: var(--color-primary); flex-shrink: 0; }
.about__badge strong { display: block; font-family: var(--font-display); font-weight: 600; font-size: 15px; }
.about__badge span { font-size: 12px; color: var(--color-ink-soft); }

.about__stats {
  margin-top: 30px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  padding-top: 26px;
  border-top: 1px solid var(--color-line);
}
.about__stats strong {
  display: flex;
  align-items: flex-start;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(32px, 4vw, 44px);
  line-height: 1;
  color: var(--color-primary-dark);
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
}
.about__stats strong .plus {
  font-size: 0.42em;
  margin-left: 2px;
  color: var(--color-primary);
}
.about__stats span { display: block; margin-top: 8px; font-size: 13px; line-height: 1.4; color: var(--color-ink-soft); }

/* Branch cards on the About page — text-only for now (no branch photos yet,
   the founder is sourcing them); a photo slot can be added to this card
   later without restructuring it. */
.branch-grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); margin-top: 32px; }
.branch-card { background: var(--color-white); border-radius: var(--radius-md); padding: 28px; box-shadow: var(--shadow-card); overflow: hidden; }
.branch-card__photo { width: calc(100% + 56px); margin: -28px -28px 20px; display: block; aspect-ratio: 16 / 10; object-fit: cover; }
.branch-card h3 { font-size: 20px; }
.branch-card__row { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: 14.5px; color: var(--color-ink-soft); }
.branch-card__row svg { width: 18px; height: 18px; color: var(--color-primary); flex-shrink: 0; }
.branch-card__row a { color: inherit; }
.branch-card__row a:hover { color: var(--color-primary); }

/* ==========================================================================
   Teachers
   ========================================================================== */
.teacher-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
@media (min-width: 900px) { .teacher-grid { grid-template-columns: repeat(4, 1fr); } }

.teacher-swiper { padding-bottom: 4px; }
.teacher-swiper .swiper-slide { width: 78vw; max-width: 260px; }
@media (min-width: 640px) { .teacher-swiper .swiper-slide { width: 45vw; max-width: 260px; } }
@media (min-width: 900px) { .teacher-swiper .swiper-slide { width: 23vw; max-width: 280px; } }

.teacher-nav { display: flex; gap: 10px; margin-top: 24px; justify-content: center; }
.teacher-nav button {
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid var(--color-line);
  background: var(--color-white);
  display: grid; place-items: center;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.teacher-nav button svg { width: 16px; height: 16px; }
.teacher-nav button:hover { background: var(--color-primary); color: var(--color-white); border-color: var(--color-primary); }

.teacher-card { text-align: left; min-width: 0; }
.teacher-card__photo {
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 3/4;
  box-shadow: var(--shadow-card);
}
.teacher-card__photo img { width: 100%; height: 100%; object-fit: cover; transition: transform 500ms ease; }
.teacher-card__social {
  position: absolute;
  left: 12px; bottom: 12px;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: rgba(255,255,255,0.94);
  color: var(--color-primary-dark);
  display: grid; place-items: center;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--transition), transform var(--transition);
}
.teacher-card__social svg { width: 15px; height: 15px; }
.teacher-card__name { margin-top: 14px; font-family: var(--font-display); font-size: 16px; }
.teacher-card__role { margin-top: 3px; font-size: 13px; color: var(--color-ink-soft); }
.teacher-card__bio { margin-top: 8px; font-size: 13px; color: var(--color-ink-soft); line-height: 1.6; }
.teacher-card__cta { margin-top: 14px; white-space: normal; text-align: center; }

/* ==========================================================================
   Highlight strip (video + gallery teaser)
   ========================================================================== */
.highlight { display: grid; gap: 18px; }
@media (min-width: 960px) { .highlight { grid-template-columns: 1.3fr 0.7fr 0.9fr; } }

.highlight__video {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  min-height: 320px;
  box-shadow: var(--shadow-card);
}
.highlight__video img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.highlight__video::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(42,31,39,0.1), rgba(42,31,39,0.75));
}
.highlight__video-body { position: relative; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; padding: 28px; color: var(--color-white); gap: 16px; min-height: 320px; }
.highlight__video-body h3 { font-size: clamp(22px, 2.6vw, 28px); max-width: 320px; }
.highlight__video .play-btn { color: var(--color-white); }

.highlight__thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (min-width: 960px) { .highlight__thumbs { grid-template-columns: 1fr; grid-template-rows: repeat(3, 1fr); } }
.highlight__thumbs a { border-radius: var(--radius-sm); overflow: hidden; aspect-ratio: 1/1; box-shadow: var(--shadow-card); }
.highlight__thumbs img { width: 100%; height: 100%; object-fit: cover; transition: transform 400ms ease; }

.highlight__copy {
  background: var(--color-ink);
  color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: 32px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 320px;
}
.highlight__copy h3 { font-size: clamp(24px, 3vw, 30px); line-height: 1.2; }
.highlight__copy .link-arrow { color: var(--color-primary-light); margin-top: 24px; }

/* ==========================================================================
   Testimonials
   ========================================================================== */
.testimonial-track { display: flex; gap: 20px; overflow: hidden; }
.testimonial-card {
  flex: 0 0 auto;
  width: min(360px, 82vw);
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 26px;
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.testimonial-card__stars { display: flex; gap: 3px; color: var(--color-gold); }
.testimonial-card__stars svg { width: 15px; height: 15px; }
.testimonial-card__quote { font-size: 15px; line-height: 1.7; color: var(--color-ink); }
.testimonial-card__author { display: flex; align-items: center; gap: 12px; margin-top: auto; }
.testimonial-card__author img { width: 42px; height: 42px; border-radius: 50%; object-fit: cover; }
.testimonial-card__author .testimonial-card__initial {
  width: 42px; height: 42px; flex-shrink: 0; border-radius: 50%;
  background: var(--color-blush-deep); color: var(--color-primary-dark);
  display: grid; place-items: center; font-family: var(--font-display); font-size: 16px; font-weight: 600;
}
.testimonial-card__author strong { display: block; font-size: 14px; }
.testimonial-card__author span { font-size: 12px; color: var(--color-ink-soft); }

.testimonial-nav { display: flex; gap: 10px; margin-top: 28px; justify-content: center; }
.testimonial-nav button {
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid var(--color-line);
  background: var(--color-white);
  display: grid; place-items: center;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.testimonial-nav button svg { width: 16px; height: 16px; }
.testimonial-nav button:hover { background: var(--color-primary); color: var(--color-white); border-color: var(--color-primary); }

/* ==========================================================================
   Schedule
   ========================================================================== */
/* min-width:0 on the grid ITEMS, not just the container: a grid item defaults
   to min-width:auto, so its own min-content (a nowrap teacher name, the
   "Înscrie-te" button, a time range) can force the whole track wider than the
   grid box. That is exactly what was happening here — measured live on a
   375px viewport: the layout box was 335px but its children rendered 379px,
   so every schedule card stuck ~24px past the right edge of the phone screen
   and the page could be dragged sideways. Founder reported it as "на лендинге
   съезжают поля, именно где занятия". Same bug class as .teacher-card. */
.schedule__layout { display: grid; gap: 32px; }
.schedule__layout > * { min-width: 0; }

/* Legal pages (terms / privacy) ------------------------------------------
   Both pages hand-wrote the same "font-size:20px; margin-bottom:10px"
   inline on every single <h2> — 11 copies in one file, 10 in the other,
   each free to drift. One class instead, matching the same clean-up done
   for the admin's button variants. */
.legal-doc {
  display: flex; flex-direction: column; gap: 28px;
  color: var(--color-ink); line-height: 1.75; font-size: 15px;
}
.legal-doc h2 { font-size: 20px; margin-bottom: 10px; }
@media (min-width: 960px) { .schedule__layout { grid-template-columns: 1.35fr 1fr; align-items: start; } }

.day-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.day-tabs button,
.day-tabs a {
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid var(--color-line);
  background: var(--color-white);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-ink-soft);
  text-decoration: none;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.day-tabs button.is-active,
.day-tabs button:hover,
.day-tabs a.is-active,
.day-tabs a:hover { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-white); }

/* A small caption above each tab row + a distinct look for branch tabs
   (dark fill instead of the day-tabs' pink) — otherwise "Centru/Ciocana"
   and "Luni/Marți" read as one undifferentiated cluster of pills with no
   visual cue for which row picks a location and which picks a day. */
.tabs-label { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-ink-soft); margin: 0 0 8px; }
.branch-tabs button { display: inline-flex; align-items: center; gap: 6px; }
.branch-tabs__pin { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.65; }
.branch-tabs button.is-active,
.branch-tabs button:hover { background: var(--color-ink); border-color: var(--color-ink); color: var(--color-white); }
.branch-tabs button.is-active .branch-tabs__pin,
.branch-tabs button:hover .branch-tabs__pin { opacity: 1; }

/* Shown on /program when reached via a specific homepage direction card
   ("Balet pentru cei mici" etc.) instead of the generic "Vezi programul
   complet" link — same idea as the admin calendar's own group filter
   banner, so a visitor immediately understands why they're seeing a
   shorter schedule than they might expect. */
.schedule-filter-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--color-blush); border: 1px solid var(--color-line);
  border-radius: var(--radius-sm); padding: 12px 16px;
  margin-bottom: 20px; font-size: 14px; color: var(--color-ink-soft);
}
.schedule-filter-banner strong { color: var(--color-ink); }
.schedule-filter-banner a { color: var(--color-primary-dark); font-weight: 600; margin-left: auto; }
.schedule-filter-banner a:hover { color: var(--color-primary); }

.schedule-group-filter select {
  width: 100%; max-width: 360px;
  padding: 13px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-line);
  background: var(--color-blush);
  font-family: inherit;
  font-size: 14px;
  color: var(--color-ink);
  transition: border-color var(--transition), background var(--transition);
}
.schedule-group-filter select:focus { outline: none; border-color: var(--color-primary); background: var(--color-white); }

.schedule-list { display: flex; flex-direction: column; gap: 12px; }
.schedule-row {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 16px 18px;
  border-radius: var(--radius-sm);
  background: var(--color-blush);
  border: 1px solid var(--color-line);
}
.schedule-row__time { font-weight: 700; color: var(--color-primary-dark); font-size: 14px; }
.schedule-row__title { font-weight: 600; font-size: 15px; }
.schedule-row__meta { font-size: 13px; color: var(--color-ink-soft); margin-top: 2px; }
.schedule-row__teacher { font-size: 13px; color: var(--color-ink-soft); text-align: right; white-space: nowrap; }
.schedule-row__cta { white-space: nowrap; }
.schedule-empty { padding: 32px; text-align: center; color: var(--color-ink-soft); border: 1px dashed var(--color-line); border-radius: var(--radius-sm); }

@media (max-width: 560px) {
  /* Below ~560px the 3-column layout gets too tight for time + title + a
     real tap target for the sign-up button — stack it instead so the button
     stays full-width and easy to tap rather than shrinking to nothing. */
  .schedule-row { grid-template-columns: 1fr; gap: 8px; }
  .schedule-row__cta { width: 100%; }
}

/* Lead form ---------------------------------------------------------------*/
.lead-card {
  background: var(--color-white);
  border-radius: var(--radius-lg);
  padding: 30px;
  box-shadow: var(--shadow-soft);
  border: 1px solid var(--color-line);
}
.lead-card h3 { font-size: 22px; }
.lead-card p { margin-top: 8px; color: var(--color-ink-soft); font-size: 14px; line-height: 1.6; }

.lead-card--cta { text-align: left; }
.lead-card__icon {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--color-blush);
  color: var(--color-primary);
  display: grid;
  place-items: center;
  margin-bottom: 6px;
}
.lead-card__icon svg { width: 26px; height: 26px; }
.lead-card__points { margin-top: 20px; margin-bottom: 24px; display: flex; flex-direction: column; gap: 12px; }
.lead-card__points li { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--color-ink); }
.lead-card__points svg { width: 18px; height: 18px; color: var(--color-primary); flex-shrink: 0; }
.lead-card__points-highlight { font-weight: 700; color: var(--color-primary-dark); }

.field { margin-top: 16px; }
/* Pairs 2 fields side by side (name+phone, branch+group) instead of
   stacking — real vertical-height savings on a form that otherwise needs
   scrolling to reach the submit button once every optional field is open.
   Each child .field keeps its own margin-top, so the row itself needs none. */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
.field-row .field { margin-top: 16px; }
@media (max-width: 340px) { .field-row { grid-template-columns: 1fr; } }
.field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--color-ink); }
/* font-size must stay >= 16px — iOS Safari auto-zooms the whole page in on
   focus of any input under 16px, then has to zoom back out on blur/submit.
   That handoff, landing right on top of the modal's own scroll-lock/close
   animation, is what read as "масштаб сбился... прокрутилась и потом
   обратно" — the form itself worked, the zoom glitch just looked broken. */
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 13px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-line);
  background: var(--color-blush);
  font-family: inherit;
  font-size: 16px;
  color: var(--color-ink);
  transition: border-color var(--transition), background var(--transition);
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  background: var(--color-white);
}
.field textarea { resize: vertical; min-height: 84px; }
.field-error { display: none; margin-top: 6px; font-size: 12px; color: #c62828; }
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: #c62828; }
.field.has-error .field-error { display: block; }
.field--honeypot { position: absolute; left: -9999px; top: -9999px; }

.field-hint {
  margin-top: 8px;
  font-size: 12px;
  color: var(--color-primary-dark);
  background: var(--color-blush);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
}
/* A JS-driven hint (the phone field's live normalised preview) starts
   empty — without this, an empty .field-hint would still render as a
   padded pink box with nothing in it. */
.field-hint:empty { display: none; }

/* Trial-vs-direct-enrollment choice on the lead form — optional, so neither
   option looks pre-selected/required the way a real form control would. */
.choice-toggle { display: flex; gap: 8px; }
.choice-toggle__option {
  flex: 1;
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-line);
  background: var(--color-blush);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-ink-soft);
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease, transform 150ms var(--ease-out);
}
.choice-toggle__option:hover { border-color: var(--color-primary-light); }
.choice-toggle__option:active { transform: scale(0.97); }
.choice-toggle__option.is-active { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-white); }

.link-arrow--sm {
  margin-top: 10px;
  font-size: 13px;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.field--callback .callback-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--color-blush);
  border: 1px solid var(--color-line);
  font-size: 13px;
  color: var(--color-ink-soft);
  line-height: 1.5;
}
.field--callback .callback-note svg { width: 18px; height: 18px; color: var(--color-primary); flex-shrink: 0; margin-top: 1px; }

.checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
}
.checkbox-label input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: var(--color-primary);
}
.checkbox-label span {
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-ink-soft);
}
.checkbox-label a { color: var(--color-primary-dark); font-weight: 600; text-decoration: underline; }
.field--checkbox.has-error .checkbox-label span { color: #c62828; }

.form-note { margin-top: 14px; font-size: 12px; color: var(--color-ink-soft); text-align: center; }
.form-alert { margin-top: 16px; padding: 12px 16px; border-radius: var(--radius-sm); font-size: 14px; display: none; }
.form-alert.is-visible { display: block; }
.form-alert--success { background: #e5f7ee; color: #1c7a4b; }
.form-alert--error { background: #fdecec; color: #b3261e; }

/* ==========================================================================
   Photo band — a photographic break between two text-heavy sections, so
   the page isn't just white section after white section. A real photo
   (not a color swap), with a proper dark scrim for contrast — a
   deliberate one-time visual beat.
   Contained in a rounded card within the normal page width now, NOT
   edge-to-edge full-bleed — real bug, live-reported: every stock photo in
   this asset set tops out at 1400px wide (checked all 6 gallery images),
   so a true full-bleed `width:100%` band on any screen wider than that
   forced the browser to upscale PAST the image's native resolution
   (object-fit:cover scales to whichever dimension needs it more, so a
   shorter band doesn't help — only a narrower one does), which read as
   "stretched"/blurry. The page's own `--container` is 1240px, safely
   under 1400px, so contained here the image never upscales. `min-height:
   62vh` on top of that made it visually swallow the whole screen on a
   typical laptop — replaced with a fixed, modest `min-height`. */
.photo-band { padding-block: 72px; }
.photo-band__frame {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-soft);
  min-height: 380px; display: flex; align-items: center;
}
.photo-band__media { position: absolute; inset: 0; z-index: 0; }
.photo-band__media img { width: 100%; height: 100%; object-fit: cover; }
.photo-band__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(20, 14, 18, 0.35) 0%, rgba(20, 14, 18, 0.72) 100%);
}
.photo-band__content { position: relative; z-index: 1; max-width: 560px; color: var(--color-white); padding: 36px; }
.photo-band__content .script-text { color: var(--color-primary-light); }
.photo-band__quote { font-family: var(--font-display); font-size: clamp(20px, 2.6vw, 28px); line-height: 1.4; margin-top: 14px; margin-bottom: 28px; }
@media (max-width: 767.98px) {
  .photo-band__frame { min-height: 320px; }
  .photo-band__content { padding: 24px; }
}

/* ==========================================================================
   CTA banner
   ========================================================================== */
.cta-banner {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding: 56px 32px;
  text-align: center;
  color: var(--color-white);
  background: linear-gradient(135deg, var(--color-primary-dark), var(--color-primary));
}
.cta-banner__title { font-size: clamp(26px, 4vw, 38px); max-width: 640px; margin-inline: auto; }
.cta-banner .script-text { color: rgba(255,255,255,0.85); }
.cta-banner__actions { margin-top: 26px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.cta-banner__note { font-size: 13px; font-weight: 700; letter-spacing: 0.03em; color: rgba(255,255,255,0.8); }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer { background: var(--color-ink); color: rgba(255,255,255,0.75); padding-block: 56px 24px; }
.footer-grid {
  display: grid;
  gap: 40px;
  grid-template-columns: 1fr;
}
@media (min-width: 860px) { .footer-grid { grid-template-columns: 1.2fr 0.8fr 1.1fr; } }

.footer-brand .brand__name { color: var(--color-white); }
.footer-brand .brand__name span { color: rgba(255,255,255,0.5); }
.footer-brand p { margin-top: 16px; font-size: 14px; line-height: 1.7; max-width: 280px; }
.footer-social { display: flex; gap: 10px; margin-top: 20px; }
.footer-social a {
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.2);
  display: grid; place-items: center;
  transition: background var(--transition), border-color var(--transition);
}
.footer-social a svg { width: 16px; height: 16px; }
.footer-social a:hover { background: var(--color-primary); border-color: var(--color-primary); }

.footer-col h4 { color: var(--color-white); font-size: 15px; margin-bottom: 16px; font-family: var(--font-body); font-weight: 700; }
.footer-col ul { display: flex; flex-direction: column; gap: 10px; }
.footer-col a, .footer-col li { font-size: 14px; }
.footer-col a:hover { color: var(--color-white); }

.footer-contact li { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.5; }
.footer-contact svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 2px; color: var(--color-primary-light); }


.footer-bottom {
  margin-top: 44px;
  padding-top: 22px;
  border-top: 1px solid rgba(255,255,255,0.12);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  font-size: 13px;
}
.footer-bottom a:hover { color: var(--color-white); }

/* ==========================================================================
   Inner page header (Teachers / Gallery / Schedule)
   ========================================================================== */
.page-hero {
  padding-block: 56px 40px;
  text-align: center;
  background: var(--color-blush);
  border-bottom: 1px solid var(--color-line);
}
.breadcrumb { font-size: 13px; color: var(--color-ink-soft); display: flex; gap: 6px; justify-content: center; margin-bottom: 14px; }
.breadcrumb a:hover { color: var(--color-primary); }

/* Gallery page ------------------------------------------------------------*/
.gallery-filters { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 32px; }
.gallery-filters--category { margin-top: -16px; }
.gallery-filters--category button { font-size: 12.5px; padding: 8px 14px; }
.gallery-filters button {
  padding: 10px 20px; border-radius: 999px; border: 1px solid var(--color-line);
  background: var(--color-white); font-weight: 600; font-size: 14px; color: var(--color-ink-soft);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.gallery-filters button.is-active, .gallery-filters button:hover { background: var(--color-primary); color: var(--color-white); border-color: var(--color-primary); }

.gallery-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
@media (min-width: 700px) { .gallery-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .gallery-grid { grid-template-columns: repeat(4, 1fr); } }

.gallery-item {
  position: relative; border-radius: var(--radius-sm); overflow: hidden; aspect-ratio: 1/1;
  box-shadow: var(--shadow-card);
  border: 0; padding: 0; background: none; display: block; width: 100%;
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 450ms ease; }
.gallery-item__badge {
  position: absolute; top: 10px; right: 10px;
  width: 32px; height: 32px; border-radius: 50%;
  background: rgba(255,255,255,0.92); color: var(--color-primary-dark);
  display: grid; place-items: center;
}
.gallery-item__badge svg { width: 14px; height: 14px; }

.lightbox {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(20, 12, 16, 0.92);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.lightbox.is-open { display: flex; }
.lightbox__frame { max-width: 900px; width: 100%; }
.lightbox__frame img, .lightbox__frame iframe { width: 100%; border-radius: var(--radius-md); aspect-ratio: 16/10; object-fit: contain; background: var(--color-ink); }
.lightbox__frame video {
  width: 100%;
  border-radius: var(--radius-md);
  /* Standard video ratio, not the photo frame's 16/10 — a real video
     rarely IS 16/10, so reusing that box left visible letterbox bars that
     (combined with the plain black fill) read as "just a bare browser
     player" rather than a designed piece of the page. */
  aspect-ratio: 16/9;
  object-fit: contain;
  background: var(--color-ink);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6);
}
.lightbox__close {
  position: absolute; top: 20px; right: 20px;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(255,255,255,0.12); color: var(--color-white);
  display: grid; place-items: center; border: 1px solid rgba(255,255,255,0.2);
}
.lightbox__close svg { width: 18px; height: 18px; }

/* Full schedule page --------------------------------------------------------*/
.schedule-table-wrap { overflow-x: auto; }
.schedule-page-grid { display: grid; gap: 16px; }
/* Bare `1fr` has an implicit min of `auto`, so a column can never shrink
   below its own content's min-content width — with a long enough group
   title/teacher name (more likely in RU than RO, e.g. "Балет для начинающих")
   the 3 columns' combined minimum exceeded the real available width and
   pushed the whole page into a horizontal scroll. `minmax(0, 1fr)` lets a
   column actually shrink and wrap its text instead. */
@media (min-width: 860px) { .schedule-page-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .schedule-page-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.day-column {
  background: var(--color-white);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 20px;
}
.day-column h3 { font-size: 17px; margin-bottom: 14px; color: var(--color-primary-dark); }
.day-column .schedule-row { background: var(--color-blush); }

/* Teachers full page --------------------------------------------------------*/
.teacher-grid--page { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 700px) { .teacher-grid--page { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .teacher-grid--page { grid-template-columns: repeat(4, 1fr); } }

/* Reveal-on-scroll base (state set only via JS to keep no-JS content visible) */
.js .reveal { will-change: transform, opacity; }

/* ==========================================================================
   Lead capture modal
   ========================================================================== */
body.modal-open { overflow: hidden; }

.lead-modal {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.lead-modal.is-open { display: flex; }

.lead-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 12, 16, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.lead-modal__panel {
  position: relative;
  width: min(480px, 100%);
  max-height: 90vh;
  background: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: 0 40px 80px -20px rgba(20, 12, 16, 0.45);
  /* Does NOT scroll — .lead-modal__close is an absolutely-positioned child
     of THIS element, not of .lead-modal__scroll below, so it stays pinned
     to the corner instead of scrolling away with the form content. */
  overflow: hidden;
}

/* The actual scrolling container — kept separate from .lead-modal__panel
   above so the close button (a sibling, not a child of this) never moves. */
.lead-modal__scroll {
  max-height: 90vh;
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 40px 32px 32px;
  /* Scroll shadows: a soft edge fades in at the top/bottom the moment
     there's more content that way, and disappears once fully scrolled —
     the only hint (since the scrollbar itself stays invisible) that the
     form continues below the fold instead of just looking cut off. */
  background-image:
    linear-gradient(var(--color-white) 30%, rgba(255, 255, 255, 0)),
    linear-gradient(rgba(255, 255, 255, 0), var(--color-white) 70%),
    radial-gradient(farthest-side at 50% 0, rgba(42, 31, 39, 0.18), rgba(42, 31, 39, 0)),
    radial-gradient(farthest-side at 50% 100%, rgba(42, 31, 39, 0.18), rgba(42, 31, 39, 0));
  background-repeat: no-repeat;
  background-position: top, bottom, top, bottom;
  background-size: 100% 40px, 100% 40px, 100% 12px, 100% 12px;
  background-attachment: local, local, scroll, scroll;
}
@media (min-width: 560px) { .lead-modal__scroll { padding: 44px 40px 36px; } }

/* Submit button pinned to the bottom of the scrolling panel — a long form
   (teacher context banner + every optional field open) could otherwise
   scroll the button out of sight with no obvious sign there's more below;
   this keeps it reachable no matter how tall the form gets, cheaper than
   trying to guess how short the form needs to stay. Negative margins pull
   it flush with the panel's own edges (must track the padding above) and a
   solid background hides content scrolling underneath it. */
.lead-modal__submit-bar {
  position: sticky;
  bottom: -32px;
  z-index: 2;
  margin: 16px -32px -32px;
  padding: 16px 32px 32px;
  background: var(--color-white);
}
.lead-modal__submit-bar::before {
  content: '';
  position: absolute;
  top: -18px;
  left: 0;
  right: 0;
  height: 18px;
  background: linear-gradient(rgba(255, 255, 255, 0), var(--color-white));
  pointer-events: none;
}
.lead-modal__submit-bar .form-note { margin-top: 10px; margin-bottom: 0; }
@media (min-width: 560px) {
  .lead-modal__submit-bar { bottom: -36px; margin: 16px -40px -36px; padding: 16px 40px 36px; }
}

.lead-modal__close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--color-line);
  background: var(--color-white);
  display: grid;
  place-items: center;
  color: var(--color-ink-soft);
  transition: background var(--transition), color var(--transition), transform var(--transition);
}
.lead-modal__close:hover { background: var(--color-blush); color: var(--color-primary); transform: rotate(90deg); }
.lead-modal__close svg { width: 16px; height: 16px; }

.lead-modal__intro h3 { font-size: 24px; margin-top: 8px; }
.lead-modal__intro p { margin-top: 8px; color: var(--color-ink-soft); font-size: 14px; line-height: 1.6; }
.lead-modal form { margin-top: 4px; }

.lead-modal__teacher {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--color-blush);
  border: 1px solid var(--color-line);
}
.lead-modal__teacher img { width: 42px; height: 42px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.lead-modal__teacher span { display: block; font-size: 12px; color: var(--color-ink-soft); }
.lead-modal__teacher strong { display: block; font-size: 14px; color: var(--color-primary-dark); margin-top: 1px; }

.lead-modal__scroll::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* Success state — replaces the form outright instead of a brief alert that
   auto-closes, so a parent never has to guess whether the request actually
   went through. Stays until they close it themselves. */
.lead-modal__success {
  text-align: center;
  padding: 12px 4px 4px;
  animation: lead-success-in 420ms var(--ease-out, ease-out);
}
@keyframes lead-success-in {
  from { opacity: 0; transform: scale(0.95); }
  to { opacity: 1; transform: scale(1); }
}
.lead-modal__success-icon {
  display: flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; margin: 0 auto 16px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
  color: #fff;
}
.lead-modal__success-icon svg { width: 28px; height: 28px; }
.lead-modal__success h3 { font-size: 22px; }
.lead-modal__success p { margin-top: 10px; color: var(--color-ink-soft); font-size: 14.5px; line-height: 1.6; }
.lead-modal__success .btn { margin-top: 22px; }

/* ==========================================================================
   Mobile floating call/sign-up buttons — a small, corner-anchored pair
   instead of a full-width bar, so they read as a deliberate feature (the
   pattern visitors already know from WhatsApp/chat widgets) rather than a
   slab blocking the page. Call has a soft pulsing ring so it draws the eye
   without being asked to.
   ========================================================================== */
.mobile-fabs {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 150;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  padding-bottom: env(safe-area-inset-bottom, 0);
  transition: opacity var(--transition), transform var(--transition);
}
/* Hidden while the hero's own matching buttons are on screen (see main.js) —
   JS-driven, so it only ever hides them on a browser that can actually
   detect that and show them again; no-JS/older-browser visitors keep the
   floating pair visible throughout, same as before this existed. */
.mobile-fabs.is-hidden { opacity: 0; transform: translateY(12px); pointer-events: none; }

.mobile-fab {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 46px;
  padding: 0 16px 0 4px;
  border-radius: 999px;
  border: 0;
  box-shadow: 0 10px 24px -8px rgba(42, 31, 39, 0.45);
  transition: transform 150ms var(--ease-out), box-shadow var(--transition);
}
.mobile-fab:active { transform: scale(0.95); }

.mobile-fab__icon {
  position: relative;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.18);
}
.mobile-fab__icon svg { width: 18px; height: 18px; position: relative; z-index: 1; }

.mobile-fab__label { font-size: 14px; font-weight: 700; color: var(--color-white); white-space: nowrap; }

.mobile-fab--signup { background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark)); }

.mobile-fab--call { background: var(--color-ink); }
.mobile-fab__ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--color-primary);
  opacity: 0.6;
  animation: fab-pulse 2.4s ease-out infinite;
}

@keyframes fab-pulse {
  0% { transform: scale(1); opacity: 0.5; }
  75% { transform: scale(1.6); opacity: 0; }
  100% { transform: scale(1.6); opacity: 0; }
}

@media (min-width: 768px) {
  .mobile-fabs { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-fab__ring { animation: none; }
}

/* ==========================================================================
   Exit-intent / scroll-depth nudge — shown at most once per visit (desktop:
   mouse leaves toward the tab bar; mobile: scrolled past ~60% without
   opening the sign-up form yet), reminding an undecided visitor the trial
   is free before they leave. Bottom-left so it never fights the bottom-
   right mobile call/sign-up buttons for the same corner.
   ========================================================================== */
.exit-nudge {
  position: fixed; left: 16px; bottom: 16px; z-index: 160;
  width: min(320px, calc(100vw - 32px));
  background: var(--color-white); border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop, 0 20px 45px -15px rgba(42,31,39,0.35));
  padding: 22px 20px 20px;
  transform: translateY(24px); opacity: 0;
  transition: transform 320ms var(--ease-out), opacity 320ms var(--ease-out);
  pointer-events: none;
}
.exit-nudge.is-visible { transform: translateY(0); opacity: 1; pointer-events: auto; }
.exit-nudge__close {
  position: absolute; top: 12px; right: 12px; width: 28px; height: 28px;
  border: 0; background: none; color: var(--color-ink-soft); cursor: pointer;
  display: grid; place-items: center;
}
.exit-nudge__close svg { width: 16px; height: 16px; }
.exit-nudge__icon {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
  background: var(--color-blush-deep); color: var(--color-primary); margin-bottom: 12px;
}
.exit-nudge__icon svg { width: 20px; height: 20px; }
.exit-nudge strong { display: block; font-family: var(--font-display); font-weight: 600; font-size: 18px; margin-bottom: 6px; }
.exit-nudge p { font-size: 13.5px; color: var(--color-ink-soft); line-height: 1.6; margin-bottom: 16px; }
.exit-nudge__actions { display: flex; flex-direction: column; gap: 8px; }
.exit-nudge__dismiss { border: 0; background: none; color: var(--color-ink-soft); font-size: 13px; cursor: pointer; padding: 4px; }
.exit-nudge__dismiss:hover { color: var(--color-ink); }
@media (max-width: 767.98px) {
  /* Was bottom: 88px — 32px short of clearing .mobile-fabs (two 46px
     buttons + 12px gap, sitting on its own bottom: 16px = a 120px-tall
     column), so the nudge's bottom edge cut across the top of the fab
     stack ("два всплывающих на одном месте" — the call button peeking out
     from behind/below the nudge card). Matches the clearance .cookie-notice
     already uses for the same reason, just less of it since this card is
     shorter (see its own comment for the fab-height math). */
  .exit-nudge { left: 16px; right: 16px; bottom: 128px; width: auto; }
}

/* Cookie notice — plain disclosure, not a consent gate (see main.js: this
   site has exactly one strictly-necessary cookie, nothing to opt in/out
   of). Left-corner card, same footprint and same bottom offsets as
   .exit-nudge right above — a full-width bar was tried first and, being
   full-width, its right edge sat directly behind .mobile-fabs (the
   right-corner call/sign-up buttons) regardless of bottom offset; this
   shape avoids that side of the screen entirely, the same way
   .exit-nudge already does. */
.cookie-notice {
  position: fixed; left: 16px; bottom: 16px; z-index: 155;
  width: min(360px, calc(100vw - 32px));
  background: var(--color-ink); color: var(--color-white);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  box-shadow: 0 20px 45px -15px rgba(42, 31, 39, 0.35);
  transform: translateY(24px); opacity: 0;
  transition: transform 320ms var(--ease-out), opacity 320ms var(--ease-out);
  pointer-events: none;
}
.cookie-notice.is-visible { transform: translateY(0); opacity: 1; pointer-events: auto; }
.cookie-notice p { margin: 0; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, 0.82); }
.cookie-notice a { color: var(--color-primary-light); text-decoration: underline; text-underline-offset: 2px; }
.cookie-notice .btn { flex-shrink: 0; margin-left: auto; }
@media (max-width: 767.98px) {
  /* Taller than .exit-nudge once the text wraps to 3 lines at this width,
     so it needs more clearance above .mobile-fabs (a 46px-tall button ×2 +
     12px gap, sitting on its own bottom:16px = a 120px-tall column) than
     .exit-nudge's 88px gives — 88px would still land inside that column. */
  .cookie-notice { left: 16px; right: 16px; bottom: 140px; width: auto; }
}

/* ==========================================================================
   Hover-only motion — gated to real pointers so a tap on touch devices
   never leaves a card "stuck" mid-zoom or a reveal stuck open.
   ========================================================================== */
@media (hover: hover) and (pointer: fine) {
  .direction-card:hover img { transform: scale(1.07); }
  .direction-card:hover .direction-card__go { background: var(--color-primary); color: var(--color-white); transform: rotate(45deg); }
  .teacher-card:hover .teacher-card__photo img { transform: scale(1.06); }
  .teacher-card:hover .teacher-card__social { opacity: 1; transform: translateY(0); }
  .highlight__thumbs a:hover img { transform: scale(1.08); }
  .gallery-item:hover img { transform: scale(1.08); }
}

/* Touch devices get no :hover, so cards otherwise feel completely inert on
   tap. A brief :active press-down (releases the instant the finger lifts,
   unlike :hover on touch which can stick) gives the same "this responded to
   me" feedback without the stuck-mid-zoom problem the block above avoids. */
@media (hover: none) {
  .direction-card,
  .teacher-card,
  .gallery-item,
  .highlight__thumbs a {
    transition: transform 180ms var(--ease-out);
  }
  .direction-card:active,
  .teacher-card:active,
  .gallery-item:active,
  .highlight__thumbs a:active {
    transform: scale(0.97);
  }
}

/* Press feedback on icon controls that had none — any pressable element
   should feel like it heard the tap, not just the primary buttons. */
.nav-toggle,
.mobile-nav__close,
.testimonial-nav button,
.footer-social a,
.lead-modal__close,
.play-btn__circle {
  transition: transform 150ms var(--ease-out), background var(--transition), color var(--transition), border-color var(--transition);
}
.nav-toggle:active,
.mobile-nav__close:active,
.testimonial-nav button:active,
.footer-social a:active,
.lead-modal__close:active { transform: scale(0.92); }
.play-btn:active .play-btn__circle { transform: scale(0.93); }

.day-tabs button,
.gallery-filters button {
  transition: transform 150ms var(--ease-out), background var(--transition), color var(--transition), border-color var(--transition);
}
.day-tabs button:active,
.gallery-filters button:active { transform: scale(0.96); }

/* About page — long-form story sections (prose blocks, achievements) */
.about__credit { margin-top: 14px; text-align: center; font-size: 13px; color: var(--color-ink-soft); }

.about-prose { max-width: 720px; }
.about-prose--center { margin-inline: auto; text-align: center; }
.about-prose .section-lede + .section-lede { margin-top: 14px; }

.about-callout {
  margin-top: 24px;
  padding: 18px 22px;
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  border-left: 3px solid var(--color-gold);
  font-size: 14.5px;
  color: var(--color-ink-soft);
  line-height: 1.7;
  text-align: left;
}
.about-callout strong { color: var(--color-ink); }

.about-list { margin-top: 18px; display: flex; flex-direction: column; gap: 12px; text-align: left; }
.about-list li { display: flex; align-items: flex-start; gap: 12px; font-size: 14.5px; color: var(--color-ink-soft); line-height: 1.6; }
.about-list svg { width: 20px; height: 20px; color: var(--color-primary); flex-shrink: 0; margin-top: 1px; }

.achievement-grid { display: grid; gap: 20px; margin-top: 28px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.achievement-card { background: var(--color-white); border-radius: var(--radius-md); box-shadow: var(--shadow-card); padding: 26px 20px; text-align: center; }
.achievement-card__year { font-family: var(--font-display); font-size: 34px; font-weight: 600; color: var(--color-primary-dark); }
.achievement-card__place { margin-top: 4px; font-size: 15px; font-weight: 600; }
.achievement-card__note { margin-top: 6px; font-size: 13px; color: var(--color-ink-soft); }

.contest-list { margin-top: 22px; max-width: 640px; margin-inline: auto; display: flex; flex-direction: column; gap: 0; text-align: left; }
.contest-list li { display: flex; align-items: flex-start; gap: 10px; font-size: 14.5px; color: var(--color-ink-soft); padding: 12px 0; border-bottom: 1px solid var(--color-line); }
.contest-list li:last-child { border-bottom: none; }
.contest-list svg { width: 16px; height: 16px; color: var(--color-gold); flex-shrink: 0; margin-top: 3px; }

/* Utility */
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
