@layer components {
  /* The film page. Narrow measure, the film itself given room, everything
     else deferential to it. */
  .project {
    max-width: 68rem;
    margin-inline: auto;
    padding: clamp(2rem, 6vw, 4.5rem) var(--gutter) var(--rhythm);
  }

  .project__head { margin-bottom: clamp(1.25rem, 3vw, 2rem); }

  .project__h {
    font-family: var(--font-display);
    font-weight: var(--display-wght);
    font-variation-settings: 'wdth' var(--display-wdth);
    font-size: clamp(1.75rem, 1rem + 3vw, 3.5rem);
    line-height: 1.02;
    letter-spacing: var(--display-tracking);
  }
  .project__client {
    color: var(--ink-quiet);
    font-size: .9375rem;
    margin-top: .5rem;
  }

  .project__media { background: var(--surface-2); }

  /* A vertical film's box is narrower than the page, and --surface-2 behind it
     read as two grey bars bracketing the film for no reason. The film's own
     black frame is the frame; either world's ground is a better surround. */
  .project__media:has(.project__frame--film.project__frame--portrait) {
    background: none;
  }

  /* An iframe has no intrinsic ratio, so it needs one given to it or it
     collapses to a default 150px tall. */
  .project__embed {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
  }

  .project__frame { position: relative; overflow: clip; }

  .project__poster {
    position: relative;
    width: 100%;
    height: auto;
    /* A vertical still would otherwise be taller than the screen and push
       everything below it out of sight. */
    max-height: 78svh;
    object-fit: contain;
    margin-inline: auto;
  }

  /* A portrait still leaves wide gaps at the sides. Rather than flat grey,
     it stands on a blurred enlargement of itself — the same answer the world
     hero gives to the same problem. */
  .project__frame--portrait { display: grid; }
  .project__frame--portrait > * { grid-area: 1 / 1; }

  .project__backdrop {
    width: 100%; height: 100%;
    object-fit: cover;
    scale: 1.16;
    filter: blur(40px) saturate(.35) brightness(.26);
  }
  .project__frame--portrait .project__poster {
    filter: drop-shadow(0 18px 45px rgb(0 0 0 / .55));
  }

  /* ---- the film itself ---------------------------------------------- */

  /* A box of the film's own shape, declared in CSS rather than taken from
     whatever image happens to be the poster — the same approach the delivery
     player takes. Nothing here moves when the video's metadata arrives. */
  .project__frame--film {
    aspect-ratio: 16 / 9;
    background: #000;
  }
  .project__frame--film.project__frame--portrait {
    aspect-ratio: 9 / 16;
    /* A vertical film at full width would be taller than the screen and push
       the write-up out of sight, so it stands in the middle at its own size.
       Same ceiling as the delivery player, for the same reason. */
    max-height: 70svh;
    width: auto;
    margin-inline: auto;
  }

  .project__video {
    display: block;
    width: 100%;
    height: 100%;
    /* contain, not cover: a film is never cropped. */
    object-fit: contain;
  }

  /* The play mark sits over the poster and leaves with the first frame. Only
     while .is-idle, which script adds — with scripting off the native control
     bar is showing instead and a second button would be two play buttons. */
  .project__play {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    gap: .75rem;
    justify-items: center;
    /* No plate over the poster: the mark and the label carry themselves, and
       a scrim would flatten the still this page exists to show. */
    background: none;
    border: 0;
    color: var(--ink-on-media);
    cursor: pointer;
    /* The still is the subject; the control is legible over it without
       dimming it, by way of the shadow on the mark below. */
    text-shadow: 0 1px 12px rgb(0 0 0 / .65);
  }

  .play-mark {
    width: clamp(3.5rem, 8vw, 5.5rem);
    height: auto;
    filter: drop-shadow(0 6px 24px rgb(0 0 0 / .55));
  }
  .play-mark__ring {
    fill: none;
    stroke: currentColor;
    stroke-width: 3;
    opacity: .85;
  }
  .play-mark__tri { fill: var(--accent); }

  .project__play-label {
    font-family: var(--font-body);
    font-size: .9375rem;
    letter-spacing: .01em;
  }
  .project__play-clock {
    font-size: .8125rem;
    font-variant-numeric: tabular-nums;
    opacity: .7;
  }

  /* One state change on a real action, not an ambient effect: the ring tightens
     and the triangle takes the accent forward. */
  @media (hover: hover) {
    .project__play:hover .play-mark__ring,
    .project__play:focus-visible .play-mark__ring { opacity: 1; stroke-width: 4; }
    .project__play:hover .play-mark__tri { scale: 1.08; }
    .play-mark__tri { transform-origin: center; transition: scale .18s ease-out; }
    .play-mark__ring { transition: opacity .18s ease-out, stroke-width .18s ease-out; }
  }
  @media (prefers-reduced-motion: reduce) {
    .play-mark__tri, .play-mark__ring { transition: none; }
  }

  .project__play:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -6px;
  }

  .project__body { margin-top: clamp(1.5rem, 4vw, 2.5rem); }

  .project__back {
    margin-top: clamp(2rem, 5vw, 3.5rem);
    padding-top: 1.25rem;
    border-top: 1px solid var(--rule);
    font-size: .9375rem;
  }
  .project__back a { border-bottom: 1px solid var(--rule); }
  .project__back a:hover { color: var(--accent); border-bottom-color: var(--accent); }
}
