@layer reset, tokens, base, components, utilities;

@layer tokens {
  :root {
    --color-paper: #f3f1ea;
    --color-ink: #15120d;
    --color-muted: #6b6358;
    --color-hairline: #dcd6ca;
    --color-surface: #e8e3d8;
    --color-accent: #ff5a2e;
    --color-accent-soft: #ff8154;
    --color-error: #7c2d12;
    --color-field: #fbfaf7;

    --font-display: "Bricolage Grotesque", "Archivo", "Helvetica Neue", sans-serif;
    --font-sans: "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif;
    --font-serif: "Fraunces", Georgia, "Times New Roman", serif;

    --measure: 64ch;
    --space-1: .5rem; --space-2: 1rem; --space-3: 1.5rem;
    --space-4: 2.5rem; --space-5: 4rem; --space-6: 6rem;
    --maxw: 1280px;
    --radius: 6px;
    --radius-lg: 16px;
    --radius-pill: 999px;

    --shadow-card: 0 22px 48px -28px rgba(21, 18, 13, .5);
    --ease: cubic-bezier(.2, .7, .2, 1);
  }
}

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }
  img, svg, video { display: block; max-width: 100%; }
  a { color: inherit; text-decoration: none; }
  button { font: inherit; color: inherit; cursor: pointer; }
  ::selection { background: var(--color-accent); color: #fff; }
}

@layer base {
  html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; -webkit-tap-highlight-color: transparent; }
  body {
    background: var(--color-paper);
    color: var(--color-ink);
    font-family: var(--font-sans);
    font-size: 17px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    position: relative;
  }
  /* subtle paper grain for atmosphere */
  body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 9999;
    pointer-events: none;
    opacity: .035;
    mix-blend-mode: multiply;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  h1, h2, h3 { font-family: var(--font-display); font-weight: 800; line-height: 1; letter-spacing: -.02em; text-wrap: balance; }
  h1 { font-size: clamp(2.7rem, 7vw, 5.4rem); line-height: .9; letter-spacing: -.035em; text-transform: uppercase; }
  h2 { font-size: clamp(1.9rem, 4vw, 3rem); letter-spacing: -.025em; }
  h3 { font-size: 1.2rem; font-weight: 700; letter-spacing: -.01em; }
  main { flex: 1; position: relative; z-index: 1; }

  .container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 2.75rem); }
  .accent { color: var(--color-accent); }
  .label { font-family: var(--font-sans); font-size: .7rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--color-muted); }
  .lede { font-size: 1.08rem; color: var(--color-muted); max-width: var(--measure); line-height: 1.6; }
  .contact-email, .contact-whatsapp { margin-top: .5rem; }
  .contact-email a, .contact-whatsapp a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
  /* keep the phone number from breaking mid-digits on narrow screens */
  .contact-whatsapp a { white-space: nowrap; }
  .section { padding-block: var(--space-5) var(--space-3); }
}

@layer utilities {
  .visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .section-end { padding-bottom: var(--space-5); }
  .mt-3 { margin-top: var(--space-3); }
  body.nav-lock { overflow: hidden; }

  /* scroll reveal — only active once JS adds .reveal-ready (degrades to visible) */
  [data-reveal] { transition: opacity .7s var(--ease), transform .7s var(--ease); }
  .reveal-ready [data-reveal]:not(.is-visible) { opacity: 0; transform: translateY(22px); }
  .reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation: none !important; transition: none !important; }
    .reveal-ready [data-reveal] { opacity: 1 !important; transform: none !important; }
  }
}

/* ---------- buttons ---------- */
@layer components {
  .btn {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .9rem 1.6rem; border-radius: var(--radius-pill);
    font-family: var(--font-sans); font-weight: 600; font-size: .78rem;
    letter-spacing: .06em; text-transform: uppercase; border: 1px solid transparent;
    -webkit-user-select: none; user-select: none;
    transition: transform .35s var(--ease), background .3s, color .3s, box-shadow .35s, border-color .3s;
  }
  .btn--primary { background: var(--color-ink); color: var(--color-paper); }
  .btn--primary:hover { transform: translateY(-2px); box-shadow: 0 14px 28px -12px rgba(21, 18, 13, .55); }
  .btn--accent { background: var(--color-accent); color: #fff; }
  .btn--accent:hover { transform: translateY(-2px); box-shadow: 0 16px 32px -12px rgba(224, 83, 58, .6); }
  .btn--ghost { background: transparent; color: var(--color-ink); border-color: color-mix(in srgb, var(--color-ink) 30%, transparent); }
  .btn--ghost:hover { background: var(--color-ink); color: var(--color-paper); transform: translateY(-2px); }
  .btn[disabled] { opacity: .45; cursor: default; transform: none; box-shadow: none; }
}

/* ---------- logo ---------- */
@layer components {
  .logo { display: inline-flex; align-items: center; gap: .7rem; color: var(--color-ink); }
  .logo__mark { width: 32px; height: 32px; transition: transform .5s var(--ease); }
  .logo:hover .logo__mark { transform: rotate(30deg); }
  .logo__lockup { display: inline-flex; flex-direction: column; align-items: center; }
  .logo__mono { font-family: var(--font-serif); font-size: 1.4rem; line-height: 1; }
  .logo__amp { font-style: italic; font-weight: 300; }
  .logo__sub { align-self: stretch; text-align: center; font-family: var(--font-sans);
    font-size: .54rem; letter-spacing: .42em; color: var(--color-muted);
    margin-top: .3em; padding-top: .3em; border-top: 1px solid var(--color-hairline); }
  .logo--stacked { flex-direction: column; gap: .5rem; }
  .logo--stacked .logo__mark { width: 46px; height: 46px; }

  /* larger header (horizontal) logo */
  .logo--horizontal { gap: .95rem; }
  .logo--horizontal .logo__mark { width: 54px; height: 54px; }
  .logo--horizontal .logo__mono { font-size: 2.25rem; }
  .logo--horizontal .logo__sub { font-size: .72rem; letter-spacing: .46em; }
}

/* ---------- language switcher ---------- */
@layer components {
  .lang { display: inline-flex; gap: .5rem; font-size: .7rem; font-weight: 600; letter-spacing: .1em; }
  .lang__item { color: var(--color-muted); transition: color .25s; }
  .lang__item.lang--active { color: var(--color-ink); }
  .lang__item:hover { color: var(--color-accent); }
}

/* ---------- nav ---------- */
@layer components {
  .nav { position: sticky; top: 0; z-index: 50;
    background: color-mix(in srgb, var(--color-paper) 82%, transparent);
    backdrop-filter: blur(12px) saturate(1.1); border-bottom: 1px solid transparent;
    -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
    transition: border-color .3s; }
  .nav__bar { display: flex; align-items: center; justify-content: space-between; min-height: 76px; gap: var(--space-3); }
  .nav__links { display: flex; align-items: center; gap: clamp(1rem, 2vw, 1.9rem); }
  .nav__link { position: relative; font-family: var(--font-sans); font-weight: 600; font-size: .76rem;
    letter-spacing: .08em; text-transform: uppercase; color: var(--color-ink); opacity: .68; transition: opacity .25s; }
  .nav__link::after { content: ""; position: absolute; left: 0; right: 100%; bottom: -5px; height: 1.5px;
    background: var(--color-accent); transition: right .35s var(--ease); }
  .nav__link:hover { opacity: 1; }
  .nav__link:hover::after, .nav__link.is-current::after { right: 0; }
  .nav__link.is-current { opacity: 1; }
  /* Contact rendered as a pill (last nav anchor) */
  .nav__link:last-of-type { background: var(--color-ink); color: var(--color-paper); opacity: 1;
    padding: .6rem 1.2rem; border-radius: var(--radius-pill); transition: background .3s, transform .3s var(--ease); }
  .nav__link:last-of-type::after { display: none; }
  .nav__link:last-of-type:hover { background: var(--color-accent); transform: translateY(-1px); }
  .nav__toggle { display: none; background: none; border: 0; flex-direction: column; gap: 5px; }
  .nav__toggle span { width: 24px; height: 1.5px; background: var(--color-ink); display: block; transition: transform .3s var(--ease); }
  .nav.is-open .nav__toggle span:first-child { transform: translateY(3.25px) rotate(45deg); }
  .nav.is-open .nav__toggle span:last-child { transform: translateY(-3.25px) rotate(-45deg); }
  @media (max-width: 860px) {
    .nav__toggle { display: flex; }
    .nav__links { position: fixed; top: 76px; left: 0; right: 0; height: calc(100vh - 76px); height: calc(100dvh - 76px);
      flex-direction: column; align-items: flex-start; gap: var(--space-3);
      background: var(--color-paper); padding: var(--space-4) var(--space-3); overflow-y: auto;
      opacity: 0; visibility: hidden; transform: translateY(-10px);
      transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s; }
    .nav.is-open .nav__links { opacity: 1; visibility: visible; transform: translateY(0); }
  }
}

/* ---------- hero ---------- */
@layer components {
  .hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center; padding-block: clamp(3rem, 7vw, 6rem) clamp(2rem, 5vw, 4rem); }
  .hero__title { margin: .7rem 0 1.3rem; max-width: 13ch; }
  .hero__lede { max-width: 38ch; }
  .hero__cta { display: flex; gap: .75rem; margin-top: 1.9rem; flex-wrap: wrap; }
  .hero__media { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: minmax(118px, 1fr); gap: .75rem; }
  /* Fixed ratio (not left to the source photo's own proportions) so a portrait-
     oriented replacement image can't blow out this row's height against the
     16:9 lg shot next to it — see .hero__shot--lg below for the matching lg ratio. */
  .hero__shot { overflow: hidden; border-radius: var(--radius-lg); background: var(--color-surface); aspect-ratio: 8 / 9; }
  .hero__shot img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease); }
  .hero__shot:hover img { transform: scale(1.06); }
  .hero__shot--lg { grid-column: 1 / -1; aspect-ratio: 16 / 9; }
  .hero__tile { background: var(--color-accent); color: #fff; border-radius: var(--radius-lg);
    display: flex; align-items: flex-end; padding: 1.1rem; min-height: 118px; overflow: hidden; position: relative; }
  .hero__tile::before { content: ""; position: absolute; inset: 0;
    background: radial-gradient(120% 90% at 85% 15%, rgba(255,255,255,.22), transparent 60%); }
  .hero__tile-label { position: relative; font-family: var(--font-display); font-weight: 700;
    text-transform: uppercase; letter-spacing: .01em; font-size: .95rem; line-height: 1.05; }

  /* staggered page-load entrance */
  html:not(.turbo-nav) :is(.hero__kicker, .hero__title, .hero__lede, .hero__cta, .hero__media) { animation: hero-in .85s var(--ease) both; }
  .hero__title { animation-delay: .06s; }
  .hero__media { animation-delay: .1s; }
  .hero__lede { animation-delay: .16s; }
  .hero__cta { animation-delay: .22s; }
  @keyframes hero-in { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }

  @media (max-width: 900px) { .hero { grid-template-columns: 1fr; } .hero__title { max-width: none; } }
}

/* ---------- section heading ---------- */
@layer components {
  .sh { margin-bottom: var(--space-3); max-width: 60ch; }
  .sh .label { margin-bottom: .6rem; }
}

/* ---------- USP band ---------- */
@layer components {
  .usp { background: var(--color-ink); color: var(--color-paper); border-radius: var(--radius-lg);
    padding: clamp(1.9rem, 4vw, 3.25rem); position: relative; overflow: hidden; }
  .usp::before { content: ""; position: absolute; right: -10%; top: -40%; width: 55%; height: 180%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--color-accent) 55%, transparent), transparent 70%);
    opacity: .9; pointer-events: none; }
  .usp .label { color: var(--color-accent-soft); }
  .usp__title { position: relative; font-size: clamp(1.5rem, 3vw, 2.4rem); max-width: 24ch; margin-top: .8rem;
    letter-spacing: -.02em; }
}

/* ---------- service cards ---------- */
@layer components {
  .svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  .svc { background: var(--color-surface); border-radius: var(--radius-lg); padding: 1.7rem 1.6rem;
    display: flex; flex-direction: column; min-height: 210px; border: 1px solid transparent;
    transition: transform .4s var(--ease), box-shadow .4s, border-color .3s; }
  .svc:hover { transform: translateY(-5px); box-shadow: var(--shadow-card); border-color: color-mix(in srgb, var(--color-ink) 8%, transparent); }
  .svc__title { font-family: var(--font-display); font-size: 1.35rem; font-weight: 700; letter-spacing: -.01em; }
  .svc__body { color: var(--color-muted); margin: .65rem 0 1.3rem; flex: 1; max-width: 38ch; }
  .svc__cta { margin-top: auto; font-weight: 600; font-size: .82rem; letter-spacing: .02em;
    display: inline-flex; gap: .35rem; transition: gap .3s var(--ease); }
  .svc:hover .svc__cta { gap: .65rem; }
  .svc-grid [data-reveal]:nth-child(2) { transition-delay: .08s; }
  .svc-grid [data-reveal]:nth-child(3) { transition-delay: .16s; }
  @media (max-width: 860px) { .svc-grid { grid-template-columns: 1fr; } }
}

/* ---------- photographers (/photographers) ---------- */
@layer components {
  .photographers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem;
    padding-block: var(--space-2) var(--space-4); }
  .photographer { background: var(--color-surface); border-radius: var(--radius-lg); overflow: hidden;
    display: flex; flex-direction: column; border: 1px solid transparent;
    transition: transform .4s var(--ease), box-shadow .4s, border-color .3s; }
  .photographer:hover { transform: translateY(-5px); box-shadow: var(--shadow-card);
    border-color: color-mix(in srgb, var(--color-ink) 8%, transparent); }
  .photographer__portrait { aspect-ratio: 4 / 5; background: var(--color-paper); overflow: hidden; }
  .photographer__img { width: 100%; height: 100%; object-fit: cover; display: block;
    transition: transform 1s var(--ease); }
  .photographer:hover .photographer__img { transform: scale(1.05); }
  .photographer__portrait--mono { display: grid; place-items: center;
    background: linear-gradient(135deg, color-mix(in srgb, var(--color-accent) 20%, var(--color-surface)), var(--color-surface)); }
  .photographer__initials { font-family: var(--font-display); font-weight: 800;
    font-size: clamp(2.6rem, 7vw, 4rem); letter-spacing: -.02em; color: var(--color-accent); }
  .photographer__body { padding: 1.4rem 1.5rem 1.6rem; display: flex; flex-direction: column; flex: 1; }
  .photographer__name { font-family: var(--font-display); font-size: 1.3rem; font-weight: 700; letter-spacing: -.01em; }
  .photographer__specialty { color: var(--color-accent); font-size: .78rem; font-weight: 600;
    letter-spacing: .04em; text-transform: uppercase; margin-top: .3rem; }
  .photographer__bio { color: var(--color-muted); margin: .7rem 0 1.2rem; flex: 1; }
  .photographer__link { margin-top: auto; font-weight: 600; font-size: .82rem; letter-spacing: .02em;
    display: inline-flex; gap: .35rem; transition: gap .3s var(--ease); }
  .photographer:hover .photographer__link { gap: .65rem; }
  @media (max-width: 980px) { .photographers { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 640px) { .photographers { grid-template-columns: 1fr; } }
}

/* ---------- home teaser grid ---------- */
@layer components {
  .work { columns: 3 300px; column-gap: 1rem; padding-block: var(--space-4); }
  .work__item { break-inside: avoid; margin-bottom: 1rem; position: relative; overflow: hidden;
    border-radius: var(--radius-lg); background: var(--color-surface); }
  .work img { width: 100%; height: auto; display: block; transition: transform 1s var(--ease); }
  .work__item:hover img { transform: scale(1.06); }
}

/* ---------- sports gallery (/work) ---------- */
@layer components {
  .gallery { padding-block: var(--space-2) var(--space-5); }

  .gallery__index { position: sticky; top: 76px; z-index: 5;
    background: color-mix(in srgb, var(--color-paper) 92%, transparent); backdrop-filter: blur(10px) saturate(1.1);
    border-block: 1px solid var(--color-hairline); margin-bottom: var(--space-3); }
  .gallery__index ol { display: flex; gap: clamp(1rem, 3vw, 2rem); list-style: none; margin: 0;
    padding: .85rem 0; overflow-x: auto; scroll-snap-type: x proximity;
    scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .gallery__index ol::-webkit-scrollbar { display: none; }
  .gallery__index a { display: inline-flex; gap: .4rem; align-items: baseline; white-space: nowrap;
    font-size: .74rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    color: var(--color-muted); transition: color .25s; scroll-snap-align: start; }
  .gallery__index a:hover { color: var(--color-ink); }
  .gallery__index b { font-family: var(--font-display); color: var(--color-ink); }
  /* On phones the row scrolls horizontally — hide the hard cut, hint with a fade */
  @media (max-width: 760px) {
    .gallery__index ol { gap: 1.25rem; padding-inline-end: 1.6rem;
      -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent);
              mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent); }
  }

  .gallery__chapter { scroll-margin-top: 130px; padding-top: var(--space-4); }
  .gallery__head { display: grid; grid-template-columns: auto 1fr; align-items: end;
    gap: clamp(1rem, 3vw, 2.4rem); margin-bottom: var(--space-3); }
  .gallery__no { font-family: var(--font-display); font-weight: 800; line-height: .72;
    font-size: clamp(3.5rem, 13vw, 9rem); letter-spacing: -.03em; }
  .gallery__name { font-family: var(--font-display); font-weight: 800; line-height: 1;
    letter-spacing: -.02em; font-size: clamp(1.8rem, 5vw, 3.2rem); margin: .35rem 0 .4rem; }
  .gallery__desc { color: var(--color-muted); font-size: .95rem; }

  /* masonry: every photo keeps its natural proportions — no cropping */
  .gallery__masonry { columns: 3 340px; column-gap: clamp(.6rem, 1.4vw, 1rem); }
  .gallery__shot { break-inside: avoid; margin: 0 0 clamp(.6rem, 1.4vw, 1rem);
    overflow: hidden; border-radius: var(--radius-lg); background: var(--color-surface); }
  .gallery__shot img { width: 100%; height: auto; display: block; transition: transform .8s var(--ease); }
  .gallery__shot:hover img { transform: scale(1.03); }

  /* Кадры /work рисуют партиалы атласа (.pa-*), но корня .pa у этой страницы
     нет ни одного предка — значит нет и его палитры: --pa-frame объявлен
     только на .pa и .pa[data-theme="light"], и рамка кадра взяла бы запасной
     #161616, чёрный прямоугольник на бумажной странице: под каждой ленивой
     картинкой, пока она грузится, и навсегда под той, чья производная не
     доехала. Объявляем токен на самой галерее — и возвращаем кадру то, что
     было у .gallery__shot: радиус --radius-lg вместо зашитых в раскладке 10px
     и зум по наведению.
     Каждый селектор пишется целиком, от .gallery, и не сворачивается в
     :is(...): сторож зеркала (spec/assets/photoatlas_layout_css_spec.rb) режет
     прелюдию по запятым, и кусок «.pa-filmstrip__item)» из :is() он принял бы
     за общее правило раскладки и потребовал бы его копию в admin.css. Это
     краска ОДНОЙ страницы, в редакторе её быть не должно. */
  .gallery { --pa-frame: var(--color-surface); }
  .gallery .pa-masonry__inner,
  .gallery .pa-series__item,
  .gallery .pa-sequence__item,
  .gallery .pa-tile__item,
  .gallery .pa-crop__item,
  .gallery .pa-filmstrip__item { border-radius: var(--radius-lg); }
  .gallery .pa-masonry__inner img,
  .gallery .pa-series__item img,
  .gallery .pa-sequence__item img,
  .gallery .pa-tile__item img,
  .gallery .pa-crop__item img,
  .gallery .pa-filmstrip__item img { transition: transform .8s var(--ease); }
  .gallery .pa-masonry__inner:hover img,
  .gallery .pa-series__item:hover img,
  .gallery .pa-sequence__item:hover img,
  .gallery .pa-tile__item:hover img,
  .gallery .pa-crop__item:hover img,
  .gallery .pa-filmstrip__item:hover img { transform: scale(1.03); }

  /* Прежняя мозаика (`columns: 3 340px`) была отзывчивой: три колонки, под
     ~1020px — две, и только под 680px — одна. Общая сетка атласа знает лишь
     про 700px, и между ними /work показывала бы три узкие колонки там, где
     раньше показывала две. !important обязателен: ширину кадра пишет
     инлайновый style (span из базы), а его специфичностью не перебить — тот же
     приём, что у правила на 700px. */
  @media (min-width: 701px) and (max-width: 1020px) {
    .gallery .pa-masonry__item { width: 50% !important; }
  }

  /* grid masonry: gapless column packing (row-span set per photo by JS from its
     height) — avoids the balancing gaps of CSS multi-column. */
  .gallery__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
    grid-auto-rows: 8px; gap: clamp(.6rem, 1.4vw, 1rem); align-items: start; }
  .gallery__grid .gallery__shot { margin: 0; }

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

/* ---------- footer ---------- */
@layer components {
  /* Вся краска футера — токенами на самом блоке. Значения ниже это тёмная плита
     сайта, ровно та же, что была; страница светлого события переопределяет
     токены у себя (body.pa-light .footer), не трогая ни одного детского
     правила. Пока дети держали rgba(255,255,255,…) числом, тема до них не
     доставала — под бумажной страницей события лежал чёрный прямоугольник. */
  .footer {
    --footer-bg: var(--color-ink);
    --footer-ink: var(--color-paper);
    --footer-sub: rgba(255, 255, 255, .65);
    --footer-muted: rgba(255, 255, 255, .6);
    --footer-faint: rgba(255, 255, 255, .55);
    --footer-line: rgba(255, 255, 255, .18);
    background: var(--footer-bg); color: var(--footer-ink); margin-top: var(--space-6);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0; position: relative; z-index: 1; }
  .footer .logo { color: var(--footer-ink); }
  .footer .logo__sub { border-color: var(--footer-line); color: var(--footer-sub); }
  .footer__inner { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-4);
    padding-block: var(--space-5); flex-wrap: wrap; }
  .footer__meta { text-align: right; }
  .footer__rights { color: var(--footer-faint); font-size: .85rem; }
  .footer__legal { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1rem; justify-content: flex-end; margin: .7rem 0 .9rem; }
  .footer__legal a { color: var(--footer-muted); font-size: .78rem; transition: color .25s; }
  .footer__legal a:hover { color: var(--footer-ink); }
  /* Facebook icon sits inline at the end of the legal-links row. */
  .footer__social-link { display: inline-flex; align-items: center; color: var(--footer-muted); transition: color .25s, transform .2s; }
  .footer__social-link:hover { color: var(--footer-ink); transform: translateY(-1px); }
  .footer__social-link svg { display: block; }
  @media (max-width: 620px) { .footer__inner { flex-direction: column; align-items: flex-start; } .footer__meta { text-align: left; } .footer__legal { justify-content: flex-start; } }
}

/* ---------- legal pages ---------- */
@layer components {
  .legal { max-width: 760px; }
  .legal__meta { color: var(--color-muted); font-size: .8rem; letter-spacing: .02em; margin-top: -.4rem; margin-bottom: var(--space-3); }
  .legal__body h2 { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; letter-spacing: -.01em; margin: var(--space-3) 0 .5rem; }
  .legal__body p { margin-bottom: .9rem; line-height: 1.7; max-width: var(--measure); }
  .legal__body ul { margin: 0 0 .9rem 1.1rem; line-height: 1.7; }
  .legal__body li { margin-bottom: .35rem; }
  .legal__body a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
}

/* ---------- flash ---------- */
@layer components {
  .flash-stack { position: fixed; top: 92px; right: 1rem; z-index: 60; display: grid; gap: .5rem; }
  .flash { padding: .8rem 1.1rem; border-radius: var(--radius); font-size: .9rem;
    background: var(--color-ink); color: var(--color-paper); box-shadow: var(--shadow-card); }
  .flash--alert { background: var(--color-error); }
}

/* ---------- lead form ---------- */
@layer components {
  .lead-form { display: grid; gap: var(--space-2); max-width: 720px; }
  .lead-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .lead-form label { display: grid; gap: .4rem; font-size: .78rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--color-muted); }
  .lead-form input, .lead-form select, .lead-form textarea {
    font: inherit; text-transform: none; letter-spacing: normal; padding: .8rem .9rem;
    background: var(--color-field); border: 1px solid var(--color-hairline); border-radius: 12px; color: var(--color-ink);
    transition: border-color .25s, box-shadow .25s; }
  .lead-form input:focus, .lead-form select:focus, .lead-form textarea:focus {
    outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent); }

  /* Replace the native <select> chrome with our own chevron (the default OS
     dropdown looked out of place against the editorial fields). */
  .lead-form select {
    appearance: none; -webkit-appearance: none; cursor: pointer;
    padding-right: 2.6rem;
    background-color: var(--color-field);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b6358' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 1rem center; background-size: 14px; }
  .lead-form select:focus {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23ff5a2e' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }

  /* Tame the native date input: brand-coloured picker popup, a custom calendar
     icon, no spin/clear buttons, same height as the other fields. */
  .lead-form input[type="date"] { appearance: none; -webkit-appearance: none; cursor: pointer; accent-color: var(--color-accent); }
  .lead-form input[type="date"]::-webkit-datetime-edit { color: var(--color-ink); }
  .lead-form input[type="date"]::-webkit-inner-spin-button,
  .lead-form input[type="date"]::-webkit-clear-button { display: none; }
  .lead-form input[type="date"]::-webkit-calendar-picker-indicator {
    cursor: pointer; opacity: .6; width: 17px; height: 17px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='%236b6358' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-size: contain; }
  .lead-form input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
  .lead-form .btn { justify-self: start; }
  .lead-form__consent { font-size: .8rem; color: var(--color-muted); max-width: var(--measure); }
  .lead-form__consent a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
  .lead-form__error { color: var(--color-error); font-weight: 600; margin-bottom: var(--space-2); }
  /* Turnstile runs in "interaction-only" mode: it only paints when Cloudflare
     decides a visitor has to prove something, so for almost everyone this
     container holds a zero-height div and costs one row of the form's gap.
     It deliberately stays in flow — a container taken out of the layout cannot
     reliably run the challenge when one is finally needed.
     :empty only matches when the script never loaded (offline, blocked). */
  .lead-form__turnstile:empty { display: none; }
  .lead-form__turnstile iframe { max-width: 100%; }
  .lead-success { padding: var(--space-3); border: 1px solid var(--color-hairline); border-radius: var(--radius-lg); background: var(--color-surface); }

  /* ===== Custom select + date controls (Stimulus-enhanced) =====
     The native <select>/<input type=date> stay in the DOM (submit value, no-JS
     and mobile fallback, styled above). When the controller connects it adds
     .is-ready / .is-custom and we swap in the branded UI below. */
  .lead-form__field { display: grid; gap: .4rem; position: relative; }
  .lead-form__field-label { font-size: .78rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--color-muted); }

  /* Shared trigger: looks exactly like a text field. */
  .field-trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    font: inherit; text-align: left; cursor: pointer; padding: .8rem .9rem; color: var(--color-ink);
    background: var(--color-field); border: 1px solid var(--color-hairline); border-radius: 12px;
    transition: border-color .25s, box-shadow .25s; }
  .field-trigger:focus-visible { outline: none; border-color: var(--color-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent); }
  .field-trigger[aria-expanded="true"] { border-color: var(--color-accent); }
  .field-trigger__chev { flex: none; width: 9px; height: 9px; margin-right: 3px; transform: translateY(-2px) rotate(45deg);
    border-right: 2px solid var(--color-muted); border-bottom: 2px solid var(--color-muted); transition: transform .15s; }
  .field-trigger[aria-expanded="true"] .field-trigger__chev { transform: translateY(2px) rotate(-135deg); border-color: var(--color-accent); }
  .field-trigger__cal { flex: none; width: 18px; height: 18px; background-repeat: no-repeat; background-size: contain; opacity: .65;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%236b6358' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E"); }

  /* Custom select: hide the native control once enhanced; show the trigger. */
  .cselect__button { display: none; }
  .cselect.is-ready .cselect__native { display: none; }
  .cselect.is-ready .cselect__button { display: flex; }
  .cselect__list { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; right: 0; margin: 0; padding: 5px;
    list-style: none; background: #fff; border: 1px solid var(--color-hairline); border-radius: 12px;
    box-shadow: 0 14px 32px -12px rgba(21, 18, 13, .35); max-height: 264px; overflow-y: auto; }
  .cselect__option { padding: .55rem .6rem; border-radius: 8px; cursor: pointer; text-transform: none; letter-spacing: normal;
    font-weight: 400; color: var(--color-ink); }
  .cselect__option:hover, .cselect__option:focus-visible { outline: none; background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
  .cselect__option.is-selected { font-weight: 600; color: var(--color-accent); }

  /* Custom date field: one styled box (placeholder + calendar icon) with a
     transparent interactive overlay. On touch/no-JS the overlay is the native
     <input type=date> (opens the OS picker — fixes the blank iOS field); on
     desktop (.is-custom) the native input is hidden and a transparent button
     opens the branded calendar instead. */
  .datefield__field { position: relative; display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    padding: .8rem .9rem; background: var(--color-field); border: 1px solid var(--color-hairline); border-radius: 12px;
    color: var(--color-ink); transition: border-color .25s, box-shadow .25s; }
  .datefield__field:focus-within { border-color: var(--color-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent); }
  .datefield__display { text-transform: none; letter-spacing: normal; }
  .datefield__display.is-empty { color: var(--color-muted); }
  .datefield__native, .datefield__trigger { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0;
    opacity: 0; border: 0; background: none; cursor: pointer; font: inherit; -webkit-appearance: none; appearance: none; }
  .datefield__trigger { display: none; }
  .datefield.is-custom .datefield__native { display: none; }
  .datefield.is-custom .datefield__trigger { display: block; }
  .cal { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; width: 286px; max-width: 100%; padding: 12px;
    background: #fff; border: 1px solid var(--color-hairline); border-radius: 14px; box-shadow: 0 14px 32px -12px rgba(21, 18, 13, .35); }
  .cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
  .cal__title { font-weight: 600; }
  .cal__nav { border: 0; background: none; cursor: pointer; font-size: 20px; line-height: 1; padding: 2px 10px;
    border-radius: 8px; color: var(--color-ink); }
  .cal__nav:hover { background: var(--color-surface); }
  .cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
  .cal__grid--dow { margin-bottom: 4px; }
  .cal__dow { text-align: center; font-size: .68rem; color: var(--color-muted); padding: 2px 0; }
  .cal__day { aspect-ratio: 1; border: 0; background: none; cursor: pointer; font: inherit; border-radius: 8px; color: var(--color-ink); }
  .cal__day--pad { cursor: default; }
  .cal__day:hover { background: color-mix(in srgb, var(--color-accent) 14%, transparent); }
  .cal__day.is-today { box-shadow: inset 0 0 0 1px var(--color-hairline); }
  .cal__day.is-selected { background: var(--color-accent); color: #fff; }
  .cal__foot { margin-top: 8px; text-align: right; }
  .cal__clear { border: 0; background: none; cursor: pointer; font: inherit; font-size: .8rem; color: var(--color-muted); }
  .cal__clear:hover { color: var(--color-accent); }

  @media (max-width: 620px) { .lead-form__row { grid-template-columns: 1fr; } }
}

/* ---------- PhotoAtlas (event pages) ---------- */
@layer components {
  /* Палитра страниц линз — тема события. По умолчанию тёмная (как было всегда);
     светлую включает data-theme="light" на корне хаба. Витрина (.pa-showcase)
     эти токены не читает. --pa-bg общий у .pa и .pa-gallery: на этом держится
     бесшовный фон под iOS-тулбаром (photoatlas_controller#hideHub). */
  .pa { --pa-ink: #f4f1ea; --pa-bg: #0b0b0c; --pa-frame: #161616;
    --pa-btn-ink: #fff; --pa-btn-line: rgba(255,255,255,.35);
    --pa-btn-bg: rgba(255,255,255,.06); --pa-btn-hover: rgba(255,255,255,.14);
    color: var(--pa-ink); background: var(--pa-bg); -webkit-user-select: none; user-select: none; }
  .pa[data-theme="light"] { --pa-ink: var(--color-ink); --pa-bg: var(--color-paper); --pa-frame: var(--color-surface);
    --pa-btn-ink: var(--color-ink); --pa-btn-line: rgba(21,18,13,.28);
    --pa-btn-bg: color-mix(in srgb, var(--color-paper) 70%, transparent);
    --pa-btn-hover: color-mix(in srgb, var(--color-paper) 92%, transparent); }
  /* Шрифтовые пресеты заголовка хаба — те же значения, что у галереи
     (gallery.css .gallery-body[data-font]). gallery.css на сайт и в ZIP не
     попадает, поэтому здесь копия. ЗЕРКАЛА: gallery.css и admin.css — менять синхронно. */
  .pa[data-font="studio"]    { --pa-title-font: var(--font-display); --pa-title-weight: 800; --pa-title-style: normal; --pa-title-case: none; --pa-title-tracking: -0.02em; }
  .pa[data-font="classic"]   { --pa-title-font: var(--font-serif);   --pa-title-weight: 400; --pa-title-style: italic; --pa-title-case: none; --pa-title-tracking: 0; }
  .pa[data-font="editorial"] { --pa-title-font: var(--font-sans);    --pa-title-weight: 600; --pa-title-style: normal; --pa-title-case: uppercase; --pa-title-tracking: 0.28em; }
  .pa-showcase { color: var(--color-ink); background: var(--color-paper); user-select: auto; }

  .pa-hub { position: relative; min-height: 100svh; overflow: hidden; }
  /* The cover is full-bleed — drop the footer's usual top gap so it meets it,
     and square its top corners with it: the 16px rounding is meant for a footer
     lifted over the page, and pressed straight against the photos it reads as
     two notches cut into them. */
  body:has(.pa-hub) .footer { margin-top: 0; border-radius: 0; }
  .pa-cover { position: absolute; inset: 0; }
  .pa-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .pa-cover__veil { position: absolute; inset: 0;
    background: radial-gradient(120% 90% at 50% 38%, transparent 52%, rgba(0,0,0,.45)),
                linear-gradient(180deg, rgba(0,0,0,.35), transparent 25%); }
  /* Заголовок — в одной из 9 точек сетки 3×3 (CoverLook, выбирается в карточке
     «Обложка»). Схема как у обложки галереи (gallery.css): середины верхней и
     нижней стороны и центр — блок между полями с центрированным текстом (длинный
     заголовок не вылезает за экран), середины боковых — translateY.
     pointer-events: none — центр/середины ложатся поверх линз и не должны глотать
     тапы по ним; ссылки в лиде включают их обратно. */
  .pa-hub__brand { position: absolute; z-index: 4; max-width: min(88%, 42rem); color: #f4f1ea; pointer-events: none;
    --pa-edge-x: clamp(1.25rem, 4vw, 3rem); --pa-edge-y: clamp(1.5rem, 5vh, 3rem); }
  .pa-hub__brand--top-left { top: var(--pa-edge-y); left: var(--pa-edge-x); }
  .pa-hub__brand--top-center { top: var(--pa-edge-y); left: var(--pa-edge-x); right: var(--pa-edge-x);
    margin-inline: auto; text-align: center; }
  .pa-hub__brand--top-right { top: var(--pa-edge-y); right: var(--pa-edge-x); text-align: right; }
  .pa-hub__brand--middle-left { top: 50%; transform: translateY(-50%); left: var(--pa-edge-x); }
  .pa-hub__brand--center { top: 50%; transform: translateY(-50%); left: var(--pa-edge-x); right: var(--pa-edge-x);
    margin-inline: auto; text-align: center; }
  .pa-hub__brand--middle-right { top: 50%; transform: translateY(-50%); right: var(--pa-edge-x); text-align: right; }
  .pa-hub__brand--bottom-left { bottom: var(--pa-edge-y); left: var(--pa-edge-x); }
  .pa-hub__brand--bottom-center { bottom: var(--pa-edge-y); left: var(--pa-edge-x); right: var(--pa-edge-x);
    margin-inline: auto; text-align: center; }
  .pa-hub__brand--bottom-right { bottom: var(--pa-edge-y); right: var(--pa-edge-x); text-align: right; }
  .pa-hub__kicker { font: 600 .72rem/1 var(--font-sans); letter-spacing: .22em; text-transform: uppercase; opacity: .82; }
  /* Регистр и трекинг задаём явно для каждого пресета: базовый h1 — uppercase. */
  .pa-hub__title { font-family: var(--pa-title-font, var(--font-display)); font-weight: var(--pa-title-weight, 800);
    font-style: var(--pa-title-style, normal); text-transform: var(--pa-title-case, none);
    letter-spacing: var(--pa-title-tracking, -0.02em); line-height: .92;
    font-size: clamp(2.4rem, 7vw, 5rem); margin-top: .4rem; }
  /* Optional editorial lead under the title (event.description, rich text) — adds
     real, crawlable copy to an otherwise image-only page. Constrained + shadowed
     to stay legible over the cover; flushes to the anchored edge for right-corner
     placements. Formatting (bold/italic/links) keeps the cover's colour. */
  .pa-hub__lead { margin-top: .85rem; max-width: 40ch;
    font: 500 clamp(.95rem, 1.6vw, 1.12rem)/1.45 var(--font-sans);
    text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
    /* Cap the on-cover teaser at 3 lines so a long intro never sprawls across
       the lenses; the full text stays in the DOM (and in meta/JSON-LD). */
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
  .pa-hub__brand--top-right .pa-hub__lead,
  .pa-hub__brand--middle-right .pa-hub__lead,
  .pa-hub__brand--bottom-right .pa-hub__lead { margin-left: auto; }
  .pa-hub__brand--top-center .pa-hub__lead,
  .pa-hub__brand--center .pa-hub__lead,
  .pa-hub__brand--bottom-center .pa-hub__lead { margin-inline: auto; }
  .pa-hub__lead a { color: inherit; text-decoration: underline; text-underline-offset: .15em; pointer-events: auto; }

  /* Цвет текста обложки — независим от темы, как у галереи. Светлый — привычный
     вид: светлые буквы под тёмной вуалью. Тёмный — чёрные буквы со светлой тенью;
     вуаль тогда не затемняет фото, а слегка высветляет края, чтобы тёмное читалось. */
  .pa[data-text-color="dark"] .pa-hub__brand { color: #111; text-shadow: 0 1px 12px rgba(255,255,255,.55); }
  .pa[data-text-color="dark"] .pa-hub__lead { text-shadow: 0 1px 6px rgba(255,255,255,.7); }
  .pa[data-text-color="dark"] .pa-cover__veil {
    background: radial-gradient(120% 90% at 50% 38%, transparent 52%, rgba(255,255,255,.3)),
                linear-gradient(180deg, rgba(255,255,255,.32), transparent 25%); }

  .pa-pill { position: absolute; left: 50%; top: clamp(1rem, 4vh, 2.2rem); transform: translateX(-50%); z-index: 5;
    padding: 12px 30px; border-radius: 999px; color: #fff; cursor: pointer;
    font: 600 clamp(.9rem,2.4vw,1.05rem)/1 var(--font-sans); letter-spacing: .03em;
    backdrop-filter: blur(18px) saturate(1.4) brightness(1.05);
    background: linear-gradient(135deg, rgba(255,255,255,.2), rgba(255,255,255,.04));
    border: 1px solid rgba(255,255,255,.5); text-shadow: 0 1px 4px rgba(0,0,0,.5);
    box-shadow: 0 10px 30px -12px rgba(0,0,0,.6), inset 0 1px 1px rgba(255,255,255,.5);
    transition: transform .3s var(--ease), box-shadow .3s; }
  .pa-pill:hover { transform: translateX(-50%) scale(1.04); }

  .pa-lens { position: absolute; z-index: 3; left: var(--pa-x); top: var(--pa-y);
    width: var(--pa-size); min-width: 96px; transform: translate(-50%, -50%);
    border: 1px solid rgba(255,255,255,.4); border-radius: 50%; overflow: hidden; cursor: pointer; padding: 0;
    background: transparent;
    /* clip-path reliably clips to a circle on iOS Safari, where overflow+border-radius
       on a transformed element does not. Outer shadow/glow via filter so clip keeps them. */
    -webkit-clip-path: circle(50%); clip-path: circle(50%);
    box-shadow: inset 0 3px 5px rgba(255,255,255,.78), inset 0 -18px 30px rgba(0,0,0,.34);
    filter: drop-shadow(0 16px 26px rgba(0,0,0,.5)) drop-shadow(0 0 13px rgba(255,90,46,.3));
    transition: transform .4s var(--ease), filter .4s; }
  /* Square height with the universal padding-top hack — no aspect-ratio/calc/vw/JS,
     works on every Safari. % is relative to the lens's own width, so the circle
     is exact even when min-width clamps the size. */
  .pa-lens::before { content: ""; display: block; padding-top: 100%; }
  .pa-lens:hover { transform: translate(-50%,-50%) scale(1.06);
    box-shadow: inset 0 1.5px 3px rgba(255,255,255,.65), inset 0 -12px 22px rgba(0,0,0,.2);
    filter: drop-shadow(0 20px 30px rgba(0,0,0,.5)) drop-shadow(0 0 18px rgba(255,90,46,.42)); }
  .pa-lens__glass { position: absolute; inset: -2px; border-radius: 50%; background-image: var(--pa-cover-url);
    background-size: var(--pa-bgw, cover); background-position: var(--pa-bgx, center) var(--pa-bgy, center);
    filter: blur(1.2px) saturate(1.28) brightness(1.04); }
  .pa-lens__shade { position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
    background: radial-gradient(115% 115% at 33% 22%, rgba(255,255,255,.36), rgba(255,255,255,.06) 26%, transparent 46%),
                radial-gradient(125% 125% at 68% 86%, rgba(0,0,0,.36), transparent 50%),
                radial-gradient(circle at 50% 42%, transparent 42%, rgba(0,0,0,.30) 86%, rgba(0,0,0,.48) 100%),
                radial-gradient(circle at 50% 50%, transparent 58%, rgba(255,90,46,.14) 100%); }
  .pa-lens__spec { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; mix-blend-mode: screen;
    background: radial-gradient(34% 22% at 31% 20%, rgba(255,255,255,.92), rgba(255,255,255,.12) 44%, transparent 60%),
                radial-gradient(12% 8% at 64% 27%, rgba(255,255,255,.6), transparent 70%); }
  /* Подпись центрируется в круге. letter-spacing небольшой и padding узкий,
     чтобы длинные одиночные слова (PERFORMANCE, DISCUSSIONS) целиком влезали в
     линзу даже при min-width на мобильном (одно слово не переносится). */
  .pa-lens__cap { position: absolute; inset: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center; text-align: center; padding: 0 .35rem;
    font: 700 clamp(.62rem,1.5vw,.78rem)/1.1 var(--font-sans);
    letter-spacing: .06em; text-transform: uppercase; color: #fff; text-shadow: 0 1px 5px rgba(0,0,0,.65); }

  /* Sits ABOVE the gallery during the dive: you fall through the cover and the
     gallery is revealed beneath as the cover zooms, blurs and fades away. */
  .pa-stage { position: fixed; inset: 0; z-index: 70;
    background-image: var(--pa-cover-url); background-size: cover; background-position: center;
    transform-origin: var(--pa-ox, 50%) var(--pa-oy, 50%);
    will-change: clip-path, transform, opacity, filter; }

  .pa-gallery { position: fixed; inset: 0; z-index: 60; overflow-y: auto; background: var(--pa-bg);
    padding: clamp(4.5rem, 9vh, 7rem) clamp(1rem, 4vw, 2.75rem) clamp(3rem, 6vh, 4rem);
    opacity: 0; transform: translateY(14px);
    transition: opacity .45s var(--ease), transform .55s var(--ease); }
  .pa-gallery[data-open] { opacity: 1; transform: translateY(0); }
  .pa-gallery__head { position: fixed; top: clamp(1rem,3vh,1.6rem); left: clamp(1rem,4vw,2.75rem); right: clamp(1rem,4vw,2.75rem);
    z-index: 2; display: flex; align-items: center; gap: 1rem; }
  .pa-gallery__back { width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--pa-btn-line);
    background: var(--pa-btn-bg); color: var(--pa-btn-ink); font-size: 1.2rem; cursor: pointer; backdrop-filter: blur(10px);
    transition: background .25s, transform .25s; }
  .pa-gallery__back:hover { background: var(--pa-btn-hover); transform: translateX(-2px); }
  .pa-gallery__name { font-family: var(--font-display); font-weight: 800; letter-spacing: .02em;
    text-transform: uppercase; font-size: clamp(1.3rem, 4vw, 2rem); }
  .pa-gallery__foot { display: flex; justify-content: center; padding-top: clamp(1.5rem, 4vh, 3rem); }
  .pa-gallery__foot-back { display: inline-flex; align-items: center; gap: .6rem; padding: .85rem 1.6rem;
    border-radius: 999px; border: 1px solid var(--pa-btn-line); background: var(--pa-btn-bg);
    color: var(--pa-btn-ink); font-size: .95rem; font-weight: 600; cursor: pointer; backdrop-filter: blur(10px);
    transition: background .25s, transform .25s; }
  .pa-gallery__foot-back:hover { background: var(--pa-btn-hover); transform: translateY(-2px); }
  /* Masonry: each photo keeps its natural proportions (aspect-ratio per item),
     widths vary by column span. Muuri positions items absolutely; the same
     packing runs in the admin editor so the public page mirrors it. */
  /* До JS кадры лежат в потоке и страница читается как обычная сетка. Muuri,
     взяв раскладку на себя, ставит на контейнер data-masonry-live — и только
     тогда кадры уходят в absolute. Без этого переключателя высоту контейнеру
     давал бы ИСКЛЮЧИТЕЛЬНО Muuri, и всюду, где скрипт не выполнился
     (устаревший service worker, упавший importmap, краулер без JS), от главы
     оставался бы заголовок над коробкой нулевой высоты. До переезда та же
     страница была чистой CSS-мозаикой и оставалась читаемой всегда. */
  .pa-masonry { position: relative; max-width: var(--maxw); margin-inline: auto;
    display: flex; flex-wrap: wrap; align-items: flex-start; }
  /* Masonry spaces frames with padding, not gap (Muuri positions items
     absolutely), so the lens gutter is halved: two neighbouring paddings add up
     to one gutter. The default keeps the pre-feature look — every lens ships
     margin: 12 (DB default), and 12 / 2 = 6px, exactly the value this used to
     hardcode. Changing the gutter in the toolbar now actually moves masonry. */
  .pa-masonry__item { position: relative; box-sizing: border-box;
    padding: calc(var(--pa-gap, 12px) / 2); margin: 0; }
  .pa-masonry[data-masonry-live] .pa-masonry__item { position: absolute; }
  .pa-masonry__inner { position: relative; overflow: hidden; border-radius: 10px; background: var(--pa-frame, #161616); }
  .pa-masonry__inner img { display: block; width: 100%; height: auto; }
  @media (max-width: 700px) {
    .pa-masonry__item { width: 100% !important; }
  }

  /* NB: the admin layout editor renders these very same partials but loads
     admin.css, not this file (see app/views/layouts/admin.html.erb), so every
     `.pa-*` layout selector below is duplicated there. Add, rename or remove
     one here and you must do the same in admin.css —
     spec/assets/photoatlas_layout_css_spec.rb fails if the two sets drift. */

  /* Series: justified rows. The packer decides which frames share a row; the
     flex-grow below (each frame's aspect ratio) makes every frame in a row land
     on the same height and fills the row exactly. */
  .pa-series { max-width: var(--maxw); margin-inline: auto; display: grid; gap: var(--pa-gap, 12px); }
  .pa-series__row { display: flex; gap: var(--pa-gap, 12px); }
  .pa-series__item { position: relative; margin: 0; min-width: 0; overflow: hidden;
    border-radius: 10px; background: var(--pa-frame, #161616); }
  .pa-series__item img { display: block; width: 100%; height: auto; }
  @media (max-width: 700px) {
    /* Rows are computed server-side and cannot re-pack for a phone, so they
       stack — one frame per line, matching what masonry already does. */
    .pa-series__row { flex-direction: column; }
    /* flex-direction: column moves the main axis to vertical, so the item's
       inline `flex: <ar> 1 0` shorthand (still set for the desktop row, see
       _series.html.erb) would now apply its flex-basis: 0 to HEIGHT instead
       of width, and the row's height is content-based — nothing left to grow
       into, so every frame collapses to 0px tall and its image gets clipped.
       Force the item off the main axis here so its height comes from its
       content (the image) again. The !important is required: an inline
       style="flex: ..." attribute outranks any stylesheet selector on
       specificity alone, media query or not. Do not remove this as
       "redundant" with the base rule above. */
    .pa-series__item { flex: 0 0 auto !important; }
  }

  /* Sequence: one frame per row, full width, natural height. */
  .pa-sequence { max-width: var(--maxw); margin-inline: auto; display: grid; gap: var(--pa-gap, 12px); }
  .pa-sequence__item { margin: 0; overflow: hidden; border-radius: 10px; background: var(--pa-frame, #161616); }
  .pa-sequence__item img { display: block; width: 100%; height: auto; }

  /* Filmstrip: a single row panned horizontally — a swipe on a phone. Frames
     share one height and take their width from their own proportions. */
  .pa-filmstrip { display: flex; gap: var(--pa-gap, 12px); overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; padding-inline: clamp(1.25rem, 4vw, 2.75rem); scrollbar-width: thin; }
  .pa-filmstrip__item { flex: 0 0 auto; height: min(70vh, 620px); margin: 0; scroll-snap-align: center;
    overflow: hidden; border-radius: 10px; background: var(--pa-frame, #161616); }
  .pa-filmstrip__item img { display: block; height: 100%; width: auto; }
  @media (max-width: 700px) { .pa-filmstrip__item { height: min(60vh, 460px); } }

  /* Tile: masonry that keeps the curated order. Columns are fixed; the row-span
     controller gives each frame a grid-row-end matching its rendered height, so
     the columns pack tightly with no balancing gaps and no CDN dependency. */
  .pa-tile { max-width: var(--maxw); margin-inline: auto; display: grid;
    grid-template-columns: repeat(var(--pa-cols, 3), 1fr);
    gap: var(--pa-gap, 12px); grid-auto-rows: 8px; align-items: start; }
  .pa-tile__item { margin: 0; overflow: hidden; border-radius: 10px; background: var(--pa-frame, #161616); }
  .pa-tile__item img { display: block; width: 100%; height: auto; }
  @media (max-width: 700px) { .pa-tile { grid-template-columns: 1fr; } }

  /* Crop: a uniform grid. Every frame is cut to the lens ratio and held in
     place by its own focal point, so faces survive the crop. */
  .pa-crop { max-width: var(--maxw); margin-inline: auto; display: grid;
    grid-template-columns: repeat(var(--pa-cols, 3), 1fr); gap: var(--pa-gap, 12px); }
  .pa-crop__item { position: relative; margin: 0; overflow: hidden; border-radius: 10px; background: var(--pa-frame, #161616); }
  .pa-crop__item img { display: block; width: 100%; height: 100%; object-fit: cover; }
  @media (max-width: 700px) { .pa-crop { grid-template-columns: 1fr; } }

  .pa-showcase__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.4rem;
    padding-block: var(--space-2) var(--space-5); }
  .pa-showcase__card { display: grid; gap: .8rem; }
  .pa-showcase__media { display: block; aspect-ratio: 16/10; overflow: hidden; border-radius: var(--radius-lg); background: var(--color-surface); }
  .pa-showcase__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease); }
  .pa-showcase__card:hover .pa-showcase__media img { transform: scale(1.05); }
  .pa-showcase__title { font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; }
  .pa-showcase__sub { color: var(--color-muted); font-size: .85rem; }

  .pa-lock { overflow: hidden; }
  /* Raise <main> above sticky nav when a gallery is open */
  .pa-lock main { z-index: 55; }

  /* Тема события на <body> (layout ставит pa-dark / pa-light по @event.theme).
     Светлая — обычная бумажная навигация на бумажном фоне. */
  body.pa-light { background: var(--color-paper); }
  /* Футер идёт за темой события: на светлой — бумага и чернила вместо тёмной
     плиты сайта, которая висела чужим чёрным прямоугольником под бумажной
     страницей. Три приглушённых тона тёмной темы (.65/.6/.55 белого) светлая
     осознанно сводит в один --color-muted: на бумаге это 5.2:1, выше порога AA
     для мелкого текста ссылок (.78rem) и строки прав (.85rem), а иерархию
     здесь и без того держат кегль с трекингом. */
  body.pa-light .footer {
    --footer-bg: var(--color-paper);
    --footer-ink: var(--color-ink);
    --footer-sub: var(--color-muted);
    --footer-muted: var(--color-muted);
    --footer-faint: var(--color-muted);
    --footer-line: var(--color-hairline);
  }
  /* Immersive transparent nav over the dark event hub (pa-dark on <body>) */
  body.pa-dark { background: #0b0b0c; }
  body.pa-dark .nav { background: transparent; backdrop-filter: none; border-bottom-color: transparent; }
  body.pa-dark .logo { color: #fff; }
  body.pa-dark .logo__sub { color: rgba(255,255,255,.6); border-top-color: rgba(255,255,255,.22); }
  body.pa-dark .nav__link { color: #fff; opacity: .78; }
  body.pa-dark .nav__link:hover, body.pa-dark .nav__link.is-current { opacity: 1; }
  body.pa-dark .nav__link:last-of-type { background: rgba(255,255,255,.12); color: #fff;
    border: 1px solid rgba(255,255,255,.35); backdrop-filter: blur(8px); }
  body.pa-dark .nav__link:last-of-type:hover { background: var(--color-accent); border-color: transparent; }
  body.pa-dark .nav__toggle span { background: #fff; }
  body.pa-dark .lang__item { color: rgba(255,255,255,.55); }
  body.pa-dark .lang__item.lang--active { color: #fff; }
  body.pa-dark .lang__item:hover { color: var(--color-accent); }
  /* Open mobile menu on a pa-dark page: make the whole overlay solid dark so the
     white nav links read (the panel's default paper bg gave white-on-white). */
  @media (max-width: 860px) {
    body.pa-dark .nav.is-open { background: #0d0d0f; }
    body.pa-dark .nav__links { background: #0d0d0f; border-top: 1px solid rgba(255,255,255,.08); }
  }
  @media (prefers-reduced-motion: reduce) {
    .pa-stage, .pa-gallery, .pa-lens { transition: none !important; }
  }
}

@layer components {
  /* ---------- on-site printing ---------- */
  .prn-hero { display: grid; grid-template-columns: 1fr 1.12fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
  .prn-hero__cta { margin-top: 2rem; }
  .prn-hero__art, .prn-kit__art {
    border-radius: var(--radius-lg);
    background: linear-gradient(165deg, #efece3, #e6e0d4);
    border: 1px solid var(--color-hairline);
    overflow: hidden;
  }
  .prn-hero__art { box-shadow: var(--shadow-card); }
  .prn-svg { width: 100%; height: auto; display: block; }

  .prn-steps { list-style: none; padding: 0; margin-top: var(--space-3);
    display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1rem, 2.5vw, 2rem); }
  .prn-step { padding: 1.7rem 1.5rem; border: 1px solid var(--color-hairline); border-radius: var(--radius-lg); background: var(--color-field); }
  .prn-step__icon { color: var(--color-accent); display: block; width: 48px; height: 48px; margin-bottom: 1.1rem; }
  .prn-step__icon svg { width: 100%; height: 100%; }
  .prn-step__n { font-family: var(--font-display); font-weight: 800; font-size: .78rem; letter-spacing: .14em; color: var(--color-muted); margin-bottom: .35rem; }
  .prn-step h3 { margin-bottom: .45rem; }
  .prn-step p { color: var(--color-muted); }
  .prn-steps [data-reveal]:nth-child(2) { transition-delay: .08s; }
  .prn-steps [data-reveal]:nth-child(3) { transition-delay: .16s; }

  .prn-kit { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, 3vw, 2rem); margin-top: var(--space-3); }
  .prn-kit__card { border: 1px solid var(--color-hairline); border-radius: var(--radius-lg); overflow: hidden; background: var(--color-field); }
  .prn-kit__art { border: 0; border-bottom: 1px solid var(--color-hairline); border-radius: 0; }
  .prn-kit__card h3 { margin: 1.5rem 1.6rem .45rem; }
  .prn-kit__card p { margin: 0 1.6rem 1.7rem; color: var(--color-muted); }
  .prn-kit [data-reveal]:nth-child(2) { transition-delay: .08s; }

  .prn-uses { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-top: var(--space-3); }
  .prn-use { padding: 1.4rem 1.3rem 1.6rem; border-top: 2px solid var(--color-ink); }
  .prn-use__n { font-family: var(--font-display); font-weight: 800; color: var(--color-accent); font-size: .85rem; letter-spacing: .12em; }
  .prn-use h3 { margin: .7rem 0 .4rem; }
  .prn-use p { color: var(--color-muted); font-size: .96rem; }
  .prn-uses [data-reveal]:nth-child(2) { transition-delay: .06s; }
  .prn-uses [data-reveal]:nth-child(3) { transition-delay: .12s; }
  .prn-uses [data-reveal]:nth-child(4) { transition-delay: .18s; }

  .prn-cta { text-align: center; border-radius: var(--radius-lg); background: var(--color-surface);
    border: 1px solid var(--color-hairline); padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 4vw, 3rem); }
  .prn-cta .lede { margin: 1rem auto 1.8rem; }

  @media (max-width: 980px) { .prn-uses { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 860px) {
    .prn-hero { grid-template-columns: 1fr; }
    .prn-steps { grid-template-columns: 1fr; }
    .prn-kit { grid-template-columns: 1fr; }
  }
  @media (max-width: 560px) { .prn-uses { grid-template-columns: 1fr; } }
}

@layer components {
  /* ---------- studio / brand manifesto ---------- */
  .studio-hero__title { margin: .6rem 0 1.3rem; max-width: 16ch; }
  .studio-hero__lede { max-width: 44ch; }
  .studio-hero__cta { margin-top: 2rem; }

  .studio-manifesto { max-width: 52rem; border-left: 3px solid var(--color-accent);
    padding-left: clamp(1.2rem, 3vw, 2.4rem); }
  .studio-manifesto__head { font-size: clamp(1.9rem, 4vw, 3rem); margin-bottom: 1.1rem; }
  .studio-manifesto__body { font-family: var(--font-serif); font-size: clamp(1.2rem, 2.2vw, 1.6rem);
    line-height: 1.5; color: var(--color-ink); }

  .studio-principles { display: grid; grid-template-columns: repeat(2, 1fr);
    gap: clamp(1rem, 3vw, 2rem); margin-top: var(--space-3); }
  .studio-principle { padding: 1.6rem 1.6rem 1.7rem; border-top: 2px solid var(--color-ink); }
  .studio-principle__n { font-family: var(--font-display); font-weight: 800; color: var(--color-accent);
    font-size: .9rem; letter-spacing: .12em; }
  .studio-principle h3 { margin: .7rem 0 .45rem; font-size: 1.3rem; }
  .studio-principle p { color: var(--color-muted); }
  .studio-principles [data-reveal]:nth-child(2) { transition-delay: .06s; }
  .studio-principles [data-reveal]:nth-child(3) { transition-delay: .12s; }
  .studio-principles [data-reveal]:nth-child(4) { transition-delay: .18s; }

  .studio-cta { text-align: center; border-radius: var(--radius-lg); background: var(--color-surface);
    border: 1px solid var(--color-hairline); padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 4vw, 3rem); }
  .studio-cta .lede { margin: 1rem auto 1.8rem; }

  @media (max-width: 760px) { .studio-principles { grid-template-columns: 1fr; } }
}
