/* ============================================================
   КОЛОМНА ФЕСТ '26 — общая дизайн-система.
   Единственный источник правды по цвету, шрифту и фактуре.
   Хардкодных цветов в страницах быть не должно.

   Опора — афиша и логотип: лимон, серый, чёрный; растровая
   бумага; наклонные блоки; рукописная кисть; линии карты района.
   ============================================================ */

:root{
  /* ---- фирменные ---- */
  --lemon:      #fdf105;
  --lemon-rgb:  253 241 5;
  --grey:       #a9abad;
  --grey-rgb:   169 171 173;
  --ink:        #0d0d0c;
  --ink-rgb:    13 13 12;

  /* ---- производные подложки ---- */
  --paper:      #e6e4df;   /* серая бумага афиши */
  --paper-rgb:  230 228 223;
  --paper-hi:   #f2f0ec;   /* засвеченный край листа */
  --paper-lo:   #cfcdc8;   /* тень сгиба */
  --dim:        #6f7173;   /* приглушённый текст по бумаге */

  /* ---- типографика ----
     Все три семейства — с полной кириллицей.
     Playfair 900 повторяет тяжёлую антикву афиши,
     PT Serif — читаемый текст, PT Sans — интерфейс и карта. */
  --display: 'Playfair Display', 'Times New Roman', serif;
  --body:    'PT Serif', Georgia, serif;
  --ui:      'PT Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* ---- фактура ---- */
  --grain: .13;          /* плотность зерна, рабочий диапазон .08–.18 */
  --tilt: -2.4deg;       /* базовый наклон блоков */
}

*{ box-sizing:border-box; margin:0; padding:0; -webkit-tap-highlight-color:transparent; }

html{ scroll-behavior:smooth; }
body{
  background:var(--paper); color:var(--ink);
  font-family:var(--body); font-size:17px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
  /* clip, а НЕ hidden: overflow-x:hidden превращает body в собственный
     контейнер прокрутки, после чего окно перестаёт скроллиться само —
     ломаются и эффекты по scrollY, и position:sticky. clip обрезает
     вылезающее по горизонтали, но контейнер прокрутки не создаёт. */
  overflow-x:clip;
}

/* ============================================================
   1. РАСТРОВАЯ БУМАГА
   Три слоя, все — псевдоэлементы, ни одной картинки:
     • неровный тон листа (два больших радиальных пятна),
     • типографский растр (точки через repeating-radial-gradient),
     • плёночное зерно (feTurbulence во вшитом data-URI).
   Зерно намеренно обесцвечено feColorMatrix: цветной шум увёл бы
   лимон в грязь. stitchTiles='stitch' убирает швы на стыках тайла.
   ============================================================ */
.paper{ position:relative; isolation:isolate; background-color:var(--paper); }
.paper::before{
  content:''; position:absolute; inset:0; z-index:-2; pointer-events:none;
  background:
    radial-gradient(70% 55% at 12% 0%,  var(--paper-hi) 0%, rgb(var(--paper-rgb)/0) 70%),
    radial-gradient(60% 60% at 92% 88%, var(--paper-lo) 0%, rgb(var(--paper-rgb)/0) 72%);
}
.paper::after{
  content:''; position:absolute; inset:0; z-index:-1; pointer-events:none;
  opacity:var(--grain); mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='table' tableValues='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:180px 180px;
}

/* Класс оставлен пустым намеренно: типографский растр из точек рябил
   под лимонным блоком и читался как дефект экрана, а не как печать.
   Фактуру держит одно зерно .paper. */
.halftone{ position:relative; }

/* ============================================================
   2. ЛИНИИ КАРТЫ РАЙОНА
   Настоящая геометрия улиц и каналов Коломны из OSM
   (_local/build/mklines.py). currentColor — красится контекстом.

   ВНИМАНИЕ: без mix-blend-mode намеренно. Блендинг заставляет Chrome
   поднимать весь блок с линиями в отдельный композитный слой, и тот
   перекрывает соседей с бо́льшим z-index — хит-тест и отрисовка расходятся.
   Поверх плоского лимона multiply всё равно ничего не давал.
   ============================================================ */
.lines{
  position:absolute; inset:0; pointer-events:none;
  background:url('../assets/kolomna-lines.svg') no-repeat center/cover;
  opacity:.5;
}

/* ============================================================
   3. НАКЛОННЫЕ БЛОКИ
   Наклоняем контейнер, содержимое возвращаем обратно —
   иначе текст едет вместе с плашкой и его тяжело читать.
   ============================================================ */
.slab{ transform:rotate(var(--tilt)); transform-origin:center; }
.slab > .straight{ transform:rotate(calc(var(--tilt) * -1)); }
.tilt-r{ --tilt:2deg; }
.tilt-l{ --tilt:-2deg; }

/* косой срез секции — лимонный клин афиши */
.wedge{ clip-path:polygon(0 4vw, 100% 0, 100% calc(100% - 3vw), 0 100%); }

/* ============================================================
   4. ТИПОГРАФИКА
   ============================================================ */
h1,h2,h3{ font-family:var(--display); font-weight:900; line-height:.92; letter-spacing:-.015em; }
h1{ font-size:clamp(46px,11vw,150px); text-transform:uppercase; }
h2{ font-size:clamp(30px,6vw,72px); text-transform:uppercase; }
h3{ font-size:clamp(20px,3vw,30px); }

.kicker{
  font-family:var(--ui); font-weight:700; text-transform:lowercase;
  letter-spacing:.02em; font-size:clamp(13px,1.7vw,18px); color:var(--dim);
}
.lead{ font-size:clamp(17px,2.1vw,23px); max-width:34em; }

/* лимонная выделялка — как маркером по строке */
.mark{
  background:linear-gradient(var(--lemon),var(--lemon)) no-repeat;
  background-size:100% .62em; background-position:0 .72em;
  padding:0 .12em;
}

/* ============================================================
   5. КНОПКИ И ССЫЛКИ
   ============================================================ */
.btn{
  --btn-bg:var(--paper-hi); --btn-shadow:3px 3px 0 rgb(var(--ink-rgb)/.22);
  position:relative; z-index:0; isolation:isolate;
  font-family:var(--ui); font-weight:700; font-size:15px; line-height:1;
  display:inline-flex; align-items:center; gap:.45em;
  padding:.62em 1.05em; border:0; background:none;
  color:var(--ink); text-decoration:none; cursor:pointer; white-space:nowrap;
  transition:transform .1s ease;
}
/* Скошенная плашка живёт в псевдоэлементе: сам скос уводит края вбок,
   а подпись остаётся прямой и читаемой. БЕЗ рамки: кнопка — печатная
   плашка с жёсткой офсетной тенью, а не обведённое поле. */
.btn::before{
  content:''; position:absolute; inset:0; z-index:-1;
  transform:skewX(-5deg);
  background:var(--btn-bg);
  box-shadow:var(--btn-shadow);
  transition:background .1s ease, box-shadow .1s ease;
}
.btn:hover{ transform:translate(-2px,-2px); }
.btn:hover{ --btn-bg:var(--lemon); --btn-shadow:4px 4px 0 var(--ink); }
.btn:active{ transform:translate(0,0); --btn-shadow:1px 1px 0 rgb(var(--ink-rgb)/.3); }
.btn.on,.btn.solid{ --btn-bg:var(--lemon); --btn-shadow:3px 3px 0 rgb(var(--ink-rgb)/.35); }
.btn.dark{ --btn-bg:var(--ink); color:var(--paper-hi); --btn-shadow:3px 3px 0 rgb(var(--ink-rgb)/.28); }
.btn.dark:hover{ --btn-bg:var(--ink); color:var(--lemon); --btn-shadow:4px 4px 0 var(--lemon); }

/* ============================================================
   6. ПЕЧАТЬ-ШТАМП  (SVG textPath внутри)
   ============================================================ */
.stamp{ width:clamp(120px,16vw,190px); color:var(--ink); opacity:.8; transform:rotate(-9deg); }
.stamp text{ font-family:var(--ui); font-weight:700; letter-spacing:.18em; font-size:12.5px; }

/* ============================================================
   7. ШАПКА САЙТА
   ============================================================ */
/* Шапка закреплена: район большой, страница длинная, и карта должна быть
   в одном движении из любого места. sticky, а не fixed, — поток не рвётся
   и под шапку не надо подкладывать распорку.
   Работает благодаря overflow-x:clip на body: clip, в отличие от hidden,
   не делает body контейнером прокрутки (см. коммент выше). */
.topnav{
  display:flex; align-items:center; gap:.7em; flex-wrap:wrap;
  padding:.8em 5vw; border-bottom:2px solid var(--ink);
  background:var(--paper-hi); position:sticky; top:0; z-index:200;
  transition:box-shadow .18s ease;
}
/* Тень появляется только когда под шапкой что-то уехало: на первом экране
   она лишняя, а в середине страницы отделяет шапку от бумаги. */
.topnav.stuck{ box-shadow:0 8px 20px -6px rgb(var(--ink-rgb)/.22); }
/* Якоря: без этого заголовок секции приезжает под закреплённую шапку.
   --nav-h ставит assets/ui.js по фактической высоте шапки. */
section[id], [id]{ scroll-margin-top:calc(var(--nav-h, 62px) + 12px); }
.topnav .logo{ height:34px; width:auto; display:block; }
.topnav a{ font-family:var(--ui); font-weight:700; font-size:14px; color:var(--ink);
  text-decoration:none; padding:.3em .1em; border-bottom:2px solid transparent; }
.topnav a:hover{ border-bottom-color:var(--lemon); }
.topnav .sp{ flex:1 1 auto; }

/* На телефоне кнопка «Открыть карту» переносится на вторую строку и шапка
   вырастает вдвое ради того, что и так есть большой кнопкой на первом экране.
   Прячем её, а пунктам меню даём воздух под палец. */
@media (max-width:700px){
  .topnav{ gap:.2em .9em; padding:.7em 6vw; flex-wrap:nowrap; }
  .topnav .btn{ display:none; }
  .topnav .logo{ height:30px; margin-right:.2em; }
  .topnav a{ font-size:15px; padding:.45em .1em; }
  /* Высоту шапки в прокрутке намеренно НЕ меняем: под ней на странице
     программы стоит второй закреплённый ряд, и «дышащая» шапка дёргала бы
     его на каждом пикселе прокрутки. */
  section[id], [id]{ scroll-margin-top:calc(var(--nav-h, 56px) + 8px); }
}

footer.site{
  background:var(--ink); color:var(--paper); font-family:var(--ui); font-size:14px;
  padding:2.4em 5vw; display:flex; gap:1.2em; align-items:center; flex-wrap:wrap;
}
footer.site b{ color:var(--lemon); }
footer.site img{ height:44px; width:auto; }

/* ============================================================
   8. ДОСТУПНОСТЬ
   ============================================================ */
:focus-visible{ outline:3px solid var(--ink); outline-offset:2px; }
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
  html{ scroll-behavior:auto; }
}

/* Подпись разработчика в подвале */
footer.site .by{ color:rgb(var(--paper-rgb) / .55); font-size:13px; }
footer.site .by a{
  color:inherit; text-decoration:none;
  border-bottom:1px solid rgba(255,255,255,.22);
  transition:color .15s, border-color .15s;
}
footer.site .by a:hover{ color:var(--lemon); border-bottom-color:var(--lemon); }
