/* ==========================================================================
   modal.css: the detail sheet.

   The sheet is composed of independent blocks that may appear in any
   combination, so nothing here assumes a neighbour exists: every block owns
   its own spacing, and every multi-column grid collapses on its own terms.
   ========================================================================== */

.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.75rem, 3vw, 3rem);
  background: var(--veil);
  backdrop-filter: blur(6px);
  animation: veil-in 0.18s ease-out;
}

/* `.modal` sets display, so the hidden attribute needs to win explicitly. */
.modal[hidden] {
  display: none;
}

.sheet {
  position: relative;
  width: min(56.25rem, 100%);
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--bg);
  box-shadow: var(--shadow-sheet);
  animation: sheet-in 0.24s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.sheet:focus {
  outline: none;
}

/* Close ------------------------------------------------------------------- */

/* A zero-height sticky strip, so the button floats on the hero at rest and
   stays reachable however long the sheet runs. */
.sheet__close-dock {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  height: 0;
  pointer-events: none;
}

/* Once the sheet is scrolled, an opaque band appears under the button. Without
   it the button sits on top of moving prose and slices words in half; with it
   the text passes cleanly out of view, the way any sticky header behaves. */
.sheet__close-dock::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 4.75rem;
  background: var(--bg);
  opacity: 0;
  transition: opacity 0.16s linear;
}

.sheet.is-scrolled .sheet__close-dock::before {
  opacity: 1;
}

.sheet__close {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin: 1rem max(1.125rem, env(safe-area-inset-right)) 0;
  background: var(--bg);
  border: 1px solid var(--edge);
  border-radius: 0;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  pointer-events: auto;
  transition: background 0.15s;
}

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

/* Hero -------------------------------------------------------------------- */

.sheet__hero {
  height: clamp(6.25rem, 18vw, 9.375rem);
  overflow: hidden;
}

.sheet__hero-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
  image-rendering: pixelated;
}

/* Header ------------------------------------------------------------------ */

.sheet__header {
  padding: 2rem var(--sheet-pad) 1.5rem;
  border-bottom: 1px solid var(--rule);
}

/* No hero above it, so the header makes room for the close button itself.
   Unreached by the current content, where every entry is dealt a plate; it is
   here because an entry may legitimately have no art. */
.sheet__close-dock + .sheet__header {
  padding-top: 4.25rem;
}

/* The press popup has neither hero nor header, just the article block, so
   that block is the one that has to leave room for the close button instead. */
.sheet__close-dock + .sheet__block {
  padding-top: 4.25rem;
}

.sheet__kicker {
  margin-bottom: 0.75rem;
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
}

.sheet__title-row {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.sheet__logo {
  flex: none;
  width: clamp(2.25rem, 6vw, 3.125rem);
  height: clamp(2.25rem, 6vw, 3.125rem);
  object-fit: contain;
}

.sheet__title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: var(--fs-sheet);
  line-height: 1.05;
  color: var(--ink);
  text-wrap: balance;
}

/* Lead and facts ---------------------------------------------------------- */

.sheet__primary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 14.375rem;
  gap: 2.875rem;
  padding: 2.125rem var(--sheet-pad) 2.875rem;
}

/* Only one of the two columns has anything in it, so let it take the full width.
   Every current entry fills both, but an entry with just a paragraph is valid. */
.sheet__primary--single {
  grid-template-columns: minmax(0, 1fr);
}

.sheet__standfirst {
  margin-bottom: 1.5rem;
  font-family: var(--serif);
  font-size: var(--fs-lede);
  line-height: 1.55;
  color: var(--ink);
  text-wrap: pretty;
}

.tldr {
  margin-bottom: 1.75rem;
}

.tldr__summary {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.9375rem 1.125rem;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  text-transform: uppercase;
  color: var(--accent);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.tldr__summary:hover {
  background: var(--surface-2);
  border-color: var(--accent);
}

.tldr__summary::-webkit-details-marker {
  display: none;
}

.tldr__summary::after {
  content: "▸";
  margin-left: auto;
  font-size: 0.6875rem;
  color: var(--faint);
  transition: rotate 0.15s ease-out;
}

.tldr[open] > .tldr__summary {
  border-bottom-color: transparent;
}

.tldr[open] > .tldr__summary::after {
  rotate: 90deg;
}

.tldr__panel {
  margin: 0;
  padding: 1.125rem;
  border: 1px solid var(--edge);
  border-top: none;
}

.detail-list {
  margin-bottom: 0;
}

.detail-list__item {
  display: flex;
  gap: 0.8125rem;
  align-items: baseline;
  padding: 0.625rem 0;
  border-bottom: 1px solid var(--surface-2);
  font-family: var(--serif);
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.detail-list__dash {
  flex: none;
  font-family: var(--mono);
  font-size: var(--fs-small);
  color: var(--accent);
}

.sheet__facts .eyebrow {
  margin-bottom: 0.8125rem;
}

.facts {
  margin-bottom: 1.125rem;
  font-size: var(--fs-small);
  line-height: 1.7;
}

.facts dt {
  color: var(--faint);
}

.facts dd {
  margin: 0 0 0.8125rem;
  color: var(--ink);
}

.sheet__links {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--rule);
  padding-top: 0.5rem;
  font-size: var(--fs-small);
  color: var(--muted);
}

.sheet__link {
  display: inline-block;
  padding: 0.6875rem 0;
  transition: color 0.18s;
}

.sheet__link:hover {
  color: var(--accent);
}

/* Sits at the very end of the sheet, outside every content section, because
   it describes the dialog rather than the entry. */
.sheet__hint {
  padding: 0 var(--sheet-pad) 2rem;
  font-size: 0.65625rem;
  color: var(--faint);
}

/* Blocks ------------------------------------------------------------------ */

.sheet__block {
  padding: 0 var(--sheet-pad) 2.125rem;
}

.sheet__block--flush {
  padding-bottom: 0;
}

.sheet__block .eyebrow {
  margin-bottom: 1.125rem;
}

/* Press card -------------------------------------------------------------- */

.press {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: 1.625rem;
  padding: 1.125rem;
  background: var(--surface);
  border: 1px solid var(--edge);
  transition: transform 0.22s, box-shadow 0.22s, border-color 0.22s;
}

.press:hover,
.press:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
  border-color: var(--accent);
}

/* The press popup (opened straight from a press card) has nothing else on
   the page to carry the image, so it runs the thumb as a full banner across
   the top instead of beside the text. */
.press--standalone {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  padding: 0;
  overflow: hidden;
}

.press--standalone .press__frame {
  height: clamp(10rem, 32vw, 15rem);
  overflow: hidden;
}

/* A photo (`--cover`) is meant to fill the banner, but a logo's `width: 62%`
   below was sized for the narrow embedded thumb. At the full banner width
   it blows the mark up past the box and spills into the text underneath. */
.press--standalone .press__img:not(.press__img--cover) {
  width: auto;
  max-width: 40%;
  height: auto;
  max-height: 70%;
}

.press--standalone .press__body {
  padding: 1.5rem 1.75rem 1.75rem;
}

.press--standalone .press__credit {
  padding: 0.5rem 1.75rem 0;
}

/* The thumb is a figure: the frame carries the photo (and, in standalone
   mode, its fixed-height crop), the credit sits below it as a caption. */
.press__thumb {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.press__frame {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 5;
  min-height: 8.25rem;
  background: var(--surface-2);
  overflow: hidden;
}

.press__credit {
  font-size: 0.65625rem;
  color: var(--faint);
  text-align: left;
}

.press__img {
  width: 62%;
  height: auto;
  object-fit: contain;
}

.press__img--cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.press__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.press__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.press__outlet {
  font-size: 0.65625rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}

.press__date {
  font-size: 0.65625rem;
  color: var(--faint);
  white-space: nowrap;
}

.press__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--fs-title);
  line-height: 1.14;
  color: var(--ink);
}

.press__summary {
  font-family: var(--serif);
  font-size: var(--fs-sub);
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.press__dek {
  font-family: var(--serif);
  font-size: var(--fs-sub);
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: pretty;
}

/* Once a `summary` carries the primary blurb, the dek is quoted from the
   original piece rather than read as the description itself. */
.press__dek--quote {
  font-style: italic;
  font-size: var(--fs-small);
  color: var(--faint);
}

.press__dek--quote::before {
  content: "“";
}

.press__dek--quote::after {
  content: "”";
}

.press__foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-top: auto;
  padding-top: 0.625rem;
  font-size: var(--fs-eyebrow);
  color: var(--faint);
}

.press__cta {
  letter-spacing: 0.1em;
  color: var(--accent);
  white-space: nowrap;
}

/* Stats ------------------------------------------------------------------- */

/* Fixed track counts rather than auto-fit: four stats auto-fitting to three
   columns leaves an orphan on the second row. The rule lives on each item, not
   on the container, so a wrapped second row gets its own rule instead of
   butting straight against the first. Column spacing is item padding, which
   keeps that rule unbroken across a row. */
.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 1px solid var(--rule);
}

.stats__item {
  display: flex;
  flex-direction: column;
  padding: 1.375rem 1.875rem 1.5rem 0;
  border-top: 1px solid var(--rule);
}

.stats__value {
  font-family: var(--serif);
  font-size: clamp(2rem, 1.5rem + 1.6vw, 2.625rem);
  line-height: 1;
  color: var(--accent);
}

.stats__key {
  margin-top: 0.625rem;
  font-size: 0.65625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.stats__note {
  margin-top: 0.375rem;
  font-family: var(--serif);
  font-size: 1.03125rem;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
}

/* Flow -------------------------------------------------------------------- */

.flow {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
}

.flow__step {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.flow__card {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  height: 100%;
  padding: 0.875rem 0.9375rem 1rem;
  background: var(--surface);
  border: 1px solid var(--edge);
}

.flow__num {
  font-size: 0.625rem;
  letter-spacing: 0.18em;
  color: var(--accent);
}

.flow__label {
  margin-top: 0.4375rem;
  font-family: var(--serif);
  font-size: var(--fs-row);
  line-height: 1.1;
  color: var(--ink);
}

.flow__note {
  margin-top: 0.5rem;
  font-size: 0.71875rem;
  line-height: 1.5;
  color: var(--muted);
  text-wrap: pretty;
}

/* Always present, even when empty, so a step that ends the chain keeps the
   same card width as one that carries a connector. */
.flow__arrow {
  flex: none;
  width: 1rem;
  text-align: center;
  font-size: 0.875rem;
  color: var(--faint);
}

/* Prose ------------------------------------------------------------------- */

.prose--columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1.5rem 2.75rem;
}

.prose--inset {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 18.75rem;
  gap: 2.75rem;
  align-items: start;
}

/* A figure with no prose beside it: centre it rather than leave a gap. Applies
   when an entry has `inset` and no `body`. */
.prose--figure .inset {
  position: static;
  max-width: 34rem;
  margin-inline: auto;
}

.prose__column {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.inset {
  position: sticky;
  top: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.inset__img {
  width: 100%;
  max-height: 23.75rem;
  object-fit: contain;
}

.inset__cap,
.shot__cap {
  font-size: 0.71875rem;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

/* Chart ------------------------------------------------------------------- */

.chart {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 15.625rem;
  gap: 2.5rem;
  align-items: end;
}

.chart__axis-label {
  margin-bottom: 0.75rem;
  font-size: 0.65625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.chart__plot {
  display: flex;
  align-items: flex-end;
  gap: 0.3125rem;
  height: 11.875rem;
  padding: 0 0.125rem 0 0.375rem;
  border-left: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
}

.chart__bar {
  flex: 1;
  min-height: 1px;
  background: var(--accent);
}

.chart__axis {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.5625rem;
  padding-left: 0.375rem;
  font-size: 0.65625rem;
  color: var(--faint);
}

.chart__caption {
  font-family: var(--serif);
  font-size: var(--fs-sub);
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

/* Reflection -------------------------------------------------------------- */

.reflection {
  display: grid;
  grid-template-columns: 9.375rem minmax(0, 1fr);
  gap: 1.875rem;
  align-items: start;
}

.reflection__aside {
  position: sticky;
  top: 1.5rem;
  font-family: var(--serif);
  font-size: var(--fs-row);
  line-height: 1.3;
  color: var(--faint);
  text-wrap: pretty;
}

.reflection__body {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  border-left: 2px solid var(--edge);
  padding-left: 1.625rem;
}

/* Photographs ------------------------------------------------------------- */

.shots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14.375rem), 1fr));
  gap: 1.125rem;
}

.shot {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.shot__img {
  width: 100%;
  height: 15.625rem;
  object-fit: cover;
  background: var(--surface-2);
  border: 1px solid var(--edge);
}

/* Tablet ------------------------------------------------------------------ */

@media (max-width: 60rem) {
  .sheet__primary,
  .prose--inset,
  .chart {
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
  }

  .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Sticky side-figures have nothing to stick beside once stacked. */
  .inset,
  .reflection__aside {
    position: static;
  }

  .inset__img {
    max-height: 21rem;
  }

  .chart {
    align-items: stretch;
  }

  /* The flow reads top-to-bottom, so the connectors have to turn with it. */
  .flow {
    flex-direction: column;
  }

  .flow__step {
    flex-direction: column;
    align-items: stretch;
  }

  .flow__arrow {
    align-self: center;
  }

  .flow__arrow--turn {
    rotate: 90deg;
  }
}

/* Phone ------------------------------------------------------------------- */

@media (max-width: 45rem) {
  /* Full-height sheet: a centred dialog wastes a phone screen, and the
     rounded-corner look reads as a broken page rather than a card. */
  .modal {
    padding: 0;
    align-items: stretch;
  }

  /* `align-items: stretch` on a fixed, inset-0 overlay already gives the sheet
     the viewport's height, so no vh/svh unit is involved. */
  .sheet {
    width: 100%;
    max-height: none;
    animation-name: sheet-up;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .sheet__header {
    padding-top: 1.5rem;
  }

  .sheet__close-dock + .sheet__header {
    padding-top: 4rem;
  }

  .sheet__close-dock + .sheet__block {
    padding-top: 4rem;
  }

  /* "Esc or click outside" is desktop advice; the close button and the back
     gesture are what a phone reader actually has. */
  .sheet__hint {
    display: none;
  }

  .press {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }

  .press--standalone {
    gap: 0;
  }

  .press__frame {
    min-height: 6.5rem;
    padding: 1rem 0;
  }

  .press--standalone .press__frame {
    height: 9rem;
    padding: 0;
  }

  .press--standalone .press__credit {
    padding: 0.5rem 1.25rem 0;
  }

  .press__img:not(.press__img--cover) {
    width: auto;
    max-height: 5rem;
  }

  .press__foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
  }

  .stats {
    grid-template-columns: minmax(0, 1fr);
  }

  .stats__item {
    padding-right: 0;
  }

  .reflection {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }

  .reflection__body {
    border-left: none;
    padding-left: 0;
  }

  .shot__img {
    height: 13rem;
  }
}
