/* =========================================================================
   SEXY CERAMIC — Design System
   The visual grammar is a direct port of the Oravo dental template:
   full-bleed dark hero with the navbar laid over the photo and the copy
   anchored to the bottom, 28px rounded section caps, white / tinted
   alternating bands, outlined pill section titles, 12px cards, pill buttons
   carrying a circular gradient arrow on the left, and a dark rounded footer.

   Oravo's tokens are remapped onto the Sexy Ceramic brand:
     blue #1E5AFF          -> pink   #E01070
     gradient #0452FF/#4E8FFF -> #C50D62 / #F3499A
     tint  #EAF2FF         -> #FDECF3
     dark  #002156         -> #3A0619
     heading #060C16       -> #0D0A0F
   Type stays Onest + Manrope. Oravo's Geist is not used.
   ========================================================================= */

/* ---------- 1. TOKENS ---------- */
:root {
  /* Surfaces */
  --white:      #FFFFFF;
  --tint:       #FDECF3;   /* Oravo light-blue #EAF2FF */
  --tint-soft:  #FEF6F9;
  --surface:    #FAFAFA;

  /* Text */
  --ink:        #0D0A0F;   /* Oravo heading #060C16 */
  --body:       #646464;   /* Oravo paragraph #646464 */
  --muted:      #8F9197;   /* Oravo gray-one #8F9197 */

  /* Lines */
  --line:       #E9E5E8;   /* Oravo pale-grey #E9EDF0 */
  --line-tint:  #F3DCE7;   /* hairline on tinted bands */
  --pastel:     #D7D0D4;   /* Oravo pastel-grey #C9C9D0 */

  /* Brand */
  --pink:       #E01070;
  --pink-hover: #C50D62;
  --pink-ink:   #B00A57;
  --pink-wash:  #FBDDE9;
  --grad:       linear-gradient(90deg, #C50D62, #F3499A);
  --grad-soft:  linear-gradient(120deg, #E01070, #F3499A);

  /* Dark band, derived from the brand pink (Oravo blue-dark #002156) */
  --deep:        #3A0619;
  --deep-2:      #4A0A22;
  --on-deep:     #FFFFFF;
  --on-deep-mute:#D8C3CC;   /* Oravo footer link grey #D4D3D3 */

  --danger:     #C8102E;

  /* Type */
  --font-display: 'Onest', 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body:    'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Oravo scale: h1 80 / h2 60 / h3 48 / h4 40 / h5 36 / h6 24 */
  --fs-h1:  clamp(2.6rem, 6vw, 5rem);
  --fs-h2:  clamp(1.9rem, 4vw, 3rem);
  --fs-h3:  clamp(1.5rem, 2.6vw, 2.25rem);
  --fs-h4:  clamp(1.15rem, 1.8vw, 1.5rem);
  --fs-xl:  1.25rem;      /* Oravo paragraph-extra-large 20 */
  --fs-lg:  1.125rem;     /* Oravo paragraph-large 18 */
  --fs-body: 1rem;
  --fs-sm:  0.875rem;     /* Oravo f14 */

  /* Rhythm — Oravo section padding 100, container 1260 / 60 */
  --sec-pad:  clamp(64px, 8vw, 100px);
  --sec-half: clamp(36px, 5vw, 50px);
  --gutter:   clamp(20px, 5vw, 60px);      /* Oravo container-padding 60px */
  --maxw:     1620px;

  /* Shape — Oravo radii */
  --r-28:    28px;
  --r-24:    24px;
  --r-20:    20px;
  --r-16:    16px;
  --r-card:  12px;
  --r-8:     8px;
  --r-pill:  200px;

  --shadow:      0 4px 24px rgba(13, 10, 15, 0.06);
  --shadow-soft: 0 2px 10px rgba(13, 10, 15, 0.04);
  --shadow-lift: 0 14px 40px rgba(13, 10, 15, 0.10);

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --header-h: 98px;
}

/* ---------- 2. RESET & BASE ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  /* The page canvas takes its colour from the root, and the root is what the
     browser paints in the rubber-band gutter above the hero and under the
     footer. Left on the body's white it read as a blank screen appearing
     below the dark footer on every touch device; the footer tone makes the
     overscroll look like the footer simply continues. */
  background: var(--deep);
}

body {
  margin: 0;
  background: var(--white);
  color: var(--body);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.5;              /* Oravo line-height-150 */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* overflow-x: hidden makes the element a scroll container. On the body that
   means iOS Safari gives the page a second, taller scroll box of its own and
   lets the user drag past the footer into blank space. overflow: clip does the
   same clipping without ever creating a scroll container, so where it exists
   both the root and the body use it, and the lock below moves to the root to
   match (a clipped root no longer inherits the body's overflow). */
@supports (overflow: clip) {
  html { overflow-x: clip; }
  body { overflow-x: clip; }
  html.is-locked { overflow: hidden; }
}
/* the drawer and the modal lock the page the same way, and pay back the same
   scrollbar track, so opening one never nudges the page sideways either */
body.is-locked { overflow: hidden; padding-right: var(--sbw, 0px); }
body.is-locked .header { padding-right: var(--sbw, 0px); }

img, video { max-width: 100%; display: block; }
/* Photographs ship as WebP with a JPEG beside them, so every one of them is
   wrapped in <picture>. display: contents keeps the wrapper out of the box
   tree, so the <img> stays the flex item / grid item its rules were written
   against and no layout had to change to gain the smaller files. */
picture { display: contents; }
figure, figcaption { margin: 0; }
button { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;              /* Oravo headings run at 500 */
  line-height: 1.1;              /* Oravo line-height-110 */
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h3); }        /* Oravo section headings use .h3 = 48px */
h3 { font-size: var(--fs-h4); line-height: 1.25; }
h4 { font-size: var(--fs-xl); font-weight: 600; line-height: 1.3; }

p { margin: 0; }

::selection { background: var(--pink); color: #fff; }

:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip-link {
  position: absolute;
  left: 16px; top: -100px;
  z-index: 300;
  background: var(--pink);
  color: #fff;
  padding: 12px 20px;
  border-radius: var(--r-pill);
  font-weight: 600;
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 16px; }

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

/* ---------- 3. LAYOUT ---------- */
.shell {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--sec-pad); position: relative; }
.section--tint { background: var(--tint); }
.section--pt-half { padding-top: var(--sec-half); }
.section--pb-half { padding-bottom: var(--sec-half); }

.lead {
  font-size: var(--fs-lg);
  line-height: 1.5;
  color: var(--body);
}

/* Oravo .section-title — outlined white pill above every section heading */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 20px;
  border: 2px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--white);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.17;
  color: var(--ink);
  width: fit-content;
}

/* Oravo .section-heading-wrap (centered) and left variant */
.sec-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
  margin-bottom: 40px;
}
.sec-head h2 { max-width: 18ch; }
.sec-head .lead { max-width: 62ch; }

.sec-head--left {
  align-items: flex-start;
  text-align: left;
  max-width: 680px;               /* Oravo .service-title-heading-wrap */
}
.sec-head--left h2 { max-width: 22ch; }

/* Oravo .case-study-heading-button-wrap — heading left, button right */
.sec-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  margin-bottom: 40px;
}
/* inside a row the gap does the spacing, so the head does not add its own */
.sec-row .sec-head--left { margin-bottom: 0; }

/* ---------- 4. BUTTONS (Oravo pill, circular gradient arrow on the left) ---------- */
.btn {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  padding: 8px 24px 8px 8px;
  border: 1px solid var(--pastel);
  border-radius: var(--r-pill);
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  overflow: hidden;
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease), color 0.4s var(--ease);
}
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--grad);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
.btn:hover { border-color: transparent; color: #fff; }
.btn:hover::before { opacity: 1; }
.btn:active { transform: translateY(1px); }

.btn__ico {
  flex: none;
  width: 40px; height: 40px;
  border-radius: 50%;
  background-image: var(--grad);
  color: #fff;
  display: grid;
  place-items: center;
  transition: background-color 0.4s var(--ease), color 0.4s var(--ease);
}
.btn__ico svg { width: 18px; height: 18px; transition: transform 0.4s var(--ease); }
.btn:hover .btn__ico { background-image: none; background-color: #fff; color: var(--pink-hover); }
.btn:hover .btn__ico svg { transform: translateX(2px); }

.btn__label { display: block; }

/* filled variant for the highest emphasis surfaces */
.btn--solid { background: var(--pink); border-color: var(--pink); color: #fff; }
.btn--solid .btn__ico { background-image: none; background-color: rgba(255, 255, 255, 0.22); color: #fff; }
.btn--solid:hover .btn__ico { background-color: #fff; color: var(--pink-hover); }

/* on dark surfaces */
.btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.34);
  color: #fff;
}
.btn--ghost:hover { color: #fff; }

/* Oravo .button-primary-small — 24px arrow */
.btn--sm { padding: 6px 18px 6px 6px; gap: 10px; font-size: var(--fs-sm); white-space: nowrap; }
.btn--sm .btn__ico { width: 30px; height: 30px; }
.btn--sm .btn__ico svg { width: 14px; height: 14px; }

.btn--block { width: 100%; justify-content: center; }

/* ---------- 5. CARD ---------- */
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(20px, 2.4vw, 28px) clamp(18px, 2vw, 24px);
}
.card--tint { background: var(--tint); }

/* ---------- 6. HEADER (laid over the hero, solid once scrolled) ---------- */
/* Oralic navbar grammar: links left, logo centred, actions right, in a
   translucent full-width bar that blurs whatever scrolls under it. */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 120;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  transition: transform 0.45s var(--ease), background-color 0.45s var(--ease),
              border-color 0.45s var(--ease), box-shadow 0.45s var(--ease);
}
/* Once the bar is solid there is nothing translucent left to blur, and a
   live backdrop-filter under a fixed element is re-computed on every scrolled
   frame. Dropping it there is most of the difference on a phone. */
.header[data-top='false'] {
  box-shadow: var(--shadow-soft);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.header[data-top='true'] {
  background: rgba(13, 10, 15, 0.28);
  border-color: rgba(255, 255, 255, 0.18);
}

.header__inner {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: 8px var(--gutter);
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 16px;
}

.brand { flex: none; display: flex; align-items: center; }
.brand img { width: 82px; height: 82px; object-fit: contain; }

/* the links live inside one outlined capsule, the current section filled */
.nav {
  /* the capsule sits just past the logo; the actions take the slack on the
     right, so nothing can collide the way a fixed grid track would */
  margin-left: clamp(16px, 3vw, 48px);
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--white);
  transition: background-color 0.45s var(--ease), border-color 0.45s var(--ease);
}
.nav a {
  padding: 9px 18px;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--body);
  white-space: nowrap;
  transition: background-color 0.3s var(--ease), color 0.3s var(--ease);
}
.nav a:hover { color: var(--ink); background: var(--tint); }
.nav a[aria-current='true'] { background: var(--pink); color: #fff; }
.nav a[aria-current='true']:hover { background: var(--pink); color: #fff; }

.header[data-top='true'] .nav { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.28); }
.header[data-top='true'] .nav a { color: rgba(255, 255, 255, 0.78); }
.header[data-top='true'] .nav a:hover { color: #fff; background: rgba(255, 255, 255, 0.14); }
.header[data-top='true'] .nav a[aria-current='true'] { background: var(--pink); color: #fff; }

.header__side { flex: none; margin-left: auto; display: flex; align-items: center; justify-content: flex-end; gap: 12px; }

/* Instagram and Telegram, the two channels people actually write on. They sit
   between the phone number and the language switch, in the same outlined
   grammar as the rest of the bar. */
.header__social { display: flex; align-items: center; gap: 6px; flex: none; }
.isocial {
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--white);
  color: var(--ink);
  transition: background-color 0.35s var(--ease), border-color 0.35s var(--ease),
              color 0.3s var(--ease), transform 0.35s var(--ease);
}
.isocial svg { width: 19px; height: 19px; display: block; }
.isocial:hover { color: var(--pink); border-color: var(--pink-wash); background: var(--pink-wash); }
.isocial:active { transform: scale(0.96); }
.isocial:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

.header[data-top='true'] .isocial {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.3);
  color: #fff;
}
.header[data-top='true'] .isocial:hover { background: rgba(255, 255, 255, 0.22); color: #fff; }
body.is-locked .header[data-top='true'] .isocial {
  background: var(--white); border-color: var(--line); color: var(--ink);
}

.header__tel {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
  transition: color 0.45s var(--ease);
}
.header__tel:hover { color: var(--pink); }
.header[data-top='true'] .header__tel { color: #fff; }

.lang {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--white);
  flex: none;
  transition: background-color 0.45s var(--ease), border-color 0.45s var(--ease);
}
.lang button {
  border: 0;
  background: none;
  border-radius: var(--r-pill);
  padding: 5px 12px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted);
  cursor: pointer;
  transition: background-color 0.3s var(--ease), color 0.3s var(--ease);
}
.lang button[aria-pressed='true'] { background: var(--pink); color: #fff; }
.lang button:hover:not([aria-pressed='true']) { color: var(--ink); }
.header[data-top='true'] .lang { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.3); }
.header[data-top='true'] .lang button:not([aria-pressed='true']) { color: rgba(255, 255, 255, 0.8); }
.header[data-top='true'] .lang button:hover:not([aria-pressed='true']) { color: #fff; }

.burger {
  display: none;
  position: relative;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--white);
  cursor: pointer;
  flex: none;
  transition: background-color 0.45s var(--ease), border-color 0.45s var(--ease);
}
.burger span {
  position: absolute;
  left: 13px;
  width: 16px; height: 1.6px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.4s var(--ease), background-color 0.45s var(--ease);
}
.burger span:nth-child(1) { top: 18px; }
.burger span:nth-child(2) { top: 24px; }
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(3px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

/* While the drawer (or a modal) locks the page the header can no longer sit
   transparent over the hero: it would float above a white surface. */
body.is-locked .header[data-top='true'] { background: var(--white); border-color: var(--line); }
body.is-locked .header[data-top='true'] .header__tel { color: var(--ink); }
body.is-locked .header[data-top='true'] .nav { background: var(--white); border-color: var(--line); }
body.is-locked .header[data-top='true'] .nav a { color: var(--body); }
body.is-locked .header[data-top='true'] .nav a[aria-current='true'] { background: var(--pink); color: #fff; }
body.is-locked .header[data-top='true'] .lang,
body.is-locked .header[data-top='true'] .burger { background: var(--white); border-color: var(--line); }
body.is-locked .header[data-top='true'] .burger span { background: var(--ink); }
body.is-locked .header[data-top='true'] .lang button:not([aria-pressed='true']) { color: var(--muted); }
.header[data-top='true'] .burger { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.3); }
.header[data-top='true'] .burger span { background: #fff; }

/* Mobile drawer */
.drawer {
  position: fixed;
  inset: var(--header-h) 0 0 0;
  z-index: 110;
  background: var(--white);
  padding: 30px var(--gutter) calc(30px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease), visibility 0.4s;
}
.drawer[data-open='true'] { opacity: 1; visibility: visible; transform: none; }

.drawer__nav { display: flex; flex-direction: column; }
.drawer__nav a {
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  transition-delay: calc(var(--i, 0) * 45ms);
}
.drawer[data-open='true'] .drawer__nav a { opacity: 1; transform: none; }

.drawer__foot { margin-top: auto; padding-top: 28px; display: flex; flex-direction: column; gap: 18px; }
.drawer__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.drawer__link { font-size: 1rem; font-weight: 600; color: var(--ink); }
.drawer__link:hover { color: var(--pink); }

/* ---------- 7. HERO (Oravo .home-one-banner-section) ---------- */
.hero {
  position: relative;
  z-index: 1;
  min-height: 100dvh;
  display: flex;
  align-items: flex-end;
  padding-top: calc(var(--header-h) + 40px);
  padding-bottom: clamp(40px, 6vw, 80px);
  border-bottom-left-radius: var(--r-28);
  border-bottom-right-radius: var(--r-28);
  /* Both hero photographs are shot on their own black field. A plum base and
     a plum scrim over them read as a colour wash laid on the picture, so the
     whole frame is neutral: the photograph's own background runs to the edges
     of the section and what you see is the picture, not a tint of it. */
  background: #050505;
  overflow: hidden;
}

.hero__bg { position: absolute; inset: 0; z-index: -1; }

.hero__photo {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* the panel dissolves into the dark base before the copy block, so the
     headline and buttons always sit on a clean field */
  -webkit-mask-image: linear-gradient(180deg, #000 0 66%, rgba(0, 0, 0, 0.3) 80%, transparent 92%);
  mask-image: linear-gradient(180deg, #000 0 66%, rgba(0, 0, 0, 0.3) 80%, transparent 92%);
}
.hero__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 34%;   /* the portrait is centred, so the crop is too */
}

/* Oravo .banner-image-overlay */
.hero__overlay {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(45deg, rgba(5, 5, 5, 0.86), rgba(5, 5, 5, 0.6) 30%, rgba(5, 5, 5, 0.28) 64%, transparent),
    linear-gradient(0deg, rgba(5, 5, 5, 0.9), rgba(5, 5, 5, 0.6) 24%, rgba(5, 5, 5, 0.2) 52%, transparent 76%);
}

/* On a phone the copy runs the full height of the hero, so the photo sits in
   the upper band and the scrim carries most of the frame. */
@media (max-width: 767px) {
  /* Phones get their own portrait frame (media/hero-mobile.jpg, picked by the
     <picture> in index.html). It carries its own black field on the left, so
     the panel takes the upper two thirds of the hero, holds its tone a little
     longer than the desktop crop does, and the headline lands on the dark
     side of the frame with the smile beside it. */
  .hero__photo {
    inset: 0 0 auto 0;
    height: 66%;
    -webkit-mask-image: linear-gradient(180deg, #000 0 72%, rgba(0, 0, 0, 0.3) 85%, transparent 96%);
    mask-image: linear-gradient(180deg, #000 0 72%, rgba(0, 0, 0, 0.3) 85%, transparent 96%);
  }
  /* the face sits right of centre and the smile sits low in that frame, so
     the crop is pulled that way instead of holding the middle */
  .hero__photo img { object-position: 62% 62%; }
  /* the copy runs down the middle of the frame here, so the scrim is stronger
     at the foot of the section than the desktop one and clears the face */
  .hero__overlay {
    background-image: linear-gradient(0deg,
      rgba(5, 5, 5, 0.94),
      rgba(5, 5, 5, 0.86) 40%,
      rgba(5, 5, 5, 0.52) 62%,
      rgba(5, 5, 5, 0.16) 82%,
      rgba(5, 5, 5, 0));
  }
}

.hero .shell { position: relative; z-index: 1; width: 100%; }

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 36px;
  align-items: end;
}

.hero__copy { display: flex; flex-direction: column; gap: clamp(28px, 4vw, 44px); }

.hero h1 { color: #fff; max-width: 15ch; }

.hero__lead { color: #fff; font-size: var(--fs-lg); max-width: 56ch; }

.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; }

/* Oravo .banner-rating-card — frosted glass block */
.hero__card {
  padding: 24px;
  border-radius: var(--r-20);
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.3);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: 100%;
  max-width: 360px;
}
/* Oravo .rating-count-wrap */
.hero__count {
  display: flex;
  align-items: flex-start;
  gap: 4px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  color: #fff;
}
.hero__count-n { font-size: clamp(3rem, 5vw, 4.25rem); }
.hero__count-s { font-size: clamp(1.5rem, 2.4vw, 2.125rem); color: var(--pink); line-height: 1.1; }

/* Oravo .rating-image-text-wrap */
.hero__clients { display: flex; align-items: center; gap: 14px; }
.hero__clients-label { min-width: 0; }
.hero__avatars { display: flex; align-items: center; flex: none; }
.hero__avatars img,
.hero__avatars-more {
  width: 52px; height: 52px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.85);
  object-fit: cover;
  object-position: 50% 50%;   /* each crop is already centred on the smile */
  flex: none;
}
/* The circles sit as a stack, each one tucked under the next. Fourteen pixels
   of overlap hid a third of every photo; twelve reads clearly as a stack and
   still leaves each smile whole.
   The photographs are wrapped in <picture>, which is display: contents and so
   generates no box of its own, so the overlap has to land on the boxes that do
   exist: the images themselves and the plus badge. */
.hero__avatars > * + * img,
.hero__avatars > * + .hero__avatars-more { margin-left: -12px; }
.hero__avatars-more {
  background: #fff;
  color: var(--pink);
  display: grid;
  place-items: center;
}
.hero__avatars-more svg { width: 20px; height: 20px; }
.hero__clients-label {
  font-size: var(--fs-lg);
  line-height: 1.25;
  color: #fff;
  max-width: 9ch;
}

/* ---------- 8. CASES ---------- */
/* Oravo .case-study-card — white card, text left, media right */
.case-card {
  padding: clamp(16px, 2vw, 20px);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--white);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
.case-card__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 18px;
  padding: clamp(8px, 2vw, 26px);
}
.case-card__copy p { max-width: 46ch; }

.compare {
  position: relative;
  border-radius: var(--r-8);
  overflow: hidden;
  aspect-ratio: 1123 / 1400;
  background: var(--surface);
  isolation: isolate;
  touch-action: pan-y;
}
.compare img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.compare__after { clip-path: inset(0 0 0 var(--pos, 50%)); }
.compare__handle {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--pos, 50%);
  width: 2px;
  background: rgba(255, 255, 255, 0.9);
  transform: translateX(-1px);
  pointer-events: none;
}
.compare__knob {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--pink);
  display: grid; place-items: center;
  box-shadow: 0 6px 20px rgba(13, 10, 15, 0.26);
}
.compare__knob svg { width: 20px; height: 20px; }
.compare__tag {
  position: absolute;
  top: 14px;
  padding: 6px 14px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.94);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--ink);
  pointer-events: none;
}
.compare__tag--before { left: 14px; }
.compare__tag--after { right: 14px; background: var(--pink); color: #fff; }
.compare__range {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  cursor: ew-resize;
  margin: 0;
}
.compare:has(.compare__range:focus-visible) { outline: 2px solid var(--pink); outline-offset: 3px; }

.hint { display: inline-flex; align-items: center; gap: 10px; font-size: var(--fs-sm); color: var(--muted); }
.hint svg { width: 16px; height: 16px; flex: none; color: var(--pink); }

/* Case rail — Oravo .blog-cards-wrap grammar */
.rail-wrap { margin-top: clamp(40px, 5vw, 60px); }
.rail-head { margin-bottom: 20px; }

.rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(230px, 1fr);
  gap: 16px;
  overflow-x: auto;
  /* overflow-x: auto alone makes the other axis a scrollport too, and a
     mandatory x-snap container then swallows vertical swipes instead of
     letting the page scroll. Pinning overflow-y hands the gesture back. */
  overflow-y: hidden;
  /* proximity, not mandatory: a mandatory container fights every flick that
     does not end exactly on a card, which is what read as lag on a phone */
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 14px;
  scrollbar-width: thin;
  scrollbar-color: var(--pink-wash) transparent;
}
.rail::-webkit-scrollbar { height: 5px; }
.rail::-webkit-scrollbar-track { background: var(--line); border-radius: 5px; }
.rail::-webkit-scrollbar-thumb { background: var(--pink-wash); border-radius: 5px; }

.rail-card {
  scroll-snap-align: start;
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
}
.rail-card__media {
  display: block;
  border-radius: var(--r-card);
  overflow: hidden;
  aspect-ratio: 719 / 900;
  background: var(--surface);
}
.rail-card img { width: 100%; height: 100%; object-fit: cover; }

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 48px);
  background: rgba(13, 10, 15, 0.86);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
.lightbox[data-open='true'] { opacity: 1; visibility: visible; }
.lightbox img {
  max-width: min(100%, 620px);
  max-height: 88dvh;
  width: auto;
  border-radius: var(--r-card);
  transform: scale(0.97);
  transition: transform 0.45s var(--ease);
}
.lightbox[data-open='true'] img { transform: none; }

.icon-close {
  position: absolute;
  top: clamp(14px, 3vw, 28px);
  right: clamp(14px, 3vw, 28px);
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  display: grid; place-items: center;
  cursor: pointer;
  transition: transform 0.4s var(--ease), background-color 0.3s var(--ease);
}
.icon-close:hover { transform: rotate(90deg); }
.icon-close svg { width: 15px; height: 15px; }

/* ---------- 9. TESTIMONIAL MARQUEE (Oravo .testimonial-section) ----------
   Dark band + edge-to-edge running rail of cards. The rail is a native
   horizontal scroller driven by rAF, so it can be swiped and dragged as well
   as run on its own. It stops while the pointer is over it, while a card has
   keyboard focus and while a video is playing, so nothing is pulled away from
   under the reader. Cards recycle from head to tail, so the loop is seamless
   with a single copy of every video in the DOM.                            */
.section--deep {
  background: var(--deep);
  color: var(--on-deep-mute);
  border-radius: var(--r-28);
  overflow: hidden;
}
.section--deep h2 { color: #fff; }

.badge--deep {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.34);
  color: #fff;
}

.rev-head {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-bottom: clamp(40px, 5vw, 64px);
}
.rev-head__title {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  max-width: 620px;
}
.rev-head__title h2 { max-width: 16ch; }
.rev-head__lead {
  margin: 0;
  max-width: 46ch;
  font-size: var(--fs-lg);
  line-height: 1.5;
  color: var(--on-deep-mute);
}

/* the rail itself */
.tmq {
  --tmq-gap: clamp(14px, 1.5vw, 24px);
  overflow: hidden;
  /* the belt is driven by a transform, so the browser keeps the vertical page
     scroll and the horizontal gesture comes to js/app.js as a drag */
  touch-action: pan-y;
  cursor: grab;
}
.tmq[data-drag='true'] { cursor: grabbing; }
.tmq::-webkit-scrollbar { width: 0; height: 0; display: none; }

.tmq__track {
  display: flex;
  align-items: stretch;
  gap: var(--tmq-gap);
  width: max-content;
  will-change: transform;
}

/* Snap mode (touch screens and reduced motion). js/app.js takes the belt
   apart: no clones, no transform, no animation frame. What is left is a
   native scroller, which is the smoothest thing a phone can do. */
.tmq[data-static='true'] {
  overflow-x: auto;
  overflow-y: hidden;
  touch-action: pan-x pan-y;
  cursor: default;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  scroll-padding-inline: var(--gutter);
}
.tmq[data-static='true'] .tmq__track {
  transform: none;
  will-change: auto;
  padding-inline: var(--gutter);
}
.tmq[data-static='true'] .tcard { scroll-snap-align: center; }

/* one testimonial — shell in brand tint, white blocks inside */
.tcard {
  flex: 0 0 auto;
  width: clamp(268px, 26vw, 380px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px;
  border-radius: var(--r-28);
  background: var(--tint);
}
@media (hover: hover) and (pointer: fine) {
  .tcard { transition: transform 0.5s var(--ease); }
  .tmq .tcard:hover { transform: translateY(-4px); }
}

.tcard__media {
  position: relative;
  aspect-ratio: 5 / 7;
  border-radius: var(--r-20);
  background: var(--white);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 2.4vw, 28px);
  padding: clamp(22px, 2.6vw, 34px) clamp(16px, 2vw, 24px);
  text-align: center;
}
.tcard--video .tcard__media { padding: 0; background: var(--ink); }

/* preload="metadata" is enough for the browser to paint the video's own first
   frame, so the card shows a real frame of the review rather than a separate
   cover image. */
.tcard--video video {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--ink);
}

.tcard__qmark { flex: none; width: 50px; height: 38px; color: var(--pink); opacity: 0.3; }
.tcard__qmark svg { display: block; width: 100%; height: 100%; }

.tcard__quote {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.0625rem, 1.4vw, 1.3rem);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* video overlay */
.tcard__play {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%; height: 100%;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: linear-gradient(transparent 40%, rgba(13, 10, 15, 0.5));
  cursor: pointer;
  transition: opacity 0.35s var(--ease);
}
.tcard[data-playing='true'] .tcard__play { opacity: 0; pointer-events: none; }
.tcard__play:focus-visible { outline: 2px solid var(--pink); outline-offset: -4px; }

.tcard__play-dot {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 62px; height: 62px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94);
  color: var(--pink);
  display: grid;
  place-items: center;
  transition: transform 0.4s var(--ease);
}
.tcard__play:hover .tcard__play-dot { transform: translate(-50%, -50%) scale(1.08); }
.tcard__play-dot svg { width: 20px; height: 20px; margin-left: 3px; }

/* author bar */
.tcard__body {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border-radius: var(--r-20);
  background: var(--white);
}
.tcard__mono {
  flex: none;
  width: 48px; height: 48px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--pink-wash);
  color: var(--pink-ink);
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1;
}
.tcard__mono--film { background: none; background-image: var(--grad); color: #fff; }
.tcard__mono--film svg { width: 17px; height: 17px; display: block; }
.tcard__mono--film .ico-play { margin-left: 2px; }

/* the same circle in the author bar doubles as the play / pause control */
button.tcard__mono {
  padding: 0;
  border: 0;
  cursor: pointer;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
button.tcard__mono:hover { transform: scale(1.07); }
button.tcard__mono:active { transform: scale(0.97); }
button.tcard__mono:focus-visible { outline: 2px solid var(--pink); outline-offset: 3px; }

.tcard__mono--film .ico-pause { display: none; }
.tcard[data-playing='true'] .tcard__mono--film .ico-play { display: none; }
.tcard[data-playing='true'] .tcard__mono--film .ico-pause { display: block; }

.tcard__info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  text-align: left;
}
.tcard__name {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.tcard__role { font-size: var(--fs-sm); color: var(--muted); }

@media (min-width: 992px) {
  .rev-head {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-end;
    gap: 48px;
  }
  .rev-head__lead { max-width: 34ch; text-align: right; }
}

/* ---------- 10. STAGES (Oralic .intro-tabs) ----------
   A column of expanding steps on the left, one tall image on the right that
   swaps with the open step.                                                 */
.scope {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(16px, 2vw, 20px);
  align-items: stretch;
}

/* the list keeps its natural height: an open step is exactly as tall as its
   own copy, and the photo keeps its own portrait proportions */
.scope__list { display: flex; flex-direction: column; gap: 8px; align-self: start; }
.scope__item { flex: 0 0 auto; }

.scope__item {
  border-radius: var(--r-16);
  border: 1px solid transparent;
  background: var(--tint-soft);
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.scope__item[data-open='true'] { background: var(--tint); border-color: var(--line-tint); }

.scope__title { margin: 0; }
.scope__head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: clamp(18px, 2vw, 24px);
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  border-radius: var(--r-16);
}
.scope__head:focus-visible { outline: 2px solid var(--pink); outline-offset: -3px; }

.scope__ico {
  flex: none;
  width: 46px; height: 46px;
  border-radius: var(--r-8);
  background: var(--white);
  color: var(--pink);
  display: grid;
  place-items: center;
  transition: color 0.4s var(--ease);
}
.scope__ico svg { width: 22px; height: 22px; }
.scope__item[data-open='false'] .scope__ico { color: var(--muted); }
.scope__head:hover .scope__ico { color: var(--pink); }

.scope__t {
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--ink);
  transition: color 0.3s var(--ease);
}
.scope__head:hover .scope__t { color: var(--pink-ink); }

.scope__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s var(--ease);
}
.scope__item[data-open='true'] .scope__panel { grid-template-rows: 1fr; }
.scope__panel > div { overflow: hidden; }
.scope__panel p {
  margin: 0;
  max-width: 52ch;
  padding: 0 clamp(18px, 2vw, 24px) clamp(18px, 2vw, 24px);
}

.scope__media {
  position: relative;
  align-self: start;
  aspect-ratio: 719 / 900;
  border-radius: var(--r-16);
  overflow: hidden;
  background: var(--surface);
}
.scope__media img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* the case photographs are shot close and lit warm, and on this pale band
     they were reading much darker than the rest of the section */
  filter: brightness(1.14) contrast(0.97) saturate(1.02);
  transition: opacity 0.35s var(--ease);
}
.scope__media[data-swapping='true'] img { opacity: 0; }

/* Oravo .choose-us-overlay, kept for the duration chip */
.scope__overlay {
  position: absolute;
  inset: 0;
  padding: 0 24px 28px;
  display: flex;
  align-items: flex-end;
  pointer-events: none;
  /* only as much shade as the duration chip needs to stay readable */
  background-image: linear-gradient(transparent 52%, rgba(13, 10, 15, 0.44));
}
.scope__overlay > span { display: flex; flex-direction: column; gap: 4px; }
.scope__overlay .k { font-size: var(--fs-sm); color: rgba(255, 255, 255, 0.82); }
.scope__overlay .v {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3vw, 2.25rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: #fff;
  line-height: 1.1;
}

/* ---------- 11. BOOKING PANELS & FORM ----------
   Copy and contacts on the left, the form card on the right, both sitting
   straight on the pink band. Used by the mid and the closing block alike.   */
.book {
  border-radius: var(--r-24);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(26px, 3vw, 40px);
  align-items: stretch;
}
.book__copy {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(28px, 4vw, 48px);
}
.book__intro { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
.book__intro h2 { font-size: var(--fs-h2); }
.book__intro .lead { max-width: 42ch; }

.book__contacts {
  border-radius: var(--r-16);
  background: var(--white);
  border: 1px solid var(--line-tint);
  padding: clamp(20px, 2.4vw, 28px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.book__row { display: flex; flex-direction: column; gap: 2px; }
.book__k { font-size: var(--fs-sm); color: var(--muted); }
.book__v {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
}
a.book__v { transition: color 0.3s var(--ease); }
a.book__v:hover { color: var(--pink-ink); }

.price-inline { display: flex; align-items: baseline; gap: 10px; }
.price-inline b {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.price-inline span { font-size: var(--fs-sm); color: var(--muted); }

.form-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-16);
  padding: clamp(20px, 2.6vw, 28px);
}

/* the booking form lives in one white card, our standard pill button at the end */
.book__form .form-card {
  display: flex;
  flex-direction: column;
  gap: 18px;
  background: var(--white);
  border-color: var(--line);
}
.book__form .form-card .form__submit { margin-top: 4px; }

.form-card__head { display: flex; flex-direction: column; gap: 6px; }
.form-card__head h3 { font-size: var(--fs-h4); font-weight: 500; }
.form-card__head p { font-size: var(--fs-sm); max-width: 46ch; }

.form { display: flex; flex-direction: column; gap: 18px; }
.form__body { display: flex; flex-direction: column; gap: 18px; }

.field { display: flex; flex-direction: column; gap: 8px; }
.field > label:not(.checkbox) { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }

/* .field sets display:flex, which would beat the user-agent rule for [hidden] */
.field[hidden] { display: none; }

/* The Telegram field and the phone field are the same question asked two
   ways, so they share one grid cell. The cell is always as tall as the taller
   of the two, which is what stops the card (and everything under it) from
   jumping when the switch flips. The channel that is off stays in the layout
   and fades out in place; visibility is delayed by the length of the fade so
   it is still painted while it leaves, and it drops out of the tab order and
   the accessibility tree once it is gone. */
.swap-fields { display: grid; }
.swap-fields > .field {
  grid-area: 1 / 1;
  transition: opacity 0.34s var(--ease), transform 0.34s var(--ease);
}
.swap-fields > .field[hidden] {
  display: flex;
  opacity: 0;
  transform: translateY(6px);
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.34s var(--ease), transform 0.34s var(--ease),
              visibility 0s linear 0.34s;
}

@media (prefers-reduced-motion: reduce) {
  .swap-fields > .field,
  .swap-fields > .field[hidden] { transition: none; }
}

/* The contact switch: one pill track, two halves, a thumb that slides between
   them. It is a radio group, so the arrow keys move the choice and only the
   chosen half is a tab stop. */
.field--pick { gap: 10px; }
.field__legend { font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }

.swap {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 4px;
  border: 1px solid var(--pastel);
  border-radius: var(--r-pill);
  background: var(--white);
  isolation: isolate;
}
.swap__thumb {
  position: absolute;
  z-index: 0;
  top: 4px; bottom: 4px; left: 4px;
  width: calc(50% - 4px);
  border-radius: var(--r-pill);
  background-image: var(--grad);
  box-shadow: 0 2px 10px rgba(197, 13, 98, 0.24);
  transition: transform 0.42s var(--ease);
}
.swap[data-pick='phone'] .swap__thumb { transform: translateX(100%); }

.swap__opt {
  position: relative;
  z-index: 1;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--body);
  cursor: pointer;
  transition: color 0.3s var(--ease);
}
.swap__opt[aria-checked='true'] { color: #fff; }
.swap__opt:hover:not([aria-checked='true']) { color: var(--ink); }
.swap__opt:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .swap__thumb { transition: none; }
}

/* Oravo .footer-input-field — pill inputs */
.field input[type='text'],
.field input[type='tel'] {
  width: 100%;
  padding: 14px 20px;
  border: 1px solid var(--pastel);
  border-radius: var(--r-pill);
  background: var(--white);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--ink);
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.field input::placeholder { color: #B3B3B8; }
.field input:hover { border-color: #C2B8BE; }
.field input:focus { outline: none; border-color: var(--pink); box-shadow: 0 0 0 3px var(--pink-wash); }
.field[data-invalid='true'] input { border-color: var(--danger); }
.field[data-invalid='true'] input:focus { box-shadow: 0 0 0 3px rgba(200, 16, 46, 0.14); }

.field textarea {
  width: 100%;
  min-height: 108px;
  padding: 14px 20px;
  border: 1px solid var(--pastel);
  border-radius: var(--r-16);
  background: var(--white);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ink);
  resize: vertical;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.field textarea::placeholder { color: #B3B3B8; }
.field textarea:hover { border-color: #C2B8BE; }
.field textarea:focus { outline: none; border-color: var(--pink); box-shadow: 0 0 0 3px var(--pink-wash); }

.field__hint { font-size: var(--fs-sm); color: var(--muted); padding-left: 20px; }
.field__error { font-size: var(--fs-sm); color: var(--danger); display: none; padding-left: 20px; }
.field[data-invalid='true'] .field__error { display: block; }

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: var(--fs-sm);
  color: var(--body);
  cursor: pointer;
  line-height: 1.5;
}
.checkbox input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 20px; height: 20px;
  margin: 1px 0 0;
  border: 1px solid var(--pastel);
  border-radius: 6px;
  background: var(--white);
  cursor: pointer;
  position: relative;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.checkbox input:checked { background: var(--pink); border-color: var(--pink); }
.checkbox input:checked::after {
  content: '';
  position: absolute;
  left: 6px; top: 2px;
  width: 5px; height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.checkbox a { color: var(--pink-ink); text-decoration: underline; text-underline-offset: 3px; }
.field[data-invalid='true'] .checkbox input { border-color: var(--danger); }

.btn[data-loading='true'] { pointer-events: none; opacity: 0.9; }
.spinner {
  display: none;
  width: 18px; height: 18px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.btn[data-loading='true'] .spinner { display: block; }
.btn[data-loading='true'] .btn__ico { display: none; }

.form__status {
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: clamp(20px, 2.6vw, 28px);
  border-radius: var(--r-card);
  background: var(--tint);
  text-align: left;
}
.form__status[data-visible='true'] { display: flex; }
.form__status p { font-size: var(--fs-sm); }
.form[data-sent='true'] .form__body { display: none; }

.form__fail {
  display: none;
  padding: 12px 18px;
  border-radius: var(--r-8);
  background: rgba(200, 16, 46, 0.08);
  color: var(--danger);
  font-size: var(--fs-sm);
}
.form__fail[data-visible='true'] { display: block; }

/* ---------- 12. PRICE (Oravo .price-plan-section) ---------- */
/* The heading runs across the top so that the plan card on the right starts
   on exactly the same line as the first fact card on the left. */
.price__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    'head'
    'facts'
    'card';
  gap: clamp(24px, 3vw, 32px);
  align-items: start;
}
.price__head {
  grid-area: head;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
}
.price__head .lead { max-width: 52ch; }

.price__intro { grid-area: facts; display: flex; flex-direction: column; gap: 20px; }
.price__intro .lead { max-width: 42ch; }

.price__minis { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }

/* Oravo .core-value-card */
.mini {
  padding: 24px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--white);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.mini__k { font-size: var(--fs-sm); font-weight: 500; color: var(--pink-ink); }
.mini__v {
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.2;
}
.mini p { font-size: var(--fs-sm); }

/* Oravo .pricing-card-wrap */
.price-card {
  grid-area: card;
  padding: clamp(20px, 2.6vw, 28px);
  border: 1px solid var(--line);
  border-radius: var(--r-24);
  background: var(--white);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
.price-card__main {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  gap: 26px;
}
.price-card__ico {
  width: 52px; height: 52px;
  border-radius: var(--r-card);
  background-image: var(--grad);
  color: #fff;
  display: grid; place-items: center;
}
.price-card__ico svg { width: 24px; height: 24px; }
.price-card__title { display: flex; flex-direction: column; gap: 12px; }
.price-card__title h3 { font-size: clamp(1.35rem, 2.2vw, 1.75rem); font-weight: 500; }
.price-card__title p { font-size: var(--fs-sm); }
.price__amount {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
}
.price__amount i { font-style: normal; color: var(--pink); }
.price__for { font-size: var(--fs-sm); color: var(--muted); }
.price-card__pay { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; width: 100%; }
.price-card__cta { grid-column: 1 / -1; }

/* Oravo .features-content-wrap — tinted "what is included" panel */
.includes-box {
  padding: clamp(24px, 3vw, 32px) 16px;
  border-radius: var(--r-16);
  background: var(--tint);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.includes-box__k { font-size: var(--fs-body); font-weight: 500; color: var(--ink); }
.includes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.includes li { display: flex; align-items: flex-start; gap: 8px; }
.includes__tick {
  flex: none;
  width: 20px; height: 20px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--pink);
  color: #fff;
  display: grid; place-items: center;
}
.includes__tick svg { width: 11px; height: 11px; }
.includes b { font-weight: 500; color: var(--ink); display: block; font-size: var(--fs-body); }
.includes p { font-size: var(--fs-sm); margin-top: 2px; }

/* ---------- 13. FAQ (Oravo .faq-section) ---------- */
/* The price card closes with a full section pad and the FAQ opens with another
   one, so the two of them were stacking about 200px of empty band between the
   card and the "Питання" pill. The FAQ keeps a shorter top pad of its own. */
#faq { padding-top: clamp(21px, 3.4vw, 45px); }
.faq__list { width: 100%; }

.faq__item { border-bottom: 1px solid var(--line); }

.faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  padding: 32px 20px 16px;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.3;
  color: var(--ink);
}
.faq__q:hover { color: var(--pink-ink); }

.faq__sign {
  flex: none;
  width: 28px; height: 28px;
  position: relative;
}
.faq__sign::before, .faq__sign::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  background: var(--ink);
  transform: translate(-50%, -50%);
  transition: transform 0.45s var(--ease), opacity 0.3s var(--ease), background-color 0.35s var(--ease);
}
.faq__sign::before { width: 18px; height: 1.6px; }
.faq__sign::after { width: 1.6px; height: 18px; }
.faq__item[data-open='true'] .faq__sign::before,
.faq__item[data-open='true'] .faq__sign::after { background: var(--pink); }
.faq__item[data-open='true'] .faq__sign::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }

.faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.45s var(--ease); }
.faq__item[data-open='true'] .faq__a { grid-template-rows: 1fr; }
.faq__a > div { overflow: hidden; }
.faq__a p {
  padding: 0 20px 28px;
  max-width: 680px;
}

/* ---------- 14. FOOTER (Glowdent .footer-section) ----------
   Three contact cards across the top, then a short body: the mark and one
   line on the left, the information column on the right. Under it the
   wordmark runs the full width as a watermark, and one centered line closes
   the page.

   The section links and the contact column that used to sit here were saying
   the same thing twice: the navigation is one screen away in the header, and
   the phone, Instagram and city are already the three cards above.          */
.footer-bg { background: var(--tint); }

.footer {
  background: var(--deep);
  color: var(--on-deep-mute);
  padding-block: clamp(26px, 3vw, 38px) 18px;
  border-top-left-radius: var(--r-28);
  border-top-right-radius: var(--r-28);
}
.footer .shell { display: flex; flex-direction: column; }

/* contact cards */
.footer__cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
.fcard {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: clamp(148px, 13vw, 194px);
  padding: clamp(22px, 2.4vw, 32px) 20px;
  border-radius: var(--r-24);
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.045);
  text-align: center;
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease), transform 0.5s var(--ease);
}
a.fcard:hover {
  background: rgba(255, 255, 255, 0.085);
  border-color: rgba(255, 255, 255, 0.18);
  transform: translateY(-3px);
}
.fcard__ico {
  width: 30px; height: 30px;
  margin-bottom: clamp(18px, 2.2vw, 28px);
  color: #fff;
}
.fcard__ico svg { width: 100%; height: 100%; display: block; }
.fcard__t {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: #fff;
}
.fcard__v { margin-top: 8px; font-weight: 500; color: var(--on-deep-mute); }

/* body */
.footer__main {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(28px, 3.5vw, 40px);
  margin-top: clamp(28px, 3.5vw, 44px);
}
.footer__lead {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}
.footer__logo { width: clamp(116px, 10vw, 148px); height: auto; object-fit: contain; }
.footer__note {
  margin: 0;
  max-width: 34ch;
  font-size: var(--fs-lg);
  line-height: 1.45;
  color: var(--on-deep-mute);
}

/* link column */
.footer__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(26px, 3vw, 34px);
}
.footer__col { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.footer__k {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  color: var(--on-deep-mute);
  opacity: 0.72;
  margin-bottom: 6px;
}
.footer__col a,
.footer__still {
  font-size: var(--fs-lg);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: #fff;
}
.footer__col a {
  transition: padding-left 0.3s var(--ease), color 0.3s var(--ease);
}
.footer__col a:hover { padding-left: 10px; color: var(--pink); }
.footer__still { color: var(--on-deep-mute); }

.footer .lang { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.2); }
.footer .lang button { color: var(--on-deep-mute); }
.footer .lang button:hover:not([aria-pressed='true']) { color: #fff; }

/* watermark wordmark: textLength pins it to the full container width, so it
   fits edge to edge whatever the font ends up measuring */
.footer__mark { margin-top: clamp(26px, 3.4vw, 44px); }
/* the wordmark is a watermark, not a headline: capped so the band closes the
   page rather than becoming a section of its own */
.footer__mark svg { display: block; width: 100%; height: auto; max-height: 148px; }
.footer__mark text {
  font-family: var(--font-display);
  font-size: 200px;
  font-weight: 500;
  fill: rgba(255, 255, 255, 0.07);
}

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 10px;
  margin: clamp(16px, 2vw, 26px) 0 0;
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--on-deep-mute);
}
.footer__bottom a { color: #fff; transition: color 0.3s var(--ease); }
.footer__bottom a:hover { color: var(--pink); }

/* ---------- 15. FLOATING CTA ---------- */
.dock {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  padding: 12px var(--gutter) calc(12px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-top: 1px solid var(--line);
  display: none;
  transform: translateY(110%);
  transition: transform 0.45s var(--ease);
}
.dock[data-show='true'] { transform: none; }

.fab {
  position: fixed;
  right: clamp(20px, 3vw, 40px);
  bottom: clamp(20px, 3vw, 40px);
  z-index: 90;
  display: none;
  align-items: center;
  gap: 12px;
  padding: 8px 24px 8px 8px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--pink);
  color: #fff;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 500;
  cursor: pointer;
  box-shadow: 0 14px 38px rgba(224, 16, 112, 0.3);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease), background-color 0.3s var(--ease);
}
.fab[data-show='true'] { opacity: 1; transform: none; }
.fab:hover { background: var(--pink-hover); }
.fab__ring {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  display: grid; place-items: center;
  flex: none;
}
.fab__ring svg { width: 18px; height: 18px; }

/* Back to the top. It shares the FAB's corner, its reveal threshold and its
   easing, and sits to the left of it so the pink pill stays the loud one.
   On the phone the dock owns the bottom edge, so the button lifts above it. */
.totop {
  position: fixed;
  right: clamp(20px, 3vw, 40px);
  bottom: clamp(20px, 3vw, 40px);
  z-index: 90;
  width: 56px; height: 56px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 10px 30px rgba(21, 3, 9, 0.12);
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease),
              background-color 0.3s var(--ease), color 0.3s var(--ease),
              border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.totop[data-show='true'] { opacity: 1; transform: none; pointer-events: auto; }
.totop svg { width: 20px; height: 20px; }
.totop:hover {
  background: var(--pink);
  border-color: var(--pink);
  color: #fff;
  box-shadow: 0 14px 34px rgba(224, 16, 112, 0.28);
}
.totop[data-show='true']:hover { transform: translateY(-3px); }
.totop:active { transform: scale(0.95); }
.totop:focus-visible { outline: 2px solid var(--pink); outline-offset: 3px; }

/* the arrow lifts inside the circle on hover, so the button reads as motion
   upwards before it is even pressed */
.totop svg { transition: transform 0.35s var(--ease); }
.totop:hover svg { transform: translateY(-2px); }

/* ---------- 16. MODAL ---------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 210;
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 40px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
.modal[data-open='true'] { opacity: 1; visibility: visible; }
.modal__scrim {
  position: absolute;
  inset: 0;
  background: rgba(13, 10, 15, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 0;
  cursor: pointer;
}
.modal__card {
  position: relative;
  width: min(560px, 100%);
  max-height: 90dvh;
  overflow-y: auto;
  padding: clamp(26px, 4vw, 36px);
  background: var(--white);
  border-radius: var(--r-24);
  box-shadow: 0 30px 80px rgba(13, 10, 15, 0.24);
  transform: translateY(16px) scale(0.985);
  transition: transform 0.45s var(--ease);
}
.modal[data-open='true'] .modal__card { transform: none; }
.modal__head { margin-bottom: 24px; padding-right: 46px; display: flex; flex-direction: column; gap: 10px; }
.modal__head h3 { font-size: clamp(1.35rem, 2.2vw, 1.75rem); font-weight: 500; }
.modal__head p { font-size: var(--fs-sm); }
.modal .icon-close { top: 16px; right: 16px; width: 42px; height: 42px; }

/* ---------- 17. MOTION ---------- */
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  /* box-shadow and border-color ride along so that a panel which is also a
     reveal target can still answer the cursor: the per-property delay list
     keeps the entry stagger on opacity and transform and leaves the hover
     properties immediate. */
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease),
              box-shadow 0.45s var(--ease), border-color 0.45s var(--ease);
  transition-delay: var(--d, 0ms), var(--d, 0ms), 0s, 0s;
}
.reveal.is-in { opacity: 1; transform: none; }

.js .mask-in { clip-path: inset(0 0 100% 0); transition: clip-path 1s var(--ease); }
.mask-in.is-in { clip-path: inset(0 0 0 0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .js .reveal { opacity: 1; transform: none; }
  .js .mask-in { clip-path: none; }
  .drawer[data-open='true'] .drawer__nav a { opacity: 1; transform: none; }
}

/* ---------- 17b. HOVER PASS ----------
   Everything that is not a button but still answers the cursor: photographs
   lift and zoom a little inside their frames, panels pick up a tinted shadow,
   the brand marks breathe. All of it lives behind (hover: hover) so a touch
   screen never sticks in a hover state, and all of it is transform and
   opacity work so nothing reflows mid-gesture.
   ==================================================================== */
@media (hover: hover) and (pointer: fine) {

  /* Case gallery: the frame lifts, the photograph inside it zooms slower than
     the frame moves, which is what makes the two read as separate planes. */
  .rail-card__media {
    transition: transform 0.55s var(--ease), box-shadow 0.55s var(--ease);
  }
  .rail-card img { transition: transform 0.9s var(--ease); }
  .rail-card:hover .rail-card__media,
  .rail-card:focus-visible .rail-card__media {
    transform: translateY(-6px);
    box-shadow: 0 18px 40px rgba(176, 10, 87, 0.16);
  }
  .rail-card:hover img,
  .rail-card:focus-visible img { transform: scale(1.06); }
  .rail-card:active .rail-card__media { transform: translateY(-2px); }

  /* Before / after comparison: no transform, because the handle is dragged
     and a moving frame would fight the gesture. A shadow is enough. */
  .compare { transition: box-shadow 0.5s var(--ease); }
  .case-card:hover .compare { box-shadow: 0 16px 44px rgba(13, 10, 15, 0.12); }

  /* Stage photograph: it changes on click already, so the hover is only a
     hint that the panel beside it is live. */
  .scope__media img { transition: opacity 0.35s var(--ease), transform 0.9s var(--ease); }
  .scope__media:hover img { transform: scale(1.04); }

  /* Review cards: the existing lift, now with a shadow under it, and the
     video frame itself creeps forward a touch. */
  .tmq .tcard { transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease); }
  .tmq .tcard:hover { box-shadow: 0 20px 46px rgba(58, 6, 25, 0.28); }
  .tcard--video video { transition: transform 0.9s var(--ease); }
  .tmq .tcard--video:hover video { transform: scale(1.03); }

  /* Price and value panels. These are also scroll-reveal targets, and the
     reveal owns their transform for the length of its entry, so the hover is
     depth rather than movement: the hairline warms and the panel lifts off
     the page with a shadow instead of with a translate. */
  .price-card:hover, .mini:hover {
    border-color: var(--line-tint);
    box-shadow: var(--shadow-lift);
  }

  /* The client photographs in the hero card: each one comes forward on its
     own, over the circles stacked on top of it. */
  .hero__avatars img {
    transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
  }
  .hero__avatars img:hover {
    transform: translateY(-4px) scale(1.12);
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.35);
    position: relative;
    z-index: 2;
  }

  /* Brand marks. */
  .brand img, .footer__logo { transition: transform 0.5s var(--ease); }
  .brand:hover img { transform: scale(1.06); }
  .footer__logo:hover { transform: scale(1.05) rotate(-2deg); }

  /* A question row tints across its full width, not just the label. */
  .faq__item { transition: background-color 0.35s var(--ease); }
  .faq__item:hover { background: var(--tint-soft); }
}

@media (prefers-reduced-motion: reduce) {
  .rail-card:hover .rail-card__media,
  .rail-card:hover img,
  .scope__media:hover img,
  .tmq .tcard--video:hover video,
  .hero__avatars img:hover,
  .brand:hover img,
  .footer__logo:hover { transform: none; }
}

/* ---------- 18. RESPONSIVE ---------- */
@media (min-width: 560px) {
  .price__minis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer__cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 992px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.62fr); gap: 40px; }
  .hero__card { justify-self: end; }
  .hero__photo { left: auto; width: 62%; }
  .hero__photo::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: linear-gradient(90deg, #050505, rgba(5, 5, 5, 0.55) 34%, transparent 68%);
  }
  .hero__photo img { object-position: 50% 32%; }

  .sec-row { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: 40px; }
  .sec-row .sec-head--left { margin-bottom: 0; }

  .case-card { grid-template-columns: minmax(0, 7fr) minmax(0, 6.4fr); }
  /* The source frames are 1123x1400: hair from about 0.10 of the height, chin
     at 0.76, the studio caption across 0.795 to 0.85 and the signature from
     0.895. A fixed pixel height changed which slice of that showed as the
     column grew, which is why the chin sat on the bottom edge at 1440 and the
     caption was cut in half on a wider screen. A ratio crops the same 82% at
     every width, and 29% down the overflow puts the window at 0.05 to 0.876:
     the head sits centred with air above it, the caption reads whole under
     the chin, and the cut lands in the gap before the signature instead of
     through it. */
  .case-card .compare { aspect-ratio: 1123 / 1155; height: auto; }
  .case-card .compare img { object-position: 50% 29%; }
  .scope { grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr); gap: 20px; }
  .scope__panel p { padding-left: calc(clamp(18px, 2vw, 24px) + 46px + 16px); }
  /* the steps stay in view while the tall photo scrolls past them */
  .scope__list { position: sticky; top: calc(var(--header-h) + 24px); }
  .book { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); }
  .price__grid {
    grid-template-columns: minmax(0, 6fr) minmax(0, 7fr);
    grid-template-areas:
      'head head'
      'facts card';
    gap: 32px clamp(24px, 3vw, 40px);
  }
  .price__minis { grid-template-columns: minmax(0, 1fr); }
  .price-card { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .footer__main { grid-template-columns: minmax(0, 1fr) auto; gap: 40px; align-items: start; }
}

@media (min-width: 1100px) {
  /* Oravo .pricing-card-sticky */
  .price-card { position: sticky; top: calc(var(--header-h) + 24px); }
}

/* the phone number is the first thing to go when the bar gets tight */
@media (max-width: 1479px) {
  .header__tel { display: none; }
  .nav a { padding: 9px 13px; }
}

/* below the desktop bar the drawer carries Instagram and Telegram instead */
@media (max-width: 1139px) {
  .header__social { display: none; }
}

@media (max-width: 1139px) {
  .nav, .header__cta { display: none; }
  .burger { display: block; }
  .header__side { margin-left: auto; }
  .dock { display: block; }
  /* the dock owns the bottom edge here, so the circle lifts clear of it */
  .totop { bottom: calc(20px + 76px + env(safe-area-inset-bottom)); }
  .footer { padding-bottom: 96px; }
}

@media (min-width: 1140px) {
  .fab { display: flex; }
  /* the pill is 56px tall, so the circle stacks directly above it rather than
     beside it: the FAB label changes width between UA and EN, the gap does not */
  .totop { bottom: calc(clamp(20px, 3vw, 40px) + 68px); }
}

@media (max-width: 639px) {
  :root { --header-h: 84px; }
  .brand img { width: 68px; height: 68px; }
  .hero__cta { width: 100%; flex-direction: column; }
  .hero__card { width: 100%; max-width: none; }
  .rail { grid-auto-columns: 74vw; }
  .stat-strip__rule { display: none; }
  .faq__q { font-size: 1.1rem; padding: 24px 0 14px; }
  .faq__a p { padding-inline: 0; }
}

/* ---------- 19. PHONE PASS ----------
   Fixes that only make sense on a real phone. Kept in one block at the end so
   the desktop grammar above stays readable.
   ========================================================================= */

/* The pill button carries a 40px arrow plus a 26-character Ukrainian label.
   Full width on a 375px screen that label breaks onto a second line, which
   reads as a bug. Below 420px the type and the arrow step down; below 375px
   the block variant drops the arrow entirely and centres the label. */
@media (max-width: 420px) {
  .btn { font-size: 0.9375rem; gap: 10px; padding: 7px 16px 7px 7px; min-height: 46px; }
  .btn__ico { width: 36px; height: 36px; }
  .btn__ico svg { width: 16px; height: 16px; }
  .btn__label { white-space: nowrap; }
}
@media (max-width: 374px) {
  .btn { font-size: 0.875rem; gap: 8px; padding: 7px 14px 7px 7px; }
  .btn__ico { width: 32px; height: 32px; }
  .btn { padding-inline: 14px; justify-content: center; min-height: 48px; }
  /* under 375px the arrow plus a 26-character label no longer fit side by side */
  .btn:not(.btn--sm) .btn__ico { display: none; }
  .btn--sm { min-height: 42px; }
}

@media (max-width: 639px) {
  /* Drawer: it is the whole navigation on a phone, so the primary action
     belongs in it. The foot no longer repeats the language switch. */
  .drawer__cta { margin-bottom: 4px; }
  .drawer__foot { padding-top: 24px; gap: 14px; }
  .drawer__link { padding-block: 9px; }          /* 27px text -> 45px target */

  /* The language pills were 28px tall, under the 44px touch minimum. */
  .lang button { display: inline-flex; align-items: center; min-height: 44px; padding: 0 15px; }

  /* Footer contact cards were three 180px-tall centred boxes, roughly a full
     screen of scrolling for three lines of text. On a phone they become rows:
     icon on the left, label and value stacked next to it. */
  .fcard {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 16px;
    min-height: 0;
    padding: 18px 20px;
    text-align: left;
  }
  .fcard__ico { grid-row: 1 / span 2; width: 26px; height: 26px; margin-bottom: 0; }
  .fcard__t { grid-column: 2; font-size: var(--fs-lg); }
  .fcard__v { grid-column: 2; margin-top: 2px; }

  /* Footer link columns: 27px rows sitting on a 10px gap. Trade the gap for
     padding so every link is a 44px+ target without changing the rhythm. */
  .footer__col { gap: 0; }
  .footer__col a { padding-block: 9px; }
  .footer__col a:hover { padding-left: 10px; }
  .footer__still { padding-block: 9px; }
  .footer__bottom a { display: inline-block; padding-block: 11px; }

  /* Same story for the phone and Instagram lines in the booking card. */
  a.book__v { display: inline-block; padding-block: 8px; }
}

/* ---------- 20. PHONE LAYOUT ----------
   Structural changes asked for on phones: full-width buttons, the cases CTA
   moved under the block, the process photo lifted under the heading, and the
   review cards sized like the reference template.
   ========================================================================= */

@media (max-width: 639px) {

  /* ---- every button spans the screen ----
     The arrow stays in flow next to the label and the pair is centred, which
     is how the block variant already read in the modal. */
  .btn {
    width: 100%;
    justify-content: center;
    text-align: center;
  }

  /* ---- cases: the CTA belongs under the block, not next to the heading ----
     display:contents dissolves .sec-row so the heading and the button become
     direct children of the section column, and the button can be ordered last
     without duplicating it in the markup. */
  #cases .shell { display: flex; flex-direction: column; }
  #cases .sec-row { display: contents; }
  /* the row is dissolved above, so its bottom margin is gone with it and the
     lead needs its own air before the first case */
  #cases .sec-head--left { margin-bottom: clamp(44px, 11vw, 64px); }
  #cases .sec-row > .btn { order: 1; margin-top: clamp(28px, 6vw, 40px); }

  /* ---- process: photo first, steps under it ---- */
  .scope__media { order: -1; }

  /* ---- reviews: card geometry taken from the reference template, where a
     card is ~90vw wide so one review fills the screen and the next one peeks --- */
  .tcard { width: min(88vw, 360px); }
  .tcard__media { aspect-ratio: 4 / 5; }
  .tcard__quote { font-size: 1.0625rem; }

}

/* ---------- 21. PRELOADER ----------
   Timeline (see js/preloader.js for the DOM cleanup):
     0.00 - 0.14s  black, nothing
     0.14 - 1.24s  the signature draws itself in writing order
     1.24 - 1.44s  hold
     1.44 - 2.06s  the black splits, the mark scales to 1.04 and travels out
                   with its half of the curtain, the hero is already behind it

   What used to make the intro stutter on a phone was doing the expensive work
   twice and then filtering it. The stroke animation re-rasterises an SVG mask
   on every frame, and that mask was mounted in both halves of the curtain, so
   the same complex path was drawn twice per frame; on top of it an animated
   drop-shadow forced yet another pass over the result.

   So the drawing now happens once, in a single centred layer. The two halves
   of the curtain hold the same mark already finished and stay invisible until
   the split, when they swap in and the solo layer disappears. The halves are
   static from that moment, so the curtain is a pure transform on two promoted
   layers and nothing is rasterised again. The animated halo is gone with it.
   ========================================================================= */

.sc-pre {
  /* one place for the timeline; the phone block below shortens it */
  --pre-draw-in: 140ms;
  --pre-draw: 1100ms;
  --pre-open-at: 1440ms;
  --pre-open: 620ms;

  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  background: transparent;   /* the two panels carry the black */
  overflow: hidden;
  /* the cover swallows clicks while it is up, so nothing behind it can be hit
     by accident; once the curtain opens the gap is simply empty */
}
.js .sc-pre { display: block; }
.sc-pre[data-done='true'] { display: none; }

/* while the curtain is closed nothing behind it may scroll. --sbw is the width
   of the scrollbar track that overflow: hidden just freed (js/preloader.js
   measures it); padding it back keeps the layout at its unlocked width, so
   nothing slides sideways when the curtain opens. The bar is fixed, so it is
   sized against the viewport and needs the same padding of its own. */
html.sc-preloading, html.sc-preloading body { overflow: hidden; }
html.sc-preloading { padding-right: var(--sbw, 0px); }
html.sc-preloading .header { padding-right: var(--sbw, 0px); }

.sc-pre__defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* the curtain: two halves that part at the vertical centre of the screen.
   The bottom half overlaps by 1px so no hairline of the page shows through
   the seam on fractional device pixel ratios; its mark is nudged back by the
   same 1px so the two halves of the signature stay perfectly aligned. */
.sc-pre__panel {
  position: absolute;
  left: 0;
  right: 0;
  height: 50%;
  overflow: hidden;
  background: #050505;
  will-change: transform;
  transform: translate3d(0, 0, 0);
}
.sc-pre__panel--top { top: 0; }
.sc-pre__panel--btm { bottom: 0; height: calc(50% + 1px); }

.sc-pre__logo {
  position: absolute;
  left: 50%;
  width: clamp(186px, 21vw, 292px);
  transform: translate(-50%, -50%);
}
.sc-pre__panel--top .sc-pre__logo { top: 100%; }
.sc-pre__panel--btm .sc-pre__logo { top: 1px; }

/* the layer that actually draws: one mark, centred on the screen, above both
   halves. Same width and same centre as the halves' copies, so the handover
   at the split is invisible. */
.sc-pre__solo {
  position: absolute;
  top: 50%; left: 50%;
  width: clamp(186px, 21vw, 292px);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.sc-pre__mark {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* The pen. pathLength="1" means the dash maths needs no measuring. There is
   exactly one of these: the mask lives in the defs and every copy of the mark
   reads the same one, which is why hiding the halves while it runs cuts the
   per-frame work in half rather than desynchronising anything. */
.sc-pre__pen {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: sc-draw var(--pre-draw) cubic-bezier(0.42, 0.02, 0.36, 1) var(--pre-draw-in) forwards;
}
/* the halves wait, unrendered, until the split hands the mark over to them */
.sc-pre__panel .sc-pre__logo { opacity: 0; }

@keyframes sc-draw { to { stroke-dashoffset: 0; } }

/* the opening. At 1440ms the finished halves take over from the solo layer in
   the same frame the curtain starts moving, so nothing is drawn twice and
   nothing is drawn again. */
.sc-pre__solo                { animation: sc-hide     1ms  linear                        var(--pre-open-at) forwards; }
.sc-pre__panel .sc-pre__logo { animation: sc-show     1ms  linear                        var(--pre-open-at) forwards; }
.sc-pre__panel--top          { animation: sc-open-top var(--pre-open) cubic-bezier(0.76, 0, 0.24, 1) var(--pre-open-at) forwards; }
.sc-pre__panel--btm          { animation: sc-open-btm var(--pre-open) cubic-bezier(0.76, 0, 0.24, 1) var(--pre-open-at) forwards; }
.sc-pre__panel .sc-pre__mark { animation: sc-lift     var(--pre-open) cubic-bezier(0.76, 0, 0.24, 1) var(--pre-open-at) forwards; }

@keyframes sc-open-top { to { transform: translate3d(0, -100%, 0); } }
@keyframes sc-open-btm { to { transform: translate3d(0, 100%, 0); } }
@keyframes sc-lift     { to { transform: scale(1.04); } }
@keyframes sc-hide     { to { opacity: 0; } }
@keyframes sc-show     { to { opacity: 1; } }

/* ---- touch screens: the same moment, without the mask animation ----
   Drawing the signature means re-rasterising an SVG mask on every frame, and
   a mask is one of the few things a phone GPU cannot help with: Safari in
   particular falls back to redrawing the masked artwork in software each time
   the dash offset moves. It holds 60fps on a laptop and stutters on a phone.

   So a touch device never animates the mask. The finished mark fades and
   settles, then the curtain opens: opacity and transform only, both of which
   the compositor handles on its own thread. The whole thing is also shorter,
   because nobody waits a beat and a half on a phone. */
@media (hover: none), (max-width: 767px) {
  .sc-pre {
    --pre-open-at: 700ms;
    --pre-open: 540ms;
  }
  .sc-pre__pen { animation: none; stroke-dashoffset: 0; }
  .sc-pre__solo {
    opacity: 0;
    animation:
      sc-mark-in 420ms cubic-bezier(0.16, 1, 0.3, 1) 60ms forwards,
      sc-hide    1ms   linear                        var(--pre-open-at) forwards;
  }
  @keyframes sc-mark-in {
    from { opacity: 0; transform: translate(-50%, -50%) scale(0.94); }
    to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  }
}

/* The bar sits under the curtain with a live backdrop blur, so every frame of
   the opening would be re-blurred through it for nothing. */
html.sc-preloading .header {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Reduced motion: no drawing and no curtain. The mark fades in, holds for a
   beat and the whole cover fades out. Durations are marked important because
   the global reduced-motion block above flattens every animation to 0.001ms. */
@media (prefers-reduced-motion: reduce) {
  .sc-pre__pen { stroke-dashoffset: 0; animation: none !important; }
  .sc-pre__panel .sc-pre__logo { opacity: 0; animation: none !important; }
  .sc-pre__solo { opacity: 1; animation: sc-fade-in 220ms linear 40ms both !important; }
  .sc-pre__panel--top,
  .sc-pre__panel--btm,
  .sc-pre__mark { animation: none !important; }
  .sc-pre { animation: sc-fade-out 240ms linear 560ms forwards !important; }
  @keyframes sc-fade-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes sc-fade-out { to { opacity: 0; } }
}
