/* ==========================================================================
   layout.css — containers, page shell, grids, section rhythm and the
   pitch-marking background layer.
   ========================================================================== */

/* ---- PAGE SHELL ---------------------------------------------------------- */

.page {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

.page__main { flex: 1 0 auto; }

/* ---- CONTAINERS ---------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--sp-gutter);
}

.container--wide   { max-width: var(--container-wide); }
.container--narrow { max-width: var(--container-narrow); }
.container--bleed  { max-width: none; padding-inline: 0; }

/* ---- SECTIONS ------------------------------------------------------------ */

.section { padding-block: var(--sp-section); }
.section--tight { padding-block: var(--sp-6); }
.section--flush-top { padding-block-start: 0; }

.section--paper   { background-color: var(--c-paper); }
.section--sunk    { background-color: var(--c-surface-3); }
.section--brand   { background-color: var(--c-surface-brand); color: var(--c-text-on-brand); }
.section--accent  { background-color: var(--c-surface-accent); color: var(--c-text-on-accent); }
.section--invert  { background-color: var(--c-surface-invert); color: var(--c-text-invert); }

.section--brand :is(h1, h2, h3, h4, h5, h6) { color: var(--c-text-on-brand); }
.section--accent :is(h1, h2, h3, h4, h5, h6) { color: var(--c-text-on-accent); }
.section--invert :is(h1, h2, h3, h4, h5, h6) { color: var(--c-text-invert); }

/* :not(.btn) matters: these are more specific than .btn, and without it a
   button dropped into an inverted section gets its label recoloured to the
   same value as its own background. */
.section--brand a:not(.btn)  { color: var(--c-accent-on-brand); text-decoration-thickness: max(0.1em, 2px); }
.section--invert a:not(.btn) { color: var(--c-floodlight); }
.section--accent a:not(.btn) { color: var(--c-ink); }

/* ---- GRIDS ---------------------------------------------------------------
   Auto-fitting grids: no media queries needed, and they never overflow at
   320px because the minimum track is clamped against the available width. */

.grid {
  display: grid;
  gap: var(--sp-5);
}

.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }

/* A fixed four-up that collapses to two then one. Used by the asks grid. */
.grid--asks { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }

/* Content plus sidebar. Sidebar drops beneath below ~62rem without a query. */
.grid--sidebar {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 28rem), 1fr));
  align-items: start;
}
.grid--sidebar > .sidebar { flex-basis: 20rem; }

@media (min-width: 62rem) {
  .grid--sidebar { grid-template-columns: minmax(0, 1fr) 20rem; }
}

.grid--gap-tight { gap: var(--sp-3); }
.grid--gap-loose { gap: var(--sp-7); }

/* ---- CLUSTER AND STACK --------------------------------------------------- */

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cluster-gap, var(--sp-3));
  align-items: center;
}
.cluster--between { justify-content: space-between; }
.cluster--end { justify-content: flex-end; }
.cluster--top { align-items: flex-start; }

.stack { display: flex; flex-direction: column; gap: var(--stack-gap, var(--sp-4)); }

/* ---- HORIZONTAL SCROLLER -------------------------------------------------
   Keyboard operable, does not trap scroll, and shows a hint of the next card
   so the affordance is obvious. */

.scroller {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(80%, 21rem);
  gap: var(--sp-5);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-block-end: var(--sp-3);
  padding-inline: var(--sp-1);
}
.scroller > * { scroll-snap-align: start; }

@media (min-width: 62rem) {
  .scroller {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: repeat(3, 1fr);
    overflow-x: visible;
  }
}

/* ---- FULL-BLEED ---------------------------------------------------------- */

.bleed {
  width: 100%;
  margin-inline: 0;
}

/* ---- PITCH MARKINGS ------------------------------------------------------
   Section 4.1: penalty-box arcs, centre circles and corner quadrants drawn as
   thin strokes at low opacity in a background layer. The SVG itself lives
   inline in the markup (see .pitch-marks > svg) so it inherits currentColor
   and costs no request. */

.has-pitch-marks {
  position: relative;
  isolation: isolate;
}

.pitch-marks {
  position: absolute;
  inset: 0;
  z-index: var(--z-under);
  overflow: hidden;
  pointer-events: none;
  color: var(--c-pitch);
  opacity: var(--o-hairline);
}

.pitch-marks svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.pitch-marks--right svg { object-position: right center; }

/* ---- HALFTONE OVERLAY ----------------------------------------------------
   A tileable dot screen, generated as an SVG data URI rather than a PNG so it
   scales, respects the theme and adds no binary asset. Deviation from the
   brief noted in the README. */

.halftone::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--o-halftone);
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Ccircle cx='1.5' cy='1.5' r='1.1' fill='%23000'/%3E%3Ccircle cx='4.5' cy='4.5' r='1.1' fill='%23000'/%3E%3C/svg%3E");
  background-size: var(--halftone-size) var(--halftone-size);
}

:root[data-theme="dark"] .halftone::after { mix-blend-mode: screen; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .halftone::after { mix-blend-mode: screen; }
}

/* ---- DUOTONE PHOTOGRAPHY -------------------------------------------------
   Two brand colours via a blend-mode stack. The image sits under a solid
   shadow-colour layer in multiply and a highlight layer in screen. */

.duotone {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: var(--duo-shadow);
}

.duotone > img,
.duotone > svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.12);
  mix-blend-mode: luminosity;
}

.duotone::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-color: var(--duo-highlight);
  mix-blend-mode: var(--duo-mix);
  opacity: 0.5;
}
