/* ============================================================
   reference — design tokens
   Palette: a clean white-to-cream page throughout — warm ink for
   text, white/cream cards for content, a bright blue accent for
   links, hovers and selected states — vivid enough to pop against
   black text, and in the same blue family as the navy wordmark.

   Type: a single-family system. Source Serif 4 handles every
   role — headlines, body, UI, captions — with hierarchy built
   from size, weight, and letter-spacing rather than a second
   typeface. Loaded as a variable font (narrowed to the 400–600
   weight range actually used, plus 400 italic) so its optical
   sizing axis does real work between a 56px headline and a 13px
   caption. The one exception is scoped locally, not here: each
   Annual Letter entry may set its own one-off headline font —
   see annual-letter-entry.njk.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,400..600;1,8..60,400&display=swap');

:root {
  /* color */
  --sky: #a4c6dc;
  --page-bg: #ffffff;
  --card: #ffffff;
  --card-shadow: rgba(8, 16, 11, 0.35);
  --ink: #201d16;
  --ink-soft: #55503f;
  --hairline: rgba(32, 29, 22, 0.1);
  --accent: #2358ff; /* the one accent color — bright blue, used for links, hover lines, and "selected" fills alike */

  /* type — one family, hierarchy from size/weight/tracking tokens */
  --font-serif: 'Source Serif 4', ui-serif, Georgia, serif;

  --text-h1: clamp(2.75rem, 3vw + 2rem, 3.5rem);       /* 44–56px */
  --weight-h1: 600;
  --tracking-h1: -0.015em;

  --text-h2: clamp(1.75rem, 1vw + 1.5rem, 2rem);       /* 28–32px */
  --weight-h2: 600;
  --tracking-h2: -0.01em;

  --text-h3: clamp(1.25rem, 0.5vw + 1.1rem, 1.375rem); /* 20–22px */
  --weight-h3: 500;
  --tracking-h3: -0.005em;

  --text-dek: 1.0625rem;    /* 17px */
  --weight-dek: 400;

  --text-body: 1.0625rem;   /* 17px */
  --weight-body: 400;

  --text-caption: 0.8125rem; /* 13px */
  --weight-caption: 400;
  --tracking-caption: 0.02em;

  --text-nav: 0.875rem;     /* 14px */
  --weight-nav: 500;
  --tracking-nav: 0.04em;

  /* homepage hero only — sized up from --text-body for a fullscreen
     display; shared by the credit-row values and the intro paragraph
     so the two stay in sync */
  --text-hero: clamp(1.05rem, 0.6vw + 0.92rem, 1.5rem);

  /* layout — fluid, not fixed, so interior pages actually grow on a real
     desktop monitor instead of capping at the same width regardless of
     screen size. --measure stays closer to a true readable prose measure
     (it's what essay body text uses); --measure-wide, used for nearly
     every page's outer container, gets more room to scale since most of
     what it holds (headers, entry lists, the corkboard grid) isn't
     limited by line-length the way flowing prose is. */
  --measure: clamp(34rem, 60vw, 46rem);
  --measure-wide: clamp(56rem, 78vw, 78rem);
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.75rem;
  --space-4: 3rem;
  --space-5: 5rem;
}

/* ============================================================
   reset + base
   ============================================================ */

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

html {
  color-scheme: light;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--page-bg);
  color: var(--ink);
  font-family: var(--font-serif);
  font-optical-sizing: auto;
  font-weight: var(--weight-body);
  font-size: var(--text-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--sky);
  outline-offset: 3px;
}

/* no italics anywhere on the site, including markdown *emphasis* / <em> */
em, i, cite { font-style: normal; }

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

h1, h2, h3 {
  font-family: var(--font-serif);
  line-height: 1.15;
  margin: 0 0 var(--space-2);
  color: var(--ink);
}

h1 { font-size: var(--text-h1); font-weight: var(--weight-h1); letter-spacing: var(--tracking-h1); }
h2 { font-size: var(--text-h2); font-weight: var(--weight-h2); letter-spacing: var(--tracking-h2); }
h3 { font-size: var(--text-h3); font-weight: var(--weight-h3); letter-spacing: var(--tracking-h3); }

p { margin: 0 0 var(--space-2); }

/* the caption/meta role — small tracked labels: dates, eyebrows, kickers */
.caption {
  font-size: var(--text-caption);
  font-weight: var(--weight-caption);
  letter-spacing: var(--tracking-caption);
}

/* ============================================================
   shell
   ============================================================ */

.shell {
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: var(--space-4) var(--space-3) var(--space-5);
}

.shell--narrow { max-width: var(--measure); }

/* ============================================================
   site header — appears on every interior page, small + quiet
   ============================================================ */

/* The bar stays pinned to the top while you scroll (so the logo and the
   menu are always one tap away), with a hairline that fades in once
   content is actually scrolling beneath it. Tapping empty space on it
   scrolls back to the top (see the script in base.njk). It's full-width
   so wide content passing underneath is hidden edge to edge. */
.site-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--page-bg);
  transition: box-shadow 0.2s ease;
}

.site-bar.is-scrolled { box-shadow: 0 1px 0 var(--hairline); }

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  max-width: var(--measure-wide);
  margin: 0 auto;
}

.site-header__mark {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.site-header__logo {
  display: block;
  height: 2rem;
  width: auto;
}

/* ---- hamburger menu, top right on every interior page ----
   Modeled on briOS's menu: a round ghost button whose two bars morph
   into an X, and a full-width panel that fades + scales in from the top
   (0.98 -> 1, 150ms) *below* the header bar, which stays put. Links are
   large and semibold in the site's own type (H2 role tokens), muted until
   hover, with the current page at full strength. Closes on Esc, on any
   click inside the panel, or via the toggle. */

.site-menu {
  position: relative;
}

.site-menu__toggle {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-right: -0.75rem; /* the bars, not the round button, sit flush with the page's right edge */
  padding: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.site-menu__toggle:hover { background: rgba(32, 29, 22, 0.06); }

.site-menu__icon { display: block; }

/* The bars rotate about their own centers while sliding together, which
   reads as the same bars-to-X morph without needing animatable SVG paths
   (Safari can't animate path data from CSS). */
.site-menu__bar {
  transform-box: view-box;
  transition: transform 0.2s ease;
}
.site-menu__bar--top { transform-origin: 12px 8px; }
.site-menu__bar--bottom { transform-origin: 12px 16px; }

.site-menu.is-open .site-menu__bar--top {
  transform: translateY(4px) rotate(45deg) scaleX(1.2);
}
.site-menu.is-open .site-menu__bar--bottom {
  transform: translateY(-4px) rotate(-45deg) scaleX(1.2);
}

/* page can't scroll out from under the open panel */
html.menu-open { overflow: hidden; }

.site-menu__panel {
  position: fixed;
  top: 0; /* set from JS on open: just below the header bar */
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 9;
  overflow-y: auto;
  background: var(--page-bg);
  border-top: 1px solid var(--hairline);
  transform-origin: top;
  transform: scale(0.98);
  opacity: 0;
  visibility: hidden; /* also keeps closed links out of the tab order */
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s linear 0.15s;
}

.site-menu.is-open .site-menu__panel {
  transform: scale(1);
  opacity: 1;
  visibility: visible;
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s;
}

.site-menu__panel ul {
  list-style: none;
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: var(--space-4) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.site-menu__panel a {
  display: block;
  width: fit-content;
  padding: 0.4rem 0;
  font-family: var(--font-serif);
  font-size: var(--text-h2);
  font-weight: 400;
  letter-spacing: var(--tracking-h2);
  line-height: 1.2;
  text-decoration: none;
  color: var(--ink-soft);
  transition: color 0.15s ease;
}

.site-menu__panel a { position: relative; color: var(--ink); }
.site-menu__panel a[aria-current="page"] { color: var(--accent); }

.site-menu__panel a::after {
  content: "";
  position: absolute;
  left: -0.03em;
  right: -0.03em;
  bottom: 0.1em;
  height: 0.32em;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%2020'%20preserveAspectRatio='none'%3E%3Cpath%20d='M2%2010%20C%2020%204,%2042%2013,%2072%208%20C%20102%203,%20132%2012,%20162%207%20C%20176%205,%20189%208,%20198%205%20L%20198.5%209.5%20C%20187%2013,%20174%2010.5,%20160%2013%20C%20130%2018,%20102%209.5,%2072%2013.5%20C%2042%2018.5,%2020%2011.5,%201.5%2015%20Z'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
          mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%2020'%20preserveAspectRatio='none'%3E%3Cpath%20d='M2%2010%20C%2020%204,%2042%2013,%2072%208%20C%20102%203,%20132%2012,%20162%207%20C%20176%205,%20189%208,%20198%205%20L%20198.5%209.5%20C%20187%2013,%20174%2010.5,%20160%2013%20C%20130%2018,%20102%209.5,%2072%2013.5%20C%2042%2018.5,%2020%2011.5,%201.5%2015%20Z'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.35s cubic-bezier(0.3, 0.7, 0.3, 1);
  pointer-events: none;
}
.site-menu__panel a:hover::after,
.site-menu__panel a:focus-visible::after { clip-path: inset(0 0 0 0); }

/* ============================================================
   homepage hero — wordmark + motto + intro
   ============================================================ */

.hero {
  min-height: 100vh;
  min-height: 100svh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: var(--space-4) var(--space-3);
  max-width: clamp(30rem, 94vw, 92rem);
  margin: 0 auto;
}

.hero__wordmark {
  width: min(100%, clamp(36rem, 86vw, 88rem));
  height: auto;
  margin: 0 auto var(--space-2);
  display: block;
}

/* the credit line — a small three-column masthead row standing in
   for the old motto, in the spirit of a magazine spread's byline */
.hero__credits {
  display: flex;
  justify-content: center;
  gap: clamp(2.5rem, 8vw, 7rem);
  margin-top: 3rem; /* same rhythm as the motto it replaced */
}

.hero__credit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}

.hero__credit-label {
  font-family: var(--font-serif);
  font-weight: var(--weight-nav);
  /* sized up beyond the standard --text-nav token — a deliberate hero-scale
     exception (still weight/tracking-consistent with the Nav/UI role) so
     the credit line reads at full-screen desktop sizes, not just mobile */
  font-size: clamp(0.8rem, 0.5vw + 0.68rem, 1.05rem);
  line-height: 1.3;
  letter-spacing: var(--tracking-nav);
  text-transform: uppercase;
  text-align: center;
  color: var(--ink-soft);
  /* reserves two lines' worth of height so a label that wraps (small
     screens) doesn't push its value out of line with the other columns */
  min-height: 2.6em;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.hero__credit-value {
  font-family: var(--font-serif);
  font-weight: var(--weight-body);
  font-size: var(--text-hero);
  color: var(--ink);
}

/* The intro paragraph is its own full-viewport "page" — same pattern as
   the hero, min-height + flex centering — sitting right after the hero's
   own full-viewport block. That guarantees a clean scroll position where
   only this text is visible: scrolled fully past the hero, and not yet
   into the card-stack below. Matches the credit-row value size above,
   so the two read as one consistent hero scale. */
.hero__intro {
  min-height: 100vh;
  min-height: 100svh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  font-size: var(--text-hero);
  font-weight: var(--weight-body);
  color: var(--ink);
  max-width: 42rem;
  margin: 0 auto;
  padding: var(--space-4) var(--space-3);
}

.hero__intro p:last-child { margin-bottom: 0; }

/* ============================================================
   homepage section index — six titles, nothing else, left-aligned to
   the same edge as every interior page. Its own full-viewport "page"
   (same pattern as the hero and intro).
   The hover treatment is the site's "hoverable line": nothing at rest,
   then a hand-drawn accent-colored stroke draws in under the title,
   left to right, like a pen. The stroke is an SVG used as a mask over
   a solid --accent background, so it follows the accent token.
   ============================================================ */

.home-index {
  min-height: 100vh;
  min-height: 100svh;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding: var(--space-4) 0;
}

.home-index__inner {
  width: 100%;
  max-width: 96rem;
  margin: 0 auto;
  padding: 0 var(--space-2);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.home-index__art {
  flex: 0 1 62%;
  margin: 0;
}

.home-index__art img {
  display: block;
  width: 100%;
  height: auto;
}

.home-index__art figcaption {
  margin-top: 0.6rem;
  font-family: var(--font-serif);
  font-size: var(--text-caption);
  color: var(--ink-soft);
  text-align: left;
}

@media (max-width: 48rem) {
  .home-index__inner { flex-direction: column; align-items: flex-start; }
  .home-index__art { flex: none; width: 100%; }
  .home-index__inner { gap: var(--space-3); }
}

.home-index ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(0.5rem, 2.2vh, 1.4rem);
  text-align: left;
}

.home-index a {
  position: relative;
  display: inline-block;
  font-family: var(--font-serif);
  font-weight: var(--weight-body);
  font-size: clamp(2.25rem, 5.5vw, 5rem);
  letter-spacing: var(--tracking-h1);
  line-height: 1.15;
  color: #000;
  text-decoration: none;
}

.home-index a::after {
  content: "";
  position: absolute;
  left: -0.03em;
  right: -0.03em;
  bottom: -0.02em;
  height: 0.32em;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%2020'%20preserveAspectRatio='none'%3E%3Cpath%20d='M2%2010%20C%2020%204,%2042%2013,%2072%208%20C%20102%203,%20132%2012,%20162%207%20C%20176%205,%20189%208,%20198%205%20L%20198.5%209.5%20C%20187%2013,%20174%2010.5,%20160%2013%20C%20130%2018,%20102%209.5,%2072%2013.5%20C%2042%2018.5,%2020%2011.5,%201.5%2015%20Z'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
          mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%2020'%20preserveAspectRatio='none'%3E%3Cpath%20d='M2%2010%20C%2020%204,%2042%2013,%2072%208%20C%20102%203,%20132%2012,%20162%207%20C%20176%205,%20189%208,%20198%205%20L%20198.5%209.5%20C%20187%2013,%20174%2010.5,%20160%2013%20C%20130%2018,%20102%209.5,%2072%2013.5%20C%2042%2018.5,%2020%2011.5,%201.5%2015%20Z'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.35s cubic-bezier(0.3, 0.7, 0.3, 1);
  pointer-events: none;
}

.home-index a:hover::after,
.home-index a:focus-visible::after {
  clip-path: inset(0 0 0 0);
}

/* ============================================================
   essay content — plain text on the page, no card surface;
   background is the same --page-bg everywhere on the site
   ============================================================ */

.card {
  color: var(--ink);
  position: relative;
}

.card + .card { margin-top: var(--space-4); }

.card__eyebrow {
  font-family: var(--font-serif);
  font-size: var(--text-caption);
  font-weight: var(--weight-caption);
  letter-spacing: var(--tracking-caption);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--space-1);
  display: block;
}

.card p, .card li { color: var(--ink); }
.card a { color: var(--accent); text-decoration-color: rgba(35,88,255,0.4); }
.card a:hover { text-decoration-color: var(--accent); }

/* anchored headings (e.g. the letter's table of contents) shouldn't land
   underneath the sticky header */
[id] { scroll-margin-top: 5rem; }

/* prose within an essay card */
.prose { max-width: var(--measure); }
.prose p { margin-bottom: var(--space-2); }
.prose h2 { margin-top: var(--space-3); }

/* ============================================================
   annual letter — a longer-form essay page: header photo,
   centered masthead + table of contents, dropped-cap opening
   ============================================================ */

.letter {
  padding-bottom: var(--space-5);
}

.letter__header {
  max-width: clamp(56rem, 82vw, 84rem);
  margin: 0 auto var(--space-4);
  padding: 0 var(--space-3);
}

.letter__header-img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 2px;
}

/* Wider than --measure (the eyebrow/dek/toc's narrow reading width isn't
   affected — they set their own tighter max-width) so the big title
   below actually has room to stay on one line instead of wrapping. */
.letter__masthead {
  max-width: clamp(40rem, 90vw, 84rem);
  margin: var(--space-4) auto var(--space-3);
  padding: 0 var(--space-3);
  text-align: center;
}

/* A deliberate, dramatic one-off for the letter's own title, scoped here
   so it never touches the H1 size used everywhere else on the site.
   nowrap + a mostly-vw-driven size (rather than a fixed rem floor) keeps
   it on one line and scaled to fit at any screen width, up to the full
   3x-of-sitewide-H1 ceiling (10.5rem) on desktop. */
.letter__masthead h1 {
  white-space: nowrap;
  font-size: clamp(2.5rem, 9vw, 10.5rem);
}

.letter__eyebrow {
  font-family: var(--font-serif);
  font-size: var(--text-caption);
  font-weight: var(--weight-caption);
  letter-spacing: var(--tracking-caption);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--space-1);
}

.letter__dek {
  font-size: var(--text-dek);
  font-weight: var(--weight-dek);
  color: var(--ink-soft);
  max-width: 30rem;
  margin: var(--space-1) auto 0;
}

.letter__toc {
  max-width: 24rem;
  margin: 0 auto var(--space-5);
  padding: 0 var(--space-3);
  text-align: center;
}

.letter__toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.letter__toc a {
  /* TOC entries are navigation, so no italic (reserved for deks/emphasis/
     citations) — styled instead as the H3/subsection role, since each
     links to what is structurally a section subhead */
  font-family: var(--font-serif);
  font-size: var(--text-h3);
  font-weight: var(--weight-h3);
  letter-spacing: var(--tracking-h3);
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid transparent;
}

.letter__toc a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.letter__body {
  margin: 0 auto;
  padding: 0 var(--space-3);
}

/* the dropped cap — only the opening paragraph of the letter */
.letter__body > p:first-of-type::first-letter {
  font-family: var(--font-serif);
  font-weight: var(--weight-h1); /* heaviest weight in the loaded 400–600 range */
  font-size: 4.6em;
  line-height: 0.78;
  float: left;
  padding-right: 0.08em;
  margin-top: 0.03em;
  color: var(--ink);
}

/* ============================================================
   page title block (non-homepage pages)
   ============================================================ */

.page-title {
  max-width: var(--measure-wide);
  margin: var(--space-4) auto var(--space-3);
  padding: 0 var(--space-3);
}

.page-title__dek {
  font-size: var(--text-dek);
  font-weight: var(--weight-dek);
  color: var(--ink-soft);
  max-width: 34rem;
}

/* ============================================================
   entry list (reading list / links / notes / projects)
   ============================================================ */

/* ---- image loading placeholder ----
   While a photo or book cover loads, its box shows a field of small
   square tiles with white grout lines — a nod to the mosaic wordmark —
   and a soft light sweeping across it, in place of a blank box. Pure CSS:
   it's the element's own background, so it's simply covered once the image
   paints, and a small script in base.njk switches the animation off
   (.is-loaded) so a finished image isn't animating behind itself. */
.entry__cover,
.letter__header-img,
.board__photo-trigger {
  background-color: #e4e6f1;
  background-image:
    linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.75) 50%, transparent 70%),
    linear-gradient(#fff 2px, transparent 2px),
    linear-gradient(90deg, #fff 2px, transparent 2px);
  background-size: 250% 100%, 12px 12px, 12px 12px;
  background-repeat: no-repeat, repeat, repeat;
  animation: tile-shimmer 2.2s ease-in-out infinite;
}

@keyframes tile-shimmer {
  from { background-position: 150% 0, 0 0, 0 0; }
  to   { background-position: -50% 0, 0 0, 0 0; }
}

.entry__cover.is-loaded,
.letter__header-img.is-loaded,
.board__photo-trigger.is-loaded {
  animation: none;
  background: none;
}

@media (prefers-reduced-motion: reduce) {
  .entry__cover,
  .letter__header-img,
  .board__photo-trigger { animation: none; }
}

/* tag filter bar — currently only on Links, but works for any list
   whose entries carry a `tags` front-matter field (see list.njk) */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  max-width: var(--measure-wide);
  margin: 0 auto var(--space-3);
  padding: 0 var(--space-3);
}

/* Rectangular, not pill-shaped — deliberately compact (small radius, tight
   padding, smaller type than the standard nav size) so a growing tag
   vocabulary wraps into a dense, calm grid instead of a crowded row of
   fat oval buttons. */
.filter-bar__tag {
  font-family: var(--font-serif);
  font-size: 0.75rem;
  font-weight: var(--weight-nav);
  letter-spacing: var(--tracking-nav);
  text-transform: uppercase;
  color: var(--ink-soft);
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 0.3rem 0.65rem;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.filter-bar__tag:hover { color: var(--accent); border-color: var(--accent); }

.filter-bar__tag.is-active {
  color: var(--card);
  background: var(--accent);
  border-color: var(--accent);
}

/* !important is deliberate: this state utility needs to beat any
   component's own `display` rule regardless of selector specificity
   or where that component's CSS happens to sit in the file. */
.is-filtered-out { display: none !important; }

/* ---- reading list: two independently-scrollable columns ---- */

.reading-columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  max-width: var(--measure-wide);
  margin: 0 auto;
}

@media (min-width: 40rem) {
  .reading-columns { grid-template-columns: 1fr 1fr; }
}

.reading-column__title { margin-bottom: var(--space-2); }

/* Each column scrolls on its own once its list outgrows this height,
   instead of the whole page scrolling — so you can browse Fiction
   without losing your place in Non-Fiction. A short list just renders
   at its natural height with no scrollbar at all. */
.reading-column__scroll {
  max-width: none;
  margin: 0;
  padding: 0 var(--space-2) 0 0;
  max-height: 70vh;
  overflow-y: auto;
}

.entries {
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: 0 var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.entry {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: var(--space-3);
  align-items: baseline;
}

.entry--with-cover {
  grid-template-columns: 4.5rem 6rem 1fr;
  align-items: start;
}

.entry__cover {
  width: 4.5rem;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: 0 10px 22px -12px var(--card-shadow);
}

.entry__date {
  font-family: var(--font-serif);
  font-size: var(--text-caption);
  font-weight: var(--weight-caption);
  color: var(--ink-soft);
  white-space: nowrap;
}

.entry__title {
  font-family: var(--font-serif);
  font-weight: var(--weight-h3);
  font-size: var(--text-h3);
  letter-spacing: var(--tracking-h3);
  color: var(--ink);
  margin: 0 0 0.15rem;
}

.entry__title a { text-decoration: none; }
.entry__title a:hover { color: var(--accent); }

.entry__meta {
  font-family: var(--font-serif);
  font-size: var(--text-caption);
  font-weight: var(--weight-caption);
  letter-spacing: var(--tracking-caption);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
}

.entry__note { color: var(--ink); font-size: 0.95rem; }

@media (max-width: 30rem) {
  .entry { grid-template-columns: 1fr; gap: 0.25rem; }

  .entry--with-cover {
    grid-template-columns: 4.5rem 1fr;
    gap: var(--space-2);
  }
  .entry--with-cover .entry__cover { grid-row: 1 / span 2; }
  .entry--with-cover .entry__date { grid-column: 2; grid-row: 1; }
  .entry--with-cover .entry__body { grid-column: 2; grid-row: 2; }
}

/* ============================================================
   corkboard — a Pinterest-style masonry board
   ============================================================ */

.board {
  max-width: var(--measure-wide);
  margin: var(--space-3) auto var(--space-4);
  padding: var(--space-2) var(--space-2) var(--space-4);
  column-count: 1;
  column-gap: var(--space-3);
}

@media (min-width: 34rem) {
  .board { column-count: 2; }
}

@media (min-width: 56rem) {
  .board { column-count: 3; }
}

.board__photo {
  display: block;
  break-inside: avoid;
  margin: 0 0 var(--space-3);
}

.board__photo-trigger {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 4px;
  overflow: hidden; /* clips the hover zoom to the photo's own frame */
  box-shadow: 0 14px 26px -16px var(--card-shadow);
  cursor: zoom-in;
}

.board__photo img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

/* fades in as it finishes loading, over the tile placeholder */
.board__photo img.is-loading { opacity: 0; }

.board__photo-trigger:hover img,
.board__photo-trigger:focus-visible img { transform: scale(1.02); }

/* the caption: a small chip that fades up from just below on hover/focus */
.board__chip {
  position: absolute;
  left: 0.75rem;
  bottom: 0.75rem;
  max-width: calc(100% - 1.5rem);
  padding: 0.3rem 0.6rem;
  background: var(--card);
  color: var(--ink);
  border-radius: 3px;
  box-shadow: 0 6px 18px -8px rgba(8, 16, 11, 0.5);
  font-family: var(--font-serif);
  font-size: var(--text-caption);
  font-weight: var(--weight-nav);
  letter-spacing: var(--tracking-caption);
  line-height: 1.3;
  text-align: left;
  opacity: 0;
  transform: translateY(4px) scale(0.96);
  transform-origin: bottom left;
  transition: opacity 0.15s ease-out, transform 0.15s ease-out;
  pointer-events: none;
}

.board__photo-trigger:hover .board__chip,
.board__photo-trigger:focus-visible .board__chip {
  opacity: 1;
  transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .board__photo img,
  .board__photo-trigger:hover img { transform: none; }
}

.board__tags {
  margin: 0.5rem 0 0;
  font-size: var(--text-caption);
  font-weight: var(--weight-caption);
  letter-spacing: var(--tracking-caption);
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ---- lightbox: click a Corkboard photo to view it full size ---- */

.lightbox {
  position: fixed;
  inset: 0;
  background: rgba(18, 17, 14, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4) var(--space-3);
  z-index: 200;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s ease, visibility 0s;
}

.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7);
  transform: scale(0.96);
  transition: transform 0.2s ease;
}

.lightbox.is-open .lightbox__img { transform: scale(1); }

.lightbox__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 2.5rem;
  height: 2.5rem;
  border: none;
  background: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}

/* ============================================================
   footer — site navigation, evenly spaced across the bottom
   ============================================================ */

.site-footer {
  max-width: var(--measure-wide);
  margin: var(--space-5) auto 0;
  padding: var(--space-3) var(--space-3) var(--space-4);
  border-top: 1px solid var(--hairline);
}

.site-footer nav ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-1) var(--space-2);
  padding: 0;
  margin: 0;
}

.site-footer nav a {
  font-family: var(--font-serif);
  font-size: var(--text-nav);
  font-weight: var(--weight-nav);
  letter-spacing: var(--tracking-nav);
  text-transform: uppercase;
  text-decoration: none;
  color: #000;
}

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

/* intro paragraph links: plain text at rest, hand-drawn accent stroke on hover */
.hero__intro a {
  position: relative;
  color: inherit;
  text-decoration: none;
}
.hero__intro a::after {
  content: "";
  position: absolute;
  left: -0.03em;
  right: -0.03em;
  bottom: -0.12em;
  height: 0.32em;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%2020'%20preserveAspectRatio='none'%3E%3Cpath%20d='M2%2010%20C%2020%204,%2042%2013,%2072%208%20C%20102%203,%20132%2012,%20162%207%20C%20176%205,%20189%208,%20198%205%20L%20198.5%209.5%20C%20187%2013,%20174%2010.5,%20160%2013%20C%20130%2018,%20102%209.5,%2072%2013.5%20C%2042%2018.5,%2020%2011.5,%201.5%2015%20Z'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
          mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20200%2020'%20preserveAspectRatio='none'%3E%3Cpath%20d='M2%2010%20C%2020%204,%2042%2013,%2072%208%20C%20102%203,%20132%2012,%20162%207%20C%20176%205,%20189%208,%20198%205%20L%20198.5%209.5%20C%20187%2013,%20174%2010.5,%20160%2013%20C%20130%2018,%20102%209.5,%2072%2013.5%20C%2042%2018.5,%2020%2011.5,%201.5%2015%20Z'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.35s cubic-bezier(0.3, 0.7, 0.3, 1);
  pointer-events: none;
}
.hero__intro a:hover::after,
.hero__intro a:focus-visible::after { clip-path: inset(0 0 0 0); }
