/* ─────────────────────────────  fonts  ───────────────────────────── */
/* self-hosted variable fonts; JetBrains Mono is subset to Latin + the box-drawing and symbol glyphs the page uses */
@font-face{font-family:'JetBrains Mono';src:url(fonts/jetbrains-mono.woff2) format('woff2');font-weight:100 800;font-display:swap}
@font-face{font-family:'Inter';src:url(fonts/inter.woff2) format('woff2');font-weight:100 900;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* ─────────────────────────────  tokens  ───────────────────────────── */
:root{
  --bg:#0a0c10; --bg-2:#0e1117; --bg-3:#151a22;
  --fg:#c9d1d9; --fg-dim:#b8c1cc; --fg-faint:#8b95a4;
  --line:#1e252f;
  --accent:#00dc82; --accent-2:#b07bff; --warn:#ffb86b;
  --glow:0 0 0 1px rgba(0,220,130,.25), 0 0 24px -6px rgba(0,220,130,.35);
  --mono:'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans:'Inter', system-ui, sans-serif;
}
html[data-theme="light"]{
  --bg:#f6f4ee; --bg-2:#fffdf7; --bg-3:#efece3;
  --fg:#1f2328; --fg-dim:#5b6472; --fg-faint:#6f7887;
  --line:#e0dbd0;
  --accent:#0a8f58; --accent-2:#6715db; --warn:#b26a00;
  --glow:0 0 0 1px rgba(10,143,88,.2), 0 0 24px -8px rgba(10,143,88,.25);
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; background:var(--bg); color:var(--fg);
  font-family:var(--mono); font-size:15.5px; line-height:1.7;
  -webkit-font-smoothing:antialiased;
}
/* subtle scanline + grid texture */
body::before{
  content:''; position:fixed; inset:0; pointer-events:none; z-index:100;
  background:
    repeating-linear-gradient(to bottom, rgba(255,255,255,.012) 0 1px, transparent 1px 3px),
    radial-gradient(1200px 600px at 70% -10%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 70%);
}
html[data-theme="light"] body::before{
  background:radial-gradient(1200px 600px at 70% -10%, color-mix(in srgb, var(--accent) 8%, transparent), transparent 70%);
}
/* live background: dot grid + data packets travelling the grid lines */
#bg{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none}
.wrap{position:relative;z-index:1}
a{color:inherit;text-decoration:none}
::selection{background:color-mix(in srgb, var(--accent) 35%, transparent)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ─────────────────────────────  status bar  ───────────────────────────── */
.statusbar{
  position:fixed; inset:0 0 auto 0; z-index:50; display:flex; align-items:stretch;
  font-size:12.5px; letter-spacing:.04em;
  background:color-mix(in srgb, var(--bg-2) 82%, transparent);
  border-bottom:1px solid var(--line); backdrop-filter:blur(14px) saturate(1.2); -webkit-backdrop-filter:blur(14px) saturate(1.2);
}
.seg{display:flex;align-items:center;gap:.5em;padding:.55em .9em;white-space:nowrap}
.seg--brand{background:var(--accent);color:var(--bg);font-weight:700}
html[data-theme="light"] .seg--brand{color:#fffdf7}
.seg--host{color:var(--fg);border-right:1px solid var(--line);min-width:0;overflow:hidden;text-overflow:ellipsis}
.statusbar nav{display:none;gap:.2em;margin-left:auto}
@media(min-width:740px){.statusbar nav{display:flex}}
.statusbar nav a{padding:.55em .8em;color:var(--fg);transition:color .15s,background .15s}
.statusbar nav a:hover{color:var(--accent);background:var(--bg-3)}
.statusbar nav kbd{
  font:inherit;font-size:11px;border:1px solid var(--line);border-radius:3px;padding:0 4px;margin-right:.45em;
  color:var(--fg-dim);background:var(--bg-3);transition:color .15s,border-color .15s
}
.statusbar nav a:hover kbd,.statusbar nav a.on kbd{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 50%,var(--line))}
.seg--clock{margin-left:auto;color:var(--fg-dim);border-left:1px solid var(--line)}
@media(min-width:740px){.seg--clock{margin-left:0}}
.tgl{
  font:inherit;cursor:pointer;background:none;border:0;border-left:1px solid var(--line);
  color:var(--fg-dim);padding:.55em .9em;white-space:nowrap;flex-shrink:0;transition:color .15s,background .15s
}
.tgl:hover{color:var(--warn);background:var(--bg-3)}

/* ─────────────────────────────  shell  ───────────────────────────── */
.wrap{max-width:1080px;margin:0 auto;padding:0 20px 120px}
.hero{min-height:100svh;display:flex;flex-direction:column;justify-content:center;gap:28px;padding:108px 0 56px}
.window{
  background:var(--bg-2);border:1px solid var(--line);border-radius:10px;overflow:hidden;
  box-shadow:0 30px 80px -40px rgba(0,0,0,.8);
}
html[data-theme="light"] .window{box-shadow:0 24px 60px -36px rgba(40,30,10,.35)}
.window__bar{
  display:flex;align-items:center;gap:8px;padding:10px 14px;
  background:var(--bg-3);border-bottom:1px solid var(--line);font-size:12.5px;color:var(--fg-faint)
}
.dot{width:11px;height:11px;border-radius:50%}
.dot:nth-child(1){background:#ff5f57}.dot:nth-child(2){background:#febc2e}.dot:nth-child(3){background:#28c840}
.window__title{margin-left:8px}
.window__body{padding:22px 20px 26px}
@media(min-width:700px){.window__body{padding:28px 30px 34px}}

.ascii{
  font-size:clamp(7px,2.3vw,16.5px);line-height:1;letter-spacing:0;white-space:pre;color:var(--accent);
  text-shadow:0 0 22px color-mix(in srgb, var(--accent) 45%, transparent);margin:0 0 4px
}
/* light mode: no glow on paper — a hard, slightly misregistered print offset instead */
html[data-theme="light"] .ascii{text-shadow:3px 3px 0 color-mix(in srgb, var(--accent-2) 22%, transparent)}
.prompt{display:flex;gap:.6em;flex-wrap:wrap;align-items:baseline;margin-top:18px}
.ps1{color:var(--accent-2);font-weight:500}
.ps1 .path{color:var(--warn)}
.cmd{color:var(--fg)}
.cursor{display:inline-block;width:.6em;height:1.05em;background:var(--accent);translate:0 2px;animation:blink 1.1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
.out{color:var(--fg-dim);margin:.2em 0 0}
.out b{color:var(--fg);font-weight:500}
.kv{display:grid;grid-template-columns:auto 1fr;gap:0 1.4em;margin:14px 0 0}
.kv dt{color:var(--fg-faint)}
.kv dd{margin:0;color:var(--fg)}
.badge{color:var(--accent)}
/* whoami output fades in after the command is typed (only when JS runs the intro) */
.js .boot{opacity:0;transition:opacity .4s}
.js .boot + .boot{transition-delay:.15s}
.js .boot.on{opacity:1}
.keys{
  margin-top:24px;padding-top:16px;border-top:1px dashed var(--line);
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;font-size:13px;color:var(--fg-faint)
}
.keys a,.keys button{
  font:inherit;cursor:pointer;background:none;border:0;padding:0;color:var(--fg-dim);
  display:inline-flex;align-items:center;gap:.5em;transition:color .15s
}
.keys a:hover,.keys button:hover{color:var(--accent)}
.keys kbd{
  font:inherit;border:1px solid var(--line);background:var(--bg-3);border-radius:4px;
  padding:0 6px;color:var(--fg);box-shadow:0 2px 0 var(--line);transition:border-color .15s,color .15s
}
.keys a:hover kbd,.keys button:hover kbd{border-color:color-mix(in srgb,var(--accent) 50%,var(--line));color:var(--accent)}
.keys__sep{width:1px;height:14px;background:var(--line)}
/* touch devices (phones, tablets) have no keyboard — drop the shortcut hints */
@media(hover:none) and (pointer:coarse){.keys,.statusbar nav kbd{display:none}}
/* jump feedback */
.toast{
  position:fixed;left:50%;bottom:24px;z-index:60;translate:-50% 12px;opacity:0;pointer-events:none;
  background:var(--bg-2);border:1px solid var(--line);border-radius:6px;padding:.5em .9em;font-size:13px;
  color:var(--fg-dim);box-shadow:var(--glow);transition:opacity .2s,translate .2s
}
.toast.show{opacity:1;translate:-50% 0}
.toast b{color:var(--accent);font-weight:500}
section.flash .cmdline{animation:flash 1.1s ease}
@keyframes flash{0%{border-bottom-color:var(--accent);box-shadow:0 1px 0 var(--accent)}100%{box-shadow:0 1px 0 transparent}}
/* theme switch: main.js clips the new snapshot to a growing circle; turn off the default cross-fade */
::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}
/* Chrome renders backdrop-filter stale inside the transition snapshot, so drop the blur while it runs */
.theming .statusbar,.theming section{backdrop-filter:none;-webkit-backdrop-filter:none}
.theme-ring{
  position:fixed;z-index:200;translate:-50% -50%;border-radius:50%;pointer-events:none;
  border:1.5px solid var(--accent);
  box-shadow:inset 0 0 18px -2px color-mix(in srgb, var(--accent) 70%, transparent)
}

/* ─────────────────────────────  sections  ───────────────────────────── */
/* each section sits on a frosted panel so the live background stays readable behind text */
section{
  margin-top:72px;padding:26px 18px 30px;border-radius:12px;scroll-margin-top:52px;
  background:color-mix(in srgb, var(--bg) 80%, transparent);
  border:1px solid color-mix(in srgb, var(--line) 70%, transparent);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px)
}
@media(min-width:700px){section{padding:30px 32px 34px}}
.cmdline{
  display:flex;gap:.6em;align-items:baseline;flex-wrap:wrap;
  padding-bottom:14px;margin-bottom:26px;border-bottom:1px dashed var(--line)
}
.cmdline .sigil{color:var(--accent)}
.cmdline h2{font:inherit;font-size:clamp(16.5px,2.4vw,21px);font-weight:500;margin:0;color:var(--fg)}
.cmdline .flag{color:var(--fg-faint)}
.cmdline .ret{margin-left:auto;color:var(--fg-faint);font-size:12.5px}
@media(max-width:599px){.cmdline .ret{display:none}}

/* who */
.who{display:grid;gap:34px}
@media(min-width:900px){.who{grid-template-columns:1.1fr .9fr;gap:48px}}
.who p{margin:0 0 14px;max-width:60ch;color:var(--fg-dim);font-family:var(--sans);font-size:16.5px;line-height:1.75}
.who p b{color:var(--fg);font-weight:600}
.who p a{color:var(--accent);border-bottom:1px dashed currentColor}
.who h3{margin:0;font-size:clamp(28.5px,4.5vw,42px);font-weight:700;letter-spacing:-.02em;font-family:var(--sans);color:var(--fg)}
.role{color:var(--accent);margin:2px 0 20px;font-size:15px}
.socials{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px}
.socials a{
  display:inline-flex;align-items:center;gap:.6em;border:1px solid var(--line);background:var(--bg-2);
  padding:.5em .9em;border-radius:6px;font-size:14px;color:var(--fg-dim);
  transition:border-color .18s, color .18s, transform .18s, box-shadow .18s
}
.socials a:hover{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 45%,var(--line));transform:translateY(-2px);box-shadow:var(--glow)}
.socials svg{width:14px;height:14px;fill:currentColor}
/* who — expertise as systemd units */
.units{display:flex;flex-direction:column;gap:12px;font-size:14px}
.unit{
  border:1px solid var(--line);background:var(--bg-2);border-radius:8px;padding:12px 16px;
  transition:border-color .18s,background .18s
}
.unit:hover{border-color:color-mix(in srgb,var(--accent) 40%,var(--line));background:var(--bg-3)}
.unit__head{display:flex;flex-wrap:wrap;align-items:center;gap:0 .6em;color:var(--fg)}
.unit__head i{width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);animation:pulse 2.4s ease-in-out infinite}
.unit:nth-child(2) .unit__head i{animation-delay:-.6s}.unit:nth-child(3) .unit__head i{animation-delay:-1.2s}.unit:nth-child(4) .unit__head i{animation-delay:-1.8s}
@keyframes pulse{50%{opacity:.35;box-shadow:0 0 2px var(--accent)}}
.unit__head b{font-weight:500;white-space:nowrap}
.unit__head span{color:var(--fg-faint)}
.unit dl{display:grid;grid-template-columns:auto 1fr;gap:0 1em;margin:6px 0 0 1.3em}
.unit dt{color:var(--fg-faint);text-align:right}
.unit dd{margin:0;color:var(--fg-dim)}
.unit dd.ok{color:var(--accent)}

/* contributions — upstream marker */
.intro{margin:-12px 0 18px;color:var(--fg-faint);font-size:14px}
.intro b{color:var(--fg-dim);font-weight:400}
.row__name .owner{color:var(--fg-faint);font-weight:400;white-space:nowrap}
.tag{border:1px solid var(--line);border-radius:4px;padding:0 6px;color:var(--accent-2);font-size:11.5px}

/* skills — tree output */
.tree{margin:0;font-size:14.5px}
.tree .node{color:var(--warn)}
.tree .leaf{display:flex;align-items:center;gap:.55em;color:var(--fg-dim);padding:1px 0}
.tree .leaf img{width:15px;height:15px}
.tree .leaf img.mono{filter:invert(1)}
html[data-theme="light"] .tree .leaf img.mono{filter:none}
.tree .leaf span.pipe{color:var(--fg-faint)}
.tree .leaf b{color:var(--fg);font-weight:400}
.tree .grp{margin-bottom:16px}
.treecols{display:grid;gap:4px}
@media(min-width:780px){.treecols{grid-template-columns:repeat(3,1fr);gap:0 36px}}

/* projects — ls -la */
.ls{display:flex;flex-direction:column}
.row{
  display:grid;grid-template-columns:1fr auto;gap:4px 16px;align-items:center;
  padding:11px 12px;border-radius:6px;border:1px solid transparent;
  transition:background .15s,border-color .15s,transform .15s
}
.row:hover{background:var(--bg-2);border-color:var(--line);transform:translateX(4px)}
.row__name{display:flex;align-items:center;gap:.6em;min-width:0}
.row__name .caret{color:var(--accent);opacity:0;transition:opacity .15s}
.row:hover .row__name .caret{opacity:1}
.row__name b{font-weight:500;color:var(--fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row:hover .row__name b{color:var(--accent)}
.row__meta{display:flex;align-items:center;gap:12px;font-size:12.5px;color:var(--fg-faint)}
/* narrow screens: meta (tag · language) drops to its own line under the name */
@media(max-width:599px){.row{grid-template-columns:1fr}.row__meta{padding-left:1.5em}}
.lang{display:inline-flex;align-items:center;gap:.45em}
.lang i{width:8px;height:8px;border-radius:50%;box-shadow:0 0 0 1px rgba(255,255,255,.12) inset}
.row__desc{
  grid-column:1/-1;color:var(--fg-faint);font-size:13px;font-family:var(--sans);line-height:1.6;
  padding-left:1.5em;max-width:88ch
}
.ls__head,.ls__foot{
  display:flex;justify-content:space-between;color:var(--fg-faint);font-size:12.5px;
  padding:0 12px 10px;border-bottom:1px solid var(--line);margin-bottom:6px
}
.ls__foot{border:0;border-top:1px solid var(--line);padding:12px 12px 0;margin:8px 0 0}
footer{
  margin-top:90px;padding-top:22px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;color:var(--fg-faint);font-size:12.5px
}
.js .reveal{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .6s cubic-bezier(.2,.7,.3,1)}
.js .reveal.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.js .reveal{opacity:1;transform:none}.cursor,.unit__head i{animation:none}}
