/* ==========================================================================
   site.css: base styles and shared components
   --------------------------------------------------------------------------
   Reads only from tokens.css. Sections:
     1. Font fallbacks      6. Page title
     2. Base                7. Buttons, links, tags
     3. Layout              8. Content components (cards, photos, posts)
     4. Header and nav      9. Subscribe form
     5. Footer             10. Motion
   ========================================================================== */

/* 1. Font fallbacks --------------------------------------------------------
   Local fonts resized to the web fonts' metrics, so text keeps its size and
   line breaks when the web font arrives. Values measured with fontTools
   from the Google Fonts files. */
@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia");
  size-adjust: 96.07%;
  ascent-override: 76.51%;
  descent-override: 27.58%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial"), local("ArialMT");
  size-adjust: 107.48%;
  ascent-override: 90.14%;
  descent-override: 22.44%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "JetBrains Mono Fallback";
  src: local("Menlo"), local("Courier New");
  size-adjust: 99.66%;
  ascent-override: 102.35%;
  descent-override: 30.1%;
  line-gap-override: 0%;
}

/* 2. Base ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + var(--space-4));
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: var(--leading);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

main { flex: 1; display: block; }
main:focus { outline: none; }

h1, h2, h3, h4 {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-serif);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
h1 { font-size: var(--step-6); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); letter-spacing: 0; }
h4 { font-size: var(--step-1); letter-spacing: 0; line-height: var(--leading-snug); }

p, ul, ol, dl, figure, blockquote, pre { margin: 0; }
p { text-wrap: pretty; }

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

a {
  color: var(--accent);
  text-decoration-line: underline;
  text-decoration-thickness: var(--hairline);
  text-underline-offset: 0.2em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  transition: color var(--dur-fast) var(--ease), text-decoration-color var(--dur-fast) var(--ease);
}
a:hover { color: var(--accent-strong); text-decoration-color: var(--gold); }

strong, b { color: var(--ink); font-weight: var(--weight-semibold); }
em, i { font-style: italic; }

code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.875em;
}
:not(pre) > code {
  padding: 0.1em 0.35em;
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}
pre {
  overflow-x: auto;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  line-height: var(--leading-snug);
}

hr {
  height: var(--hairline);
  margin: var(--space-7) 0;
  border: 0;
  background: var(--line);
}

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

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

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: var(--paper);
  font-size: var(--step-n1);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; color: var(--paper); }

/* Small technical labels: dates, metrics, tags. The "nerdy" signal. */
.mono {
  font-family: var(--font-mono);
  font-size: var(--step-n1);
  font-feature-settings: "zero" 1;
}
.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step-n2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* 3. Layout ---------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: calc(var(--wrap) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--wide { max-width: calc(var(--wrap-wide) + 2 * var(--gutter)); }

.section { padding-block: var(--space-section); }
.section + .section { padding-top: 0; }

.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  margin-bottom: var(--space-6);
}
.section__head h2 { font-size: var(--step-3); }

/* Reading column for prose: ~68 characters. */
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 1.1em; }
.prose h2 { margin-top: 2em; font-size: var(--step-3); }
.prose h3 { margin-top: 1.75em; }
.prose h2 + *, .prose h3 + * { margin-top: 0.6em; }
.prose ul, .prose ol { padding-left: 1.25em; }
.prose li + li { margin-top: 0.35em; }
.prose li::marker { color: var(--ink-3); }
.prose blockquote {
  padding-left: var(--space-5);
  border-left: 2px solid var(--gold);
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-style: italic;
  color: var(--ink);
}

/* Verse: poems get the serif, a longer line, and a narrower column. */
.verse {
  max-width: var(--measure-narrow);
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: var(--leading-verse);
  color: var(--ink);
}
.verse p + p { margin-top: 1.4em; }

/* Kuba divider: a thin chain of lozenges after Kasai raffia cloth.
   Decorative, so it uses the gold at low emphasis. */
.kuba {
  height: 10px;
  margin: var(--space-7) 0;
  border: 0;
  background-color: var(--gold);
  opacity: 0.7;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='10' viewBox='0 0 40 10'%3E%3Cpath d='M0 5 10 .5 20 5 10 9.5Z M20 5 30 .5 40 5 30 9.5Z' fill='none' stroke='%23000' stroke-width='1'/%3E%3Crect x='8.5' y='3.5' width='3' height='3' transform='rotate(45 10 5)'/%3E%3C/svg%3E") repeat-x left center / 40px 10px;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='10' viewBox='0 0 40 10'%3E%3Cpath d='M0 5 10 .5 20 5 10 9.5Z M20 5 30 .5 40 5 30 9.5Z' fill='none' stroke='%23000' stroke-width='1'/%3E%3Crect x='8.5' y='3.5' width='3' height='3' transform='rotate(45 10 5)'/%3E%3C/svg%3E") repeat-x left center / 40px 10px;
}
.kuba--short { width: 120px; }

/* 4. Header and nav -------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
          backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: var(--hairline) solid var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-right: auto;
  color: var(--ink);
  text-decoration: none;
}
.brand:hover { color: var(--ink); }
.brand__mark { width: 38px; height: 25px; flex: none; }
.brand__name {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* The mark: lifted wings, green edges and veins, gold cells. */
.mark__edge { fill: var(--wing-edge); }
.mark__cell { fill: var(--gold); }
.mark__vein { stroke: var(--wing-edge); }

/* Navigation: four sections (Work, Writing, Math, Life) from _data/nav.yml.
   Wide screens: each section is a small menu. Narrow screens: one sheet
   with every section open, no nested toggles. */
.site-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-1) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-nav__link,
.footer-nav a {
  position: relative;
  display: inline-block;
  padding-block: var(--space-2);
  color: var(--ink-2);
  font-size: var(--step-n1);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
button.site-nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding-inline: 0;
  border: 0;
  background: none;
  font-family: inherit;
  line-height: inherit;
  cursor: pointer;
}
/* Growing gold underline: the one hover signature for navigation. */
.site-nav__link::after,
.footer-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  height: 1.5px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.site-nav__link:hover,
.footer-nav a:hover { color: var(--ink); }
.site-nav__link:hover::after,
.footer-nav a:hover::after { transform: scaleX(1); }
.site-nav__link[aria-current="page"],
.is-current > .nav-group__toggle { color: var(--ink); }
.site-nav__link[aria-current="page"]::after,
.is-current > .nav-group__toggle::after { transform: scaleX(1); background: var(--accent); }

.nav-group { position: relative; }
.nav-group__label { display: none; }
.nav-group__caret { transition: transform var(--dur) var(--ease); }
.nav-group.is-open .nav-group__caret { transform: rotate(180deg); }

.nav-group__panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  left: calc(var(--space-3) * -1);
  z-index: 60;
  display: none;
  min-width: 17rem;
  margin: 0;
  padding: var(--space-2);
  list-style: none;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  box-shadow: var(--shadow-float);
}
.nav-group.is-open > .nav-group__panel { display: block; animation: nav-in var(--dur) var(--ease); }
/* Without JavaScript, hover and keyboard focus open the menus. */
html:not(.js) .nav-group:hover > .nav-group__panel,
html:not(.js) .nav-group:focus-within > .nav-group__panel { display: block; }
@keyframes nav-in {
  from { opacity: 0; transform: translateY(calc(var(--rise) * -0.5)); }
  to { opacity: 1; transform: none; }
}

.nav-item {
  display: grid;
  gap: 2px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease);
}
.nav-item:hover { background: var(--surface); }
.nav-item__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--ink);
  font-size: var(--step-n1);
  font-weight: var(--weight-medium);
}
.nav-item__ext { width: 0.9em; height: 0.9em; color: var(--ink-3); }
.nav-item__desc { color: var(--ink-3); font-size: var(--step-n1); line-height: var(--leading-snug); }
.nav-item[aria-current="page"] .nav-item__title { color: var(--accent); }

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.site-header__hi { margin-right: var(--space-3); }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-round);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.icon-btn:hover { color: var(--ink); background: var(--surface); }
.icon-btn svg { width: 18px; height: 18px; }

/* The toggle needs JavaScript; without it the OS theme applies. */
html:not(.js) .theme-toggle { display: none; }

/* Show the icon for the theme you would switch to. */
.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

.menu-toggle {
  display: none;
  padding: var(--space-2) var(--space-3);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: var(--step-n1);
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.site-nav__extra { display: none; }

/* Narrow screens: the nav becomes one sheet behind a Menu button, with
   every section listed under a small label. Without JavaScript the sheet
   is simply always shown under the header. */
@media (max-width: 59.99rem) {
  .site-header__inner { flex-wrap: wrap; row-gap: 0; }
  .site-header__hi,
  .js .site-header__actions .btn { display: none; }
  .js .menu-toggle { display: inline-flex; }

  .site-nav {
    order: 3;
    width: 100%;
    padding: var(--space-2) 0 var(--space-5);
  }
  .js .site-nav {
    display: none;
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .js .site-header.is-open .site-nav { display: block; }

  .site-nav__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));
    align-items: start;
    gap: var(--space-5) var(--space-4);
  }
  button.nav-group__toggle { display: none; }
  .nav-group__label {
    display: block;
    margin-bottom: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--step-n2);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-3);
  }
  .nav-group__panel,
  .nav-group.is-open > .nav-group__panel {
    position: static;
    display: block;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    animation: none;
  }
  .nav-item { padding: var(--space-1) 0; }
  .nav-item:hover { background: none; }
  .nav-item__title,
  .nav-group--single .site-nav__link {
    padding: 0;
    font-family: var(--font-serif);
    font-size: var(--step-1);
    font-weight: var(--weight-regular);
    color: var(--ink);
  }
  .nav-item__desc { display: none; }
  .nav-group--single .site-nav__link { padding-block: var(--space-1); }
  .nav-group--single .site-nav__link::after { display: none; }
  .nav-group--single .site-nav__link[aria-current="page"] { color: var(--accent); }

  .site-nav__extra {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-6);
  }
}

/* 5. Footer ---------------------------------------------------------------- */
.site-footer {
  position: relative;
  margin-top: var(--space-section);
  padding-block: var(--space-8) var(--space-6);
  border-top: var(--hairline) solid var(--line);
  font-size: var(--step-n1);
  overflow: hidden;
}
/* A Kuba lattice, barely there. The one texture in the footer. */
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--ink);
  opacity: 0.03;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.25'%3E%3Cpath d='M0 24 24 0 48 24 24 48Z'/%3E%3Cpath d='M12 24 24 12 36 24 24 36Z'/%3E%3C/g%3E%3Crect x='21' y='21' width='6' height='6' transform='rotate(45 24 24)'/%3E%3C/svg%3E") repeat 0 0 / 48px 48px;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.25'%3E%3Cpath d='M0 24 24 0 48 24 24 48Z'/%3E%3Cpath d='M12 24 24 12 36 24 24 36Z'/%3E%3C/g%3E%3Crect x='21' y='21' width='6' height='6' transform='rotate(45 24 24)'/%3E%3C/svg%3E") repeat 0 0 / 48px 48px;
  pointer-events: none;
}
.site-footer { isolation: isolate; }

.site-footer__grid {
  display: grid;
  gap: var(--space-7) var(--space-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.site-footer__grid > :first-child { grid-column: 1 / -1; }
@media (min-width: 48rem) {
  .site-footer__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 64rem) {
  .site-footer__grid { grid-template-columns: minmax(0, 1.6fr) repeat(4, minmax(0, 1fr)); }
  .site-footer__grid > :first-child { grid-column: auto; }
}

.site-footer__hello {
  margin-bottom: var(--space-2);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: var(--step-2);
  line-height: var(--leading-snug);
}
.site-footer__email {
  font-family: var(--font-mono);
  font-size: var(--step-n1);
  word-break: break-all;
}
.site-footer__cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.footer-nav h2 {
  margin-bottom: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--step-n2);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-3);
}
.footer-nav ul { margin: 0; padding: 0; list-style: none; }
.footer-nav a { padding-block: var(--space-1); font-weight: var(--weight-regular); }
.footer-nav a::after { bottom: 2px; }
.footer-nav .note { color: var(--ink-3); }
.footer-nav--inline { margin-top: var(--space-7); }
.footer-nav--inline ul { display: flex; flex-wrap: wrap; gap: 0 var(--space-5); }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: var(--hairline) solid var(--line);
  color: var(--ink-3);
}
.site-footer__closing {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  color: var(--ink-2);
}

/* 6. Page title ------------------------------------------------------------ */
.page-title {
  padding-block: var(--space-7) var(--space-6);
}
.page-title .eyebrow { margin-bottom: var(--space-4); color: var(--accent); }
.page-title h1 { max-width: 18ch; }
.page-title__sub {
  max-width: var(--measure);
  margin-top: var(--space-4);
  font-size: var(--step-0);
  line-height: var(--leading-snug);
  color: var(--ink-2);
}
.page-title__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  margin-top: var(--space-5);
}

/* 7. Buttons, links, tags -------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-5);
  border: var(--hairline) solid transparent;
  border-radius: var(--radius);
  font: inherit;
  font-size: var(--step-n1);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover { background: var(--accent-strong); color: var(--on-accent); }
.btn--ghost { border-color: var(--line-strong); color: var(--ink); background: transparent; }
.btn--ghost:hover { border-color: var(--ink); color: var(--ink); }
.btn--sm { min-height: 36px; padding: var(--space-1) var(--space-4); }

/* A text link with an arrow that nudges on hover. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--accent);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.link-arrow svg {
  width: 1em;
  height: 1em;
  transition: transform var(--dur) var(--ease);
}
.link-arrow:hover svg { transform: translateX(3px); }
.link-arrow[href^="http"]:hover svg { transform: translate(2px, -2px); }

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.tag {
  display: inline-block;
  padding: 0.15em 0.55em;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--step-n2);
  line-height: 1.6;
  color: var(--ink-2);
  white-space: nowrap;
}

/* Filter row: plain words with the same underline as the nav. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0 0 var(--space-6);
  padding: 0;
  list-style: none;
}
.filter {
  position: relative;
  padding: var(--space-1) 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  font: inherit;
  font-size: var(--step-n1);
  cursor: pointer;
}
.filter::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.filter:hover { color: var(--ink); }
.filter:hover::after { transform: scaleX(1); }
.filter[aria-pressed="true"] { color: var(--ink); }
.filter[aria-pressed="true"]::after { transform: scaleX(1); background: var(--accent); }

/* Big mono numerals for key metrics. */
.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  gap: var(--space-6) var(--space-5);
  margin: var(--space-6) 0 0;
}
.metrics dd { margin: 0; }
.metric { display: flex; flex-direction: column-reverse; justify-content: flex-end; gap: var(--space-1); }
.metric__value {
  font-family: var(--font-mono);
  font-size: var(--step-2);
  font-weight: var(--weight-regular);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-feature-settings: "zero" 1, "tnum" 1;
}
.metric__label { font-size: var(--step-n1); line-height: var(--leading-snug); color: var(--ink-3); }

/* 8. Content components ---------------------------------------------------- */

/* Media frame: one aspect ratio per grid, one radius everywhere, and a quiet
   neutral surface so screenshots read as the subject. */
.frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
  aspect-ratio: var(--ratio, 16 / 10);
}
.frame > img,
.frame > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Wide screenshots: anchor to the top left, where UIs keep their title
   and navigation. */
.frame--screen > img { object-position: left top; }
/* A hairline inside the edge, so a dark screenshot keeps its shape on a
   dark page (and a light one on paper). */
.frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 var(--hairline) var(--line);
  pointer-events: none;
}

/* Phone. A screenshot shown whole inside a phone drawn in CSS: a metal edge,
   a black bezel, a rounded screen and the side buttons. Sizes are in cqi
   (hundredths of the phone's width), so it reads the same at any size. The
   phone stays dark in both themes, like the real thing. */
.device {
  display: block;
  container-type: inline-size;
}
.device__body {
  position: relative;
  display: block;
  padding: 3.2cqi;
  border: 1.1cqi solid transparent;
  border-radius: 15cqi;
  background:
    linear-gradient(#050506, #050506) padding-box,
    linear-gradient(150deg, #8a8d92, #3a3c40 22%, #1d1e21 55%, #4b4e53 85%, #8a8d92) border-box;
  box-shadow: var(--shadow-float);
}
.device__body::before,
.device__body::after {
  content: "";
  position: absolute;
  width: 1.1cqi;
  background: linear-gradient(90deg, #2a2c30, #6e7176);
}
/* Action button and volume rocker on the left, power on the right. */
.device__body::before {
  left: -2.2cqi;
  top: 17%;
  height: 5%;
  border-radius: 1cqi 0 0 1cqi;
  box-shadow: 0 13cqi 0 0 #4b4e53, 0 28cqi 0 0 #4b4e53;
}
.device__body::after {
  right: -2.2cqi;
  top: 27%;
  height: 11%;
  border-radius: 0 1cqi 1cqi 0;
  background: linear-gradient(90deg, #6e7176, #2a2c30);
}
.device__screen {
  display: block;
  overflow: hidden;
  border-radius: 11.5cqi;
  background: #000;
}
.device__screen img { width: 100%; height: auto; }

/* Three phones standing on the page; the middle one in front. In a card
   they sit on the card's frame like any other cover. */
.stage {
  display: flex;
  justify-content: center;
  align-items: center;
  padding-block: var(--space-4);
}
.stage--card { overflow: hidden; }
.stage .device { flex: none; width: min(25%, 15rem); }
.stage .device:nth-child(2) { position: relative; z-index: 1; }
.stage .device:not(:nth-child(2)) { transform: scale(0.9); }
.stage .device:first-child { margin-right: -1%; }
.stage .device:last-child { margin-left: -1%; }
/* In a card the frame keeps its ratio, so the phones are sized to fit it. */
.stage--card { padding: 0; }
.stage--card .device { width: 21%; }
@media (max-width: 47.99rem) {
  .stage:not(.stage--card) .device { width: 40%; }
  .stage:not(.stage--card) .device:first-child { margin-right: -10%; }
  .stage:not(.stage--card) .device:last-child { margin-left: -10%; }
}

/* Laptop. A wide screenshot on a laptop drawn in CSS: black bezel with a
   camera, a 16:10 screen, an aluminium base with the opening notch. Sizes
   in cqi again. Silver on paper, space grey in the dark theme. */
.laptop {
  --deck-hi: #e6e7e9;
  --deck-mid: #c3c5c9;
  --deck-lo: #8e9196;
  container-type: inline-size;
  width: min(100%, 68rem);
  margin-inline: auto;
}
.laptop__lid {
  position: relative;
  width: 86cqi;
  margin-inline: auto;
  padding: 1.7cqi 1.4cqi 1.9cqi;
  border-radius: 2.4cqi 2.4cqi 0.4cqi 0.4cqi;
  background: #08080a;
  box-shadow: 0 0 0 0.22cqi #3b3d41, var(--shadow-float);
}
.laptop__lid::before {
  content: "";
  position: absolute;
  top: 0.65cqi;
  left: 50%;
  width: 0.5cqi;
  height: 0.5cqi;
  border-radius: 50%;
  background: #1f2226;
  transform: translateX(-50%);
}
.laptop__screen {
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  border-radius: 0.5cqi;
  background: #000;
}
.laptop__screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}
.laptop__base {
  position: relative;
  height: 1.9cqi;
  border-radius: 0.3cqi 0.3cqi 5cqi 5cqi / 0.3cqi 0.3cqi 1.6cqi 1.6cqi;
  background: linear-gradient(var(--deck-hi), var(--deck-mid) 45%, var(--deck-lo));
  box-shadow: 0 1.6cqi 2.4cqi -1.4cqi var(--page-shade);
}
.laptop__base::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 13cqi;
  height: 0.75cqi;
  border-radius: 0 0 1cqi 1cqi;
  background: linear-gradient(var(--deck-lo), var(--deck-mid));
  transform: translateX(-50%);
}
:root[data-theme="dark"] .laptop { --deck-hi: #6c6f74; --deck-mid: #44474c; --deck-lo: #26282b; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .laptop { --deck-hi: #6c6f74; --deck-mid: #44474c; --deck-lo: #26282b; }
}

/* Typographic cover for projects without a screenshot. */
.frame__type {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-5);
}
.frame__title {
  font-family: var(--font-serif);
  font-size: var(--step-3);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
}

/* Project card. The whole card is one link; the title carries the name. */
.project-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.project-card .frame { transition: transform var(--dur-slow) var(--ease); }
.project-card__body { display: flex; flex-direction: column; gap: var(--space-2); }
.project-card__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}
.project-card__title { font-size: var(--step-1); }
.project-card__title a { color: var(--ink); text-decoration: none; }
.project-card__title a::before { content: ""; position: absolute; inset: 0; border-radius: var(--radius); }
.project-card__year { color: var(--ink-3); flex: none; }
.project-card__line { color: var(--ink-2); }
.project-card__award { color: var(--gold-ink); }
.project-card .tags { margin-top: var(--space-1); }
.project-card:hover .frame { transform: translateY(calc(var(--rise) * -1)); }
.project-card:hover .project-card__title a { color: var(--accent); }
.project-card:focus-within .frame { outline: 2px solid var(--focus); outline-offset: 3px; }
.project-card a:focus-visible { outline: none; }

.project-card--lg { gap: var(--space-5); }
.project-card--lg .project-card__title { font-size: var(--step-3); }
.project-card--lg .project-card__line { font-size: var(--step-0); line-height: var(--leading); }
@media (min-width: 60rem) {
  .project-card--lg {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    align-items: center;
    gap: var(--space-7);
  }
}

.project-grid {
  display: grid;
  gap: var(--space-8) var(--space-6);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
}
/* Exactly three across on wide screens (featured work). */
@media (min-width: 60rem) {
  .project-grid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Photo grid: uniform tiles, captions in small text. */
.photo-grid {
  display: grid;
  gap: var(--space-5) var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.photo-grid--portrait { --ratio: 4 / 5; }
.photo-grid--landscape { --ratio: 3 / 2; }
.photo-grid--square { --ratio: 1 / 1; }
.photo-grid figure { display: flex; flex-direction: column; gap: var(--space-2); }
.photo-grid figcaption {
  font-size: var(--step-n1);
  line-height: var(--leading-snug);
  color: var(--ink-3);
}
.photo-grid a { display: block; border-radius: var(--radius); }
.photo-grid a .frame img { transition: transform var(--dur-slow) var(--ease); }
.photo-grid a:hover .frame img { transform: scale(1.02); }

/* Post list item. */
.post-list { margin: 0; padding: 0; list-style: none; border-top: var(--hairline) solid var(--line); }
.post-item {
  position: relative;
  display: grid;
  gap: var(--space-1) var(--space-6);
  padding-block: var(--space-5);
  border-bottom: var(--hairline) solid var(--line);
}
@media (min-width: 48rem) {
  .post-item { grid-template-columns: 9rem 1fr; }
  .post-item__meta { padding-top: 0.35em; }
}
.post-item__meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); color: var(--ink-3); }
@media (min-width: 48rem) { .post-item__meta { flex-direction: column; } }
.post-item__tag { color: var(--accent); }
.post-item__title { font-size: var(--step-2); }
.post-item__title a { color: var(--ink); text-decoration: none; }
.post-item__title a::before { content: ""; position: absolute; inset: 0; }
.post-item__title a:hover { color: var(--accent); }
.post-item__summary { margin-top: var(--space-1); max-width: var(--measure); color: var(--ink-2); }

/* 9. Subscribe form -------------------------------------------------------- */
.subscribe { max-width: 34rem; }
.subscribe__lede { margin-bottom: var(--space-4); color: var(--ink-2); }
.subscribe__row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.input {
  flex: 1 1 14rem;
  min-width: 0;
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: var(--step-0);
}
.input::placeholder { color: var(--ink-3); opacity: 1; }
.input:focus-visible { outline-offset: 1px; border-color: var(--accent); }
.subscribe__msg { min-height: 1.6em; margin-top: var(--space-2); font-size: var(--step-n1); color: var(--ink-3); }
.subscribe__msg[data-state="ok"] { color: var(--accent); }
.subscribe__msg[data-state="error"] { color: var(--gold-ink); }

/* 10. Motion --------------------------------------------------------------- */
/* Short fade and a small rise, once, as things enter. JavaScript adds .js;
   without it everything is simply visible. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(var(--rise));
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
}
