/* Shared site styles.
 * Order: tokens -> document -> frame -> legacy hero -> writing -> homepage
 *        -> mobile layouts -> reduced motion.
 * Serif overrides stay beside their components; mobile candidate modifiers
 * follow the shared mobile layout. Page-local overrides load after this file.
 * The centered-wheel experiment loads home-reveal.css separately.
 */

/* ==========================================================================
   1. Theme and typography tokens
   ========================================================================== */

:root {
  --paper: #f2f1e8;
  --ink: #2b2b2b;
  --mute: #6f6e67;
  --rule: rgba(43, 43, 43, 0.16);
  --tint: rgba(43, 43, 43, 0.06);
  --grain-op: 1;
  --grain: var(--grain-dark);
  /* both speckles, named for the colour of the noise: dark one on light paper, light one on dark */
  --grain-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.25 0 0 0 0 0.2 0 0 0 0 0.12 0 0 0 .22 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --grain-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 .95 0 0 0 0 .85 0 0 0 .12 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Consolas, monospace;
  --display: var(--mono);
  --text: var(--mono);
  --gutter: clamp(20px, 4vw, 48px);
}

/* Neutral charcoal, with a flat background and restrained contrast. */
[data-theme="dark"] {
  color-scheme: dark;
  --paper: #18181b;
  --ink: #e4e4e7;
  --mute: #a1a1aa;
  --rule: rgba(228, 228, 231, 0.14);
  --tint: rgba(228, 228, 231, 0.06);
  --grain: none;
  --grain-op: 0;
}

[data-theme="black"] {
  --paper: #0b0b0b;
  --ink: #f2f1e8;
  --mute: #aaa8a0;
  --rule: rgba(242, 241, 232, 0.18);
  --tint: rgba(242, 241, 232, 0.07);
  --grain: var(--grain-light);
  --grain-op: 0.5;
}

/* the wheel page's blueprint palette, and the home page's default */
[data-theme="blueprint"] {
  --paper: #0a2a52;
  --ink: #d6ecff;
  --mute: #91aec9;
  --rule: rgba(214, 236, 255, 0.18);
  --tint: rgba(214, 236, 255, 0.07);
  --grain: var(--grain-light);
  --grain-op: 0.5;
}

[data-font="serif"] {
  --display: "Newsreader", "Iowan Old Style", Georgia, serif;
  --text: "Newsreader", "Iowan Old Style", Georgia, serif;
}

/* ==========================================================================
   2. Document defaults and accessibility
   ========================================================================== */

* {
  box-sizing: border-box;
}

html {
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: 16px;
  line-height: 1.75;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  transition:
    background 0.4s ease,
    color 0.4s ease;
}

/* paper grain over everything */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  background-image: var(--grain);
  opacity: var(--grain-op);
}

a {
  color: inherit;
}

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

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

[data-font="serif"] body {
  font-size: clamp(18.5px, 0.45vw + 17px, 20px);
  line-height: 1.67;
}

/* ==========================================================================
   3. Header, footer, and theme controls
   ========================================================================== */

/* Contact navigation has its own row above the mobile artwork. */
.top-nav {
  position: relative;
  z-index: 2;
  display: flex;
  flex: 0 0 auto;
  justify-content: flex-end;
  gap: 24px;
  padding: clamp(20px, 2vw, 28px) var(--gutter);
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.67;
  letter-spacing: 0.015em;
}

.top-nav .nav-title {
  margin-inline-end: auto;
}

.top-nav a {
  text-decoration: none;
  text-underline-offset: 0.2em;
}

.top-nav a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

/* Pending links retain their place while explaining that a destination is coming. */
.pending {
  position: relative;
}

.pending-tooltip {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + 8px);
  z-index: 3;
  padding: 6px 10px;
  border-radius: 3px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.5;
  white-space: nowrap;
  text-decoration: none;
  pointer-events: none;
  visibility: hidden;
}

.pending:not([data-pending-dismissed]):is(:hover, :focus, [data-pending-open]) .pending-tooltip {
  visibility: visible;
}

.bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: clamp(20px, 3vw, 30px) var(--gutter);
}

.bar .name {
  font-family: var(--display);
  font-size: 23px;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.015em;
  text-decoration: none;
}

.bar nav {
  margin-left: auto;
  display: flex;
  gap: clamp(14px, 3vw, 28px);
  align-items: baseline;
}

.bar nav a,
.bar nav button,
.foot a {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.015em;
  color: var(--mute);
  text-decoration: none;
  transition: color 0.2s;
}

.bar nav button {
  all: unset;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.015em;
  color: var(--mute);
  transition: color 0.2s;
}

.bar nav a:hover,
.bar nav button:hover,
.bar nav button:focus-visible,
.foot a:hover {
  color: var(--ink);
}

.bar nav a[aria-current] {
  color: var(--ink);
}

.foot {
  margin-top: auto;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 32px var(--gutter) max(24px, env(safe-area-inset-bottom));
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.015em;
  color: var(--mute);
}

.foot .links {
  display: flex;
  gap: 18px;
  align-items: baseline;
}

.foot button {
  all: unset;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.015em;
  color: var(--mute);
  transition: color 0.2s;
}

.foot button:hover,
.foot button:focus-visible {
  color: var(--ink);
}

/* the theme swatches: one small circle per theme, split into its own paper and ink */
.foot .swatches {
  display: flex;
  gap: 9px;
  align-items: center;
}

.foot .swatch {
  display: block;
  box-sizing: border-box;
  width: 13px;
  height: 13px;
  padding: 0;
  border: 0.5px solid var(--mute);
  border-radius: 50%;
  outline: 1px solid transparent;
  outline-offset: 2px;
  transition:
    outline-color 0.2s,
    transform 0.2s;
}

.foot .swatch:hover {
  transform: scale(1.15);
}

.foot .swatch[aria-pressed="true"] {
  outline-color: var(--ink);
}

.foot .swatch:focus-visible {
  outline-color: var(--ink);
}

[data-font="serif"] .bar .name {
  font-size: 25px;
  letter-spacing: -0.015em;
}

/* ==========================================================================
   4. Legacy split hero and shared wheel canvas
   ========================================================================== */

/* the wheel runs off the left edge and sits a little low; the sentence is centred in what's left */
.home {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  grid-template-areas: "art intro";
  align-items: center;
  column-gap: clamp(8px, 2vw, 32px);
  padding: 0 var(--gutter) 0 0;
}

.intro {
  grid-area: intro;
  justify-self: start;
  position: relative;
  z-index: 1;
  padding-left: clamp(0px, 1.5vw, 24px);
}

.say {
  margin: 0;
  max-width: 11.5em;
  font-family: var(--display);
  font-size: clamp(26px, 3.2vw, 44px);
  line-height: 1.2;
  letter-spacing: -0.03em;
}

.say.name {
  max-width: none;
  font-size: clamp(30px, 3.6vw, 54px);
  line-height: 1.05;
  letter-spacing: -0.045em;
}

.contact {
  margin: 16px 0 0;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--mute);
}

.contact a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

.contact a:hover {
  color: var(--ink);
  text-decoration-thickness: 2px;
}

.say a {
  font-style: italic;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.13em;
}

.say a:hover {
  text-decoration-thickness: 3px;
}

.art {
  grid-area: art;
  margin: 0;
  justify-self: start;
  width: 100%;
}

.art canvas {
  display: block;
  width: min(100%, calc(72svh * var(--ar, 1.4)));
  height: auto;
  margin-right: auto;
  aspect-ratio: var(--ar, 1.4);
  cursor: crosshair;
  touch-action: pan-y;
  opacity: 0;
  transition: opacity 1s ease;
}

.art canvas.ready {
  opacity: 1;
}

.art figcaption {
  margin: 4px 0 0;
  text-align: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--mute);
}

[data-font="serif"] .say {
  font-size: clamp(34px, 4.3vw, 62px);
  line-height: 1.12;
  letter-spacing: -0.005em;
}

[data-font="serif"] .say.name {
  font-size: clamp(27px, 2.9vw, 42px);
  line-height: 1;
  letter-spacing: -0.015em;
}

@media (max-width: 760px) {
  /* title at the top; the wheel fills what's left, zoomed so it runs off the sides and bottom */
  .home {
    grid-template-columns: 1fr;
    grid-template-areas: "intro" "art";
    grid-template-rows: auto minmax(0, 1fr);
    align-content: stretch;
    row-gap: 0;
    padding: 0;
  }
  .intro {
    padding: 0 12px;
  }
  .art {
    position: relative;
    margin: 0;
    transform: none;
    overflow: hidden;
    align-self: stretch;
    min-height: 52svh;
  }
  .art canvas {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 150vw;
    max-width: none;
    height: auto;
    transform: translate(-50%, -46%);
  }
}

/* ==========================================================================
   5. Writing lists and articles
   ========================================================================== */

.list,
.post {
  width: 100%;
  max-width: 45rem;
  margin: 0 auto;
  padding: clamp(34px, 6vw, 72px) var(--gutter) clamp(72px, 10vw, 112px);
}

.list h1,
.post h1 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(42px, 3vw + 24px, 64px);
  line-height: 1.02;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.list h1 {
  margin-bottom: 28px;
}

.year {
  margin: 44px 0 10px;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: var(--mute);
}

.row {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  column-gap: 20px;
  padding: 18px 0 20px;
  border-top: 1px solid var(--rule);
  text-decoration: none;
}

.row:last-child {
  border-bottom: 1px solid var(--rule);
}

.row time {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--mute);
  padding-top: 0.45em;
}

.row .t {
  font-family: var(--display);
  font-size: clamp(24px, 1.2vw + 18px, 30px);
  line-height: 1.16;
  letter-spacing: -0.018em;
  text-wrap: pretty;
}

.row .s {
  grid-column: 2;
  color: var(--mute);
  font-size: 16.5px;
  line-height: 1.5;
  margin-top: 7px;
  text-wrap: pretty;
}

.row:hover .t {
  font-style: italic;
}

.empty {
  color: var(--mute);
}
@media (max-width: 560px) {
  .row {
    grid-template-columns: 1fr;
  }
  .row .s {
    grid-column: 1;
  }
  .row time {
    padding-top: 0;
    margin-bottom: 7px;
  }
}

/* Article content and previous/next navigation. */
.post header {
  margin-bottom: clamp(38px, 5vw, 54px);
}

.meta {
  margin: 0 0 18px;
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.03em;
  color: var(--mute);
}

.prose p,
.prose ul,
.prose ol,
.prose pre,
.prose blockquote {
  margin: 0 0 1.25em;
  text-wrap: pretty;
}

.prose h2,
.prose h3,
.prose h4 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.12;
  margin: 2.35em 0 0.65em;
  text-wrap: balance;
}

.prose h2 {
  font-size: clamp(28px, 1vw + 24px, 34px);
  letter-spacing: -0.02em;
}

.prose h3 {
  font-size: clamp(23px, 0.6vw + 21px, 28px);
  letter-spacing: -0.015em;
}

.prose h4 {
  font-size: 20px;
  font-style: italic;
}

.prose a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

.prose a:hover {
  text-decoration-thickness: 2px;
}

.prose ul,
.prose ol {
  padding-left: 1.3em;
}

.prose li {
  margin: 0.25em 0;
  padding-left: 0.2em;
}

.prose blockquote {
  padding-left: 1.1em;
  border-left: 1px solid var(--ink);
  font-style: italic;
}

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

.prose hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.4em 0;
}

.prose code {
  font-family: var(--mono);
  font-size: 0.92em;
  background: var(--tint);
  padding: 0.12em 0.38em;
  border-radius: 3px;
}

.prose pre {
  overflow-x: auto;
  padding: 1em 1.15em;
  background: var(--tint);
  border-radius: 6px;
  line-height: 1.5;
}

.prose pre code {
  background: none;
  padding: 0;
  font-size: 14px;
}

.prose img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 1.6em 0;
}

.pn {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 72px;
  padding-top: 26px;
  border-top: 1px solid var(--rule);
}

.pn a {
  text-decoration: none;
  font-family: var(--display);
  font-size: 22px;
  line-height: 1.22;
  letter-spacing: -0.015em;
}

.pn a[rel="next"] {
  text-align: right;
}

.pn a span {
  display: block;
  margin-bottom: 4px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--mute);
}

.pn a:hover {
  font-style: italic;
}

[data-font="serif"] .list h1,
[data-font="serif"] .post h1 {
  font-size: clamp(42px, 3vw + 24px, 64px);
  line-height: 1.02;
  letter-spacing: -0.025em;
}

[data-font="serif"] .row .t {
  font-size: clamp(24px, 1.2vw + 18px, 30px);
  line-height: 1.16;
  letter-spacing: -0.018em;
}

[data-font="serif"] .row .s {
  font-size: 16.5px;
}

[data-font="serif"] .prose h2 {
  font-size: clamp(28px, 1vw + 24px, 34px);
  letter-spacing: -0.02em;
}

[data-font="serif"] .prose h3 {
  font-size: clamp(23px, 0.6vw + 21px, 28px);
  letter-spacing: -0.015em;
}

[data-font="serif"] .prose h4 {
  font-size: 20px;
}

[data-font="serif"] .prose code {
  font-size: 0.8em;
}

[data-font="serif"] .pn a {
  font-size: 22px;
  letter-spacing: -0.015em;
}

.prose strong {
  font-weight: 600;
}

/* ==========================================================================
   6. Homepage composition: intro, wheel, and quotation
   ========================================================================== */

.is-home {
  --home-secondary: color-mix(in srgb, var(--ink) 82%, var(--paper));
  --wheel-width: min(56vw, calc(82svh * 1.15));
}

.is-home--sans {
  --text: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
}

/*
 * Design measurement guides for checking the text and canvas bounds.
 * Keep these styles available for future design work, even when the guides are
 * turned off in the UI by removing the `design-guides` class from the page.
 */
.is-home.design-guides .bar--home,
.is-home.design-guides .art canvas,
.is-home.design-guides .home-secondary-copy {
  outline: 1px solid color-mix(in srgb, var(--ink) 38%, transparent);
  outline-offset: -1px;
}

.is-home .bar--home {
  position: fixed;
  z-index: 1;
  top: clamp(84px, 14svh, 132px);
  left: clamp(var(--gutter), 10vw, 152px);
  width: min(27rem, 33vw);
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  padding: 0;
}

.is-home--long .bar--home {
  position: relative;
  top: auto;
  left: auto;
  margin: clamp(84px, 14svh, 132px) 0 clamp(64px, 10svh, 96px)
    clamp(var(--gutter), 10vw, 152px);
}

.is-home .bar--home .name {
  display: block;
  color: var(--home-secondary);
  font-family: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  font-size: clamp(29px, 2.4vw, 37px);
  font-weight: 400;
  line-height: 0.98;
  letter-spacing: -0.025em;
}

.is-home .home-summary {
  max-width: 34ch;
  margin: 30px 0 0;
  color: var(--home-secondary);
  font-family: var(--text);
  font-size: 16px;
  line-height: 1.56;
  text-wrap: pretty;
}

.is-home--two-text .home-summary strong {
  font-weight: 600;
}

.is-home .home-projects {
  max-width: 34ch;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--text);
  font-size: 16px;
  line-height: 1.42;
}

.is-home .home-projects li + li {
  margin-top: 7px;
}

.is-home .home-projects a {
  color: var(--home-secondary);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.is-home .home-projects a:hover {
  color: var(--ink);
  text-decoration-thickness: 2px;
}

.is-home--two-text .home-secondary-copy {
  position: fixed;
  z-index: 1;
  bottom: clamp(84px, 14svh, 132px);
  right: clamp(var(--gutter), 10vw, 152px);
  width: min(27rem, 33vw);
  color: var(--home-secondary);
  font-family: var(--text);
  font-size: 16px;
  line-height: 1.56;
  text-wrap: pretty;
}

.is-home--two-text .home-secondary-copy p {
  margin: 0 0 0 auto;
  max-width: 34ch;
}

.home-quote {
  max-width: 34ch;
  margin: 0 0 0 auto;
}

.home-quote blockquote {
  margin: 0;
}

.home-quote--italic blockquote {
  font-style: italic;
}

.home-quote figcaption {
  margin-top: 14px;
  font-size: 0.875em;
  line-height: 1.5;
  color: var(--mute);
}

[data-font="mono"] .is-home .home-summary,
[data-font="mono"] .is-home .home-projects {
  font-size: 14px;
}

.is-home .home {
  display: block;
  padding: 0;
}

.is-home .art {
  position: fixed;
  top: 50%;
  left: 50%;
  width: var(--wheel-width);
  min-height: 0;
  overflow: visible;
  transform: translate(-50%, -50%);
}

.is-home .art canvas {
  position: static;
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
  transform: none;
}

/* ==========================================================================
   7. Shared mobile layout (760px and below)
   ========================================================================== */

@media (max-width: 760px) {
  .bar {
    padding-top: 20px;
    padding-bottom: 20px;
  }
  .list,
  .post {
    padding-top: 28px;
  }
  .post h1 {
    font-size: 34px;
  }
  .is-home {
    --wheel-width: min(132vw, 560px);
  }
  .is-home .bar--home {
    position: relative;
    top: auto;
    left: auto;
    width: 100%;
    flex: 0 0 auto;
    margin: 0;
    padding: 40px var(--gutter) 24px;
  }
  .is-home .bar--home .name {
    font-size: 29px;
  }
  .is-home .home-summary {
    max-width: none;
    margin-top: 22px;
    font-size: 15.5px;
    line-height: 1.54;
  }
  .is-home .home-projects {
    max-width: none;
    margin-top: 20px;
    font-size: 15.5px;
    line-height: 1.38;
  }
  .is-home .home-projects li + li {
    margin-top: 9px;
  }
  .is-home .home {
    flex: 0 0 auto;
    display: flex;
    min-height: clamp(330px, 82vw, 390px);
    align-items: center;
    justify-content: center;
    overflow: hidden;
  }
  .is-home--two-text .home-secondary-copy {
    position: relative;
    bottom: auto;
    left: auto;
    right: auto;
    width: 100%;
    flex: 0 0 auto;
    margin: 0;
    padding: 28px var(--gutter) 40px;
    font-size: 15.5px;
    line-height: 1.54;
  }
  .is-home--two-text .home-secondary-copy p {
    margin-left: 0;
    max-width: none;
  }
  .is-home--two-text .home-secondary-copy--inset {
    padding-inline: 40px;
  }
  .home-quote {
    max-width: none;
    margin-left: 0;
  }
  .is-home .art {
    position: relative;
    top: auto;
    left: auto;
    width: var(--wheel-width);
    flex: 0 0 auto;
    transform: none;
  }
  .is-home .foot {
    flex: 0 0 auto;
    padding-top: 22px;
  }
}

/* ==========================================================================
   8. Wheel-first mobile candidate
   ========================================================================== */

@media (max-width: 760px) {
  /* Artwork first, with enough crop to read as an opening image rather than a banner. */
  .is-home--wheel-first {
    --wheel-width: min(124vw, 540px);
  }
  .is-home--wheel-first .home {
    min-height: clamp(350px, 88vw, 410px);
    align-items: center;
  }
  .is-home--wheel-first .art {
    transform: none;
  }
  .is-home--wheel-first .bar--home {
    padding-top: 24px;
    margin-top: -80px;
  }
}

/* ==========================================================================
   9. Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  body,
  .say a,
  .art canvas {
    transition: none;
  }
}
