/* Two stacked copies of the same markup:
   .site = the finished site, .bp = the blueprint underneath.
   Layout rules live on .layer so both copies line up pixel-for-pixel;
   .site / .bp only change colors, outlines and paint — never box sizes. */

:root {
  --paper: #f2efe7;
  --ink: #111110;
  --muted: #6f6b62;
  --line: #d9d4c7;
  --accent: #ff4f1a;

  --bp-bg: #0f3a9e;
  --bp-grid: rgba(214, 228, 255, 0.10);
  --bp-grid-major: rgba(214, 228, 255, 0.20);
  --bp-ink: #d6e4ff;
  --bp-dim: rgba(214, 228, 255, 0.45);
  --bp-note: #ffd166;

  /* --display = all reading text and headlines (Leo preferred this over a serif body, 2026-10-12)
     --serif   = italic accent words and the one big About line only
     --mono    = data (years, roles, places, numbers, labels), small caps
     --hand belongs to the blueprint only; the signature is Leo's own (signature.png). */
  --display: "Inter Tight", system-ui, sans-serif;
  --serif: "Instrument Serif", Georgia, serif;
  --mono: "JetBrains Mono", ui-monospace, monospace;
  --label: 500 11px/1.6 var(--mono);
  --label-track: .08em;
  --hand: "Architects Daughter", "Comic Sans MS", cursive; /* placeholder until Leo's handwriting font exists */
  --ease: cubic-bezier(.2, .8, .2, 1);
}

* { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 54px; /* height of the fixed top bar */
  /* Scrolling is smoothed by Lenis and the section stops live in app.js (gateScroll). */
}
/* Lenis housekeeping */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 17px/1.55 var(--display);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
kbd {
  font: 0.8em var(--mono);
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 4px;
}

/* ── stage ───────────────────────────────────────────── */
.stage { position: relative; }
.layer { width: 100%; }
.bp {
  position: absolute;
  inset: 0;
  pointer-events: none;
  clip-path: inset(0 0 0 0);
  will-change: clip-path;
}

/* ── shared layout (both layers) ─────────────────────── */
.layer [data-note], .layer [data-dim] { position: relative; }

.nav {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 32px;
  /* full-width bar, content still aligned to the 1280px column */
  padding: 18px max(32px, calc((100% - 1280px) / 2 + 32px));
  border-bottom: 1px solid;
  font: var(--label);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
}
.logo { font-weight: 500; }
.links { display: flex; gap: 24px; margin-left: auto; }
.clock { min-width: 9ch; text-align: right; }

.hero {
  max-width: 1280px; margin: 0 auto;
  padding: 12vh 32px 10vh;
  min-height: calc(100vh - 54px - 170px); /* hero + the stats strip fill the first screen together */
  display: grid;
  grid-template-columns: 1fr minmax(260px, 340px);
  gap: 48px;
  align-content: center;
  align-items: end;
}
.hero-main { display: flex; flex-direction: column; min-width: 0; }
.kicker {
  margin: 0 0 28px;
  font: var(--label);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  align-self: flex-start;
}
.headline {
  margin: 0;
  font: 700 clamp(60px, 10vw, 150px)/0.9 var(--display);
  letter-spacing: -0.045em;
  align-self: flex-start;
}
.headline .line { display: block; }
.headline em, .cta-h em {
  font: italic 400 1.08em/0.9 var(--serif);
  letter-spacing: -0.02em;
}
.swap { display: inline-block; min-width: 6ch; white-space: nowrap; }
.cta-h em { display: inline-block; white-space: nowrap; }
.lede {
  max-width: 34rem;
  margin: 56px 0 0;
  font-size: 20px; line-height: 1.5;
  align-self: flex-start;
}
.hint {
  margin: 48px 0 0;
  font: 400 11px/1.6 var(--mono);
  letter-spacing: .04em;
}

.stats {
  max-width: 1280px; margin: 0 auto;
  padding: 0 32px;
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.stat { padding: 28px 24px 28px 0; border-top: 1px solid; }
.stat b {
  display: block;
  font: 600 clamp(34px, 3.9vw, 54px)/1 var(--display);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stat span { display: block; margin-top: 12px; font-size: 14px; max-width: 22ch; }

.block { position: relative; max-width: 1280px; margin: 0 auto; padding: 88px 32px 64px; /* heading sits just under the sheet title block */ min-height: calc(100vh - 54px); /* each section is at least one full screen under the top bar */ }
.block-h { margin-bottom: 44px; }
.block-h h2 {
  margin: 0;
  font: 600 clamp(36px, 5vw, 64px)/1 var(--display);
  letter-spacing: -0.035em;
  display: inline-block;
}

/* drawing-sheet label: runs up the left edge of each section and stays put while you read it */
.sheet { display: block; margin: 0 0 16px; font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; }
@media (min-width: 861px) {
  .sheet { position: absolute; left: 6px; top: 18vh; bottom: 0; width: 20px; margin: 0; }
  .sheet span { position: sticky; top: 92px; display: block; writing-mode: vertical-rl; transform: rotate(180deg); white-space: nowrap; }
}

/* Things I've built — index cards: number, name in the serif voice, hairline, data line */
.builds { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); column-gap: 32px; }
.build { display: flex; flex-direction: column; min-height: 360px; padding: 18px 0 0; border-top: 1px solid; }
.build .n { font: var(--label); letter-spacing: var(--label-track); }
.build .body { margin: auto 0; padding: 44px 0; }
.build h3 {
  margin: 0 0 14px;
  font: 600 clamp(30px, 3.6vw, 48px)/1.05 var(--display);
  letter-spacing: -0.03em;
}
.build .body p { margin: 0; max-width: 32rem; }
.build .body .status {
  display: flex; align-items: center; gap: 9px; margin: 0 0 14px;
  font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase;
}
.build .status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.site .build .body .status { color: var(--accent); }
.site .build .status::before { animation: dot-pulse 2.4s ease-out infinite; }
@media (prefers-reduced-motion: reduce) { .site .build .status::before { animation: none; } }
.build .meta {
  display: flex; justify-content: space-between; gap: 16px;
  margin: 0; padding: 14px 0 22px;
  border-top: 1px solid;
  font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase;
}

/* Where I've worked — index rows: year · name + line · role/place */
.rows { list-style: none; margin: 0; padding: 0; border-bottom: 1px solid; }
.row {
  display: grid; grid-template-columns: 120px 1fr 260px; gap: 24px;
  align-items: baseline;
  padding: 28px 0;
  border-top: 1px solid;
}
.row .yr, .row .role { font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; }
.row .role { text-align: right; }
.row h3 { margin: 0 0 6px; font: 600 clamp(20px, 2vw, 26px)/1.2 var(--display); letter-spacing: -0.02em; }
.row p { margin: 0; max-width: 36rem; }

.about .big {
  margin: 0 0 32px;
  font: 400 clamp(28px, 3.4vw, 44px)/1.2 var(--serif);
  max-width: 44rem;
}
.tags { display: flex; flex-wrap: wrap; gap: 10px; list-style: none; margin: 0; padding: 0; }
.tags li { padding: 7px 14px; border: 1px solid; border-radius: 999px; font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; }
.about .small { margin: 28px 0 0; font-size: 15px; max-width: 40rem; }

/* "Let's build something." owns a full screen; the receipt only appears if the visitor scrolls on. */
.contact { min-height: calc(100vh - 54px); padding-top: 88px; padding-bottom: 8vh; display: flex; flex-direction: column; justify-content: flex-start; }
.contact > * { align-self: flex-start; }
.contact .contact-foot { align-self: stretch; }
.receipt { position: relative; min-height: calc(100vh - 54px - 138px); /* receipt + footer make the last screen */ display: flex; align-items: center; justify-content: center; padding: 96px 32px; }
.cta-h {
  margin: 0 0 48px;
  font: 700 clamp(56px, 10vw, 140px)/0.92 var(--display);
  letter-spacing: -0.045em;
  display: inline-block;
}
.cta { display: flex; flex-wrap: wrap; gap: 12px; }
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 48px; padding: 0 22px;
  border: 1px solid;
  border-radius: 999px;
  font: 500 15px var(--display);
}

.foot {
  max-width: 1280px; margin: 0 auto;
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 32px 32px 84px; /* clears the fixed Blueprint button */
  border-top: 1px solid;
  font: 400 11px/1.6 var(--mono); letter-spacing: .04em;
}

.ph { font: 0.85em var(--mono); padding: 1px 5px; border-radius: 3px; }

/* ── finished site paint ─────────────────────────────── */
.site { background: var(--paper); color: var(--ink); }
.site .muted, .site .kicker, .site .sheet, .site .clock, .site .hint,
.site .build .n, .site .build .meta, .site .row .yr, .site .row .role, .site .foot, .site .stat span { color: var(--muted); }
.site .build .body p, .site .row p { color: #45423b; }
.site .stat, .site .build, .site .build .meta, .site .row, .site .rows, .site .foot { border-color: var(--line); }
.site .nav { background: var(--paper); border-color: var(--line); }
.site .headline em, .site .cta-h em { color: var(--accent); }
.site .links a:hover, .site .logo:hover { color: var(--accent); }
.site .tags li { border-color: var(--line); background: #fbfaf6; }
.site .btn { background: var(--ink); color: var(--paper); border-color: var(--ink); transition: background .25s, color .25s, border-color .25s, transform .25s var(--ease); }
.site .btn.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.site .btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; transform: translateY(-2px); }
.site .ph { background: #ffe9a8; color: #6b4f00; }
.site .next h3 { color: var(--muted); }
.site a:focus-visible, .bp-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* Things I've built: the card under the cursor fills with a light orange wash
   (wiping down from its top edge), with the orange line across the top. Paint only —
   the wash sits behind the text and changes no sizes, so the blueprint stays aligned. */
.site .build { position: relative; isolation: isolate; }
.site .build::before, .site .build::after {
  content: ""; position: absolute; left: -12px; right: -12px;
  pointer-events: none;
}
.site .build::after {
  top: 0; bottom: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(255, 79, 26, .13), rgba(255, 79, 26, .06));
  transform: scaleY(0); transform-origin: top;
  opacity: 0;
  transition: transform .45s var(--ease), opacity .3s;
}
.site .build::before {
  top: -1px; height: 2px; z-index: 1;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease);
}
.site .build:hover::after { transform: scaleY(1); opacity: 1; }
.site .build:hover::before { transform: scaleX(1); }
.site .build .n, .site .build .meta { transition: color .3s; }
.site .build:hover .n { color: var(--accent); }
.site .build:hover .meta { color: var(--ink); border-color: rgba(255, 79, 26, .35); }

/* scroll reveals — finished layer only */
.site .rv { opacity: 0; transform: translateY(28px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.site .rv.in { opacity: 1; transform: none; }

/* ── blueprint paint ─────────────────────────────────── */
.bp {
  color: var(--bp-ink);
  background-color: var(--bp-bg);
  background-image:
    linear-gradient(var(--bp-grid-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid-major) 1px, transparent 1px),
    linear-gradient(var(--bp-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
}
.bp * { color: var(--bp-ink) !important; }
.bp .nav { background: var(--bp-bg); border-color: var(--bp-dim); border-bottom-style: dashed; }
.bp h1, .bp h1 *, .bp h2, .bp h2 *, .bp h3, .bp .stat b {
  color: transparent !important;
  -webkit-text-stroke: 1px var(--bp-ink);
}
.bp .headline em, .bp .cta-h em { -webkit-text-stroke: 1px var(--bp-note); }
.bp .kicker, .bp .lede, .bp .hint, .bp .stat, .bp .build .body, .bp .row .what,
.bp .tags li, .bp .btn, .bp .about .big, .bp .logo, .bp .links a, .bp .clock, .bp .sheet span {
  outline: 1px dashed var(--bp-dim);
  outline-offset: 4px;
}
.bp .stat, .bp .build, .bp .build .meta, .bp .row, .bp .rows, .bp .foot, .bp .tags li, .bp .btn { border-color: var(--bp-dim); }
/* only restyle sides that actually have a border, or the blueprint grows 3px "medium" borders and drifts */
.bp .stat, .bp .build, .bp .build .meta, .bp .row, .bp .foot { border-top-style: dashed; }
.bp .rows { border-bottom-style: dashed; }
.bp .tags li, .bp .btn { border-style: dashed; }
.bp .btn { background: transparent; }
.bp .ph { background: rgba(255, 209, 102, .16); color: var(--bp-note) !important; }
.bp .hint { visibility: hidden; }

/* annotations only exist in the blueprint */
.bp .note {
  position: absolute;
  left: 0; top: calc(100% + 10px);
  z-index: 2;
  max-width: 34ch;
  font: 14px/1.35 var(--hand);
  color: var(--bp-note) !important;
  -webkit-text-stroke: 0;
  letter-spacing: 0;
  text-transform: none;
  white-space: normal;
  pointer-events: none;
}
.bp .headline > .note { left: 0; top: calc(100% + 6px); width: 44ch; max-width: none; }
.bp .kicker > .note { left: calc(100% + 20px); top: 0; width: 34ch; }
.bp .stats > .note { top: -26px; }
.bp .build > .note { left: auto; right: 0; top: 8px; text-align: right; }
.bp .rows > .note { top: -30px; left: auto; right: 0; }
.bp .cta-h > .note { left: calc(100% + 24px); top: 12px; width: 26ch; }
.bp .lede > .note, .bp .about .big > .note { top: calc(100% + 12px); }

/* dimension lines */
.bp [data-dim]::before {
  content: "├─ " attr(data-w) "px ─┤";
  position: absolute;
  left: 0; top: -22px;
  font: 10px var(--mono);
  color: var(--bp-dim);
  letter-spacing: .06em;
  white-space: nowrap;
}

/* drafting animation during the intro */
.bp.drafting [data-draft] { animation: draft .7s var(--ease) both; animation-delay: calc(var(--i) * 70ms); }
@keyframes draft { from { opacity: 0; transform: translateY(6px); } }

/* ── lens ─────────────────────────────────────────────── */
.lens {
  position: fixed; left: 0; top: 0; z-index: 20;
  width: 200px; height: 200px;
  margin: -100px 0 0 -100px;
  border-radius: 50%;
  border: 1.5px solid var(--bp-note);
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s;
  will-change: transform;
}
.lens::before, .lens::after {
  content: ""; position: absolute; background: var(--bp-note);
  left: 50%; top: 50%;
}
.lens::before { width: 14px; height: 1px; margin: 0 0 0 -7px; }
.lens::after { width: 1px; height: 14px; margin: -7px 0 0 0; }
body.lensing .lens { opacity: 1; }
.lens-label {
  position: absolute; left: 50%; top: 100%;
  transform-origin: top center;
  margin-top: 10px;
  font: 10px var(--mono);
  color: var(--bp-bg);
  background: var(--bp-note);
  padding: 2px 6px;
  border-radius: 3px;
  white-space: nowrap;
}

/* ── intro scan line ──────────────────────────────────── */
.scan {
  position: fixed; top: 0; bottom: 0; left: 0; z-index: 25;
  width: 2px;
  background: var(--bp-note);
  box-shadow: 0 0 24px 6px rgba(255, 209, 102, .55);
  opacity: 0;
  pointer-events: none;
}

/* ── build progress ───────────────────────────────────── */
.progress { position: fixed; inset: 0 0 auto 0; z-index: 30; height: 2px; pointer-events: none; }
.progress-bar { position: absolute; inset: 0; background: var(--accent); transform: scaleX(0); transform-origin: left; }

/* ── blueprint toggle ─────────────────────────────────── */
.bp-toggle {
  position: fixed; right: 20px; bottom: 20px; z-index: 30;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 16px;
  border: 1px solid var(--ink); border-radius: 999px;
  background: var(--paper); color: var(--ink);
  font: 500 12px var(--mono); letter-spacing: .04em;
  cursor: pointer;
  transition: background .25s, color .25s, border-color .25s;
}
.bp-toggle:hover, .bp-toggle[aria-pressed="true"] { background: var(--bp-bg); color: var(--bp-note); border-color: var(--bp-bg); }

body.intro .bp-toggle, body.intro .progress { opacity: 0; }

/* ── responsive ───────────────────────────────────────── */
@media (max-width: 860px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .builds { grid-template-columns: 1fr; }
  .build { min-height: 280px; }
  .row { grid-template-columns: 96px 1fr; }
  .row .role { grid-column: 2; text-align: left; }
  .bp .kicker > .note { display: none; }
  .bp .cta-h > .note { left: 0; top: calc(100% + 8px); }
}
@media (max-width: 560px) {
  body { font-size: 16px; }
  .nav { padding: 14px 16px; gap: 16px; }
  .links { display: none; }
  .clock { margin-left: auto; }
  .hero, .stats, .block { padding-left: 16px; padding-right: 16px; }
  .hero { min-height: 80vh; padding-top: 6vh; }
  .lede { font-size: 18px; }
  .row { grid-template-columns: 1fr; gap: 6px; }
  .row .role { grid-column: 1; }
  .foot { padding: 24px 16px 88px; }
  .bp .note { max-width: 24ch; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .site .rv { opacity: 1; transform: none; transition: none; }
  .bp.drafting [data-draft] { animation: none; }
}


/* ── classified panels ─────────────────────────────────
   Finished site: text is redacted (solid bars).
   Blueprint: the same text, handwritten, inks in as the lens passes. */
.secret { font: 16px/1.5 var(--hand); }
.secret-title { margin: 0 0 14px; font: 11px var(--mono); letter-spacing: .08em; text-transform: uppercase; }
.secret dl { margin: 0; display: grid; gap: 10px; }
.secret dl > div { display: grid; grid-template-columns: 96px 1fr; gap: 12px; }
.secret dt { font: 11px/2 var(--mono); letter-spacing: .04em; text-transform: uppercase; }
.secret dd { margin: 0; }
.secret .ink { -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.secret .ph { font: inherit; padding: 0; }

.site .secret { padding: 20px; border: 1px dashed var(--line); border-radius: 6px; }
.site .secret-title { color: var(--accent); }
.site .secret dt { color: var(--muted); }
.site .secret .ink, .site .secret .ink .ph {
  color: transparent; background: var(--ink); border-radius: 2px;
}
.bp .secret { padding: 20px; border: 1px dashed var(--bp-note); border-radius: 6px; }
.bp .secret-title { color: var(--bp-note) !important; }
.bp .secret .ink, .bp .secret .ink * { color: #fff !important; background: none; }

/* write-on: revealed left → right when the lens reaches it */
.bp .note, .bp .secret .ink {
  clip-path: inset(-4px 100% -4px 0);
  transition: clip-path 1.1s cubic-bezier(.55, .1, .35, 1);
}
.bp .note.inked, .bp .secret .ink.inked { clip-path: inset(-4px -4px -4px 0); }

.contact-foot {
  margin-top: 72px;
  display: flex; justify-content: space-between; align-items: end; gap: 48px; flex-wrap: wrap;
}
.contact-foot .secret { flex: 1 1 360px; max-width: 520px; }

@media (max-width: 1100px) {
  .hero { grid-template-columns: 1fr; align-content: center; }
  .hero .secret { max-width: 520px; }
}
@media (prefers-reduced-motion: reduce) {
  .bp .note, .bp .secret .ink { clip-path: none; transition: none; }
}


/* ── discovery counter (top bar) ─────────────────────── */
.found { white-space: nowrap; }
.found b { font-weight: 500; display: inline-block; }
.site .found { color: var(--muted); }
.site .found b { color: var(--ink); transition: color .3s; }
.site .found.tick b { animation: tick .6s var(--ease); color: var(--accent); }
.site .found.all b { color: var(--accent); }
@keyframes tick { 30% { transform: translateY(-3px) scale(1.25); } }

.secret-mid { margin-top: 48px; max-width: 520px; }

/* Off the clock: a scratch-off card. app.js adds .scratch and lays a foil canvas over the text;
   without JS the panel keeps the plain redaction bars. */
.site .secret.scratch dl { position: relative; }
.site .secret.scratch:not(.cleared) dl { -webkit-user-select: none; user-select: none; }
.site .secret.scratch .ink, .site .secret.scratch .ink .ph { color: var(--ink); background: none; }
.site .secret.scratch .ink.scratched { animation: scratched 1s var(--ease); }
@keyframes scratched { 0%, 30% { color: var(--accent); } }
.foil {
  position: absolute; left: 0; top: 0; z-index: 1;
  touch-action: pan-y; /* side-to-side rubs scratch on phones; up and down still scrolls */
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Ccircle cx='14' cy='14' r='11' fill='%23e0b85a' stroke='%23866621' stroke-width='1.5'/%3E%3Ccircle cx='14' cy='14' r='7.5' fill='none' stroke='%23866621' stroke-width='1' opacity='.6'/%3E%3C/svg%3E") 14 14, crosshair;
}
.site .secret.cleared .foil { pointer-events: none; }

/* ── visit receipt ───────────────────────────────────── */
.ticket-wrap { margin: 0 auto; width: min(340px, 100%); }
.slot { height: 10px; border-radius: 6px; margin: 0 -14px; position: relative; z-index: 1; }
.ticket-clip { overflow: hidden; padding: 0 28px 44px; margin: 0 -28px; }
.ticket {
  position: relative;
  padding: 26px 22px 22px;
  font: 12px/1.5 var(--mono);
  --tp: #fffdf7;
}
.t-head { margin: 0; font-size: 13px; letter-spacing: .14em; text-transform: uppercase; text-align: center; }
.t-sub { margin: 2px 0 18px; text-align: center; letter-spacing: .04em; }
.t-rows { margin: 0; padding: 14px 0; border-top: 1px dashed; border-bottom: 1px dashed; display: grid; gap: 6px; }
.t-rows > div { display: flex; justify-content: space-between; gap: 16px; }
.t-rows dd { margin: 0; font-variant-numeric: tabular-nums; text-align: right; }
.t-verdict { margin: 16px 0; min-height: 3em; font: 16px/1.35 var(--hand); }
.t-btn { width: 100%; justify-content: center; font-family: var(--mono); font-size: 12px; letter-spacing: .04em; }
.barcode { height: 34px; margin-top: 18px; }
.stamp {
  position: absolute; right: 18px; top: 64px;
  padding: 4px 12px;
  border: 2px solid; border-radius: 4px;
  font: 600 16px var(--mono); letter-spacing: .16em; text-transform: uppercase;
  transform: rotate(-12deg) scale(1.6);
  opacity: 0;
  pointer-events: none;
}
.ticket.cleared .stamp { opacity: .9; transform: rotate(-12deg) scale(1); transition: transform .35s cubic-bezier(.3, 1.6, .5, 1), opacity .15s; }

.site .slot { background: var(--ink); box-shadow: inset 0 3px 0 rgba(255, 255, 255, .12); }
.site .ticket { background: var(--tp); color: var(--ink); box-shadow: 0 18px 40px -22px rgba(0, 0, 0, .35); }
.site .ticket::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 10px;
  background:
    linear-gradient(135deg, var(--tp) 25%, transparent 25%) -6px 0 / 12px 12px repeat-x,
    linear-gradient(225deg, var(--tp) 25%, transparent 25%) -6px 0 / 12px 12px repeat-x;
}
.site .t-sub, .site .t-rows dt { color: var(--muted); }
.site .t-rows { border-color: var(--line); }
.site .barcode { background: repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px 5px, var(--ink) 5px 6px, transparent 6px 10px, var(--ink) 10px 13px, transparent 13px 15px); }
.site .stamp { color: var(--accent); }
/* printing: the paper feeds out of the slot in steps */
.site .ticket { transform: translateY(-104%); }
.site .ticket-wrap.printed .ticket { transform: none; transition: transform 2.4s steps(26, end); }

.bp .slot { outline: 1px dashed var(--bp-dim); }
.bp .ticket { outline: 1px dashed var(--bp-note); outline-offset: -1px; }
.bp .t-rows { border-color: var(--bp-dim); }
.bp .barcode { background: repeating-linear-gradient(90deg, var(--bp-dim) 0 1px, transparent 1px 5px); }
.bp .stamp { color: var(--bp-note) !important; }
.bp .t-verdict { color: var(--bp-note) !important; }

@media (max-width: 560px) {
  .found { margin-left: auto; }
  .found-label { display: none; }
  .clock { margin-left: 0; min-width: 0; }
  .receipt { padding: 72px 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .site .ticket { transform: none; }
  .site .ticket-wrap.printed .ticket { transition: none; }
}


/* ── section separators ────────────────────────────────
   A fine measuring scale across the content column at the top of each section:
   hairline, light minor ticks, a numbered major tick every 100px, and a small
   numbered tab hanging from the right end. Built in app.js (.rule / .rule-tab). */
.rule {
  position: absolute; top: 0; left: 32px; right: 32px;
  display: flex; justify-content: space-between; gap: 24px;
  padding-top: 9px;
  border-top: 1px solid;
  font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase;
  pointer-events: none;
}
.rule::before, .rule::after {                 /* small end marks, like the corners of a drawing sheet */
  content: ""; position: absolute; top: -1px; width: 1px; height: 9px; background: currentColor;
}
.rule::before { left: 0; }
.rule::after { right: 0; }
.rule .r-sheet b { font-weight: 500; }
.site .rule { border-color: var(--ink); color: var(--muted); }
.site .rule .r-sheet b { color: var(--ink); }
.bp .rule { border-color: var(--bp-ink); border-top-style: dashed; }
@media (max-width: 560px) {
  .rule { left: 16px; right: 16px; }
  .rule .r-by { display: none; }
}

/* ── Where I've worked: timeline spine ─────────────────
   A vertical line between the year column and the names, with a dot per job.
   On arrival the line draws downward; as it reaches each dot the dot fills and
   that row's text slides out from the line. Hover (or click to pin) keeps one
   job in full ink and fades the rest. All paint/transform — no layout change. */
.rows { --spine-x: 127px; --dot-y: 37px; }
.rows::before {
  content: ""; position: absolute; left: var(--spine-x); top: calc(var(--dot-y) + 6px); bottom: 0;
  width: 1px; pointer-events: none;
}
.row { position: relative; }
.row::before {
  content: ""; position: absolute; left: calc(var(--spine-x) - 5px); top: var(--dot-y);
  width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid; box-sizing: border-box;
  pointer-events: none;
}
.site .rows::before { background: var(--ink); transform-origin: top; transition: transform 1.8s linear; }
.site .row { cursor: pointer; }
.site .row::before {
  border-color: var(--ink); background: var(--paper);
  transition: transform .35s cubic-bezier(.3, 1.7, .5, 1), background .25s, border-color .25s, box-shadow .25s;
}
.site .row.on::before { background: var(--accent); border-color: var(--accent); }
.site .row > * { transition: opacity .55s var(--ease), transform .55s var(--ease); }

/* Entrance, per row, when the spine reaches its dot:
   dot pops with a ring pulse → hairline grows out from the spine → name rises out of
   its line → description fades up → role/city slides in from the right. */
.site .row .what h3 { transition: clip-path .7s var(--ease), transform .7s var(--ease); }
.site .row .what .facts { transition: opacity .6s var(--ease) .16s, transform .6s var(--ease) .16s; }
.site .row > .role { transition: opacity .6s var(--ease) .24s, transform .6s var(--ease) .24s; }
.site .rows.js-spine .row { border-top-color: transparent; }
.site .row::after {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 1px;
  background: var(--line); pointer-events: none;
  transform-origin: var(--spine-x) 0;
  transition: transform .8s var(--ease);
}
.site .row.on::before { animation: dot-pulse .9s ease-out; }
@keyframes dot-pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 79, 26, .5); }
  100% { box-shadow: 0 0 0 14px rgba(255, 79, 26, 0); }
}

/* before the line arrives (only when the script is running) */
.site .rows.js-spine:not(.live)::before { transform: scaleY(0); }
.site .rows.js-spine .row:not(.on)::before { transform: scale(0); }
.site .rows.js-spine .row:not(.on)::after { transform: scaleX(0); }
.site .rows.js-spine .row:not(.on) > .yr { opacity: 0; transform: translateX(10px); }
.site .rows.js-spine .row:not(.on) .what h3 { clip-path: inset(0 0 100% 0); transform: translateY(55%); }
.site .rows.js-spine .row:not(.on) .what .facts { opacity: 0; transform: translateY(8px); }
.site .rows.js-spine .row:not(.on) > .role { opacity: 0; transform: translateX(18px); }

/* focus: the hovered or pinned job stays in full ink, the rest fade */
.site .rows:hover .row.on:not(:hover):not(.pinned) > *,
.site .rows.has-pin .row.on:not(.pinned):not(:hover) > * { opacity: .28; }
.site .row.on:hover::before, .site .row.pinned::before { box-shadow: 0 0 0 5px rgba(255, 79, 26, .2); transform: scale(1.25); }
.site .row.pinned .yr { color: var(--accent); }

.bp .rows::before { background: var(--bp-dim); }
.bp .row::before { border-color: var(--bp-ink); border-style: dashed; }

@media (max-width: 860px) { .rows { --spine-x: 104px; } }
@media (max-width: 560px) {
  .rows { --spine-x: 5px; --dot-y: 31px; }
  .row { padding-left: 28px; }
}
@media (prefers-reduced-motion: reduce) {
  .site .rows::before, .site .row::before, .site .row > * { transition: none; }
}


/* ── Off the clock: toy box ─────────────────────────────
   The hobby tags are physical pills (Matter.js). They rain into the box when the
   section arrives, can be dragged, thrown and stacked, and scrolling shakes the box.
   The list keeps its normal layout (both layers line up); the finished site moves each
   pill with a transform from that resting spot. The blueprint shows the resting spots. */
.toybox { position: relative; height: 300px; margin-top: 4px; border-bottom: 1px solid; user-select: none; -webkit-user-select: none; }
.toybox .tags { position: relative; padding-top: 30px; } /* room for the hint above the resting spots */
.toy-hint {
  position: absolute; right: 0; top: 4px; margin: 0;
  font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase;
  pointer-events: none;
}
.site .toybox { border-color: var(--ink); }
.site .toy-hint { color: var(--muted); }
.toy-hint .for-touch { display: none; }
@media (pointer: coarse) { .toy-hint .for-touch { display: inline; } .toy-hint .for-mouse { display: none; } }
.site .toybox.physics .tags li { opacity: 0; will-change: transform; transition: opacity .15s; }
.site .toybox.physics .tags li.live { opacity: 1; }
.site .toybox.physics.draggable .tags li { cursor: grab; }
.site .toybox.physics.grabbing, .site .toybox.physics.grabbing .tags li { cursor: grabbing; }
.site .toybox.physics .tags li:hover { border-color: var(--accent); color: var(--accent); }
.bp .toybox { border-bottom-style: dashed; border-color: var(--bp-dim); }
@media (max-width: 560px) { .toybox { height: 360px; } }


/* Phones: press-and-hold X-ray. Stop iOS from popping its text-selection callout or
   magnifier during the hold in the lens zones. Touch-only, so desktop is untouched. */
@media (pointer: coarse) {
  .hero, .contact, .secret { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
}


/* ── fact chips: the numbers and specifics, in the data voice ── */
.facts { margin: 10px 0 0; font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; }
.site .facts { color: var(--ink); }
.facts.lang { margin-top: 24px; }
.build .body .facts { margin-top: 12px; }

/* Where I've worked: chips by default; hover (or tap to pin) swaps in the full sentence */
.row .what { display: grid; }
.row .what > * { grid-column: 1; }
.row .what h3 { grid-row: 1; }
.row .what .facts, .row .what p:not(.facts) { grid-row: 2; align-self: start; margin-top: 4px; }
.site .row .what p:not(.facts) { opacity: 0; transition: opacity .3s var(--ease); }
.site .row:hover .what p:not(.facts), .site .row.pinned .what p:not(.facts) { opacity: 1; }
.site .rows .row.on:hover .what .facts, .site .rows .row.pinned .what .facts { opacity: 0; transition: opacity .2s; }
.bp .row .what p:not(.facts) { visibility: hidden; }

/* hero hint: easier to notice, with the same crosshair as the Blueprint button */
.hint { display: inline-flex; align-items: center; gap: 8px; align-self: flex-start; }
.hint svg { flex: none; }
.site .hint { color: var(--ink); }
.site .hint svg { color: var(--accent); }

/* ── loading screen: a blueprint "cover sheet" that explains the idea ── */
.loader {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  padding: 24px;
  color: var(--bp-ink);
  background-color: var(--bp-bg);
  background-image:
    linear-gradient(var(--bp-grid-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid-major) 1px, transparent 1px),
    linear-gradient(var(--bp-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  transition: opacity .45s var(--ease);
}
.loader[hidden] { display: none; }
.loader.out { opacity: 0; pointer-events: none; }
.loader-sheet {
  width: min(560px, 100%);
  padding: 36px 36px 28px;
  outline: 1px dashed var(--bp-dim);
  outline-offset: 0;
  background: rgba(15, 58, 158, .55);
}
.loader-sheet > * { animation: l-in .6s var(--ease) both; }
.loader-sheet > *:nth-child(2) { animation-delay: .08s; }
.loader-sheet > *:nth-child(3) { animation-delay: .22s; }
.loader-sheet > *:nth-child(4) { animation-delay: .34s; }
.loader-sheet > *:nth-child(n+5) { animation-delay: .42s; }
@keyframes l-in { from { opacity: 0; transform: translateY(8px); } }
.l-tag { margin: 0 0 22px; font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; color: var(--bp-note); }
.l-name {
  margin: 0 0 18px;
  font: 700 clamp(44px, 9vw, 72px)/0.95 var(--display); letter-spacing: -0.04em;
  color: transparent; -webkit-text-stroke: 1px var(--bp-ink);
}
.l-line { margin: 0 0 8px; font: italic 400 clamp(24px, 4.4vw, 32px)/1.15 var(--serif); color: var(--bp-note); }
.l-sub { margin: 0 0 28px; font-size: 16px; line-height: 1.5; max-width: 40ch; }
.l-bar { height: 2px; background: var(--bp-dim); overflow: hidden; }
.l-bar span { display: block; height: 100%; background: var(--bp-note); transform: scaleX(0); transform-origin: left; }
.l-status { display: flex; justify-content: space-between; margin: 12px 0 0; font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; }
.l-skip {
  position: fixed; right: 20px; bottom: 20px;
  min-height: 44px; padding: 0 16px;
  border: 1px dashed var(--bp-dim); border-radius: 999px; background: none;
  font: 500 12px var(--mono); letter-spacing: .04em; color: var(--bp-ink); cursor: pointer;
}
.l-skip:hover, .l-skip:focus-visible { color: var(--bp-note); border-color: var(--bp-note); outline: none; }
@media (prefers-reduced-motion: reduce) { .loader-sheet > * { animation: none; } }


/* the cover sheet gets signed while it loads: Leo's real signature (signature.png is a time map
   recorded from him signing on his phone: red = when each bit of ink appeared, green = ink coverage) */
.l-sig { display: flex; align-items: center; gap: 12px; margin: -6px 0 18px; }
.l-sig-label { font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; color: var(--bp-note); }
.l-sig-canvas { display: block; width: 150px; height: auto; }

/* link out from a "Things I've built" card */
.card-link { display: inline-block; margin-top: 16px; font: var(--label); letter-spacing: var(--label-track); text-transform: uppercase; text-decoration: underline; text-underline-offset: 4px; }
.site .card-link { color: var(--ink); text-decoration-color: var(--accent); }
.site .card-link:hover { color: var(--accent); }
