/* Player: Vimeo lightbox (a modal <dialog>). On preview hosts the play links
   open Vimeo in a new tab instead, so this never shows there.
   Cream since r6: an opaque cream backdrop, navy controls, the orange quote
   button, and a paper box while the video loads. The film's own pixels are
   untouched. Since r7, when Vimeo's player doesn't come, the box shows the
   poster with a link to the film on Vimeo, never a black frame. */

.player {
  /* The frame is the largest 16:9 that fits between the page gutters and
     leaves room for the title bar above it and the foot below, up to 2400 px
     wide. --player-chrome is everything in the dialog that isn't the frame:
     player.js measures it when the player opens and on resize; the value here
     is the first guess. The dialog is the frame plus the gutters, and at least
     40rem wide where the screen allows, so the title, Close and the quote
     button keep one row each. Short landscape screens (a phone turned
     sideways) put those in a column beside the frame instead, see the end
     of this file. */
  --player-pad-y: clamp(var(--space-4), 3dvh, var(--space-7));
  --player-gutters: calc(var(--gutter-l) + var(--gutter-r));
  --player-chrome: calc(2 * var(--size-control) + 2 * var(--space-4) + 2 * var(--player-pad-y));
  --player-frame-w: max(160px, min(100vw - var(--player-gutters), (100dvh - var(--player-chrome)) * 16 / 9, 2400px));
  width: min(100vw, max(var(--player-frame-w) + var(--player-gutters), 40rem));
  max-width: 100vw;
  max-height: 100dvh;
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text);
  color-scheme: light;
  overflow: visible;
  /* Sizes change with the screen and the measured chrome, never animated
     (reduced motion gives every property a short transition otherwise). */
  transition-property: none;
}
.player::backdrop {
  /* Solid cream (r6; it was solid ink). Opaque because at 0.94 the page's
     headline and chips ghosted through behind the title bar and the foot,
     and still did faintly at 0.975. */
  background: var(--color-bg);
}
.player[open] { animation: player-in 420ms var(--motion-ease-out-expo) both; }
.player[open]::backdrop { animation: player-fade 320ms var(--ease-out) both; }
@keyframes player-in { from { opacity: 0; transform: translateY(14px) scale(0.985); } }
@keyframes player-fade { from { opacity: 0; } }

.player__inner {
  display: grid;
  gap: var(--space-4);
  padding: var(--player-pad-y) var(--gutter-r) var(--player-pad-y) var(--gutter-l);
}
.player__bar { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); }
.player__close svg { width: 16px; height: 16px; }
.player__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: var(--player-frame-w);
  max-width: 100%;
  margin-inline: auto;
  /* Paper with a navy hairline while the film loads, never a black box. */
  background: var(--color-bg-media);
  box-shadow: 0 0 0 1px var(--line-panel);
  border-radius: var(--radius-media);
  overflow: hidden;
  transition-property: none;
}
.player__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; transition: opacity 320ms var(--ease-out); }
/* While the film loads (player.js): the iframe stays hidden, since Vimeo's
   page is black until it draws, and a thin navy line runs across the middle
   of the paper box, the preloader's line in small. player.js also makes the
   hidden iframe inert with tabindex -1, so it takes no focus or clicks. */
.player__frame.is-loading iframe,
.player__frame.is-fallback iframe { opacity: 0; }
.player__frame.is-loading::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(30%, 200px);
  height: 2px;
  margin: -1px 0 0 calc(min(30%, 200px) / -2);
  border-radius: 2px;
  background: linear-gradient(90deg, var(--gist-navy), var(--gist-navy)) 0 0 / 40% 100% no-repeat, rgb(var(--gist-navy-rgb) / 0.14);
  animation: player-loading 1100ms var(--motion-ease-in-out) infinite alternate;
}
@keyframes player-loading { from { background-position: 0 0, 0 0; } to { background-position: 100% 0, 0 0; } }
/* Reduced motion: the line holds still (motion.css cuts every animation to
   1 ms, which on a looping one would flicker). */
@media (prefers-reduced-motion: reduce) {
  .player__frame.is-loading::after { animation: none !important; background-position: 50% 0, 0 0; }
}
/* No player (r7). Vimeo can't be reached, hasn't said it's ready after 5 s,
   or said it can't play the film here. The box shows the film's poster on
   its paper ground, and the whole poster is a link to the film on Vimeo (a
   new tab), like a poster on Work. A paper tag with navy words sits in the
   middle; pointed at or focused it turns into the orange button with an ink
   label, like the Play tag. No scrim and no shadow. If Vimeo turns up late
   and draws, the film takes the poster's place. */
.player__fallback {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--color-bg-media);
  animation: player-fade 320ms var(--ease-out) both;
}
.player__fallback[hidden] { display: none; }
.player__fallback img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.player__vimeo {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  color: var(--color-text);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
/* The ring sits just inside the box's edge (it clips), navy with a cream
   band inside it, as on the Work posters. */
.player__vimeo:focus-visible { --focus-offset: -3px; outline-width: 3px; box-shadow: inset 0 0 0 6px var(--gist-cream); }
.player__vimeo-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.75em;
  min-height: var(--size-control);
  padding: 0 var(--space-control-x) 0 var(--space-5);
  border-radius: var(--radius-control);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: 0 0 0 1px var(--line-panel);
  font-family: var(--type-label-family);
  font-weight: var(--type-label-weight);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-tracking);
  text-transform: var(--type-label-case);
  line-height: 1;
  white-space: nowrap;
  transition: background-color var(--hover) var(--ease-out), color var(--hover) var(--ease-out), box-shadow var(--hover) var(--ease-out);
}
.player__vimeo-tag svg { width: 16px; height: 16px; flex: none; }
.player__vimeo-ext { display: inline-flex; margin-left: -0.25em; }
.player__vimeo-ext svg { width: 12px; height: 12px; }
/* Phones: the Play tag's size from Work (44 px, small label), so the tag
   doesn't cover most of a 320 px box. */
@media (max-width: 520px) {
  .player__vimeo-tag {
    min-height: var(--size-touch-min);
    padding: 0 var(--space-4) 0 var(--space-3);
    font-size: var(--type-label-small-size);
    letter-spacing: var(--type-label-small-tracking);
  }
}
@media (hover: hover) {
  .player__vimeo:hover .player__vimeo-tag { background: var(--color-action); color: var(--color-on-action); box-shadow: 0 0 0 1px var(--color-action); }
}
.player__vimeo:focus-visible .player__vimeo-tag { background: var(--color-action); color: var(--color-on-action); box-shadow: 0 0 0 1px var(--color-action); }
.player__foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-3) var(--space-6); }
.player__title { font-size: var(--type-heading-4-size); font-weight: 600; }

/* Short landscape screens (a phone turned sideways). Chrome above and below
   the frame took most of the height there and left a small video (408x230 on
   an 844x390 phone, 226x127 on 568x320). Here the frame takes the full
   height on the left, and Close, the title, the meta and the quote button
   stack in a column on its right: Close at the top, the title and meta under
   it, the button level with the frame's bottom edge, with the short label
   "Get a quote". player.js still
   measures --player-chrome; this layout doesn't use it. */
@media (orientation: landscape) and (max-height: 480px) {
  .player {
    /* At least 11rem, so the short label "Get a quote" and its arrow fit on one
       line (10rem split it "Get a / quote" on 568 to 640 wide phones). */
    --player-side: clamp(11rem, 27vw, 16rem);
    --player-col-gap: var(--space-5);
    --player-frame-w: max(160px, min(100vw - var(--player-gutters) - var(--player-side) - var(--player-col-gap), (100dvh - 2 * var(--player-pad-y)) * 16 / 9, 2400px));
    width: min(100vw, var(--player-frame-w) + var(--player-col-gap) + var(--player-side) + var(--player-gutters));
  }
  .player__inner {
    grid-template-columns: var(--player-frame-w) var(--player-side);
    grid-template-rows: auto minmax(0, 1fr);
    column-gap: var(--player-col-gap);
    row-gap: var(--space-4);
  }
  .player__frame { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
  .player__bar { grid-column: 2; grid-row: 1; flex-direction: column-reverse; align-items: flex-start; justify-content: flex-start; gap: var(--space-2); }
  .player__close { align-self: flex-end; margin-right: calc(-1 * var(--space-3)); }
  .player__foot { grid-column: 2; grid-row: 2; align-self: stretch; flex-direction: column; flex-wrap: nowrap; align-items: stretch; justify-content: space-between; gap: var(--space-4); }
  .player__foot .btn { white-space: normal; text-wrap: balance; text-align: left; justify-content: space-between; line-height: 1.25; padding: var(--space-3) var(--space-4); }
  /* The column is 176 to 256 px wide, and the full label stacked three or four
     lines deep there. It reads "Get a quote" (the nav's own words); the video
     beside it says what "like this" means. */
  .player__quote-more { display: none; }
}
