:root {
  --paper: #f7f7f3;
  --paper-2: #efeee8;
  --ink: #303030;
  --soft: rgba(48, 48, 48, 0.46);
  --line: rgba(48, 48, 48, 0.28);
  --dark: #151515;
  --dark-soft: rgba(247, 247, 243, 0.62);
  --dark-line: rgba(247, 247, 243, 0.25);
  --blue: #4e7ea7;
  --mono: system-ui, sans-serif;
  --sans: "Hanken Grotesk", sans-serif;
  --display: "Barlow Condensed", "Hanken Grotesk", sans-serif;
  --script: "Allura", cursive;
  /* Organic film grain for dark grounds, an SVG turbulence tile rather than a
     geometric line pattern, so black sections read as photographic rather
     than like a generated gradient. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; }
html {
  overflow-x: hidden;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  overflow-x: hidden;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.026) 1px, transparent 1px),
    radial-gradient(circle at 38% 26%, rgba(0, 0, 0, 0.035), transparent 32%),
    var(--paper);
  background-size: 7px 100%, auto, auto;
  color: var(--ink);
  font-family: var(--sans);
  letter-spacing: 0;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.11;
  mix-blend-mode: multiply;
  background-image: radial-gradient(circle, rgba(0, 0, 0, 0.68) 0.45px, transparent 0.8px);
  background-size: 3px 3px;
}

body.tree-card-open {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

body.tree-card-open::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 88;
  pointer-events: auto;
  background: rgba(247, 247, 243, 0.62);
  backdrop-filter: blur(22px);
}

a { color: inherit; text-decoration: none; }
img, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }

.script {
  font-family: var(--script);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

.opening-gate {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: #050505;
  transition: opacity 520ms ease, visibility 520ms ease;
}

.opening-gate.is-hidden { opacity: 0; visibility: hidden; }

.opening-gate video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 80;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: 76px;
  padding: 0 clamp(30px, 5.2vw, 106px);
  background: rgba(247, 247, 243, 0.86);
  backdrop-filter: blur(15px);
  font-family: var(--mono);
  font-size: 13px;
  text-transform: uppercase;
}

.brand {
  display: inline-flex;
  width: 42px;
  height: 42px;
  align-items: center;
  color: var(--ink);
}

.brand-mark {
  width: 36px;
  height: 36px;
  overflow: visible;
}

.brand-mark line {
  stroke: currentColor;
  stroke-width: 11;
  stroke-linecap: round;
}

.brand-mark circle {
  fill: currentColor;
}

.topbar nav {
  display: flex;
  gap: clamp(22px, 3vw, 48px);
}

.topbar a { transition: opacity 160ms ease; }
.topbar a:hover { opacity: 0.56; }

.hero {
  min-height: calc(100vh - 72px);
  position: relative;
  display: grid;
  align-content: center;
  justify-items: center;
  padding: 42px clamp(30px, 5.2vw, 106px) 118px;
}

.hero h1 {
  margin: 0;
  display: grid;
  justify-items: center;
  font-family: var(--display);
  font-size: clamp(110px, 14.2vw, 258px);
  font-weight: 500;
  line-height: 0.72;
  text-transform: uppercase;
}

.hero h1 .script {
  margin-top: -0.08em;
  margin-left: 0.72em;
  font-size: 0.56em;
  transform: rotate(-7deg);
}

.television {
  width: min(880px, 76vw);
  margin: 30px auto 0;
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  justify-items: center;
}

.television__frame {
  position: relative;
  width: 100%;
  isolation: isolate;
}

.television__asset {
  position: relative;
  z-index: 4;
  width: 100%;
  height: auto;
  filter: saturate(0.88) contrast(1.06);
  transform: scale(0.88);
  transform-origin: center 54%;
  pointer-events: none;
}

.television__screenContent {
  position: absolute;
  left: 8.6%;
  top: 11.9%;
  z-index: 1;
  width: 67.1%;
  height: 69.4%;
  overflow: hidden;
  border-radius: 8.5% / 10.5%;
  background: #0b1012;
}

.television__screenContent.is-switching {
  animation: tv-signal-jump 180ms steps(2, end);
}

.tv-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.95) contrast(1.08) brightness(0.78);
}

.television__glass,
.television__screenContent::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 8;
  pointer-events: none;
  background:
    linear-gradient(rgba(255, 255, 255, 0.08) 50%, rgba(0, 0, 0, 0.18) 50%),
    radial-gradient(circle at 50% 35%, transparent 45%, rgba(0, 0, 0, 0.34));
  background-size: 100% 4px, auto;
  mix-blend-mode: screen;
  opacity: 0.42;
}

.surface-reel,
.surface-frame {
  position: absolute;
  inset: 0;
}

.surface-reel {
  overflow: hidden;
  background: #111;
}

.surface-frame {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  filter: saturate(0.92) contrast(1.06) brightness(0.92);
  transform: none;
  transition: opacity 80ms steps(1, end), filter 80ms linear;
}

.surface-frame.is-active {
  opacity: 1;
  transform: none;
  filter: saturate(1.03) contrast(1.12) brightness(0.9);
}

.surface-reel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(255, 87, 62, 0.18), transparent 18%, rgba(71, 139, 255, 0.16) 38%, transparent 62%),
    linear-gradient(rgba(255,255,255,0.12) 1px, transparent 1px);
  background-size: 100% 100%, 100% 3px;
  opacity: 0;
}

.television__screenContent.is-switching .surface-reel::before {
  opacity: 0.75;
}

.television figcaption {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  bottom: auto;
  z-index: 6;
  margin: -25px -81px 0 0;
  max-width: 250px;
  font-family: var(--mono);
  font-size: clamp(14px, 1.05vw, 16px);
  line-height: 1.18;
  text-transform: uppercase;
}

.hero__dial {
  position: absolute;
  left: clamp(30px, 5.2vw, 106px);
  bottom: 72px;
  margin: 0;
  display: grid;
  grid-template-columns: 15px repeat(4, auto);
  gap: 8px;
  align-items: center;
  font-family: var(--mono);
  font-size: 12px;
}

.hero__dial img {
  width: 14px;
  height: 14px;
  opacity: 0.84;
}

.hero__dial span:nth-of-type(3) { grid-column: auto; }

.positioning {
  min-height: 96vh;
  display: grid;
  align-content: center;
  gap: 42px;
  padding: 92px clamp(30px, 5.2vw, 106px);
}

.positioning p {
  max-width: 920px;
  margin: 0;
  font-size: clamp(28px, 3.2vw, 42px);
  font-weight: 700;
  line-height: 0.98;
  text-transform: uppercase;
}

/* Direct child only: the caption line, not the .reveal-word spans that
   initScrollHighlight() now injects inside the paragraph above it. */
.positioning > span {
  font-family: var(--mono);
  font-size: clamp(12px, 1.1vw, 16px);
  text-transform: uppercase;
}

.work-section {
  min-height: 98vh;
  position: relative;
  padding: 58px clamp(30px, 5.2vw, 106px) 96px;
  scroll-margin-top: 110px;
}

.section-title--work {
  display: grid;
  justify-items: end;
  margin: 0 0 24px;
}

.section-title h2 {
  margin: 0;
  font-size: clamp(74px, 10.4vw, 178px);
  font-weight: 700;
  line-height: 0.82;
  text-transform: uppercase;
}

.section-title--work .script {
  display: block;
  margin: 0 0 -0.24em -0.34em;
  font-size: 0.76em;
}

.time-range {
  margin: 0 0 18px;
  font-family: var(--mono);
  font-size: 13px;
  text-transform: uppercase;
}

.work-stage {
  display: grid;
  grid-template-columns: minmax(232px, 292px) minmax(0, 1fr);
  gap: clamp(22px, 2.8vw, 38px);
  align-items: start;
}

.work-list {
  align-self: end;
  display: grid;
  font-family: var(--mono);
  text-transform: uppercase;
}

.work-list a {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  min-height: 32px;
  border-bottom: 1px solid var(--line);
  color: rgba(48, 48, 48, 0.34);
  transition: color 160ms ease, padding-left 160ms ease, opacity 160ms ease;
}

.work-list a:first-child { border-top: 1px solid var(--line); }

.work-list strong {
  overflow-wrap: anywhere;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.08;
  text-transform: none;
}

.work-list em {
  display: none;
}

.work-list a:hover,
.work-list a:focus-visible,
.work-list a.is-active {
  color: var(--ink);
  padding-left: 8px;
  outline: 0;
}

.project-preview {
  grid-column: 2;
  margin: 0;
}

.project-preview__media {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: transparent;
}

.project-preview__media::after {
  content: none;
  display: none;
}

.project-preview__media img,
.project-preview__media video {
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: min(38vh, 390px);
  object-fit: contain;
}

.project-slideshow {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
}

.project-slideshow img {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity 70ms steps(1, end);
}

.project-slideshow img.is-active {
  opacity: 1;
}

.project-preview figcaption {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding-top: 8px;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
}

.project-note {
  grid-column: 2;
  min-width: 0;
  display: grid;
  gap: 6px;
  width: min(780px, 100%);
  margin-top: -150px;
  align-self: start;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.4;
  text-transform: uppercase;
}

.project-note span { color: var(--blue); }

.project-note h3 {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(22px, 2.25vw, 36px);
  font-weight: 700;
  line-height: 0.9;
  text-transform: uppercase;
  overflow-wrap: normal;
}

.project-note p { margin: 0; }
.project-note a { justify-self: start; border-bottom: 1px solid currentColor; }

.methodology {
  position: relative;
  min-height: 330vh;
  padding: 96px clamp(30px, 5.2vw, 106px) 160px;
  scroll-margin-top: 110px;
}

.methodology__title {
  position: sticky;
  top: 92px;
  height: 0;
  z-index: 2;
  pointer-events: none;
  transition: opacity 160ms linear;
}

.methodology__title h2 {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0;
  font-size: clamp(72px, 9.8vw, 178px);
  line-height: 0.78;
  text-transform: uppercase;
}

.methodology__title .script {
  display: inline-block;
  margin: 0 -0.075em;
  font-size: 0.82em;
  text-transform: none;
  transform: translateY(0.035em) rotate(-5deg);
}

.methodology__claim {
  position: sticky;
  top: 92px;
  z-index: 1;
  min-height: calc(100vh - 92px);
  display: grid;
  align-content: end;
  justify-items: end;
  gap: 22px;
  padding-bottom: 128px;
  pointer-events: none;
  transition: opacity 160ms linear;
}

.methodology.is-pinned .methodology__title {
  position: fixed;
  left: clamp(30px, 5.2vw, 106px);
  right: clamp(30px, 5.2vw, 106px);
  top: 112px;
}

.methodology.is-pinned .methodology__claim {
  position: fixed;
  left: clamp(30px, 5.2vw, 106px);
  right: clamp(30px, 5.2vw, 106px);
  top: 0;
  min-height: 100vh;
  padding-bottom: 128px;
}

.methodology.is-after .methodology__title,
.methodology.is-after .methodology__claim {
  opacity: 0;
}

.methodology__claim p {
  width: min(760px, 60vw);
  margin: 0;
  color: rgba(48, 48, 48, 0.38);
  font-size: clamp(18px, 2.1vw, 32px);
  font-weight: 700;
  line-height: 0.96;
  text-align: right;
  text-transform: uppercase;
}

.methodology__claim p + p {
  font-family: var(--mono);
  font-size: clamp(12px, 1.15vw, 18px);
  font-weight: 400;
  line-height: 1.25;
}

.method-stack {
  position: relative;
  z-index: 5;
  display: grid;
  gap: 30vh;
  width: min(560px, 42vw);
  margin: 0 auto;
  padding-top: 4vh;
  padding-bottom: 20vh;
}

.method-card {
  position: sticky;
  top: 40vh;
  aspect-ratio: 4 / 3;
  min-height: 0;
  padding: 24px;
  border: 1px solid rgba(48, 48, 48, 0.48);
  background: rgba(247, 247, 243, 0.96);
  font-family: var(--mono);
  text-transform: uppercase;
  box-shadow: 0 22px 52px rgba(0,0,0,0.055);
  transform: translateY(var(--card-offset, 64px));
  opacity: 1;
  transition: transform 420ms ease, min-height 220ms ease;
}

.method-card.is-visible,
.method-card:hover,
.method-card:focus-within {
  transform: translateY(var(--card-offset, 0));
  opacity: 1;
}

.method-card:hover,
.method-card:focus-within {
  opacity: 1;
}

.method-card::before {
  content: "•••";
  display: block;
  margin: -24px -24px 22px;
  padding: 8px 14px;
  border-bottom: 1px solid rgba(48, 48, 48, 0.48);
  color: rgba(48, 48, 48, 0.42);
  letter-spacing: 3px;
}

.method-card summary {
  display: grid;
  gap: 22px;
  cursor: pointer;
  list-style: none;
}

.method-card summary::-webkit-details-marker { display: none; }

.method-card span,
.moves-card__head span,
.permits-card > span {
  font-size: 16px;
}

.method-card strong,
.moves-card__head strong,
.permits-card > strong {
  font-size: 18px;
  font-weight: 500;
}

.method-card em {
  color: rgba(48, 48, 48, 0.46);
  font-family: system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  font-style: normal;
  line-height: 1.3;
  letter-spacing: 0;
}

.method-card p,
.permits-card li {
  color: rgba(48, 48, 48, 0.5);
  font-size: clamp(13px, 1.05vw, 17px);
  line-height: 1.26;
}

.method-card[open] { min-height: 0; }

.moves-card,
.permits-card {
  display: grid;
  gap: 22px;
}

.moves-card {
  aspect-ratio: auto;
  height: auto;
  min-height: max-content;
}

.permits-card {
  aspect-ratio: auto;
  min-height: max-content;
  align-content: start;
}

.moves-card__head { display: grid; gap: 16px; }
.moves {
  display: grid;
  gap: 8px;
  counter-reset: move;
}

.moves button {
  min-height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  background: transparent;
  cursor: pointer;
  font-family: var(--mono);
  text-align: left;
  text-transform: none;
}

.moves button::before {
  counter-increment: move;
  content: counter(move, lower-alpha) ". ";
  color: rgba(48, 48, 48, 0.46);
  margin-right: 0.42em;
  transition: color 160ms ease;
}

.moves button:hover,
.moves button:focus-visible {
  background: var(--ink);
  color: var(--paper);
  outline: 0;
}

.moves button:hover::before,
.moves button:focus-visible::before {
  color: rgba(247, 247, 243, 0.68);
}

.move-tip { min-height: 60px; }
.permits-card ul { margin: 0; padding-left: 22px; }

.writing-dark {
  min-height: 112vh;
  position: relative;
  z-index: 12;
  display: grid;
  align-content: center;
  gap: 68px;
  padding: 88px clamp(30px, 5.2vw, 106px) 104px;
  background: var(--grain), var(--dark);
  background-size: 160px 160px, auto;
  background-blend-mode: overlay, normal;
  color: var(--dark-soft);
  scroll-margin-top: 110px;
}

.writing-years {
  position: absolute;
  right: clamp(30px, 5.2vw, 106px);
  top: 84px;
  margin: 0;
  font-family: var(--mono);
  font-size: 13px;
  text-transform: uppercase;
}

.writing-placeholder {
  width: min(320px, 30vw);
  height: 120px;
  justify-self: center;
  border: 1px dashed rgba(247, 247, 243, 0.18);
  opacity: 0.35;
}

.writing-dark__intro {
  display: grid;
  grid-template-columns: minmax(240px, 0.36fr) minmax(420px, 1fr);
  gap: clamp(70px, 8vw, 130px);
  align-items: center;
}

.writing-dark h2 {
  margin: 0;
  color: var(--paper);
  font-size: clamp(86px, 9.2vw, 148px);
  line-height: 0.72;
  text-transform: uppercase;
}

.writing-dark__intro p {
  justify-self: end;
  max-width: 720px;
  margin: 0;
  font-size: clamp(16px, 1.85vw, 26px);
  font-weight: 700;
  line-height: 1.04;
  text-transform: uppercase;
}

.writing-table {
  display: grid;
  border-top: 1px solid var(--dark-line);
  font-family: var(--mono);
  text-transform: uppercase;
}

.writing-table a {
  position: relative;
  display: grid;
  grid-template-columns: 120px minmax(250px, 0.55fr) 1fr;
  gap: 28px;
  padding: 18px 0;
  border-bottom: 1px solid var(--dark-line);
}

.writing-table a:hover strong { color: #fff; }
.writing-table strong { color: var(--paper); font-weight: 500; }
.writing-table em { color: rgba(247, 247, 243, 0.46); font-style: normal; }

.writing-popover {
  position: fixed;
  z-index: 100;
  right: max(42px, 10vw);
  top: 52vh;
  width: min(360px, 34vw);
  padding: 8px;
  border: 1px solid rgba(247, 247, 243, 0.42);
  background: rgba(21, 21, 21, 0.96);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.42);
  pointer-events: none;
  opacity: 0;
  filter: blur(4px);
  transform: translate3d(0, -50%, 0);
  transition: opacity 130ms ease, filter 130ms ease;
}

.writing-popover.is-visible {
  opacity: 1;
  filter: blur(0);
  transform: translate3d(0, -50%, 0);
}

.writing-popover img {
  width: 100%;
  max-height: 430px;
  object-fit: contain;
  filter: grayscale(0.1) contrast(1.03);
}

.about {
  min-height: 108vh;
  display: grid;
  align-content: center;
  padding: 108px clamp(30px, 5.2vw, 106px);
  scroll-margin-top: 110px;
}

.about h2 {
  margin: 0 0 78px;
  text-align: center;
  font-size: clamp(86px, 11vw, 178px);
  line-height: 0.82;
  text-transform: none;
}

.about h2 .script {
  display: inline-block;
  margin: 0 -0.12em;
  font-size: 0.66em;
  transform: rotate(-6deg) translateY(0.03em);
}

.about__grid {
  display: grid;
  grid-template-columns: minmax(220px, 360px) minmax(340px, 720px);
  gap: clamp(42px, 6vw, 104px);
  align-items: center;
  justify-content: center;
}

.about__portrait {
  margin: 0;
  display: grid;
  gap: 14px;
  justify-items: end;
}

.about__portrait img {
  width: min(100%, 360px);
  aspect-ratio: 0.8;
  object-fit: cover;
  filter: grayscale(1) contrast(1.12);
}

.about__portrait figcaption {
  font-family: var(--mono);
  font-size: 18px;
  text-align: right;
  text-transform: uppercase;
}

.about__text {
  display: grid;
  gap: 18px;
  font-family: var(--mono);
  text-transform: none;
}

.about-current {
  width: min(620px, 100%);
  margin: 0;
  font-size: clamp(16px, 1.32vw, 22px);
  font-weight: 700;
  line-height: 1.16;
  text-transform: uppercase;
}

.about-beside {
  position: relative;
  width: min(640px, 100%);
  margin: 0;
  font-family: var(--mono);
  font-size: clamp(16px, 1.32vw, 22px);
  font-weight: 700;
  line-height: 1.16;
}

.aside-trigger {
  display: inline;
  border: 0;
  padding: 0;
  background: transparent;
  color: rgba(48, 48, 48, 0.32);
  cursor: pointer;
  font: inherit;
  line-height: inherit;
  text-align: left;
  text-transform: none;
  filter: blur(15px);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.12em;
  transition: color 180ms ease, filter 180ms ease;
}

.aside-hint {
  position: absolute;
  left: 0;
  top: calc(100% + 14px);
  z-index: 4;
  color: var(--blue);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  line-height: 1.2;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 180ms ease, transform 180ms ease;
}

.aside-hint.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.aside-trigger:hover,
.aside-trigger:focus-visible,
.aside-trigger[aria-expanded="true"] {
  color: var(--ink);
  filter: blur(0);
  outline: 0;
}

.tree-card { display: contents; }

.tree-card__open {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 96;
  width: min(1120px, 92vw);
  height: min(690px, 82vh);
  margin: 0;
  padding: 0;
  border: 0;
  background: rgba(247, 247, 243, 0.96);
  color: #2f2f2f;
  box-shadow: 0 28px 80px rgba(48, 48, 48, 0.18);
  overflow: hidden;
  animation: tree-pop 420ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* Reaching the last line, or pressing Close, now plays this in reverse
   before the element actually disappears, held visible by JS for exactly
   the animation's length. Without a class to switch to, closing had no way
   to run any animation at all: [hidden] cuts to display:none immediately. */
.tree-card__open.is-closing {
  animation: tree-pop-out 320ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

.tree-card__open img,
.tree-card__open video {
  position: absolute;
  display: block;
  object-fit: cover;
}

.tree-card__cyanotype {
  left: 6%;
  bottom: 7%;
  width: 54%;
  height: 52%;
  z-index: 1;
  filter: saturate(0.92) contrast(1.05);
}

.tree-card__dogwood {
  left: 24%;
  top: 3%;
  width: 194.83px;
  margin-top: 22px;
  margin-left: 178px;
  aspect-ratio: 1;
  z-index: 3;
}

.tree-card__feather {
  left: 12%;
  top: 19%;
  width: 158.92px;
  margin-top: 66px;
  margin-left: -40px;
  aspect-ratio: 0.78;
  z-index: 4;
  border: 3px solid var(--paper);
  box-shadow: 0 12px 24px rgba(48, 48, 48, 0.12);
}

.tree-card__tree {
  position: absolute;
  right: 8%;
  top: 8%;
  z-index: 6;
  width: 28%;
  height: 56%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.tree-card__tree-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 18px 32px rgba(48, 48, 48, 0.16));
  transition: opacity 420ms ease;
}

.tree-card__tree-img--closed {
  opacity: 1;
}

.tree-card__tree-img--open {
  inset: 0;
  opacity: 0;
}

.tree-card__open.is-tree-open .tree-card__tree-img--closed {
  opacity: 0;
}

.tree-card__open.is-tree-open .tree-card__tree-img--open {
  opacity: 1;
}

.tree-card__hint {
  position: absolute;
  right: 7%;
  top: 64%;
  z-index: 7;
  width: min(300px, 29%);
  margin: 0;
  color: #4e9bd2;
  font-family: var(--sans);
  font-size: clamp(17px, 1.55vw, 25px);
  font-weight: 400;
  line-height: 1.08;
  text-align: left;
  transition: opacity 220ms ease, transform 220ms ease;
}

.tree-card__open.is-tree-open .tree-card__hint {
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
}

.tree-card__content {
  position: absolute;
  right: 10.2%;
  top: 22%;
  z-index: 9;
  width: min(270px, 25%);
  height: min(230px, 33%);
  padding: 18px 16px;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  background: rgba(208, 208, 208, 0.88);
  opacity: 0;
  pointer-events: none;
  transform: translateY(10px);
  transition: opacity 260ms ease 180ms, transform 260ms ease 180ms;
  scrollbar-width: thin;
  scrollbar-color: rgba(48, 48, 48, 0.34) transparent;
}

.tree-card__open.is-tree-open .tree-card__content {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.tree-card__content h3 {
  display: none;
}

.tree-card__content ol {
  display: block;
  width: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: visible;
  counter-reset: none;
}

.tree-card__content li {
  display: block;
  font-family: var(--sans);
  font-size: clamp(13px, 0.9vw, 15px);
  font-weight: 500;
  line-height: 1.2;
  text-transform: none;
}

.tree-card__content li + li::before {
  content: none;
}

.tree-card__content li + li {
  margin-top: 0.65em;
}

@keyframes tree-pop {
  from { opacity: 0; transform: translate(-50%, calc(-50% + 34px)) scale(0.985); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes tree-pop-out {
  from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  to { opacity: 0; transform: translate(-50%, calc(-50% + 20px)) scale(0.98); }
}

@keyframes tv-signal-jump {
  0% { transform: translate(0, 0); filter: hue-rotate(0deg); }
  35% { transform: translate(-2px, 1px); filter: hue-rotate(16deg) contrast(1.22); }
  70% { transform: translate(2px, -1px); filter: hue-rotate(-18deg) contrast(1.18); }
  100% { transform: translate(0, 0); filter: hue-rotate(0deg); }
}

.skill-section {
  min-height: 106vh;
  display: grid;
  align-content: center;
  gap: 44px;
  padding: 104px clamp(30px, 5.2vw, 106px);
}

.skill-lead {
  max-width: 1120px;
  margin: 0 auto;
  font-size: clamp(42px, 6.5vw, 118px);
  font-weight: 700;
  line-height: 0.94;
  text-align: center;
  text-transform: uppercase;
}

.skill-copy {
  width: min(980px, 100%);
  margin: 0 auto;
  display: grid;
  gap: 18px;
  font-family: var(--mono);
  font-size: clamp(16px, 1.35vw, 23px);
  line-height: 1.34;
  text-align: center;
  text-transform: uppercase;
}

.skill-copy p { margin: 0; }

/* Skill-section choreography, set by initSkillChoreography(): the headline
   punches in as one statement, the paragraphs cascade in reading order,
   the chips pop in fast afterwards as a set to scan and click rather than
   read. */
.skill-lead {
  opacity: 0;
  transform: translateY(28px) scale(1.035);
  transition:
    opacity 720ms cubic-bezier(0.16, 0.84, 0.2, 1),
    transform 720ms cubic-bezier(0.16, 0.84, 0.2, 1);
}

.skill-lead.is-revealed {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.skill-copy p {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 640ms cubic-bezier(0.16, 0.84, 0.2, 1) var(--reveal-delay, 0ms),
    transform 640ms cubic-bezier(0.16, 0.84, 0.2, 1) var(--reveal-delay, 0ms);
}

.skill-copy p.is-revealed {
  opacity: 1;
  transform: translateY(0);
}

.skill-strips button {
  opacity: 0;
  transform: translateY(14px) scale(0.88);
  transition:
    opacity 460ms cubic-bezier(0.34, 1.56, 0.64, 1) var(--reveal-delay, 0ms),
    transform 460ms cubic-bezier(0.34, 1.56, 0.64, 1) var(--reveal-delay, 0ms);
}

.skill-strips button.is-revealed {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.skill-strips {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  width: min(1380px, 100%);
  margin: 8px auto 0;
}

.skill-strips button {
  position: relative;
  min-height: 42px;
  padding: 0 16px;
  border: 1px solid currentColor;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 14px;
  text-transform: uppercase;
  outline-offset: 3px;
}

.skill-strips button:hover,
.skill-strips button:focus-visible,
.skill-strips button[aria-expanded="true"] {
  background: var(--ink);
  color: var(--paper);
  outline: 0;
}

.skill-strips .tag-label {
  position: relative;
  z-index: 1;
}

.skill-strips .tag-note {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  z-index: 40;
  width: max-content;
  max-width: 360px;
  padding: 14px 16px;
  border: 1px solid rgba(247, 247, 243, 0.16);
  border-radius: 6px;
  background: rgba(20, 21, 23, 0.96);
  color: rgba(247, 247, 243, 0.9);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.42);
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0;
  text-align: center;
  text-transform: none;
  white-space: normal;
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transform: translate(-50%, 8px);
  transition: opacity 180ms ease, transform 180ms ease, visibility 180ms ease;
}

.skill-strips .tag-note::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -7px;
  border: 7px solid transparent;
  border-top-color: rgba(20, 21, 23, 0.96);
}

.skill-strips button:hover .tag-note,
.skill-strips button:focus-visible .tag-note,
.skill-strips button[aria-expanded="true"] .tag-note {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transform: translate(-50%, 0);
}

.skill-strips button.note-left .tag-note {
  left: 0;
  transform: translate(0, 8px);
}

.skill-strips button.note-left:hover .tag-note,
.skill-strips button.note-left:focus-visible .tag-note,
.skill-strips button.note-left[aria-expanded="true"] .tag-note {
  transform: translate(0, 0);
}

.skill-strips button.note-left .tag-note::after { left: 34px; }

.skill-strips button.note-right .tag-note {
  left: auto;
  right: 0;
  transform: translate(0, 8px);
}

.skill-strips button.note-right:hover .tag-note,
.skill-strips button.note-right:focus-visible .tag-note,
.skill-strips button.note-right[aria-expanded="true"] .tag-note {
  transform: translate(0, 0);
}

.skill-strips button.note-right .tag-note::after {
  left: auto;
  right: 30px;
}

.tool-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-start;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(247, 247, 243, 0.14);
}

.tool-chips > span {
  padding: 3px 8px;
  border: 1px solid rgba(247, 247, 243, 0.18);
  border-radius: 4px;
  color: rgba(247, 247, 243, 0.72);
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.35;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.contact {
  position: relative;
  min-height: 100vh;
  display: grid;
  align-items: end;
  padding: clamp(24px, 4vw, 52px) clamp(30px, 5.2vw, 106px);
  background: var(--dark);
  color: var(--paper);
  overflow: hidden;
}

.contact-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.3;
  font-family: var(--mono);
  text-transform: uppercase;
}

.contact-tv__set {
  position: absolute;
  left: max(-120px, -7vw);
  right: auto;
  bottom: max(-180px, -11vw);
  z-index: 1;
  width: min(1380px, 112vw);
  aspect-ratio: 2048 / 1080;
}

.contact-tv__frame {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  filter: saturate(0.92) contrast(1.08) brightness(0.78);
}

.contact-tv__screen {
  position: absolute;
  left: 0.6%;
  top: 13.4%;
  z-index: 2;
  width: 67.2%;
  height: 82.4%;
  overflow: hidden;
  border-radius: 0 0 7% 7% / 0 0 7% 7%;
  background: #030303;
}

.contact-tv__screen video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.72) contrast(1.18) brightness(0.54);
}

.contact-tv__screen::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(rgba(255,255,255,0.08) 50%, rgba(0,0,0,0.28) 50%),
    radial-gradient(circle at 47% 38%, transparent 46%, rgba(0,0,0,0.58));
  background-size: 100% 4px, auto;
  opacity: 0.62;
  mix-blend-mode: screen;
}

.contact-tv__links {
  position: relative;
  z-index: 9;
  width: min(1040px, 78vw);
  padding: 14px 0;
  border-top: 1px solid rgba(247, 247, 243, 0.34);
  border-bottom: 1px solid rgba(247, 247, 243, 0.34);
  flex-wrap: wrap;
  justify-content: space-between;
}

.contact-links span,
.contact a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: rgba(247, 247, 243, 0.72);
}

.contact a::before { content: "+"; }

.contact a {
  border-bottom: 1px solid rgba(247, 247, 243, 0.28);
}

.contact a:hover,
.contact a:focus-visible {
  color: var(--paper);
  outline: 0;
}

.page-transition {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: grid;
  place-items: center;
  background: #050505;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 120ms steps(1, end), visibility 120ms steps(1, end);
}

.page-transition.is-active {
  opacity: 1;
  visibility: visible;
}

.page-transition video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Main-page readability pass: keep labels light, let prose read normally. */
.topbar nav a,
.positioning > span,
.work-list,
.project-preview figcaption,
.project-note span,
.project-note h3,
.project-note a,
.method-card,
.method-card summary,
.method-card p,
.writing-table,
.contact-links {
  text-transform: none;
}

.topbar nav {
  font-size: 14px;
}

.television {
  width: min(480px, 64vw);
}

.positioning p {
  font-size: clamp(26px, 3.3vw, 48px);
  line-height: 1.03;
  text-transform: uppercase;
}

.work-list a {
  min-height: 54px;
  font-size: clamp(17px, 1.65vw, 28px);
}

.work-list span,
.project-note span,
.time-range,
.contact-links {
  font-size: 13px;
  letter-spacing: 0.02em;
}

.project-note h3,
.method-card strong,
.writing-table strong {
  font-size: clamp(20px, 1.65vw, 28px);
  line-height: 1.08;
}

.method-card p,
.writing-table em,
.project-note p,
.skill-copy,
.about-current,
.about-beside {
  font-size: clamp(15px, 1.08vw, 18px);
  line-height: 1.35;
}

.skill-copy {
  text-transform: none;
}

.project-note {
  margin-top: -150px;
}

.contact-tv {
  min-height: 100vh;
  padding: 0 clamp(24px, 4vw, 64px) clamp(24px, 4vw, 52px);
}

.contact-tv__set {
  left: 50%;
  bottom: max(-180px, -11vw);
  width: max(100vw, calc(100vh * 1.896));
  min-width: 100vw;
  transform: translateX(-50%);
}

.contact-tv__frame {
  object-position: center;
}

.contact-tv__links {
  width: min(1180px, 88vw);
  margin-inline: auto;
  text-transform: none;
}

@media (max-width: 1120px) {
  .topbar { grid-template-columns: auto 1fr; gap: 18px; }
  .topbar nav { justify-self: end; }
  .television {
    width: min(480px, 78vw);
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .television figcaption {
    justify-self: end;
    margin: -20px -44px 0 0;
  }
  .work-stage {
    grid-template-columns: minmax(240px, 330px) minmax(360px, 1fr);
  }
  .project-note {
    grid-column: 2;
    margin-top: -120px;
  }
  .time-range { position: static; margin: -52px 0 48px; }
  .writing-dark__intro { grid-template-columns: 1fr; }
  .contact-tv__set {
    left: 50%;
    bottom: max(-150px, -10vw);
    width: max(112vw, calc(100vh * 1.896));
    transform: translateX(-50%);
  }
  .contact-tv__links {
    width: min(760px, 78vw);
    gap: 10px 14px;
  }
}

@media (max-width: 760px) {
  .topbar {
    position: static;
    grid-template-columns: 1fr;
    justify-items: start;
    padding-block: 18px;
  }
  .topbar nav { order: 0; justify-self: start; flex-wrap: wrap; }
  .hero { min-height: auto; padding-top: 54px; }
  .hero h1 { font-size: clamp(70px, 22vw, 118px); }
  .hero__dial { position: static; margin-top: 28px; }
  .television { width: min(100%, 560px); }
  .television figcaption {
    max-width: min(300px, 100%);
    margin: 8px 0 0;
  }
  .work-stage,
  .about__grid {
    grid-template-columns: 1fr;
  }
  .project-preview,
  .project-note {
    grid-column: auto;
    margin-top: 0;
  }
  .work-list a { grid-template-columns: 48px 1fr; }
  .work-list em { display: none; }
  .methodology__title { position: relative; top: auto; height: auto; }
  .methodology__claim p { width: 100%; }
  .method-card { position: relative; top: auto; }
  .method-stack { gap: 28px; padding-bottom: 0; }
  .writing-years { position: static; justify-self: end; }
  .writing-placeholder { width: 100%; height: 72px; }
  .writing-table a { grid-template-columns: 58px 1fr; }
  .writing-table em { grid-column: 2; }
  .writing-popover { display: none; }
  .contact {
    min-height: 86vh;
    padding-inline: 22px;
  }
  .contact-tv__set {
    left: 50%;
    bottom: 56px;
    width: max(188vw, calc(100vh * 1.896));
    transform: translateX(-50%);
  }
  .contact-tv__links {
    width: 100%;
    flex-wrap: wrap;
    justify-content: flex-start;
  }
  .tree-card__open {
    width: min(560px, 94vw);
    height: min(560px, 82vh);
    min-height: 0;
  }
  .tree-card__tree {
    right: 4%;
    top: 8%;
    width: 38%;
  }
  .tree-card__hint {
    right: 4%;
    top: 62%;
    width: 38%;
    font-size: 17px;
  }
  .tree-card__content {
    right: 6%;
    top: 22%;
    width: min(178px, 36vw);
    height: 168px;
  }
  .tree-card__content li {
    font-size: 11px;
  }
}

/* 2026-08-22 opening/about/method/contact motion pass */
body.tree-card-open::before {
  background: rgba(247, 247, 243, 0.86);
  backdrop-filter: blur(42px) saturate(0.9);
  -webkit-backdrop-filter: blur(42px) saturate(0.9);
}

.television figcaption {
  right: clamp(-330px, -19vw, -140px);
  top: 72%;
  max-width: min(430px, 30vw);
  margin: 0;
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(18px, 1.45vw, 26px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
}

.hero__dial {
  left: clamp(220px, 23vw, 470px);
  bottom: clamp(130px, 16vh, 190px);
  grid-template-columns: 24px repeat(4, auto);
  gap: 16px;
  font-size: clamp(20px, 1.6vw, 27px);
  font-weight: 700;
}

.hero__dial img {
  width: 24px;
  height: 24px;
}

.television figcaption {
  top: 76%;
  right: clamp(-460px, -26vw, -300px);
  max-width: clamp(320px, 25vw, 470px);
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(22px, 1.9vw, 32px);
  font-weight: 700;
  line-height: 1.08;
  text-transform: none;
}

.methodology__claim {
  align-content: center;
  padding-bottom: 0;
  transform: translateY(-22vh);
}

.methodology.is-pinned .methodology__claim {
  padding-bottom: 0;
  transform: translateY(-22vh);
}

.method-stack {
  padding-top: 132vh;
}

.about-current {
  font-size: 20px;
}

.about-beside {
  font-size: 19px;
}

.tree-card__open {
  background: transparent;
  box-shadow: none;
  isolation: isolate;
}

.tree-card__open::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: transparent;
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  -webkit-mask-image: radial-gradient(circle at 77% 39%, #000 0 38%, transparent 70%);
  mask-image: radial-gradient(circle at 77% 39%, #000 0 38%, transparent 70%);
}

.tree-card__tree {
  top: 6%;
  right: 8.5%;
  width: 34%;
  height: 70%;
  cursor: pointer;
}

.tree-card__tree-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 560ms ease, transform 560ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.tree-card__tree-img--closed,
.tree-card__tree-img--open {
  transform: translateY(-8%) scale(0.98);
}

.tree-card__open.is-tree-open .tree-card__tree-img--open {
  opacity: 1;
  transform: translateY(-8%) scale(1);
}

.tree-card__open.is-tree-open .tree-card__tree-img--closed {
  opacity: 0;
  transform: translateY(-8%) scale(1.02);
}

.tree-card__hint {
  top: auto;
  bottom: 34%;
  right: 25.5%;
  left: auto;
  width: max-content;
  opacity: 0;
  pointer-events: none;
  transform: translate(50%, 6px);
  padding: 6px 11px;
  border: 1px solid rgba(48, 48, 48, 0.4);
  border-radius: 3px;
  background: rgba(247, 247, 243, 0.92);
  color: rgba(48, 48, 48, 0.85);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.tree-card__tree:hover + .tree-card__hint,
.tree-card__tree:focus-visible + .tree-card__hint {
  opacity: 1;
  transform: translateY(0);
}

.tree-card__open.is-tree-open .tree-card__hint {
  opacity: 0;
  transform: translateY(10px);
}

.tree-card__content {
  top: 21%;
  right: 11.2%;
  width: min(360px, 29%);
  height: clamp(136px, 18vh, 154px);
  padding: 0;
  overflow-y: auto;
  overflow-x: hidden;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  scrollbar-width: none;
  mask-image: linear-gradient(to bottom, transparent 0, #000 12%, #000 86%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 12%, #000 86%, transparent 100%);
}

.tree-card__content::-webkit-scrollbar {
  display: none;
}

.tree-card__copy {
  min-height: 190%;
  padding: 16px 0 150px;
}

.tree-card__content p {
  width: min(286.53px, calc(100% - 44px));
  margin: 0 0 30px 44px;
  color: rgba(24, 24, 24, 0.96);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 300;
  line-height: 1.32;
}

.tree-card__content p:last-child {
  margin-bottom: 90px;
}

.contact-tv__screen::after {
  animation: contactScan 5.6s linear infinite;
  opacity: 0.78;
}

@keyframes contactScan {
  0% { background-position: 0 0, 0 0; }
  100% { background-position: 0 24px, 0 0; }
}

@media (max-width: 760px) {
  .television figcaption {
    position: static;
    max-width: min(360px, 100%);
    margin: 14px auto 0;
    font-size: 18px;
    text-align: center;
  }

  .hero__dial {
    position: static;
    margin: 24px auto 0;
    font-size: 17px;
  }

  .television figcaption {
    position: static;
    max-width: min(360px, 100%);
    margin: 14px auto 0;
    font-size: 18px;
    text-align: center;
  }

  .methodology__claim,
  .methodology.is-pinned .methodology__claim {
    transform: translateY(-8vh);
  }

  .method-stack {
    padding-top: 78vh;
  }

  .about-current {
    font-size: 18px;
  }

  .about-beside {
    font-size: 17px;
  }

  .tree-card__tree {
    top: 2%;
    right: 50%;
    width: min(260px, 62vw);
    height: 42%;
    transform: translateX(50%);
  }

  .tree-card__hint {
    top: 42%;
    right: 50%;
    width: min(300px, 72vw);
    transform: translate(50%, 8px);
  }

  .tree-card__tree:hover + .tree-card__hint,
  .tree-card__tree:focus-visible + .tree-card__hint {
    transform: translate(50%, 0);
  }

  .tree-card__content {
    top: 41%;
    right: 50%;
    width: min(360px, 74vw);
    height: clamp(136px, 24vh, 154px);
    transform: translate(50%, 10px);
  }

  .tree-card__open.is-tree-open .tree-card__content {
    transform: translate(50%, 0);
  }

  .tree-card__content p {
    width: min(286.53px, calc(100% - 44px));
    margin: 0 0 30px 44px;
    font-size: 14px;
    font-weight: 300;
  }

  .contact-tv__set {
    bottom: -8vh;
    width: 230vw;
  }
}

/* ===========================================================================
   Home polish, 2026-08-23
   =========================================================================== */

/* --- Hero: caption and dial read as one quiet annotation layer -------------
   Both were set at display weight, which put them in competition with the
   name and the television. They are notes, so they are sized and weighted
   like notes, and identically to each other. */
.television figcaption {
  top: 74%;
  right: clamp(-330px, -19vw, -168px);
  max-width: clamp(230px, 18.5vw, 316px);
  margin: 0;
  color: rgba(48, 48, 48, 0.8);
  font-family: var(--sans);
  font-size: clamp(15px, 1.12vw, 19px);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.005em;
  text-transform: none;
}

.hero__dial {
  left: clamp(200px, 21vw, 430px);
  bottom: clamp(120px, 15vh, 178px);
  grid-template-columns: 17px repeat(4, auto);
  gap: 13px;
  color: rgba(48, 48, 48, 0.8);
  font-family: var(--sans);
  font-size: clamp(15px, 1.12vw, 19px);
  font-weight: 400;
  letter-spacing: 0.005em;
}

.hero__dial img {
  width: 17px;
  height: 17px;
  opacity: 0.7;
}

/* --- Hero entrance --------------------------------------------------------
   The set arrives rather than being already there: the cabinet lifts in, the
   screen wakes a beat later, then the caption and the dial settle. Nothing
   moves until the opening gate is out of the way, so the animation is not
   spent behind the opening video. */
.television {
  opacity: 0;
  transform: translateY(38px) scale(0.955);
  transition:
    opacity 900ms cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 1150ms cubic-bezier(0.18, 0.86, 0.22, 1);
}

.television__screenContent {
  opacity: 0;
  transform: scale(1.04);
  transition:
    opacity 620ms ease 420ms,
    transform 900ms cubic-bezier(0.2, 0.8, 0.2, 1) 420ms;
}

.television figcaption,
.hero__dial {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 700ms ease 760ms,
    transform 780ms cubic-bezier(0.2, 0.8, 0.2, 1) 760ms;
}

body.hero-ready .television {
  opacity: 1;
  transform: none;
}

body.hero-ready .television__screenContent {
  opacity: 1;
  transform: none;
}

body.hero-ready .television figcaption,
body.hero-ready .hero__dial {
  opacity: 1;
  transform: none;
}

/* The screen wakes with one signal snap, so the reel reads as a set switching
   on rather than an image that faded up. */
body.hero-ready .surface-reel::before {
  animation: heroSignalWake 620ms ease-out 420ms 1;
}

@keyframes heroSignalWake {
  0% { opacity: 0.85; }
  40% { opacity: 0.25; }
  62% { opacity: 0.7; }
  100% { opacity: 0; }
}

/* --- Methodology claim ----------------------------------------------------
   The claim used to be pulled up by a viewport-relative offset, which on a
   short window landed it straight on top of the word METHODOLOGY. It now sits
   against the bottom of the pinned frame with the title's height reserved
   above it, so the two can never collide at any window height. */
.methodology__claim,
.methodology.is-pinned .methodology__claim {
  align-content: end;
  padding-top: clamp(150px, 22vh, 280px);
  padding-bottom: clamp(56px, 11vh, 132px);
  transform: none;
}

.methodology__claim p {
  color: rgba(48, 48, 48, 0.5);
}

.methodology__claim p + p {
  color: rgba(48, 48, 48, 0.42);
}

/* --- The other introduction ----------------------------------------------
   The prompt used to snap in only while the tree was hovered, which meant a
   reader who never happened to pass over it never learned the tree opened at
   all. It is now quietly present from the moment the card appears, breathing
   on a slow cycle, and it firms up as soon as the pointer is anywhere near. */
.tree-card__hint {
  opacity: 0.62;
  transform: translate(50%, 0);
  transition:
    opacity 620ms cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 620ms cubic-bezier(0.2, 0.8, 0.2, 1),
    border-color 420ms ease,
    background 420ms ease;
  animation: treePromptBreathe 4.2s ease-in-out infinite;
}

.tree-card__tree:hover + .tree-card__hint,
.tree-card__tree:focus-visible + .tree-card__hint,
.tree-card__open:hover .tree-card__hint {
  opacity: 1;
  transform: translate(50%, -2px);
  border-color: rgba(48, 48, 48, 0.7);
  background: var(--paper);
  animation: none;
}

.tree-card__open.is-tree-open .tree-card__hint {
  opacity: 0;
  transform: translate(50%, 10px);
  animation: none;
}

/* The tree itself carries the same invitation, so the affordance is on the
   thing you actually click and not only on the label beside it. */
.tree-card__tree {
  animation: treeBreathe 4.2s ease-in-out infinite;
  transition: filter 420ms ease;
}

.tree-card__tree:hover,
.tree-card__tree:focus-visible {
  animation: none;
  filter: drop-shadow(0 10px 26px rgba(72, 151, 210, 0.28));
  outline: none;
}

.tree-card__open.is-tree-open .tree-card__tree {
  animation: none;
}

@keyframes treePromptBreathe {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.86; }
}

@keyframes treeBreathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.018); }
}

/* A named way out, because the card covers the page and the only previous
   exits were Escape and a guess at the backdrop. Same button as everywhere
   else on the site: a plain border that fills solid on hover. */
.tree-card__close {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 12;
  display: inline-flex;
  align-items: center;
  width: max-content;
  min-height: 30px;
  padding: 0 11px;
  border: 1px solid rgba(48, 48, 48, 0.4);
  border-radius: 3px;
  background: rgba(247, 247, 243, 0.92);
  color: rgba(48, 48, 48, 0.85);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 420ms ease 380ms, transform 420ms cubic-bezier(0.2, 0.8, 0.2, 1) 380ms, background 160ms ease, color 160ms ease, border-color 160ms ease;
}

.tree-card__open:not([hidden]) .tree-card__close {
  opacity: 1;
  transform: translateY(0);
}

.tree-card__close:hover,
.tree-card__close:focus-visible {
  background: var(--paper);
  color: var(--ink);
  border-color: rgba(48, 48, 48, 0.7);
  outline: none;
}

/* --- Skills into contact --------------------------------------------------
   The dark section used to travel up over the skills on a negative margin,
   rounded corners and its own drop shadow, at the same time as the newer
   perspective-driven television reveal below was trying to run. The two
   never agreed with each other: the negative margin alone was crowding the
   join, and running both at once was the bad transition. One system now
   owns this handoff (see "Closing television, scroll-linked" further down);
   this block only adds the breathing room the crowded version was missing. */
.skill-section {
  position: relative;
  z-index: 1;
  padding-bottom: clamp(140px, 20vh, 240px);
}

.contact {
  position: relative;
  z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
  .television,
  .television__screenContent,
  .television figcaption,
  .hero__dial {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .tree-card__hint,
  .tree-card__hint::after,
  .tree-card__tree {
    animation: none;
  }

  .tree-card__hint { opacity: 0.9; }
}

@media (max-width: 760px) {
  .television figcaption {
    font-size: 15px;
    font-weight: 400;
  }

  .hero__dial {
    font-size: 15px;
    font-weight: 400;
    grid-template-columns: 16px repeat(4, auto);
    gap: 11px;
  }

  .tree-card__close {
    top: 1%;
    padding: 7px 13px;
    font-size: 11px;
  }

  .skill-section {
    padding-bottom: clamp(90px, 14vh, 150px);
  }
}

/* A short window is where the claim and the title used to collide, so the
   pair is re-proportioned rather than left to overlap. */
@media (max-height: 640px) {
  .methodology__title h2 {
    font-size: clamp(54px, 6.6vw, 112px);
  }

  .methodology__claim,
  .methodology.is-pinned .methodology__claim {
    padding-top: clamp(118px, 30vh, 196px);
    padding-bottom: clamp(26px, 6.5vh, 54px);
  }

  .methodology__claim p {
    font-size: clamp(15px, 1.55vw, 24px);
  }

  .methodology__claim p + p {
    font-size: clamp(11px, 0.95vw, 15px);
  }
}

/* The trailing run-off was long enough that the closing line scrolled back out
   of the frame before the copy reached its end, so the piece finished on empty
   space. Trimmed so the last line can come to rest in view. */
.tree-card__copy {
  padding-bottom: 44px;
}

.tree-card__content p:last-child {
  margin-bottom: 12px;
}

/* ---------------------------------------------------------------------------
   Closing television, scroll-linked
   The section was one and a half screens tall with the set parked at the very
   bottom, so most of it was empty black before anything happened. It is now
   just over a screen, and the set is staged across that screen: tilted back,
   small and dim at the top of the section, upright, forward and lit by the
   time it settles. Every value comes from --tv-* written by contact-stage.js.
--------------------------------------------------------------------------- */
.contact {
  min-height: 94vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(28px, 4.5vh, 52px);
  padding: clamp(30px, 5vw, 76px) clamp(28px, 4.6vw, 94px);
  perspective: 1500px;
  perspective-origin: 50% 60%;
  /* A soft paper-to-transparent band used to sit across the top here, meant
     to ease the join with the section above. It read as an unexplained line
     instead, so the section now just starts black. */
  background: var(--grain), #080808;
  background-size: 160px 160px, auto;
  background-blend-mode: overlay, normal;
  transform: none;
}

.contact-tv__set {
  position: relative;
  left: auto;
  bottom: auto;
  /* Wider, so the set fills more of the section: at the old size the TV was
     short enough that the section's own black ground showed as a plain bar
     above and below it, with nothing happening in either. */
  width: min(1200px, 86vw);
  transform-origin: 50% 100%;
  transform:
    translateY(var(--tv-y, 60px))
    rotateX(var(--tv-rot, 34deg))
    scale(var(--tv-scale, 0.8));
  opacity: var(--tv-opacity, 0.3);
  filter: saturate(0.92) contrast(1.12) brightness(var(--tv-bright, 0.5));
  transition: none;
}

/* The links used to trail below the whole cabinet, in the page's own
   background, landing as a second, disconnected block once the television
   was no longer big enough to sit behind it by accident. They now live on
   the set itself, low on the screen, the way a lower third sits on a CRT. */
/* Centred at 50% of the whole cabinet, the links sat off-centre from the
   actual screen: the wood speaker grille takes up the right third of the
   image, so the screen's own centre is at 34.2%, not 50%, and the wider
   50%-centred band was spilling past the screen's right edge onto the
   grille. Centred and sized to the screen's own bounds instead. */
.contact-tv__links {
  position: absolute;
  left: 34.2%;
  bottom: 6%;
  z-index: 9;
  width: 58%;
  padding: 10px 14px;
  border-radius: 3px;
  background: rgba(3, 3, 3, 0.5);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: var(--tv-progress, 0);
  transform: translate(-50%, calc((1 - var(--tv-progress, 0)) * 16px));
  transition: none;
}

.contact.is-in-view .contact-tv__links {
  opacity: var(--tv-progress, 1);
}

/* The skills page gives up the stage on the same progress value. */
.skill-section {
  opacity: calc(1 - var(--recede, 0) * 0.56);
  transform: translateY(calc(var(--recede, 0) * -20px));
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .contact-tv__set {
    transform: none;
    opacity: 1;
    filter: saturate(0.92) contrast(1.12) brightness(0.9);
  }

  .contact-tv__links {
    opacity: 1;
    transform: none;
  }

  .skill-section {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 760px) {
  .contact {
    min-height: 86vh;
    perspective: 900px;
    gap: 24px;
  }

  .contact-tv__set {
    width: min(94vw, 480px);
  }

  .contact-tv__links {
    bottom: 8%;
    width: 60%;
    padding: 8px 10px;
  }
}

/* ---------------------------------------------------------------------------
   Writing section entrance
   The dark section used to just be there once scrolled to, no arrival of its
   own. The heading and each writing entry now fade up in place as the
   section is reached, the same "SERVICES" appear used on
   eric-cole.framer.website: opacity and a short lift, staggered row by row.
--------------------------------------------------------------------------- */
.writing-dark__intro,
.writing-table a {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 640ms cubic-bezier(0.2, 0.8, 0.2, 1) var(--reveal-delay, 0ms),
    transform 640ms cubic-bezier(0.2, 0.8, 0.2, 1) var(--reveal-delay, 0ms);
}

.writing-dark__intro.is-revealed,
.writing-table a.is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .writing-dark__intro,
  .writing-table a {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
   Scroll Text Highlight, after Originkit
   Each word starts dim and lights up word by word as its paragraph scrolls
   through the centre of the screen, scrubbed directly to scroll position.
   The colour itself is set inline per word by initScrollHighlight(); this
   just makes the words inline-block so each can carry its own colour without
   breaking the line.
--------------------------------------------------------------------------- */
.reveal-word {
  display: inline-block;
  color: rgb(150, 150, 150);
}

/* ---------------------------------------------------------------------------
   Text Gather, after Originkit
   Every character starts scattered, dim, and slightly rotated (values set
   inline per character by initTextGather()) and gathers into place once,
   the first time its heading scrolls into view.
--------------------------------------------------------------------------- */
/* Each word is its own unbreakable box so the line can only wrap at a real
   space between words, never between two letters of the same word - which
   is what plain adjacent .gather-char boxes allow by default. */
.gather-word {
  display: inline-block;
  white-space: nowrap;
}

.gather-char {
  display: inline-block;
  opacity: 0.28;
  transform: translate(var(--gx, 0px), var(--gy, 0px)) rotate(var(--gr, 0deg));
  transition:
    transform 850ms cubic-bezier(0.16, 0.84, 0.2, 1),
    opacity 850ms cubic-bezier(0.16, 0.84, 0.2, 1);
}

.gather-char.is-gathered {
  opacity: 1;
  transform: translate(0, 0) rotate(0deg);
}

@media (prefers-reduced-motion: reduce) {
  .reveal-word {
    color: rgb(10, 10, 10);
  }

  .gather-char {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .skill-lead,
  .skill-copy p,
  .skill-strips button {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
   Mobile recruiter layout, 2026-09-01
   Phones get a different reading order: identity, fit, proof, contact. The
   animated portfolio atmosphere stays, but desktop staging stops controlling
   small-screen spacing.
--------------------------------------------------------------------------- */
.mobile-recruiter {
  display: none;
}

.contact-mobile-actions {
  display: none;
}

@media (max-width: 760px) {
  body {
    background:
      linear-gradient(90deg, rgba(0, 0, 0, 0.022) 1px, transparent 1px),
      radial-gradient(circle at 26% 8%, rgba(78, 126, 167, 0.12), transparent 34%),
      var(--paper);
    background-size: 7px 100%, auto, auto;
  }

  body::after {
    opacity: 0.075;
  }

  .opening-gate video {
    object-position: 50% 50%;
  }

  .topbar {
    position: sticky;
    top: 0;
    display: flex;
    justify-content: space-between;
    grid-template-columns: none;
    gap: 14px;
    min-height: 58px;
    padding: 10px 16px;
  }

  .brand {
    width: 34px;
    height: 34px;
  }

  .brand-mark {
    width: 30px;
    height: 30px;
  }

  .topbar nav {
    display: none;
  }

  .hero {
    min-height: auto;
    align-content: start;
    padding: 30px 18px 20px;
    overflow: hidden;
  }

  .hero h1 {
    width: 100%;
    font-size: clamp(66px, 25vw, 108px);
    line-height: 0.75;
  }

  .hero h1 .script {
    margin-left: 0.54em;
  }

  .television {
    width: min(92vw, 390px);
    margin-top: 22px;
    opacity: 1;
    transform: none;
  }

  .television__asset {
    transform: scale(0.92);
  }

  .television figcaption {
    position: static;
    max-width: 280px;
    margin: 8px auto 0;
    color: rgba(48, 48, 48, 0.72);
    font-size: 15px;
    line-height: 1.28;
    text-align: center;
  }

  .hero__dial {
    position: static;
    grid-template-columns: 16px repeat(4, auto);
    justify-content: center;
    gap: 10px;
    margin: 16px auto 0;
    color: rgba(48, 48, 48, 0.66);
    font-size: 14px;
  }

  .hero__dial img {
    width: 16px;
    height: 16px;
  }

  .mobile-recruiter {
    display: grid;
    gap: 14px;
    padding: 26px 18px 34px;
    border-top: 1px solid rgba(48, 48, 48, 0.16);
    border-bottom: 1px solid rgba(48, 48, 48, 0.16);
    background:
      linear-gradient(180deg, rgba(247, 247, 243, 0.86), rgba(239, 238, 232, 0.94)),
      var(--paper-2);
  }

  .mobile-recruiter__eyebrow,
  .mobile-recruiter__tags,
  .mobile-recruiter__actions {
    font-family: var(--mono);
  }

  .mobile-recruiter__eyebrow {
    margin: 0;
    color: var(--blue);
    font-size: 12px;
    letter-spacing: 0.02em;
  }

  .mobile-recruiter h2 {
    max-width: 11.5ch;
    margin: 0;
    font-family: var(--display);
    font-size: clamp(39px, 12.2vw, 54px);
    font-weight: 600;
    line-height: 0.9;
    text-transform: uppercase;
  }

  .mobile-recruiter p:not(.mobile-recruiter__eyebrow) {
    width: 100%;
    max-width: min(34ch, calc(100vw - 36px));
    min-width: 0;
    margin: 0;
    color: rgba(48, 48, 48, 0.76);
    font-size: 16px;
    line-height: 1.42;
    overflow-wrap: anywhere;
  }

  .mobile-recruiter__tags,
  .mobile-recruiter__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  .mobile-recruiter__tags span {
    padding: 7px 9px;
    border: 1px solid rgba(48, 48, 48, 0.22);
    border-radius: 3px;
    background: rgba(247, 247, 243, 0.58);
    font-size: 12px;
  }

  .mobile-recruiter__actions a {
    min-height: 42px;
    display: inline-flex;
    align-items: center;
    padding: 0 12px;
    border: 1px solid rgba(48, 48, 48, 0.36);
    border-radius: 3px;
    background: rgba(48, 48, 48, 0.92);
    color: var(--paper);
    font-size: 13px;
  }

  .positioning {
    min-height: auto;
    gap: 22px;
    padding: 58px 18px 64px;
  }

  .positioning p {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    font-size: clamp(28px, 10vw, 43px);
    line-height: 1;
    overflow-wrap: anywhere;
    word-break: normal;
  }

  .positioning .reveal-word,
  .about .reveal-word {
    max-width: 100%;
    white-space: normal;
  }

  .positioning span {
    font-size: 12px;
    line-height: 1.35;
  }

  .work-section {
    min-height: auto;
    padding: 48px 18px 68px;
    scroll-margin-top: 68px;
  }

  .section-title--work {
    justify-items: start;
    margin-bottom: 12px;
  }

  .section-title h2,
  .methodology__title h2,
  .writing-dark h2,
  .about h2 {
    font-size: clamp(54px, 18vw, 86px);
    line-height: 0.86;
  }

  .time-range {
    margin: 0 0 22px;
  }

  .work-stage {
    display: grid;
    grid-template-columns: 1fr;
    gap: 22px;
  }

  .project-preview {
    order: 1;
    grid-column: auto;
  }

  .project-preview__media {
    min-height: 210px;
    align-items: center;
    border-top: 1px solid rgba(48, 48, 48, 0.18);
    border-bottom: 1px solid rgba(48, 48, 48, 0.18);
  }

  .project-preview__media img,
  .project-preview__media video {
    max-height: 230px;
  }

  .project-preview figcaption {
    font-size: 11px;
  }

  .work-list {
    order: 2;
    gap: 10px;
  }

  .work-list a {
    grid-template-columns: 38px minmax(0, 1fr);
    gap: 10px;
    min-height: auto;
    padding: 13px 0 14px;
    border-top: 1px solid rgba(48, 48, 48, 0.18);
    border-bottom: 0;
    color: var(--ink);
  }

  .work-list a:last-child {
    border-bottom: 1px solid rgba(48, 48, 48, 0.18);
  }

  .work-list a:hover,
  .work-list a:focus-visible,
  .work-list a.is-active {
    padding-left: 0;
  }

  .work-list span {
    padding-top: 3px;
    color: var(--blue);
    font-size: 12px;
  }

  .work-list strong {
    font-size: clamp(20px, 6vw, 27px);
    font-weight: 600;
    line-height: 1.02;
  }

  .work-list em {
    display: block;
    grid-column: 2;
    color: rgba(48, 48, 48, 0.56);
    font-family: var(--sans);
    font-size: 13px;
    font-style: normal;
    line-height: 1.3;
  }

  .work-list a::after {
    content: attr(data-copy);
    grid-column: 2;
    color: rgba(48, 48, 48, 0.66);
    font-family: var(--sans);
    font-size: 14px;
    line-height: 1.35;
    text-transform: none;
  }

  .project-note {
    display: none;
  }

  .methodology {
    min-height: auto;
    padding: 58px 18px 76px;
    scroll-margin-top: 68px;
  }

  .methodology__title,
  .methodology.is-pinned .methodology__title,
  .methodology__claim,
  .methodology.is-pinned .methodology__claim {
    position: relative !important;
    left: auto;
    right: auto;
    top: auto;
    min-height: 0;
    height: auto;
    padding: 0;
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }

  .methodology__title {
    margin-bottom: 24px;
  }

  .methodology__title h2 {
    flex-wrap: wrap;
  }

  .methodology__claim {
    justify-items: start;
    align-content: start;
    gap: 14px;
    margin-bottom: 28px;
  }

  .methodology__claim p {
    width: 100%;
    font-size: clamp(20px, 7vw, 32px);
    line-height: 1.02;
    text-align: left;
  }

  .methodology__claim p + p {
    font-size: 14px;
    line-height: 1.34;
  }

  .method-stack {
    width: 100%;
    gap: 14px;
    padding: 0;
    margin: 0;
  }

  .method-card {
    position: relative;
    top: auto;
    aspect-ratio: auto;
    min-height: 0;
    padding: 18px;
    transform: none !important;
  }

  .method-card::before {
    margin: -18px -18px 16px;
  }

  .method-card summary {
    gap: 12px;
  }

  .method-card strong,
  .moves-card__head strong,
  .permits-card > strong {
    font-size: 18px;
  }

  .method-card p,
  .permits-card li {
    font-size: 14px;
    line-height: 1.36;
  }

  .moves {
    gap: 7px;
  }

  .moves button {
    min-height: 44px;
  }

  .writing-dark {
    min-height: auto;
    gap: 32px;
    padding: 58px 18px 70px;
    scroll-margin-top: 68px;
  }

  .writing-placeholder {
    display: none;
  }

  .writing-dark__intro {
    gap: 18px;
  }

  .writing-dark__intro p {
    justify-self: start;
    font-size: 16px;
    line-height: 1.28;
  }

  .writing-table a {
    grid-template-columns: 42px minmax(0, 1fr);
    gap: 10px;
    padding: 14px 0;
  }

  .writing-table strong {
    font-size: 17px;
    line-height: 1.16;
  }

  .writing-table em {
    grid-column: 2;
    font-size: 13px;
    line-height: 1.32;
  }

  .about {
    min-height: auto;
    padding: 58px 18px 70px;
    scroll-margin-top: 68px;
  }

  .about h2 {
    margin-bottom: 28px;
  }

  .about__grid {
    gap: 24px;
  }

  .about__portrait {
    justify-items: start;
  }

  .about__portrait img {
    width: min(250px, 72vw);
  }

  .about-current,
  .about-beside {
    font-size: 16px;
    line-height: 1.35;
  }

  .aside-trigger {
    filter: blur(6px);
  }

  .tree-card__open {
    width: min(94vw, 420px);
    height: min(78vh, 540px);
  }

  .tree-card__close {
    z-index: 12;
  }

  .tree-card__dogwood,
  .tree-card__feather {
    opacity: 0.58;
  }

  .tree-card__tree {
    top: 3%;
    right: 50%;
    width: min(250px, 60vw);
    height: 40%;
    transform: translateX(50%);
  }

  .tree-card__hint {
    top: 39%;
    right: 50%;
    bottom: auto;
    width: max-content;
    transform: translate(50%, 8px);
  }

  .tree-card__tree:hover + .tree-card__hint,
  .tree-card__tree:focus-visible + .tree-card__hint {
    transform: translate(50%, 0);
  }

  .tree-card__content {
    top: 42%;
    right: 50%;
    width: min(330px, 76vw);
    height: clamp(146px, 25vh, 190px);
    transform: translate(50%, 8px);
  }

  .tree-card__content p {
    width: calc(100% - 28px);
    margin: 0 0 22px 14px;
    font-size: 14px;
  }

  .skill-section {
    min-height: auto;
    padding: 58px 18px 76px;
    opacity: 1;
    transform: none;
  }

  .skill-lead {
    font-size: clamp(42px, 14vw, 64px);
    line-height: 0.9;
  }

  .skill-copy {
    width: 100%;
    gap: 16px;
  }

  .skill-copy p {
    font-size: 15px;
    line-height: 1.42;
  }

  .skill-strips {
    width: 100%;
    gap: 8px;
  }

  .skill-strips button {
    min-height: 46px;
    padding: 11px 12px;
  }

  .tag-label {
    font-size: 13px;
    line-height: 1.2;
  }

  .tag-note {
    font-size: 13px;
    line-height: 1.34;
  }

  .contact {
    min-height: 72vh;
    gap: 18px;
    padding: 46px 14px 34px;
    overflow: hidden;
  }

  .contact-tv__set {
    width: min(118vw, 520px);
    max-width: none;
    transform:
      translateY(calc(var(--tv-y, 36px) * 0.42))
      rotateX(calc(var(--tv-rot, 22deg) * 0.5))
      scale(max(var(--tv-scale, 0.88), 0.9));
  }

  .contact-tv__links {
    left: 50%;
    right: auto;
    bottom: 5%;
    width: min(82vw, 320px);
    display: flex;
    justify-content: center;
    gap: 6px;
    padding: 8px;
    transform: translate(-50%, calc((1 - var(--tv-progress, 0)) * 12px));
  }

  .contact-links span,
  .contact-links a {
    font-size: 11px;
    line-height: 1.15;
  }

  .contact-links span {
    width: 100%;
    text-align: center;
  }
}

@media (max-width: 380px) {
  .topbar nav a {
    padding-inline: 7px;
    font-size: 11px;
  }

  .mobile-recruiter h2 {
    font-size: 40px;
  }

  .work-list strong {
    font-size: 19px;
  }

  .contact-tv__links {
    width: 86vw;
  }
}

/* Mobile finesse pass, 2026-09-03: more tactile, less oversized, less blue. */
@media (max-width: 760px) {
  body {
    background:
      linear-gradient(90deg, rgba(0, 0, 0, 0.022) 1px, transparent 1px),
      var(--paper);
    background-size: 7px 100%, auto;
  }

  .mobile-recruiter {
    background:
      linear-gradient(180deg, rgba(247, 247, 243, 0.94), rgba(239, 238, 232, 0.78)),
      var(--paper);
  }

  .mobile-recruiter__eyebrow,
  .work-list span {
    color: rgba(48, 48, 48, 0.58);
  }

  .mobile-recruiter__tags span {
    background: rgba(247, 247, 243, 0.52);
  }

  .project-preview__media {
    min-height: 168px;
    background: rgba(239, 238, 232, 0.42);
  }

  .project-preview__media img,
  .project-preview__media video {
    width: 100%;
    max-height: 180px;
    object-fit: cover;
    filter: grayscale(1) contrast(1.05) brightness(0.95);
  }

  .skill-section {
    display: block;
    padding: 42px 18px 52px;
  }

  .skill-lead {
    max-width: 9.5ch;
    margin: 0 0 20px;
    font-size: clamp(34px, 10.5vw, 46px);
    line-height: 0.94;
    text-align: left;
  }

  .skill-copy {
    width: 100%;
    gap: 12px;
    margin: 0 0 24px;
    text-align: left;
  }

  .skill-copy p {
    color: rgba(48, 48, 48, 0.76);
    font-size: 14px;
    line-height: 1.42;
  }

  .skill-strips {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    width: 100%;
    margin: 0;
  }

  .skill-strips button {
    width: 100%;
    min-height: 0;
    padding: 12px 12px;
    border-color: rgba(48, 48, 48, 0.42);
    background: rgba(247, 247, 243, 0.58);
    text-align: left;
    transform: none;
  }

  .skill-strips button:hover,
  .skill-strips button:focus-visible,
  .skill-strips button[aria-expanded="true"] {
    background: rgba(48, 48, 48, 0.92);
    color: var(--paper);
  }

  .skill-strips .tag-label {
    display: block;
    font-size: 12.5px;
    line-height: 1.2;
  }

  .skill-strips .tag-note {
    display: none;
    position: static;
    width: 100%;
    max-width: none;
    max-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    color: rgba(247, 247, 243, 0.76);
    font-size: 13px;
    line-height: 1.38;
    text-align: left;
    opacity: 1;
    overflow: hidden;
    visibility: visible;
    transform: none;
    transition: max-height 240ms ease, margin-top 240ms ease;
  }

  .skill-strips .tag-note::after {
    content: none;
  }

  .skill-strips button[aria-expanded="true"] .tag-note {
    display: block;
    max-height: none;
    margin-top: 10px;
  }

  .tool-chips {
    justify-content: flex-start;
    margin-top: 10px;
  }

  .tool-chips span {
    border-color: rgba(247, 247, 243, 0.22);
    color: rgba(247, 247, 243, 0.78);
  }

  .contact {
    min-height: auto;
    display: block;
    padding: 38px 18px 42px;
    background: var(--grain), #080808;
    background-size: 160px 160px, auto;
  }

  .contact-tv__set {
    width: min(100%, 430px);
    margin: 0 auto;
    transform:
      translateY(calc(var(--tv-y, 28px) * 0.24))
      rotateX(calc(var(--tv-rot, 18deg) * 0.32))
      scale(max(var(--tv-scale, 0.92), 0.94));
  }

  .contact-tv__screen {
    background:
      radial-gradient(circle at 50% 42%, rgba(247, 247, 243, 0.08), transparent 46%),
      url("web-assets/og-card.jpg") center / cover,
      #030303;
  }

  .contact-tv__screen video {
    opacity: 0.82;
    filter: saturate(0.66) contrast(1.16) brightness(0.62);
  }

  .contact-tv__screen::after {
    animation: contactScan 5.6s linear infinite;
  }

  .contact-tv__links {
    display: none;
  }

  .contact.is-in-view .contact-tv__links {
    opacity: 0;
  }

  .contact-mobile-actions {
    width: min(100%, 430px);
    margin: 18px auto 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    font-family: var(--mono);
  }

  .contact-mobile-actions span,
  .contact-mobile-actions a {
    min-height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;
    border: 1px solid rgba(247, 247, 243, 0.28);
    border-radius: 3px;
    background: rgba(247, 247, 243, 0.08);
    color: rgba(247, 247, 243, 0.78);
    font-size: 12px;
    line-height: 1.15;
    text-align: center;
    word-break: break-word;
  }

  .contact-mobile-actions span,
  .contact-mobile-actions a[href^="mailto"] {
    grid-column: 1 / -1;
  }

  .contact-mobile-actions a:active {
    background: rgba(247, 247, 243, 0.18);
    transform: translateY(1px);
  }

  .contact a::before {
    content: none;
  }
}

/* Mobile product pass, 2026-09-04: recruiter-first flow with tactile cards. */
.mobile-jump,
.mobile-project-toggle,
.skill-mobile-brief,
.mobile-project-media,
.mobile-project-meta {
  display: none;
}

@media (max-width: 760px) {
  html {
    scroll-padding-top: 64px;
  }

  html,
  body {
    max-width: 100%;
    overflow-x: clip;
  }

  body {
    background:
      linear-gradient(90deg, rgba(0, 0, 0, 0.022) 1px, transparent 1px),
      linear-gradient(180deg, #f8f8f4 0%, #efeee8 54%, #f8f8f4 100%);
    background-size: 7px 100%, auto;
  }

  .topbar {
    border-bottom: 1px solid rgba(48, 48, 48, 0.1);
    background: rgba(248, 248, 244, 0.82);
    backdrop-filter: blur(14px);
  }

  .hero {
    min-height: auto;
    padding: 26px 18px 12px;
  }

  .hero h1 {
    width: 100%;
    max-width: 100%;
    font-size: clamp(58px, 18.5vw, 78px);
    justify-items: center;
  }

  .hero h1 > span:first-child {
    transform: scaleX(0.92);
    transform-origin: center;
  }

  .television {
    width: min(82vw, 330px);
    margin-top: 14px;
  }

  .television figcaption {
    max-width: 24ch;
    margin-top: 4px;
    font-size: 15px;
  }

  .hero__dial {
    margin-top: 12px;
  }

  .mobile-recruiter {
    gap: 16px;
    padding: 24px 18px 22px;
    background: rgba(248, 248, 244, 0.9);
  }

  .mobile-recruiter > *,
  .work-section > *,
  .methodology > *,
  .skill-section > *,
  .contact > * {
    min-width: 0;
    max-width: 100%;
  }

  .mobile-recruiter__eyebrow {
    color: rgba(48, 48, 48, 0.56);
    font-size: 11px;
  }

  .mobile-recruiter h2 {
    max-width: 12ch;
    font-size: clamp(36px, 10.8vw, 48px);
  }

  .mobile-recruiter p:not(.mobile-recruiter__eyebrow) {
    max-width: 36ch;
    font-size: 15.5px;
    line-height: 1.45;
  }

  .mobile-recruiter__tags {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 7px;
    width: 100%;
    max-width: 354px;
    justify-self: center;
  }

  .mobile-recruiter__tags span {
    min-width: 0;
    padding: 6px 8px;
    color: rgba(48, 48, 48, 0.68);
    font-size: 11px;
    text-align: center;
    white-space: normal;
  }

  .mobile-recruiter__actions {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 7px;
    width: 100%;
    max-width: 354px;
    justify-self: center;
  }

  .mobile-recruiter__actions a {
    min-width: 0;
    justify-content: center;
    min-height: 40px;
    padding: 0 6px;
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .mobile-jump {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    width: 100%;
    max-width: 354px;
    max-width: 100%;
    justify-self: center;
    margin-top: 2px;
    overflow: hidden;
    border: 1px solid rgba(48, 48, 48, 0.28);
    border-radius: 4px;
    font-family: var(--mono);
  }

  .mobile-jump a {
    min-width: 0;
    min-height: 36px;
    display: grid;
    place-items: center;
    background: rgba(48, 48, 48, 0.92);
    color: var(--paper);
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .positioning {
    display: none;
  }

  .work-section {
    min-height: auto !important;
    padding: 34px 14px 36px;
  }

  .section-title--work {
    margin-bottom: 4px;
    padding-left: 6px;
  }

  .section-title h2,
  .methodology__title h2,
  .writing-dark h2,
  .about h2 {
    font-size: clamp(48px, 15vw, 72px);
    max-width: 100%;
    overflow-wrap: anywhere;
  }

  .time-range {
    margin-bottom: 16px;
    color: rgba(48, 48, 48, 0.52);
    font-size: 11px;
  }

  .work-stage {
    gap: 14px;
  }

  .project-preview {
    display: none;
  }

  .work-list {
    order: 1;
    gap: 10px;
    width: 100%;
    max-width: 362px;
    justify-self: center;
  }

  .work-list a {
    position: relative;
    grid-template-columns: 82px minmax(0, 1fr) auto;
    grid-template-rows: auto auto auto;
    column-gap: 12px;
    row-gap: 4px;
    min-height: 112px;
    padding: 10px;
    border: 1px solid rgba(48, 48, 48, 0.18);
    border-radius: 6px;
    background: rgba(248, 248, 244, 0.78);
    box-shadow: 0 10px 26px rgba(48, 48, 48, 0.055);
    transition: transform 180ms ease, background 180ms ease, border-color 180ms ease;
  }

  .work-list a:nth-of-type(n + 4) {
    display: none;
  }

  .work-section.is-expanded .work-list a:nth-of-type(n + 4) {
    display: grid;
  }

  .work-list a:hover,
  .work-list a:focus-visible,
  .work-list a.is-active {
    border-color: rgba(48, 48, 48, 0.34);
    background: rgba(255, 255, 252, 0.9);
    transform: translateY(-1px);
  }

  .work-list a:active {
    transform: translateY(1px);
  }

  .mobile-project-media {
    grid-row: 1 / -1;
    grid-column: 1;
    display: block;
    min-height: 92px;
    overflow: hidden;
    border: 1px solid rgba(48, 48, 48, 0.16);
    border-radius: 4px;
    background: #e8e6de;
  }

  .mobile-project-media img,
  .mobile-project-media video {
    width: 100%;
    height: 100%;
    min-height: 92px;
    display: block;
    object-fit: cover;
    filter: grayscale(1) contrast(1.05) brightness(0.96);
  }

  .work-list span:not(.mobile-project-media):not(.mobile-project-meta) {
    grid-column: 2;
    padding: 0;
    color: rgba(48, 48, 48, 0.48);
    font-size: 10px;
    line-height: 1;
  }

  .work-list strong {
    grid-column: 2 / 4;
    font-size: clamp(20px, 5.8vw, 25px);
    line-height: 0.98;
  }

  .work-list em {
    grid-column: 2 / 4;
    color: rgba(48, 48, 48, 0.58);
    font-size: 12px;
    line-height: 1.25;
  }

  .work-list a::after {
    grid-column: 2 / 4;
    display: -webkit-box;
    color: rgba(48, 48, 48, 0.72);
    font-size: 13px;
    line-height: 1.28;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .mobile-project-meta {
    grid-column: 2 / 4;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 2px;
    color: rgba(48, 48, 48, 0.5);
    font-family: var(--mono);
    font-size: 10.5px;
  }

  .mobile-project-meta b,
  .mobile-project-meta i {
    font-weight: 400;
    font-style: normal;
  }

  .mobile-project-meta i::after {
    content: " ->";
  }

  .mobile-project-toggle {
    order: 2;
    width: 100%;
    max-width: 362px;
    justify-self: center;
    min-height: 42px;
    display: grid;
    place-items: center;
    border: 1px solid rgba(48, 48, 48, 0.32);
    border-radius: 4px;
    background: rgba(48, 48, 48, 0.92);
    color: var(--paper);
    font-family: var(--mono);
    font-size: 12px;
  }

  .methodology {
    min-height: auto !important;
    padding: 40px 14px 50px !important;
  }

  .methodology__title,
  .methodology.is-pinned .methodology__title,
  .methodology__claim,
  .methodology.is-pinned .methodology__claim {
    position: relative !important;
    inset: auto !important;
    height: auto !important;
    min-height: 0 !important;
    padding: 0 !important;
    opacity: 1 !important;
    transform: none !important;
    pointer-events: auto !important;
  }

  .methodology__title {
    margin: 0 0 16px;
  }

  .methodology__title h2 {
    justify-content: flex-start;
    font-size: clamp(38px, 11.5vw, 54px);
    line-height: 0.86;
  }

  .methodology__title h2 span {
    display: inline-block;
  }

  .methodology__claim p {
    max-width: 100%;
    font-size: clamp(23px, 7.2vw, 30px);
    line-height: 1;
    overflow-wrap: anywhere;
  }

  .methodology__claim {
    gap: 12px;
    margin: 0 0 18px;
  }

  .method-stack {
    gap: 10px;
    margin-top: 0;
  }

  .skill-section {
    padding: 42px 14px 50px;
  }

  .skill-lead {
    max-width: 10.5ch;
    margin-bottom: 10px;
    font-size: clamp(34px, 10.2vw, 45px);
  }

  .skill-mobile-brief {
    display: block;
    max-width: 31ch;
    margin: 0 0 18px;
    color: rgba(48, 48, 48, 0.64);
    font-size: 14px;
    line-height: 1.35;
  }

  .skill-copy {
    display: none;
  }

  .skill-strips {
    gap: 9px;
    width: 100%;
    max-width: 362px;
    justify-content: stretch;
    justify-self: center;
  }

  .skill-strips button {
    position: relative;
    display: block;
    height: auto;
    min-height: 44px;
    max-height: none;
    padding: 13px 12px;
    border-radius: 6px;
    box-shadow: 0 8px 20px rgba(48, 48, 48, 0.045);
    overflow: hidden;
  }

  .skill-strips .tag-label {
    width: 100%;
    font-size: 12px;
  }

  .skill-strips .tag-note {
    display: none;
    font-size: 13px;
  }

  .skill-strips button[aria-expanded="true"] .tag-note {
    display: block;
    margin-top: 10px;
  }

  .writing-dark {
    padding-top: 48px;
  }

  .writing-table a {
    border-top-color: rgba(247, 247, 243, 0.16);
  }

  .about {
    padding-top: 48px;
  }

  .contact {
    padding-top: 34px;
  }

  .contact-tv__set {
    width: min(94vw, 390px);
  }

  .contact-mobile-actions {
    gap: 7px;
  }

  .contact-mobile-actions span,
  .contact-mobile-actions a {
    min-height: 44px;
    border-radius: 4px;
  }
}

@media (max-width: 380px) {
  .mobile-recruiter__actions {
    grid-template-columns: repeat(2, 1fr);
  }

  .work-list a {
    grid-template-columns: 72px minmax(0, 1fr) auto;
  }

  .mobile-project-media,
  .mobile-project-media img,
  .mobile-project-media video {
    min-height: 86px;
  }
}

/* Mobile polish pass, 2026-09-05: remove rough poster scale and mobile-only bugs. */
@media (max-width: 760px) {
  .tree-card__open[hidden] {
    display: none !important;
  }

  .mobile-recruiter {
    padding: 22px 20px 24px;
    border-top-color: rgba(48, 48, 48, 0.1);
    border-bottom-color: rgba(48, 48, 48, 0.1);
    background:
      linear-gradient(180deg, rgba(255, 255, 252, 0.78), rgba(242, 241, 236, 0.9)),
      var(--paper);
  }

  .mobile-recruiter__eyebrow {
    font-size: 10.5px;
    line-height: 1.2;
  }

  .mobile-recruiter h2 {
    max-width: 11.5ch;
    font-size: clamp(32px, 8.9vw, 42px);
    line-height: 0.96;
    text-transform: none;
  }

  .mobile-recruiter p:not(.mobile-recruiter__eyebrow) {
    max-width: 32ch;
    color: rgba(48, 48, 48, 0.72);
    font-size: 14.5px;
    line-height: 1.42;
  }

  .mobile-recruiter__tags,
  .mobile-recruiter__actions,
  .mobile-jump {
    width: 100%;
    max-width: 332px;
  }

  .mobile-recruiter__tags span {
    min-height: 34px;
    display: grid;
    place-items: center;
    padding: 5px 8px;
    border-color: rgba(48, 48, 48, 0.16);
    background: rgba(255, 255, 252, 0.42);
    color: rgba(48, 48, 48, 0.62);
    font-size: 10.5px;
  }

  .mobile-recruiter__actions a {
    min-height: 46px;
    border-radius: 5px;
    font-size: 12px;
  }

  .mobile-jump {
    border-color: rgba(48, 48, 48, 0.18);
    background: rgba(48, 48, 48, 0.92);
  }

  .mobile-jump a {
    min-height: 42px;
  }

  .work-list,
  .mobile-project-toggle,
  .skill-strips {
    max-width: 344px;
  }

  .work-list a {
    grid-template-columns: 76px minmax(0, 1fr);
    min-height: 104px;
    padding: 9px;
  }

  .mobile-project-media {
    min-height: 86px;
  }

  .mobile-project-media img,
  .mobile-project-media video {
    min-height: 86px;
  }

  .work-list strong,
  .work-list em,
  .work-list a::after,
  .mobile-project-meta {
    grid-column: 2;
  }

  .mobile-project-meta {
    align-items: flex-start;
    flex-direction: column;
    gap: 2px;
  }

  .contact-mobile-actions {
    max-width: 348px;
  }

  .contact-mobile-actions span,
  .contact-mobile-actions a {
    position: relative;
    min-height: 46px;
    border: 1px solid rgba(247, 247, 243, 0.24);
    outline: 0;
    box-shadow: none;
    -webkit-tap-highlight-color: transparent;
  }

  .contact-mobile-actions .contact-mobile-phone {
    grid-column: 1 / -1;
    pointer-events: auto;
  }

  .contact-mobile-actions .contact-mobile-phone:focus,
  .contact-mobile-actions .contact-mobile-phone:focus-visible {
    border-color: rgba(247, 247, 243, 0.5);
    outline: 0;
    box-shadow: 0 0 0 1px rgba(247, 247, 243, 0.18);
  }

  body.tree-card-open::before {
    background: rgba(247, 247, 243, 0.9);
    backdrop-filter: blur(14px);
  }

  .tree-card__open {
    top: max(12px, env(safe-area-inset-top)) !important;
    right: 12px !important;
    bottom: auto !important;
    left: 12px !important;
    width: auto !important;
    height: auto !important;
    max-height: calc(100vh - 24px);
    max-height: calc(100dvh - 24px);
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    overflow: auto;
    border: 1px solid rgba(48, 48, 48, 0.18);
    border-radius: 10px;
    background: rgba(248, 248, 244, 0.94);
    box-shadow: 0 18px 56px rgba(48, 48, 48, 0.14);
    animation: none;
    transform: none !important;
  }

  .tree-card__open::before {
    display: none;
  }

  .tree-card__close {
    position: relative;
    inset: auto;
    z-index: 20;
    justify-self: start;
    margin: 14px;
    min-height: 40px;
    padding: 0 14px;
    background: rgba(255, 255, 252, 0.78);
    font-size: 12px;
  }

  .tree-card__open .tree-card__cyanotype,
  .tree-card__open .tree-card__dogwood,
  .tree-card__open .tree-card__feather {
    display: none !important;
  }

  .tree-card__tree,
  .tree-card__hint {
    display: none;
  }

  .tree-card__content,
  .tree-card__open.is-tree-open .tree-card__content {
    position: relative;
    inset: auto;
    z-index: 10;
    width: auto;
    height: auto;
    max-height: calc(100vh - 112px);
    max-height: calc(100dvh - 112px);
    margin: 0 16px 18px;
    padding: 18px 16px 42px;
    overflow: auto;
    border: 1px solid rgba(48, 48, 48, 0.16);
    border-radius: 8px;
    background: rgba(255, 255, 252, 0.78);
    box-shadow: 0 12px 30px rgba(48, 48, 48, 0.08);
    opacity: 1;
    transform: none;
    visibility: visible;
  }

  .tree-card__copy {
    display: block;
  }

  .tree-card__content p {
    width: auto;
    margin: 0 0 18px;
    color: rgba(48, 48, 48, 0.78);
    font-size: 15px;
    line-height: 1.45;
  }

  .tree-card__content p:last-child {
    margin-bottom: 0;
  }
}
