/* Ink on warm paper (a faint grain in light mode), soft charcoal in dark mode: narrow Instrument
   Sans for headings, normal width for reading. Red marks the
   current job on the timeline, the link down to the resume, and links you point at. Light mode
   is the default, whatever the system's setting; the header's toggle picks dark (data-theme on
   <html>, set by site.js). The header and footer come next, then each page's own layout. */
:root {
  --paper: light-dark(#FAF8F4, #1C1D1F);
  --wash: light-dark(#F0EDE7, #27282B);
  --ink: light-dark(#1D1C1A, #E2E3E4);
  --muted: light-dark(#625F5A, #A2A6AB);
  --rule: light-dark(#E5E1DA, #34363A);
  /* Paper grain: tiled noise, drawn only in light mode. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .3 0 0 0 0 .25 0 0 0 0 .2 0 0 0 .09 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --accent: light-dark(#C8102E, #FF5A6B);
  --sans: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --page: 1200px;
  --gutter: clamp(20px, 4vw, 40px);
  color-scheme: light;
}
:root[data-theme="dark"] { color-scheme: dark; --grain: none; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  background: var(--grain), var(--paper);
  color: var(--ink);
  font: 400 18px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; height: auto; }
p, h1, h2, h3, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: var(--ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--accent); }
a:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; border-radius: 4px; }

.wrap { max-width: var(--page); margin-inline: auto; padding-inline: var(--gutter); }
.narrow { font-stretch: 75%; letter-spacing: -.02em; }

/* Icons: line icons are stroked, brand marks are filled. Both take the link's color. */
.ic { width: 24px; height: 24px; }
.ic.line { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ic.brand { width: 22px; height: 22px; fill: currentColor; }

/* Header: the name on the left; the home page’s sections and the light/dark toggle on the right.
   On a case study, Work is marked as the section you’re in. */
.top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 24px; padding-block: 28px; }
.name, .name:hover { color: var(--ink); text-decoration: none; font-weight: 600; font-size: 18px; }
.top .tools { display: flex; align-items: center; gap: 24px; }
.top nav ul { display: flex; flex-wrap: wrap; gap: 4px 24px; }
.top nav a { color: var(--muted); text-decoration: none; font-size: 16px; font-weight: 500; }
.top nav a:hover, .top nav a[aria-current] { color: var(--ink); }
.top nav a[aria-current] { font-weight: 600; box-shadow: inset 0 -2px 0 var(--accent); }

/* The light/dark toggle (see site.js). */
/* The padding makes it easier to hit; the negative margin keeps it from widening the header. */
.theme { display: grid; padding: 8px; margin: -8px; border: 0; border-radius: 50%; background: none; color: var(--muted); cursor: pointer; }
.theme:hover { color: var(--ink); }
.theme:focus-visible { outline: 2px solid var(--ink); }
.theme .ic { width: 20px; height: 20px; }

/* Footer: email and social links, and the copyright. */
.foot { padding-block: 28px 40px; border-top: 1px solid var(--rule); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 24px; }
.foot ul { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; }
.foot a { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 10px; }
.foot a:hover { background: var(--wash); }
.foot p { color: var(--muted); font-size: 14px; }

/* The home page (index.html). */
/* Hero: the title and a short intro, set flush right, then the three cards.
   Sizes and gaps follow the window height so they stay in proportion on short screens. */
.hero {
  display: flex; flex-direction: column;
  gap: clamp(28px, 5vh, 56px);
  padding-block: clamp(48px, 8vh, 96px) clamp(56px, 8vh, 96px);
}
.intro { display: grid; justify-items: end; text-align: right; gap: clamp(10px, 1.8vh, 18px); }
.intro h1 { font-size: clamp(44px, min(7.4vw, 11vh), 104px); line-height: .92; font-weight: 600; text-wrap: balance; }
/* The one red link, all in small caps: down to the resume. */
.to-resume { color: var(--accent); font-weight: 600; font-variant-caps: all-small-caps; letter-spacing: .04em; text-decoration: none; }
.to-resume span { display: inline-block; transition: transform .2s ease; }
.to-resume:hover span { transform: translateX(4px); }
.intro .lede { max-width: 36em; color: var(--muted); font-size: clamp(17px, 2.1vh, 20px); line-height: 1.5; text-wrap: balance; }
.intro .now { font-size: 16px; color: var(--muted); }
.intro .now b { color: var(--ink); font-weight: 600; }

.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2.4vw, 32px); }
/* The card takes all the spare height, so the three cards match and the links line up. */
.work { display: grid; grid-template-rows: 1fr auto; gap: 14px; text-decoration: none; color: var(--ink); }
.card {
  display: grid; align-content: start; gap: 12px; padding: clamp(14px, 2vh, 20px);
  border: 1px solid var(--rule); border-radius: 18px;
  transition: border-color .2s ease;
}
/* The screenshot leads, in full color, then the role, the name, the result and what I did. */
.card img { order: -1; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: left top; border-radius: 10px; background: var(--wash); box-shadow: 0 0 0 1px var(--rule); }
.card .role { font-size: 13px; font-weight: 600; letter-spacing: .02em; color: var(--muted); text-transform: uppercase; }
.card h2 { font-size: clamp(24px, 3.2vh, 32px); line-height: 1; font-weight: 600; }
.card .stat { display: grid; gap: 2px; padding-block: 10px; border-block: 1px solid var(--rule); }
.card .stat b { font-size: clamp(32px, 4.6vh, 44px); line-height: 1; font-weight: 600; font-stretch: 75%; letter-spacing: -.01em; }
.card .stat span { font-size: 14px; color: var(--muted); }
.card .text { display: grid; gap: 8px; align-content: start; font-size: 15px; line-height: 1.45; }
.card .text b { font-weight: 600; }
.work .go { font-weight: 600; font-size: 16px; padding-left: 4px; }
.work .go span { display: inline-block; transition: transform .2s ease; }
.work:hover .card { border-color: var(--ink); }
.work:hover .go { color: var(--accent); }
.work:hover .go span { transform: translateX(4px); }
.work:focus-visible { outline: none; }
.work:focus-visible .card { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .card, .card img, .work .go span, .to-resume span { transition: none; } }

/* Resume: a timeline down the left, each job's title beside what it involved. */
.resume { padding-block: clamp(64px, 9vw, 112px); border-top: 1px solid var(--rule); }
.resume-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 12px 24px; margin-bottom: clamp(40px, 5vw, 64px); }
.resume-head h2 { font-size: clamp(36px, 4.4vw, 56px); line-height: 1; font-weight: 600; }
.resume-head a { font-weight: 600; }

.timeline { border-left: 2px solid var(--ink); margin-left: 6px; }
.job { position: relative; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 12px clamp(24px, 5vw, 72px); padding: 0 0 clamp(40px, 5vw, 56px) clamp(28px, 4vw, 48px); }
.job:last-child { padding-bottom: 4px; }
/* A 14px dot centered on the 2px line, which sits just left of each job (-2px to 0). */
.job::before {
  content: ""; position: absolute; left: -8px; top: .45em; box-sizing: border-box;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--paper); border: 2px solid var(--ink);
}
.job.now::before { background: var(--accent); border-color: var(--accent); }
.job h3 { font-size: clamp(24px, 2.4vw, 30px); line-height: 1.1; font-weight: 600; }
.job .org { margin-top: 4px; }
.job time { display: block; margin-top: 2px; color: var(--muted); font-size: 16px; font-variant-numeric: tabular-nums; }
.job ul { display: grid; gap: 8px; padding-top: .2em; }
.job li { padding-left: 18px; position: relative; }
.job li::before { content: ""; position: absolute; left: 0; top: .72em; width: 8px; height: 1px; background: var(--muted); }

.extras { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 24px clamp(24px, 5vw, 72px); margin-top: clamp(48px, 6vw, 72px); padding-left: calc(6px + 2px + clamp(28px, 4vw, 48px)); }
.extras h3 { font-size: 16px; font-weight: 600; color: var(--muted); margin-bottom: 8px; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips li { padding: 4px 12px; border: 1px solid var(--rule); border-radius: 999px; font-size: 15px; }

/* Section headings, then apps, about and contact. */
.sec-head { display: grid; gap: 8px; padding-top: 28px; border-top: 1px solid var(--rule); }
.sec-head h2 { font-size: clamp(30px, 3.6vw, 40px); line-height: 1.05; font-weight: 600; }
.sec-head p { color: var(--muted); max-width: 40em; }

.apps-sec { padding-bottom: clamp(96px, 12vw, 160px); }
.apps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px clamp(32px, 5vw, 72px); margin-top: 40px; }
.app { display: grid; grid-template-columns: 64px 1fr; gap: 4px 20px; align-items: start; }
.app img { grid-row: span 3; width: 64px; height: 64px; }
.app h3 { font-size: 20px; line-height: 1.3; font-weight: 600; }
.app h3 a { color: inherit; text-decoration: none; }
.app h3 a:hover { text-decoration: underline; }
.app .kind { font-size: 15px; color: var(--muted); }
.app .head { font-size: 16px; }

.about-sec { padding-bottom: clamp(96px, 12vw, 160px); }
.about { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(40px, 6vw, 96px); margin-top: 40px; }
.story { display: grid; gap: 20px; align-content: start; max-width: 36em; }
.story img { width: 120px; height: 120px; border-radius: 50%; }
.career h3 { font-size: 16px; font-weight: 600; color: var(--muted); margin-bottom: 12px; }
.career ol { border-top: 1px solid var(--rule); }
.career li { display: grid; grid-template-columns: 1fr auto; gap: 0 16px; padding-block: 14px; border-bottom: 1px solid var(--rule); font-size: 16px; }
.career b { font-weight: 600; }
.career span { color: var(--muted); }
.career time { grid-column: 2; grid-row: 1; color: var(--muted); font-variant-numeric: tabular-nums; }
.button {
  display: inline-block; justify-self: start; margin-top: 24px;
  padding: 12px 20px; border-radius: 999px;
  background: var(--ink); color: var(--paper);
  font-weight: 600; font-size: 16px; text-decoration: none;
}
.button:hover { background: var(--accent); color: var(--paper); }

.contact { padding-block: 28px clamp(64px, 8vw, 96px); border-top: 1px solid var(--rule); }
.contact h2 { font-size: clamp(36px, 6vw, 72px); line-height: 1; font-weight: 600; max-width: 14ch; }
.contact .links { display: flex; flex-wrap: wrap; gap: 12px 32px; margin-top: 32px; font-size: 20px; font-weight: 500; }

/* Narrow windows: the cards stack, so the first screen scrolls; jobs put the details under the title. */
@media (max-width: 900px) {
  .cards { grid-template-columns: 1fr; max-width: 560px; width: 100%; margin-inline: auto; }
  .job, .extras { grid-template-columns: 1fr; }
  .about { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .apps { grid-template-columns: 1fr; }
}

/* The case studies (work/<case>/index.html): the sidebar beside the story. */
.layout { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); padding-top: clamp(24px, 4vw, 48px); }

/* The sidebar: every case study, this one marked, then this page's sections. */
.side { position: sticky; top: 24px; align-self: start; display: grid; gap: 32px; font-size: 16px; }
.side h2 { font-size: 14px; font-weight: 600; color: var(--muted); margin-bottom: 10px; }
.catalog { border-top: 1px solid var(--rule); }
.catalog a { display: grid; gap: 0; padding: 10px 0 10px 14px; border-bottom: 1px solid var(--rule); text-decoration: none; color: var(--muted); }
.catalog a:hover { color: var(--ink); }
.catalog b { font-weight: 600; }
.catalog span { font-size: 14px; font-variant-numeric: tabular-nums; }
.catalog a[aria-current] { color: var(--ink); box-shadow: inset 3px 0 0 var(--accent); }
.catalog a[aria-current] span { color: var(--muted); }
.toc { display: grid; gap: 6px; }
.toc a { color: var(--muted); text-decoration: none; }
.toc a:hover { color: var(--accent); }

/* The case study itself. */
.study { display: grid; gap: clamp(28px, 3vw, 40px); padding-bottom: clamp(48px, 6vw, 80px); }
.study h1 { margin-top: 12px; font-size: clamp(56px, 8vw, 104px); line-height: .9; font-weight: 600; }
.study .sub { margin-top: 12px; font-size: clamp(20px, 2.2vw, 26px); color: var(--muted); }
.outcome { padding-left: 20px; border-left: 3px solid var(--accent); font-size: clamp(22px, 2.4vw, 30px); line-height: 1.3; font-weight: 600; max-width: 26em; }
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 32px; font-size: 16px; }
.facts dt { font-size: 14px; color: var(--muted); }

.sec { display: grid; gap: 18px; padding-top: clamp(32px, 4vw, 48px); border-top: 1px solid var(--rule); scroll-margin-top: 24px; }
.sec > h2 { font-size: clamp(28px, 3vw, 36px); line-height: 1.05; font-weight: 600; }
.sec > p, .sec > .ticks { max-width: 40em; }
.surface { display: grid; gap: 12px; margin-top: 8px; }
.surface h3 { font-size: 19px; font-weight: 600; }
.parts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 40px; }
.parts h3 { font-size: 15px; font-weight: 600; color: var(--muted); margin-bottom: 10px; }

/* Narrow windows: the sidebar moves above the story, the case studies in a row. */
@media (max-width: 900px) {
  .layout { grid-template-columns: 1fr; }
  .side { position: static; gap: 20px; }
  .catalog { display: flex; flex-wrap: wrap; gap: 8px; border-top: 0; }
  .catalog a { padding: 6px 12px; border: 1px solid var(--rule); border-radius: 999px; }
  .catalog a[aria-current] { border-color: var(--ink); box-shadow: none; }
  .catalog span, .side .toc-block { display: none; }
  .parts, .facts { grid-template-columns: 1fr; }
}

/* Where you are: Work, then this case study. */
.crumbs { display: flex; flex-wrap: wrap; gap: 8px; font-size: 15px; color: var(--muted); }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--accent); }

/* Screenshots: desktop screens full width or in pairs, phone screens in threes. */
.shot { overflow: hidden; border-radius: 14px; background: var(--wash); box-shadow: 0 0 0 1px var(--rule); }
.shot img { width: 100%; }
.pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.phones { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.phones .shot { border-radius: 24px; }
.caption { margin-top: 10px; font-size: 14px; line-height: 1.45; color: var(--muted); }

/* Lists of what I did and what others did. */
.ticks { display: grid; gap: 8px; }
.ticks li { position: relative; padding-left: 18px; }
.ticks li::before { content: ""; position: absolute; left: 0; top: .72em; width: 8px; height: 1px; background: var(--muted); }
.ticks b { font-weight: 600; }

/* Footnote markers and the notes they point to. */
sup { line-height: 0; }
sup a { padding-left: 1px; color: var(--accent); font-size: .75em; font-weight: 600; text-decoration: none; }
.notes { display: grid; gap: 10px; font-size: 14px; line-height: 1.5; color: var(--muted); counter-reset: note; }
.notes li { position: relative; padding-left: 24px; counter-increment: note; }
.notes li::before { content: counter(note) "."; position: absolute; left: 0; color: var(--ink); font-weight: 600; }
.notes a { color: var(--muted); word-break: break-word; }
.notes a:hover { color: var(--accent); }

/* The results table, with the winning row in bold. */
.results { width: 100%; border-collapse: collapse; font-size: 16px; font-variant-numeric: tabular-nums; }
.results th, .results td { padding: 12px 12px 12px 0; text-align: left; border-bottom: 1px solid var(--rule); }
.results thead th { font-size: 14px; font-weight: 600; color: var(--muted); }
.results tbody th { font-weight: 400; }
.results td { text-align: right; }
.results thead th:not(:first-child) { text-align: right; }
.results .best th, .results .best td { font-weight: 700; }
.results .best td:last-child { color: var(--accent); }

/* The way out at the end: the next case study, or back to all the work. */
.next { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: end; gap: 16px 32px; padding-block: 28px clamp(56px, 8vw, 96px); border-top: 1px solid var(--rule); }
.next .label { font-size: 15px; color: var(--muted); }
.next .to { font-size: clamp(30px, 4vw, 48px); line-height: 1; font-weight: 600; text-decoration: none; }
.next .to span { display: inline-block; transition: transform .2s ease; }
.next .to:hover span { transform: translateX(6px); }
.next .all { font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .next .to span { transition: none; } }

@media (max-width: 700px) {
  .pair { grid-template-columns: 1fr; }
  .phones { gap: 8px; }
  .phones .shot { border-radius: 14px; }
}

/* Page not found (404.html). */
.missing { display: grid; gap: 16px; padding-block: clamp(48px, 10vh, 120px) clamp(64px, 12vh, 160px); }
.missing h1 { font-size: clamp(44px, 7vw, 88px); line-height: .95; font-weight: 600; }
.missing p { color: var(--muted); max-width: 36em; }
