/* ==========================================================================
   Trey Moen
   ========================================================================== */

:root {
  /* Dark ground, warm-white ink, mid-century accents. Terracotta is the
     signature; --accent-text is terracotta bright enough for small text. */
  --bg: #0b0b0d;
  --bg-2: #121215;
  --bg-3: #1b1b1f;
  --fg: #fdfdf9;
  --fg-2: rgba(253, 253, 249, 0.74);
  --fg-3: rgba(253, 253, 249, 0.5);
  --line: rgba(253, 253, 249, 0.13);
  --terracotta: #d4503c;
  --accent-text: #f0543c;
  --mustard: #e2a834;
  --sage: #8f9d73;
  --teal: #4fb3a9;
  --on-accent: #0b0b0d; /* text on terracotta fills */

  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --serif: "Newsreader", Georgia, serif;

  --fluid: cubic-bezier(0.16, 1, 0.3, 1);
  --organic: cubic-bezier(0.65, 0, 0.35, 1);
  --pad: clamp(20px, 4.5vw, 64px);

  color-scheme: dark;
}

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

html {
  background: var(--bg);
  color: var(--fg);
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 80px;
}

body {
  margin: 0;
  min-height: 100vh;
  overflow-x: clip;
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.55;
  font-variation-settings: "wdth" 100;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3 { margin: 0; font-weight: 800; }
p { margin: 0; }

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

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

.mono {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.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 {
  position: fixed;
  top: 12px; left: 12px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--fg);
  color: var(--bg);
  border-radius: 999px;
  transform: translateY(-200%);
  transition: transform 0.3s var(--fluid);
}
.skip:focus { transform: none; }

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px var(--pad);
  transition: padding 0.5s var(--fluid);
}

.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transition: opacity 0.5s var(--fluid);
  pointer-events: none;
}

.nav.is-scrolled { padding-block: 12px; }
.nav.is-scrolled::before { opacity: 1; }

.nav__mark {
  position: relative;
  display: inline-block;
  width: 2.1em; /* the resting width; the hover narrows the letters inside it */
  font-size: 22px;
  font-weight: 900;
  letter-spacing: -0.02em;
  font-variation-settings: "wdth" 125;
  transition:
    font-variation-settings 0.6s var(--fluid),
    opacity 0.4s var(--fluid),
    transform 0.5s var(--fluid),
    visibility 0s;
}
.nav__mark:hover { font-variation-settings: "wdth" 62; }


/* The mark only appears once the nav turns into the sticky bar. Hidden with
   visibility too, so it can't be tabbed to while invisible. */
.js .nav:not(.is-scrolled) .nav__mark {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition:
    font-variation-settings 0.6s var(--fluid),
    opacity 0.3s var(--fluid),
    transform 0.3s var(--fluid),
    visibility 0s linear 0.3s;
}

.nav__dot {
  position: absolute;
  top: 3px;
  right: -11px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--terracotta);
  animation: signal 2.4s var(--organic) infinite;
}

@keyframes signal {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.7); }
}

/* --------------------------------------------------------------------------
   Split text entrances
   -------------------------------------------------------------------------- */

.split__clip {
  display: inline-block;
  vertical-align: top;
  clip-path: inset(-0.4em -0.5em 0 -0.5em);
}

.split__char,
.split__word {
  display: inline-block;
  will-change: transform;
}

.js .split__char,
.js .split__word {
  transform: translateY(112%) rotate(4deg);
  transition: transform 1.25s var(--fluid);
  transition-delay: calc(var(--i, 0) * 70ms + 250ms);
}

.js .split__word { transition-delay: calc(var(--i, 0) * 80ms + 150ms); }

.js.is-ready .split__char,
.js.is-ready .split__word { transform: none; }

.vt .split__char,
.vt .split__word { transition: none; }

/* Titles that widen on hover keep their resting line breaks (set by main.js). */
.lock-line {
  display: block;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

/* The home page is one screen: the name bottom-left, portrait and links
   bottom-right. Posts live on the Blog page. */
.page-home {
  display: flex;
  flex-direction: column;
  height: 100svh;
  min-height: 0;
}

.hero {
  flex: 1;
  min-height: 0;
  display: grid;
  position: relative;
  grid-template-columns: minmax(0, 1fr) max-content;
  grid-template-areas: "name aside";
  align-content: end;
  gap: 28px clamp(24px, 4vw, 72px);
  /* Bottom padding leaves room for the Blog tab standing on the footer. */
  padding: 84px var(--pad) clamp(68px, 9vh, 88px);
}

/* Mid-century shapes floating in the space above the name (drawn by
   main.js). Only the shapes themselves catch the pointer. */
.blobs {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden; /* blobs run off the screen edges without adding scroll */
  pointer-events: none;
  -webkit-tap-highlight-color: transparent; /* no grey box flashing over a tapped shape */
}
.blobs__svg { display: block; width: 100%; height: 100%; overflow: visible; }
.blobs .shape > * {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
}
.blobs .shape:active > * { cursor: grabbing; }
.hero > :not(.blobs) { position: relative; z-index: 1; }
.page-home .hero { overflow-y: clip; }

/* The name is sized from its own column rather than the viewport, so it
   can never run into the aside. */
.hero__name {
  grid-area: name;
  align-self: end;
  container-type: inline-size;
  /* Resting width and weight; main.js animates around these. */
  --name-wdth: 100;
  --name-wght: 820;
  font-weight: var(--name-wght);
  line-height: 0.8;
  text-transform: uppercase;
  font-variation-settings: "wdth" var(--name-wdth);
}

.hero__line {
  display: block;
  white-space: nowrap;
  /* "MOEN" plus its indent is 3.4em at rest, so 27.5cqi fills ~94% of the
     column (main.js reins the widening in to fit). Capped by height too, so
     the home page always fits one screen; no fixed maximum, so it keeps
     growing on big monitors. */
  font-size: min(27.5cqi, 34svh);
  letter-spacing: -0.035em;
  margin-left: -0.04em;
}

.hero__line + .hero__line { padding-left: 0.3em; }

.hero__name .split__char { transform-origin: 0 100%; }

.hero__aside {
  grid-area: aside;
  align-self: end;
  display: grid;
  justify-items: start;
  gap: clamp(18px, 2.2vh, 32px);
  width: 100%;
  padding-bottom: 0.6vw;
}

/* Fade only: a rise from below would briefly poke past the bottom of this
   one-screen page and flash a scrollbar. */
.js .hero__aside {
  opacity: 0;
  transition: opacity 1.2s var(--fluid) 1.1s;
}
.js.is-ready .hero__aside { opacity: 1; }
.vt .hero__aside { transition: none; }

/* Blog page: a plain list of posts, newest first. */
.entries {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.entries li { border-bottom: 1px solid var(--line); }

.entry {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  grid-template-areas:
    "date title"
    "date desc";
  align-items: baseline;
  column-gap: 24px;
  row-gap: 6px;
  padding: clamp(20px, 3vw, 32px) 4px;
}

.entry__date { grid-area: date; color: var(--fg-3); }

.entry__title {
  grid-area: title;
  font-size: clamp(26px, 3.2vw, 46px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.015em;
  --wdth: 88;
  --wdth-hover: 106;
  font-variation-settings: "wdth" var(--wdth);
  transition: font-variation-settings 0.7s var(--fluid), color 0.3s;
}

.entry__desc { grid-area: desc; color: var(--fg-2); }

.entry:hover .entry__title,
.entry:focus-visible .entry__title {
  color: var(--terracotta);
  font-variation-settings: "wdth" var(--wdth-fit, var(--wdth-hover));
}

.page-home .footer {
  position: relative;
  padding-block: 14px calc(14px + env(safe-area-inset-bottom));
}

/* Blog drawer: a terracotta tab standing on the footer's top line opens a
   sheet of posts that slides up over the page (a native modal <dialog>). */
.drawer-tab {
  position: absolute;
  left: 50%;
  bottom: 100%;
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 24px 13px;
  border-radius: 14px 14px 0 0;
  background: var(--terracotta);
  color: var(--on-accent);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transform: translateX(-50%);
  transition: padding 0.4s var(--fluid);
}

.drawer-tab span { transition: transform 0.4s var(--fluid); }
.drawer-tab:hover { padding-bottom: 19px; }
.drawer-tab:hover span { transform: translateY(-3px); }

.drawer {
  position: fixed;
  inset: auto 0 0;
  width: min(100% - 2 * var(--pad), 1180px);
  max-width: none;
  max-height: min(78svh, 720px);
  margin: 0 auto;
  padding: 0;
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 22px 22px 0 0;
  background: var(--bg-2);
  color: var(--fg);
  overflow: hidden;
  transform: translateY(100%);
  transition: transform 0.5s var(--fluid);
}

.drawer[open] { display: flex; flex-direction: column; }

/* The sheet itself takes focus when it opens (see main.js), so nothing
   inside is highlighted until someone tabs to it. */
.drawer:focus { outline: none; }
.drawer.is-open { transform: none; }

.drawer::backdrop {
  background: rgba(5, 5, 6, 0);
  transition: background-color 0.4s;
}
.drawer.is-open::backdrop { background: rgba(5, 5, 6, 0.62); }

/* The top of the sheet is the drag handle: pull it down to dismiss. */
.drawer__grab {
  padding: 12px 36px 0;
  cursor: grab;
  touch-action: none;
}
.drawer__grab:active { cursor: grabbing; }

.drawer__handle {
  display: block;
  width: 44px;
  height: 4px;
  margin: 0 auto 16px;
  border-radius: 4px;
  background: rgba(253, 253, 249, 0.25);
}

.drawer__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding-bottom: 12px;
}

.drawer__title {
  display: flex;
  gap: 14px;
  margin: 0;
  font-weight: 400;
  color: var(--accent-text);
}
.drawer__title span { color: var(--fg-3); }

.drawer__close {
  padding: 6px 0;
  border: 0;
  background: none;
  color: var(--fg-2);
  cursor: pointer;
  transition: color 0.3s;
}
.drawer__close:hover { color: var(--fg); }

.drawer .entries {
  min-height: 0;
  max-width: none;
  margin: 0;
  padding: 0 36px calc(18px + env(safe-area-inset-bottom));
  overflow-y: auto;
}

.drawer .entry { padding-block: 18px; }
.drawer .entry__title { font-size: clamp(22px, 2.4vw, 32px); }

/* Portrait in a liquid blob over a flat terracotta shadow. main.js draws both
   shapes as clip paths; the border-radius here is the static fallback. */
.portrait {
  position: relative;
  margin: 0;
  width: clamp(160px, 30svh, 480px);
  aspect-ratio: 1;
}

.portrait__shade,
.portrait__blob {
  position: absolute;
  inset: 0;
  border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%;
}

/* Live layers overhang the box so a full bulge never runs out of photo. */
.portrait.is-live .portrait__shade,
.portrait.is-live .portrait__blob { inset: -8%; }

.portrait__shade {
  background: var(--terracotta);
  transform: translate(12px, 10px);
}

.portrait__blob { overflow: hidden; }

.portrait.is-live .portrait__shade,
.portrait.is-live .portrait__blob { border-radius: 0; }

.portrait__blob img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 55% 22%;
  transform: scale(1.3);
  transform-origin: 55% 30%;
  filter: saturate(0.92) contrast(1.04);
  transition: transform 1.2s var(--fluid), filter 0.8s;
}

/* On the larger live layer (116% of the box), nudge the photo down a touch
   so the top of the hair clears the blob's edge. */
.portrait.is-live .portrait__blob img { transform: translateY(6%) scale(1.02); }
/* Zoom on real hover only: a tap would leave it zoomed in. */
@media (hover: hover) {
  .portrait:hover .portrait__blob img { transform: scale(1.42); filter: saturate(1.1) contrast(1.06); }
  .portrait.is-live:hover .portrait__blob img { transform: translateY(6%) scale(1.1); }
}

.hero__tagline {
  font-size: clamp(26px, 2.3vw, 60px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.01em;
}

.links {
  --pill-size: clamp(48px, 3.2vw, 72px);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 15px 0 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-2);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition:
    transform 0.6s var(--fluid),
    background-color 0.35s,
    color 0.35s,
    border-color 0.35s;
}

.pill svg { width: 16px; height: 16px; flex: none; }

/* Hover styles only where hover is real: iOS keeps :hover on after a tap. */
@media (hover: hover) {
  .pill:hover {
    background: var(--fg);
    border-color: var(--fg);
    color: var(--bg);
  }
}

/* Explicit width, not aspect-ratio: Safari sizes the flex row from the icon's
   intrinsic width otherwise, and wraps every button onto its own line. */
.pill.pill--icon {
  width: var(--pill-size, 48px);
  height: var(--pill-size, 48px);
  flex: none;
  padding: 0;
  justify-content: center;
}

.pill.pill--icon svg { width: 44%; height: 44%; }

/* Icon buttons: the label (or, for Email, the obfuscated address) appears in
   a bubble below. The button itself never changes size, so hovering near its
   edge can't make it jump out from under the pointer. The bubble is part of
   the link, so moving onto it keeps it open. */
.pill--icon { position: relative; }

.pill__tip {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  padding: 7px 12px;
  border-radius: 8px;
  background: var(--fg);
  color: var(--bg);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  transform: translateY(-6px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s, transform 0.4s var(--fluid), visibility 0s linear 0.25s;
}

/* Little pointer on top of the bubble, under the button's centre. */
.pill__tip::before {
  content: "";
  position: absolute;
  right: calc(var(--pill-size, 48px) / 2 - 5px);
  top: 0;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--fg);
  transform: translateY(-50%) rotate(45deg);
}

/* Invisible bridge across the gap, so the pointer can travel down onto it. */
.pill__tip::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 12px;
}

@media (hover: hover) {
  .pill--icon:hover .pill__tip {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
    transition: opacity 0.25s, transform 0.4s var(--fluid), visibility 0s;
  }
}

.pill--icon:focus-visible .pill__tip {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition: opacity 0.25s, transform 0.4s var(--fluid), visibility 0s;
}

/* Esc dismisses it until the pointer leaves or focus moves (main.js). */
.pill--icon.is-tip-dismissed .pill__tip {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Liquid fill: a wave-topped tide that rises under the pointer. */
.liquid::before {
  content: "";
  position: absolute;
  inset: -22px 0 0;
  z-index: -1;
  background: var(--terracotta);
  transform: translateY(101%);
  transition: transform 0.85s var(--fluid);
  -webkit-mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 22' preserveAspectRatio='none'%3E%3Cpath d='M0 11 C40 0 80 0 120 11 S200 22 240 11 V22 H0Z'/%3E%3C/svg%3E") 0 0 / 240px 22px repeat-x,
    linear-gradient(#000 0 0) 0 21px / 100% calc(100% - 21px) no-repeat;
  mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 22' preserveAspectRatio='none'%3E%3Cpath d='M0 11 C40 0 80 0 120 11 S200 22 240 11 V22 H0Z'/%3E%3C/svg%3E") 0 0 / 240px 22px repeat-x,
    linear-gradient(#000 0 0) 0 21px / 100% calc(100% - 21px) no-repeat;
}

.liquid:hover::before,
.liquid:focus-visible::before {
  transform: translateY(0);
  animation: tide 1.8s linear infinite;
}

@keyframes tide {
  to {
    -webkit-mask-position: 240px 0, 0 21px;
    mask-position: 240px 0, 0 21px;
  }
}

/* Footer ------------------------------------------------------------------ */

.footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 24px;
  padding: 26px var(--pad) calc(26px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  color: var(--fg-3);
}


/* --------------------------------------------------------------------------
   Articles (blog pages)
   -------------------------------------------------------------------------- */

.progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 45;
  height: 2px;
  background: linear-gradient(90deg, var(--terracotta), var(--mustard));
  transform: scaleX(0);
  transform-origin: 0 50%;
}

.article {
  padding: clamp(120px, 14vw, 180px) var(--pad) clamp(60px, 8vw, 110px);
}

.article__head {
  max-width: 1280px;
  margin: 0 auto clamp(48px, 7vw, 96px);
}

.back {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: clamp(28px, 4vw, 48px);
  color: var(--fg-2);
  transition: color 0.3s, gap 0.5s var(--fluid);
}
.back svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.back:hover { color: var(--accent-text); gap: 16px; }

.article__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-bottom: 22px;
  color: var(--fg-3);
}
.article__meta span:first-child { color: var(--accent-text); }

.article__title {
  font-size: clamp(54px, 10vw, 156px);
  font-weight: 850;
  line-height: 0.86;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  font-variation-settings: "wdth" 76;
  max-width: 12ch;
}

.article__desc {
  margin-top: 28px;
  max-width: 34ch;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(24px, 2.6vw, 36px);
  line-height: 1.2;
  color: var(--fg-2);
}

.article__body {
  display: grid;
  grid-template-columns: minmax(160px, 1fr) minmax(0, 700px) minmax(0, 1fr);
  gap: 0 clamp(24px, 4vw, 64px);
  max-width: 1280px;
  margin: 0 auto;
}

.article__aside {
  grid-column: 1;
  align-self: start;
  position: sticky;
  top: 110px;
  display: grid;
  gap: 18px;
  padding-top: 8px;
  color: var(--fg-3);
}

.article__aside dl { margin: 0; display: grid; gap: 14px; }
.article__aside dt { color: var(--fg-3); margin-bottom: 2px; }
.article__aside dd { margin: 0; color: var(--fg); }

.prose { grid-column: 2; min-width: 0; }

.article__foot {
  grid-column: 2;
  margin-top: 64px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  color: var(--fg-3);
}

/* Prose ------------------------------------------------------------------- */

.prose {
  font-size: clamp(17px, 1.3vw, 19px);
  line-height: 1.72;
  color: var(--fg-2);
}

.prose > * + * { margin-top: 1.25em; }

.prose p,
.prose li { text-wrap: pretty; }

.prose strong { color: var(--fg); font-weight: 650; }

.prose a:not(.pill):not(.chip) {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: rgba(240, 84, 60, 0.7);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: color 0.3s, text-decoration-color 0.3s, text-underline-offset 0.4s var(--fluid);
}
.prose a:not(.pill):not(.chip):hover {
  color: var(--accent-text);
  text-decoration-color: var(--accent-text);
  text-underline-offset: 0.34em;
}

.prose h2 {
  margin-top: 2.6em;
  padding-top: 0.9em;
  border-top: 1px solid var(--line);
  font-size: clamp(32px, 3.6vw, 52px);
  font-weight: 850;
  line-height: 0.95;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  font-variation-settings: "wdth" 74;
  color: var(--fg);
}

.prose h2 .mono { display: block; margin-bottom: 14px; color: var(--accent-text); }

.prose h3 {
  margin-top: 2.2em;
  font-size: clamp(24px, 2.2vw, 30px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
  font-variation-settings: "wdth" 88;
  color: var(--fg);
}

.prose h4 {
  margin: 2em 0 0;
  font-size: 20px;
  font-weight: 650;
  color: var(--fg);
}

.prose h2 + *, .prose h3 + *, .prose h4 + * { margin-top: 0.7em; }

.prose ul {
  padding: 0;
  list-style: none;
}

.prose ul li {
  position: relative;
  padding-left: 30px;
}
.prose ul li + li { margin-top: 0.7em; }
.prose ul li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.86em;
  width: 14px;
  height: 2px;
  border-radius: 2px;
  background: var(--terracotta);
}

.prose figure { margin: 2.4em 0; }
.prose figure img {
  width: 100%;
  height: auto;
  border-radius: 12px;
  cursor: zoom-in;
  background: var(--bg-3);
}

.prose figcaption {
  margin-top: 12px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
  letter-spacing: 0.02em;
  color: var(--fg-3);
}

/* Wide figures break out of the text column, but only once there's margin
   on both sides to break into. */
@media (min-width: 1180px) {
  .prose .wide { margin-inline: clamp(-200px, -12vw, 0px); }
}

.gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin: 2.4em 0;
}
.gallery figure { margin: 0; }
.gallery img { aspect-ratio: 4 / 3; object-fit: cover; }
.gallery--tall img { aspect-ratio: 3 / 4; }

.soon {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border: 1px dashed rgba(226, 168, 52, 0.45);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mustard);
}
.soon::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: signal 1.6s var(--organic) infinite;
}

.prose .figure--portrait img {
  width: auto;
  max-width: 100%;
  max-height: min(84vh, 900px);
  margin-inline: auto;
}
.prose .figure--portrait figcaption { text-align: center; }

.toc { display: grid; gap: 8px; }
.toc a {
  position: relative;
  width: fit-content;
  color: var(--fg-2);
  transition: color 0.3s, transform 0.5s var(--fluid);
}
.toc a::before {
  content: "";
  position: absolute;
  left: -16px;
  top: 50%;
  width: 8px;
  height: 1px;
  background: var(--accent-text);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s var(--fluid);
}
.toc a:hover { color: var(--fg); }
.toc a:hover::before { transform: scaleX(1); }

/* Project entries */
.project {
  scroll-margin-top: 110px;
  padding: 1.6em 0 0;
}
.project + .project { margin-top: 1.6em; border-top: 1px dashed var(--line); }
.prose .project > * + * { margin-top: 0.9em; }
.prose .project h3 { margin-top: 0; }
.project__meta { color: var(--mustard); }

/* Next post */
.next {
  max-width: 1280px;
  margin: clamp(90px, 12vw, 170px) auto 0;
}

.next__link {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 18px 24px;
  padding: clamp(28px, 4vw, 48px) 16px;
  border-block: 1px solid var(--line);
  isolation: isolate;
  overflow: hidden;
  transition: color 0.5s var(--fluid);
}

.next__label { grid-column: 1 / -1; color: var(--accent-text); transition: color 0.4s; }

.next__title {
  font-size: clamp(36px, 8vw, 120px);
  font-weight: 850;
  line-height: 0.88;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  --wdth: 70;
  --wdth-hover: 90;
  font-variation-settings: "wdth" var(--wdth);
  transition: font-variation-settings 0.9s var(--fluid);
}

.next__arrow {
  display: grid;
  place-items: center;
  width: clamp(56px, 7vw, 96px);
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 50%;
  transition: transform 0.8s var(--fluid), background-color 0.4s, color 0.4s, border-color 0.4s;
}
.next__arrow svg {
  width: 40%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.next__link:hover,
.next__link:focus-visible { color: var(--on-accent); }
.next__link:hover .next__label,
.next__link:focus-visible .next__label { color: var(--on-accent); }
.next__link:hover .next__title,
.next__link:focus-visible .next__title { font-variation-settings: "wdth" var(--wdth-fit, var(--wdth-hover)); }
.next__link:hover .next__arrow,
.next__link:focus-visible .next__arrow {
  transform: rotate(-45deg);
  background: var(--bg);
  border-color: var(--bg);
  color: var(--fg);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--fg);
  transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}
.chip:hover { background: var(--fg); color: var(--bg); border-color: var(--fg); }

.project__title a { text-decoration: none !important; }
.project__title a::after {
  content: " ↗";
  font-size: 0.7em;
  color: var(--accent-text);
}

/* Reading list */
.reads {
  margin: 2em 0 0;
  padding: 0;
  list-style: none;
  counter-reset: read;
  border-top: 1px solid var(--line);
}

.reads li { counter-increment: read; }

.reads a {
  position: relative;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: 4px 16px;
  padding: 18px 10px;
  border-bottom: 1px solid var(--line);
  isolation: isolate;
  overflow: hidden;
  text-decoration: none !important;
  transition: color 0.4s;
}

.reads a::after {
  content: counter(read, decimal-leading-zero);
  grid-column: 1;
  grid-row: 1;
  padding-top: 5px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--fg-3);
}

.reads__title {
  grid-column: 2;
  color: var(--fg);
  font-weight: 600;
  line-height: 1.3;
  --wdth: 100;
  --wdth-hover: 110;
  font-variation-settings: "wdth" var(--wdth);
  transition: font-variation-settings 0.7s var(--fluid), color 0.4s;
}

.reads__author {
  grid-column: 2;
  font-size: 15px;
  color: var(--fg-3);
  transition: color 0.4s;
}

.reads__year {
  grid-column: 3;
  grid-row: 1;
  padding-top: 4px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--mustard);
  transition: color 0.4s;
}

.reads a:hover .reads__title,
.reads a:focus-visible .reads__title { color: var(--on-accent); font-variation-settings: "wdth" var(--wdth-fit, var(--wdth-hover)); }
.reads a:hover :is(.reads__author, .reads__year),
.reads a:focus-visible :is(.reads__author, .reads__year),
.reads a:hover::after,
.reads a:focus-visible::after { color: var(--on-accent); }

/* Lightbox */
.lightbox {
  max-width: none;
  max-height: none;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: clamp(16px, 4vw, 48px);
  border: 0;
  background: transparent;
  color: var(--fg);
  cursor: zoom-out;
}

.lightbox[open] { display: grid; place-items: center; }

.lightbox::backdrop {
  background: rgba(8, 8, 10, 0.88);
  animation: fade 0.4s var(--fluid);
}

.lightbox figure { margin: 0; display: grid; gap: 14px; justify-items: center; }

.lightbox img {
  max-width: min(100%, 1400px);
  max-height: calc(100vh - 140px);
  border-radius: 12px;
  animation: zoom 0.7s var(--fluid);
}

.lightbox figcaption { max-width: 70ch; text-align: center; color: var(--fg-2); }

@keyframes fade { from { opacity: 0; } }
@keyframes zoom { from { opacity: 0; transform: scale(0.92) translateY(20px); } }

/* --------------------------------------------------------------------------
   Page transitions (cross-document view transitions)
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

::view-transition-old(root) { animation: 380ms var(--organic) both vt-out; }
::view-transition-new(root) { animation: 760ms var(--fluid) both vt-in; }

@keyframes vt-out { to { opacity: 0; transform: translateY(-30px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(50px); } }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (min-width: 961px) {
  /* Wide screens: the photo, tagline, and icons line up on the right edge. */
  .hero__aside { justify-items: end; text-align: right; }
  .links { justify-content: flex-end; }
}

@media (max-width: 960px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "name" "aside";
    row-gap: clamp(20px, 3.5vh, 36px);
    padding-top: 72px;
  }
  /* The name goes condensed and heaviest below desktop width, which lets it
     stand much taller while still spanning the width. "MOEN" plus its
     indent is 2.7em at this width, so 35cqi fills about 94% of the column. */
  .hero__name { --name-wdth: 72; --name-wght: 900; }
  .hero__line { font-size: min(35cqi, 32svh); }

  /* Photo with the tagline and icons beside it, all scaling with the screen. */
  .hero__aside {
    align-self: start;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: clamp(14px, 3vw, 28px);
    row-gap: 12px;
  }
  .portrait { grid-row: 1 / span 2; width: clamp(110px, 30vw, 260px); }
  .hero__tagline { grid-column: 2; align-self: end; font-size: clamp(22px, 6.2vw, 56px); }
  .links { grid-column: 2; align-self: start; --pill-size: clamp(42px, 6.4vw, 56px); }

  .article__body { grid-template-columns: minmax(0, 1fr); }
  .article__aside {
    grid-column: 1;
    position: static;
    margin-bottom: 40px;
  }
  .article__aside dl { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
  .prose, .article__foot { grid-column: 1; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }

  /* Phones: a touch more photo relative to the width, tighter icons. */
  .portrait { width: clamp(110px, 34vw, 220px); }
  .hero__tagline { font-size: clamp(22px, 5.6vw, 32px); }
  .links { gap: 6px; --pill-size: 42px; }
  .entry {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "date" "title" "desc";
  }
  .drawer__grab { padding-inline: 20px; }
  .drawer .entries { padding-inline: 20px; }

  .gallery { grid-template-columns: minmax(0, 1fr); }
  .reads a { grid-template-columns: 34px minmax(0, 1fr); }
  .reads__year { grid-column: 2; grid-row: auto; padding-top: 0; }
}

@media (max-width: 380px) {
  .portrait { grid-row: auto; }
  .hero__tagline { align-self: center; }
  .links { grid-column: 1 / -1; }
}

/* Very short screens: let the home page scroll rather than squeeze. */
@media (max-height: 600px) {
  .page-home { height: auto; min-height: 100svh; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
  @view-transition { navigation: none; }
}
