/* Home page hero: near-black in both site themes. Everything here is scoped to .hero-stage,
   or to pages that contain it, so the rest of the site is untouched. */

html:has(.hero-stage) {
  --hero-ink: #0a0a0a;
}

.hero-stage {
  --color-text: #f7f7f5;
  --color-foreground: #f7f7f5;
  --color-text-secondary: #cfcfcb;
  --color-secondary: #cfcfcb;
  --color-muted: #b5b5b0;
  --color-border: rgba(255, 255, 255, 0.18);
  --color-border-strong: rgba(255, 255, 255, 0.42);
  --color-accent: var(--gold-tint);
  --color-accent-hover: var(--gold-tint-hover);
  --color-accent-fill: var(--gold-tint);
  --color-accent-fill-hover: var(--gold-tint-hover);
  --color-accent-contrast: #0a0a0a;
  --color-hover: rgba(255, 255, 255, 0.1);
  --color-active: rgba(255, 255, 255, 0.16);
  color-scheme: dark;

  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  min-height: 100svh;
  margin-top: calc(-1 * var(--header-height));
  padding-top: calc(var(--header-height) + 2rem);
  padding-top: calc(var(--header-height) + clamp(1.25rem, 4svh, 4rem));
  padding-bottom: clamp(3rem, 30svh - 6rem, 18rem);
  overflow: hidden;
  background: var(--hero-ink);
  color: var(--color-text);
}

.hero-ribbon,
.hero-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* The poster is on screen from the first paint. It stays quiet while the live lines draw over it,
   lets go once they have nearly crossed the page, and comes up to full strength if they never arrive. */
.hero-poster {
  fill: none;
  stroke: #ebebeb;
  stroke-width: 0.9;
  opacity: 0.55;
  transition: opacity 0.3s ease;
}

.hero-poster path {
  vector-effect: non-scaling-stroke;
}

.hero-stage[data-ribbon='live'] .hero-poster {
  opacity: 0;
  visibility: hidden;
  transition: opacity 1.2s ease 0.9s, visibility 0s linear 2.1s;
}

.hero-stage[data-ribbon='static'] .hero-poster {
  opacity: 1;
}

.hero-stage[data-ribbon='static'] .hero-ribbon {
  display: none;
}

/* The gold light in plain CSS: it crosses the poster from the first paint, and keeps going for anyone
   without live lines. Multiply tints only the lines and leaves the black, so only the light moves. */
.hero-glow {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  background: linear-gradient(100deg, transparent, var(--gold-tint) 50%, transparent);
  /* the tilted gradient is already gold at the band's side edges on a tall phone hero; this keeps them soft */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 35%, #000 65%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 35%, #000 65%, transparent);
  mix-blend-mode: multiply;
  pointer-events: none;
  animation: hero-glow 4s linear infinite;
}

@keyframes hero-glow {
  from {
    transform: translateX(60%);
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  to {
    transform: translateX(260%);
  }
}

.hero-stage[data-ribbon='live'] .hero-glow {
  display: none;
}

.hero-stage[data-paused] .hero-glow,
html[data-hero-passed] .hero-glow {
  animation-play-state: paused;
}

/* Stops the motion for anyone who wants it still, on this visit and later ones. On the page's right edge,
   clear of the text. */
.hero-pause {
  position: absolute;
  z-index: 3;
  right: max(var(--gutter), calc((100% - var(--container-width)) / 2 + var(--gutter)));
  bottom: var(--space-5);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: rgba(10, 10, 10, 0.72);
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: color var(--transition-base), border-color var(--transition-base);
}

.hero-pause:hover {
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

/* a full 44px target for a thumb */
@media (max-width: 1023px) {
  .hero-pause {
    width: 2.75rem;
    height: 2.75rem;
  }
}

.hero-content {
  position: relative;
  z-index: 2;
  width: 100%;
}

.hero-copy {
  position: relative;
  max-width: 41rem;
}

/* The scrim follows the text block, so it covers any language at any width. It protects the text
   over the poster; the live lines fade themselves out under the text in the shader instead. */
.hero-copy::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: -3rem;
  bottom: -5rem;
  left: -100vw;
  right: -9rem;
  background: var(--hero-ink);
  opacity: 0.82;
  -webkit-mask-image:
    linear-gradient(to left, transparent, #000 9rem),
    linear-gradient(to top, transparent, #000 5rem);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to left, transparent, #000 9rem),
    linear-gradient(to top, transparent, #000 5rem);
  mask-composite: intersect;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

/* gives way only once the poster has gone, and comes back at once if the poster does */
.hero-stage[data-ribbon='live'] .hero-copy::before {
  opacity: 0;
  transition: opacity 0.5s ease 2.1s;
}

/* Reduced motion skips the draw-on, so the lines are at full strength from the first paint and the two
   layers simply cross-fade. From then on it is everyone's hero: the lines drift and the light travels. */
@media (prefers-reduced-motion: reduce) {
  .hero-poster {
    opacity: 1;
    transition: none;
  }

  .hero-ribbon {
    opacity: 0;
    transition: opacity 0.4s ease;
  }

  .hero-stage[data-ribbon='live'] .hero-ribbon {
    opacity: 1;
  }

  .hero-stage[data-ribbon='live'] .hero-poster {
    transition: opacity 0.4s ease, visibility 0s linear 0.4s;
  }

  .hero-stage[data-ribbon='live'] .hero-copy::before {
    transition-delay: 0.4s;
  }
}

.hero-title {
  font-size: clamp(2rem, min(1.35rem + 3.3vw, 9.5svh), 4.25rem);
  font-weight: 450;
  line-height: 1.04;
  letter-spacing: -0.032em;
}

.hero-lede {
  max-width: 36rem;
  margin-top: clamp(1rem, 2.8svh, 1.5rem);
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  line-height: 1.55;
  color: var(--color-secondary);
}

/* Spacing tightens on short screens so the ribbon still shows on the first screen */
.hero-actions {
  margin-top: clamp(1.5rem, 4.4svh, 2.25rem);
}

.hero-values {
  margin-top: clamp(1.25rem, 3.6svh, 2rem);
}

/* The outline button carries its own backing, so its label never sits directly on a line */
.hero-stage .hero-btn-quiet {
  background: rgba(10, 10, 10, 0.72);
}

.hero-stage .hero-btn-quiet:hover {
  background: #1f1f1f;
}

/* Phones and portrait screens: the ribbon takes the space left below the text. The live lines read
   the poster's box, so this one rule places both. */
@media (max-width: 767px), (max-aspect-ratio: 10/11) {
  .hero-stage {
    justify-content: flex-start;
    padding-bottom: 0;
  }

  .hero-band {
    position: relative;
    flex: 1 1 auto;
    min-height: clamp(8rem, 24svh, 16rem);
  }

  .hero-poster {
    inset: auto 0 calc((100% + 30px) / -15);
    height: calc((100% + 30px) / 0.75);
  }

  .hero-copy::before {
    bottom: -3rem;
    -webkit-mask-image:
      linear-gradient(to left, transparent, #000 9rem),
      linear-gradient(to top, transparent, #000 3rem);
    mask-image:
      linear-gradient(to left, transparent, #000 9rem),
      linear-gradient(to top, transparent, #000 3rem);
  }
}

/* The one-line subheading is for phones */
.hero-lede-short {
  display: none;
}

/* Below 1024px the header has its own Book a call button, so the hero keeps one booking prompt, not two */
@media (max-width: 1023px) {
  .hero-calendly {
    display: none;
  }
}

/* ---- Phones: one full screen. The headline at the top, the ribbon filling the screen behind it, and one
   gold action at the bottom within reach of a thumb. Each text block carries its own scrim, so the
   shader's fade under the text is switched off (--ribbon-cover). ---- */
@media (max-width: 767px) {
  .hero-stage {
    --ribbon-cover: none;
    --hero-scrim: color-mix(in srgb, var(--hero-ink) 72%, transparent);
    --hero-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E");
    padding-top: calc(var(--header-height) + clamp(1rem, 4svh, 2.5rem));
    padding-bottom: var(--space-5);
  }

  .hero-content,
  .hero-copy {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
  }

  /* The ribbon runs wider than the screen, so it keeps the proportions it has on a desktop: noise
     coming in low on the left, the twist in the middle and the wave rising behind the headline. */
  .hero-band {
    position: absolute;
    inset: -2% 0 10%;
    min-height: 0;
  }

  .hero-poster {
    inset: 0 auto 0 -35%;
    width: 165%;
    height: 100%;
  }

  .hero-copy::before {
    display: none;
  }

  .hero-title {
    font-size: clamp(2.25rem, min(12vw, 6.4svh), 3.5rem);
    line-height: 1.02;
  }

  .hero-lede {
    position: relative;
    max-width: 24rem;
    margin-top: var(--space-4);
    font-size: 1.125rem;
    line-height: 1.5;
  }

  .hero-lede-full {
    display: none;
  }

  .hero-lede-short {
    display: inline;
  }

  .hero-actions {
    position: relative;
    margin-top: auto;
    padding-top: var(--space-6);
    gap: var(--space-2);
  }

  .hero-values {
    display: none;
  }

  .hero-lede::before,
  .hero-actions::before {
    content: '';
    position: absolute;
    z-index: -1;
    left: -100vw;
    right: -100vw;
    pointer-events: none;
  }

  .hero-lede::before {
    top: -100svh;
    bottom: -4rem;
    background: linear-gradient(to top, transparent, var(--hero-scrim) 4rem);
  }

  .hero-actions::before {
    top: -2rem;
    bottom: -100svh;
    background: linear-gradient(to bottom, transparent, var(--hero-scrim) 4rem);
  }

  /* the second action is a quiet text link */
  .hero-stage .hero-btn-quiet,
  .hero-stage .hero-btn-quiet:hover,
  .hero-stage .hero-btn-quiet:active {
    align-self: flex-start;
    justify-content: flex-start;
    width: auto;
    min-height: 44px;
    padding: 0;
    border-color: transparent;
    background: transparent;
  }

  .hero-stage .hero-btn-quiet:hover {
    text-decoration: underline;
    text-decoration-color: var(--color-accent);
    text-underline-offset: 0.3em;
  }

  .hero-stage .hero-btn-quiet::after {
    content: '';
    flex: none;
    width: 1rem;
    height: 1rem;
    background: var(--color-accent);
    -webkit-mask: var(--hero-arrow) center / contain no-repeat;
    mask: var(--hero-arrow) center / contain no-repeat;
    transition: transform var(--transition-base);
  }

  .hero-stage .hero-btn-quiet:hover::after {
    transform: translateX(3px);
  }
}

/* a phone on its side is already wide, so the ribbon only spans the screen */
@media (max-width: 767px) and (orientation: landscape) {
  .hero-poster {
    left: 0;
    width: 100%;
  }
}

@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .hero-stage .hero-btn-quiet::after {
    transition: none;
  }

  .hero-stage .hero-btn-quiet:hover::after {
    transform: none;
  }
}

/* ---- Header over the hero ---- */
html:has(.hero-stage) .site-header {
  transition: background-color var(--transition-base), border-color var(--transition-base);
}

html:has(.hero-stage):not([data-hero-passed]) .site-header {
  background: color-mix(in srgb, var(--hero-ink) 72%, transparent);
  border-bottom-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

html:has(.hero-stage):not([data-hero-passed]) :is(.site-logo, .nav-links, .menu-toggle, .header-book) {
  --color-bg: var(--hero-ink);
  --color-text: #f7f7f5;
  --color-text-secondary: #d5d5d1;
  --color-border: rgba(255, 255, 255, 0.24);
  --color-hover: rgba(255, 255, 255, 0.1);
  --color-active: rgba(255, 255, 255, 0.16);
  --color-accent: var(--gold-tint);
}

/* The film after the hero, as part of the dark page rather than a player on it. The section is the film's own
   background colour, so the hero runs straight into it and the picture has no edge: it is feathered into the dark.
   Scrolling pins it under the header and grows it until it fills the screen, holds it there for a moment and lets
   go; below it the page fades from dark into the next section. The script only reports how far the growth has come
   (--film-e, 0 to 1) and where the picture sits; the look is here. Without a sticky stage (an old browser, or no
   script) it is the same dark band with the picture in it. There are no reduced-motion rules on purpose: the film
   and its growth are the same for everyone, and the pause button is always there. */

.promo-film {
  /* The film's own background: the colour of its rim over 30 frames of each cut of version 2 (mean #090908 and #0a0a09,
     median #080808; the open picture inside is #0a0a0a and the corners vignette down to #060606). The hero's is #0a0a0a,
     one step lighter, and the join between them is feathered. If the film is rendered again, measure it again. */
  --film-ink-rgb: 9 9 9;
  --film-ink: rgb(var(--film-ink-rgb));
  --film-ratio: 1.77778; /* 16:9; portrait screens get the 4:5 cut */
  --film-run-ratio: 1.25; /* how far the page scrolls while the film is pinned, in screens */
  --film-grow-from: 0.05; /* where in that scroll the growth starts and ends; the film holds after that */
  --film-grow-to: 0.72;
  --film-max-crop: 1.1; /* the most the full-screen picture may be cropped beyond fitting whole */

  /* Where the film draws its "Book a call" on the last card, as a share of the picture, and the size of its text in
     hundredths of the picture's width (measured on the last full frame of each cut, at 1920 and 1080 wide). The live
     button sits exactly over it. */
  --cta-x: 39.583%;
  --cta-y: 42.963%;
  --cta-w: 20.833%;
  --cta-h: 8.889%;
  --cta-font: 1.91;
  --cta-line: 0.0833; /* the outline, 1.6px of the film's 1920 */

  position: relative;
  background: var(--film-ink);
  color-scheme: dark;
}

@media (orientation: portrait) {
  .promo-film {
    --film-ratio: 0.8;
    --cta-x: 28.704%;
    --cta-y: 40%;
    --cta-w: 42.593%;
    --cta-h: 8%;
    --cta-font: 3.9;
    --cta-line: 0.148; /* 1.6px of the film's 1080 */
  }
}

/* a shorter pin on phones and upright screens */
@media (orientation: portrait), (max-width: 767px) {
  .promo-film {
    --film-run-ratio: 0.9;
  }
}

/* The hero's black runs on into the film's: the join is feathered, so not even a step of one in the colour shows */
.promo-film::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 5rem;
  background: linear-gradient(to bottom, var(--hero-ink, #0a0a0a), transparent);
  pointer-events: none;
}

.promo-film-view {
  position: relative;
  padding: clamp(2rem, 8vw, 5rem) var(--gutter);
}

/* The card holds its shape before anything loads, so nothing below it moves */
.promo-film-card {
  position: relative;
  width: 100%;
  max-width: 80rem;
  margin-inline: auto;
  aspect-ratio: var(--film-ratio);
}

.promo-film-frame {
  position: absolute;
  inset: 0;
  container-type: inline-size;
  background: var(--film-ink) center / cover no-repeat;
}

/* The film's own picture is a little darker than its background towards the corners (a vignette); this lifts anything
   darker than the page to the page's colour and leaves everything lighter alone, so the picture's edge has no ring */
.promo-film-floor {
  position: absolute;
  z-index: 1;
  inset: 0;
  background: var(--film-ink);
  mix-blend-mode: lighten;
  pointer-events: none;
}

/* No box: the picture's edges melt into the page in the film's own colour, in a soft eased fade that stays clear of
   the film's own margins (its words start 7% in). Where the picture runs off the screen the fade is off the screen too.
   It reaches 2px past the picture: where the picture sits between two pixels its last row is only partly drawn, and a
   fade that stopped at the same line would leave a fifth of the film's brightest line there as a hairline. */
.promo-film-frame::after {
  content: '';
  position: absolute;
  z-index: 2;
  inset: -2px;
  background:
    linear-gradient(to right, rgb(var(--film-ink-rgb)), rgb(var(--film-ink-rgb) / 0.85) 14%, rgb(var(--film-ink-rgb) / 0.5) 38%, rgb(var(--film-ink-rgb) / 0.17) 66%, transparent 100%) left / 8% 100% no-repeat,
    linear-gradient(to left, rgb(var(--film-ink-rgb)), rgb(var(--film-ink-rgb) / 0.85) 14%, rgb(var(--film-ink-rgb) / 0.5) 38%, rgb(var(--film-ink-rgb) / 0.17) 66%, transparent 100%) right / 8% 100% no-repeat,
    linear-gradient(to bottom, rgb(var(--film-ink-rgb)), rgb(var(--film-ink-rgb) / 0.85) 14%, rgb(var(--film-ink-rgb) / 0.5) 38%, rgb(var(--film-ink-rgb) / 0.17) 66%, transparent 100%) top / 100% 12% no-repeat,
    linear-gradient(to top, rgb(var(--film-ink-rgb)), rgb(var(--film-ink-rgb) / 0.85) 14%, rgb(var(--film-ink-rgb) / 0.5) 38%, rgb(var(--film-ink-rgb) / 0.17) 66%, transparent 100%) bottom / 100% 12% no-repeat;
  pointer-events: none;
}

/* While the picture is still a card its sides melt away further than they do once it fills the screen: the film's
   ribbons and sliding pages run off its sides, and this lets them go into the page instead of ending on a line. It lets
   go as the picture grows, so the words at the film's margins are at full strength on the big picture, and it keeps clear
   of the top, where the film sets its titles. */
.promo-film-veil {
  position: absolute;
  z-index: 2;
  inset: -2px;
  background:
    linear-gradient(to right, rgb(var(--film-ink-rgb)), rgb(var(--film-ink-rgb) / 0.9) 8%, rgb(var(--film-ink-rgb) / 0.6) 26%, rgb(var(--film-ink-rgb) / 0.3) 48%, rgb(var(--film-ink-rgb) / 0.1) 72%, transparent 100%) left / 15% 100% no-repeat,
    linear-gradient(to left, rgb(var(--film-ink-rgb)), rgb(var(--film-ink-rgb) / 0.9) 8%, rgb(var(--film-ink-rgb) / 0.6) 26%, rgb(var(--film-ink-rgb) / 0.3) 48%, rgb(var(--film-ink-rgb) / 0.1) 72%, transparent 100%) right / 15% 100% no-repeat;
  -webkit-mask-image: linear-gradient(to bottom, transparent 18%, #000 42%);
  mask-image: linear-gradient(to bottom, transparent 18%, #000 42%);
  opacity: calc(1 - var(--film-e, 0));
  pointer-events: none;
  will-change: opacity;
}

/* The poster arrives with the film, after the page has loaded, so it never competes with the hero */
.promo-film-frame[data-armed] {
  background-image: url('/video/maxwell-film-16x9.webp');
}

@media (orientation: portrait) {
  .promo-film-frame[data-armed] {
    background-image: url('/video/maxwell-film-4x5.webp');
  }
}

/* When the browser will not start the film by itself, the poster is shown over it, with a play button */
.promo-film-frame[data-blocked]::before {
  content: '';
  position: absolute;
  z-index: 1;
  inset: 0;
  background: inherit;
}

.promo-film-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The live "Book a call", laid over the one drawn on the film's last card. It covers the drawn one with the same
   fill, the same outline and the same gold, so the swap is a fade and nothing seems to change. Fill, outline and
   text colour were tuned until the difference between it and the drawn one, as the browser shows each, was as small as
   it gets (the film's own picture is softer than live text, so they are close, not equal). The drawn button's glow
   is part of the film and stays under the live one, so the live one adds none of its own. The outline is an inset ring
   rather than a border so that it can be a fraction of a pixel wide, as the drawn one is on most screens. Its size is a
   share of the picture's width, so it keeps its place at every size and while the picture grows. */
.promo-film-cta {
  position: absolute;
  z-index: 3;
  top: var(--cta-y);
  left: var(--cta-x);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--cta-w);
  height: var(--cta-h);
  padding-top: 0.1em; /* the drawn text sits a hair lower in its pill than centred text does */
  border: 0;
  border-radius: 999px;
  background: radial-gradient(ellipse 50% 73% at 50% 50%, rgb(50 43 16), rgb(44 38 14) 50%, rgb(30 25 11));
  box-shadow: inset 0 0 0 calc(var(--cta-line) * 1cqw) #c2af63;
  color: #d8be62;
  font-family: var(--font-sans);
  font-size: 1.1rem;
  font-size: calc(var(--cta-font) * 1cqw);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  animation: promo-film-cta-in 0.5s ease both;
  transition: color var(--transition-base), box-shadow var(--transition-base);
}

.promo-film-cta:hover {
  box-shadow:
    inset 0 0 0 calc(var(--cta-line) * 1cqw) #efcd64,
    0 0 2.4cqw rgba(201, 162, 39, 0.3);
  color: #f4de96;
}

@media (forced-colors: active) {
  .promo-film-cta {
    border: 1px solid ButtonText;
  }
}

.promo-film-cta:focus-visible {
  outline: 2px solid var(--gold-tint);
  outline-offset: 0.5cqw;
}

@keyframes promo-film-cta-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* Captions and buttons keep to the page, not to the picture: they neither grow with it nor sit on its feathered edge */
.promo-film-ui {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Captions in the site's own type, low and centred, clear of the controls in the top corner */
.promo-film-caption {
  position: absolute;
  left: 50%;
  bottom: clamp(1rem, 5svh, 2.5rem);
  width: max-content;
  max-width: min(44rem, 90%);
  margin: 0;
  transform: translateX(-50%);
  text-align: center;
  white-space: pre-line;
}

.promo-film-caption span {
  padding: 0.12em 0.45em;
  border-radius: var(--radius-sm);
  background: rgba(10, 10, 10, 0.8);
  color: #f7f7f5;
  font-size: clamp(0.875rem, 0.8rem + 0.4vw, 1.125rem);
  line-height: 1.75;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* On the page's right edge, like the hero's own pause button, clear of the captions */
.promo-film-controls {
  position: absolute;
  top: var(--space-4);
  right: max(var(--gutter), calc((100% - var(--container-width)) / 2 + var(--gutter)));
  display: flex;
  gap: var(--space-2);
  pointer-events: auto;
}

.promo-film-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: var(--radius-md);
  background: rgba(10, 10, 10, 0.72);
  color: #e6e6e3;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--transition-base), border-color var(--transition-base);
}

.promo-film-button:hover {
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.5);
}

.promo-film-button:focus-visible,
.promo-film-start:focus-visible {
  outline: 2px solid var(--gold-tint);
  outline-offset: 2px;
}

/* The sound button says what it does; gold until the visitor has heard the film, so it reads as the invitation */
.promo-film-sound {
  padding-inline: var(--space-3);
}

.promo-film-sound[data-invite] {
  border-color: rgba(201, 162, 39, 0.65);
}

.promo-film-sound[data-invite]:hover {
  border-color: var(--gold-tint);
}

/* After the film: a small, quiet way to see it again, never started by anything but a click */
.promo-film-button[data-again] {
  padding-inline: var(--space-3);
  border-color: rgba(255, 255, 255, 0.14);
  background: transparent;
  color: #b8b8b4;
}

.promo-film-button[data-again]:hover {
  border-color: rgba(255, 255, 255, 0.4);
  color: #ffffff;
}

.promo-film-start {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4.5rem;
  height: 4.5rem;
  padding: 0 0 0 0.2rem;
  border: 1px solid var(--gold-tint);
  border-radius: 50%;
  background: rgba(10, 10, 10, 0.72);
  color: var(--gold-tint);
  cursor: pointer;
  transform: translate(-50%, -50%);
  pointer-events: auto;
  transition: color var(--transition-base), border-color var(--transition-base), background-color var(--transition-base);
}

.promo-film-start:hover {
  border-color: var(--gold-tint-hover);
  background: rgba(10, 10, 10, 0.88);
  color: var(--gold-tint-hover);
}

/* a full 44px target for a thumb, and captions that are never below 16px */
@media (max-width: 1023px) {
  .promo-film-button {
    min-width: 2.75rem;
    height: 2.75rem;
  }
}

@media (max-width: 767px) {
  .promo-film-caption span {
    font-size: 1rem;
  }
}

/* Below the film the page fades from the film's dark into whatever follows, in the theme's own colour, rather than
   ending on an edge. The fade takes the place of the next section's top padding. */
.promo-film-fade {
  height: calc(var(--section-space) + clamp(2rem, 8svh, 5rem));
  background: linear-gradient(to bottom, var(--film-ink), var(--color-bg));
  background: linear-gradient(
    to bottom,
    var(--film-ink) 0%,
    color-mix(in srgb, var(--color-bg) 4%, var(--film-ink)) 20%,
    color-mix(in srgb, var(--color-bg) 20%, var(--film-ink)) 40%,
    color-mix(in srgb, var(--color-bg) 55%, var(--film-ink)) 60%,
    color-mix(in srgb, var(--color-bg) 90%, var(--film-ink)) 80%,
    var(--color-bg) 100%
  );
}

.promo-film + .section {
  padding-top: 0;
}

/* ---- The pin ----
   Needs a sticky stage that can work, so it is only built where the browser has everything it takes. Elsewhere
   the picture in its dark band, above, is the whole story. */
@media (scripting: enabled) {
  @supports (overflow: clip) and (height: 100lvh) and (container-type: size) and selector(:has(*)) {
    /* The page's body hides sideways overflow, which makes it a scroll container, and nothing sticks inside one.
       Clipping hides the same overflow without becoming a scroll container; the window still does the scrolling. */
    body:has(.promo-film-track) {
      overflow-x: clip;
    }

    /* The runway: the stage pins for as long as it takes the page to scroll this far. Its height is set in screens
       (the large one, so a phone's collapsing toolbar never shows what is behind) plus the distance of the pin. */
    .promo-film-track {
      position: relative;
      height: calc(100lvh - var(--header-height) + 100svh * var(--film-run-ratio));
    }

    .promo-film-stage {
      position: sticky;
      top: var(--header-height);
      height: calc(100lvh - var(--header-height));
      overflow: clip;
    }

    /* What a visitor is certain to see, with a phone's toolbars out: the picture fills this, never the stage below it */
    .promo-film-view {
      height: calc(100svh - var(--header-height));
      padding: 0;
      overflow: clip;
    }

    /* The picture starts as the biggest 16:9 (or 4:5) box that fits in the dark with room round it */
    .promo-film-slot {
      display: grid;
      place-items: center;
      height: 100%;
      padding: clamp(0.75rem, 6svh, 3.5rem) clamp(1rem, 7vw, 7rem);
      container-type: size;
    }

    .promo-film-card {
      width: min(100cqw, calc(100cqh * var(--film-ratio)));
      max-width: none;
      margin-inline: 0;
    }
  }
}

