/* ═══════════════════════════════════════════════════════════
   SOAR Initiative — stylesheet

   PALETTE lives in :root below. Recolouring the entire site is
   an edit to those lines and nothing else.

   Contrast is assigned by ROLE, not by taste: navy carries all
   text on light backgrounds, light blue carries accents, fills
   and borders. Light blue on white measures ~2.9:1, under the
   4.5:1 needed for body text, so it never sets reading copy.
   --accent (#2c6fa8) is the darkened blue used for links, at
   ~5.3:1 on paper.

   Type uses a system font stack — deliberately no Google Fonts,
   which would issue a request to Google on every page load.
   ═══════════════════════════════════════════════════════════ */

:root {
  /* Type — Avenir Next where installed, with close system fallbacks. */
  --font-body: "Avenir Next", Avenir, "Segoe UI", Helvetica, Arial,
    sans-serif;
  --font-display: var(--font-body);

  /* Ink — text on light backgrounds */
  --ink: #0d1b2a; /* headings          ~17:1 on paper */
  --ink-body: #1b3a53; /* body              ~11:1 on paper */
  --ink-muted: #4a6377; /* secondary text    ~6.3:1 on paper */

  /* Navy — used as a background for dark blocks */
  --navy: #0f2438;
  --navy-deep: #0a1826;

  /* Accent — light blue family */
  --accent: #2c6fa8; /* links             ~5.3:1 on paper */
  --accent-strong: #1d5687; /* link hover */
  --accent-soft: #5b9bd5; /* borders, marks */
  --accent-pale: #b8d8ef; /* text on navy, rules */
  --accent-wash: #eef4fa; /* section fills */
  --accent-wash-deep: #dfebf7; /* gradient end */

  --paper: #ffffff;
  --rule: #d8e4ee;

  /* Per-agenda hues for the research figures. Deliberately desaturated
     so they distinguish the three theories without breaking out of the
     restrained palette the rest of the site keeps to. */
  --fig-eut: #b0743a; /* bronze  */
  --fig-infra: #695aa0; /* violet  */
  --fig-active: #37897a; /* teal    */

  --wrap: 62rem;
  --step: 1.5rem;
}

/* ── Reset ───────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-body);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* ── Layout ──────────────────────────────────────────────── */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--step);
}

/* Direct children of <main> are constrained by default… */
main > * {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--step);
}

/* …and .bleed opts out, running edge to edge with its own .wrap inside. */
main > .bleed {
  max-width: none;
  padding-inline: 0;
}

/* Interior pages (no bands) need their own breathing room against the
   header and footer. Pages that open or close on a band zero the
   corresponding side, since the band's own padding already provides it. */
main {
  padding-block: 4rem 5rem;
}

main:has(> .bleed:first-child) {
  padding-top: 0;
}

main > * + * {
  margin-top: 4.5rem;
}

/* Full-bleed bands carry their own vertical padding and sit flush against
   each other, so alternating background colours meet with no white gap. */
main > .bleed {
  margin-top: 0;
  padding-block: 4.5rem;
}

/* If the page ends on a band, its padding is the bottom spacing. */
main:has(> .bleed:last-child) {
  padding-bottom: 0;
}

/* ── Bands ───────────────────────────────────────────────── */

/* Bands host decorative background layers in ::before / ::after.
   `overflow: hidden` keeps oversized shapes from creating horizontal
   scroll; content sits above them via z-index on the inner .wrap. */
.bleed {
  position: relative;
  overflow: hidden;
}

.bleed > .wrap {
  position: relative;
  z-index: 1;
}

.bleed::before,
.bleed::after {
  pointer-events: none;
  z-index: 0;
}

.band--tint {
  background: var(--accent-wash);
  border-block: 1px solid var(--rule);
}

.band--navy {
  background: linear-gradient(140deg, var(--navy) 0%, var(--navy-deep) 100%);
  color: var(--accent-pale);
}

.band--navy h2,
.band--navy h3 {
  color: var(--paper);
}

.band--navy .eyebrow {
  color: var(--accent-soft);
}

.band--navy .eyebrow::after {
  background: linear-gradient(to right, var(--accent-soft), transparent);
}

.band--navy a {
  color: var(--accent-pale);
}

.band--navy a:hover {
  color: var(--paper);
}

/* ── Background elements ─────────────────────────────────────
   Decorative only, drawn entirely with CSS gradients so the site
   still makes zero external requests. Each is masked so it fades
   out rather than ending abruptly, and all sit at very low alpha
   so text contrast is untouched.
   ─────────────────────────────────────────────────────────── */

/* Dot grid across the hero, fading toward the bottom right. */
.hero-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    rgba(45, 111, 168, 0.22) 1px,
    transparent 1px
  );
  background-size: 22px 22px;
  -webkit-mask-image: linear-gradient(to bottom right, #000, transparent 62%);
  mask-image: linear-gradient(to bottom right, #000, transparent 62%);
}

/* Phase-portrait figure in the hero (inline SVG, see hero-figure.njk).
   Replaces the earlier concentric-ring gradient with actual drawn shape.
   Sized in rem so it scales with the type rather than the viewport. */
.hero-figure {
  position: absolute;
  top: 50%;
  right: -5rem;
  transform: translateY(-50%);
  width: 31rem;
  height: 31rem;
  z-index: 0;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(circle, #000 52%, transparent 76%);
  mask-image: radial-gradient(circle, #000 52%, transparent 76%);
}

/* On narrower screens it sits behind the text, so pull it further out
   and fade it down rather than letting it compete. */
@media (max-width: 62rem) {
  .hero-figure {
    right: -13rem;
    opacity: 0.5;
  }
}

/* ── Research agendas: expandable notes and hover figures ────
   Native details elements make the theory notes accessible by pointer
   and keyboard. Hovering also fades up each theory's diagram alongside.
   Targeting is done with :has(), so this page still ships no JavaScript.

   The figures are decorative — every theory is named in the text, so
   nothing here is information-only-on-hover. They're aria-hidden, and
   they're removed entirely below 62rem, where there is no room and no
   hover to speak of.
   ─────────────────────────────────────────────────────────── */

.agendas {
  position: relative;
}

.agendas__col {
  max-width: 36rem;
}

.agendas__hint {
  font-size: 0.85rem;
  color: var(--ink-muted);
  font-style: italic;
  margin-top: 1rem;
}

.agendas__stage {
  position: absolute;
  top: 50%;
  right: -1rem;
  transform: translateY(-50%);
  width: 23rem;
  height: 23rem;
  pointer-events: none;
}

.agenda-figure {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: scale(0.94);
  transition:
    opacity 0.45s ease,
    transform 0.45s ease;
}

.agendas:has(li[data-fig="eut"]:hover) .agenda-figure[data-fig="eut"],
.agendas:has(li[data-fig="infra"]:hover) .agenda-figure[data-fig="infra"],
.agendas:has(li[data-fig="active"]:hover) .agenda-figure[data-fig="active"] {
  opacity: 0.9;
  transform: scale(1);
}

/* Signal that the rows respond to the pointer. */
.theories--live > li {
  transition:
    border-left-color 0.25s ease,
    transform 0.25s ease;
}

.theories--live > li:hover {
  transform: translateX(3px);
}

.theories--live li[data-fig="eut"]:hover {
  border-left-color: var(--fig-eut);
}

.theories--live li[data-fig="infra"]:hover {
  border-left-color: var(--fig-infra);
}

.theories--live li[data-fig="active"]:hover {
  border-left-color: var(--fig-active);
}

@media (max-width: 62rem) {
  .agendas__stage,
  .agendas__hint {
    display: none;
  }

  .agendas__col {
    max-width: none;
  }
}

/* Reveal still works; it just arrives without the movement. */
@media (prefers-reduced-motion: reduce) {
  .agenda-figure {
    transition: opacity 0.2s ease;
    transform: none;
  }

  .agendas:has(li:hover) .agenda-figure {
    transform: none;
  }

  .theories--live > li:hover {
    transform: none;
  }
}

/* Section figures — smaller siblings of .hero-figure, sitting to the
   right of body copy inside a band. Body text is capped at 68ch, which
   leaves the right-hand space these occupy. */
.band-figure {
  position: absolute;
  top: 50%;
  right: -2rem;
  transform: translateY(-50%);
  width: 23rem;
  height: 23rem;
  z-index: 0;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(circle, #000 58%, transparent 82%);
  mask-image: radial-gradient(circle, #000 58%, transparent 82%);
}

/* As the column narrows the figure would start colliding with text, so
   pull it out and fade it before removing it entirely. */
@media (max-width: 68rem) {
  .band-figure {
    right: -7rem;
    opacity: 0.4;
  }
}

@media (max-width: 46rem) {
  .band-figure {
    display: none;
  }
}

/* ── Angled band edges ───────────────────────────────────────
   A band pulls itself up by the angle height and clips a diagonal
   off its top edge, so the previous band shows through the gap.
   Extra top padding keeps content clear of the slope.
   Selector is `main > .bleed.band--angled` so it outweighs the
   `main > .bleed { margin-top: 0 }` rule above. */

main > .bleed.band--angled {
  --angle: 3.5rem;
  margin-top: calc(var(--angle) * -1);
  padding-top: calc(4.5rem + var(--angle));
  clip-path: polygon(0 var(--angle), 100% 0, 100% 100%, 0 100%);
}

@media (max-width: 40rem) {
  main > .bleed.band--angled {
    --angle: 2rem;
  }
}

/* Fine diagonal hatching on tinted bands. */
.band--tint::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    135deg,
    rgba(45, 111, 168, 0.06) 0 1px,
    transparent 1px 15px
  );
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent 85%);
  mask-image: linear-gradient(to bottom, #000, transparent 85%);
}

/* Navy bands: pale dot grid plus a soft glow in the top corner. */
.band--navy::before,
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    rgba(184, 216, 239, 0.16) 1px,
    transparent 1px
  );
  background-size: 24px 24px;
  -webkit-mask-image: linear-gradient(to top right, #000, transparent 68%);
  mask-image: linear-gradient(to top right, #000, transparent 68%);
  pointer-events: none;
  z-index: 0;
}

.band--navy::after {
  content: "";
  position: absolute;
  top: -40%;
  right: -6rem;
  width: 36rem;
  height: 36rem;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(91, 155, 213, 0.2),
    transparent 62%
  );
}

/* The footer is not a .bleed, so it needs its own containment. */
.site-footer {
  position: relative;
  overflow: hidden;
}

.site-footer__inner {
  position: relative;
  z-index: 1;
}

/* Respect a reduced-motion / reduced-data preference by dropping the
   heavier decorative layers. */
@media (prefers-reduced-motion: reduce) {
  .hero-band::after,
  .band--navy::after {
    display: none;
  }
}

/* ── Typography ──────────────────────────────────────────── */

h1,
h2,
h3 {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.18;
  letter-spacing: -0.005em;
  margin: 0 0 0.75rem;
  font-weight: 600;
}

h1 {
  font-size: clamp(2rem, 5vw, 2.85rem);
}
h2 {
  font-size: clamp(1.4rem, 3vw, 1.8rem);
}
h3 {
  font-size: 1.125rem;
}

p {
  margin: 0 0 1.1rem;
  max-width: 68ch;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--accent-strong);
  text-decoration-thickness: 2px;
}

/* The lede stays serif so the hero reads as one typographic unit. */
.lede {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.55;
  color: var(--ink-body);
}

.muted {
  color: var(--ink-muted);
}

/* Accent label above a heading */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 0.7rem;
}

/* Short accent rule trailing the eyebrow label */
.eyebrow::after {
  content: "";
  flex: 1;
  height: 2px;
  background: linear-gradient(
    to right,
    var(--accent-soft),
    transparent
  );
  max-width: 8rem;
}

/* ── Accessibility ───────────────────────────────────────── */

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
}

.skip-link:focus {
  left: var(--step);
  top: 0.5rem;
  z-index: 10;
  background: var(--paper);
  padding: 0.6rem 1rem;
  border: 2px solid var(--accent);
}

/* ── Header ──────────────────────────────────────────────── */

/* Navy header, bookending the navy footer. */
.site-header {
  background: linear-gradient(140deg, var(--navy) 0%, var(--navy-deep) 100%);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.4rem;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--paper);
  text-decoration: none;
}

.wordmark__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: 0.01em;
}

/* The expansion is deliberately quiet — separated by a hairline rule,
   smaller and in pale blue, so the short name stays dominant. */
.wordmark__expansion {
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  color: var(--accent-pale);
  padding-left: 0.7rem;
  border-left: 1px solid rgba(184, 216, 239, 0.35);
}

/* Below this width it would crowd the nav, so it drops out. */
@media (max-width: 44rem) {
  .wordmark__expansion {
    display: none;
  }
}

/* Accent block before the wordmark — a mark that needs no logo file
   and survives a rename. */
.wordmark::before {
  content: "";
  flex: 0 0 auto; /* a flex item now that .wordmark is a flex row */
  width: 0.55rem;
  height: 1.1rem;
  border-radius: 1px;
  background: linear-gradient(
    to bottom,
    var(--accent-pale),
    var(--accent-soft)
  );
}

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.95rem;
}

.nav a {
  color: var(--accent-pale);
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 2px solid transparent;
}

.nav a:hover {
  color: var(--paper);
  border-bottom-color: var(--accent-soft);
}

.nav a[aria-current="page"] {
  color: var(--paper);
  font-weight: 650;
  border-bottom-color: var(--accent-soft);
}

/* ── Hero band ───────────────────────────────────────────── */

.hero-band {
  background:
    radial-gradient(
      60rem 26rem at 15% -10%,
      var(--accent-wash) 0%,
      transparent 70%
    ),
    linear-gradient(160deg, var(--accent-wash) 0%, var(--accent-wash-deep) 100%);
  border-bottom: 1px solid var(--rule);
  padding-block: 4.5rem 4rem;
}

.hero h1 {
  max-width: 20ch;
}

.hero .lede {
  max-width: 56ch;
  margin-bottom: 0;
}

/* ── Grids ───────────────────────────────────────────────── */

.grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  margin-top: 2rem;
}

.card {
  background: var(--accent-wash);
  border-radius: 6px;
  border-top: 3px solid var(--accent-soft);
  padding: 1.5rem;
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(15, 36, 56, 0.09);
}

.card h3 {
  margin-bottom: 0.4rem;
}

.card p {
  margin-bottom: 0;
  font-size: 0.97rem;
}

/* Two even columns that collapse to one on narrow screens. */
.grid--two {
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 2.5rem;
}

/* Theory lists: accent rules instead of bullets. */
.theories {
  list-style: none;
  margin: 0.75rem 0 1.1rem;
  padding: 0;
}

.theories > li {
  padding: 0.5rem 0 0.5rem 1.1rem;
  border-left: 3px solid var(--accent-soft);
  margin-bottom: 0.4rem;
  background: linear-gradient(
    to right,
    var(--accent-wash),
    transparent 70%
  );
}

.theory-details summary {
  cursor: pointer;
  font-weight: 600;
}

.theory-details summary::marker {
  color: var(--accent);
}

.theory-details[open] summary {
  color: var(--ink);
  margin-bottom: 0.85rem;
}

.theory-notes {
  margin: 0;
  padding-left: 1.25rem;
}

.theory-notes li {
  margin-bottom: 0.8rem;
  padding-left: 0.25rem;
}

.theory-notes li::marker {
  color: var(--accent-soft);
}

.theory-notes li:last-child {
  margin-bottom: 0.25rem;
}

/* On a tinted band the card fill would match the background, so invert
   to white — the card reads as raised rather than disappearing. */
.band--tint .card {
  background: var(--paper);
}

/* Numbered variant for the research directions */
.grid--numbered {
  counter-reset: card;
}

.grid--numbered .card {
  counter-increment: card;
}

.grid--numbered .card h3::before {
  content: counter(card, decimal-leading-zero);
  display: block;
  font-size: 1.6rem;
  font-weight: 750;
  line-height: 1;
  color: var(--accent-soft);
  margin-bottom: 0.5rem;
  letter-spacing: -0.02em;
}

/* Unfilled variant — used for team members, where a tinted card would
   make the grid look heavier than it should. */
.card--plain {
  background: none;
  border-top: none;
  padding: 0;
}

.card--plain:hover {
  transform: none;
  box-shadow: none;
}

/* Team member: circular portrait */
.person__photo {
  width: 6.5rem;
  height: 6.5rem;
  border-radius: 50%;
  object-fit: cover;
  /* Deliberately faint: a solid fill reads as a broken image rather than
     as a slot waiting for a portrait. */
  background: linear-gradient(
    150deg,
    var(--accent-wash),
    var(--accent-wash-deep)
  );
  border: 1px solid var(--rule);
  margin-bottom: 0.9rem;
}

.person__role {
  color: var(--accent);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

/* ── Panels ──────────────────────────────────────────────── */

.panel {
  background: var(--accent-wash);
  border-left: 4px solid var(--accent-soft);
  border-radius: 4px;
  padding: 2rem;
}

.panel > :last-child {
  margin-bottom: 0;
}

/* Dark variant — a strong colour block to anchor the page */
.panel--dark {
  background: linear-gradient(140deg, var(--navy) 0%, var(--navy-deep) 100%);
  border-left: 4px solid var(--accent-soft);
  color: var(--accent-pale);
}

.panel--dark h2 {
  color: var(--paper);
}

.panel--dark a {
  color: var(--accent-pale);
  text-decoration-thickness: 1px;
}

.panel--dark a:hover {
  color: var(--paper);
}

/* ── Post list ───────────────────────────────────────────── */

.posts {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
}

.posts li {
  padding: 1.3rem 1rem 1.3rem 0;
  border-top: 1px solid var(--rule);
  transition: padding-left 0.15s ease;
}

.posts li:last-child {
  border-bottom: 1px solid var(--rule);
}

.posts li:hover {
  padding-left: 0.6rem;
  border-left: 3px solid var(--accent-soft);
}

.posts h3 {
  margin-bottom: 0.25rem;
}

.posts a {
  text-decoration: none;
}

.posts a:hover {
  text-decoration: underline;
}

.post__date {
  color: var(--ink-muted);
  font-size: 0.87rem;
}

/* ── Article ─────────────────────────────────────────────── */

.article {
  max-width: 42rem;
}

.article h2 {
  margin-top: 2.5rem;
}

.article blockquote {
  margin: 1.5rem 0;
  padding: 0.5rem 0 0.5rem 1.2rem;
  border-left: 3px solid var(--accent-soft);
  color: var(--ink-muted);
}

/* ── Footer ──────────────────────────────────────────────── */

/* No margin here: bottom spacing comes either from the last band's own
   padding (homepage) or from main's padding-bottom (interior pages).
   Adding a margin as well stacks the two into an oversized gap. */
.site-footer {
  background: linear-gradient(140deg, var(--navy) 0%, var(--navy-deep) 100%);
  color: var(--accent-pale);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  padding-block: 2.5rem;
}

.site-footer__name {
  margin: 0;
  color: var(--paper);
  font-weight: 650;
  font-size: 1rem;
}

.nav--footer {
  font-size: 0.9rem;
}

.nav--footer a {
  color: var(--accent-pale);
}

.nav--footer a:hover {
  color: var(--paper);
  border-bottom-color: var(--accent-pale);
}
