/* ==========================================================================
   Nadzeya AI — Editorial Digital
   Design tokens per ТЗ §15.1. Do not introduce colors outside this palette.
   ========================================================================== */

@font-face {
  font-family: "DM Sans";
  src: url("../assets/fonts/DMSans-Variable.woff2") format("woff2-variations"), url("../assets/fonts/DMSans-Variable.woff2") format("woff2");
  font-weight: 100 1000;
  font-style: normal;
  font-display: swap;
}
@font-face {
  /* Archivo Black has zero Cyrillic coverage — it silently fell back to
     DM Sans on every Russian/Belarusian character, making the RU headline
     render in a visibly different typeface than EN/PL. Unbounded covers
     Latin + Cyrillic + Polish diacritics in one file, so all three
     language versions now render identically. */
  font-family: "Unbounded";
  src: url("../assets/fonts/Unbounded-900.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Unbounded";
  src: url("../assets/fonts/Unbounded-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  /* Handwritten accent line, matched to the reference's script tagline.
     Most casual script fonts (incl. the one the reference uses) have no
     Cyrillic glyphs at all — checked this one's coverage before using it,
     after getting burned by that exact gap with the display font. */
  font-family: "Caveat";
  src: url("../assets/fonts/Caveat-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
/* Inter kept self-hosted but no longer the default — available via --font-inter if ever needed */
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* fixed brand tokens — do not modify */
  --color-warm-ivory: #F4F0E7;
  --color-white: #FFFFFF;
  --color-ink: #111111;
  --color-nadzeya-yellow: #ECB614;
  --color-peach-accent: #E6A07A;
  --font-primary: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-display: "Unbounded", "DM Sans", sans-serif;

  /* derived, non-brand utility values */
  --ink-08: rgba(17,17,17,0.08);
  --ink-14: rgba(17,17,17,0.14);
  --ink-30: rgba(17,17,17,0.3);
  --ink-60: rgba(17,17,17,0.6);
  --white-70: rgba(255,255,255,0.7);
  --white-30: rgba(255,255,255,0.3);
  /* Nav hover state: brand yellow lightened toward white so hover reads as
     a distinct, lighter step above the solid-yellow "active page" color
     rather than the same shade twice. */
  --color-nadzeya-yellow-light: #F2CC5B;

  --container-max: 1360px;
  --text-max: 40rem;
  --page-pad: clamp(20px, 5vw, 64px);

  --space-xs: clamp(0.75rem, 0.6rem + 0.6vw, 1.25rem);
  --space-s: clamp(1.25rem, 1rem + 1vw, 2rem);
  --space-m: clamp(1.75rem, 1.4rem + 1.6vw, 2.75rem);
  --space-l: clamp(3rem, 2.2rem + 3vw, 5rem);
  --space-xl: clamp(4rem, 2.8rem + 5vw, 7.5rem);
  --space-xxl: clamp(5rem, 3rem + 8vw, 10rem);

  --dur-fast: 150ms;
  --dur-base: 240ms;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);

  --border-hair: 1px solid var(--color-ink);
  --border-hair-14: 1px solid var(--ink-14);
}

/* ---- reset --------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
body {
  margin: 0;
  background: var(--color-warm-ivory);
  color: var(--color-ink);
  font-family: var(--font-primary);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p { margin: 0; }
svg { display: block; }

::selection { background: var(--color-nadzeya-yellow); color: var(--color-ink); }

/* ---- typography ------------------------------------------------------ */
.h1 {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.6rem, 1.4rem + 0.95vw, 2.2rem);
  line-height: 1.08;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
.hero__title {
  /* Unbounded renders noticeably larger than Archivo Black did at the
     same font-size (wider, rounder letterforms), so this needs to run
     smaller than the old value to read as the same visual size.
     Weight 700 (not the 900 used for h2/h3/wordmark) so the hero line
     reads as less heavy, per direct request. */
  font-family: "Unbounded", "DM Sans", sans-serif;
  font-weight: 700;
  font-size: clamp(1.9rem, 1.65rem + 1.15vw, 2.65rem);
  line-height: 1.18;
}
.h2 {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.625rem, 1.35rem + 1.3vw, 2.75rem);
  line-height: 1;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
.h3 {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.125rem);
  line-height: 1.3;
  letter-spacing: -0.005em;
  text-transform: uppercase;
}
.lead {
  font-weight: 400;
  font-size: clamp(0.9375rem, 0.9rem + 0.2vw, 1.0625rem);
  line-height: 1.55;
  color: var(--ink-60);
}
.lead--bold { font-weight: 700; color: var(--color-ink); }
.body {
  font-weight: 400;
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--ink-60);
}
.label {
  font-weight: 700;
  font-size: 0.6875rem;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.eyebrow {
  font-weight: 700;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  color: var(--ink-60);
}
.eyebrow::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  background: var(--color-nadzeya-yellow);
  border-radius: 50%;
  flex: none;
}
.accent { color: var(--color-nadzeya-yellow); }
mark.accent {
  background: none;
  color: inherit;
}
.italic-note { font-style: italic; font-weight: 400; }

/* ---- layout ------------------------------------------------------------ */
.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding-left: var(--page-pad);
  padding-right: var(--page-pad);
}
.measure { max-width: var(--text-max); }
/* Flowing bio/story copy (obo-mne): every paragraph reads as one voice at
   one size — no alternating in lead-sized pull quotes — and justified so
   the block reads as a solid column instead of a ragged edge. */
.bio { display: flex; flex-direction: column; gap: 1rem; }
.bio p { text-align: justify; }
.section { padding-top: var(--space-xl); padding-bottom: var(--space-xl); }
.section--tight { padding-top: var(--space-l); padding-bottom: var(--space-l); }
.section--dark { background: var(--color-ink); color: var(--color-white); }
.section--white { background: var(--color-white); }
.rule { border: none; border-top: var(--border-hair-14); margin: 0; }
.rule--strong { border-top: 1.5px solid var(--color-ink); }

.grid { display: grid; gap: var(--space-m); }
.grid-12 { grid-template-columns: repeat(12, 1fr); }
/* Services page text/photo pair — kept as real classes (not the inline
   grid-column styles used before) specifically so the 900px collapse
   below can reset placement too. An explicit inline grid-column always
   wins over a stylesheet media query, so the old inline version forced a
   2-column layout on phones even after .grid-12 itself had collapsed to
   one column — that was the mobile "everything overlapping" bug. */
.service-col-text { grid-column: 1 / span 6; align-self: center; }
.service-col-photo { grid-column: 8 / span 5; }
/* Checkerboard variant — alternating rows (e.g. every other FAQ entry)
   swap which side the text/photo pair sits on, purely for visual rhythm
   down a long list of otherwise-identical rows. Mobile still collapses
   to one column via the same reset below, text first either way. */
.grid-12--reverse .service-col-text { grid-column: 8 / span 5; }
.grid-12--reverse .service-col-photo { grid-column: 1 / span 6; }
@media (max-width: 900px) {
  .grid-12 { grid-template-columns: 1fr; }
  .service-col-text, .service-col-photo { grid-column: auto; align-self: auto; }
  /* Several other pages (obo-mne, kontakty, reklama, sozdanie-saitov...)
     place grid-12 children with an inline grid-column instead of the two
     classes above. Inline styles always beat a stylesheet rule, so those
     kept their desktop column widths/positions after the grid collapsed
     to one column — same overflow bug the classes above were built to
     fix, just not covered by them. A blanket reset for every direct
     child closes that gap for all of them at once. */
  .grid-12 > * { grid-column: auto !important; align-self: auto !important; }
}

/* ---- buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.75em 1.15em;
  font-weight: 700;
  font-size: 0.85rem;
  border: 1.5px solid var(--color-ink);
  border-radius: 0;
  background: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn svg { width: 1.05em; height: 1.05em; transition: transform var(--dur-base) var(--ease); }
.btn:hover svg { transform: translate(0.12em, -0.12em); }
.btn:active { transform: scale(0.98); }
.btn-primary {
  background: var(--color-nadzeya-yellow);
  border-color: var(--color-nadzeya-yellow);
  color: var(--color-ink);
}
.btn-primary:hover { background: var(--color-ink); border-color: var(--color-ink); color: var(--color-nadzeya-yellow); }
.btn-secondary { background: transparent; border-color: var(--color-ink); color: var(--color-ink); }
.btn-secondary:hover { background: var(--color-ink); color: var(--color-warm-ivory); }
.btn-on-dark { border-color: var(--color-white); color: var(--color-white); }
.btn-on-dark:hover { background: var(--color-white); color: var(--color-ink); }
.btn-block { width: 100%; justify-content: center; }

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-weight: 700;
  font-size: 0.95rem;
  padding-bottom: 0.2em;
  border-bottom: 1.5px solid var(--color-ink);
  transition: opacity var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.text-link svg { width: 1em; height: 1em; transition: transform var(--dur-base) var(--ease); }
.text-link:hover svg { transform: translate(0.14em, -0.14em); }
.text-link:hover { opacity: 0.6; }
.text-link--on-dark { border-color: var(--color-white); }

/* ---- header -------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-warm-ivory);
  border-bottom: var(--border-hair-14);
}

/* Overlay header: floats transparent over a dark hero photo with white text,
   then becomes a solid plate once the hero has scrolled past (JS toggles
   .is-scrolled — see main.js). Only used on pages with a .hero section. */
.site-header--overlay {
  position: fixed;
  left: 0; right: 0;
  background: var(--color-ink);
  border-bottom-color: transparent;
  transition: background var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease);
}
.site-header--overlay .wordmark,
.site-header--overlay .main-nav a,
.site-header--overlay .nav-toggle,
.site-header--overlay .nav-toggle-icon span {
  color: var(--color-white);
  text-shadow: 0 1px 12px rgba(0,0,0,0.5), 0 1px 2px rgba(0,0,0,0.6);
}
.site-header--overlay .nav-toggle-icon span { background: var(--color-white); box-shadow: 0 1px 6px rgba(0,0,0,0.5); }
.site-header--overlay .nav-toggle { border-color: rgba(255,255,255,0.7); }
.site-header--overlay .lang-switch a { color: var(--white-70); text-shadow: 0 1px 10px rgba(0,0,0,0.5); }
.site-header--overlay .lang-switch a[aria-current="true"] { color: var(--color-nadzeya-yellow); }
.site-header--overlay .lang-switch .sep { color: var(--white-30); }

.site-header--overlay.is-scrolled {
  background: var(--color-warm-ivory);
  border-bottom: var(--border-hair-14);
}
.site-header--overlay.is-scrolled .wordmark,
.site-header--overlay.is-scrolled .main-nav a,
.site-header--overlay.is-scrolled .nav-toggle,
.site-header--overlay.is-scrolled .nav-toggle-icon span,
.site-header--overlay.is-scrolled .lang-switch a {
  color: var(--color-ink);
  text-shadow: none;
}
.site-header--overlay.is-scrolled .nav-toggle-icon span { background: var(--color-ink); box-shadow: none; }
.site-header--overlay.is-scrolled .nav-toggle { border-color: var(--color-ink); }
.site-header--overlay.is-scrolled .lang-switch a { color: var(--ink-30); }
.site-header--overlay.is-scrolled .lang-switch a:hover { color: var(--color-nadzeya-yellow-light); }
.site-header--overlay.is-scrolled .lang-switch a[aria-current="true"] { color: var(--color-nadzeya-yellow); }
.site-header--overlay.is-scrolled .lang-switch .sep { color: var(--ink-30); }
.site-header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1.1rem;
  padding-bottom: 1.1rem;
}
.wordmark { font-family: var(--font-display); font-weight: 900; font-size: 1.05rem; letter-spacing: -0.01em; text-transform: uppercase; }
.wordmark span { color: var(--color-nadzeya-yellow); }
.main-nav { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.25rem); }
.main-nav a {
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  padding: 0.4em 0;
  transition: color var(--dur-fast) var(--ease);
}
.main-nav a:hover { color: var(--color-nadzeya-yellow-light); }
.main-nav a[aria-current="page"] { color: var(--color-nadzeya-yellow); }
/* .is-scrolled sets .main-nav a to ink via a higher-specificity compound
   selector (.site-header--overlay.is-scrolled ...) than the plain rules
   above, so hover/active need their own equally-specific override here —
   otherwise the scrolled state's ink color would win and hover/active
   would silently stop working once the header solidifies on scroll. */
.site-header--overlay.is-scrolled .main-nav a:hover { color: var(--color-nadzeya-yellow-light); }
.site-header--overlay.is-scrolled .main-nav a[aria-current="page"] { color: var(--color-nadzeya-yellow); }
.header-actions { display: flex; align-items: center; gap: 1.1rem; }

.lang-switch { display: flex; align-items: center; gap: 0.4rem; font-weight: 700; font-size: 0.78rem; letter-spacing: 0.02em; }
.lang-switch a { color: var(--ink-30); padding: 0.2em 0.05em; }
.lang-switch a:hover { color: var(--color-nadzeya-yellow-light); }
.lang-switch a[aria-current="true"] { color: var(--color-nadzeya-yellow); }
.lang-switch .sep { color: var(--ink-30); }
.nav-toggle {
  display: none;
  width: 2.3rem;
  height: 2.3rem;
  border: 1.5px solid var(--color-ink);
  background: none;
  align-items: center;
  justify-content: center;
  flex: none;
}
.nav-toggle-icon { width: 1.05rem; height: 0.72rem; position: relative; }
.nav-toggle-icon span {
  position: absolute; left: 0; width: 100%; height: 1.5px; background: var(--color-ink);
  transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease), top var(--dur-base) var(--ease);
}
.nav-toggle-icon span:nth-child(1) { top: 0; }
.nav-toggle-icon span:nth-child(2) { top: 50%; margin-top: -0.75px; }
.nav-toggle-icon span:nth-child(3) { top: 100%; margin-top: -1.5px; }
.nav-open .nav-toggle-icon span:nth-child(1) { top: 50%; transform: rotate(45deg); }
.nav-open .nav-toggle-icon span:nth-child(2) { opacity: 0; }
.nav-open .nav-toggle-icon span:nth-child(3) { top: 50%; transform: rotate(-45deg); }

/* Compact modal card instead of a full-screen takeover — dark scrim behind,
   a bordered ivory card floating below the header, sharp corners and a
   dedicated close square to match the rest of the site's editorial
   language (see .nav-toggle for the same button treatment). */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: rgba(15, 15, 15, 0.72);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: var(--page-pad);
  padding-top: max(var(--page-pad), 4.75rem);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease), visibility 0s linear var(--dur-base);
}
.nav-open .mobile-nav {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--dur-base) var(--ease), visibility 0s linear;
}
.mobile-nav__card {
  position: relative;
  width: 100%;
  max-width: 22rem;
  background: var(--color-warm-ivory);
  border: var(--border-hair);
  padding: var(--space-l) var(--space-m) var(--space-m);
  color: var(--color-ink);
  transform: translateY(-10px);
  transition: transform var(--dur-base) var(--ease);
}
.nav-open .mobile-nav__card { transform: translateY(0); }
.mobile-nav__close {
  position: absolute;
  top: var(--space-s);
  right: var(--space-s);
  width: 2.3rem;
  height: 2.3rem;
  border: 1.5px solid var(--color-ink);
  background: none;
  color: var(--color-ink);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mobile-nav__close svg { width: 1rem; height: 1rem; }
.mobile-nav ul { display: flex; flex-direction: column; gap: 0.5rem; padding-right: 2.25rem; }
.mobile-nav a { font-family: var(--font-display); font-weight: 700; font-size: clamp(0.95rem, 3.2vw, 1.1rem); letter-spacing: -0.005em; text-transform: uppercase; display: inline-block; padding: 0.15em 0; color: var(--color-ink); transition: color var(--dur-fast) var(--ease); }
.mobile-nav a:hover { color: var(--color-nadzeya-yellow-light); }
.mobile-nav a[aria-current="page"] { color: var(--color-nadzeya-yellow); }
.mobile-nav a span { color: inherit; }
.mobile-nav__footer { margin-top: var(--space-m); display: flex; flex-direction: column; gap: 0.5rem; }
.mobile-nav__footer a { font-weight: 700; font-size: 0.85rem; color: var(--ink-60); }
.mobile-nav__cta { margin-top: var(--space-s); }
.mobile-nav .lang-switch { margin-top: var(--space-m); }
.mobile-nav .lang-switch a {
  font-family: var(--font-primary);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  padding: 0.2em 0.05em;
  display: inline;
  color: var(--ink-30);
}
.mobile-nav .lang-switch a:hover { color: var(--color-nadzeya-yellow-light); }
.mobile-nav .lang-switch a[aria-current="true"] { color: var(--color-nadzeya-yellow); }
body.nav-open { overflow: hidden; }
@media (max-width: 860px) {
  .main-nav { display: none; }
  .nav-toggle { display: inline-flex; }
  /* The header CTA doesn't shrink (button text won't wrap), so next to
     the wordmark it was wider than the viewport and the two overlapped
     instead of wrapping — same "Описать задачу" action is one tap away
     in the menu, so just drop it here rather than fight the width. */
  .site-header .header-actions .btn { display: none; }
}
.mobile-nav__cta { margin-top: var(--space-m); }

/* ---- hero ------------------------------------------------------------
   .hero__photo and .hero__content share the same grid cell so the photo
   always stretches to match the content's height — no matter how many
   lines the H1 wraps to at a given viewport width. */
.hero {
  position: relative;
  display: grid;
}
.hero__photo {
  grid-area: 1 / 1;
  position: relative;
  min-height: 88vh;
  background: var(--color-ink);
  overflow: hidden;
}
.hero__photo img {
  width: 100%; height: 100%; object-fit: cover; object-position: 68% 22%;
  position: absolute; inset: 0;
  opacity: 0;
  animation: heroFade 16s ease-in-out infinite;
  /* Promote each frame to its own GPU layer — without this, Safari in
     particular redraws the two full-bleed photos on the same layer every
     frame of the opacity tween, which reads as a flickery shimmer
     ("рябь") instead of a clean dissolve. */
  will-change: opacity;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: translateZ(0);
}
/* Second image runs exactly half a cycle out of phase with the first, so
   at every instant opacity(1) + opacity(2) === 1 — one photo is always
   the mirror of the other rather than both briefly dimming together,
   which is what read as a "swimming"/pulsing cross-fade before. */
.hero__photo img:nth-of-type(1) { animation-delay: 0s; }
.hero__photo img:nth-of-type(2) { animation-delay: -8s; }
@keyframes heroFade {
  0%, 35.7% { opacity: 1; }
  50% { opacity: 0; }
  85.7% { opacity: 0; }
  100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__photo img { animation: none; opacity: 0; }
  .hero__photo img:first-of-type { opacity: 1; }
}
.hero__photo::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(17,17,17,0.18) 0%, rgba(17,17,17,0.08) 30%, rgba(17,17,17,0.62) 100%);
}
.hero__grain { position: absolute; inset: 0; opacity: 0.05; mix-blend-mode: overlay; pointer-events: none; }
.hero__content {
  grid-area: 1 / 1;
  position: relative;
  z-index: 2;
  align-self: end;
  /* Match .container's centered edge (not just page-pad from the raw
     viewport edge) so the hero heading lines up with the header logo
     and every other section on wide screens, where .container stops
     growing at --container-max and starts centering itself. */
  padding-top: var(--space-xl);
  padding-bottom: 4.5rem;
  padding-left: max(var(--page-pad), calc((100% - var(--container-max)) / 2 + var(--page-pad)));
  padding-right: max(var(--page-pad), calc((100% - var(--container-max)) / 2 + var(--page-pad)));
  color: var(--color-white);
}
.hero__eyebrow { color: var(--white-70); }
.hero__eyebrow::before { }
.hero__title { margin-top: -2rem; }
.hero__tagline {
  font-family: "Caveat", cursive;
  font-style: normal;
  font-weight: 700;
  font-size: clamp(1.35rem, 1.2rem + 0.7vw, 1.9rem);
  color: var(--color-nadzeya-yellow);
  margin-top: 0.25rem;
}
.hero__bottom { margin-top: var(--space-m); }
.hero__lead { margin-top: 0; color: var(--white-70); font-size: clamp(0.875rem, 0.84rem + 0.18vw, 0.9375rem); }
.hero__actions { margin-top: var(--space-s); display: flex; flex-wrap: wrap; gap: 1rem; }

/* On narrow phones the bottom-anchored text stack got tall enough to climb
   up over the face in the photo. Shrinking the type and tightening the
   stack keeps the whole block shorter so it sits below the face instead
   of on top of it. */
@media (max-width: 640px) {
  .hero__title { margin-top: 0; font-size: clamp(1.5rem, 1.1rem + 4.5vw, 1.9rem); }
  .hero__tagline { font-size: 1.1rem; }
  .hero__bottom { margin-top: 0.75rem; }
  .hero__lead { font-size: 0.8125rem; }
  .hero__actions { margin-top: 0.75rem; }
  .hero__content { padding-bottom: 2.75rem; }
}

/* ---- interior-page photo hero -------------------------------------------
   Same crossfade technique as the homepage .hero (staggered opacity
   keyframes, one GPU layer per frame), generalised from 2 photos to 9 and
   scaled down for a section heading rather than the full landing hero. */
.page-hero {
  position: relative;
  display: grid;
  color: var(--color-white);
}
.page-hero__photo {
  grid-area: 1 / 1;
  position: relative;
  min-height: 58vh;
  background: var(--color-ink);
  overflow: hidden;
}
.page-hero__photo img {
  width: 100%; height: 100%; object-fit: cover;
  position: absolute; inset: 0;
  opacity: 0;
  /* 36s = 6 photos × 6s each — this duration and the keyframe percentages
     below are only correct for exactly 6 <img> children. Fewer/more
     photos need both the duration and the 100/n% split recalculated,
     otherwise there's a stretch of the cycle with every image hidden and
     the plain --color-ink background (black) showing through instead —
     that gap read as a long black flash between photos. */
  animation: pageHeroFade 36s ease-in-out infinite;
  will-change: opacity;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: translateZ(0);
}
.page-hero__photo img:nth-of-type(1) { animation-delay: 0s; }
.page-hero__photo img:nth-of-type(2) { animation-delay: -6s; }
.page-hero__photo img:nth-of-type(3) { animation-delay: -12s; }
.page-hero__photo img:nth-of-type(4) { animation-delay: -18s; }
.page-hero__photo img:nth-of-type(5) { animation-delay: -24s; }
.page-hero__photo img:nth-of-type(6) { animation-delay: -30s; }
/* A "hold at full opacity, then fully hidden" shape (like an earlier
   version of this) leaves a beat where the image that just faded out is
   at 0 and the next hasn't started rising yet — .page-hero__photo's
   plain ink background shows through as a black flash in that gap. This
   tent shape instead has each image ramp from 0 up to 1 and back down to
   0 over a full two-slice-wide window (12s) centred on its own delay
   slot, so it's always overlapping both neighbours: one image finishing
   its fall through exactly the same seconds the next is rising through
   its start — with the matching ease-in-out timing function, a falling
   and a rising curve offset like this sum to ~1 throughout the overlap,
   so opacity never actually dips toward black. Same trick as .hero's
   2-photo crossfade above, generalised from a half-cycle offset to a
   1/6-cycle offset for 6 photos. */
@keyframes pageHeroFade {
  0% { opacity: 0; }
  16.67% { opacity: 1; }
  33.33% { opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .page-hero__photo img { animation: none; opacity: 0; }
  .page-hero__photo img:first-of-type { opacity: 1; }
}
.page-hero__photo::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(17,17,17,0.3) 0%, rgba(17,17,17,0.18) 35%, rgba(17,17,17,0.72) 100%);
}
.page-hero__content {
  grid-area: 1 / 1;
  position: relative;
  z-index: 2;
  align-self: end;
  padding-top: var(--space-xl);
  padding-bottom: 3.5rem;
  padding-left: max(var(--page-pad), calc((100% - var(--container-max)) / 2 + var(--page-pad)));
  padding-right: max(var(--page-pad), calc((100% - var(--container-max)) / 2 + var(--page-pad)));
}
.page-hero__lead { margin-top: var(--space-m); color: var(--white-70); }
@media (max-width: 640px) {
  .page-hero__photo { min-height: 62vh; }
  .page-hero__content { padding-bottom: 2.75rem; }
}

/* ---- helper: photo bleed ------------------------------------------------ */
.figure { position: relative; overflow: hidden; background: var(--color-ink); }
.figure img {
  width: 100%; height: 100%; object-fit: cover;
  /* Same duration/easing as .service-card and .review-card hover-zoom,
     so every photo on the site moves the same way. */
  transition: transform 650ms cubic-bezier(0.16, 1, 0.3, 1);
}
.figure:hover img { transform: scale(1.06); }
.figure--tall { aspect-ratio: 4 / 5; }
.figure--wide { aspect-ratio: 16 / 10; }
.figure--square { aspect-ratio: 1 / 1; }

/* ---- help list (services teaser) & pricing list --------------------------
   Bordered grid of compact cells rather than a dense stacked table — each
   item gets real breathing room, no repeated boxed buttons. */
.help-list, .price-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: var(--border-hair-14);
  border-left: var(--border-hair-14);
}
.help-item, .price-item {
  border-right: var(--border-hair-14);
  border-bottom: var(--border-hair-14);
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
}
@media (max-width: 720px) {
  .help-list, .price-list { grid-template-columns: 1fr; }
}

.help-item__index { font-weight: 700; font-size: 0.75rem; color: var(--ink-30); }
.help-item__title { margin-top: 0.6rem; }
.help-item__body { margin-top: 0.6rem; }
.help-item__link { margin-top: 1.25rem; }
.help-item__arrow { display: none; }

.price-item__desc { margin-top: 0.6rem; }
.price-item__figures { display: flex; flex-direction: column; gap: 0.3rem; margin-top: 1.1rem; }
.price-item__figure { font-size: 0.8125rem; }
.price-item__figure dt { display: inline; color: var(--ink-60); font-weight: 400; }
.price-item__figure dt::after { content: " — "; color: var(--ink-30); }
.price-item__figure dd { display: inline; margin: 0; font-weight: 700; color: var(--color-ink); }
.price-item__cta { margin-top: 1.25rem; }
.price-item__cta .btn { display: none; }
.price-item__cta .text-link { font-size: 0.8125rem; }

/* ---- numbered process ------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-m); }
.step__num { font-family: var(--font-display); font-weight: 900; font-size: 1.75rem; color: var(--color-nadzeya-yellow); line-height: 1; }
.step__title { margin-top: 1rem; font-weight: 700; }
.step__body { margin-top: 0.5rem; }
.steps__arrow { display: none; }
@media (min-width: 901px) {
  .steps { grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr; align-items: start; }
  .steps__arrow { display: flex; justify-content: center; padding-top: 0.35rem; color: var(--color-nadzeya-yellow); }
  .steps__arrow svg { width: 1.4rem; height: 1.4rem; animation: steps-arrow-nudge 1.6s ease-in-out infinite; }
}
@keyframes steps-arrow-nudge {
  0%, 100% { transform: translateX(0); opacity: 0.7; }
  50% { transform: translateX(5px); opacity: 1; }
}
@media (max-width: 900px) { .steps { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .steps { grid-template-columns: 1fr; } }

/* ---- photo grid (editorial) -------------------------------------------- */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}
.photo-grid .figure:nth-child(3n+1) { grid-column: span 2; }
@media (max-width: 760px) {
  .photo-grid { grid-template-columns: repeat(2, 1fr); }
  .photo-grid .figure:nth-child(3n+1) { grid-column: span 2; }
}

/* ---- form -------------------------------------------------------------- */
.form-field { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: var(--space-s); }
.form-field label { font-weight: 700; font-size: 0.95rem; }
.form-field .hint { font-weight: 400; color: var(--ink-60); font-size: 0.85rem; }
.form-field input,
.form-field textarea,
.form-field select {
  font-family: var(--font-primary);
  font-size: 1rem;
  padding: 0.95em 1em;
  border: 1.5px solid var(--color-ink);
  border-radius: 0;
  background: var(--color-white);
  color: var(--color-ink);
  width: 100%;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.form-field textarea { resize: vertical; min-height: 9rem; }
.form-field input:focus,
.form-field textarea:focus,
.form-field select:focus {
  outline: 2px solid var(--color-nadzeya-yellow);
  outline-offset: 1px;
  border-color: var(--color-ink);
}
.form-field select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M2 5l6 6 6-6' fill='none' stroke='%23111111' stroke-width='1.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 1em center;
  background-size: 0.9em;
  padding-right: 2.6em;
}
.form-check { display: flex; align-items: flex-start; gap: 0.75rem; margin: var(--space-s) 0; }
.form-check input {
  appearance: none;
  width: 1.15rem; height: 1.15rem;
  border: 1.5px solid var(--color-ink);
  flex: none;
  margin-top: 0.15em;
  position: relative;
  background: var(--color-white);
}
.form-check input:checked { background: var(--color-ink); }
.form-check input:checked::after {
  content: "";
  position: absolute; left: 3px; top: -1px;
  width: 5px; height: 9px;
  border-right: 1.5px solid var(--color-warm-ivory);
  border-bottom: 1.5px solid var(--color-warm-ivory);
  transform: rotate(45deg);
}
.form-check label { font-size: 0.9rem; color: var(--ink-60); }
.form-check a { color: var(--color-ink); border-bottom: 1px solid var(--ink-30); }
.form-status { margin-top: var(--space-s); padding: 1.5rem; border: var(--border-hair); display: none; }
.form-status.is-visible { display: block; }
.form-status--error { border-color: #b3261e; }

/* ---- footer -------------------------------------------------------------- */
.site-footer { background: var(--color-ink); color: var(--color-white); }
.site-footer .wordmark { color: var(--color-white); }
/* Three-column footer (homepage): brand + copyright on the left, social
   icons centered in the middle, legal documents stacked on the right. */
.site-footer__row {
  padding-top: 2rem;
  padding-bottom: 2rem;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: var(--space-l);
}
.site-footer__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.6rem; }
.site-footer__copyright { color: var(--white-70); font-size: 0.8rem; margin: 0; }
.site-footer__social { display: flex; align-items: center; gap: 1rem; justify-self: center; }
.site-footer__social a {
  display: flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem;
  border: 1.5px solid rgba(255,255,255,0.3);
  color: var(--color-white);
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.site-footer__social svg { width: 1.05rem; height: 1.05rem; }
.site-footer__social a:hover { border-color: var(--color-nadzeya-yellow); background: var(--color-nadzeya-yellow); color: var(--color-ink); }
.site-footer__legal {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  color: var(--white-70);
  font-size: 0.75rem;
  justify-self: end;
}
.site-footer__legal a:hover { color: var(--color-white); }
.site-footer__legal button { background: none; border: none; color: inherit; font-size: inherit; padding: 0; font-family: inherit; text-align: left; }
.site-footer__legal button:hover { color: var(--color-white); }
@media (max-width: 640px) {
  .site-footer__row { grid-template-columns: 1fr; justify-items: start; }
  .site-footer__social { justify-self: start; }
  .site-footer__legal { justify-self: start; }
}

/* ---- reveal on scroll --------------------------------------------------- */
[data-reveal] { opacity: 0; transform: translateY(14px); transition: opacity 620ms var(--ease), transform 620ms var(--ease); }
[data-reveal].is-visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ---- cookie banner -------------------------------------------------- */
.cookie-banner {
  position: fixed;
  right: var(--page-pad); bottom: var(--page-pad);
  left: var(--page-pad);
  max-width: 26rem;
  margin-left: auto;
  background: var(--color-white);
  border: 1.5px solid var(--color-ink);
  padding: var(--space-s);
  z-index: 200;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(1rem);
  transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease), visibility 0s linear var(--dur-base);
}
.cookie-banner.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease), visibility 0s linear;
}
.cookie-banner p { font-size: 0.9rem; color: var(--ink-60); margin-top: 0.6rem; }
.cookie-banner__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: var(--space-s); }
.cookie-banner__actions .btn { padding: 0.85em 1.3em; font-size: 0.85rem; }

/* ---- testimonials carousel ------------------------------------------------
   Infinite-loop, arrow- and swipe-driven. The track is padded with clones
   of the first/last cards so wrapping is seamless; see main.js. No autoplay
   — motion only happens on explicit user action, per the brand's restrained
   motion rule. */
.testimonial-carousel { position: relative; }
.testimonial-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  border-top: var(--border-hair-14);
  border-bottom: var(--border-hair-14);
}
.testimonial-track::-webkit-scrollbar { display: none; }
.testimonial {
  flex: 0 0 82%;
  aspect-ratio: 1 / 1;
  scroll-snap-align: start;
  border-right: var(--border-hair-14);
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.testimonial:first-child { border-left: var(--border-hair-14); }
.testimonial__stars { display: flex; gap: 0.2rem; flex: none; }
.testimonial__stars svg { width: 0.95rem; height: 0.95rem; fill: var(--color-nadzeya-yellow); }
.testimonial__quote {
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--ink-60);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 7;
  overflow: hidden;
}
.testimonial__name { font-weight: 700; font-size: 0.85rem; margin-top: auto; }
.testimonial__role { font-size: 0.75rem; color: var(--ink-30); margin-top: 0.15rem; }
@media (min-width: 560px) {
  .testimonial { flex-basis: 46%; }
}
@media (min-width: 901px) {
  .testimonial { flex-basis: 31%; }
}

/* ---- help section: one-line heading + edge-bleeding carousel ----------- */
.help__title {
  margin-bottom: var(--space-m);
  font-size: clamp(0.8125rem, 0.675rem + 0.65vw, 1.375rem);
}
/* Deliberate exception to the site's usual container alignment: this
   carousel runs edge to edge on both sides, cards spilling off-screen
   at the start and end, for a genuinely endless-scroll feel. */
.help__carousel-bleed {
  width: 100%;
}
.help__cta-row { display: flex; justify-content: flex-end; margin-top: var(--space-m); }
.help__cta-caveat {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: "Caveat", cursive;
  font-weight: 700;
  font-size: clamp(1.35rem, 1.2rem + 0.7vw, 1.9rem);
  color: var(--color-ink);
  transition: opacity var(--dur-fast) var(--ease);
}
.help__cta-caveat svg { width: 0.9em; height: 0.9em; transition: transform var(--dur-base) var(--ease); }
.help__cta-caveat:hover { opacity: 0.6; }
.help__cta-caveat:hover svg { transform: translate(0.12em, -0.12em); }

/* ---- service card carousel (photo squares, hover-reveal description) ---- */
.service-carousel { position: relative; }
/* On narrow screens the peeking edge card gets hard-cropped mid-word by
   the viewport, reading as broken text rather than an intentional "more
   to scroll" hint. Fading it out at the edge makes the crop look
   deliberate instead of like a layout bug. */
@media (max-width: 900px) {
  .service-carousel {
    -webkit-mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 56px), transparent 100%);
    mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 56px), transparent 100%);
  }
}
.service-track {
  display: flex;
  /* Auto-drift keeps it moving on its own, but — same as the reviews
     carousel — swipe/trackpad and the thin arrow buttons can take over
     and page it manually too; touch-action locks that manual drag to
     the horizontal axis so it can't also be dragged vertically. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  gap: 10px;
}
.service-track::-webkit-scrollbar { display: none; }
.service-card {
  position: relative;
  flex: 0 0 clamp(230px, 22vw, 320px);
  aspect-ratio: 1 / 1;
  scroll-snap-align: start;
  overflow: hidden;
  background: var(--color-ink);
  color: var(--color-white);
  display: block;
  /* Plain <div> now (it no longer links anywhere — see main.js), so the
     pointer cursor an <a> gets for free has to be set explicitly to keep
     the same "this is clickable" affordance. */
  cursor: pointer;
  transform: scale(1);
  transition: transform 650ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* A square card is too short to hold the longest title + full description
   once expanded (hover on desktop, tap on touch) below ~1300px, where the
   card's own width hasn't grown enough yet to make room — the text was
   getting clipped by the card's bottom edge instead of fully showing.
   Fixed, taller card here (measured against the longest title/description
   pairing) fits it with room to spare; above 1300px the card is wide
   enough that the square proportions already have enough height. */
@media (max-width: 1300px) {
  .service-card { aspect-ratio: auto; height: 360px; }
}
/* Hovering (or keyboard-focusing) one card eases it up while its
   neighbours ease back slightly — a single coordinated motion instead
   of one card abruptly popping on its own. */
.service-track:has(.service-card:hover) .service-card:not(:hover),
.service-track:has(.service-card:focus-visible) .service-card:not(:focus-visible),
.service-track:has(.service-card.is-active) .service-card:not(.is-active) {
  transform: scale(0.965);
}
.service-card:hover,
.service-card:focus-visible,
.service-card.is-active {
  transform: scale(1.06);
  z-index: 3;
}
.service-card img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.service-card::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(17,17,17,0) 40%, rgba(17,17,17,0.85) 100%);
  transition: background 300ms var(--ease);
}
.service-card:hover::after,
.service-card:focus-visible::after,
.service-card.is-active::after { background: rgba(17,17,17,0.82); }
.service-card__body {
  position: absolute; left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: var(--space-s);
}
.service-card__title {
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.25;
  /* Reserve room for two lines and pin text to the top of that box, so a
     one-line title and a two-line title both start at the same height —
     otherwise the bottom-anchored card body makes shorter titles sit
     lower than longer ones. */
  min-height: 2.5rem;
  display: flex;
  align-items: flex-start;
}
/* Below ~1045px the card's flex-basis clamp bottoms out at a fixed 230px,
   so the longest titles wrap to 3 lines instead of 2 — the reserved
   2-line box above was too short for that, so the rule/link underneath
   dropped lower on those cards than on their neighbours. Reserve a third
   line here so every card's rule lines up again. */
@media (max-width: 1045px) {
  .service-card__title { min-height: 3.75rem; }
}
.service-card__rule {
  width: 2.25rem;
  border-top: 1.5px solid var(--color-white);
  margin-top: 0.75rem;
}
.service-card__desc {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--white-70);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 300ms var(--ease), opacity 250ms var(--ease), margin-top 300ms var(--ease);
}
.service-card:hover .service-card__desc,
.service-card:focus-visible .service-card__desc,
.service-card.is-active .service-card__desc {
  max-height: 18rem;
  opacity: 1;
  margin-top: 0.75rem;
}
/* ---- services page (uslugi-i-tseny): tile grid, chip lists, detail panel ---- */
.chip-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chip-row .tag { font-size: 0.7rem; font-weight: 700; }

/* Single-column list with a small dot marker — the two-column version read
   as a jumbled block (unclear reading order); one column top-to-bottom
   with a disc bullet is unambiguous. */
.list-dots { list-style: disc outside; padding-left: 1.1em; display: flex; flex-direction: column; gap: 0.45rem; }
.list-dots li { font-size: 0.9rem; line-height: 1.6; }
.list-dots li::marker { color: var(--color-nadzeya-yellow); }

/* Narrower wrapper for the services page's full-width dark blocks — keeps
   them from stretching edge to edge of the usual --container-max. */
.container--narrow { max-width: 1120px; margin: 0 auto; padding-left: var(--page-pad); padding-right: var(--page-pad); }

/* Service grid — one uniform 3×3 grid of square photo tiles (visual index
   only: number + name). Every tile opens the SAME single detail panel
   below the grid — only one write-up is ever expanded at a time, and the
   grid itself never reflows or fragments into per-tile accordions. */
.service-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (max-width: 760px) { .service-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .service-grid { grid-template-columns: 1fr; } }

.tile {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--color-ink);
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--color-white);
  text-align: left;
  cursor: pointer;
}
.tile img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 650ms cubic-bezier(0.16, 1, 0.3, 1);
}
.tile:hover img, .tile:focus-visible img { transform: scale(1.05); }
.tile::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(17,17,17,0.05) 0%, rgba(17,17,17,0.35) 35%, rgba(17,17,17,0.9) 100%);
  transition: background 300ms var(--ease);
}
.tile[aria-expanded="true"]::after { background: rgba(17,17,17,0.85); }
.tile__body { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: var(--space-s); }
.tile__num { font-family: var(--font-display); font-weight: 900; font-size: 0.8rem; color: var(--color-nadzeya-yellow); }
.tile__title { margin-top: 0.35rem; font-family: var(--font-display); font-weight: 900; text-transform: uppercase; letter-spacing: -0.005em; font-size: clamp(0.95rem, 2.3vw, 1.15rem); line-height: 1.2; }
.tile__desc { margin-top: 0.5rem; font-size: 0.8rem; line-height: 1.5; color: var(--white-70); }
.tile[aria-expanded="true"] { outline: 3px solid var(--color-nadzeya-yellow); outline-offset: -3px; }

/* Shared detail panel — one collapsible block per category, all living
   directly under the grid; JS keeps at most one open (see main.js), so the
   panel always reads as a single clean area, never several at once. */
.service-panel { margin-top: var(--space-l); }
.service-tile__detail {
  max-height: 0;
  overflow: hidden;
  transition: max-height 420ms var(--ease);
}
.detail-text { text-align: justify; hyphens: none; }
@media (max-width: 640px) { .detail-text { text-align: left; hyphens: none; } }
.price-figure { color: var(--color-nadzeya-yellow); }

/* Service block headline — same Unbounded/uppercase treatment as .h2, but
   sized for a ~500px column instead of a full-width section, so a short
   name ("Создание сайтов") sits on one line and a longer one wraps with
   real breathing room between the two lines instead of .h2's line-height:1. */
.service-heading {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  font-size: clamp(1.4rem, 1.15rem + 1.1vw, 2rem);
  line-height: 1.2;
  /* Flush both edges like .detail-text below it, instead of ragged-right
     — with the wide (edge-to-edge) column these headings now sit in, a
     left-only rag looked inconsistent next to the justified answer
     text. No visible effect on the short 2-3 word titles this class is
     also used for elsewhere (justify only kicks in once a line wraps). */
  text-align: left;
  hyphens: none;
}

/* FAQ question — reuses the same .service-col-text/.service-col-photo
   accordion layout as the services list, but a full-sentence question
   set at .service-heading's uppercase/900-weight size would run 12+
   lines tall. Same display font for brand continuity, lighter weight,
   no uppercase, sized for reading a sentence rather than a 2-3 word
   name. */
.faq-question {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.005em;
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.15rem);
  line-height: 1.4;
  text-align: justify;
  hyphens: none;
}
/* FAQ items sit in .container (not the narrower .container--narrow) so
   their left edge lines up with the hero heading and the closing CTA
   above/below — with .container--narrow it was a page-width class
   narrower than everything around it, sitting ~120px further right at
   wide viewports. Question and answer both run the full container width
   too (overriding .measure's 40rem cap) — a capped column read as a
   stray island floating in the left half of an otherwise-empty section,
   same complaint as .hero__content/.page-hero__content before those lost
   their own max-width. */
.faq-measure { max-width: none; }

/* Caveat-script "Подробнее" toggle for a dark detail block — the filled
   yellow button stays the one CTA (consistent with every other button on
   the site); this is only the reveal-more affordance next to the short lead. */

.detail-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-family: "Caveat", cursive;
  font-weight: 700;
  font-size: clamp(1.05rem, 0.95rem + 0.45vw, 1.3rem);
  color: var(--color-nadzeya-yellow);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease);
}
.detail-toggle svg { width: 0.8em; height: 0.8em; transition: transform var(--dur-base) var(--ease); }
.detail-toggle:hover { opacity: 0.7; }
.detail-toggle[aria-expanded="true"] svg { transform: rotate(90deg); }

/* ---- reviews: rounded, Google-style, auto-scrolling ---------------------
   Deliberate contrast with the rest of the page's sharp editorial edges —
   reviews get soft corners, a star row and an initial avatar. Scrolling
   drifts continuously via the same [data-carousel] auto-drift as the
   homepage's service carousel (see main.js), but — unlike that one — this
   track also takes native swipe/trackpad scrolling and a pair of thin
   prev/next arrows (.carousel-nav), so once the drift is paused (hover,
   touch, focus) the visitor can keep paging manually; the drift itself
   just resumes a little while after they let go. Cards are a fixed,
   uniform footprint (same trick as .service-card): hovering/focusing one
   scales it up while the rest ease down slightly (via :has()); the quote
   itself doesn't grow the card — it unclamps into a scrollable area
   within the same box, so a long review is read by scrolling inside the
   (now larger, elevated) card, not by the row reflowing. Card widths are
   percentages of the track (not vw), so the row always holds a whole
   number of cards edge to edge — never a stray half-card peeking in. */
.review-scroller {
  display: flex;
  gap: 1.1rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Locks touch dragging to the horizontal axis only — without this a
     finger dragging the row is free to wander vertically too (the
     browser treats the gesture as ambiguous and lets it drift), which
     on a touch screen reads as the cards not being anchored in place. */
  touch-action: pan-x;
}
.review-scroller::-webkit-scrollbar { display: none; }
.review-scroller:has(.review-card:hover) .review-card:not(:hover),
.review-scroller:has(.review-card:focus-within) .review-card:not(:focus-within) {
  transform: scale(0.965);
}
.review-card {
  flex: 0 0 100%;
  height: 260px;
  scroll-snap-align: start;
  background: var(--color-white);
  border: 1.5px solid var(--ink-14);
  border-radius: 22px;
  padding: var(--space-s);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  overflow: hidden;
  transform: scale(1);
  transition: transform 400ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow var(--dur-base) var(--ease);
}
@media (min-width: 560px) {
  .review-card { flex-basis: calc((100% - 1.1rem) / 2); }
}
@media (min-width: 901px) {
  .review-card { flex-basis: calc((100% - 2 * 1.1rem) / 3); }
}
.review-card:hover, .review-card:focus-within {
  transform: scale(1.06);
  z-index: 5;
  box-shadow: 0 14px 36px rgba(17,17,17,0.16);
}
.review-card__head { display: flex; align-items: center; gap: 0.75rem; flex: none; }
.review-card__avatar {
  width: 2.75rem; height: 2.75rem;
  border-radius: 50%;
  background: var(--color-nadzeya-yellow);
  color: var(--color-ink);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 900; font-size: 1rem;
  flex: none;
}
.review-card__name { font-weight: 700; font-size: 0.9rem; }
.review-card__role { font-size: 0.75rem; color: var(--ink-30); margin-top: 0.1rem; }
.review-card__stars { display: flex; gap: 0.15rem; color: var(--color-nadzeya-yellow); flex: none; }
.review-card__stars svg { width: 0.85rem; height: 0.85rem; fill: currentColor; }
/* Plain max-height clipping instead of -webkit-line-clamp — clamp toggling
   is flaky across engines when combined with a flex child; max-height is
   plain CSS1 and transitions cleanly. */
.review-card__quote {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-60);
  flex: 1;
  max-height: 4.7em;
  overflow: hidden;
  transition: max-height var(--dur-base) var(--ease);
}
.review-card:hover .review-card__quote,
.review-card:focus-within .review-card__quote {
  max-height: 1000px;
  overflow-y: auto;
}
.review-carousel { width: 100%; }

/* Thin prev/next arrows next to the reviews heading — ghost circles, no
   fill, matching the site's restrained line-work rather than looking like
   a bolted-on slider widget. */
.carousel-nav { display: flex; gap: 0.5rem; flex: none; }
.carousel-nav__btn {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  border: 1.5px solid var(--ink-14);
  background: transparent;
  color: var(--color-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.carousel-nav__btn svg { width: 1rem; height: 1rem; }
.carousel-nav__btn:hover, .carousel-nav__btn:focus-visible {
  border-color: var(--color-ink);
  background: var(--color-nadzeya-yellow);
}

/* ---- misc page bits ---------------------------------------------------- */
.kicker-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-s); flex-wrap: wrap; }
.tag {
  display: inline-block;
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.4em 0.75em;
  border: 1px solid var(--color-ink);
}
.tag--yellow { background: var(--color-nadzeya-yellow); border-color: var(--color-nadzeya-yellow); }
.divider-dotted { border: none; border-top: 1.5px dotted var(--ink-30); }
.legal h2 { margin-top: var(--space-l); }
.legal h3 { margin-top: var(--space-m); }
.legal p, .legal li { color: var(--ink-60); }
.legal p + p, .legal ul { margin-top: 1rem; }
.legal li { margin-top: 0.5rem; }
.legal ul { padding-left: 1.25rem; list-style: disc; }
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--color-nadzeya-yellow); color: var(--color-ink);
  padding: 0.75em 1.25em; font-weight: 700;
}
.skip-link:focus { left: var(--page-pad); top: var(--page-pad); }
