/* davidngo.com · site.css · 261013 · v1.1
   Builds on tokens.css (the design language). Nothing here overrides a token. */

/* --- Fonts: IBM Plex, self-hosted, latin subset --- */
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/ibm-plex-sans-latin-400-normal.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url(fonts/ibm-plex-sans-latin-500-normal.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url(fonts/ibm-plex-sans-latin-600-normal.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url(fonts/ibm-plex-mono-latin-500-normal.woff2) format("woff2")}

/* Tokens v1.1 (261015) supply --dn-photon-display, --dn-t-hero, --dn-t-label, --dn-ease and --dn-dur-*.
   Nothing site-level is defined here any more. */

/* --- Base --- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:72px}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;font-size:var(--dn-t-body);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3{margin:0}
p{margin:0;max-width:65ch}
ul,ol{margin:0;padding-left:1.15em;max-width:65ch}
li{margin:0 0 6px}
li::marker{color:var(--dn-muted)}
a:focus-visible,button:focus-visible{outline:2px solid var(--dn-photon);outline-offset:3px;border-radius:var(--dn-radius)}
.wrap{max-width:72rem;margin-inline:auto;padding-inline:clamp(16px,4vw,48px)}
.mono{font-family:var(--dn-font-mono)}
.lead{font-size:var(--dn-t-lead);color:var(--dn-ink-2);max-width:60ch;line-height:1.45}
.muted{color:var(--dn-muted)}
.skip{position:absolute;left:-999px;top:8px;z-index:20;background:var(--dn-ink);color:var(--dn-paper);padding:8px 12px;border-radius:var(--dn-radius);text-decoration:none}
.skip:focus{left:16px}

/* --- Nav --- */
.nav{position:sticky;top:0;z-index:10;background:var(--dn-paper);border-bottom:var(--dn-rule) solid var(--dn-hairline)}
.nav .wrap{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:56px}
.lockup{display:inline-flex;align-items:center;gap:12px;color:var(--dn-ink);text-decoration:none;font-weight:500}
.lockup svg{display:block;height:22px;width:auto;flex:none}
.nav nav{display:flex;align-items:center;gap:20px;flex:none}
.nav-links{list-style:none;margin:0;padding:0;display:flex;gap:20px;flex-wrap:nowrap;align-items:center;font-family:var(--dn-font-mono);font-size:var(--dn-t-label);letter-spacing:var(--dn-track-label);text-transform:uppercase;max-width:none}
.nav-links a{color:var(--dn-muted);text-decoration:none;padding-block:4px}
.nav-links a:hover{color:var(--dn-ink)}
.theme{font:500 var(--dn-t-label)/1 var(--dn-font-mono);letter-spacing:var(--dn-track-label);text-transform:uppercase;color:var(--dn-muted);background:transparent;border:var(--dn-rule) solid var(--dn-hairline);border-radius:var(--dn-radius);padding:7px 10px;cursor:pointer}
.theme:hover{color:var(--dn-ink);border-color:var(--dn-ink)}
@media (max-width:640px){.nav-links{display:none}}

/* --- Hero --- */
.hero{position:relative;overflow:hidden}
.hero .wrap{position:relative;padding-block:clamp(40px,7vw,88px) clamp(40px,6vw,64px);display:grid;gap:20px}
.grating{position:absolute;top:0;bottom:0;right:0;width:min(33%,600px);background:var(--dn-ink);opacity:.085;pointer-events:none;
  -webkit-mask:url(grating.svg) left top/600px auto repeat-y;mask:url(grating.svg) left top/600px auto repeat-y}
@media (max-width:900px){.grating{display:none}}
.hero h1{font-size:clamp(38px,6.2vw,var(--dn-t-hero));font-weight:600;line-height:1.05;letter-spacing:var(--dn-track-display);max-width:16ch;text-wrap:balance}
.hero h1 .photon{color:var(--dn-photon-display)}
.hero .dn-coupler{max-width:28rem;margin-block:4px}
.now{display:grid;grid-template-columns:max-content 1fr;gap:8px 24px;margin:24px 0 0;max-width:62ch}
.now dt{font-family:var(--dn-font-mono);font-size:var(--dn-t-caption);letter-spacing:var(--dn-track-label);text-transform:uppercase;color:var(--dn-muted);padding-top:3px}
.now dd{margin:0}
@media (max-width:480px){.now{grid-template-columns:1fr;gap:2px 0}.now dt{padding-top:10px}}

/* --- Stats --- */
.stats{list-style:none;margin:0;max-width:none;padding:28px 0;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:24px 32px;border-top:var(--dn-rule) solid var(--dn-hairline);border-bottom:var(--dn-rule) solid var(--dn-hairline)}
.stats li{display:grid;gap:6px}
.stats b{font-size:var(--dn-t-h1);font-weight:600;line-height:1;letter-spacing:var(--dn-track-display);font-variant-numeric:tabular-nums}
.stats span{font-family:var(--dn-font-mono);font-size:var(--dn-t-label);letter-spacing:var(--dn-track-label);text-transform:uppercase;color:var(--dn-muted)}

/* --- Sections --- */
.s{padding-block:clamp(48px,7vw,72px);border-top:var(--dn-rule) solid var(--dn-hairline)}
.s:first-of-type{border-top:0}
.head{display:grid;gap:12px;margin-bottom:32px}
.head h2{font-size:clamp(26px,3.4vw,31px);font-weight:600;line-height:1.15;letter-spacing:var(--dn-track-display);text-wrap:balance}
.head .lead{margin-top:8px}
h3{font-size:20px;font-weight:600;line-height:1.25;letter-spacing:var(--dn-track-display)}
.kv{display:grid;grid-template-columns:max-content 1fr;gap:10px 24px;margin:0;max-width:65ch}
.kv dt{font-family:var(--dn-font-mono);font-size:var(--dn-t-caption);letter-spacing:var(--dn-track-label);text-transform:uppercase;color:var(--dn-muted);padding-top:3px}
.kv dd{margin:0}
@media (max-width:480px){.kv{grid-template-columns:1fr;gap:2px 0}.kv dt{padding-top:12px}}
.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.grid>*{min-width:0}
.dn-panel{display:grid;gap:10px;align-content:start;padding:20px}
.dn-panel p{max-width:none}
.two{display:grid;gap:40px;grid-template-columns:5fr 7fr;align-items:start}
.two>*{min-width:0}
@media (max-width:860px){.two{grid-template-columns:1fr;gap:32px}}
.prose{display:grid;gap:16px}

/* --- Timeline --- */
.tl{list-style:none;margin:0;padding:0;max-width:none;border-top:var(--dn-rule) solid var(--dn-hairline)}
.tl>li{position:relative;display:grid;grid-template-columns:11rem minmax(0,65ch);gap:6px 32px;padding-block:24px;border-bottom:var(--dn-rule) solid var(--dn-hairline);margin:0}
.tl .meta{display:grid;gap:4px;align-content:start;padding-top:3px}
.tl .when{font-family:var(--dn-font-mono);font-size:var(--dn-t-caption);color:var(--dn-muted);font-variant-numeric:tabular-nums}
.tl .org{font-weight:500;color:var(--dn-ink)}
.tl .org small{display:block;font-weight:400;font-size:14px;color:var(--dn-muted)}
.tl p{margin-top:6px;color:var(--dn-ink-2)}
.tl ul{margin-top:8px}
.tl li li{display:block;padding:0;border:0;margin:0 0 6px}
@media (max-width:640px){.tl>li{grid-template-columns:1fr;gap:4px}.tl .meta{gap:2px;margin-bottom:6px}.tl .org small{display:inline}.tl .org small::before{content:" · "}}

/* --- Figure --- */
figure{margin:0;display:grid;gap:10px;min-width:0}
figcaption{font-family:var(--dn-font-mono);font-size:var(--dn-t-label);letter-spacing:var(--dn-track-label);text-transform:uppercase;color:var(--dn-muted)}
.fig{background:var(--dn-surface);border:var(--dn-rule) solid var(--dn-hairline);border-radius:var(--dn-radius);padding:20px}
.diagram{display:grid;grid-template-columns:minmax(0,15rem) minmax(0,1fr);column-gap:32px;row-gap:0;align-items:center;font-family:var(--dn-font-mono)}
.diagram .n{grid-column:1;position:relative;border:1.5px solid var(--dn-ink);border-radius:var(--dn-radius);padding:10px 12px;margin-bottom:30px;display:grid;gap:3px}
.diagram .n:nth-of-type(1){grid-row:1}.diagram .n:nth-of-type(2){grid-row:3}.diagram .n:nth-of-type(3){grid-row:5}.diagram .n:nth-of-type(4){grid-row:7}.diagram .n:nth-of-type(5){grid-row:9;margin-bottom:0}
.diagram .n b{font-weight:500;font-size:12.5px;letter-spacing:var(--dn-track-label);text-transform:uppercase}
.diagram .n span{font-size:12px;color:var(--dn-muted)}
.diagram .n:not(:nth-of-type(5))::after{content:"";position:absolute;left:50%;top:100%;width:1.5px;height:21px;background:var(--dn-ink)}
.diagram .n:not(:nth-of-type(5))::before{content:"";position:absolute;left:50%;top:calc(100% + 21px);transform:translateX(-50%);border-left:5px solid transparent;border-right:5px solid transparent;border-top:8px solid var(--dn-ink)}
.diagram .side{grid-column:2;font-size:12px;color:var(--dn-muted);line-height:1.5;max-width:none;margin-bottom:30px}
.diagram .side.s2{grid-row:3}.diagram .side.s4{grid-row:7}.diagram .side.s5{grid-row:9;margin-bottom:0}
.diagram .llm{position:relative;border:2px solid var(--dn-photon);background:var(--dn-photon-soft);border-radius:var(--dn-radius);padding:10px 12px;display:grid;gap:3px;color:var(--dn-photon-text)}
.diagram .llm b{font-weight:500;font-size:12.5px;letter-spacing:var(--dn-track-label);text-transform:uppercase}
.diagram .llm span{font-size:12px}
.diagram .llm::before{content:"";position:absolute;right:100%;top:50%;width:32px;border-top:1.5px dashed var(--dn-photon)}
.diagram .llm::after{content:"";position:absolute;right:calc(100% + 26px);top:50%;transform:translateY(-50%);border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:8px solid var(--dn-photon)}
.diagram .note{margin-top:8px}
.diagram .ret{grid-column:1 / -1;grid-row:10;margin-top:24px;padding-top:12px;border-top:var(--dn-rule) solid var(--dn-hairline);font-size:12px;color:var(--dn-muted);line-height:1.5;max-width:none}
.diagram .ret b{font-weight:500;color:var(--dn-ink);letter-spacing:var(--dn-track-label);text-transform:uppercase}
@media (max-width:560px){
  .diagram{grid-template-columns:1fr;column-gap:0}
  .diagram .side{grid-column:1;position:relative;margin:0 0 30px 0;padding-left:12px;border-left:1.5px solid var(--dn-hairline)}
  .diagram .side.s2{grid-row:4}.diagram .side.s4{grid-row:8}.diagram .side.s5{grid-row:10;margin-bottom:0}
  .diagram .n:nth-of-type(2),.diagram .n:nth-of-type(4),.diagram .n:nth-of-type(5){margin-bottom:8px}
  .diagram .n:nth-of-type(2)::after,.diagram .n:nth-of-type(2)::before,.diagram .n:nth-of-type(4)::after,.diagram .n:nth-of-type(4)::before{display:none}
  .diagram .side.s2::after,.diagram .side.s4::after{content:"";position:absolute;left:50%;top:100%;width:1.5px;height:21px;background:var(--dn-ink)}
  .diagram .side.s2::before,.diagram .side.s4::before{content:"";position:absolute;left:50%;top:calc(100% + 21px);transform:translateX(-50%);border-left:5px solid transparent;border-right:5px solid transparent;border-top:8px solid var(--dn-ink)}
  .diagram .side.s2{border-left:0;padding-left:0}
  .diagram .llm::before,.diagram .llm::after{display:none}
  .diagram .ret{grid-row:11}
}
.prompts{background:var(--dn-surface-2);border-radius:var(--dn-radius);padding:14px 16px;font-family:var(--dn-font-mono);font-size:13.5px;line-height:1.7;margin:0;white-space:pre-wrap;overflow-x:auto}
.prompts .c{color:var(--dn-muted)}

/* --- Contact --- */
.contact a{text-decoration-color:var(--dn-photon)}

/* --- Footer --- */
footer{padding-block:32px 72px;border-top:var(--dn-rule) solid var(--dn-hairline)}
footer .wrap{display:flex;justify-content:space-between;align-items:center;gap:16px 32px;flex-wrap:wrap}
footer .lockup svg{height:22px}
footer .tag{font-family:var(--dn-font-mono);font-size:var(--dn-t-label);letter-spacing:var(--dn-track-label);text-transform:uppercase;color:var(--dn-muted)}

/* --- Print --- */
@media print{
  :root{--dn-paper:#fff;--dn-surface:#fff;--dn-ink:#000;--dn-ink-2:#222;--dn-muted:#555}
  .nav,.theme,.grating,.skip{display:none!important}
  .hero .wrap{padding-top:0}
  .s{padding-block:24px}
  .head,.tl>li,.dn-panel,.fig,.stats{break-inside:avoid}
  .stats{grid-template-columns:repeat(4,1fr);gap:16px}
  .stats b{font-size:31px}
  .hero h1{font-size:44px}
  .hero h1 .photon{color:#D3741D}
  a{color:inherit;text-decoration:none}
  .contact a::after{content:" (" attr(href) ")";font-family:var(--dn-font-mono);font-size:12px;color:#555}
  .contact a[href^="mailto"]::after{content:""}
}

/* --- Motion ---
   Design language: static by default, motion only to show a mechanism. So the coupler and the timeline
   rules draw themselves, the Quinn diagram plays one turn top to bottom, the numbers count up and the nav
   marks where you are. Two gates: the head script adds html.motion only when the OS does not ask for
   reduced motion, and this block is screen-only. Print, reduced motion and no-JS all get the static page.
   Per-element delays come from --mo-delay, set by the script when the element enters the viewport.
   Curve and durations are the tokens --dn-ease and --dn-dur-*. */
.nav .wrap{position:relative}
.ind{position:absolute;bottom:-1px;height:2px;background:var(--dn-photon);opacity:0;pointer-events:none}
.ind.on{opacity:1}
.nav-links a[aria-current]{color:var(--dn-ink)}
@media screen and (prefers-reduced-motion:no-preference){
  .ind{transition:left .35s var(--dn-ease),width .35s var(--dn-ease),opacity .2s linear}
  .theming,.theming *,.theming *::before,.theming *::after{transition:background-color .3s linear,color .3s linear,border-color .3s linear!important}

  /* Hero: plays once on load. Title block, label, headline, coupler draws, lead, facts. */
  .motion .hero .wrap>*{animation:mo-rise .55s var(--dn-ease) both}
  .motion .hero .wrap>:nth-child(2){animation-delay:.07s}
  .motion .hero .wrap>:nth-child(3){animation-delay:.14s}
  .motion .hero .wrap>:nth-child(5){animation-delay:.34s}
  .motion .hero .wrap>:nth-child(6){animation-delay:.42s}
  .motion .hero .dn-coupler{animation:none}
  .motion .hero .dn-coupler::before{transform-origin:left;animation:mo-draw var(--dn-dur-draw) var(--dn-ease) .26s both}
  .motion .hero .dn-coupler::after{animation:mo-fade .25s linear .7s both}
  .motion .grating{top:-25%;bottom:-25%;will-change:transform} /* no opacity keyframe here: a finished animation on this masked element drops it from full-page captures */

  /* Units that rise in as they enter. Keep this list in sync with SEL in the page script. */
  .motion :where(.stats>li,.head>*,.tl>li,.grid>.dn-panel,.two>.prose>:not(.kv),.kv>*){opacity:0;transform:translateY(12px);transition:opacity var(--dn-dur-2) var(--dn-ease),transform var(--dn-dur-2) var(--dn-ease);transition-delay:var(--mo-delay,0s)}
  .motion :where(.stats>li,.head>*,.tl>li,.grid>.dn-panel,.two>.prose>:not(.kv),.kv>*).is-in{opacity:1;transform:none}

  /* Coupler under a section title: the hairline draws left to right, then the amber segment lands. */
  .motion .head>.dn-coupler{opacity:1;transform:none}
  .motion .head>.dn-coupler::before{transform:scaleX(0);transform-origin:left;transition:transform var(--dn-dur-draw) var(--dn-ease);transition-delay:calc(var(--mo-delay,0s) + .1s)}
  .motion .head>.dn-coupler::after{opacity:0;transition:opacity .25s linear;transition-delay:calc(var(--mo-delay,0s) + .55s)}
  .motion .head>.dn-coupler.is-in::before{transform:scaleX(1)}
  .motion .head>.dn-coupler.is-in::after{opacity:1}

  /* Timeline: each row's rule draws after the row lands. */
  .motion .tl>li{border-bottom-color:transparent}
  .motion .tl>li::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--dn-hairline);transform:scaleX(0);transform-origin:left;transition:transform .7s var(--dn-ease);transition-delay:calc(var(--mo-delay,0s) + .2s)}
  .motion .tl>li.is-in::after{transform:scaleX(1)}

  /* Quinn diagram: one turn, top to bottom. Node, connector, arrowhead, next node. The LLM joins from the side. */
  .motion .diagram :is(.n,.side,.ret){opacity:0;transform:translateY(-6px);transition:opacity .3s var(--dn-ease),transform .3s var(--dn-ease)}
  .motion .diagram .side.s2{transform:translateX(8px)}
  .motion .diagram.is-in :is(.n,.side,.ret){opacity:1;transform:none}
  .motion .diagram .n::after,.motion .diagram .side::after{transform:scaleY(0);transform-origin:top;transition:transform .18s linear}
  .motion .diagram .n::before,.motion .diagram .side::before{opacity:0;transition:opacity .1s linear}
  .motion .diagram.is-in .n::after,.motion .diagram.is-in .side::after{transform:scaleY(1)}
  .motion .diagram.is-in .n::before,.motion .diagram.is-in .side::before{opacity:1}
  .motion .diagram .llm::before{transform:scaleX(0);transform-origin:right;transition:transform .2s linear .95s}
  .motion .diagram .llm::after{opacity:0;transition:opacity .1s linear 1.12s}
  .motion .diagram.is-in .llm::before{transform:scaleX(1)}
  .motion .diagram.is-in .llm::after{opacity:1}
  .motion .diagram .n:nth-of-type(1){transition-delay:.25s}
  .motion .diagram .n:nth-of-type(1)::after{transition-delay:.45s}
  .motion .diagram .n:nth-of-type(1)::before{transition-delay:.6s}
  .motion .diagram .n:nth-of-type(2){transition-delay:.65s}
  .motion .diagram .side.s2{transition-delay:.8s}
  .motion .diagram .side.s2::after{transition-delay:1.05s}
  .motion .diagram .side.s2::before{transition-delay:1.2s}
  .motion .diagram .n:nth-of-type(2)::after{transition-delay:1.05s}
  .motion .diagram .n:nth-of-type(2)::before{transition-delay:1.2s}
  .motion .diagram .n:nth-of-type(3){transition-delay:1.25s}
  .motion .diagram .n:nth-of-type(3)::after{transition-delay:1.45s}
  .motion .diagram .n:nth-of-type(3)::before{transition-delay:1.6s}
  .motion .diagram .n:nth-of-type(4){transition-delay:1.65s}
  .motion .diagram .side.s4{transition-delay:1.8s}
  .motion .diagram .side.s4::after{transition-delay:1.95s}
  .motion .diagram .side.s4::before{transition-delay:2.1s}
  .motion .diagram .n:nth-of-type(4)::after{transition-delay:1.95s}
  .motion .diagram .n:nth-of-type(4)::before{transition-delay:2.1s}
  .motion .diagram .n:nth-of-type(5){transition-delay:2.15s}
  .motion .diagram .side.s5{transition-delay:2.3s}
  .motion .diagram .ret{transition-delay:2.6s}

  @keyframes mo-rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
  @keyframes mo-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  @keyframes mo-fade{from{opacity:0}to{opacity:1}}
}
