:root{
  --bg: oklch(0.97 0.006 85);
  --text: oklch(0.18 0.008 85);
  --text-muted: oklch(0.42 0.008 85);
  --text-muted-2: oklch(0.5 0.008 85);
  --accent: oklch(0.68 0.16 45);
  --accent-text: oklch(0.5 0.16 45);
  --accent-tint: oklch(0.68 0.16 45 / 0.12);
  --line: oklch(0.18 0.008 85 / 0.2);
  --line-faint: oklch(0.18 0.008 85 / 0.05);
  --card-bg: oklch(1 0 0);
  --tag-bg: oklch(0.5 0.008 85 / 0.1);
  --btn-primary-bg: oklch(0.2 0.01 85);
  --btn-primary-text: oklch(0.97 0.006 85);
  --shadow-resting: 0 1px 2px oklch(0.18 0.008 85 / 0.06);
  --shadow-hover: 0 20px 40px oklch(0.18 0.008 85 / 0.12);
  --selection: oklch(0.68 0.16 45 / 0.3);
  --spotlight-radius: 600px;
  --spotlight-color: oklch(0.68 0.16 45 / 0.1);
  --spotlight-stop: 60%;

  /* Loader curtain — fixed brand colors, deliberately not overridden under
     [data-theme="dark"] below. A one-time splash moment reads better as a
     consistent dark-ink curtain regardless of which theme it's about to
     reveal, rather than flipping to a light curtain in dark mode. */
  --loader-bg: oklch(0.18 0.008 85);
  --loader-fg: oklch(0.97 0.006 85);
}

/* Dark theme — toggled via data-theme on <html>, set before paint by the
   blocking script in <head> so there's no flash of the wrong theme. */
:root[data-theme="dark"]{
  --bg: oklch(0.1 0.008 60);
  --text: oklch(0.93 0.012 60);
  --text-muted: oklch(0.72 0.012 60);
  --text-muted-2: oklch(0.6 0.012 60);
  --accent: oklch(0.72 0.15 45);
  --accent-text: oklch(0.78 0.15 45);
  --accent-tint: oklch(0.72 0.15 45 / 0.16);
  --line: oklch(0.93 0.012 60 / 0.25);
  --line-faint: oklch(0.93 0.012 60 / 0.05);
  --card-bg: oklch(0.24 0.014 60);
  --tag-bg: oklch(0.93 0.012 60 / 0.08);
  --btn-primary-bg: oklch(0.93 0.012 60);
  --btn-primary-text: oklch(0.1 0.008 60);
  --shadow-resting: 0 1px 2px oklch(0 0 0 / 0.2);
  --shadow-hover: 0 20px 40px oklch(0 0 0 / 0.35);
  --selection: oklch(0.72 0.15 45 / 0.35);
  --spotlight-radius: 350px;
  --spotlight-color: oklch(0.72 0.15 45 / 0.35);
  --spotlight-stop: 70%;
}

*{ box-sizing: border-box; }
html, body{
  margin:0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Space Grotesk', sans-serif;
  transition: background-color 0.25s ease, color 0.25s ease;
}
a{ color: inherit; text-decoration: none; }
::selection{ background: var(--selection); }

/* Warm-paper background: crossing diagonal lines + cursor-following spotlight glow */
.bg{
  position: relative;
  min-height: 100vh;
  background: var(--bg);
  background-image:
    repeating-linear-gradient(45deg, var(--line-faint) 0px, var(--line-faint) 1px, transparent 1px, transparent 64px),
    repeating-linear-gradient(-45deg, var(--line-faint) 0px, var(--line-faint) 1px, transparent 1px, transparent 64px),
    radial-gradient(var(--spotlight-radius) circle at var(--x, 50%) var(--y, 30%), var(--spotlight-color), transparent var(--spotlight-stop));
  transition: background-color 0.25s ease;
}

/* Nav — sticky header, always visible while scrolling */
.nav{
  position: sticky; top: 0; z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--line-faint);
  transition: background-color 0.25s ease, border-color 0.25s ease;
}
.nav-inner{ display:flex; align-items:center; justify-content:space-between; max-width:1180px; margin:0 auto; padding: 20px 32px; gap: 24px; }
.nav-brand{ font-weight:700; font-size:18px; letter-spacing:-0.01em; }
.nav-links{ display:flex; gap:32px; font-size:14px; font-weight:500; align-items:center; }
.nav-links a:hover{ color: var(--accent-text); }

.theme-toggle{
  display:flex; align-items:center; justify-content:center;
  width:36px; height:36px; flex-shrink:0;
  border-radius:100px;
  border:1.5px solid var(--line);
  background:transparent;
  color: var(--text);
  cursor:pointer;
  padding:0;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.theme-toggle:hover{ border-color: var(--accent); color: var(--accent-text); }
.theme-toggle svg{ width:16px; height:16px; }
.theme-toggle .icon-sun{ display:none; }
.theme-toggle .icon-moon{ display:block; }
:root[data-theme="dark"] .theme-toggle .icon-sun{ display:block; }
:root[data-theme="dark"] .theme-toggle .icon-moon{ display:none; }

/* Hero */
.hero{ max-width:1180px; margin:0 auto; padding:120px 32px 100px; position:relative; }
.eyebrow{
  font-family:'IBM Plex Mono', monospace;
  font-size:13px;
  letter-spacing:0.1em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin:0 0 24px;
}
h1{
  font-weight:700;
  font-size:92px;
  line-height:1;
  letter-spacing:-0.03em;
  margin:0 0 32px;
  max-width:820px;
}
.bio{ font-size:20px; line-height:1.6; color: var(--text-muted); max-width:560px; margin:0 0 40px; }
.bio em{ color: var(--text); font-style: normal; }

.btn-row{ display:flex; gap:16px; flex-wrap:wrap; }
.btn-primary{
  background: var(--btn-primary-bg); color: var(--btn-primary-text);
  padding:16px 28px; border-radius:100px; font-weight:600; font-size:15px;
  transition: opacity 0.2s ease;
}
.btn-primary:hover{ opacity:0.85; }
.btn-secondary{
  border:1.5px solid var(--line);
  padding:16px 28px; border-radius:100px; font-weight:600; font-size:15px;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.btn-secondary:hover{ border-color: var(--accent); color: var(--accent-text); }

/* Selected work */
.work{ max-width:1180px; margin:0 auto; padding:0 32px 160px; position:relative; }
.work-header{ display:flex; justify-content:space-between; align-items:baseline; margin-bottom:40px; }
.work-header h2{ font-size:36px; font-weight:700; letter-spacing:-0.02em; margin:0; }
.work-count{ font-family:'IBM Plex Mono', monospace; font-size:13px; color: var(--text-muted-2); }

.grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:24px; }
.card{
  position: relative;
  background: var(--card-bg);
  border-radius:28px;
  padding:40px;
  display:flex; flex-direction:column; gap:24px;
  box-shadow: var(--shadow-resting);
  transition: transform 0.25s ease, box-shadow 0.25s ease, background-color 0.25s ease;
}
.card:hover{ transform: translateY(-6px); box-shadow: var(--shadow-hover); }
.card-top{ display:flex; justify-content:space-between; align-items:flex-start; min-height:24px; }
.card-num{ font-family:'IBM Plex Mono', monospace; font-size:13px; color: var(--text-muted-2); }
.card-tag{
  background: var(--tag-bg); color: var(--text-muted);
  font-family:'IBM Plex Mono', monospace; font-size:11px; letter-spacing:0.06em;
  padding:6px 12px; border-radius:100px;
}
.card h3{ font-size:26px; font-weight:700; margin:0 0 12px; letter-spacing:-0.01em; }
.card-title-link{ display:block; }
.card-title-link:hover h3{ color: var(--accent-text); }
/* Whole-card hit area: the title link stretches an invisible overlay across the
   card, so clicking anywhere opens the detail page. Anchors can't nest, so the
   real "Live app"/"Code" links are lifted above the overlay instead. Cards with
   no title link (WoW, no detail page yet) stay non-clickable, as intended. */
.card-title-link::after{ content:''; position:absolute; inset:0; border-radius:28px; z-index:1; }
.card:has(.card-title-link){ cursor: pointer; }
.card p{ font-size:15px; line-height:1.65; color: var(--text-muted); margin:0; }
.card-links{ position:relative; z-index:2; display:flex; gap:20px; margin-top:auto; font-size:13px; font-weight:600; }
.link-accent{ color: var(--accent-text); }
.link-muted{ color: var(--text-muted); }
.link-accent:hover, .link-muted:hover{ color: var(--text); }

@media (max-width:720px){
  h1{ font-size:52px; }
  .grid{ grid-template-columns:1fr; }
  .nav-links{ gap:20px; }
  .hero{ padding:80px 24px 64px; }
}

/* ---- Article / project detail pages ---- */
.article{ max-width:820px; margin:0 auto; padding: 56px 32px 140px; position:relative; }
.article h1{ font-size:48px; margin-bottom:8px; }
.article .eyebrow{ margin-bottom:0; }
h2.section-title{ font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:24px; letter-spacing:-0.01em; margin:0 0 16px; }
.about-text{ color: var(--text-muted); font-size:17px; line-height:1.7; max-width:70ch; margin:0 0 16px; }

.detail-back{
  font-family:'IBM Plex Mono', monospace;
  font-size:13px;
  color: var(--text-muted);
  text-decoration:none;
}
.detail-back:hover{ color: var(--accent-text); }

/* Footer */
footer{ border-top:1px solid var(--line); padding:32px 0 60px; }
footer .shell, footer .bg-inner{ max-width:1180px; margin:0 auto; padding:0 32px; display:flex; justify-content:flex-end; align-items:center; }
footer, footer a{
  font-family:'IBM Plex Mono', monospace;
  font-size:12px;
  color: var(--text-muted);
  text-decoration:none;
}
footer a:hover{ color: var(--accent-text); }
footer .links{ display:flex; gap:20px; align-items:center; }

@media (max-width:680px){
  .article h1{ font-size:36px; }
  .article{ padding: 40px 24px 100px; }
}

/* ---- Loader — one-time curtain-reveal intro, plays once per session ---- */
#loader-overlay{
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
}
#loader-overlay .curtain-top,
#loader-overlay .curtain-bottom{
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  background: var(--loader-bg);
  transition: transform 0.7s cubic-bezier(0.83, 0, 0.17, 1);
}
#loader-overlay .curtain-top{ top: 0; }
#loader-overlay .curtain-bottom{ top: 50%; }
#loader-overlay.reveal .curtain-top{ transform: translateY(-100%); }
#loader-overlay.reveal .curtain-bottom{ transform: translateY(100%); }

#loader-overlay .loading-layer{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  opacity: 1;
  transition: opacity 0.35s ease;
}
#loader-overlay.reveal .loading-layer{ opacity: 0; }

#loader-overlay .initials{
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 300;
  font-size: 32px;
  letter-spacing: 0.14em;
  color: var(--loader-fg);
}
#loader-overlay .load-row{
  display: flex;
  align-items: center;
  gap: 14px;
}
#loader-overlay .bar-track{
  width: 180px;
  height: 2px;
  background: color-mix(in oklch, var(--loader-fg) 20%, transparent);
  position: relative;
}
#loader-overlay .bar-fill{
  position: absolute;
  inset: 0 auto 0 0;
  height: 100%;
  width: 0%;
  background: var(--loader-fg);
  transition: width 1.4s ease;
}
#loader-overlay .counter{
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 400;
  font-size: 14px;
  color: color-mix(in oklch, var(--loader-fg) 65%, transparent);
  font-variant-numeric: tabular-nums;
  min-width: 24px;
}
