/*
 * Work case study (UI round 13, operator-directed; Design amendment
 * AMD-20261001-WORK-CASE-STUDY).
 *
 * Loaded after work-detail.css, which keeps the plate, crop and key rules.
 * This sheet composes the amended Work detail:
 *   1. the top: title, tagline and the action row beside (or above) the hero,
 *      and the stamp as a compact strip with the maturity pill;
 *   2. the story as a role-coloured sequence with a progress rail;
 *   3. Scale as number tiles and Stack as chips;
 *   4. the image viewer (stage + filmstrip), built by gallery-lightbox.js
 *      from the plain gallery list, which stays the no-JavaScript form;
 *   5. motion extras (hairlines that draw in, glow on frames).
 * Colours come from the scheme tokens and the round 13 role and status tokens
 * in site.css. Motion here is transform and opacity, plus the fog blur the
 * site's emergence already uses for the stage change; every animation and
 * transition resolves at once under the site's reduced-motion contract
 * (reduced-motion.css), and no rule hides content unless script has taken
 * ownership of showing it.
 */

/* ---------------------------------------------------------------------- */
/* 1. The top                                                              */
/* ---------------------------------------------------------------------- */

/* The article lays its blocks out as a wrapping row: the title block and the
   hero share the first line when the column is wide enough for both (about
   52rem; the hero takes the larger share), and stack otherwise, with no
   viewport breakpoint. The header's own
   box is dissolved so its two parts (title block, stamp) take part directly. */
.work-detail {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(1.5rem, 3vw, 2.25rem) clamp(1.5rem, 3vw, 2.5rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.work-detail > .entry-header { display: contents; }
.work-detail > .entry-header > div:first-child { order: 1; flex: 1 1 20rem; min-width: 0; }
.work-detail > .identity-plate { order: 2; flex: 6 1 30rem; min-width: 0; margin: 0; }
.work-detail > .entry-header > .entry-stamp { order: 3; flex: 0 0 100%; min-width: 0; }
.work-detail > .entry-narrative { order: 4; flex: 0 0 100%; min-width: 0; margin: 0; }
.work-detail > .fact-strip { order: 5; flex: 0 0 100%; min-width: 0; margin: 0; }
.work-detail > .gallery { order: 6; flex: 0 0 100%; min-width: 0; margin: 0; }
.work-detail > .verification-links,
.work-detail > .book-launcher { order: 7; flex: 0 0 100%; }

/* The dissolved header's parts fog in with the column (press-fog-motion.css
   animates the article's direct children; the header has no box of its own). */
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .work-detail-surface > .work-detail > .entry-header > div:first-child {
  animation: cardEmerge .9s cubic-bezier(.33, 0, .18, 1) .12s backwards;
}
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .work-detail-surface > .work-detail > .entry-header > .entry-stamp {
  animation: cmdWellIn .55s cubic-bezier(.33, 0, .18, 1) .25s backwards;
}

.work-detail .entry-header .lede { max-width: 46ch; }

/* The title's fallback face is sized to the display face (Fraunces sets these
   titles within about 1.5 percent of Georgia Bold at 89.5 percent, measured in
   layout over the Work titles, and never wider, so the fallback does not
   wrap a title the display face fits), so a late font swap does not re-wrap the title and push the hero. */
@font-face {
  font-family: "Tarva Title Fallback";
  src: local("Georgia Bold"), local("Georgia-Bold");
  font-weight: 100 900;
  size-adjust: 89.5%;
}
.work-detail .entry-header h1 { font-family: "Fraunces", "Tarva Title Fallback", Georgia, "Times New Roman", serif; }

/* The action row: the entry's own links (hosted book, public site, store
   links) as utility keys directly under the tagline, then the availability
   line. The section labels stay for assistive technology. */
.work-detail .entry-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  margin-top: 1.35rem;
}
.work-detail .entry-actions > section,
.work-detail .entry-actions .verification-link-body,
.work-detail .entry-actions .book-launcher > div { display: contents; }
.work-detail .entry-actions .narrative-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.work-detail .entry-actions .inline-action { order: 1; margin-top: 0; padding: 0 16px; background-color: var(--utility-key); }
.work-detail .entry-actions [data-book-launcher-link]::after { content: "→"; margin-left: .55rem; color: var(--cyan); }
.work-detail .entry-actions :is(.availability-note, .linkless-reason) {
  order: 2;
  flex: 0 0 100%;
  max-width: 52ch;
  color: var(--text-body);
  font-size: .875rem;
  line-height: 1.55;
}

/* The stamp: one compact strip (Year, Status, Role side by side). */
.work-detail .entry-stamp { padding: 12px 18px 14px; }
.work-detail .entry-stamp dl {
  grid-template-columns: none;
  grid-template-rows: auto auto;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  align-items: start;
  gap: 6px 22px;
}
.work-detail .entry-stamp dt,
.work-detail .entry-stamp dd { padding: 0; border-top: 0; }
.work-detail .entry-stamp dd { align-self: start; }

/* The maturity pill: tone from the governed status (work-detail.mjs
   STATUS_TONE_BY_STATUS), a dot, and a slow pulse only for live work. */
.work-detail .entry-stamp .maturity {
  --pill-word: var(--status-still);
  --pill-dot: var(--status-still-dot);
  --pill-line: var(--status-still-line);
  --pill-ground: var(--status-still-ground);
  position: relative;
  justify-self: start;
  margin-top: -3px;
  padding: 4px 11px 4px 25px;
  border: 1px solid var(--pill-line);
  border-radius: 13px;
  color: var(--pill-word);
  background: var(--pill-ground);
  font-weight: 600;
}
.work-detail .entry-stamp .maturity[data-status-tone="live"] { --pill-word: var(--status-live); --pill-dot: var(--status-live-dot); --pill-line: var(--status-live-line); --pill-ground: var(--status-live-ground); }
.work-detail .entry-stamp .maturity[data-status-tone="beta"] { --pill-word: var(--status-beta); --pill-dot: var(--status-beta-dot); --pill-line: var(--status-beta-line); --pill-ground: var(--status-beta-ground); }
.work-detail .entry-stamp .maturity[data-status-tone="build"] { --pill-word: var(--status-build); --pill-dot: var(--status-build-dot); --pill-line: var(--status-build-line); --pill-ground: var(--status-build-ground); }
.work-detail .entry-stamp .maturity::before,
.work-detail .entry-stamp .maturity::after {
  content: "";
  position: absolute;
  top: calc(4px + .725em - 3.5px);
  left: 10px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pill-dot);
}
.work-detail .entry-stamp .maturity::after { display: none; }
.work-detail .entry-stamp .maturity[data-status-tone="live"]::after {
  display: block;
  animation: statusPulse 2.8s cubic-bezier(.33, 0, .18, 1) infinite;
}
@keyframes statusPulse {
  0%   { opacity: .55; transform: scale(1); }
  70%  { opacity: 0;   transform: scale(2.9); }
  100% { opacity: 0;   transform: scale(2.9); }
}

/* ---------------------------------------------------------------------- */
/* 2. The story: a role-coloured sequence                                  */
/* ---------------------------------------------------------------------- */

.work-detail .entry-narrative {
  position: relative;
  display: grid;
  gap: 14px;
  max-width: none;
  padding: 0 0 0 34px;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

/* The progress rail: a hairline track and a fill that follows the scroll
   (work-story.js sets --story-progress); without script it is simply full. */
.work-detail .entry-narrative::before,
.work-detail .entry-narrative::after {
  content: "";
  position: absolute;
  top: 26px;
  bottom: 26px;
  left: 10px;
  width: 2px;
  border-radius: 1px;
  background: var(--rule);
  pointer-events: none;
}
.work-detail .entry-narrative::after {
  background: linear-gradient(180deg, var(--role-problem-edge), var(--role-system-edge) 30%, var(--role-outcome-edge) 55%, var(--role-proof-edge) 78%, var(--role-role-edge));
  transform: scaleY(var(--story-progress, 1));
  transform-origin: 50% 0;
}

/* One card per section. Firstlight status edge and hover bloom: values copied
   from tarva-ui-library src/themes/serras/tokens.css ("Firstlight card
   system", commit 7d1969a) so this site does not depend on the library:
   a tinted edge (role hue at 34 to 38 percent), a resting glow
   (0 22px 52px -32px, 22 to 28 percent), a bloom revealed by opacity
   (0 26px 64px -20px, 55 percent), fast expo-out in (.26s / .16s) and a slow
   soft-decel out (.46s / .34s). The library scales to 1.028; these full-width
   cards use 1.012.
   The section itself never transforms: its surface is the ::after layer and
   its bloom is a layer behind that, and only those two scale on hover. The
   rail dot (::before) therefore stays exactly on the rail line. */
.work-detail .entry-narrative .narrative {
  --card-word: var(--role-role);
  --card-edge: var(--role-role-edge);
  --card-ground: var(--role-role-ground);
  --card-edge-op: 34%;
  --card-rest-op: 0%;
  position: relative;
  isolation: isolate;
  display: block;
  max-width: none;
  margin: 0;
  padding: 19px 25px 22px 25px;
  border: 0;
}
.work-detail .entry-narrative .narrative:first-child,
.work-detail .entry-narrative .narrative:last-child { padding: 19px 25px 22px 25px; border: 0; }
.work-detail .entry-narrative .narrative[data-narrative-section="problem"] { --card-word: var(--role-problem); --card-edge: var(--role-problem-edge); --card-ground: var(--role-problem-ground); --card-edge-op: 38%; --card-rest-op: 28%; }
.work-detail .entry-narrative .narrative[data-narrative-section="system"] { --card-word: var(--role-system); --card-edge: var(--role-system-edge); --card-ground: var(--role-system-ground); --card-rest-op: 26%; }
.work-detail .entry-narrative .narrative[data-narrative-section="outcome"] { --card-word: var(--role-outcome); --card-edge: var(--role-outcome-edge); --card-ground: var(--role-outcome-ground); --card-rest-op: 24%; }
.work-detail .entry-narrative .narrative[data-narrative-section="proof"] { --card-word: var(--role-proof); --card-edge: var(--role-proof-edge); --card-ground: var(--role-proof-ground); --card-rest-op: 26%; }

.work-detail .entry-narrative .narrative-label { margin: 0 0 .6rem; color: var(--card-word); }
.work-detail .entry-narrative .narrative-copy p { max-width: 72ch; }

/* The card surface (edge, tinted ground, resting glow). */
.work-detail .entry-narrative .narrative::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  border: 1px solid color-mix(in oklab, var(--card-edge) var(--card-edge-op), transparent);
  border-left: 3px solid var(--card-edge);
  border-radius: var(--radius-well);
  background: linear-gradient(var(--card-ground), var(--card-ground)), var(--well);
  box-shadow: 0 22px 52px -32px color-mix(in oklab, var(--card-edge) var(--card-rest-op), transparent);
  pointer-events: none;
  transform: scale(1);
  transition: transform .46s cubic-bezier(.33, 0, .18, 1), border-color .34s cubic-bezier(.33, 0, .18, 1);
}
/* The bloom (role-coloured, revealed by opacity), behind the surface. */
.work-detail .entry-narrative .narrative-copy::before {
  content: "";
  position: absolute;
  z-index: -2;
  inset: 0;
  border-radius: var(--radius-well);
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 26px 64px -20px color-mix(in oklab, var(--card-edge) var(--bloom-strength), transparent);
  transform: scale(1);
  transition: opacity .32s cubic-bezier(.4, 0, .2, 1), transform .46s cubic-bezier(.33, 0, .18, 1);
}
@media (hover: hover) {
  .work-detail .entry-narrative .narrative:hover { z-index: 1; }
  .work-detail .entry-narrative .narrative:hover::after {
    border-color: color-mix(in oklab, var(--card-edge) 58%, transparent);
    border-left-color: var(--card-edge);
    transform: scale(1.012);
    transition: transform .26s cubic-bezier(.16, 1, .3, 1), border-color .16s cubic-bezier(.16, 1, .3, 1);
  }
  .work-detail .entry-narrative .narrative:hover .narrative-copy::before {
    opacity: 1;
    transform: scale(1.012);
    transition: opacity .28s cubic-bezier(.16, 1, .3, 1) .03s, transform .26s cubic-bezier(.16, 1, .3, 1);
  }
}

/* The rail's dot for each section: a plain filled circle centred on the rail
   line (no ring, box or ground of its own; a soft glow of its own colour in
   the dark scheme only). Lit by default; once the script
   owns the rail (data-rail="live") a dot lights as its section is reached. */
.work-detail .entry-narrative .narrative::before {
  content: "";
  position: absolute;
  top: 21px;
  left: -29px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--card-edge);
  box-shadow: 0 0 12px color-mix(in oklab, var(--card-edge) var(--dot-glow), transparent);
  transition: background-color .5s cubic-bezier(.33, 0, .18, 1), box-shadow .5s cubic-bezier(.33, 0, .18, 1), transform .5s cubic-bezier(.16, 1, .3, 1);
}
.work-detail .entry-narrative[data-rail="live"] .narrative:not([data-lit="true"])::before {
  background: var(--control-line);
  box-shadow: none;
  transform: scale(.67);
}

/* Staggered emergence as a card is reached (work-story.js marks only cards
   that start below the fold; nothing is hidden without it). Reuses the site's
   cmdWellIn, with the card's index as its delay. */
.work-detail [data-emerge="wait"] { opacity: 0; }
.work-detail [data-emerge="in"] { animation: cmdWellIn .6s cubic-bezier(.33, 0, .18, 1) calc(var(--emerge-index, 0) * 80ms) backwards; }

/* ---------------------------------------------------------------------- */
/* 3. Scale tiles and Stack chips                                          */
/* ---------------------------------------------------------------------- */

.work-detail .fact-strip { position: relative; gap: 14px; padding-top: 22px; }
.work-detail .fact-strip p { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.work-detail .fact-strip .fact-sep { display: none; }
.work-detail .fact-strip .fact-token {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 5px 11px;
  border: 1px solid var(--chip-line);
  border-radius: var(--radius-control);
  color: var(--text-hi);
  background: var(--chip-ground);
  font: 500 .75rem/1.35 var(--font-meta, "JetBrains Mono", ui-monospace, SFMono-Regular, monospace);
  letter-spacing: .02em;
}
.work-detail .fact-strip .fact-token--figure {
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 3px;
  min-width: 6.75rem;
  padding: 10px 14px 11px;
  border-color: color-mix(in oklab, var(--role-system-edge) 44%, transparent);
  border-radius: var(--radius-key);
  color: var(--text-2);
  background: linear-gradient(var(--role-system-ground), var(--role-system-ground)), var(--chip-ground);
}
.work-detail .fact-strip .fact-figure {
  display: block;
  color: var(--text-hi);
  font: 600 1.75rem/1 var(--font-display, "Fraunces", Georgia, serif);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: 0;
}

/* ---------------------------------------------------------------------- */
/* 4. The image viewer: stage and filmstrip                                */
/* ---------------------------------------------------------------------- */

.work-detail .gallery { position: relative; padding-top: 22px; }
.work-detail .gallery[data-viewer="ready"] { display: block; }
.work-detail .gallery[data-viewer="ready"].two { grid-template-columns: none; }

.work-detail .viewer-stage { position: relative; }
.work-detail .viewer-track { display: grid; }
.work-detail .viewer-track > .media-frame { grid-area: 1 / 1; min-width: 0; margin: 0; }
.work-detail .viewer-track > .media-frame:not([data-active="true"]) { visibility: hidden; pointer-events: none; }
.work-detail .viewer-track > .media-frame[data-state="in"] { animation: viewerIn .44s cubic-bezier(.33, 0, .18, 1) both; }
.work-detail .viewer-track > .media-frame[data-state="out"] { visibility: visible; animation: viewerOut .17s cubic-bezier(.45, .05, .6, 1) both; }
@keyframes viewerIn {
  from { opacity: 0; filter: blur(10px); transform: scale(.985); }
  to   { opacity: 1; filter: none; transform: none; }
}
@keyframes viewerOut {
  from { opacity: 1; filter: none; }
  to   { opacity: 0; filter: blur(10px); }
}

/* Every screen sits in the same box (the widest-shaped screen's ratio), so a
   change of image never moves the page. */
.work-detail .viewer-track > .media-frame > img,
.work-detail .viewer-track .viewer-browser { width: 100%; aspect-ratio: var(--stage-ratio, 16 / 10); }
.work-detail .viewer-track > .media-frame > img { height: auto; object-fit: contain; cursor: zoom-in; }

/* A full-page capture scrolls inside a browser-style frame. */
.work-detail .viewer-track .viewer-browser {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line-detail);
  border-radius: 8px;
  background: var(--well);
}
.work-detail .viewer-track .viewer-chrome {
  display: flex;
  flex: none;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  border-bottom: 1px solid var(--line-detail);
  background: var(--chip-ground);
}
.work-detail .viewer-track .viewer-chrome i { width: 8px; height: 8px; border-radius: 50%; background: var(--control-line); }
.work-detail .viewer-track .viewer-chrome b { flex: 1; max-width: 22rem; height: 14px; margin-left: 10px; border: 1px solid var(--line-detail); border-radius: 7px; background: var(--well); }
.js .work-detail .viewer-track .media-frame--tall .media-crop {
  flex: 1;
  width: auto;
  min-height: 0;
  aspect-ratio: auto;
  max-height: none;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-mask-image: none;
  mask-image: none;
  cursor: zoom-in;
}
.js .work-detail .viewer-track .media-frame--tall .media-crop img { width: 100%; height: auto; object-fit: fill; border-radius: 0; }
.work-detail .viewer-track .media-frame--tall .media-crop:focus-visible { box-shadow: inset var(--focus-ring); }
.work-detail .gallery[data-viewer="ready"] .media-full-link { display: none; }

/* Controls under the stage. */
.work-detail .viewer-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 0 10px;
}
.work-detail .viewer-bar button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--control-line);
  border-radius: var(--radius-control);
  color: var(--text-hi);
  background: var(--utility-key);
  box-shadow: var(--lip);
  font: 500 .6875rem/1.2 var(--font-meta, "JetBrains Mono", ui-monospace, monospace);
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color .18s ease-out, transform .28s cubic-bezier(.22, 1, .36, 1);
}
.work-detail .viewer-bar button:hover { border-color: var(--control-line-strong); }
.work-detail .viewer-bar button:active { transform: translateY(1px); }
.work-detail .viewer-count {
  min-width: 4.5rem;
  color: var(--text-2);
  font: 500 .6875rem/1 var(--font-meta, "JetBrains Mono", ui-monospace, monospace);
  font-variant-numeric: tabular-nums;
  letter-spacing: .14em;
  text-align: center;
}
.work-detail .viewer-bar [data-viewer-expand] { margin-left: auto; }

/* The filmstrip. */
.work-detail .viewer-strip {
  display: flex;
  gap: 10px;
  margin: 0 -4px;
  padding: 4px 4px 10px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}
.work-detail .viewer-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 8.5rem;
  aspect-ratio: 16 / 10;
  min-height: 44px;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--control-line);
  border-radius: var(--radius-control);
  background: var(--work-detail-plate);
  scroll-snap-align: start;
  cursor: pointer;
  transition: border-color .18s ease-out, transform .28s cubic-bezier(.22, 1, .36, 1);
}
.work-detail .viewer-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; opacity: .6; transition: opacity .25s ease-out; }
.work-detail .viewer-thumb:hover img,
.work-detail .viewer-thumb:focus-visible img,
.work-detail .viewer-thumb[aria-selected="true"] img { opacity: 1; }
.work-detail .viewer-thumb:hover { transform: translateY(-2px); border-color: var(--control-line-strong); }
.work-detail .viewer-thumb[aria-selected="true"] { border-color: var(--cyan); box-shadow: 0 0 0 1px var(--cyan); }
.work-detail .viewer-thumb:focus-visible { box-shadow: var(--focus-ring); }

/* ---------------------------------------------------------------------- */
/* 5. Motion extras                                                        */
/* ---------------------------------------------------------------------- */

/* Divider hairlines above the facts and the gallery draw in from the left
   when reached (work-story.js); without script they are simply drawn. */
.work-detail .fact-strip::before,
.work-detail .gallery::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), var(--rule) 60%, transparent);
  transform-origin: 0 50%;
  transition: transform 1.1s cubic-bezier(.33, 0, .18, 1);
}
.work-detail [data-draw="wait"]::before { transform: scaleX(0); }

/* Glow on the hero plate and the stage (the bloom is on the wrapper; the
   plate itself clips its image). */
.work-detail .identity-plate { position: relative; transition: transform .46s cubic-bezier(.33, 0, .18, 1); }
.work-detail .identity-plate::after,
.work-detail .viewer-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-plate);
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 26px 64px -20px color-mix(in oklab, var(--cyan) var(--bloom-strength), transparent);
  transition: opacity .32s cubic-bezier(.4, 0, .2, 1);
}
@media (hover: hover) {
  .work-detail .identity-plate:hover { transform: scale(1.012); transition: transform .26s cubic-bezier(.16, 1, .3, 1); }
  .work-detail .identity-plate:hover::after,
  .work-detail .viewer-stage:hover::after { opacity: 1; transition: opacity .28s cubic-bezier(.16, 1, .3, 1) .03s; }
}

/* Reduced motion: nothing scales, pulses or waits. */
@media (prefers-reduced-motion: reduce) {
  .work-detail .entry-narrative .narrative:hover::after,
  .work-detail .entry-narrative .narrative:hover .narrative-copy::before,
  .work-detail .identity-plate:hover,
  .work-detail .viewer-thumb:hover { transform: none; }
  .work-detail .entry-stamp .maturity::after { animation: none; display: none; }
  .work-detail [data-emerge="wait"] { opacity: 1; }
  .work-detail [data-draw="wait"]::before { transform: none; }
}
html[data-motion-preference="reduce"] .work-detail .entry-narrative .narrative:hover::after,
html[data-motion-preference="reduce"] .work-detail .entry-narrative .narrative:hover .narrative-copy::before,
html[data-motion-preference="reduce"] .work-detail .identity-plate:hover,
html[data-motion-preference="reduce"] .work-detail .viewer-thumb:hover { transform: none; }
html[data-motion-preference="reduce"] .work-detail .entry-stamp .maturity::after { animation: none; display: none; }
html[data-motion-preference="reduce"] .work-detail [data-emerge="wait"] { opacity: 1; }
html[data-motion-preference="reduce"] .work-detail [data-draw="wait"]::before { transform: none; }

/* ---------------------------------------------------------------------- */
/* Narrow layouts (approved breakpoints)                                   */
/* ---------------------------------------------------------------------- */

@media (max-width: 767px) {
  .work-detail .entry-stamp dl {
    grid-template-columns: 5.5rem 1fr;
    grid-template-rows: none;
    grid-auto-flow: row;
    gap: 10px .75rem;
  }
  .work-detail .entry-stamp .maturity { margin-top: -5px; }
  .work-detail .entry-narrative { padding-left: 26px; }
  .work-detail .entry-narrative::before,
  .work-detail .entry-narrative::after { left: 6px; }
  .work-detail .entry-narrative .narrative,
  .work-detail .entry-narrative .narrative:first-child,
  .work-detail .entry-narrative .narrative:last-child { padding: 17px 17px 19px 18px; }
  .work-detail .entry-narrative .narrative::before { left: -25px; }

  /* On a phone the stage is a swipeable, snapping row; every screen is laid
     out, so the blur change is not used. */
  .work-detail .viewer-track {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .work-detail .viewer-track::-webkit-scrollbar { display: none; }
  .work-detail .viewer-track > .media-frame { flex: 0 0 100%; scroll-snap-align: center; scroll-snap-stop: always; }
  .work-detail .viewer-track > .media-frame:not([data-active="true"]) { visibility: visible; pointer-events: auto; }
  .work-detail .viewer-track > .media-frame[data-state] { animation: none; }
  .work-detail .viewer-thumb { width: 6.25rem; }
  .work-detail .viewer-bar [data-viewer-expand] { padding: 0 12px; }
}

/* ---------------------------------------------------------------------- */
/* Progressive media (UI round 14, part D)                                 */
/* ---------------------------------------------------------------------- */

/* Blur-up: each shipped hero and gallery image carries a tiny placeholder of
   itself (about a hundred bytes, inline; a derivative of the same cleared
   image), painted behind the image at the image's own box, so the frame is
   never empty while the image loads and nothing moves when it arrives. The
   image paints over it; gallery-lightbox.js removes it once the image is in
   and sharpens an image that arrives late. The image's opacity is never
   lowered, so the largest paint is not delayed. */
:is(.work-detail, .concept-surface) .media-frame img[data-lqip] {
  background-image: var(--lqip);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
}
:is(.work-detail, .concept-surface) .media-frame img[data-lqip-state="in"],
:is(.work-detail, .concept-surface) .media-frame img[data-lqip-state="done"] { background-image: none; }
:is(.work-detail, .concept-surface) .media-frame img[data-lqip-state="in"] { animation: lqipIn .5s cubic-bezier(.33, 0, .18, 1) both; }
@keyframes lqipIn {
  from { filter: blur(10px); }
  to   { filter: blur(0); }
}

/* The identity plate (the hero image, or the logotype plate when there is no
   hero) is the page's largest paint. The column's emergence starts each block
   at opacity 0, which held that paint back by its whole delay and duration; the
   plate now emerges by focus alone (blur and light, never opacity), so it is
   painted with the first frame. */
@keyframes heroFogIn {
  0%   { transform: translateY(7px); filter: blur(5px) brightness(.75); }
  55%  { transform: translateY(2px); filter: blur(2px) brightness(.88); }
  100% { transform: none; filter: none; }
}
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .work-detail-surface > .work-detail > .identity-plate[data-work-identity-plate],
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .concept-surface > .identity-plate[data-identity-plate="hero"] {
  animation-name: heroFogIn;
}

/* On a Work detail without a hero image the title block can be the largest
   paint; the same rule applies: it emerges by focus, never from opacity 0. (The
   header has no box of its own: its title block is the animated part.) */
@keyframes headerFogIn {
  0%   { filter: blur(6px) brightness(.6) saturate(.5); }
  38%  { filter: blur(4px) brightness(.78) saturate(.7); }
  100% { filter: none; }
}
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .work-detail-surface > .work-detail:has(> .identity-plate[data-work-identity-plate="logotype"]) > .entry-header > div:first-child {
  animation-name: headerFogIn;
}

/* A concept page's first screen is its header and its summary; one of them is the
   largest paint, so both emerge by focus as well. */
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .concept-surface > .entry-header:first-child { animation-name: headerFogIn; }
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .concept-surface > .lab-story { animation-name: heroFogIn; }

/* The section pages (Home, Work, Idea Lab, About, Contact): their first block (the
   identity or the title) is the largest paint there, so it follows the same rule.
   To return to the fade from nothing, remove this one rule. */
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .section-surface > :first-child:not(.work-index):not(.content-end-recovery):not(style),
:is(html.js.arrival-seen body, html.js body:not([data-arrival-state="pending"])) [data-route-content] > .section-surface > .work-index > :first-child {
  animation-name: headerFogIn;
}

@media (prefers-reduced-motion: reduce) {
  :is(.work-detail, .concept-surface) .media-frame img[data-lqip-state="in"] { animation: none; }
}
html[data-motion-preference="reduce"] :is(.work-detail, .concept-surface) .media-frame img[data-lqip-state="in"] { animation: none; }

/* ---------------------------------------------------------------------- */
/* Phone rhythm (UI round 17, operator-directed)                           */
/* ---------------------------------------------------------------------- */
/* "under /work/... that also on mobile should have some more space between
   sections". On phones the Work index and the project pages take the Home phone
   rhythm: about 88 to 96px between major sections and more air between the
   blocks inside them. Desktop spacing is unchanged. */
@media (max-width: 767px) {
  /* /work/: title, band, filters, grid. */
  .work-surface .work-index__header.section-intro { margin-bottom: 3rem; }
  .work-surface .work-band { gap: 20px; margin-bottom: 4rem; }
  .work-surface .work-filters { gap: .75rem; margin-bottom: 5.5rem; }
  .work-surface .work-index__list { gap: 20px; margin-bottom: 5.5rem; }
  /* Project pages: header, hero, stamp are one opening group (40px apart); the
     story, the stack and scale, the viewer and the pager are 88 to 96px apart. */
  .work-detail { row-gap: 2.5rem; margin-bottom: 5.5rem; }
  .work-detail > .entry-narrative { margin-top: 3rem; row-gap: 1.5rem; }
  .work-detail > .fact-strip { margin-top: 2rem; row-gap: 1.5rem; }
  .work-detail > .gallery { margin-top: 2rem; }
  :is(.work-detail-surface, .concept-surface) .work-sequence { margin-bottom: 4rem; }
}
