:root {
  --bg: #ffffff;
  --bg2: #f4f4f5;
  --text: #09090b;
  --muted: #6b6b73;
  --accent: #2563eb;
  --border: #e4e4e7;
  --tag-bg: #eff6ff;
  --tag-text: #1d4ed8;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #09090b;
    --bg2: #18181b;
    --text: #fafafa;
    --muted: #a1a1aa;
    --accent: #60a5fa;
    --border: #27272a;
    --tag-bg: #1e3a5f;
    --tag-text: #93c5fd;
  }
}

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

html {
  scroll-behavior: smooth;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  font-size: 15px;
}

/* NAV */
nav {
  position: sticky; top: 0; z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 0 2rem;
  display: flex; align-items: center; justify-content: space-between;
  height: 56px;
}

.nav-logo { 
  font-weight: 700; font-size: 1rem; letter-spacing: -.3px; 
}

.nav-logo a { 
  text-decoration: none;
  color: var(--muted);
  transition: color .2s;    
}

.nav-links { display: flex; gap: 1.5rem; }

.nav-links a {
  color: var(--muted);
  text-decoration: none;
  font-size: .875rem;
  transition: color .2s;
}

.nav-links a:hover { color: var(--accent); }

.nav-links a[aria-current="page"] {
  color: var(--text);
  border-bottom: 1px solid var(--accent);
}

/* HERO */
.hero {
  max-width: 720px; margin: 0 auto;
  padding: 5rem 2rem 3rem;
}

.hero-label {
  font-size: .75rem; font-weight: 600; letter-spacing: .1em;
  color: var(--accent);
  margin-bottom: .75rem;
}

.hero h1 {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 800; letter-spacing: -.5px;
  line-height: 1.1; margin-bottom: 1rem;
}

.hero p {
  font-size: 1.05rem; color: var(--muted);
  max-width: 560px; margin-bottom: 2rem;
}

.hero-links { display: flex; gap: 1rem; flex-wrap: wrap; }

.btn {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .55rem 1.2rem; border-radius: 8px;
  font-size: .875rem; font-weight: 500;
  text-decoration: none; cursor: pointer;
  transition: background-color .2s, border-color .2s, color .2s, opacity .2s;
  border: none;
}

.btn-primary { background: var(--accent); color: #fff; }

.btn-primary:hover { opacity: .85; }

.btn-outline {
  border: 1px solid var(--border);
  background: transparent; color: var(--text);
}

.btn-outline:hover { border-color: var(--accent); color: var(--accent); }

/* SECTION */
/* Sticky nav is 56px tall; without this an anchor jump hides the target under
   it. Every deep-link destination needs this, not just <section> — the resume
   is linked at .job and .mig granularity (/#job-chop, /#mig-agentic), and
   those land at viewport top with the nav drawn over them otherwise. */
section,
.job,
.mig {
  scroll-margin-top: 72px;
}

section {
  max-width: 720px; margin: 0 auto;
  padding: 2rem 2rem;
  border-top: 1px solid var(--border);
}

section h2 {
  font-size: .7rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
  margin-bottom: 1.5rem;
}

/* EXPERIENCE */
.job { margin-bottom: 2rem; }

.job-header {
  display: flex; justify-content: space-between;
  align-items: baseline; flex-wrap: wrap; gap: .5rem;
  margin-bottom: .25rem;
}

.job-title { font-weight: 700; font-size: 1rem; }

.job-meta { font-size: .8rem; color: var(--muted); }

.job ul { list-style: none; padding: 0; margin-top: .5rem; }

.job ul li {
  padding: .2rem 0 .2rem 1rem;
  position: relative; color: var(--muted); font-size: .9rem;
}

.job ul li::before {
  content: '→'; position: absolute; left: 0;
  color: var(--accent); font-size: .75rem; top: .3rem;
}

/* SKILLS */
.skill-group { margin-bottom: 1.25rem; }

.skill-group-label {
  font-size: .75rem; font-weight: 600;
  color: var(--muted); margin-bottom: .5rem;
}

.tags { display: flex; flex-wrap: wrap; gap: .4rem; }

.tag {
  background: var(--tag-bg); color: var(--tag-text);
  font-size: .75rem; font-weight: 500;
  padding: .25rem .6rem; border-radius: 6px;
}

/* CONTACT */
.contact-list { display: flex; flex-direction: column; gap: .75rem; }

.contact-item {
  display: flex; gap: .75rem; align-items: center;
  font-size: .9rem;
}

.contact-item span { color: var(--muted); width: 70px; }

.contact-item a { color: var(--accent); text-decoration: none; }

.contact-item a:hover { text-decoration: underline; }

/* INNER PAGE */
.inner-page {
  max-width: 720px; margin: 0 auto;
  padding: 3rem 2rem;
}

.back-btn {
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--muted); font-size: .875rem;
  text-decoration: none; margin-bottom: 2rem;
  cursor: pointer; background: none; border: none;
  transition: color .2s;
}

.back-btn:hover { color: var(--accent); }

.inner-page h1 { font-size: 1.75rem; font-weight: 800; margin-bottom: .5rem; }

.inner-page .subtitle { color: var(--muted); margin-bottom: 2rem; }

.inner-page p { color: var(--muted); line-height: 1.8; margin-bottom: 1rem; }

/* EDUCATION */
.edu {
  display: flex; justify-content: space-between;
  align-items: baseline; flex-wrap: wrap;
}

.edu-name { font-weight: 600; }

.edu-meta { color: var(--muted); font-size: .85rem; }

footer {
  text-align: center; padding: 3rem 2rem;
  font-size: .8rem; color: var(--muted);
  border-top: 1px solid var(--border);
  max-width: 720px; margin: 0 auto;
}

/* Available to assistive tech, absent from the visual layout. Used for the
   diagram's long description, which is far too long for a visible caption. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* SKIP LINK */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: .6rem 1rem;
  background: var(--accent);
  color: #fff;
  font-size: .875rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 8px;
}

.skip-link:focus {
  left: 0;
}

/* FOCUS */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ===========================================================
   PROGRESSIVE DISCLOSURE
   Three layers, in increasing depth:
     L0  static markup            — the 20-second scan
     L1  <details>/<summary>      — evidence, inline, no navigation
     L2  a separate page          — full case study
     L-inf  .tag[data-ev] popover — one line of context on a term
   Rule: disclosure adds evidence, it never *carries* a claim.
   Anything load-bearing must survive with every panel closed.
   =========================================================== */

/* Availability chips under the hero */
.avail {
  display: flex; flex-wrap: wrap; gap: .4rem;
  margin: -1rem 0 1.75rem;
}

.chip {
  font-size: .75rem; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px;
  padding: .2rem .65rem; white-space: nowrap;
}

.chip strong { color: var(--text); font-weight: 600; }

.section-note {
  font-size: .8rem; color: var(--muted);
  margin: -1.1rem 0 1.25rem;
}

/* Shared disclosure affordance. The caret is decorative; the state is
   carried by the native `open` attribute, so screen readers get it free. */
details > summary { cursor: pointer; list-style: none; }
details > summary::-webkit-details-marker { display: none; }
details > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.caret {
  display: inline-block; color: var(--accent);
  font-size: .62rem; transition: transform .2s ease; flex: none;
}

details[open] > summary .caret { transform: rotate(90deg); }

/* L1 — migration ledger */
.ledger { border-top: 1px solid var(--border); }

.mig { border-bottom: 1px solid var(--border); }

.mig > summary {
  display: grid; grid-template-columns: 1fr auto auto;
  align-items: baseline; gap: .75rem;
  padding: .8rem .5rem .8rem .25rem;
  transition: background-color .15s;
}

.mig > summary:hover { background: var(--tag-bg); }

.mig-move { font-size: .95rem; font-weight: 600; letter-spacing: -.2px; }
.mig-move .arrow { color: var(--accent); font-weight: 400; padding: 0 .3rem; }
.mig-move .from { color: var(--muted); font-weight: 500; }

.mig-where { font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }

.mig-body {
  padding: 0 .5rem 1rem 1.1rem; margin: -.15rem 0 0 .25rem;
  border-left: 2px solid var(--border);
}

.mig-body p { font-size: .9rem; color: var(--muted); max-width: 40rem; }
.mig-body p + p { margin-top: .6rem; }

/* L2 entry points */
.cards { display: grid; gap: .75rem; }

.card {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--border); border-radius: 12px;
  padding: 1rem 1.1rem;
  transition: border-color .2s, background-color .2s;
}

.card:hover { border-color: var(--accent); background: var(--bg2); }

.card-kicker {
  display: block; font-size: .68rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); margin-bottom: .35rem;
}

.card-title { display: block; font-weight: 700; font-size: .98rem; margin-bottom: .3rem; }
.card-desc { display: block; font-size: .875rem; color: var(--muted); }
.card-more { display: inline-block; font-size: .8rem; color: var(--accent); margin-top: .5rem; }

/* Experience: scope is always visible, evidence is disclosed */
.job-scope { font-size: .9rem; color: var(--muted); margin: .3rem 0 .55rem; max-width: 40rem; }

.job details > summary {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .8rem; font-weight: 600; color: var(--accent);
  padding: .2rem 0;
}

.job details > summary:hover { text-decoration: underline; }

/* Deep-linked disclosure: /#job-chop opens and highlights that role. */
.job:target { animation: job-flash 1.6s ease; }

@keyframes job-flash {
  0%, 40% { background: var(--bg2); }
  100% { background: transparent; }
}

/* L-inf — evidence popover on skill tags */
button.tag {
  cursor: pointer; font-family: inherit;
  border: 1px solid transparent;
}

button.tag::after { content: ' \00B7'; opacity: .55; }

button.tag:hover,
button.tag[aria-expanded="true"] { border-color: var(--accent); }

#evidence {
  position: fixed; z-index: 80; width: min(20rem, 78vw);
  padding: .75rem .85rem; border-radius: 12px;
  background: var(--bg); border: 1px solid var(--border);
  box-shadow: 0 12px 22px rgba(15, 23, 42, .10), 0 4px 10px rgba(15, 23, 42, .05);
  opacity: 0; pointer-events: none; transform: translateY(4px);
  transition: opacity .15s ease, transform .15s ease;
}

#evidence.open { opacity: 1; pointer-events: auto; transform: translateY(0); }
#evidence .ev-term { font-size: .75rem; font-weight: 700; margin-bottom: .25rem; }
#evidence .ev-body { font-size: .85rem; color: var(--muted); line-height: 1.55; }

/* Contact: engagement terms behind a disclosure */
.engage { margin-top: 1.25rem; }

.engage > summary {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .8rem; font-weight: 600; color: var(--accent);
}

.engage p { font-size: .875rem; color: var(--muted); margin-top: .6rem; max-width: 40rem; }

/* ===========================================================
   L2 PAGES — how-i-work.html, projects.html
   =========================================================== */
.prose { max-width: 40rem; }
.prose p { color: var(--muted); font-size: .95rem; }
.prose p + p { margin-top: .75rem; }

/* The stylesheet has no base <a> rule — every other link is styled through the
   component it sits in (.nav-links a, .contact-item a, .card). A link in
   flowing prose belonged to no component, so it fell back to the UA default:
   #0000EE, which is 2.12:1 against the dark background and 1.81:1 once
   visited. The underline stays: inside a paragraph, colour alone is not a
   sufficient cue that something is a link. */
.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  transition: text-decoration-thickness .15s ease;
}

.prose a:hover { text-decoration-thickness: 2px; }

.prose h2,
.prose h3 {
  font-size: .95rem; font-weight: 700; color: var(--text);
  margin: 1.75rem 0 .5rem;
  text-transform: none; letter-spacing: normal;
}

.prose ol, .prose ul { margin: .6rem 0 .6rem 1.1rem; }
.prose li { color: var(--muted); font-size: .92rem; padding: .18rem 0; }
.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .85em; background: var(--bg2);
  padding: .1rem .3rem; border-radius: 4px;
}

.pull {
  border-left: 2px solid var(--accent);
  padding: .35rem 0 .35rem 1rem; margin: 1.25rem 0;
  font-size: .95rem; color: var(--text); max-width: 38rem;
}

.metric-row { display: flex; flex-wrap: wrap; gap: 1.75rem; margin: 1.25rem 0 .5rem; }
.metric-val { font-size: 1.65rem; font-weight: 800; letter-spacing: -.5px; font-variant-numeric: tabular-nums; }
.metric-lbl { font-size: .75rem; color: var(--muted); margin-top: .1rem; }

.proj { border-top: 1px solid var(--border); padding: 1.5rem 0; }
.proj-title { font-size: 1rem; font-weight: 700; text-transform: none; letter-spacing: normal; margin: 0; }
.proj-sub { font-size: .8rem; color: var(--muted); margin: .15rem 0 .75rem; }

@media (max-width: 560px) {
  .mig > summary { grid-template-columns: 1fr auto; }
  .mig-where { grid-column: 1 / -1; margin-top: -.4rem; }
}

/* PIPELINE DIAGRAM — projects.html.
   The figure sits inside the prose column, so the 1080px artwork renders at
   roughly 640px and its 11px labels are not readable. That is on purpose: the
   figure is a thumbnail, and clicking it opens the same SVG at full size in a
   <dialog>. Light and dark are two files swapped by <picture>. */
.diagram { margin: 1.75rem 0 1.25rem; }

/* The script strips the href and sets role="button", so the cursor and focus
   affordances have to be stated here rather than inherited from :link. */
.diagram-zoom { display: block; cursor: zoom-in; border-radius: 12px; }

.diagram-zoom img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
  transition: border-color .2s;
}

.diagram-zoom:hover img,
.diagram-zoom:focus-visible img { border-color: var(--accent); }

.diagram-zoom:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.diagram figcaption {
  font-size: .75rem;
  color: var(--muted);
  line-height: 1.6;
  margin-top: .6rem;
}

.diagram-hint { color: var(--accent); }

/* Full-size overlay. <dialog> earns its place here: focus trapping, Escape to
   close and top-layer stacking all come free. The artwork is pinned to its
   1080px design width so it stays legible and pans on a small screen, rather
   than being shrunk back down to the size the thumbnail already is. */
.lightbox {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(96vw, 1140px);
  max-width: none;
  /* height must be definite for the auto margins to centre it: with height
     auto and inset 0, the box stretches to fill and the margins resolve to
     zero, so max-height then clamps it against the top-left corner. */
  height: fit-content;
  max-height: 92vh;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}

.lightbox::backdrop { background: rgba(0, 0, 0, .72); }

/* Fallback for browsers without <dialog>: position the panel and fake the
   backdrop with a spread shadow, so the overlay still covers the page. */
.lightbox.is-fallback {
  display: block;
  z-index: 999;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .72);
}

.lightbox-scroll {
  overflow: auto;
  max-height: 92vh;
  overscroll-behavior: contain;
}

.lightbox-scroll img { display: block; width: 1080px; max-width: none; height: auto; }

.lightbox-close {
  position: absolute;
  top: .6rem; right: .6rem;
  width: 2rem; height: 2rem;
  display: flex; align-items: center; justify-content: center;
  font: inherit; font-size: 1.15rem; line-height: 1;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
}

.lightbox-close:hover { border-color: var(--accent); color: var(--accent); }

/* MOTION */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
