/* ============================================================
   Project pages (project.html). One template, six worlds: the
   colours come from each video's thumbnail (data.js
   PROJECT_PAGES), and so does the scenery (js/scenes.js).
   Page order: hero, player, numbers, story, more work, footer.
   ============================================================ */

body.pp {
  background: linear-gradient(to bottom, var(--tone-sky) 0, var(--tone-bg) 115svh) no-repeat, var(--tone-bg);
  color: var(--tone-ink);
}
.pp ::selection { background: var(--accent); color: var(--tone-deep); }
.pp :focus-visible { outline-color: var(--pop); }
.pp .eyebrow { color: color-mix(in srgb, var(--tone-ink) 58%, transparent); }
.pp .railtext { color: color-mix(in srgb, var(--tone-ink) 40%, transparent); }
.pp main .btn { --btn-bg: var(--tone-ink); --btn-fg: var(--tone-bg); }

/* the scenery: one canvas fixed behind the whole page, under the footer */
.pfx { position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
/* Scenery reaches past the sides (orbits, eyes, clouds). body's own clip
   is handed to the viewport, which phones still let you pan, so main clips
   sideways itself. Only sideways: the front clouds still hang downward. */
.pp main { position: relative; z-index: 1; overflow-x: clip; }

/* ---- the painted world (js/backdrop.js) ----
   One painting behind the hero, under the scenery canvas and above the
   page's flat colour, which it dissolves into at the foot. It is drawn a
   touch large (js/backdrop.js OVER) so its pointer drift never shows an
   edge, and it settles from larger still as it fades in. No mask and no
   filter here: the bar's glass blurs this, and the picture moves under the
   scroll, so everything on it has to stay a plain composited layer. */
body.pp--painted {
  background: linear-gradient(to bottom, var(--tone-sky) 0, var(--tone-bg) min(100svh, 66rem)) no-repeat, var(--tone-bg);
}
.pbg {
  position: absolute;
  inset: 0 0 auto;
  z-index: 0;
  height: min(118svh, 78rem);
  overflow: hidden;
  pointer-events: none;
}
.pbg__pic {
  position: absolute;
  inset: 0;
  display: block;
  opacity: 0;
  scale: 1.1;
  translate: calc(var(--px, 0) * -7px) calc(var(--py, 0) * -5px + var(--sy, 0) * 1px);
  transition: opacity 800ms ease, scale 1800ms cubic-bezier(.2,.7,.2,1);
}
.pbg.is-in .pbg__pic { opacity: 1; scale: 1.04; }
.pbg__img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: var(--at); transform-origin: var(--at); scale: var(--zoom, 1); }
@media (max-aspect-ratio: 4/5) { .pbg__img { object-position: var(--at-tall); transform-origin: var(--at-tall); scale: var(--zoom-tall, 1); } }

/* what gathers behind the copy: night in a dark world, haze in a light one */
.pbg__pool {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, color-mix(in srgb, var(--zenith, transparent) 88%, transparent), color-mix(in srgb, var(--zenith, transparent) 40%, transparent) 7%, transparent 17%),
    radial-gradient(ellipse 44% 30% at var(--pool-x, 50%) 41%, color-mix(in srgb, var(--pool) var(--pool-k), transparent), transparent);
  opacity: 0;
  transition: opacity 800ms ease;
}
.pbg.is-in .pbg__pool { opacity: 1; }
/* the foot of the painting, gone into the page */
.pbg::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 46%;
  background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--tone-bg) 74%, transparent) 62%, var(--tone-bg));
}
/* the painted moon or sun, breathing: a soft bloom laid over where it is */
.pbg__glow {
  position: absolute;
  top: 0;
  left: 0;
  width: 46vmax;
  aspect-ratio: 1;
  margin: -23vmax 0 0 -23vmax;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--glow) 46%, transparent), color-mix(in srgb, var(--glow) 12%, transparent) 46%, transparent);
  opacity: 0;
  animation: pbg-breathe 13s ease-in-out 900ms infinite alternate;
}
@keyframes pbg-breathe { from { opacity: 0.25; } to { opacity: 0.9; } }
/* فصل عجيب's lamp is an old bulb. When it stutters the whole room dips,
   and the title with it (.ph__title--flicker, on the same clock). */
.pbg--flicker::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #06040a;
  opacity: 0;
  animation: pbg-dip 11s linear 2s infinite;
}
@keyframes pbg-dip {
  0%, 40%, 46%, 100% { opacity: 0; }
  41% { opacity: 0.2; }
  42.5% { opacity: 0.04; }
  44% { opacity: 0.14; }
}

/* The copy over a painting. The title is lit from where the painting's
   light is: backdrop.js fills each word from that point and aims the two
   shadows away from it (--fx, --fy, a unit vector). The first shadow is
   the hard edge every title has, the second is the one the room casts. */
.ph__title--lit {
  filter:
    drop-shadow(calc(var(--fx, 0) * 0.05em) calc(var(--fy, 1) * 0.05em) 0 var(--edge, color-mix(in srgb, var(--accent2) 55%, #000)))
    drop-shadow(calc(var(--fx, 0) * 0.14em) calc(var(--fy, 1) * 0.14em) 0.3em var(--cast, #0008))
    drop-shadow(0 0 0.22em var(--halo, transparent));
}
.ph__title--flicker { animation: ph-dip 11s linear 2s infinite; }
@keyframes ph-dip {
  0%, 40%, 46%, 100% { opacity: 1; }
  41% { opacity: 0.8; }
  42.5% { opacity: 0.96; }
  44% { opacity: 0.86; }
}
.pp--painted .ph__tag { color: var(--tone-ink); text-shadow: 0 1px 1.1em var(--pool), 0 0 0.3em color-mix(in srgb, var(--pool) 70%, transparent); }
.pp--painted .ph .eyebrow { color: color-mix(in srgb, var(--tone-ink) 82%, transparent); text-shadow: 0 1px 0.9em var(--pool); }

/* Glass, where the painting is too busy for bare words (bg.plate): the
   tagline sits on a frosted slip of the world's own night or haze, and so
   does the outlined button. A blur is cut off by any opacity on a parent,
   so on a painted page the copy never fades as a block: each piece carries
   its own fade, in and out. */
.pp--painted .ph__copy { opacity: 1; }
.pp--painted .ph__copy > :not(.ph__acts),
.pp--painted .ph__acts > * { opacity: calc(1 - var(--out) * 1.15); }
.pp--painted .ph__acts { animation-name: p-lift; }
.pp--painted .ph__acts > * { animation: p-fade 900ms cubic-bezier(.2,.75,.2,1) 660ms both; }
@keyframes p-lift { from { transform: translate3d(0, 18px, 0); } }
@keyframes p-fade { from { opacity: 0; } }
.pp--painted .ph__acts .btn--ghost:not(:hover) {
  background: color-mix(in srgb, var(--pool) 46%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
}
.pp--plate .ph__tag {
  max-width: 36ch;
  padding: 0.55em 1.25em 0.6em;
  border-radius: 1.3em;
  background: color-mix(in srgb, var(--pool) 52%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(170%);
  backdrop-filter: blur(18px) saturate(170%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tone-ink) 16%, transparent), 0 18px 40px -24px #000a;
  text-shadow: none;
}
.pp--plate .ph .eyebrow {
  justify-self: center;
  padding: 0.35em 1.1em;
  border-radius: 999px;
  color: var(--tone-ink);
  background: color-mix(in srgb, var(--pool) 46%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  text-shadow: none;
}
@media (prefers-reduced-transparency: reduce) {
  .pp--plate .ph__tag, .pp--plate .ph .eyebrow, .pp--painted .ph__acts .btn--ghost:not(:hover) {
    background: color-mix(in srgb, var(--pool) 92%, transparent);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* باب الحجرة: the painting's subject fills one side, so on a wide screen
   the copy takes the other. dir is rtl: start is the right. */
@media (min-width: 901px) and (min-aspect-ratio: 5/4) {
  .pp--side .ph__copy { justify-items: start; text-align: start; padding-inline-end: 44%; }
  .pp--side .ph__eyebrow { justify-content: flex-start; }
  .pp--side .ph__tag { margin-inline: 0; }
  .pp--side .ph__acts { justify-content: flex-start; }
  .pp--side .pbg { --pool-x: 76%; }
  /* the video stays in the copy's column, so the painting's subject keeps
     its own side all the way down the first screen */
  .pp--side .player { width: min(56%, 70rem); margin-inline: 0 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .pbg__pic { scale: 1.04; translate: none; transition: opacity 300ms ease; }
  .pbg__glow { animation: none; opacity: 0.55; }
  .pbg--flicker::before, .ph__title--flicker { animation: none; }
  .pp--painted .ph__acts > * { animation: none; }
}

/* ---- the bar on a light world (القرد والغيلم) ----
   It keeps its white logo and ink like every other page, so the faint frost
   it wears before any scroll turns to the world's night glass instead. */
@media (min-width: 901px) {
  .pp--light .nav[data-on-tone]:not(.is-stuck) {
    background: color-mix(in srgb, var(--nav-glass) 64%, transparent);
    backdrop-filter: blur(18px) saturate(180%);
    -webkit-backdrop-filter: blur(18px) saturate(180%);
  }
}

/* =============================================================== hero === */

/* The hero sits over the top of the player (its bottom padding is where
   the player rises into it), so it lets clicks through and only its copy
   takes them. That keeps the front clouds above the player's corners. */
.ph {
  --px: 0; --py: 0; --out: 0;
  position: relative;
  z-index: 4;
  min-height: min(92svh, 60rem);
  display: grid;
  align-items: center;
  padding-block: clamp(6.5rem, 15vh, 9rem) clamp(8rem, 20vh, 12rem);
  text-align: center;
  pointer-events: none;
}
.ph__back, .ph__front { position: absolute; inset: 0; pointer-events: none; }
.ph__back { z-index: 0; translate: calc(var(--px) * -12px) calc(var(--py) * -8px); }
.ph__front { z-index: 4; translate: calc(var(--px) * -30px) calc(var(--py) * -16px); }

.ph__copy {
  position: relative;
  z-index: 3;
  display: grid;
  justify-items: center;
  pointer-events: auto;
  translate: 0 calc(var(--out) * 14vh);
  opacity: calc(1 - var(--out) * 1.15);
}
.ph__eyebrow { justify-content: center; animation: p-rise 900ms cubic-bezier(.2,.75,.2,1) 80ms both; }

.ph__title {
  font-size: clamp(3.25rem, 11.5vw, 10rem);
  line-height: 1.08;
  max-width: 14ch;
  text-wrap: balance;
  /* a hard edge under the letters, like the thumbnails' 3D titles */
  filter: drop-shadow(0 0.05em 0 var(--edge, color-mix(in srgb, var(--accent2) 55%, #000)));
}
.pp--light .ph__title { --edge: var(--accent2); }
/* each word is its own clipped fill, padded for the tashkeel above it */
.ph__w {
  display: inline-block;
  padding-block: 0.3em 0.1em;
  margin-block: -0.3em -0.1em;
  background: linear-gradient(to bottom, var(--tone-ink) 40%, color-mix(in srgb, var(--tone-ink) 68%, var(--accent)) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: p-word 1100ms cubic-bezier(.2,.75,.2,1) both;
  animation-delay: calc(160ms + var(--i) * 120ms);
}
@keyframes p-word { from { opacity: 0; transform: translate3d(0, 0.32em, 0) scale(0.94); filter: blur(12px); } }
@keyframes p-rise { from { opacity: 0; transform: translate3d(0, 18px, 0); } }

.ph__tag {
  margin: clamp(0.9rem, 2vw, 1.4rem) auto 0;
  max-width: 32ch;
  font-size: clamp(1.125rem, 1.8vw, 1.5rem);
  line-height: 1.6;
  color: color-mix(in srgb, var(--tone-ink) 86%, transparent);
  text-wrap: balance;
  animation: p-rise 900ms cubic-bezier(.2,.75,.2,1) 520ms both;
}
.ph__acts {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.7rem;
  animation: p-rise 900ms cubic-bezier(.2,.75,.2,1) 660ms both;
}
/* play points right in every language: media controls are never mirrored */
.ph__tri { width: 0.62em; aspect-ratio: 1; background: currentColor; clip-path: polygon(12% 4%, 96% 50%, 12% 96%); }

/* ---- scenery pieces (js/scenes.js) ---- */

/* .sun and .eyes are shared with the news hero: sections.css */

.orbit {
  position: absolute;
  top: 48%;
  left: -24%;
  width: min(62rem, 110vw);
  aspect-ratio: 1;
  translate: 0 -50%;
}
.orbit svg { width: 100%; height: 100%; overflow: visible; }
.orbit__ring { transform-box: view-box; transform-origin: 50% 50%; animation: p-spin var(--spin) linear infinite; }
@keyframes p-spin { to { transform: rotate(360deg); } }

.spot { position: absolute; inset: 0; }
.spot__beam {
  position: absolute;
  top: -12%;
  left: 50%;
  width: min(76rem, 150vw);
  height: 125%;
  translate: -50% 0;
  background: linear-gradient(to bottom, #ffffffb8, #ffffff2e 50%, transparent 88%);
  clip-path: polygon(45% 0, 55% 0, 92% 100%, 8% 100%);
  filter: blur(26px);
  opacity: 0.5;
  animation: p-flicker 9s linear infinite;
}
.spot__pool {
  position: absolute;
  left: 50%;
  bottom: 2%;
  width: min(46rem, 90vw);
  height: 9rem;
  translate: -50% 0;
  background: radial-gradient(closest-side, #ffffff36, transparent);
}
/* an old bulb: steady, with the odd stutter */
@keyframes p-flicker {
  0%, 40%, 44.5%, 100% { opacity: 0.5; }
  41% { opacity: 0.34; }
  42% { opacity: 0.56; }
  43.5% { opacity: 0.4; }
  72% { opacity: 0.46; }
}

.swirls { position: absolute; inset: 4% -4%; }
.swirls svg { width: 100%; height: 100%; }
.swirls path {
  fill: none;
  stroke: var(--accent);
  stroke-opacity: 0.3;
  stroke-width: 1.6;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: p-draw 2.6s cubic-bezier(.45,0,.2,1) forwards;
  animation-delay: calc(300ms + var(--i) * 380ms);
}
@keyframes p-draw { to { stroke-dashoffset: 0; } }

@media (max-width: 760px) {
  .orbit { left: -62%; top: 40%; opacity: 0.7; }
}

/* ============================================================= player === */

/* above everything in the hero, clouds included: nothing may sit on the
   video or catch a click meant for it */
.pwatch {
  position: relative;
  z-index: 5;
  margin-top: calc(clamp(8rem, 20vh, 12rem) * -0.72);
  padding-bottom: clamp(3rem, 7vw, 5.5rem);
}
.player {
  --in: 1;
  position: relative;
  width: min(100%, 70rem);
  margin-inline: auto;
  aspect-ratio: 16 / 9;
  border-radius: clamp(16px, 2.2vw, 30px);
  overflow: hidden;
  background: #000;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--tone-ink) 20%, transparent),
    0 50px 100px -50px #000d,
    0 0 90px -24px color-mix(in srgb, var(--accent) 55%, transparent);
  transform: perspective(1800px) rotateX(calc((1 - var(--in)) * 18deg)) scale(calc(0.86 + var(--in) * 0.14));
  transform-origin: 50% 0;
  will-change: transform;
}
.player iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.player.is-playing .player__face { display: none; }

.player__face {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.player__face:focus-visible { outline: 3px solid var(--pop); outline-offset: -6px; border-radius: inherit; }
.player__face img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 900ms cubic-bezier(.2,.7,.2,1);
}
.player__face::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 60% at 50% 50%, transparent, #0005), linear-gradient(to top, #000b, transparent 42%);
}
.player__btn {
  position: relative;
  z-index: 2;
  width: clamp(4.5rem, 9vw, 7rem);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #ffffff38;
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 0 0 1.5px #ffffff70, 0 18px 40px -12px #0009;
  transition: transform 420ms cubic-bezier(.3,1.4,.5,1), background 220ms ease;
}
.player__btn i { width: 34%; aspect-ratio: 1; background: #fff; clip-path: polygon(20% 8%, 92% 50%, 20% 92%); translate: 8% 0; }
.player__face:hover img { scale: 1.04; }
.player__face:hover .player__btn { transform: scale(1.08); background: color-mix(in srgb, var(--accent) 60%, transparent); }
.player__face:active .player__btn { transform: scale(0.94); transition-duration: 90ms; }
.player__label {
  position: absolute;
  z-index: 2;
  inset-inline-start: clamp(1rem, 3vw, 2rem);
  inset-block-end: clamp(0.8rem, 2.4vw, 1.6rem);
  display: grid;
  text-align: start;
  line-height: 1.35;
}
.player__label b { font-family: var(--display); font-size: clamp(1.1rem, 2vw, 1.6rem); }
.player__label small { font-size: 0.8125rem; opacity: 0.78; }

/* ============================================================ numbers === */

.pstats { position: relative; z-index: 2; }
.pstats__row {
  list-style: none;
  margin-block: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-block: 1px solid color-mix(in srgb, var(--tone-ink) 16%, transparent);
}
.pstats__row li {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
  padding: clamp(1.4rem, 3vw, 2.4rem) clamp(0.5rem, 2vw, 1.5rem);
  text-align: center;
}
.pstats__row li + li { border-inline-start: 1px solid color-mix(in srgb, var(--tone-ink) 16%, transparent); }
.pstats b {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.4rem, 5.4vw, 4.75rem);
  line-height: 1;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pstats b small { margin-inline-start: 0.2em; font-size: 0.36em; font-weight: 700; color: var(--pop); }
.pstats__l { font-size: 0.9375rem; color: color-mix(in srgb, var(--tone-ink) 68%, transparent); }
.pstats__note {
  margin-block: 0.85rem 0;
  font-size: 0.8125rem;
  text-align: center;
  color: color-mix(in srgb, var(--tone-ink) 52%, transparent);
}
.pstory__read { margin-top: 0.5rem; }

/* the comic's own button in the hero: filled where the video's is a ghost,
   because the pages are the whole story and the video is the teaser */
.ph__read { --btn-bg: var(--accent); --btn-fg: var(--tone-deep); }

@media (max-width: 720px) {
  .pstats__row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pstats__row li:nth-child(3) { border-inline-start: 0; }
  .pstats__row li:nth-child(n + 3) { border-top: 1px solid color-mix(in srgb, var(--tone-ink) 16%, transparent); }
}

/* ========================================================== the award === */
/* غَمَام's prize, in the same rosette as إنجازاتنا on the home page but built
   for a dark page: no cream paper and no sun, just this world's own ink with
   one cool rim of light on it, and a faint pool of the accent underneath so
   it lifts off the night without shouting.

   It follows عَنِ الحِكَايَة, whose second paragraph names the competition, so
   it climbs back into that section's bottom bay: close enough to read as the
   end of the story, with a full bay still under it before أَعْمَالٌ أُخْرَى. */

.pprize {
  position: relative;
  z-index: 3;
  margin-top: calc(var(--bay) * -0.55);
}
.pprize__bar {
  container-type: inline-size;
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2.2vw, 1.6rem);
  width: min(100%, 54rem);
  margin-inline: auto;
  padding: clamp(0.9rem, 2vw, 1.35rem) clamp(1.1rem, 2.4vw, 1.7rem);
  border-radius: clamp(14px, 1.8vw, 22px);
  background:
    radial-gradient(80% 160% at 8% 0%, color-mix(in srgb, var(--accent) 13%, transparent) 0%, transparent 70%),
    color-mix(in srgb, var(--tone-sky) 42%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--tone-ink) 22%, transparent),
    0 0 0 1px color-mix(in srgb, var(--tone-ink) 12%, transparent),
    0 26px 60px -40px #000;
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
}

/* three squares turned 30° apart: the same rosette as the home page medal */
.pprize__seal {
  position: relative;
  isolation: isolate;
  flex: none;
  width: clamp(4.5rem, 11cqw, 6.5rem);
  aspect-ratio: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
  color: var(--tone-ink);
  filter: drop-shadow(0 6px 14px #0009);
}
.pprize__seal i {
  position: absolute;
  inset: 9%;
  z-index: -1;
  border-radius: 24%;
  background: color-mix(in srgb, var(--tone-ink) 13%, var(--tone-deep));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
}
.pprize__seal i:nth-child(2) { rotate: 30deg; }
.pprize__seal i:nth-child(3) { rotate: 60deg; }
.pprize__seal::after {
  content: '';
  position: absolute;
  inset: 15%;
  z-index: -1;
  border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--tone-ink) 34%, transparent);
}
.pprize__seal b {
  font-family: var(--display);
  font-weight: 800;
  font-size: 2.1rem;
  line-height: 1;
  color: var(--accent);
  margin-block: -0.12em -0.04em;
}
.pprize__seal span {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.625rem;
  line-height: 1.25;
  white-space: nowrap;
  color: color-mix(in srgb, var(--tone-ink) 78%, transparent);
}

.pprize__copy { flex: 1 1 auto; min-width: 0; }
.pprize__rank {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1rem, 2.1vw, 1.375rem);
  line-height: 1.4;
  color: var(--tone-ink);
}
.pprize__note {
  margin: 0.3rem 0 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--tone-ink) 62%, transparent);
}
/* The awarding body's own mark, quiet: it is a source, not a headline. It is
   drawn in dark ink for paper, so it sits on its own pale chip rather than
   disappearing into the night. */
.pprize__plaque {
  flex: none;
  width: clamp(4rem, 10cqw, 6rem);
  height: auto;
  padding: 0.5rem 0.6rem;
  border-radius: 10px;
  background: #f4f3f0;
  box-shadow: 0 10px 24px -18px #000;
  opacity: 0.9;
}

@media (max-width: 560px) {
  .pprize__bar { flex-wrap: wrap; justify-content: center; text-align: center; }
  .pprize__copy { flex-basis: 100%; order: 3; }
}

/* ========================================================= the stills === */
/* A slow strip of frames from the work itself, under the video. It is meant
   to sit quietly behind the writing that follows, so it has no tilt and no
   lean: only the drift, a frame that grows a little under the pointer, and
   the grab (js/stills.js). Masked at both ends so frames arrive and leave
   instead of being cut off by the screen edge. pan-y leaves vertical swipes
   to the page and gives sideways ones to the strip. */

.strip {
  position: relative;
  z-index: 2;
  padding-bottom: clamp(2.25rem, 5vw, 4rem);
}
.strip__frame {
  overflow: clip;
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  cursor: grab;
  -webkit-mask-image: linear-gradient(to left, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(to left, transparent, #000 6%, #000 94%, transparent);
}
.strip__frame.is-dragging { cursor: grabbing; }
.strip__frame:focus-visible { outline: 3px solid var(--accent); outline-offset: 6px; }
.strip__track {
  display: flex;
  gap: clamp(0.6rem, 1.4vw, 1.1rem);
  width: max-content;
  will-change: transform;
}
.strip__shot {
  flex: none;
  margin: 0;
  width: clamp(15rem, 30vw, 27rem);
  border-radius: clamp(10px, 1.3vw, 16px);
  overflow: hidden;
  background: color-mix(in srgb, var(--tone-ink) 8%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--tone-ink) 14%, transparent);
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* the frame under the pointer grows, a little: no tilt, no lift, no shadow */
@media (hover: hover) and (pointer: fine) {
  .strip__shot:hover { transform: scale(1.035); }
}
/* a hand dragging the strip is not pointing at any one frame */
.strip__frame.is-dragging .strip__shot { transform: none; transition: none; }
.strip__shot img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  user-select: none;
  -webkit-user-select: none;
}

/* Reduced motion: the same frames, none of the drift. It becomes a row you
   push yourself, which is also what a keyboard gets. */
.strip__frame.is-still {
  overflow-x: auto;
  touch-action: auto;
  cursor: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-inline: clamp(1rem, 4vw, 2rem);
}
.strip__frame.is-still .strip__shot { transition: none; transform: none; }
.strip__frame.is-still .strip__track { transform: none !important; }
.strip__frame.is-still .strip__shot { scroll-snap-align: center; }

@media (max-width: 600px) {
  .strip__shot { width: 74vw; }
}

/* ============================================================== story === */

.pstory { z-index: 2; }
.pstory__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.7fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: end;
}
.pstory__copy p { max-width: 50ch; color: color-mix(in srgb, var(--tone-ink) 80%, transparent); }
.pstory__copy .pstory__lede {
  margin-top: clamp(1rem, 2vw, 1.5rem);
  font-size: clamp(1.25rem, 2.1vw, 1.8rem);
  line-height: 1.6;
  font-weight: 500;
  color: var(--tone-ink);
}
.pfacts { margin: 0; border-top: 1px solid color-mix(in srgb, var(--tone-ink) 16%, transparent); }
.pfacts div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding-block: 1rem;
  border-bottom: 1px solid color-mix(in srgb, var(--tone-ink) 16%, transparent);
}
.pfacts dt { font-size: 0.9375rem; color: color-mix(in srgb, var(--tone-ink) 62%, transparent); }
.pfacts dd { margin: 0; font-family: var(--display); font-weight: 700; font-size: 1.125rem; text-align: end; }

@media (max-width: 880px) { .pstory__grid { grid-template-columns: 1fr; } }

/* ========================================================= more work === */

/* bottom padding is headroom for the footer's cloud edge */
.pmore { z-index: 2; padding-bottom: calc(var(--bay) + clamp(3rem, 7vw, 6rem)); }
.pmore__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 1rem 2rem; }
.pmore__all {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding-bottom: 0.15em;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.0625rem;
  text-decoration: none;
  background: linear-gradient(var(--pop), var(--pop)) 100% 100% / 100% 2px no-repeat;
}
.pmore__all span { transition: translate 300ms cubic-bezier(.2,.7,.3,1); }
.pmore__all:hover span { translate: -5px 0; }

.pmore__row {
  margin-top: clamp(1.5rem, 3.5vw, 2.75rem);
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(0.75rem, 2vw, 1.75rem);
  align-items: start;
}
.pmore__row .cover { width: 100%; margin: 0; }

@media (max-width: 900px) {
  .pmore__row {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: min(44vw, 13rem);
    margin-inline: calc(var(--gutter) * -1);
    padding: 1rem var(--gutter);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .pmore__row::-webkit-scrollbar { display: none; }
  .pmore__row .cover { scroll-snap-align: center; }
}

/* ============================================================= footer === */

/* the shared footer (sections.css), in this work's own night */
.pp .pfoot { --foot-bg: var(--tone-deep); --foot-accent: var(--accent); }
/* The bank of clouds over the footer. In sections.css it hangs above the
   footer's own box, and WebKit (Safari, Orion) did not paint it there on
   these pages while Chromium did. The cause was never pinned down from a
   WebKit build (the likeliest is the footer's sideways clip taking what
   stands above it too), so the fix does not depend on it: here nothing
   stands outside the box. The footer starts one cloud's
   height early (--rise, the tallest cloud in project.html: min(34rem, 66vw)
   wide at 721:372), that much of its top is clear instead of filled, and
   the bank sits inside it exactly where it was. The clear part lets clicks
   through to the page it overlaps. */
.pp .pfoot {
  --rise: min(17.6rem, 34.2vw);
  margin-top: calc(var(--rise) * -1);
  padding-top: calc(var(--rise) + clamp(2rem, 5vw, 4rem));
  background: linear-gradient(to bottom, transparent var(--rise), var(--foot-bg) var(--rise));
  pointer-events: none;
}
.pp .pfoot .shell { pointer-events: auto; }
.pp .pfoot__clouds {
  bottom: auto;
  top: calc(var(--rise) - clamp(4rem, 9vw, 8rem) + 2px);
  /* its own layer, so nothing composited in the page under it can end up
     painted over it */
  transform: translateZ(0);
}
.pp .pfoot__mark { top: var(--rise); }

/* ===================================================== reduced motion === */

@media (prefers-reduced-motion: reduce) {
  .ph__w, .ph__eyebrow, .ph__tag, .ph__acts { animation: none; }
  .ph__copy { translate: none; opacity: 1; }
  .ph__back, .ph__front { translate: none; }
  .player { transform: none; }
  .player__face img, .player__btn, .pmore__all span { transition: none; }
  .orbit__ring, .spot__beam { animation: none; }
  .swirls path { animation: none; stroke-dashoffset: 0; }
}
