/* ============================================================
 * Cinematic hero — full bleed, layered parallax
 * Layers are positioned by CSS; transforms are written per frame
 * by the rAF loop in hero-cinematic.jsx via --py / --scale.
 * ============================================================ */

/* styles.css sets body { padding-top: 68px } to clear the fixed nav. A full
 * bleed hero has to run underneath it instead — the nav floats over the plate
 * and the hero itself provides the clearance for everything below. */
html.has-cine-hero body {
  padding-top: 0;
}

.hero-cine {
  position: relative;
  width: 100vw;
  /* svh so mobile browser chrome doesn't crop the composition */
  height: 100svh;
  min-height: 640px;
  margin-left: calc(50% - 50vw); /* escape any max-width container */
  overflow: hidden;
  background: #0E0D0C;
  isolation: isolate;
}

/* Keyboard users need a way past the fixed nav into the content. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 12px 20px;
  border-radius: 0 0 var(--radius-md) 0;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--f-sans);
  font-size: 14px;
  font-weight: 600;
}
.skip-link:focus {
  left: 0;
}

/* ---- plate layers ---- */

.hero-cine__layer {
  position: absolute;
  inset: -8% 0 -8% 0; /* bleed so parallax never exposes an edge */
  width: 100%;
  will-change: transform;
  transform: translate3d(0, var(--py, 0px), 0) scale(var(--scale, 1));
  backface-visibility: hidden;
}

.hero-cine__layer img,
.hero-cine__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hero-cine__layer--back  { z-index: 1; }
.hero-cine__layer--mid   { z-index: 2; }
.hero-cine__layer--fore  { z-index: 3; }

/* ---- carousel crossfade ----
 * Both the active and outgoing story layers are mounted for one brief
 * window (see the JS: prevIndex clears ~80ms after CROSSFADE_MS), stacked
 * and cross-faded by opacity alone — no slide, no parallax on the swap,
 * matching the brief's "subtle, not carousel chrome" instruction. The
 * active layer sits above so its fade-in is what the eye follows. */
.hero-cine__layer.is-active   { z-index: 2; opacity: 1; transition: opacity 700ms cubic-bezier(0.32, 0.72, 0, 1); }
.hero-cine__layer.is-outgoing { z-index: 1; opacity: 0; transition: opacity 700ms cubic-bezier(0.32, 0.72, 0, 1); }
/* Outside a transition only one layer is mounted at all, so this rule
   mostly matters during the ~700ms both are present. */

/* ---- grade + scrims ----
 * Contrast for the headline is carried here, measured against the
 * actual plate rather than assumed. Tune these, not the type color. */

.hero-cine__scrim {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}

/* bottom-weighted scrim: protects headline + CTAs */
.hero-cine__scrim--base {
  /* Eased back from 0.92/0.72/0.28 once the generated plate replaced the
   * placeholder: that plate is already dark on the left where the type sits,
   * so the old scrim was darkening dark and the frame read as murk. The type
   * still clears contrast on the plate alone. */
  background:
    linear-gradient(
      to top,
      rgba(14, 13, 12, 0.74) 0%,
      rgba(14, 13, 12, 0.46) 30%,
      rgba(14, 13, 12, 0.14) 62%,
      rgba(14, 13, 12, 0.04) 100%
    );
}

/* top scrim so the nav stays legible over bright sky */
.hero-cine__scrim--top {
  background: linear-gradient(
    to bottom,
    rgba(14, 13, 12, 0.55) 0%,
    rgba(14, 13, 12, 0.00) 22%
  );
}

/* cool grade that deepens on scroll — the handoff to the system world */
.hero-cine__scrim--grade {
  background: #0E0D0C;
  opacity: var(--grade, 0);
}

/* Dissolve into whatever section follows. Kept deliberately short — at 18%
 * it lightened the same band the base scrim was darkening to carry the CTAs,
 * and the two cancelled into mud. A narrow seam reads as intent. */
.hero-cine__scrim--handoff {
  background: linear-gradient(to top, var(--bg) 0%, transparent 7%);
}

/* ---- content ---- */

/* Text left, the film invitation right and vertically centred against it.
 * The two sit on one baseline row so the play control reads as part of the
 * composition rather than a button parked under the paragraph. */
.hero-cine__content {
  position: relative;
  z-index: 5;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 0 var(--gutter) clamp(64px, 9vh, 112px);
  max-width: var(--max-w);
  margin: 0 auto;
  will-change: transform, opacity;
  transform: translate3d(0, var(--content-py, 0px), 0);
  opacity: var(--content-op, 1);
}

.hero-cine__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Directly under the lead, on the same left axis as the headline. Parked in
 * a right-hand column it read as floating debris rather than part of the
 * composition. */
.hero-cine__actions {
  margin-top: 40px;
}

.hero-cine__eyebrow {
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  /* Cream, not the brand pink. This line sits at the horizon — the brightest
     band of the plate — and the loop's brightness there changes with each
     cast member, so no single pink survives every frame ("BEHIND THE STAY"
     disappeared). The title proves cream holds against the same sky. The
     brand cue moves to the rule below, which is pink and needs no contrast.
     The base scrim cannot cover this; it was tried at 18% and muddied the
     whole frame, so it lives at 7% and legibility is carried on the glyphs. */
  color: #F5F1EA;
  text-shadow: 0 1px 14px rgba(10, 8, 12, 0.78);
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
}

.hero-cine__eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: var(--accent);
}

.hero-cine__title {
  font-family: var(--f-display);
  color: #F5F1EA;
  font-weight: 400;
  font-size: clamp(44px, 7.4vw, 116px);
  line-height: 0.98;
  letter-spacing: -0.015em;
  text-wrap: balance;
  margin: 0 0 24px;
  /* 22ch, not 16ch: "The Omnichannel AI CRM" is 22 characters and has to sit
     on one line, or the product name breaks across two. The container and
     the font-size clamp still constrain this well below 22ch on mobile. */
  max-width: 22ch;
  text-shadow: 0 2px 40px rgba(0, 0, 0, 0.45);
}

.hero-cine__title em {
  font-style: italic;
  color: var(--accent);
  /* "AI CRM" is the accented phrase, so it must not wrap mid-phrase — a
     highlight split across two lines reads as two highlights. Six
     characters; it fits at every width. */
  white-space: nowrap;
}

/* The forced break in the H1 is a desktop measure. Below this the headline
   needs every line it can wrap onto: the font-size clamp bottoms out at
   44px, so "The Omnichannel AI CRM" stops fitting on one line at around
   440px of viewport and would run off the side. Dropping the <br> hands the
   line back to `text-wrap: balance`. */
@media (max-width: 560px) {
  .hero-cine__title br { display: none; }
}

/* .hero-cine__text is display:flex;flex-direction:column with the default
   align-items:stretch, so without this the row stretches to the full
   column width instead of shrink-wrapping its content — same reason the
   single badge needed align-self:flex-start before there were three. */
.hero-cine__badges {
  display: flex;
  flex-wrap: wrap;
  align-self: flex-start;
  justify-content: flex-start;
  gap: 10px;
  margin: 0 0 22px;
}

/* Translucent + backdrop-blur, same treatment as .hero-cine__btn-ghost
   below — a solid pill would fight the photo, but plain text here would
   inherit the eyebrow's reliance on text-shadow alone, and a trust claim
   is exactly the wrong place to risk sitting unreadable over a bright
   frame of the loop. position:relative anchors the tooltip.

   --tint is set inline per-instance (HeroBadge's style prop) to that
   badge's own colour (--c-whatsapp / --accent / --c-email) — the icon
   fill AND the hover glow below both read the one variable, so "this
   badge's colour" is declared once, not duplicated between the icon
   background and a hard-coded shadow colour that would drift from it. */
.hero-cine__badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 15px 8px 8px;
  background: rgba(245, 241, 234, 0.10);
  border: 1px solid rgba(245, 241, 234, 0.30);
  border-radius: 999px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--f-sans);
  font-size: 13px;
  font-weight: 500;
  color: #F5F1EA;
  cursor: default;
  transition: background 220ms ease, border-color 220ms ease, transform 220ms ease, box-shadow 220ms ease;
}
/* Subtle lift + a soft glow tinted with the badge's own colour, not a
   generic white shadow — that's what makes three badges with three
   colours feel like one considered system on hover instead of one flat
   effect copy-pasted three times. */
.hero-cine__badge:hover {
  background: rgba(245, 241, 234, 0.16);
  border-color: color-mix(in srgb, var(--tint) 55%, rgba(245, 241, 234, 0.3));
  transform: translateY(-2px);
  box-shadow:
    0 10px 24px -10px rgba(0, 0, 0, 0.45),
    0 0 0 1px color-mix(in srgb, var(--tint) 20%, transparent) inset;
}
.hero-cine__badge:focus-visible {
  outline: 2px solid #F5F1EA;
  outline-offset: 2px;
}
.hero-cine__badge-icon {
  position: relative;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  /* A flat fill on a small circle reads as a sticker; a top-left highlight
     reads as a lit, dimensional object — the cheapest move that separates
     "premium" from "clipart" at this size. */
  background: radial-gradient(circle at 32% 28%, color-mix(in srgb, var(--tint) 100%, white 28%), var(--tint) 72%);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.hero-cine__badge:hover .hero-cine__badge-icon {
  transform: scale(1.1);
}
.hero-cine__badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-whatsapp);
  flex-shrink: 0;
  position: relative;
}
.hero-cine__badge-dot::before {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--c-whatsapp);
  animation: hero-cine-badge-ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes hero-cine-badge-ping {
  0% { transform: scale(0.6); opacity: 0.9; }
  75%, 100% { transform: scale(2.1); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-cine__badge-dot::before { animation: none; opacity: 0.5; }
}

/* Tooltip — hand-built, not shadcn/Radix: this page has no build step (no
   npm, no bundler, plain React + Babel-in-browser), so there's nowhere to
   install that dependency. Solid dark panel rather than translucent —
   unlike the pill itself, this can land anywhere over the photo depending
   on scroll/viewport, and a trust explanation is the wrong place to risk
   sitting unreadable over a bright frame of the loop. */
.hero-cine__badge-tip {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content;
  max-width: 240px;
  padding: 10px 12px;
  background: #14100F;
  color: #F5F1EA;
  border: 1px solid rgba(245, 241, 234, 0.14);
  border-radius: 10px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  box-shadow: 0 12px 28px -8px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease, transform 160ms ease;
  z-index: 5;
}
.hero-cine__badge-tip.is-open {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.hero-cine__badge-tip-arrow {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 9px;
  height: 9px;
  background: #14100F;
  border-right: 1px solid rgba(245, 241, 234, 0.14);
  border-bottom: 1px solid rgba(245, 241, 234, 0.14);
  clip-path: polygon(0 0, 100% 0, 100% 100%);
  margin-top: -5px;
}
/* First pill sits close to the left edge of the container; a centered
   tooltip on it would clip against the viewport on narrow screens. Anchor
   its tooltip to its own left edge instead of centering. */
.hero-cine__badge:first-child .hero-cine__badge-tip {
  left: 0;
  transform: translateX(0) translateY(4px);
}
.hero-cine__badge:first-child .hero-cine__badge-tip.is-open {
  transform: translateX(0) translateY(0);
}
.hero-cine__badge:first-child .hero-cine__badge-tip-arrow {
  left: 16px;
  transform: translateX(-50%);
}

.hero-cine__lead {
  font-family: var(--f-sans);
  font-size: 18px;
  line-height: 1.55;
  color: rgba(245, 241, 234, 0.78);
  max-width: 52ch;
  text-wrap: pretty;
  margin: 0;
}


/* The ghost button inherits --ink, which is dark under the light theme the
 * rest of the page uses. Over a photographic plate it has to be cream. */
.hero-cine__btn-ghost {
  color: #F5F1EA;
  border-color: rgba(245, 241, 234, 0.30);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.hero-cine__btn-ghost:hover {
  border-color: rgba(245, 241, 234, 0.62);
  background: rgba(245, 241, 234, 0.10);
}

/* Focus must stay visible against a photograph, not just against a flat bg. */
.hero-cine a:focus-visible {
  outline: 2px solid #F5F1EA;
  outline-offset: 3px;
  border-radius: 999px;
}

/* ---- nav inversion ----
 * .gm-nav is position:fixed with background color-mix(var(--bg) 80%), so over
 * a dark hero in the light theme it renders as a cream bar across the plate.
 * Re-point the token scope instead of restyling every child: --ink drives the
 * logo fill, links, and burger; --bg drives the CTA's text colour. */
/* Keep a handle on the page's OWN palette before the nav re-points it, so any
   descendant that is not nav chrome can opt back out. Resolved here on <html>,
   where the nav override is not in scope, so these hold the real theme values
   under both light and dark. */
.has-cine-hero {
  --page-bg: var(--bg);
  --page-ink: var(--ink);
  --page-ink-2: var(--ink-2);
  --page-ink-3: var(--ink-3);
  --page-hairline: var(--hairline);
  --page-hairline-strong: var(--hairline-strong);
}

.has-cine-hero .gm-nav:not(.scrolled) {
  --ink: #F5F1EA;
  --ink-2: rgba(245, 241, 234, 0.78);
  --ink-3: rgba(245, 241, 234, 0.58);
  --bg: #0E0D0C;
  --hairline: rgba(245, 241, 234, 0.14);
  --hairline-strong: rgba(245, 241, 234, 0.24);
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* The mega menu is a CHILD of .gm-nav, so it inherited the inversion above and
   rendered dark-with-cream-text over the hero, then flipped to the normal light
   panel the moment the page scrolled — one menu, two colour schemes, depending
   on scroll position. The inversion is for the BAR's chrome only (logo, links,
   burger, CTA); a dropped panel is page surface and keeps the page's palette. */
/* .gm-drop is the Resources dropdown, added later and identical in kind:
   another dropped panel inside the inverted bar. It shipped reading the
   bar's palette and rendered a black panel over the light mega menu. */
.has-cine-hero .gm-nav:not(.scrolled) .gm-mega,
.has-cine-hero .gm-nav:not(.scrolled) .gm-drop {
  --bg: var(--page-bg);
  --ink: var(--page-ink);
  --ink-2: var(--page-ink-2);
  --ink-3: var(--page-ink-3);
  --hairline: var(--page-hairline);
  /* the "see all" pill's border reads this one */
  --hairline-strong: var(--page-hairline-strong);
}

/* ---- the single product artifact ---- */

.hero-cine__bubble {
  position: absolute;
  z-index: 5;
  right: max(var(--gutter), calc(50vw - var(--max-w) / 2));
  top: 46%;
  width: min(320px, 78vw);
  padding: 14px 16px;
  border-radius: var(--radius-lg) var(--radius-lg) 6px var(--radius-lg);
  background: rgba(245, 241, 234, 0.10);
  border: 1px solid rgba(245, 241, 234, 0.18);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  color: #F5F1EA;
  font-family: var(--f-sans);
  will-change: transform, opacity;
  transform: translate3d(0, var(--bubble-py, 0px), 0);
  /* Fades with the rest of the hero content, otherwise it rises straight
   * into the fixed nav and sits there at full opacity. */
  opacity: var(--content-op, 1);
}

.hero-cine__bubble-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(245, 241, 234, 0.62);
  margin-bottom: 8px;
}

.hero-cine__bubble-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-whatsapp);
  box-shadow: 0 0 8px var(--c-whatsapp);
}

.hero-cine__bubble-body {
  font-size: 14px;
  line-height: 1.5;
  text-wrap: pretty;
}

.hero-cine__bubble-time {
  margin-top: 8px;
  font-family: var(--f-mono);
  font-size: 11px;
  color: rgba(245, 241, 234, 0.45);
}

/* ---- carousel dots ----
 * Deliberately quiet — thin strokes, no shadow, generous hit target without
 * a visually heavy control. Centered on the whole hero and stacked above
 * the scroll cue (same absolute/bottom/left:50% recipe as .hero-cine__cue
 * below), not parked under the watch-film button on the copy block's left
 * axis — a carousel indicator reads as chrome for the SLIDE, not as part
 * of the text column above it. */
.hero-cine__dots {
  position: absolute;
  z-index: 5;
  bottom: 68px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  opacity: var(--content-op, 1);
}

.hero-cine__dot {
  width: 20px;
  height: 6px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: rgba(245, 241, 234, 0.28);
  cursor: pointer;
  transition: background 220ms ease, width 220ms ease;
}
.hero-cine__dot:hover {
  background: rgba(245, 241, 234, 0.5);
}
.hero-cine__dot.is-active {
  width: 32px;
  background: rgba(245, 241, 234, 0.92);
}
.hero-cine__dot:focus-visible {
  outline: 2px solid #F5F1EA;
  outline-offset: 3px;
}

/* Visually hidden but announced — the aria-live story-change notice. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- scroll cue ---- */

.hero-cine__cue {
  position: absolute;
  z-index: 5;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(245, 241, 234, 0.55);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.6);
  opacity: var(--content-op, 1);
}

/* ---- entrance ---- */

.hero-cine__rise {
  opacity: 0;
  transform: translateY(28px);
  filter: blur(6px);
  transition:
    opacity 900ms cubic-bezier(0.32, 0.72, 0, 1),
    transform 900ms cubic-bezier(0.32, 0.72, 0, 1),
    filter 900ms cubic-bezier(0.32, 0.72, 0, 1);
}

.hero-cine.is-ready .hero-cine__rise {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

.hero-cine.is-ready .hero-cine__rise:nth-child(1) { transition-delay: 80ms; }
.hero-cine.is-ready .hero-cine__rise:nth-child(2) { transition-delay: 180ms; }
.hero-cine.is-ready .hero-cine__rise:nth-child(3) { transition-delay: 300ms; }
.hero-cine.is-ready .hero-cine__rise:nth-child(4) { transition-delay: 420ms; }

/* ---- mobile ---- */

@media (max-width: 860px) {
  /* Mobile focal points, per story, not one shared guess.
   *
   * All three master plates are ~2.33:1 (2206x946 / 4032x1728 / 1920x810) —
   * NOT 16:9, whatever an earlier version of this comment assumed. Cover
   * onto a portrait phone (e.g. 390x844) scales the plate to match
   * CONTAINER HEIGHT exactly (the plate is far wider than the container, so
   * height is always the constraining axis and never crops) and only ever
   * reveals about the middle ~20% of the plate's WIDTH — so which ~20%
   * survives is a per-plate art-direction call, read off the actual image:
   *   - "the-note": her face sits at ~48% across → a near-centre crop.
   *   - "once": she sits at ~32% across, left of centre → biasing right (the
   *     old shared rule) put the visible window at [80%,100%] and cropped
   *     her out completely, leaving only the turntable and window.
   *   - "memory": she sits at ~62% across → right-of-centre, close to (but
   *     not exactly) what the old shared rule assumed.
   * Each story now carries its own `mobileFocus` in hero-cinematic.jsx,
   * consumed here via --mobile-focus on .hero-cine__layer; vertical stays
   * "center" everywhere since there's no vertical crop to tune. A dedicated
   * portrait plate per story would still be the eventual proper fix. */
  .hero-cine__layer img,
  .hero-cine__video { object-position: var(--mobile-focus, 50% center); }

  /* The three trust pills ("Official Meta Tech Provider" / "AI Guest
   * Memory" / "Self-Healing Data") are a desktop-density device — three
   * hoverable pills with tooltips, designed for a cursor. On a phone they
   * either wrap into their own two-line block above the headline (pure
   * clutter competing with the copy) or, worse, get skimmed with no way to
   * see the tooltip proof behind each claim. Dropped on mobile entirely
   * rather than shrunk; the lead paragraph already carries the substance of
   * the claim ("one guest profile... campaigns, journeys, loyalty and B2B
   * pipeline"). */
  .hero-cine__badges { display: none; }

  .hero-cine__bubble { display: none; }
  .hero-cine__content { justify-content: flex-end; padding-bottom: 88px; }
  .hero-cine__lead { font-size: 16px; margin-bottom: 28px; }
  .hero-cine__actions { width: 100%; }
  .hero-cine__actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ---- reduced motion: static, complete, not broken ---- */

@media (prefers-reduced-motion: reduce) {
  .hero-cine__layer,
  .hero-cine__content,
  .hero-cine__bubble {
    transform: none !important;
    will-change: auto;
  }
  /* Manual dot navigation still works under reduced motion (it's a
     deliberate user action) — the crossfade itself just becomes an
     instant cut instead of a 700ms fade. */
  .hero-cine__layer.is-active,
  .hero-cine__layer.is-outgoing {
    transition: none;
  }
  .hero-cine__scrim--grade { opacity: 0 !important; }
  .hero-cine__rise {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }
}
