
/* The same tokens the PDF renderer uses, so the page and the document
   printed from it read as one identity. Contrast on white as measured:
   ink 16.3:1, soft 8.0:1, acc 6.5:1. Nothing below 4.5:1 is used for text. */
:root { --ink:#0f1c2b; --soft:#3a4f64; --rule:#d7e2ee; --acc:#0a5fa8; --bg:#ffffff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --ink:#e7eef6; --soft:#90a5b9; --rule:#27374a; --acc:#7cc2f7; --bg:#0d141d; }
}
* { box-sizing:border-box; }
body { margin:0; background:var(--bg); color:var(--ink);
  font:16.5px/1.65 Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif; }
.wrap { max-width:78ch; margin:0 auto; padding:40px 22px 80px; }
a { color:var(--acc); }
.back { font-size:13px; letter-spacing:.05em; text-transform:uppercase; text-decoration:none;
  border:1px solid var(--rule); border-radius:999px; padding:6px 14px; color:var(--soft); }
.back:hover { color:var(--acc); border-color:var(--acc); }
h1 { font-size:33px; margin:24px 0 2px; letter-spacing:-.02em; }
.role { font-size:17.5px; color:var(--acc); margin:0 0 8px; font-weight:600; }
.meta { color:var(--soft); font-size:15px; margin:0 0 6px; }
.lede { font-size:17px; margin:20px 0 0; }
h2 { font-size:12.5px; letter-spacing:.17em; text-transform:uppercase; color:var(--acc);
  border-bottom:1px solid var(--rule); padding-bottom:7px; margin:38px 0 15px; }
h3 { font-size:17.5px; margin:0 0 2px; }
.sub { color:var(--soft); font-size:15px; margin:0 0 10px; }
ul { margin:0 0 15px; padding-left:20px; }
li { margin-bottom:7px; }
.skill { margin-bottom:10px; }
.skill b { color:var(--ink); }
/* Label and value both sit in ink, distinguished by weight alone — the
   PDF sets them the same way. Dimming the value added a third colour to
   the line and dropped it from 16.3:1 to 8.0:1 for no gain. */
.skill span { color:var(--ink); }
.proj { margin-bottom:17px; }
/* repo_link() emits `sub private` when a repo is closed; with no rule for it
   the note read as a continuation of the description above it */
.private { font-size:14px; color:var(--soft); opacity:.85; }
.lede-role { font-size:16.5px; margin:0 0 10px; color:var(--ink); font-weight:500; }
footer { margin-top:46px; border-top:1px solid var(--rule); padding-top:15px;
  color:var(--soft); font-size:14px; }
/* ---- layout switcher ---- */
.views { display:inline-flex; gap:2px; margin:18px 0 0; padding:3px;
  border:1px solid var(--rule); border-radius:999px; font-size:13px; }
.views a, .views .on { padding:5px 15px; border-radius:999px; text-decoration:none;
  color:var(--soft); letter-spacing:.03em; }
.views a:hover { color:var(--acc); }
.views .on { background:var(--acc); color:var(--bg); font-weight:600; }

/* ---- career timeline ----
   The spine is a border on the list, so it grows with the content and needs no
   fixed height. Cards are lifted off it with a two-layer shadow: a tight dark
   one for contact and a wide soft one for distance, which is what reads as
   depth on a light page. */
.tl { list-style:none; margin:0; padding:0 0 0 26px; border-left:2px solid var(--rule); }
.tl-i { position:relative; margin:0 0 30px; }
/* Centre the node on the spine: the list pads 26px and the border is 2px, so
   the spine centre is 27px left of the card. The dot is 12px wide inside a 3px
   ring, so 18px overall and half of that is 9. 27 + 9 = 36. */
.tl-i::before {
  content:""; position:absolute; left:-36px; top:5px; width:12px; height:12px;
  border-radius:50%; background:var(--acc); border:3px solid var(--bg);
  box-shadow:0 0 0 2px var(--rule);
}
.tl-edu::before { background:var(--bg); border-color:var(--acc); }
.tl-when { font-size:12.5px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--soft); margin-bottom:6px; font-weight:600; }
.tl-card {
  border:1px solid var(--rule); border-radius:12px; padding:17px 19px 6px;
  background:var(--bg);
  box-shadow:0 1px 2px rgba(10,30,60,.07), 0 10px 24px -12px rgba(10,30,60,.22);
  transition:transform .16s ease, box-shadow .16s ease;
}
.tl-card:hover {
  transform:translateY(-2px);
  box-shadow:0 2px 4px rgba(10,30,60,.09), 0 18px 34px -14px rgba(10,30,60,.30);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tl-card {
    box-shadow:0 1px 2px rgba(0,0,0,.5), 0 12px 28px -14px rgba(0,0,0,.75);
  }
}
@media (prefers-reduced-motion: reduce) {
  .tl-card { transition:none; }
  .tl-card:hover { transform:none; }
}
/* the card list nests inside the timeline <ol>, and a nested list defaults
   to hollow circles, which does not match the detailed view */
.tl-card ul { margin-bottom:12px; list-style:disc; }

/* ---- certification chips ---- */
.chips { list-style:none; display:flex; flex-wrap:wrap; gap:8px; margin:0 0 4px; padding:0; }
.chips li { border:1px solid var(--rule); border-radius:999px; padding:6px 14px;
  font-size:14px; color:var(--soft); margin:0; }

@media print {
  :root { --ink:#000; --soft:#333; --rule:#bbb; --acc:#000; --bg:#fff; }
  .back, .views, footer .noprint { display:none; }
  .wrap { max-width:none; padding:0; }
  body { font-size:11pt; }
  /* depth is a screen affordance; on paper it is just grey mush */
  .tl-card { box-shadow:none; border-radius:0; border:0; border-left:1px solid #bbb;
    padding:0 0 0 12px; }
  .tl { border-left:0; padding-left:0; }
  .tl-i::before { display:none; }
  .tl-i { break-inside:avoid; }
  .chips li { border-radius:0; }
}
