.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 32px;
  width: 187px;
  height: 42px;
  padding: 10px 8px 10px 47px;
  border: none;
  border-radius: 999px;
  font-family: "SFT Schrifted Sans TRIAL";
  font-weight: 600;
  font-size: 16px;
  line-height: 1.2;
  letter-spacing: 0.16px;
  white-space: nowrap;
  cursor: pointer;
}

.button__icon {
  position: relative;
  width: 33px;
  height: 33px;
  flex-shrink: 0;
}

.button__icon img {
  position: absolute;
  inset: 0;
  width: 33px;
  height: 33px;
}

.button__icon-hover,
.button__icon-disabled {
  opacity: 0;
}

/* Type=Primary */
.button--primary {
  background-color: var(--semantic-primary);
  color: var(--semantic-text-inverse);
}

.button--primary:hover {
  background-color: var(--semantic-foreground);
}

/* Type=Secondary */
.button--secondary {
  background-color: var(--semantic-foreground);
  color: var(--semantic-text-inverse);
}

.button--secondary:hover {
  background-color: var(--semantic-primary-hover);
}

/* Type=Tertiary */
.button--tertiary {
  background-color: var(--semantic-background);
  color: var(--semantic-text-primary);
}

.button--tertiary:hover {
  background-color: var(--semantic-foreground);
  color: var(--semantic-text-inverse);
}

.button:hover .button__icon-default {
  opacity: 0;
}

.button:hover .button__icon-hover {
  opacity: 1;
}

/* State=Disabled (all types share the same disabled look) */
.button:disabled {
  background-color: var(--semantic-muted);
  color: var(--semantic-text-disabled);
  cursor: not-allowed;
}

.button:disabled .button__icon-default,
.button:disabled .button__icon-hover {
  opacity: 0;
}

.button:disabled .button__icon-disabled {
  opacity: 1;
}

/* ==========================================================================
   Nav/MenuLabel
   ========================================================================== */

.nav-menu-label {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-Link-L-Regular-family);
  font-size: var(--font-Link-L-Regular-size);
  font-weight: var(--font-Link-L-Regular-weight);
  line-height: var(--font-Link-L-Regular-line-height);
  letter-spacing: var(--font-Link-L-Regular-letter-spacing);
  color: var(--semantic-text-primary);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.nav-menu-label__dot {
  display: block;
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 7px;
  height: 7px;
  opacity: 0;
}

.nav-menu-label__dot img {
  display: block;
  width: 7px;
  height: 7px;
}

/* State=Hover, Theme=Light, Weight=Regular */
.nav-menu-label:not(.nav-menu-label--bold):not(.nav-menu-label--dark):not(.nav-menu-label--disabled):hover {
  color: var(--semantic-primary);
}

.nav-menu-label:not(.nav-menu-label--bold):not(.nav-menu-label--dark):not(.nav-menu-label--disabled):hover .nav-menu-label__dot {
  opacity: 1;
}

/* Weight=Bold (only defined for Theme=Light in Figma) */
.nav-menu-label--bold {
  font-family: var(--font-Link-L-DemiBold-family);
  font-size: var(--font-Link-L-DemiBold-size);
  font-weight: var(--font-Link-L-DemiBold-weight);
  line-height: var(--font-Link-L-DemiBold-line-height);
  letter-spacing: var(--font-Link-L-DemiBold-letter-spacing);
  padding: 1px 0;
}

.nav-menu-label--bold:not(.nav-menu-label--disabled):hover {
  color: var(--semantic-primary);
}

/* Theme=Dark */
.nav-menu-label--dark {
  color: var(--semantic-text-inverse);
}

/* State=Hover, Theme=Dark, Weight=Regular (Figma's own export uses the DemiBold text style here) */
.nav-menu-label--dark:not(.nav-menu-label--disabled):hover {
  font-family: var(--font-Link-L-DemiBold-family);
  font-weight: var(--font-Link-L-DemiBold-weight);
  line-height: var(--font-Link-L-DemiBold-line-height);
  color: var(--semantic-text-inverse);
}

/* State=Disabled (same color regardless of Theme, per Figma) */
.nav-menu-label--disabled {
  color: var(--semantic-text-disabled);
  pointer-events: none;
  cursor: not-allowed;
}

/* ==========================================================================
   Nav/Header
   ========================================================================== */

.nav-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 1200px;
  padding: 8px 0;
}

.nav-header__logo {
  width: 84px;
  height: 42px;
  flex-shrink: 0;
}

.nav-header__logo img {
  display: block;
  width: 84px;
  height: 42px;
}

.nav-header__menu {
  display: flex;
  gap: 60px;
  align-items: flex-start;
  padding-top: 8px;
  flex-shrink: 0;
}

.nav-header__contact {
  display: flex;
  gap: 32px;
  align-items: center;
  flex-shrink: 0;
}

.nav-header__phone {
  display: flex;
  gap: 9px;
  align-items: center;
  flex-shrink: 0;
}

.nav-header__phone-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.nav-header__phone-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1px 0;
  font-family: var(--font-Link-L-DemiBold-family);
  font-size: var(--font-Link-L-DemiBold-size);
  font-weight: var(--font-Link-L-DemiBold-weight);
  line-height: var(--font-Link-L-DemiBold-line-height);
  letter-spacing: var(--font-Link-L-DemiBold-letter-spacing);
  color: var(--semantic-text-primary);
  white-space: nowrap;
}

/* State=Scrolled */
.nav-header--scrolled {
  width: 1376px;
  background-color: var(--Neutral-100);
  border: 1px solid var(--Neutral-200);
  border-radius: 24px;
  padding: 20px 88px;
}

/* Responsive shell: mobile-first (Nav/Header/Mobile, node 91:1162,
   fetched from the "Schur Concrete - mobile" page frame 91:1123) +
   desktop breakpoint (Nav/Header, node 193:333).
   1024px is not a Figma value — no tablet frame was provided, it's a
   conventional mobile/desktop split.

   position:fixed (not sticky/static) on purpose: the navbar must be taken
   completely OUT of document flow so it can never push .hero down and
   leave empty space above it — it only overlays the hero as a layer on
   top (see js/main.js for how .hero__stage is kept clear of it while
   scrolling).

   Mobile numbers are node 91:1162's own (top:10px, padding:20px 10px,
   justify-content:space-between for its only two children — logo +
   burger, no menu/contact) — left/right:10px (not width:fit-content +
   translateX centering) so it's fluid across viewport widths the same
   way the mobile Hero photo below it is, instead of a fixed px width. */
.nav-header--responsive {
  /* Overrides the base .nav-header{width:1200px} rule (same specificity,
     but that rule is declared earlier and this one previously didn't set
     width at all, so 1200px silently won and blew out the page's
     scrollWidth on every viewport under 1200px — the actual root cause
     of the reported horizontal scroll, not the mobile Hero markup. */
  width: auto;
  position: fixed;
  top: 10px;
  left: 10px;
  right: 10px;
  z-index: 100;
  padding: 20px 10px;
  background-color: var(--Neutral-100);
  border: 1px solid var(--Neutral-200);
  border-radius: 24px;
  box-sizing: border-box;
  justify-content: space-between;
}

.nav-header--responsive .nav-header__menu,
.nav-header--responsive .nav-header__contact {
  display: none;
}

/* Nav/BurgerMenu/Default — mobile only. Opening a dropdown on click
   is added behavior: Figma only shows the closed icon. */
.nav-header__burger {
  margin-left: auto;
}

.nav-header__burger-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  cursor: pointer;
  list-style: none;
}

.nav-header__burger-btn::-webkit-details-marker {
  display: none;
}

.nav-header__burger-btn img {
  display: block;
  width: 24px;
  height: 24px;
}

.nav-header__mobile-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 20px;
  background-color: var(--Neutral-100);
  border: 1px solid var(--Neutral-200);
  border-radius: 24px;
  box-sizing: border-box;
}

.nav-header__mobile-menu {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.nav-header__mobile-contact {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

@media (min-width: 1024px) {
  /* Figma numbers (fileKey JmYoex09QPMmompAX7kaTT, "Schur Concrete - main
     page" frame): Nav/Header instance sits at x=120 y=40 w=1200 h=58,
     i.e. top:40px. Its own width (1200, 120px inset) doesn't match the
     hero photo's final inset (32px, 1376 wide) — by explicit direction,
     the navbar is widened to 1376px/32px inset so its edges align with
     the scrolled hero card (step 4), reusing the padding (20px 88px) and
     content arrangement (space-between: logo / menu / contact spread to
     the edges) from the Scrolled Nav/Header variant, whose 1376+88px
     padding already nets the same 1200px content width as Default. */
  .nav-header--responsive {
    top: 40px;
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: 1376px;
    padding: 20px 88px;
    gap: 0;
    justify-content: space-between;
  }

  .nav-header--responsive .nav-header__menu,
  .nav-header--responsive .nav-header__contact {
    display: flex;
  }

  .nav-header__burger {
    display: none;
  }
}

/* ==========================================================================
   Play (video-play button)
   ========================================================================== */

.play {
  display: inline-block;
  width: 113.973px;
  height: 113.973px;
}

.play svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Figma's Default -> Scroll (hover) transition (node 92:1914) changes
   TWO things on the SAME disc group (fill circle + stroke circle
   together): the stroke goes from 24% to 100% opacity, and the whole
   group gains a red inner-shadow filter. The previous approach applied
   that filter to a separate stroke-ONLY duplicate circle — an inner
   shadow needs a filled shape to sit inside, so on a strokeless ring it
   rendered as a distorted reddish blur instead of a red glow inside a
   solid white ring. */
.play__ring {
  transition: stroke-opacity 0.2s ease;
}

.play:hover .play__ring {
  stroke-opacity: 1;
}

/* Each .play instance's SVG defines its own <filter> with a locally
   unique id (SVG ids must be unique per document, and a page could
   have more than one .play instance) and points --play-hover-filter at
   it inline, so this shared rule never hardcodes one specific id. */
.play:hover .play__ellipse {
  filter: var(--play-hover-filter);
}

/* ==========================================================================
   Spec card
   ========================================================================== */

.spec-card {
  position: relative;
  width: 168px;
  height: 252px;
  border: 1px solid var(--semantic-border);
  border-radius: 32px;
  overflow: hidden;
  background-color: var(--semantic-background);
  flex-shrink: 0;
}

.spec-card:hover {
  height: 320px;
  background-color: var(--semantic-primary);
}

.spec-card__bg {
  position: absolute;
  left: -1px;
  overflow: hidden;
  pointer-events: none;
}

.spec-card__bg img {
  position: absolute;
  display: block;
  max-width: none;
}

.spec-card__bg--hover {
  opacity: 0;
}

.spec-card__bg--hover img {
  mix-blend-mode: color-burn;
}

.spec-card:hover .spec-card__bg--default {
  opacity: 0;
}

.spec-card:hover .spec-card__bg--hover {
  opacity: 1;
}

.spec-card__icon-row {
  position: absolute;
  left: 39px;
  top: 15px;
  display: flex;
  align-items: center;
  gap: 7px;
}

.spec-card__dash {
  display: block;
  width: 9.009px;
  height: 1.67px;
}

.spec-card__index {
  margin: 0;
  font-family: var(--font-Body-L-Bold-family);
  font-size: var(--font-Body-L-Bold-size);
  font-weight: var(--font-Body-L-Bold-weight);
  line-height: var(--font-Body-L-Bold-line-height);
  letter-spacing: var(--font-Body-L-Bold-letter-spacing);
  color: var(--semantic-text-primary);
}

.spec-card:hover .spec-card__index {
  color: var(--semantic-text-inverse);
}

.spec-card__value {
  position: absolute;
  left: 39px;
  margin: 0;
  font-family: var(--font-Body-L-Bold-family);
  font-size: var(--font-Body-L-Bold-size);
  font-weight: var(--font-Body-L-Bold-weight);
  line-height: var(--font-Body-L-Bold-line-height);
  letter-spacing: var(--font-Body-L-Bold-letter-spacing);
  color: var(--semantic-text-inverse);
  opacity: 0;
}

.spec-card:hover .spec-card__value {
  opacity: 1;
}

.spec-card__title {
  position: absolute;
  left: 39px;
  top: 119px;
  width: 126.615px;
  margin: 0;
  font-family: var(--font-Body-M-Regular-family);
  font-size: var(--font-Body-M-Regular-size);
  font-weight: var(--font-Body-M-Regular-weight);
  line-height: var(--font-Body-M-Regular-line-height);
  letter-spacing: var(--font-Body-M-Regular-letter-spacing);
  color: var(--semantic-text-primary);
}

.spec-card:hover .spec-card__title {
  color: var(--semantic-text-inverse);
}

.spec-card__title--hover {
  opacity: 0;
}

.spec-card:hover .spec-card__title--default {
  opacity: 0;
}

.spec-card:hover .spec-card__title--hover {
  opacity: 1;
}

/* Spec/Rotation */
.spec-card--rotation .spec-card__bg--default { bottom: -228px; height: 713px; width: 206px; }
.spec-card--rotation .spec-card__bg--default img { height: 18.06%; left: -11.48%; top: 51.98%; width: 94.23%; }
.spec-card--rotation .spec-card__bg--hover { bottom: -160px; height: 713px; width: 206px; }
.spec-card--rotation .spec-card__bg--hover img { height: 48.34%; left: -4.8%; top: 32.47%; width: 89.98%; }
.spec-card--rotation .spec-card__value { top: 85px; white-space: nowrap; }

/* Spec/VerticalHeight */
.spec-card--vertical-height .spec-card__bg--default,
.spec-card--vertical-height .spec-card__bg--hover { top: -1px; height: 506px; width: 208px; }
.spec-card--vertical-height .spec-card__bg--default img { height: 47.63%; left: -37.63%; top: 0.62%; width: 173.84%; }
.spec-card--vertical-height .spec-card__bg--hover img { height: 63.44%; left: -62.43%; top: 0; width: 231.55%; }
.spec-card--vertical-height .spec-card__value { top: 67px; width: 78px; }

/* Spec/HoseLength */
.spec-card--hose-length .spec-card__bg--default { bottom: -228px; height: 713px; width: 206px; }
.spec-card--hose-length .spec-card__bg--default img { height: 20.45%; left: -6.68%; top: 52.23%; width: 106.68%; }
.spec-card--hose-length .spec-card__bg--hover { bottom: -160px; height: 713px; width: 206px; }
.spec-card--hose-length .spec-card__bg--hover img { height: 45.17%; left: -0.1%; top: 32.91%; width: 84.08%; }
.spec-card--hose-length .spec-card__value { top: 85px; white-space: nowrap; }

/* Spec/HorizontalReach */
.spec-card--horizontal-reach { height: 253px; }
.spec-card--horizontal-reach .spec-card__bg--default { bottom: -259px; height: 713px; width: 206px; }
.spec-card--horizontal-reach .spec-card__bg--default img { height: 17.35%; left: 6.8%; top: 47.67%; width: 90.5%; }
.spec-card--horizontal-reach .spec-card__bg--hover { bottom: -192px; height: 713px; width: 206px; }
.spec-card--horizontal-reach .spec-card__bg--hover img { height: 49.81%; left: 0.07%; top: 25.12%; width: 92.72%; }
.spec-card--horizontal-reach .spec-card__value { top: 67px; width: 81px; }

/* Spec/StrokePerMinute */
.spec-card--stroke-per-minute { height: 253px; }
.spec-card--stroke-per-minute .spec-card__bg--default { bottom: -228px; height: 713px; width: 206px; }
.spec-card--stroke-per-minute .spec-card__bg--default img { height: 11.81%; left: 10.66%; top: 55.52%; width: 61.61%; }
.spec-card--stroke-per-minute .spec-card__bg--hover { bottom: -161px; height: 713px; width: 206px; }
.spec-card--stroke-per-minute .spec-card__bg--hover img { height: 44.81%; left: -1.42%; top: 32.54%; width: 83.4%; }
.spec-card--stroke-per-minute .spec-card__value { top: 85px; white-space: nowrap; }

/* Spec/ConcretePressure */
.spec-card--concrete-pressure { height: 251px; }
.spec-card--concrete-pressure .spec-card__bg--default { bottom: -228px; height: 713px; width: 206px; }
.spec-card--concrete-pressure .spec-card__bg--default img { height: 13.36%; left: 8.44%; top: 54.83%; width: 69.7%; }
.spec-card--concrete-pressure .spec-card__bg--hover { bottom: -159px; height: 713px; width: 206px; }
.spec-card--concrete-pressure .spec-card__bg--hover img { height: 44.95%; left: -0.6%; top: 33.03%; width: 83.66%; }
.spec-card--concrete-pressure .spec-card__value { top: 67px; width: 90px; }

/* Spec/LinePumping (no numeric value; the title itself grows and moves up on hover) */
.spec-card--line-pumping { height: 249px; }
.spec-card--line-pumping .spec-card__bg--default { bottom: -259px; height: 713px; width: 167px; }
.spec-card--line-pumping .spec-card__bg--default img { height: 13.18%; left: 8.03%; top: 51.18%; width: 84.83%; }
.spec-card--line-pumping .spec-card__bg--hover { bottom: -188px; height: 507px; width: 167px; }
.spec-card--line-pumping .spec-card__bg--hover img { height: 64.4%; left: 0; top: 0.09%; width: 105.14%; }
.spec-card--line-pumping .spec-card__title--hover { position: absolute; left: 39px; top: 67px; width: 113px; }

/* ==========================================================================
   Card/Feature
   ========================================================================== */

.card-feature {
  position: relative;
  width: 216px;
  height: 350px;
  padding: 24px;
  border-radius: 32px;
  overflow: hidden;
  box-sizing: border-box;
  flex-shrink: 0;
}

.card-feature:hover {
  background-color: var(--semantic-card-foreground);
}

.card-feature__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 32px;
  pointer-events: none;
}

.card-feature:hover .card-feature__photo {
  opacity: 0;
}

.card-feature__content {
  position: absolute;
  left: 24px;
  top: 24px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 164px;
}

.card-feature__content--default {
  gap: 220px;
  color: var(--semantic-text-inverse);
}

.card-feature__content--hover {
  left: 50%;
  transform: translateX(-50%);
  gap: 142px;
  color: var(--semantic-text-inverse);
  opacity: 0;
}

.card-feature:hover .card-feature__content--default {
  opacity: 0;
}

.card-feature:hover .card-feature__content--hover {
  opacity: 1;
}

.card-feature__index {
  margin: 0;
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
}

.card-feature__title {
  margin: 0;
  font-family: var(--font-Body-XL-DemiBold-family);
  font-size: var(--font-Body-XL-DemiBold-size);
  font-weight: var(--font-Body-XL-DemiBold-weight);
  letter-spacing: var(--font-Body-XL-DemiBold-letter-spacing);
}

.card-feature__title p {
  margin: 0;
  line-height: var(--font-Body-XL-DemiBold-line-height);
}

.card-feature__title--single {
  line-height: var(--font-Body-XL-DemiBold-line-height);
}

.card-feature__badge {
  display: flex;
  align-items: center;
  gap: 8px;
}

.card-feature__badge-dot {
  display: block;
  width: 7px;
  height: 7px;
}

.card-feature__badge .card-feature__index {
  white-space: nowrap;
}

.card-feature__text-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  width: 100%;
}

.card-feature__desc {
  margin: 0;
  font-family: var(--font-Body-M-Regular-family);
  font-size: var(--font-Body-M-Regular-size);
  font-weight: var(--font-Body-M-Regular-weight);
  line-height: var(--font-Body-M-Regular-line-height);
  letter-spacing: var(--font-Body-M-Regular-letter-spacing);
}

/* Card/Feature/ReliableEquipment */
.card-feature--reliable-equipment .card-feature__photo { object-position: bottom; }

/* Card/Feature/BestPrice */
.card-feature--best-price { height: 306px; }
.card-feature--best-price .card-feature__content--default { gap: 154px; }
.card-feature--best-price .card-feature__content--hover { gap: 88px; }
.card-feature--best-price:not(:hover) { background-color: var(--semantic-primary); }

/* Card/Feature/Professional */
.card-feature--professional .card-feature__content { width: 165px; }

/* Card/Feature/DirectContact */
.card-feature--direct-contact { height: 306px; }
.card-feature--direct-contact:hover { height: 310px; }
.card-feature--direct-contact:not(:hover) { background-color: var(--semantic-secondary); }
.card-feature--direct-contact .card-feature__content--default { gap: 154px; color: var(--semantic-text-primary); }
.card-feature--direct-contact .card-feature__content--hover { gap: 88px; }

/* Card/Feature/GiveBack */
.card-feature--give-back .card-feature__photo { object-position: bottom; }
.card-feature--give-back .card-feature__title--single { white-space: nowrap; }

/* ==========================================================================
   Category
   ========================================================================== */

.category {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  width: 1200px;
}

.category__icon-group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 280px;
  flex-shrink: 0;
}

.category__icon {
  display: block;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.category__title {
  margin: 0;
  width: 182px;
  font-family: var(--font-Body-2XL-Regular-family);
  font-size: var(--font-Body-2XL-Regular-size);
  font-weight: var(--font-Body-2XL-Regular-weight);
  line-height: var(--font-Body-2XL-Regular-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
  color: var(--semantic-text-inverse);
}

.category__photo {
  width: 342px;
  height: 227px;
  border-radius: 32px;
  object-fit: cover;
  flex-shrink: 0;
}

.category__desc {
  margin: 0;
  width: 244px;
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
  color: var(--semantic-text-disabled);
  flex-shrink: 0;
}

.category__arrow {
  display: block;
  width: 33px;
  height: 33px;
  flex-shrink: 0;
}


/* ==========================================================================
   Section/Hero — rebuilt from a fresh Figma fetch (fileKey JmYoex09QPMmompAX7kaTT,
   node 91:1061). Coordinates below are relative to that node as returned by
   get_metadata, not carried over from the previous implementation:
     - Section/Hero:                    1440 x 787
     - Hero/BackgroundPhoto/Default:    x32  y16   1376 x 755
     - "A Schur thing" text:            x121 y32   1199 x 148
     - Hero/BackgroundPhoto/Mask group: x30  y110.5 1378 x 611.5
     - image 25 (masked photo):         x30  y16   1378 x 755
     - Content (form + caption):        x120 y149  1200 x 590
   Background photo and the masked overlay photo are the SAME source image
   (verified byte-identical after downloading both via Figma MCP) — Figma
   just renders it twice: once plain (object-position:center) as the far
   background, once clipped through the Vector 125 hill silhouette
   (object-position:bottom) as the near layer.

   .hero__stage's BASE size/position is always the final Figma box (1376x755
   at 32,16, radius 32px) — the full-bleed "100vw x 100vh, no radius" look at
   scroll=0 is a SCALE (computed in js/main.js from the viewport size) plus an
   animated border-radius, both driven by the same scrubbed GSAP tween. This
   is deliberate: .hero__bg-photo and .hero__mask-layer are plain inset:0
   children with NO transform of their own, so they are pixel-identical to
   the stage's box at every single frame of that scale — there is no way for
   them to drift apart, which is what caused the visible seam before (the
   mask layer used to have its own, differently-sized/positioned box and its
   own translateY animation).
   ========================================================================== */

/* Fluid rebuild (not in Figma, by request): a literal width:1440px here
   (this file's earlier version) is a real bug at any viewport narrower
   than 1440px — tablet widths (769-1439px) got real horizontal page
   overflow (up to ~670px at 769px, measured), since this block-level
   width forced the page wider than the viewport regardless of what its
   transformed children were doing. width:100% + max-width:1920px caps
   growth at the requested 1920 breakpoint (beyond it, centers with
   margins — same convention every other section already uses at
   1440px, just Hero's own cap is 1920). aspect-ratio replaces the fixed
   height so it still reserves the right vertical space for ScrollTrigger's
   pin-spacer at any width (.hero has no normal-flow children — both
   .hero__stage and .hero__scroll-indicator are position:absolute — so
   without an explicit height/ratio it would collapse to 0).
   container-type:inline-size makes the cqw unit below available to
   .hero__stage/.hero__title/.hero__content: 1cqw = 1% of .hero's own
   (capped) width, so every absolutely-positioned descendant scales
   proportionally with it instead of staying frozen at literal 1440px-
   design pixel values. js/main.js's cover/settle transform math already
   measures these via live getBoundingClientRect() calls, so it adapts
   automatically — no JS math changes needed for the scale itself, only
   for the border-radius target (see FINAL_RADIUS in js/main.js). */
.hero {
  position: relative;
  width: 100%;
  max-width: 1920px;
  aspect-ratio: 1440 / 787;
  margin: 0 auto;
  container-type: inline-size;
  background-color: var(--semantic-background);
}

.hero__stage {
  position: absolute;
  left: 2.2222cqw; /* 32px at the 1440px base */
  top: 1.1111cqw; /* 16px */
  width: 95.5556cqw; /* 1376px */
  height: 52.4306cqw; /* 755px — cqw used for a vertical dimension too: valid, and correct here because height is locked to width via .hero's own aspect-ratio */
  border-radius: 2.2222cqw; /* 32px */
  overflow: hidden;
  transform-origin: center center;
}

.hero__bg-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* Thin atmospheric haze between the far peaks and the near hill, for depth. */
.hero__haze {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(210, 224, 236, 0.22) 0%,
    rgba(210, 224, 236, 0.10) 22%,
    rgba(210, 224, 236, 0) 42%
  );
}

/* "A Schur thing" — sits ABOVE the background photo but BELOW the mask layer
   (z-index 2 < mask's 3). This stacking is what makes the hill silhouette's
   real alpha edge cover the text where it's opaque and reveal it where it's
   transparent (sky) — a static property of the layout, matching Figma,
   independent of whatever the mask's entrance animation is doing. */
/* Position AND font-size/letter-spacing in cqw (relative to .hero, same
   base as .hero__stage above) so the title scales together with the
   fluid stage instead of overflowing/shrinking out of proportion at
   tablet or 1920 widths — font-family/weight/line-height still come
   from the shared token, only its two length values are overridden. */
.hero__title {
  position: absolute;
  left: 6.1806cqw; /* 89px */
  top: 1.1111cqw; /* 16px */
  width: 83.2639cqw; /* 1199px */
  height: 10.2778cqw; /* 148px */
  z-index: 2;
  margin: 0;
  font-family: var(--font-Heading-2XL-DemiBold-family);
  font-size: 10.2778cqw; /* 148px */
  font-weight: var(--font-Heading-2XL-DemiBold-weight);
  line-height: var(--font-Heading-2XL-DemiBold-line-height);
  letter-spacing: 0.1028cqw; /* 1.48px */
  color: var(--semantic-text-inverse);
  text-transform: uppercase;
  white-space: nowrap;
}

/* Masked layer: a plain inset:0 sibling of .hero__bg-photo — pixel-identical
   to the stage's box at every scale, on purpose (see the note on
   .hero__stage above). It has no border-radius/overflow of its own anymore;
   the parent stage's overflow:hidden + animated border-radius clips it, so
   there is only ONE clipping edge for the whole hero, not two independently
   moving ones.

   clip-path (not mask-image, despite two earlier attempts at this — first a
   hand-traced SVG mask, then images/hero-mask.webp/png as a mask-image):
   mask-image had real, reproducible cross-browser/GPU-compositing
   alignment bugs that never showed up in software-rendered checks here but
   were real on the actual reporting device, across three separate rounds
   of position-tuning. clip-path doesn't share that failure mode. The
   polygon below is the exact ridge line traced directly from
   images/hero-mask.png's own alpha channel (topmost opaque pixel per
   column, sampled every 8px), transformed by the same squish+offset the
   mask-image approach used (755/770 vertical squish, -8.2px offset at the
   1440px base) so the silhouette still lines up with the real mountain in
   images/hero/photo.png — same visual result, structurally incapable of
   the class of bug that kept recurring. */
.hero__mask-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  clip-path: polygon(0.0% 46.966%, 0.581% 46.966%, 1.163% 46.966%, 1.744% 46.966%, 2.326% 47.096%, 2.907% 47.096%, 3.488% 47.355%, 4.07% 47.485%, 4.651% 47.485%, 5.233% 47.485%, 5.814% 47.485%, 6.395% 47.355%, 6.977% 47.226%, 7.558% 47.096%, 8.14% 46.836%, 8.721% 46.706%, 9.302% 46.446%, 9.884% 46.187%, 10.465% 45.927%, 11.047% 45.797%, 11.628% 45.407%, 12.209% 45.148%, 12.791% 44.758%, 13.372% 44.368%, 13.953% 43.979%, 14.535% 43.589%, 15.116% 43.329%, 15.698% 42.94%, 16.279% 42.42%, 16.86% 42.161%, 17.442% 41.771%, 18.023% 41.381%, 18.605% 41.122%, 19.186% 40.992%, 19.767% 40.732%, 20.349% 40.342%, 20.93% 40.083%, 21.512% 40.342%, 22.093% 40.472%, 22.674% 40.342%, 23.256% 40.342%, 23.837% 40.342%, 24.419% 40.083%, 25.0% 40.083%, 25.581% 39.953%, 26.163% 39.953%, 26.744% 39.693%, 27.326% 39.433%, 27.907% 39.174%, 28.488% 38.784%, 29.07% 38.265%, 29.651% 37.875%, 30.233% 37.355%, 30.814% 37.096%, 31.395% 36.446%, 31.977% 35.927%, 32.558% 35.537%, 33.14% 35.018%, 33.721% 34.498%, 34.302% 34.109%, 34.884% 33.719%, 35.465% 33.2%, 36.047% 32.68%, 36.628% 32.161%, 37.209% 31.641%, 37.791% 31.252%, 38.372% 30.732%, 38.953% 30.342%, 39.535% 29.953%, 40.116% 29.953%, 40.698% 29.953%, 41.279% 29.823%, 41.86% 29.433%, 42.442% 28.784%, 43.023% 28.265%, 43.605% 28.005%, 44.186% 27.745%, 44.767% 27.485%, 45.349% 27.745%, 45.93% 27.875%, 46.512% 27.485%, 47.093% 27.485%, 47.674% 28.135%, 48.256% 28.524%, 48.837% 28.784%, 49.419% 28.914%, 50.0% 29.174%, 50.581% 29.433%, 51.163% 29.563%, 51.744% 29.693%, 52.326% 29.823%, 52.907% 29.953%, 53.488% 30.083%, 54.07% 30.213%, 54.651% 30.213%, 55.233% 30.213%, 55.814% 30.213%, 56.395% 30.083%, 56.977% 30.083%, 57.558% 29.823%, 58.14% 29.693%, 58.721% 29.433%, 59.302% 29.174%, 59.884% 28.914%, 60.465% 28.524%, 61.047% 28.265%, 61.628% 27.875%, 62.209% 27.355%, 62.791% 26.966%, 63.372% 26.446%, 63.953% 26.057%, 64.535% 25.537%, 65.116% 25.148%, 65.698% 24.758%, 66.279% 24.368%, 66.86% 23.849%, 67.442% 23.589%, 68.023% 23.329%, 68.605% 22.94%, 69.186% 22.42%, 69.767% 21.901%, 70.349% 21.771%, 70.93% 21.511%, 71.512% 20.862%, 72.093% 19.693%, 72.674% 19.174%, 73.256% 18.784%, 73.837% 18.005%, 74.419% 17.615%, 75.0% 17.615%, 75.581% 17.615%, 76.163% 17.485%, 76.744% 17.615%, 77.326% 17.485%, 77.907% 17.226%, 78.488% 16.446%, 79.07% 15.667%, 79.651% 15.148%, 80.233% 14.368%, 80.814% 13.979%, 81.395% 13.719%, 81.977% 13.589%, 82.558% 13.589%, 83.14% 13.459%, 83.721% 13.589%, 84.302% 13.459%, 84.884% 13.719%, 85.465% 13.719%, 86.047% 13.719%, 86.628% 13.719%, 87.209% 13.849%, 87.791% 13.849%, 88.372% 13.849%, 88.953% 13.719%, 89.535% 13.719%, 90.116% 13.719%, 90.698% 13.719%, 91.279% 13.719%, 91.86% 13.719%, 92.442% 13.589%, 93.023% 13.459%, 93.605% 13.459%, 94.186% 13.459%, 94.767% 13.459%, 95.349% 13.329%, 95.93% 13.2%, 96.512% 13.2%, 97.093% 13.07%, 97.674% 12.94%, 98.256% 12.68%, 98.837% 12.55%, 99.419% 12.291%, 99.927% 12.161%, 100% 100%, 0% 100%);
  -webkit-clip-path: polygon(0.0% 46.966%, 0.581% 46.966%, 1.163% 46.966%, 1.744% 46.966%, 2.326% 47.096%, 2.907% 47.096%, 3.488% 47.355%, 4.07% 47.485%, 4.651% 47.485%, 5.233% 47.485%, 5.814% 47.485%, 6.395% 47.355%, 6.977% 47.226%, 7.558% 47.096%, 8.14% 46.836%, 8.721% 46.706%, 9.302% 46.446%, 9.884% 46.187%, 10.465% 45.927%, 11.047% 45.797%, 11.628% 45.407%, 12.209% 45.148%, 12.791% 44.758%, 13.372% 44.368%, 13.953% 43.979%, 14.535% 43.589%, 15.116% 43.329%, 15.698% 42.94%, 16.279% 42.42%, 16.86% 42.161%, 17.442% 41.771%, 18.023% 41.381%, 18.605% 41.122%, 19.186% 40.992%, 19.767% 40.732%, 20.349% 40.342%, 20.93% 40.083%, 21.512% 40.342%, 22.093% 40.472%, 22.674% 40.342%, 23.256% 40.342%, 23.837% 40.342%, 24.419% 40.083%, 25.0% 40.083%, 25.581% 39.953%, 26.163% 39.953%, 26.744% 39.693%, 27.326% 39.433%, 27.907% 39.174%, 28.488% 38.784%, 29.07% 38.265%, 29.651% 37.875%, 30.233% 37.355%, 30.814% 37.096%, 31.395% 36.446%, 31.977% 35.927%, 32.558% 35.537%, 33.14% 35.018%, 33.721% 34.498%, 34.302% 34.109%, 34.884% 33.719%, 35.465% 33.2%, 36.047% 32.68%, 36.628% 32.161%, 37.209% 31.641%, 37.791% 31.252%, 38.372% 30.732%, 38.953% 30.342%, 39.535% 29.953%, 40.116% 29.953%, 40.698% 29.953%, 41.279% 29.823%, 41.86% 29.433%, 42.442% 28.784%, 43.023% 28.265%, 43.605% 28.005%, 44.186% 27.745%, 44.767% 27.485%, 45.349% 27.745%, 45.93% 27.875%, 46.512% 27.485%, 47.093% 27.485%, 47.674% 28.135%, 48.256% 28.524%, 48.837% 28.784%, 49.419% 28.914%, 50.0% 29.174%, 50.581% 29.433%, 51.163% 29.563%, 51.744% 29.693%, 52.326% 29.823%, 52.907% 29.953%, 53.488% 30.083%, 54.07% 30.213%, 54.651% 30.213%, 55.233% 30.213%, 55.814% 30.213%, 56.395% 30.083%, 56.977% 30.083%, 57.558% 29.823%, 58.14% 29.693%, 58.721% 29.433%, 59.302% 29.174%, 59.884% 28.914%, 60.465% 28.524%, 61.047% 28.265%, 61.628% 27.875%, 62.209% 27.355%, 62.791% 26.966%, 63.372% 26.446%, 63.953% 26.057%, 64.535% 25.537%, 65.116% 25.148%, 65.698% 24.758%, 66.279% 24.368%, 66.86% 23.849%, 67.442% 23.589%, 68.023% 23.329%, 68.605% 22.94%, 69.186% 22.42%, 69.767% 21.901%, 70.349% 21.771%, 70.93% 21.511%, 71.512% 20.862%, 72.093% 19.693%, 72.674% 19.174%, 73.256% 18.784%, 73.837% 18.005%, 74.419% 17.615%, 75.0% 17.615%, 75.581% 17.615%, 76.163% 17.485%, 76.744% 17.615%, 77.326% 17.485%, 77.907% 17.226%, 78.488% 16.446%, 79.07% 15.667%, 79.651% 15.148%, 80.233% 14.368%, 80.814% 13.979%, 81.395% 13.719%, 81.977% 13.589%, 82.558% 13.589%, 83.14% 13.459%, 83.721% 13.589%, 84.302% 13.459%, 84.884% 13.719%, 85.465% 13.719%, 86.047% 13.719%, 86.628% 13.719%, 87.209% 13.849%, 87.791% 13.849%, 88.372% 13.849%, 88.953% 13.719%, 89.535% 13.719%, 90.116% 13.719%, 90.698% 13.719%, 91.279% 13.719%, 91.86% 13.719%, 92.442% 13.589%, 93.023% 13.459%, 93.605% 13.459%, 94.186% 13.459%, 94.767% 13.459%, 95.349% 13.329%, 95.93% 13.2%, 96.512% 13.2%, 97.093% 13.07%, 97.674% 12.94%, 98.256% 12.68%, 98.837% 12.55%, 99.419% 12.291%, 99.927% 12.161%, 100% 100%, 0% 100%);
}

.hero__mask-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: bottom;
}

/* Optional cinematic film-grain: an inline SVG turbulence filter, no image
   asset needed. Very low opacity, blended so it reads as texture, not noise. */
.hero__grain {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* Bottom-anchored, positioned relative to .hero__stage (now its parent),
   not .hero. left:88/bottom:32 are Figma's own numbers re-derived relative
   to the stage instead of the outer section: stage's own left inset is 32
   (vs. Content's original x:120 relative to Section), so 120-32=88; stage
   height 755 minus Content's original (y:149-16=133 relative to stage) minus
   its own height (590) leaves exactly 32px — matching the same 32px used
   for the stage's own corner radius, not a coincidence, just how it was
   nested in Figma.

   cqw here (same base as .hero__stage/.hero__title — .hero's own width,
   not .hero__stage's) still lines up correctly even though this
   element's containing block is .hero__stage: cqw always resolves to
   the same absolute length anywhere in .hero's subtree, and .hero__stage
   itself scales by the identical proportional factor, so the two stay
   correctly nested at any viewport width. */
.hero__content {
  position: absolute;
  left: 6.1111cqw; /* 88px */
  bottom: 2.2222cqw; /* 32px */
  width: 83.3333cqw; /* 1200px */
  z-index: 5;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.hero__form,
.hero-mobile__form {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  padding: 20px;
  border-radius: 16px;
  background-color: rgba(255, 255, 255, 0.24);
  border: 1px solid rgba(255, 255, 255, 0.24);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

/* cqw (not a literal 407px) so it keeps shrinking/growing proportionally
   with .hero__content's own now-fluid width instead of overflowing it at
   narrow tablet widths. */
.hero__form {
  width: 28.2639cqw; /* 407px */
}

/* Figma's mobile Form/FieldsGroup (node 143:233) is 332px, not desktop's
   407px — same glass-card look (shared rule above), different width.
   width:100% (of .hero-mobile__content, itself already a % of the fluid
   photo-wrap) instead of that literal px value — the fixed 332px doesn't
   shrink below itself, causing real horizontal overflow at any viewport
   narrower than ~350px (e.g. 320/340px phones): a rubber/fluid layout
   bug, not a Figma value to preserve as-is. */
.hero-mobile__form {
  width: 100%;
}

.hero__form-heading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: center;
  color: var(--semantic-text-inverse);
}

/* font-size in cqw (not the shared var() token) — .hero__form-title is
   desktop-only (mobile uses its own separate .hero-mobile__form-title),
   so no scoping needed here; it just needs to scale with the now-fluid
   form instead of staying frozen at a literal 42px. */
.hero__form-title {
  margin: 0;
  font-family: var(--font-Heading-M-DemiBold-family);
  font-size: 2.9167cqw; /* 42px */
  font-weight: var(--font-Heading-M-DemiBold-weight);
  line-height: var(--font-Heading-M-DemiBold-line-height);
  letter-spacing: var(--font-Heading-M-DemiBold-letter-spacing);
}

/* Desktop-only (see .hero__form-title above) — font-size in cqw. */
.hero__form-subtitle {
  margin: 0;
  font-family: var(--font-Body-L-Regular-family);
  font-size: 1.25cqw; /* 18px */
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
}

.hero__form-fields {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.hero__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 100%;
}

.hero__field label {
  font-family: var(--font-Link-L-Regular-family);
  font-size: var(--font-Link-L-Regular-size);
  font-weight: var(--font-Link-L-Regular-weight);
  line-height: var(--font-Link-L-Regular-line-height);
  letter-spacing: var(--font-Link-L-Regular-letter-spacing);
  color: var(--semantic-text-inverse);
}

.hero__field input {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 21px;
  border: none;
  border-radius: 999px;
  background-color: rgba(235, 235, 235, 0.4);
  font-family: var(--font-Link-L-Regular-family);
  font-size: var(--font-Link-L-Regular-size);
  font-weight: var(--font-Link-L-Regular-weight);
  line-height: var(--font-Link-L-Regular-line-height);
  letter-spacing: var(--font-Link-L-Regular-letter-spacing);
  color: var(--semantic-text-inverse);
}

.hero__field input::placeholder {
  color: var(--semantic-text-inverse);
  opacity: 0.54;
}

.hero__submit {
  width: 100%;
  height: 42px;
  border: none;
  border-radius: 999px;
  background-color: var(--semantic-primary);
  color: var(--semantic-text-inverse);
  font-family: var(--font-Link-L-DemiBold-family);
  font-size: var(--font-Link-L-DemiBold-size);
  font-weight: var(--font-Link-L-DemiBold-weight);
  line-height: var(--font-Link-L-DemiBold-line-height);
  letter-spacing: var(--font-Link-L-DemiBold-letter-spacing);
  cursor: pointer;
  box-shadow: 0 0 0 0 rgba(192, 15, 21, 0.55);
  transition: box-shadow 0.3s ease, transform 0.15s ease;
}

.hero__submit:hover {
  animation: heroSubmitPulse 1.6s ease-out infinite;
}

.hero__submit:active {
  transform: scale(0.97);
}

/* Desktop-only cqw overrides for the rest of the glass-card form's own
   internals (.hero__form itself already has its own cqw width override
   above). These classes/selectors are SHARED with .hero-mobile's form
   (same markup, same class names) — every rule below is scoped under
   .hero specifically so .hero-mobile's own fixed-px sizing (matching
   its own separate Figma mobile frame) is untouched.

   Without this, the fixed px gap/padding/font-size values stayed frozen
   at their 1440px-design size while .hero__form's own width shrank with
   cqw (see the override above) — at tablet widths the same 20px padding/
   16px text ate up a much bigger share of a much narrower box than at
   1440px, so the form read as disproportionately cramped compared to
   desktop instead of scaling down with everything else around it. */
.hero .hero__form {
  gap: 1.0417cqw; /* 15px */
  padding: 1.3889cqw; /* 20px */
  border-radius: 1.1111cqw; /* 16px */
}

.hero .hero__form-heading {
  gap: 0.5556cqw; /* 8px */
}

.hero .hero__form-fields {
  gap: 0.6944cqw; /* 10px */
}

.hero .hero__field {
  gap: 0.3472cqw; /* 5px */
}

.hero .hero__field label {
  font-size: 1.1111cqw; /* 16px, Link/L/Regular */
  letter-spacing: 0.0111cqw; /* 0.16px */
}

.hero .hero__field input {
  padding: 0.8333cqw 1.4583cqw; /* 12px 21px */
  font-size: 1.1111cqw; /* 16px, Link/L/Regular */
  letter-spacing: 0.0111cqw; /* 0.16px */
}

.hero .hero__submit {
  height: 2.9167cqw; /* 42px */
  font-size: 1.1111cqw; /* 16px, Link/L/DemiBold */
  letter-spacing: 0.0111cqw; /* 0.16px */
}

@keyframes heroSubmitPulse {
  0% { box-shadow: 0 0 0 0 rgba(192, 15, 21, 0.55); }
  70% { box-shadow: 0 0 0 14px rgba(192, 15, 21, 0); }
  100% { box-shadow: 0 0 0 0 rgba(192, 15, 21, 0); }
}

.hero__caption {
  margin: 0;
  width: 258px;
  font-family: var(--font-Body-XL-DemiBold-family);
  font-size: var(--font-Body-XL-DemiBold-size);
  font-weight: var(--font-Body-XL-DemiBold-weight);
  line-height: var(--font-Body-XL-DemiBold-line-height);
  letter-spacing: var(--font-Body-XL-DemiBold-letter-spacing);
  color: var(--semantic-text-inverse);
}

/* Desktop-only override (more specific than the shared rule above, which
   .hero-mobile's own caption keeps using unchanged as a literal 258px —
   .hero-mobile isn't a cqw container, so cqw here would resolve wrong if
   applied to the shared rule instead of scoped to .hero specifically). */
.hero .hero__caption {
  width: 17.9167cqw; /* 258px at the 1440px base */
}

/* Scroll indicator — not in Figma, added per request. Fades out early in
   the pinned scroll (handled in js/main.js). */
.hero__scroll-indicator {
  position: absolute;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--semantic-text-inverse);
  pointer-events: none;
}

.hero__scroll-indicator span {
  font-family: var(--font-Link-L-Regular-family);
  font-size: 12px;
  letter-spacing: 0.16px;
  text-transform: uppercase;
  opacity: 0.8;
}

.hero__scroll-indicator svg {
  display: block;
  animation: heroScrollBounce 1.6s ease-in-out infinite;
}

@keyframes heroScrollBounce {
  0%, 100% { transform: translateY(0); opacity: 0.5; }
  50% { transform: translateY(8px); opacity: 1; }
}

/* No @media (prefers-reduced-motion: reduce) block here on purpose: js/main.js
   already detects it and calls gsap.set() with the correct resting values.
   A CSS "opacity/transform: none !important" fallback would win over those
   inline styles regardless of source order and silently undo them. */

/* ============================================================
   Mobile Hero (Figma fileKey JmYoex09QPMmompAX7kaTT, node 143:225,
   "Section/Hero" 375x964 mobile frame) — a separate, simplified layout,
   not a squeezed-down version of the desktop one above. Figma marks
   Hero/BackgroundPhoto/Mask hidden on this frame, so there is
   deliberately no mask layer / mountain silhouette here, just one flat
   background photo. Shown only below the hero's existing 769px
   breakpoint (see the @media block at the end of this section) — the
   same breakpoint js/main.js already branches its
   ScrollTrigger.matchMedia on.

   Fluid rebuild: 375px is Figma's reference frame width, not a fixed
   canvas to render at — a literal `width:375px` here (an earlier version
   of this file had that) is a real bug at any viewport narrower than
   375px (e.g. 360px devices): it doesn't shrink, so the page gets 15px
   of unwanted horizontal scroll and text can end up clipped by that
   scroll boundary. Below, ONE element (.hero-mobile__photo-wrap) is the
   single fluid unit that actually sizes the section — full width minus
   Figma's 10px side inset, height following via aspect-ratio (355:932,
   Figma's own ratio) instead of a fixed 932px. Title and Content are
   both positioned in percentages *of that one box* (not of some
   separate fixed-height canvas), so they scale together with it and
   never exceed its edges at any viewport width. This also matches the
   actual Figma layering: Content (143:232) starts at y148, well inside
   the photo's y16–y948 span, so it's genuinely an overlay on the lower
   two-thirds of the photo, not a block stacked below it. */
/* container-type:inline-size (not in Figma, by request): makes the cqw
   unit below available to .hero-mobile__title, so its font-size scales
   continuously with the section's own fluid width (same technique used
   for every fluid-canvas heading elsewhere in this file) instead of
   staying frozen at a literal 40px — at a wider mobile frame, the form/
   content grow wider and the title now grows proportionally with them. */
.hero-mobile {
  display: none;
  position: relative;
  width: 100%;
  box-sizing: border-box;
  container-type: inline-size;
  background-color: var(--semantic-background);
  /* padding, not margin: the photo-wrap's own top spacing used to live in
     its margin-top, but a margin-top on a first child with nothing above
     it inside this section collapses into .hero-mobile's own (JS-driven)
     margin-top instead of adding to it — silently losing Figma's 16px
     canvas inset. Padding never collapses, so it's used here instead. */
  padding-top: 16px;
}

.hero-mobile__photo-wrap {
  position: relative;
  width: auto;
  margin: 0 10px 16px;
  aspect-ratio: 355 / 932;
}

/* Photo height growth is damped above the 375px Figma reference width
   (not in Figma, by request): aspect-ratio alone would keep scaling
   height 1:1 with width (e.g. ~1963px tall at a 768px frame), leaving a
   lot of empty photo below the title/form, whose own content height
   doesn't grow nearly as fast.

   The formula below is derived directly from the content stack, not a
   separate "looks about right" curve, so the title→form, form→caption
   and caption→bottom-edge gaps all stay proportional (per request)
   instead of just the box shrinking on its own:
     height = content-top(35.2cqw) + form-height(587px, fixed — the
       form's own internals aren't cqw-scaled; this is the form's real
       rendered height, ~13px taller than Figma's own 574px node height,
       since the browser's own text metrics for this font don't match
       Figma's exactly — using the real measured value here, not
       Figma's, is what keeps the bottom gap actually proportional)
       + form→caption gap (8.5333cqw) + caption-height(67px, fixed,
       real rendered height) + caption→bottom gap (33.6cqw)
     = (35.2 + 8.5333 + 33.6)cqw + (587 + 67)px = 77.3333cqw + 654px.
   At the 375px reference this comes to 290+654=944px — 12px more than
   the aspect-ratio value (932px) right at the 375/376px seam, for the
   same real-vs-Figma text metric reason; that's an imperceptible,
   one-time 12px step at an exact pixel boundary essentially no real
   device sits on, traded for the bottom gap actually staying close to
   proportional all the way to 768px (~1248px there) instead of drifting. */
@media (min-width: 376px) {
  .hero-mobile__photo-wrap {
    aspect-ratio: auto;
    height: calc(77.3333cqw + 654px);
  }
}

/* border-radius lives on the <img> itself, not a wrapper with
   overflow:hidden — Title/Content below are siblings positioned over
   this same box, and clipping the wrapper would risk cutting off the
   button/last field if the real rendered text height ever runs a few px
   past Figma's own estimate.

   object-position-x is a scroll-scrubbed CSS variable (not in Figma, by
   request — see js/main.js): this photo is the same wide source image
   as desktop's, and the truck (with its boom extended) is itself wider
   than this narrow box at any single crop, so a static object-position
   can never show the whole thing — 40% (the resting/no-JS/reduced-motion
   default, showing the cab) pans to 90% (the boom tip) as the section
   scrolls. */
.hero-mobile__photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--hero-mobile-photo-x, 40%) bottom;
  border-radius: 32px;
}

/* node 143:228: 40px, tracking 0.4px — NOT the same as the shared
   --font-Heading-2XL-DemiBold-mobile token (1px tracking); that token is
   used elsewhere and wasn't re-verified against this specific node, so
   the value here is taken directly from this node's own fresh fetch
   rather than reused, per "don't invent / don't assume" for this file.
   Position is left/top/width as % of the photo box (not px): relative
   to the photo (left10/top16/w355/h932 within the 375 frame), title's
   own box is left12/top72/w328 → 12/355, 72/932, 328/355.

   font-size/letter-spacing in cqw (not the literal 40px/0.4px, by
   request): relative to .hero-mobile's own width (375px reference, see
   container-type above), so the title grows/shrinks in step with the
   form/content around it across the whole fluid mobile range, not just
   at the exact 375px Figma frame.

   top is ALSO cqw now (not the original height-relative 7.725%, by
   request): top/bottom percentages resolve against the containing
   block's HEIGHT, which .hero-mobile__photo-wrap's own height no longer
   scales 1:1 with width (see the height formula below) — keeping top in
   %  would drift the title↔form gap out of proportion as that height
   is deliberately damped. cqw ties top to the SAME axis (width) that
   font-size now scales on, so the gap stays proportional throughout. */
.hero-mobile__title {
  position: absolute;
  left: 3.380%;
  top: 19.2cqw; /* 72px at the 375px reference width */
  width: 92.394%;
  z-index: 2;
  margin: 0;
  font-family: "SFT Schrifted Sans TRIAL";
  font-size: 10.6667cqw; /* 40px at the 375px reference width */
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.1067cqw; /* 0.4px */
  color: var(--semantic-text-inverse);
  text-transform: uppercase;
  white-space: nowrap;
}

/* Content (143:232): caption (using the shared .hero__caption class —
   node 143:266 is pixel-identical to desktop's: 258px, Body/XL/DemiBold)
   stacked above the form, 32px gap, per Figma's own child order — the
   opposite order from desktop. Position as % of the photo box, same
   method as the title: left11.5/top132/w332 relative to the photo
   (355x932) → 11.5/355, 132/932, 332/355.

   top and the form↔caption gap are cqw now, same reasoning as
   .hero-mobile__title's top above (proportional to width, not to the
   deliberately-non-1:1-scaling photo height) — otherwise the
   title→form and form→caption spacing would compress/overlap at wider
   mobile frames instead of staying proportional. */
.hero-mobile__content {
  position: absolute;
  left: 3.239%;
  top: 35.2cqw; /* 132px at the 375px reference width */
  width: 93.521%;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8.5333cqw; /* 32px at the 375px reference width */
}

/* node 143:236 "Book a pour" — 24px/line-height 1, distinct from the
   desktop title's 42px (--font-Heading-M-DemiBold), so not reusing that
   token here. */
.hero-mobile__form-title {
  margin: 0;
  font-family: "SFT Schrifted Sans TRIAL";
  font-size: 24px;
  font-weight: 600;
  line-height: 1;
}

/* node 143:237 — 16px/line-height 1 (desktop's subtitle token is 1.4). */
.hero-mobile__form-subtitle {
  margin: 0;
  font-family: "SFT Schrifted Sans TRIAL";
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
}

@media (max-width: 768px) {
  .hero {
    display: none;
  }

  .hero-mobile {
    display: block;
  }
}

/* ============================================================
   Mobile "What Sets Us Apart" (Figma fileKey JmYoex09QPMmompAX7kaTT,
   node 144:294, "Section/WhatSetsUsApart", 375x860 mobile frame).
   Base/mobile-first styles, no media query (see index.html for the
   <section id="why us"> markup). Numbers below are node 144:294's own
   metadata coordinates, not estimated.
   ============================================================ */
/* padding-top:40px (not Figma's own literal 32px node-y, by request):
   matches the section's own badges→heading gap (40px, see
   .why-us__heading below) exactly, so the Hero→badges gap and the
   badges→heading gap read as the same spacing rather than two
   different amounts — same value at every breakpoint (mobile and
   desktop both use it unchanged; see the removed 100vh/3 desktop
   margin-top note further down). */
.why-us {
  position: relative; /* positioning context for .why-us__play only */
  padding: 40px 0;
  container-type: inline-size; /* lets .why-us__heading's font-size below use cqw at every width, not just ≥1200px */
  overflow-x: hidden; /* not in Figma: js/main.js slides the heading in from well off-screen (translateX past +/-viewport width) — without clipping that here, the off-screen starting position itself inflates the page's real horizontal scroll range. Doesn't affect the mobile pinned card-scroll: GSAP pins .why-us__cards-scroll via position:fixed while active, which isn't constrained by an ancestor's overflow unless that ancestor also has its own transform/perspective (.why-us doesn't). */
  background-color: var(--semantic-background);
}

/* Section/TrustBadges/Default (144:295) at x88/y32, 16px vertical gap
   between its 3 badges. Each badge is individually offset within the
   group in Figma (x0/x37/x1.5) — preserved exactly rather than
   left-aligning all three to the same edge.

   margin:0 auto (not the literal x88 left-inset, by request): x88 was
   only ever a coincidental near-center at exactly the 375px Figma
   frame — at any other fluid mobile width it reads as a fixed left
   offset that drifts further off-center as the frame widens (measured
   up to ~650px off-center at 1024px). auto-centering keeps the whole
   group centered at any width instead. */
.why-us__badges {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 0 auto;
  width: fit-content;
}

.why-us__badge {
  display: flex;
  align-items: center;
  gap: 15px;
}

.why-us__badge--price {
  margin-left: 37px;
}

.why-us__badge--quality {
  margin-left: 1.5px;
}

.why-us__badge span {
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
  color: var(--semantic-text-primary);
  white-space: nowrap;
}

/* Section/Heading/WhatSetsUsApart (144:305): x10/y172, w355 (10px inset
   each side of the 375 frame), lowercase, second line right-aligned.
   This node's own tracking is 0.64px — the shared
   --font-Heading-XL-DemiBold-mobile token says 1px (a different node's
   value), so the literal per-node value from get_design_context is used
   for letter-spacing instead of the token, same as the Hero mobile
   title's handling of the same token/node mismatch.

   text-align:center (not the mobile frame's own left/right-aligned
   lines, by request): "Us Apart" being right-aligned inside a
   full-width block only reads as "the two lines frame the same center
   point" at exactly the 375px Figma width — at any wider fluid mobile
   frame, "What Sets" (left-default) and "Us Apart" (right-aligned)
   drift apart to their own edges instead of staying together as one
   centered heading. Desktop's own right-alignment (its two lines
   deliberately overlap at a specific offset, per Figma) is unaffected —
   see the min-width:1200px override further down, which now sets
   text-align:right there explicitly since it can no longer inherit it
   from here.

   font-size/letter-spacing in cqw (not the literal 64px/0.64px, by
   request): lets the heading grow "a few percent" with the fluid
   section width instead of staying frozen at the exact 375px value. */
.why-us__heading {
  margin: 40px 10px 0;
  text-align: center;
  font-family: var(--font-Heading-XL-DemiBold-mobile-family);
  font-size: 17.0667cqw; /* 64px at the 375px reference width */
  font-weight: var(--font-Heading-XL-DemiBold-mobile-weight);
  line-height: var(--font-Heading-XL-DemiBold-mobile-line-height);
  letter-spacing: 0.1707cqw; /* 0.64px */
  color: var(--semantic-text-primary);
  text-transform: lowercase;
}

.why-us__heading-line {
  display: block;
}

/* Icon/Play/Default (144:308) is a direct sibling of Section/Cards in
   Figma (not nested inside it), positioned in section-relative
   coordinates (x39/y275) — it overlaps the top-left of the first card
   simply by floating there (the cards row starts lower, at y365), not
   via any special clipping/z-index trick. Sizing/hover-ring come from
   the shared .play component (components.html/css) via the combined
   class="why-us__play play" in the markup; this rule only positions it. */
.why-us__play {
  position: absolute;
  left: 39px;
  top: 275px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  z-index: 2;
}

/* Section/Cards (144:309 mobile / 118:322 desktop) is 1200px wide
   INSIDE the 375px mobile frame — a deliberate horizontal-scroll strip
   of 5 cards there. overflow-x:auto is a no-op once the row fits inside
   its container (desktop, see media query below), so it's left
   unconditional rather than toggled per breakpoint. */
.why-us__cards-scroll {
  margin-top: 65px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-left: 11px;
}

.why-us__cards {
  position: relative;
  width: 1200px;
  height: 463px;
  perspective: 1000px; /* not in Figma, by request: gives js/main.js's rotateY flip-in a real sense of depth instead of looking flat */
}

/* Cards themselves reuse the existing .card-feature component
   (components.html — base styles + hover states in this file's
   "Card/Feature" block above) instead of a separate implementation.
   Only grid placement is added here, scoped under .why-us__cards so
   .card-feature's own rules aren't touched. left/top match both the
   144:309 (mobile) and 118:322 (desktop) instance positions, which are
   pixel-identical, so one set of rules covers both breakpoints.

   backface-visibility:hidden (not in Figma, by request): js/main.js
   flips each card in from rotateY(180deg) — without this, the 180deg
   starting frame would show the card mirrored/backwards instead of
   simply not-yet-visible. */
.why-us__cards .card-feature {
  position: absolute;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* top:0 is repeated per-card (not left on the shared rule above) on
   purpose: ".why-us__cards .card-feature" has higher specificity (two
   classes) than a single ".why-us__card--*" class, so a shared
   "top: 0" there was silently winning over best-price/direct-contact's
   own top:157px and collapsing the zigzag stagger back to a flat row. */
.why-us__card--reliable { left: 0; top: 0; }
.why-us__card--best-price { left: 246px; top: 157px; }
.why-us__card--professional { left: 492px; top: 0; }
.why-us__card--direct-contact { left: 738px; top: 157px; }
.why-us__card--give-back { left: 984px; top: 0; }

/* ============================================================
   Desktop "What Sets Us Apart" (Figma fileKey JmYoex09QPMmompAX7kaTT,
   node 91:996, "Section/WhatSetsUsApart", 1440x861 desktop frame).
   Only what changes from the mobile-first rules above — everything not
   overridden here (fonts, colors, radii, card internals, card grid
   positions, which are pixel-identical between the two frames) is
   inherited as-is. 1200px matches the breakpoint requested, not a
   Figma value.

   .why-us is fluid (100%, capped at Figma's native 1440px) rather than
   a fixed 1440px canvas — a literal width:1440px here overflowed and
   clipped the heading text (mid-word) at any viewport between 1200 and
   1440px, i.e. across most of this breakpoint's own range, not just at
   its edge. container-type:inline-size + cqw below scale the heading
   proportionally with it (same Figma ratios, just not fixed px), so it
   never clips; cqw is 1% of the container's own width, which is capped
   at 1440px the same way the old fixed width was, so at ≥1440px the
   heading renders at the exact literal Figma px values either way. */
@media (min-width: 1200px) {
  /* padding-top override, not the mobile-first 40px, by request: on
     desktop .why-us__heading is position:absolute at a fixed cqw offset
     from .why-us's own top (independent of .why-us__badges, which sits
     in normal flow right after the padding) — so unlike mobile (where
     the badges→heading gap is a plain margin-top on the heading,
     automatically unaffected by padding changes), increasing this
     section's padding-top pushes badges down without moving the
     heading, which shrinks the badges→heading gap instead of leaving it
     alone. Solving "Hero→badges gap == badges→heading gap" for this
     breakpoint's own numbers (badges height 24px, heading's own cqw top
     ≈97px at 1440px) gives 36.5px here, vs the mobile value of 40px.
     cqw can't be used for this property directly — .why-us is the
     container query host, and a container can't size itself off its
     own cqw. 36.5px is exact at 1440px+ (both gaps 36.5px); it drifts
     to ~28px "ideal" right at the 1200px edge (a few px of imprecision,
     same order of magnitude as similar cqw/fixed-px mismatches already
     accepted elsewhere in this file, e.g. Hero mobile's caption→bottom
     gap). */
  .why-us {
    width: 100%;
    max-width: 1440px;
    margin: 0 auto;
    padding-top: 36.5px;
    /* container-type:inline-size already set unconditionally above */
  }

  /* Figma: row of 3, gap112, centered as a group (calc(50%+0.5px) with
     translateX(-50%) in the source) — margin:auto centering is the
     equivalent result without replicating that sub-pixel offset, which
     is Figma auto-layout rounding noise, not a meaningful design value. */
  .why-us__badges {
    flex-direction: row;
    gap: 112px;
    width: fit-content;
    margin: 0 auto;
  }

  /* Mobile's per-badge stagger (144:299 x37, 144:302 x1.5) doesn't exist
     on this frame (91:1004 x311, 91:1009 x548 — even spacing via gap
     alone), so it's reset here. */
  .why-us__badge--price,
  .why-us__badge--quality {
    margin-left: 0;
  }

  /* Section/Heading/WhatSetsUsApart (91:1012): 1200x237 at x120/y97. Its
     two lines genuinely overlap vertically in Figma (line-center gap of
     124px inside a 168px-tall line), so — like Hero's overlapping
     photo/title layers — this one heading needs position:absolute for
     its two lines; nothing else in this section does. */
  .why-us__heading {
    position: absolute;
    left: 8.3333cqw;   /* 120px / 1440px */
    top: 6.7361cqw;    /* 97px / 1440px */
    width: 83.3333cqw; /* 1200px / 1440px */
    height: 16.4583cqw; /* 237px / 1440px */
    margin: 0;
    font-size: 11.6667cqw;      /* 168px / 1440px */
    letter-spacing: 0.1167cqw;  /* 1.68px / 1440px */
    /* Figma's own export has whitespace-nowrap on this node — without it,
       "Us Apart" wraps inside its 667px box (that width is the text's own
       intrinsic width at 168px, not a wrap constraint). */
    white-space: nowrap;
  }

  /* text node 91:1013 "What Sets": x0/y-31/w800/h168 relative to the
     heading box above, expressed the same way (cqw = % of 1440px). */
  .why-us__heading-line {
    position: absolute;
    left: 0;
    top: -2.1528cqw;   /* -31px / 1440px */
    width: 55.5556cqw; /* 800px / 1440px */
  }

  /* text node 91:1014 "Us Apart": x545/y93/w667/h168 relative to the
     heading box. text-align:right is set explicitly here now (used to
     inherit from the base rule, which is now text-align:center for the
     mobile centering fix above — desktop's own intentional
     right-alignment/overlap is otherwise unchanged). */
  .why-us__heading-line--right {
    text-align: right;
    left: 37.8472cqw; /* 545px / 1440px */
    top: 6.4583cqw;   /* 93px / 1440px */
    width: 46.3194cqw; /* 667px / 1440px */
  }

  /* Icon/Play/Default (91:1015): x600/y190 (mobile was x39/y275). */
  .why-us__play {
    left: 600px;
    top: 190px;
  }

  /* Section/Cards (118:322) fits inside the 1440px frame at its native
     1200px width (120px inset each side) once the viewport is wide
     enough — margin-top:310px lands the row at the same y366 Figma
     gives it (32 section padding-top + 24 badge row height + 310 =
     366), keeping it in normal flow rather than switching to
     position:absolute. overflow-x:auto is inherited unchanged from the
     mobile-first rule on purpose: the 1200px-wide card row (fixed size,
     reusing the shared .card-feature component as-is) doesn't fit in a
     1200px viewport with a 120px left inset, so auto-scroll is the
     fallback for that range instead of clipping the last card. */
  .why-us__cards-scroll {
    margin-top: 310px;
    padding-left: 120px;
  }
}

/* Restored by explicit request (was removed for one message, then
   reported as WhatSetsUsApart overlapping/covering Hero on real
   desktop testing — this margin-top is what was preventing that,
   independent of the .why-us padding-top above, which stays 40px so
   the badges→heading gap fix from that same earlier message is
   unaffected: this is margin BEFORE .why-us's own box, that padding is
   AFTER it, so both can be correct at once). Hero's own height is now
   fluid (aspect-ratio-based, scales with viewport width) rather than a
   fixed 787px, so at narrower desktop/tablet widths it's shorter still
   relative to typical viewport heights than it used to be — the gap
   this margin creates is what keeps Hero's pin fully releasing (and
   settling) before WhatSetsUsApart's own content is on screen. */
@media (min-width: 769px) {
  .why-us {
    margin-top: calc(100vh / 3);
  }
}

/* ==========================================================================
   Section/Equipment (Figma fileKey JmYoex09QPMmompAX7kaTT, node 144:455
   mobile 375px frame / 91:1036 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above. <equipment> is a
   non-standard tag by request; display:block makes it behave as a normal
   block-level section container.

   The mobile frame's own "Equipment" cards group (144:458) is a literal,
   unmodified copy of the desktop one (144:459-465 share the exact same
   x/y/width/height as 91:1039's children) — Figma itself never redesigned
   this row for mobile, it's the same 1200px-wide row at every breakpoint.
   .spec-card / .spec-card__* below are components.html's own markup and
   CSS, reused verbatim (not restyled) per instruction; only the
   .equipment__cards-scroll wrapper is new, giving that fixed-width row
   the same horizontal-scroll fallback Section/WhatSetsUsApart's row
   already uses for the same reason.

   .equipment is a cq container (container-type:inline-size) from this
   base rule up — not just inside the desktop media query, by request
   ("резинова верстка"): every property below uses cqw units (1% of
   .equipment's own current width, Figma's 375px mobile frame as the
   375->cqw reference) instead of the old frozen max-width:375px, so the
   whole composition scales continuously with the viewport exactly the
   way the >=1200px desktop rule already scales its own 1440px numbers —
   reusing that established mechanism rather than inventing a new one.
   This growth is capped at the @media(min-width:768px) block further
   down: past 768px every value freezes at its own 768px-equivalent size
   instead of continuing to scale, by request — this mobile composition
   is a portrait layout (694px tall on a 375px-wide frame) with no
   Figma-defined tablet frame, so letting it keep scaling proportionally
   all the way to 1199px would make the section unreasonably tall on a
   wider tablet before the desktop rule's own, entirely different
   landscape composition takes over at 1200px.

   height is calc(91.2cqw + 352px), NOT a flat 185.067cqw (694px/375px)
   scaled from the mobile frame's own total height — .spec-card stays
   fixed px (not cqw, see above), so scaling the SECTION's own height by
   the same ratio as everything else leaves a growing gap between the
   fixed-size cards and the section's own (scaled-up) bottom edge as the
   viewport widens, up to ~468px extra by 768px — a real bug, not a
   Figma value. 91.2cqw is .equipment__cards-scroll's own top (below);
   352px is the tallest card's own height (320px, Spec/VerticalHeight)
   plus Figma's own 32px trailing gap after it (144:455's own height694
   - cards-scroll-top342 - cardHeight320 = 32) — both fixed, matching the
   cards' own fixed sizing. This reduces to the exact literal 694px at
   375px width (91.2%*375 + 352 = 694), so nothing shifts at the mobile
   reference frame. */
.equipment {
  display: block;
  position: relative;
  width: 100%;
  height: calc(91.2cqw + 352px); /* cards-scroll-top(cqw) + tallest card(320px) + Figma's own 32px trailing gap */
  container-type: inline-size;
  margin: 0 auto;
  overflow: hidden;
  background-color: var(--semantic-background);
}

/* node 144:467: 64px Heading/XL/DemiBold/mobile, lowercase. Letter-spacing
   is this node's own fetched value (0.64px) — the shared
   --font-Heading-XL-DemiBold-mobile token's 1px belongs to a different
   node and doesn't match this one, same situation as Hero's and
   WhatSetsUsApart's mobile headings. Starts at opacity:0 — js/main.js
   fades it in once, prefers-reduced-motion sets it to 1 directly.
   font-size is cqw (not the fixed --font-...-mobile-size var) so it
   grows proportionally with the section, by request — same reasoning
   as .equipment above. */
.equipment__heading {
  position: absolute;
  left: 2.667cqw;   /* 10px / 375px */
  top: 8.533cqw;    /* 32px / 375px */
  width: 94.667cqw; /* 355px / 375px */
  margin: 0;
  font-family: var(--font-Heading-XL-DemiBold-mobile-family);
  font-size: 17.067cqw; /* 64px / 375px */
  font-weight: var(--font-Heading-XL-DemiBold-mobile-weight);
  line-height: var(--font-Heading-XL-DemiBold-mobile-line-height);
  letter-spacing: 0.1707cqw; /* 0.64px / 375px */
  color: var(--Neutral-700);
  text-transform: lowercase;
  z-index: 1;
  opacity: 0;
}

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

.equipment__truck-layer {
  position: absolute;
  opacity: 0;
}

/* Equipment/TruckIllustration/Default (144:457): x-36.62/y163.93/
   w442.24/h137.89 — its own left is genuinely negative in Figma (the
   illustration bleeds past the frame edge on both sides); .equipment's
   overflow:hidden clips it the same way the frame itself would. */
.equipment__truck-layer--default {
  left: -9.765cqw;    /* -36.619px / 375px */
  top: 43.7152cqw;    /* 163.932px / 375px */
  width: 117.930cqw;  /* 442.239px / 375px */
  height: 36.7707cqw; /* 137.89px / 375px */
}

/* The Default layer's own image is zoomed/cropped inside its box (Figma:
   height 213.81%, top -40.33%) rather than plain object-fit — reproduced
   exactly since it's a deliberate crop into the source illustration, not
   a simple cover fit. */
.equipment__truck-crop {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.equipment__truck-crop img {
  position: absolute;
  left: 0;
  top: -40.33%;
  width: 100%;
  height: 213.81%;
  max-width: none;
}

/* Equipment/TruckIllustration/Scrolled (144:456) is genuinely a
   different Figma box (x0.03/y113/w386.34/h281.99) from Default's — but
   js/main.js now crossfades Default straight into Scrolled with zero
   movement, by request ("не має бути ніяких стрибків... стояти на тому ж
   місці що і перша картинка"), so Scrolled is deliberately given
   Default's own box instead of its literal Figma one: the two source
   images (equipment-truck-default.png / -scrolled.png) are the exact
   same 1536x1024 render of the same truck in the same pose, just two
   different visual treatments (photo vs. line art) — reusing Default's
   own box + crop percentages means both layers frame the truck
   identically, so the crossfade has nothing left to jump. */
.equipment__truck-layer--scrolled {
  left: -9.765cqw;    /* matches --default, see comment above */
  top: 43.7152cqw;
  width: 117.930cqw;
  height: 36.7707cqw;
  overflow: hidden;
}

.equipment__truck-layer--scrolled img {
  position: absolute;
  left: 0;
  top: -40.33%;
  width: 100%;
  height: 213.81%;
  max-width: none;
}

.equipment__cards-scroll {
  position: absolute;
  left: 2.667cqw;  /* 10px / 375px */
  top: 91.2cqw;    /* 342px / 375px */
  right: 2.667cqw; /* 10px / 375px */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  z-index: 2;
}

.equipment__cards {
  display: flex;
  align-items: flex-start;
  gap: 4px; /* 172 - 168 = 4px between every card, both breakpoints */
}

/* 768px+ (up to the 1200px desktop cutover): freezes every cqw value
   above at its own 768px-equivalent size (val/375*768, as a fixed px)
   instead of letting it keep growing — see the "potim stop" reasoning
   in the .equipment comment up top. */
@media (min-width: 768px) {
  .equipment {
    max-width: 768px;
    height: 1052.16px; /* cards-scroll-top(700.16px, 91.2cqw*768px) + tallest card(320px) + Figma's own 32px trailing gap */
  }

  .equipment__heading {
    left: 20.48px;    /* 10px / 375px * 768px */
    top: 65.536px;    /* 32px / 375px * 768px */
    width: 727.68px;  /* 355px / 375px * 768px */
    font-size: 131.072px; /* 64px / 375px * 768px */
    letter-spacing: 1.311px; /* 0.64px / 375px * 768px */
  }

  .equipment__truck-layer--default,
  .equipment__truck-layer--scrolled {
    left: -75.005px;  /* -36.619px / 375px * 768px */
    top: 335.98px;    /* 163.932px / 375px * 768px */
    width: 905.99px;  /* 442.239px / 375px * 768px */
    height: 282.34px; /* 137.89px / 375px * 768px */
  }

  .equipment__cards-scroll {
    left: 20.48px;   /* 10px / 375px * 768px */
    top: 700.16px;   /* 342px / 375px * 768px */
    right: 20.48px;  /* 10px / 375px * 768px */
  }
}

/* Desktop (91:1036, 1440px frame). container-type:inline-size + cqw
   below scale the heading and truck layers fluidly between 1200 and
   1440px viewport width — a literal fixed width:1440px here reproduces
   the exact overflow/clipping bug already fixed once on
   Section/WhatSetsUsApart's heading (168px text doesn't fit a narrower
   viewport at a fixed px size). cqw is 1% of the container's own
   (capped) width, so at >=1440px these resolve to the exact literal
   Figma px values either way. .spec-card itself stays fixed px (not
   cqw) since it's components.html's own untouched component — the
   .equipment__cards-scroll wrapper is the horizontal-scroll fallback
   for whatever width shortfall that creates, same as mobile. */
@media (min-width: 1200px) {
  .equipment {
    max-width: 1440px;
    height: 59.236cqw; /* 853px / 1440px */
  }

  /* node 91:1048: 168px Heading/XL/DemiBold, lowercase, tracking 1.68px
     (this node's own value, not the shared token's 1px). */
  .equipment__heading {
    left: 0;
    right: 0;
    width: 81.319cqw;  /* 1171px */
    margin: 0 auto;
    top: 2.222cqw;     /* 32px */
    font-size: 11.667cqw; /* 168px */
    letter-spacing: 0.1167cqw; /* 1.68px */
    color: var(--semantic-text-primary);
    white-space: nowrap;
  }

  /* Equipment/TruckIllustration/Default (91:1038): x140/y427/w1161/h362.
     Scrolled shares this exact box too (not its own true 91:1037 one) —
     js/main.js crossfades Default straight into Scrolled with zero
     movement here (see the mobile/tablet comment on
     .equipment__truck-layer--scrolled above), then, on desktop only,
     translates Scrolled down by a further 236px (a Figma value, the
     settled gap under the heading — not derived from 91:1037's own box),
     which is where cards-scroll's own top:266px ends up sitting above
     it. */
  .equipment__truck-layer--default,
  .equipment__truck-layer--scrolled {
    left: 9.722cqw;    /* 140px */
    top: 29.653cqw;    /* 427px */
    width: 80.625cqw;  /* 1161px */
    height: 25.139cqw; /* 362px */
  }

  /* Equipment (91:1039): x120/y266/w1200 — outer positioning only; the
     1200px-wide row of fixed-size cards inside still scrolls
     horizontally if the viewport is narrower than 1200+2*120px. */
  .equipment__cards-scroll {
    left: 8.333cqw;  /* 120px */
    right: auto;
    top: 18.472cqw;  /* 266px */
    width: 83.333cqw; /* 1200px */
  }
}

/* ==========================================================================
   Section/AboutUs (Figma fileKey JmYoex09QPMmompAX7kaTT, node 146:516
   mobile 375px frame / 91:1049 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above. <About> is a
   non-standard tag by request; display:block makes it behave as a
   normal block-level section container.

   Unlike Hero/Equipment, both Figma frames already lay this section out
   as plain centered normal-flow content (flex-column, no absolute
   positioning) — so it stays normal flow here too; no fixed-canvas/cqw
   scaling is needed since nothing here is wide enough to risk
   overflowing between 1200 and 1440px (940px content max).

   .about-us is a cq container (container-type:inline-size) from this
   base rule up, same technique as Section/Equipment, by request
   ("резинова верстка... заголовок збільшувався пропорційно як в
   попередніх блоках"): .about-us__heading's font-size/letter-spacing
   below are cqw (375px mobile frame as the reference) instead of the
   fixed --font-Heading-XL-DemiBold-mobile-* tokens, so they scale
   continuously with the viewport. Growth is capped at the
   @media(min-width:768px) block further down — past 768px the heading
   freezes at its own 768px-equivalent size instead of continuing to
   scale, same "proportional up to ~768px, then stop" convention already
   used on Section/Equipment, before the existing >=1200px desktop rule
   takes over with its own, already-fluid-independent values. Nothing
   else in this section (photo, bio, button) scales — not asked for, and
   photo is explicitly "same size both breakpoints" per Figma. */
/* margin-top:20px (mobile/tablet only, reset to 0 at >=1200px below) is
   this section's own real Figma gap from Section/Equipment (144:455
   bottom y4640, 146:516 top y4660) — by request. Desktop's own two
   frames (91:1036/91:1049) sit exactly flush (0px), which is preserved
   in the @media(min-width:1200px) block further down. */
.about-us {
  display: block;
  position: relative;
  margin-top: 20px;
  padding: 32px 0; /* Section height564 - Content(500) = 64, symmetric top/bottom */
  background-color: var(--semantic-background);
  container-type: inline-size;
}

.about-us__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  width: 100%;
}

.about-us__text-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
}

/* node 146:520: 64px Heading/XL/DemiBold/mobile, lowercase. Letter-
   spacing is this node's own fetched value (0.64px) — the shared
   --font-Heading-XL-DemiBold-mobile token's 1px belongs to a different
   node, same situation as Hero's/Equipment's mobile headings. font-size/
   letter-spacing are cqw (not the fixed token/0.64px) so they grow
   proportionally with the section, by request — see the class comment
   above. */
.about-us__heading {
  margin: 0;
  font-family: var(--font-Heading-XL-DemiBold-mobile-family);
  font-size: 17.067cqw; /* 64px / 375px */
  font-weight: var(--font-Heading-XL-DemiBold-mobile-weight);
  line-height: var(--font-Heading-XL-DemiBold-mobile-line-height);
  letter-spacing: 0.1707cqw; /* 0.64px / 375px */
  color: var(--Neutral-700);
  text-transform: lowercase;
  text-align: center;
  white-space: nowrap;
  opacity: 0; /* animated in by js/main.js; prefers-reduced-motion sets to 1 directly */
}

/* Section/AboutUs/Photo (146:521): 281x164, same size both breakpoints. */
.about-us__photo {
  width: 281px;
  height: 164px;
  border-radius: 32px;
  overflow: hidden;
  opacity: 0;
}

.about-us__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* node 146:522: 24px Body/2XL/Regular/mobile. */
.about-us__bio {
  margin: 0;
  width: 100%;
  font-family: var(--font-Body-2XL-Regular-mobile-family);
  font-size: var(--font-Body-2XL-Regular-mobile-size);
  font-weight: var(--font-Body-2XL-Regular-mobile-weight);
  line-height: var(--font-Body-2XL-Regular-mobile-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-mobile-letter-spacing);
  color: var(--Neutral-700);
  text-align: center;
  opacity: 0;
}

/* Toggle/ReadMore/Default (141:350 / 146:523): reuses the shared
   .button/.button--secondary component as-is (same bg/text color/font/
   padding/radius/gap) — only its fixed width:187px (sized for "book
   now") doesn't match this instance's natural ~159px content width, so
   it's reset to auto here rather than touching the shared rule. */
.about-us__more {
  width: auto;
  opacity: 0;
}

/* 768px+ (up to the 1200px desktop cutover): freezes the heading's cqw
   values above at their own 768px-equivalent size (val/375*768, as a
   fixed px) instead of letting them keep growing — same "potim stop"
   reasoning as Section/Equipment's own tablet freeze. */
@media (min-width: 768px) {
  .about-us__heading {
    font-size: 131.072px; /* 64px / 375px * 768px */
    letter-spacing: 1.311px; /* 0.64px / 375px * 768px */
  }
}

@media (min-width: 1200px) {
  .about-us {
    margin-top: 0; /* desktop's own Section/Equipment+Section/AboutUs frames sit exactly flush, per Figma */
    padding: 49px 0; /* Section height660 - Content(562) = 98, symmetric top/bottom */
  }

  .about-us__content {
    width: 940px;
    max-width: calc(100% - 40px);
    margin: 0 auto;
  }

  /* node 91:1057: 168px Heading/XL/DemiBold, tracking 1.68px (this
     node's own value, not the shared token's 1px). */
  .about-us__heading {
    font-family: var(--font-Heading-XL-DemiBold-family);
    font-size: var(--font-Heading-XL-DemiBold-size);
    font-weight: var(--font-Heading-XL-DemiBold-weight);
    line-height: var(--font-Heading-XL-DemiBold-line-height);
    letter-spacing: 1.68px;
    color: var(--semantic-text-primary);
  }

  /* node 91:1059: 32px Body/2XL/Regular. */
  .about-us__bio {
    font-family: var(--font-Body-2XL-Regular-family);
    font-size: var(--font-Body-2XL-Regular-size);
    font-weight: var(--font-Body-2XL-Regular-weight);
    line-height: var(--font-Body-2XL-Regular-line-height);
    letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
    color: var(--semantic-text-primary);
  }
}

/* ==========================================================================
   Section/OurServices (Figma fileKey JmYoex09QPMmompAX7kaTT, node 91:1219
   mobile 375px frame / 91:1102 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as Section/WhatSetsUsApart. <services> is a
   non-standard tag by request; display:block makes it behave as a normal
   block-level section container the way a real element would.
   ========================================================================== */
.services {
  display: block;
  position: relative;
  background-color: var(--semantic-background);
  padding: 44px 0 51px; /* logo top y44; section height1950 - LinePumping bottom1899 = 51 */
}

.services__logo {
  width: 84px;
  height: 42px;
  margin: 0 auto;
}

.services__logo img {
  display: block;
  width: 100%;
  height: 100%;
}

/* Section/Heading/ServicesIntro (91:1220): w355, 40px Heading/L/DemiBold/
   mobile, centered. margin-top 16 = heading top102 - logo bottom86.
   width/max-width (not a bare fixed width) so it can't overflow a
   viewport narrower than 375px — same fix as the mobile Hero rebuild. */
/* width:calc(100% - 20px) (not the literal 355px, by request — "заголовок
   розширюється на весь екран"): a fixed 355px width only ever matched
   the exact 375px reference frame — on any wider mobile/tablet
   viewport within this range (e.g. 600–767px) it stayed frozen at
   355px instead of actually using the extra space, since max-width
   only constrains it on the narrow side. Using the same calc() as the
   width directly makes it genuinely stretch with the screen. */
.services__heading {
  margin: 16px auto 0;
  width: calc(100% - 20px);
  font-family: var(--font-Heading-L-DemiBold-mobile-family);
  font-size: var(--font-Heading-L-DemiBold-mobile-size);
  font-weight: var(--font-Heading-L-DemiBold-mobile-weight);
  line-height: var(--font-Heading-L-DemiBold-mobile-line-height);
  letter-spacing: var(--font-Heading-L-DemiBold-mobile-letter-spacing);
  text-align: center;
  /* Read by js/main.js to know what color to scrub every word to — by
     explicit request the WHOLE heading (both lines, including "to your
     project needs:") reveals to this one color, not just line 1 — kept
     as a custom property (not hardcoded in JS) so it stays a single
     source of truth across breakpoints. Same token on both breakpoints
     on purpose (also by request), even though line 1's own Figma title
     color differs slightly per breakpoint (#151516 desktop / #1f1f1f
     mobile) — this reveal color is added behavior, not a Figma value. */
  --services-word-color: var(--semantic-text-primary);
}

.services__heading-line {
  display: block;
}

/* .services__word (both lines) starts gray — the "unrevealed" state
   added by request, not present in Figma — js/main.js scrubs each
   word's color to --services-word-color as the heading scrolls into
   view. Mobile's own muted gray (Neutral-200 / #d7d7d7, node 91:1221's
   real color) is reused as the "unrevealed" starting color; the
   desktop override below swaps it for #a5a5a5, node 91:1104's own. */
.services__word {
  color: var(--Neutral-200);
}

.services__stack {
  position: relative;
  margin-top: 42px; /* BoomPumping card top364 - heading bottom322 */
}

/* width:calc(100% - 20px) (not the literal 355px), same reasoning as
   .services__heading above, by request: Card/Service/BoomPumping and
   Card/Service/LinePumping should also stretch with the screen instead
   of staying frozen at the exact 375px reference width. */
.service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
  width: calc(100% - 20px);
  margin: 0 auto;
  padding: 24px 0;
  box-sizing: border-box;
  border-top: 1px solid var(--Neutral-200);
  background-color: var(--semantic-background);
}

.service-card--boom {
  z-index: 1;
}

/* z-index:2 so it visually rides on top of BoomPumping. Its resting
   margin-top (the permanent overlap) is set by js/main.js from real
   measured heights, not a hardcoded guess — see computeServiceCardOverlap()
   there. Without JS (or prefers-reduced-motion), it stays at its natural,
   non-overlapping flow position — a plain sequential fallback. */
.service-card--line {
  z-index: 2;
}

.service-card__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  width: 100%;
}

.service-card__title-row {
  display: flex;
  align-items: center;
  gap: 24px;
  width: 100%;
}

.service-card__bullet {
  display: block;
  width: 7px;
  height: 7px;
  flex-shrink: 0;
}

.service-card__bullet img {
  display: block;
  width: 100%;
  height: 100%;
}

.service-card__title {
  margin: 0;
  font-family: var(--font-Heading-M-DemiBold-mobile-family);
  font-size: var(--font-Heading-M-DemiBold-mobile-size);
  font-weight: var(--font-Heading-M-DemiBold-mobile-weight);
  line-height: var(--font-Heading-M-DemiBold-mobile-line-height);
  letter-spacing: var(--font-Heading-M-DemiBold-mobile-letter-spacing);
  color: var(--Neutral-700);
  white-space: nowrap;
}

.service-card__desc {
  margin: 0;
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
  color: #696969;
  width: 100%;
}

/* aspect-ratio (not the literal 472px height, by request — "резинова
   верстка"): a fixed height alongside a fluid width doesn't shrink the
   box's PROPORTIONS at narrower phones, just its width, so at e.g.
   320px the box gets visibly taller/narrower than Figma's own 355:472
   ratio intended. aspect-ratio keeps height following width instead. */
.service-card__media {
  width: 100%;
  aspect-ratio: 355 / 472;
  border-radius: 32px;
  overflow: hidden;
}

/* object-fit:fill (not cover, mobile only, by request): stretches the
   photo to completely fill the box instead of cropping it — desktop's
   own override further down restores cover (unchanged, not part of
   this request). object-position is a no-op under fill (nothing left
   to crop/anchor) but harmless to leave set. */
.service-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
  object-position: bottom;
}

/* Tablet breakpoint (not in Figma — only a 375px mobile frame and a
   1440px desktop frame exist, by request). Below this, cards use the
   mobile-first stacked layout unchanged; the @media(min-width:1200px)
   block further down still fully overrides the row layout's own
   dimensions once it applies, so this is only "live" for the
   768–1199px range in between.

   Switches cards to the same side-by-side row arrangement as desktop,
   but expressed as fluid percentages of the card's own (still fluid)
   width instead of desktop's literal fixed pixels (708px media /
   421px content / 1200px card), which would overflow a sub-1200px
   viewport if reused as-is. The percentages themselves are exactly the
   desktop pixel values' own ratios (708/1200, 421/1200, 71/1200), so
   the row keeps the same relative proportions all the way up to where
   the 1200px breakpoint takes over with the literal values. Text size/
   color intentionally still comes from the mobile-first rules at this
   range (not the desktop overrides below) — this is a layout-only
   fluidity fix, not a typography change. */
@media (min-width: 768px) {
  /* Same calc() as the card's own tablet margin below (20px each side)
     so the heading also "expands to the full screen" at this
     breakpoint, by request, instead of staying at the mobile-first
     rule's narrower width. */
  .services__heading {
    width: calc(100% - 40px);
  }

  .service-card {
    flex-direction: row;
    align-items: flex-start;
    gap: 5.9167%; /* 71px / 1200px */
    width: 100%;
    max-width: calc(100% - 40px);
  }

  .service-card__content {
    width: 35.0833%; /* 421px / 1200px */
    flex-shrink: 0;
  }

  .service-card__media {
    width: 59%; /* 708px / 1200px */
    aspect-ratio: 708 / 472;
    flex-shrink: 0;
  }

  /* object-fit:fill is inherited unchanged from the mobile-first rule
     here (by request, tablet photos should also be fill, not cover). */
}

@media (min-width: 1200px) {
  .services {
    padding: 32px 0 32px; /* logo top32; section height1447 - LinePumping bottom1415 = 32 */
  }

  .services__heading {
    margin-top: 12px; /* heading top86 - logo bottom74 */
    width: 1025px;
    max-width: calc(100% - 40px);
    font-family: var(--font-Heading-L-DemiBold-family);
    font-size: var(--font-Heading-L-DemiBold-size);
    font-weight: var(--font-Heading-L-DemiBold-weight);
    line-height: var(--font-Heading-L-DemiBold-line-height);
    letter-spacing: var(--font-Heading-L-DemiBold-letter-spacing);
    /* --services-word-color already equals --semantic-text-primary in
       the base rule — no override needed here, same color both breakpoints. */
  }

  /* Node 91:1104's own unrevealed gray (#a5a5a5) — different from mobile's
     #d7d7d7 (91:1221), so this one still needs a breakpoint override. */
  .services__word {
    color: var(--semantic-text-disabled);
  }

  .services__stack {
    margin-top: 36px; /* BoomPumping card top359 - heading bottom323 */
  }

  .service-card {
    flex-direction: row;
    align-items: flex-start;
    gap: 71px;
    width: 1200px;
    max-width: calc(100% - 40px);
    padding: 24px 0;
    border-top-color: var(--semantic-border);
  }

  .service-card__content {
    gap: 36px;
    width: 421px;
    flex-shrink: 0;
  }

  .service-card__title {
    font-family: var(--font-Heading-M-DemiBold-family);
    font-size: var(--font-Heading-M-DemiBold-size);
    font-weight: var(--font-Heading-M-DemiBold-weight);
    line-height: var(--font-Heading-M-DemiBold-line-height);
    letter-spacing: var(--font-Heading-M-DemiBold-letter-spacing);
    color: var(--semantic-text-primary);
  }

  .service-card__desc {
    color: #626262;
  }

  .service-card__media {
    width: 708px;
    height: 472px;
    flex-shrink: 0;
  }

  /* object-fit:cover restores the pre-existing desktop behavior — the
     mobile-only object-fit:fill above (by request) would otherwise
     leak into this breakpoint too since it's the same shared selector. */
  .service-card__media img {
    object-fit: cover;
    object-position: center;
  }
}

/* ==========================================================================
   Section/Donate (Figma fileKey JmYoex09QPMmompAX7kaTT, node 91:1257
   mobile 375px frame / 91:840 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above. <Donate> is a
   non-standard tag by request; display:block makes it behave as a
   normal block-level section container.

   .donate is a cq container (container-type:inline-size) from this base
   rule up, same technique as Section/Equipment and Section/AboutUs, by
   request ("резинова верстка... брекпоїнт для планшетної версії"):
   .donate__content and .donate__card below use width:calc(100% - 20px)
   directly (not width:355px + max-width:calc(...), which only guards
   the narrow side and freezes at the literal 355px on any wider mobile
   viewport within this range), and .donate__headline-text's font-size
   is cqw (375px mobile frame as the reference) instead of the fixed
   --font-Heading-L-DemiBold-mobile-size token, so it grows
   proportionally with the section. Growth is capped at the
   @media(min-width:768px) block further down, same "proportional up to
   ~768px, then stop" convention already used on those two sections,
   before the existing >=1200px desktop rule takes over. Everything else
   (amount/caption font-sizes, the two 226px-wide inner blocks) stays
   fixed — not asked for, and .donate__amount/.donate__caption-title are
   already "identical at both breakpoints" per their own comments below,
   so there's no mobile->desktop value to interpolate between anyway. */
.donate {
  display: block;
  position: relative;
  padding: 44px 0; /* Content top44; section height761 - Content bottom(44+673=717) = 44, symmetric */
  background-color: var(--Neutral-100); /* #fcfcfc — this node's own literal bg, not --semantic-background */
  container-type: inline-size;
}

.donate__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
  width: calc(100% - 20px);
  margin: 0 auto;
}

.donate__headline {
  width: 100%;
}

/* node 91:1260/91:1843: 40px Heading/L/DemiBold/mobile. Letter-spacing
   is 0px on this node at both breakpoints (matches the shared token
   exactly, unlike other sections' headings — no override needed).
   font-size is cqw (not the fixed token) so it grows proportionally
   with the section, by request — see the class comment above. */
.donate__headline-text {
  margin: 0;
  font-family: var(--font-Heading-L-DemiBold-mobile-family);
  font-size: 10.667cqw; /* 40px / 375px */
  font-weight: var(--font-Heading-L-DemiBold-mobile-weight);
  line-height: var(--font-Heading-L-DemiBold-mobile-line-height);
  letter-spacing: var(--font-Heading-L-DemiBold-mobile-letter-spacing);
}

/* .donate__word starts gray — the "unrevealed" state added by request
   (same mechanism as Section/OurServices' heading reveal), not present
   in Figma anywhere in this section, so there's no real per-breakpoint
   gray to borrow here (unlike OurServices, which had one) — reusing
   the same Neutral-200 token for both breakpoints instead of inventing
   a new color. --word-color (read by js/main.js) is where each word's
   REAL final color (Figma-accurate, one of the two below) lives. */
.donate__word {
  color: var(--Neutral-200);
}

.donate__word--primary {
  --word-color: var(--Neutral-700); /* mobile's own dark, #1f1f1f (91:1260) */
}

.donate__word--highlight {
  --word-color: var(--semantic-primary); /* #c00f15, same both breakpoints */
}

/* Section/Donate/DonationCard (91:1261 mobile / 91:844 desktop): same
   internal text sizes at both breakpoints, only the card's own
   width/height/bg/text-color differ. width:100% (matches
   .donate__content's own fluid width, its parent, instead of the old
   width:355px+max-width:100% which froze at the literal 355px on any
   wider mobile viewport) — height stays a fixed 333px rather than
   aspect-ratio: unlike an image box, this card holds fixed-size text
   content (amount-group/caption are their own fixed 226px-wide blocks,
   unchanged below) that already relies on today's 333px - 88px padding
   fitting it at the narrow end; scaling height down via aspect-ratio at
   narrower widths would shrink that available room and risk clipping
   the same content that already fits today. */
.donate__card {
  width: 100%;
  height: 333px;
  box-sizing: border-box;
  padding: 44px 24px;
  border-radius: 32px;
  background-color: var(--Neutral-700); /* #1f1f1f — this node's own literal bg */
  display: flex;
  flex-direction: column;
  align-items: center;
}

.donate__amount-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 56px;
  width: 226px;
  color: var(--Neutral-100); /* #fcfcfc — this node's own literal text color */
}

/* node 91:1263/91:846: 42px Heading/M/DemiBold — identical at both
   breakpoints in Figma, no mobile-specific size exists for this node. */
.donate__amount {
  margin: 0;
  font-family: var(--font-Heading-M-DemiBold-family);
  font-size: var(--font-Heading-M-DemiBold-size);
  font-weight: var(--font-Heading-M-DemiBold-weight);
  line-height: var(--font-Heading-M-DemiBold-line-height);
  letter-spacing: var(--font-Heading-M-DemiBold-letter-spacing);
}

.donate__caption {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 226px;
}

/* node 91:1265/91:848: 32px Body/2XL/Regular — also identical at both
   breakpoints (not the 24px -mobile variant of this token). */
.donate__caption-title {
  margin: 0;
  font-family: var(--font-Body-2XL-Regular-family);
  font-size: var(--font-Body-2XL-Regular-size);
  font-weight: var(--font-Body-2XL-Regular-weight);
  line-height: var(--font-Body-2XL-Regular-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
}

/* node 91:1266/91:849: 16px Body/M/Regular (0.16px tracking — the
   shared token already matches this node exactly). */
.donate__caption-subtitle {
  margin: 0;
  font-family: var(--font-Body-M-Regular-family);
  font-size: var(--font-Body-M-Regular-size);
  font-weight: var(--font-Body-M-Regular-weight);
  line-height: var(--font-Body-M-Regular-line-height);
  letter-spacing: var(--font-Body-M-Regular-letter-spacing);
}

/* 768px+ (up to the 1200px desktop cutover): freezes .donate__content's
   width and .donate__headline-text's font-size at their own
   768px-equivalent size instead of letting them keep growing all the
   way to 1199px — same "proportional up to ~768px, then stop"
   reasoning as Section/Equipment's own tablet freeze. .donate__card
   (width:100% of .donate__content) is capped along with it. */
@media (min-width: 768px) {
  .donate__content {
    max-width: 748px; /* 768px - 20px */
  }

  .donate__headline-text {
    font-size: 81.92px; /* 40px / 375px * 768px */
  }
}

@media (min-width: 1200px) {
  .donate {
    padding: 32px 0; /* Content top32; section height538 - Content bottom(32+474=506) = 32, symmetric */
    background-color: var(--semantic-background); /* white — this node's own literal bg, different from mobile's #fcfcfc */
  }

  /* .donate__headline uses flex:1 rather than Figma's literal fixed
     width:714px — see the HTML comment above this section for why a
     rigid width here would overflow at exactly 1200px viewport width. */
  .donate__content {
    flex-direction: row;
    align-items: center;
    gap: 190px;
    width: 100%;
    max-width: 1200px;
  }

  .donate__headline {
    flex: 1;
    min-width: 0;
  }

  /* node 91:843: 72px Heading/L/DemiBold, letter-spacing 0px (matches
     the shared token exactly). */
  .donate__headline-text {
    font-family: var(--font-Heading-L-DemiBold-family);
    font-size: var(--font-Heading-L-DemiBold-size);
    font-weight: var(--font-Heading-L-DemiBold-weight);
    line-height: var(--font-Heading-L-DemiBold-line-height);
    letter-spacing: var(--font-Heading-L-DemiBold-letter-spacing);
  }

  .donate__word--primary {
    --word-color: var(--semantic-text-primary); /* desktop's own dark, #151516 (91:843) */
  }

  .donate__card {
    width: 296px;
    height: 436px;
    flex-shrink: 0;
    background-color: var(--semantic-foreground); /* #151516 — this node's own literal bg */
  }

  .donate__amount-group {
    color: var(--semantic-text-inverse); /* white — this node's own literal text color */
  }
}

/* ==========================================================================
   Section/Reviews (Figma fileKey JmYoex09QPMmompAX7kaTT, node 91:1267
   mobile 375px frame / 91:946 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above. <review> is a
   non-standard tag by request; display:block makes it behave as a
   normal block-level section container.

   Figma's own DOM order differs per breakpoint (mobile: rating, photo,
   cards; desktop: photo, rating, cards) — the HTML below follows
   mobile's order and the desktop override just reorders visually via
   flex `order`, rather than duplicating markup.

   .reviews__content below uses width:calc(100% - 20px) directly (not
   width:355px + max-width:calc(...), which only guards the narrow side
   and freezes at the literal 355px on any wider mobile viewport within
   this range) for a genuinely fluid mobile layout, by request
   ("резинова верстка для мобільної версії"). Growth is capped at the
   new @media(min-width:768px) block further down (same "proportional
   up to ~768px, then stop" convention already used on the other
   sections) before the existing >=1200px desktop rule takes over. None
   of this section's own text (google-text/score-number/description/
   card-text/card-name) uses a -mobile font token — every one of them is
   already identical at both breakpoints per Figma (see each rule's own
   comment below), so there's no separate heading-style scale to add
   here the way AboutUs/Equipment/Donate each had. */
.reviews {
  display: block;
  position: relative;
  padding: 44px 0; /* Content top44; section height1430 - Content bottom(44+1356=1400) = 30, not quite symmetric — Figma's own numbers, not rounded to match */
  background-color: var(--Neutral-100); /* #fcfcfc — this node's own literal bg */
}

.reviews__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
  width: calc(100% - 20px);
  margin: 0 auto;
}

.reviews__rating {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
  width: 100%;
}

/* Section/Reviews/RatingSummary/GoogleBadge (99:432/91:950): icon(40x40)
   + text, text offset ml55/mt6 in Figma's own grid-overlay markup —
   reproduced as a simple flex row (gap15 = ml55 - icon width40) with
   the text's own 6px top margin for the same optical offset. */
.reviews__google-badge {
  display: flex;
  align-items: flex-start;
  gap: 15px;
}

.reviews__google-icon {
  display: block;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}

/* node 91:956/99:438: 24px Body/XL/DemiBold, tracking 0.24px (matches
   the shared token exactly). */
.reviews__google-text {
  margin: 6px 0 0;
  font-family: var(--font-Body-XL-DemiBold-family);
  font-size: var(--font-Body-XL-DemiBold-size);
  font-weight: var(--font-Body-XL-DemiBold-weight);
  line-height: var(--font-Body-XL-DemiBold-line-height);
  letter-spacing: var(--font-Body-XL-DemiBold-letter-spacing);
  color: var(--Neutral-700);
}

.reviews__score-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.reviews__score {
  display: flex;
  align-items: center;
  gap: 11px;
}

/* node 91:959/99:441: 32px Body/2XL/Regular — the literal (non-mobile)
   token; this node uses 32px at both breakpoints, not the -mobile 24px
   variant. */
.reviews__score-number {
  margin: 0;
  font-family: var(--font-Body-2XL-Regular-family);
  font-size: var(--font-Body-2XL-Regular-size);
  font-weight: var(--font-Body-2XL-Regular-weight);
  line-height: var(--font-Body-2XL-Regular-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
  color: var(--Neutral-700);
  white-space: nowrap;
}

.reviews__stars {
  display: block;
  width: 123px;
  height: 23px;
  flex-shrink: 0;
}

/* node 91:966/99:448: 18px Body/L/Regular. */
.reviews__description {
  margin: 0;
  width: 100%;
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
  color: var(--Neutral-700);
}

/* aspect-ratio (355:592, Figma's own mobile ratio) + max-height:700px —
   this section's two requests ended up in tension: "height takes up too
   much space, shrink it" (fixed at a flat 592px) vs. later "must change
   proportionally when stretching" (aspect-ratio, height growing with
   width again). Both together: it scales proportionally with width up
   to 700px tall (~420px viewport width), then holds at that 700px cap
   for anything wider — capped by request, so it doesn't balloon back up
   to the ~1247px it reached at 900px width before the fixed-height
   fix. 700px is a judgment call, not a Figma value (Figma has no
   tablet-width frame to derive one from). object-fit:fill (not cover,
   by request) stretches the image to completely fill the box — cover
   would just crop instead — including the widening gap between the
   image's own ratio and the box's once height is capped but width keeps
   growing. */
.reviews__photo {
  width: 100%;
  aspect-ratio: 355 / 592;
  max-height: 700px;
  border-radius: 32px;
  overflow: hidden;
}

.reviews__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* Section/Reviews/Divider (91:995) is desktop-only — hidden here,
   positioned/shown in the @media block below. */
.reviews__divider {
  display: none;
}

.reviews__cards {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
}

/* Section/Reviews/ReviewCard/* (99:403,412,421 / 91:968,977,986): glass
   card, backdrop-blur 60px over the photo/background behind it. */
.reviews__card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  width: 100%;
  padding: 16px 24px;
  border-radius: 32px;
  box-sizing: border-box;
  backdrop-filter: blur(60px);
  -webkit-backdrop-filter: blur(60px);
}

/* node 91:975/99:410 etc.: 18px Body/L/Regular. */
.reviews__card-text {
  margin: 0;
  width: 100%;
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
  color: var(--Neutral-700);
}

/* node 91:976/99:411 etc.: 18px Body/L/Bold. */
.reviews__card-name {
  margin: 0;
  font-family: var(--font-Body-L-Bold-family);
  font-size: var(--font-Body-L-Bold-size);
  font-weight: var(--font-Body-L-Bold-weight);
  line-height: var(--font-Body-L-Bold-line-height);
  letter-spacing: var(--font-Body-L-Bold-letter-spacing);
  color: var(--Neutral-700);
  white-space: nowrap;
}

/* 768px+ (up to the 1200px desktop cutover): freezes .reviews__content's
   width at its own 768px-equivalent size instead of letting it keep
   growing all the way to 1199px — same "proportional up to ~768px, then
   stop" reasoning as Section/Equipment's own tablet freeze.
   .reviews__photo (width:100% of .reviews__content, capped at its own
   max-height:700px) is capped along with it. */
@media (min-width: 768px) {
  .reviews__content {
    max-width: 748px; /* 768px - 20px */
  }
}

@media (min-width: 1200px) {
  .reviews {
    padding: 32px 0 64px; /* Content top32; section height688 - Content bottom(32+592=624) = 64 — Figma's own numbers (previously implemented as a symmetric 32px 0, missing this asymmetry) */
    background-color: var(--semantic-background); /* white — this node's own literal bg, different from mobile's #fcfcfc */
  }

  .reviews__content {
    position: relative;
    flex-direction: row;
    align-items: flex-end;
    gap: 105px;
    width: 100%;
    max-width: 1194px;
  }

  .reviews__photo {
    order: 1;
    width: 410px;
    height: 592px;
    flex-shrink: 0;
  }

  /* object-fit:cover restores desktop's original behavior — the
     mobile/tablet-only object-fit:fill above (by request, scoped to
     "в резиновій верстці") would otherwise leak into this breakpoint
     too since it's the same shared img selector. */
  .reviews__photo img {
    object-fit: cover;
  }

  .reviews__rating {
    order: 2;
    width: 254px;
    flex-shrink: 0;
  }

  .reviews__google-text,
  .reviews__score-number,
  .reviews__description,
  .reviews__card-text,
  .reviews__card-name {
    color: var(--semantic-text-primary); /* #151516 — this node's own literal color, replacing mobile's #1f1f1f */
  }

  /* node 91:995: a 1px horizontal line stretched to 592px and rotated
     ~90deg in Figma's own export — reproduced directly as a vertical
     line instead, same visual result. Positioned absolutely (not as a
     4th flex item) so it doesn't disturb the row's own 105px gaps:
     x826.638 relative to PhotoGroup's own left edge (410 + 105 + 254 +
     57.638 into the next gap), y1 (33 - the group's own top32),
     height592, color var(--semantic-border) matching the source SVG's
     own #c9c9c9 stroke. */
  .reviews__divider {
    display: block;
    position: absolute;
    left: 826.638px;
    top: 1px;
    width: 1px;
    height: 592px;
    background-color: var(--semantic-border);
  }

  .reviews__cards {
    order: 3;
    width: 320px;
    flex-shrink: 0;
  }
}

/* ==========================================================================
   Section/Projects (Figma fileKey JmYoex09QPMmompAX7kaTT, node 147:321
   mobile 375px frame / 91:850 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above.

   Category rows reuse the .category component (icon-group, photo,
   desc, arrow) verbatim from earlier in this file — the rules below
   only adapt it to be mobile-responsive (the shared .category is a
   fixed 1200px-wide desktop row) and add the click-to-expand
   Default/Active states, all scoped under .projects so the shared
   component itself stays untouched.
   ========================================================================== */
.projects {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 74px;
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 40px 10px;
  box-sizing: border-box;
  border-radius: 32px;
  overflow: hidden;
  background-color: var(--Neutral-700); /* #1f1f1f — matches Figma's var(--semantic/muted-foreground, #1f1f1f) fallback exactly */
}

.projects__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  width: 100%;
  text-align: center;
  color: var(--semantic-text-inverse);
}

/* node 147:323: 64px Heading/XL/DemiBold/mobile, letter-spacing 0.64px —
   the node's own literal value; the shared mobile token itself says 1px
   (same known token/node mismatch as Section/WhatSetsUsApart's heading). */
.projects__heading {
  margin: 0;
  text-transform: lowercase;
  font-family: var(--font-Heading-XL-DemiBold-mobile-family);
  font-size: var(--font-Heading-XL-DemiBold-mobile-size);
  font-weight: var(--font-Heading-XL-DemiBold-mobile-weight);
  line-height: var(--font-Heading-XL-DemiBold-mobile-line-height);
  letter-spacing: 0.64px;
}

.projects__desc {
  margin: 0;
  width: 100%;
  font-family: var(--font-Body-2XL-Regular-mobile-family);
  font-size: var(--font-Body-2XL-Regular-mobile-size);
  font-weight: var(--font-Body-2XL-Regular-mobile-weight);
  line-height: var(--font-Body-2XL-Regular-mobile-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-mobile-letter-spacing);
}

.projects__desc p {
  margin: 0;
}

.projects__list {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 32px;
  width: 100%;
}

.projects__divider {
  width: 100%;
  height: 0;
  border-top: 1px solid #696969; /* Neutral/500 — no CSS variable defined for this token in variables.css */
}

.projects .category {
  width: 100%;
  flex-wrap: wrap;
  row-gap: 16px;
}

.projects .category__icon-group {
  order: 1;
  width: auto;
  flex: 1 1 auto;
  min-width: 0;
  /* node 148:489 (mobile): icon-group is 280px wide (icon18 + title182 +
     the remaining 80px as the space-between gap) — with the group made
     fluid above, justify-content:space-between collapses that gap to 0
     whenever the group is narrower than 280px, so it's reproduced here
     as an explicit gap matching Figma's own 80px exactly. */
  justify-content: flex-start;
  gap: 80px;
}

.projects .category__title {
  width: auto;
  flex: 1 1 auto;
  min-width: 0;
}

.projects .category__arrow-btn {
  order: 2;
  display: block;
  flex-shrink: 0;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

/* Arrow hover effect — same default/hover icon-crossfade technique
   already used by .button__icon-default/.button__icon-hover: the
   "hover" image is Icon/Color=Light/State=Active (the same asset
   used for the persisted expanded state), crossfaded in via opacity. */
.projects .category__arrow {
  position: relative;
}

.projects .category__arrow-default,
.projects .category__arrow-hover {
  position: absolute;
  inset: 0;
  display: block;
  width: 33px;
  height: 33px;
}

.projects .category__arrow-hover {
  opacity: 0;
}

.projects .category__arrow-btn:hover .category__arrow-default,
.projects .category.is-active .category__arrow-default {
  opacity: 0;
}

.projects .category__arrow-btn:hover .category__arrow-hover,
.projects .category.is-active .category__arrow-hover {
  opacity: 1;
}

/* Photo/desc are hidden until a category is toggled to Active by
   main.js; all 4 categories start collapsed (Default) on load. */
.projects .category__desc {
  order: 3;
  display: none;
  width: 100%;
}

.projects .category__photo {
  order: 4;
  display: none;
  width: 100%;
  height: 227px;
}

.projects .category.is-active .category__desc,
.projects .category.is-active .category__photo {
  display: block;
}

@media (min-width: 1200px) {
  .projects {
    padding: 40px 120px;
  }

  .projects__header {
    width: 886px;
  }

  /* node 91:852: 168px Heading/XL/DemiBold, letter-spacing 1.68px —
     the node's own literal value; the shared token itself says 1px
     (same known mismatch as the mobile heading above). */
  .projects__heading {
    font-family: var(--font-Heading-XL-DemiBold-family);
    font-size: var(--font-Heading-XL-DemiBold-size);
    font-weight: var(--font-Heading-XL-DemiBold-weight);
    line-height: var(--font-Heading-XL-DemiBold-line-height);
    letter-spacing: 1.68px;
  }

  .projects__desc {
    font-family: var(--font-Body-2XL-Regular-family);
    font-size: var(--font-Body-2XL-Regular-size);
    font-weight: var(--font-Body-2XL-Regular-weight);
    line-height: var(--font-Body-2XL-Regular-line-height);
    letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
  }

  .projects .category {
    flex-wrap: nowrap;
    row-gap: 0;
  }

  .projects .category__icon-group {
    flex: none;
    width: 280px;
  }

  .projects .category__title {
    flex: none;
    width: 182px;
  }

  .projects .category__arrow-btn {
    order: 4;
  }

  .projects .category__photo {
    order: 2;
    width: 342px;
    height: 227px;
    flex-shrink: 0;
  }

  .projects .category__desc {
    order: 3;
    width: 244px;
  }
}

/* ==========================================================================
   Section/Contact (Figma fileKey JmYoex09QPMmompAX7kaTT, node 91:1360
   mobile 375px frame / 91:894 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above.

   The video/photo (342x199) and the "book now" button (187x42, reusing
   .button/.button--primary verbatim) are identical at both breakpoints
   in Figma — no responsive sizing needed for either.

   .contact is a cq container (container-type:inline-size) from this
   base rule up, same technique as the other sections, by request
   ("резинова верстка... заголовок збільшувався пропорційно як в
   попередніх екранах"): .contact__content below uses
   width:calc(100% - 20px) directly (not width:355px +
   max-width:calc(...), which only guards the narrow side and freezes at
   the literal 355px on any wider mobile viewport within this range),
   and .contact__heading's font-size/letter-spacing are cqw (375px
   mobile frame as the reference) instead of the fixed
   --font-Heading-XL-DemiBold-mobile-* tokens, so it grows proportionally
   with the section. Growth is capped at the new
   @media(min-width:768px) block further down (same "proportional up to
   ~768px, then stop" convention already used on the other sections)
   before the existing >=1200px desktop rule takes over.
   .contact__video-wrap and .contact__desc stay as they are — not asked
   for, and the video is explicitly "identical at both breakpoints" per
   the comment above. */
.contact {
  display: block;
  position: relative;
  padding: 44px 0; /* Content top44; section height608 - Content bottom(44+520=564) = 44, symmetric */
  background-color: var(--semantic-background);
  container-type: inline-size;
}

.contact__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  width: calc(100% - 20px);
  margin: 0 auto;
  text-align: center;
}

/* node 91:1363: 64px Heading/XL/DemiBold/mobile, letter-spacing 0.64px —
   the node's own literal value; the shared mobile token itself says 1px
   (same known token/node mismatch as this heading elsewhere in this file).
   font-size/letter-spacing are cqw (not the fixed token/0.64px) so they
   grow proportionally with the section, by request — see the class
   comment above. */
.contact__heading {
  margin: 0;
  width: 100%;
  text-transform: lowercase;
  white-space: nowrap; /* node 91:1363/91:897: text box is deliberately wider than its container and overflows centered — matches Figma exactly, not a bug */
  color: #1f1f1f; /* Neutral/700 — this node's own literal color, mobile only */
  font-family: var(--font-Heading-XL-DemiBold-mobile-family);
  font-size: 17.067cqw; /* 64px / 375px */
  font-weight: var(--font-Heading-XL-DemiBold-mobile-weight);
  line-height: var(--font-Heading-XL-DemiBold-mobile-line-height);
  letter-spacing: 0.1707cqw; /* 0.64px / 375px */
}

.contact__desc {
  margin: 0;
  width: 100%;
  color: #1f1f1f; /* Neutral/700 — this node's own literal color, mobile only */
  font-family: var(--font-Body-2XL-Regular-mobile-family);
  font-size: var(--font-Body-2XL-Regular-mobile-size);
  font-weight: var(--font-Body-2XL-Regular-mobile-weight);
  line-height: var(--font-Body-2XL-Regular-mobile-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-mobile-letter-spacing);
}

.contact__video-wrap {
  position: relative;
  width: 342px;
  max-width: 100%;
  height: 199px;
  border-radius: 32px;
  overflow: hidden;
  flex-shrink: 0;
  background-color: var(--Neutral-700); /* fallback while the video's first frame loads */
}

.contact__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.contact__button {
  flex-shrink: 0;
}

@media (min-width: 768px) {
  .contact__content {
    max-width: 748px;
  }

  .contact__heading {
    font-size: 131.072px; /* 64px / 375px * 768px, frozen */
    letter-spacing: 1.311px; /* 0.64px / 375px * 768px, frozen */
  }
}

@media (min-width: 1200px) {
  .contact {
    padding: 32px 0 64px; /* Content top32; section height694 - Content bottom(32+598=630) = 64 — Figma's own numbers, not symmetric */
  }

  .contact__content {
    width: 852px;
    max-width: 100%;
  }

  /* node 91:897: 168px Heading/XL/DemiBold, letter-spacing 1.68px — the
     node's own literal value; the shared token itself says 1px (same
     known mismatch as the mobile heading above). */
  .contact__heading {
    color: var(--semantic-text-primary); /* #151516 — this node's own literal color, replacing mobile's #1f1f1f */
    font-family: var(--font-Heading-XL-DemiBold-family);
    font-size: var(--font-Heading-XL-DemiBold-size);
    font-weight: var(--font-Heading-XL-DemiBold-weight);
    line-height: var(--font-Heading-XL-DemiBold-line-height);
    letter-spacing: 1.68px;
  }

  .contact__desc {
    width: 739px;
    color: var(--semantic-text-primary); /* #151516 — this node's own literal color, replacing mobile's #1f1f1f */
    font-family: var(--font-Body-2XL-Regular-family);
    font-size: var(--font-Body-2XL-Regular-size);
    font-weight: var(--font-Body-2XL-Regular-weight);
    line-height: var(--font-Body-2XL-Regular-line-height);
    letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
  }
}

/* ==========================================================================
   Section/Footer (Figma fileKey JmYoex09QPMmompAX7kaTT, node 91:1367
   mobile 375px frame / 91:901 desktop 1440px frame). Mobile-first base
   below; desktop override in the @media(min-width:1200px) block further
   down — same breakpoint as the sections above.

   .footer__left (logo+desc) and .footer__right (contact-group+terms-row)
   are a flexbox regrouping of Figma's own flat, independently-positioned
   siblings — every margin below is computed from the real fetched x/y/
   width/height of each node, not invented.
   ========================================================================== */
.footer {
  display: block;
  position: relative;
  padding-top: 44px; /* logo's own top offset (91:1407 y44) */
  overflow: hidden;
  background-color: var(--semantic-primary);
}

.footer__top {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.footer__left {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.footer__logo {
  display: block;
  width: 79px;
  height: 37px;
}

/* node 91:1368: 24px Body/2XL/Regular/mobile. Gap above: logo bottom81 to
   desc top105 = 24px (91:1407/91:1368). */
.footer__desc {
  margin: 24px 0 0;
  width: 355px;
  max-width: calc(100% - 20px);
  text-align: center;
  color: var(--Neutral-100); /* #fcfcfc — this node's own literal color, mobile only */
  font-family: var(--font-Body-2XL-Regular-mobile-family);
  font-size: var(--font-Body-2XL-Regular-mobile-size);
  font-weight: var(--font-Body-2XL-Regular-mobile-weight);
  line-height: var(--font-Body-2XL-Regular-mobile-line-height);
  letter-spacing: var(--font-Body-2XL-Regular-mobile-letter-spacing);
}

/* Gap above: desc bottom209 to contact-group top253 = 44px (91:1368/91:1369). */
.footer__right {
  margin-top: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.footer__contact-group {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* node 91:1370: 18px Body/L/Bold. */
.footer__email {
  margin: 0;
  color: var(--Neutral-100); /* #fcfcfc — this node's own literal color */
  font-family: var(--font-Body-L-Bold-family);
  font-size: var(--font-Body-L-Bold-size);
  font-weight: var(--font-Body-L-Bold-weight);
  line-height: var(--font-Body-L-Bold-line-height);
  letter-spacing: var(--font-Body-L-Bold-letter-spacing);
}

/* Gap above: email bottom18 to phone top34 = 16px (91:1370/91:1371). */
.footer__phone {
  margin-top: 16px;
  display: flex;
  align-items: center;
  gap: 9px;
}

.footer__phone-icon {
  display: block;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* node 91:1374: 18px Body/L/Bold. */
.footer__phone-number {
  color: var(--Neutral-100); /* #fcfcfc — this node's own literal color */
  font-family: var(--font-Body-L-Bold-family);
  font-size: var(--font-Body-L-Bold-size);
  font-weight: var(--font-Body-L-Bold-weight);
  line-height: var(--font-Body-L-Bold-line-height);
  letter-spacing: var(--font-Body-L-Bold-letter-spacing);
  white-space: nowrap;
}

/* node 91:1375/91:1376: 16px Link/L/DemiBold, lowercase, tracking 0.16px
   (matches the shared token exactly). Figma's own literal width (164px)
   is a few px narrower than its own content (pl24 + text90 + gap16 +
   icon33 + pr10 = 173px) and wraps the label — width:auto (hug content)
   here instead, height/padding/gap all still exactly as fetched. Gap
   above: phone bottom54 to button top70 = 16px (91:1371/91:1375). */
.footer__button {
  margin-top: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  height: 42px;
  padding: 10px 10px 10px 24px;
  box-sizing: border-box;
  border: none;
  border-radius: 999px;
  background-color: var(--Neutral-100); /* #fcfcfc — this node's own literal bg */
  color: var(--Neutral-700); /* #1f1f1f — this node's own literal color */
  text-transform: lowercase;
  white-space: nowrap;
  cursor: pointer;
  font-family: var(--font-Link-L-DemiBold-family);
  font-size: var(--font-Link-L-DemiBold-size);
  font-weight: var(--font-Link-L-DemiBold-weight);
  line-height: var(--font-Link-L-DemiBold-line-height);
  letter-spacing: var(--font-Link-L-DemiBold-letter-spacing);
}

.footer__button-icon {
  display: block;
  width: 33px;
  height: 33px;
  flex-shrink: 0;
}

/* node 91:1409: Terms/Privacy Policy row, justify-content:space-between
   across the full 355px width (Terms x0 width51, Privacy Policy x239
   width116 — 239+116=355, exactly the row's own width). Gap above:
   contact-group bottom365 to terms-row top409 = 44px (91:1369/91:1409). */
.footer__terms-row {
  margin-top: 44px;
  display: flex;
  justify-content: space-between;
  width: 355px;
  max-width: calc(100% - 20px);
}

/* node 91:1410/91:1411: 18px Body/L/Regular. */
.footer__terms-link {
  margin: 0;
  color: var(--Neutral-100); /* #fcfcfc — this node's own literal color, mobile only */
  text-decoration: none;
  white-space: nowrap;
  font-family: var(--font-Body-L-Regular-family);
  font-size: var(--font-Body-L-Regular-size);
  font-weight: var(--font-Body-L-Regular-weight);
  line-height: var(--font-Body-L-Regular-line-height);
  letter-spacing: var(--font-Body-L-Regular-letter-spacing);
}

/* node 91:1412: 376px wide (essentially edge-to-edge on the 375px mobile
   frame) — width:100% here, no max-width cap. Gap above: terms-row
   bottom427 to wordmark top498 = 71px (91:1409/91:1412). */
.footer__wordmark {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 71px;
}

@media (min-width: 1200px) {
  .footer {
    padding: 45px 120px 0; /* logo's own top offset (91:941 y45); left/right gutter matches logo/desc left120 and button/terms right edge 1440-120=1320 */
  }

  .footer__top {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    width: 100%;
  }

  .footer__left {
    align-items: flex-start;
  }

  /* node 91:902: 32px Body/2XL/Regular, left-aligned (not centered like
     mobile). Gap above: logo bottom82 to desc top100 = 18px
     (91:941/91:902). */
  .footer__desc {
    margin-top: 18px;
    width: 464px;
    max-width: none;
    text-align: left;
    color: var(--semantic-text-inverse); /* #ffffff — this node's own literal color, replacing mobile's #fcfcfc */
    font-family: var(--font-Body-2XL-Regular-family);
    font-size: var(--font-Body-2XL-Regular-size);
    font-weight: var(--font-Body-2XL-Regular-weight);
    line-height: var(--font-Body-2XL-Regular-line-height);
    letter-spacing: var(--font-Body-2XL-Regular-letter-spacing);
  }

  /* Right column starts 55px lower than the row's own top (desc top100 -
     logo top45 = 55) — email (91:908) sits level with desc, not logo. */
  .footer__right {
    margin-top: 55px;
    align-items: flex-end;
  }

  .footer__contact-group {
    align-items: flex-end;
  }

  /* Gap above: email bottom118 to phone top130 = 12px (91:908/91:904). */
  .footer__phone {
    margin-top: 12px;
  }

  .footer__phone-number,
  .footer__email,
  .footer__terms-link {
    color: var(--semantic-text-inverse); /* #ffffff — this node's own literal color, replacing mobile's #fcfcfc */
  }

  /* Gap above: phone bottom150 to button top164 = 14px (91:904/91:909). */
  .footer__button {
    margin-top: 14px;
  }

  /* node 91:943/91:944: desktop shows Privacy Policy (x1087) to the LEFT
     of Terms (x1263) — the reverse of mobile's reading order. DOM order
     stays Terms-then-Privacy (matching mobile); order:-1 below just
     flips the visual order for this breakpoint, gap60 = 1263 - (1087+116).
     Gap above: contact-group bottom206 to terms-row top218 = 12px
     (91:909/91:943). */
  .footer__terms-row {
    margin-top: 12px;
    justify-content: flex-start;
    gap: 60px;
    width: auto;
    max-width: none;
  }

  .footer__terms-link--privacy {
    order: -1;
  }

  /* node 91:945: 1195.875px wide, fitting the padded content area
     (1440 - 2*120 = 1200) almost exactly. Gap above: left column's own
     bottom (desc bottom240) to wordmark top290 = 50px (91:902/91:945). */
  .footer__wordmark {
    margin-top: 50px;
  }
}
