/* ==========================================================================
   Denty — Hero
   One full-bleed composition, layered:
     1. hero-background.png — abstract blue atmosphere, covers the section
     2. ::before — a very soft tonal vignette for depth (no new visual
        "elements", just atmosphere behind the photo)
     3. hero-photo.png — a pre-cut transparent PNG (dentists + tooth); it
        blends into the background on its own, no mask/gradient hacks
     4. title, top-left — the only other object in the composition
     5. Header, floating on top (transparent — see header.css)
   The photo is absolutely positioned against the Hero itself (not sharing
   a grid track with the text), sized to dominate the right side and bleed
   slightly past the Hero's own edges for a cinematic, not-boxed-in feel.
   No cards, no badges, no extra copy — typography and the one photo are
   the entire visual vocabulary.
   ========================================================================== */

.hero {
  position: relative;
  min-height: 100svh;
  background-color: var(--color-primary);
  overflow: hidden;
  /* Deliberately NO stacking context here (no isolation / z-index /
     transform): the fixed Header lives inside this element, and any
     stacking context on the Hero would trap the Header's z-index inside
     it — then every positioned section further down the page would
     paint over the Header. Keep it out of that. */
  display: flex;
  flex-direction: column;
}

/* The textured background lives on its own element (not on .hero) so it
   can settle from a slight zoom (opening-sequence step 1) without scaling
   the header/title/photo along with it. heroBgDrift below is its slow
   idle drift — starts once the settle has finished. */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("../assets/hero-background.png");
  background-size: cover;
  /* Animated (heroBgDrift) — starts and settles on center, so this is
     also the correct static/reduced-motion position. */
  background-position: 50% 50%;
  background-repeat: no-repeat;
  transform-origin: 50% 55%;
  animation: heroBgSettle 700ms cubic-bezier(0.22, 1, 0.36, 1) both,
    heroBgDrift 20s ease-in-out 700ms infinite;
}

/* Soft tonal vignette: a touch of light top-left (echoes the header/title
   corner) and a deeper pool of blue bottom-right (grounds the photo) —
   entirely atmospheric, tuned to stay under the "cheap glow" threshold.
   Lives on .hero-bg (not .hero) so the Hero needs no stacking context. */
.hero-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 60% 50% at 18% 10%, rgba(255, 255, 255, 0.08), transparent 60%),
    radial-gradient(ellipse 75% 65% at 88% 100%, rgba(3, 18, 58, 0.32), transparent 65%);
}

@keyframes heroBgSettle {
  from {
    transform: scale(1.06);
  }
  to {
    transform: scale(1);
  }
}

/* Very slow, barely-perceptible drift — the same single background image
   just eases its position a couple of percent and back; this is also what
   stands in for "waking up" the light-curve baked into that image, since
   it isn't a separate layer. */
@keyframes heroBgDrift {
  0%,
  100% {
    background-position: 50% 50%;
  }
  50% {
    background-position: 52% 48%;
  }
}

.hero-inner {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  align-items: flex-start;
  max-width: var(--container-width);
  width: 100%;
  margin-inline: auto;
  /* Same token as .header-inner's left padding (variables.css) — this is
     what keeps the logo and "СТОМАТОЛОГИЯ" on one shared vertical axis. */
  padding-left: var(--content-inset-left);
  padding-right: var(--container-padding);
  /* Header gets its own ~105-145px zone of quiet air before the headline
     starts — enough to read as deliberate whitespace, not so much that
     the title drifts down into the Hero's geometric center. (Pulled in
     15px from 120-160 — the connection between Header and headline was
     reading as slightly too loose.) */
  padding-top: calc(var(--header-height) + clamp(105px, 10vh, 145px));
}

/* -------------------------------------------------------------- Text -- */

.hero-text {
  /* vw, not % — % would resolve against .hero-inner's capped max-width
     (1440px), so past that width the column would stop growing while the
     vw-driven title font keeps scaling, breaking "НОВОГО ПОКОЛЕНИЯ" onto
     two lines at wide viewports. vw tracks the true viewport instead.
     Measured in-browser: uppercase/700 "НОВОГО ПОКОЛЕНИЯ" needs ~10.05x
     its own font-size of width — 51vw against the 4.4vw title font
     (10.05 x 4.4 = 44.2vw needed) keeps a steady ~13-15% safety margin at
     every width. Landing at ~735px / ~51% of viewport around 1440px —
     pulled in from the previous 53% pass to sit closer to the 40-45%
     "share of the composition" target without reopening the wrap risk
     that a straight 40-45vw column would hit at this font size. */
  width: clamp(590px, 51vw, 900px);
  /* Small optical nudge downward, independent of the horizontal position
     (which stays anchored to --content-inset-left / the logo). Plain
     margin, not transform — transform is reserved for the entrance motion
     on the children below (staggered separately), not a standing hack. */
  margin-top: 10px;
}

.hero-title {
  font-family: var(--font-hero);
  text-transform: uppercase;
  color: var(--color-white);
}

.hero-title-line1,
.hero-title-line2 {
  display: block;
  font-weight: 700;
  /* ~4% down from clamp(50,4.4vw,78) — still a big, confident headline,
     just not quite so heavy against the Header above it. Shrinking (not
     growing) only ever *adds* wrap safety margin, so this doesn't reopen
     the "НОВОГО ПОКОЛЕНИЯ"-style wrap risk tracked elsewhere in this file. */
  font-size: clamp(48px, 4.2vw, 75px);
  line-height: 0.92;
  letter-spacing: -0.045em;
  animation: heroLineIn 550ms cubic-bezier(0.22, 1, 0.36, 1) 60ms both;
}

.hero-title-line2 {
  /* The highlighted line trails the first by a beat. */
  animation-delay: 140ms;
}

/* "Стоматология", "нового поколения" and "в Ташкенте" are three separate
   block-level siblings inside .hero-text — with no centering/flex wrapper
   pulling any of them off it, they all start flush at .hero-text's own
   left edge by default. That's the one shared editorial axis, and it's
   the same axis .hero-inner's left padding already lines up with the
   Header logo (see variables.css --content-inset-left). */
.hero-title-sub {
  display: flex;
  align-items: baseline;
  column-gap: 0.32em;
  /* Tighter than before — reads as a continuation of the headline, not a
     separate subtitle line. */
  margin-top: clamp(28px, 2.8vw, 42px);
  /* Same entrance as the headline, just a touch later — a soft stagger,
     not a dramatic delay. */
  animation: heroLineIn 550ms cubic-bezier(0.22, 1, 0.36, 1) 220ms both;
}

.hero-title-sub-prefix,
.hero-title-sub-city {
  color: var(--color-white);
  font-size: clamp(30px, 3.2vw, 46px);
}

/* "В" stays light — a lead-in, not competing for attention. */
.hero-title-sub-prefix {
  font-weight: 500;
  letter-spacing: 0.1em;
}

/* "ТАШКЕНТЕ" carries the identity accent — done entirely through weight
   and tighter tracking (denser type), no colour/pill/underline. */
.hero-title-sub-city {
  font-weight: 700;
  letter-spacing: -0.005em;
}

/* --------------------------------------------------------------- Media -- */

.hero-media {
  position: absolute;
  z-index: 1;
  /* Bleed past the Hero's own right/bottom edges (.hero clips it cleanly
     via overflow:hidden) — reads as the photo naturally emerging from the
     frame, and the bottom bleed in particular adds a bit of cinematic
     depth, rather than the visual sitting inside a boxed-in slot.
     right pulled in from -5% to -7% — combined with the ~10% smaller
     width below, that anchors the whole visual further right and opens
     up more negative space between it and the headline. */
  right: -7%;
  bottom: -8%;
  /* Another ~4% down on top of the earlier 10% cut (630/61vw/1260 ->
     605/58.5vw/1210) — a light final touch for a bit more breathing room
     between the headline and the tooth. Still width-driven (not
     transform:scale), so the aspect-ratio box scales it with zero
     distortion. */
  width: clamp(605px, 58.5vw, 1210px);
  /* Matches hero-photo.png's real 1536x1024 pixel size exactly, so
     object-fit:contain has zero internal letterboxing — the box IS the
     picture, not an oversized invisible frame around it. */
  aspect-ratio: 1536 / 1024;
  pointer-events: none;
  will-change: transform;
}

.hero-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: right bottom;
  /* No mask needed — hero-photo.png is a pre-cut transparent PNG, so it
     already blends into hero-background.png on its own. */
  transform-origin: 70% 100%;
  animation: heroVisualIn 700ms cubic-bezier(0.22, 1, 0.36, 1) 40ms both;
}

/* Once js/hero.js confirms the intro is fully finished, it adds .is-idle
   to #hero and the photo switches from "entrance" to "always-alive" — a
   barely-there float. Gating it behind this class (rather than just
   listing a second animation from load) is what keeps it from fighting
   heroVisualIn over the same `transform` property: only one of the two
   animations is ever actually assigned to the element at a time. */
.hero.is-idle .hero-image {
  animation: heroFloat 10s ease-in-out infinite;
}

/* ------------------------------------------------------------ Glow -- */

/* One wrapper, three small soft lights over the existing tool-contact
   points already visible in the photo (top-center, right, lower-left).
   Screen blend + heavy blur + low opacity: this reads as ambient light
   breathing, not as drawn circles or UI. */
.hero-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
}

.hero-glow-spot {
  position: absolute;
  width: 14%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(210, 232, 255, 0.9) 0%, rgba(160, 200, 255, 0.35) 45%, transparent 72%);
  filter: blur(26px);
  opacity: 0;
  transform: translate(-50%, -50%);
}

.hero.is-idle .hero-glow-spot {
  animation: heroGlowBreathe 4s ease-in-out infinite;
}

/* Coordinates match the tool tips already lit in hero-photo.png: back
   dentist (top-center), right dentist, and the lower-left polisher. */
.hero-glow-spot--1 {
  top: 29%;
  left: 64%;
  animation-delay: 0s;
}

.hero-glow-spot--2 {
  top: 27%;
  left: 79%;
  animation-delay: 1.3s;
}

.hero-glow-spot--3 {
  top: 50%;
  left: 46%;
  animation-delay: 2.6s;
}

/* ------------------------------------------------------------- Motion -- */

/* Intro (each runs once, fill-mode:both) */

/* Line "mask" reveal: the clip window opens top-to-bottom while the line
   rises into it — text is uncovered, not faded. The generous negative
   insets keep glyph overshoot (tight tracking, 0.92 line-height) from
   being shaved by the mask. */
@keyframes heroLineIn {
  from {
    clip-path: inset(-10% -3% 100% -3%);
    transform: translateY(0.4em);
  }
  to {
    clip-path: inset(-10% -3% -14% -3%);
    transform: translateY(0);
  }
}

/* Visible from the first frame — only a hair of scale settles, never an
   opacity fade or a translate; the photo is "already there", not
   arriving. */
@keyframes heroVisualIn {
  from {
    transform: scale(1.02);
  }
  to {
    transform: scale(1);
  }
}

/* Idle / ambient (only active once .hero.is-idle is set by js/hero.js) */

@keyframes heroFloat {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-6px);
  }
}

@keyframes heroGlowBreathe {
  0%,
  100% {
    opacity: 0.14;
  }
  50% {
    opacity: 0.26;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero,
  .hero-bg,
  .hero-title-line1,
  .hero-title-line2,
  .hero-title-sub,
  .hero-image,
  .hero.is-idle .hero-image,
  .hero-glow-spot,
  .hero.is-idle .hero-glow-spot {
    animation: none;
  }

  .hero-title-line1,
  .hero-title-line2,
  .hero-title-sub,
  .hero-image {
    opacity: 1;
    transform: none;
  }

}

@media (max-width: 860px) {
  /* Mobile keeps the float and glow, just quieter — parallax is already
     fully disabled in js/hero.js below this breakpoint. */
  @keyframes heroFloat {
    0%,
    100% {
      transform: translateY(0);
    }
    50% {
      transform: translateY(-3px);
    }
  }

  .hero-glow-spot {
    width: 18%;
  }

  .hero.is-idle .hero-glow-spot {
    animation-name: heroGlowBreatheSoft;
  }

  @keyframes heroGlowBreatheSoft {
    0%,
    100% {
      opacity: 0.08;
    }
    50% {
      opacity: 0.16;
    }
  }
}

/* ================================================================== */
/* Responsive                                                          */
/* ================================================================== */

@media (max-width: 1280px) {
  /* Image width is the one thing that still needs its own tuning below
     1280px: the base 58.5vw formula floors at 605px here, which starts
     crowding the text column. */
  .hero-media {
    right: -6%;
    bottom: -6%;
    width: 54vw;
  }
}

@media (max-width: 860px) {
  .hero {
    min-height: auto;
  }

  .hero-inner {
    padding-left: var(--content-inset-left);
    padding-right: var(--content-inset-left);
    padding-top: calc(var(--header-height) + 32px);
    padding-bottom: 32px;
    display: block;
  }

  .hero-text {
    width: 100%;
  }

  .hero-title-line1,
  .hero-title-line2 {
    font-size: clamp(44px, 9vw, 60px);
    line-height: 0.98;
  }

  .hero-title-sub {
    margin-top: 16px;
  }

  .hero-title-sub-prefix,
  .hero-title-sub-city {
    font-size: clamp(20px, 5vw, 26px);
  }

  .hero-media {
    position: relative;
    right: auto;
    bottom: auto;
    width: 100%;
    aspect-ratio: 1536 / 1024;
    margin-top: 8px;
  }

  .hero-image {
    object-position: center bottom;
  }
}

@media (max-width: 480px) {
  .hero-title-line1,
  .hero-title-line2 {
    font-size: clamp(38px, 10.5vw, 48px);
  }
}
