/* ============================================================================
   КО-КО — Дизайн-система птахофабрики
   ----------------------------------------------------------------------------
   Шар 1  Foundations  — примітивні токени (палітра, шрифти, простір, радіуси…)
   Шар 2  Semantic     — семантичні аліаси (що для чого)
   Шар 3  Base         — reset + типографічні дефолти
   Шар 4  Components   — .btn, .card, .medallion, .site-header, .hero…
   Шар 5  Utilities    — мінімальний набір хелперів
   ============================================================================ */

/* ==========================================================================
   ШАР 1 — FOUNDATIONS
   ========================================================================== */

:root {
  color-scheme: light;

  /* ——— Базова палітра ——————————————————————————————————————————————— */
  --coco-blue-700: #0f4a7d;
  --coco-blue-600: #14649f;
  --coco-blue-500: #1f7fbe;   /* синій фотографії, посилання */
  --coco-blue-300: #7bb8dd;
  --coco-blue-100: #e3f0f8;

  --coco-yolk-700: #8a5d00;   /* жовток як текст: 5.2:1 на yolk-100 */
  --coco-yolk-600: #c98d00;
  --coco-yolk-500: #f0a800;   /* жовток — акцент прайсів і рейтингу */
  --coco-yolk-400: #ffbe1f;
  --coco-yolk-100: #fff3d6;

  --coco-grass-700: #2f5c18;
  --coco-grass-600: #3d7521;
  --coco-grass-550: #458325;  /* hover для кнопок: 4.6:1 з білим */
  --coco-grass-500: #4f9429;  /* фірмовий зелений: бренд і декор */
  --coco-grass-400: #5aa62f;
  --coco-grass-300: #a5cf85;
  --coco-grass-100: #ecf5e4;
  --coco-grass-050: #f6f8f4;  /* м’яка підкладка карток «Чому ми» */

  --coco-clay-500: #b8552b;   /* теплий вторинний акцент (брудер) */
  --coco-alert-500: #c0392b;
  --coco-alert-100: #f7eceb;  /* підкладка «немає в наявності» та помилок */

  --coco-ink-900: #111111;
  --coco-ink-850: #1f2b1c;    /* заголовки: чорнило з зеленим підтоном */
  --coco-ink-800: #1f1d1b;
  --coco-ink-700: #3a3733;
  --coco-ink-500: #6f6a63;
  --coco-ink-400: #8a857c;

  --coco-line-450: #879080;  /* межа контролів: 3.3:1 з білим, 3.1:1 з --surface-soft */
  --coco-line-300: #d8ddd4;
  --coco-line-250: #e4e7e1;
  --coco-line-200: #eef0ec;
  --coco-line-150: #dfe4da;

  --coco-shell-100: #f6f4ef;  /* тепла шкаралупа */
  --coco-white: #ffffff;

  /* ——— Шрифти ——————————————————————————————————————————————————————— */
  --font-display: "Oswald", "PT Sans Narrow", "Arial Narrow", sans-serif;
  --font-body: "PT Sans", "Segoe UI", Tahoma, sans-serif;
  --font-narrow: "PT Sans Narrow", "PT Sans", sans-serif;
  --font-mono: "Roboto Mono", "Consolas", monospace;

  /* ——— Scale ——————————————————————————————————————————————————————— */
  /* One design pixel. Sizes are written as a count of these, so the page grows
     as one piece — type, photos, gaps, radii, shadows — the way browser zoom
     would. It is exactly 1px up to a 1180px viewport, so tablets and phones are
     untouched (which is why rules inside the max-width queries keep raw px),
     then tracks the viewport and settles at 1.5px from 1770px on, where the
     container stops growing too. 1770 is the 1180px column the page was drawn
     for, times 1.5: tie the cap to anything else and the layout squeezes or
     sprawls relative to its type (at 1600 the header no longer fits one row).
     Hairlines, focus rings and breakpoints stay in
     real px: a line should stay crisp, and a breakpoint is a fact about the
     viewport, not a design size. */
  --px: clamp(1px, 100vw * 1.5 / 1770, 1.5px);

  /* Розміри: fluid там, де це заголовки блоків */
  --fs-display: clamp(40 * var(--px), 4.4vw, 70 * var(--px));
  --fs-hero: clamp(40 * var(--px), 4.4vw, 70 * var(--px));
  --fs-h1: clamp(32 * var(--px), 3.2vw, 48 * var(--px));
  --fs-h2: calc(26 * var(--px));
  --fs-h3: calc(22 * var(--px));
  --fs-h4: calc(19 * var(--px));
  --fs-h5: calc(17 * var(--px));
  --fs-body-lg: calc(18 * var(--px));
  --fs-body: calc(16 * var(--px));
  --fs-sm: calc(14 * var(--px));
  --fs-xs: calc(13 * var(--px));
  --fs-2xs: calc(11 * var(--px));
  --fs-nav: calc(12 * var(--px));
  --fs-price: calc(26 * var(--px));
  --fs-phone: calc(17 * var(--px));

  --lh-tight: 1.05;
  --lh-heading: 1.2;
  --lh-body: 1.6;
  --lh-loose: 1.75;

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-bold: 700;

  --ls-tight: -0.01em;
  --ls-heading: 0.02em;
  --ls-caps: 0.08em;
  --ls-caps-wide: 0.1em;
  --ls-button: 0.07em;

  /* Композитні типографічні токени */
  --text-display: var(--fw-bold) var(--fs-display)/var(--lh-tight) var(--font-display);
  --text-h1: var(--fw-bold) var(--fs-h1)/1.1 var(--font-display);
  --text-h2: var(--fw-bold) var(--fs-h2)/var(--lh-heading) var(--font-display);
  --text-h3: var(--fw-bold) var(--fs-h3)/1.15 var(--font-display);
  --text-h4: var(--fw-bold) var(--fs-h4)/var(--lh-heading) var(--font-display);
  --text-lead: var(--fw-regular) var(--fs-body-lg)/var(--lh-loose) var(--font-body);
  --text-default: var(--fw-regular) var(--fs-body)/var(--lh-body) var(--font-body);
  --text-caption: var(--fw-regular) var(--fs-sm)/1.65 var(--font-body);
  --text-button: var(--fw-bold) var(--fs-nav)/1 var(--font-body);
  --text-price: var(--fw-bold) var(--fs-price)/1 var(--font-narrow);

  /* ——— Простір ————————————————————————————————————————————————————— */
  --sp-1: calc(4 * var(--px));
  --sp-2: calc(8 * var(--px));
  --sp-3: calc(12 * var(--px));
  --sp-4: calc(16 * var(--px));
  --sp-5: calc(20 * var(--px));
  --sp-6: calc(24 * var(--px));
  --sp-7: calc(28 * var(--px));
  --sp-8: calc(32 * var(--px));
  --sp-10: calc(40 * var(--px));
  --sp-12: calc(48 * var(--px));
  --sp-16: calc(64 * var(--px));
  --sp-18: calc(72 * var(--px));
  --sp-20: calc(80 * var(--px));
  --sp-24: calc(96 * var(--px));

  --container-max: 1770px;
  --container-pad: var(--sp-8);
  --grid-gap: calc(26 * var(--px));
  --section-py: var(--sp-24);
  --header-py: calc(26 * var(--px));
  --control-h: calc(40 * var(--px));
  --control-h-lg: calc(52 * var(--px));
  --tap-min: calc(44 * var(--px));

  /* ——— Радіуси ————————————————————————————————————————————————————— */
  --radius-none: 0;
  --radius-sm: calc(6 * var(--px));
  --radius-md: calc(14 * var(--px));    /* кнопки-«кошик», інпути */
  --radius-lg: calc(20 * var(--px));    /* картки */
  --radius-xl: calc(28 * var(--px));
  --radius-2xl: calc(44 * var(--px));   /* верхні кути футера */
  --radius-pill: 999px; /* дефолт для кнопок і чипів */
  --radius-circle: 50%; /* медальйони з фото */

  /* ——— Обводки ————————————————————————————————————————————————————— */
  --border-hairline: 1px solid var(--coco-line-200);
  --border-card: 1px solid var(--coco-line-200);
  /* WCAG 1.4.11: the edge is the only thing that says "this is a field" or
     "this is a button", so it owes 3:1 against both grounds it touches — the
     white fill inside and the section ground outside. Decorative hairlines
     (cards, separators, chips) carry no such duty and stay light. */
  --border-control: 1px solid var(--coco-line-450);
  --ring-medallion: calc(6 * var(--px));
  --ring-medallion-sm: calc(5 * var(--px));
  --ring-medallion-lg: calc(7 * var(--px));
  --ring-photo: calc(10 * var(--px));

  /* ——— Тіні ———————————————————————————————————————————————————————— */
  --shadow-none: none;
  --shadow-card: 0 calc(16 * var(--px)) calc(40 * var(--px)) rgba(22, 40, 26, 0.07);
  --shadow-card-hover: 0 calc(22 * var(--px)) calc(52 * var(--px)) rgba(22, 40, 26, 0.13);
  --shadow-medallion: 0 calc(10 * var(--px)) calc(24 * var(--px)) rgba(22, 40, 26, 0.2);
  --shadow-portrait: 0 calc(26 * var(--px)) calc(60 * var(--px)) rgba(22, 40, 26, 0.22);
  --shadow-cta: 0 calc(12 * var(--px)) calc(28 * var(--px)) rgba(61, 117, 33, 0.3);
  --shadow-cta-hover: 0 calc(16 * var(--px)) calc(34 * var(--px)) rgba(61, 117, 33, 0.38);
  --shadow-focus: 0 0 0 3px rgba(31, 127, 190, 0.3);
  --shadow-field-focus: 0 0 0 3px rgba(61, 117, 33, 0.18);

  --overlay-scrim: rgba(17, 17, 17, 0.55);
  --tint-shell: linear-gradient(180deg, var(--coco-shell-100) 0%, var(--coco-white) 100%);

  /* ——— Рух ————————————————————————————————————————————————————————— */
  --dur-fast: 120ms;
  --dur-base: 180ms;
  --dur-slow: 320ms;
  --ease-standard: ease-out;
  --ease-inout: cubic-bezier(0.4, 0, 0.2, 1);
  --transition-control: background-color var(--dur-base) var(--ease-standard),
                        color var(--dur-base) var(--ease-standard),
                        border-color var(--dur-base) var(--ease-standard),
                        box-shadow var(--dur-base) var(--ease-standard);
  --transition-card: box-shadow var(--dur-base) var(--ease-standard),
                     transform var(--dur-base) var(--ease-standard);
  --press-shift: 1px;

  /* ——— Z-шар ——————————————————————————————————————————————————————— */
  --z-content: 1;
  --z-medallion: 2;
  --z-header: 10;

  /* ==========================================================================
     ШАР 2 — SEMANTIC (єдина точка, де компоненти беруть колір)
     ========================================================================== */

  /* Two greens, one hue. --accent backs or forms text, so it sits deep enough
     to clear 4.5:1 against white and against the light surfaces. --accent-decor
     is the brand green untouched: it only ever fills shapes nobody reads. */
  --accent: var(--coco-grass-600);
  --accent-hover: var(--coco-grass-550);
  --accent-press: var(--coco-grass-700);
  --accent-decor: var(--coco-grass-500);
  --accent-soft: var(--coco-grass-050);

  --text-heading: var(--coco-ink-850);
  --text-body: var(--coco-ink-700);
  --text-muted: var(--coco-ink-500);
  --text-inverse: var(--coco-white);
  --text-inverse-muted: rgba(255, 255, 255, 0.92);
  --text-inverse-faint: rgba(255, 255, 255, 0.85);
  --text-link: var(--accent);
  --text-link-hover: var(--coco-grass-700);
  --text-price-color: var(--coco-ink-850);

  --surface-page: var(--coco-white);
  --surface-card: var(--coco-white);
  --surface-soft: var(--coco-grass-050);
  --surface-shell: var(--coco-shell-100);
  --surface-accent: var(--accent);
  --surface-footer: var(--accent);

  --border-default: var(--coco-line-200);
  --border-strong: var(--coco-line-300);
  --border-interactive: var(--coco-line-450);
  --border-inverse: rgba(255, 255, 255, 0.24);

  --focus-ring: var(--coco-blue-500);
}

/* ==========================================================================
   ШАР 3 — BASE
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* Components set display freely, so the attribute needs the last word: a
   hidden panel that a grid rule keeps showing is a bug waiting to ship. */
[hidden] { display: none !important; }

body {
  margin: 0;
  /* One unbreakable token — a pasted link, a long code, a run-on name — must
     never push a card past its container and take the page sideways with it. */
  overflow-wrap: break-word;
  background: var(--surface-page);
  color: var(--text-body);
  font: var(--text-default);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 {
  margin: 0;
  color: var(--text-heading);
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  text-wrap: pretty;
}

h1 { font: var(--text-display); letter-spacing: var(--ls-tight); }
h2 { font: var(--text-h1); }
h3 { font: var(--text-h3); }
h4 { font: var(--text-h4); }

p { margin: 0; }

a {
  color: var(--text-link);
  text-decoration: none;
  transition: var(--transition-control);
}
a:hover { color: var(--text-link-hover); }

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

/* The parts the browser draws — selection, the caret, native checkboxes and
   selects — take the palette too, instead of the platform blue. The focus ring
   stays blue on purpose (see :focus-visible below). */
:root { accent-color: var(--accent); caret-color: var(--accent); }
::selection { background: var(--coco-grass-100); color: var(--text-heading); }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ==========================================================================
   ШАР 4 — COMPONENTS
   ========================================================================== */

/* ——— Layout ——————————————————————————————————————————————————————— */

/* Обгортка сторінки: система координат для декоративних кіл героя.
   clip, not hidden: overflow:hidden turns this into a scroll container, and a
   scroll container makes position:sticky stick to it instead of the viewport.
   The blobs only ever spill sideways, so clipping one axis is enough. */
.page { position: relative; overflow-x: clip; }

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section { padding-top: var(--section-py); }
.section--flush { padding-top: 0; }
.section--center { text-align: center; }

.section__lead {
  margin: var(--sp-4) auto 0;
  max-width: calc(520 * var(--px));
  font: var(--text-default);
  line-height: var(--lh-loose);
  color: var(--text-muted);
}

.section--center .section__lead { margin-inline: auto; }

.grid { display: grid; gap: var(--grid-gap); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* ——— Кнопки ——————————————————————————————————————————————————————— */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap-min);
  padding: var(--sp-4) var(--sp-8);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font: var(--text-button);
  text-transform: uppercase;
  letter-spacing: var(--ls-button);
  white-space: nowrap;
  cursor: pointer;
  transition: var(--transition-control), transform var(--dur-fast) var(--ease-standard);
}
.btn:active { transform: translateY(var(--press-shift)); }
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  pointer-events: none;
  transform: none;
}

/* Основна дія — фірмовий зелений */
.btn--primary {
  background: var(--accent);
  color: var(--text-inverse);
  box-shadow: var(--shadow-cta);
}
.btn--primary:hover {
  background: var(--accent-hover);
  color: var(--text-inverse);
  box-shadow: var(--shadow-cta-hover);
}
.btn--primary:active { background: var(--accent-press); box-shadow: var(--shadow-cta); }

/* Другорядна — контурна */
.btn--ghost {
  background: transparent;
  border-color: var(--border-interactive);
  color: var(--text-heading);
}
.btn--ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

/* Жовткова — розпродажі, акції */
.btn--yolk {
  background: var(--coco-yolk-500);
  color: var(--coco-ink-900);
}
.btn--yolk:hover { background: var(--coco-yolk-400); color: var(--coco-ink-900); }
.btn--yolk:active { background: var(--coco-yolk-600); }

/* Інверсна — на зеленому футері */
.btn--inverse {
  background: var(--coco-white);
  color: var(--accent-press);
}
.btn--inverse:hover { background: var(--coco-grass-100); color: var(--accent-press); }

/* Розміри */
.btn--sm {
  min-height: calc(34 * var(--px));
  padding: calc(9 * var(--px)) var(--sp-4);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
}
.btn--lg { padding: var(--sp-4) var(--sp-8); min-height: var(--control-h-lg); }

/* Форма */
.btn--square { border-radius: var(--radius-md); padding: var(--sp-3) var(--sp-5); }
.btn--block { display: flex; width: 100%; }

/* ——— Чипи, бейджі, прайси ————————————————————————————————————————— */

/* A chip is a static label, not a control — it keeps the light hairline it
   always had rather than following --border-control to the 3:1 edge. */
.chip {
  display: inline-block;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  font: var(--fw-bold) var(--fs-2xs)/1 var(--font-body);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-wide);
  color: var(--text-heading);
}

.badge {
  display: inline-block;
  padding: calc(6 * var(--px)) var(--sp-3);
  border-radius: var(--radius-pill);
  font: var(--fw-bold) var(--fs-2xs)/1 var(--font-body);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
}
.badge--stock { background: var(--coco-grass-100); color: var(--coco-grass-600); }
.badge--hit { background: var(--coco-yolk-100); color: var(--coco-yolk-700); }
.badge--out { background: var(--coco-alert-100); color: var(--coco-alert-500); }

/* The price is the number the visitor came for, so it gets the display face at
   --fs-price and the unit shrinks away underneath it. It used to sit in a grey
   pill at --fs-xs, level with the stock badge, which read as metadata. */
.price {
  font: var(--text-price);
  color: var(--text-price-color);
}
.price small {
  font: var(--fw-regular) var(--fs-xs)/1 var(--font-body);
  color: var(--text-muted);
}

.rating {
  font: var(--fw-regular) var(--fs-xs)/1 var(--font-body);
  color: var(--accent);
  letter-spacing: var(--ls-caps-wide);
}
.rating span {
  color: var(--text-muted);
  letter-spacing: 0;
}

/* ——— Медальйон: кругле фото в акцентному кільці ————————————————— */

.medallion {
  border-radius: var(--radius-circle);
  overflow: hidden;
  background: var(--coco-white);
  border: var(--ring-medallion) solid var(--accent-decor);
  flex: 0 0 auto;
}
.medallion img { width: 100%; height: 100%; object-fit: cover; }

.medallion--sm { border-width: var(--ring-medallion-sm); }
.medallion--lg { border-width: var(--ring-medallion-lg); }
.medallion--white { border-color: var(--coco-white); box-shadow: var(--shadow-medallion); }
.medallion--portrait {
  border-width: var(--ring-photo);
  border-color: var(--coco-white);
  box-shadow: var(--shadow-portrait);
}

/* ——— Картки —————————————————————————————————————————————————————— */

.card {
  background: var(--surface-card);
  border: var(--border-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  transition: var(--transition-card);
}
.card:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }

/* Картка каталогу: медальйон виїжджає над карткою */
.card--product {
  margin-top: calc(84 * var(--px));
  padding: 0 var(--sp-5) var(--sp-6);
  text-align: center;
}
.card--product .medallion {
  width: calc(168 * var(--px));
  height: calc(168 * var(--px));
  margin: calc(-84 * var(--px)) auto 0;
  position: relative;
  z-index: var(--z-medallion);
}
.card__title {
  margin-top: var(--sp-4);
  font: var(--text-h4);
  text-transform: uppercase;
  color: var(--text-heading);
}
.card__text {
  margin-top: var(--sp-3);
  font: var(--text-caption);
  color: var(--text-muted);
}
.card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}

/* Рейтинг усередині товарної картки — між назвою та підвалом */
.card__rating { margin-top: var(--sp-3); }

/* М’яка картка без обводки — блоки «Чому ми» */
.card--soft {
  background: var(--surface-soft);
  border: 0;
  box-shadow: none;
  padding: var(--sp-8) var(--sp-7) var(--sp-8);
}
.card--soft:hover { box-shadow: none; transform: none; }
.card__number {
  font: var(--fw-bold) calc(34 * var(--px))/1 var(--font-display);
  color: var(--accent);
}
.card--soft .card__title { margin-top: var(--sp-4); }

/* ——— Шапка ——————————————————————————————————————————————————————— */

.site-header {
  position: relative;
  z-index: var(--z-header);
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--header-py) var(--container-pad);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-4) var(--sp-10);
}

.brand {
  /* nowrap below keeps the lockup on one line; without min-width a longer name
     would refuse to shrink and shove the menu button off screen. */
  min-width: 0;
  overflow: hidden;
  font: var(--fw-bold) calc(22 * var(--px))/1 var(--font-display);
  color: var(--text-heading);
  text-transform: uppercase;
  letter-spacing: var(--ls-heading);
  white-space: nowrap;
}
.brand:hover { color: var(--accent); }

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-7);
  font: var(--fw-bold) var(--fs-nav)/1 var(--font-body);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
}
.site-nav a { color: var(--text-heading); }
.site-nav a:hover { color: var(--accent); }

.site-header__aside {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

/* The panel exists only so the phone layout has something to collapse. On a wide
   screen it is a pass-through, and nav and aside sit in the header row exactly as
   if it were not there. */
.site-header__panel { display: contents; }

.nav-toggle { display: none; }

.phone {
  font: var(--fw-bold) var(--fs-phone)/1 var(--font-narrow);
  color: var(--text-heading);
  white-space: nowrap;
}
.phone:hover { color: var(--accent); }

/* ——— Герой ———————————————————————————————————————————————————————— */

.hero {
  position: relative;
  overflow: hidden;
  padding-bottom: var(--sp-10);
}

.hero__inner {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-10);
  align-items: center;
  padding-top: var(--sp-10);
}

/* Sized by its longest word, which runs 6.72× the font size: at a fixed 66px
   "ПТАХОФАБРИКИ" outgrew its column below ~1180px and broke mid-word. 5.8vw is
   the steepest slope that still fits the two-column hero at 681px; from 1180px
   up the --px cap takes over and the title scales with the page. */
.hero__title {
  margin-top: calc(22 * var(--px));
  font-size: clamp(40 * var(--px), 5.8vw, 66 * var(--px));
}

.hero__lead {
  margin-top: var(--sp-5);
  font: var(--text-lead);
  color: var(--text-body);
  max-width: min(480 * var(--px), 92%);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-8);
}

/* Кругле фото + три супутні мініатюри */
.hero__figure {
  --hero-portrait: min(480 * var(--px), 40vw);
  position: relative;
  min-width: 0;
  display: grid;
  place-items: center;
  padding: var(--sp-5) 0 var(--sp-10);
}
.hero__portrait {
  width: var(--hero-portrait);
  height: var(--hero-portrait);
}

/* The green discs behind the portrait. Every size and offset is a multiple of
   --hero-portrait and both are anchored to the portrait's centre, so the discs
   are one drawing with the photo: they shrink when it shrinks and never drift
   away from it, whatever the window does. They used to hang off the page's
   right edge and scale with the viewport, while the photo scaled with its
   column, and the two parted company between breakpoints. The ratios are read
   off the 1920px layout. .hero clips whatever runs past its edges. */
.hero__figure::before,
.hero__figure::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: calc(var(--sp-5) + var(--hero-portrait) / 2);
  aspect-ratio: 1;
  border-radius: var(--radius-circle);
  pointer-events: none;
}
.hero__figure::before {
  width: calc(var(--hero-portrait) * 1.43);
  translate: -50% calc(-50% - var(--hero-portrait) * 0.165);
  background: var(--accent-decor);
}
.hero__figure::after {
  width: calc(var(--hero-portrait) * 0.6);
  translate: calc(-50% + var(--hero-portrait) * 0.05) calc(-50% - var(--hero-portrait) * 0.27);
  background: var(--coco-grass-300);
  opacity: 0.5;
}
.hero__thumb { position: absolute; }
.hero__thumb--1 { left: 1%;  top: 9%;    width: calc(72 * var(--px)); height: calc(72 * var(--px)); }
.hero__thumb--2 { right: 0;  top: 6%;     width: calc(64 * var(--px)); height: calc(64 * var(--px)); }
.hero__thumb--3 { left: 8%;  bottom: 6%;  width: calc(64 * var(--px)); height: calc(64 * var(--px)); }

/* ——— Пагінація-точки ————————————————————————————————————————————— */

.dots {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-12);
}
/* The mark a pagination dot needs to read as one is 9px; the target a thumb
   needs is --tap-min. Those are two different objects, so the button is the
   target and ::before carries the mark. No gap: the boxes already sit
   --tap-min apart, and a gap on top of that would scatter the row. */
.dots button,
.dots span {
  display: grid;
  place-items: center;
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.dots button::before,
.dots span::before {
  content: "";
  width: calc(9 * var(--px));
  height: calc(9 * var(--px));
  border-radius: var(--radius-pill);
  background: var(--coco-line-150);
  /* Animating width is normally a layout-thrash tell, and here it is neither.
     The circle has to become a stadium, which no transform can do without
     bending the caps into ellipses, and the pseudo lives inside a fixed
     --tap-min grid cell, so the invalidation cannot leave this one box. */
  transition: var(--transition-control), width var(--dur-base) var(--ease-standard);
}
.dots [aria-current="true"]::before,
.dots .is-active::before { width: calc(26 * var(--px)); background: var(--accent); }

/* ——— Форми ———————————————————————————————————————————————————————— */

.field { display: grid; gap: var(--sp-2); }
.field__label {
  font: var(--fw-bold) var(--fs-2xs)/1 var(--font-body);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-wide);
  color: var(--text-muted);
}
.input,
.select,
.textarea {
  width: 100%;
  min-height: var(--control-h-lg);
  padding: var(--sp-3) var(--sp-4);
  background: var(--coco-white);
  border: var(--border-control);
  border-radius: var(--radius-md);
  font: var(--text-default);
  color: var(--text-body);
  transition: var(--transition-control);
}
.textarea { min-height: calc(120 * var(--px)); resize: vertical; }
.input:disabled,
.select:disabled,
.textarea:disabled {
  background: var(--surface-soft);
  color: var(--text-muted);
  cursor: not-allowed;
}
.input::placeholder,
.textarea::placeholder { color: var(--coco-ink-400); }
.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-field-focus);
}
.field__hint { font: var(--fw-regular) var(--fs-xs)/1.5 var(--font-body); color: var(--text-muted); }
.field--error .input { border-color: var(--coco-alert-500); }
.field--error .field__hint { color: var(--coco-alert-500); }

/* ——— Сповіщення ——————————————————————————————————————————————————— */

.alert {
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius-md);
  font: var(--text-caption);
}
.alert--success { background: var(--coco-grass-100); color: var(--coco-grass-600); }
.alert--info { background: var(--coco-blue-100); color: var(--coco-blue-700); }
.alert--warning { background: var(--coco-yolk-100); color: var(--coco-yolk-700); }
.alert--error { background: var(--coco-alert-100); color: var(--coco-alert-500); }

/* ——— Футер ———————————————————————————————————————————————————————— */

.site-footer {
  margin: var(--section-py) var(--sp-6) 0;
  background: var(--surface-footer);
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  padding: var(--sp-16) var(--sp-10) var(--sp-12);
  color: var(--text-inverse);
}
.site-footer__grid {
  /* Aligned to the content edge of .container, so the footer columns line up
     with the page above at every width instead of carrying their own cap. */
  max-width: calc(var(--container-max) - 2 * var(--container-pad));
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(220 * var(--px)), 1fr));
  gap: calc(36 * var(--px));
  align-items: start;
}
/* The footer ground is --accent itself, so the global link hover green would
   land dark-on-dark (1.4:1). Inside the footer a hover keeps the inverse ink
   and signals itself with the underline instead. */
.site-footer a:hover { color: var(--text-inverse); }
.site-footer .brand { color: var(--text-inverse); }
/* The footer brand is a <div>, not a link, so the rule above misses it while
   `.brand:hover` still fires — it needs its own guard. */
.site-footer .brand:hover { color: var(--text-inverse); }
.site-footer p { color: var(--text-inverse-muted); font: var(--text-caption); line-height: var(--lh-loose); }
.site-footer__about { max-width: calc(280 * var(--px)); margin-top: var(--sp-4); }

.footer__heading {
  margin-bottom: var(--sp-4);
  font: var(--fw-bold) var(--fs-2xs)/1 var(--font-body);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps-wide);
  color: var(--text-inverse-faint);
}
.footer__list {
  display: grid;
  gap: calc(9 * var(--px));
  font: var(--fw-regular) var(--fs-sm)/1.4 var(--font-body);
}
.footer__list a { color: var(--text-inverse); }
.footer__list a:hover { color: var(--text-inverse); text-decoration: underline; }
.footer__phones {
  display: grid;
  gap: calc(9 * var(--px));
  font: var(--fw-bold) var(--fs-phone)/1.2 var(--font-narrow);
  color: var(--text-inverse);
}
.footer__phones a { color: var(--text-inverse); }
.site-footer__legal {
  max-width: calc(var(--container-max) - 2 * var(--container-pad));
  margin: var(--sp-10) auto 0;
  padding-top: var(--sp-5);
  border-top: 1px solid var(--border-inverse);
  font: var(--fw-regular) calc(12 * var(--px))/1.5 var(--font-body);
  color: var(--text-inverse-faint);
}

/* ==========================================================================
   ШАР 5 — UTILITIES
   ========================================================================== */

.u-accent { color: var(--accent); }
.u-muted { color: var(--text-muted); }
.u-center { text-align: center; }
.u-text-left { text-align: left; }
.u-nowrap { white-space: nowrap; }
.u-mt-4 { margin-top: var(--sp-4); }
.u-mt-8 { margin-top: var(--sp-8); }
.u-mt-12 { margin-top: var(--sp-12); }
.u-mt-16 { margin-top: var(--sp-16); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: var(--sp-4);
  z-index: 100;
  padding: var(--sp-3) var(--sp-5);
  background: var(--accent);
  color: var(--text-inverse);
  border-radius: var(--radius-pill);
  font: var(--text-button);
  text-transform: uppercase;
  /* Parked above the viewport with translate rather than top: the motion then
     runs on the compositor and never touches layout. */
  translate: 0 calc(-100% - var(--sp-4));
  transition: translate var(--dur-base) var(--ease-standard);
}
/* The skip link carries its own --accent ground, so like the footer it has to
   opt out of the global dark-green link hover. */
.skip-link:hover { color: var(--text-inverse); }
.skip-link:focus { translate: 0 0; color: var(--text-inverse); }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

/* Windows high-contrast throws away backgrounds and shadows, so anything whose
   edge or state was carried by paint alone has to restate it as a border. */
@media (forced-colors: active) {
  .btn,
  .tile,
  .card,
  .input,
  .select,
  .textarea,
  .site-header__panel { border: 1px solid; }

  .input:focus,
  .select:focus,
  .textarea:focus {
    outline: 2px solid;
    outline-offset: 1px;
  }

  .nav-toggle__bars,
  .nav-toggle__bars::before,
  .nav-toggle__bars::after { background: CanvasText; }

  .dots [aria-current="true"]::before { background: Highlight; }
}

/* What makes a 20px-tall link unhittable is the finger, not the viewport — a
   laptop with a touchscreen has the same problem at 1440px. So the tap floor
   keys off the pointer, and mouse-driven desktops keep the compact footer they
   were drawn with. */
@media (pointer: coarse) {
  .skip-link { min-height: var(--tap-min); }
  .brand { min-height: var(--tap-min); }

  /* In a column of short links the gap is dead space between targets. Zero it
     and let each row grow to the floor instead: same rhythm, no dead bands. */
  .footer__list,
  .footer__phones { gap: 0; }
  .footer__list a,
  .footer__phones a {
    display: flex;
    align-items: center;
    min-height: var(--tap-min);
  }
}

@media (max-width: 1024px) {
  .grid--4,
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  :root { --section-py: var(--sp-16); }
  .site-footer { padding-inline: var(--sp-6); }
}

@media (max-width: 680px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); }
  /* One column gives the title the full width back, so it can be larger than
     the two-column slope allows: 12.5vw keeps the longest word inside the
     column down to 320px. */
  .hero__title { font-size: clamp(32px, 12.5vw, 66px); }
  .hero__figure::before,
  .hero__figure::after { display: none; }
  .hero__figure { --hero-portrait: min(360px, 78vw); }
  .hero__thumb--1 { left: -2%; }
  .hero__thumb--2 { right: -2%; }
}

@media (max-width: 620px) {
  :root { --container-pad: var(--sp-5); --grid-gap: var(--sp-5); }
  .grid--4,
  .grid--3 { grid-template-columns: minmax(0, 1fr); }
  /* Navigation is not optional on a phone. Its resting state is a plain stacked
     block, so a visitor whose JavaScript never arrives still has every link;
     the collapsing menu below is an enhancement layered on top of that. */
  .site-header {
    position: relative;
    flex-wrap: wrap;
    gap: var(--sp-3);
  }
  .site-header__panel {
    height: calc(100vh - 96px);
    display: flex;
    flex-direction: column;
    gap: var(--sp-6);
    width: 100%;
  }
  .site-nav {
    display: grid;
    gap: var(--sp-1);
    align-items: start;
  }
  .site-nav a { padding-block: var(--sp-3); }
  .site-header__aside {
    margin-left: 0;
    display: grid;
    gap: var(--sp-4);
    justify-items: start;
  }

  /* Enhancement: with JS the same panel folds behind a button. Phone and CTA
     travel into it, because brand + phone + CTA + button do not fit across
     375px. */
  .js .site-header { flex-wrap: nowrap; }

  .js .nav-toggle {
    display: grid;
    place-items: center;
    margin-left: auto;
    width: var(--tap-min);
    height: var(--tap-min);
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-heading);
    cursor: pointer;
  }
  .nav-toggle__bars,
  .nav-toggle__bars::before,
  .nav-toggle__bars::after {
    display: block;
    width: 22px;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform var(--dur-base) var(--ease-standard),
                translate var(--dur-base) var(--ease-standard),
                background-color var(--dur-base) var(--ease-standard);
  }
  .nav-toggle__bars { position: relative; }
  .nav-toggle__bars::before { content: ""; position: absolute; top: 0; translate: 0 -7px; }
  .nav-toggle__bars::after { content: ""; position: absolute; top: 0; translate: 0 7px; }

  .nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { translate: 0 0; transform: rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bars::after { translate: 0 0; transform: rotate(-45deg); }

  .js .site-header__panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: var(--z-header);
    padding: var(--sp-6) var(--container-pad) var(--sp-7);
    background: var(--surface-card);
    border-top: 1px solid var(--border-strong);
    box-shadow: var(--shadow-card-hover);
    visibility: hidden;
    opacity: 0;
    translate: 0 -8px;
    transition: opacity var(--dur-base) var(--ease-standard),
                translate var(--dur-base) var(--ease-standard),
                visibility var(--dur-base) var(--ease-standard);
  }
  .js .site-header__panel[data-open] {
    visibility: visible;
    opacity: 1;
    translate: 0 0;
  }
  /* Scoped to the phone breakpoint on purpose: above it the panel is a
     pass-through and a class left behind by a stale script must never be able
     to lock the page. The scroll position survives, because overflow:hidden
     freezes the viewport where it stands instead of reflowing it. */
  body.is-menu-open { overflow: hidden; }
  .phone { font-size: var(--fs-sm); }
  .site-footer { margin-inline: var(--sp-3); border-radius: var(--radius-xl) var(--radius-xl) 0 0; }
}
