/* ═══════════════════════════════════════════════════════════════════════════
 * THIS FILE IS THREE FILES, ON PURPOSE.
 *
 * It was css/fonts.css + css/style.css + css/v6-chrome.css until Lighthouse
 * put a number on what that cost: four render-blocking stylesheets, ~480ms of
 * the mobile LCP, on a site with NO BUILD STEP to concatenate them. Every
 * separate stylesheet in the <head> is a round trip before the first pixel,
 * and the page's LCP element is its headline — text, which cannot paint until
 * the CSS arrives.
 *
 * So they are one file, in cascade order, each still under its own banner:
 *
 *    1. TYPE      — the self-hosted @font-face set (was css/fonts.css)
 *    2. THE SITE  — everything that was already here
 *    3. V6 CHROME — grain, progress, thread, loader (was css/v6-chrome.css)
 *
 * If a build step ever arrives, split them back and let it do the joining.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────── 1. TYPE ─────────────────────────────────── */

/*
 * The site's type, self-hosted.
 *
 * V6's two faces — Playfair Display for display, Manrope for everything else.
 * This file replaces the `@import url(fonts.googleapis.com…)` that stood at the
 * top of style.css, for three reasons the work order names and one it does not:
 *
 *   · no third-party request on any page of the site;
 *   · Cyrillic is guaranteed present rather than hoped for — the site is
 *     Bulgarian first, and a missing subset falls back mid-sentence;
 *   · an @import at the top of a stylesheet is a serial round trip before a
 *     single rule can apply, which is the worst possible place for one;
 *   · and the two critical files are preloaded in every page's <head>, which
 *     an @import cannot be.
 *
 * Each subset is served only when its characters appear (unicode-range), so
 * Bulgarian costs one extra file, not a second font.
 */

/* Manrope — variable 400–700, the interface and body face */
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/Manrope-400-700-normal-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/Manrope-400-700-normal-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/Manrope-400-700-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/Manrope-400-700-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Playfair Display — 500 and 600 roman, 500 italic for <em> */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-500-normal-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-500-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-500-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-600-normal-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-600-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-600-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-500-italic-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-500-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/PlayfairDisplay-500-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ──────────────────────────── 2. THE SITE ──────────────────────────────── */

/* Type is self-hosted in css/fonts.css, linked before this file in every
   page's <head>. The Google Fonts @import that stood here was a third-party
   request AND a serial round trip before the first rule could apply. */

:root {
  /* Magenta for text on a light ground — AA at 7.10:1. See redesign-v6.css. */
  --pink-ink: #a80b58;
  /* V6 "Director's Cut" palette — KD's decision of 11 September.
     
     This replaces the session-10 purple rebrand whose audit stood here. That
     note argued for #6D2F6B on ivory and banned pink outright; V6 reverses it,
     so the numbers below were re-measured for the new palette rather than
     edited.

     WHAT PASSES (measured, not assumed):

       #fffaf6 (paper)  on #090508 (ink)   19.54:1  AAA
       #fffaf6 (paper)  on #401127 (wine)  15.26:1  AAA
       #21151c (char)   on #f4eee8 (cream) 15.35:1  AAA
       #f2d99d (gold2)  on #090508         14.65:1  AAA
       #f2d99d (gold2)  on #401127         11.44:1  AAA
       #ff6fb3 (pink2)  on #090508          7.89:1  AAA
       #ff6fb3 (pink2)  on #401127          6.16:1  AA
       #e50f79 (pink)   on #090508          4.51:1  AA  (only just)

     WHAT DOES NOT, AND THEREFORE THE ONE RULE THIS PALETTE NEEDS:

       #e50f79 (pink)   on #f4eee8 (cream)  3.90:1  large text only
       #ffffff (white)  on #e50f79          4.49:1  large text only

     So MAGENTA IS NOT A BODY-TEXT COLOUR ON A LIGHT GROUND, and white is not
     a body-text colour on magenta. It is an accent: rules, underlines, node
     dots, borders, the active bar, large display numerals. Small text that
     wants to look pink on a dark ground uses --pink-text (#ff6fb3, 7.89:1);
     on a light ground it uses --char or --ink.

     This is also why V6's own primary button is CREAM with dark ink rather
     than magenta with white — at 4.49:1 the obvious version would have been
     the least readable control on the site. */
  --ink: #090508;
  --ivory: #fffaf6;
  --wine: #401127;
  --rose-gold: #ff6fb3;
  --rose-gold-soft: rgba(109, 47, 107, 0.28);
  --pink-bright: #e50f79;
  --gold: #c9a35f;
  --blush: #F1E7F0;
  --body-text: #17131C;
  --white: #FFFFFF;

  /* "The pink that is readable HERE." Light ground is the default, because
     most cards are white; .section--ink below swaps it for the dark-ground
     value. Markup asks for --pink-text and gets the right one either way,
     which is what stopped the event date rendering at 2.6:1 on a white card. */
  --pink-text: var(--pink-ink);

  /* Canonical names for the accent. Prefer these in new code. */
  --purple: #e50f79;
  --purple-deep: #b80c60;
  --purple-soft: #F1E7F0;
  --purple-on-dark: #ff6fb3;

  --font-display: 'Playfair Display', 'Georgia', serif;
  --font-body: 'Manrope', system-ui, sans-serif;

  --max-width: 1240px;
  --gutter: clamp(1.25rem, 4vw, 4rem);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--body-text);
  background: var(--ivory);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  margin: 0 0 0.5em;
  font-weight: 600;
  line-height: 1.15;
}

p {
  margin: 0 0 1em;
}

a {
  color: inherit;
}

img {
  max-width: 100%;
  display: block;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--ivory);
  padding: 0.75rem 1.25rem;
  z-index: 100;
}

.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
}

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--rose-gold);
  margin-bottom: 0.75em;
  display: block;
}

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.hairline {
  border: none;
  border-top: 1px solid var(--rose-gold-soft);
  margin: 0;
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(250, 246, 241, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rose-gold-soft);
}

.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem var(--gutter);
  max-width: var(--max-width);
  margin: 0 auto;
  gap: 1.5rem;
}

.wordmark {
  /* inline-block, not inline: this anchor contains a BLOCK <small>, and an
     inline box cannot contain one. The anchor's width was therefore measured
     wrong, and in the flex header bar the nav was laid out on top of it —
     invisible while the header had a cream ground, obvious once V6 made it
     transparent. */
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.wordmark small {
  display: block;
  font-family: var(--font-body);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* Gold. The header is V6's ink now, not the cream bar this line was written
     for — on that cream, gold measured 1.28:1 and --pink-ink was the fix. On
     the ink it is the other way round: gold is 14.65:1 and the dark magenta
     would be the unreadable one. */
  color: var(--gold2, #f2d99d);
  font-weight: 700;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.92rem;
  font-weight: 600;
}

.site-nav a {
  text-decoration: none;
  color: var(--body-text);
  position: relative;
  padding-bottom: 3px;
  white-space: nowrap;
}

.site-nav a:hover {
  color: var(--ink);
}

/* Grouped nav items (About > Founder, What We Offer > Mentor/Academy/Book,
   and the page-builder's overflow "More" group) — hover/focus-revealed
   submenu on desktop, always-open flat list on mobile. Keeps the top-level
   bar to a fixed, wrap-proof item count regardless of how many CMS pages
   get added to the menu later. */
.nav-item {
  position: relative;
}

.nav-item__trigger {
  display: flex;
  align-items: center;
  gap: 0.3em;
  background: none;
  border: none;
  padding: 0 0 3px;
  margin: 0;
  font: inherit;
  font-weight: 600;
  color: var(--body-text);
  cursor: pointer;
  white-space: nowrap;
}

.nav-item__trigger::after {
  content: '\25be';
  font-size: 0.7em;
}

.nav-item__trigger:hover,
.nav-item:focus-within .nav-item__trigger {
  color: var(--ink);
}

.nav-item__submenu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 0.75rem;
  padding: 0.5rem 0;
  min-width: 190px;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--rose-gold-soft);
  border-radius: 4px;
  box-shadow: 0 12px 24px rgba(26, 26, 26, 0.12);
  z-index: 60;
}

/* The 0.75rem above this menu was a dead gap.
 *
 * `margin-top` puts the space OUTSIDE the element, so the pointer travelling
 * from the trigger down to the first link crossed twelve pixels that belonged
 * to neither — `.nav-item:hover` went false and the menu vanished before it
 * could be clicked. This bridges the gap with a transparent strip that is
 * part of the menu, so the journey never leaves the hoverable area. */
.nav-item__submenu::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -0.85rem;
  height: 0.85rem;
}

.nav-item:hover .nav-item__submenu,
.nav-item:focus-within .nav-item__submenu,
.nav-item.is-open .nav-item__submenu {
  display: flex;
}

.nav-item__submenu a {
  padding: 0.55em 1.1rem;
  color: var(--body-text);
}

.nav-item__submenu a:hover {
  background: var(--ivory);
  color: var(--ink);
}

.nav-toggle {
  display: none;
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--ink);
}

.locale-switch {
  display: flex;
  border: 1px solid var(--rose-gold-soft);
  border-radius: 999px;
  overflow: hidden;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
}

.locale-switch button {
  border: none;
  background: transparent;
  padding: 0.4em 0.85em;
  cursor: pointer;
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 700;
}

.locale-switch button[aria-pressed='true'] {
  /* Active state — pink per the brief, not near-black. Ink text: white/
     ivory on pink-bright fails AA (3.75:1 / 3.54:1), ink passes (4.57:1). */
  background: var(--pink-bright);
  color: var(--ink);
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  /* Reduced from min(88vh,760px) — until real event/member photography
     exists, a near-full-viewport block of flat colour read as broken
     rather than intentional. Short enough that the next section is
     visible on load at common desktop heights. */
  min-height: min(52vh, 460px);
  display: flex;
  align-items: center;
  color: var(--ivory);
  background: linear-gradient(180deg, rgba(78, 19, 39, 0.35) 0%, rgba(78, 19, 39, 0.78) 100%), var(--wine);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

.hero__inner {
  position: relative;
  z-index: 2;
  padding: 3rem var(--gutter);
  max-width: var(--max-width);
  margin: 0 auto;
  width: 100%;
}

.hero .eyebrow {
  /* Dark --wine background — the darkened --rose-gold fails here (lower
     than on pure --ink), and at this size --pink-bright now fails too
     (3.81:1, since --wine is lighter than the old pure --ink); --gold
     passes (6.35:1) and is what this file uses on --wine consistently. */
  color: var(--gold);
}

/* Brand-mark placeholder treatment — stands in for a real hero photograph
   until one exists. Hidden on mobile (the hero is already content-sized
   there via the 880px breakpoint below, no need to compete for space). */
.hero__mark {
  /* Anchored inside .hero__inner (real, box-model padding — the same
     reference frame the headline text uses), not independently against
     the full-bleed .hero via vw-based right:var(--gutter). The old
     approach put the mark's right edge at genuine risk of sitting past
     the real content edge on any system where the vertical scrollbar
     reserves layout width — vw units are computed against the full
     viewport including that reserved strip, so a right-edge offset built
     from vw could land a few pixels further right than the actual visible
     edge. Reported as a real clip at 1425px on such a system; anchoring
     to .hero__inner's own padded box side-steps the whole vw/scrollbar
     mismatch, since --gutter here is already the container's own padding,
     not a second, independent offset added on top of it.
     z-index left at auto (not the earlier explicit 1) and placed first in
     the DOM — inside the same stacking context as the text now, an
     explicit z-index would paint it above the positioned/static headline
     content; default stacking plus DOM order keeps it behind instead. */
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  width: clamp(140px, 18vw, 260px);
  opacity: 0.85;
  pointer-events: none;
}

@media (max-width: 1100px) {
  .hero__mark {
    width: clamp(110px, 15vw, 180px);
    opacity: 0.6;
  }
}

@media (max-width: 880px) {
  .hero__mark {
    display: none;
  }
}

.hero h1 {
  color: var(--white);
  font-size: clamp(2.4rem, 6vw, 4.5rem);
  max-width: 16ch;
}

.hero__strap {
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  max-width: 42ch;
  color: rgba(255, 253, 251, 0.92);
  font-weight: 500;
}

/* ---------- Section shell ---------- */

.section {
  padding: clamp(3.5rem, 8vw, 6.5rem) 0;
}

.section--ink {
  /* --wine, not --ink — near-black is text-only per the brand guideline,
     and a warm dark surface (13.49:1 for this ivory text) reads as the
     brand's plum rather than as cold black. */
  background: var(--wine);
  color: var(--ivory);
  /* #ff6fb3 is 6.16:1 on wine; the light-ground #a80b58 would be 1.8:1. */
  --pink-text: var(--rose-gold);
}

.section--ink h2, .section--ink h3 {
  color: var(--ivory);
}

/* .branch-card is a white card that can sit inside .section--ink (the
   Events page folds Branches in as a dark-banded section) — its own
   inline color:var(--body-text) fixes the card's paragraphs, but this h3
   rule needs to win over .section--ink h3 above specifically, or the
   branch name renders ivory-on-white (found live: 1.06:1, essentially
   invisible). article.branch-card h3 outranks .section--ink h3 on
   specificity (0,1,2 vs 0,1,1), so this holds regardless of source order. */
article.branch-card h3 {
  color: var(--ink);
}

.section__head {
  max-width: 640px;
  margin-bottom: 2.5rem;
}

.section__head h2 {
  font-size: clamp(1.8rem, 3.5vw, 2.6rem);
}

/* ---------- Events intro ---------- */

.events-intro {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}

@media (max-width: 860px) {
  .events-intro {
    grid-template-columns: 1fr;
  }
}

/* ---------- Quote ---------- */

.quote-block {
  text-align: center;
  max-width: 760px;
  margin: 0 auto;
}

.quote-block blockquote {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.4rem, 3vw, 2.1rem);
  line-height: 1.4;
  margin: 0 0 1rem;
}

.quote-block cite {
  /* Always sits inside .section--ink (a "featured quote" is a dark band by
     design) — --rose-gold is built for light backgrounds and fails badly
     here (2.47:1); --gold is this file's dark-background small-text color
     throughout, and passes (6.35:1). Missed in the first pass: this rule
     wasn't touched because the earlier sweep only checked spans with an
     inline color override, not every CSS class capable of landing on
     --wine. */
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.85rem;
  color: var(--gold);
}

/* ---------- Stats ---------- */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  text-align: center;
}

@media (max-width: 700px) {
  .stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

.stats__value {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 5vw, 3.2rem);
  color: var(--ink);
  font-weight: 700;
}

.stats__label {
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rose-gold);
  font-weight: 700;
}

/* ---------- Testimonials ---------- */

.testimonial-wall {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
}

@media (max-width: 860px) {
  .testimonial-wall {
    grid-template-columns: 1fr;
  }
}

.testimonial-card {
  background: var(--white);
  border: 1px solid var(--rose-gold-soft);
  border-radius: 4px;
  padding: 1.75rem;
}

.testimonial-card p {
  font-style: italic;
}

.testimonial-card .who {
  font-weight: 700;
  color: var(--ink);
  font-size: 0.9rem;
}

.testimonial-card .biz {
  font-size: 0.82rem;
  color: var(--rose-gold);
  font-weight: 600;
}

/* ---------- Video features ---------- */

.video-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

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

.video-card {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: 4px;
  overflow: hidden;
  background: var(--rose-gold-soft);
  display: flex;
  align-items: flex-end;
  color: var(--white);
}

.video-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-card__label {
  position: relative;
  z-index: 2;
  padding: 1.25rem;
  background: linear-gradient(180deg, transparent, rgba(26, 20, 22, 0.85));
  width: 100%;
  font-weight: 600;
  font-size: 0.92rem;
}

.video-card__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: rgba(255, 253, 251, 0.92);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  z-index: 2;
}

/* ---------- Event cards ---------- */

.event-card {
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.event-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(26, 26, 26, 0.12);
}

/* ---------- Press banner ---------- */

.press-banner {
  display: flex;
  gap: 2.5rem;
  align-items: center;
  overflow-x: auto;
  padding: 0.5rem 0 1rem;
  scrollbar-width: thin;
}

.press-banner__item {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--body-text);
  opacity: 0.75;
  transition: opacity 0.2s ease;
  white-space: nowrap;
}

.press-banner__item:hover {
  opacity: 1;
}

.press-banner__item img {
  height: 32px;
  width: auto;
  object-fit: contain;
}

.press-banner__item span {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
}

/* ---------- Tiles ---------- */

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

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

.tile {
  display: block;
  text-decoration: none;
  background: var(--white);
  border: 1px solid var(--rose-gold-soft);
  padding: 2.25rem 1.75rem;
  text-align: center;
  border-radius: 4px;
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--ink);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.tile:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(26, 26, 26, 0.12);
}

.tile--primary {
  /* Primary CTA — pink dominant, per the brief, not near-black. Checked
     most carefully as asked: white text on this pink is 3.75:1 and FAILS
     normal-text AA; --ink text is 4.57:1 and passes. */
  background: var(--pink-bright);
  color: var(--ink);
}

/* ---------- Footer ---------- */

.site-footer {
  /* --wine, not --ink — see .section--ink above for the same reasoning. */
  background: var(--wine);
  color: var(--ivory);
  padding: 3rem 0 2rem;
}

.site-footer__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 2rem;
  margin-bottom: 2rem;
}

.site-footer .wordmark {
  color: var(--ivory);
}

.site-footer__strap {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.2rem;
  max-width: 24ch;
}

.social-row {
  display: flex;
  gap: 1rem;
}

.social-row a {
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid rgba(250, 246, 241, 0.35);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  font-size: 0.85rem;
}

.site-footer__bottom {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.82rem;
  color: rgba(250, 246, 241, 0.72);
  padding-top: 1.5rem;
  border-top: 1px solid rgba(250, 246, 241, 0.18);
}

.site-footer__bottom a {
  text-decoration: none;
  color: inherit;
}

.site-footer__bottom a:hover {
  /* On the --wine footer background, not on light — --rose-gold (the
     darkened, light-background-safe pink) fails badly here (2.47:1);
     --gold passes (6.35:1). */
  color: var(--gold);
}

.legal-links {
  display: flex;
  gap: 1rem;
}

/* ---------- Scroll reveal ---------- */

/* Visible by default — the opacity:0 pre-state only switches on once
   .js-reveal is present on <html>, which main.js sets right before it
   starts observing. If main.js never runs (blocked, errors, slow CDN),
   content stays visible instead of permanently blank — this exact class
   of bug (opacity:0 gated on JS with no CSS fallback) was flagged in the
   session 10 design concept review and turned out to already exist here
   too, so it's fixed sitewide rather than just in the new markup. */
[data-reveal] {
  opacity: 1;
  transform: none;
}

.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}

.js-reveal [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- Mobile nav ---------- */

@media (max-width: 1100px) {
  [data-repeat="values"],
  [data-repeat="press"],
  [data-repeat="branches"],
  [data-repeat="events"] {
    grid-template-columns: repeat(3, 1fr) !important;
  }

  [data-repeat="team"] {
    grid-template-columns: repeat(3, 1fr) !important;
  }
}

@media (max-width: 880px) {
  .hero {
    min-height: auto;
    padding-top: 3rem;
  }

  [data-repeat="values"],
  [data-repeat="gallery"],
  [data-repeat="press"],
  [data-repeat="branches"],
  [data-repeat="events"],
  [data-repeat="blog-posts"] {
    grid-template-columns: 1fr !important;
  }

  [data-repeat="portraits"],
  [data-repeat="team"] {
    grid-template-columns: 1fr 1fr !important;
  }

  main .wrap[style*="1fr 1.4fr"] {
    grid-template-columns: 1fr !important;
  }

  .wotm-card {
    grid-template-columns: 1fr !important;
  }

  .nav-toggle {
    display: block;
  }

  .site-nav {
    position: fixed;
    inset: 0 0 auto 0;
    top: 64px;
    background: var(--ivory);
    flex-direction: column;
    align-items: flex-start;
    padding: 1.5rem var(--gutter) 2rem;
    border-bottom: 1px solid var(--rose-gold-soft);
    transform: translateY(-110%);
    transition: transform 0.3s ease;
  }

  .site-nav.is-open {
    transform: translateY(0);
  }

  .site-header__bar {
    flex-wrap: wrap;
  }

  /* Grouped items just flatten into the stacked mobile menu — no hover
     available on touch, so the submenu is always open here. */
  .nav-item {
    width: 100%;
  }

  .nav-item__trigger {
    cursor: default;
    opacity: 0.7;
  }

  .nav-item__trigger::after {
    display: none;
  }

  .nav-item__submenu {
    display: flex !important;
    position: static;
    margin-top: 0.4rem;
    padding: 0;
    min-width: 0;
    border: none;
    box-shadow: none;
    background: none;
  }

  .nav-item__submenu a {
    padding: 0.5em 0 0.5em 1rem;
  }
}


/* ---- Form fields -------------------------------------------------------
   Every control on the site's public forms. Previously each input repeated
   the same six inline declarations; this is the same look in one place, and
   it gives the labels somewhere to live. Labels are real <label for=...>
   elements now, not placeholders: a placeholder disappears the moment you
   type into the field and is not a programmatic label at all.
   -------------------------------------------------------------------- */
.form-row { display: grid; gap: 0.35rem; }

.form-label {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  /* Inherited, not asserted. Hard-coding --body-text here made every label on
     the contact form 1.1:1 the moment the page ground went dark. */
  color: inherit;
}

.form-label .optional {
  font-weight: 400;
  opacity: 0.65;
}

.form-field {
  padding: 0.75em;
  border: 1px solid var(--rose-gold-soft);
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 1rem;
  background: var(--white);
  color: var(--body-text);
  width: 100%;
}

.form-field:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 1px;
  border-color: var(--purple);
}

textarea.form-field { resize: vertical; min-height: 5.5rem; }


/* The club's stated right to refuse membership, above the Join form. Carried
   over from the old site verbatim - it is the basis every rejection cites. */
.join-refusal {
  margin-top: 1rem;
  padding: 0.85rem 1rem;
  border-left: 3px solid var(--purple);
  background: var(--purple-soft);
  font-size: 0.9rem;
  line-height: 1.5;
}

/* --------------------------------------------------------------------
   UNTRANSLATED CONTENT — the visible half of the fallback rule.

   js/i18n-fallback.js decides what to show when a translation is missing:
   the Bulgarian original, never a blank region. These two rules are what
   make that visible instead of silent — a quiet marker on the words that
   came back in the other language, and one line at the top of the page.

   Deliberately understated. This is a club's website, not a bug report:
   it should read as "we haven't got to this yet", not as an error.
   -------------------------------------------------------------------- */
[data-untranslated] {
  /* A hairline under the words. Derived from the text's OWN colour rather than
     set to the site purple, because these markers land on the dark hero bands
     as often as on paper, and a fixed accent disappears against #090508.
     Not a colour change to the text itself: it keeps its designed contrast. */
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: color-mix(in srgb, currentColor 60%, transparent);
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}

/* Social links that hold WORDS, not icons.
 *
 * `.social-row a` is a 2.25rem circle — written for an icon set that this
 * footer does not have. What it actually contains is "Facebook", "Instagram"
 * and "YouTube", so each word overflowed a 36px box and ran straight through
 * its neighbours: three overlapping labels in a row.
 *
 * The circles stay circles wherever the content is genuinely short (the
 * member cards use "IG" and "FB"). Anything longer than three characters gets
 * a pill that fits it. Nothing here needs an image to be readable.
 */
.social-row a {
  width: auto;
  min-width: 2.25rem;
  padding: 0 0.85em;
  border-radius: 999px;
  white-space: nowrap;
  gap: 0.4em;
}

/* The wordmark was too small to read.
 *
 * It carries the club's whole name and its Bulgarian line in a header that is
 * now near-black, and it was set at the size it had when the bar was cream and
 * shorter. Both lines go up, and the Bulgarian line stops being 9.6px — which
 * is under this site's own 10px floor for small caps. */
.site-header .wordmark {
  font-size: 1.28rem;
  line-height: 1.15;
}
.site-header .wordmark small {
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  margin-top: 0.18em;
}
.site-header .adm-emblem,
.site-header__bar img {
  width: 46px;
  height: 46px;
}

/* `hidden` has to win.
 *
 * The UA sheet says `[hidden] { display: none }` at the lowest possible
 * specificity, so ANY inline display beats it — and several blocks on the
 * submit-event form are written as `<div hidden style="display:grid">`. The
 * result: the "Where online" fields and the recurring-pattern fields were on
 * screen the whole time, whatever was selected, and the form asked for a Zoom
 * link for an event with a street address.
 *
 * Fixing it here rather than in the markup covers every such block at once,
 * including any written later. */
[hidden] {
  display: none !important;
}

.untranslated-notice {
  margin: 0;
  padding: 0.6rem var(--gutter);
  background: var(--purple-soft);
  color: var(--purple-deep);
  font-family: var(--font-body);
  font-size: 0.8125rem;
  line-height: 1.5;
  text-align: center;
  border-bottom: 1px solid rgba(109, 47, 107, 0.18);
}

/* On a dark band the soft purple would glow; keep it readable either way. */
@media (prefers-contrast: more) {
  [data-untranslated] {
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
  }
}


/* ─────────────────────────── 3. V6 CHROME ──────────────────────────────── */

/*
 * V6 chrome — the four things the design puts on top of every page.
 *
 *   1. the grain
 *   2. the scroll progress bar
 *   3. the signature thread
 *   4. the loader (homepage, first visit of a session, and nowhere else)
 *
 * All four are decoration. Every one of them is inert without JavaScript, sits
 * behind `pointer-events: none`, is hidden from assistive technology, and stops
 * moving under `prefers-reduced-motion`. Nothing here can prevent a person
 * reading the page, which is the whole test for an ornament.
 */

/* ── 1. The grain ───────────────────────────────────────────────────────────
 * Lifted from V6 exactly: one 180×180 fractal-noise tile, at 5.2% over
 * soft-light. It is an SVG data URI rather than an image request, so it costs
 * no round trip and cannot 404.
 */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  opacity: 0.052;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.72'/%3E%3C/svg%3E");
}

/* ── 2. Scroll progress ─────────────────────────────────────────────────── */
.v6-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 0;
  z-index: 2400;
  pointer-events: none;
  background: linear-gradient(90deg, var(--pink, #e50f79), var(--gold2, #f2d99d));
  transition: width 120ms linear;
}

/* ── 3. The signature thread ────────────────────────────────────────────────
 * A single hairline drawn across the whole document, revealed by scroll. V6
 * blends it with `screen`, which is why it only ever shows on the dark bands
 * and disappears politely over the cream ones — no per-section handling.
 */
.v6-thread {
  position: fixed;
  inset: 0;
  z-index: 2300;
  pointer-events: none;
  opacity: 0.54;
  mix-blend-mode: screen;
}
.v6-thread svg {
  width: 100%;
  height: 100%;
}
.v6-thread path {
  fill: none;
  stroke: url(#v6ThreadGradient);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

/* ── 4. The loader ──────────────────────────────────────────────────────────
 * Homepage only, first visit per session only, 1.2s ceiling, and never at all
 * under prefers-reduced-motion — the element is not even created in that case,
 * so the rules below are the fallback and not the guarantee.
 */
.v6-loader {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: #080407;
  display: grid;
  place-items: center;
  transition: opacity 600ms ease, visibility 600ms ease;
}
.v6-loader.is-done {
  opacity: 0;
  visibility: hidden;
}
.v6-loader__stage {
  display: grid;
  place-items: center;
  gap: 22px;
  text-align: center;
  padding: 0 24px;
}
.v6-loader__mark {
  width: 84px;
  height: 84px;
  border-radius: 999px;
  background: var(--cream, #f4eee8);
  display: grid;
  place-items: center;
}
.v6-loader__mark img {
  width: 60px;
  height: 60px;
  object-fit: contain;
}
.v6-loader__word {
  font-family: var(--serif, 'Playfair Display', Georgia, serif);
  font-weight: 500;
  font-size: clamp(1.25rem, 3.2vw, 1.75rem);
  color: var(--paper, #fffaf6);
  margin: 0;
}
.v6-loader__place {
  font-family: var(--sans, 'Manrope', Arial, sans-serif);
  font-size: 0.75rem; /* 10px in V6; the order's floor is 10, this is 12 */
  font-weight: 600;
  letter-spacing: 0.23em;
  text-transform: uppercase;
  color: var(--muted-ink, rgba(255, 255, 255, 0.62));
  margin: 0;
}
.v6-loader__thread {
  width: 140px;
  height: 1px;
  background: linear-gradient(90deg, var(--pink, #e50f79), var(--gold2, #f2d99d));
}

/* ── Reveal, and why it is guarded ──────────────────────────────────────────
 * Hidden-then-revealed states apply ONLY under `.js` on <html>. Without that
 * guard a reader with no JavaScript — or with JavaScript that failed to
 * execute — gets a page of invisible content. The class is set by an inline
 * script in <head>, so it is on before first paint and there is no flash.
 */
.js [data-v6-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 700ms var(--ease, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 700ms var(--ease, cubic-bezier(0.16, 1, 0.3, 1));
  will-change: opacity, transform;
}
.js [data-v6-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* ── Sticky stages need an unbroken containing block ────────────────────────
 * `overflow: hidden` on ANY ancestor silently kills `position: sticky`, and
 * the site's shell sets it to stop horizontal spill. `clip` stops the spill
 * the same way without creating a scroll container, which is what breaks
 * sticky. This is the order's deviation 4, stated where it applies.
 */
html,
body,
main,
.page-shell,
.site-main {
  overflow-x: clip;
}

@media (prefers-reduced-motion: reduce) {
  .v6-progress,
  .v6-thread {
    display: none;
  }
  .js [data-v6-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}


/* ── V6: the header is ink, not cream ────────────────────────────────────────
 * A cream bar across the top of a near-black design reads as a different site
 * before you have read a word. The homepage overrides this again in
 * redesign-v6.css to go fully transparent over the hero.
 */
.site-header {
  background: rgba(10, 5, 8, 0.9);
  border-bottom-color: rgba(255, 255, 255, 0.12);
}
.site-header .wordmark,
.site-header a,
.site-header .nav-item__trigger,
.site-header button {
  color: var(--paper, #fffaf6);
}
.site-header .nav-item__submenu {
  background: rgba(10, 5, 8, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
}
.site-header .wordmark small {
  color: var(--gold2, #f2d99d);
}

/* Hover states, which the repaint above forgot.
 *
 * The header went from cream to near-black and the base colours came with it,
 * but every :hover in this file still resolved to --ink — near-black text on a
 * near-black bar. So a nav link vanished at the exact moment you pointed at
 * it, which is the one moment it has to be readable.
 *
 * Gold rather than white, because white is the resting colour and a hover has
 * to be distinguishable from it. #f2d99d is 14.65:1 on this ground. */
.site-header .site-nav a:hover,
.site-header .site-nav a:focus-visible,
.site-header .nav-item__trigger:hover,
.site-header .nav-item:focus-within .nav-item__trigger,
.site-header .wordmark:hover,
.site-header .nav-toggle:hover {
  color: var(--gold2, #f2d99d);
}

/* The submenu sits on the same dark ground, so its hover was the same bug —
   an ivory wash behind near-black text on a panel that is neither. */
.site-header .nav-item__submenu a {
  color: var(--paper, #fffaf6);
}
.site-header .nav-item__submenu a:hover,
.site-header .nav-item__submenu a:focus-visible {
  background: rgba(255, 255, 255, 0.08);
  color: var(--gold2, #f2d99d);
}

/* ── Rich text from the CMS ─────────────────────────────────────────────────
 *
 * "Her story" and the membership descriptions are written in a real editor
 * now — paragraphs, bold, lists, quotes, links. js/main.js serialises that to
 * a small set of tags; this is what those tags look like. Scoped to `.rt` so
 * it can never reach the rest of the page.
 */
.rt > :first-child {
  margin-top: 0;
}
.rt > :last-child {
  margin-bottom: 0;
}
.rt p {
  margin: 0 0 0.85em;
}
.rt h3,
.rt h4,
.rt h5 {
  margin: 1.4em 0 0.4em;
  line-height: 1.25;
}
.rt h3 {
  font-size: 1.2rem;
}
.rt h4 {
  font-size: 1.05rem;
}
.rt a {
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.rt ul.rt-list,
.rt ol.rt-list {
  margin: 0 0 0.9em;
  padding-left: 1.3em;
  display: grid;
  gap: 0.35em;
}
.rt ul.rt-list {
  list-style: disc;
}
.rt ol.rt-list {
  list-style: decimal;
}
.rt li::marker {
  color: var(--pink-text);
}
.rt blockquote {
  margin: 1.1em 0;
  padding: 0.2em 0 0.2em 1.1em;
  border-left: 2px solid var(--pink-text);
  font-style: italic;
}
.rt code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
}

/* ── Carousel ───────────────────────────────────────────────────────────────
 *
 * Scroll-snap, not a library. The strip is a real scrolling element, so a
 * trackpad, a touchscreen and the keyboard all work before a line of
 * JavaScript runs; the buttons js/main.js adds are an improvement on that
 * rather than the mechanism. With scripting off the pictures are all still
 * there and still scrollable, which a JS carousel cannot say.
 */
.carousel {
  position: relative;
}
.carousel__track {
  display: grid;
  grid-auto-flow: column;
  /* A LENGTH, not a percentage.
     A percentage track inside a scroll container resolves against space the
     container is still deciding, and the grid shrink-fits to exactly the
     visible width — measured: four slides at 32% produced scrollWidth ===
     clientWidth and a carousel that could not scroll. A clamp cannot do that,
     and it keeps the photographs big enough to be worth looking at. */
  grid-auto-columns: clamp(240px, 30vw, 380px);
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 1rem;
  padding-bottom: 0.5rem;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}
.carousel__track:focus-visible {
  outline: 2px solid var(--pink-text);
  outline-offset: 4px;
}
.carousel__slide {
  margin: 0;
  scroll-snap-align: start;
}
.carousel__slide img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 4px;
}
.carousel__btn {
  position: absolute;
  top: calc(50% - 1.4rem);
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  border: 1px solid var(--rose-gold-soft);
  background: rgba(9, 5, 8, 0.82);
  color: var(--ivory);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  backdrop-filter: blur(6px);
  transition: opacity 0.25s ease, background 0.25s ease;
}
.carousel__btn--prev {
  left: -0.6rem;
}
.carousel__btn--next {
  right: -0.6rem;
}
.carousel__btn:hover:not(:disabled) {
  background: var(--wine);
}
.carousel__btn:disabled {
  opacity: 0.28;
  cursor: default;
}
/* Everything fits: the buttons would be decoration, so they go. */
.carousel.is-static .carousel__btn {
  display: none;
}
@media (max-width: 700px) {
  .carousel__track {
    grid-auto-columns: minmax(200px, 72%);
  }
  .carousel__btn {
    display: none;
  }
}

/* A video in the carousel. The frame keeps the player's own shape — 16:9 for
   YouTube, 4:5 for Instagram — so neither is letterboxed into the other's. */
.video-card {
  display: grid;
  gap: 0.6rem;
}
.video-card__frame {
  position: relative;
  width: 100%;
  border-radius: 4px;
  overflow: hidden;
  background: #090508;
}
.video-card__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.video-card figcaption {
  font-size: 0.88rem;
  line-height: 1.5;
}
