:root {
  --paper: #FBFBF8;
  --ink: #1A1916;
  --ink-soft: #57544C;
  --rule: #DEDCD2;
  --accent: #1F4E79;
  --accent-dim: #A2B4C9;
  --serif: "STIX Two Text", "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, monospace;
  color-scheme: light;
}

/* dark palette: same warm cast as the light one, accent lightened to keep
   contrast. [data-theme] is the visitor's explicit choice (set by JS from
   localStorage); the media query covers system preference and no-JS.
   keep both blocks in sync. */
:root[data-theme="dark"] {
  --paper: #171613;
  --ink: #E8E6DE;
  --ink-soft: #9B968A;
  --rule: #3A382F;
  --accent: #8FB7DD;
  --accent-dim: #50647A;
  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #171613;
    --ink: #E8E6DE;
    --ink-soft: #9B968A;
    --rule: #3A382F;
    --accent: #8FB7DD;
    --accent-dim: #50647A;
    color-scheme: dark;
  }
}

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

::selection { background: var(--accent); color: var(--paper); }

a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-dim);
  /* no transition: link states snap, they don't fade */
}
a:hover { color: var(--accent); border-bottom-color: var(--accent); }
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-bottom-color: transparent;
}

/* inverse video on hover — terminal selection idiom; fine pointers only
   so touch devices never get a stuck hover state */
@media (hover: hover) and (pointer: fine) {
  a:hover {
    background: var(--accent);
    color: var(--paper);
    border-bottom-color: var(--accent);
  }
  .memmap .val a:hover { border-bottom-color: var(--accent); }
}

.card {
  width: 100%;
  max-width: 42rem;
  padding: 2rem 1.5rem;
}

/* ---------- hero: memory map ---------- */
h1 {
  font-size: clamp(2.2rem, 7vw, 3.4rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin-bottom: 0.4rem;
}
h1 .cursor {
  display: inline-block;
  width: 0.5em;
  height: 0.9em;
  margin-left: 0.12em;
  background: var(--accent);
  vertical-align: baseline;
  transform: translateY(0.08em);
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* cursor goes solid while the machine is "busy" (boot) or the visitor is
   active; .hold is toggled by JS, blink resumes on idle */
.hold h1 .cursor { animation: none; }

/* during boot the name is typed in by JS; hide it pre-type so the cursor
   starts at column 0 (JS restores display immediately, see index.html) */
.boot h1 .name { display: none; }

.subtitle {
  font-style: italic;
  color: var(--ink-soft);
  margin-bottom: 2rem;
}

.memmap {
  font-family: var(--mono);
  font-size: 0.875rem;
  line-height: 1.75;
  position: relative;
  padding: 0.875rem 0;
}
/* hairlines as pseudo-elements so the boot sequence can draw them in */
.memmap::before,
.memmap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--rule);
  transform-origin: left;
}
.memmap::before { top: 0; }
.memmap::after { bottom: 0; }

.memmap .row {
  display: grid;
  grid-template-columns: 10.5rem 1fr;
  gap: 0 1rem; /* no row gap: on mobile the value wraps under its field */
  align-items: baseline;
  position: relative;
  /* bleed cancels: highlight extends past the text, columns don't move;
     extra left padding indents fields like code inside the braces */
  padding-inline: 0.75rem;
  padding-left: 2.75rem;
  margin-inline: -0.75rem;
}
.memmap .field { color: var(--ink-soft); }
.memmap .val a { border-bottom-color: var(--rule); }
.memmap .kw { color: var(--ink-soft); }

/* debugger line-select on hover — instant on/off, no transition */
@media (hover: hover) and (pointer: fine) {
  .memmap .row::before {
    content: ">";
    content: ">" / "";
    position: absolute;
    left: 0.1rem;
    color: var(--accent);
    opacity: 0;
  }
  .memmap .row:hover {
    background: var(--rule);
    background: color-mix(in srgb, var(--rule) 55%, transparent);
  }
  .memmap .row:hover::before { opacity: 1; }
  .memmap .row:hover .field { color: var(--ink); }
}

/* ---------- experience ---------- */
.experience { margin-top: 2.25rem; }

.label {
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  display: block;
  margin-bottom: 1rem;
}

.entry { margin-bottom: 1.4rem; }
.entry:last-child { margin-bottom: 0; }
.entry h2 {
  font-size: 1rem;
  font-weight: 600;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
}
.entry h2 .date {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--ink-soft);
}
.entry .org {
  font-style: italic;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

/* ---------- contact footnotes ---------- */
.footnotes {
  margin-top: 2.25rem;
  border-top: 1px solid var(--rule);
  padding-top: 1.1rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.footnotes p { margin-bottom: 0.3rem; }
.footnotes sup {
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--accent);
  margin-right: 0.4rem;
}

footer {
  margin-top: 2.25rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--ink-soft);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* ---------- boot sequence ----------
   .boot is set on <html> by an inline head script, only when JS is
   available AND prefers-reduced-motion is not set. Without it, nothing
   below applies and the page renders complete and static.
   All effects are opacity/transform with space reserved — zero CLS. */

@keyframes appear { from { opacity: 0; } to { opacity: 1; } }

@keyframes rise {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}

@keyframes draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.boot .subtitle { animation: rise 220ms cubic-bezier(0.2, 0, 0, 1) 560ms both; }

.boot .memmap::before { animation: draw 280ms steps(10, end) 600ms both; }
.boot .memmap::after  { animation: draw 280ms steps(10, end) 1080ms both; }

.boot .memmap > p,
.boot .memmap .row { animation: appear 30ms linear both; }

.boot .memmap > p:first-of-type { animation-delay: 660ms; }
.boot .memmap > p:last-of-type  { animation-delay: 1080ms; }

.boot .memmap .row:nth-of-type(1) { animation-delay: 720ms; }
.boot .memmap .row:nth-of-type(2) { animation-delay: 770ms; }
.boot .memmap .row:nth-of-type(3) { animation-delay: 820ms; }
.boot .memmap .row:nth-of-type(4) { animation-delay: 870ms; }
.boot .memmap .row:nth-of-type(5) { animation-delay: 920ms; }
.boot .memmap .row:nth-of-type(6) { animation-delay: 970ms; }

.boot .experience { animation: rise 220ms cubic-bezier(0.2, 0, 0, 1) 1140ms both; }
.boot .footnotes  { animation: rise 220ms cubic-bezier(0.2, 0, 0, 1) 1200ms both; }
.boot footer      { animation: rise 220ms cubic-bezier(0.2, 0, 0, 1) 1260ms both; }

/* ---------- theme toggle ----------
   hidden until JS removes [hidden]; without JS the media query above
   still applies the system theme, there's just nothing to click. */
.theme-toggle {
  position: fixed;
  top: 0.9rem;
  right: 1rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  background: none;
  border: 0;
  padding: 0.4rem 0.5rem;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .theme-toggle:hover { background: var(--accent); color: var(--paper); }
}
.theme-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- responsive ---------- */
@media (max-width: 560px) {
  /* field + value stack as a pair; small margin separates entries */
  .memmap .row { grid-template-columns: 1fr; margin-bottom: 0.4rem; }
  .memmap .row:last-of-type { margin-bottom: 0; }
  .memmap .row .field { color: var(--accent-dim); }
}
