/* ==========================================================================
   hero-cinematic.css — the video hero. Loaded by index.html only.

   It was built for a concept page (dummy.html) that was renamed over
   index.html on 16 Jul 2026, so this is now the live home page's hero, not a
   spike. It is still loaded AFTER site.css and scoped to `.cine`/`.nav--over`,
   which is what keeps the other three pages untouched — but "untouched" now
   means about/products/contact, NOT the home page. Anything you change here
   ships to the front door.

   The footage (a drone push down Sheikh Zayed Road at golden hour) has a busy
   skyline on both flanks and no natural empty space to set type into — so the
   grade has to *manufacture* the negative space. It's built left-weighted: the
   copy sits on engineered darkness at the left, while the skyline stays open and
   legible on the right, which is the whole reason for using the footage.
   ========================================================================== */

.cine {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;          /* excludes mobile browser chrome */
  padding: calc(var(--nav-h) + 56px) 0 0;
  background: #060E1E;
}

/* ---------- layer 1: the footage ---------- */
.cine__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  /* a 1KB blurred thumbnail, so there is never a black frame — not while the
     poster decodes, and not while the video buffers */
  background: #060E1E url("../img/hero-skyline-lqip.jpg") center / cover no-repeat;
}
.cine__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Darkened for legibility, but NOT desaturated: the golden-hour light is the
     entire reason this footage is worth using, and it only survives on the right
     where the scrim lets go. */
  filter: saturate(1.06) contrast(1.08) brightness(0.84);
  transform: scale(1.04);      /* hides any sub-pixel edge on scaled playback */
}

/* ---------- layer 2: the scrim that makes room for the type ---------- */
.cine__grade {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    /* left-weighted, so the copy has contrast and the skyline stays open right */
    linear-gradient(
      90deg,
      rgba(6, 14, 30, 0.94) 0%,
      rgba(6, 14, 30, 0.80) 28%,
      rgba(6, 14, 30, 0.42) 55%,
      rgba(6, 14, 30, 0.12) 80%,
      rgba(6, 14, 30, 0.04) 100%
    ),
    /* top: gives the transparent nav something to sit on.
       bottom: gives the glass stat bar something to sit on. */
    linear-gradient(
      180deg,
      rgba(6, 14, 30, 0.62) 0%,
      rgba(6, 14, 30, 0.06) 24%,
      rgba(6, 14, 30, 0.10) 52%,
      rgba(6, 14, 30, 0.72) 86%,
      rgba(6, 14, 30, 0.92) 100%
    );
}

/* A whisper of brand navy through the midtones — enough to tie the footage to
   the palette. Kept low and masked away from the right: `mix-blend-mode: color`
   replaces hue outright, so at any real strength it turns golden hour grey. */
.cine__tint {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, #23406F 0%, #0B1F3A 100%);
  mix-blend-mode: color;
  opacity: 0.30;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 30%, transparent 68%);
  mask-image: linear-gradient(90deg, #000 0%, #000 30%, transparent 68%);
}

.cine__vignette {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 78% 68% at 52% 44%,
    transparent 42%,
    rgba(4, 10, 22, 0.55) 100%
  );
}

/* the site's PCB grid motif, carried onto the video so the page reads as one
   design rather than a stock clip with a header bolted on */
.cine__grid {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, transparent 70%);
  mask-image: linear-gradient(90deg, #000 0%, transparent 70%);
}

/* Film grain. Oversized and moved with a transform rather than
   background-position, so it animates on the compositor instead of repainting a
   full-screen layer sixty times a second. */
.cine__grain {
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  z-index: 1;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: cineGrain 0.72s steps(1) infinite;
}

/* ---------- layer 3: content ---------- */

/* These three are .container children of a flex COLUMN, and .container carries
   `margin: 0 auto`. An auto margin on the cross axis beats `align-items: stretch`
   — so without an explicit width they collapse to shrink-to-fit and centre
   themselves, which turns the figures bar into a single narrow column. */
.cine__inner,
.cine__bar { width: 100%; }

.cine__inner {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 26px;
  padding-top: 24px;
  padding-bottom: 48px;
}

.cine__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 9px 18px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  font-size: var(--fs-micro);
  font-weight: 600;
  /* Same token as the .eyebrow on every other page. These two components have
     always played the same role and never shared a value — 0.24em here against
     0.3em there, for no reason anyone recorded. */
  letter-spacing: var(--tr-caps-wide);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  white-space: nowrap;
}
.cine__eyebrow svg { flex: none; display: block; }

/* The headline is the reason this file was reopened. It was Sora 800 — the
   default display face of a thousand SaaS templates — and the client read the
   page as generic on sight, which was a fair verdict on the type rather than
   on the footage or the layout.

   Bricolage Grotesque 800 is doing two things Sora could not. It has a voice at
   this weight (the angled Y junction, the tailed a, the tight tt), and it is
   materially narrower, which is what lets "Your trusted partner in" hold one
   line at this measure — under Sora it did too, but under any of the wider
   grotesques tried alongside it the line broke into an accidental three-line
   stack. If you swap the display face again, re-check that break first: the
   whole composition rests on two lines, not three. */
.cine__title {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--fs-d1);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  color: #fff;
  max-width: 16ch;
  text-shadow: 0 2px 40px rgba(0, 0, 0, 0.35);
}

/* This is the single gesture that stops the hero reading as a template: the
   accent clause changes FACE, not just colour. Before, the <em> was
   `font-style: normal` plus an amber — which is to say it did nothing a colour
   swap could not, and a colour swap is what every stock hero already does.

   Three things here are load-bearing:
   - font-style: italic, restored. The <em> is finally allowed to be one.
   - 1.06em, because Instrument Serif's cap-height sits noticeably below
     Bricolage's at a matched size; left equal, the serif line reads as an
     accident rather than as a deliberate change of voice.
   - font-weight: 400 stated outright. The family ships one weight, and with
     font-synthesis-weight: none set globally an inherited 800 would silently
     render as 400 anyway — better that the rule says what actually paints. */
.cine__title em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 1.06em;
  letter-spacing: -0.008em;
  color: var(--amber-light);
}

/* Each line is a window; the text slides up into it. `overflow: hidden` on a
   line box clips descenders, so the box is padded and then pulled back by the
   same amount.

   0.12em -> 0.18em. The second line is now Instrument Serif italic set 6%
   larger than the roman, and an italic serif descender reaches materially
   further below the baseline than the grotesque this was measured against —
   at 0.12em the tail of the italic was landing on the clip edge. If the accent
   face, its size multiplier or the line-height changes, re-check this. */
.cine__line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.18em;
  margin-bottom: -0.18em;
}
.cine__line > span {
  display: block;
  transform: translateY(115%);
  animation: cineLineUp 1.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.cine__line:nth-child(1) > span { animation-delay: 0.20s; }
.cine__line:nth-child(2) > span { animation-delay: 0.33s; }

.cine__lede {
  margin: 0;
  /* Measured in characters, not pixels, and deliberately a little tighter than
     the 520px it replaces: Inter sets wider than the Manrope this was tuned
     for, and the copy has to stay inside the left, dark end of the grade or it
     loses its contrast against the skyline. */
  max-width: 52ch;
  font-size: clamp(1rem, 1.15vw, 1.125rem);
  line-height: var(--lh-body);
  color: rgba(255, 255, 255, 0.74);
  text-wrap: pretty;
}

.cine__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  margin-top: 4px;
}

/* frosted secondary button, for use on the footage */
.btn--glass {
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.26);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.btn--glass:hover {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.55);
  color: #fff;
}

/* ---------- layer 4: the glass figures bar ----------
   Light glass, not dark. The cells are frosted white and the type is the
   site's navy, so the bar reads as the same card material used on the rest of
   the site rather than as a hole cut in the footage.

   Two things about this bar are counter-intuitive, and both are measured:

   1. Lowering the cell alpha does NOT reveal the skyline. The grade sits at
      0.72–0.92 opacity of #060E1E across the bar's band — and the left-weighted
      90deg grade puts another 0.94–0.42 on top of it exactly where this bar
      lives, so the two together are ~95–98% opaque there. The backdrop is flat
      near-black and the footage contributes under ~10% of it. Dropping alpha
      therefore just composites the cell toward GREY rather than toward the
      skyline: by 0.62 it has stopped being white at all, and 0.74 was tried and
      read dull. **On this bar, "brighter" and "more opaque" are the same dial.**
      0.80 is the settled trade. Wanting it both brighter and more see-through
      means lightening the 90deg grade, i.e. giving up the left-weighted
      composition the whole hero is built on — that is the real cost, not a
      tweak.
   2. For the same reason, `brightness()` in the backdrop-filter buys nothing.
      Near-black times 2.2 is still near-black: swept over the clip, it moved
      the labels 3.52 -> 3.67:1 at alpha 0.74. Don't reach for it again.

   So the composite is dominated by the alpha, and the only lever that actually
   pays for more transparency is darker ink — see the two colours below. */
.cine__bar {
  position: relative;
  z-index: 3;
  padding-bottom: 34px;
}
.cine__bar-inner {
  /* Deliberately NOT full width. The whole composition is left-weighted so the
     skyline keeps breathing on the right — a bar spanning the container would
     fight that, and would also run straight under the fixed WhatsApp button. */
  max-width: 820px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  /* the 1px gap showing the darker backing IS the divider — no extra borders */
  gap: 1px;
  background: rgba(11, 31, 58, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 18px;
  overflow: hidden;
  backdrop-filter: blur(20px) saturate(1.25);
  -webkit-backdrop-filter: blur(20px) saturate(1.25);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.38);
}
/* Every number below is measured on the worst frame of the loop and the worst
   cell of the four, at 1440x900 — these are glass over moving footage, so the
   type's contrast is whatever the composite happens to be when a light passes
   underneath. Re-run tools/hero_test.py after touching any of them.

   The ink here is a rung darker than the equivalent ink elsewhere on the site,
   and that is what pays for the transparency. At the old 0.86 the stock
   --muted / --amber-ink pair measured 4.64 and 3.41; the two colours below hold
   better-than-original ratios at 0.80:

              alpha 0.86 (old)      alpha 0.80 (now)
     labels   --muted     4.64      #455370      4.90      (needs 4.5 — 11.5px body)
     the +    --amber-ink 3.41      #965716      3.63      (needs 3.0 — 32px = large)
     figures  --navy     10.12      --navy       8.82      (needs 3.0 — 32px = large)

   The + is the binding constraint, not the labels — it is the reason 0.86 could
   not simply be lowered, and the reason the ink cannot simply be handed back as
   the alpha rises. Its stock --amber-ink measures 2.97 at 0.80 and only 3.13 at
   0.82, i.e. it does not clear 3:1 again until ~0.85 with any margin worth
   having — the whole amber ramp is pitched for dark ground (see --amber-ink in
   site.css). Below ~0.66 nothing in the amber family clears 3:1 at all.

   Both colours are as LIGHT as AA allows at this alpha, deliberately: darker ink
   reads as dull just as surely as a grey surface does, so it is not free either.
   If you raise the alpha, lighten these back toward --muted / --amber-ink rather
   than leaving them — and re-measure, don't eyeball. */
.cine__stat {
  background: rgba(255, 255, 255, 0.80);
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  transition: background 0.35s ease;
}
.cine__stat:hover { background: rgba(255, 255, 255, 0.88); }
/* Tabular, lining figures. ambient.js counts these from "0" up to 500 one
   frame at a time, and with proportional figures every digit has its own
   advance width — so the number twitched and dragged the "+" sideways for the
   whole run, inside a cell whose left edge is a hard vertical in a four-up
   grid. Tabular locks all ten digits to one width and the count is dead still.
   The comment above this block warns that the numerals must not reflow between
   "0" and "500"; this is what actually enforces it. */
.cine__stat-num {
  font-family: var(--display);
  font-weight: 800;
  font-size: 2rem;
  line-height: 1.05;
  color: var(--navy);
  letter-spacing: var(--tr-tight);
  font-variant-numeric: tabular-nums lining-nums;
}
/* The "+" is the one glyph here that isn't ink, so it's the one that had to
   move: --amber-light was right on the old dark cell, and even --amber-dark only
   measured 2.2:1 on the light one. The whole amber ramp is pitched for dark
   ground — see --amber-ink in site.css.

   One rung darker than --amber-ink, and hero-local rather than a new global
   token: --amber-ink is carrying glyphs elsewhere on grounds this bar knows
   nothing about (4.43:1 on --card-face), so darkening it globally would be
   changing colours on pages that never asked. Same hue, so it still reads amber
   rather than brown — but only just. This is the glyph that goes muddy first if
   the alpha ever drops again; it is the accent the eye actually reads as
   "colour" in this bar. */
.cine__stat-num .plus { color: #965716; }
/* "Mon–Sat" is a word, not a figure — it won't fit the cell at display size */
.cine__stat--sm .cine__stat-num {
  font-size: 1.375rem;
  letter-spacing: var(--tr-snug);
  padding-top: 6px;
}
/* One rung off --muted, and hero-local for the same reason as the + above. It
   still sits well clear of the --navy figures in luminance (0.086 vs 0.026), so
   the quiet-label / loud-figure hierarchy the cell is built on survives it. */
/* Size and weight move (11.5 -> 11px, 700 -> 600) to match the micro-label
   register the rest of the site now shares; the COLOUR deliberately does not.
   #455370 is the measured value from the contrast table above and WCAG ratios
   are a function of the colour pair alone — a lighter stroke does not change
   the 4.90:1, and this label owes the full 4.5 at any size under 18px, so
   there is no headroom to spend on a lighter ink. */
.cine__stat-label {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: #455370;
}

/* ---------- the nav rides transparent over the hero ---------- */
.nav {
  transition: background-color 0.4s ease, border-color 0.4s ease;
}
.nav__logo { position: relative; display: flex; }
.nav__logo img { transition: opacity 0.4s ease; }
.nav__logo .is-light {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}

/* Two scoping rules govern everything below, and both exist for the same
   reason: the mobile drawer is a light panel that lives *inside* `.nav`, so it
   inherits anything written for the bar.

   1. Every reversed-out colour is scoped to `.nav__links` — the desktop row.
      An unscoped `.nav--over .nav__link` also paints the drawer's links white,
      which on a #F8F9FB panel is invisible text (measured 1.01:1).
   2. The bar's own chrome stands down while the drawer is open. A transparent
      bar with a reversed lockup, sitting directly on top of an opaque light
      panel, reads as two unrelated components. `:not(.is-drawer-open)` simply
      lets the base `.nav` rules apply again rather than restating them here. */
.nav--over:not(.is-drawer-open) {
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.nav--over:not(.is-drawer-open) .nav__logo .is-light { opacity: 1; }
.nav--over:not(.is-drawer-open) .nav__logo .is-dark { opacity: 0; }
/* Reversed type needs more weight than positive type to hold the same apparent
   stroke — light on dark blooms, and these links sit on moving footage rather
   than a flat ground. 500 on the light pages, 600 here. */
.nav--over .nav__links .nav__link {
  color: rgba(255, 255, 255, 0.82);
  font-weight: 600;
}
.nav--over .nav__links .nav__link:hover { color: #fff; }
.nav--over .nav__links .nav__item--active .nav__link { color: #fff; }
.nav--over .nav__links .nav__cta {
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.26);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: none;
}
.nav--over .nav__links .nav__cta:hover {
  background: var(--amber);
  border-color: var(--amber);
  color: var(--navy);
}
.nav--over:not(.is-drawer-open) .nav__burger {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.24);
}
.nav--over:not(.is-drawer-open) .nav__burger span { background: #fff; }

/* ---------- load-in choreography ---------- */
.cine__eyebrow,
.cine__lede,
.cine__cta,
.cine__bar {
  opacity: 0;
  animation: cineRise 1s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
.cine__eyebrow { animation-delay: 0.06s; }
.cine__lede    { animation-delay: 0.52s; }
.cine__cta     { animation-delay: 0.64s; }
.cine__bar     { animation-delay: 0.76s; }

@keyframes cineLineUp {
  to { transform: translateY(0); }
}
@keyframes cineRise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}
@keyframes cineGrain {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-3%, 2%); }
  40%  { transform: translate(2%, -3%); }
  60%  { transform: translate(-2%, -2%); }
  80%  { transform: translate(3%, 1%); }
  100% { transform: translate(0, 0); }
}

/* ---------- responsive ----------
   Short viewports matter as much as narrow ones here: a 1366x768 laptop leaves
   roughly 650px of page once browser chrome is taken out. At full size the hero
   runs to ~810px, which shoves the figures bar off the bottom of the screen —
   the one element that most needs to be seen. So it gives ground on height. */
@media (min-width: 901px) and (max-height: 820px) {
  .cine { padding-top: calc(var(--nav-h) + 20px); }
  .cine__inner {
    gap: 18px;
    padding-top: 6px;
    padding-bottom: 26px;
  }
  .cine__title { font-size: clamp(2.125rem, 4.2vw, 3.5rem); }
  .cine__lede { font-size: 1rem; line-height: 1.6; }
  .cine__stat { padding: 16px 24px; }
  .cine__stat-num { font-size: 1.625rem; }
  .cine__stat--sm .cine__stat-num { font-size: 1.1875rem; }
  .cine__bar { padding-bottom: 22px; }
}

@media (max-width: 900px) {
  .cine {
    padding-top: calc(var(--nav-h) + 32px);
    min-height: 92svh;
  }
  /* on a phone the left-weighted scrim doesn't work — the copy spans the full
     width, so the whole frame has to carry it */
  .cine__grade {
    background:
      linear-gradient(180deg,
        rgba(6, 14, 30, 0.72) 0%,
        rgba(6, 14, 30, 0.42) 30%,
        rgba(6, 14, 30, 0.70) 66%,
        rgba(6, 14, 30, 0.95) 100%);
  }
  .cine__grid {
    -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 60%);
    mask-image: linear-gradient(180deg, #000 0%, transparent 60%);
  }
  .cine__inner { gap: 18px; padding-top: 12px; padding-bottom: 24px; }
  .cine__title {
    max-width: 100%;
    font-size: clamp(2rem, 7.4vw, 2.875rem);
  }
  .cine__lede { font-size: var(--fs-md); line-height: 1.6; }
  /* The pill runs the full width of a narrow screen at 0.22em; the micro-label
     tracking is the one that still fits. */
  .cine__eyebrow { letter-spacing: var(--tr-caps); }

  .cine__stat { padding: 15px 18px; }
  .cine__stat-num { font-size: 1.5rem; }
  .cine__stat--sm .cine__stat-num { font-size: 1.0625rem; padding-top: 4px; }
  /* Was also dropped to 0.625rem (10px) here, which was over-aggressive: at
     <=520 the bar becomes a 2x2 grid with ~175px cells, and even at 4-across
     the track floor is 180px, so the scale's own 11px fits either way. This is
     the smallest text on the site and it sits on the glass panel at #455370 —
     already the lightest ink AA allows against that backdrop — so shrinking it
     as well was a double hit on legibility. The tighter tracking is what
     actually buys the fit, so that part stays. */
  .cine__stat-label { letter-spacing: 0.1em; }
  .cine__bar-inner { max-width: none; }

  /* The WhatsApp button is fixed to the bottom-right of the *viewport*, so any
     bottom-anchored panel lands under it. Leave it a corner to live in rather
     than let it sit on top of the opening hours. */
  .cine__bar { padding-bottom: 96px; }
}

@media (max-width: 520px) {
  .cine__cta { width: 100%; }
  .cine__cta .btn { flex: 1 1 100%; }
  /* grid-auto-rows so the two rows of the 2x2 always match. Below ~360px a
     couple of the longer labels still take two lines however they are tracked,
     and without this only the row containing them grew — 94/94/76/76, which
     reads as a mistake. Equal rows make the wrap a non-event instead, which is
     why the label keeps its 11px rather than being shrunk to dodge it. */
  .cine__bar-inner { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 1fr; }
}

/* The narrowest phones. Restoring the label to the scale's 11px (see the note in
   the 900px block) left "PRODUCTS IN STOCK" and "CERTIFIED SUPPLIER" wrapping in
   a 2x2 cell at 360px — 17 caps at 11px with 0.1em tracking measure ~122px and
   the content box was only ~123px. The room is bought back from padding and a
   touch of tracking rather than from the type size, because a wrapped label
   makes its whole grid row taller and the four cells stop matching. */
@media (max-width: 430px) {
  .cine__stat { padding: 14px 12px; }
  .cine__stat-label { letter-spacing: 0.06em; }
}

/* ---------- reduced motion ----------
   No auto-playing footage, no grain flicker, no choreography — hero-cinematic.js
   also declines to download the video at all, so the poster is all that loads. */
@media (prefers-reduced-motion: reduce) {
  .cine__line > span,
  .cine__eyebrow,
  .cine__lede,
  .cine__cta,
  .cine__bar {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .cine__grain { animation: none; }
}
