/* ==========================================================================
   site.css — THE SHARED, CANONICAL SITE STYLESHEET.
   This is the ONE stylesheet every real page links. It is concept D ("Warm earth /
   the maker's hand", the FINAL approved design) copied VERBATIM: the concept-D :root
   design tokens are SITE LAW and every selector/value below is unchanged from
   assets/concept-d.css. Do not fork concept-specific styles here — edit tokens in
   :root only, and only with explicit owner approval.

   Provenance (concept D = winning concept C + four approved grafts):
     (1) STICKY/FIXED header  — mechanic from concept-B, restyled in C tokens.
     (2) HERO wall-label      — museum work-label from concept-A, in C type/colour.
     (3) SYMPATHY-GIFT band   — dark espresso section (framing from concept-B), C palette.
     (4) PRICING tier lines   — a "who it's for" line per card (pattern from concept-A).

   Winner's tokens become site law, so everything the site needs lives in :root.
   ========================================================================== */

:root {
  /* --- PALETTE: warm paper + kiln clay + studio sage + sepia ink -----------
     Composed for this concept from the culture-guide earth family
     (petportraits terracotta #e97c5a / cream #f5f0e7 / teal #0d726a,
      W&W tan #cca38b). Ours leans deeper & more hand-thrown: kiln clay
      instead of soft terracotta, muslin & flax instead of flat white,
      eucalyptus sage as the quiet second voice, warm gold only as a hairline. */

  --clay:        #b3542e;   /* PRIMARY accent — kiln-fired terracotta (CTAs, rules) */
  --clay-deep:   #944327;   /* pressed clay — hovers, active */
  --clay-soft:   #d98b63;   /* thinned clay — tints, glows */

  --sage:        #6d7a5b;   /* SECONDARY — studio eucalyptus (living-pet voice) */
  /* Тот же тон, три ступени темнее. Заведён 08.09.2026 для метки «уходит в печать» на полосе
     вариантов (`p.css`). 🔴 Причина измеримая, а не вкусовая: у `--sage` и `--clay` почти
     совпадает СВЕТЛОТА (L* 49.4 против 47.1, контраст между собой 1.09:1) — в оттенках серого это
     один и тот же серый, и различаются они только тоном. Для аудитории 65+, у которой контрастная
     чувствительность падает первой, две такие рамки выглядят одинаково. У `--sage-deep` L* 29.4 и
     контраст к бумаге 8.35:1. Не осветлять: на `#4a5a42` разница снова схлопывается.
     ⚠️ Токен должен жить ИМЕННО ЗДЕСЬ: `concept-c.css` — архивный файл конкурса концепций, его ни
     одна боевая страница не подключает (проверено грепом: только `_archive/concept-c.php`). */
  --sage-deep:   #3a4a30;
  --sage-soft:   #8e9b7d;

  --ink:         #2b2018;   /* warm sepia-black — body text, never #000 */
  --ink-soft:    #574a3d;   /* muted ink — secondary text */
  --ink-faint:   #8a7b6b;   /* captions, eyebrow labels */

  --paper:       #f6efe1;   /* warm flax paper — page base */
  --muslin:      #efe5d3;   /* raw muslin — alternating sections */
  --flax:        #e7dbc4;   /* deeper woven flax — cards / panels */
  --cream:       #fbf6ec;   /* lifted cream — raised cards on dark */

  --espresso:    #2a2119;   /* dark studio wall — inverse sections */
  --espresso-2:  #34291f;   /* lifted espresso — cards on dark */

  --gold:        #b3903c;   /* WARM GOLD HAIRLINE ONLY — <=5%, never fill/gradient */

  --line:        #d8c7a8;   /* hairline on paper */
  --line-ink:    rgba(43,32,24,.16);

  /* --- TYPE: antiqua-accent display + humanist body + one signature ---------
     Fraunces (soft old-style serif, opsz warmth) = "gallery / made by hand".
     Mulish (humanist sans) = calm premium body, NOT geometric mid-market.
     Caveat = the maker's signature, used exactly ONCE. */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body:    "Mulish", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-hand:    "Caveat", "Segoe Script", cursive;

  /* --- SCALE (premium air: body 18px, large fluid display) ------------------ */
  --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.92rem);
  --step-0:  clamp(1.06rem, 1.01rem + 0.24vw, 1.19rem);
  --step-1:  clamp(1.28rem, 1.18rem + 0.5vw, 1.6rem);
  --step-2:  clamp(1.6rem, 1.4rem + 1vw, 2.3rem);
  --step-3:  clamp(2.1rem, 1.7rem + 2vw, 3.4rem);
  --step-4:  clamp(2.7rem, 2rem + 3.6vw, 5rem);
  --step-hero: clamp(3rem, 2rem + 6vw, 6.5rem);

  /* --- RADII (hand-made, soft but not bubbly) ------------------------------- */
  --r-sm: 3px;
  --r-md: 6px;
  --r-lg: 12px;
  --r-pill: 999px;

  /* --- SPACE --------------------------------------------------------------- */
  --gutter: clamp(1.15rem, 4vw, 3.5rem);
  --section-y: clamp(4.5rem, 9vw, 8.5rem);
  --measure: 66ch;

  /* --- SHADOW (warm, low, like light across a bench) ------------------------ */
  --shadow-frame: 0 1px 0 rgba(255,255,255,.4), 0 22px 44px -28px rgba(58,38,20,.55);
  --shadow-card:  0 14px 30px -22px rgba(58,38,20,.5);
}

/* ==========================================================================
   RESET / BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.66;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Paper grain — a thin studio texture over the whole page (multiply, subtle) */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: .5;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.055'/%3E%3C/svg%3E");
}

img { max-width: 100%; display: block; }
/* 🔴 И СРАЗУ ЖЕ ОБРАТНО ДЛЯ [hidden] (01.09.2026). Строка выше — обычный сброс, но у неё есть
   последствие, которое ловится только глазами: авторское правило БЬЁТ правило браузера
   `[hidden] { display: none }`, поэтому <img hidden> продолжает занимать место и рисоваться.
   На странице портрета клиента из-за этого поверх мозаики висел значок битой картинки с
   подписью «Winston — Version 3»: элемент `#p-flat` (готовый файл мастера) стоит скрытым у
   каждого варианта фермы, то есть у КАЖДОГО сегодняшнего клиента. Точечные заплаты на этот
   случай уже были в трёх местах (order.css: .sendnote/.lowcount/.cropmodal, p.css: .p-act) —
   значит чинить надо не четвёртое место, а сам сброс. */
[hidden] { display: none !important; }
a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 460;
  line-height: 1.04;
  letter-spacing: -0.012em;
  margin: 0;
  font-optical-sizing: auto;
}

::selection { background: var(--clay-soft); color: var(--ink); }

/* ==========================================================================
   SHARED PRIMITIVES
   ========================================================================== */
.wrap { width: min(1200px, 100% - (var(--gutter) * 2)); margin-inline: auto; }
.wrap--narrow { width: min(820px, 100% - (var(--gutter) * 2)); margin-inline: auto; }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--clay);
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
}
.eyebrow::before {
  content: "";
  width: 1.9em;
  height: 2px;
  background: var(--clay);
  display: inline-block;
}
.eyebrow--sage { color: var(--sage); }
.eyebrow--sage::before { background: var(--sage); }
.eyebrow--light { color: var(--clay-soft); }
.eyebrow--light::before { background: var(--clay-soft); }
.eyebrow--center { justify-content: center; }

.lede {
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: var(--measure);
  font-weight: 400;
}

/* Buttons — a pressed clay stamp */
.btn {
  --btn-bg: var(--clay);
  --btn-fg: var(--cream);
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--step-0);
  letter-spacing: 0.005em;
  line-height: 1;
  padding: 1.05em 1.9em;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  text-decoration: none;
  transition: transform .28s cubic-bezier(.2,.8,.2,1), background-color .28s, box-shadow .28s;
  box-shadow: 0 10px 22px -14px rgba(120,54,20,.9);
}
.btn:hover { background: var(--btn-bg, var(--clay-deep)); transform: translateY(-2px); box-shadow: 0 16px 30px -14px rgba(120,54,20,.95); }
.btn--clay:hover { background: var(--clay-deep); }
.btn:active { transform: translateY(0); }
.btn .arrow { transition: transform .28s cubic-bezier(.2,.8,.2,1); }
.btn:hover .arrow { transform: translateX(4px); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border: 1.5px solid var(--ink);
  box-shadow: none;
}
.btn--ghost:hover { background: var(--ink); color: var(--paper); }
.btn--sage { --btn-bg: var(--sage); box-shadow: 0 10px 22px -14px rgba(70,84,50,.9); }
.btn--sage:hover { background: #5b6749; }
.btn--onDark {
  background: var(--cream); color: var(--ink);
}
.btn--onDark:hover { background: #fff; }

.link-underline {
  color: var(--clay);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1.5px solid var(--clay-soft);
  padding-bottom: 1px;
  transition: border-color .25s, color .25s;
}
.link-underline:hover { color: var(--clay-deep); border-color: var(--clay); }

/* Section rhythm */
section { padding-block: var(--section-y); position: relative; }
.section-head { max-width: 44rem; margin-bottom: clamp(2rem, 4vw, 3.4rem); }
.section-head h2 { font-size: var(--step-3); margin-top: 0.6rem; }
.section-head .lede { margin-top: 1.1rem; }

/* Ornamental centered rule */
.rule-ornament {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  color: var(--ink-faint);
}
.rule-ornament::before, .rule-ornament::after {
  content: ""; height: 1px; width: min(120px, 22vw); background: var(--line);
}
.rule-ornament span { font-family: var(--font-display); font-size: 1.3rem; color: var(--clay); }

/* ==========================================================================
   HEADER
   ========================================================================== */
/* TRANSPLANT 1 (from concept-B sticky header): pin the header so "Begin a portrait"
   stays reachable on the long emotional scroll. C's hero is a full-bleed dark stage, so
   the header uses `position: fixed` (overlays the hero without stealing its top edge — the
   pinned-CTA benefit of B's `position: sticky`, adapted to a full-bleed hero). Transparent
   over the dark hero; a translucent espresso backdrop + blur fades in once scrolled
   (.is-scrolled, toggled in concept-d.js) so cream text stays legible over any section. */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  padding-block: clamp(0.75rem, 1.8vw, 1.15rem);
  padding-top: clamp(1.1rem, 2.4vw, 1.9rem);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color .35s ease, backdrop-filter .35s ease,
              padding .35s ease, border-color .35s ease, box-shadow .35s ease;
}
.site-header.is-scrolled {
  padding-top: clamp(0.75rem, 1.8vw, 1.15rem);
  background: color-mix(in srgb, var(--espresso) 86%, transparent);
  backdrop-filter: saturate(1.15) blur(14px);
  -webkit-backdrop-filter: saturate(1.15) blur(14px);
  border-bottom-color: rgba(217,139,99,.22);
  box-shadow: 0 14px 30px -26px rgba(0,0,0,.7);
}
/* color-mix fallback for engines without it: solid espresso, still on-brand */
@supports not (background: color-mix(in srgb, red, blue)) {
  .site-header.is-scrolled { background: rgba(42,33,25,.94); }
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
/* TODO-GAP: brand name not chosen — neutral wordmark placeholder */
.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55rem;
  color: var(--cream);
  text-decoration: none;
}
/* ЗНАК БРЕНДА (29.08.2026, GAP-8). Лапа из плиток слева от словесной марки.
   ⚠️ Выравнивание у .brand — по базовой линии текста (align-items: baseline), а у картинки
   базовой линии нет: она села бы нижним краем на линию букв и «провалилась» вниз. Поэтому
   собственный self-end + микросдвиг: знак стоит на той же оптической линии, что и буквы.
   На узком экране словесная марка ужимается первой, знак остаётся — он и есть опознавание. */
.brand__logo {
  align-self: center;
  flex: 0 0 auto;
  display: block;
  transform: translateY(1px);
}
@media (max-width: 480px) {
  .brand__logo { width: 26px; height: 26px; }
}
/* 🔴 ПОЧЕМУ ЗДЕСЬ nowrap И ЖЁСТКИЙ ЗАПРЕТ СЖАТИЯ (29.08.2026, поймано owner'ом на скриншоте).
   Знак добавил в строку шапки лишние ~40 px, и на среднем экране флексбокс сделал ровно то, что
   умеет: начал ужимать элементы по ширине. «Pet Story Mosaic» сложилось в ДВЕ строки, а пункт
   «How it works» — в три. Выглядит как сломанная вёрстка, хотя ни одно правило не «сломалось».
   Лечение — сказать флексбоксу правду о том, что здесь не ужимается: название бренда и пункты
   меню переносить нельзя, они атомарны. Сжиматься разрешено только промежуткам. */
.brand__mark {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.brand { flex: 0 0 auto; }
.nav a, .nav__links a { white-space: nowrap; }
/* Подпись-хвост («A PLACE TO PUT THE LOVE») — единственное, что здесь МОЖНО прятать: она
   декоративная. На тесном экране уходит первой, до того как начнёт рваться что-то смысловое. */
@media (max-width: 1100px) { .brand__tag { display: none; } }
.brand__tag {
  font-size: 0.62rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  font-weight: 700;
  opacity: 0.72;
}
.nav { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.1rem); }
.nav a {
  color: var(--cream);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  opacity: 0.9;
  transition: opacity .2s;
}
.nav a:not(.btn):hover { opacity: 1; }
.nav a:not(.btn) { position: relative; }
.nav a:not(.btn)::after {
  content: ""; position: absolute; left: 0; bottom: -5px; height: 1.5px; width: 0;
  background: var(--clay-soft); transition: width .28s ease;
}
.nav a:not(.btn):hover::after { width: 100%; }
.nav .btn { padding: 0.72em 1.3em; font-size: 0.88rem; }
.nav__links { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.1rem); }
.nav-toggle { display: none; }
/* Пункт «Contact» существует ТОЛЬКО в выпадающем меню телефона (решение владельца 10.09.2026).
   На десктопе шапка — узкая строка, и лишний пункт отнимает место у кнопки заказа; там человек
   скорее долистает до блока цен или до подвала. На телефоне шапки как ряда ссылок нет вовсе, а
   меню — единственная точка, доступная БЕЗ прокрутки. Правило снимается в мобильном блоке ниже. */
.nav__mobile-only { display: none; }

/* ==========================================================================
   HERO — the living deep-zoom of Winston (the product's monopoly)
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  padding: 0;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--espresso);
}
#hero-osd, .hero__stage {
  position: absolute;
  inset: 0;
  z-index: 1;
}
/* Warm loading underlay so the stage is never a black box before tiles load */
.hero__poster {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(120% 90% at 62% 34%, rgba(217,139,99,.35), transparent 60%),
    radial-gradient(90% 80% at 30% 70%, rgba(109,122,91,.28), transparent 62%),
    linear-gradient(160deg, #3a2a1c 0%, #2a2119 60%, #211a13 100%);
  animation: posterDrift 26s ease-in-out infinite alternate;
  transform-origin: 60% 40%;
}
@keyframes posterDrift {
  from { transform: scale(1.04); }
  to   { transform: scale(1.16); }
}
/* Scrim for legibility of the text over the mosaic */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(to top, rgba(28,20,13,.9) 0%, rgba(28,20,13,.5) 32%, rgba(28,20,13,.12) 58%, rgba(28,20,13,.4) 100%),
    linear-gradient(105deg, rgba(28,20,13,.55) 0%, transparent 55%);
}
.hero__inner {
  position: relative;
  z-index: 3;
  width: 100%;
  padding-bottom: clamp(3rem, 7vw, 6rem);
  padding-top: 8rem;
}
.hero__offer {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  background: rgba(179,84,46,.16);
  border: 1px solid rgba(217,139,99,.55);
  color: var(--cream);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 0.6em 1.1em;
  border-radius: var(--r-pill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.hero__offer .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--clay-soft); box-shadow: 0 0 0 4px rgba(217,139,99,.25); }
.hero h1 {
  color: var(--cream);
  font-size: var(--step-hero);
  font-weight: 420;
  letter-spacing: -0.02em;
  margin-top: 1.1rem;
  max-width: 15ch;
  text-shadow: 0 2px 30px rgba(0,0,0,.35);
}
.hero h1 em { font-style: italic; color: var(--clay-soft); }
.hero__sub {
  color: rgba(251,246,236,.86);
  font-size: var(--step-1);
  line-height: 1.5;
  max-width: 46ch;
  margin-top: 1.3rem;
  font-weight: 400;
}
.hero__cta {
  display: flex;
  align-items: center;
  gap: 1.3rem;
  flex-wrap: wrap;
  margin-top: 2rem;
}
.hero__note {
  color: rgba(251,246,236,.78);
  font-size: 0.95rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}
.hero__note::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--sage-soft); }

/* "Explore" hint anchored to the stage — hero is a scene, not a tool */
.hero__hint {
  position: absolute;
  top: clamp(6rem, 12vh, 9rem);
  right: var(--gutter);
  z-index: 3;
  color: rgba(251,246,236,.8);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 0.6em;
  writing-mode: vertical-rl;
}
.hero__hint .pulse {
  width: 9px; height: 9px; border-radius: 50%; background: var(--clay-soft);
  animation: hintPulse 2.4s ease-in-out infinite;
}
@keyframes hintPulse {
  0%,100% { opacity: .35; transform: scale(.8); }
  50% { opacity: 1; transform: scale(1.15); }
}

/* TRANSPLANT 2 (from concept-A hero wall-label): a museum "work label" / catalogue record,
   framing the hero mosaic as a real piece with a catalogue entry. Fields verbatim from A
   ("Winston · Golden Retriever · 500 photographs · Giclée on canvas") but re-set in C type
   (Fraunces italic title + Mulish tracked caps) and cream tone. Anchored TOP-LEFT with a clay
   left-rule so it never crowds the H1/offer (bottom-left) or the vertical hint (right). */
.hero__plate {
  position: absolute;
  top: clamp(6rem, 13vh, 9rem);
  left: var(--gutter);
  z-index: 3;
  max-width: 15rem;
  padding-left: 1rem;
  border-left: 1px solid rgba(217,139,99,.55);
  color: rgba(251,246,236,.9);
}
.hero__plate-title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 420;
  font-size: 1.2rem;
  line-height: 1;
  color: var(--cream);
}
.hero__plate-meta {
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(251,246,236,.62);
  margin-top: 0.5rem;
  line-height: 1.85;
}

/* ==========================================================================
   TRUST ROW — facts only
   ========================================================================== */
.trust {
  background: var(--espresso);
  color: var(--cream);
  padding-block: clamp(1.4rem, 2.6vw, 2rem);
  border-top: 1px solid rgba(217,139,99,.22);
}
.trust .wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1.2rem, 4vw, 3.5rem);
  flex-wrap: wrap;
}
.trust__item {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: rgba(251,246,236,.92);
}
.trust__item svg { width: 20px; height: 20px; flex: none; stroke: var(--clay-soft); }
.trust__sep { width: 5px; height: 5px; border-radius: 50%; background: rgba(217,139,99,.5); }

/* ==========================================================================
   HOW IT WORKS — 3 steps
   ========================================================================== */
.how { background: var(--paper); }
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  counter-reset: step;
}
.step {
  position: relative;
  padding-top: 2.4rem;
  border-top: 2px solid var(--line);
}
.step__num {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 5vw, 4rem);
  font-weight: 300;
  color: var(--clay);
  line-height: 0.8;
  font-style: italic;
}
.step__num::after {
  content: ""; display: block; width: 40px; height: 2px; background: var(--clay-soft); margin-top: 1rem;
}
.step h3 { font-size: var(--step-2); margin-top: 1.3rem; }
.step p { color: var(--ink-soft); margin-top: 0.8rem; font-size: var(--step-0); }
.step:nth-child(2) .step__num { color: var(--sage); }
.step:nth-child(2) .step__num::after { background: var(--sage-soft); }

.how__reassure {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding: clamp(1.6rem, 3vw, 2.4rem) clamp(1.6rem, 3.5vw, 2.8rem);
  background: var(--flax);
  border-left: 3px solid var(--clay);
  border-radius: var(--r-md);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 420;
  line-height: 1.34;
  color: var(--ink);
  max-width: 40ch;
}

/* ==========================================================================
   WINSTON STORY
   ========================================================================== */
.story { background: var(--muslin); overflow: hidden; }
.story .wrap {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.story__frame {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--espresso);
  box-shadow: var(--shadow-frame);
  border: 1px solid rgba(43,32,24,.1);
}
.story__frame::after {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 8px rgba(251,246,236,.65), inset 0 0 0 9px rgba(43,32,24,.12);
  pointer-events: none;
}
.story__frame-osd { position: absolute; inset: 0; }
.story__frame-poster {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 50% 38%, rgba(217,139,99,.4), transparent 62%),
    linear-gradient(160deg, #3a2a1c, #241b13);
}
.story__caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 1.4rem 1.5rem 1.2rem;
  background: linear-gradient(to top, rgba(28,20,13,.86), transparent);
  color: var(--cream);
  font-size: 0.9rem;
  letter-spacing: 0.02em;
}
.story h2 { font-size: var(--step-3); margin-top: 0.7rem; }
.story__body { margin-top: 1.3rem; max-width: 42ch; }
.story__body p { color: var(--ink-soft); }
.story__body p + p { margin-top: 1rem; }
.story__meta {
  margin-top: 1.8rem;
  display: flex;
  gap: 2rem;
  flex-wrap: wrap;
}
.story__stat .n { font-family: var(--font-display); font-size: var(--step-2); color: var(--clay); font-style: italic; }
.story__stat .l { font-size: 0.82rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); font-weight: 700; }
.story__link { margin-top: 1.9rem; }
.signature {
  font-family: var(--font-hand);
  font-size: 2.1rem;
  color: var(--clay);
  line-height: 1;
  margin-top: 1.6rem;
  transform: rotate(-3deg);
  display: inline-block;
}
.signature + .signature-role { display: block; font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); font-weight: 700; margin-top: 0.5rem; }

/* ==========================================================================
   LIVING PET — "For the one beside you" (sage voice)
   ========================================================================== */
.living {
  background: var(--sage);
  color: var(--cream);
  position: relative;
  overflow: hidden;
}
.living::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(80% 120% at 88% 10%, rgba(255,255,255,.1), transparent 55%);
  pointer-events: none;
}
.living .wrap { position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.living h2 { color: var(--cream); font-size: var(--step-3); margin-top: 0.7rem; }
.living p { color: rgba(251,246,236,.9); margin-top: 1.1rem; max-width: 42ch; font-size: var(--step-0); }
.living .eyebrow { color: #e6ddc9; }
.living .eyebrow::before { background: #cdd6bb; }
.living__cta { margin-top: 1.8rem; }
.living__aside {
  border: 1px solid rgba(251,246,236,.28);
  border-radius: var(--r-md);
  padding: clamp(1.6rem, 3vw, 2.4rem);
  background: rgba(43,32,24,.12);
  backdrop-filter: blur(2px);
}
.living__aside p { font-family: var(--font-display); font-size: var(--step-2); line-height: 1.32; margin-top: 0; color: var(--cream); font-weight: 420; }

/* ==========================================================================
   PRICING — gallery placards
   ========================================================================== */
.pricing { background: var(--paper); }
.pricing .section-head { max-width: 46rem; }
.price-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.1rem, 2.4vw, 1.8rem);
}
.price-card {
  position: relative;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: clamp(1.6rem, 3vw, 2.3rem);
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-card);
  transition: transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s;
}
.price-card::before {
  content: "";
  position: absolute; top: 0; left: clamp(1.6rem,3vw,2.3rem); right: clamp(1.6rem,3vw,2.3rem);
  height: 3px; background: var(--line); border-radius: 3px;
}
.price-card:hover { transform: translateY(-6px); box-shadow: 0 26px 44px -26px rgba(58,38,20,.55); }
.price-card--feature {
  background: var(--espresso);
  color: var(--cream);
  border-color: var(--espresso);
  transform: translateY(-14px);
}
.price-card--feature::before { background: var(--clay); }
.price-card--feature:hover { transform: translateY(-20px); }
.price-card__tag {
  align-self: flex-start;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--clay);
  border: 1px solid var(--clay-soft);
  border-radius: var(--r-pill);
  padding: 0.35em 0.8em;
  margin-bottom: 1.2rem;
}
.price-card--feature .price-card__tag { color: var(--cream); background: var(--clay); border-color: var(--clay); }
.price-card__spacer { height: calc(0.66rem + 1.2em + 1.2rem + 0.7em); }
.price-card h3 { font-size: var(--step-2); }
.price-card__size { font-size: 0.92rem; color: var(--ink-faint); letter-spacing: 0.02em; margin-top: 0.3rem; }
.price-card--feature .price-card__size { color: rgba(251,246,236,.7); }
.price-card__price {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 5vw, 3.2rem);
  font-weight: 380;
  margin-top: 1.3rem;
  line-height: 1;
}
.price-card__price sup { font-size: 0.42em; top: -1.2em; font-weight: 500; color: var(--clay); }
.price-card--feature .price-card__price sup { color: var(--clay-soft); }
.price-card__ship { font-size: 0.9rem; color: var(--sage); font-weight: 700; margin-top: 0.7rem; display: inline-flex; align-items: center; gap: 0.5em; }
.price-card--feature .price-card__ship { color: var(--sage-soft); }
.price-card__ship::before { content: ""; width: 15px; height: 15px; border-radius: 50%; border: 2px solid currentColor; }
/* TRANSPLANT 4 (from concept-A editions): a short "who it's for / where it lives" line per tier. */
.price-card__desc {
  margin-top: 1.1rem;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 30ch;
}
.price-card--feature .price-card__desc { color: rgba(251,246,236,.78); }
.price-card__foot { margin-top: auto; padding-top: 1.6rem; }
.price-card .btn { width: 100%; justify-content: center; }
.price-card:not(.price-card--feature) .btn { background: transparent; color: var(--ink); border: 1.5px solid var(--ink); box-shadow: none; }
.price-card:not(.price-card--feature) .btn:hover { background: var(--ink); color: var(--paper); }

.price-note {
  margin-top: clamp(1.8rem, 3.5vw, 2.6rem);
  text-align: center;
  color: var(--ink-soft);
  font-size: var(--step-0);
  max-width: 56ch;
  margin-inline: auto;
}
.price-note strong { color: var(--ink); font-weight: 700; }
/* Строка про ролик — намеренно ТИШЕ основной заметки и отделена линией: она про другой товар,
   который к выбору размера холста отношения не имеет. Если сделать её вровень с ценами, тройка
   карточек перестанет читаться как «выбери одно из трёх». */
.price-note--film {
  margin-top: 1.2rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
  font-size: var(--step--1);
  color: var(--ink-faint);
  max-width: 52ch;
}
/* Контакт — ещё тише строки про ролик и БЕЗ разделительной линии: вторая линия подряд разрезала бы
   низ блока цен на полоски. Это не отдельный товар и не новая мысль, а приглашение спросить, если
   человек застрял на выборе, — поэтому оно просто прижато к предыдущей строке. */
.price-note--contact {
  margin-top: 0.9rem;
  font-size: var(--step--1);
  color: var(--ink-faint);
  max-width: 52ch;
}

/* ==========================================================================
   GIVING — dark studio wall
   ========================================================================== */
.giving { background: var(--espresso); color: var(--cream); position: relative; overflow: hidden; }
.giving::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(70% 90% at 15% 20%, rgba(179,84,46,.18), transparent 55%);
}
.giving .wrap { position: relative; text-align: center; max-width: 52rem; }
.giving h2 {
  color: var(--cream);
  font-size: var(--step-3);
  margin-top: 1rem;
  font-weight: 400;
}
.giving h2 .hl { color: var(--clay-soft); font-style: italic; }
.giving p { color: rgba(251,246,236,.82); margin-top: 1.4rem; font-size: var(--step-1); max-width: 46ch; margin-inline: auto; line-height: 1.55; }
.giving__line { margin-top: 2rem; }
.giving__line .link-underline { color: var(--clay-soft); border-color: rgba(217,139,99,.55); }
.giving__line .link-underline:hover { color: var(--cream); border-color: var(--clay-soft); }

/* ==========================================================================
   GIFT — sympathy gift (between giving and FAQ)
   TRANSPLANT 3 (from concept-B gift): its own DARK espresso band, visually setting the
   tender "the buyer is not the owner, someone is grieving" scenario apart from the paper
   flow. Palette is C's native espresso (a sibling of the giving/final espresso sections),
   so it stays inside C's language — no franken-mix. Form-card = a lifted translucent panel
   on the dark wall (echo of B's on-dark gift form), inputs dark, C clay CTA.
   ========================================================================== */
.gift { background: var(--espresso); color: var(--cream); position: relative; overflow: hidden; }
.gift::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(90% 120% at 85% 12%, rgba(179,84,46,.22), transparent 55%);
  pointer-events: none;
}
.gift__grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center;
}
.gift h2 { color: var(--cream); font-size: var(--step-3); margin-top: 0.7rem; max-width: 15ch; font-weight: 400; }
.gift h2 em { font-style: italic; color: var(--clay-soft); }
.gift__copy p { color: rgba(251,246,236,.82); margin-top: 1.2rem; max-width: 42ch; font-size: var(--step-0); }
.gift__copy p em { color: var(--clay-soft); font-style: italic; }
.gift__form-card {
  background: var(--espresso-2);
  border: 1px solid rgba(251,246,236,.16);
  border-radius: var(--r-lg);
  padding: clamp(1.7rem, 3.2vw, 2.6rem);
  box-shadow: 0 22px 44px -30px rgba(0,0,0,.7);
}
.gift__form-card h3 { color: var(--cream); font-size: var(--step-1); }
.gift__form-card > p { font-size: 0.95rem; color: rgba(251,246,236,.6); margin-top: 0.6rem; }
.gift-form { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 0.9rem; }
.gift-form label { font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; color: rgba(251,246,236,.6); }
.gift-form input {
  font-family: var(--font-body);
  font-size: var(--step-0);
  padding: 0.9em 1.1em;
  border: 1.5px solid rgba(251,246,236,.22);
  border-radius: var(--r-md);
  background: rgba(251,246,236,.06);
  color: var(--cream);
  transition: border-color .2s, box-shadow .2s, background-color .2s;
  width: 100%;
}
.gift-form input::placeholder { color: rgba(251,246,236,.4); }
.gift-form input:focus { outline: none; border-color: var(--clay-soft); background: rgba(251,246,236,.1); box-shadow: 0 0 0 3px rgba(217,139,99,.16); }
.gift-form .btn { justify-content: center; margin-top: 0.4rem; }
.gift-form__note { font-size: 0.82rem; color: rgba(251,246,236,.5); text-align: center; margin-top: 0.2rem; }

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq { background: var(--paper); }
.faq .wrap { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.faq__aside { position: sticky; top: 2.5rem; }
.faq__aside h2 { font-size: var(--step-3); margin-top: 0.7rem; }
.faq__aside p { color: var(--ink-soft); margin-top: 1.1rem; max-width: 32ch; }
.faq-list { display: flex; flex-direction: column; }
.faq-item { border-top: 1px solid var(--line); }
.faq-item:last-child { border-bottom: 1px solid var(--line); }
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 1.4rem 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 460;
  color: var(--ink);
  transition: color .2s;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--clay); }
.faq-item__icon {
  flex: none;
  width: 28px; height: 28px;
  border: 1.5px solid var(--clay);
  border-radius: 50%;
  position: relative;
  margin-top: 0.15em;
  transition: transform .3s, background-color .3s;
}
.faq-item__icon::before, .faq-item__icon::after {
  content: ""; position: absolute; background: var(--clay);
  top: 50%; left: 50%; transform: translate(-50%,-50%);
}
.faq-item__icon::before { width: 11px; height: 1.5px; }
.faq-item__icon::after { width: 1.5px; height: 11px; transition: transform .3s; }
.faq-item[open] .faq-item__icon { background: var(--clay); }
.faq-item[open] .faq-item__icon::before,
.faq-item[open] .faq-item__icon::after { background: var(--cream); }
.faq-item[open] .faq-item__icon::after { transform: translate(-50%,-50%) scaleY(0); }
.faq-item__body {
  padding-bottom: 1.5rem;
  color: var(--ink-soft);
  max-width: 58ch;
  animation: faqOpen .35s ease;
}
.faq-item__body strong { color: var(--ink); }
@keyframes faqOpen { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* ==========================================================================
   FINAL CTA
   ========================================================================== */
.final { background: var(--espresso); color: var(--cream); text-align: center; overflow: hidden; position: relative; }
.final::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 80% at 50% 120%, rgba(179,84,46,.25), transparent 60%);
}
.final .wrap { position: relative; max-width: 46rem; }
.final h2 {
  color: var(--cream);
  font-size: var(--step-4);
  font-weight: 400;
  letter-spacing: -0.02em;
}
.final h2 em { font-style: italic; color: var(--clay-soft); }
.final p { color: rgba(251,246,236,.82); font-size: var(--step-1); margin-top: 1.3rem; max-width: 40ch; margin-inline: auto; }
.final__cta { margin-top: 2.3rem; display: flex; gap: 1.2rem; justify-content: center; flex-wrap: wrap; }
.final__note { margin-top: 1.6rem; font-size: 0.95rem; color: rgba(251,246,236,.7); }
/* Ссылка на вьюер под финальным призывом (T4-в). Секция тёмная, поэтому свой цвет: обычный
   `link-underline` рассчитан на светлый фон и здесь был бы почти невидим. Намеренно ТИШЕ кнопок —
   это выход для сомневающегося, а не второй призыв. */
.final__more { margin-top: 1.1rem; font-size: 0.92rem; }
.final__more a {
  color: rgba(251,246,236,.72);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(251,246,236,.35);
}
.final__more a:hover { color: var(--cream); text-decoration-color: var(--cream); }
/* Кнопка «поделиться» выглядит как ссылка намеренно: на этой странице должна оставаться одна
   кнопка-действие — «Begin a portrait». Но это <button>, а не <a>, потому что переход никуда не
   происходит: открывается системное меню или копируется адрес. */
.final__more .js-share {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: rgba(251,246,236,.72);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(251,246,236,.35);
}
.final__more .js-share:hover { color: var(--cream); text-decoration-color: var(--cream); }

/* ==========================================================================
   FOOTER
   ========================================================================== */
.site-footer { background: #211a13; color: rgba(251,246,236,.7); padding-block: clamp(3rem, 6vw, 4.5rem) 2.5rem; }
.site-footer .wrap { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 2.5rem; }
.site-footer .brand { color: var(--cream); }
.site-footer__about { margin-top: 1.2rem; font-size: 0.92rem; max-width: 34ch; line-height: 1.6; }
.footer-col h4 { font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--clay-soft); font-family: var(--font-body); font-weight: 700; }
.footer-col ul { list-style: none; padding: 0; margin: 1.1rem 0 0; display: flex; flex-direction: column; gap: 0.7rem; }
.footer-col a { text-decoration: none; font-size: 0.95rem; opacity: 0.82; transition: opacity .2s, color .2s; }
.footer-col a:hover { opacity: 1; color: var(--clay-soft); }
.footer-bottom {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.6rem;
  border-top: 1px solid rgba(251,246,236,.12);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font-size: 0.82rem; opacity: 0.65;
}

/* ==========================================================================
   REVEAL ANIMATION (page load / scroll)
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .8s cubic-bezier(.2,.8,.2,1), transform .8s cubic-bezier(.2,.8,.2,1); }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-d="1"] { transition-delay: .08s; }
.reveal[data-d="2"] { transition-delay: .16s; }
.reveal[data-d="3"] { transition-delay: .24s; }
.hero__inner .reveal { opacity: 0; transform: translateY(26px); animation: heroRise .95s cubic-bezier(.2,.8,.2,1) forwards; }
.hero__inner .reveal[data-d="1"] { animation-delay: .15s; }
.hero__inner .reveal[data-d="2"] { animation-delay: .35s; }
.hero__inner .reveal[data-d="3"] { animation-delay: .55s; }
.hero__inner .reveal[data-d="4"] { animation-delay: .75s; }
@keyframes heroRise { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001s !important; transition-duration: .001s !important; }
  .hero__poster { animation: none; }
  .reveal { opacity: 1; transform: none; }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 960px) {
  .steps { grid-template-columns: 1fr; gap: 2rem; }
  .story .wrap, .living .wrap, .gift__grid, .faq .wrap { grid-template-columns: 1fr; }
  .faq__aside { position: static; }
  .story__frame { max-width: 460px; }
  .price-grid { grid-template-columns: 1fr; max-width: 460px; margin-inline: auto; }
  .price-card--feature { transform: none; order: -1; }
  .price-card--feature:hover { transform: translateY(-6px); }
  .price-card__spacer { display: none; }
  .site-footer .wrap { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 720px) {
  .nav__links { display: none; }
  .nav__links.open {
    display: flex; flex-direction: column; align-items: flex-start;
    position: absolute; top: calc(100% + 0.6rem); right: var(--gutter); left: var(--gutter);
    background: var(--espresso-2); padding: 1.4rem; border-radius: var(--r-md);
    box-shadow: var(--shadow-card); gap: 1.1rem;
  }
  /* Здесь «Contact» появляется — и только здесь. `display: block`, а не `flex`: пункты
     выпадающего меню стоят колонкой, и остальные ссылки в нём — обычные строчные элементы. */
  .nav__mobile-only { display: block; }
  .nav-toggle {
    display: inline-flex; flex-direction: column; gap: 4px; background: none; border: 0; cursor: pointer; padding: 6px;
  }
  .nav-toggle span { width: 24px; height: 2px; background: var(--cream); display: block; transition: transform .3s, opacity .3s; }
  .hero__hint { display: none; }
  .hero__plate { display: none; }
  .hero h1 { max-width: 100%; }
  .trust .wrap { flex-direction: column; gap: 1rem; }
  .trust__sep { display: none; }
  .site-footer .wrap { grid-template-columns: 1fr; }
  .final__cta { flex-direction: column; align-items: center; }
  .hero__cta { flex-direction: column; align-items: flex-start; }
}


/* ==========================================================================
   PORTRAIT STRIP — "Your portraits", shown on /order AND on /p.
   Moved here from assets/order.css on 07.08 when the strip gained a second home: a component
   used by two pages cannot keep its styles inside one page's stylesheet. Markup differs by
   page (the wizard's rows can switch and resume; the preview page only points), the look does
   not — that is exactly what belongs in the shared sheet.
   ========================================================================== */
.portraits { margin: 0 0 1.4rem; }
/* A quiet caption, not a page heading: it names the strip for the person who has one portrait in
   it and would otherwise wonder what the box is. */
.portraits__h {
  margin: 0 0 .5rem; font-family: var(--font-body, inherit);
  font-size: .8rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-faint);
}
.portraits__list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.portraits__row { border-bottom: 1px solid var(--line); background: var(--cream); }
.portraits__row:last-child { border-bottom: 0; }

/* ⚠️ COLUMNS THAT LINE UP ACROSS ROWS (owner, live run 08.08). This was flex, so every row laid
   itself out from its own content: on the active row the "you're here" chip pushed the meta to the
   right, and the two rows started their second column at different places. A list whose columns do
   not line up does not read as a list — which is the SAME complaint as 07.08 ("the top row looks
   like a heading"), only its remaining half.

   Fixed widths for the first two columns are what makes this work: the row and the <a> inside it
   are two SEPARATE grids (the link has to be the click target, so it cannot be a grid item spread
   across the row), and only identical, content-independent templates put their cells at the same x.
   Column assignment is explicit, so a missing cell — no chip on an inactive row, no "Open" on the
   active one — leaves a gap instead of shifting everything left. */
.portraits { --pcols: minmax(6rem, 10rem) 6.6rem minmax(0, 1fr) auto; }

.portraits__row,
.portraits__link {
  display: grid; grid-template-columns: var(--pcols);
  align-items: center; gap: .25rem .6rem;
}
.portraits__link {
  grid-column: 1 / -1;                       /* the link owns the whole row and re-grids inside it */
  padding: .85rem 1rem; min-height: 44px;
  text-decoration: none; color: inherit;
}
.portraits__link:hover { background: var(--muslin); }
/* The row that opens the started-but-empty portrait is a <button> (a POST, not a link — see
   order.php), so it has to be stripped back to looking like the rows around it. */
.portraits__link--btn { width: 100%; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; }
.portraits__row--new .link-underline { grid-column: 1 / -1; }

.portraits__pet  { grid-column: 1; font-family: var(--font-display); font-size: 1.02rem; color: var(--ink);
                   min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portraits__here { grid-column: 2; }
.portraits__meta { grid-column: 3; font-size: .88rem; color: var(--ink-faint); }
.portraits__open { grid-column: 4; justify-self: end; font-size: .88rem; color: var(--clay); border-bottom: 1px solid currentColor; }
/* Cells that sit directly in the row (the active one has no link) carry the row's own padding. */
.portraits__row > .portraits__pet  { padding: .85rem 0 .85rem 1rem; }
.portraits__row > .portraits__here { margin-block: .85rem; }
.portraits__row > .portraits__meta { padding-block: .85rem; }
.portraits__row > .portraits__open { padding: .85rem 1rem .85rem 0; }

/* ⚠️ ONE MARKER, NOT THREE (owner, live run 07.08). The active row used to differ from the others
   in three ways at once — tinted background, clay edge on the left, and no "Open" on the right —
   and three differences stop reading as "a row in a special state" and start reading as "an element
   of a different kind". Owner said exactly that: the top row looked like a HEADING and the one
   below it like the first entry, so a two-row list did not read as a list at all.
   Now the state is carried by one thing: a chip beside the name. It stays beside the name (plan
   item 6 — at the far edge it was the least-seen thing on the row), but it is a chip rather than
   loose uppercase text, because with the tint gone it has to carry the signal alone.
   Colours are literal rgba, not color-mix: this must not fall back to invisible on an old engine. */
.portraits__here {
  align-self: center;
  margin: 0 0 0 .1rem;
  padding: .2rem .5rem;
  border: 1px solid rgba(179, 84, 46, .45);
  border-radius: var(--r-pill);
  background: rgba(179, 84, 46, .10);
  font-size: .7rem; line-height: 1.5; letter-spacing: .06em; text-transform: uppercase;
  color: var(--clay);
  white-space: nowrap;
}
.portraits__row.is-active { background: var(--cream); box-shadow: none; }
.portraits__row.is-active .portraits__pet { font-weight: 600; padding-left: 1rem; }

.portraits__row--new { background: transparent; }
.portraits__row--new .link-underline { padding: .85rem 1rem; display: block; width: 100%; text-align: left; background: none; border: 0; font: inherit; color: var(--clay); cursor: pointer; }

@media (max-width: 520px) {
  /* Two columns on a phone: the name and its marker on the first line, the meta beneath them.
     The chip and "Open" never appear on the same row (the row you are standing in has nothing to
     open), so they can share the second column without ever colliding. */
  .portraits { --pcols: minmax(0, 1fr) auto; }
  .portraits__meta { grid-column: 1 / -1; }
  .portraits__open { grid-column: 2; }
  .portraits__row > .portraits__pet  { padding-bottom: .25rem; }
  .portraits__row > .portraits__meta { padding-top: 0; padding-left: 1rem; }
  .portraits__row > .portraits__here { margin-block: .85rem 0; }

  /* D11 (owner 28.08, from his phone): "You are here тоже накладывается на край блока". True — on a
     phone the chip lands in the right-hand column, and only the NAME and the OPEN cells carried the
     row's side padding, so the chip sat flush against the border. The padding belongs to the row's
     edge, not to whichever element happens to be there. */
  .portraits__row > .portraits__here { margin-right: 1rem; }

  /* …and "See its page" was orphaned on a line of its own, pushed to the right by a margin-left:auto
     meant for a flex row. It belongs beside the state it describes: on the same line as the meta,
     at the left, where the eye already is after reading "sent Aug 27 — going to print". */
  .portraits__open--here { grid-column: 1 / -1; justify-self: start; margin-left: 1rem; }
}

/* D11, second half: the link carried TWO underlines — the base rule draws a border under the whole
   cell, the modifier adds text-decoration under the words. On a wide cell the two do not line up,
   which is the "полоска какая-то под этой надписью" from the screenshot. The modifier keeps the one
   that follows the text. */
.portraits__open--here { border-bottom: 0; }

/* Quiet way out of the rows: for a portrait this browser does not know about (another device, or
   a different email). Not a call to action — the people who need it are looking for it. */
.portraits__more { margin: .55rem 0 0; font-size: .86rem; color: var(--ink-faint); }

/* ПАРА «ИЗДАЛЕКА / ВБЛИЗИ» перед вопросами (29.08.2026).
   Две картинки РОВНО одного размера и без зазора-разделителя между подписями: сравнение работает
   только если глаз не тратит время на выяснение, что с чем сравнивают. На телефоне они встают
   друг под друга — и это правильный порядок, «целиком» сверху: сначала узнавание, потом деталь. */
.proof { background: var(--paper); padding-block: clamp(2.6rem, 6vw, 4.4rem); }
.proof h2 { margin: .3rem 0 1.6rem; max-width: 22ch; }
.proof__pair {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(.8rem, 2vw, 1.4rem);
}
@media (max-width: 720px) { .proof__pair { grid-template-columns: 1fr; } }
.proof__fig { margin: 0; }
.proof__fig img {
  display: block; width: 100%; height: auto;
  border-radius: var(--r-md); border: 1px solid var(--line);
}
.proof__fig figcaption {
  margin-top: .55rem; font-size: .88rem; color: var(--ink-soft);
}
.proof__note { margin: 1.1rem 0 0; font-size: .86rem; color: var(--ink-faint); max-width: 62ch; }

/* --------------------------------------------------------------------------
   FAMILY WORDS (.words) — the family's own line about their animal.
   Used on /winston for Anne Marie's words, spoken 31.08.2026. Deliberately the
   QUIETEST section of the page: it is the last thing read before the footer and
   must not compete with the portrait. Paper ground (no card, no dark band), one
   hairline rule, display italic. Nothing here is Winston-specific — a second
   origin story would reuse the same block.
   -------------------------------------------------------------------------- */
.words { background: var(--paper); }
.words .wrap { max-width: 46rem; text-align: center; }
.words__rule {
  width: 3.5rem; height: 1px;
  margin: 0 auto clamp(1.6rem, 3vw, 2.2rem);
  background: var(--clay-soft);
}
.words blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--step-2);
  line-height: 1.35;
  color: var(--ink);
  text-wrap: balance;
}
.words__by {
  margin: clamp(1.2rem, 2.5vw, 1.7rem) 0 0;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.words__by span { display: block; margin-top: .4rem; letter-spacing: .1em; font-weight: 400; text-transform: none; }

/* ==========================================================================
   SEE IT HAPPEN — слайдер «фотография / мозаика» + зацикленный ролик (02.09.2026, D15)
   ==========================================================================
   Шторка сделана ДВУМЯ полными картинками друг над другом, верхняя обрезается clip-path'ом.
   Ни одна не масштабируется независимо, поэтому выравнивание, подобранное по зрачкам, не может
   разъехаться от ширины экрана. Без JS видна нижняя целиком — блок не пустеет.
   Ручка — настоящий input[type=range] с нулевой непрозрачностью поверх кадра: клавиатура, палец и
   скринридер достаются даром, а своя реализация того же — три известных бага. */
.see { padding: clamp(3.5rem, 7vw, 6rem) 0; background: var(--paper); }
.see__lede { max-width: 54ch; margin: 0.9rem auto 0; color: var(--ink-soft); }
.ba { max-width: 900px; margin: clamp(1.8rem, 4vw, 3rem) auto 0; }
.ba__stage {
  position: relative;
  aspect-ratio: 3 / 2;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--espresso);
  box-shadow: var(--shadow-frame);
  touch-action: pan-y;            /* вертикальная прокрутка страницы пальцем не должна ломаться */
}
.ba__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ba__img--over { clip-path: inset(0 calc(100% - var(--ba, 50%)) 0 0); }
.ba__tag {
  position: absolute; bottom: 0.9rem; z-index: 3;
  padding: 0.35rem 0.7rem; border-radius: 999px;
  font-size: 0.78rem; letter-spacing: .02em;
  background: rgba(28,20,13,.62); color: var(--cream);
  backdrop-filter: blur(3px); pointer-events: none;
}
.ba__tag--l { left: 0.9rem; }
.ba__tag--r { right: 0.9rem; }
/* Прозрачный поверх кадра: он и есть управление, поэтому занимает весь кадр. */
.ba__range {
  position: absolute; inset: 0; z-index: 4;
  width: 100%; height: 100%; margin: 0; padding: 0;
  opacity: 0; cursor: ew-resize;
  -webkit-appearance: none; appearance: none; background: transparent;
}
.ba__range::-webkit-slider-thumb { -webkit-appearance: none; width: 44px; height: 100%; }
.ba__range::-moz-range-thumb { width: 44px; height: 100%; border: 0; background: transparent; }
.ba__range:focus-visible + .ba__handle .ba__grip { outline: 3px solid var(--clay); outline-offset: 3px; }
.ba__handle {
  position: absolute; top: 0; bottom: 0; z-index: 5;
  left: var(--ba, 50%); transform: translateX(-50%);
  width: 2px; background: rgba(251,246,236,.9);
  box-shadow: 0 0 0 1px rgba(28,20,13,.25);
  pointer-events: none;
}
.ba__grip {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--cream); box-shadow: var(--shadow-card);
}
/* Две стрелки внутри кружка — рисуются рамками, без единого лишнего запроса. */
.ba__grip::before, .ba__grip::after {
  content: ""; position: absolute; top: 50%; width: 0; height: 0;
  border-top: 6px solid transparent; border-bottom: 6px solid transparent;
  transform: translateY(-50%);
}
.ba__grip::before { left: 11px; border-right: 7px solid var(--clay); }
.ba__grip::after  { right: 11px; border-left: 7px solid var(--clay); }
.ba__hint { margin-top: 0.8rem; text-align: center; font-size: 0.86rem; color: var(--ink-soft); }

.see__film { max-width: 900px; margin: clamp(2.5rem, 5vw, 4rem) auto 0; text-align: center; }
.see__film-h { margin: 0 0 0.4rem; }
.see__film-b { margin: 0 0 1.2rem; color: var(--ink-soft); }
.see__video {
  display: block; width: 100%; height: auto;
  border-radius: var(--r-md); box-shadow: var(--shadow-frame); background: var(--espresso);
}
/* Ссылка на полный ролик. Существует ОТДЕЛЬНО от клика по кадру намеренно: клик по кадру site.js
   отключает, когда у видео появились контролы, а этот путь работает всегда — в том числе с
   клавиатуры и для читалок экрана, которым кликабельный <video> ни о чём не говорит. */
.see__film-more { margin: 0.9rem 0 0; font-size: var(--step--1); }

/* --- Слайдер: управление пальцем (03.09.2026, партия из Telegram) ------------------------------
   Три строки, каждая закрывает свой симптом с iPhone:
   `touch-action: pan-y`  — вертикаль остаётся браузеру (страница прокручивается), горизонталь наша
                            (иначе резкий свайп уходит в системный жест переключения приложений);
   `user-select: none`    — долгое нажатие больше не начинает выделять «текст под картинкой»;
   `-webkit-touch-callout`— и не показывает лупу/меню iOS поверх кадра. */
.ba__stage {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  cursor: ew-resize;
}
.ba__img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
/* Ползунок остаётся для клавиатуры и скринридера, но больше НЕ лежит поверх кадра: именно он и
   ломал перетаскивание пальцем (тянулся только невидимый бегунок шириной 44 px). */
.ba__range {
  position: absolute; width: 1px; height: 1px; inset: auto auto 0 0;
  opacity: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  cursor: default;
}
.ba__range:focus-visible { clip: auto; clip-path: none; width: 100%; height: 6px; opacity: 1;
  inset: auto 0 -14px 0; accent-color: var(--clay); }

/* Кнопки управления вьюером (OpenSeadragon).
   ⚠️ НЕ ПОДНИМАТЬ z-index у САМОГО контейнера вьюера — первая редакция этой правки (03.09) так и
   сделала, и подпись «Winston — a golden retriever from California» ушла под холст: она лежит в
   рамке отдельным слоем. Кнопки OSD рисуются поверх холста сами; трогать надо только подпись —
   поднять её и увести текст от угла с кнопками, оставив клики кнопкам (pointer-events: none). */
#hero-osd .openseadragon-container img,
#story-osd .openseadragon-container img { width: 30px; height: 30px; }
.story__caption { z-index: 7; pointer-events: none; }

/* --- Кнопки управления вьюером на страницах сайта (03.09.2026) ---------------------------------
   Вид скопирован с эталонной страницы `petmosaic.php` (.pm__btn) по прямому требованию владельца:
   «на других страницах ты используешь кнопки другие, а я бы хотел, чтобы они были именно такие».
   Классы СВОИ (`osdctl`), а не общие с эталоном: у той страницы свой файл стилей и своя жизнь,
   и связывать их одним селектором значило бы, что правка вида одной молча меняет другую. */
.osdctl {
  position: absolute; right: 14px; bottom: 14px; z-index: 6;
  display: flex; gap: 10px; align-items: center;
}
#story-osd .osdctl { top: 14px; bottom: auto; }   /* внизу рамки истории живёт подпись */
.osdctl__btn {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  border: 1px solid rgba(251,246,236,.22);
  border-radius: 50%;
  background: rgba(42,33,25,.62);
  color: var(--cream);
  cursor: pointer; padding: 0;
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  backdrop-filter: blur(12px) saturate(1.2);
  box-shadow: 0 12px 26px -16px rgba(0,0,0,.7);
  transition: background-color .2s, transform .2s, border-color .2s;
}
@supports (background: color-mix(in srgb, red, blue)) {
  .osdctl__btn { background: color-mix(in srgb, var(--espresso) 46%, transparent); }
}
.osdctl__btn:hover { background: var(--clay); border-color: var(--clay); transform: translateY(-2px); }
.osdctl__btn:active { transform: translateY(0); }
.osdctl__btn:focus-visible { outline: 2px solid var(--clay-soft); outline-offset: 2px; }
.osdctl__btn svg {
  width: 19px; height: 19px; display: block;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* 🔴 РАЗМЕР КНОПОК НА ТЕЛЕФОНЕ — ПО ПАЛЬЦУ, А НЕ ПО МАКЕТУ (владелец, 09.09.2026, на своём
   iPhone: «очень маленькие, крохотные, буквально миллиметров по 7… человеку с большими пальцами
   очень тяжело будет нажимать»). Было 38 px ≈ 6,7 мм — это меньше и общепринятого минимума
   касания (44 pt), и нашей же планки 44 px у кнопок мастера заказа. Стало 56 px ≈ 10 мм.
   ⚠️ Промежуток увеличен ВМЕСТЕ с кнопками, и это не косметика: четыре круга по 56 px с прежним
   зазором 8 px читаются как одна полоса, и палец мажет по соседней — то есть кнопки стали бы
   больше, а попадать в них было бы не легче. */
@media (max-width: 720px) {
  .osdctl { gap: 14px; right: 12px; bottom: 12px; }
  .osdctl__btn { width: 56px; height: 56px; }
  .osdctl__btn svg { width: 26px; height: 26px; }

  /* 🔴 ПЛАШКА ПОДНЯТА НА ДВЕ СВОИ ВЫСОТЫ (владелец, 09.09.2026, вариант A).
     Зачем: на телефоне кадр героя шире, чем на десктопе, морда Винстона влезает целиком — и
     глаза приходятся ровно на плашку. «Глаза должны быть чистыми».
     ⚠️ Сдвиг сделан ОТСТУПАМИ, а не `transform`: плашка появляется анимацией `heroRise`, которая
     заканчивается на `transform: none` и любой наш transform молча стёрла бы.
     ⚠️ Отрицательный отступ у плашки тянет за собой ВЕСЬ блок, поэтому ровно столько же
     возвращается заголовку — иначе вверх уехали бы и заголовок, и текст, и кнопка.
     🔴 ЕДИНИЦА — rem, А НЕ em, И ЭТО НЕ ПЕДАНТИЗМ. `em` считается от кегля САМОГО элемента:
     у плашки это ~14 px, у заголовка ~44 px. Написав обоим «4.8em», я поднял плашку на 67 px и
     опустил заголовок на 211 px — текст уехал за нижний край экрана. Компенсация обязана быть
     тем же ЧИСЛОМ ПИКСЕЛЕЙ, значит единица должна быть общей.
     Высота плашки ≈ 2.4 × 14 px ≈ 34 px; две высоты ≈ 68 px ≈ 4.2rem. */
  .hero__offer { margin-top: -4.2rem; }
  .hero h1 { margin-top: calc(1.1rem + 4.2rem); }
}
/* 🔴 В ПОЛНОМ ЭКРАНЕ ПАНЕЛЬ СТОИТ СВЕРХУ, И ЭТО НЕ ВКУСОВЩИНА (владелец, 09.09.2026, вторая
   проверка на iPhone): «все кнопки оказались снизу, хотя раньше они были сверху… поверх этих
   кнопок наезжает айфоновская плашка с URL, и я эти кнопки теперь не вижу».
   Причина, по которой они уехали вниз: панель переносится ВНУТРЬ элемента вьюера, и правило
   `#story-osd .osdctl { top: 14px }` перестаёт совпадать — остаётся общее `bottom: 14px`.
   Низ экрана на телефоне занят браузером (адресная строка Safari, панель Телеграма), и любые
   наши кнопки там будут перекрыты. Верх свободен. Отступ — от безопасной зоны, иначе на iPhone
   панель лезет под «чёлку». */
.osdctl--full {
  right: calc(14px + env(safe-area-inset-right, 0px));
  top: calc(14px + env(safe-area-inset-top, 0px));
  bottom: auto;
}
#story-osd .osdctl--full,
#hero-osd  .osdctl--full { top: calc(14px + env(safe-area-inset-top, 0px)); bottom: auto; }

/* --------------------------------------------------------------------------
   WHERE HE IS NOW (.wherenow) — жизнь портрета ПОСЛЕ нас: снимок передачи в
   UC Davis плюс их собственная утверждённая фраза. Две колонки на широком
   экране, стопка на телефоне. Фотография — настоящий репортажный кадр, а не
   наша работа, поэтому она в лёгкой рамке и с подписью, а не подана как
   произведение. Секция стоит между .story (muslin) и .living (sage), поэтому
   фон — paper: три соседние секции не повторяют цвет.
   -------------------------------------------------------------------------- */
.wherenow { background: var(--paper); }
.wherenow .wrap {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(1.6rem, 4vw, 3.4rem);
  align-items: center;
  max-width: 68rem;
}
@media (max-width: 820px) { .wherenow .wrap { grid-template-columns: 1fr; } }
.wherenow__fig { margin: 0; }
.wherenow__fig img {
  display: block; width: 100%; height: auto;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-frame);
}
.wherenow__fig figcaption {
  margin-top: .75rem;
  font-size: .84rem; line-height: 1.5;
  color: var(--ink-faint);
}
.wherenow h2 { font-size: var(--step-2); margin-top: .7rem; }
.wherenow__body { margin-top: 1.1rem; color: var(--ink-soft); max-width: 48ch; }
