/* ============================================================================
   Project page — the new case-study layout (first used by fy.html)

   The home page's language, stretched into a story:
     · the same ruled frame, 1px rules with a white halo either side
     · black and white at rest — footage wakes into colour as it reaches the
       middle of the screen (the page's version of "hover")
     · variable type: width and weight move with the pointer
     · chapters: text sticks beside its own media while the media scrolls
   Loaded on top of site.css.
   ========================================================================= */

:root {
  --halo: 2px;
  --live-time: .7s;
  --ease-grid: cubic-bezier(.65, 0, .25, 1);
}

.pg { border: var(--rule); margin-top: var(--gutter); }
/* the contact row sits straight under the frame: share one rule, not two */
main:has(> .pg) + .site-footer { margin-top: -1px; }

/* --- the ruled grid shared by the head and the index --------------------- */
.pg-grid {
  display: grid;
  gap: 1px;
  background: var(--ink);
}
.pg-grid > * { background: var(--paper); position: relative; min-width: 0; }

/* the white halo along every rule, above whatever fills the cell */
.pg-halo::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 var(--halo) var(--paper);
  pointer-events: none;
  z-index: 3;
}

/* --- head: the name across the full width, then subtitle + facts, then the
   four chapters ------------------------------------------------------------ */
.pg-head { grid-template-columns: repeat(12, 1fr); }

/* One spacing unit for everything in the head: the distance from the F of
   the name to the grid line. The cell's padding and every gap between its
   parts use it, and each line of text is trimmed to its letters (cap height
   to baseline), so the gaps measure letter to letter, not box to box. */
.pg-title {
  --hu: 1.6rem;
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--hu);
  padding: var(--hu);
  container-type: inline-size;
}
.pg-back, .pg-name, .pg-sub, .pg-craft dt, .pg-craft dd { text-box: trim-both cap alphabetic; }
/* the name's letters are separate boxes (for the width animation): trim each */
.pg-name .ch { text-box: trim-both cap alphabetic; }
.pg-back {
  align-self: flex-start;
  font-size: .875rem;
  font-variation-settings: "wdth" 75, "wght" 500;
  transition: color .2s var(--ease);
}
.pg-back:hover { color: var(--blue); }
/* the link back home sits above the big title (whose letters reach up over
   it) and gets a generous click area without changing the spacing */
.pg-back { position: relative; z-index: 5; }
.pg-back::before { content: ""; position: absolute; inset: -.9rem -1rem; }
/* the title only reacts to where the pointer is, never to clicks */
.pg-name { pointer-events: none; }

/* the big title: sized to its tile, letters swell toward the pointer */
.pg-name {
  /* sized so the name, fully swollen (wdth 100, wght 800), exactly spans the
     tile — at rest it fills about 80%, and it can never overflow */
  font-size: 15.85cqi;
  line-height: .82;
  letter-spacing: -.02em;
  white-space: nowrap;
}
.pg-name .ch {
  display: inline-block;
  --w: 88; --g: 800;
  font-variation-settings: "wdth" var(--w), "wght" var(--g), "opsz" 96;
  transition: font-variation-settings .25s linear;
}
.pg-name .sp { display: inline-block; width: .22em; }

/* The facts sit to the right of the sentence whenever the head is wide
   enough for both (the sentence keeps at least ~22em); otherwise they go
   under it, side by side. Measured on the head itself, not the screen.
   Beside it, the first fact's label lines up with the sentence's cap
   height, so the two share one top line. */
.pg-lede {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: var(--hu);
}
@container (min-width: 44rem) {
  .pg-lede { grid-template-columns: minmax(0, 1fr) auto; }
  .pg-craft { flex-direction: column; }
}
.pg-sub {
  margin: 0;
  max-width: 34em;
  font-family: var(--serif);
  font-style: italic;
  font-variation-settings: "wght" 615;
  font-size: 1.75rem;
  line-height: 1.15;
  letter-spacing: -.01em;
}
.pg-craft { margin: 0; display: flex; flex-wrap: wrap; gap: var(--hu); }
.pg-craft div { display: flex; flex-direction: column; gap: .36rem; }
.pg-craft dt {
  font-size: .6875rem;
  font-variation-settings: "wdth" 75, "wght" 500;
  color: var(--blue);
}
.pg-craft dd { margin: 0; font-size: .875rem; line-height: 1.4; }
.pg-craft dd a { text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 1px; transition: color .2s var(--ease); }
.pg-craft dd a:hover { color: var(--blue); }


/* --- chapter index: four tiles in a 2 × 2 grid, like the home grid -------- */
.pg-index {
  grid-column: 1 / -1;
  grid-template-columns: repeat(4, 1fr);
  background: var(--ink);        /* the rules between the four tiles */
}

.pg-tile {
  display: flex;
  flex-direction: column;
  color: inherit;
}
/* One height for the chapter tiles on every page, however many there are
   (four, three or two across) — the image area is fixed, the bar sits under
   it. The images are cropped to fill (object-fit: cover), never stretched. */
.pg-tile__img { height: var(--tile-h, 12rem); position: relative; overflow: hidden; }
.pg-tile__img img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  opacity: .85;
  transform: scale(1.04);
  transition: filter .4s var(--ease), opacity .4s var(--ease), transform .6s var(--ease-grid);
}
.pg-tile:hover .pg-tile__img img,
.pg-tile:focus-visible .pg-tile__img img { filter: none; opacity: 1; transform: scale(1); }

/* the bar: tight at rest, opens up and turns blue on hover — as on the home page */
.pg-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .6rem;
  padding: 4px;
  border-top: var(--rule);
  background: var(--paper);
  position: relative;
  z-index: 4;
  box-shadow: 0 calc(-1 * var(--halo)) 0 var(--paper);
  transition: background-color .3s var(--ease), color .3s var(--ease), padding .5s var(--ease-grid);
}
.pg-bar .tt, .pg-bar .pg-no { text-box: trim-both cap text; font-size: 1rem; line-height: 1.1; white-space: nowrap; }
.pg-bar .tt { overflow-x: clip; }
.pg-bar .ch, .pg-no {
  display: inline-block;
  --w: 75; --g: 300;
  font-variation-settings: "wdth" var(--w), "wght" var(--g);
  transition: font-variation-settings .55s var(--ease-grid);
  transition-delay: calc(var(--i, 0) * 22ms);
}
.pg-bar .sp { display: inline-block; width: .28em; }
.w { white-space: nowrap; }
.pg-tile:hover .pg-bar,
.pg-tile:focus-visible .pg-bar { background: var(--blue); color: var(--paper); padding: .45rem .7rem .55rem; }
.pg-tile:hover .ch, .pg-tile:hover .pg-no,
.pg-tile:focus-visible .ch, .pg-tile:focus-visible .pg-no { --w: 100; --g: 800; }

/* --- chapter index, typographic (default; ?index=tiles shows the image
   tiles above instead, for comparison: project.js §0) ------------------------
   No images, one line per chapter: number (blue), title, ↓, all at one
   small size, in a row of cells like the project strip at the top. On hover
   the cell fills blue and the title swells, as on the home grid. Phones:
   one chapter per row. */
html:not(.index-tiles) .pg-tile__img { display: none; }
html:not(.index-tiles) .pg-tile { min-height: var(--index-h, auto); }
.pg-index.is-measuring .ch { transition: none !important; }
html:not(.index-tiles) .pg-bar,
html:not(.index-tiles) .pg-tile:hover .pg-bar,
html:not(.index-tiles) .pg-tile:focus-visible .pg-bar {
  flex: 1;
  display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr) auto;
  align-items: center;
  column-gap: .5rem;
  padding: .45rem .7rem .55rem;     /* the strip's cells */
  border-top: 0;
  box-shadow: none;
  transition: background-color .3s var(--ease), color .3s var(--ease);
}
html:not(.index-tiles) .pg-bar .pg-no,
html:not(.index-tiles) .pg-bar .tt,
html:not(.index-tiles) .pg-bar::after {
  font-size: 1rem;                  /* the strip's size */
  line-height: 1.1;
  text-box: trim-both cap alphabetic;
}
html:not(.index-tiles) .pg-bar .pg-no { order: 0; color: var(--blue); --w: 75; --g: 500; }
html:not(.index-tiles) .pg-bar .tt { order: 1; white-space: normal; overflow: visible; display: flex; flex-wrap: wrap; }
html:not(.index-tiles) .pg-bar .tt .w { display: inline-flex; white-space: nowrap; }
html:not(.index-tiles) .pg-bar::after { content: "↓"; order: 2; color: var(--blue); }
html:not(.index-tiles) .pg-tile:hover .pg-bar .pg-no,
html:not(.index-tiles) .pg-tile:hover .pg-bar::after,
html:not(.index-tiles) .pg-tile:focus-visible .pg-bar .pg-no,
html:not(.index-tiles) .pg-tile:focus-visible .pg-bar::after { color: var(--paper); }
/* the number keeps its weight on hover; the title turns bold but stays
   condensed (wdth 75), so even the longest title stays on one line */
html:not(.index-tiles) .pg-tile:hover .pg-no,
html:not(.index-tiles) .pg-tile:focus-visible .pg-no { --w: 75; --g: 500; }
html:not(.index-tiles) .pg-tile:hover .tt .ch,
html:not(.index-tiles) .pg-tile:focus-visible .tt .ch { --w: 75; --g: 800; }
@media (max-width: 640px) {
  html:not(.index-tiles) .pg-index { grid-template-columns: minmax(0, 1fr) !important; }
  html:not(.index-tiles) .pg-index > .pg-tile { grid-column: auto !important; }
}

/* --- media that wakes into colour ---------------------------------------- */
.pg-media { position: relative; overflow: hidden; background: var(--paper); }
.pg-media > video,
.pg-media > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  opacity: .85;
  transition: filter var(--live-time) var(--ease), opacity var(--live-time) var(--ease);
}
.pg-media.is-live > video,
.pg-media.is-live > img { filter: none; opacity: 1; }
/* a video sits over its poster and only shows once it is actually playing */
.pg-media > video { position: absolute; inset: 0; }
.pg-media > img + video:not(.is-playing) { opacity: 0; }

.pg-wide   { aspect-ratio: 16 / 9; }
.pg-band   { aspect-ratio: 3 / 1; }
.pg-square { aspect-ratio: 1; }
.pg-tall   { aspect-ratio: 9 / 16; }
.pg-portrait { aspect-ratio: 4 / 5; }
.pg-poster { aspect-ratio: 2708 / 3998; }
.pg-photo  { aspect-ratio: 3 / 2; }
.pg-story  { aspect-ratio: 1311 / 1819; }
.pg-flow   { aspect-ratio: 2880 / 476; }
.pg-figma  { aspect-ratio: 1820 / 1610; }
/* a diagram on white: shown whole, never cropped */
.pg-flow > img { object-fit: contain; }

/* the logo animation is black on white: shown smaller, well clear of the
   rules, rather than cropped to the cell */
.pg-logo > video,
.pg-logo > img { object-fit: contain; padding: 22%; }

/* bar under a media cell */
.pg-cap {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: .45rem .7rem .55rem;
  border-top: var(--rule);
  font-size: .9375rem;
  font-variation-settings: "wdth" 80, "wght" 500;
}
.pg-cap > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.pg-cap small { font-family: var(--note); font-style: italic; font-size: .875rem; color: var(--ink-mute); font-variation-settings: normal; }
/* a caption in a narrow column (the FY memory film): title and note on two
   lines, both whole, instead of cut off with dots */
@media (min-width: 901px) {
  .pg-cap--stack { flex-direction: column; align-items: flex-start; gap: .3rem; }
  .pg-cap--stack > * { white-space: normal; overflow: visible; }
}

.pg-sound, .pg-pill {
  font: inherit;
  font-variation-settings: "wdth" 80, "wght" 600;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  padding: .15em .8em .22em;
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.pg-sound:hover { border-color: var(--blue); color: var(--blue); }
.pg-sound[aria-pressed="true"] { background: var(--blue); border-color: var(--blue); color: var(--paper); }
/* a link out of the page (research boards and the like), in the copy column */
.pg-pill { display: inline-block; margin-top: 1.1rem; }
.pg-pill:hover { border-color: var(--blue); color: var(--blue); }

/* a line said out loud: a headline or pull quote inside the copy column */
.pg-say {
  font-family: var(--serif);
  font-style: italic;
  font-variation-settings: "wght" 615;
  font-size: 1.5rem;
  line-height: 1.15;
  letter-spacing: -.01em;
  text-wrap: balance;
  margin: 0 0 1rem;
}
.pg-ch__text p + .pg-say, .case__copy p + .pg-say { margin-top: 1.2rem; }
.pg-say, .pg-say + p { text-indent: 0 !important; }
.pg-say + p { margin-top: 0 !important; }
.pg-lead { font-variation-settings: "wdth" 85, "wght" 700; }

/* --- hero ---------------------------------------------------------------- */
.pg-hero { border-top: var(--rule); }

/* --- chapters: text sticks beside its media ------------------------------ */
.pg-ch {
  display: grid;
  grid-template-columns: 33.85% 1fr;
  border-top: var(--rule);
}
.pg-ch__text {
  align-self: start;
  position: sticky;
  top: 0;
  padding: 1.3rem 1.4rem 1.8rem 1.6rem;
}
.pg-ch__no {
  display: block;
  font-size: .75rem;
  font-variation-settings: "wdth" 75, "wght" 500;
  color: var(--blue);
  margin-bottom: .5rem;
}
.pg-ch__title {
  font-size: 2.5rem;
  line-height: .95;
  letter-spacing: -.02em;
  font-variation-settings: "wdth" 85, "wght" 800;
  margin-bottom: 1rem;
}
.pg-ch__text p + p { margin-top: .6em; }
.pg-hint {
  margin-top: 1.2rem;
  font-family: var(--note);
  font-style: italic;
  font-size: .9375rem;
  color: var(--ink-mute);
}

.pg-ch__media { border-left: var(--rule); min-width: 0; }
/* the media always closes with a rule, as if another row followed. When the
   copy column beside it runs longer (the closing block of the last chapter),
   the media ends as a finished cell instead of an open one. Pulled down 1px,
   so where the media does reach the end its rule lands exactly on the one
   that is already there and never doubles. */
.pg-ch__media > :last-child { border-bottom: var(--rule); margin-bottom: -1px; }
/* every block in a media column is ruled off from the one above it; a row
   of captions brings its own rules */
.pg-stack > * + *,
.pg-ch__media > * + * { border-top: var(--rule); }
.pg-ch__media > .pg-row:has(> .pg-cap) { border-top: 0; }
/* Rows: each rule sits in a 1px gap between the cells (pulled into it with a
   -1px margin), so it never eats into a cell. Every column keeps its full
   width, side-by-side media come out exactly the same size, and the captions
   under them line up. */
.pg-row { display: grid; gap: 1px; }
.pg-row > * + * { border-left: var(--rule); margin-left: -1px; box-sizing: content-box; }
.pg-grid-2x2 > *, .pg-row--4 > * { box-sizing: content-box; }
/* minmax(0, 1fr), not 1fr: a column may never grow to fit something that
   won't shrink (a caption, a button) — that pushed media off the screen */
.pg-row--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pg-row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pg-row--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.pg-index.pg-index--3 { grid-template-columns: repeat(3, 1fr); }
.pg-index.pg-index--2 { grid-template-columns: repeat(2, 1fr); }
/* two-by-two: the rule between the rows */
.pg-grid-2x2 > :nth-child(3) { border-left: 0; margin-left: 0; }
.pg-grid-2x2 > :nth-child(n+3) { border-top: var(--rule); margin-top: -1px; }
.pg-row--tall { grid-template-columns: 36% minmax(0, 1fr); }
.pg-row--tall-r { grid-template-columns: minmax(0, 1fr) 36%; }

.pg-scrub { cursor: ew-resize; }

/* flavour: a still library in a 2 × 2 grid beside the ad */
.pg-quad { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--ink); align-content: start; }
.pg-quad > * { background: var(--paper); }

/* --- in memory ----------------------------------------------------------- */
.pg-memory__film { position: sticky; top: 0; align-self: start; }
.pg-play {
  position: absolute;
  inset: auto 1rem 1rem 1rem;
  z-index: 4;
  font: inherit;
  font-size: 1rem;
  font-variation-settings: "wdth" 85, "wght" 700;
  padding: .7rem 1rem .8rem;
  border: 0;
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.pg-play:hover { background: var(--blue); color: var(--paper); }
.pg-memory.is-playing .pg-play { opacity: 0; pointer-events: none; }

.pg-board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--ink); }
.pg-board button {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: var(--paper);
  cursor: pointer;
  aspect-ratio: 336 / 597;
  overflow: hidden;
}
.pg-board img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  opacity: .85;
  transition: filter .35s var(--ease), opacity .35s var(--ease);
}
.pg-board button::after {                 /* halo + the current-scene marker */
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 var(--halo) var(--paper);
  transition: box-shadow .3s var(--ease);
}
.pg-board button:hover img,
.pg-board button.is-now img { filter: none; opacity: 1; }
.pg-board button.is-now::after { box-shadow: inset 0 0 0 var(--halo) var(--paper), inset 0 0 0 calc(var(--halo) + 4px) var(--blue); }
.pg-board span {
  position: absolute;
  left: 6px; top: 6px;
  z-index: 2;
  font-size: .75rem;
  font-variation-settings: "wdth" 75, "wght" 600;
  background: var(--paper);
  padding: 2px 5px 3px;
}
.pg-board button.is-now span { background: var(--blue); color: var(--paper); }

/* the closing column of the last chapter reuses the case-page foot
   (site.css) — sticky at the bottom, fading in once the copy has passed */
.pg-ch .case__copy { padding: 1.3rem 1.4rem 1.8rem 1.6rem; }

/* The foot is positioned, so it paints above ordinary borders — and at
   fractional widths its blue bar can land on half a device pixel of the
   rule beside it. The three rules it can touch are redrawn above it: the
   frame's edge, the column rule, and the contact row's top line. */
.pg { position: relative; }
.pg::before {
  content: "";
  position: absolute;
  inset: -1px;
  border: var(--rule);
  pointer-events: none;
  z-index: 4;
}
.pg-ch__media { position: relative; }
.pg-ch__media::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: -1px;
  width: 1px;
  background: var(--ink);
  pointer-events: none;
  z-index: 4;
}
main:has(> .pg) + .site-footer { position: relative; z-index: 4; }

/* a media column that fills its chapter's full height, however long the
   text beside it: the .pg-grow row takes whatever is left above the
   captions, so the rules always run to the bottom */
.pg-fill { display: flex; flex-direction: column; }
.pg-fill > .pg-grow { flex: 1; min-height: 16rem; }
.pg-grow > .pg-media > * { position: absolute; inset: 0; }
.pg-contain > img, .pg-contain > video { object-fit: contain; }

/* rows where the tall video sets the height: the other column fits it
   exactly — its media flexes to whatever is left above the caption */
.pg-row--tall.pg-row--fit > :last-child { display: flex; flex-direction: column; }
.pg-row--tall.pg-row--fit > :last-child > .pg-media { aspect-ratio: auto; flex: 1; min-height: 0; }
.pg-row--tall.pg-row--fit > :last-child > .pg-media > * { position: absolute; inset: 0; }

/* the same, with the fitting column named explicitly (it can sit on
   either side) */
.pg-row--fit > .pg-fitcol { display: flex; flex-direction: column; }
.pg-row--fit > .pg-fitcol > .pg-media { aspect-ratio: auto; flex: 1; min-height: 0; }
.pg-row--fit > .pg-fitcol > .pg-media > * { position: absolute; inset: 0; }

/* --- phones -------------------------------------------------------------- */
@media (max-width: 900px) {
  .pg-head { grid-template-columns: 1fr; }
  .pg-title, .pg-index { grid-column: 1 / -1; }
  .pg-grow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pg-fill > .pg-grow { min-height: 0; }
  .pg-grow > .pg-media { aspect-ratio: 1; }
  /* chapter tiles: always two across, the same height on every page; an
     odd one out takes the full width */
  .pg-index, .pg-index.pg-index--3, .pg-index.pg-index--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pg-index > .pg-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .pg-tile__img { height: clamp(8rem, 34vw, 15rem); }
  .pg-sub { font-size: 1.4rem; }

  .pg-ch { grid-template-columns: 1fr; }
  .pg-ch__text, .pg-memory__film { position: static; }
  .pg-ch__media { border-left: 0; border-top: var(--rule); order: 2; }
  .pg-ch__media::before { display: none; }
  .pg-ch__text > * { max-width: 38rem; }
  .pg-row--tall, .pg-row--tall-r { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pg-row--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pg-row--4 > :nth-child(3) { border-left: 0; margin-left: 0; }
  .pg-row--4 > :nth-child(n+3) { border-top: var(--rule); margin-top: -1px; }
}
@media (max-width: 640px) {
  /* Pairs that are too small side by side go one under the other: a tall
     video with its neighbour, and any row marked .pg-row--stack. The rule
     between them turns from vertical to horizontal. */
  .pg-row--tall, .pg-row--tall-r, .pg-row--stack { grid-template-columns: minmax(0, 1fr); }
  .pg-row--tall > * + *, .pg-row--tall-r > * + *, .pg-row--stack > * + * {
    border-left: 0; margin-left: 0;
    border-top: var(--rule); margin-top: -1px;
  }
  /* a column that filled the height beside a tall video takes its own
     proportions again once it stands alone (--ar on the cell, or square) */
  .pg-row--tall.pg-row--fit > :last-child > .pg-media,
  .pg-row--fit > .pg-fitcol > .pg-media { flex: none; aspect-ratio: var(--ar, 16 / 9); }
  .pg-row--tall.pg-row--fit > :last-child > .pg-media.pg-square { aspect-ratio: 1; }

  .pg-row--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pg-row--3 > :nth-child(3) { grid-column: 1 / -1; border-left: 0; margin-left: 0; border-top: var(--rule); margin-top: -1px; }
  .pg-board { grid-template-columns: repeat(4, 1fr); }
}

/* --- viewer (project.js §6): a graphic full screen on phones ------------ */
html.pv-open { overflow: hidden; }
.pv {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transition: opacity .2s var(--ease);
  overscroll-behavior: contain;
  --pv-fade: 1;
}
.pv.is-open { opacity: 1; }
.pv[hidden] { display: none; }
/* the white behind it fades as it is swiped away, so the page shows through */
.pv-bg { position: absolute; inset: 0; background: var(--paper); opacity: var(--pv-fade); }
.pv-top, .pv-cap { position: relative; opacity: var(--pv-fade); }
.pv-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
  border-bottom: var(--rule);
}
.pv-count {
  padding: 0 .9rem;
  font-size: .9375rem;
  font-variation-settings: "wdth" 80, "wght" 500;
}
.pv-close {
  width: 48px; height: 48px;
  display: grid; place-items: center;
  padding: 0; border: 0; border-left: var(--rule);
  background: none; color: var(--ink);
  cursor: pointer;
}
.pv-close svg { width: 20px; height: 20px; stroke: currentColor; stroke-width: 1.6; fill: none; }
.pv-close:hover { color: var(--blue); }
.pv-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  touch-action: none;              /* the viewer handles every gesture itself */
  user-select: none;
  -webkit-user-select: none;
}
.pv-track { display: flex; height: 100%; will-change: transform; }
.pv-track.is-moving { transition: transform .32s var(--ease-grid); }
.pv-slide {
  flex: 0 0 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.pv-media { position: relative; transform-origin: 0 0; will-change: transform; }
.pv-media.is-moving { transition: transform .28s var(--ease-grid); }
.pv-media img, .pv-film {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  object-fit: contain;
  -webkit-user-drag: none;
}
.pv-film { opacity: 0; transition: opacity .2s var(--ease); }
.pv-film.is-playing { opacity: 1; }
.pv-cap {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: .6rem calc(.9rem + env(safe-area-inset-right)) calc(.7rem + env(safe-area-inset-bottom)) calc(.9rem + env(safe-area-inset-left));
  border-top: var(--rule);
  font-size: .9375rem;
  font-variation-settings: "wdth" 80, "wght" 500;
}
.pv-cap__t { flex: none; }
.pv-cap__s {
  flex: 1; min-width: 0;
  font-family: var(--note); font-style: italic; font-size: .875rem;
  color: var(--ink-mute); font-variation-settings: normal;
}
.pv-sound { margin-left: auto; flex: none; }

/* a phone turned sideways is turned to see the graphic bigger: the caption
   and counter step aside, only a small close button floats in the corner */
@media (orientation: landscape) and (max-height: 500px) {
  .pv-top {
    position: absolute;
    top: 0; right: 0;
    z-index: 2;
    border: 0;
    background: var(--paper);
    border-left: var(--rule);
    border-bottom: var(--rule);
  }
  .pv-count, .pv-cap { display: none; }
  .pv-close { border-left: 0; }
}


@media (prefers-reduced-motion: reduce) {
  .pg-media > video, .pg-media > img, .pg-tile__img img, .pg-name .ch { transition: none; }
}

/* --- nav: the strip of projects (project.js §8) ---------------------------
   Pinned to the top of the screen, with its own rule all round (so the
   bottom line is there while it's pinned, too). Cells are tile bars: thin
   and condensed at rest, bold and blue when open. No cell ever changes
   width on hover: project.js measures the strip and reserves the room, in
   one of three modes (data-mode):
     full     every cell is wide enough for its name in bold
     names    this page's cell is; the others keep their resting width, and
              pointing at one turns it blue without making it bold
     numbers  numbers only, this page's in blue */
.pgnav {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  gap: 1px;
  background: var(--ink);                 /* the rules between the cells */
  border: var(--rule);
  margin-top: var(--gutter);              /* where the page used to start */
}
.pgnav + .pg { margin-top: -1px; }        /* at rest the two share one rule */
.pgnav > a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .6rem;
  padding: .45rem .7rem .55rem;
  background: var(--paper);
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  transition: background-color .3s var(--ease), color .3s var(--ease);
}
.pgnav__home { flex: none; padding-inline: 1rem 1.2rem !important; }
.pgnav__item { flex: 1 1 0; }
.pgnav .tt, .pgnav .pg-no, .pgnav__home {
  font-size: 1rem;
  line-height: 1.1;
  font-variation-settings: "wdth" 75, "wght" 300;
  transition: font-variation-settings .45s var(--ease-grid);
}
.pgnav__home { font-variation-settings: "wdth" 75, "wght" 500; }

.pgnav__item.is-current { background: var(--blue); color: var(--paper); }
.pgnav__item.is-current :is(.tt, .pg-no),
.pgnav__item.is-bold :is(.tt, .pg-no) { font-variation-settings: "wdth" 100, "wght" 800; }
@media (hover: hover) {
  .pgnav > a:hover { background: var(--blue); color: var(--paper); }
  .pgnav__home:hover { font-variation-settings: "wdth" 100, "wght" 800; }
  .pgnav[data-mode="full"] .pgnav__item:hover :is(.tt, .pg-no) { font-variation-settings: "wdth" 100, "wght" 800; }
}

/* numbers only */
.pgnav[data-mode="numbers"] .pgnav__item { justify-content: center; }
.pgnav[data-mode="numbers"] .pgnav__item .tt { display: none; }

/* measuring: every cell at its own content width, names shown, no motion */
.pgnav.is-measuring > a { flex: none !important; min-width: 0 !important; transition: none; }
.pgnav.is-measuring .tt { display: inline !important; }
.pgnav.is-measuring.is-measuring-numbers .tt { display: none !important; }
.pgnav.is-measuring :is(.tt, .pg-no) { transition: none; }

@media (max-width: 640px) {
  .pgnav > a { padding-inline: .5rem; gap: .45rem; }
  .pgnav__home { padding-inline: .6rem .7rem !important; }
}
@media (max-width: 340px) {
  .pgnav__word { display: none; }         /* the smallest phones: the arrow alone */
}

/* --- Tel Aviv: generator and process layouts ----------------------------- */
/* the generator beside two of its loops (Tel Aviv, The archive): the
   interface column is as tall as the two postcards */
.tlv-gen { display: grid; grid-template-columns: minmax(0, .575fr) minmax(0, 1fr); gap: 1px; background: var(--ink); }
.tlv-gen > * { background: var(--paper); min-width: 0; }
.tlv-gen__ui { display: flex; flex-direction: column; }
.tlv-gen__ui .pg-media { flex: 1; min-height: 0; background: #111; }
.tlv-gen__ui img { width: 100%; height: 100%; object-fit: cover; object-position: top; filter: none !important; }
.tlv-gen__loops { display: grid; gap: 1px; background: var(--ink); }
.tlv-gen__loops > * { background: var(--paper); }
@media (max-width: 640px) {
  .tlv-gen { grid-template-columns: minmax(0, 1fr); }
  .tlv-gen__ui .pg-media { flex: none; aspect-ratio: 3 / 4; }
}
/* a step of the process (Tel Aviv, Work in progress), its video beside its stills; the
   video takes N/(N+1) of the width, so with N square stills stacked
   beside it both sides are exactly as tall */
.tlv-step + .tlv-step { border-top: var(--rule); }
.tlv-step__grid { display: grid; gap: 1px; background: var(--ink); }
.tlv-step--1 .tlv-step__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.tlv-step--2 .tlv-step__grid { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.tlv-step--3 .tlv-step__grid { grid-template-columns: minmax(0, 3fr) minmax(0, 1fr); }
.tlv-step__grid > .pg-media, .tlv-step__stills > .pg-media { aspect-ratio: 1; }
.tlv-step__stills { display: grid; gap: 1px; background: var(--ink); align-content: stretch; }
.tlv-step__stills > .pg-media { aspect-ratio: auto; min-height: 0; }
.tlv-step__stills > .pg-media > img { position: absolute; inset: 0; }
.tlv-step--2 .tlv-step__stills { grid-template-rows: repeat(2, minmax(0, 1fr)); }
.tlv-step--3 .tlv-step__stills { grid-template-rows: repeat(3, minmax(0, 1fr)); }
@media (max-width: 640px) {
  .tlv-step__grid { grid-template-columns: minmax(0, 1fr) !important; }
  .tlv-step__stills { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); grid-template-rows: none !important; }
  .tlv-step__stills > .pg-media { aspect-ratio: 1; }
}
