/* ============================================================================
   matthewdavis-ops.github.io — shared design system
   Layout: a document with a masthead. Ruled sections, dates in a left rail,
   one amber accent doing all the signaling. Contrast verified WCAG AA in both
   themes.

   Every page links this file. Pages carry a small inline <style> block only
   for components that exist on that page alone (index: masthead/portrait and
   résumé density; career: nothing; writing: .theme/.posts/.award;
   research: .paper/.venue/.abstract).
   ========================================================================= */

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; }
img { max-width: 100%; height: auto; }

/* ---------- tokens ---------- */
:root {
  --paper: #f6f6f4;
  --card: #ffffff;
  --ink: #121a1f;
  --ink-2: #3f5059;
  --ink-3: #5f6f76;
  --rule: #d9dcd9;
  --rule-2: #b9bfbc;
  --amber: #8a6214;
  --navy: #0d3345;
  --school: #2f6b4f;
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-mono: "Roboto Mono", ui-monospace, Menlo, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0c171d;
    --card: #122129;
    --ink: #e8edef;
    --ink-2: #a9bcc4;
    --ink-3: #8da8b3;
    --rule: #22353f;
    --rule-2: #35505c;
    --amber: #d6a24d;
    --navy: #a9cfe2;
    --school: #7cc3a0;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --paper: #0c171d;
  --card: #122129;
  --ink: #e8edef;
  --ink-2: #a9bcc4;
  --ink-3: #8da8b3;
  --rule: #22353f;
  --rule-2: #35505c;
  --amber: #d6a24d;
  --navy: #a9cfe2;
  --school: #7cc3a0;
  color-scheme: dark;
}

/* ---------- base ---------- */
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 780px;
  margin: 0 auto;
  padding-inline: 22px;
  padding-block: 34px 60px;
  display: flex;
  flex-direction: column;
  gap: 34px;
}

/* ---------- nav ---------- */
nav.site {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 12px;
}
nav.site a { color: var(--ink-3); text-decoration: none; }
nav.site a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
nav.site a[aria-current="page"] { color: var(--amber); font-weight: 500; }

/* ---------- masthead ---------- */
header.mast { display: flex; flex-direction: column; gap: 12px; }
.name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(30px, 7vw, 46px);
  line-height: 1.04;
  letter-spacing: -0.025em;
  margin: 0;
  text-wrap: balance;
}
/* .disciplines is the profile page's name for the same element */
.kicker, .disciplines {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(12px, 2.6vw, 13.5px);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--amber);
  margin: 0;
}
.standfirst {
  font-size: 17.5px;
  color: var(--ink-2);
  margin: 0;
  border-top: 2px solid var(--ink);
  padding-top: 14px;
  /* Runs the full column on purpose. The rule above this text is this
     element's own border-top, so capping the measure also capped the rule
     and left it short of the section rules below it. Justified, with
     hyphenation doing the work that would otherwise show up as word gaps. */
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
  /* break only words of 7+ characters, never leaving fewer than 3 either side */
  -webkit-hyphenate-limit-before: 3;
  -webkit-hyphenate-limit-after: 3;
  hyphenate-limit-chars: 7 3 3;
}
.standfirst strong { color: var(--ink); font-weight: 600; }
/* a second standfirst paragraph continues the first — no second rule above it */
.standfirst + .standfirst { border-top: 0; padding-top: 0; margin-top: -3px; }

/* ---------- sections ---------- */
section { display: flex; flex-direction: column; gap: 14px; }
.sec-head {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.sec-head::after { content: ""; flex: 1; height: 2px; background: var(--amber); opacity: 0.5; }
p { margin: 0; }
section > p + p { margin-top: -2px; }
.prose { max-width: 64ch; display: flex; flex-direction: column; gap: 13px; }
.prose p { font-size: 16.5px; }
.prose strong { font-weight: 600; }

/* ---------- entries / timeline ---------- */
.entry {
  display: grid;
  grid-template-columns: 136px 1fr;
  gap: 4px 22px;
  padding-block: 18px;
  border-top: 1px solid var(--rule);
}
.entry:first-of-type { border-top: 0; padding-top: 4px; }
.when {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  padding-top: 5px;
  line-height: 1.45;
}
.what { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.role {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  line-height: 1.25;
  margin: 0;
  letter-spacing: -0.01em;
}
/* .org sits inside .what, so `.what p` below sets its size — a font-size here
   would be dead code. Change the size on `.what p`, not here. */
.org { color: var(--ink-2); }
.org b { color: var(--ink); font-weight: 600; }
.what p { font-size: 15.5px; }
.what p.note { color: var(--ink-2); }
/* .meta and .cred-note set font-size: 12.5px, but `.what p` above is (0,1,1)
   and a bare `.meta` is (0,1,0) — so inside an entry they were rendering at
   body size in a monospace face, which reads far larger than the serif around
   them. Scoped to (0,2,1) to actually win. Fourth time this trap has come up
   here: compare a rule against what already MATCHES the element, not against
   the other rules. */
.what p.meta, .what p.cred-note { font-size: 12.5px; }
.what ul { margin: 4px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.what li { font-size: 15.5px; line-height: 1.55; }
.what li b { font-weight: 600; }
/* .cred-note is the profile page's name for the same element */
.meta, .cred-note {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-3);
  line-height: 1.5;
}

/* track labels: work vs school */
.track {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  display: inline-block;
  align-self: flex-start;
  padding: 2px 7px;
  border-radius: 2px;
  margin-bottom: 2px;
}
.track.work { background: var(--navy); color: var(--paper); }
.track.school { background: var(--school); color: var(--paper); }
.entry.school { border-left: 3px solid var(--school); padding-left: 16px; margin-left: -19px; }
.entry.gap-note {
  border-top: 1px dashed var(--rule-2);
  border-bottom: 1px dashed var(--rule-2);
  background: color-mix(in srgb, var(--amber) 7%, transparent);
  padding-inline: 14px;
  border-radius: 3px;
}

/* ---------- lists & items ---------- */
ul { margin: 0; padding-left: 19px; display: flex; flex-direction: column; gap: 7px; }
li { font-size: 15.5px; min-width: 0; }
.stack { display: flex; flex-direction: column; gap: 13px; }
.item { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: baseline; min-width: 0; }
.tag {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--navy);
  padding: 3px 8px;
  border-radius: 2px;
  white-space: nowrap;
}
.tag.top { background: var(--amber); }
.item-body { min-width: 0; font-size: 15.5px; }
.item-body b { font-weight: 600; }
.item-body span { color: var(--ink-2); }
.item-body .ref {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 4px;
  overflow-wrap: anywhere;
}
.item-body .ref a { color: var(--ink-3); }

/* titled list — works with or without a trailing meta note */
.titles { margin: 2px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
.titles li { font-size: 15px; color: var(--ink-2); }
.titles li i { color: var(--ink); font-style: italic; }
.titles li .meta { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); }

.inline-list { font-size: 15.5px; color: var(--ink-2); margin: 0; }
.inline-list b { color: var(--ink); font-weight: 600; }

/* grouped columns — collapses to one column on narrow screens */
.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 20px 30px; }
.colgroup { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.colgroup h3 {
  font-family: var(--font-display); font-weight: 700; font-size: 11.5px;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--amber); margin: 0;
}
.colgroup ul { margin: 0; padding-left: 17px; display: flex; flex-direction: column; gap: 4px; }
.colgroup li { font-size: 14.5px; line-height: 1.45; color: var(--ink-2); }
.colgroup li b { color: var(--ink); font-weight: 600; }

/* ---------- callout ---------- */
.callout {
  border-left: 3px solid var(--amber);
  padding: 2px 0 2px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* The amber rule and the indent already mark this as an aside. Capping
     the measure too was a second, redundant inset, and it left the block
     visibly narrower than the justified standfirst above it. */
}
.callout p {
  font-size: 16px;
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
  -webkit-hyphenate-limit-before: 3;
  -webkit-hyphenate-limit-after: 3;
  hyphenate-limit-chars: 7 3 3;
}
.callout .lbl {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--amber);
}

/* ---------- links & footer ---------- */
a { color: var(--amber); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { color: var(--ink); }
a:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; border-radius: 2px; }

footer {
  border-top: 2px solid var(--ink);
  padding-top: 13px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-3);
}
footer a { color: var(--ink-3); }

/* ---------- responsive ---------- */
@media (max-width: 560px) {
  .entry { grid-template-columns: 1fr; gap: 8px; }
  .when { padding-top: 0; }
  .entry.school { margin-left: 0; }
  .item { grid-template-columns: 1fr; gap: 5px; }
  .tag { justify-self: start; }
}

/* ---------- print ---------- */
@media print {
  :root {
    --paper: #fff; --card: #fff; --ink: #000; --ink-2: #333; --ink-3: #555;
    --rule: #ccc; --rule-2: #999; --amber: #7a5612; --navy: #0d3345; --school: #27543e;
  }
  body { background: #fff; font-size: 10pt; line-height: 1.42; }
  .wrap { padding-block: 0; max-width: none; gap: 16px; }
  nav.site { display: none; }
  .name { font-size: 26pt; }
  .entry { padding-block: 10px; }
  .role { font-size: 13pt; }
  .what p, li, .item-body, .prose p { font-size: 9.8pt; }
  .inline-list, .titles li, .colgroup li { font-size: 9.8pt; }
  .cols { gap: 10px 22px; }
  .colgroup h3 { font-size: 9pt; }
  .colgroup { break-inside: avoid; }
  .item, li, .theme { break-inside: avoid; }
  .sec-head { break-after: avoid; }
  a { text-decoration: none; }
}

/* ---------- essays ---------- */
.essay { display: flex; flex-direction: column; gap: 16px; max-width: 60ch; }
.essay p { font-size: 17.5px; line-height: 1.68; }
/* :last-child, not :last-of-type, silently did nothing on 2026-07, whose essay
   ends with the illustration plate rather than the closing paragraph - nine
   essays closed in bold and one closed in body weight. Fifth time a selector
   here has been checked against the other rules instead of against what
   actually matches the element. */
.essay p:last-of-type { font-weight: 600; color: var(--ink); }

.dateline {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.05em;
  color: var(--ink-3);
}

/* prev / next between essays */
.essay-nav {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  border-top: 1px solid var(--rule);
  padding-top: 15px;
  font-size: 15px;
}
.essay-nav a { text-decoration: none; max-width: 46%; }
.essay-nav a:hover { text-decoration: underline; text-underline-offset: 3px; }
.essay-nav .dir {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 3px;
}
.essay-nav .nx { text-align: right; margin-left: auto; }

/* the index list */
.elist { display: flex; flex-direction: column; }
.elist .e {
  position: relative;
  display: grid;
  grid-template-columns: 112px 1fr;
  gap: 4px 22px;
  padding-block: 17px;
  border-top: 1px solid var(--rule);
}
.elist .e:first-child { border-top: 0; padding-top: 3px; }
.elist .e .mo {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-3);
  padding-top: 4px;
}
.elist .e .b { min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.elist .e .hd {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.elist .e .hd.cold { font-family: var(--font-body); font-weight: 400; font-style: italic; }
.elist .e .hd a { color: var(--amber); text-decoration: none; }
.elist .e .hd a::after { content: ""; position: absolute; inset: 0; }
.elist .e:hover .hd a { text-decoration: underline; text-underline-offset: 3px; }
.elist .e:hover .mo { color: var(--ink-2); }
.elist .e .g { font-size: 15.5px; color: var(--ink-2); }

@media (max-width: 560px) {
  .elist .e { grid-template-columns: 1fr; gap: 6px; }
  .elist .e .mo { padding-top: 0; }
  .essay-nav { flex-direction: column; gap: 12px; }
  .essay-nav .nx { text-align: left; margin-left: 0; }
}

@media print {
  .essay p { font-size: 10.5pt; line-height: 1.5; }
  .essay-nav, nav.site { display: none; }
  .elist .e { break-inside: avoid; }
}

/* illustration plates inside an essay — shown at native size, never upscaled */
.essay figure { margin: 7px auto; display: flex; flex-direction: column; gap: 7px; max-width: 100%; }
.essay figure img {
  display: block;
  width: 488px;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--rule-2);
  border-radius: 3px;
}
.essay figure figcaption {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
@media print { .essay figure { break-inside: avoid; } }

/* ---------- part break ---------- */
/* Where a page carries two titled parts (Writing: the clinical work, then the
   essays. Research: semantic addressing, then the 2019 project), the second
   part opens with a rule and extra air. The structure is already semantic -
   separate sections, separate headings - so this is presentational only, and
   doing it with a border rather than an <hr> lets one declaration carry both
   the line and the space. Matches the weight of the standfirst rule below the
   part heading, so the two read as a bracket around it. */
.part-break {
  border-top: 2px solid var(--ink);
  padding-top: 30px;
  margin-top: 8px;
}
@media print { .part-break { padding-top: 18px; break-before: auto; } }

/* ---------- identity block: identical on every page ---------- */
.identity { display: flex; flex-direction: column; gap: 14px; }
.mast-row { display: flex; align-items: center; gap: 22px; }
.mast-text { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.portrait {
  width: 118px; height: 118px; flex: none;
  border-radius: 50%; object-fit: cover; object-position: 50% 32%;
  border: 1px solid var(--rule-2);
}
.name-id {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(34px, 8vw, 54px); line-height: 1.02;
  letter-spacing: -0.02em; color: var(--ink); margin: 0;
}
.contact {
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--rule-2);
  padding-block: 10px;
  display: flex; flex-wrap: wrap; gap: 6px 20px;
  font-family: var(--font-mono); font-size: 13px; color: var(--ink-2);
}
.contact .url { color: var(--ink); font-weight: 500; }
.contact .sep { color: var(--rule-2); }
/* On screen the address is redundant - the reader is already here. In print it
   is the only route back to the site, so it comes back for the PDF only. */
.contact .url, .contact .url + .sep { display: none; }

/* nav is navigation, not metadata: it carries the same affordance as a link */
nav.site { gap: 6px; border-bottom: 0; padding-bottom: 0; letter-spacing: 0.02em; }
nav.site a {
  color: var(--ink-2); text-decoration: none;
  border: 1px solid var(--rule-2); border-radius: 3px; padding: 4px 7px;
}
nav.site a:hover { color: var(--ink); border-color: var(--amber); text-decoration: none; }
nav.site a[aria-current="page"] { color: var(--amber); border-color: var(--amber); }

@media (max-width: 440px) {
  .mast-row { gap: 15px; }
  .portrait { width: 84px; height: 84px; }
}
@media print {
  .contact .url, .contact .url + .sep { display: inline; }
  /* The resume lives in the contact strip rather than the nav: it is a
     download, not a section of the site. It comes out in print, where the
     page being printed IS the resume and a link to itself is circular. */
  .contact .r-sep, .contact .resume { display: none; }
}
