/* Studio — the creative homepage as one printed monograph.

   One grid, one type system, one day of light. The page opens on ivory paper
   and turns to night behind a sunset photograph in Photography, so every
   chapter after it — Arcade, About, Contact — shares the same warm dark as the
   cover's object vitrine. Colours are registered custom properties, which is
   what lets the whole document cross-fade between the two tones instead of
   cutting from one to the other.

   Palette: Ryan Yang identity kit (ivory, graphite, brass). Text contrast was
   measured, not eyeballed: graphite 14.6:1 and muted 5.0:1 on ivory, brass-ink
   5.3:1; ivory 15.4:1, muted 6.1:1 and brass 8.0:1 on night. Raw brass is a
   graphic colour on ivory (2.0:1) and never sets body text there. */

@property --bg { syntax: '<color>'; inherits: true; initial-value: #F6F2EA; }
@property --fg { syntax: '<color>'; inherits: true; initial-value: #1F2022; }
@property --fg-2 { syntax: '<color>'; inherits: true; initial-value: rgba(31, 32, 34, .68); }
@property --line { syntax: '<color>'; inherits: true; initial-value: rgba(31, 32, 34, .14); }
@property --accent-ink { syntax: '<color>'; inherits: true; initial-value: #7E5E28; }
@property --surface { syntax: '<color>'; inherits: true; initial-value: #EDE7DC; }

:root {
  --ivory-kit: #F6F2EA;
  --graphite: #1F2022;
  --night: #171513;
  --night-ink: #F1EBE0;
  --brass: #C8A863;

  --bg: #F6F2EA;
  --fg: #1F2022;
  --fg-2: rgba(31, 32, 34, .68);
  --line: rgba(31, 32, 34, .14);
  --accent: var(--brass);
  --accent-ink: #7E5E28;
  --surface: #EDE7DC;

  /* Names the kept modules (project stories, assistant, loader, professional
     mode) still read. They follow the new palette rather than the old amber. */
  --ivory: #F6F2EA;
  --plaster: #EDE7DC;
  --ink: #1F2022;
  --ink-soft: rgba(31, 32, 34, .68);
  --amber: #B08A45;
  --amber-text: #7E5E28;
  --gold: #C8A863;
  --seam: #A38A64;
  --calibration: #7E5E28;

  --serif: "Fraunces", "Iowan Old Style", Georgia, serif;
  --sans: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --margin: clamp(20px, 4.4vw, 76px);
  --gutter: clamp(12px, 1.6vw, 26px);
  --hd-h: 72px;
  --radius: 6px;

  --f-mega: clamp(5.25rem, 24.6vw, 30rem);
  --f-chapter: clamp(3.4rem, 10.4vw, 11.5rem);
  --f-display: clamp(2.6rem, 5.4vw, 6rem);
  --f-h3: clamp(1.45rem, 1.9vw, 2rem);
  --f-lede: clamp(1.2rem, 1.7vw, 1.6rem);
  --f-body: clamp(1rem, .96vw, 1.0625rem);
  --f-small: .875rem;
  --f-label: .75rem;

  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-out: cubic-bezier(.19, 1, .22, 1);
  --tone-time: 1.1s;

  transition:
    --bg var(--tone-time) var(--ease-out),
    --fg var(--tone-time) var(--ease-out),
    --fg-2 var(--tone-time) var(--ease-out),
    --line var(--tone-time) var(--ease-out),
    --accent-ink var(--tone-time) var(--ease-out),
    --surface var(--tone-time) var(--ease-out);
}

:root[data-tone="night"] {
  --bg: #171513;
  --fg: #F1EBE0;
  --fg-2: rgba(241, 235, 224, .6);
  --line: rgba(241, 235, 224, .15);
  --accent-ink: #C8A863;
  --surface: #211E1A;
}

/* No script, no scroll-driven tone: the night chapters carry their own. */
html:not(.js) [data-tone="night"] {
  --bg: #171513;
  --fg: #F1EBE0;
  --fg-2: rgba(241, 235, 224, .6);
  --line: rgba(241, 235, 224, .15);
  --accent-ink: #C8A863;
  --surface: #211E1A;
  background: var(--bg);
  color: var(--fg);
}

@media (max-width: 760px) {
  :root { --hd-h: 60px; }
}

/* Cross-document fades between this page and the case studies, photography
   and arcade, which opt in the same way. Browsers without it navigate as
   they always have. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  /* The old page settles back as the new one rises over it. A case study's
     plate is named on both pages, so it carries across (studio.js). */
  ::view-transition-old(root) { animation: .5s var(--ease-expo) both page-out; }
  ::view-transition-new(root) { animation: .8s var(--ease-expo) .06s both page-in; }
  ::view-transition-group(plate) { animation-duration: .8s; animation-timing-function: var(--ease-expo); }
}
@keyframes page-out { to { opacity: 0; scale: .985; } }
@keyframes page-in { from { opacity: 0; translate: 0 36px; } }

/* Without JavaScript nothing sets a presentation, so show the creative one
   alone rather than both documents stacked. */
html:not([data-site-mode]) #professional-portfolio-view { display: none; }

/* ---------------------------------------------------------------- base */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: auto;
}

/* Lenis owns wheel smoothing; the document keeps its native height. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
/* hidden, not clip: clip stops the root being a scroll container, and the
   document then reports a one-screen scrollHeight while the loader holds it. */
.lenis.lenis-stopped { overflow: hidden; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--f-body);
  line-height: 1.6;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* clip, not hidden: hidden would make <body> a scroll container. */
  overflow-x: clip;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ol, ul { list-style: none; }
em { font-style: normal; }

::selection { background: var(--brass); color: var(--graphite); }

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: fixed;
  z-index: 100020;
  top: 12px;
  left: 12px;
  padding: 12px 18px;
  background: var(--fg);
  color: var(--bg);
  font-size: var(--f-small);
  border-radius: 999px;
  transform: translateY(-160%);
  transition: transform .3s var(--ease-expo);
}
.skip-link:focus-visible { transform: none; }

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

/* Print grain. One small generated tile, composited once — no per-frame
   filter work. overlay reads on both tones. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 100001;
  pointer-events: none;
  /* Plain alpha, not a blend mode: a blended full-screen layer made the GPU
     re-blend the whole page under it on every scrolled frame. */
  opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------- the light
   Behind all content (z-index -1 under the body's canvas background) and
   above the page colour. Soft edges come from box-shadow, painted once; the
   scroll only moves and skews the layers, which the compositor does. */

.sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
/* The room's shade, deepest away from the window. Measured: muted text stays
   5.06:1 and brass-ink 4.71:1 at its darkest. */
.sky::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 125% 95% at 88% 0%, transparent 30%, rgba(90, 66, 36, .08) 100%);
  transition: opacity var(--tone-time) var(--ease-out);
}
:root[data-tone="night"] .sky::before { opacity: 0; }
.sky__window {
  position: absolute;
  top: -14vh;
  right: -6vw;
  width: min(62vw, 980px);
  height: 96vh;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 1.25fr 1fr;
  gap: clamp(22px, 3.2vw, 54px);
  transform-origin: 100% 0%;
  transform: skewX(-12deg);
  will-change: transform, opacity;
}
.sky__window i {
  border-radius: 3px;
  background: rgba(255, 254, 250, .92);
  box-shadow: 0 0 64px 28px rgba(255, 254, 250, .82);
}
.sky__window i:nth-child(-n + 3) { border-radius: 50% 50% 3px 3px / 34% 34% 3px 3px; }
.sky__window--gold { opacity: 0; }
.sky__window--gold i {
  background: rgba(255, 190, 110, .42);
  box-shadow: 0 0 76px 34px rgba(255, 176, 92, .36);
}
.sky__lamp {
  position: absolute;
  left: -20vw;
  bottom: -30vh;
  width: 90vw;
  height: 90vw;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(214, 160, 84, .15), rgba(214, 160, 84, .05) 55%, transparent);
  opacity: 0;
  will-change: opacity, transform;
}
/* Before the scroll owner arrives (and with reduced motion) the room keeps
   its morning light, and the lamp comes on with the night tone. */
:root[data-tone="night"] .sky__window { opacity: 0 !important; }
:root[data-tone="night"]:not(.motion) .sky__lamp { opacity: 1; }
:root:not(.motion) .sky__window,
:root:not(.motion) .sky__lamp { transition: opacity var(--tone-time) var(--ease-out); }
html[data-site-mode="professional"] .sky { display: none; }

@media (max-width: 760px) {
  .sky__window { width: 110vw; height: 70vh; right: -30vw; gap: 18px; }
  .sky__window i { box-shadow: 0 0 40px 18px rgba(255, 254, 250, .82); }
  .sky__window--gold i { box-shadow: 0 0 44px 20px rgba(255, 176, 92, .36); }
}

/* ---------------------------------------------------------------- daylight
   daylight.js: the window light above, drawn. Shown once it has loaded and
   while the page is in its day tone; the CSS light steps aside for it. */

.daylight {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  z-index: -1;
  pointer-events: none;
  visibility: hidden;
}
.daylight canvas { display: block; width: 100%; height: 100%; }
.daylight-on .daylight { visibility: visible; }
.daylight-on .sky { visibility: hidden; }
html[data-site-mode="professional"] .daylight { display: none; }

/* ---------------------------------------------------------------- night over the lake
   night.js: the sunset photograph, redrawn and relit behind the night
   chapters. Hidden until the sunset is about to fill the screen; from then
   on the page's frame of it steps aside, Golden hour dissolves onto the
   canvas, and the canvas is the picture. Sized to the large viewport so a phone's URL bar moving never
   resizes it. */

.night {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  z-index: -1;
  pointer-events: none;
  visibility: hidden;
}
.night canvas { display: block; width: 100%; height: 100%; }
.night-on .night { visibility: visible; }
.night-on .photo__dusk-frame { visibility: hidden; }
/* Small type keeps its contrast where a lit building passes behind it: a
   dark halo that is invisible against the sky. Only while the night is on
   screen (on the day's paper it would be a grey smudge), and wide enough to
   read as shade rather than an outline. Titles are large enough. */
.night-on :is(.arcade, .about, .contact) :is(p, li, dl, blockquote, label, .link-arrow) {
  text-shadow: 0 0 7px rgba(13, 12, 11, .9), 0 0 16px rgba(13, 12, 11, .85);
}
/* The coda starts over the night rather than as a dark block rising over
   it; the room's still covers the city once the cover has filled the
   screen (studio.js keeps the night drawn until then). */
.night-finale .finale { background: transparent; }
html[data-site-mode="professional"] .night { display: none; }

/* ---------------------------------------------------------------- first visit
   studio.js: a scroll cue at the foot of the first screen, and once, a card
   with the three things worth knowing. Near-opaque graphite so they read on
   the paper and over the vitrine alike (no backdrop blur: it would be redone
   on every scrolled frame). */

.scroll-cue {
  position: fixed;
  z-index: 900;
  left: 50%;
  bottom: clamp(18px, 3.4vh, 32px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px 9px 12px;
  border-radius: 999px;
  background: rgba(31, 32, 34, .9);
  color: #F1EBE0;
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  translate: -50% 12px;
  transition: opacity .6s var(--ease-expo), translate .6s var(--ease-expo);
}
.scroll-cue.is-on { opacity: 1; translate: -50% 0; }
.guide-on .scroll-cue { opacity: 0; }
/* A drop running down a short line: the way the page goes. */
.scroll-cue i {
  position: relative;
  width: 1px;
  height: 18px;
  background: rgba(241, 235, 224, .25);
  overflow: hidden;
}
.scroll-cue i::after {
  content: "";
  position: absolute;
  left: -1px;
  top: -6px;
  width: 3px;
  height: 6px;
  border-radius: 2px;
  background: var(--brass);
  animation: cue-drop 1.6s var(--ease-expo) infinite;
}
@keyframes cue-drop { to { transform: translateY(26px); } }
html[data-site-mode="professional"] .scroll-cue { display: none; }

.guide {
  position: fixed;
  z-index: 1001;
  left: var(--margin);
  bottom: clamp(18px, 4vh, 40px);
  width: min(380px, calc(100vw - 2 * var(--margin)));
  padding: 20px 22px 18px;
  border-radius: 14px;
  background: rgba(31, 32, 34, .96);
  color: #F1EBE0;
  border: 1px solid rgba(241, 235, 224, .12);
  box-shadow: 0 24px 60px -24px rgba(12, 10, 8, .55);
  opacity: 0;
  translate: 0 18px;
  transition: opacity .7s var(--ease-expo), translate .7s var(--ease-expo);
}
.guide.is-on { opacity: 1; translate: 0 0; }
.guide__tag {
  margin-bottom: 14px;
  color: var(--brass);
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.guide__list { list-style: none; display: grid; gap: 14px; }
.guide__list li { display: grid; grid-template-columns: 20px 1fr; gap: 14px; align-items: start; }
.guide__list svg { width: 20px; height: 20px; fill: none; stroke: var(--brass); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; margin-top: 1px; }
.guide__list p { font-size: var(--f-small); line-height: 1.5; color: rgba(241, 235, 224, .78); }
.guide__list strong { color: #F1EBE0; font-weight: 500; }
.guide__ok {
  margin-top: 18px;
  min-height: 40px;
  padding: 0 18px;
  border-radius: 999px;
  background: #F1EBE0;
  color: var(--graphite);
  font: 500 var(--f-small) / 1 var(--sans);
  transition: background-color .3s ease;
}
.guide__ok:hover { background: var(--brass); }
.guide__ok:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
/* The chapter list it points at, ringed while the card is up. */
.guide-on .hd-nav__list,
.guide-on .hd-menu {
  outline: 1px solid rgba(200, 168, 99, .7);
  outline-offset: 10px;
  border-radius: 999px;
  animation: guide-ring 2.2s ease-in-out infinite;
}
@keyframes guide-ring { 50% { outline-color: rgba(200, 168, 99, .15); } }
@media (max-width: 1099px) { .guide-on .hd-nav__list { outline: 0; animation: none; } }
@media (min-width: 1100px) { .guide-on .hd-menu { outline: 0; animation: none; } }
@media (max-width: 760px) {
  .guide { left: 12px; right: 12px; width: auto; bottom: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-cue i::after, .guide-on .hd-nav__list, .guide-on .hd-menu { animation: none; }
}

/* ---------------------------------------------------------------- type */

.label,
.chapter__tag,
.work__index,
.work__kind,
.work__facts dt,
.caps__no,
.about__label,
.about__ledger dt,
.cover__role,
.cover__place,
.cover__caption,
.photo__dusk-where {
  font-family: var(--sans);
  font-size: var(--f-label);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* the mask has to reach below the baseline or Fraunces loses its descenders */
  padding: 0 .04em .16em;
  margin: 0 -.04em -.16em;
}
.w__i { display: inline-block; will-change: transform; }

/* ---------------------------------------------------------------- controls */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .7em;
  min-height: 48px;
  padding: 0 22px;
  border-radius: 999px;
  border: 1px solid var(--fg);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--f-small);
  font-weight: 500;
  letter-spacing: .01em;
  white-space: nowrap;
  transition: background-color .35s var(--ease-expo), color .35s var(--ease-expo), transform .35s var(--ease-expo), translate .6s var(--ease-expo);
}
.btn--solid { --btn-bg: var(--fg); --btn-fg: var(--bg); }
.btn:hover { --btn-bg: var(--accent); --btn-fg: var(--graphite); border-color: var(--accent); }
.btn:active { transform: scale(.97); }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  min-height: 44px;
  font-size: var(--f-small);
  font-weight: 500;
  color: var(--fg);
  background: linear-gradient(currentColor, currentColor) 0 calc(50% + .85em) / 100% 1px no-repeat;
  transition: background-size .5s var(--ease-expo), color .3s ease;
}
.link-arrow span { transition: transform .5s var(--ease-expo); }
.link-arrow:hover { color: var(--accent-ink); }
.link-arrow:hover span { transform: translateX(5px); }
.link-arrow--light { color: #F6F2EA; }
.link-arrow--light:hover { color: var(--brass); }

/* ---------------------------------------------------------------- header */

.hd {
  position: fixed;
  z-index: 1000;
  inset: 0 0 auto;
  height: var(--hd-h);
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 0 var(--margin);
  color: var(--fg);
  transition: transform .6s var(--ease-expo), color .4s ease;
}
.hd::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Near-opaque rather than frosted: a backdrop blur over moving content is
     redone on every scrolled frame. */
  background: color-mix(in srgb, var(--bg) 95%, transparent);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transition: opacity .4s ease;
}
.hd.is-scrolled::before { opacity: 1; }
.hd.is-hidden:not(:focus-within):not([data-menu="open"]) { transform: translateY(-100%); }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-family: var(--serif);
  font-size: 1.125rem;
  font-weight: 460;
  letter-spacing: -.01em;
  margin-right: auto;
}
.brand-mark {
  width: 28px;
  height: 23px;
  background: currentColor;
  -webkit-mask: url("../img/ry-mark.svg") center / contain no-repeat;
  mask: url("../img/ry-mark.svg") center / contain no-repeat;
}

.hd-nav { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 40px); }
.hd-nav__list { display: flex; gap: clamp(14px, 2vw, 32px); }
.hd-nav__list a {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-height: 44px;
  align-items: center;
  font-size: var(--f-small);
  font-weight: 500;
  color: var(--fg-2);
  transition: color .3s ease;
}
.hd-nav__list a em {
  font-size: .6875rem;
  font-variant-numeric: tabular-nums;
  color: var(--accent-ink);
  opacity: 0;
  transform: translateY(3px);
  transition: opacity .3s ease, transform .4s var(--ease-expo);
}
.hd-nav__list a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 9px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .5s var(--ease-expo);
}
.hd-nav__list a:hover,
.hd-nav__list a[aria-current="true"] { color: var(--fg); }
.hd-nav__list a:hover em,
.hd-nav__list a[aria-current="true"] em { opacity: 1; transform: none; }
.hd-nav__list a[aria-current="true"]::after { transform: scaleX(1); transform-origin: left; }
.hd-nav__mail { display: none; }

.hd-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
}

.hd-menu { display: none; }

.hd-nav__foot { display: flex; align-items: center; gap: 14px; }
/* Sound: four bars that lie flat when off and breathe when on. */
.hd-sound {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-width: 44px;
  min-height: 44px;
  color: var(--fg-2);
  transition: color .3s ease;
}
.hd-sound:hover,
.hd-sound[aria-pressed="true"] { color: var(--fg); }
.hd-sound:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 6px; }
/* Off, the bars lie flat as one short line (spaced dots read as a "more" menu). */
.hd-sound__bars { display: inline-flex; align-items: center; gap: 0; height: 14px; transition: gap .4s var(--ease-expo); }
.hd-sound[aria-pressed="true"] .hd-sound__bars { gap: 2px; }
.hd-sound__bars i {
  width: 3px;
  height: 100%;
  border-radius: 0;
  background: currentColor;
  transform: scaleY(.1);
  transition: transform .5s var(--ease-expo);
}
.hd-sound[aria-pressed="true"] .hd-sound__bars i { animation: hd-sound 1.1s ease-in-out infinite alternate; }
.hd-sound[aria-pressed="true"] .hd-sound__bars i:nth-child(2) { animation-duration: .8s; animation-delay: -.3s; }
.hd-sound[aria-pressed="true"] .hd-sound__bars i:nth-child(3) { animation-duration: 1.3s; animation-delay: -.6s; }
.hd-sound[aria-pressed="true"] .hd-sound__bars i:nth-child(4) { animation-duration: .95s; animation-delay: -.2s; }
@keyframes hd-sound { from { transform: scaleY(.25); } to { transform: scaleY(1); } }
.hd-sound__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .hd-sound[aria-pressed="true"] .hd-sound__bars i { animation: none; transform: scaleY(.7); }
}

/* The mode switch, docked. mode-toggle.js places it in [data-mode-dock]. */
/* Docked, it is a control among the others: full labels, full opacity, none
   of the phone-only floating rules in mode-toggle.css. */
.hd-mode .site-mode-toggle-container {
  position: static;
  opacity: 1 !important;
  transform: none !important;
  pointer-events: auto !important;
}
.hd-mode .site-mode-toggle {
  background: transparent;
  border: 1px solid var(--line);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.hd-mode .site-mode-option {
  width: auto;
  min-width: 0;
  min-height: 34px;
  padding: 0 14px;
  gap: 6px;
  color: var(--fg-2);
  font-size: .75rem;
}
.hd-mode .site-mode-option::after { content: none !important; }
.hd-mode .site-mode-option.is-active { background: var(--fg); color: var(--bg); }
.hd-mode .site-mode-option:not(.is-active):hover { color: var(--fg); background: transparent; }

@media (max-width: 1099px) {
  .hd-menu {
    position: relative;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 0 4px 0 14px;
    font-size: var(--f-small);
    font-weight: 500;
  }
  .hd-menu__now { display: inline-flex; gap: 8px; color: var(--fg-2); }
  .hd-menu__now em { color: var(--accent-ink); font-variant-numeric: tabular-nums; }
  .hd-menu__label { display: none; }
  .hd-menu__icon {
    position: relative;
    width: 34px;
    height: 34px;
    border: 1px solid var(--line);
    border-radius: 50%;
  }
  .hd-menu__icon::before,
  .hd-menu__icon::after {
    content: "";
    position: absolute;
    left: 10px;
    right: 10px;
    height: 1.5px;
    background: currentColor;
    transition: transform .5s var(--ease-expo);
  }
  .hd-menu__icon::before { top: 13px; }
  .hd-menu__icon::after { top: 19px; }
  .hd[data-menu="open"] .hd-menu__icon::before { transform: translateY(3px) rotate(45deg); }
  .hd[data-menu="open"] .hd-menu__icon::after { transform: translateY(-3px) rotate(-45deg); }
  .hd[data-menu="open"] .hd-menu__now { visibility: hidden; }

  .hd-nav {
    position: fixed;
    inset: 0;
    z-index: 1;
    flex-direction: column;
    align-items: stretch;
    justify-content: space-between;
    gap: 32px;
    padding: calc(var(--hd-h) + 5vh) var(--margin) max(28px, env(safe-area-inset-bottom));
    background: var(--bg);
    visibility: hidden;
    clip-path: inset(0 0 100% 0);
    transition: clip-path .75s var(--ease-expo), visibility 0s linear .75s;
  }
  .hd[data-menu="open"] .hd-nav {
    visibility: visible;
    clip-path: inset(0 0 0 0);
    transition: clip-path .75s var(--ease-expo), visibility 0s;
  }
  .hd-nav__list { flex-direction: column; gap: 0; }
  .hd-nav__list li { border-top: 1px solid var(--line); }
  .hd-nav__list li:last-child { border-bottom: 1px solid var(--line); }
  .hd-nav__list a {
    display: flex;
    align-items: baseline;
    gap: 16px;
    min-height: 0;
    padding: 1.6vh 0;
    font-family: var(--serif);
    font-size: clamp(2.1rem, 8.6vw, 3.6rem);
    font-weight: 340;
    line-height: 1.02;
    letter-spacing: -.03em;
    color: var(--fg);
  }
  .hd-nav__list a::after { display: none; }
  .hd-nav__list a em {
    font-family: var(--sans);
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: .06em;
    opacity: 1;
    transform: none;
    min-width: 1.6em;
  }
  .hd-nav__list a[aria-current="true"] span { color: var(--accent-ink); }
  .hd-nav__foot { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
  .hd-sound { justify-content: flex-start; font-size: var(--f-small); }
  .hd-sound__label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
  .hd-mode .site-mode-option { min-height: 44px; padding: 0 18px; font-size: .8125rem; }
  .hd-nav__mail {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: var(--f-small);
    color: var(--fg-2);
  }
  body.menu-open { overflow: hidden; }
}

/* ---------------------------------------------------------------- chapters */

section[id] { position: relative; scroll-margin-top: 0; }

.chapter {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: clamp(20px, 3vw, 44px);
  align-items: end;
  padding: clamp(110px, 17vh, 200px) var(--margin) clamp(52px, 8vh, 100px);
}
.chapter__rule {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--line);
  transform-origin: left;
}
.chapter__no {
  grid-column: 1 / 2;
  grid-row: 2;
  align-self: start;
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: .08em;
  font-variant-numeric: tabular-nums;
  color: var(--accent-ink);
}
.chapter__tag {
  grid-column: 2 / 7;
  grid-row: 2;
  align-self: start;
  color: var(--fg-2);
}
.chapter__title {
  grid-column: 1 / 10;
  grid-row: 3;
  font-family: var(--serif);
  font-size: var(--f-chapter);
  font-weight: 320;
  line-height: .9;
  letter-spacing: -.04em;
  text-wrap: balance;
}
.chapter__lede {
  grid-column: 10 / 13;
  grid-row: 3;
  max-width: 34ch;
  padding-bottom: .5em;
  color: var(--fg-2);
  text-wrap: pretty;
}
.chapter--bare { padding-bottom: clamp(28px, 4vh, 48px); }

@media (max-width: 1099px) {
  .chapter__title { grid-column: 1 / -1; }
  .chapter__lede { grid-column: 1 / 9; grid-row: 4; }
}
@media (max-width: 760px) {
  .chapter { row-gap: 18px; padding-top: clamp(96px, 16vh, 140px); }
  .chapter__no { grid-column: 1 / 3; }
  .chapter__tag { grid-column: 3 / -1; }
  .chapter__lede { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------- 01 work
   Each product stands on its own colour field, drawn from its interface —
   never pasted over a render. On wide screens with motion, the five plates
   share one sticky stage and wipe up over each other as the copy beside them
   scrolls (studio.js); everywhere else each plate sits above its own copy. */

.work__list {
  display: grid;
  gap: clamp(96px, 16vh, 180px);
  padding: 0 var(--margin);
}
.work__item {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: 32px;
  align-items: center;
}
.work__text { scroll-margin-top: calc(var(--hd-h) + 24px); }

.work__plate {
  --plate: #ECE8F6;
  --ghost: rgba(31, 32, 34, .07);
  --light: rgba(255, 255, 255, .7);
  position: relative;
  grid-column: 1 / 8;
  aspect-ratio: 1 / 1;
  max-height: 82svh;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  background:
    radial-gradient(ellipse 70% 55% at 50% 12%, var(--light), transparent 70%),
    var(--plate);
  cursor: pointer;
  isolation: isolate;
}
.work__plate--habitforge { --plate: #ECE8F7; --ghost: rgba(76, 52, 190, .09); }
.work__plate--seekr { --plate: #EDE5DA; --ghost: rgba(160, 80, 30, .09); }
.work__plate--traintogether { --plate: #0D100E; --ghost: rgba(120, 220, 120, .06); --light: rgba(90, 200, 120, .16); }
.work__plate--digimimic { --plate: #0B0D11; --ghost: rgba(230, 180, 100, .07); --light: rgba(230, 170, 90, .2); }
.work__plate--ibkr { --plate: #191B1E; --ghost: rgba(200, 168, 99, .08); --light: rgba(200, 168, 99, .14); }

.work__plate-inner {
  position: absolute;
  inset: 0;
  transform-origin: 50% 40%;
}
.work__ghost {
  position: absolute;
  z-index: 0;
  left: -.04em;
  top: -.12em;
  font-family: var(--serif);
  font-size: min(42vw, 44vh, 560px);
  font-weight: 250;
  line-height: 1;
  letter-spacing: -.06em;
  color: var(--ghost);
  pointer-events: none;
  user-select: none;
}
.work__tilt {
  position: absolute;
  inset: 0;
  z-index: 1;
  perspective: 1400px;
  transform-style: preserve-3d;
}
.work__device {
  position: absolute;
  display: block;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .9s var(--ease-expo);
}
.work__device picture { display: block; }
.work__device img { width: 100%; height: auto; }

/* Phone crops whose bottom bezel is out of frame rise from the plate's edge,
   the way product photography crops a device. */
.work__device--rise {
  left: 50%;
  bottom: 0;
  height: 80%;
  translate: -50% 0;
  filter: drop-shadow(0 40px 60px rgba(0, 0, 0, .28));
}
.work__device--rise picture { height: 100%; }
.work__device--rise img { width: auto; height: 100%; max-width: none; border-radius: 16% 16% 0 0 / 7.4% 7.4% 0 0; }

/* HabitForge's listing art is two phones on its own lavender ground; the
   plate is that ground, and the sheet's cut edges dissolve into it. */
.work__device--sheet {
  left: 50%;
  bottom: 0;
  width: 58%;
  margin-left: -29%;
}
.work__plate--habitforge .work__notes li { --reach: clamp(84px, 8.4vw, 132px); }
.work__device--sheet picture {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 7%, #000 93%, transparent 100%);
}

.work__device--wide {
  left: 10%;
  right: 10%;
  top: 50%;
  translate: 0 -50%;
  filter: drop-shadow(0 40px 70px rgba(0, 0, 0, .6));
}
.work__device--wide img { border-radius: 6.4% / 12.5%; }

/* Callouts. Each one is a dot on the feature and a hairline out past the
   device's edge to a short label, drawn when the product takes the stage. */
.work__notes { position: absolute; inset: 0; pointer-events: none; }
.work__notes li {
  --reach: clamp(90px, 11vw, 180px);
  position: absolute;
  top: var(--y);
  height: 0;
  color: var(--note-ink, #1F2022);
}
.work__plate[data-tone-plate="dark"] .work__notes li { --note-ink: #EDE6D8; }
.work__notes li[data-side="right"] { left: var(--x); right: calc(-1 * var(--reach)); }
.work__notes li[data-side="left"] { right: calc(100% - var(--x)); left: calc(-1 * var(--reach)); }
.work__notes li::before {
  content: "";
  position: absolute;
  top: -5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--brass);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--brass) 28%, transparent);
}
.work__notes li[data-side="right"]::before { left: -5px; }
.work__notes li[data-side="left"]::before { right: -5px; }
.work__notes li::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: currentColor;
  opacity: .45;
}
.work__notes li[data-side="right"]::after { left: 8px; transform-origin: left; }
.work__notes li[data-side="left"]::after { right: 8px; transform-origin: right; }
.work__notes span {
  position: absolute;
  bottom: 8px;
  width: max-content;
  max-width: calc(var(--reach) - 8px);
  font-size: .75rem;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: .01em;
}
.work__notes li[data-side="right"] span { right: 0; text-align: right; }
.work__notes li[data-side="left"] span { left: 0; }
/* Drawn in when the plate is the one on stage (studio.js), shown outright
   without the stage. */
.motion .work__notes li::before { scale: 0; transition: scale .5s var(--ease-expo); }
.motion .work__notes li::after { scale: 0 1; transition: scale .8s var(--ease-expo) .12s; }
.motion .work__notes span { opacity: 0; translate: 0 6px; transition: opacity .5s ease .45s, translate .6s var(--ease-expo) .45s; }
.motion .is-noted .work__notes li::before { scale: 1; }
.motion .is-noted .work__notes li::after { scale: 1 1; }
.motion .is-noted .work__notes span { opacity: 1; translate: 0 0; }
.motion .is-noted .work__notes li:nth-child(2)::before { transition-delay: .15s; }
.motion .is-noted .work__notes li:nth-child(2)::after { transition-delay: .27s; }
.motion .is-noted .work__notes li:nth-child(2) span { transition-delay: .6s; }
.motion .is-noted .work__notes li:nth-child(3)::before { transition-delay: .3s; }
.motion .is-noted .work__notes li:nth-child(3)::after { transition-delay: .42s; }
.motion .is-noted .work__notes li:nth-child(3) span { transition-delay: .75s; }
/* Landscape devices leave no room at the sides: their leaders run vertically
   to labels above and below. */
.work__notes li:is([data-side="top"], [data-side="bottom"]) { --reach: clamp(70px, 9vh, 120px); left: var(--x); width: 0; height: auto; }
.work__notes li[data-side="top"] { top: calc(-1 * var(--reach)); bottom: calc(100% - var(--y)); }
.work__notes li[data-side="bottom"] { top: var(--y); bottom: calc(-1 * var(--reach)); }
.work__notes li[data-side="top"]::before { top: auto; bottom: -5px; left: -5px; }
.work__notes li[data-side="bottom"]::before { top: -5px; left: -5px; }
.work__notes li:is([data-side="top"], [data-side="bottom"])::after { left: 0; right: auto; width: 1px; height: auto; }
.work__notes li[data-side="top"]::after { top: 0; bottom: 8px; transform-origin: bottom; }
.work__notes li[data-side="bottom"]::after { top: 8px; bottom: 0; transform-origin: top; }
.work__notes li:is([data-side="top"], [data-side="bottom"]) span { max-width: 190px; }
.work__notes li[data-side="top"] span { top: 0; bottom: auto; left: 10px; }
.work__notes li[data-side="bottom"] span { top: auto; bottom: 0; right: 10px; left: auto; text-align: right; }
.motion .work__notes li:is([data-side="top"], [data-side="bottom"])::after { scale: 1 0; }
.motion .is-noted .work__notes li:is([data-side="top"], [data-side="bottom"])::after { scale: 1 1; }
@media (max-width: 1099px) { .work__notes { display: none; } }

.work__device--term {
  left: 10%;
  right: 10%;
  top: 44%;
  translate: 0 -50%;
  padding: clamp(18px, 2.4vw, 32px);
  border: 1px solid rgba(241, 235, 224, .12);
  border-radius: 12px;
  background: linear-gradient(to bottom, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015));
  box-shadow: 0 40px 80px -20px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
  color: #E9E2D4;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: clamp(.78rem, 1.05vw, 1rem);
  line-height: 1.9;
}
.term__bar {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 18px;
  color: rgba(233, 226, 212, .5);
  font-size: .75em;
  letter-spacing: .04em;
}
.term__bar i { width: 10px; height: 10px; border-radius: 50%; background: rgba(233, 226, 212, .18); }
.term__bar span { margin-left: 10px; }
.term__lines li { counter-increment: line; }
.term__lines li::before {
  content: counter(line);
  display: inline-block;
  width: 2.2em;
  color: rgba(233, 226, 212, .28);
}
.term__lines li { color: #E9E2D4; }
/* The plate's foot: how the analyzer is built, drawn in brass hairlines, with
   the order path stopping at the adapter. Draws when the product takes the stage. */
.term__flow {
  position: absolute;
  left: 10%;
  right: 10%;
  bottom: 9%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 18px;
  color: rgba(233, 226, 212, .62);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: clamp(.62rem, .78vw, .74rem);
  letter-spacing: .02em;
}
.term__flow span {
  padding: 6px 10px;
  border: 1px solid rgba(233, 226, 212, .16);
  border-radius: 999px;
  white-space: nowrap;
}
.term__flow span.is-key { border-color: rgba(200, 168, 99, .6); color: var(--brass); }
.term__flow i {
  position: relative;
  flex: 1 1 18px;
  height: 1px;
  background: rgba(200, 168, 99, .55);
  transform-origin: left;
}
.term__flow i::after {
  content: "";
  position: absolute;
  right: -1px;
  top: -3px;
  border: 3.5px solid transparent;
  border-left: 5px solid rgba(200, 168, 99, .8);
  border-right: 0;
}
.term__stop {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: 39%;
  color: rgba(233, 226, 212, .55);
}
.term__stop b { font-weight: 400; text-decoration: line-through; text-decoration-color: rgba(200, 168, 99, .6); }
.term__stop em { flex: 0 1 150px; height: 0; border-top: 1px dashed rgba(233, 226, 212, .34); transform-origin: right; }
.term__stop strong { color: var(--brass); font-weight: 400; }
/* Only the stage marks a product as noted; elsewhere the flow is simply drawn. */
@media (min-width: 1100px) {
  .motion .term__flow :is(i, .term__stop em) { scale: 0 1; transition: scale .9s var(--ease-out); }
  .motion .term__flow :is(span, .term__stop) { opacity: 0; transition: opacity .6s var(--ease-out); }
  .motion .is-noted .term__flow :is(i, .term__stop em) { scale: 1 1; }
  .motion .is-noted .term__flow :is(span, .term__stop) { opacity: 1; }
  .motion .is-noted .term__flow > :nth-child(2) { transition-delay: .15s; }
  .motion .is-noted .term__flow > :nth-child(3) { transition-delay: .3s; }
  .motion .is-noted .term__flow > :nth-child(4) { transition-delay: .45s; }
  .motion .is-noted .term__flow > :nth-child(5) { transition-delay: .6s; }
  .motion .is-noted .term__flow > :nth-child(6) { transition-delay: .75s; }
  .motion .is-noted .term__flow > :nth-child(7) { transition-delay: .9s; }
  .motion .is-noted .term__flow .term__stop,
  .motion .is-noted .term__flow .term__stop em { transition-delay: 1.15s; }
}
@media (max-width: 699px) { .term__flow { display: none; } }
.term__note {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed rgba(233, 226, 212, .16);
  color: var(--brass);
  font-size: .9em;
  line-height: 1.5;
}

.work__text {
  grid-column: 9 / 13;
  display: grid;
  gap: 14px;
  align-content: center;
}
.work__index { color: var(--fg-2); font-variant-numeric: tabular-nums; }
.work__index span { color: var(--accent-ink); }
.work__name {
  font-family: var(--serif);
  font-size: var(--f-display);
  font-weight: 340;
  line-height: .94;
  letter-spacing: -.035em;
  margin-top: 4px;
}
.work__kind { color: var(--fg-2); }
.work__lede {
  font-family: var(--serif);
  font-size: var(--f-lede);
  font-weight: 360;
  line-height: 1.3;
  letter-spacing: -.01em;
  max-width: 26ch;
  margin-top: 10px;
  text-wrap: pretty;
}
.work__facts {
  display: grid;
  margin-top: 12px;
  border-top: 1px solid var(--line);
}
.work__facts div {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--f-small);
}
.work__facts dt { color: var(--fg-2); padding-top: .15em; }

/* The story is the primary action; the three destinations sit under it. */
.work__actions {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  align-items: center;
  gap: 10px 26px;
  margin-top: 18px;
}
.work__actions .work__story { grid-column: 1 / -1; justify-self: start; }
.work__actions a {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  min-height: 44px;
  font-size: var(--f-small);
  font-weight: 500;
  color: var(--fg);
  background: linear-gradient(currentColor, currentColor) 0 calc(50% + .8em) / 0 1px no-repeat;
  transition: background-size .5s var(--ease-expo), color .3s ease;
}
.work__actions a:hover { background-size: 100% 1px; color: var(--accent-ink); }

.work__story {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  padding: 6px 22px 6px 6px;
  border-radius: 999px;
  background: var(--fg);
  color: var(--bg);
  font-size: var(--f-small);
  font-weight: 500;
  transition: background-color .35s var(--ease-expo), color .35s var(--ease-expo), translate .6s var(--ease-expo);
}
.work__story-thumb {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  transition: transform .6s var(--ease-expo);
}
.work__story:hover { background: var(--accent); color: var(--graphite); }
.work__story:hover .work__story-thumb { transform: scale(1.12) rotate(-6deg); }
.work__story:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 3px; }

@media (max-width: 1099px) {
  .work__plate { grid-column: 1 / -1; max-height: none; aspect-ratio: 5 / 4; }
  .work__text { grid-column: 1 / 11; }
  .work__device--sheet { width: 52%; margin-left: -26%; }
  .work__device--wide { left: 10%; right: 10%; }
  .work__device--term { left: 14%; right: 14%; }
}
@media (max-width: 760px) {
  .work__plate { aspect-ratio: 4 / 5; }
  .work__device--rise { height: 84%; }
  .work__device--sheet { width: 94%; margin-left: -47%; }
  .work__device--wide { left: 5%; right: 5%; }
  .work__device--term { left: 6%; right: 6%; font-size: .74rem; }
  .work__text { grid-column: 1 / -1; }
  .work__facts div { grid-template-columns: 6.5rem 1fr; }
  .work__ghost { font-size: 58vw; }
}

/* The shared stage. Only with motion (the wipes live in JS) and only where
   there is room for copy and plate side by side. The items dissolve into one
   grid so every plate can occupy the same cell and stick together. */
@media (min-width: 1100px) {
  .motion .work__list {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: repeat(5, auto);
    column-gap: var(--gutter);
    row-gap: 0;
  }
  .motion .work__item { display: contents; }
  .motion .work__text {
    grid-column: 1 / 5;
    min-height: calc(100svh - var(--hd-h));
    padding: 8vh 0;
  }
  .motion .work__item:nth-child(1) .work__text { grid-row: 1; }
  .motion .work__item:nth-child(2) .work__text { grid-row: 2; }
  .motion .work__item:nth-child(3) .work__text { grid-row: 3; }
  .motion .work__item:nth-child(4) .work__text { grid-row: 4; }
  .motion .work__item:nth-child(5) .work__text { grid-row: 5; }
  .motion .work__list .work__plate {
    grid-column: 6 / 13;
    grid-row: 1 / 6;
    align-self: start;
    position: sticky;
    top: calc(var(--hd-h) + 2.5vh);
    height: calc(100svh - var(--hd-h) - 5vh);
    max-height: none;
    aspect-ratio: auto;
  }
  /* Each plate rises over the last through a wipe (studio.js drives --wipe);
     a line of light rides its edge, so the change reads even between two
     dark plates, and fades as the wipe completes. */
  .motion .work__item + .work__item .work__plate {
    --wipe: 0;
    clip-path: inset(calc((1 - var(--wipe)) * 100%) 0 0 0 round var(--radius));
  }
  .motion .work__item + .work__item .work__plate::after {
    content: "";
    position: absolute;
    z-index: 4;
    left: 0;
    right: 0;
    top: calc((1 - var(--wipe)) * 100%);
    height: 1px;
    background: linear-gradient(90deg, rgba(232, 206, 140, 0), rgba(232, 206, 140, .95) 30%, rgba(255, 244, 214, 1) 50%, rgba(232, 206, 140, .95) 70%, rgba(232, 206, 140, 0));
    box-shadow: 0 0 22px 5px rgba(232, 206, 140, .32);
    opacity: calc(min(1, var(--wipe) * 12) * min(1, (1 - var(--wipe)) * 12));
    pointer-events: none;
  }
  /* The last product is lifted off the stage over the Capabilities bench
     laid beneath it (studio.js drives --lift); it stays above the bench. */
  .motion .work__item:last-child .work__plate { z-index: 2; }
  .motion .work__plate.is-lifting {
    --lift: 0;
    clip-path: none;
    box-shadow:
      0 calc(var(--lift) * 34px) calc(var(--lift) * 70px) calc(var(--lift) * -18px) rgba(31, 26, 18, calc(var(--lift) * .42)),
      0 calc(var(--lift) * 90px) calc(var(--lift) * 160px) calc(var(--lift) * -40px) rgba(31, 26, 18, calc(var(--lift) * .3));
  }
}

/* ---------------------------------------------------------------- 02 capabilities */

.caps__field {
  padding: 0 var(--margin);
  font-family: var(--serif);
  font-size: clamp(2rem, 4.9vw, 5.4rem);
  font-weight: 330;
  line-height: 1.08;
  letter-spacing: -.03em;
  text-wrap: pretty;
  color: var(--fg-2);
}
.caps__field a {
  color: var(--fg);
  border-radius: 4px;
  transition: color .3s ease;
}
.caps__field a:hover,
.caps__field a:focus-visible {
  color: var(--accent-ink);
  opacity: 1 !important;
}
.caps__field sup {
  top: -1.5em;
  margin: 0 .25em 0 .1em;
  font-family: var(--sans);
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--accent-ink);
  vertical-align: baseline;
  position: relative;
}

.caps__disciplines {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gutter);
  padding: clamp(80px, 14vh, 160px) var(--margin) 0;
}
.caps__disciplines li {
  display: grid;
  align-content: start;
  gap: 12px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.caps__disciplines h3 {
  font-family: var(--sans);
  font-size: var(--f-small);
  font-weight: 600;
  letter-spacing: .01em;
}
.caps__claim {
  font-family: var(--serif);
  font-size: var(--f-h3);
  font-weight: 360;
  line-height: 1.12;
  letter-spacing: -.02em;
  text-wrap: balance;
}
.caps__disciplines p:not(.caps__claim):not(.caps__no) { color: var(--fg-2); font-size: var(--f-small); max-width: 32ch; }
.caps__no { color: var(--accent-ink); }
.caps__disciplines .link-arrow { justify-self: start; margin-top: 4px; }
/* With the sculptures, each discipline's rule becomes the shelf they stand on. */
.caps__object { display: none; }
.has-instruments .caps__disciplines li { padding-top: 0; border-top: 0; }
.has-instruments .caps__object {
  display: block;
  aspect-ratio: 5 / 4;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.caps__object canvas { display: block; width: 100%; height: 100%; }

/* The bench (studio.js; wide screens with motion): the sentence is the index
   on the left while one discipline at a time stands on the right, its tools
   labelling it. Each piece stands where the last stood, over its numeral.
   It is laid under the end of Work (studio.js sets the overlap and height),
   on the same columns as Work's stage, and shows only once it holds the
   screen, uncovered by the last plate lifting away. */
.caps__labels { display: none; }
.is-bench { height: 640svh; }
.is-bench .caps__frame {
  position: sticky;
  top: 0;
  z-index: 1;
  height: 100svh;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: 1fr auto auto 1fr;
  column-gap: var(--gutter);
  padding: calc(var(--hd-h) + 2vh) var(--margin) 3vh;
}
.is-bench:not(.is-reached) .caps__frame { opacity: 0; }
.is-bench .chapter {
  grid-column: 1 / 6;
  grid-row: 2;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 14px;
  row-gap: 12px;
  align-items: start;
  padding: 0 0 clamp(22px, 3.4vh, 36px);
  will-change: transform;
}
.is-bench .chapter__no { grid-column: 1; }
.is-bench .chapter__tag { grid-column: 2; }
.is-bench .chapter__title {
  grid-column: 1 / -1;
  margin-top: 6px;
  font-size: clamp(48px, 4.6vw, 80px);
}
.is-bench .chapter__lede {
  grid-column: 1 / -1;
  grid-row: 4;
  max-width: 44ch;
  padding: 0;
  font-size: var(--f-small);
}
.is-bench .caps__field {
  grid-column: 1 / 6;
  grid-row: 3;
  padding: 0;
  font-size: clamp(26px, 2.3vw, 40px);
  will-change: transform;
}
.is-bench .caps__field a { transition: color .45s ease; }
.is-bench .caps__field a.is-lit { color: var(--accent-ink); }
.is-bench .caps__field sup { transition: color .45s ease; color: var(--fg-2); }
.is-bench .caps__field sup.is-lit { color: var(--accent-ink); }
.is-bench .caps__disciplines {
  position: relative;
  grid-column: 6 / 13;
  grid-row: 1 / -1;
  align-self: stretch;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  padding: 0;
}
/* The bed: the footprint the last plate leaves on the bench as it lifts. */
.is-bench .caps__disciplines::before {
  content: "";
  grid-area: 1 / 1;
  margin: .5vh 0;
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(31, 32, 34, .045), rgba(31, 32, 34, .015));
  box-shadow: inset 0 1px 0 rgba(31, 32, 34, .06), inset 0 0 0 1px rgba(31, 32, 34, .05);
  opacity: var(--bed, 1);
  pointer-events: none;
}
.is-bench .caps__disciplines li {
  grid-area: 1 / 1;
  display: grid;
  grid-template-columns: 1fr min(520px, 60%) 1fr;
  grid-template-rows: repeat(5, auto);
  align-content: center;
  row-gap: 10px;
  padding: 0;
  border: 0;
  visibility: hidden;
  transition: visibility 0s linear .5s;
}
.is-bench .caps__disciplines li.is-on { visibility: visible; transition: visibility 0s; }
.is-bench .caps__disciplines li > * {
  grid-column: 2;
  opacity: 0;
  translate: 0 14px;
  transition: opacity .35s ease, translate .5s var(--ease-expo);
}
.is-bench .caps__disciplines li.is-on > * { opacity: 1; translate: 0 0; }
.is-bench .caps__disciplines .caps__object {
  grid-row: 1;
  align-self: center;
  position: relative;
  z-index: 1;
  margin: 0;
  translate: 0 0;
}
.is-bench .caps__disciplines .caps__no {
  grid-column: 1 / -1;
  grid-row: 1;
  place-self: center;
  z-index: 0;
  font-family: var(--serif);
  font-size: min(30vw, 54vh, 520px);
  font-weight: 250;
  line-height: .8;
  letter-spacing: -.06em;
  text-transform: none;
  color: rgba(126, 94, 40, .085);
  translate: 0 40px;
  pointer-events: none;
  user-select: none;
}
.is-bench .caps__disciplines h3 { grid-row: 2; margin-top: 8px; }
.is-bench .caps__disciplines .caps__claim { grid-row: 3; }
.is-bench .caps__disciplines p:not(.caps__claim):not(.caps__no) { grid-row: 4; }
.is-bench .caps__disciplines .link-arrow { grid-row: 5; }
.is-bench li.is-on h3 { transition-delay: .1s; }
.is-bench li.is-on .caps__claim { transition-delay: .18s; }
.is-bench li.is-on p:not(.caps__claim):not(.caps__no) { transition-delay: .26s; }
.is-bench li.is-on .link-arrow { transition-delay: .34s; }
.is-bench .caps__labels {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.caps__wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.caps__wires path {
  fill: none;
  stroke: var(--fg);
  stroke-opacity: .45;
  stroke-width: 1;
  stroke-dasharray: 1;
}
.caps__wires circle {
  fill: var(--brass);
  stroke: color-mix(in srgb, var(--brass) 28%, transparent);
  stroke-width: 9;
}
.caps__label {
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--serif);
  font-size: clamp(15px, 1.12vw, 18px);
  font-weight: 400;
  font-variation-settings: "opsz" 72;
  line-height: 1.08;
  letter-spacing: -.01em;
  white-space: nowrap;
  color: var(--fg);
  transform-origin: 0 0;
  opacity: 0;
  will-change: transform, opacity;
}

@media (max-width: 1099px) {
  .caps__disciplines { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 56px; }
}
@media (max-width: 560px) {
  .caps__disciplines { grid-template-columns: 1fr; row-gap: 44px; }
}

/* ---------------------------------------------------------------- 03 photography */

/* Golden hour (passage.js): a long pinned stage for the 3D walk, ending
   exactly over the sunset frame below, which is drawn up underneath its last
   screen so the two can hand over without a seam. About half a screen of
   scrolling for each of the seven prints. */
.passage { display: none; }
.has-passage .passage {
  position: relative;
  z-index: 2;
  display: block;
  height: 640svh;
  margin-top: clamp(80px, 14vh, 160px);
  pointer-events: none;
}
/* Transparent: the walk is seen through a lens that opens in the page (passage.js). */
.passage__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}
.passage__stage canvas { width: 100%; height: 100%; }
/* On a slip of paper: it is read over the lens barrel, the walls and the sunset. */
.passage__label {
  position: absolute;
  left: calc(var(--margin) - 10px);
  bottom: clamp(24px, 5vh, 48px);
  max-width: calc(100% - var(--margin) - 72px);
  padding: 7px 10px 6px;
  border-radius: 4px;
  background: rgba(250, 247, 241, .9);
  box-shadow: 0 8px 20px -12px rgba(60, 42, 20, .45);
  white-space: pre-wrap;
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: rgba(31, 32, 34, .78);
}
/* An f-number is lowercase: f/1.4, never F/1.4. */
.passage__stop {
  letter-spacing: .02em;
  text-transform: none;
}
.has-passage .photo__dusk { margin-top: -100svh; z-index: 1; }

.photo__dusk {
  position: relative;
  height: 100svh;
  min-height: 520px;
  margin-top: clamp(80px, 14vh, 160px);
  color: #F6F2EA;
}
.photo__dusk-frame {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #231a14;
}
.photo__dusk-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 58%;
  transform-origin: 50% 60%;
}
/* The foot of the frame is the night itself, so the sunset has no lower edge
   against the dark page. */
.photo__dusk-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--night), rgba(23, 21, 19, .6) 16%, rgba(12, 10, 8, 0) 46%);
}
/* Nightfall (studio.js): the sun goes down as the frame leaves. */
.photo__night {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--night);
  opacity: 0;
  will-change: opacity;
}
.photo__blinds {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  pointer-events: none;
}
/* Slats in the room's own paper, a shade darker so they read as blinds, with
   the light catching their top edge. Without motion they are simply open. */
.photo__blinds i {
  flex: 1 1 0;
  background: linear-gradient(to right, #E4DCCD, #EFE8DC 45%, #DED5C5);
  transform: scaleX(0);
  will-change: transform;
}
.motion .photo__blinds i { transform: scaleX(.93); }
.photo__dusk figcaption {
  position: absolute;
  z-index: 1;
  left: var(--margin);
  right: var(--margin);
  bottom: clamp(24px, 5vh, 56px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 32px;
}
.photo__dusk-where { color: rgba(246, 242, 234, .82); }

/* ---------------------------------------------------------------- 04 arcade */

.arcade__body {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: 40px;
  padding: 0 var(--margin);
  align-items: start;
}
.arcade__board {
  grid-column: 1 / 6;
  display: block;
  overflow: hidden;
  border-radius: var(--radius);
  background: #101010;
}
.arcade__board img { width: 100%; height: auto; scale: 1.08; }
/* Live (arcade/hub.js initShowcase): the poster gives way to the real solver
   of whichever game is pointed at, crossfading as the reader moves down the
   list, with that engine's own telemetry along the foot of the board. */
.arcade__board { position: relative; }
/* The screen's glow as it powers on and off (studio.js drives --crt): a CRT's
   picture collapses to a bright line, then a point. */
.arcade__board::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(closest-side, #fffaf0, #f2d7a4 45%, rgba(214, 170, 96, .35) 80%, rgba(214, 170, 96, 0));
  opacity: var(--crt, 0);
}
.arcade__board picture { display: block; transition: opacity .5s ease; }
.arcade__board.is-live picture { opacity: 0; }
.arcade__live { position: absolute; inset: 0; opacity: 0; transition: opacity .55s ease; }
.arcade__live.is-on { opacity: 1; }
.arcade__live canvas { display: block; width: 100%; height: 100%; }
.arcade__status {
  position: absolute;
  z-index: 1;
  left: 16px;
  right: 16px;
  bottom: 14px;
  overflow: hidden;
  color: rgba(200, 168, 99, .9);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .72rem;
  letter-spacing: .04em;
  white-space: nowrap;
  text-overflow: ellipsis;
  pointer-events: none;
}
.arcade__games a[data-game]:hover strong,
.arcade__games a[data-game]:focus-visible strong { color: var(--accent); }
.arcade__games {
  grid-column: 7 / 13;
  border-top: 1px solid var(--line);
}
.arcade__games li { border-bottom: 1px solid var(--line); }
.arcade__games a {
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr) auto;
  grid-template-areas: "n name go" "n what go";
  column-gap: 16px;
  row-gap: 4px;
  align-items: baseline;
  padding: clamp(18px, 2.6vh, 28px) 0;
  transition: color .3s ease;
}
/* The row's text slides on hover with a transform, not padding, so the
   hover never forces a layout pass. */
.arcade__games a :is(em, strong, span) { transition: translate .6s var(--ease-expo); }
.arcade__games a:hover :is(em, strong, span) { translate: 14px 0; }
.arcade__games em {
  grid-area: n;
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}
.arcade__games strong {
  grid-area: name;
  font-family: var(--serif);
  font-size: clamp(1.75rem, 2.8vw, 3rem);
  font-weight: 340;
  line-height: 1;
  letter-spacing: -.03em;
}
.arcade__games span { grid-area: what; color: var(--fg-2); font-size: var(--f-small); }
.arcade__games i {
  grid-area: go;
  align-self: center;
  font-style: normal;
  font-size: 1.25rem;
  color: var(--accent-ink);
  opacity: 0;
  transform: translateX(-10px);
  transition: opacity .4s ease, transform .6s var(--ease-expo);
}
.arcade__games a:hover i,
.arcade__games a:focus-visible i { opacity: 1; transform: none; }
.arcade__all { grid-column: 7 / 13; justify-self: start; }

@media (max-width: 900px) {
  .arcade__board { grid-column: 1 / -1; max-width: 520px; }
  .arcade__games,
  .arcade__all { grid-column: 1 / -1; }
  .arcade__games i { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- 05 about
   One light still on. Read against the night over the lake (night.js):
   the statement switches on like windows, the desk opens out of one lit
   window in the city (clipped from the window's own rectangle, studio.js),
   and the creed passes while the city goes to bed. */

.about__statement {
  margin: 0 var(--margin);
  max-width: 19.5em;
  font-family: var(--serif);
  font-size: clamp(2rem, 4.3vw, 5rem);
  font-weight: 300;
  line-height: 1.07;
  letter-spacing: -.03em;
  text-wrap: pretty;
}
/* Words that switch on (studio.js); no mask, so their light can spread. */
.lw { display: inline; }

.about__window {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  padding: clamp(120px, 20vh, 220px) var(--margin) 0;
  align-items: start;
}
.about__room {
  --room-h: min(80svh, 64vw);
  grid-column: 6 / 13;
  grid-row: 1;
  z-index: 2;
  position: sticky;
  top: calc((100svh - var(--room-h)) / 2);
  height: var(--room-h);
  overflow: hidden;
  border-radius: var(--radius);
  background: #0f0e0c;
}
.about__room picture { display: block; height: 100%; }
.about__room img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
/* The window's own light, while the room is still only a window. */
.about__glass {
  position: absolute;
  inset: 0;
  background: radial-gradient(closest-side, #ffd9a0, #f0b46a 70%, #c8863e);
  opacity: 0;
  pointer-events: none;
}
.about__side {
  grid-column: 1 / 5;
  grid-row: 1;
  display: grid;
  gap: clamp(72px, 16vh, 180px);
  padding: 8vh 0 12vh;
}
.about__who { display: grid; gap: 22px; justify-items: start; }
.about__portrait {
  position: relative;
  width: min(78%, 340px);
  aspect-ratio: 4 / 5;
  overflow: hidden;
  transform-origin: 50% 50%;
  /* The studio's arched window. */
  border-radius: 50% 50% var(--radius) var(--radius) / 36% 36% var(--radius) var(--radius);
  background: #0f0e0c;
}
.about__portrait picture { display: block; height: 100%; }
.about__portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 26%; }
.about__name {
  display: grid;
  gap: 6px;
  font-family: var(--serif);
  font-size: clamp(1.7rem, 2.3vw, 2.4rem);
  font-weight: 330;
  line-height: 1;
  letter-spacing: -.02em;
}
.about__name span {
  font-family: var(--sans);
  font-size: var(--f-label);
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.about__ledger { display: grid; border-top: 1px solid var(--line); }
.about__ledger div { padding: 16px 0 18px; border-bottom: 1px solid var(--line); display: grid; gap: 6px; }
.about__ledger dt { color: var(--fg-2); font-size: var(--f-label); font-weight: 500; letter-spacing: .08em; text-transform: uppercase; }
.about__ledger dd { font-size: 1.0625rem; }

.about__method {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: clamp(48px, 8vh, 88px);
  padding: clamp(160px, 28vh, 300px) var(--margin) 0;
  align-items: start;
}
.about__creed {
  grid-column: 1 / -1;
  font-family: var(--serif);
  font-size: clamp(3rem, 8.4vw, 9.5rem);
  font-weight: 320;
  line-height: .92;
  letter-spacing: -.04em;
}
.about__creed > span { display: block; }
.about__creed-b { color: var(--accent-ink); }
.about__bias {
  grid-column: 1 / 6;
  font-family: var(--serif);
  font-size: var(--f-lede);
  font-weight: 360;
  line-height: 1.32;
  letter-spacing: -.01em;
  padding-left: 22px;
  border-left: 1px solid var(--accent);
}
.about__notes {
  grid-column: 7 / 13;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gutter);
}
.about__notes p:not(.about__label) { color: var(--fg-2); font-size: var(--f-small); line-height: 1.65; }
.about__label { color: var(--accent-ink); margin-bottom: 10px; }

@media (max-width: 1099px) {
  .about__room { --room-h: auto; position: relative; top: 0; grid-column: 1 / -1; aspect-ratio: 4 / 5; max-height: 86svh; width: 100%; }
  .about__side { grid-column: 1 / -1; grid-row: 2; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); padding: 56px 0 0; align-items: end; }
  .about__bias { grid-column: 1 / -1; }
  .about__notes { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  .about__side { grid-template-columns: 1fr; row-gap: 40px; }
  .about__notes { grid-template-columns: 1fr; row-gap: 28px; }
}

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

.contact { padding-bottom: 0; }
.contact__title {
  padding: 0 var(--margin);
  font-family: var(--serif);
  font-size: clamp(3.3rem, 9.6vw, 11rem);
  font-weight: 320;
  line-height: .9;
  letter-spacing: -.04em;
  max-width: 11ch;
  text-wrap: balance;
}
/* The brass seal. Until (or unless) the live one arrives, the same mark
   stands in flat, in the same brass. */
.contact__seal {
  position: absolute;
  z-index: 0;
  right: var(--margin);
  top: clamp(170px, 24vh, 270px);
  width: clamp(200px, 22vw, 380px);
  aspect-ratio: 6 / 5;
  pointer-events: none;
}
.contact__seal canvas { position: relative; z-index: 1; width: 100%; height: 100%; }
.contact__seal::before {
  content: "";
  position: absolute;
  inset: 16%;
  background: var(--brass);
  -webkit-mask: url("../img/ry-mark.svg") center / contain no-repeat;
  mask: url("../img/ry-mark.svg") center / contain no-repeat;
  opacity: .85;
}
.contact__seal.is-live::before { display: none; }
.contact__title { position: relative; z-index: 1; }
@media (max-width: 900px) {
  .contact__seal { position: relative; right: auto; top: auto; width: min(52vw, 260px); margin: -8px var(--margin) 8px auto; }
}

.contact__lead {
  margin: clamp(28px, 5vh, 52px) var(--margin) 0;
  max-width: 44ch;
  color: var(--fg-2);
  font-size: 1.0625rem;
}
.contact__mail {
  display: grid;
  gap: 8px;
  margin: clamp(56px, 10vh, 120px) var(--margin) 0;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.contact__email {
  justify-self: start;
  font-family: var(--serif);
  font-size: clamp(2.2rem, 7.2vw, 8rem);
  font-weight: 320;
  line-height: 1.02;
  letter-spacing: -.035em;
  color: var(--accent-ink);
  overflow-wrap: anywhere;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 2px no-repeat;
  transition: background-size .7s var(--ease-expo), color .3s ease;
}
.contact__email:hover { background-size: 100% 2px; color: var(--fg); }
.contact__mail-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; margin-top: 12px; }
.copy-button {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: var(--f-small);
  font-weight: 500;
  transition: border-color .3s ease, background-color .3s ease, translate .6s var(--ease-expo);
}
.copy-button:hover { border-color: var(--fg); }
.copy-status { font-size: var(--f-small); color: var(--fg-2); min-height: 1.4em; }

.contact__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 36px;
  margin: 36px var(--margin) 0;
}
.contact__links a {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  min-height: 44px;
  font-weight: 500;
  background: linear-gradient(currentColor, currentColor) 0 calc(50% + .8em) / 0 1px no-repeat;
  transition: background-size .5s var(--ease-expo), color .3s ease;
}
.contact__links a:hover { background-size: 100% 1px; color: var(--accent-ink); }

.contact__brief {
  margin: clamp(56px, 9vh, 96px) var(--margin) 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.contact__brief summary {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px 24px;
  min-height: 72px;
  padding: 16px 0;
  cursor: pointer;
  list-style: none;
}
.contact__brief summary::-webkit-details-marker { display: none; }
.contact__brief summary span {
  font-family: var(--serif);
  font-size: var(--f-h3);
  font-weight: 360;
  letter-spacing: -.02em;
}
.contact__brief summary em { color: var(--fg-2); font-size: var(--f-small); }
.contact__brief summary i {
  position: relative;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 50%;
}
.contact__brief summary i::before,
.contact__brief summary i::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 1.5px;
  background: currentColor;
  translate: -50% -50%;
  transition: transform .5s var(--ease-expo);
}
.contact__brief summary i::after { transform: rotate(90deg); }
.contact__brief[open] summary i::after { transform: rotate(0deg); }

.contact-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px var(--gutter);
  padding: 16px 0 44px;
}
.field { display: grid; gap: 8px; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: var(--f-label); font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); }
.field input,
.field textarea {
  width: 100%;
  padding: 12px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  font-size: 1.0625rem;
  resize: vertical;
  transition: border-color .3s ease;
}
.field input::placeholder,
.field textarea::placeholder { color: var(--fg-2); opacity: .6; }
.field input:focus,
.field textarea:focus { outline: none; border-bottom-color: var(--accent-ink); }
.field input:focus-visible,
.field textarea:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 4px; }
.field-error { display: none; font-size: var(--f-small); color: #E4A48A; }
:root:not([data-tone="night"]) .field-error { color: #9B3B1D; }
.field [aria-invalid="true"] { border-bottom-color: currentColor; }
.field:has([aria-invalid="true"]) .field-error { display: block; }
.form-submit { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 24px; }
#formStatus { font-size: var(--f-small); color: var(--fg-2); max-width: 46ch; }

@media (max-width: 760px) {
  .contact-form { grid-template-columns: 1fr; }
  .contact__brief summary { grid-template-columns: 1fr auto; }
  .contact__brief summary em { grid-column: 1; grid-row: 2; }
  .contact__brief summary i { grid-column: 2; grid-row: 1 / 3; }
}

/* ---------------------------------------------------------------- colophon */

.colophon {
  margin-top: clamp(96px, 16vh, 180px);
  overflow: hidden;
}
.colophon__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 36px;
  padding: 24px var(--margin);
  border-top: 1px solid var(--line);
  font-size: var(--f-small);
  color: var(--fg-2);
}
.colophon__brand { display: inline-flex; align-items: center; gap: 10px; }
.colophon__brand i {
  width: 22px;
  height: 18px;
  background: currentColor;
  -webkit-mask: url("../img/ry-mark.svg") center / contain no-repeat;
  mask: url("../img/ry-mark.svg") center / contain no-repeat;
}
.colophon__support { display: flex; flex-wrap: wrap; align-items: center; gap: 0 20px; }
.colophon__support a,
.colophon__top { display: inline-flex; align-items: center; min-height: 44px; color: var(--fg); }
.colophon__support a:hover,
.colophon__top:hover { color: var(--accent-ink); }
.colophon__mark {
  padding: 0 var(--margin);
  font-family: var(--serif);
  font-size: var(--f-mega);
  font-weight: 300;
  line-height: .74;
  letter-spacing: -.05em;
  white-space: nowrap;
  color: color-mix(in srgb, var(--fg) 7%, var(--bg));
  user-select: none;
  margin-bottom: -.06em;
}
/* Decorative type, drawn from generated content so it is not page text. */
.colophon__mark span { display: block; }
.colophon__mark span::before { content: attr(data-word); }

/* The coda (the studio) is styled in finale.css, shared by every page. */

/* ---------------------------------------------------------------- utilities
   The assistant launcher and the arcade/overlay utilities follow the tone. */

#project-assistant { z-index: 900; }

@media (prefers-reduced-motion: reduce) {
  :root { --tone-time: 0s; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* A software rasterizer receives the static presentation. */
html[data-webgl-fallback="true"] #main-content *,
html[data-webgl-fallback="true"] #hd * {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  filter: none !important;
}

/* ---------------------------------------------------------------- cursor label */

.cursor-label {
  position: fixed;
  z-index: 100005;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 104px;
  height: 104px;
  margin: -52px 0 0 -52px;
  padding: 14px;
  border-radius: 50%;
  background: var(--brass);
  color: var(--graphite);
  font-size: .75rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .02em;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  scale: .2;
  transition: opacity .3s ease, scale .5s var(--ease-expo);
  will-change: translate;
}
.cursor-label.is-on { opacity: 1; scale: 1; }
@media (hover: hover) and (pointer: fine) {
  .motion [data-cursor] { cursor: none; }
}

/* Browsers without cross-document view transitions (Firefox) still see the
   next page arrive rather than appear: a short fade from the paper, set up
   before first paint by a line in each page's head. No fill after it ends,
   so it leaves no stacking context behind. */
@keyframes page-arrive { from { opacity: 0; } }
.no-vt body { animation: page-arrive .5s cubic-bezier(.2, .7, .2, 1) backwards; }
@media (prefers-reduced-motion: reduce) { .no-vt body { animation: none; } }
