/*
 * Pinned hero.
 *
 * The prototype used container queries and cqw units against a wrapper this
 * theme does not have, so the breakpoints are media queries and the fluid
 * wordmark uses vw.
 */

.ad-hero {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /*
   * Sized against the space BELOW the sticky header, not the whole viewport.
   * At 100vh the hero starts at the header's bottom edge and runs 91px past
   * the fold, hiding the SCROLL cue and the coordinates until the visitor
   * scrolls, which is the one thing a scroll cue must not do.
   *
   * --ad-header-h is measured by ui.js; the fallback matches the rendered
   * header so the layout is right before scripts run.
   *
   * svh rather than vh so a mobile browser's collapsing toolbar cannot push
   * the furniture off screen either.
   */
  height: calc(100vh - var(--ad-header-h, 91px));
  height: calc(100svh - var(--ad-header-h, 91px));
  min-height: 520px;
  max-height: calc(1000px - var(--ad-header-h, 91px));
  padding: 100px var(--ad-space-page) 88px;
  text-align: center;
  overflow: hidden;
}

/* ------------------------------------------------------ background layers */

.ad-hero__bg {
  position: absolute;
  inset: -8% 0;       /* vertical bleed so the parallax never shows an edge */
  will-change: transform;
}

.ad-hero__gradient {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--ad-color-hero-grad) 0%, var(--ad-color-bg) 100%);
}

.ad-hero__grid {
  position: absolute;
  inset: 0;
  opacity: .6;
  background-image:
    linear-gradient(var(--ad-color-grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--ad-color-grid-line) 1px, transparent 1px);
  background-size: 56px 56px;
  animation: ad-drift 8s linear infinite;
  /* The prototype omitted the -webkit- prefix, which drops the mask in Safari. */
  -webkit-mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, #000 30%, transparent 80%);
}

@keyframes ad-drift {
  to { background-position: 0 56px, 56px 0; }
}

.ad-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: .5;
  pointer-events: none;
}

.ad-hero__scan {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  opacity: .5;
  background: linear-gradient(90deg, transparent, var(--ad-color-accent), transparent);
  animation: ad-scan 7s linear infinite;
}

@keyframes ad-scan {
  from { top: -2px; }
  to   { top: 100%; }
}

/* ----------------------------------------------------------- content */

.ad-hero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 28px;
  max-width: 1200px;
  will-change: transform, opacity;
}

.ad-hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--ad-font-mono);
  font-size: 13px;
  letter-spacing: .16em;
  color: var(--ad-color-accent);
}

.ad-hero__square {
  width: 8px;
  height: 8px;
  background: var(--ad-color-accent);
}

.ad-hero__wordmark {
  position: relative;
  width: min(1160px, 92vw);
}

.ad-hero__h1 {
  margin: 0;
  line-height: .9;
  color: var(--ad-color-text);
}

.ad-hero__h1 svg,
.ad-hero__glitch svg {
  display: block;
  width: 100%;
  height: auto;
}

/*
 * The accent clone that produces the glitch. Stacked exactly over the h1 and
 * hidden from assistive tech, so the wordmark is announced once.
 */
.ad-hero__glitch {
  position: absolute;
  inset: 0;
  color: var(--ad-color-accent);
  clip-path: inset(0 0 100% 0);
  animation: ad-glitch 5s steps(1) infinite;
}

.ad-hero__glitch .ad-wordmark__dot { fill: currentColor; }

@keyframes ad-glitch {
  0%, 86%, 100% { clip-path: inset(0 0 100% 0); transform: none; }
  88%  { clip-path: inset(18% 0 58% 0); transform: translate(-8px, 0); }
  91%  { clip-path: inset(62% 0 8% 0);  transform: translate(8px, 0); }
  94%  { clip-path: inset(38% 0 44% 0); transform: translate(-4px, 0); }
  97%  { clip-path: inset(0 0 100% 0); }
}

.ad-hero__sub {
  max-width: 620px;
  font-size: 20px;
  line-height: 1.5;
  color: var(--ad-color-text-secondary);
}

.ad-hero__actions {
  display: flex;
  gap: 12px;
}

.ad-hero__cta {
  min-height: 52px;
  font-size: 15px;
}

.ad-btn--outline {
  background: transparent;
  color: var(--ad-color-text);
  border: 1px solid var(--ad-color-border-input);
}

.ad-btn--outline:hover,
.ad-btn--outline:focus-visible {
  border-color: var(--ad-color-accent);
  color: var(--ad-color-accent);
}

/* ------------------------------------------------------------ furniture */

.ad-hero__scroll,
.ad-hero__coords {
  position: absolute;
  bottom: 28px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--ad-font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  color: var(--ad-color-text-meta);
}

.ad-hero__scroll { inset-inline-start: var(--ad-space-page); }
.ad-hero__coords { inset-inline-end: var(--ad-space-page); }

.ad-hero__caret {
  width: 6px;
  height: 12px;
  background: var(--ad-color-accent);
  animation: ad-blink 1s steps(1) infinite;
}

@keyframes ad-blink {
  50% { opacity: 0; }
}

/* --------------------------------------------------------------- reveal */

/*
 * Opt-IN. Nothing is hidden until the `js` class confirms the script is
 * running, so a JavaScript failure leaves a fully readable page. The
 * prototype's [data-reveal]{opacity:0} hid the entire document instead.
 */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity .9s cubic-bezier(.2, .7, .2, 1) var(--ad-reveal-delay, 0s),
    transform .9s cubic-bezier(.2, .7, .2, 1) var(--ad-reveal-delay, 0s);
}

.js [data-reveal][data-in] {
  opacity: 1;
  transform: none;
}

/* ---------------------------------------------------------- responsive */

@media (max-width: 640px) {
  .ad-hero {
    min-height: 560px;
    padding: 120px var(--ad-space-page-mobile) 80px;
  }

  .ad-hero__sub { font-size: 17px; }

  .ad-hero__actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  .ad-hero__scroll,
  .ad-hero__coords { display: none; }
}

/*
 * Reduced motion: stop every ambient loop and render the reveal immediately.
 * The hero also stops being sticky, because a pinned viewport-height panel is
 * itself a motion effect.
 */
@media (prefers-reduced-motion: reduce) {
  .ad-hero { position: relative; }

  .ad-hero__grid,
  .ad-hero__scan,
  .ad-hero__glitch,
  .ad-hero__caret {
    animation: none;
  }

  .ad-hero__glitch { display: none; }

  .js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Same treatment when the visitor has asked for motion to stop (SC 2.2.2). */
[data-ad-motion="off"] .ad-hero__grid,
[data-ad-motion="off"] .ad-hero__scan,
[data-ad-motion="off"] .ad-hero__glitch,
[data-ad-motion="off"] .ad-hero__caret {
  animation: none;
}

[data-ad-motion="off"] .ad-hero__glitch { display: none; }
