/* Joseph Yang. Base: the stacked document underneath. Without JS (or before the app is ready) this is the whole
   site. The .nl rules further down turn it into the flight-plan chart and never remove any of this text. */
a, button { -webkit-tap-highlight-color: transparent; }
@font-face { font-family: "Source Serif 4 Display"; src: url(/fonts/ss4-display-400.woff2) format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Source Serif 4"; src: url(/fonts/ss4-text-400.woff2) format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url(/fonts/plex-sans-400.woff2) format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url(/fonts/plex-sans-500.woff2) format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
/* metric-matched fallbacks, computed with Capsize from the subset files (xWidthAvg, ascent, descent) */
@font-face { font-family: "SS4D Fallback"; src: local("Georgia"); size-adjust: 91.75%; ascent-override: 112.92%; descent-override: 36.51%; line-gap-override: 0%; }
@font-face { font-family: "SS4D Fallback TNR"; src: local("Times New Roman"), local("Liberation Serif"); size-adjust: 100.68%; ascent-override: 102.90%; descent-override: 33.27%; line-gap-override: 0%; }
@font-face { font-family: "SS4 Fallback"; src: local("Georgia"); size-adjust: 100.94%; ascent-override: 102.63%; descent-override: 33.19%; line-gap-override: 0%; }
@font-face { font-family: "SS4 Fallback TNR"; src: local("Times New Roman"), local("Liberation Serif"); size-adjust: 110.77%; ascent-override: 93.53%; descent-override: 30.24%; line-gap-override: 0%; }
@font-face { font-family: "Plex Fallback"; src: local("Arial"), local("Helvetica"), local("Liberation Sans"); size-adjust: 101.17%; ascent-override: 101.32%; descent-override: 27.18%; line-gap-override: 0%; }

:root {
  --ground: #0D0B09; --ground-warm: #14100C; --ground-cool: #0A0D12;
  --ink: #ECE5D8; --ink-2: #B5AC9E; --ink-3: #8A8073; --rule: #2B2620; --rule-2: #3D362E; --dot: rgba(236, 229, 216, .13);
  --amber: #E8A453; --amber-ink: #EDB36E; --amber-core: #FFE3BF; --blue: #7FA9D9; --blue-core: #DCE9F8;
  --display: "Source Serif 4 Display", "SS4D Fallback", "SS4D Fallback TNR", serif;
  --serif: "Source Serif 4", "SS4 Fallback", "SS4 Fallback TNR", serif;
  --sans: "IBM Plex Sans", "Plex Fallback", system-ui, sans-serif;
  /* five steps */
  --t-ui: .8125rem; --lh-ui: 18px; --t-body: 1.125rem; --lh-body: 28px; --t-lead: 1.5rem; --lh-lead: 32px;
  --t-title: 2.5rem; --lh-title: 44px; --t-hero: clamp(3.25rem, 6.6vw, 6rem);
  /* spacing */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px; --s8: 72px; --s9: 112px;
  --m: clamp(24px, 5.5vw, 96px); --g: 24px;
  --ease-out: cubic-bezier(.16, 1, .3, 1); --ease-in: cubic-bezier(.4, 0, 1, 1); --ease-flight: cubic-bezier(.45, 0, .2, 1);
  --d-quick: 120ms; --d-ui: 200ms; --d-panel: 360ms;
  /* hero knobs: --name-en sizes the signature (its width; height = width / 3.077), --name-zh the 楊景鈞 column (one glyph box);
     the column is 1.4502 boxes wide and its ink 3.07 boxes tall. Defaults: signature 940px and column ink 330px at 1440x900. */
  --name-en: min(940px, 65.28vw); --name-zh: min(7.5vw, 12vh); --zh-w: calc(var(--name-zh) * 1.4502); --zh-ink: calc(var(--name-zh) * 3.07);
  --mm-h: 112px;
  --safe-t: env(safe-area-inset-top, 0px); --safe-r: env(safe-area-inset-right, 0px); --safe-b: max(env(safe-area-inset-bottom, 0px), var(--tb, 0px)); --safe-l: env(safe-area-inset-left, 0px);
}
/* short desktop viewports: the signature also scales with the height, so its tail keeps >= 12px clear of the nav (1280x720 -> 752px, 1366x768 -> 803px); 781px and taller unchanged */
@media (min-width: 760px) and (min-height: 500px) and (max-height: 780px) { :root { --name-en: min(940px, 65.28vw, 104.5vh); } }
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--ground); scroll-padding-top: 80px; overscroll-behavior: none; }
body { margin: 0; background: var(--ground); color: var(--ink); font: 400 var(--t-body)/var(--lh-body) var(--serif); font-synthesis: none; font-kerning: normal; font-variant-numeric: oldstyle-nums proportional-nums; overflow-x: hidden; }
h1, h2, h3, h4, p { margin: 0; font-weight: 400; }
h1, h2, h3, h4 { text-wrap: balance; }
p { text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: var(--ink-2); text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: rgba(232, 164, 83, .6); text-underline-offset: .25em; transition: color var(--d-quick), text-decoration-color var(--d-quick); }
@media (hover: hover) { a:hover { color: var(--ink); text-decoration-color: var(--amber-ink); } }
a:focus-visible { color: var(--ink); text-decoration-color: var(--amber-ink); }
:focus-visible { outline: 2px solid var(--amber-ink); outline-offset: 3px; border-radius: 2px; }
[tabindex="-1"]:focus { outline: none; }
.skip { position: absolute; left: var(--m); top: -64px; z-index: 60; background: var(--ink); color: var(--ground); padding: var(--s2) var(--s3); border-radius: 2px; text-decoration: none; font: 500 var(--t-ui)/var(--lh-ui) var(--sans); }
.skip:focus { top: var(--s4); }
.nowrap { white-space: nowrap; }
.sep { display: none; }
.vh { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.field, .nl-only { display: none; }
.ui, .bar, .index, .foot, .crumb, .soon, .status, .t-when, .tag, .kick, .where, .pn, .route, .skip { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-variant-numeric: lining-nums tabular-nums; }

/* ---- type roles ---- */
.hero h1 { font: 400 var(--t-hero)/.94 var(--display); letter-spacing: -.022em; margin-bottom: var(--s5); }
.lede { font: 400 var(--t-lead)/var(--lh-lead) var(--serif); max-width: 22ch; text-wrap: balance; margin-bottom: var(--s5); hanging-punctuation: first; }
.links { display: flex; flex-wrap: wrap; column-gap: var(--s5); }
.links a { display: inline-flex; align-items: center; min-height: 44px; }
.links a { position: relative; }
.links a::after { content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: max(100%, 44px); transform: translateX(-50%); }   /* a 44px target for the short X link, without moving it */
.hero .links { margin-top: var(--s5); }
main section h2 { font: 400 var(--t-title)/var(--lh-title) var(--display); letter-spacing: -.01em; margin-bottom: var(--s4); }
main section h2#work-title, .kick, .tag, .t-when, .where { font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; color: var(--ink-3); }
main section h2#work-title { margin-bottom: var(--s3); }
.kick, .tag, .where { margin-bottom: var(--s3); }
.school h3 { font: 400 var(--t-lead)/var(--lh-lead) var(--serif); margin-bottom: var(--s2); transition: color 240ms; }
.school p { color: var(--ink-2); transition: color 240ms; }
main section .school p + p { margin-top: 0; }
.school + .school { margin-top: var(--s6); }
.org h3, .leg > h3, main h4 { font: 400 var(--t-title)/var(--lh-title) var(--display); letter-spacing: -.01em; margin-bottom: var(--s4); }
.org-role { color: var(--ink-2); margin-bottom: var(--s4); }
.org-sum { color: var(--ink-2); max-width: 34rem; }
.nl .org-role .rl { display: block; }   /* r12: desktop stacks the three Shift roles, one per line */
.nl .org-role .sl { display: none; }
.t-when { margin-bottom: var(--s3); }
main section p + p { margin-top: var(--s4); }
.more { margin-top: var(--s6) !important; }
.big { font: 400 var(--t-lead)/var(--lh-lead) var(--serif); max-width: 28rem; hanging-punctuation: first; }
main section .big + p { margin-top: var(--s5); }
main section p { max-width: 34rem; }
.leg-body, .leg + .leg { margin-top: var(--s7); }
.soon, .status { display: block; margin-top: var(--s2); font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; color: var(--ink-3); }
#contact .links { margin-top: var(--s6); }
#contact .links li:first-child { flex-basis: 100%; }
#contact .links li:first-child a { font: 400 var(--t-lead)/var(--lh-lead) var(--serif); color: var(--amber-ink); }
@media (hover: hover) { #contact .links li:first-child a:hover { color: var(--amber-core); } }
#contact .links li:first-child a:focus-visible { color: var(--amber-core); }
.foot { display: flex; flex-wrap: wrap; gap: 0 var(--s4); font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; color: var(--ink-3); }
.foot p { margin: 0; }

/* ---- stacked document (no JS, and the base the chart sits on) ---- */
.bar { position: sticky; top: 0; z-index: 30; background: rgba(13, 11, 9, .94); border-bottom: 1px solid var(--rule); }
.bar-in { padding: 0 var(--m); display: flex; align-items: center; gap: var(--s5); height: 64px; }
.mark { color: var(--ink); text-decoration: none; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; margin-left: -7px; }
.mark svg { display: block; }
.bar ul { margin-left: auto; display: flex; gap: 28px; }
.bar ul a { display: flex; align-items: center; min-height: 44px; font: 400 .875rem/1 var(--sans); color: var(--ink-2); text-decoration: none; white-space: nowrap; }
@media (hover: hover) { .bar ul a:hover { color: var(--ink); } }
.bar ul a[aria-current] { color: var(--ink); text-decoration: underline; text-decoration-color: var(--ink-3); text-underline-offset: 6px; }
.hero { padding: var(--s9) var(--m) var(--s8); }
main { padding: 0 var(--m); }
main > section { padding: var(--s8) 0; max-width: 34rem; }
.no-js main > section + section, html:not(.nl) main > section + section { border-top: 0; }
html:not(.nl) .foot { padding: var(--s7) var(--m) var(--s8); }

/* ---- interior pages: writing index, essay, 404 ---- */
html:has(.page-head), body:has(.page-head) { min-height: 100vh; min-height: 100dvh; }
body:has(.page-head) { display: flex; flex-direction: column; background: radial-gradient(circle at 1px 1px, var(--dot) 1px, transparent 1.4px) 0 0 / 26px 26px, var(--ground); }
body:has(.page-head) main.page-body { flex: 1; }
.page-head, main.page-body, .site-footer { width: 100%; padding-left: var(--m); padding-right: var(--m); }
.page-head .wrap, .page-body .wrap, .site-footer .wrap { max-width: 34rem; }
.page-head { padding-top: var(--s9); padding-bottom: var(--s7); }
.page-head nav { margin-bottom: var(--s6); }
.crumb { font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; }
.crumb a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink-2); }
.page-head h1 { font: 400 var(--t-title)/var(--lh-title) var(--display); letter-spacing: -.01em; margin-bottom: var(--s4); }
.page-head .lede { color: var(--ink-2); max-width: 28rem; margin-bottom: 0; }
main.page-body { padding-bottom: var(--s8); }
main.page-body p + p { margin-top: var(--s4); }
.entry { padding: var(--s5) 0; }
.entry:first-child { padding-top: 0; }
.entry h2 { font: 400 var(--t-lead)/var(--lh-lead) var(--serif); margin-bottom: var(--s3); }
.entry h2 a { color: var(--ink); }
.entry p { color: var(--ink-2); }
.site-footer { padding-bottom: var(--s7); }
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: 0 var(--s4); padding-top: var(--s6); border-top: 1px solid var(--rule); font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; color: var(--ink-3); -webkit-font-smoothing: antialiased; font-variant-numeric: lining-nums tabular-nums; }
.site-footer p { margin: 0; }
.page-body .sep + a, .page-body a + .sep { margin-left: var(--s5); }
.page-head::before { content: ""; display: block; width: min(16rem, 60%); height: 34px; margin-bottom: var(--s5);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 34'%3E%3Cpath d='M5 28 C70 30 90 6 150 12' fill='none' stroke='%23E8A453' stroke-opacity='.6' stroke-width='1.25'/%3E%3Cpath d='M150 12 C190 16 220 17 250 6' fill='none' stroke='%237FA9D9' stroke-opacity='.45' stroke-width='1' stroke-dasharray='2 4'/%3E%3Cpath d='M5 22 V34' stroke='%23E8A453' stroke-width='1.25'/%3E%3Ccircle cx='250' cy='6' r='3' fill='%230D0B09' stroke='%237FA9D9' stroke-width='1.25'/%3E%3C/svg%3E") 0 0 / 100% 100% no-repeat; }

/* =================== the chart (.nl, desktop first) =================== */
.nl, .nl body { height: 100%; height: 100dvh; overflow: hidden; }
.nl .field { display: block; position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; }
.nl .nl-only { display: revert; }
.nl .vh.nl-only { display: block; }
.nl .mm { display: none; }
.nl .bar { position: fixed; left: 0; right: 0; top: 0; background: transparent; border: 0; transition: background-color var(--d-ui); }
.nl.ready:not([data-at="top"]) .bar { background: rgba(13, 11, 9, .94); }
/* the calligraphy intro: two canvases over the chart, under the hero text */
.nl .ink { display: block; position: fixed; inset: 0; z-index: 1; pointer-events: none; transition: opacity var(--d-ui); }
.nl .ink canvas { position: absolute; left: 0; top: 0; }
.nl.ready:not([data-at="top"]) .ink { opacity: 0; }
.nl .strip { position: fixed; inset: 0; z-index: 2; pointer-events: none; }
.nl .zone { display: none; }
.nl .hero { position: absolute; left: 0; top: 0; bottom: 0; width: calc(50% - 12px); margin: 0; padding: 0 0 8svh var(--m); display: flex; flex-direction: column; justify-content: center; transition: opacity var(--d-panel) var(--ease-out), transform var(--d-panel) var(--ease-out); }
.nl .hero a { pointer-events: auto; }
.nl.ready:not([data-at="top"]) .hero { opacity: 0; transform: translateX(-16px); transition-duration: var(--d-ui); transition-timing-function: var(--ease-in); }
.nl.ready:not([data-at="top"]) .hero a { pointer-events: none; }
.nl:not(.ready):has(main :target) .hero { opacity: 0; }
/* the signature replaces the visible h1 (the h1 stays for screen readers); without the intro assets the h1 shows */
.nl .sig { display: block; width: var(--name-en); max-width: none; aspect-ratio: 1880 / 611; margin: 0 0 var(--s6); }
.nl .hero .lede { font-size: 1.875rem; line-height: 1.32; max-width: 560px; text-wrap: wrap; }
/* round 8 (Joseph): a soft scrim under the one-liner and links (not the signature), so the map sits a step darker behind the text; desktop only */
@media (min-width: 760px) and (min-height: 500px) {
  .nl .hero-copy { position: relative; }
  .nl .hero-copy::before { content: ""; position: absolute; z-index: -1; pointer-events: none; left: calc(-1 * var(--m)); right: -96px; top: calc(var(--name-en) * 611 / 1880 + var(--s6) - 20px); bottom: -28px; background: var(--ground); opacity: .72;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 160px), transparent), linear-gradient(transparent, #000 28px, #000 calc(100% - 36px), transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, #000 calc(100% - 160px), transparent), linear-gradient(transparent, #000 28px, #000 calc(100% - 36px), transparent); mask-composite: intersect; }
}
.nl:not(.ink-fail) .hero h1 { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }
.nl.ink-fail .sig { display: none; }
.nl.ink-play .late, .nl.ink-play .bar { visibility: hidden; opacity: 0; }
.nl.ink-play.handoff .late, .nl.ink-play.handoff .bar { visibility: visible; opacity: 1; transition: opacity 600ms var(--ease-out); }
.nl.ink-play.handoff .bar { transition: opacity 600ms var(--ease-out), background-color var(--d-ui); }
.start-p { margin-top: var(--s6); }
.start { display: inline-flex; align-items: center; min-height: 44px; font: 500 .875rem/1 var(--sans); color: var(--ink-2); text-decoration-color: rgba(232, 164, 83, .6); }
.nl main { position: absolute; inset: 0; margin: 0; padding: 0; pointer-events: none; }
.nl main > section { position: absolute; top: 22svh; bottom: 112px; left: calc(50% + 12px); right: var(--m); max-width: 34rem; padding: 0 var(--s2) var(--s6) 0; overflow-y: auto; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 32px), transparent); mask-image: linear-gradient(#000 calc(100% - 32px), transparent);
  opacity: 0; visibility: hidden; transition: opacity 160ms var(--ease-in), visibility 0s linear 160ms; }
.nl main > section::-webkit-scrollbar { display: none; }
.nl main > section.on, .nl:not(.ready) main > section:is(:target, :has(:target)) { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity var(--d-panel) var(--ease-out), visibility 0s; }
@keyframes pin { from { opacity: 0; transform: translateY(6px); } }
/* back on the landing the section panel and the stop readout leave at once: no Education fading under the hero (the round-4 "ghost") */
@media (min-width: 760px) and (min-height: 500px) { .nl.ready[data-at="top"] main > section, .nl.ready[data-at="top"] .route { opacity: 0; visibility: hidden; transition: none; } }
.nl main > section.on > * { animation: pin var(--d-panel) var(--ease-out) both; }
.nl main > section.on > :nth-child(2) { animation-delay: 50ms; }
.nl main > section.on > :nth-child(n+3) { animation-delay: 100ms; }
.nl.rm main > section.on > *, .nl.rm main > section.on .leg > * { animation: none !important; }
/* place kickers: two words share one slot and crossfade when the stop changes inside a panel */
.nl .where { position: relative; }
.nl .where .w1, .nl .where .w2 { transition: opacity 240ms; }
.nl .where .w2 { position: absolute; left: 0; top: 0; opacity: 0; }
.nl #education[data-stop="sv"] .w1, .nl #work[data-stop="gen2"] .w1 { opacity: 0; }
.nl #education[data-stop="sv"] .w2, .nl #work[data-stop="gen2"] .w2 { opacity: 1; }
.nl .where-sv, .nl .where-g2 { display: none; }
/* Education: Taiwan and Silicon Valley share the panel; the school of the current stop is the emphasized one */
/* Work: two stops in one panel. The kicker and the org block stay put; only the leg body changes. */
.nl #work-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }
.nl #work.on { animation: none; }
.nl #work.on > .leg { animation: none; }
.nl #work .leg { display: none; margin: 0; }
.nl #work[data-stop="moon"] #moonwalkers, .nl #work[data-stop="gen2"] #moonwalkers, .nl #work[data-stop="gen2"] #second-generation { display: block; }
.nl #work[data-stop="gen2"] #moonwalkers .leg-body { display: none; }
.nl #work #second-generation { margin-top: var(--s7); }
.nl #work .org, .nl #work .leg-body > *, .nl #work #second-generation > * { animation: pin var(--d-panel) var(--ease-out) both; transition: opacity 160ms var(--ease-in); }
.nl #work .org > :nth-child(2), .nl #work .leg-body > :nth-child(2), .nl #work #second-generation > h4 { animation-delay: 50ms; }
.nl #work .org > :nth-child(n+3), .nl #work .leg-body > :nth-child(n+3), .nl #work #second-generation > p { animation-delay: 100ms; }
.nl #work .fade { opacity: 0 !important; }
/* contact: centred on the seam */
.nl main > #contact { left: 50%; right: auto; width: min(30rem, calc(100% - 2 * var(--m))); max-width: none; transform: translateX(-50%); top: calc(34svh + 72px); bottom: 64px; padding: 0; text-align: center; overflow: visible; -webkit-mask-image: none; mask-image: none; }
.nl #contact .big { margin: 0 auto; }
.nl #contact .links { justify-content: center; }
@media (max-height: 759px) { .nl main > #contact { top: calc(28svh + 64px); } }

/* mini-map (Route), bottom left; hidden on the hero */
.nl .route { position: fixed; z-index: 4; left: var(--m); bottom: 56px; width: 280px; height: 96px; transition: opacity 300ms, visibility 0s; }
.nl[data-at="top"] .route { opacity: 0; visibility: hidden; transition: opacity 300ms, visibility 0s linear 300ms; }
.route svg { position: absolute; inset: 0; width: 280px; height: 96px; overflow: visible; }
.route .coast circle { fill: rgba(236, 229, 216, .34); }
.route .ahead { fill: none; stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 2 3; }
.route .flown { fill: none; stroke: var(--amber); stroke-width: 1; }
.route ol { position: absolute; inset: 0; }
.route a { position: absolute; left: calc(var(--x, 0) * 1px - 12px); top: calc(var(--y, 0) * 1px - 12px); width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; color: var(--ink-3); text-decoration: none; }
.route a::before { content: ""; box-sizing: border-box; width: 5px; height: 5px; border: 1px solid currentColor; border-radius: 50%; background: var(--ground); transition: all var(--d-ui); }
.route a[aria-current]::before { width: 6px; height: 6px; border: 0; background: var(--amber); box-shadow: 0 0 0 4px var(--ground), 0 0 0 5px rgba(232, 164, 83, .3); }
.route a[aria-current][data-go="contact"]::before { background: var(--blue); box-shadow: 0 0 0 4px var(--ground), 0 0 0 5px rgba(127, 169, 217, .3); }
.route a span { position: absolute; bottom: calc(100% - 4px); left: 50%; transform: translateX(-50%); padding: var(--s1) var(--s2); background: var(--ground); color: var(--ink); font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity var(--d-ui); }
@media (hover: hover) { .route a:hover span { opacity: 1; } .route a:hover { color: var(--ink); } }
.route a:focus-visible span { opacity: 1; }
.route.tipoff a span { opacity: 0 !important; }
/* the current stop is already named by the readout underneath: no second, hovering copy of it (it read as a ghost of the readout) */
.route a[aria-current] span { display: none; }
.route-read { position: absolute; left: 0; top: calc(100% + 6px); display: flex; gap: var(--s3); margin: 0; font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; white-space: nowrap; transition: opacity var(--d-ui); }
.route-read b { font-weight: 500; color: var(--ink); }
.route-read span { color: var(--ink-2); }
.route-read.swap { opacity: 0; transition: none; }
.route-read.hide { visibility: hidden; }
/* previous / next, on the column-7 line, sharing the readout's baseline */
.nl .pn { position: fixed; z-index: 4; left: calc(50% + 12px); bottom: 19px; display: flex; gap: var(--s6); transition: opacity var(--d-ui); }
.nl[data-at="top"] .pn { visibility: hidden; opacity: 0; }
.nl[data-at="contact"] .pn { left: calc(50% + 32px); }
.nl .pn.fly { opacity: .5; }
.pn a { display: inline-flex; align-items: center; min-height: 44px; font: 500 var(--t-ui)/var(--lh-ui) var(--sans); letter-spacing: .01em; color: var(--ink-2); text-decoration-color: var(--rule-2); pointer-events: auto; }
@media (hover: hover) { .pn a:hover { text-decoration-color: var(--amber); } }
.pn a:focus-visible { text-decoration-color: var(--amber); }
.pn a[hidden] { display: none; }

.nl .foot { position: fixed; z-index: 3; right: var(--m); bottom: 32px; margin: 0; padding: 0; opacity: 0; transition: opacity 400ms; pointer-events: none; }
.nl .foot.on { opacity: 1; }

/* =================== phone (round 9; r11; r12b): one plain document. A text bar, the name lockup, one map =================== */
@media (max-width: 759px), (max-height: 499px) {
  :root { --t-body: 1.125rem; --lh-body: 29px; --t-lead: 1.3125rem; --lh-lead: 30px; --t-title: 2.125rem; --lh-title: 38px; --t-hero: 3.25rem; --pl: max(20px, var(--safe-l)); --pr: max(20px, var(--safe-r)); }
  html.ph { --mh: max(190px, 28svh); scroll-padding-top: calc(52px + var(--safe-t) + var(--mh)); }
  @media (orientation: landscape) { html.ph { --mh: 42svh; } }   /* r11: landscape, a short strip across the top */
  /* r11: the one map, pinned under the bar; the text scrolls beneath it */
  .ph .pmap { position: sticky; top: calc(44px + var(--safe-t)); z-index: 20; box-sizing: border-box; height: var(--mh); margin: 28px 0 0; padding: 0 var(--safe-r) 0 var(--safe-l); background: var(--ground); border-bottom: 1px solid var(--rule); }
  .ph .pmap canvas, .ph .pfull canvas { display: block; width: 100%; height: 100%; background: #0D0B09; -webkit-tap-highlight-color: transparent; }
  /* r12b: the upright landing map (phone.js) */
  .ph .pfull { display: none; }
  .ph.fl .pfull { display: block; position: fixed; z-index: 0; left: 0; right: 0; top: 0; height: 100lvh; padding: 0 var(--safe-r) 0 var(--safe-l); pointer-events: none; }
  .ph.fl.pin .pfull { z-index: 21; top: calc(44px + var(--safe-t)); height: calc(var(--mh) - 1px); pointer-events: auto; }
  .ph.fl:not(.pin) .pmap { visibility: hidden; }
  .ph.fl .hero, .ph.fl main { position: relative; z-index: 1; }
  .ph.fl .hero { box-sizing: border-box; min-height: calc(100lvh - var(--mh) - 73px - var(--safe-t)); }
  @media (prefers-reduced-motion: no-preference) { html.ph { scroll-behavior: smooth; } }
  .ph .sen { position: absolute; top: 8px; left: 0; width: 1px; height: 1px; pointer-events: none; }
  .ph .bar { padding-top: var(--safe-t); background: transparent; border-bottom-color: transparent; transition: background-color 160ms, border-color 160ms; }
  .ph .bar.solid { background: var(--ground); border-bottom-color: var(--rule); }
  .ph .bar-in { height: 44px; padding: 0 var(--pr) 0 var(--pl); gap: 0; }
  .ph .mark { display: none; }
  .ph .bar ul { flex: 1; margin: 0; justify-content: space-between; gap: 0 8px; overflow-x: auto; scrollbar-width: none; }
  .ph .bar ul::-webkit-scrollbar { display: none; }
  .ph .bar ul.overflows { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 16px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 16px), transparent); }
  .ph .bar li { flex: none; }
  .ph .bar ul a { justify-content: center; min-width: 44px; font: 500 15px/20px var(--sans); color: var(--ink-2); }
  .ph .bar ul a[aria-current] { color: var(--ink); text-decoration: underline 1px var(--amber); text-underline-offset: 6px; }
  .ph .hero { padding: 24px var(--pr) 0 var(--pl); }
  .ph .hero-copy { max-width: 34em; }
  /* the lockup box (see geom() in phone.js) */
  .ph .sig { display: block; position: relative; width: min(100%, 420px); aspect-ratio: 2.286; }
  .ph .ink { display: block; position: absolute; left: -10px; top: -10px; pointer-events: none; }
  .ph:not(.ink-fail) .hero h1 { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .ph.ink-fail .sig { display: none; }
  .ph .hero .lede { margin: 20px 0 0; font: 400 1.5rem/32px var(--serif); max-width: 20ch; }
  .ph .where, .ph .t-when, .ph main section h2#work-title { font: 500 15px/20px var(--sans); letter-spacing: .01em; color: var(--ink-2); }
  .ph .links { column-gap: 24px; }
  .ph .links a { font: 400 18px/24px var(--sans); }
  .ph .hero .links { margin-top: 16px; }
  .ph main { padding: 24px var(--pr) 0 var(--pl); }
  .ph main > section { max-width: 34em; padding: 0 0 56px; }
  /* r10: the bar's marker, a 1px amber line that slides to the current link */
  .ph .bar ul.mk-on { position: relative; }
  .ph .bar ul.mk-on a[aria-current] { text-decoration: none; }
  .ph .bar .mk { position: absolute; left: 0; bottom: 6px; width: 1px; height: 1px; background: var(--amber); transform-origin: 0 0; pointer-events: none; opacity: 0; }
  .ph .bar .mk.on { opacity: 1; }
  .ph.mo .bar .mk.go { transition: transform 280ms cubic-bezier(.2, .7, .2, 1); }
  /* r10: section headings fade up (html.mo; never under reduced motion) */
  .ph.mo .rise { opacity: 0; transform: translateY(12px); }
  .ph.mo .rise.in { opacity: 1; transform: none; transition: opacity 420ms cubic-bezier(.16, 1, .3, 1), transform 420ms cubic-bezier(.16, 1, .3, 1); }
  .ph.mo .rise.in.hd { transition-delay: 60ms; }
  .ph.mo .rise.in.now { transition: none; }
  .ph .where, .ph .t-when { margin-bottom: 6px; }
  .ph .where .w2 { display: none; }
  .ph main section h2 { font: 400 2.125rem/38px var(--display); margin-bottom: 8px; }
  .ph main section h2#work-title { margin-bottom: 0; }
  .ph .school h3, .ph main h4 { font: 400 1.5rem/30px var(--serif); margin-bottom: 8px; }
  .ph .org h3, .ph #second-generation h4 { font: 400 1.75rem/34px var(--display); margin-bottom: 8px; }
  .ph .school p, .ph .org-role, .ph .org-sum { font-size: 1.125rem; line-height: 28px; color: var(--ink-2); }   /* r10: body text >= 18px */
  .ph body { overflow-x: clip; }   /* r10: no scroll container above the sticky bar (hidden computes overflow-y to auto) */
  .ph .more a { display: inline-flex; align-items: center; min-height: 44px; margin-block: -8px; }   /* r10: a 44px target, the line box unchanged */
  .ph .skip { display: inline-flex; align-items: center; min-height: 44px; box-sizing: border-box; }
  .ph .org-role { margin-bottom: 8px; }
  .ph .school + .school, .ph .leg + .leg { margin-top: 48px; }
  .ph .leg-body { margin-top: 32px; }
  .ph main section p + p, .ph main section .big + p { margin-top: 18px; }
  .ph .big { font: 400 1.3125rem/30px var(--serif); }
  .ph .more { margin-top: 18px !important; }
  .ph #work .leg:first-child { margin-top: 20px; }
  .ph #contact .links { margin-top: 20px; }
  .ph #contact .links li:first-child a { font: 400 1.3125rem/30px var(--serif); }
  .ph .foot { padding: 0 var(--pr) calc(48px + env(safe-area-inset-bottom, 0px)) var(--pl); font-size: 15px; line-height: 20px; color: var(--ink-2); }
}
@media (max-height: 499px) {
  .ph .sig { max-width: 457px; }
  :root { --pl: max(24px, var(--safe-l)); --pr: max(24px, var(--safe-r)); }
}
@media (prefers-reduced-motion: reduce) {
  .nl .hero { transform: none; transition: opacity 200ms linear !important; }
  .nl main > section { transform: none; transition: opacity 200ms linear, visibility 0s linear 200ms !important; }
  .nl main > section.on { transition: opacity 200ms linear, visibility 0s !important; }
  .nl.ready[data-at="top"] main > section { transition: none !important; }
  .nl main > #contact { transform: translateX(-50%); }
  .nl main section *, .nl #work .leg > * { animation: none !important; }
}
.nl main > #contact.on > .links { animation: none; }
.nl main > #contact.on > :nth-child(2) { animation-delay: 60ms; }
.nl main > #contact.on .links li { animation: pin var(--d-panel) var(--ease-out) 120ms both; }
.nl main > #contact.on .links li + li { animation-delay: 180ms; }
/* desktop polish (launch night): desktop-only (.nl), so phones (.ph) render exactly as r10 */
@media (min-width: 760px) and (min-height: 500px) and (max-height: 860px) { .nl main > section:not(#contact) { top: 18svh; bottom: 88px; } }   /* 1: short screens get a taller panel, so the last line of each stop is not clipped (1280x800 Gen2) */
.nl .pn a { gap: .3em; }   /* 2: space between the arrows and their labels */
.nl .route a[aria-current] span { display: block; opacity: 0 !important; }   /* 3: the current route link keeps its accessible name; it still shows no hovering label */
.nl .route-read b:empty { display: none; }   /* 4: Contact readout starts on the margin */
.nl .bar ul a { padding: 0 10px; margin: 0 -10px; }   /* 6: focus ring clear of the text; links do not move */
.nl .bar ul a:focus-visible { outline-offset: -4px; }
.nl #contact .big { text-wrap: balance; }   /* 7: no short last line; wording unchanged */
/* r12e: short screens: lockup below the bar */
@media (max-height: 699px) { .nl { --name-en: min(940px, 65.28vw, 92vh, (100vh - 385px) * 3.077); } .nl .hero { justify-content: flex-start; padding-top: 66px; } }
@media (min-height: 781px) { .nl .hero { padding-bottom: calc(8svh + 78px); } }
