/* The home page hero: the scan film (js/hero-film.js) full bleed under a 30% scrim, the copy at the
   left margin, a status line, the note and the pause control along the bottom.
   Layers, bottom to top: the poster, the film's canvas, the scrim, the HUD canvas, the copy.
   The poster paints first; the film fades in over it once its first frame is drawn. Reduced motion,
   no WebGL or no script: the poster and the whole headline, nothing moving.
   Sizes come from the design system's tokens (css/cantic.css); the fallbacks are the same values,
   for a page without it. */

.film {
  --film-ease: cubic-bezier(.22, 1, .36, 1);
  --film-margin: clamp(20px, 5.556vw, 107px);
  --film-mono: var(--mono, 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace);
  --film-sans: var(--sans, 'Geist', 'Helvetica Neue', Arial, sans-serif);
  --film-signal: var(--signal, #ff4d2e);
  --film-btn-h: var(--btn-h, clamp(40px, 2.778vw, 53.33px));
  --film-fs-button: var(--fs-button, clamp(15px, 1.042vw, 20px));
  --film-radius: var(--radius, 5px);
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: 1fr auto;
  height: 100vh;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  background: #000;
  color: #fff;
}

.film__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #000;
}

.film__poster,
.film__poster img,
.film__gl,
.film__hud,
.film__scrim {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.film__poster img {
  object-fit: cover;
}

.film__gl,
.film__hud {
  opacity: 0;
  transition: opacity .6s var(--film-ease);
  pointer-events: none;
}

.film.is-live .film__gl,
.film.is-live .film__hud {
  opacity: 1;
}

/* Lost context, or held on the poster by the quality governor: Safari keeps showing a lost
   canvas's last picture, so it is hidden, not just faded. */
.film.is-lost .film__gl,
.film.is-lost .film__hud,
.film.is-held .film__gl,
.film.is-held .film__hud,
.film.is-still .film__gl,
.film.is-still .film__hud {
  opacity: 0;
  visibility: hidden;
}

/* A 30% black scrim, darker towards the copy on the left (towards the top on portrait screens) and
   along the top, under the header. The film is bright (about 30 of 255 on average), so the copy keeps
   a dark ground of its own: the darker part reaches past the right end of the sub-line's lines
   (about 56% of the width) and of the longer Spanish headline, so the brightest points that pass
   behind them still leave 4.5:1 for the sub-line and 3:1 for the headline. */
.film__scrim {
  background:
    linear-gradient(180deg, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, 0) 18%),
    linear-gradient(90deg, rgba(0, 0, 0, .74) 0%, rgba(0, 0, 0, .68) 30%, rgba(0, 0, 0, .6) 48%, rgba(0, 0, 0, .42) 62%, rgba(0, 0, 0, 0) 78%),
    rgba(0, 0, 0, .3);
}

@media (max-aspect-ratio: 4/5) {
  .film__scrim {
    background:
      linear-gradient(180deg, rgba(0, 0, 0, .74) 0%, rgba(0, 0, 0, .68) 52%, rgba(0, 0, 0, .2) 68%, rgba(0, 0, 0, 0) 78%),
      rgba(0, 0, 0, .3);
  }
}

/* The copy */

.film__copy {
  position: relative;
  z-index: 1;
  align-self: center;
  padding: 72px var(--film-margin) 24px;
  max-width: 1920px;
}

.film__eyebrow {
  margin: 0 0 8px;
  font: 400 12px/1.2 var(--film-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .78);
}

.film__eyebrow-short {
  display: none;
}

.film__title {
  position: relative;
  max-width: 15em;
  margin: 0;
  font: 400 clamp(36px, 4.444vw, 85.33px)/1.08 var(--film-sans);
  letter-spacing: -.03em;
  text-wrap: balance;
  -webkit-text-stroke: .1px rgba(0, 0, 0, .5);
}

.film__lead {
  max-width: 30em;
  margin: clamp(16px, 1.667vw, 32px) 0 0;
  font: 400 clamp(19px, 1.667vw, 32px)/1.45 var(--film-sans);
  letter-spacing: -.015em;
  color: rgba(255, 255, 255, .86);
  text-wrap: pretty;
}

.film__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  margin-top: clamp(24px, 2.222vw, 42px);
}

/* The button and the link take the design system's sizes (its .btn and .tlink): the button's
   height, text and corners, and a hit area of at least 44 px for both. */
:where(.film) .film__btn {
  position: relative;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--film-btn-h);
  padding: 0 clamp(16px, 1.111vw, 21.33px);
  border: 1px solid #fff;
  border-radius: var(--film-radius);
  background: #fff;
  color: #000;
  font: 400 var(--film-fs-button)/1.1 var(--film-sans);
  letter-spacing: -.01em;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color .3s var(--film-ease), color .3s var(--film-ease);
}

:where(.film) .film__link {
  position: relative;
  color: #fff;
  font: 400 var(--film-fs-button)/1.4 var(--film-sans);
  letter-spacing: -.01em;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

:where(.film) .film__btn::after,
:where(.film) .film__link::after {
  content: '';
  position: absolute;
  inset: min(0px, calc(50% - 22px)) 0;
}

@media (hover: hover) {
  :where(.film) .film__btn:hover {
    background: transparent;
    color: #fff;
  }

  :where(.film) .film__link:hover {
    text-decoration-thickness: 2px;
  }
}

/* The small print under the actions, on a page whose hero tells a client case (the food page): the
   track record's line on how the engagements are recorded. */
.film__fine {
  max-width: 44em;
  margin: 18px 0 0;
  font: 400 clamp(13px, .833vw, 16px)/1.45 var(--film-sans);
  color: rgba(255, 255, 255, .66);
}

/* The industry picker (js/picker.js), on the actions' row on wide screens and on a line of its own on
   phones: a field as tall as the button, its label inside it in the film's mono until something is
   typed, and a menu of the nine industries that opens under it (the script moves the menu to the end
   of the page, so the hero never clips it). Hidden without the script: the menu lists the same pages. */
.pick {
  position: relative;
  flex: 0 1 300px;
  min-width: 240px;
}

html:not(.js) .pick {
  display: none;
}

.pick__box {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  height: var(--film-btn-h);
  border: 1px solid rgba(255, 255, 255, .34);
  border-radius: var(--film-radius);
  background: rgba(0, 0, 0, .55);
  transition: border-color .3s var(--film-ease), background-color .3s var(--film-ease);
}

.pick__box:focus-within,
.pick.is-open .pick__box {
  border-color: #fff;
  background: rgba(0, 0, 0, .78);
}

@media (hover: hover) {
  .pick__box:hover {
    border-color: rgba(255, 255, 255, .7);
  }
}

.pick__icon {
  flex: none;
  width: 18px;
  height: 18px;
  margin-left: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  color: rgba(255, 255, 255, .78);
  pointer-events: none;
}

/* the label sits where the words will be typed, and gives way to them */
.pick__label {
  position: absolute;
  left: 40px;
  right: 40px;
  top: 50%;
  overflow: hidden;
  font: 400 12px/1.2 var(--film-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: rgba(255, 255, 255, .78);
  transform: translateY(-50%);
  pointer-events: none;
  transition: opacity .2s var(--film-ease);
}

.pick.has-value .pick__label {
  opacity: 0;
}

.pick__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  margin: 0;
  padding: 0 4px 0 10px;
  border: 0;
  background: transparent;
  color: #fff;
  font: 400 var(--film-fs-button)/1.2 var(--film-sans);
  letter-spacing: -.01em;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.pick__open {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: rgba(255, 255, 255, .78);
  cursor: pointer;
}

.pick__open .icon {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  transition: transform .3s var(--film-ease);
}

.pick.is-open .pick__open .icon {
  transform: rotate(180deg);
}

/* the menu: black, in the film's frame, an industry a line; the active one carries the red node */
.pick__list {
  --pick-ease: cubic-bezier(.22, 1, .36, 1);
  position: absolute;
  z-index: 60;
  box-sizing: border-box;
  max-height: min(60vh, 432px);
  margin: 0;
  padding: 6px;
  overflow: auto;
  overscroll-behavior: contain;
  list-style: none;
  border: 1px solid rgba(255, 255, 255, .26);
  border-radius: var(--radius, 5px);
  background: #0b0b0b;
  box-shadow: 0 18px 48px rgba(0, 0, 0, .55);
  color: #fff;
  font: 400 clamp(16px, 1.042vw, 20px)/1.3 var(--sans, 'Geist', 'Helvetica Neue', Arial, sans-serif);
  letter-spacing: -.01em;
}

.pick__list[hidden] {
  display: none;
}

.pick__option {
  position: relative;
  padding: 11px 12px 11px 30px;
  border-radius: 3px;
  cursor: pointer;
}

.pick__option[hidden] {
  display: none;
}

.pick__option::before {
  content: '';
  position: absolute;
  left: 12px;
  top: 50%;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .34);
  transition: background-color .15s var(--pick-ease);
}

.pick__option[aria-selected='true'] {
  background: rgba(255, 255, 255, .1);
}

.pick__option[aria-selected='true']::before {
  background: var(--signal, #ff4d2e);
}

.pick__empty {
  padding: 11px 12px;
  color: rgba(255, 255, 255, .72);
}

.pick__empty a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Until the typing starts, the headline is held back (hidden, so it keeps its space), so it never shows
   in full and is then typed again. If the script never runs, it shows after four seconds anyway. */
.js .film:not(.is-typed) .film__title[data-film-type]:not(.is-typing) {
  animation: film-title-wait 0s 4s both;
}

@keyframes film-title-wait {
  from {
    visibility: hidden;
  }

  to {
    visibility: visible;
  }
}

/* The typed headline: the letters are hidden, not removed, so nothing below it moves. */
.film__title.is-typing .film__ch {
  visibility: hidden;
}

.film__title.is-typing .film__ch.on {
  visibility: visible;
}

.film__caret {
  position: absolute;
  top: 0;
  left: 0;
  width: .3em;
  pointer-events: none;
  transition: opacity .4s var(--film-ease);
}

.film__caret::after {
  content: '';
  position: absolute;
  top: 60%;
  left: .1em;
  width: .15em;
  height: .15em;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
}

.film__title.is-typed .film__caret {
  opacity: 0;
}

/* The copy under the headline fades in, once, as soon as the headline starts typing (is-started, set
   by js/hero-film.js). If the script never runs, it fades in after four seconds anyway. */
.js .film [data-film-rise] {
  animation: film-show .6s var(--film-ease) 4s both;
}

.js .film:is(.is-started, .is-typed) [data-film-rise] {
  animation: film-fade .6s var(--film-ease) var(--rise, 0s) both;
}

/* film-show's twin under another name, so the fade starts afresh rather than mid-way through the
   fallback's clock */
@keyframes film-fade {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes film-show {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* The bottom row: the status line, the note and the pause control. */
.film__foot {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
  padding: 0 var(--film-margin) 28px;
  font: 400 12px/1.4 var(--film-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
}

/* It sits on a dark band that fades out above it, so its 12 px type keeps 4.5:1 over the
   brightest points of the film and the poster. */
.film__foot::before {
  content: '';
  position: absolute;
  inset: -56px 0 0;
  z-index: -1;
  background: linear-gradient(0deg, rgba(0, 0, 0, .66), rgba(0, 0, 0, .6) calc(100% - 56px), rgba(0, 0, 0, 0));
  pointer-events: none;
}

.film__status {
  margin: 0;
  max-width: 62em;
}

.film__status a {
  position: relative;
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* a 44 px target round the 12 px link */
.film__status a::after {
  content: '';
  position: absolute;
  inset: calc(50% - 22px) 0;
}

.film__status::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: 0 10px 1px 0;
  border-radius: 50%;
  background: var(--film-signal);
  vertical-align: middle;
}

.film__aside {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-left: auto;
}

.film__note {
  margin: 0;
}

.film__toggle {
  box-sizing: border-box;
  min-width: 44px;
  height: 44px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, .34);
  border-radius: var(--film-radius);
  background: transparent;
  color: #fff;
  font: inherit;
  letter-spacing: inherit;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .3s var(--film-ease), color .3s var(--film-ease), border-color .3s var(--film-ease);
}

/* a tap would leave the white fill stuck on a touch screen */
@media (hover: hover) {
  .film__toggle:hover {
    border-color: #fff;
    background: #fff;
    color: #000;
  }
}

.film__toggle:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.film__toggle[hidden] {
  display: none;
}

/* without the script nothing moves, so there is nothing to pause */
html:not(.js) .film__toggle {
  display: none;
}

/* The description of the illustration and the pause control's spoken state: for screen readers. */
.film__desc,
.film__said {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Phones and portrait screens (the film's portrait framing, js/hero-film.js): the copy at the top,
   the film's subjects framed low in the band beneath it. */
@media (max-width: 767px), (max-aspect-ratio: 4/5) {
  .film {
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: 100vh;
    min-height: 100svh;
  }

  /* The scrim's dark top is a share of the hero's height, but the copy's length is not (the Spanish
     sub-line takes a line more): where the copy ends, its last lines (the button and the link) get
     a dark ground of their own, which fades out in the space left for the film's subjects. */
  .film__copy {
    --film-room: clamp(130px, 19svh, 210px);
    align-self: stretch;
    padding-top: 76px;
    background: linear-gradient(180deg,
      rgba(0, 0, 0, 0) calc(100% - var(--film-room) - 150px),
      rgba(0, 0, 0, .42) calc(100% - var(--film-room) - 50px),
      rgba(0, 0, 0, .42) calc(100% - var(--film-room)),
      rgba(0, 0, 0, 0) calc(100% - var(--film-room) + 90px));
  }

  .film__copy::after {
    content: '';
    display: block;
    height: var(--film-room);
  }

  .film__foot {
    margin-top: auto;
  }

  /* the portrait poster's subjects are low in its frame; a hero wider than 2:3 crops its top */
  .film__poster img {
    object-position: 50% 100%;
  }
}

/* touch screens: 44 px buttons, as everywhere in the design system */
@media (pointer: coarse) {
  .film {
    --film-btn-h: var(--btn-h, 44px);
  }
}

@media (max-width: 767px) {
  .film__eyebrow-long {
    display: none;
  }

  /* the industries line: two groups, one per line, so no separator is left at a line's end */
  .film__eyebrow-group {
    display: block;
  }

  .film__eyebrow-sep {
    display: none;
  }

  .film__eyebrow-short {
    display: inline;
  }

  .film__actions {
    gap: 12px 20px;
  }

  .pick {
    flex: 1 1 100%;
    min-width: 0;
  }
}

@media (pointer: coarse) {
  .pick__input {
    font-size: max(16px, var(--film-fs-button));
  }
}

/* The poster script and the storyboard: the film alone, or held on one frame. */
.film.is-poster .film__scrim,
.film.is-poster .film__copy,
.film.is-poster .film__foot {
  display: none;
}

.film.is-poster .film__gl,
.film.is-held-frame .film__gl,
.film.is-held-frame .film__hud {
  transition: none;
}

.film__meter {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 100;
  margin: 0;
  padding: 6px 8px;
  background: rgba(0, 0, 0, .78);
  color: #b8f5c4;
  font: 400 12px/1.4 var(--mono, ui-monospace, Menlo, monospace);
  white-space: pre;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .film__gl,
  .film__hud,
  .film__caret,
  :where(.film) .film__btn,
  .film__toggle {
    transition: none;
  }

  .js .film [data-film-rise],
  .js .film:is(.is-started, .is-typed) [data-film-rise] {
    animation: none;
  }
}

/* Shown at once, and kept: once the copy has risen (is-risen, set by js/hero-film.js), pausing and
   playing never start the rise again. */
.js .film.is-paused [data-film-rise],
.js .film.is-risen [data-film-rise],
.js .film.is-still [data-film-rise],
.js .film.is-held-frame [data-film-rise] {
  animation: none;
}
