/* ============================================================
   BOOKISH — EB Garamond (SIL OFL) in every role, embedded.
   One classical old-style serif; hierarchy comes from size,
   weight and tracking rather than from mixing families.
   ============================================================ */
@font-face {
  font-family: "Bookish";
  src: url(/fonts/ebg-400.woff2) format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Bookish";
  src: url(/fonts/ebg-500.woff2) format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Bookish";
  src: url(/fonts/ebg-600.woff2) format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Bookish";
  src: url(/fonts/ebg-500-italic.woff2) format("woff2");
  font-weight: 500; font-style: italic; font-display: swap;
}

/* ============================================================
   TOKENS
   ============================================================ */
:root {
  --ground:     #e3e7dd;
  --card:       #eef1e9;
  --card-hover: #f9fbf7;
  --ink:        #171a16;
  --muted:      #3c4139;
  --hairline:   #c5cabb;
  --accent:     #14505c;

  --type: "Bookish", "EB Garamond", Georgia, "Iowan Old Style", serif;

  --body:   clamp(17px, 1.35vw, 19.5px);

  --shell:  1240px;
  --gutter: clamp(20px, 4vw, 56px);
  --rail:   clamp(120px, 13vw, 170px);
  --chapter-rail: clamp(140px, 16vw, 205px);   /* wider: holds italic titles */
  --chapter-gap:  clamp(20px, 3vw, 44px);
  --radius: 3px;
  --ease:   cubic-bezier(0.2, 0.7, 0.3, 1);
}

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

html {
  -webkit-text-size-adjust: 100%;
  background: var(--ground);
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* anchors must clear the sticky nav */
#contact { scroll-margin-top: clamp(70px, 12vh, 100px); }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--type);
  font-weight: 400;
  font-size: 100%;
  line-height: 1.62;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.shell {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter) clamp(56px, 9vh, 96px);
}

/* The 404 has too little content to reach the fold, which would leave the
   colophon floating in the middle of the screen. svh (not vh) so mobile browser
   chrome doesn't push the footer below the fold and invent a scrollbar. */
.shell--short {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}
.shell--short .foot { margin-top: auto; }

a { color: inherit; }

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

/* Tracked small caps — the utility voice, same family as everything else. */
/* Chapter titles borrow the italic serif voice used by the section heads,
   sized for the rail. Tracked caps were the weakest option available. */
.label {
  font-size: clamp(19px, 1.6vw, 22px);
  font-weight: 500;
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.15;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}

.rule { height: 1px; border: 0; margin: 0; background: var(--hairline); }

/* Visible only when focused. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 12px 18px;
  background: var(--accent);
  color: #eef1e9;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  text-decoration: none;
}
.skip:focus { left: 0; }

/* ============================================================
   NAV — slim, quiet, above the masthead on both pages
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--ground);
  transition: transform 260ms var(--ease);
  will-change: transform;
  display: flex;
  flex-wrap: wrap;
  gap: 10px clamp(18px, 2.4vw, 30px);
  padding-top: clamp(14px, 2.2vh, 22px);
  padding-bottom: 14px;
  margin-bottom: clamp(26px, 4vw, 42px);
  border-bottom: 1px solid var(--hairline);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.nav a {
  color: var(--muted);
  text-decoration: none;
  transition: color 160ms var(--ease);
  /* padding buys a real tap target; 19px of text was below the 24px minimum */
  padding: 9px 0;
  margin: -9px 0;
}
.nav a:hover, .nav a:focus-visible { color: var(--accent); }

/* Slid out of view on scroll down; JS toggles this. */
.nav--away { transform: translateY(-100%); }

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
  .nav--away { transform: none; }
}

/* The page you are on is stated, not linked away from. */
.nav [aria-current="page"] {
  color: var(--ink);
  cursor: default;
}

/* ============================================================
   MASTHEAD — name first, then portrait beside the intro
   ============================================================ */
.masthead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 32px;
  padding-bottom: clamp(16px, 2.2vw, 24px);
}

.name {
  margin: 0;
  font-size: clamp(40px, 5.4vw, 74px);
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.02;
  text-wrap: balance;
}

.place {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  white-space: nowrap;
}

.hero {
  display: grid;
  grid-template-columns: minmax(190px, 282px) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 62px);
  align-items: start;
  padding: clamp(30px, 4vw, 46px) 0 clamp(34px, 4.5vw, 54px);
  border-top: 1px solid var(--hairline);
}

/* Wide screens: the photo fills the row so its height matches the text. Scoped to
   a min-width query because in the stacked layout the row height is the image. */
@media (min-width: 901px) {
  .hero { align-items: stretch; }
  .portrait {
    height: 100%;
    aspect-ratio: auto;
    object-position: center center;
  }
}

.portrait {
  width: 100%;
  height: auto;          /* the height="" attribute would otherwise beat aspect-ratio */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 22%;
  display: block;
  border-radius: 2px;
  background: var(--card);
}

/* About's intro has no photo column to bound it, so it needs the same measure as
   the prose below it — uncapped it ran ~150 characters per line. */
.intro .lede { max-width: none; }

.intro {
  display: grid;
  /* identical template to .chapter, including the year column, so the body
     column comes out exactly the same width */
  grid-template-columns: var(--chapter-rail) minmax(0, 1fr) clamp(72px, 7vw, 104px);
  column-gap: var(--chapter-gap);
  padding: clamp(28px, 4vw, 44px) 0 clamp(32px, 4.5vw, 52px);
  border-top: 1px solid var(--hairline);
}
.intro > * { grid-column: 2; }

.lede {
  font-size: var(--body);
  line-height: 1.62;
  margin: 0;
  max-width: none;
  text-wrap: pretty;
}
.lede + .lede { margin-top: 15px; }

/* ============================================================
   BANDS — one continuous vertical sequence. Extra page width
   becomes columns inside each row, not longer lines.
   ============================================================ */
.bands { margin-top: clamp(14px, 1.8vw, 20px); }

.bands-head { margin-top: clamp(40px, 6vh, 68px); }

.band {
  display: grid;
  grid-template-columns: var(--rail) minmax(150px, 230px) minmax(0, 1fr);
  grid-template-areas: "label title blurb";
  column-gap: clamp(20px, 3vw, 44px);
  align-items: start;
  text-decoration: none;
  color: var(--ink);
  background: var(--card);
  border-top: 1px solid var(--hairline);
  border-left: 3px solid var(--hairline);
  padding: clamp(15px, 1.8vw, 22px) clamp(20px, 2.4vw, 30px);
  transition: background 180ms var(--ease), border-color 180ms var(--ease),
              box-shadow 180ms var(--ease);
}
.band:last-child { border-bottom: 1px solid var(--hairline); }

/* Text inside an anchor is hard to select because dragging across it starts a
   link drag. Disabling the drag lets the copy be selected normally. */
a.band {
  -webkit-user-drag: none;
  user-select: text;
  -webkit-user-select: text;
}

a.band:hover, a.band:focus-visible {
  background: var(--card-hover);
  border-left-color: var(--accent);
  /* inset shadow thickens the accent rail without shifting content */
  box-shadow: inset 5px 0 0 var(--accent);
}
a.band:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.band__label {
  grid-area: label;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  transition: color 180ms ease;
}
a.band:hover .band__label,
a.band:focus-visible .band__label { color: var(--accent); }

.band__title {
  grid-area: title;
  margin: 0;
  font-size: clamp(22px, 1.9vw, 27px);
  font-weight: 500;
  line-height: 1.12;
  text-wrap: balance;
  transition: color 180ms var(--ease);
}
a.band:hover .band__title,
a.band:focus-visible .band__title { color: var(--accent); }

.band__blurb {
  grid-area: blurb;
  margin: 0;
  font-size: 16.5px;
  line-height: 1.52;
  color: var(--muted);
  text-wrap: pretty;
}

/* ============================================================
   CONTACT — serif heading, rule, then squared action buttons
   ============================================================ */
.contact { margin-top: clamp(40px, 7vh, 76px); }

.section-head {
  margin: 0;
  font-size: clamp(25px, 2.7vw, 36px);
  font-weight: 500;
  font-style: italic;
  line-height: 1;
  letter-spacing: -0.005em;
}

/* Left-aligned to the same spine as the nav, the masthead and "What I'm
   building". Centring gave the three elements in this block three different
   left edges (665 / 271 / 637 at 1440px) because each one centres on its own
   width — so the closing section was the only place the page's left edge broke. */
.contact__head { text-align: left; }

.contact__body { padding-top: clamp(8px, 1vw, 12px); }

.contact__invite {
  margin: 0;
  max-width: none;
  font-size: 17.5px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

.contact__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 22px;
  margin-top: clamp(24px, 3.2vw, 36px);
}

/* Squared, tracked, no radius — the reference's register. */
.btn {
  display: inline-flex;
  align-items: center;
  padding: 11px 20px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background 180ms var(--ease), color 180ms var(--ease),
              border-color 180ms var(--ease);
}
/* Same petrol as the accent rail that appears on card hover. */
.btn--solid {
  background: var(--accent);
  border-color: var(--accent);
  color: #eef1e9;
}
.btn--solid:hover, .btn--solid:focus-visible { background: #0f4450; border-color: #0f4450; }

.btn--accent {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
}
.btn--accent:hover, .btn--accent:focus-visible {
  background: var(--accent);
  color: #eef1e9;
}

/* LinkedIn as its mark, not a button */
.contact__icon {
  display: inline-flex;
  padding: 6px;
  margin: -6px;
  color: var(--muted);
  transition: color 180ms var(--ease), transform 180ms var(--ease);
}
.contact__icon svg { width: 33px; height: 33px; display: block; fill: currentColor; }
.contact__icon:hover, .contact__icon:focus-visible {
  color: var(--accent);
  transform: translateY(-2px);
}

/* ============================================================
   FOOTER
   ============================================================ */
.foot {
  margin-top: clamp(34px, 5vh, 56px);
  padding-top: 22px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.foot__links {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.foot__links a { color: var(--muted); text-decoration: none; }
.foot__links a:hover, .foot__links a:focus-visible { color: var(--accent); }

/* A sentence, so it stays sentence-cased rather than tracked caps. */
.foot__colophon {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
  text-align: center;
}

/* ============================================================
   ABOUT
   ============================================================ */
.back {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  display: inline-block;
  margin-bottom: clamp(28px, 4vw, 44px);
  transition: color 180ms ease;
}
.back:hover, .back:focus-visible { color: var(--accent); }

.chapter {
  display: grid;
  grid-template-columns: var(--chapter-rail) minmax(0, 1fr) clamp(72px, 7vw, 104px);
  grid-template-areas: "label body when";
  column-gap: var(--chapter-gap);
  padding: clamp(28px, 3.5vw, 44px) 0;
  border-top: 1px solid var(--hairline);
}

.chapter__rail { grid-area: label; }

.chapter__when {
  grid-area: when;
  justify-self: end;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--muted);
  margin: 0;
  white-space: nowrap;
}

.chapter__body { grid-area: body; min-width: 0; }

.prose {
  font-size: var(--body);
  line-height: 1.66;
  margin: 0;
  max-width: none;
  text-wrap: pretty;
}
.prose + .prose { margin-top: 16px; }
.prose b { font-weight: 600; }

/* Closing line of the long version. */
.prose--closing {
  font-style: italic;
  color: var(--muted);
  font-size: clamp(18px, 1.5vw, 21.5px);
  margin-top: clamp(20px, 2.4vw, 28px);
}

/* A beat: a declarative one-liner the copy sets up and lands. Used sparingly —
   three times across the page — so it reads as rhythm, not a tic. Italic matches
   the heading voice; full ink distinguishes it from the fading closing line. */
.prose--beat {
  font-size: clamp(21px, 1.85vw, 26px);
  font-style: italic;
  line-height: 1.38;
  color: var(--ink);
  max-width: 52ch;
  text-wrap: pretty;
}
.prose + .prose--beat { margin-top: clamp(26px, 3.2vw, 40px); }
.prose--beat + .prose { margin-top: clamp(26px, 3.2vw, 40px); }

/* Hand-off from the landing intro to the long version. */
/* Underlined at rest so it reads as a link without needing a hover to find out.
   The offset keeps the rule clear of Garamond's descenders instead of striking
   through the y and the comma. */
.more-link {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: text-decoration-thickness 160ms var(--ease);
}
.more-link:hover, .more-link:focus-visible { text-decoration-thickness: 2px; }

/* anchored chapters must clear the sticky nav */
.chapter[id] { scroll-margin-top: clamp(70px, 12vh, 100px); }


/* Hand-off from the summary to the long version. */
/* Set as running prose, not a tracked-caps label: it reads as the next sentence
   after the intro rather than as UI chrome. The accent colour carries the link;
   the underline only appears on hover / keyboard focus. */
.intro__more {
  margin: clamp(20px, 2.6vw, 28px) 0 0;
  font-size: var(--body);
  color: var(--muted);
}

/* Two-line comparison, set as a ledger rather than a sentence. */
.ledger {
  margin: clamp(18px, 2.4vw, 26px) 0;
  padding: 0;
  display: grid;
  gap: 0;
  font-size: var(--body);
  max-width: none;   /* fills the column, like .prose */
}
.ledger div {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  column-gap: 20px;
  padding: 10px 0;
  border-bottom: 1px solid var(--hairline);
}
.ledger div:first-child { border-top: 1px solid var(--hairline); }
.ledger dt {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 3px;
}
.ledger dd { margin: 0; font-size: 17.5px; line-height: 1.45; }

@media (max-width: 540px) {
  .ledger div { grid-template-columns: minmax(0, 1fr); row-gap: 3px; }
}

.record {
  list-style: none;
  margin: clamp(20px, 2.5vw, 28px) 0 0;
  padding: 0;
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 72ch;
}
.record li {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr);
  column-gap: 18px;
  padding: 8px 0;
  border-top: 1px solid var(--hairline);
}
.record li:last-child { border-bottom: 1px solid var(--hairline); }
.record span + span { color: var(--ink); }

.facts {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(20px, 2.5vw, 34px);
  font-size: 16.5px;
  line-height: 1.5;
}
.facts div { display: flex; flex-direction: column; gap: 7px; }
.facts dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted);
}
.facts dd { margin: 0; }

/* ============================================================
   ENTRANCE
   ============================================================ */
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.head { animation: rise 620ms var(--ease) 40ms both; }
.band { animation: rise 520ms var(--ease) both; }
.band:nth-child(1) { animation-delay: 165ms; }
.band:nth-child(2) { animation-delay: 230ms; }
.band:nth-child(3) { animation-delay: 295ms; }
.band:nth-child(4) { animation-delay: 360ms; }
.band:nth-child(5) { animation-delay: 425ms; }

@media (prefers-reduced-motion: reduce) {
  .head, .band { animation: none !important; opacity: 1; transform: none; }
  .band, .band__label { transition: none !important; }
}

/* ============================================================
   NARROW
   ============================================================ */
@media (max-width: 900px) {
  .hero { grid-template-columns: minmax(0, 1fr); }
  .portrait { max-width: 208px; }

  .band {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "label"
      "title"
      "blurb";
    align-items: start;
    row-gap: 9px;
  }


  .contact { grid-template-columns: minmax(0, 1fr); row-gap: 14px; }

  .intro { grid-template-columns: minmax(0, 1fr); }
  .intro > * { grid-column: 1; }

  .chapter {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label when"
      "body  body";
    row-gap: 16px;
  }
}

@media (max-width: 540px) {
  .record li { grid-template-columns: minmax(0, 1fr); row-gap: 2px; }
}

/* Mobile: every label spelled out, allowed to wrap to two rows. Nothing is
   abbreviated and the type stays at a thumb-friendly size; the cost is ~29px. */
@media (max-width: 480px) {
  .nav { gap: 8px 14px; }
}
