/* ============================================================
   Palette — light editorial ground, single crimson accent.
   Change values here to re-theme the whole site.
   ============================================================ */
:root {
  --bg: #f2f0ed;
  --surface: #e9e6e1;
  --surface-alt: #e4e0da;
  --border: #d6d2cd;
  --text: #14120f;
  --text-muted: #6f6b66;
  --accent: #3b60c5;
  --accent-hover: #283f7d;
  /* Used only for the one accented word in a headline. */
  --highlight: #3b60c5;

  /* Display face is a grotesk, body is a serif — the contrast is what
     gives the pages their editorial feel. Both ship with macOS, so
     nothing is downloaded and nothing silently falls back. */
  --display: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --body: Georgia, "Times New Roman", serif;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --dur-fast: 120ms;
  --dur-base: 160ms;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.03em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

/* One accented word per headline — never two, or neither reads as the
   important one. Wrap it in <em> in the content files. */
h1 em,
h2 em,
.article-title em {
  font-style: normal;
  color: var(--highlight);
}

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--dur-base) var(--ease-out);
}

a:hover,
a:focus {
  color: var(--accent-hover);
  text-decoration: underline;
}

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

:focus:not(:focus-visible) {
  outline: none;
}

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

/* ---------- Shell ---------- */
.shell {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 3rem;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 2rem 0 1.5rem;
  /* Heavier rule than the hairlines elsewhere: this is a masthead. */
  border-bottom: 2px solid var(--text);
}

/* Masthead set in two colours, the way a bias bar is. The two halves
   are separate spans in the markup. */
.wordmark {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.9rem;
  line-height: 1;
  letter-spacing: -0.035em;
}

.wordmark span:first-child {
  color: var(--lever-trust);
}

.wordmark span:last-child {
  color: var(--lever-urgency);
}

.wordmark:hover {
  text-decoration: none;
}

.wordmark:hover span:first-child {
  color: var(--lever-urgency);
}

.wordmark:hover span:last-child {
  color: var(--lever-trust);
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.menu-btn {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color var(--dur-base) var(--ease-out);
}

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

/* ---------- Fullscreen menu ---------- */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--bg);
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease-out);
}

.overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.overlay-close {
  position: absolute;
  top: 1.5rem;
  right: 3rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--text);
  background: none;
  border: 0;
  cursor: pointer;
}

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

/* Each nav word reveals its own drawing. Swap the files in
   images/nav/ for your own illustrations — same filenames. */
.overlay-art {
  justify-self: center;
  width: 300px;
  height: 300px;
  display: grid;
  place-items: center;
  color: var(--text);
}

/* The drawings are ink on white. Multiplying them onto the page colour
   removes the white entirely, so no drawing shows a pale square against
   the cream — and a new drawing dropped in later blends the same way. */
.overlay-art img {
  mix-blend-mode: multiply;
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
  /* Ink-wash drawings arrive on a white background; multiply drops that
     white into the page's cream so no bright square shows behind them. */
  mix-blend-mode: multiply;
}

.overlay-art img.show {
  opacity: 1;
}

.overlay-nav {
  display: flex;
  flex-direction: column;
  padding-right: 3rem;
}

.overlay-nav a {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.2rem, 6vw, 4.6rem);
  line-height: 1.04;
  letter-spacing: -0.035em;
  color: var(--accent);
  width: fit-content;
  border-bottom: 3px solid transparent;
}

.overlay-nav a:hover {
  border-bottom-color: var(--accent);
  text-decoration: none;
}

/* ---------- Language toggle ---------- */
/* Built like the language bar on an episode card: three square
   segments, and each language keeps its own colour wherever it shows
   up on the site. */
:root {
  --lang-en: var(--lever-trust);
  --lang-es: var(--lever-urgency);
  --lang-pl: var(--lever-consensus);
}

.lang-toggle {
  display: inline-flex;
  border: 2px solid var(--text);
  border-radius: 3px;
  overflow: hidden;
  background: #fff;
}

.lang-toggle button {
  border: 0;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-family: var(--display);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 0.38rem 0.85rem;
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}

.lang-toggle button:last-child {
  border-right: 0;
}

.lang-toggle button[data-lang="en"] { --lang: var(--lang-en); }
.lang-toggle button[data-lang="es"] { --lang: var(--lang-es); }
.lang-toggle button[data-lang="pl"] { --lang: var(--lang-pl); }

.lang-toggle button:hover:not(.active) {
  background: color-mix(in srgb, var(--lang) 12%, #fff);
  color: var(--lang);
}

.lang-toggle button.active {
  background: var(--lang);
  color: #fff;
}

/* ---------- Content ---------- */
.content {
  padding: 3.5rem 0 4rem;
}

.site-footer {
  border-top: 1px solid var(--border);
  padding: 1.5rem 0 2.5rem;
  font-family: var(--display);
  font-size: 0.8rem;
  color: var(--text-muted);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.footer-links {
  display: flex;
  gap: 1.5rem;
}

.footer-links a {
  color: var(--accent);
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--accent-hover);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- Home / About ---------- */
.hero {
  display: flex;
  gap: 3rem;
  align-items: flex-start;
  flex-wrap: wrap;
}

.hero-text {
  flex: 1 1 420px;
  min-width: 0;
}

.hero-text h1 {
  font-size: clamp(2.2rem, 4.4vw, 3.4rem);
  max-width: 16ch;
  margin-bottom: 0.35em;
}

.hero-text .tagline {
  color: var(--text-muted);
  font-family: var(--display);
  font-size: 0.95rem;
  font-weight: 700;
  margin: 0;
}

.hero-photo {
  flex: 0 1 265px;
  aspect-ratio: 3 / 4;
  filter: grayscale(1) contrast(1.05);
}

.hero-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.bio {
  margin-top: 1.5rem;
  max-width: 62ch;
}

.bio p {
  margin: 0 0 1.15em;
}

/* ==============================================================
   Episode cards
   --------------------------------------------------------------
   News-card layout: a coloured frame per episode, a pill naming the
   psychological lever, a short data line, a grotesk headline, and a
   segmented language bar along the bottom.

   Lever colours. Each episode inherits one through --lever, so the
   frame, the pill, the accented word in the headline and the language
   bar are always the same colour. Add a new lever here and in
   EPISODE_LEVERS in js/articles.js.
   ============================================================== */
:root {
  --lever-trust: #2f52ae;
  --lever-reward: #a35a12;
  /* Imperial purple, the colour Rome reserved for rank — and dark
     enough to still read as an accent inside a headline. */
  --lever-authority: #5c2a53;
  --lever-urgency: #9d2933;
  /* Social proof — the lever of the crowd. */
  --lever-consensus: #2d6a4a;
  /* Isolation — deep teal, the ink of the "06" poster: a closed room
     rather than a crowd. */
  --lever-isolation: #124f63;
  --lever-default: #3a3733;
  --card: #fbfaf8;
}

.ep-section-label {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 3rem 0 0.9rem;
}

.ep-section-label:first-child {
  margin-top: 0.25rem;
}

.ep-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.1rem;
}

.ep-card {
  --lever: var(--lever-default);
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 3px solid var(--lever);
  border-radius: 4px;
  overflow: hidden;
}

[data-lever="trust"] { --lever: var(--lever-trust); }
[data-lever="reward"] { --lever: var(--lever-reward); }
[data-lever="authority"] { --lever: var(--lever-authority); }
[data-lever="urgency"] { --lever: var(--lever-urgency); }
[data-lever="consensus"] { --lever: var(--lever-consensus); }
[data-lever="isolation"] { --lever: var(--lever-isolation); }
[data-lever="default"] { --lever: var(--lever-default); }

/* Posters run monochrome in the grid, the way wire photos do, and
   return to full colour when the reader points at the card. */
.ep-media {
  background: color-mix(in srgb, var(--lever) 7%, #fff);
}

.ep-media img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center top;
  filter: grayscale(1) contrast(1.04);
  transition: filter 320ms var(--ease-out);
}

.ep-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 0.9rem 1rem 0.85rem;
}

.ep-tagline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.6rem;
  margin: 0 0 0.6rem;
}

.ep-pill {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #fff;
  background: var(--lever);
  padding: 0.24rem 0.5rem;
  border-radius: 2px;
}

.ep-meta {
  font-family: var(--display);
  font-size: 0.72rem;
  color: var(--text-muted);
}

/* In the grid the pill always gets its own line. Spanish and Polish
   labels are longer than English, and letting them wrap freely made
   card headers sit at different heights in different languages. */
.ep-grid .ep-tagline {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
}

.ep-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.28rem;
  line-height: 1.08;
  letter-spacing: -0.03em;
  margin: 0 0 0.5rem;
}

.ep-title a {
  color: var(--text);
  transition: color var(--dur-base) var(--ease-out);
}

/* The whole card is the click target; the headline carries the link. */
.ep-title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.ep-title a:hover {
  color: var(--lever);
  text-decoration: none;
}

.ep-title em {
  font-style: normal;
  color: var(--lever);
}

/* Some posters carry a different headline from the article. Without it
   on the card, the poster and the text underneath look like they belong
   to two different pieces. */
.ep-subtitle {
  font-family: var(--body);
  font-style: italic;
  font-size: 0.92rem;
  line-height: 1.35;
  color: var(--text-muted);
  margin: -0.15rem 0 0.55rem;
}

.ep-card.is-featured .ep-subtitle {
  font-size: 1.05rem;
  margin: -0.2rem 0 0.8rem;
  max-width: 30ch;
}

.ep-excerpt {
  font-family: var(--body);
  font-size: 1rem;
  color: var(--text-muted);
  margin: 0 0 1rem;
  max-width: 46ch;
}

.ep-date {
  font-family: var(--display);
  font-size: 0.72rem;
  color: var(--text-muted);
  margin: auto 0 0;
}

/* Language bar — which translations exist, and a way into them. */
.ep-langbar {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 3px solid var(--lever);
}

.ep-lang {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-align: center;
  padding: 0.4rem 0;
  color: var(--text-muted);
  background: #fff;
  border-right: 1px solid var(--border);
}

.ep-lang:last-child {
  border-right: 0;
}

.ep-lang.is-current {
  background: var(--lever);
  color: #fff;
}

/* Reduced motion still gets the colour change, just not the scale. */
@media (max-width: 560px) {
  .topbar {
    padding: 1.4rem 0 1rem;
  }

  .wordmark {
    font-size: 1.4rem;
  }

  .topbar-right {
    gap: 0.85rem;
  }

  .lang-toggle button {
    padding: 0.32rem 0.6rem;
    font-size: 0.68rem;
  }
}

/* Not translated yet — shown, but plainly inactive. */
.ep-lang.is-missing {
  color: color-mix(in srgb, var(--text-muted) 40%, #fff);
}

a.ep-lang:hover,
a.ep-lang:focus {
  background: color-mix(in srgb, var(--lever) 12%, #fff);
  color: var(--lever);
  text-decoration: none;
}

.ep-title a:focus-visible {
  outline: 2px solid var(--lever);
  outline-offset: 3px;
}

/* Latest episode — same card, laid on its side and given room. */
.ep-card.is-featured {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 1fr auto;
}

/* The poster fills whatever height the text block needs, rather than
   the text block being stretched to the height of the poster. */
.ep-card.is-featured {
  min-height: 330px;
}

.ep-card.is-featured .ep-media {
  grid-row: 1 / 3;
  position: relative;
}

.ep-card.is-featured .ep-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
}

.ep-card.is-featured .ep-body {
  padding: 1.5rem 1.6rem 1.3rem;
  justify-content: center;
}

.ep-card.is-featured .ep-date {
  margin: 0;
}

/* Headline kept narrow on purpose: it wraps to two or three lines and
   fills the column, the way a lead story does. */
.ep-card.is-featured .ep-title {
  font-size: clamp(1.7rem, 3.2vw, 2.5rem);
  max-width: 20ch;
  margin-bottom: 0.7rem;
}

.ep-card.is-featured .ep-excerpt {
  max-width: 34ch;
}

.ep-card.is-featured .ep-langbar {
  grid-column: 2;
}

@media (hover: hover) and (pointer: fine) {
  .ep-card:hover .ep-media img {
    filter: none;
  }
}

.empty-state {
  color: var(--text-muted);
  padding: 1.5rem 0;
}

/* The episode's lever colour carries into the article itself, so the
   pill, the accented word, the section numerals and the pull quote all
   agree. Links keep the site accent — navigation and identity stay
   distinguishable. */
.article-layout[data-lever] .article-header h1 em,
.article-layout[data-lever] .article-body h2::before,
.article-layout[data-lever] .article-body p.pull-quote {
  color: var(--lever);
}

.article-header .ep-tagline {
  margin-bottom: 0.9rem;
}

.article-langbar {
  width: max-content;
  min-width: 200px;
  margin-top: 1.4rem;
  border: 3px solid var(--lever);
  border-radius: 3px;
}

.article-langbar .ep-lang {
  padding: 0.35rem 1.1rem;
}

/* ---------- Single article ---------- */
.article-header {
  border-bottom: 1px solid var(--border);
  padding-bottom: 1.5rem;
  margin-bottom: 1.5rem;
}

.article-header h1 {
  font-size: clamp(2rem, 4.2vw, 3.2rem);
  max-width: 20ch;
}

/* Optional second title — used when the episode poster carries a
   different headline from the article itself. */
.article-subtitle {
  font-family: var(--body);
  font-style: italic;
  font-size: 1.25rem;
  color: var(--text-muted);
  margin: 0.2rem 0 0;
  max-width: 32ch;
}

.article-header .article-date {
  font-family: var(--display);
  font-size: 0.8rem;
  color: var(--text-muted);
  display: block;
  margin-bottom: 0.6rem;
}

/* Poster sits beside the text, like the portrait on the About page.
   Kept small on purpose — the source files are low resolution and
   scaling them up makes that visible. */
.article-layout {
  display: flex;
  gap: 3rem;
  align-items: flex-start;
  flex-wrap: wrap;
}

.article-main {
  flex: 1 1 420px;
  min-width: 0;
}

.article-photo-frame {
  flex: 0 1 170px;
  max-width: 170px;
  margin: 0;
}

.article-photo {
  margin: 0;
}

.article-body {
  counter-reset: section;
  max-width: 62ch;
}

.article-body p {
  margin: 0 0 1.15em;
}

.article-body h2 {
  font-size: 1.35rem;
  margin-top: 1.9em;
  display: flex;
  align-items: baseline;
  gap: 0.6em;
}

.article-body h2::before {
  counter-increment: section;
  content: counter(section, upper-roman);
  color: var(--accent);
  font-size: 0.85em;
}

/* Evidence image inside an article — a screenshot, a document, a scan.
   The caption carries the explanation, so keep them together. */
.article-figure {
  margin: 2rem 0;
}

.article-figure img {
  width: 100%;
  border: 1px solid var(--border);
}

.article-figure figcaption {
  font-family: var(--display);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-muted);
  margin-top: 0.6rem;
}

/* Credit line — the small note about the artwork an episode is built
   on. Sits just above the sources list. Same ink as a figure caption. */
.article-body p.article-credit {
  font-family: var(--display);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-muted);
  margin-top: 2.5rem;
}

/* Pull quote — for the single line in an article that should stop
   someone scrolling. Use sparingly: one per article, at most. */
.article-body p.pull-quote {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.65rem;
  line-height: 1.14;
  letter-spacing: -0.025em;
  color: var(--accent);
  max-width: 40ch;
  margin: 2em 0;
}

/* Inline highlights inside an article.
   .key    — bold, same ink as the body. For sentences the reader must not miss.
   .accent — the site's accent colour. Use sparingly: it only works while rare. */
.article-body .key {
  font-weight: 700;
}

.article-body .accent {
  color: var(--accent);
  font-weight: 600;
}

.article-body ul {
  margin: 0 0 1.15em;
  padding-left: 1.3em;
}

.article-body li {
  margin-bottom: 0.6em;
}

.article-body sup a {
  font-size: 0.75em;
}

.sources-list {
  margin: 0;
  padding-left: 1.3em;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.sources-list li {
  margin-bottom: 0.5em;
}

.back-link {
  display: inline-block;
  margin-top: 2.5rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9rem;
}

/* ---------- Contact ---------- */
.contact-list {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  max-width: 62ch;
}

.contact-list li {
  padding: 1rem 0;
  border-bottom: 1px solid var(--border);
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
}

.contact-list .label {
  flex: 0 0 110px;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ---------- Privacy / generic text page ---------- */
.text-page h2 {
  margin-top: 2.2rem;
  font-size: 1.2rem;
}

.text-page .content h2,
.text-page h2 {
  margin-top: 2.6rem;
  margin-bottom: 0.8rem;
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: -0.03em;
  color: var(--accent);
}

.text-page p,
.text-page li {
  color: var(--text-muted);
  max-width: 66ch;
}

.updated {
  font-family: var(--display);
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 2rem;
}

/* ---------- Language swap ----------
   Switching EN/ES replaces a whole page of text at once. Without a
   transition that reads as a glitch rather than a change. */
.lang-swappable {
  transition: opacity var(--dur-base) var(--ease-out);
}

.lang-swappable.is-swapping {
  opacity: 0;
}

/* ---------- Reduced motion ----------
   Gentler, not none: colour and opacity still carry meaning. */
@media (prefers-reduced-motion: reduce) {
  .lang-toggle button:active {
    transform: none;
  }

  .ep-media img {
    transition: none;
  }
}

/* ---------- Responsive ---------- */
@media (max-width: 820px) {
  .shell {
    padding: 0 1.5rem;
  }

  .overlay {
    grid-template-columns: 1fr;
    align-content: center;
  }

  .overlay-art {
    display: none;
  }

  .overlay-nav {
    padding: 0 1.5rem;
  }

  .overlay-close {
    right: 1.5rem;
  }

  .content {
    padding: 2.5rem 0 3rem;
  }

  .hero {
    flex-direction: column-reverse;
    gap: 2rem;
  }

  .hero-photo {
    flex: none;
    width: 300px;
    max-width: 100%;
  }

  /* Featured card stacks: whole poster on top, uncropped. */
  .ep-card.is-featured {
    grid-template-columns: 1fr;
  }

  .ep-card.is-featured .ep-media {
    grid-row: auto;
  }

  .ep-card.is-featured {
    min-height: 0;
  }

  .ep-card.is-featured .ep-media img {
    position: static;
    height: auto;
    /* Full-width portrait would run past a phone screen. Show the whole
       poster on a tinted panel instead of cropping — every episode
       poster is laid out differently, so no single crop suits them all. */
    max-height: 420px;
    aspect-ratio: 1 / 1;
    object-fit: contain;
  }

  .ep-card.is-featured .ep-langbar {
    grid-column: 1;
  }

  .ep-card.is-featured .ep-body {
    padding: 1.1rem 1.1rem 0.9rem;
  }

  .article-body p.pull-quote {
    font-size: 1.3rem;
  }

  /* Poster above the title on narrow screens, mirroring the About page. */
  .article-layout {
    flex-direction: column-reverse;
    gap: 2rem;
  }

  .article-photo-frame {
    flex: none;
  }
}

/* ==============================================================
   Anatomy of Manipulation Tactics — the reference section.
   Deliberately plainer than an article page: no episode number,
   no poster, so the reader knows which part of the site they are in.
   ============================================================== */
.tactic-group {
  margin-top: 3rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
}

.tactic-group h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -0.02em;
  margin: 0 0 0.4rem;
}

.tactic-blurb {
  color: var(--text-muted);
  max-width: 52ch;
  margin: 0 0 1.4rem;
}

.tactic-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.tactic-list li {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border);
}

.tactic-name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.05rem;
}

.tactic-soon {
  font-family: var(--display);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Section-level status line, used while the entries are unpublished */
.tactic-status {
  font-family: var(--display);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}

/* Intro line above the contact list; swaps with the language toggle */
.contact-intro {
  max-width: 52ch;
  margin: 0 0 2rem;
}

/* ==============================================================
   My approach — the long essay page.
   --------------------------------------------------------------
   Structure comes from js/approach-content.js, which reads the shape
   of the text rather than its wording, so all three languages get the
   same treatment. Deliberately quieter than an episode: no poster, no
   colour coding, one neutral frame colour throughout.
   ============================================================== */
/* Title and reading time ride along in a rail on the left while the
   essay scrolls past — the page is long enough that the reader loses
   sight of where they are otherwise. */
.approach-layout {
  display: grid;
  grid-template-columns: 215px minmax(0, 1fr);
  gap: 3.5rem;
  align-items: start;
}

.approach-rail {
  position: sticky;
  top: 6.5rem;
}

.approach-rail h1 {
  font-size: 1.85rem;
  margin-bottom: 0.55rem;
}

.page-tagline {
  margin: 0;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

.approach-progress {
  width: 2px;
  height: 150px;
  margin-top: 1.5rem;
  background: var(--border);
}

.approach-progress span {
  display: block;
  width: 100%;
  height: 0;
  background: var(--lever);
}

.approach-body {
  max-width: 62ch;
}

/* The essay is long — set it in ink, not in the muted grey the shorter
   text pages use, or it becomes tiring to read. */
.text-page .approach-body p {
  color: var(--text);
  max-width: none;
  margin: 0 0 1.15em;
}

.text-page .approach-body .approach-lead {
  font-size: 1.32rem;
  line-height: 1.48;
  margin-bottom: 1.6em;
}

/* One-line paragraphs are a deliberate rhythm in this text. Pulled
   closer together they read as beats; at full paragraph spacing they
   just read as gaps. */
.text-page .approach-body p.beat {
  margin-bottom: 0.4em;
}

.text-page .approach-body p.beat + p:not(.beat) {
  margin-top: 1.15em;
}

.text-page .approach-body h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.4rem;
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--text);
  /* Full measure, and never balanced. Balancing evens out the line
     lengths, which on a long heading reads as verse rather than as a
     heading — let it fill each line and break only at the end. */
  max-width: none;
  text-wrap: pretty;
  margin: 2.8rem 0 1rem;
}

/* A short rule instead of a full-width one: this page turns a corner
   often, and twenty full rules would read as twenty interruptions. */
.text-page .approach-body h2::before {
  content: "";
  display: block;
  width: 2.4rem;
  height: 3px;
  background: var(--lever);
  margin-bottom: 0.85rem;
}

/* Set as a statement, not a section break: it completes the sentence
   above it. Carries the site accent so it reads as the line the page
   has been building towards. */
.text-page .approach-body h2.statement {
  font-family: var(--display);
  font-size: 1.55rem;
  line-height: 1.16;
  letter-spacing: -0.025em;
  color: var(--accent);
  max-width: none;
  text-wrap: pretty;
  margin: 1.6rem 0 1.8rem;
}

.text-page .approach-body h2.statement::before {
  display: none;
}

/* Headings that arrive in a run are one thought in stages, not three
   sections — hold them together on a single rule. */
.approach-ladder {
  margin: 2.8rem 0;
  padding-left: 1.2rem;
  border-left: 3px solid var(--lever);
}

.text-page .approach-ladder h2 {
  margin: 0 0 0.5rem;
  font-size: 1.22rem;
  text-wrap: pretty;
}

.text-page .approach-ladder h2:last-child {
  margin-bottom: 0;
}

.text-page .approach-ladder h2::before {
  display: none;
}

.approach-notes {
  margin-top: 3.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
  max-width: 66ch;
}

.text-page .approach-notes h2 {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 1rem;
}

.text-page .approach-notes h2::before {
  display: none;
}

.approach-notes .sources-list {
  font-size: 0.85rem;
  line-height: 1.55;
}

@media (max-width: 900px) {
  .approach-layout {
    grid-template-columns: 1fr;
    gap: 1.8rem;
  }

  .approach-rail {
    position: static;
  }

  .approach-progress {
    display: none;
  }

  .approach-rail h1 {
    font-size: clamp(2rem, 6vw, 2.6rem);
  }

  .page-tagline {
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
  }

  .text-page .approach-body .approach-lead {
    font-size: 1.14rem;
  }

  .text-page .approach-body h2 {
    font-size: 1.2rem;
    margin-top: 2.2rem;
  }
}

/* Footnote links, both directions. Anchors get a scroll margin so the
   target does not land underneath the sticky top bar. */
.approach-body sup {
  scroll-margin-top: 6.5rem;
}

.approach-body sup a {
  font-size: 0.78em;
  font-weight: 700;
}

.approach-notes li {
  scroll-margin-top: 6.5rem;
}

.approach-notes li:target {
  color: var(--text);
}

.note-back {
  font-family: var(--display);
  font-size: 0.95em;
  text-decoration: none;
}

.note-back:hover {
  text-decoration: none;
}

/* A question lifted out of a run of questions. Set in the body face
   like its neighbours, with weight rather than size marking it, so the
   run reads as one list. */
.text-page .approach-body p.question {
  font-weight: 700;
  margin-bottom: 0.4em;
}
