/* ============================================================
   Ziya — hero section

   The plate is a lit black stage with two plush characters on
   the right. The copy sits in the left third, which is where
   the stage stays dark. Measured across the whole loop (/255):

     copy column   x 0.00-0.43   1-15    the stage
     characters    x 0.43-0.88   up to 255
     amber rim     x 0.88-1.00   40-120

   Nothing goes over the footage: at luma 15 the copy column
   needs no scrim, so the plate is never dimmed.

   The clip is a boomerang — it plays forward, then back — so
   the loop point is a real frame step instead of the jump the
   raw plate cut on (mean absolute difference 7.58 to 0.41).
   ============================================================ */

:root {
  --ink:     #05040A;   /* the stage reads #020204; lifted so it is not pure black */
  --white:   #FFFFFF;
  --mist:    rgba(255, 255, 255, .62);
  --pink:    #FF6AA2;   /* sampled #E95D96 off the burnt-in headline, lifted */
  --amber:   #FFC46A;   /* sampled #F4BF64 at the other end of the same ramp */
  --hair:    rgba(255, 255, 255, .16);

  --display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --body:    "Outfit", "Helvetica Neue", Arial, sans-serif;
  --gutter:  clamp(1.5rem, 5vw, 5rem);
  --ease:    cubic-bezier(.22, .61, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; }

body {
  background: var(--ink);
  color: var(--white);
  font-family: var(--body);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

:focus-visible { outline: 2px solid var(--pink); outline-offset: 4px; }

/* ---------- stage ---------- */

.hero {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto 1fr;
  padding: 0 var(--gutter) clamp(2rem, 6vh, 4rem);
}

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* Far enough back that a couple of degrees reads as a lean and not a flip. */
  perspective: 1800px;
}

/* The plate leans toward the pointer. The characters' heads cannot be moved
   on their own — they are welded to the bodies in the footage, and the pompom
   hair has no edge clean enough to cut along — so the stage turns instead,
   which with the pupils following reads as the pair turning to look at you.

   The 3% scale is the cost of the lean: perspective pulls the far corner in by
   a few pixels, and this keeps plate under the whole frame. It magnifies about
   the centre, which pushes the cast away from the copy rather than into it. */
.hero__stage {
  position: absolute;
  inset: 0;
  transform: scale(1.03);
  will-change: transform;
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Cover crops the sides on anything squarer than 16:9, and the copy column
     depends on the dark left third surviving that crop — so the bias is small
     and toward the left, trimming empty stage rather than the column. */
  object-position: 18% center;
  display: block;
}

/* ---------- the characters' pupils ----------
   Not an overlay on the footage — the plate has no pupils left in it. These
   are the pupils, four marks a few pixels wide sitting exactly where the
   painted ones were, free to look wherever the pointer is. script.js writes
   each one's position and size straight into the transform, because both
   change every video frame as the characters move. */

.eyes {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  contain: strict;
}

.eye {
  position: absolute;
  top: 0;
  left: 0;
  /* A fixed 100px box scaled by the transform: the eyeballs change size as the
     characters move toward the camera, and scaling never costs a layout. */
  width: 100px;
  height: 100px;
  margin: -50px 0 0 -50px;
  border-radius: 50%;
  background:
    radial-gradient(ellipse 46% 30% at 33% 20%,
                    rgba(255, 255, 255, .9), rgba(255, 255, 255, 0) 72%),
    radial-gradient(circle at 50% 40%, #17131D, #05040A 66%);
  opacity: 0;
  will-change: transform;
}

.eye[data-on] { opacity: 1; }

/* ---------- top bar ---------- */

.topbar {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: clamp(1.3rem, 3.2vh, 2.1rem);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.1rem, 1.4vw, 1.3rem);
  letter-spacing: -.01em;
}

/* The mark is an eye, because that is the one thing both characters lead with.
   Two boxes rather than an SVG: at this size the mark is a disc inside a disc,
   which CSS draws on its own, and it keeps the moving part a plain element.
   The proportions match favicon.svg — the pupil is 42% of the iris across. */
.brand__eye {
  position: relative;
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--pink), var(--amber));
}

/* The pupil follows the pointer — script.js writes --px/--py in the range -1..1
   and the translate below scales that to the couple of pixels an eye this size
   can move without the iris losing its centre. */
.brand__pupil {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--ink);
  transform: translate(calc(var(--px, 0) * 2.6px), calc(var(--py, 0) * 2.6px));
  transition: transform .12s linear;
}

.brand__word { white-space: nowrap; }

/* ---------- nav ---------- */

.nav {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.4vw, 2.1rem);
}

.nav__link,
.nav__cta {
  font-size: .82rem;
  font-weight: 500;
  letter-spacing: .01em;
  white-space: nowrap;
}

.nav__link {
  color: var(--mist);
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.nav__link:hover, .nav__link:focus-visible {
  color: var(--white);
  border-color: var(--hair);
}

/* the one nav item that can drift over a lit part of the stage, so it brings
   its own ground the way a button does rather than sitting on a scrim */
.nav__cta {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: .5rem 1.1rem;
  border: 1px solid var(--hair);
  border-radius: 999px;
  background: rgba(5, 4, 10, .55);
  transition: background .3s var(--ease), border-color .3s var(--ease),
              color .3s var(--ease);
}
.nav__cta:hover, .nav__cta:focus-visible {
  background: var(--white);
  border-color: var(--white);
  color: var(--ink);
}

/* ---------- burger (narrow only) ---------- */

.burger {
  display: none;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
.burger span {
  display: block;
  width: 22px;
  height: 1.5px;
  margin: 5px auto;
  background: currentColor;
  border-radius: 2px;
  transition: transform .3s var(--ease);
}
.burger[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
.burger[aria-expanded="true"] span:last-child  { transform: translateY(-3.25px) rotate(-45deg); }

/* ---------- copy ---------- */

.hero__copy {
  position: relative;
  z-index: 1;
  align-self: center;
  min-width: 0;
  /* The stage stays dark out to 43% of the plate's width, and cover crops the
     sides, so the column is sized to that strip rather than to the viewport. */
  max-width: min(37rem, 43vw);
}

.title {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.4rem, 5.4vw, 4.5rem);
  line-height: 1.02;
  letter-spacing: -.035em;
}

.title__line { display: block; }

.title__line--grad {
  background: linear-gradient(96deg, var(--pink) 4%, var(--amber) 96%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  /* keeps each line its own sweep if it ever wraps, rather than stretching one
     gradient across both */
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}

.lede {
  max-width: 34ch;
  margin: clamp(1.1rem, 2.6vh, 1.7rem) 0 0;
  font-size: clamp(.95rem, 1.15vw, 1.06rem);
  line-height: 1.6;
  color: var(--mist);
}

/* ---------- button ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: .8rem;
  min-height: 48px;          /* tap-target floor at every size below, too */
  margin-top: clamp(1.5rem, 3.4vh, 2.4rem);
  padding: .95rem 1.7rem;
  border-radius: 999px;
  background: var(--white);
  color: var(--ink);
  font-size: .92rem;
  font-weight: 600;
  transition: background .3s var(--ease), color .3s var(--ease),
              transform .3s var(--ease);
}
.btn__arrow { width: 22px; height: 11px; flex: none; }

.btn:hover, .btn:focus-visible {
  background: linear-gradient(96deg, var(--pink), var(--amber));
  color: var(--ink);
}

/* ============================================================
   Narrow and portrait: cover crops a 16:9 plate down to one
   character on a phone, so the footage becomes a band with the
   whole cast in it and the copy sits on plain stage below.
   ============================================================ */

@media (max-width: 900px),
       (max-width: 1200px) and (orientation: portrait) {

  .hero {
    grid-template-rows: auto auto 1fr;
    padding-inline: 0;
    row-gap: clamp(1.2rem, 3vh, 2rem);
  }

  .topbar, .hero__copy { padding-inline: var(--gutter); }

  .topbar { order: -1; }     /* the wordmark stays above the band */

  /* No lean in the band: it is sized so the whole frame fits with four pixels
     to spare, and a lean would spend them on the characters' heads. */
  .hero__stage { transform: none; }

  .hero__media {
    position: relative;
    inset: auto;
    width: 100%;
    /* The band's shape is not a free choice: the plate has to be 1.462x the
       band's width for its full width to still reach both edges once the cast
       is pulled to the centre (see the transform below), which makes it 0.822x
       as tall. Give the band exactly that ratio and the whole 16:9 frame fits
       with no vertical crop — otherwise the width constraint wins and the
       characters lose their heads. */
    aspect-ratio: 1 / .822;
    max-height: 46svh;
    -webkit-mask-image: linear-gradient(to bottom, #000 78%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 78%, transparent 100%);
  }

  /* Centre the pair in the band. Their midpoint sits at 65.8% of the plate's
     width, so the video is sized to the band's height and pulled left by that
     fraction of its own width, putting both characters on the centre line.
     Fallback for browsers without container units: plain cover, cropped as far
     right as it goes, which is as close to centred as they can get. */
  .hero__video { object-position: 82% center; }

  @supports (width: 1cqw) {
    .hero__media { container-type: size; }

    .hero__video {
      inset: 50% auto auto 50%;
      /* Big enough to cover the band from the anchor: 177.8cqh is the width that
         makes the plate exactly as tall as the band, 148cqw the width that still
         reaches both edges once the pair is pulled to the middle. Whichever is
         larger wins, so there is never a bare edge to expose — and the band's
         aspect above is set so the two land within a few pixels of each other. */
      width: max(148cqw, 177.8cqh);
      height: auto;
      aspect-ratio: 16 / 9;
      object-position: center;
      transform: translate(-65.8%, -50%);
    }
  }

  .burger { display: block; position: relative; z-index: 4; }

  .nav {
    position: fixed;
    inset: 0;
    z-index: 3;
    flex-direction: column;
    justify-content: center;
    gap: 1.6rem;
    /* only while the menu is open, and it replaces the view rather than tinting
       it — the footage never sits under a permanent scrim, and at anything short
       of opaque the headline ghosts through the links */
    background: var(--ink);
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s var(--ease), visibility .3s var(--ease);
  }
  .nav[data-open] { opacity: 1; visibility: visible; }

  .nav__link, .nav__cta { font-size: 1.05rem; }
  .nav__cta { min-height: 44px; padding: .8rem 1.6rem; }

  .hero__copy {
    align-self: start;
    max-width: none;
  }

  .title { font-size: clamp(2.2rem, 9vw, 3.2rem); }
  .lede  { max-width: 40ch; }
  .btn   { width: 100%; justify-content: center; }
}

/* ---------- small phones ---------- */

@media (max-width: 380px) {
  .hero__media { min-height: 22svh; }
  .title { font-size: clamp(2rem, 9.2vw, 2.4rem); }
  .lede  { font-size: .9rem; }
}

/* ---------- short viewports (phone held sideways) ----------
   Wider than 16:9, so a stacked band does not fit — go back to the overlay
   and let the copy sit on the dark column again. */

@media (max-height: 560px) and (min-width: 561px) {
  .hero {
    grid-template-rows: auto 1fr;
    padding-inline: var(--gutter);
    row-gap: 0;
  }

  .topbar { order: 0; }
  .topbar, .hero__copy { padding-inline: 0; }

  /* undo the band: it is a backdrop again, so every constraint the narrow rules
     put on the media and the video has to come back off */
  .hero__media {
    position: absolute;
    inset: 0;
    width: auto;
    aspect-ratio: auto;
    max-height: none;
    container-type: normal;
    -webkit-mask-image: none;
            mask-image: none;
  }

  .hero__video {
    inset: 0;
    width: 100%;
    height: 100%;
    transform: none;
    object-position: 18% center;
  }

  .hero__copy { align-self: center; max-width: min(30rem, 52vw); }

  .title { font-size: clamp(1.8rem, 5vw, 2.6rem); }
  .lede  { max-width: 32ch; font-size: .88rem; }
  .btn   { width: auto; margin-top: 1.1rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; }
  .brand__pupil { transform: none; }   /* the eye holds still */
  .hero__stage { transform: none; }    /* and the stage does not lean */
}
