/* Bazyl Horsey portfolio
   Styles only. Structure lives in src/Main.elm and is rendered by Jorn.
   Theme is a class on the root element, which Jorn patches like any other
   attribute. One self-hosted display face for headlines, system fonts for
   everything else, no reset from anywhere, no build tooling. */

/* Big Shoulders Display (SIL OFL 1.1, fonts/BigShoulders-OFL.txt). A condensed
   grotesk drawn for Chicago, named for Sandburg's "City of the Big Shoulders":
   signage and gig-poster DNA. Latin subset, variable weight, 29 KB. */
@font-face {
  font-family: "Big Shoulders Display";
  src: url("fonts/bigshoulders.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  background: #ebe8df;
  font-family: system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* The shell sets data-theme on <html> before first paint and keeps it in
   sync with the Elm theme, so overscroll and the area behind the page match. */
html[data-theme="night"],
html[data-theme="night"] body {
  background: #141210;
  color-scheme: dark;
}

html[data-theme="paper"] {
  color-scheme: light;
}

/* theme ------------------------------------------------------------- */

.page {
  --sans: system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    "Liberation Mono", monospace;
  --display: "Big Shoulders Display", "Arial Narrow", var(--sans);
  --gap: 1px;
  /* In rem, not px: this tracks the root font scale below, so the whole layout
     grows on a large display instead of stranding a narrow column in the
     middle of the screen. */
  --maxw: 72.5rem;

  min-height: 100vh;
  font-family: var(--sans);
}

.page--paper {
  /* Newsprint and black ink, one signal color: inspection-tag orange. It is
     the color of a QC fail tag on a dock and of a punk flyer on a telephone
     pole, which covers both halves of this site with one hue.
     --accent is the fill (caret, dot, chips, big figures, the band).
     --accent-text is the same hue darkened to pass 4.5:1 for small text. */
  --paper: #ebe8df;
  --paper-2: #dfdbd0;
  --ink: #121110;
  --ink-2: #34312c;
  --muted: #55514a;
  --accent: #e8501a;
  --accent-text: #a8350a;
  --accent-ink: #121110;
  --line: #121110;
  --shadow: 4px 4px 0 var(--ink);
  --grain: 0.26;

  background: var(--paper);
  color: var(--ink);
}

/* The second selector covers the prerendered HTML, which is always built as
   paper: a night visitor sees night colors from the first paint, before Jorn
   mounts and swaps the class. After mount the shell keeps <html data-theme>
   in sync with the class, so the two never disagree. */
.page--night,
html[data-theme="night"] .page {
  /* The same page with the ink and paper swapped, and the same orange,
     brightened a step so it holds up on warm near-black. One brand, two
     lighting conditions, not two palettes. */
  --paper: #141210;
  --paper-2: #1e1b18;
  --ink: #ece8df;
  --ink-2: #c9c4b9;
  --muted: #9a958b;
  --accent: #ff5a1f;
  --accent-text: #ff5a1f;
  --accent-ink: #141210;
  --line: #ece8df;
  --shadow: 4px 4px 0 #000;
  --grain: 0.14;

  background: var(--paper);
  color: var(--ink);
}

/* paper grain, generated by feTurbulence so there is no image file */
.page::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--grain);
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

.page--night::before,
html[data-theme="night"] .page::before {
  mix-blend-mode: screen;
}

.page > * {
  position: relative;
  z-index: 1;
}

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

a {
  color: inherit;
}

::selection {
  background: var(--accent);
  color: var(--accent-ink);
}

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

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  --pad: clamp(1.1rem, 4vw, 2.5rem);
  padding-inline: var(--pad);
}

/* top bar ----------------------------------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--paper);
  border-bottom: var(--gap) solid var(--line);
}

.topbar-in {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  height: 3.1rem;
}

.mark {
  font: 700 0.72rem/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
}

.topnav {
  display: flex;
  gap: 1.15rem;
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: none;
}

.topnav::-webkit-scrollbar {
  display: none;
}

.topnav a {
  font: 400 0.78rem/1 var(--mono);
  color: var(--muted);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding: 0.4rem 0;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}

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

.theme {
  flex: none;
  font: 600 0.7rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink);
  background: transparent;
  border: var(--gap) solid var(--line);
  padding: 0.42rem 0.6rem;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.theme:hover {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

/* hero -------------------------------------------------------------- */

.hero {
  padding-block: clamp(3.2rem, 11vw, 7rem) clamp(2.6rem, 7vw, 4.5rem);
}

.hero {
  display: grid;
  gap: 3rem;
  align-items: center;
}

@media (min-width: 1000px) {
  .hero {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
    column-gap: 3.5rem;
  }
}

/* fig. 1 ---------------------------------------------------------------- */

.diagram {
  width: 100%;
  max-width: 400px;
  height: auto;
  justify-self: center;
  overflow: visible;
}

@media (min-width: 1000px) {
  .diagram {
    justify-self: end;
  }
}

.diagram .dg-box {
  fill: var(--paper);
  stroke: var(--line);
  stroke-width: 1.5;
}

.diagram .dg-shadow {
  fill: var(--ink);
}

.page--night .diagram .dg-shadow,
html[data-theme="night"] .diagram .dg-shadow {
  fill: #000;
}

.diagram .dg-tick,
.diagram .dg-head {
  fill: var(--ink);
}

.diagram .dg-tick {
  fill: var(--accent);
}

.diagram .dg-edge {
  stroke: var(--ink);
  stroke-width: 1.5;
}

.diagram .dg-title {
  font: 700 14px var(--mono);
  letter-spacing: 0.12em;
  fill: var(--ink);
}

.diagram .dg-sub {
  font: 400 13px var(--sans);
  fill: var(--ink-2);
}

.diagram .dg-hot {
  font-weight: 700;
  fill: var(--accent-text);
}

.diagram .dg-label,
.diagram .dg-cap,
.diagram .dg-foot {
  font: 500 11px var(--mono);
  letter-spacing: 0.06em;
  fill: var(--muted);
}

.diagram .dg-cap {
  font-weight: 700;
  letter-spacing: 0.16em;
}

.diagram .dg-loop {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
}

.diagram .dg-loop-head {
  fill: var(--accent);
}

.diagram .dg-loop-label {
  font: 700 11px var(--mono);
  letter-spacing: 0.1em;
  fill: var(--accent-text);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 1.8rem;
  padding: 0.4rem 0.75rem;
  border: var(--gap) solid var(--line);
  font: 500 0.72rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

.status .dot {
  width: 8px;
  height: 8px;
  background: var(--accent);
  border-radius: 50%;
  animation: pulse 2.4s ease-in-out infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.28;
  }
}

.name {
  margin: 0 0 0.12em;
  font-family: var(--display);
  font-size: clamp(4.2rem, 16vw, 9.5rem);
  font-weight: 900;
  line-height: 0.9;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.caret {
  display: inline-block;
  width: 0.13em;
  height: 0.72em;
  margin-left: 0.1em;
  background: var(--accent);
  vertical-align: 0.04em;
  animation: blink 1.15s steps(1) infinite;
}

@keyframes blink {
  0%,
  50% {
    opacity: 1;
  }
  50.01%,
  100% {
    opacity: 0;
  }
}

.lede {
  max-width: 34ch;
  margin: 0 0 2.4rem;
  font-size: clamp(1.1rem, 2.4vw, 1.42rem);
  line-height: 1.45;
  color: var(--ink-2);
  font-weight: 450;
}

.claim-line {
  max-width: 30ch;
  margin: 0 0 2.4rem;
  font-size: clamp(1.35rem, 3.4vw, 2.1rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.02em;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}

.btn {
  display: inline-block;
  padding: 0.78rem 1.25rem;
  border: var(--gap) solid var(--line);
  font: 600 0.8rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-decoration: none;
  color: var(--ink);
  transition: transform 0.12s, box-shadow 0.12s, background 0.15s, color 0.15s;
}

.btn:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow);
}

.btn-solid {
  background: var(--ink);
  color: var(--paper);
}

.btn-solid:hover {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

/* sections ---------------------------------------------------------- */

.section {
  padding-block: clamp(3.4rem, 9vw, 6rem);
}

.band-rule {
  border-top: var(--gap) solid var(--line);
}

.eyebrow {
  margin: 0 0 1.4rem;
  font: 600 0.72rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.17em;
  color: var(--accent-text);
}

.h2 {
  margin: 0 0 2.4rem;
  max-width: 18ch;
  font-family: var(--display);
  font-size: clamp(2.5rem, 6vw, 4.2rem);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.005em;
}

/* split: heading on the left, argument on the right ------------------- */

@media (min-width: 1000px) {
  .split {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    column-gap: 4rem;
    align-items: start;
  }
  .split-head {
    position: sticky;
    top: 5.5rem;
  }
  .split-head .h2 {
    margin-bottom: 0;
  }
}

/* claims ------------------------------------------------------------ */

.claims {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: c;
}

.claims li {
  counter-increment: c;
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  column-gap: 1.2rem;
  padding-block: 1.9rem;
  border-top: var(--gap) solid var(--line);
}

.claims li:last-child {
  border-bottom: var(--gap) solid var(--line);
}

/* The counter is a grid item too, so place it deliberately: column one,
   spanning both rows. Without this the <p> wraps back into the 4.5rem number
   column and renders as a one-word-per-line ribbon. */
.claims li::before {
  content: "0" counter(c);
  grid-column: 1;
  grid-row: 1 / span 2;
  font: 600 0.82rem/1.9 var(--mono);
  color: var(--accent-text);
  letter-spacing: 0.05em;
}

.claims li h3 {
  grid-column: 2;
  margin: 0 0 0.55rem;
  font-size: 1.24rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.015em;
}

.claims li p {
  grid-column: 2;
  margin: 0;
  max-width: 62ch;
  color: var(--ink-2);
}

/* said about working with me ---------------------------------------- */

/* Sits right under the claim section, outside its grid, so the sticky
   heading on the left cannot slide down over the cards. */
.said {
  margin-top: calc(-1 * clamp(1.6rem, 5vw, 3rem));
  padding-bottom: clamp(1rem, 3vw, 2rem);
}

/* Phones and tablets: a swipeable strip. The next card peeks in from the
   right so it reads as "there is more", and snap keeps cards from landing
   half-on. No JS, no autoplay. */
.said-track {
  list-style: none;
  margin: 0 calc(-1 * var(--pad));
  padding: 0.4rem var(--pad) 1rem;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(85%, 26rem);
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--pad);
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

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

.said-card {
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1.4rem;
  padding: 1.5rem;
  border: var(--gap) solid var(--line);
  border-top: 4px solid var(--accent);
  background: var(--paper);
}

.said-card blockquote {
  margin: 0;
}

.said-card blockquote p {
  margin: 0;
  font-size: 1.06rem;
  line-height: 1.55;
  color: var(--ink);
}

.said-who {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.said-who a,
.said-who b {
  font-weight: 700;
  width: fit-content;
  color: var(--ink);
}

.said-who b {
  border-bottom: 2px solid transparent;
}

.said-who a {
  text-decoration: none;
  border-bottom: 2px solid var(--accent);
}

.said-who a:hover {
  color: var(--accent-text);
}

.said-who span {
  font: 600 0.68rem/1.3 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}

/* Wide screens: three cards and a sliver of the next, so it is obvious the
   strip keeps going. Stays inside the column instead of bleeding to the edge. */
@media (min-width: 1000px) {
  .said-track {
    margin: 0;
    padding: 0.4rem 0 1rem;
    scroll-padding-inline: 0;
    grid-auto-columns: calc((100% - 3rem) / 3.2);
  }
}

.said-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.said-head .eyebrow {
  margin: 0;
}

.said-nav {
  display: flex;
  gap: 0.5rem;
}

.said-arrow {
  width: 2.4rem;
  height: 2.4rem;
  display: grid;
  place-items: center;
  font: 600 1rem/1 var(--sans);
  color: var(--ink);
  background: var(--paper);
  border: var(--gap) solid var(--line);
  cursor: pointer;
  transition: transform 0.14s, box-shadow 0.14s;
}

.said-arrow:hover {
  transform: translate(-2px, -2px);
  box-shadow: 2px 2px 0 var(--ink);
}

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

/* essay page ------------------------------------------------------- */

.essay {
  padding-block: clamp(3rem, 8vw, 5.5rem) clamp(3rem, 8vw, 5rem);
}

.essay-head,
.essay-body,
.essay-end {
  max-width: 42rem;
  margin-inline: auto;
}

.essay-head {
  padding-bottom: 2.2rem;
  margin-bottom: 2.6rem;
  border-bottom: var(--gap) solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.1rem;
}

.essay-head .eyebrow {
  margin: 0;
}

.essay-title {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2.7rem, 8vw, 4.6rem);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.005em;
}

.essay-byline {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  font: 600 0.72rem/1.3 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}

.essay-byline b {
  color: var(--ink);
}

.essay-head .link {
  margin-top: 0.3rem;
}

.essay-body {
  font-size: 1.1rem;
  line-height: 1.72;
  color: var(--ink-2);
}

.essay-body h2 {
  margin: 3rem 0 0.9rem;
  font-size: 1.45rem;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.essay-body h2:first-child {
  margin-top: 0;
}

.essay-body p {
  margin: 0 0 1.15rem;
}

.essay-quote {
  margin: 1.8rem 0;
  padding: 0.2rem 0 0.2rem 1.3rem;
  border-left: 4px solid var(--accent);
}

.essay-quote p {
  margin: 0;
  font-size: 1.3rem;
  line-height: 1.5;
  font-weight: 600;
  color: var(--ink);
}

.essay-steps,
.essay-bullets {
  margin: 1.4rem 0 1.6rem;
  padding: 0;
  list-style: none;
}

.essay-steps {
  counter-reset: s;
  border-top: var(--gap) solid var(--line);
}

.essay-steps li {
  counter-increment: s;
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  padding-block: 0.95rem;
  border-bottom: var(--gap) solid var(--line);
}

.essay-steps li::before {
  content: counter(s, decimal-leading-zero);
  font: 600 0.8rem/2.15 var(--mono);
  color: var(--accent-text);
  letter-spacing: 0.05em;
}

.essay-bullets li {
  position: relative;
  padding-left: 1.3rem;
  margin-bottom: 0.7rem;
}

.essay-bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--accent);
}

.essay-steps strong,
.essay-bullets strong {
  color: var(--ink);
}

.essay-end {
  margin-top: 3.2rem;
  padding-top: 2rem;
  border-top: var(--gap) solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}

/* receipts ---------------------------------------------------------- */

.nums {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: var(--gap) solid var(--line);
  background: var(--gap);
  gap: var(--gap);
}

.num {
  background: var(--paper);
  padding: 1.5rem 1.2rem 1.3rem;
  min-height: 8.5rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.9rem;
  transition: background 0.18s;
}

.num:hover {
  background: var(--paper-2);
}

.num b {
  display: block;
  font-family: var(--mono);
  font-size: clamp(1.9rem, 3.6vw, 2.6rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--accent);
}

.num span {
  display: block;
  font-size: 0.84rem;
  line-height: 1.4;
  color: var(--muted);
}

/* Same grid, but living inside a role entry rather than owning a section, so
   it sits closer to the prose and the figures are sized down to match. */
.nums--inline {
  margin-top: 1.7rem;
}

.nums--inline .num {
  min-height: 0;
  padding: 1.05rem 1rem 0.95rem;
}

/* Figures in the display face, sized to their own cell so "10.9→3" and
   "400→26" fit at every width. */
.nums--inline .num {
  container-type: inline-size;
}

.nums--inline .num b {
  font-family: var(--display);
  font-size: clamp(1.6rem, 17cqi, 2.6rem);
  font-weight: 800;
  letter-spacing: 0;
  white-space: nowrap;
}

.nums--inline .num span {
  font-size: 0.78rem;
}

/* work -------------------------------------------------------------- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0 0 1.6rem;
}

.filter {
  font: 600 0.7rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  background: transparent;
  border: var(--gap) solid var(--line);
  padding: 0.45rem 0.7rem;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

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

.filter.is-on {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.work {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.4rem;
}

.card {
  min-width: 0;
  border: var(--gap) solid var(--line);
  padding: 1.5rem;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  transition: transform 0.14s, box-shadow 0.14s, background 0.18s;
}

.card:hover {
  transform: translate(-3px, -3px);
  box-shadow: var(--shadow);
}

.card-feature {
  grid-column: 1 / -1;
  background: var(--paper-2);
}

.card-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.card-head h3 {
  margin: 0 0.3rem 0 0;
  font-size: 1.32rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.card p {
  margin: 0;
  color: var(--ink-2);
  max-width: 66ch;
}

.card-quote {
  font-size: 1.05rem;
  line-height: 1.55;
  color: var(--ink) !important;
  border-left: 3px solid var(--accent);
  padding-left: 1rem;
}

.tag,
.chip {
  font: 600 0.66rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.34rem 0.5rem;
  border: var(--gap) solid var(--line);
  white-space: nowrap;
}

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

.tag.chip-done,
.tag.chip-next,
.tag.chip-plan {
  color: var(--accent-ink);
  border-color: var(--accent);
}

.tag.chip-done {
  background: var(--accent);
}

.tag.chip-next {
  background: var(--ink);
  color: var(--paper);
}

.tag.chip-plan {
  color: var(--muted);
  border-style: dashed;
  background: transparent;
}

.roadmap {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.84rem;
  border: var(--gap) solid var(--line);
  background: var(--paper);
}

.roadmap td {
  padding: 0.55rem 0.7rem;
  border-bottom: var(--gap) solid var(--line);
  vertical-align: middle;
}

.roadmap tr:last-child td {
  border-bottom: 0;
}

.roadmap td:first-child {
  width: 2.4rem;
  font-family: var(--mono);
  color: var(--muted);
  text-align: center;
}

.roadmap td:nth-child(2) {
  color: var(--ink-2);
}

.roadmap td:last-child {
  width: 6.4rem;
  text-align: right;
}

.roadmap .chip {
  display: inline-block;
}

.chip-done {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.chip-next {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.chip-plan {
  color: var(--muted);
  border-style: dashed;
}

.link {
  align-self: flex-start;
  margin-top: auto;
  font: 500 0.8rem/1 var(--mono);
  color: var(--accent-text);
  text-decoration: none;
  border-bottom: var(--gap) solid var(--accent-text);
  padding-bottom: 0.28rem;
  word-break: break-word;
}

.link:hover {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* path -------------------------------------------------------------- */

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

.path li {
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 1.6rem;
  padding-block: 2rem;
  border-top: var(--gap) solid var(--line);
}

.path li:last-child {
  border-bottom: var(--gap) solid var(--line);
}

.path-when {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.path-when b {
  font: 700 0.86rem/1 var(--mono);
  letter-spacing: -0.01em;
}

.path-when span {
  font: 400 0.74rem/1 var(--mono);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.path-what h3 {
  margin: 0 0 0.5rem;
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.path-role {
  display: block;
  font: 400 0.78rem/1.5 var(--mono);
  color: var(--accent-text);
  letter-spacing: 0.02em;
  margin-top: 0.25rem;
}

.path-what p {
  margin: 0 0 0.9rem;
  max-width: 68ch;
  color: var(--ink-2);
}

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

/* writing ----------------------------------------------------------- */

.writes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.4rem;
}

/* The first group sits right under the heading, not 3rem below it. */
.h2 + div > .group-label:first-child {
  margin-top: 0;
}

.write--paper h3 {
  max-width: 40ch;
  font-size: 1.3rem;
}

.write--paper p {
  max-width: 68ch;
}

.write-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.6rem;
}

.write {
  border-top: 4px solid var(--ink);
  padding-top: 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Scoped under .write so it outranks ".write p", which was quietly blowing
   these labels up to body size. */
.write .write-meta {
  margin: 0;
  font: 600 0.68rem/1.4 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}

.write h3 {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1.32;
  letter-spacing: -0.012em;
}

.write p {
  margin: 0;
  font-size: 0.92rem;
  color: var(--ink-2);
}

/* posts: the written-down half, as a compact index under the features */

.group-label {
  margin: 3rem 0 1rem;
  font: 600 0.72rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.17em;
  color: var(--muted);
}

.posts {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: var(--gap) solid var(--line);
}

.posts li {
  border-bottom: var(--gap) solid var(--line);
}

.post {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr) 2rem;
  gap: 1.4rem;
  align-items: baseline;
  padding: 1.15rem 0.2rem;
  text-decoration: none;
  color: var(--ink);
  transition: background 0.15s;
}

.post:hover {
  background: var(--paper-2);
}

.post-meta {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.post-meta b {
  font: 700 0.86rem/1 var(--mono);
}

.post-meta span {
  font: 400 0.72rem/1 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.post-body {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.post-title {
  font-size: 1.12rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.012em;
}

.post-gist {
  max-width: 64ch;
  font-size: 0.92rem;
  color: var(--ink-2);
}

.post-go {
  justify-self: end;
  font: 600 1rem/1 var(--mono);
  color: var(--accent-text);
  transition: transform 0.15s;
}

.post:hover .post-go {
  transform: translateX(4px);
}

/* band -------------------------------------------------------------- */

/* Off the clock: a quiet panel on the second paper tone. It keeps the flyer
   DNA in the label strip, the tilted name and the numbered tracks, and stays
   out of the way of the work. */
.band {
  --band-bg: var(--paper-2);
  --band-ink: var(--ink);
  --band-dim: var(--ink-2);
  --band-rule: var(--line);

  position: relative;
  overflow: hidden;
  background: var(--band-bg);
  color: var(--band-ink);
  border-block: var(--gap) solid var(--line);
  padding-block: clamp(3.4rem, 9vw, 6rem);
}

/* Photocopy noise, heavier than the page grain. */
.band::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 1.6 -0.55'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

.band-in {
  position: relative;
}

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

.band-name {
  margin: 0 0 1.1rem;
  font-family: var(--display);
  transform: rotate(-1.4deg);
  transform-origin: left bottom;
  font-size: clamp(2.8rem, 9vw, 5.6rem);
  font-weight: 900;
  line-height: 0.85;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--band-ink);
}

.band-sub {
  margin: 0 0 2.6rem;
  font-family: var(--mono);
  font-size: 0.95rem;
  display: inline-block;
  padding: 0.35rem 0.6rem;
  background: var(--band-ink);
  color: var(--band-bg);
  letter-spacing: 0.01em;
}

.tracks {
  list-style: none;
  margin: 0 0 2.4rem;
  padding: 0;
  border-top: var(--gap) solid var(--band-rule);
  max-width: 34rem;
}

.tracks {
  counter-reset: t;
}

/* Two columns once there is room: six tracks read as a short block, not a
   long list. Fills down each column first, like a record sleeve: 01 to 03 on
   the left, 04 to 06 on the right. Main.elm sets --track-rows to half the
   track count, rounded up, so adding a song keeps the columns balanced. */
@media (min-width: 701px) {
  .tracks {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(var(--track-rows, 3), auto);
    grid-auto-flow: column;
    column-gap: 2.4rem;
    max-width: 46rem;
    border-top: 0;
  }
  /* The rule above each column, so it breaks at the gap like the others. */
  .tracks li.col-top {
    border-top: var(--gap) solid var(--band-rule);
  }
}

.tracks li {
  counter-increment: t;
  display: flex;
  gap: 1rem;
  align-items: baseline;
  padding: 0.85rem 0.2rem;
  border-bottom: var(--gap) solid var(--band-rule);
}

.tracks li::before {
  content: "0" counter(t);
  font: 600 0.78rem/1 var(--mono);
  letter-spacing: 0.08em;
}

.tracks b {
  font-size: 1.16rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.band-note {
  max-width: 52ch;
  margin: 0;
  color: var(--band-dim);
  font-weight: 500;
  font-size: 0.96rem;
}

/* contact ----------------------------------------------------------- */

.contact-lede {
  max-width: 44ch;
  margin: 0 0 2.4rem;
  font-size: 1.06rem;
  color: var(--ink-2);
}

.links {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: var(--gap) solid var(--line);
}

.links li {
  display: flex;
  align-items: baseline;
  gap: 1.2rem;
  padding: 0.95rem 0.2rem;
  border-bottom: var(--gap) solid var(--line);
  flex-wrap: wrap;
}

.links-k {
  width: 6.5rem;
  flex: none;
  font: 600 0.72rem/1.6 var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}

.links a {
  font-family: var(--mono);
  font-size: 1rem;
  color: var(--ink);
  text-decoration: none;
  border-bottom: var(--gap) solid var(--accent);
  padding-bottom: 0.2rem;
  word-break: break-all;
}

.links a:hover {
  color: var(--accent-text);
}

/* footer ------------------------------------------------------------ */

.foot {
  border-top: var(--gap) solid var(--line);
  padding-block: 3rem 3.4rem;
}

.foot-line {
  margin: 0 0 0.9rem;
  font-size: clamp(1.2rem, 3vw, 1.7rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}

.foot-sub {
  margin: 0 0 0.7rem;
  max-width: 62ch;
  font-size: 0.89rem;
  color: var(--muted);
}

.foot-fine {
  font-size: 0.8rem;
}

/* responsive -------------------------------------------------------- */

/* Big displays. Everything here is rem-based, so scaling the root font scales
   the whole page proportionally: wider column, larger type, same design. A
   1160px column on a 27 inch screen reads as a small island. */
@media (min-width: 1500px) {
  html {
    font-size: 18px;
  }
}

@media (min-width: 1900px) {
  html {
    font-size: 20px;
  }
}

@media (max-width: 1000px) {
  .nums {
    grid-template-columns: repeat(2, 1fr);
  }
  .writes {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
  .work {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 700px) {
  body {
    font-size: 16px;
  }
  html {
    scroll-padding-top: 6.5rem;
  }
  .topbar-in {
    flex-wrap: wrap;
    height: auto;
    row-gap: 0;
    padding-top: 0.55rem;
  }
  .mark {
    margin-right: auto;
  }
  .theme {
    padding: 0.65rem 0.8rem;
  }
  .topnav {
    order: 3;
    width: 100%;
    margin-left: 0;
    gap: 0.95rem;
    justify-content: space-between;
    border-top: var(--gap) solid var(--line);
    margin-top: 0.55rem;
  }
  .topnav a {
    padding: 0.85rem 0;
  }
  .filter {
    padding: 0.75rem 0.85rem;
  }
  .link {
    padding-block: 0.5rem 0.35rem;
  }
  .links a {
    padding-block: 0.35rem;
  }
  .claims li {
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }
  .claims li::before {
    grid-column: 1;
    grid-row: auto;
    line-height: 1;
  }
  .claims li h3,
  .claims li p {
    grid-column: 1;
  }
  .path li {
    grid-template-columns: 1fr;
    gap: 0.7rem;
  }
  .post {
    grid-template-columns: minmax(0, 1fr) 1.5rem;
    gap: 0.6rem 1rem;
  }
  .post-meta {
    grid-column: 1 / -1;
    flex-direction: row;
    gap: 0.8rem;
  }
  .num {
    min-height: 7rem;
  }
  .links li {
    gap: 0.4rem 1rem;
  }
  .links-k {
    width: 100%;
  }
  .hero {
    padding-top: 2.6rem;
  }
  .btn {
    flex: 1 1 auto;
    text-align: center;
  }
}

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

@media print {
  .topbar,
  .page::before,
  .foot,
  .essay-end,
  .essay-head .link {
    display: none !important;
  }
  /* Ink on white whatever theme was on screen. */
  .page {
    --paper: #fff;
    --paper-2: #f3f1ec;
    --ink: #121110;
    --ink-2: #2b2925;
    --muted: #55514a;
    --line: #121110;
    --accent-text: #a8350a;
  }
  .essay {
    padding: 0;
  }
  .essay-head {
    padding-bottom: 1.2rem;
    margin-bottom: 1.6rem;
  }
  .essay-body {
    font-size: 11pt;
    line-height: 1.55;
  }
  .essay-body h2 {
    margin-top: 1.7em;
    break-after: avoid;
  }
  .essay-quote,
  .essay-steps li,
  .essay-bullets li {
    break-inside: avoid;
  }
  body {
    background: #fff;
  }
  .page--night,
  .page--paper {
    background: #fff;
    color: #000;
  }
}