
:root{
  --vfr-rococo_zier:url(frames/rococo_zier.webp);
  --vfr-rococo_zier-ar:1.3333;
  --vfr-barocker_bild:url(frames/barocker_bild.webp);
  --vfr-barocker_bild-ar:1.7768;
  --vfr-barock:url(frames/barock.webp);
  --vfr-barock-ar:0.7500;
  --vfr-barock_leerfeld:url(frames/barock_leerfeld.webp);
  --vfr-barock_leerfeld-ar:1.0000;
  --vfr-gotischer_bild:url(frames/gotischer_bild.webp);
  --vfr-gotischer_bild-ar:0.7500;
  --vfr-ovaler_vintage:url(frames/ovaler_vintage.webp);
  --vfr-ovaler_vintage-ar:0.7500;
  --vfr-renaissance:url(frames/renaissance.webp);
  --vfr-renaissance-ar:1.3333;
  --vfr-vintage:url(frames/vintage.webp);
  --vfr-vintage-ar:0.7500;
  --vfr-vintage_perlenborduere:url(frames/vintage_perlenborduere.webp);
  --vfr-vintage_perlenborduere-ar:0.7500;
  --vfr-achteckige_zier:url(frames/achteckige_zier.webp);
  --vfr-achteckige_zier-ar:1.0000;
  --vfr-barocke_zeichn:url(frames/barocke_zeichn.webp);
  --vfr-barocke_zeichn-ar:0.7500;
  --vfr-baroque_frame:url(frames/baroque_frame.webp);
  --vfr-baroque_frame-ar:0.7500;
  --vfr-floraler_rund:url(frames/floraler_rund.webp);
  --vfr-floraler_rund-ar:1.0000;
  --vfr-viktorianischer_zier:url(frames/viktorianischer_zier.webp);
  --vfr-viktorianischer_zier-ar:1.0000;
}

/* ---- шкала кеглей ------------------------------------------------------
   Слой стоит ПЕРЕД clean.src.css и модулями: он приводит к порядку базовую
   таблицу сайта, но не спорит с тем, что сделано осознанно. Кто идёт
   позже — тот и прав, и это ровно то, что нужно.
   -------------------------------------------------------------------- */
:root{
  --t-xs:12px;
  --t-sm:13.5px;
  --t-md:15px;
  --t-lg:17px;
  --h-xs:clamp(17px, 1.8vw, 20px);
  --h-sm:clamp(19px, 2.2vw, 24px);
  --h-md:clamp(22px, 2.8vw, 32px);
  --h-lg:clamp(27px, 4vw, 50px);
  --h-xl:clamp(34px, 6vw, 74px);
}

.fhint, .kicker, .lang, .theme-bar .lbl, .gate .go, .filter .lbl, .work .wa, .work .ask, .fig figcaption, .drow .t, .guest .yrs, .fact dt, .plate .meta, .addr .lead, .colophon, .rubrik, .hwerk .hname, .fglabel, .kat-card .cr, .kat-card .cw, .km-role, .chapter .cyear, .ag-n, .ag-dur, .book-cover .bsub, .book-cover .bfoot, .ah-go, .wc-artist, .wc-dim, .fmt-meta, .d-season, .cl-row .cl-lbl, .cart-row .cr-price, .cart-note, .cart-fab .cf-count, .cart-msg, .sigline{font-size:var(--t-xs)}
.navlinks a, .cue, .wallcard p, .stat .l, .artist-legend, .filter button, .work .wd, .fact dd small, .fbtns button, .freset, .kat-count, .km-work .wm, .km-ask, .hist-lede .src, .ag-note, .ag-bar button, .sub-role p, .k-back, .k-role, .k-wm, .k-ask, .ah-hint, .route-links a, .menu-item .mi-desc, .cart-line-total, .feat, .ask-status{font-size:var(--t-sm)}
.hero-meta, .gate .num, .gate p, .opener .meta, .artist-search input, .artist-empty, .kids-note, .work .amt, .cat-note, .drow .l, .era p, .guest p, .plate p, .host .who, .host .who b, .hours, .foot-top p, .foot-links, .foot-links a, .foot-links button, .km-born, .km-bio p, .book .badge, .book .ghost, .sub-form input, .sub-form button, .sub-msg, .cta-final .cta-btns a, .k-born, .wc-sub, .wc-title, .ther-links .ghost, .amode p, .anreise-cta .ghost, .menu-tab, .menu-item .mi-price, .menu-placeholder, .cart-row .cr-name, .cart-qty button, .cart-qty span, .cart-empty, .cart-total .ct-l, .cart-order, .cart-fab, .event-book-btn, .hours-note, .fmt p, .fmt-book, .dinner p, .cart-input, .menu-intro, .cl-row, .ask-input, .ask-send{font-size:var(--t-md)}
.body, .addr, .chapter p, .book p, .k-bio p, .km-work .wt, .k-wt, .menu-item .mi-name, .ag-t, .cta-final p{font-size:var(--t-lg)}
.art-link, .fact dd, .kat-card .cn, .ah-name, .cart-head h4{font-size:var(--h-xs)}
.lede, .wallcard h3, .work .wt, .gate h3, .era .when, .era h3, .guest h3, .plate h3, .sub-role h3, .amode h3, .drow .m, .menu-cat h3, .fmt h3, .dinner h3, .ask-title, .cart-total .ct-v{font-size:var(--h-sm)}
.h-md, .chapter h3, .host blockquote, .k-works-h, .visit h2, .book-cover .bt{font-size:var(--h-md)}
.h-lg, .stat .n, .km-name, .book h2, .cta-final h2, .chapter .cnum{font-size:var(--h-lg)}
.h-xl{font-size:var(--h-xl)}

/* На узком экране имя работы падало до 9.5px и переставало читаться. */
@media (max-width:640px){
  .hwerk .hname{font-size:var(--t-xs)}
}

/* ---- радиусы ----------------------------------------------------------
   0 у карточек, 40px у плавающих панелей, 50% у круглых кнопок — как
   записано в системе. Таблетки в 20, 22 и 30 пикселей сводятся к одной,
   прямоугольники с двумя-тремя пикселями скругления — к нулю.
   -------------------------------------------------------------------- */
:root{ --r-flat:0; --r-pill:999px; --r-panel:40px }

/* ---- движение ---------------------------------------------------------
   Три длительности и две кривые на весь сайт: система из MOTION.md.
   В коде до этого жили четырнадцать длительностей и пять кривых —
   каждая сама по себе, и вместе они читались как сбой, а не как замысел.
   Первая кривая уже была самой частой, пятнадцать употреблений против
   шести у ближайшей: система закрепляет своё, а не приносит чужое.
   -------------------------------------------------------------------- */
:root{
  --d-fast:240ms;      /* отклик на действие: ховер, нажатие, переключатель */
  --d-mid:560ms;       /* появление: текст, карточки, изображения, линии */
  --d-slow:1200ms;     /* большие моменты и счёт цифр */
  --step:60ms;         /* шаг лесенки, один на весь сайт */
  --lift:12px;         /* ход появления: короткий подъём к своей линии */
  --e-out:cubic-bezier(.23,1,.32,1);
  --e-inout:cubic-bezier(.77,0,.175,1);
}
.artist-search, .filter button, .fbtns button, .ag-bar .ag-stop, .cart-fab .cf-count, .feat, .d-season{border-radius:var(--r-pill)}
.route-links a, .menu-tab, .cart-qty button{border-radius:var(--r-flat)}
.theme-bar, .cart-fab{border-radius:var(--r-panel)}

/* ---- интерлиньяж и трекинг --------------------------------------------
   Двадцать три интерлиньяжа и восемнадцать трекингов сводятся к пяти и
   пяти. Ступени снова взяты по самому частому и по самому заметному:
   кикер, например, оставлен на своих 0.22em, а к нему подтянуто всё, что
   было разряжено сильнее.
   -------------------------------------------------------------------- */
:root{
  --lh-1:1.05;
  --lh-2:1.16;
  --lh-3:1.3;
  --lh-4:1.6;
  --lh-5:1.8;
  --tr-1:-0.02em;
  --tr-2:0.02em;
  --tr-3:0.08em;
  --tr-4:0.14em;
  --tr-5:0.22em;
}
.stat .n, .host .mono, .chapter .cnum, .book-cover .bt, .menu-item .mi-add, .cart-close, .cart-qty button, .hero h1, .h-xl, .km-name, .cta-final h2{line-height:var(--lh-1)}
.h-lg, .book h2, .h-md, .gate h3, .wallcard h3, .visit h2, .chapter h3, .work .wt, .guest h3, .plate h3, .fbtns button, .kat-card .cn, .km-work .wt, .ag-t, .sub-role h3, .k-wt, .wc-title, .amode h3, .dinner h3, .era .when, .ah-name, .fmt h3{line-height:var(--lh-2)}
.era h3, .fact dd, .host blockquote, .hwerk .hname, .cart-row .cr-name, .kat-card .cr, .book-cover .bsub{line-height:var(--lh-3)}
body, .km-bio p, .book p, .lede, .wallcard p, .work .wd, .fact dd small, .sub-role p, .menu-item .mi-desc, .cart-note, .cl-row, .ask-area, .gate p, .era p, .guest p, .plate p, .amode p, .hours-note, .fmt p, .dinner p, .menu-intro{line-height:var(--lh-4)}
.artist-grid, .kids-note, .chapter p, .k-bio p, .addr{line-height:var(--lh-5)}
.h-xl, .stat .n, .km-name, .chapter .cnum, .book h2, .cta-final h2, .h-lg, .hero h1, .host .mono, .gate h3, .chapter h3, .book-cover .bt, .k-works-h, .menu-cat h3{letter-spacing:var(--tr-1)}
.navlinks a, .stat .l, .hwerk .hname, .book-cover .bsub, .wc-artist, .route-links a, .cue, .work .wa, .fig figcaption{letter-spacing:var(--tr-2)}
.lang, .kat-card .cr, .km-ask, .k-ask, .fmt-meta, .gate .num, .work .ask, .wordmark text, .k-role{letter-spacing:var(--tr-3)}
.gate .go, .chapter .cyear, .ag-n, .book-cover .bfoot, .ah-go, .d-season, .cl-row .cl-lbl, .drow .t, .guest .yrs, .plate .meta, .host .who b, .rubrik, .theme-bar .lbl, .fact dt, .addr .lead, .filter .lbl, .fglabel, .km-role{letter-spacing:var(--tr-4)}
.kicker, .sigline, .brand{letter-spacing:var(--tr-5)}

/* ---- семь литералов цвета ---------------------------------------------
   Остальные двести десять объявлений уже ссылаются на токены системы.
   -------------------------------------------------------------------- */
.book-cover .bt{color:var(--ink)}
.book-cover .bt em{color:var(--accent-ink)}
.book-cover .bsub{color:var(--ink-soft)}
.book-cover .bfoot{color:var(--ink-faint)}
.ah-name{color:#fff}
.ah-go{color:#fff}
.cta-final p{color:var(--on-accent)}

/* ---- вуаль под именем художника ---------------------------------------
   Имя набрано белым: оно рассчитано лежать на фотографии, а фотографий
   пока нет — отсюда белое по светлому и контраст 1.06 в аудите. Кадры
   будут, поэтому цвет не трогаем; вуаль под текстом делаем чуть плотнее
   и чуть выше, чтобы имя держалось и на светлом снимке.
   Было: 72% и до 46% высоты. Стало: 82% и до 58%.
   -------------------------------------------------------------------- */
.ah-card .ah-ph::after{
  background:linear-gradient(to top, rgba(15,26,38,.82), transparent 58%)}

/* ============================================================
   CADRE / clean — композиция дизайн-системы и ничего сверх неё.

   Здесь нет рамок, заходного экрана, развески, логотипа-маски и
   орнамента. Сетки, цвета, темы и расстановка блоков принадлежат
   дизайн-системе и берутся из неё же — этот файл их не переопределяет.

   Остаётся ровно четыре вещи, и каждая объясняет, почему она осталась:

   1. Шрифты. Оригинальные @font-face вырезаются из шаблона (иначе
      в бандле висят 20 начертаний, которые никто не просит), поэтому
      пару надо назвать здесь, иначе сайт уедет на системные.
   2. Правило `<em>`.
   3. Подписи на рисованных картах: в SVG зашиты имена гарнитур,
      которых в наборе нет.
   4. Ничего.

   Это файл для разработки: сюда возвращаются решения по одному, по мере
   того как их принимают. Всё, что было раньше, живёт в rahmenwerk.src.css
   и никуда не делось.
   ============================================================ */

@font-face{font-family:'Manrope';font-style:normal;font-weight:400;font-display:swap;src:url(emb/emb-1.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;font-display:swap;src:url(emb/emb-2.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:'Manrope';font-style:normal;font-weight:500;font-display:swap;src:url(emb/emb-1.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:500;font-display:swap;src:url(emb/emb-2.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:'Manrope';font-style:normal;font-weight:600;font-display:swap;src:url(emb/emb-1.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:600;font-display:swap;src:url(emb/emb-2.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:'Manrope';font-style:normal;font-weight:700;font-display:swap;src:url(emb/emb-1.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:700;font-display:swap;src:url(emb/emb-2.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:400;font-display:swap;src:url(emb/emb-3.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:400;font-display:swap;src:url(emb/emb-4.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:400;font-display:swap;src:url(emb/emb-5.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:400;font-display:swap;src:url(emb/emb-6.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}

:root{
  --font-wordmark:"Playfair Display",Georgia,serif;
  --font-sans:"Manrope",system-ui,sans-serif;
  --serif:var(--font-wordmark); --sans:var(--font-sans);
}

body{font-family:var(--font-sans);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3,.h-xl,.h-lg{font-family:var(--font-wordmark)}

/* <em> — цветовой акцент, не курсив. Базовая таблица наклоняет его из
   классовых селекторов, поэтому голый `em` не выигрывает. */
em{font-style:normal}
.h-xl em,.h-lg em,.h-md em,.hero h1 em,
.manifest p em,.book h2 em,.cta-final h2 em{font-style:normal}

/* ---- знак в шапке ----------------------------------------------------
   Логотип — не орнамент, поэтому он возвращается в чистую ветку. Базовая
   таблица набирает в шапке слово «CADRE» разрядкой; здесь оно гасится и
   на его месте стоит настоящий знак маской, чтобы он шёл за цветом темы
   и не тянул отдельной картинкой. В герое знак не восстанавливаю: там
   сейчас крупный набор Playfair, и это отдельное решение.
   -------------------------------------------------------------------- */
:root{ --logo-frame:url("emb/logo-cadre-trim.webp"); --logo-word:url("emb/logo-cadre-trim.webp");
       --logo-ar:1.2304 }

/* Знак двухслойный: рама и набор красятся по-разному, а одна маска даёт
   один цвет. Поэтому два слоя поверх друг друга, оба с одним viewBox —
   рисунок совпадает пиксель в пиксель. Цвета из темы: рама фирменным
   фиолетом, набор чернилами, так что ночью знак не пропадает. */
.cadre-mark::before,.cadre-mark::after{content:"";position:absolute;inset:0}
.cadre-mark::before{background:#9C9A96;
  -webkit-mask:var(--logo-frame) center/contain no-repeat;
          mask:var(--logo-frame) center/contain no-repeat}
/* В шапке знак прижат к левой линии колонки — маска без центровки,
   иначе зазор маски не давал логотипу встать по линии. */
.brand.cadre-mark::before{-webkit-mask-position:left center;mask-position:left center}
/* Набор внутри рамы — чёрный, как просили. Не var(--ink): чернила темы
   это тёмно-синий, и на светлом знак выходил синим по синему, а рама и
   набор почти сливались. Ночью чёрный пропал бы вовсе, поэтому там
   набор возвращается к цвету темы. */
/* Новый знак одноцветный (#9C9A96) и однослойный — второй слой не нужен. */
.cadre-mark::after{content:none}

.brand{color:transparent;position:relative;overflow:visible;
  letter-spacing:normal;height:58px;width:calc(58px * var(--logo-ar));
  display:block;padding:0}

/* карты подписаны вручную, именами старых гарнитур */
svg [font-family*="Inter"]{font-family:var(--font-sans)}
svg [font-family*="Fraunces"]{font-family:var(--font-wordmark)}

/* ---- две версии вместо пяти ------------------------------------------
   Дизайн-система даёт пять тем. Остаются две: светлая santorini — первый
   пункт палитры и версия по умолчанию, она же стоит в разметке, — и night,
   последний пункт. Три средние (seaglass, lavender, ice) не удалены, они
   по-прежнему объявлены системой и работают, если выставить data-theme
   руками; их просто больше не предлагают в переключателе. Вернуть —
   убрать это правило.

   Ночь не включается сама: ни по системной теме, ни по часам. Сайт всегда
   открывается светлым, тёмный — сознательный выбор посетителя.
   -------------------------------------------------------------------- */
/* ---- переключатель темы в шапке ---------------------------------------
   Плашка «Palette» висела плавающей таблеткой в правом нижнем углу и
   перекрывала содержимое. Тем осталось две, поэтому она переехала в шапку,
   к переключателю языка: снимаем фиксированное положение, фон, тень и
   подпись — остаются два кружка справа сверху.
   -------------------------------------------------------------------- */
header .theme-bar{position:static;z-index:auto;padding:0;gap:8px;
  border:0;border-radius:0;background:none;box-shadow:none;
  backdrop-filter:none;margin-left:clamp(12px,1.6vw,22px)}
header .theme-bar .lbl{display:none}
header .theme-bar .swatch{width:30px;height:30px;border-width:1px}
header .theme-bar .swatch svg{width:16px;height:16px;flex:none}
header .theme-bar .swatch[aria-pressed="true"]{border-color:var(--hair)}

.swatch[data-theme-set="seaglass"],
.swatch[data-theme-set="lavender"],
.swatch[data-theme-set="ice"]{display:none}

:root{
  --fr-01a:url(emb/emb-9.webp);
  --fr-01b:url(emb/emb-10.webp);
  --fr-02a:url(emb/emb-11.webp);
  --fr-02b:url(emb/emb-12.webp);
  --fr-04a:url(emb/emb-13.webp);
  --fr-04b:url(emb/emb-14.webp);
  --fr-08a:url(emb/emb-15.webp);
  --fr-08b:url(emb/emb-16.webp);
  --fr-15a:url(emb/emb-17.webp);
  --fr-15b:url(emb/emb-18.webp);
  --fr-18a:url(emb/emb-19.webp);
  --fr-18b:url(emb/emb-20.webp);
  --fr-19a:url(emb/emb-21.webp);
  --fr-19b:url(emb/emb-22.webp);
  --fr-20a:url(emb/emb-23.webp);
  --fr-20b:url(emb/emb-24.webp);
}

:root{
  --photo-art-abstrakt:url(emb/emb-25.webp);
  --photo-art-figurativ:url(emb/emb-26.webp);
  --photo-art-kinder:url(emb/emb-27.webp);
  --photo-art-neue-positionen:url(emb/emb-28.webp);
  --photo-b1-hero:url(emb/emb-29.webp);
  --photo-fassade:url(emb/emb-30.webp);
}

/* ---- герой без фотографии --------------------------------------------
   Фотография интерьера стояла справа на весь рост героя. Убрана 18 августа:
   герой держат рамки, развешанные по фону, а не кадр. Сам файл никуда не
   делся — лежит в assets/photos/b1-hero.jpg и подключается одной строкой,
   если решение поменяется. Пока на него нет ссылки, build.py его в бандл
   не кладёт, поэтому и 246 КБ из веса ушли.
   -------------------------------------------------------------------- */
/* overflow: стена продолжается за краем окна, и это правильно — но без
   обрезки крупные рамы давали 128px горизонтальной прокрутки. */
.hero{position:relative;isolation:isolate;overflow:hidden}
.hero .hero-main,.hero .hero-meta{margin-inline:0 auto}

/* ---- развеска рамок в герое -------------------------------------------
   Шесть слотов, расставленных руками в ?slots и выгруженных оттуда же.
   Пропорции подтянуты к настоящим рамкам набора: отклонение нигде не больше
   0.08, то есть форма сохранена и растягивать ничего не нужно.

   1 → рамка 19 (0.80)   2 → рамка 1  (0.72)   3 → рамка 2  (1.97)
   4 → рамка 15 (0.58)   5 → рамка 20 (1.49)   6 → рамка 19 (0.80)

   Слой лежит под содержимым: у героя свой контекст наложения, поэтому
   отрицательный z-index кладёт рамки поверх градиента системы, но под текст.
   -------------------------------------------------------------------- */
.hero .slotfield.baked{position:absolute;inset:0;z-index:-1;pointer-events:none}
body[data-slots] .hero .slotfield.baked{display:none}  /* правим — прячем */

/* Пока работаем с прототипом: красные прямоугольники своей пропорции.
   Настоящие рамки включаются атрибутом data-frames="real" на body —
   маски уже в бандле, вёрстка та же, меняется только заливка. */
.hero .slotfield.baked .slot{position:absolute;left:var(--x);top:var(--y);
  width:var(--w);aspect-ratio:var(--ar);translate:-50% -50%;
  --sway:0deg;rotate:calc(var(--rot) + var(--sway));
  transform-origin:50% -6%;
  border:2px solid #e2342c;background:none}
/* Середина сквозная: прототип должен читаться как рама, а не как плашка.
   Две линии — внешний край и просвет, между ними тело рамы, внутри пусто.
   Линия сплошная, а не пунктирная: пунктир при движении мерцает. */
.hero .slotfield.baked .slot::after{content:"";position:absolute;
  inset:24% 20%;border:1.5px solid rgba(226,52,44,.5);background:none}

body[data-frames="real"] .hero .slotfield.baked .slot,
body[data-frames="native"] .hero .slotfield.baked .slot{
  /* Было .5 прозрачности бледным сиреневым по белому: контраст к фону
     около 1.6:1, то есть не рама, а след от рамы. Предмет на стене
     должен быть предметом — полная непрозрачность и чернильный тон. */
  border:0;background:var(--frame-colour,var(--accent-ink,var(--accent)));opacity:1;
  -webkit-mask:var(--fr) center/100% 100% no-repeat;
          mask:var(--fr) center/100% 100% no-repeat}
body[data-frames="real"] .hero .slotfield.baked .slot::after,
body[data-frames="native"] .hero .slotfield.baked .slot::after{
  inset:0;border:0;background:var(--accent);opacity:1;
  -webkit-mask:var(--fra) center/100% 100% no-repeat;
          mask:var(--fra) center/100% 100% no-repeat}

/* родные цвета рамок — вторая проба, включается data-frames="native" */
body[data-frames="native"] .hero .slotfield.baked .slot{
  background:var(--fc);opacity:.62}
body[data-frames="native"] .hero .slotfield.baked .slot::after{
  background:var(--fa);opacity:.8}

/* Возвращена прежняя развеска: шесть слотов на исходных местах и в
   исходных размерах. Прототип — красные прямоугольники с настоящими
   пропорциями рам; настоящие включаются адресом ?real.
   -------------------------------------------------------------------- */
.hero .slot:nth-child(1){--x:76.5%;--y:65.8%;--w:22%;--rot:0deg;--ar:0.80;
  --fr:var(--fr-19a);--fra:var(--fr-19b);--fc:#00575D;--fa:#7776A1}
.hero .slot:nth-child(2){--x:47.2%;--y:16.7%;--w:16%;--rot:0deg;--ar:0.72;
  --fr:var(--fr-01a);--fra:var(--fr-01b);--fc:#008185;--fa:#86B9B7}
.hero .slot:nth-child(3){--x:75.3%;--y:23.3%;--w:19.4%;--rot:0deg;--ar:1.97;
  --fr:var(--fr-02a);--fra:var(--fr-02b);--fc:#800021;--fa:#B9024D}
.hero .slot:nth-child(4){--x:98.4%;--y:42.5%;--w:15.7%;--rot:0deg;--ar:0.58;
  --fr:var(--fr-15a);--fra:var(--fr-15b);--fc:#002195;--fa:#7776A1}
.hero .slot:nth-child(5){--x:12.7%;--y:17.5%;--w:22.6%;--rot:0deg;--ar:1.49;
  --fr:var(--fr-20a);--fra:var(--fr-20b);--fc:#390084;--fa:#7776A1}
.hero .slot:nth-child(6){--x:53.1%;--y:63.8%;--w:16.7%;--rot:0deg;--ar:0.80;
  --fr:var(--fr-19a);--fra:var(--fr-19b);--fc:#00575D;--fa:#7776A1}

/* ---- дубль плашки в герое ---------------------------------------------
   Разбор арт-директора: одна и та же строка стоит в первом экране дважды —
   сверху «Brunch · Apéro · Kunst · Events — Baden», снизу «Brunch · Apéro ·
   Art · Events». Тот же смысл, да ещё с разнобоем KUNST/ART внутри одного
   экрана. Нижнюю убираем: верхняя стоит у заголовка и работает кикером,
   нижняя не работала никак. Стрелка «Zur Karte» остаётся — это
   единственный призыв на первом экране.
   -------------------------------------------------------------------- */
.hero .sigline{display:none}

/* ---- A7: четыре карточки категорий на «Галерее» ----------------------
   В карточке лежит <svg class="canvas"> с заглушкой — он же задаёт коробке
   пропорцию 200×250, поэтому его нельзя убрать совсем: карточка схлопнется.
   Гасим содержимое и кладём работу фоном самого svg. Порядок файлов
   совпадает с порядком карточек: абстракция, фигуратив, новые имена, дети.
   -------------------------------------------------------------------- */
.wallcard .canvas > *{display:none}
.wallcard .canvas{background:var(--art) center/cover no-repeat}

/* Подпись у системы лежит поверх картинки — с бледной заглушкой это
   читалось, с живописью нет. Уводим её под работу, музейной этикеткой:
   вуаль поверх картины была бы вторым злом. Для этого холст выходит из
   absolute в поток, а карточка отдаёт ему свою пропорцию 4:5. */
.wallcard{aspect-ratio:auto;padding:0;overflow:visible;justify-content:flex-start}
.wallcard .canvas{position:relative;inset:auto;display:block;
  width:100%;height:auto;aspect-ratio:4/5}
.wallcard .lbl{margin-top:16px}
.wallcard p{margin:4px 0 0}
.wallcard:nth-child(1) .canvas{--art:var(--photo-art-abstrakt)}
.wallcard:nth-child(2) .canvas{--art:var(--photo-art-figurativ)}
.wallcard:nth-child(3) .canvas{--art:var(--photo-art-neue-positionen)}
.wallcard:nth-child(4) .canvas{--art:var(--photo-art-kinder)}

@media (max-width:900px){
  /* Схема-заглушка держала собственную ширину в 415px внутри колонки в
     350px, и текст рядом обрезался на 40 пикселей. Картинка обязана
     ужиматься до колонки, а не наоборот. */
  .fig svg,.split svg{max-width:100%;height:auto}
  .split{min-width:0}
  .split > *{min-width:0}

  /* Узкий экран. Было min-height:0 — и герой собирался по содержимому в
     390px при окне в 897: первый экран наполовину пустой, а фиолетовый
     блок начинался сразу под текстом. Даём ему рост окна за вычетом
     шапки; svh, а не vh, иначе панель браузера съедает низ. */
  .hero{min-height:calc(100svh - 85px);justify-content:center}
  .hero .hero-main{align-self:start}
  .hero .hero-main,.hero .hero-meta{max-width:100%}
}

/* ---- страница художника ----------------------------------------------
   Как было: имя, под ним портрет по центру (`margin:0 auto` из системы),
   под ним текст в одну колонку — три отдельных этажа и много пустоты
   по бокам.

   Как стало: портрет — левой колонкой и липнет при прокрутке, био — правой,
   работы уходят вниз во всю ширину. Строки и колонки расставлены явно,
   потому что в разметке кнопка «спросить» идёт ПОСЛЕ works, а по смыслу
   должна стоять под биографией.

   Портрет есть не у всех (23 из 27), поэтому двухколонник включает
   соседний селектор: нет портрета — био само занимает всю ширину, пустой
   колонки не остаётся.
   -------------------------------------------------------------------- */
/* Имена не переносим и не рвём: автопереноса в системе нет (hyphens:manual),
   но обычный дефис внутри фамилии остаётся законным местом разрыва —
   его подменяет на неразрывный скрипт страницы художника. Здесь запрещаем
   всё остальное: разрыв слова по буквам и автоматическую расстановку. */
#k-body > .row h1,.ah-name,.k-wt,.wa{hyphens:none;overflow-wrap:normal;
  word-break:normal}

/* Имя уехало в тело, и в «шапке» страницы остался пустой #k-head — а вместе
   с ним весь нижний отступ секции. Схлопываем: сверху остаётся только
   ссылка «назад», воздух под ней даёт уже следующая секция. */
#p-kuenstler .opener{padding-bottom:0}
#k-head:empty{display:none}
/* Ссылка «назад» и имя стояли в 96px друг от друга: 74 из них — штатный
   верхний отступ секции, рассчитанный на секцию с собственным заголовком.
   Здесь заголовок сразу за ссылкой, поэтому расстояние ужимаем. Правило
   адресное: секция сразу после индекса — та самая, где лежит карточка. */
#p-kuenstler #k-index + section{padding-top:clamp(18px,3vh,36px)}
/* На списке верхняя секция скрыта — а именно она держала отступ под
   фиксированной шапкой (123px против её 85px). Индекс оставался с обычным
   отступом секции в 74px и залезал под меню: кикер «Wer hier ausgestellt
   hat» подрезался. Отдаём индексу тот же отступ, что у остальных страниц. */
#p-kuenstler #k-index{padding-top:clamp(104px,15vh,168px)}

@media (min-width:900px){
  #k-body{display:grid;align-items:start;
    grid-template-columns:minmax(230px,300px) minmax(0,1fr);
    column-gap:clamp(32px,5vw,72px)}
  /* портрет держит всю левую колонку, справа — имя, роль, текст, кнопка */
  #k-body .k-portrait{grid-column:1;grid-row:1 / span 3;margin:0;width:100%}
  #k-body > .row h1{margin:0}
  #k-body > .row .meta{margin-top:8px;max-width:40ch}

  /* Текст занимает свою колонку целиком. В системе у него стоит max-width
     в 62 знака — при колонке в 788px это оставляло полторы сотни пикселей
     пустоты справа, и правый край текста не совпадал ни с чем.
     Колонка одна и та же и когда портрета нет (у четверых его нет):
     левая просто пустует, зато у всех страниц один левый край и один
     правый, а строки не растягиваются на всю полосу. */
  #k-body .k-bio{grid-column:2;grid-row:2;margin:20px 0 0;max-width:none}
  #k-body .k-ask{grid-column:2;grid-row:3;justify-self:start;
    align-self:start;margin-top:20px}
  #k-body > .row{grid-column:2;grid-row:1;display:block;margin:0}

  #k-body .k-works-h{grid-column:1/-1;grid-row:4;
    margin-top:clamp(40px,6vh,72px)}
  #k-body .k-works{grid-column:1/-1;grid-row:5}
}
@media (max-width:899px){
  /* Узкий экран: этажи, но портрет прижат влево, а не по центру. Имя лежит
     в разметке после портрета — ради колонки на широком экране, — поэтому
     здесь поднимаем его наверх: сначала имя, потом фотография, потом текст. */
  #k-body{display:flex;flex-direction:column}
  #k-body > .row{order:-1;margin:0 0 24px}
  #k-body .k-portrait{margin-left:0;margin-right:0;width:min(100%,320px)}
}

/* ---- названия работ ---------------------------------------------------
   Были 17px курсивом — рядом с крупным именем читались как сноска.
   Ставим тем же начертанием, что и имя: Playfair, прямое, крупнее.
   Курсив у названия картины — музейная норма, если захочется вернуть:
   снять font-style. --------------------------------------------------- */
.k-wt{font-family:var(--serif);font-style:normal;font-weight:400;
  font-size:clamp(20px,1.7vw,26px);line-height:1.2;letter-spacing:-.01em}
.k-wm{font-size:14px;margin-top:8px}

/* ---- знак в футере ----------------------------------------------------
   Вместо слова «CADRE», набранного текстом, — настоящий знак во всю ширину
   и обрезанный ровно пополам нижним краем.

   Как режется: маска масштабируется по ширине (`100% auto`), её натуральная
   высота — ширина / 2.483. Коробке даём вдвое более плоскую пропорцию и
   прижимаем маску к верху — видна ровно верхняя половина. Футер и так
   с overflow:hidden, так что ничего не выпирает.
   -------------------------------------------------------------------- */
/* Раньше здесь стояло слово, набранное текстом: огромное, бледное и
   подрезанное снизу. С настоящим знаком подрез не работает — у рамы есть
   низ, и срезать его значит сломать предмет. Знак стоит целиком,
   посередине, между навигацией футера и копирайтом. */
/* Футер по мотивам макета: три колонки с красными шапками, под ними —
   знак во всю мочь, полупрозрачный и подрезанный нижним краем футера. */
.foot-cols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:32px clamp(28px,4vw,56px);padding-bottom:clamp(40px,7vh,72px);align-items:start}
/* Знак крупно слева, текстовые колонки — справа. Цвет берёт из текста через маску. */
.foot-logo{width:100%;max-width:460px;height:auto;align-self:start;justify-self:start;display:block;margin:0}
@media(max-width:900px){.foot-cols{grid-template-columns:1fr 1fr}.foot-logo{grid-column:1/-1;max-width:220px}}
.fcol-h{display:block;font-size:var(--t-xs,12.5px);letter-spacing:.18em;text-transform:uppercase;font-weight:600;color:var(--accent-ink,var(--accent));margin-bottom:14px}
.fcol p{font-size:var(--t-lg,14.5px);color:var(--ink-soft);margin:0 0 9px;max-width:42ch}
.fcol a{color:var(--ink-soft);text-decoration:none;transition:color .25s ease}
.fcol a:hover{color:var(--accent-ink,var(--accent))}
.fcol .foot-links{display:flex;flex-direction:column;align-items:flex-start;gap:9px}
.fcol .foot-links button{text-align:left}
@media(max-width:760px){.foot-cols{grid-template-columns:1fr;gap:26px}.foot-logo{max-width:180px}}
footer .colophon{position:static;margin-top:0;padding:clamp(20px,3vh,32px) 0 clamp(14px,2vh,22px);border-top:1px solid rgba(255,255,255,.3)}
/* Знак: полная рама с набором, полупрозрачно, виден верхними ~60% —
   низ уходит за край футера, как гигантская надпись в макете. */
footer .wordmark{display:block;position:relative;overflow:hidden;
  width:min(var(--fw-w,640px),96%);margin:clamp(28px,5vh,54px) auto 0;
  aspect-ratio:calc(var(--logo-ar)/(var(--fw-v,.6)));opacity:.6}
/* временная панель подбора размера знака в футере */
.fw-tuner{position:absolute;right:0;top:0;display:flex;flex-direction:column;gap:8px;
  font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);z-index:5}
.fw-tuner label{display:flex;align-items:center;gap:8px}
.fw-tuner input[type="range"]{width:140px;accent-color:var(--accent)}
.fw-tuner output{min-width:5ch;color:var(--ink-soft)}
footer .wordmark::before,footer .wordmark::after{inset:0 0 auto 0;height:auto;
  aspect-ratio:var(--logo-ar)}

/* ---- третий блок «Erst der Ort, dann der Teller» -----------------------
   Первое место на сайте, где рамка делает свою работу: держит картину.
   До этого в правой половине стояла схема-заглушка — три пустых
   прямоугольника и два кружка-тарелки на серой плите.

   Из трёх разобранных вариантов выбран первый: рамка по сетке, в правой
   колонке. Два других — навылет к краю окна и во всю сетку сверху — сняты
   19 августа; вылет резал рамку краем окна, а полная ширина растила блок
   вдвое и уводила текст под нижний край.

   Рамка №4 из набора: пропорция 1.286, проём 13.3% по горизонтали и 21%
   по вертикали — числа из frames-meta.json, коробка берёт форму рамки и
   ничего не растягивает. Проём у неё 1.62, у кадра 3:2 — 1.5, разницу
   съедает cover.

   Фотография — временная: до генерации кадра Б4 «накрытый стол» здесь
   стоит интерьер Б1, чтобы было видно, как рамка держит настоящий
   снимок, а не серую плашку.

   Рамку показываем настоящей, не прототипом: смысл блока именно в том,
   держит она картину или нет, а красный контур на этот вопрос не отвечает.
   Цвет — из темы, не родной: вопрос о родных цветах ещё открыт.
   -------------------------------------------------------------------- */
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"]){
  --fr-ar:1.286;--fr-px:13.3%;--fr-py:21%;
  --fr:var(--fr-04a);--fra:var(--fr-04b);
  position:relative;margin:0;
  /* фигура — ячейка сетки с justify-self:center из системы, поэтому она
     сжималась до 430px по внутренней ширине svg. Растягиваем на колонку. */
  width:100%;justify-self:stretch}

/* Схему гасим, но сам svg оставляем: он держит коробку. Пропорцию у него
   отбираем — теперь её задаёт рамка. Фотография обрезана по проёму:
   иначе она лезла бы наружу и просвечивала сквозь резьбу. */
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"]) > svg > *{display:none}
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"]) > svg{
  display:block;width:100%;height:auto;aspect-ratio:var(--fr-ar);
  background:var(--photo-b1-hero) center/cover no-repeat;
  clip-path:inset(var(--fr-py) var(--fr-px))}

/* Рамка двумя слоями поверх кадра — линия и акцент, как в герое.
   Кладём не на всю фигуру, а ровно на коробку кадра: подпись остаётся
   в потоке под рамкой и ничем не перекрыта. */
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"])::before,
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"])::after{
  content:"";position:absolute;left:0;right:0;top:0;
  aspect-ratio:var(--fr-ar);pointer-events:none}
/* Рама была залита плоским цветом и рядом с золочёными рамами на самом
   снимке читалась как перекрашенный пластик. Резьбе нужен материал:
   свет сверху, тень снизу. Градиент внутри той же маски — вертикальный
   переход от светлого к тёмному, как на настоящем багете. */
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"])::before{
  background:#403B61;
  -webkit-mask:var(--fr) center/100% 100% no-repeat;
          mask:var(--fr) center/100% 100% no-repeat}
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"])::after{
  background:#403B61;
  -webkit-mask:var(--fra) center/100% 100% no-repeat;
          mask:var(--fra) center/100% 100% no-repeat}

/* Подпись — музейной этикеткой под работой, по левому краю рамки.
   Была по центру: ось ни к чему не привязана, слева текст выключен влево. */
/* Тень под нижним валиком: без неё рама не лежит на стене, а плавает. */
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"]) > svg{
  box-shadow:0 22px 40px -30px rgba(25,55,79,.55)}
#p-start .fig:has(> svg[aria-label^="Gedeckter Tisch"]) figcaption{
  text-align:left;margin-top:16px}



/* Набор из кусочков рамок снят 24 августа: вензель и уголки, вырезанные
   подконтурами, выглядели обрезками, а не орнаментом. Правило теперь
   простое — либо рамка целиком, либо ничего. Там, где просился кусок,
   ставится заглушка, чтобы место было видно. */


/* ---- портреты художников: прямые карточки -------------------------------
   Рамы с портретов сняты 29 августа словом владелицы: «в оригинале
   линия лучше выглядела». Лента возвращается к родному виду базовой
   таблицы — снимок 3:4, вуаль, белое имя. Прежний вариант с овальными
   рамами живёт в истории git этого файла.
   -------------------------------------------------------------------- */

.wallcard .lbl,.wallcard p{padding-inline:0px}


/* ---- работы в рамах героя ----------------------------------------------
   Маска в CSS стирает не только фон элемента, но и всё его содержимое.
   Пока рама висела маской на самом слоте, картина внутри исчезала вместе
   с проёмом — то есть ровно там, где должна была быть видна. Поэтому у
   занятой рамы резьба уезжает на псевдоэлемент, а слот остаётся простым
   контейнером: картина внутри, рама поверх неё.
   -------------------------------------------------------------------- */
body[data-frames="real"] .hero .slotfield.baked .slot:has(> .art){
  background:none;opacity:1;
  -webkit-mask:none;mask:none}
body[data-frames="real"] .hero .slotfield.baked .slot:has(> .art)::before{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:var(--accent);
  -webkit-mask:var(--fr) center/100% 100% no-repeat;
          mask:var(--fr) center/100% 100% no-repeat}
body[data-frames="real"] .hero .slotfield.baked .slot:has(> .art)::after{
  opacity:1;z-index:3}

/* Работа садится в проём и обрезается по нему. */
.hero .slotfield.baked .slot > .art{position:absolute;z-index:1;
  background-position:center;background-size:cover;background-repeat:no-repeat;
  pointer-events:none}
.hero .slotfield.baked .slot > .art.oval{clip-path:ellipse(50% 50%)}


/* ---- дрейф стены в герое -----------------------------------------------
   Рамы идут за прокруткой медленнее текста. Сдвиг пишет скрипт, доля у
   каждой своя: крупная рама ближе к стене и отстаёт сильнее.
   -------------------------------------------------------------------- */
.hero .slotfield.baked .slot{
  translate:-50% calc(-50% + var(--drift, 0px))}

/* ---- развеска четвёртого блока -----------------------------------------
   Рама приходит снизу и садится. Качание после посадки делает маятник
   из slots.py — тот же, что держит стену героя.
   -------------------------------------------------------------------- */
.sec.gates .gate::before{
  rotate:calc(var(--fr-rot, 0deg) + var(--sway, 0deg))}
.sec.gates .gate .num{
  rotate:calc(var(--fr-rot, 0deg) + var(--sway, 0deg))}

.sec.gates .gate[data-hangs]{opacity:var(--hang-o, 1);
  translate:0 var(--hang-y, 0px);
  transition:opacity .7s cubic-bezier(.23,1,.32,1),
             translate .9s cubic-bezier(.23,1,.32,1)}

@media (prefers-reduced-motion:reduce){
  .hero .slotfield.baked .slot{translate:-50% -50%}
  .sec.gates .gate[data-hangs]{opacity:1!important;translate:0!important;
    transition:none}
}


/* ---- бумага вместо сплошного белого ------------------------------------
   Тёплый тон, не серый: серый рядом с фирменным сиреневым даёт больничное
   освещение. Чередование идёт по секциям страницы, поэтому работает на
   всех девяти сразу и не требует разметки.
   -------------------------------------------------------------------- */
/* Владелица 25 августа: «убери этот тупой бежевый цвет, он меня бесит»
   и «можно сейчас сайт сделать в 2-3 цветах, потом будем раскрашивать».
   Тёплая бумага #F7F3EC была четвёртым цветом и единственным тёплым на
   холодном сайте — она спорила и с чернилами, и с фиолетом. Тихая
   полоса теперь не отдельный цвет, а сами чернила в три процента:
   поверхность выводится из палитры, а не приносится со стороны. */
:root{ --paper:#F6F8FA; --paper-line:rgba(25,55,79,.14) }
body[data-theme="night"]{ --paper:#1B2436; --paper-line:rgba(255,255,255,.12) }

.page > section:nth-of-type(even):not(.manifest):not(.hero){
  background:var(--paper)}

/* Стык двух листов — волосок, а не пустота. */
.page > section:nth-of-type(even):not(.manifest):not(.hero){
  box-shadow:inset 0 1px 0 var(--paper-line),
             inset 0 -1px 0 var(--paper-line)}

/* ---- карта: меню и прейскурант -----------------------------------------
   Отточие через ::after шириной 100vw было ошибкой: оно уезжало на 1190
   пикселей за правый край и давало странице горизонтальную прокрутку, а
   промежуток между блюдом и ценой при этом не заполняло — начиналось уже
   под ценой. Вместо трюка — волосок под всей строкой: он связывает
   название с ценой ровно так же и не может никуда вылезти.
   -------------------------------------------------------------------- */
.menu-item{align-items:baseline;
  border-bottom:1px solid var(--hair,rgba(25,55,79,.14))}
.menu-item .mi-name{font-family:var(--serif)}
.menu-item .mi-price{font-variant-numeric:lining-nums tabular-nums}

/* ---- табличка: номер в раме --------------------------------------------
   Номер главы и номер двери — не текст, а литера на табличке. Тот же
   приём, что в развеске «под одной крышей».
   -------------------------------------------------------------------- */
/* На тёплой бумаге номер при непрозрачности .75 давал контраст 2.61 при
   норме 3. Прозрачность убрана, тон взят чернильный. */
.chapter .cnum{font-family:var(--serif);opacity:1;
  color:var(--accent-ink,var(--accent))}

/* ---- этикетка ----------------------------------------------------------
   Название, автор, год — три строки разного веса под работой, как
   музейная подпись. Раньше они шли подряд без отбивки и слипались
   в «Alley in BloomAnna Oster2025».
   -------------------------------------------------------------------- */
.work .wt,.kat-card .cn,.wc-title{display:block;font-family:var(--serif)}
.work .wa,.kat-card .cr,.wc-artist{display:block;margin-top:4px;
  color:var(--ink-soft);letter-spacing:.06em;text-transform:uppercase}
.work .wd,.kat-card .cw,.wc-dim{display:block;margin-top:0px;
  color:var(--ink-faint)}
/* Подпись работы в каталоге шла тремя строчными кусками подряд и
   слипалась в «Alley in BloomAnna Oster2025» — это стояло в чек-листе
   с самого начала. Три строки разного веса, как на музейной этикетке. */
.wc-meta{display:block;padding-top:8px}

:root{ --cap-pad:clamp(14px, 1.5vw, 22px) }

.wallcard .lbl,
.wallcard h3,
.wallcard p,
.work .wt, .work .wa, .work .wd, .work .amt, .work .ask,
.kat-card .cn, .kat-card .cr, .kat-card .cw,
.fig figcaption,
.hwerk .hname{
  padding-inline:var(--cap-pad)}

/* Подпись под работой начинается там же, где кончается поле карточки, и
   дышит снизу — иначе следующая карточка начинается сразу за буквами. */
.wallcard .lbl{padding-block:12px 4px}
.wallcard p{padding-bottom:12px}

/* Имя работы в каталоге стоит под квадратной картинкой и центровано.
   Поле прибавилось к его собственной мере, и длинное имя вылезло за
   правый край карточки на девять пикселей. Мера считается вместе с
   полем. */
.hwerk .hname{box-sizing:border-box;max-width:100%}

:root{
  --fc-violett:#535280;
  --fc-tiffany:#3E8F86;
  --fc-fuchsia:#A85685;
  --fc-gold:#8A6F35;
  --fc-schiefer:#4A6B85;
  --fc-moos:#5B7A63;
}

/* Развеска «под одной крышей» звучала на двух добавочных тонах —
   сине-сером и золоте. С 25 августа они сняты: владелица попросила
   держать сайт в двух-трёх цветах и раскрашивать потом. Палитра выше
   не удалена и остаётся готовой — вернуть эти две строки будет делом
   одной минуты, когда дойдёт до раскраски.

.sec.gates .gate:nth-child(2)::before{background:var(--fc-schiefer)}
.sec.gates .gate:nth-child(5)::before{background:var(--fc-gold)}
*/

/* Портреты художников — фиолет: их двенадцать в ряд, и цветная чехарда
   в ленте читалась бы именно как пестрота. */


/* ---- переключатель вида -------------------------------------------------
   Две кнопки вместо двух блоков. Стоит над сеткой и говорит, сколько
   всего работ и авторов — раньше этого числа не было нигде.
   -------------------------------------------------------------------- */
.kv-bar{display:flex;align-items:baseline;gap:clamp(14px,2vw,26px);
  flex-wrap:wrap;margin:0 0 clamp(18px,2.4vh,30px)}
.kv-count{font-size:var(--t-sm);color:var(--ink-faint);
  letter-spacing:.14em;text-transform:uppercase}
.kv-switch{display:flex;gap:0px;margin-left:auto}
.kv-switch button{font:inherit;font-size:var(--t-sm);cursor:pointer;
  padding:8px 16px;border:1px solid var(--hair,rgba(25,55,79,.14));
  background:none;color:var(--ink-soft);border-radius:var(--r-pill,999px);
  transition:color .25s,background-color .25s}
.kv-switch button[aria-pressed="true"]{background:var(--accent-ink);
  color:var(--bg);border-color:var(--accent-ink)}

/* ---- вид «в настоящую величину» ----------------------------------------
   Работы висят от общей нижней линии и держат свой настоящий размер.
   Мелкая работа рядом с крупной — и есть весь смысл этого вида.
   -------------------------------------------------------------------- */
/* Развеска по средней оси, а не по нижней линии. Страница обещает
   прямым текстом: «auf Mittelachse 145 cm und im Verhältnis ihrer wahren
   Masse». Нижняя линия — это полка в магазине; ось — это стена в зале,
   и именно её здесь и обещали. Центры работ стоят на одной высоте,
   верх и низ у каждой свои. */
.wc-grid[data-view="true"]{display:flex;flex-wrap:wrap;
  align-items:flex-start;gap:clamp(20px,2.6vw,44px);
  padding-top:var(--axis-pad,0px)}
.wc-grid[data-view="true"] .wc-tile{margin-top:var(--top,0px)}
.wc-grid[data-view="true"] .wc-tile{width:auto}
.wc-grid[data-view="true"] .wc-frame{display:block;
  width:var(--w);height:var(--h)}
.wc-grid[data-view="true"] .wc-frame img{width:100%;height:100%;
  object-fit:cover}
.wc-grid[data-view="true"] .wc-meta{max-width:var(--w)}

/* Работы без указанного размера в настоящем виде притушены: их мера
   неизвестна, и делать вид, что известна, нельзя. */
.wc-grid[data-view="true"] .wc-tile[data-nodim] .wc-frame{opacity:.5}
.wc-grid[data-view="true"] .wc-tile[data-nodim] .wc-dim::after{
  content:" · Mass unbekannt"}

/* Стена из 27 работ снята: тот же материал показан сеткой выше, только
   полным набором. Секцию помечает скрипт — полагаться на устройство
   разметки через :has оказалось нельзя, стена лежит глубже. */
section.hwall-sec{display:none}


/* ---- план квартала на «Визите» -----------------------------------------
   Свой рисунок вместо iframe Google: чернила по белому, Лиммат фиолетовой
   лентой, пунктир вокзал-CADRE. Одна ссылка на живую карту.
   -------------------------------------------------------------------- */
.plan-anreise{max-width:560px}
.plan-anreise svg{display:block;width:100%;height:auto;background:var(--bg);
  border:1px solid var(--hair,rgba(25,55,79,.14))}
.plan-anreise .pl-t{font-family:var(--sans);font-size:12px;
  fill:var(--ink-soft);letter-spacing:.04em}
.plan-anreise .pl-b{font-weight:600;fill:var(--ink)}
.plan-anreise .pl-w{fill:var(--accent);font-style:italic}
.plan-anreise .pl-min{font-family:var(--sans);font-size:11px;
  letter-spacing:.18em;fill:var(--accent-ink)}
.plan-go{display:inline-block;margin-top:12px;font-size:var(--t-sm);
  color:var(--accent-ink);text-decoration:none;
  border-bottom:1px solid currentColor;padding-bottom:0px;
  transition:color var(--d-fast,240ms) var(--e-out)}
.plan-go:hover{color:var(--ink)}
/* Три чипа-дороги под картой дублировали абзацы справа и ссылку — сняты. */
.route-links{display:none}

/* ---- кухня: карта в две колонки ----------------------------------------
   Меню лентой в один столбец занимало 1380px и читалось как список дел.
   Карта в ресторане читается по колонкам: глаз держит рядом два-три
   блюда и сравнивает.
   -------------------------------------------------------------------- */
@media (min-width:901px){
  .menu-sec .menu-cats{columns:2;column-gap:clamp(40px,4.5vw,72px)}
  .menu-sec .menu-cat{break-inside:avoid;margin-bottom:clamp(22px,3vh,38px)}
}
.menu-sec .menu-cat h3{font-family:var(--serif);
  padding-bottom:8px;margin-bottom:4px;
  border-bottom:1px solid var(--accent-ink,var(--accent))}

/* ---- вино и сезон: текст рядом, без заглушек ---------------------------
   Оба блока были разворотами «текст плюс нарисованная схема». Схемы
   убраны, тексты встали двумя колонками под картой — они дополняют
   меню, а не претендуют на отдельный экран.
   -------------------------------------------------------------------- */
/* Одна сетка на весь блок: слева текстовая колонка, справа узкая полоса
   под иллюстрацию. Оба текста стоят в одной левой колонке, поэтому строй
   держится и когда картинка одна. */
.essen-notes{display:grid;grid-template-columns:1fr;gap:0;
  margin-top:clamp(64px,10vh,130px);
  padding-block:clamp(48px,7vh,88px)}
.essen-notes > div{min-width:0}
.essen-col{min-width:0}
.essen-notes > div + div{margin-top:clamp(40px,6vh,76px)}
@media(min-width:900px){.essen-notes > .essen-col + .essen-rail{margin-top:0}}
.essen-notes > div{min-width:0}
.essen-notes h3{font-family:var(--serif);margin:0 0 12px}

/* Плотнее: заголовок ближе к тексту, абзацы ближе друг к другу. */
.essen-notes p{margin-top:0;margin-bottom:11px}
.essen-notes p.body{font-size:16px}
.essen-notes figcaption{font-size:14px}
.essen-notes p:last-child{margin-bottom:0}
.essen-notes > .essen-col > div + div > h3{margin-top:0}
/* Порядок внутри блока: заголовок → первый абзац → фото → остальной текст.
   Селекторы идут и через .essen-col: скрипт заворачивает текст в неё, и
   правила на прямых детей .essen-notes переставали действовать — фото
   оказывалось первым. */
.essen-notes > div,.essen-col > div{display:flex;flex-direction:column}
.essen-notes > div > h3,.essen-col > div > h3{order:1}
.essen-notes > div > p:first-of-type,.essen-col > div > p:first-of-type{order:2}
.essen-notes > div > figure,.essen-col > div > figure{order:3}
.essen-notes > div > p:not(:first-of-type),.essen-col > div > p:not(:first-of-type){order:4}
.essen-notes > div > a,.essen-col > div > a{order:5}
@media(min-width:900px){
  /* Слева весь текст, справа рама. Раму ведём от ШИРИНЫ колонки — высоту
     даёт пропорция. Обратный ход (высота от текста, ширина от пропорции)
     даёт круговую зависимость: трек auto уже посчитан, и рама вылезает
     в поле страницы. */
  /* Рама прижата к правому краю, её высота не больше высоты текста, зазор
     между колонками — не более 15% ширины блока. Ширину рамы считает скрипт
     (--rahmen-w) из высоты текста: чистым CSS это круговая зависимость. */
  .essen-notes{grid-template-columns:minmax(0,1fr) auto;
    gap:0 clamp(20px,2.4vw,40px);align-items:start}
  .essen-rail{align-self:start;min-width:0}
  .essen-notes .essen-rail figure{margin:0 0 0 auto;
    width:var(--rahmen-w,min(100%,400px))}
  /* Строка не должна быть длиннее читаемой (~66 знаков), поэтому вместо
     растяжки текста сужаем сам блок: рама встаёт вплотную за текстом,
     пустого коридора между ними нет. */
  .essen-notes p,.essen-notes .body{max-width:66ch}
  .essen-notes{max-width:min(100%,calc(66ch + 40px + 400px))}
  .essen-notes .essen-rail .fig-rahmen{width:100%;height:auto}
  .essen-notes > .essen-col > div + div{margin-top:clamp(20px,3vh,38px)}
}
.essen-notes figure{margin:0 0 22px;width:100%}
@media(max-width:899px){
  /* На узких экранах текст идёт во всю ширину колонки — ограничение строки
     (66ch) нужно только рядом с рамой на десктопе. */
  .essen-notes p,.essen-notes .body{max-width:none}
  .essen-notes > div + div,.essen-col > div + div{margin-top:36px}
  /* Рама во всю ширину на телефоне, но на планшете не распухает. */
  .essen-notes figure{margin:20px auto;width:min(100%,420px)}
}
.essen-notes figure > img{display:block;width:100%;height:auto}
.essen-notes figure figcaption{margin-top:10px;text-align:left;
  font-size:12.5px;color:var(--ink-faint);letter-spacing:.03em}

/* Схемы-заглушки на этой странице сняты: вайрфрейм на месте фотографии
   не помогает никому. */
.page#p-essen .fig:has(svg){display:none}

/* ---- события: карточки видны, низ ровный, даты нет — календаря нет ----- */
.dinner{background:var(--bg);display:flex;flex-direction:column;
  padding:32px}
.dinner .fmt-book{margin-top:auto;align-self:flex-start}
.d-season{border-radius:0;margin-bottom:12px}

/* ---- термы: карточки существуют, фантомной колонки нет ---------------- */
@media (min-width:901px){
  .wall-cards{grid-template-columns:repeat(3,1fr)}
  .dinner-list{grid-template-columns:repeat(3,1fr)}
}
/* Карточки трёх путей зовутся .plate; заливка была неотличима от фона
   секции — карточка существовала только как хайрлайн. */
#p-thermen .plate{background:rgba(25,55,79,.05);
  border:1px solid rgba(25,55,79,.22)}
#p-thermen section:has(.pslot){background:var(--bg)}

/* ---- визит: одна дорога к карте, а не четыре -------------------------- */
.anreise-cta{display:none}

/* ---- KUNST BUCH #1 в Артканалоге ---------------------------------------
   Юбилейная книга галереи: те же художники первого года, что и каталог.
   Обложка настоящая, из материалов владелицы; лежит файлом buch/cover.webp.
   ------------------------------------------------------------------- */
.kb{display:grid;grid-template-columns:minmax(280px,.92fr) 1.08fr;
  gap:clamp(28px,4.5vw,64px);align-items:center;margin-top:0}
.kb img{display:block;width:100%;height:auto;border:0}
.kb .kicker{margin-bottom:12px}
.kb h2{margin:0 0 16px}
.kb-note{font-size:var(--t-md);color:var(--ink-soft);max-width:52ch;
  margin:0}
@media (max-width:760px){
  /* На узком экране блок открывается рубрикой и заголовком, фото следом. */
  .kb{display:flex;flex-direction:column;align-items:flex-start}
  .kb > div{display:contents}
  .kb .kicker{order:1}
  .kb h2{order:2;margin-bottom:20px}
  .kb img{order:3;max-width:260px}
  .kb-note{order:4;margin-top:20px}
}


/* ==== Галерея: стена ======================================================
   Работы висят по средней оси 145 см в настоящем соотношении размеров.
   Ось и пол прочерчены: без них «настоящий размер» — просто слова.
   ------------------------------------------------------------------- */
.gw{position:relative;margin-block:clamp(20px,3vh,40px)}

.gw-head{display:flex;align-items:baseline;gap:clamp(12px,2vw,24px);
  flex-wrap:wrap;margin:0 0 clamp(14px,2vh,24px)}
.gw-count{font-size:var(--t-sm);color:var(--ink-faint);
  letter-spacing:.14em;text-transform:uppercase}
.gw-hint{font-size:var(--t-sm);color:var(--ink-faint);margin-left:auto}

/* Кто сейчас перед вами. Строка меняется по ходу вдоль стены — так
   идёт рядом человек, который знает зал. Меняется только текст, коробка
   стоит: подпрыгивающая строка читалась бы как сбой. */
.gw-now{min-height:1.5em;font-size:var(--t-sm);color:var(--ink-soft);
  letter-spacing:.02em;transition:opacity var(--d-fast,240ms) var(--e-out)}
.gw-now b{font-weight:400;font-family:var(--serif);color:var(--ink)}
.gw-now.gw-swap{opacity:0}

/* Полоса прокрутки — это и есть шаг вдоль стены. Прокрутка своя, не
   страничная: горизонталь на всей странице однажды уже была граблей. */
.gw-wall{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
  padding-bottom:8px}

.gw-run{position:relative;display:flex;align-items:flex-start;
  height:var(--wall-h);width:max-content;min-width:100%}

/* ---- большой момент: ось прочерчивается ------------------------------
   Третий из четырёх больших моментов сайта (`MOTION.md`). Стена не
   проявляется и не выезжает: сначала через весь экран проводят линию
   развески, потом на неё по очереди садятся работы. Это и есть то, что
   делают в зале перед выставкой, — сперва отбивают высоту, потом вешают.

   По умолчанию всё на месте: и линия проведена, и работы висят. Начальное
   состояние ставит скрипт и сам же снимает — не сыграет, останется
   готовая стена, а не пустая. */
.gw-run.gw-draw::before{transform:scaleX(0)}
.gw-run::before{transform-origin:left center;
  transition:transform var(--d-slow,1200ms) var(--e-out)}

.gw-run.gw-arrive .gw-w{opacity:0;transform:translateY(18px)}
.gw-run .gw-w{transition:opacity var(--d-mid,560ms) var(--e-out),
                          transform var(--d-mid,560ms) var(--e-out)}

@media (prefers-reduced-motion:reduce){
  .gw-run.gw-draw::before{transform:none}
  .gw-run.gw-arrive .gw-w{opacity:1;transform:none}
}

/* Пол и ось. Ось подписана: 145 см — число, которое стоит знать. */
.gw-run::after,.gw-run::before{content:"";position:absolute;left:0;right:0;
  height:1px;pointer-events:none}
.gw-run::before{top:var(--axis-top);background:var(--accent-ink);opacity:.28}
.gw-run::after{bottom:0;background:var(--ink-faint);opacity:.5}

.gw-axis-lbl{position:absolute;left:0;top:var(--axis-top);
  transform:translateY(-100%);padding-bottom:4px;
  font-size:var(--t-sm);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint);pointer-events:none}

/* Одна работа. Смещение сверху таково, что середина работы попадает на
   ось: сколько именно — считает скрипт и кладёт в --top. */
.gw-w{position:relative;flex:0 0 auto;margin-top:var(--top);
  margin-right:var(--gap);padding:0;border:0;background:none;
  font:inherit;color:inherit;cursor:pointer;display:block;
  transition:transform .3s var(--ease,cubic-bezier(.2,.7,.3,1))}
.gw-w:hover,.gw-w:focus-visible{transform:translateY(-5px)}
.gw-w:active{transform:translateY(-5px)}
.gw-w:focus-visible{outline:2px solid var(--accent-ink);outline-offset:6px}

.gw-w img{display:block;width:var(--w);height:var(--h);object-fit:cover;
  background:var(--hair,rgba(25,55,79,.08))}

/* Подпись висит под работой и не мешает соседке: она уже, чем работа,
   и не растягивает шаг развески. */
.gw-cap{position:absolute;top:calc(var(--h) + 10px);left:0;width:var(--w);
  min-width:120px;text-align:left;pointer-events:none}
.gw-t{display:block;font-family:var(--serif);font-size:var(--t-sm);
  line-height:var(--lh-tight,1.25)}
.gw-a{display:block;font-size:var(--t-sm);color:var(--ink-soft)}
.gw-d{display:block;font-size:var(--t-sm);color:var(--ink-faint);
  font-variant-numeric:lining-nums tabular-nums}

/* Работа без указанного размера висит приглушённой: её мера неизвестна,
   и делать вид, что известна, нельзя. */
.gw-w[data-nodim] img{opacity:.55}

/* Старые заглушки снимает скрипт и только после того, как стена собрана.
   Пометку ставит он же — таблица стилей ничего не прячет сама. */
.gw-done .gw-old{display:none}

@media (max-width:900px){
  .gw-hint{margin-left:0;width:100%}
}

/* ==== четырнадцать рам ===================================================
   Третьим блоком стояли четыре нарисованные заглушки под заголовком
   «Vier Wände, vier Handschriften»: ни одной работы, ни одной ссылки.
   Вместо них — рамы дома, настоящие, все четырнадцать. Нажатие открывает
   работу, которая в этой раме лучше всего сидит: примерка с другого
   конца.
   ------------------------------------------------------------------- */
.gr-grid{display:flex;flex-wrap:wrap;align-items:flex-end;
  gap:clamp(18px,2.6vw,44px);margin-top:clamp(20px,3vh,36px)}
.gr-one{position:relative;padding:0;border:0;background:none;font:inherit;
  cursor:pointer;display:block;flex:0 0 auto;
  transition:transform var(--d-fast,240ms) var(--e-out)}
.gr-one:hover,.gr-one:focus-visible{transform:translateY(-5px)}
.gr-one:focus-visible{outline:2px solid var(--accent-ink);outline-offset:6px}
.gr-one i{display:block;height:var(--h);width:auto;aspect-ratio:var(--ar,1);
  background:var(--ink-faint);
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat;
  transition:background-color var(--d-fast,240ms) var(--e-out)}
.gr-one:hover i,.gr-one:focus-visible i{background:var(--accent-ink)}
.gr-n{display:block;margin-top:8px;font-size:var(--t-sm);
  color:var(--ink-faint);letter-spacing:.02em;max-width:14em}


/* ==== люди: шапка с кадром над родной лентой ============================= */
.lw{display:grid;grid-template-columns:minmax(260px,2fr) 3fr;
  gap:clamp(28px,4vw,64px);align-items:center;
  margin-bottom:clamp(26px,4vh,48px)}

/* Число — самое крупное на странице после героя: это главный факт
   блока, и он должен читаться раньше текста. */
.lw-num{font-family:var(--serif);font-weight:300;line-height:.92;
  font-size:clamp(110px,13vw,190px);letter-spacing:-.03em;
  color:var(--ink);margin:clamp(14px,2vh,24px) 0 0;
  font-variant-numeric:lining-nums tabular-nums;
  font-feature-settings:'lnum' 1}
.lw-cap{font-size:var(--t-md);color:var(--ink-soft);margin:8px 0 0;
  max-width:24em}
.lw-all{display:inline-block;margin-top:clamp(14px,2vh,22px);
  font-size:var(--t-md);color:var(--accent-ink);text-decoration:none;
  border-bottom:1px solid currentColor;padding-bottom:0px;
  transition:color var(--d-fast,240ms) var(--e-out)}
.lw-all:hover{color:var(--ink)}

.lw-foto{position:relative;overflow:visible;margin:0}
.lw-foto img{display:block;width:100%;height:auto;aspect-ratio:1.5;
  object-fit:cover}
/* рамка группового фото: внутренняя линия по краю снимка, узор снаружи */
/* рама только вокруг снимка; подпись — ниже, вне рамы.
   Носитель держит пропорцию SVG (1536×1024), снимок лежит точно в проёме:
   слева/справа 10.6%, сверху/снизу 14.85% — измерено по альфе файла. */
.artists-home .lw-frame{position:relative;display:block;width:100%;aspect-ratio:1536/1024}
.artists-home .lw-frame::after{content:"";position:absolute;inset:0;
  z-index:2;pointer-events:none;opacity:.92;
  background:url(frames/rahmen-gross.webp) center/100% 100% no-repeat}
.artists-home .lw-frame img{position:absolute;left:10.6%;top:14.85%;
  width:78.8%;height:70.3%;max-width:none;object-fit:cover;aspect-ratio:auto}
.artists-home .lw-cap2{margin-top:clamp(14px,2vh,20px)}
.lw-cap2{margin:8px 0 0;font-size:var(--t-xs);color:var(--ink-faint);
  text-align:left}

@media (max-width:900px){
  .lw{display:block}
  .lw-foto{margin-top:clamp(16px,3vh,26px)}
}


/* ==== фильтры каталога ===================================================
   Стоят над сеткой работ, а не над списком авторов. Каждая кнопка знает,
   сколько за ней работ; кнопка с нулём не показывается вовсе.
   ------------------------------------------------------------------- */
.wf{margin:0 0 clamp(18px,2.4vh,30px)}
.wf-row{display:flex;flex-wrap:wrap;align-items:baseline;
  gap:clamp(10px,1.4vw,20px);padding-block:8px}
.wf-lbl{flex:0 0 auto;min-width:88px;font-size:var(--t-xs);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
.wf-btns{display:flex;flex-wrap:wrap;gap:4px}

.wf-btns button{font:inherit;font-size:var(--t-sm);cursor:pointer;
  display:inline-flex;align-items:center;gap:8px;
  padding:8px 12px;border-radius:var(--r-pill,999px);
  border:1px solid var(--hair,rgba(25,55,79,.14));
  background:none;color:var(--ink-soft);
  transition:color var(--d-fast,240ms) var(--e-out),
             background-color var(--d-fast,240ms) var(--e-out),
             border-color var(--d-fast,240ms) var(--e-out)}
.wf-btns button:hover{color:var(--ink);border-color:var(--ink-faint)}
.wf-btns button[aria-pressed="true"]{background:var(--accent-ink);
  color:var(--bg);border-color:var(--accent-ink)}
.wf-btns button:focus-visible{outline:2px solid var(--accent-ink);
  outline-offset:3px}

/* Число за кнопкой: есть ли смысл нажимать. */
.wf-n{font-size:var(--t-xs);opacity:.6;font-variant-numeric:lining-nums tabular-nums}

/* Кружок цвета — средний цвет тех работ, которые за кнопкой стоят.
   Образец не выдуман: он посчитан. */
.wf-dot{width:13px;height:13px;border-radius:50%;display:block;
  background:var(--c);box-shadow:inset 0 0 0 1px rgba(25,55,79,.18)}

.wf-foot{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;
  margin-top:8px;font-size:var(--t-sm);color:var(--ink-faint)}
.wf-count{font-variant-numeric:lining-nums tabular-nums;letter-spacing:.06em}
.wf-reset{font:inherit;font-size:var(--t-sm);background:none;border:0;
  padding:0;color:var(--accent-ink);cursor:pointer;
  border-bottom:1px solid currentColor}
.wf-reset[hidden]{display:none}

/* Отсев. Прячет скрипт по действию человека, а не таблица стилей сама. */
.wc-tile.wf-out{display:none}

/* Пусто — это тоже ответ, и он должен быть виден. */
.wf-empty{padding:clamp(30px,5vh,60px) 0;color:var(--ink-soft);
  font-size:var(--t-md)}
.wf-empty[hidden]{display:none}

@media (max-width:700px){
  .wf-lbl{min-width:100%;padding-bottom:0px}
}


/* ==== карточка работы ====================================================
   Поверх страницы, во весь экран. Ничего не прячет: каталог остаётся
   под ней целым.
   ------------------------------------------------------------------- */
.wk{position:fixed;inset:0;z-index:9000;background:var(--bg);
  display:flex;flex-direction:column;
  opacity:0;transition:opacity var(--d-mid,560ms) var(--e-out)}
.wk.open{opacity:1}
.wk[hidden]{display:none}

.wk-top{display:flex;align-items:baseline;gap:20px;flex-wrap:wrap;
  padding:clamp(16px,2.4vh,28px) clamp(18px,4vw,60px) 0}
.wk-kicker{font-size:var(--t-xs);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-faint)}
.wk-close{margin-left:auto;font:inherit;font-size:var(--t-sm);
  background:none;border:0;cursor:pointer;color:var(--ink-soft);
  letter-spacing:.14em;text-transform:uppercase;padding:4px 0;
  border-bottom:1px solid currentColor;
  transition:color var(--d-fast,240ms) var(--e-out)}
.wk-close:hover{color:var(--ink)}

.wk-body{flex:1 1 auto;min-height:0;display:grid;
  grid-template-columns:1fr minmax(260px,30%);
  gap:clamp(20px,3vw,54px);
  padding:clamp(14px,2vh,26px) clamp(18px,4vw,60px) clamp(18px,3vh,34px)}

/* ---- сцена: работа в раме -------------------------------------------- */
.wk-stage{position:relative;display:flex;align-items:center;
  justify-content:center;min-height:0;min-width:0}
.wk-frame{position:relative;height:min(100%,var(--fh,70vh));
  aspect-ratio:var(--ar,.75);flex:0 0 auto;
  transition:aspect-ratio var(--d-mid,560ms) var(--e-out)}
.wk-frame::before{content:"";position:absolute;inset:0;
  background:var(--accent-ink,var(--accent));
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat}

/* Проём. Паспарту белое, работа лежит в нём целиком. */
.wk-hole{position:absolute;overflow:hidden;background:var(--bg);
  left:var(--hx);top:var(--hy);width:var(--hw);height:var(--hh);
  display:flex;align-items:center;justify-content:center}
.wk-hole img{max-width:100%;max-height:100%;width:auto;height:auto;
  object-fit:contain;
  opacity:0;transform:translateY(var(--lift,12px));
  transition:opacity var(--d-mid,560ms) var(--e-out),
             transform var(--d-mid,560ms) var(--e-out)}
.wk-hole img.hung{opacity:1;transform:none}

/* Без рамы — работа просто на стене. */
.wk-frame[data-bare]::before{display:none}
.wk-frame[data-bare] .wk-hole{left:0;top:0;width:100%;height:100%;
  box-shadow:0 1px 0 var(--hair,rgba(25,55,79,.14))}

/* ---- настоящая величина ---------------------------------------------- */
/* Настоящая величина: ширину задаём числом, высота идёт от пропорции
   рамы. Убирать aspect-ratio нельзя — дети рамы лежат абсолютно, и без
   пропорции коробка становится нулевой высоты. */
.wk-true .wk-frame{height:auto;width:var(--tw)}
.wk-true .wk-hole img{width:100%;height:100%}
.wk-ruler{position:absolute;left:50%;bottom:-34px;translate:-50% 0;
  width:var(--rw);border-top:1px solid var(--ink-faint);
  font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint);text-align:center;padding-top:4px}
.wk-ruler::before,.wk-ruler::after{content:"";position:absolute;top:0;
  width:1px;height:7px;background:var(--ink-faint)}
.wk-ruler::before{left:0}
.wk-ruler::after{right:0}
.wk-ruler[hidden]{display:none}

/* ---- правая колонка --------------------------------------------------- */
.wk-side{display:flex;flex-direction:column;gap:clamp(14px,2vh,22px);
  overflow:auto;min-height:0}
.wk-title{font-family:var(--serif);font-size:var(--h-md);
  line-height:1.15;color:var(--ink);margin:0}
.wk-artist{font-size:var(--t-md);color:var(--accent-ink);
  text-decoration:none;border-bottom:1px solid currentColor;
  align-self:flex-start;padding-bottom:0px;
  transition:color var(--d-fast,240ms) var(--e-out)}
.wk-artist:hover{color:var(--ink)}
.wk-facts{margin:0;font-size:var(--t-sm);color:var(--ink-soft);
  line-height:1.9}
.wk-facts b{font-weight:400;color:var(--ink-faint);
  display:inline-block;min-width:6.5em}

.wk-lbl{font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint);margin:0}

/* Четырнадцать рам: полоса образцов. */
.wk-frames{display:flex;flex-wrap:wrap;gap:8px}
.wk-frames button{width:46px;height:56px;padding:0;cursor:pointer;
  border:1px solid transparent;background:none;position:relative;
  transition:border-color var(--d-fast,240ms) var(--e-out)}
.wk-frames button::before{content:"";position:absolute;inset:4px;
  background:var(--ink-faint);
  -webkit-mask:var(--f) center/contain no-repeat;
          mask:var(--f) center/contain no-repeat;
  transition:background-color var(--d-fast,240ms) var(--e-out)}
.wk-frames button[aria-pressed="true"]{border-color:var(--accent-ink)}
.wk-frames button[aria-pressed="true"]::before{background:var(--accent-ink)}
.wk-frames button:focus-visible{outline:2px solid var(--accent-ink);
  outline-offset:2px}
.wk-frames button[data-bare]::before{
  -webkit-mask:none;mask:none;background:none;
  border:1px dashed var(--ink-faint)}

.wk-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:auto;
  padding-top:12px}
.wk-btn{font:inherit;font-size:var(--t-sm);cursor:pointer;
  padding:8px 16px;border-radius:var(--r-pill,999px);
  border:1px solid var(--hair,rgba(25,55,79,.14));background:none;
  color:var(--ink-soft);text-decoration:none;display:inline-block;
  transition:color var(--d-fast,240ms) var(--e-out),
             background-color var(--d-fast,240ms) var(--e-out),
             border-color var(--d-fast,240ms) var(--e-out)}
.wk-btn:hover{color:var(--ink);border-color:var(--ink-faint)}
.wk-btn[aria-pressed="true"]{background:var(--accent-ink);color:var(--bg);
  border-color:var(--accent-ink)}
.wk-price{font-size:var(--t-sm);color:var(--ink-faint)}

/* Ходы между работами. */
.wk-nav{display:flex;gap:8px}
.wk-nav button{font:inherit;font-size:var(--t-sm);background:none;
  border:0;padding:0;cursor:pointer;color:var(--ink-faint);
  transition:color var(--d-fast,240ms) var(--e-out)}
.wk-nav button:hover{color:var(--accent-ink)}
.wk-nav button[disabled]{opacity:.35;cursor:default}

@media (max-width:900px){
  .wk-body{grid-template-columns:1fr;grid-template-rows:1fr auto;
    overflow:auto}
  .wk-stage{min-height:46vh}
  .wk-frame{height:min(46vh,var(--fh,46vh))}
}
@media (prefers-reduced-motion:reduce){
  .wk,.wk-hole img,.wk-frame{transition:none}
}


/* ==== стена за заставкой =================================================
   Слой ничего не держит и ни на что не влияет: он под текстом по слою и
   вне текста по месту. Считает места скрипт, здесь только вид.
   ------------------------------------------------------------------- */
/* Полоса стены под текстом. Без неё свободного места в заставке нет
   вовсе: текст занимает её почти целиком, и рама легла бы на строку.
   Полоса заодно даёт заставке воздух, которого ей и не хватало. */
.opener{position:relative;padding-bottom:clamp(64px,13vh,168px)}

/* ---- тёмная заставка ---------------------------------------------------
   Владелица 25 августа: «добавь больше тёмных блоков, по примеру второго
   блока на первой странице». Второй блок — фиолетовая комната: полный
   цвет, белый текст. Теперь так открывается каждая страница, кроме
   главной (её первые три блока защищены): входишь в раздел через
   цветную дверь. Прежнее правило «тёмная полоса не чаще одной на
   страницу» пересмотрено её словом.

   Фон берёт --accent-ink: в базовой версии это фирменный фиолет, в
   цветной — тон комнаты, и одна и та же строка красит обе. */
.page:not(#p-start) section.opener{background:var(--accent-ink)}
.page:not(#p-start) section.opener :is(h1,h2){color:#fff}
.page:not(#p-start) section.opener em{color:rgba(255,255,255,.82)}
.page:not(#p-start) section.opener p{color:rgba(255,255,255,.78)}
.page:not(#p-start) section.opener .kicker{color:rgba(255,255,255,.6)}
/* Рамы на тёмной стене — белые и тихие, тёмного на тёмном не видно. */
.page:not(#p-start) section.opener .op-wall i{
  background:#fff;opacity:.14}

/* Шапка была прозрачной и над тёмной дверью пропадала: чернильные
   ссылки на чернильном фоне. Теперь у неё своя подложка — матовое
   стекло, где браузер умеет, и просто фон, где нет. Это правка
   удобства, не украшение: навигация обязана читаться на любой стене. */
header.nav{background:var(--bg)}
@supports (backdrop-filter:blur(10px)) or (-webkit-backdrop-filter:blur(10px)){
  header.nav{background:color-mix(in srgb,var(--bg) 84%,transparent);
    -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
}
.opener > .in,.opener > .wrap{position:relative;z-index:1}

.op-wall{position:absolute;inset:0;overflow:hidden;pointer-events:none;
  z-index:0}
/* Рама просто есть. Ни проявления, ни выхода по прокрутке: слой стены
   по `MOTION.md` **уже висит**, когда страница открылась. Проявление
   здесь было бы и лишним движением, и лишним риском — не сыграл таймер,
   и стена осталась невидимой навсегда. */
.op-wall i{position:absolute;display:block;height:var(--h);width:auto;
  aspect-ratio:var(--ar,1);opacity:.32;
  background:var(--accent-ink,var(--accent));
  transform:translate3d(0,var(--dy,0px),0);
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat;
  }

@media (prefers-reduced-motion:reduce){
  .op-wall i{transform:none!important}
}


/* ==== бронь стола ========================================================
   Одна колонка полей, ширина по строке: форма читается сверху вниз, а
   не собирается глазами по сетке.
   ------------------------------------------------------------------- */
.tb{max-width:52ch}
.tb-row{display:flex;flex-wrap:wrap;gap:clamp(10px,1.4vw,18px);
  margin-top:12px}
.tb-f{flex:1 1 150px;min-width:0;display:flex;flex-direction:column;gap:4px}
.tb-f > span{font-size:var(--t-xs);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-faint)}
.tb input,.tb select,.tb textarea{font:inherit;font-size:var(--t-md);
  color:var(--ink);background:none;padding:8px 12px;
  border:1px solid var(--hair,rgba(25,55,79,.14));
  border-radius:var(--r-flat,0);width:100%;
  transition:border-color var(--d-fast,240ms) var(--e-out)}
.tb input:focus,.tb select:focus,.tb textarea:focus{outline:none;
  border-color:var(--accent-ink)}
.tb textarea{resize:vertical;min-height:78px}

.tb-note{font-size:var(--t-sm);color:var(--ink-faint);margin:12px 0 0;
  line-height:1.7}
.tb-warn{font-size:var(--t-sm);color:var(--accent-ink);margin:12px 0 0;
  line-height:1.7}
.tb-warn[hidden]{display:none}
.tb-warn a{color:inherit}

.tb-go{margin-top:16px;font:inherit;font-size:var(--t-md);cursor:pointer;
  display:inline-block;text-decoration:none;
  padding:12px 24px;border-radius:var(--r-pill,999px);
  border:1px solid var(--accent-ink);background:var(--accent-ink);
  color:var(--bg);
  transition:background-color var(--d-fast,240ms) var(--e-out),
             color var(--d-fast,240ms) var(--e-out)}
.tb-go:hover{background:none;color:var(--accent-ink)}
.tb-go[aria-disabled="true"]{opacity:.4;pointer-events:none}

/* Что именно уйдёт письмом — видно до отправки. */
.tb-sum{margin-top:16px;padding-top:12px;
  border-top:1px solid var(--hair,rgba(25,55,79,.14));
  font-size:var(--t-sm);color:var(--ink-soft);line-height:1.8;
  white-space:pre-line}


/* ==== история ============================================================ */

/* Пометка у главы. Не кнопка: нажимать нечего, и делать вид нельзя. */
.hs-soon{display:inline-flex;align-items:center;gap:8px;
  font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint);margin-top:8px}
.hs-soon::before{content:"";width:6px;height:6px;border-radius:50%;
  border:1px solid currentColor}

/* Аудиогид без списка: одна мысль и один ход дальше. */
.audioguide .ag-list,.audioguide .ag-bar,
.audioguide .ag-grid,.audioguide .ag-wrap{display:none}
.hs-ag{max-width:46ch}
.hs-ag p{margin:12px 0 0;font-size:var(--t-md);color:var(--ink-soft)}
.hs-ag a{color:var(--accent-ink);text-decoration:none;
  border-bottom:1px solid currentColor;padding-bottom:0px}

/* ---- ритм страницы -----------------------------------------------------
   Пять экранов одного серого подряд — не ритм. База: белое. Смена
   главы — тёмная полоса, и она одна на хронике Aquae. Подписка —
   отдельная полоса над подвалом, а не карточки со стоковыми иконками. */
#p-historie .sec{background:var(--bg)}
#p-historie .subscribe{background:var(--paper)}
#p-historie .cta-final{background:var(--accent-ink)}

#p-historie .hs-dunkel{background:var(--accent-ink)}
#p-historie .hs-dunkel :is(h2,h3){color:#fff}
#p-historie .hs-dunkel :is(p,li,dd){color:rgba(255,255,255,.78)}
#p-historie .hs-dunkel :is(.kicker,.rubrik,dt){color:rgba(255,255,255,.6)}
#p-historie .hs-dunkel .drow .m{color:#fff}
#p-historie .hs-dunkel .drow .l{color:rgba(255,255,255,.75)}
#p-historie .hs-dunkel .drow .t{color:rgba(255,255,255,.55)}
#p-historie .hs-dunkel .drow{border-color:rgba(255,255,255,.18)}

/* Настоящая обложка: муляжные градиенты и набранный заголовок сняты,
   печатная вещь показывается фотографией, как ей и положено. */
#p-historie .hs-realcover{background:none;box-shadow:none;padding:0;
  width:min(300px,72vw);aspect-ratio:auto}
#p-historie .hs-realcover::before,#p-historie .hs-realcover::after{
  display:none}
#p-historie .hs-realcover img{display:block;width:100%;height:auto;
  box-shadow:0 24px 60px -28px rgba(25,55,79,.5)}

/* Контурные иконки — чужой язык на сайте гравированных рам. */
#p-historie .subscribe svg,#p-historie .hs-gaeste svg{display:none}


/* ==== хозяйка зала ======================================================
   Инициал живёт в проёме рамы, а не сам по себе. Рама называется
   «пустое поле» — портрета нет, и притворяться нечем.
   ------------------------------------------------------------------- */
.hg{position:relative;width:clamp(160px,17vw,230px);
  aspect-ratio:1;flex:0 0 auto}
.hg::before{content:"";position:absolute;inset:0;
  background:var(--accent-ink,var(--accent));
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat}
.hg-hole{position:absolute;left:22.1%;top:23.8%;width:55.4%;height:52.1%;
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.hg-hole .mono{font-family:var(--serif);font-weight:300;
  font-size:clamp(44px,5vw,74px);line-height:1;color:var(--ink);
  margin:0}
.hg-lbl{position:absolute;left:0;right:0;top:calc(100% + 12px);
  text-align:center;font-size:var(--t-xs);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-faint)}

@media (max-width:700px){
  .hg{width:clamp(130px,40vw,180px)}
}


/* Форма запроса пользуется теми же классами, что бронь стола: это одно
   и то же действие, и выглядеть оно должно одинаково. Здесь — только
   то, чего в брони нет. */
.cta-final .tb{max-width:56ch;margin-inline:auto;text-align:left}
.tb-f.wide{flex:1 1 100%}

/* Призыв стоит на тёмной полосе, а поля формы рассчитаны на белую
   стену: на тёмном они пропадали вместе с рамками и подписями.
   Здесь та же форма, только вывернутая по цвету. */
.cta-final .tb input,.cta-final .tb select,.cta-final .tb textarea{
  color:var(--on-accent,#fff);border-color:rgba(255,255,255,.3)}
.cta-final .tb input:focus,.cta-final .tb select:focus,
.cta-final .tb textarea:focus{border-color:var(--on-accent,#fff)}
.cta-final .tb .tb-f > span{color:rgba(255,255,255,.66)}
.cta-final .tb-sum{color:rgba(255,255,255,.82);
  border-top-color:rgba(255,255,255,.24)}
.cta-final .tb-note{color:rgba(255,255,255,.62)}
.cta-final .tb-go{background:var(--on-accent,#fff);color:var(--ink);
  border-color:var(--on-accent,#fff)}
.cta-final .tb-go:hover{background:none;color:var(--on-accent,#fff)}
/* Поле выбора рисует список средствами системы — на тёмном фоне текст
   в нём должен остаться читаемым. */
.cta-final .tb select option{color:var(--ink);background:var(--bg)}


/* ==== слот под снимок ====================================================
   Пустая рама на месте фотографии, которой ещё нет. Подпись остаётся
   своя, под рамой — этикеткой, как у работы в зале.
   Класс называется pslot, а не ph: короткое `.ph` в бандле уже занято —
   под ним двадцать семь чужих элементов в каталоге, и мой набор стилей
   их перекрасил бы.
   ------------------------------------------------------------------- */
.pslot{position:relative;display:block;width:100%;max-width:420px;
  margin-inline:auto}
.pslot-fr{position:relative;width:100%;aspect-ratio:var(--ar,1);
  background:var(--accent-ink,var(--accent));opacity:.3;
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat}
.pslot-note{display:block;margin-top:12px;text-align:left;
  font-size:var(--t-xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint)}
.pslot-cap{display:block;margin-top:4px;text-align:left;
  font-size:var(--t-sm);color:var(--ink-soft);line-height:1.6}


/* ==== сквозная стена =====================================================
   Слой под всем содержанием и вне его по месту. Никогда не перекрывает
   текст: места считает скрипт.
   ------------------------------------------------------------------- */
.page{position:relative}
.wand{position:absolute;inset:0;overflow:hidden;pointer-events:none;
  z-index:0}
.page > section,.page > div{position:relative;z-index:1}

.wand i{position:absolute;display:block;height:var(--h);width:auto;
  aspect-ratio:var(--ar,1);opacity:var(--o,.13);
  background:var(--accent-ink,var(--accent));
  transform:translate3d(0,var(--dy,0px),0);
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat}

@media (prefers-reduced-motion:reduce){
  .wand i{transform:none!important}
}


/* ==== перевеска ==========================================================
   Двигается содержание, стена стоит. Поэтому берём секции, а не саму
   страницу: `.wand` лежит в странице прямым ребёнком и в выборку не
   попадает.
   ------------------------------------------------------------------- */
.page > section{transition:opacity var(--d-mid,560ms) var(--e-out),
                transform var(--d-mid,560ms) var(--e-out)}

/* Снимают со стены: вверх и гаснет. Быстро — это не событие, это уход. */
.page.umh-out > section{opacity:0;transform:translateY(-14px);
  transition-duration:var(--d-fast,240ms);
  transition-delay:calc(var(--uh,0) * var(--step,60ms))}

/* Вешают: приходит снизу на свою линию. */
.page.umh-in > section{opacity:0;transform:translateY(16px)}

@media (prefers-reduced-motion:reduce){
  .page > section,.page.umh-out > section,.page.umh-in > section{
    opacity:1!important;transform:none!important;transition:none!important}
}


/* ==== страница художников: групповой кадр ===============================
   Заставка индекса стояла пустой. Из архива книги пришёл настоящий
   кадр: все художники перед домом. Он и есть ответ на заголовок
   «Wer hier ausgestellt hat».
   ------------------------------------------------------------------- */
.kg{margin-top:clamp(20px,3vh,36px)}
.kg img{display:block;width:100%;height:auto}
.kg figcaption{margin-top:8px;font-size:var(--t-xs);
  color:var(--ink-faint);text-align:left}

/* ==== страница художника ================================================ */
#p-kuenstler .k-bio p{max-width:62ch}
#p-kuenstler .k-role{margin-top:8px}

/* Сетка работ по числу работ: одна — во всю меру, не в трёхколоннике. */
#p-kuenstler .k-works[data-n="1"]{grid-template-columns:minmax(0,640px)}
#p-kuenstler .k-works[data-n="2"]{grid-template-columns:repeat(2,minmax(0,1fr))}

/* Портрет в раме. Голый прямоугольник с тенью был единственным на сайте
   способом показать изображение без рамы — и стоял именно там, где рама
   нужнее всего.

   Обёртка занимает место портрета в сетке #k-body: тот стоял в первой
   колонке на три ряда, и без этих строк рама выпадала из раскладки
   и наезжала на имя. */
#k-body .kfr{grid-column:1;grid-row:1 / span 3}
.kfr{position:relative;width:min(300px,80vw);aspect-ratio:.7533;
  margin:0 auto 8px}
.kfr::before{content:"";position:absolute;inset:0;
  background:var(--accent-ink,var(--accent));
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat}
.kfr img.k-portrait,#k-body .kfr img.k-portrait{position:absolute;
  left:24.6%;top:18.5%;width:50.4%;height:60.5%;
  object-fit:cover;object-position:50% 20%;grid-column:auto;grid-row:auto;
  margin:0;border:0;box-shadow:none;border-radius:0;
  animation:none;opacity:1;transform:none;aspect-ratio:auto}


/* ---- раскладчик рамок (только чистая ветка, ?slots) ------------------- */
.slotfield{position:absolute;inset:0;z-index:-1;pointer-events:none}
body[data-slots="edit"] .slotfield{z-index:60;pointer-events:auto}
body[data-slots="off"] .slotfield{display:none}

.slot{position:absolute;left:var(--x);top:var(--y);width:var(--w);
  aspect-ratio:var(--ar);translate:-50% -50%;
  --sway:0deg;rotate:calc(var(--rot) + var(--sway));
  transform-origin:50% -6%;
  border:2px solid #e2342c;background:rgba(226,52,44,.05);
  box-sizing:border-box}
.slot .ap{position:absolute;inset:24% 20%;border:1px dashed rgba(226,52,44,.5)}
.slot .tag{position:absolute;left:-2px;top:-19px;white-space:nowrap;
  font:500 10px/1 var(--font-sans);letter-spacing:.06em;color:#e2342c}
.slot .h{position:absolute;width:13px;height:13px;background:#e2342c;
  display:none;box-sizing:border-box}
body[data-slots="edit"] .slot{cursor:grab}
body[data-slots="edit"] .slot .h{display:block}
.slot .h.se{right:-7px;bottom:-7px;cursor:nwse-resize}
.slot .h.ee{right:-7px;top:50%;margin-top:-8px;cursor:ew-resize;
  background:#fff;border:2px solid #e2342c}
.slot .h.ss{left:50%;bottom:-7px;margin-left:-8px;cursor:ns-resize;
  background:#fff;border:2px solid #e2342c}
.slot .h.rt{left:50%;top:-30px;margin-left:-8px;border-radius:50%;
  cursor:crosshair}

#slotbar{position:fixed;left:14px;bottom:14px;z-index:9999;width:250px;
  max-height:74vh;overflow:auto;padding:12px;border-radius:12px;
  font:12px/1.45 var(--font-sans);color:var(--ink);
  background:color-mix(in srgb,var(--bg) 94%,transparent);
  border:1px solid var(--hair);backdrop-filter:blur(12px);
  box-shadow:0 18px 50px -22px rgba(25,55,79,.5)}
#slotbar h4{margin:0 0 8px;font:500 10px/1 var(--font-sans);
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint)}
#slotbar .row{display:flex;gap:4px;align-items:center;margin-bottom:4px}
#slotbar .row b{width:16px;color:#e2342c;font-weight:600}
#slotbar .row span{color:var(--ink-faint);font-variant-numeric:lining-nums tabular-nums}
#slotbar button{cursor:pointer;border:1px solid var(--hair);border-radius:7px;
  background:none;color:var(--ink);font:inherit;padding:4px 8px;margin:0px 4px 0 0}
#slotbar button:hover{background:var(--card)}
#slotbar .hint{color:var(--ink-faint);margin:8px 0 0}


/* ---- заходная сцена ---------------------------------------------------- */
body{--in-out:cubic-bezier(.23,1,.32,1);        /* появление и уход */
     --in-move:cubic-bezier(.77,0,.175,1)}      /* движение по экрану */

/* Показ содержимого — отдельным классом, не тем же атрибутом, что такт
   полёта: иначе смена состояния выбивает правило анимации и рамки скачком
   встают по местам, не долетев. */
body[data-intro] header,
body[data-intro] footer,
body[data-intro] .hero .hero-main,
body[data-intro] .hero .hero-meta{
  opacity:0;transition:opacity .8s var(--in-out)}
body[data-intro].intro-open header,
body[data-intro].intro-open footer,
body[data-intro].intro-open .hero .hero-main,
body[data-intro].intro-open .hero .hero-meta{opacity:1}

/* На время сцены вращаем от середины: точка над верхним краем нужна
   маятнику, здесь она уводила бы рамку вбок. Слои — композитору заранее. */
body[data-intro] .hero .slotfield.baked .slot{transform-origin:50% 50%;
  will-change:transform,opacity}
/* до первого такта рамок не видно: иначе полсекунды показывается готовая
   стена и разом пропадает */
body[data-intro="shut"] .hero .slotfield.baked .slot{opacity:0}

body[data-intro="run"] .hero .slotfield.baked .slot{
  animation-duration:2.2s;animation-fill-mode:both;
  animation-timing-function:cubic-bezier(.23,1,.32,1);
  animation-delay:calc(var(--i) * .30s)}

/* Знак в центре сцены. Слои рисует общее правило .cadre-mark, здесь
   только место и размер: с рамой знак стал почти квадратным и просит
   вдвое больше места, чем прежняя надпись. */
#intro-mark{position:fixed;left:50%;top:50%;translate:-50% -50%;
  width:min(200px,24vw);aspect-ratio:var(--logo-ar);z-index:9002;
  opacity:0;pointer-events:none;
  transition:opacity .6s var(--in-out)}
#intro-mark.on{opacity:1}


/* ---- второй блок: фиолетовая комната ------------------------------------
   Подложка — акцентный фиолетовый светлой темы (--accent-ink, #535280).
   Не ночная тема: та синяя, а тут нужен именно фирменный фиолет.

   Три слоя движения, каждый со своей ролью:
     наезд     — фраза приходит чуть крупнее и садится в размер;
     загорание — слово выходит из размытия, а не просто выцветает;
     параллакс — фасад, фраза и приписка идут за прокруткой с разной
                 скоростью, отсюда ощущение глубины комнаты.
   -------------------------------------------------------------------- */
/* Градиент боковой, не «светлое→тёмное»: светлота держится ровной,
   меняется только оттенок — сиреневый уходит в баклажан и обратно. */
.sec.manifest{background:linear-gradient(100deg,#4B4770 0%,#565285 34%,#403B61 68%,#4B4770 100%);
  padding-block:clamp(120px,20vh,220px);overflow:hidden;position:relative}

/* Фасад «Kunstwerkstube» — призраком, одними очертаниями.
   Наложение мягким светом, а не по светимости: светимость подменяет
   светлоту фона целиком, и вместо очертаний выходила фотография с
   фиолетовым налётом. Мягкий свет только модулирует подложку.
   Снимок уже обесцвечен и поджат в самом файле, поэтому фильтр лёгкий.
   Нет файла — переменная не определена, слой не рисуется, блок цел.

   Слой нарочно выше блока на 120px сверху и снизу: он ездит от параллакса
   в пределах ±96px, и при точной высоте на краях открывалась бы голая
   подложка. Запас в пикселях, а не в процентах: сдвиг тоже в пикселях, и
   на короткой секции процент дал бы запас меньше хода. Лишнее срезает
   overflow секции.
   Фасад отстаёт от прокрутки сильнее всех — он дальше всего, за спиной
   у текста; доля 2.1 против 1.0 у приписки и 0.55 у фразы. */
.sec.manifest::before{content:"";position:absolute;inset:-120px 0;
  pointer-events:none;
  background:var(--photo-fassade) center 58%/cover no-repeat;
  opacity:.11;filter:grayscale(1) contrast(2.3) brightness(1.04);
  mix-blend-mode:soft-light;
  transform:translate3d(0,var(--parbg,0px),0);will-change:transform}
.sec.manifest > *{position:relative}

/* Раскладка: огромная фраза сверху слева, маленькая приписка снизу справа.
   Сетку системы здесь ломаем — две равные колонки держали фразу мелкой и
   заполняли блок ровно наполовину. */
.sec.manifest .flex{display:block}
.sec.manifest p{font-size:clamp(38px,6.2vw,92px);line-height:1.03;
  letter-spacing:-.02em;max-width:15ch;margin:0}
/* Разбор арт-директора: «единственный содержательный абзац на странице
   подан самым нечитаемым способом на сайте» — 15px курсивом поверх
   фотографии, при заголовке в 89px рядом. Между 89 и 15 не было ничего.
   Теперь 19px, прямое начертание, полная непрозрачность и мера покороче;
   под текстом местное затемнение снимка, чтобы буквы не спорили с окном
   фасада. */
.sec.manifest .aside{max-width:36ch;margin:clamp(44px,8vh,96px) 0 0 auto;
  font-size:19px;line-height:1.62;font-style:normal;
}
/* Затемнения под приписткой нет и не будет: пробовал 24 августа, чтобы
   отделить текст от фасада, — читается как тёмное пятно на ровной
   стене. Читаемость держат кегль и прямое начертание, а не подложка. */
/* У Manrope нет курсива, и приписка наклонялась синтетически — на
   19 пикселях это уже видно как перекос, а не как начертание. */
.sec.manifest .aside,
.sec.manifest .aside p,
.sec.manifest .aside .w2{font-style:normal}
.sec.manifest,
.sec.manifest p,
.sec.manifest .w{color:#fff}
.sec.manifest .aside,
.sec.manifest .aside p{color:#fff}
.sec.manifest em{color:#B9D6D3}

/* параллакс: сдвиг задаёт скрипт, у колонок разная доля */
.sec.manifest .flex > *{will-change:transform}
.sec.manifest p{transform:translateY(calc(var(--par,0px) * .55))}
.sec.manifest .aside{transform:translateY(var(--par,0px))}

/* наезд: фраза приходит крупнее и садится */
.sec.manifest.armed p{transform:translateY(calc(var(--par,0px) * .55)) scale(1.045)}
.sec.manifest.lit p{
  animation:zoomSettle 2.8s cubic-bezier(.23,1,.32,1) both}
@keyframes zoomSettle{
  from{transform:scale(1.045)}
  to  {transform:scale(1)}}

.sec.manifest .w,.sec.manifest .w2{display:inline-block;white-space:pre}

/* Переходы, а не ключевые кадры. У кадров конечное состояние — заливка
   анимации: пока она числится запущенной, она перебивает любые обычные
   правила, и если время по какой-то причине не идёт, слово застревает на
   первом кадре навсегда. У перехода конечное состояние — обычный стиль:
   не сработал переход, слово всё равно на месте. */
.sec.manifest.armed .w{opacity:0;filter:blur(9px);transform:translateY(.32em)}
.sec.manifest.armed p{transform:scale(1.045)}

.sec.manifest.armed .w,
.sec.manifest.armed p{
  transition:opacity 1.7s cubic-bezier(.23,1,.32,1),
             filter 1.7s cubic-bezier(.23,1,.32,1),
             transform 2.1s cubic-bezier(.23,1,.32,1)}
.sec.manifest.armed .w{transition-delay:calc(var(--w) * .24s)}

/* Приписка идёт строками. Двигаем её словам translate, а не transform:
   у самой приписки transform уже занят параллаксом. Слова одной строки
   получают один и тот же --ln, поэтому строка выходит целиком. */
.sec.manifest.armed .w2{opacity:0;filter:blur(5px);translate:0 .3em;
  transition:opacity 1s cubic-bezier(.23,1,.32,1),
             filter 1s cubic-bezier(.23,1,.32,1),
             translate 1.2s cubic-bezier(.23,1,.32,1);
  transition-delay:calc(var(--after,0s) + var(--ln,0) * .16s)}

/* слово загорается: выходит из размытия, а не просто проявляется */
.sec.manifest.armed.lit .w{opacity:1;filter:blur(0);transform:none}
.sec.manifest.armed.lit .w2{opacity:1;filter:blur(0);translate:0 0}
.sec.manifest.armed.lit p{transform:scale(1)}

@media (prefers-reduced-motion:reduce){
  .sec.manifest .w,.sec.manifest .w2,.sec.manifest .aside,.sec.manifest p{
    transition:none!important;opacity:1!important;filter:none!important;
    transform:none!important;translate:none!important}}


/* ---- появление и качание рамки ----------------------------------------
   Крутится не вся фигура, а три слоя, из которых сложена рамка: кадр и
   два слоя резьбы. Подпись остаётся в потоке и не качается вместе с ними —
   этикетка приклеена к стене, а не к раме.

   Гвоздь — над верхним краем (50% -6%), как у развески в герое: рамка
   висит на нём, а не вращается вокруг своей середины.
   -------------------------------------------------------------------- */
#p-start .fig[data-hangs] > svg,
#p-start .fig[data-hangs]::before,
#p-start .fig[data-hangs]::after{
  transform-origin:50% -6%;rotate:var(--sway,0deg)}

#p-start .fig[data-hangs] > svg,
#p-start .fig[data-hangs]::before,
#p-start .fig[data-hangs]::after,
#p-start .fig[data-hangs] figcaption{
  transition:opacity .95s cubic-bezier(.23,1,.32,1),
             translate .95s cubic-bezier(.23,1,.32,1)}
#p-start .fig[data-hangs] figcaption{transition-delay:.28s}

/* Прячем только после того, как скрипт добавил armed, и только до lit. */
#p-start .fig.armed > svg,
#p-start .fig.armed::before,
#p-start .fig.armed::after,
#p-start .fig.armed figcaption{opacity:0;translate:0 18px}
#p-start .fig.armed.lit > svg,
#p-start .fig.armed.lit::before,
#p-start .fig.armed.lit::after,
#p-start .fig.armed.lit figcaption{opacity:1;translate:0 0}

@media (prefers-reduced-motion:reduce){
  #p-start .fig[data-hangs] > svg,
  #p-start .fig[data-hangs]::before,
  #p-start .fig[data-hangs]::after,
  #p-start .fig[data-hangs] figcaption{
    transition:none!important;opacity:1!important;translate:none!important;
    rotate:0deg!important}}


/* ---- шесть дверей одной стеной -----------------------------------------
   Ряд из шести рам разного рисунка и размера, с лёгким наклоном. Внутри
   рамы только номер; название и строчка описания стоят под рамой.
   -------------------------------------------------------------------- */
.sec.gates .grid{grid-template-columns:repeat(3,1fr);
  gap:clamp(26px,3.4vw,56px) clamp(20px,2.6vw,44px);
  align-items:end}

.sec.gates{--fr-h:clamp(190px, 22vh, 290px)}
.sec.gates .gate{background:none;border:0;box-shadow:none;padding:0;
  display:flex;flex-direction:column;align-items:center;text-align:center;
  position:relative;isolation:isolate;
  transition:transform .3s cubic-bezier(.2,.7,.2,1)}

/* Коробка рамы берёт свою пропорцию — иначе резьбу плющит. */
/* Базовая таблица держит .gate::before абсолютным — коробка рамы не
   вставала в поток и схлопывалась в ноль. Возвращаем в поток. */
.sec.gates .gate::before{content:"";display:block;position:relative;
  inset:auto;opacity:1;
  /* Задаём высотой, а не шириной: на стене рамы висят примерно на одной
     высоте, а ширина у каждой своя — от её же пропорции. От ширины
     ячейки высота выходила в полтысячи пикселей. */
  height:var(--fr-h);width:auto;aspect-ratio:var(--fr-ar,1);
  rotate:var(--fr-rot,0deg);
  background:var(--accent-ink,var(--accent));
  -webkit-mask:var(--fr) center/100% 100% no-repeat;
          mask:var(--fr) center/100% 100% no-repeat}

/* Номер сидит в проёме крупной литерой — это табличка на раме, а не
   текст в рамке: одна цифра не читается как запертый абзац. */
.sec.gates .gate .num{position:absolute;left:50%;top:0;translate:-50% 0;
  height:var(--fr-h);
  display:flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-size:clamp(28px,3.4vw,46px);
  color:var(--accent-ink,var(--accent));opacity:.75;
  letter-spacing:0;line-height:1;rotate:var(--fr-rot,0deg)}

/* Этикетка под рамой. */
.sec.gates .gate h3{margin:clamp(14px,1.8vh,22px) 0 0}
.sec.gates .gate p{margin:4px 0 0;max-width:26ch}
.sec.gates .gate .go{margin-top:clamp(10px,1.4vh,16px)}

/* Наведение: подъём на 5px и сдвиг цвета, как велит система. Никакого
   сжатия. */
.sec.gates .gate:hover{transform:translateY(-5px)}
.sec.gates .gate:hover::before{background:var(--accent)}

@media (max-width:900px){
  .sec.gates .grid{grid-template-columns:repeat(2,1fr)}
  .sec.gates{--fr-h:clamp(140px, 18vh, 180px)}
  .sec.gates .gate{--fr-rot:0deg}
}

@media (prefers-reduced-motion:reduce){
  .sec.gates .gate{transition:none}
  .sec.gates .gate:hover{transform:none}
}

.sec.gates .gate:nth-child(1){--fr:var(--vfr-baroque_frame);--fr-ar:var(--vfr-baroque_frame-ar,1);--fr-rot:-1.2deg}
.sec.gates .gate:nth-child(2){--fr:var(--vfr-achteckige_zier);--fr-ar:var(--vfr-achteckige_zier-ar,1);--fr-rot:0.8deg}
.sec.gates .gate:nth-child(3){--fr:var(--vfr-barock_leerfeld);--fr-ar:var(--vfr-barock_leerfeld-ar,1);--fr-rot:-0.6deg}
.sec.gates .gate:nth-child(4){--fr:var(--vfr-vintage);--fr-ar:var(--vfr-vintage-ar,1);--fr-rot:1.1deg}
.sec.gates .gate:nth-child(5){--fr:var(--vfr-renaissance);--fr-ar:var(--vfr-renaissance-ar,1);--fr-rot:-0.9deg}
.sec.gates .gate:nth-child(6){--fr:var(--vfr-vintage_perlenborduere);--fr-ar:var(--vfr-vintage_perlenborduere-ar,1);--fr-rot:0.7deg}

/* ---- карточная сетка с вензелями ----------------------------------------
   Владелица 28 августа: «сетка обычная, но внутри рисунок, скомбини-
   рованный с вензелями рамки — они с какого-то краю перекрывают».
   Прежнее правило «либо рамка целиком, либо ничего» отменено её словом:
   вензель здесь не обломок, а приём — орнамент врастает в картинку.

   Карточки ровной сеткой, как в референсе: изображение сверху, номер,
   заголовок, текст, ссылка. Орнамент — крупный фрагмент векторной рамы,
   у каждой карточки свой и со своего края; хвост обрезается краем
   карточки.
   ------------------------------------------------------------------- */
/* Владелица: «обязательно все блоки и все картинки одного размера».
   Ряды сетки равные, ссылка прижата к низу — шесть карточек стоят как
   одна отливка, картинки — фиксированная высота у всех. */
.sec.gates .grid{align-items:stretch;grid-auto-rows:1fr}
/* Поле держит карточка; дети без боковых отступов — одна левая линия
   без сложения полей, которое дважды ломало выравнивание. */
.sec.gates .gate{position:relative;overflow:hidden;
  background:var(--bg);border:1px solid var(--hair,rgba(25,55,79,.12));
  padding:0 20px 24px;text-align:left;align-items:stretch;
  display:flex;flex-direction:column}
.sec.gates .gate::before{display:none}

/* Изображение: рисунок или живопись, во всю ширину карточки. */
/* order:-1 — картинка первой, как в референсе: скрипт добавляет её в
   конец разметки, а место ей сверху. */
.sec.gates .gate .mini{position:relative;left:auto;top:auto;order:-1;
  translate:none;rotate:none;
  width:calc(100% + 44px);margin-inline:-20px;
  height:clamp(150px,16vw,200px);
  display:flex;align-items:center;justify-content:center;
  /* Тонированная бумага: на чисто-белом белое кружево логотипа тает,
     а на лёгком фиолете читается — и рисунки становятся оттисками. */
  background:rgba(119,118,161,.16);pointer-events:none;overflow:hidden;
  color:var(--accent-ink)}

/* Язык миниатюр: штрих и две отмывки. Без этих правил SVG чернеет
   заливкой по умолчанию — уже наступали. */
.mini .ln{stroke:currentColor;fill:none;stroke-width:1.6;
  stroke-linecap:round}
.mini .thin{stroke-width:1.1;opacity:.55}
.mini .fn{fill:currentColor}
.mini .fnw{fill:currentColor;opacity:.14}
.mini .fnw2{fill:currentColor;opacity:.26}
.mini text{font-family:var(--serif);fill:var(--ink)}
.mini .route{stroke-dasharray:3 6}

.sec.gates .gate .mini > svg{width:auto;height:78%;overflow:visible}
.sec.gates .gate .mini > img{width:100%;height:100%;object-fit:cover;
  box-shadow:none}

/* Вензель: белый кружевной силуэт рамы ПОВЕРХ картинки, коллажем.
   Владелица 28 августа: «в левом углу красивая, чуть ли не кружевная
   силуэт рамки — не портит картинку, а дополняет; можно белым».
   Белому кружеву на светлом нужна тонкая тень, иначе оно тает.
   Живёт внутри зоны изображения: текст не трогает, хвост режется краем. */
.sec.gates .gate .korn{position:absolute;pointer-events:none;
  width:var(--kw);aspect-ratio:var(--ar,1);
  left:var(--kx);top:var(--ky);rotate:var(--kr,0deg);
  background:#fff;
  filter:drop-shadow(0 1px 1.5px rgba(25,55,79,.4));
  -webkit-mask:var(--f) center/100% 100% no-repeat;
          mask:var(--f) center/100% 100% no-repeat}
.sec.gates .gate .korn.k2{filter:drop-shadow(0 1px 1px rgba(25,55,79,.3));
  opacity:.9}

/* Номер и текст — как в референсе: слева, по сетке. Базовая таблица
   центрирует содержимое ворот и на узкой ширине делает это ещё раз
   отдельным правилом — поэтому левая линия здесь прибита на всех
   ширинах явно, а не полагается на наследование. */
.sec.gates .gate,
.sec.gates .gate h3,
.sec.gates .gate p{text-align:left}
/* База ограничивает абзац узкой мерой — в карточке текст живёт во всю
   её ширину, владелица: «ширина текста по ширине карточки». */
.sec.gates .gate h3,
.sec.gates .gate p{width:100%;max-width:none;box-sizing:border-box;
  margin:0}
@media (max-width:900px){
  .sec.gates .gate{align-items:stretch;text-align:left;padding:0 20px 20px}
  .sec.gates .gate .mini{width:calc(100% + 40px);margin-inline:-20px}
}

/* Номер и текст — по сетке. */
.sec.gates .gate .num{position:static;height:auto;translate:none;
  rotate:none;display:block;text-align:left;
  font-size:26px;line-height:1;opacity:1;color:var(--ink);
  font-variant-numeric:lining-nums;font-feature-settings:'lnum' 1;
  padding:16px 0 0;margin:0}
.sec.gates .gate h3{padding:8px 0 0;margin:0;text-align:left}
.sec.gates .gate p{padding:8px 0 0;margin:0;text-align:left}
.sec.gates .gate .go{margin:auto 0 0!important;padding:12px 0 0;
  align-self:flex-start}

@media (max-width:900px){
  .sec.gates .gate .mini{height:170px}
}
@media (prefers-reduced-motion:reduce){
  .mini .route,.mini .welle{transition:none}
}


/* ---- архетипы появления -------------------------------------------------
   Система из MOTION.md. Прячет и показывает только скрипт: в таблице
   стилей нет ни одного правила, которое спрятало бы текст само по себе.
   Нет атрибута — абзац просто стоит на месте.

   Направление одно на весь сайт: снизу к своей линии. Картину поднимают
   к гвоздю, а не роняют сверху.
   -------------------------------------------------------------------- */
[data-appear]{opacity:0;transform:translateY(var(--lift,12px));
  transition:opacity var(--d-mid,560ms) var(--e-out,cubic-bezier(.23,1,.32,1)),
             transform var(--d-mid,560ms) var(--e-out,cubic-bezier(.23,1,.32,1));
  transition-delay:calc(var(--ap,0) * var(--step,60ms))}
[data-appear].seen{opacity:1;transform:none}

/* Заголовок: курсивное слово отстаёт на полшага. Сдвигать его отдельно
   нельзя — inline-block сломал бы перенос строки в длинном заголовке,
   поэтому отстаёт только проявление. */
[data-appear="title"] em{opacity:0;
  transition:opacity var(--d-mid,560ms) var(--e-out,cubic-bezier(.23,1,.32,1));
  transition-delay:calc(var(--ap,0) * var(--step,60ms) + var(--step,60ms))}
[data-appear="title"].seen em{opacity:1}

/* Имена в длинном списке выходят по одному. Это исключение из правила
   «лесенка кончается на шестом шаге», и оно осознанное: сто пять имён —
   это и есть содержание блока, а не украшение к нему. Шаг считает
   скрипт так, чтобы весь список уложился примерно в две с половиной
   секунды, сколько бы имён ни было.

   Светятся не все, а только те, у кого есть страница: мерцание в списке
   означает «этого можно открыть», а не «здесь красиво». */
[data-appear="name"]{transition-delay:var(--nd,0ms)}
@keyframes nm-glow{
  from{color:var(--accent);text-shadow:0 0 12px rgba(119,118,161,.5)}
  to{color:inherit;text-shadow:0 0 0 rgba(119,118,161,0)}
}
[data-appear="name"].seen[data-glow]{
  animation:nm-glow 900ms var(--e-out,cubic-bezier(.23,1,.32,1)) both;
  animation-delay:var(--nd,0ms)}

/* Линия прочерчивается слева направо. Это же и есть ось развески. */
[data-appear="rule"]{opacity:1;transform:scaleX(0);transform-origin:left center;
  transition:transform var(--d-mid,560ms) var(--e-out,cubic-bezier(.23,1,.32,1))}
[data-appear="rule"].seen{transform:scaleX(1)}

/* Слой ходит только пока едет: постоянный will-change на сорока работах —
   это сорок слоёв в памяти. */
[data-appear]:not(.seen){will-change:opacity,transform}
[data-appear].seen{will-change:auto}

@media (prefers-reduced-motion:reduce){
  [data-appear],[data-appear] em{opacity:1!important;transform:none!important;
    transition:none!important}
  [data-appear="name"].seen[data-glow]{animation:none}}



/* --------------------------------------------------------------------
   Мобильная отделка: пальцу нужна цель не меньше 44px, а служебные
   подписи не должны падать ниже 12px. Правила собраны в одном месте,
   чтобы не растекались по файлу.
   -------------------------------------------------------------------- */
@media(max-width:899px){ /* и планшет: там тоже палец */
  .fmt-tab,.menu-tab,.filter button,.kat-tab,.tab,
  .wf-btns button,.kv-switch button{min-height:44px;padding-block:11px}
  .fmt-book,.cart-close{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .cart-close{min-width:44px}
  .cat-note a{display:inline-block;padding-block:8px}
  .plan-go{min-height:44px;display:inline-flex;align-items:center}
  .addr a,.plan a,.tl-n a,.body a{display:inline-block;padding-block:7px}
  .mi-add{min-height:44px;min-width:44px}
  .anf-next,.anf-back,.anf-send{min-height:46px;padding-block:13px}
  .art-link,.k-back,.k-ask{min-height:44px;display:inline-flex;align-items:center}
  .foot-links button,.foot-links a{min-height:40px;display:inline-flex;align-items:center}
  .fmt-ph b{font-size:12px}
  .fmt-ph em{font-size:11px}
  .anf-f > span{font-size:12px}
  .anf-step{font-size:12.5px}
  .anf-sum,.anf-msg{font-size:13px}
  /* Карточки формата и шаги формы на узком экране — в один столбец. */
  .picks{grid-template-columns:1fr}
  .anf{padding:18px}
  .anf-grid{grid-template-columns:1fr}
}


/* Цифры по всему сайту — единой высоты (lining): у Fraunces/текстовых
   начертаний встречались «старостильные» цифры разной высоты. */
html, body, input, select, textarea, button{font-variant-numeric:lining-nums;font-feature-settings:"lnum" 1}
