/* dor.ky. Dark-first console; light theme is the field-note paper/green.
   Every colour, face and rule in the site comes from these tokens. */
:root{
  /* Row hover: a tint of the ink rather than a raised surface, so it lifts
     without glaring on the paper theme. */
  --row-hover:color-mix(in srgb, var(--ink) 5%, transparent);
  --bg:#0C0F10; --panel:#141A1B; --raise:#171E1F; --ink:#E9EDEB; --mid:#8B9793; --faint:#6A736F;
  --rule:#212829; --accent:#7FC3A8; --accent-ink:#9BD3BC; --wash:#16211E; --warn:#D9A25F;
  /* syntax: one hue family per role, tuned against the graphite ground */
  --code-bg:#0F1518; --code-rule:#222C30;
  --hl-comment:#5F6B6B; --hl-keyword:#E08A63; --hl-string:#9CC79B; --hl-value:#9CC79B;
  --hl-name:#7FC3A8; --hl-type:#8FB7D9; --hl-number:#D9A25F; --hl-variable:#D8DEDC;
  --display:"Archivo",system-ui,-apple-system,"Segoe UI",sans-serif;
  --body:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --measure:68ch;
}
:root[data-theme="light"]{
  --bg:#F6F4EE; --panel:#EFEDE5; --raise:#FFFEFB; --ink:#19211D; --mid:#667069; --faint:#98A099;
  --rule:#D8DCD6; --accent:#156149; --accent-ink:#0E4937; --wash:#DCEBE3; --warn:#8A5A12;
  --code-bg:#F1EFE7; --code-rule:#DFDCD1;
  --hl-comment:#8A8F87; --hl-keyword:#A8442A; --hl-string:#2F6B3C; --hl-value:#2F6B3C;
  --hl-name:#156149; --hl-type:#26557F; --hl-number:#8A5A12; --hl-variable:#28312C;
}
@media (prefers-color-scheme:light){:root:not([data-theme="dark"]){
  --bg:#F6F4EE; --panel:#EFEDE5; --raise:#FFFEFB; --ink:#19211D; --mid:#667069; --faint:#98A099;
  --rule:#D8DCD6; --accent:#156149; --accent-ink:#0E4937; --wash:#DCEBE3; --warn:#8A5A12;
  --code-bg:#F1EFE7; --code-rule:#DFDCD1;
  --hl-comment:#8A8F87; --hl-keyword:#A8442A; --hl-string:#2F6B3C; --hl-value:#2F6B3C;
  --hl-name:#156149; --hl-type:#26557F; --hl-number:#8A5A12; --hl-variable:#28312C;}}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--body);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;font-family:var(--display);font-weight:600;letter-spacing:-.03em;text-wrap:balance}
/* titles and wordmarks take the display face; everything else is body */
.bar b,.line .msg,.reach .v,.cv b,.acts .t,.pkg .nm{font-family:var(--display)}
.pkg .nm{font-family:var(--mono)}
p,ul,ol,figure,pre{margin:0}
img{max-width:100%}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.wrap{max-width:960px;margin:0 auto;padding:0 26px}
.lbl{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.tnum{font-variant-numeric:tabular-nums}
.skip{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip:focus-visible{position:fixed;width:auto;height:auto;clip-path:none;left:12px;top:12px;background:var(--accent);color:var(--bg);font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;padding:8px 12px;z-index:20}
/* values that still need a real number */
.tbc{border-bottom:1px dotted var(--faint);cursor:help}
.tt{display:inline-flex;align-items:center;margin-left:auto;background:none;border:0;color:var(--mid);padding:0;cursor:pointer}
.tt svg{width:15px;height:15px}
.tt:hover{color:var(--accent)}

/* ---------------- top bar ---------------- */
/* Source order is id, controls, nav; order puts the nav back in the middle on
   desktop and drops it to its own full-width row when it collapses. */
.bar{display:flex;align-items:center;gap:14px 24px;flex-wrap:wrap;padding:18px 0;border-bottom:1px solid var(--rule)}
.bar .id{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 10px;min-width:0}
.dot{width:7px;height:7px;flex:none;background:var(--accent);align-self:center}
.bar b{font-size:14.5px;letter-spacing:-.01em}
.bar .role{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--mid)}
.bar .ctl{order:2;display:flex;align-items:center;gap:18px;flex:none}
.bar nav{order:1;display:flex;gap:20px;align-items:center;font-size:14px;color:var(--mid);margin-left:auto}
.bar nav a[aria-current]{color:var(--ink);font-weight:600}
.bar nav a:hover{color:var(--accent)}
/* Hamburger: hidden until the breakpoint below, where the bars morph to a cross. */
.bar .menu{display:none;background:none;border:0;color:var(--mid);padding:4px 0;cursor:pointer}
.bar .menu:hover{color:var(--accent)}
.bar .menu[aria-expanded="true"]{color:var(--ink)}
.bar .menu .bars{display:block;width:18px}
.bar .menu .bars i{display:block;height:1.5px;background:currentColor;transition:transform .18s,opacity .18s}
.bar .menu .bars i+i{margin-top:4px}
.bar .menu[aria-expanded="true"] .bars i:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.bar .menu[aria-expanded="true"] .bars i:nth-child(2){opacity:0}
.bar .menu[aria-expanded="true"] .bars i:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}

@media (max-width:720px){
  .bar{gap:12px 16px;position:relative}
  .bar .ctl{margin-left:auto;gap:20px}
  .bar .menu{display:block}
  /* Own row inside the header, so it pushes the page down instead of
     overlaying it and needs no scroll lock. */
  .bar nav{order:3;flex-basis:100%;margin:0;display:none;flex-direction:column;align-items:stretch;gap:0;padding-bottom:4px}
  .bar nav[data-open]{display:flex}
  .bar nav a{padding:13px 0;border-top:1px solid var(--rule);font-size:15.5px;color:var(--ink)}
  .bar nav a[aria-current]{color:var(--accent)}
}

/* ---------------- page head ---------------- */
.head{padding:52px 0 34px}
.head h1{font-size:clamp(29px,4.1vw,42px);line-height:1.07;max-width:38ch}
.head h1 em{font-style:normal;color:var(--accent)}
.head p{color:var(--mid);font-size:16.5px;line-height:1.62;margin-top:20px;text-wrap:pretty}
.head p.narrow{max-width:66ch}
.head.short{padding:44px 0 26px}

/* ---------------- metric strip ---------------- */
.strip{display:flex;flex-wrap:wrap;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.strip div{flex:1 1 160px;padding:14px 18px;border-left:1px solid var(--rule)}
.strip div:first-child{border-left:0;padding-left:0}
.strip .v{font-family:var(--mono);font-size:19px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.strip .k{font-size:12.5px;color:var(--mid);margin-top:3px}

/* ---------------- section heads ---------------- */
.sec{padding:38px 0 0}
.sec.gap{padding-top:72px}
.sechead{display:flex;justify-content:space-between;align-items:baseline;gap:14px;padding-bottom:10px;border-bottom:1px solid var(--rule)}
.sechead a{color:var(--accent)}

/* ---------------- writing stream ---------------- */
.yr{display:flex;align-items:center;gap:14px;padding:72px 0 14px}
/* The topmost year sits right under the section head, so it needs no gap.
   :first-of-type would match the section head div, not this. */
.sechead + .yr{padding-top:14px}
.yr b{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.16em;color:var(--faint);font-variant-numeric:tabular-nums}
.yr .n{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.yr hr{flex:1;border:0;border-top:1px solid var(--rule)}
.log{display:flex;flex-direction:column}
.line{display:grid;grid-template-columns:84px 108px minmax(0,1fr) 44px;gap:18px;align-items:baseline;padding:15px 0;border-bottom:1px solid var(--rule)}
.line:hover{background:var(--row-hover)}
.line .ts,.line .rt{font-family:var(--mono);font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums}
.line .rt{text-align:right}
.line .tag{justify-self:start;font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-ink);background:var(--wash);padding:3px 7px}
.line .tag.w{color:var(--warn);background:color-mix(in srgb,var(--warn) 14%,transparent)}
.line .msg{font-size:17.5px;font-weight:600;letter-spacing:-.025em;line-height:1.3}
.line .msg span{display:block;font-size:14.5px;font-weight:400;letter-spacing:0;color:var(--mid);margin-top:4px}
.line:hover .msg{color:var(--accent)}

/* ---------------- service / capability grid ---------------- */
.svc{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule);margin-top:14px}
.svc article{background:var(--panel);padding:16px 18px;display:flex;gap:12px;align-items:start}
.svc article.wide{grid-column:1/-1}
.svc .st{width:6px;height:6px;margin-top:8px;flex:none;background:var(--accent)}
.svc .st.w{background:var(--warn)}
.svc h3{font-size:15.5px;letter-spacing:-.02em}
.svc p{color:var(--mid);font-size:14px;line-height:1.5;margin-top:4px}
.svc .m{font-family:var(--mono);font-size:10px;color:var(--faint);margin-top:7px;letter-spacing:.05em}

/* ---------------- package rows ---------------- */
.pkgs{display:flex;flex-direction:column}
.pkg{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 16px;align-items:baseline;padding:13px 12px;margin:0 -12px;border-bottom:1px solid var(--rule)}
.pkg:hover{background:var(--row-hover)}
.pkg .nm{font-family:var(--mono);font-size:13.5px;letter-spacing:-.01em;color:var(--ink)}
.pkg:hover .nm{color:var(--accent)}
.pkg .ds{grid-column:1;font-size:14px;color:var(--mid);margin-top:4px}
.pkg .st{font-family:var(--mono);font-size:11px;color:var(--faint);text-align:right;font-variant-numeric:tabular-nums}
.pkg .meta{grid-column:2;display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:baseline;gap:4px 16px}
.pkg .meta .st{min-width:74px}
.pkg .buy{color:var(--accent)}
.pkg:hover .buy{text-decoration:underline}
@media (max-width:640px){.pkg{grid-template-columns:minmax(0,1fr)}.pkg .meta{grid-column:1;justify-content:flex-start}.pkg .meta .st{text-align:left;min-width:0}}
.pkg .nm em{font-style:normal;font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--warn);border:1px solid color-mix(in srgb,var(--warn) 45%,transparent);padding:2px 6px;margin-left:8px}
/* Card grid: same rows, laid out three across. The 1px gap over a rule
   coloured background draws the hairlines, matching the .svc blocks, so the
   grid needs no borders of its own. */
.pkgs.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule);margin-top:14px}
.cards .pkg{display:flex;flex-direction:column;gap:6px;background:var(--panel);border-bottom:0;margin:0;padding:15px 16px}
.cards .pkg .ds{margin-top:0;flex:1}
.cards .pkg .meta{grid-column:auto;justify-content:flex-start;gap:4px 14px;margin-top:2px}
.cards .pkg .meta .st{text-align:left;min-width:0}
@media (max-width:900px){.pkgs.cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.pkgs.cards{grid-template-columns:minmax(0,1fr)}}
.osnote{margin-top:14px;font-size:14.5px;color:var(--mid);max-width:66ch}
.osnote.wide{max-width:none}
.osnote b{color:var(--ink);font-weight:600}

/* ---------------- platform chips ---------------- */
.chips{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:16px}
.chiplead{width:100%;font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--faint);margin-top:8px}
.chiplead:first-child{margin-top:0}
.chip{font-size:13px;color:var(--mid);border:1px solid var(--rule);padding:4px 10px}
.chip.on{color:var(--ink);border-color:var(--accent);background:var(--wash)}

/* ---------------- band ---------------- */
.band{margin-top:34px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule)}
.band div{background:var(--panel);padding:16px 18px}
.band h4{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);font-weight:400;margin-bottom:7px}
.band p{color:var(--mid);font-size:14.5px;line-height:1.5}
.band p b{color:var(--ink);font-weight:600}
.band.two{grid-template-columns:repeat(2,minmax(0,1fr))}

/* ---------------- prose (about, article) ---------------- */
.prose{font-size:17px;line-height:1.68;max-width:var(--measure)}
.prose > p{margin-top:20px}
.prose > p:first-child{margin-top:0}
.prose h2{font-size:19px;letter-spacing:-.025em;margin:38px 0 0}
/* Subheads within a section. Headings are not in the margin reset at the top of
   this file, so without this an h3 takes the browser default of 1em, which is
   both the size of an h2 and half its space above. */
.prose h3{font-size:16.5px;letter-spacing:-.02em;margin:30px 0 0}
/* Jump targets stop short of the viewport edge, so the heading a reader
   lands on keeps some air above it rather than sitting flush at the top. */
.prose h2,.prose h3,.prose h4{scroll-margin-top:32px}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
.prose h2 + p{margin-top:12px}
.prose h3 + p{margin-top:10px}
.prose ul{margin-top:16px;padding-left:20px;color:var(--ink)}
.prose li{margin-top:7px}
.prose strong{font-weight:600}
.prose code{
  font-family:var(--mono);font-size:.85em;background:var(--wash);color:var(--accent-ink);
  padding:2px 6px;border:1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  white-space:nowrap;
}
.prose pre{
  margin-top:22px;background:var(--code-bg);border:1px solid var(--code-rule);
  border-left:3px solid var(--accent);padding:18px 20px;overflow-x:auto;
  font-family:var(--mono);font-size:13.5px;line-height:1.75;color:var(--hl-variable);
  tab-size:4;
}
.prose pre code{background:none;border:0;padding:0;font-size:inherit;line-height:inherit;display:block;color:inherit;white-space:pre}
.prose pre .c{color:var(--hl-comment)}
.prose blockquote{margin:24px 0 0;padding-left:18px;border-left:2px solid var(--rule);color:var(--mid)}
.prose a{color:var(--accent);border-bottom:1px solid var(--rule)}
.prose a:hover{border-color:var(--accent)}

/* ---------------- article ---------------- */
.article{max-width:calc(68ch + 240px);padding-right:240px}
.article .kick{font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--accent)}
.article h1{font-size:clamp(28px,3.6vw,40px);line-height:1.08;margin:14px 0 16px;max-width:24ch}
.article .standfirst{font-size:18.5px;line-height:1.55;color:var(--mid);max-width:58ch}
.article .byline{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:22px;padding-bottom:18px;border-bottom:1px solid var(--rule);font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--mid)}
.article .byline.repo{margin-bottom:30px}
.article .byline a{display:inline-flex;align-items:center;gap:7px}
.article .byline svg{width:13px;height:13px;flex:none}
.note{float:right;clear:right;width:190px;margin:8px -240px 18px 0;font-size:12.5px;line-height:1.5;color:var(--mid);border-top:1px solid var(--accent);padding-top:8px}
.note b{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--accent-ink);margin-bottom:4px;font-weight:400}
.toc{float:right;clear:right;width:190px;margin:0 -240px 24px 0;position:sticky;top:28px}
.toc b{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--faint);margin-bottom:8px;font-weight:400}
.toc a{display:block;font-size:12.5px;color:var(--mid);padding:3px 0 3px 10px;border-left:1px solid var(--rule)}
.toc a:hover{color:var(--ink);border-color:var(--accent)}
.figcap{font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;color:var(--faint);margin-top:8px}
.endnote{margin-top:34px;padding:18px 20px;background:var(--panel);border-left:2px solid var(--accent);font-size:15.5px;line-height:1.6;color:var(--mid)}
.endnote b{color:var(--ink);font-weight:600}
.postfoot{margin-top:38px;padding-top:20px;border-top:1px solid var(--rule);display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.postfoot a{display:block;padding:14px 16px;border:1px solid var(--rule)}
.postfoot a:hover{border-color:var(--accent)}
.postfoot span{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--faint)}
.postfoot svg{width:12px;height:12px;flex:none}
.postfoot p{margin-top:6px;font-size:15.5px;font-weight:500;letter-spacing:-.01em}

/* ---------------- key/value rows (about, contact) ---------------- */
.kv{border-top:1px solid var(--rule);margin-top:14px}
.kv div{display:grid;grid-template-columns:150px minmax(0,1fr);gap:18px;padding:13px 0;border-bottom:1px solid var(--rule);align-items:baseline}
.kv dt{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.kv dd{margin:0;font-size:15.5px;color:var(--ink)}
.kv dd small{display:block;color:var(--mid);font-size:14px;margin-top:3px}
.kv a{color:var(--accent)}

/* ---------------- timeline ---------------- */
.cv{border-top:1px solid var(--rule);margin-top:14px}
.cv .r{display:grid;grid-template-columns:120px minmax(0,1fr);gap:18px;padding:15px 0;border-bottom:1px solid var(--rule)}
.cv .yrs{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;color:var(--faint);padding-top:3px}
.cv b{font-size:15.5px;font-weight:600;letter-spacing:-.01em}
.cv p{font-size:14.5px;color:var(--mid);line-height:1.55;margin-top:4px}

/* ---------------- contact cards ---------------- */
.reach{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule);margin-top:14px}
.reach a{background:var(--panel);padding:18px 20px;display:block}
.reach a:hover{background:var(--raise)}
.reach .h{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.reach .v{font-size:16.5px;font-weight:600;letter-spacing:-.02em;margin-top:6px}
.reach a:hover .v{color:var(--accent)}
.reach p{color:var(--mid);font-size:14px;line-height:1.5;margin-top:5px}

/* ---------------- footer ---------------- */
.foot{margin-top:38px;padding:18px 0 56px;border-top:1px solid var(--rule);display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;font-family:var(--mono);font-size:10.5px;color:var(--mid)}
.foot .links{display:flex;gap:16px;flex-wrap:wrap}
.foot a:hover{color:var(--accent)}

/* ---------------- responsive ---------------- */
@media (max-width:1080px){
  .article{padding-right:0;max-width:none}
  .note,.toc{float:none;width:auto;margin:20px 0;position:static;max-width:var(--measure)}
  .note{border-top:0;border-left:2px solid var(--accent);padding:2px 0 2px 14px}
  .toc{border-left:1px solid var(--rule);padding-left:14px}
  .toc a{border-left:0;padding-left:0}
}
@media (max-width:1000px){.band{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:820px){.svc,.band,.band.two,.reach,.postfoot{grid-template-columns:1fr}.svc article.wide{grid-column:auto}}
@media (max-width:620px){
  .line{grid-template-columns:54px minmax(0,1fr);gap:6px 14px}
  .line .tag{grid-row:1;grid-column:2}.line .msg{grid-column:1/-1}.line .rt{display:none}
  .pkg{grid-template-columns:minmax(0,1fr) auto;gap:6px 12px}.pkg .ds{grid-column:1/-1}
  .kv div,.cv .r{grid-template-columns:1fr;gap:4px}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---------------- about: grid, hobbies, achievements ---------------- */
.about-grid{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,.7fr);gap:clamp(30px,5vw,64px);align-items:start}
.hobbies{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule);margin-top:14px}
.hobbies article{background:var(--panel);padding:18px 20px;display:flex;flex-direction:column;gap:8px}
.hobbies h3{font-size:16px;letter-spacing:-.02em}
.hobbies p{color:var(--mid);font-size:14px;line-height:1.5}
.achv{border-top:1px solid var(--rule);margin-top:14px}
.achv .r{display:grid;grid-template-columns:74px minmax(0,1fr) 170px;gap:18px;align-items:baseline;padding:14px 0;border-bottom:1px solid var(--rule)}
.achv .yrs{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;color:var(--faint);font-variant-numeric:tabular-nums}
.achv h3{font-size:15.5px;font-weight:500;letter-spacing:-.01em}
.achv .res{font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;color:var(--mid);text-align:right}
@media (max-width:820px){.about-grid,.hobbies{grid-template-columns:1fr}}
@media (max-width:620px){.achv .r{grid-template-columns:70px minmax(0,1fr);gap:5px 16px}.achv .res{grid-column:2;text-align:left}}
.achv .res .ok{color:var(--accent)}
.achv .res .plan{color:var(--faint)}
.achv h3 a{border-bottom:1px solid var(--rule);padding-bottom:1px}
.achv h3 a:hover{color:var(--accent);border-color:var(--accent)}

/* ---------------- activities (Strava) ---------------- */
.acts{margin-top:14px;border-top:1px solid var(--rule)}
.acts .hdr,.acts .r{display:grid;grid-template-columns:150px minmax(0,1fr) 84px 76px 86px;gap:16px;align-items:baseline;padding:11px 0;border-bottom:1px solid var(--rule)}
.acts .hdr{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);padding:8px 0}
.acts .r:hover{background:var(--row-hover)}
.acts .d{font-family:var(--mono);font-size:11px;color:var(--faint)}
.acts .t{font-size:15px;font-weight:500;letter-spacing:-.01em}
.acts .r:hover .t{color:var(--accent)}
.acts .num{font-family:var(--mono);font-size:12px;text-align:right;color:var(--mid)}
.acts .r .num:first-of-type{color:var(--ink)}
@media (max-width:760px){
  .acts .hdr{display:none}
  .acts .r{grid-template-columns:minmax(0,1fr) auto;gap:4px 14px}
  .acts .d{grid-column:1/-1}
  .acts .t{grid-column:1}
  .acts .num{grid-column:2;text-align:right}
}

/* ---------------- heading permalinks ---------------- */
/* heading_anchors gives every heading an id and a permalink anchor. Keep both,
   for deep links and for the contents list, but never render the pilcrow. */
.prose .heading-permalink{
  font-size:0;
  line-height:0;
  color:transparent;
  text-decoration:none;
  /* Still a jump target, so leave it in flow rather than display:none. */
}

/* ---------------- post updates ---------------- */
/* Notes added after publishing. Amber is the site's only warning colour, and
   this is the one place on a post where it earns its keep. */
.updates{
  margin:22px 0 0;
  border:1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  border-left:3px solid var(--warn);
  background:color-mix(in srgb, var(--warn) 10%, transparent);
  padding:4px 18px;
  max-width:var(--measure);
}
.updates .update{padding:14px 0;border-top:1px solid color-mix(in srgb, var(--warn) 25%, transparent)}
.updates .update:first-child{border-top:0}
.updates .when{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--warn);margin-bottom:6px;
}
.updates .upnote{font-size:15.5px;line-height:1.6;color:var(--ink)}
.updates .upnote p{margin-top:10px}
.updates .upnote p:first-child{margin-top:0}
.updates .upnote a{color:var(--accent-ink);border-bottom:1px solid var(--accent)}
.updates .upnote a:hover{color:var(--accent);border-color:var(--accent-ink)}
.updates .upnote code{font-family:var(--mono);font-size:.85em;background:var(--panel);padding:1px 5px;border:1px solid var(--rule)}

/* ---------------- syntax highlighting ---------------- */
/* Rendered server side by tempest/highlight. Colours come from the tokens
   above so the two themes stay coherent rather than importing a vendor theme. */
.prose pre .hl-comment{color:var(--hl-comment);font-style:italic}
.prose pre .hl-keyword{color:var(--hl-keyword)}
.prose pre .hl-string,
.prose pre .hl-value{color:var(--hl-string)}
.prose pre .hl-property,
.prose pre .hl-name{color:var(--hl-name)}
.prose pre .hl-type,
.prose pre .hl-attribute{color:var(--hl-type)}
.prose pre .hl-number{color:var(--hl-number)}
.prose pre .hl-variable{color:var(--hl-variable)}
.prose pre .hl-operator,
.prose pre .hl-punctuation{color:var(--mid)}
.prose pre .hl-generic{color:var(--ink)}
/* The language, quietly, top right of the block. */
.prose pre[data-lang]{position:relative;padding-top:26px}
.prose pre[data-lang]::before{
  content:attr(data-lang);
  position:absolute;top:6px;right:12px;
  font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);
}

/* ---------------- listing refinements ---------------- */
/* Imported posts carry long summaries, so hold the dek to two lines and keep
   every row the same shape. */
.line .msg span{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
}
.line .tag:empty{background:none;border:0}

.pager{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:26px 0 0;font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:var(--mid);
}
.pager a{color:var(--accent)}
.pager a:hover{color:var(--ink)}
.pager .count{color:var(--faint);text-transform:uppercase;font-size:10px;letter-spacing:.12em}
@media (max-width:620px){.pager{flex-direction:column;gap:8px;align-items:flex-start}}
