/* ==========================================================================
   The Money Edit
   --------------------------------------------------------------------------
   One stylesheet for all three page types. There is no JavaScript anywhere
   on this site, so every effect below is CSS only and the pages work with
   scripting disabled.

   The look is meant to feel like an instrument panel rather than a blog. The
   reference given was the Iron Man interface, read as precision and assembly
   rather than as military hardware, and softened toward luxury because the
   audience for this writing is not an engineering one. So: deep ink, one
   accent per day, hairlines instead of boxes, oversized numerals, and a
   short assembling motion on load.

   Contents
     1. Tokens
     2. Per day accent palette
     3. Reset and base
     4. Motion
     5. Page frame and atmosphere
     6. Masthead
     7. Entry card
     8. Figure panel
     9. Term of the day
    10. Archive index
    11. Glossary
    12. Footer and navigation
    13. Responsive
   ========================================================================== */


/* 1. Tokens ================================================================ */

:root {
  /* Surfaces, from deepest to most raised. The blue undertone keeps the dark
     from reading as muddy brown on warm displays. */
  --ink:            #06070A;
  --surface:        #0C0E14;
  --surface-raised: #12141D;
  --surface-glass:  rgba(255, 255, 255, 0.025);

  /* Hairlines. Borders on this site are always one pixel and always faint.
     A heavier border would turn the panels into boxes, which is the blog
     look the design is trying to avoid. */
  --line:        rgba(255, 255, 255, 0.08);
  --line-strong: rgba(255, 255, 255, 0.14);

  /* Text. Four steps is enough to build a hierarchy without needing weight
     changes everywhere. */
  --text:      #F4F5F8;
  --text-soft: #A8AEBE;
  --text-mute: #6C7386;
  --text-faint:#464C5C;

  /* Movement. Deliberately not pure red and green. Saturated signal colors
     look like an alarm, and the tone of this writing is calm. */
  --up:   #63D9A4;
  --down: #F2879B;

  /* Typography */
  --font-display: 'Instrument Serif', 'Iowan Old Style', Georgia, serif;
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* A fluid type scale. clamp lets the headline shrink on a phone without a
     media query, which matters because most of these are opened from a
     notification. */
  /* Capped at 3.9rem rather than something larger. Measured against real
     headlines, Instrument Serif runs about 0.32em per character here, so a
     44 character headline needs about 810px against a frame of 820px. That
     is what sets the 3.6rem cap. Larger tips headlines of that length onto
     a second line holding one or two words, which is the shape that made
     the block look lopsided. At this size a headline of up to roughly eight
     words sits on one line and squares up against the measure.

     Headlines can run to ten words, and those still wrap. text-wrap: pretty
     on the heading keeps the overflow from collapsing to a single orphan. */
  --size-hero:  clamp(2.2rem, 1.3rem + 3.3vw, 3.6rem);
  --size-lede:  clamp(1.05rem, 0.98rem + 0.34vw, 1.25rem);
  --size-body:  1.0125rem;
  --size-small: 0.8125rem;
  --size-micro: 0.6875rem;

  /* Rhythm */
  --measure: 34rem;     /* comfortable reading width for prose */
  --frame: 46rem;       /* outer page width, sized so the stack reads as cards rather than as a page */
  --gutter: clamp(1.25rem, 0.6rem + 3vw, 3.5rem);

  --radius: 14px;
  --radius-sm: 9px;

  /* Set per page by the renderer from a hash of the entry date. The fallback
     is champagne so a page still looks intentional if the variable is
     ever missing. */
  --accent: #E8C88A;
  --accent-soft: rgba(232, 200, 138, 0.14);
  --bloom-x: 50%;
  --bloom-y: 0%;
}


/* 2. Per day accent palette ================================================
   Eight curated tones rather than a computed hue. A hash mapped straight onto
   the 360 degree hue wheel eventually lands on a color that looks wrong on
   this background, and there is nobody reviewing the site at 9:30am to catch
   it. A fixed set guarantees every day looks deliberate.

   The renderer picks one by hashing the entry date, so a given day always
   gets the same tone no matter when the site is rebuilt.
   ========================================================================== */

.accent-0 { --accent: #E8C88A; --accent-soft: rgba(232, 200, 138, 0.14); } /* champagne */
.accent-1 { --accent: #8FC7E8; --accent-soft: rgba(143, 199, 232, 0.14); } /* ice */
.accent-2 { --accent: #C9A0EA; --accent-soft: rgba(201, 160, 234, 0.14); } /* orchid */
.accent-3 { --accent: #7FD6B0; --accent-soft: rgba(127, 214, 176, 0.14); } /* jade */
.accent-4 { --accent: #EDA278; --accent-soft: rgba(237, 162, 120, 0.14); } /* copper */
.accent-5 { --accent: #A3AEF5; --accent-soft: rgba(163, 174, 245, 0.14); } /* periwinkle */
.accent-6 { --accent: #F2A0B6; --accent-soft: rgba(242, 160, 182, 0.14); } /* rose */
.accent-7 { --accent: #D9DE86; --accent-soft: rgba(217, 222, 134, 0.14); } /* citrine */


/* 3. Reset and base ======================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--ink);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: 1.68;
  /* tnum gives figures a fixed width so columns of numbers line up.
     cv11 is the Inter alternate that gives a single storey lowercase g,
     which reads a little softer. */
  font-feature-settings: 'tnum' 1, 'cv11' 1;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

a { color: inherit; }

p { margin: 0 0 1.05em; }
p:last-child { margin-bottom: 0; }

ul { margin: 0 0 1.05em; padding-left: 1.15em; }
li { margin-bottom: 0.4em; }

strong { font-weight: 600; color: var(--text); }
em { font-style: italic; }

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--surface-glass);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}

/* Keyboard focus has to stay obvious. The accent ring is the same tone as
   the rest of the page so it reads as part of the design. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* Visible only to screen readers. Used for the skip link and for headings
   that would otherwise be implied by layout alone. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--gutter);
  z-index: 10;
  background: var(--accent);
  color: var(--ink);
  padding: 0.6rem 1rem;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-size: var(--size-small);
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { top: 0; }


/* 4. Motion ================================================================
   The assembling entrance. Each block carries a --step index set inline by
   the renderer, and the delay is derived from it, so adding a section never
   means touching the stylesheet.
   ========================================================================== */

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@keyframes sweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

@keyframes bloom-in {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: none; }
}

.rise {
  opacity: 0;
  animation: rise 0.72s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  animation-delay: calc(var(--step, 0) * 75ms);
}

/* Anyone who has asked their system to reduce motion gets the finished state
   immediately. This is not an optional nicety, the entrance is prominent
   enough to be a problem for motion sensitivity. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rise { animation: none; opacity: 1; }
  .rail::after { animation: none; }
  .bloom { animation: none; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}


/* 5. Page frame and atmosphere ============================================= */

/* The accent bloom. A soft radial wash placed by the renderer using
   --bloom-x and --bloom-y, so the light falls in a slightly different place
   each day. Fixed position so it stays put while the reader scrolls, which
   makes it read as ambient light rather than as a graphic. */
.bloom {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      62rem 42rem at var(--bloom-x) var(--bloom-y),
      color-mix(in oklab, var(--accent) 17%, transparent),
      transparent 68%
    ),
    radial-gradient(
      40rem 30rem at calc(100% - var(--bloom-x)) 78%,
      color-mix(in oklab, var(--accent) 7%, transparent),
      transparent 70%
    );
  animation: bloom-in 1.4s ease-out both;
}

/* The instrument grid. Two repeating gradients at very low opacity, masked
   so the lines fade out before they reach the bottom of the screen. Without
   the mask the grid competes with the text. */
.grid-overlay {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255,255,255,0.028) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,0.028) 1px, transparent 1px);
  background-size: 88px 88px;
  -webkit-mask-image: radial-gradient(78% 58% at 50% 12%, #000 20%, transparent 100%);
  mask-image: radial-gradient(78% 58% at 50% 12%, #000 20%, transparent 100%);
}

.page {
  position: relative;
  z-index: 1;
  max-width: var(--frame);
  margin: 0 auto;
  padding: 0 var(--gutter) 6rem;
}

/* The top rail. A hairline with a slow accent sweep travelling along it,
   which is the single most direct nod to the interface reference. */
.rail {
  position: relative;
  height: 1px;
  background: var(--line);
  overflow: hidden;
}
.rail::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: sweep 5.5s cubic-bezier(0.45, 0, 0.25, 1) infinite;
  opacity: 0.85;
}


/* 6. Masthead ============================================================== */

.masthead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.25rem;
  flex-wrap: wrap;
  padding: 1.5rem 0 1.35rem;
}

.wordmark {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--text-soft);
  text-decoration: none;
  transition: color 0.25s ease;
}
.wordmark:hover { color: var(--accent); }

/* The small square that marks the day's accent, so the tone reads as
   deliberate rather than as a random tint. */
.wordmark::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 0.75em;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
  vertical-align: middle;
}

.masthead-nav {
  display: flex;
  gap: 1.6rem;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.masthead-nav a {
  color: var(--text-mute);
  text-decoration: none;
  transition: color 0.25s ease;
}
.masthead-nav a:hover,
.masthead-nav a[aria-current='page'] { color: var(--accent); }


/* 7. The entry as a stack of cards ==========================================
   The entry is not a page of prose, it is a small stack of objects. Each one
   is a raised surface with an edge and a shadow, sitting on the background
   rather than printed onto it. That distinction is the whole design. A
   document is read, an object is picked up, and this arrives at the opening
   bell wanting to be glanced at first and read second.

   Depth is built from three layers every time: a soft gradient for the face,
   a one pixel inset highlight along the top edge to catch the light, and a
   wide low shadow underneath to lift it off the page.
   ========================================================================== */

.entry {
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  padding-top: clamp(1.25rem, 0.6rem + 2.5vw, 2.75rem);
}

.widget {
  position: relative;
  overflow: hidden;
  padding: clamp(1.25rem, 0.85rem + 1.5vw, 1.9rem);
  border: 1px solid rgba(255, 255, 255, 0.085);
  border-radius: 20px;
  background:
    linear-gradient(168deg,
      rgba(255, 255, 255, 0.055),
      rgba(255, 255, 255, 0.017) 44%,
      rgba(255, 255, 255, 0.006));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 20px 44px -28px rgba(0, 0, 0, 0.95);
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.45s ease;
}

/* A card should respond to being pointed at. It is a small thing but it is
   most of what separates an object from a panel. */
.widget:hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 28px 56px -28px rgba(0, 0, 0, 1);
}


/* 7a. Closing bell ---------------------------------------------------------
   The loudest card, and the reason to open this at 9:30. It carries the
   accent, a live pulse, and the only genuinely large numerals on the page.
   -------------------------------------------------------------------------- */

.widget--bell {
  border-color: color-mix(in oklab, var(--accent) 30%, transparent);
  background:
    linear-gradient(165deg,
      color-mix(in oklab, var(--accent) 13%, transparent),
      rgba(255, 255, 255, 0.02) 52%,
      rgba(255, 255, 255, 0.005));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 26px 64px -30px color-mix(in oklab, var(--accent) 45%, transparent),
    0 20px 44px -30px rgba(0, 0, 0, 0.9);
}

/* A slow highlight travelling across the face, so the card reads as lit
   rather than printed. Skewed so it crosses on a diagonal. */
.widget--bell::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 45%;
  height: 100%;
  pointer-events: none;
  transform: skewX(-18deg);
  background: linear-gradient(90deg,
    transparent,
    color-mix(in oklab, var(--accent) 9%, transparent),
    transparent);
  animation: sheen 7s cubic-bezier(0.4, 0, 0.3, 1) infinite;
}

@keyframes sheen {
  0%   { transform: translateX(-140%) skewX(-18deg); }
  55%  { transform: translateX(360%) skewX(-18deg); }
  100% { transform: translateX(360%) skewX(-18deg); }
}

/* The datestamp. Sits above the card stack rather than inside any card, so
   every entry carries a date whether or not it reports figures. The trailing
   hairline is what makes it read as an instrument label rather than a byline. */
.entry-stamp {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1.15rem;
  padding: 0 0.35rem;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
}
.entry-stamp::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--accent-soft), transparent);
}

.bell-strip {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 1.35rem;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
}

.bell-strip time {
  margin-left: auto;
  color: var(--text-mute);
  letter-spacing: 0.16em;
}

/* The pulse. This is the one element that says the information is fresh. */
.bell-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 2.6s ease-out infinite;
}

@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 65%, transparent); }
  70%  { box-shadow: 0 0 0 10px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* The tape. Up to three headline numbers, sized to be read across a room.
   Separate tiles with their own edges rather than a divided grid, so an odd
   count never leaves an empty cell behind. */
.tape {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.65rem;
}

.tape-tile {
  padding: 0.85rem 0.95rem 0.9rem;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 13px;
  background: rgba(0, 0, 0, 0.3);
}

.tape-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 0.55rem;
  /* Index names vary in length. One line keeps every tile the same height. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tape-value {
  display: block;
  font-family: var(--font-mono);
  font-size: clamp(1.45rem, 1.1rem + 1.3vw, 2rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--text);
}

.tape-change {
  display: block;
  margin-top: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-mute);
}

.tape-tile[data-direction='up'] .tape-change { color: var(--up); }
.tape-tile[data-direction='down'] .tape-change { color: var(--down); }
.tape-tile[data-direction='up'] .tape-change::before { content: '\2191\00a0'; }
.tape-tile[data-direction='down'] .tape-change::before { content: '\2193\00a0'; }

/* Everything past the first three, as a quiet list under the tape. */
.bell-rest {
  margin-top: 1.15rem;
  padding-top: 0.95rem;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 0.6rem;
}

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

.bell-row-label {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-mute);
}

.bell-row-value {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text);
  text-align: right;
}

.bell-row[data-direction='up'] .bell-row-value { color: var(--up); }
.bell-row[data-direction='down'] .bell-row-value { color: var(--down); }
.bell-row[data-direction='up'] .bell-row-value::before { content: '\2191\00a0'; }
.bell-row[data-direction='down'] .bell-row-value::before { content: '\2193\00a0'; }


/* 7b. The story ------------------------------------------------------------ */

.entry-headline {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--size-hero);
  line-height: 1.04;
  letter-spacing: -0.018em;
  margin: 0 0 1.6rem;
  text-wrap: pretty;
}

.section { margin-bottom: 1.9rem; }
.section:last-child { margin-bottom: 0; }

.section-label {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0 0 0.85rem;
}
.section-label::before {
  content: '';
  width: 14px;
  height: 1px;
  background: var(--accent);
}

.section-body { color: var(--text-soft); }
.section-body strong { color: var(--text); }
.section-body a {
  color: var(--accent);
  text-decoration-color: var(--accent-soft);
  text-underline-offset: 3px;
}

/* "What it means for you" is the reason this project exists, so it is lifted
   out of the run of prose rather than being the third heading of three. */
.section--payoff {
  padding: 1.2rem 1.35rem;
  border-left: 2px solid var(--accent);
  border-radius: 0 13px 13px 0;
  background: var(--accent-soft);
}
.section--payoff .section-label { color: var(--accent); }
.section--payoff .section-body { color: var(--text); }


/* 8. Term of the day =======================================================
   A flashcard. Building vocabulary is the point of reading this daily, so
   the term gets a card of its own rather than a footnote.
   ========================================================================== */

.widget--term {
  border-color: color-mix(in oklab, var(--accent) 24%, transparent);
  background:
    linear-gradient(150deg,
      color-mix(in oklab, var(--accent) 11%, transparent),
      rgba(255, 255, 255, 0.012) 60%);
}

.term-label {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.75rem;
}

.term-name {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 1.3rem + 1.1vw, 2.15rem);
  font-weight: 400;
  line-height: 1.15;
  margin: 0 0 0.6rem;
  color: var(--text);
}

.term-definition {
  color: var(--text-soft);
  margin: 0;
}


/* 9. Source ================================================================ */

.entry-source {
  margin: 0;
  font-size: var(--size-small);
  color: var(--text-mute);
}
.entry-source a {
  color: var(--text-soft);
  text-underline-offset: 3px;
  text-decoration-color: var(--line-strong);
}
.entry-source a:hover { color: var(--accent); }


/* 10. Archive index ======================================================== */

.hero {
  padding: clamp(3rem, 1.5rem + 7vw, 7rem) 0 clamp(2.5rem, 1rem + 5vw, 4.5rem);
  border-bottom: 1px solid var(--line);
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3rem, 1.6rem + 6.4vw, 6.5rem);
  line-height: 0.95;
  letter-spacing: -0.025em;
  margin: 0 0 1.35rem;
}

.hero-tagline {
  font-size: var(--size-lede);
  color: var(--text-soft);
  max-width: 30rem;
  margin: 0;
}

.archive-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 3.25rem 0 0.5rem;
}

.archive-heading h2 {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0;
}

.archive-count {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.12em;
  color: var(--text-faint);
}

.archive-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}

.archive-item { border-bottom: 1px solid var(--line); }

/* Each row is a full width link so the whole strip is a target, which
   matters far more on a phone than on a laptop. */
.archive-link {
  display: grid;
  grid-template-columns: 5.5rem 1fr auto;
  align-items: center;
  gap: 1.5rem;
  padding: 1.5rem 0.9rem;
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: background 0.3s ease, padding-left 0.3s ease;
}
.archive-link:hover {
  background: var(--surface-glass);
  padding-left: 1.4rem;
}

.archive-date {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
}

.archive-title {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.05rem + 0.65vw, 1.65rem);
  font-weight: 400;
  line-height: 1.22;
  color: var(--text);
  transition: color 0.3s ease;
}
.archive-link:hover .archive-title { color: var(--accent); }

/* The chevron is decorative, so it is hidden from assistive technology in
   the markup and only styled here. */
.archive-arrow {
  font-family: var(--font-mono);
  color: var(--text-faint);
  transition: transform 0.3s ease, color 0.3s ease;
}
.archive-link:hover .archive-arrow {
  color: var(--accent);
  transform: translateX(4px);
}

/* Empty state. Every entry starts as a draft in Notion, so a build with
   nothing promoted yet is a normal state and should not look broken. */
.empty {
  padding: 5rem 0;
  text-align: center;
  color: var(--text-mute);
  max-width: 32rem;
  margin: 0 auto;
}
.empty h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2rem;
  color: var(--text);
  margin: 0 0 0.85rem;
}


/* 11. Glossary ============================================================= */

.glossary-list {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.glossary-item {
  background: var(--surface);
  padding: 1.6rem 1.75rem;
}

.glossary-term {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 400;
  margin: 0 0 0.5rem;
  color: var(--accent);
}

.glossary-definition {
  color: var(--text-soft);
  margin: 0 0 0.75rem;
  max-width: var(--measure);
}

.glossary-source {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.1em;
  color: var(--text-faint);
  text-decoration: none;
}
.glossary-source:hover { color: var(--accent); }


/* 12. Footer and navigation ================================================ */

.card-source {
  margin: 0 0 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  max-width: var(--measure);
  font-size: var(--size-small);
  color: var(--text-mute);
}
.card-source a {
  color: var(--text-soft);
  text-underline-offset: 3px;
  text-decoration-color: var(--line-strong);
}
.card-source a:hover { color: var(--accent); }

/* Previous and next. The grid keeps next hard right even when previous is
   absent, which happens on the oldest entry. */
.card-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 3rem;
}

.card-nav-link {
  background: var(--surface);
  padding: 1.4rem 1.6rem;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  transition: background 0.3s ease;
}
.card-nav-link:hover { background: var(--surface-raised); }
.card-nav-link.is-next { text-align: right; align-items: flex-end; }

.card-nav-direction {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.card-nav-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--text);
  line-height: 1.25;
}
.card-nav-link:hover .card-nav-title { color: var(--accent); }

.site-footer {
  padding-top: 2.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.site-footer a { color: var(--text-mute); text-decoration: none; }
.site-footer a:hover { color: var(--accent); }


/* 13. Responsive ===========================================================
   Only two breakpoints. The layout is mostly fluid by construction, using
   clamp for type and auto-fit for the figure grid, so there is very little
   left to correct at a specific width.
   ========================================================================== */

@media (max-width: 42rem) {
  .archive-link {
    grid-template-columns: 1fr auto;
    gap: 0.5rem 1rem;
    padding: 1.25rem 0.75rem;
  }
  /* Date moves above the headline instead of beside it. */
  .archive-date { grid-column: 1 / -1; }
  .archive-title { grid-column: 1; }

  .card-nav { grid-template-columns: 1fr; }
  .card-nav-link.is-next { text-align: left; align-items: flex-start; }

  .figures { padding: 1.15rem; }
  .card-headline { max-width: none; }
}

@media (max-width: 26rem) {
  .masthead { gap: 0.75rem; }
  .masthead-nav { gap: 1.1rem; }
}

/* Printing a card should give a clean readable page, not a screenshot of a
   dark interface. */
@media print {
  .bloom, .grid-overlay, .rail, .card-nav, .masthead-nav, .skip-link { display: none; }
  body { background: #fff; color: #111; }
  .card-headline, .term-name, .hero-title { color: #111; }
  .section-body, .card-lede { color: #333; }
  .figures, .figure { background: #fff; border-color: #ccc; }
}

/* The link from the windowed front page to the complete archive. */
.archive-more {
  margin: 1.75rem 0 0;
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.archive-more a {
  color: var(--text-mute);
  text-decoration: none;
  transition: color 0.25s ease;
}
.archive-more a:hover { color: var(--accent); }

/* Sources. Attribution is a card of its own rather than small print, because
   this writing summarises other people's reporting and an entry can draw on
   more than one article. */
.source-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}

.source-list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: rgba(0, 0, 0, 0.22);
  text-decoration: none;
  transition: border-color 0.3s ease, background 0.3s ease;
}
.source-list a:hover {
  border-color: color-mix(in oklab, var(--accent) 40%, transparent);
  background: rgba(0, 0, 0, 0.32);
}

.source-title {
  color: var(--text-soft);
  font-size: 0.9rem;
  line-height: 1.4;
}
.source-list a:hover .source-title { color: var(--text); }

/* The publisher, so credit is legible without reading the whole title. */
.source-host {
  font-family: var(--font-mono);
  font-size: var(--size-micro);
  letter-spacing: 0.12em;
  color: var(--text-faint);
  white-space: nowrap;
}
.source-list a:hover .source-host { color: var(--accent); }

/* Which edition this is, shown beside the date. The brief runs twice a day,
   so a reader arriving from a notification needs to know which one they
   opened without inferring it from the content. */
.entry-edition {
  padding: 0.2rem 0.55rem;
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  border-radius: 999px;
  background: var(--accent-soft);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  white-space: nowrap;
}

/* The same distinction in the archive list, kept quiet so the headline stays
   the thing being scanned. */
.archive-edition {
  display: block;
  margin-top: 0.3rem;
  color: var(--text-faint);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
}
