/* ==========================================================================
   Tushar Jaju · Portfolio
   Single stylesheet, design-token driven, fully responsive.
   ========================================================================== */

/* --------- Design tokens ---------
   Warm-neutral palette with a single signal accent (oklch). Low-chroma
   so it reads research-grade, not template-y. */
:root {
  --bg: #f5f1e8;
  --bg-soft: #ede6d6;
  --surface: #fbf7ee;
  --surface-2: #f0eadc;
  --text: #1a1714;
  --text-muted: #6b645a;
  --border: rgba(26, 23, 20, 0.10);
  --border-strong: rgba(26, 23, 20, 0.20);
  /* Single signal accent — burnt amber, oklch low-sat */
  --accent: oklch(0.62 0.14 55);
  --accent-2: oklch(0.68 0.14 55);
  --accent-soft: oklch(0.62 0.14 55 / 0.10);
  --danger: oklch(0.55 0.18 25);
  --shadow-sm: 0 1px 2px rgba(26, 23, 20, 0.06);
  --shadow-md: 0 4px 12px rgba(26, 23, 20, 0.08);
  --shadow-lg: 0 12px 32px rgba(26, 23, 20, 0.12);
  --radius: 4px;
  --radius-sm: 3px;
  --nav-h: 64px;

  --grid-pattern: radial-gradient(circle, rgba(26, 23, 20, 0.04) 1px, transparent 1px);
  --grid-size: 28px;

  --font-sans: "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Code", Menlo, monospace;
}

body.dark-mode {
  /* Near-black warm neutral. Same accent — works on both. */
  --bg: #0e0d0b;
  --bg-soft: #15140f;
  --surface: #1a1814;
  --surface-2: #221f19;
  --text: #e8e1d2;
  --text-muted: #897f70;
  --border: rgba(232, 225, 210, 0.08);
  --border-strong: rgba(232, 225, 210, 0.18);
  --accent: oklch(0.72 0.14 55);
  --accent-2: oklch(0.78 0.14 55);
  --accent-soft: oklch(0.72 0.14 55 / 0.12);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 16px 36px rgba(0, 0, 0, 0.50);
  --grid-pattern: radial-gradient(circle, rgba(232, 225, 210, 0.030) 1px, transparent 1px);
}

/* --------- Reset --------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-sans);
  background-color: var(--bg);
  color: var(--text);
  line-height: 1.55;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.4s ease, color 0.4s ease;

  background-image: var(--grid-pattern);
  background-size: var(--grid-size) var(--grid-size);
}

/* No body padding — sections handle their own left gutter for the rail.
   This lets section backgrounds go full-bleed (edge-to-edge), which is what
   the alternating-background pattern needs to read clearly. */

img { max-width: 100%; display: block; }
a { color: var(--accent); text-decoration: none; transition: color 0.2s ease; }
a:hover { color: var(--accent-2); }

button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }

code {
  font-family: var(--font-mono);
  font-size: 0.85em;
}

/* --------- Fluid type --------- */
h1 {
  font-family: var(--font-mono);
  font-size: clamp(2.2rem, 4.5vw + 1rem, 4.4rem);
  line-height: 1.02;
  letter-spacing: -0.04em;
  margin: 0 0 0.4em;
  font-weight: 700;
  text-wrap: balance;
}
h2 {
  font-family: var(--font-mono);
  font-size: clamp(1.8rem, 1.6vw + 1.2rem, 2.6rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin: 0 0 0.4em;
  font-weight: 700;
  text-wrap: balance;
}
h3 {
  font-family: var(--font-mono);
  font-size: clamp(1.05rem, 0.4vw + 0.95rem, 1.25rem);
  letter-spacing: -0.02em;
  margin: 0 0 0.4em;
  font-weight: 600;
}
p  { font-size: clamp(0.98rem, 0.25vw + 0.9rem, 1.08rem); margin: 0 0 1em; color: var(--text-muted); text-wrap: pretty; }
.lede { font-size: clamp(1.1rem, 0.5vw + 1rem, 1.35rem); color: var(--text); line-height: 1.45; }
.sub  { color: var(--text-muted); }

/* --------- Skip link --------- */
.skip-link {
  position: absolute; top: -40px; left: 8px;
  background: var(--accent); color: #fff; padding: 8px 12px;
  border-radius: 6px; z-index: 9999;
  transition: top 0.2s ease;
}
.skip-link:focus { top: 8px; color: #fff; }

/* --------- Navigation --------- */
.site-nav {
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(1rem, 4vw, 2.5rem);
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--border);
  z-index: 100;
}
.nav-brand {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.02em;
  color: var(--text);
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
}
.nav-brand:hover { color: var(--accent); }

.nav-links {
  list-style: none; display: flex; flex-wrap: wrap; gap: clamp(0.4rem, 1.5vw, 1.2rem);
  margin: 0; padding: 0;
}
.nav-links a {
  font-family: var(--font-mono);
  color: var(--text-muted);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  transition: color 0.2s ease, background-color 0.2s ease;
}
.nav-links a:hover { color: var(--accent); background: var(--accent-soft); }
.nav-links a.active { color: var(--accent); background: var(--accent-soft); }
/* Icons hidden on desktop (text labels visible). Swapped at ≤768 below. */
.nav-icon { display: none; }
.nav-label { display: inline; }

#theme-toggle {
  width: 38px; height: 38px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 0.3s ease, background 0.3s ease, border-color 0.3s ease;
  color: var(--text);
}
#theme-toggle:hover { background: var(--accent-soft); border-color: var(--accent); transform: rotate(20deg); }

/* --------- Side rail (profile shortcuts) --------- */
.side-rail {
  position: fixed;
  top: 50%; left: 26px;
  transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 0.7rem;
  z-index: 50;
}
.side-rail a {
  width: 42px; height: 42px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-muted);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  font-size: 1.05rem;
  transition: transform 0.25s ease, background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.side-rail a:hover {
  background: var(--surface);
  color: var(--accent);
  border-color: var(--accent);
  transform: translateY(-2px);
}

@media (max-width: 900px) {
  .side-rail {
    top: auto; bottom: clamp(0.8rem, 2vw, 1.2rem);
    left: 50%; transform: translateX(-50%);
    flex-direction: row;
    background: color-mix(in srgb, var(--surface) 85%, transparent);
    backdrop-filter: blur(8px);
    padding: 0.5rem 0.7rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    box-shadow: var(--shadow-md);
  }
  .side-rail a { width: 38px; height: 38px; box-shadow: none; border: none; }
}

/* --------- Layout primitives ---------
   Every natural .section fills the viewport (min-height: 100svh) with
   content vertically centered. Adapted from Sai Aryan Goswami's pattern
   (`min-h-screen flex flex-col justify-center`). Dead space when content
   is shorter than viewport reads as atmospheric breathing room — the
   per-section bg rails (atmospheric scrolling text) give that empty space
   visual texture so it doesn't look unfinished.

   Projects + Experience use their own scroll-jacking and don't carry the
   .section class. */
.section {
  scroll-margin-top: var(--nav-h);
  padding-block: clamp(3rem, 6vh, 4.5rem);
  padding-inline: clamp(1rem, 5vw, 3rem);
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  position: relative;
  overflow: hidden;
}
@media (min-width: 901px) {
  .section { padding-inline: max(96px, clamp(1rem, 5vw, 3rem)); }
}
.section-inner {
  max-width: 1080px;
  margin-inline: auto;
  width: 100%;
  position: relative;
  z-index: 1;
}

/* :target isolation is now redundant for .section (which is always full
   viewport) — kept as no-op so existing behavior is unchanged. */
.section:target {
  min-height: 100svh;
}
.section:target .section-inner { width: 100%; }

/* --------- Section atmospheric rails ---------
   Vertical scrolling text on the left/right edges of natural sections.
   Adapted from Sai's .CPP / .PY / .TSX rails — gives empty space a
   technical texture without competing with content. Per-section content
   is set inline via `data-rail-text` to keep the markup readable. */
.section-rail {
  position: absolute;
  top: 0;
  bottom: 0;
  width: clamp(3.5rem, 6vw, 6rem);
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  opacity: 0.05;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
}
.section-rail--left { left: 0; }
.section-rail--right { right: 0; }
.section-rail-text {
  position: absolute;
  top: 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 700;
  font-size: clamp(2.2rem, 3.6vw, 3.6rem);
  white-space: nowrap;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  color: var(--text);
  letter-spacing: 0.05em;
  will-change: transform;
}
.section-rail--left .section-rail-text {
  left: 50%;
  animation: section-rail-up 55s linear infinite;
}
.section-rail--right .section-rail-text {
  right: 50%;
  animation: section-rail-down 65s linear infinite;
}
@keyframes section-rail-up {
  0%   { transform: translate(-50%, 0); }
  100% { transform: translate(-50%, -50%); }
}
@keyframes section-rail-down {
  0%   { transform: translate(50%, -50%); }
  100% { transform: translate(50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .section-rail-text { animation: none; }
}

.section-head {
  text-align: center;
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
  max-width: 720px;
}
.section-head h2 { color: var(--text); }
.section-head .section-sub { color: var(--text-muted); margin: 0; }

.section-eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 0.35rem 0;
  margin-bottom: 0.9rem;
  position: relative;
}
.section-eyebrow::before {
  content: "—— ";
  color: var(--accent);
  opacity: 0.6;
}

/* --------- Buttons --------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.85rem 1.3rem;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: -0.01em;
  transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  border: 1px solid transparent;
  cursor: pointer;
}
.btn-primary {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.btn-primary:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  transform: translateY(-1px);
}
.btn-ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--border-strong);
}
.btn-ghost:hover {
  border-color: var(--text);
  transform: translateY(-1px);
}

.action-buttons { display: flex; gap: 0.8rem; flex-wrap: wrap; margin-top: 1.5rem; }

/* --------- Hero --------- */
.hero {
  display: flex; align-items: center;
  min-height: 100svh;
  scroll-margin-top: var(--nav-h);
  padding: calc(var(--nav-h) + clamp(1rem, 4vw, 2.5rem)) clamp(1rem, 5vw, 3rem) clamp(2.5rem, 6vw, 4rem);
  width: 100%;
  position: relative;
  overflow: hidden;
}
@media (min-width: 901px) {
  .hero { padding-inline: max(96px, clamp(1rem, 5vw, 3rem)); }
}

/* Vertical scrolling text rail behind the hero. Full-bleed atmosphere — at
   ~6% opacity it reads as a texture, not a competing element. The rail's
   text is duplicated so translateY(-50%) loops seamlessly. */
.hero-rail {
  position: absolute;
  top: 0; right: -2rem; bottom: 0;
  width: clamp(80px, 15vw, 220px);
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  opacity: 0.06;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
}
.hero-rail-text {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 700;
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  letter-spacing: 0.06em;
  white-space: nowrap;
  color: var(--text);
  writing-mode: vertical-rl;
  text-orientation: mixed;
  position: absolute;
  top: 0; right: 50%;
  transform: translateX(50%);
  animation: hero-rail-scroll 65s linear infinite;
  will-change: transform;
}
@keyframes hero-rail-scroll {
  0%   { transform: translate(50%, 0); }
  100% { transform: translate(50%, -50%); }
}

.hero-grid { position: relative; z-index: 1; }

/* Title cycler — rotates roles every 5s with a shuffle transition. */
.hero-cycler {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: clamp(0.95rem, 0.25vw + 0.85rem, 1.05rem);
  letter-spacing: 0.04em;
  color: var(--accent);
  margin: 0 0 1rem;
  min-height: 1.6em;
  font-weight: 500;
}
.hero-cycler::before {
  content: "> ";
  opacity: 0.6;
}
.hero-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
}
.hero-text { min-width: 0; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.78rem; font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border-strong);
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-sm);
  margin: 0 0 1.6rem;
  text-transform: uppercase;
}
.eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
  50%      { box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 0%, transparent); }
}
.accent { color: var(--accent); }

.hero-image { display: flex; justify-content: center; }
.avatar {
  width: clamp(200px, 30vw, 360px);
  aspect-ratio: 4 / 5;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-lg);
  position: relative;
  transition: transform 0.4s ease;
}
.avatar:hover { transform: scale(1.04); }
.avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: grayscale(100%) sepia(30%) contrast(1.1) brightness(1.02);
  transition: filter 0.4s ease;
}
.avatar:hover img { filter: grayscale(100%) sepia(45%) contrast(1.15) brightness(1.05); }

@media (max-width: 820px) {
  .hero-grid { grid-template-columns: 1fr; text-align: center; }
  .hero-image { order: -1; }
  .action-buttons { justify-content: center; }
  .eyebrow { margin-left: auto; margin-right: auto; }
}

/* --------- About status panel --------- */
.about-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: stretch;
}
.about-text { display: flex; flex-direction: column; }
.about-text p { color: var(--text-muted); }
.about-text strong { color: var(--text); }
.about-text .profile-links { margin-top: auto; }

.about-status {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: clamp(1.2rem, 2vw, 1.6rem);
}
.status-row {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 0.8rem;
  padding: 0.6rem 0;
  border-bottom: 1px dashed var(--border);
  align-items: baseline;
}
.status-row:last-of-type { border-bottom: none; }
.status-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.status-value {
  color: var(--text);
  font-size: 0.96rem;
  font-weight: 500;
  line-height: 1.4;
}
.status-row--featured {
  display: block;
  padding: 0.9rem;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--radius-sm);
  margin: 0.3rem 0;
}
.status-row--featured .status-label {
  color: var(--accent);
  display: block;
  margin-bottom: 0.4rem;
}
.status-row--featured .status-value {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
  display: block;
  margin-bottom: 0.4rem;
  line-height: 1.4;
}
.status-meta {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
  letter-spacing: 0.04em;
}
.status-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
  margin-top: 0.6rem;
}
.status-grid .stat-box { padding: 0.9rem 0.8rem; }
.status-grid .stat-value { font-size: clamp(1.2rem, 1vw + 0.9rem, 1.6rem); }
.status-grid .stat-box h4 { font-size: 0.66rem; }

@media (max-width: 820px) {
  .about-grid { grid-template-columns: 1fr; }
  .status-grid { grid-template-columns: repeat(3, 1fr); }
  .mc-row { grid-template-columns: 130px 1fr; gap: 0.6rem; font-size: 0.78rem; }  .arch-map-body { font-size: 0.74rem; padding: 0.8rem 0.9rem; }
}
@media (max-width: 520px) {
  .status-grid { grid-template-columns: 1fr; }
  .status-row { grid-template-columns: 1fr; gap: 0.2rem; }
  .mc-row { grid-template-columns: 1fr; gap: 0.15rem; padding: 0.6rem 0.9rem; }
  .mc-row dt { font-size: 0.7rem; opacity: 0.85; }
}

.profile-links {
  display: flex; flex-wrap: wrap; gap: 0.6rem;
  margin: 1.5rem 0;
}
.profile-links a {
  position: relative; /* anchor for the hover preview card */
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.55rem 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.profile-links a:hover {
  color: var(--accent);
  border-color: var(--accent);
  transform: translateY(-1px);
}

/* Arrow that marks each chip as an outbound link (matches the coursework idiom) */
.profile-link-arrow {
  font-size: 0.6rem;
  margin-left: 0.05rem;
  color: var(--text-muted);
  transition: color 0.2s ease, transform 0.2s ease;
}
.profile-links a:hover .profile-link-arrow {
  color: var(--accent);
  transform: translate(1px, -1px);
}

/* Hover preview: self-contained info card floating above the chip. Pure
   CSS — favicon comes from a tiny endpoint, the rest is static markup. */
.link-preview {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  width: max-content;
  max-width: 250px;
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.6rem 0.7rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  box-shadow: var(--shadow-lg);
  text-align: left;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(-50%) translateY(6px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
  z-index: 50;
}
.profile-links a:hover .link-preview,
.profile-links a:focus-visible .link-preview {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
/* Little caret pointing down at the chip */
.link-preview::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--surface);
}
.link-preview-favicon {
  width: 28px; height: 28px;
  flex-shrink: 0;
  border-radius: 6px;
  background: var(--bg-soft);
  padding: 3px;
  object-fit: contain;
}
.link-preview-text { display: flex; flex-direction: column; gap: 0.12rem; min-width: 0; }
.link-preview-domain {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--text);
}
.link-preview-desc {
  font-size: 0.68rem;
  line-height: 1.35;
  color: var(--text-muted);
  white-space: normal;
}
.link-preview-cta {
  margin-top: 0.2rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.link-preview-cta i { font-size: 0.56rem; margin-left: 0.1rem; }

/* Hover previews are a pointer affordance — on touch the chip just navigates. */
@media (hover: none) {
  .link-preview { display: none; }
}

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.8rem;
  margin-top: 1.5rem;
}
.stat-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.2rem 1rem;
  text-align: left;
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.stat-box:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
}
.stat-value {
  font-family: var(--font-mono);
  font-size: clamp(1.8rem, 1.5vw + 1.2rem, 2.6rem);
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.04em;
  line-height: 1;
  margin: 0 0 0.5rem;
}
.stat-box h4 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text-muted);
  margin: 0;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.4;
}

@media (max-width: 820px) {
  .contact-grid { grid-template-columns: 1fr; }
  .contact-form { grid-template-columns: 1fr; }
  .contact-form .field--wide { grid-column: auto; }
}

/* --------- About divider --------- */
.about-divider {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: clamp(1.25rem, 2.5vw, 1.75rem) 0 clamp(0.75rem, 1.5vw, 1rem);
}
.about-divider-line {
  flex: 1;
  height: 1px;
  background: var(--border);
}
.about-divider-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
  letter-spacing: 0.08em;
  text-transform: lowercase;
}

/* --------- Model card --------- */
.model-card {
  margin-top: clamp(0.75rem, 1.5vw, 1rem);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  overflow: hidden;
  font-family: var(--font-mono);
}
.model-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.55rem 1rem;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
  font-size: 0.72rem;
}
.model-card-tag { color: var(--accent); font-weight: 600; letter-spacing: 0.04em; }
.model-card-meta { color: var(--text-muted); letter-spacing: 0.04em; }
.model-card-body {
  margin: 0;
  padding: 0.3rem 0;
}
.mc-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 1rem;
  padding: 0.32rem 1rem;
  border-bottom: 1px dashed var(--border);
  font-size: 0.83rem;
}
.mc-row:last-child { border-bottom: none; }
.mc-row dt { color: var(--accent); font-weight: 500; }
.mc-row dd { margin: 0; color: var(--text); word-break: break-word; overflow-wrap: anywhere; }
.mc-string { color: oklch(0.55 0.12 145); }
body.dark-mode .mc-string { color: oklch(0.72 0.14 145); }
.mc-list { color: var(--text-muted); }

/* --------- Now grid --------- */
.now-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.7rem;
  margin-top: clamp(0.8rem, 1.6vw, 1.1rem);
}
.now-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 0.8rem 0.95rem;
}
.now-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin-bottom: 0.5rem;
}
.now-pulse {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
  animation: pulse 2.4s ease-in-out infinite;
}
.now-value { color: var(--text); font-size: 0.9rem; margin: 0 0 0.3rem; line-height: 1.45; }
.now-meta { font-family: var(--font-mono); font-size: 0.7rem; color: var(--text-muted); margin: 0; letter-spacing: 0.02em; }
@media (max-width: 820px) { .now-grid { grid-template-columns: 1fr; } }

/* About section: content (model_card + now-grid + live-stats) often exceeds
   100svh on shorter laptops. Pin to top so growth pushes downward into the
   added bottom padding, instead of centering and clipping the bottom. */
#about.section {
  justify-content: flex-start;
  padding-top: clamp(3rem, 7vw, 5rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}

/* --------- Live stats (GitHub + HuggingFace, fetched on load) --------- */
.live-stats {
  margin-top: clamp(1rem, 2vw, 1.4rem);
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  overflow: hidden;
  font-family: var(--font-mono);
}
.live-stats-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 0.9rem;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
  font-size: 0.68rem;
}
.live-stats-tag { color: var(--accent); font-weight: 600; letter-spacing: 0.04em; }
.live-stats-status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.16rem 0.55rem 0.16rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text-muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.62rem;
  font-weight: 600;
  transition: color 0.25s ease, background 0.25s ease, border-color 0.25s ease;
}
.stats-pulse {
  width: 7px; height: 7px; border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-muted);
  animation: pulse 1.4s ease-in-out infinite; /* fetching state */
}

/* LIVE: green badge with a dot that keeps pinging — the broadcast-style cue
   that the numbers were just pulled live from the APIs. */
[data-stats-status][data-state="ok"] {
  color: oklch(0.7 0.15 145);
  background: color-mix(in srgb, oklch(0.7 0.15 145) 12%, transparent);
  border-color: color-mix(in srgb, oklch(0.7 0.15 145) 38%, transparent);
}
[data-stats-status][data-state="ok"] .stats-pulse {
  background: oklch(0.72 0.16 145);
  animation: live-ping 1.8s ease-out infinite;
}
@keyframes live-ping {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, oklch(0.7 0.15 145) 55%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in srgb, oklch(0.7 0.15 145) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, oklch(0.7 0.15 145) 0%, transparent); }
}

/* CACHED (fallback): muted, static — clearly not live. */
[data-stats-status][data-state="error"] { color: var(--text-muted); }
[data-stats-status][data-state="error"] .stats-pulse { background: var(--text-muted); animation: none; }

.live-stats-body { padding: 0.3rem 0; }
.live-stats .stat-line {
  display: grid;
  grid-template-columns: 20px 110px 1fr auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.45rem 0.85rem;
  border-bottom: 1px dashed var(--border);
  color: var(--text);
  text-decoration: none;
  transition: background 0.18s ease, color 0.18s ease;
}
.live-stats .stat-line:last-child { border-bottom: none; }
.live-stats .stat-line:hover { background: var(--bg-soft); }
.live-stats .stat-line:hover .stat-key { color: var(--text); }
.live-stats .stat-icon { color: var(--accent); text-align: center; font-size: 0.85rem; }
.live-stats .stat-key { color: var(--accent); font-weight: 500; font-size: 0.78rem; transition: color 0.18s ease; }
.live-stats .stat-value {
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 500;
}
.live-stats .stat-tail {
  font-size: 0.66rem;
  color: var(--text-muted);
  letter-spacing: 0.02em;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 280px;
}

@media (max-width: 700px) {
  .live-stats .stat-line {
    grid-template-columns: 20px 1fr;
    gap: 0.5rem;
    row-gap: 0.15rem;
    padding: 0.5rem 0.75rem;
  }
  .live-stats .stat-key { font-size: 0.72rem; }
  .live-stats .stat-value { grid-column: 2; font-size: 0.78rem; }
  .live-stats .stat-tail { grid-column: 2; max-width: none; text-align: left; font-size: 0.62rem; }
}

/* --------- Open Source --------- */
/* Tallest content section (library cards + usage snippets + artifact ledger).
   Pin to top like About/Skills so on shorter laptops it grows downward and
   scrolls, instead of vertically centering and clipping under the fixed nav.
   Overflow-to-scroll here is intended, not a bug — same as About. */
#opensource.section {
  justify-content: flex-start;
  padding-top: clamp(3rem, 7vw, 5rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}
.oss-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 2vw, 1.5rem);
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}
@media (max-width: 720px) { .oss-grid { grid-template-columns: 1fr; } }

.oss-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius);
  padding: clamp(1.1rem, 2vw, 1.5rem);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.oss-card:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.oss-card-head { display: flex; align-items: center; gap: 0.55rem; }
.oss-card-icon { color: var(--accent); font-size: 1rem; }
.oss-card-name {
  font-family: var(--font-mono);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text);
  margin: 0;
}
.oss-card-version {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  background: var(--bg-soft);
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
}
.oss-card-desc { margin: 0; color: var(--text-muted); font-size: 0.9rem; line-height: 1.5; }
.oss-card-tags {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  list-style: none; margin: 0; padding: 0;
}
.oss-card-tags li {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
}
.oss-card-install {
  display: flex; align-items: center; gap: 0.5rem;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.7rem;
  font-family: var(--font-mono);
  overflow-x: auto;
}
.oss-install-prompt { color: var(--accent); font-weight: 700; }
.oss-card-install code { color: var(--text); font-size: 0.8rem; white-space: nowrap; }

/* Real usage — code panel that harmonizes with the warm card in light mode
   and adopts the skills-terminal dark look in dark mode. Same syntax-color
   family in both (amber keyword, green result). */
.oss-code {
  margin: 0;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75rem 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.65;
  color: var(--text);
  overflow-x: auto;
  white-space: pre;
  tab-size: 2;
}
.oss-code-kw  { color: var(--accent); }
.oss-code-out { color: oklch(0.52 0.13 150); }

/* Dark mode: match the skills terminal exactly. */
body.dark-mode .oss-card-install,
body.dark-mode .oss-code {
  background: #07090e;
  border-color: var(--border-strong);
  color: #d9d4c6;
}
body.dark-mode .oss-card-install code { color: #d9d4c6; }
body.dark-mode .oss-code-kw  { color: #c4a3ff; }
body.dark-mode .oss-code-out { color: #34d399; }

/* Models & datasets ledger — compact, always-open rows (no dropdowns);
   the base→delta line is the point, so it's never hidden behind a click. */
.oss-artifacts {
  margin-top: clamp(1.3rem, 2.5vw, 2rem);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.2rem, 3vw, 2.5rem);
}
@media (max-width: 720px) { .oss-artifacts { grid-template-columns: 1fr; gap: 1.5rem; } }
.oss-art-heading {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 0 0 0.5rem;
  display: flex; align-items: center; gap: 0.45rem;
}
.oss-art-heading i { color: var(--accent); font-size: 0.8rem; }
.oss-art-list { list-style: none; margin: 0; padding: 0; }
.oss-art { padding: 0.6rem 0; border-bottom: 1px dashed var(--border); }
.oss-art:last-child { border-bottom: none; }
.oss-art-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.oss-art-name {
  font-family: var(--font-mono);
  font-size: 0.8rem; font-weight: 600; color: var(--text);
  word-break: break-word;
}
.oss-art-from {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.06rem 0.45rem;
  border-radius: 999px;
  white-space: nowrap;
}
.oss-art-from::after { content: " \2192"; opacity: 0.7; }
.oss-art-links {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 0.7rem;
  font-family: var(--font-mono); font-size: 0.68rem;
}
.oss-art-links a { color: var(--accent); display: inline-flex; align-items: center; gap: 0.2rem; }
.oss-art-links a i { font-size: 0.55rem; }
.oss-art-dl { color: var(--text-muted); display: inline-flex; align-items: center; gap: 0.25rem; white-space: nowrap; }
.oss-art-dl i { font-size: 0.58rem; }
.oss-art-desc { margin: 0.32rem 0 0; font-size: 0.75rem; line-height: 1.45; color: var(--text-muted); }
.oss-art-base { color: var(--text); font-weight: 500; }

.oss-card-foot {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 0.6rem;
  margin-top: auto;
  padding-top: 0.25rem;
}
.oss-downloads {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--text);
}
.oss-dl-icon { color: var(--accent); font-size: 0.75rem; }
.oss-dl-value { font-weight: 600; }
.oss-live {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-family: var(--font-mono); font-size: 0.58rem;
  text-transform: uppercase; letter-spacing: 0.08em;
  padding: 0.08rem 0.42rem; border-radius: 999px;
  border: 1px solid transparent; color: var(--text-muted);
}
.oss-live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-muted); }
.oss-live[data-state="loading"] .oss-live-dot { animation: pulse 1.4s ease-in-out infinite; }
.oss-live[data-state="live"] {
  color: oklch(0.7 0.15 145);
  background: color-mix(in srgb, oklch(0.7 0.15 145) 12%, transparent);
  border-color: color-mix(in srgb, oklch(0.7 0.15 145) 35%, transparent);
}
.oss-live[data-state="live"] .oss-live-dot {
  background: oklch(0.72 0.16 145);
  animation: live-ping 1.8s ease-out infinite;
}
.oss-card-links {
  display: inline-flex; align-items: center; gap: 0.9rem;
  font-family: var(--font-mono); font-size: 0.75rem;
}
.oss-card-links a { color: var(--accent); display: inline-flex; align-items: center; gap: 0.25rem; }
.oss-card-links a i { font-size: 0.6rem; }
.oss-card-links a:hover { color: var(--accent-2); }

/* --------- Architecture map --------- */
.arch-map {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  overflow: hidden;
}
.arch-map-head {
  padding: 0.7rem 1rem;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 0.74rem;
}
.arch-map-tag { color: var(--text-muted); }
.arch-map-body {
  margin: 0;
  padding: 1rem 1.2rem;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.7;
  color: var(--text);
  overflow-x: auto;
}
.arch-domain { color: var(--accent); font-weight: 600; }
.arch-node { color: var(--text); font-weight: 500; }
.arch-node--pub { color: var(--accent); font-weight: 700; }
.arch-comment { color: var(--text-muted); }

/* --------- Skills: interactive terminal + chip groups ---------
   Skills section is the "fill the viewport" section now: a fake terminal
   centered above, with the command pre-typed and a "press Enter / click to
   reveal" hint. Hitting Enter or clicking runs through a fake safetensor
   shard load (5 shards, animated progress bars, MB counter, ✓ markers),
   and as each shard finishes loading the corresponding skill group below
   fades in. Reads as ML/research without saying so. */
.skills-terminal-wrap {
  width: 100%;
  max-width: 760px;
  margin: 0 auto clamp(2rem, 4vw, 3rem);
}

.terminal {
  background: #07090e;
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--text);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  outline: none;
  cursor: pointer;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.terminal:hover { border-color: var(--accent); }
.terminal:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-md);
}
.terminal.is-running { cursor: default; }

/* Until it's run, the terminal breathes a soft accent ring so it reads as
   interactive. Pauses on hover/focus (those have their own accent states)
   and stops entirely once the script runs. */
.terminal:not(.is-running):not(:hover):not(:focus-visible) {
  animation: terminal-attention 2.6s ease-in-out infinite;
}
@keyframes terminal-attention {
  0%, 100% { box-shadow: var(--shadow-md); border-color: var(--border-strong); }
  50%      { box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-md); border-color: var(--accent); }
}

.terminal-bar {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.95rem;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
}
.terminal-bar-title {
  font-size: 0.72rem;
  color: var(--text-muted);
  letter-spacing: 0.02em;
  font-family: "JetBrains Mono", monospace;
}

.terminal-body {
  padding: 1rem 1.2rem;
  min-height: 200px;
  max-height: 38vh;
  overflow-y: auto;
  font-size: 0.82rem;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.terminal-body::-webkit-scrollbar { width: 6px; }
.terminal-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }

.terminal-prompt-line {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35em;
  margin-bottom: 0.5rem;
  align-items: baseline;
}
.term-user, .term-host { color: #5dd4d4; font-weight: 600; }
.term-at, .term-colon, .term-dollar { color: var(--text-muted); }
.term-path { color: #c4a3ff; }
.term-cmd { color: var(--text); }

.terminal-comment {
  color: #6b7280;
  margin: 0.2rem 0 0.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4em;
  font-size: 0.82rem;
}
.terminal-comment-hash { color: #4b5563; }

/* Run hint: an explicit, accent-coloured call-to-action so the
   click/Enter affordance can't be missed. */
.terminal-run-hint {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0.45rem 0 0.5rem;
}
.terminal-run-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  animation: run-cta-ping 2s ease-in-out infinite;
}
.terminal-run-cta i.fa-play {
  font-size: 0.68rem;
  animation: run-cta-bob 1.6s ease-in-out infinite;
}
@keyframes run-cta-ping {
  0%   { box-shadow: 0 0 0 0 var(--accent-soft); }
  70%  { box-shadow: 0 0 0 8px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes run-cta-bob {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(2px); }
}
.terminal-comment-key {
  display: inline-block;
  border: 1px solid var(--border-strong);
  background: rgba(255, 255, 255, 0.03);
  padding: 0.05rem 0.45rem;
  border-radius: 4px;
  font-size: 0.72rem;
  color: var(--accent);
  font-weight: 500;
  margin: 0 0.15rem;
  letter-spacing: 0.02em;
}

.terminal-cursor {
  display: inline-block;
  width: 0.55em;
  height: 1em;
  background: var(--accent);
  vertical-align: -0.15em;
  margin-left: 0.1em;
  animation: terminal-blink 1.05s steps(1) infinite;
}
@keyframes terminal-blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

.terminal-output {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: 0.5rem;
}
.terminal-output-line {
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.55;
  animation: term-line-in 0.22s ease;
  font-family: "JetBrains Mono", monospace;
  white-space: pre-wrap;
}
@keyframes term-line-in {
  0%   { opacity: 0; transform: translateX(-3px); }
  100% { opacity: 1; transform: translateX(0); }
}
.terminal-output-line .prompt { color: #c4a3ff; }
.terminal-output-line .repl { color: #5dd4d4; font-weight: 600; }
.terminal-output-line .ts { color: #4b5563; opacity: 0.7; }
.terminal-output-line .info { color: #6b7280; font-weight: 600; }
.terminal-output-line .warn { color: #fbbf24; font-weight: 600; }
.terminal-output-line .err { color: #f87171; font-weight: 600; }
.terminal-output-line .num { color: var(--accent); font-weight: 600; }
.terminal-output-line .file { color: #c4a3ff; }
.terminal-output-line .val { color: #5dd4d4; }
.terminal-output-line .comment { color: #6b7280; opacity: 0.85; }
.terminal-output-line .ok { color: #34d399; font-weight: 600; }
.terminal-output-line .pct {
  display: inline-block;
  min-width: 3.5em;
  text-align: right;
  color: var(--text);
  font-weight: 600;
}
.terminal-output-line .size { color: var(--text-muted); }
.terminal-output-line .bar { color: rgba(160, 185, 215, 0.18); letter-spacing: 0; }
.terminal-output-line .bar-fill { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .terminal-cursor { animation: none; opacity: 0.7; }
  .terminal-output-line { animation: none; }
  .terminal:not(.is-running):not(:hover):not(:focus-visible) { animation: none; }
  .terminal-run-cta,
  .terminal-run-cta i.fa-play { animation: none; }
  .stats-pulse,
  [data-stats-status][data-state="ok"] .stats-pulse { animation: none; }
  .oss-live .oss-live-dot { animation: none; }
}

/* Skills section: terminal + 5 cards exceeds 100svh on shorter laptops, so
   let the section grow to fit content while still filling the viewport when
   content is shorter. justify-content: flex-start avoids vertical centering
   pushing the bottom row below the fold. */
#skills.section {
  min-height: 100svh;
  justify-content: flex-start;
  padding-top: clamp(3rem, 7vw, 5rem);
  padding-bottom: clamp(2.5rem, 6vw, 4rem);
}

/* At ~770–900px the 5 skill-groups want to fall into 2+2+1, leaving the last
   card alone on its row. Force basis high enough that it wraps to 2+2 on the
   first pair of rows then 1 centered, which reads cleaner. */
@media (min-width: 700px) and (max-width: 900px) {
  .skill-group { flex: 1 1 calc(50% - 0.6rem); max-width: 420px; }
}

/* Skill chip groups — flex-wrap with centered last row.
   Hidden by default until the reveal_skills.py script runs. */
.skill-groups {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.8rem;
}
.skill-group {
  flex: 1 1 280px;
  max-width: 340px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1rem;
  /* Initial hidden state — JS adds .is-revealed as each shard "loads". */
  opacity: 0;
  transform: translateY(18px);
  pointer-events: none;
  transition: opacity 0.55s ease,
              transform 0.55s cubic-bezier(0.22, 1, 0.36, 1),
              border-color 0.25s ease,
              box-shadow 0.25s ease;
}
.skill-group.is-revealed {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.skill-group.is-revealed:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
}
.skill-group h3 {
  display: flex; align-items: center; gap: 0.5rem;
  color: var(--text);
  margin-bottom: 0.9rem;
  font-size: 1rem;
}
.skill-group h3 i { color: var(--accent); }

.chips {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; gap: 0.4rem;
}
.chips li {
  background: transparent;
  color: var(--text);
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius-sm);
  font-size: 0.78rem;
  font-family: var(--font-mono);
  border: 1px solid var(--border);
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.chips li:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* --------- Projects: horizontal-scroll ---------
   Outer is 280vh tall — that's the "scroll budget" the user spends panning
   through the rail. Inner is sticky, pinned to viewport. JS maps scroll
   progress into translateX on the rail. Pattern adapted from Sai Aryan
   Goswami's portfolio; vanilla-JS port (no Framer Motion). */
.section-projects {
  scroll-margin-top: var(--nav-h);
  height: 280vh;
  position: relative;
}
.section-projects:target {
  /* Override the .section:target isolation rule so sticky still works. */
  min-height: auto;
  height: 280vh;
  display: block;
}

.projects-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: center;
}

.projects-bg-text {
  position: absolute;
  /* Sit near the top of the sticky viewport — visible *above* the cards
     rather than hidden behind them. */
  top: clamp(2.5rem, 5vh, 4.5rem);
  left: 0; right: 0;
  pointer-events: none;
  z-index: 0;
  white-space: nowrap;
  overflow: hidden;
  opacity: 0.085;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: clamp(4.5rem, 12vw, 11rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
  line-height: 1;
}
.projects-bg-text span {
  display: inline-block;
  animation: projects-bg-scroll 60s linear infinite;
}
@keyframes projects-bg-scroll {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.projects-rail {
  display: flex;
  gap: clamp(1rem, 2vw, 1.5rem);
  padding-inline: max(96px, clamp(1rem, 5vw, 3rem));
  align-items: stretch;
  position: relative;
  z-index: 1;
  will-change: transform;
}

.project-card {
  flex: 0 0 clamp(380px, 38vw, 540px);
  height: clamp(560px, 76vh, 720px);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  /* More generous padding, slightly larger on the left so content reads
     anchored from a margin rather than hugging the edge. */
  padding: clamp(1.7rem, 2.4vw, 2.4rem) clamp(1.5rem, 2.2vw, 2.2rem) clamp(1.7rem, 2.4vw, 2.4rem) clamp(2rem, 2.8vw, 2.8rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: border-color 0.35s ease, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.project-card:hover {
  border-color: var(--accent);
  transform: translateY(-3px);
}

.project-card--intro {
  background: transparent;
  border: 1px dashed var(--border-strong);
  justify-content: center;
}
.project-card--intro h2 {
  font-size: clamp(2rem, 3vw, 3rem);
  margin-bottom: 0.3em;
}
.project-card--intro:hover { transform: none; }
.project-intro-hint {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.85rem;
  color: var(--accent);
  margin-top: 1.2rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.project-card--featured {
  flex: 0 0 clamp(420px, 44vw, 620px);
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
  position: relative;
}
.project-card--featured::after {
  content: "PUBLISHED · IMPACT 2025";
  position: absolute;
  top: 1rem; right: 1rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent);
  padding: 0.25rem 0.55rem;
  border-radius: var(--radius-sm);
}
.project-card--featured .project-title,
.project-card--featured .project-body p,
.project-card--featured .project-body strong,
.project-card--featured .project-metrics li,
.project-card--featured .project-metrics b {
  color: var(--bg);
}
.project-card--featured .project-num { color: var(--accent); opacity: 1; }
.project-card--featured .project-tag,
.project-card--featured .project-branch {
  color: color-mix(in srgb, var(--bg) 70%, transparent);
}
.project-card--featured .project-tech code {
  background: rgba(255,255,255,0.06);
  border-color: rgba(255,255,255,0.10);
  color: var(--bg);
}
.project-card--featured .project-links a {
  background: rgba(255,255,255,0.08);
  color: var(--bg);
}
.project-card--featured .project-links a:hover {
  background: var(--accent);
  color: #fff;
}

.project-card--end {
  flex: 0 0 clamp(220px, 18vw, 280px);
  background: transparent;
  border: 1px dashed var(--border-strong);
  justify-content: center;
  align-items: center;
  text-align: center;
  font-family: var(--font-mono);
  color: var(--text-muted);
  font-size: 0.85rem;
  text-decoration: none;
  display: flex;
  transition: border-color 0.25s ease, color 0.25s ease, transform 0.25s ease;
}
.project-card--end:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-3px);
}
.project-end-text { margin: 0; line-height: 1.8; }
.project-end-cta {
  display: inline-block;
  margin-top: 0.4rem;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.project-meta {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  margin-bottom: 0.4rem;
}
.project-num {
  font-family: var(--font-mono);
  font-size: clamp(2.8rem, 4vw, 3.8rem);
  font-weight: 700;
  color: var(--text);
  opacity: 0.18;
  line-height: 1;
  letter-spacing: -0.04em;
}
.project-branch {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.project-card--featured .project-branch { color: var(--accent); }

.project-title {
  margin: 0.4rem 0 0.2rem;
  font-size: clamp(1.55rem, 2vw, 2.05rem);
  color: var(--text);
  line-height: 1.15;
}
.project-tag {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.84rem;
  color: var(--text-muted);
  margin: 0 0 1rem;
}

.project-body {
  flex: 1 1 auto;
  overflow-y: auto;
  margin-bottom: 0.6rem;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
  padding-right: 0.4rem;
}
.project-body::-webkit-scrollbar { width: 6px; }
.project-body::-webkit-scrollbar-track { background: transparent; }
.project-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.project-body p {
  font-size: 0.96rem;
  color: var(--text-muted);
  margin: 0 0 0.75rem;
  line-height: 1.6;
}

.project-metrics {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.project-metrics li {
  font-size: 0.9rem;
  color: var(--text-muted);
  padding-left: 1.2rem;
  position: relative;
  line-height: 1.45;
}
.project-metrics li::before {
  content: "▸";
  position: absolute;
  left: 0; top: 0;
  color: var(--accent);
  font-size: 0.82rem;
}
.project-metrics b { color: var(--text); }

.project-tech {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0.7rem 0 0.8rem;
}
.project-tech code {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  font-size: 0.76rem;
}

.project-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.project-links a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.55rem 0.95rem;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 8px;
  font-size: 0.86rem;
  font-weight: 500;
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.project-links a:hover {
  background: var(--accent);
  color: #fff;
  transform: translateY(-1px);
}

/* Reduced-motion: vertical stack instead of scroll-jack (hostile to a11y). */
@media (prefers-reduced-motion: reduce) {
  .section-projects { height: auto; }
  .projects-sticky {
    position: relative;
    height: auto;
    padding: clamp(3rem, 6vh, 4.5rem) 0;
    overflow: visible;
  }
  .projects-rail {
    flex-direction: column;
    gap: 1.2rem;
    transform: none !important;
    padding-inline: clamp(1rem, 5vw, 3rem);
    align-items: stretch;
  }
  .project-card {
    flex: 0 0 auto;
    height: auto;
    min-height: 0;
    width: 100%;
  }
  .project-card--end { display: none; }
  .projects-bg-text span { animation: none; }
}

/* Mobile: keep the scroll-jacking pattern (Sai's portfolio does this on
   mobile too) — vertical finger-swipe drives horizontal card translation,
   so the swipe-direction conflict that breaks native overflow-x on touch
   never happens. Just tune card size + padding for narrow viewports. */
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .project-card {
    flex: 0 0 80vw;
    max-width: 360px;
    height: clamp(440px, 70vh, 560px);
    padding: clamp(1.3rem, 2vw, 1.7rem) clamp(1.2rem, 2vw, 1.5rem) clamp(1.3rem, 2vw, 1.7rem) clamp(1.5rem, 2.4vw, 1.9rem);
  }
  .project-card--end { display: none; }
  .projects-bg-text {
    opacity: 0.06;
    font-size: clamp(2.8rem, 9vw, 5rem);
  }
  .projects-rail { gap: 0.9rem; }
  /* Slightly smaller numerals + title to keep the card readable at 80vw */
  .project-num { font-size: clamp(2.4rem, 7vw, 3rem); }
  .project-title { font-size: clamp(1.4rem, 5vw, 1.7rem); }
}

/* --------- Experience: scroll-jacking outer ----------
   Section is 240vh tall — that's the user's scroll budget for this section.
   Sticky inner pins to the viewport; JS translates the rail Y to reel the
   timeline upward as scroll progresses. Falls back to natural-stack on
   small screens / reduced-motion. */
.section-experience {
  scroll-margin-top: var(--nav-h);
  height: 240vh;
  position: relative;
}

.experience-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.experience-header {
  flex: 0 0 auto;
  text-align: center;
  padding: calc(var(--nav-h) + clamp(0.8rem, 2vh, 1.6rem)) clamp(1rem, 5vw, 3rem) clamp(0.8rem, 2vh, 1.4rem);
  max-width: 720px;
  margin-inline: auto;
}
.experience-header .section-eyebrow { margin-bottom: 0.6rem; }
.experience-header h2 {
  color: var(--text);
  font-size: clamp(1.6rem, 1.4vw + 1rem, 2.2rem);
  margin: 0 0 0.4rem;
}
.experience-header .section-sub {
  color: var(--text-muted);
  margin: 0;
  font-size: clamp(0.92rem, 0.25vw + 0.85rem, 1rem);
}

.experience-viewport {
  flex: 1 1 auto;
  overflow: hidden;
  position: relative;
  width: 100%;
  max-width: 1080px;
  margin-inline: auto;
  padding-inline: clamp(1rem, 5vw, 3rem);
  /* Soft mask so cards fade rather than hard-clipping at the viewport edge */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 5%, black 95%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, black 5%, black 95%, transparent 100%);
}
@media (min-width: 901px) {
  .experience-viewport { padding-inline: max(96px, clamp(1rem, 5vw, 3rem)); }
}

.experience-rail {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 1rem 0 2rem;
  will-change: transform;
}

@media (prefers-reduced-motion: reduce), (max-width: 768px) {
  /* Drop scroll-jacking on phones / reduced-motion: natural vertical scroll. */
  .section-experience {
    height: auto;
    padding-block: clamp(3rem, 6vh, 4.5rem);
    padding-inline: clamp(1rem, 5vw, 3rem);
  }
  .experience-sticky {
    position: relative;
    height: auto;
    overflow: visible;
  }
  .experience-header { padding-top: 0; }
  .experience-viewport {
    overflow: visible;
    -webkit-mask-image: none;
            mask-image: none;
    padding-inline: 0;
  }
  .experience-rail {
    position: static;
    transform: none !important;
    padding: 1rem 0;
  }
}

/* --------- Experience: type badge --------- */
.timeline-type {
  display: inline-block;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
  border-radius: 4px;
  margin-bottom: 0.55rem;
  border: 1px solid var(--border);
  background: var(--bg-soft);
  color: var(--text-muted);
  font-weight: 600;
}
/* Role + Research carry the strongest signal — get the accent treatment.
   Hackathon + Competition stay neutral so they don't outshout the role. */
.timeline-type--role,
.timeline-type--research {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  background: var(--accent-soft);
}

/* --------- Experience: timeline ---------
   Vertical timeline. Date column on the left, content card on the right,
   with a connector thread + dots running between them. The current role
   has a pulsing dot. Coursework collapses to a chip strip at the bottom. */
.timeline {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
  display: flex;
  flex-direction: column;
  gap: clamp(1.6rem, 3vw, 2.4rem);
  position: relative;
}
.timeline::before {
  content: "";
  position: absolute;
  top: 0.8rem;
  bottom: 0.8rem;
  left: calc(120px + 1rem);
  width: 1px;
  background: linear-gradient(to bottom, transparent, var(--border-strong) 6%, var(--border-strong) 94%, transparent);
}

.timeline-entry {
  display: grid;
  grid-template-columns: 120px 2rem 1fr;
  align-items: start;
  position: relative;
}
.timeline-entry::before {
  content: "";
  position: absolute;
  left: calc(120px + 1rem - 5px);
  top: 0.7rem;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--border-strong);
  z-index: 1;
  transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.timeline-entry--current::before {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  animation: timeline-pulse 2.6s ease-in-out infinite;
}
.timeline-entry--research::before,
.timeline-entry--rank::before {
  background: var(--accent);
  border-color: var(--accent);
}
@keyframes timeline-pulse {
  0%, 100% { box-shadow: 0 0 0 3px var(--accent-soft); }
  50%      { box-shadow: 0 0 0 8px transparent; }
}

.timeline-date {
  grid-column: 1 / 2;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.78rem;
  color: var(--text-muted);
  line-height: 1.4;
  padding-top: 0.55rem;
  text-align: right;
  padding-right: 0.6rem;
}
.timeline-date-from { color: var(--text); font-weight: 500; }
.timeline-date-arrow { color: var(--accent); font-weight: 700; }
.timeline-date-to { color: var(--accent); font-weight: 500; }

.timeline-card {
  grid-column: 3 / 4;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem;
  transition: border-color 0.3s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease;
}
.timeline-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.timeline-entry--current .timeline-card { border-color: var(--accent-soft); }

.timeline-card-head { margin-bottom: 0.7rem; }
.timeline-role {
  font-size: 1.05rem;
  color: var(--text);
  margin: 0 0 0.2rem;
}
.timeline-org {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.78rem;
  color: var(--text-muted);
  margin: 0;
  letter-spacing: 0.04em;
}
.timeline-paper-title {
  font-style: italic;
  color: var(--text);
  font-size: 0.95rem;
  margin: 0 0 0.7rem;
  padding: 0.3rem 0 0.3rem 0.8rem;
  border-left: 2px solid var(--accent-soft);
  line-height: 1.4;
}
.timeline-points {
  list-style: none;
  padding: 0;
  margin: 0 0 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.timeline-points li {
  font-size: 0.88rem;
  color: var(--text-muted);
  padding-left: 1.1rem;
  position: relative;
  line-height: 1.5;
}
.timeline-points li::before {
  content: "▸";
  position: absolute;
  left: 0; top: 0;
  color: var(--accent);
  font-size: 0.78rem;
}
.timeline-points strong { color: var(--text); }

.timeline-stack {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0.7rem 0 0;
}
.timeline-stack code {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-size: 0.72rem;
}

/* Hackathon ranking — stat-box-style number to give the rank visual weight */
.timeline-rank {
  margin: 0.4rem 0 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.timeline-rank-num {
  font-size: 2.4rem;
  font-weight: 700;
  color: var(--accent);
  line-height: 1;
}
.timeline-rank-of {
  color: var(--text-muted);
  font-size: 0.88rem;
}
.timeline-rank-pct {
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 600;
  background: var(--accent-soft);
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  letter-spacing: 0.04em;
}

/* --------- Coursework strip --------- */
.coursework {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid var(--border);
  text-align: center;
}
.coursework-label {
  display: block;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.9rem;
}
.coursework-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
}
.coursework-list a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.8rem;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 999px;
  font-size: 0.78rem;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.coursework-list a:hover {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}
.coursework-list code {
  font-size: 0.74rem;
  background: none;
  border: none;
  padding: 0;
  color: inherit;
}
.coursework-list a i { font-size: 0.7rem; opacity: 0.7; }

@media (max-width: 768px) {
  .timeline { padding-left: 0; }
  .timeline::before {
    left: 6px;
    top: 1rem;
  }
  .timeline-entry {
    grid-template-columns: 1.5rem 1fr;
    row-gap: 0.4rem;
  }
  .timeline-entry::before {
    left: 1px;
    top: 1rem;
  }
  .timeline-date {
    grid-column: 2 / 3;
    flex-direction: row;
    align-items: baseline;
    text-align: left;
    padding-top: 0;
    padding-right: 0;
    padding-left: 0.8rem;
    gap: 0.4rem;
  }
  .timeline-card {
    grid-column: 2 / 3;
    margin-left: 0.8rem;
  }
}

/* --------- Contact --------- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
.contact-info {
  display: flex; flex-direction: column; gap: 1.3rem;
}
.contact-item h3 {
  color: var(--text);
  font-size: 0.98rem;
  margin-bottom: 0.3rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.contact-item h3 i { color: var(--accent); }
.contact-item p { margin: 0; }

.contact-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(1.2rem, 2.5vw, 2rem);
}
.contact-form .field { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.contact-form .field--wide,
.contact-form button { grid-column: 1 / -1; }

.contact-form label {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-muted);
}
.contact-form input,
.contact-form textarea {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
  font: inherit;
  color: var(--text);
  font-size: 0.95rem;
  transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
  width: 100%;
}
.contact-form textarea { resize: vertical; min-height: 120px; }
.contact-form input::placeholder,
.contact-form textarea::placeholder { color: var(--text-muted); opacity: 0.7; }
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.contact-form input:invalid:not(:placeholder-shown),
.contact-form textarea:invalid:not(:placeholder-shown) {
  border-color: color-mix(in srgb, var(--danger) 60%, var(--border));
}
.field-error {
  font-size: 0.78rem;
  color: var(--danger);
  min-height: 1em;
}

.contact-form button {
  justify-self: start;
}

/* --------- Arrival highlight (nav-click feedback) --------- */
/* When a section is navigated-to (its ID is in the URL hash), pulse a subtle
   accent ring around the eyebrow so the user gets a visual confirmation that
   matches the click. Self-clears after the animation. */
@keyframes arrival-eyebrow-pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent); }
  30%  { box-shadow: 0 0 0 14px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.section.is-arrived .section-eyebrow,
.hero.is-arrived .eyebrow {
  animation: arrival-eyebrow-pulse 1.6s ease-out 1;
}

/* --------- Reveal animations --------- */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; }
}

/* --------- Responsive — Sai-style breakpoint sweep ---------- */

/* --- 768 and below: tablets ---
   Hero rail shrinks. Projects bg-text shrinks. Top text-nav transforms
   into a bottom-floating icon pill — section icons + theme toggle. The
   side-rail (LinkedIn / GitHub etc) hides on this width since the pill
   takes its bottom-of-screen position. */
@media (max-width: 768px) {
  .projects-bg-text { font-size: clamp(3.5rem, 9vw, 6rem); }
  .hero-rail { width: clamp(60px, 11vw, 120px); }

  /* Top nav → bottom pill. */
  .site-nav {
    top: auto;
    bottom: clamp(0.8rem, 2vw, 1.2rem);
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: auto;
    max-width: calc(100vw - 1.5rem);
    height: auto;
    border-radius: 999px;
    border: 1px solid var(--border-strong);
    background: color-mix(in srgb, var(--surface) 92%, transparent);
    backdrop-filter: saturate(160%) blur(12px);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
    padding: 0.4rem;
    gap: 0.25rem;
    box-shadow: var(--shadow-md);
  }
  .nav-brand { display: none; }
  .nav-links {
    flex-wrap: nowrap;
    gap: 0.1rem;
    padding: 0;
    margin: 0;
  }
  .nav-links a {
    width: 38px;
    height: 38px;
    padding: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.95rem;
  }
  .nav-icon { display: inline-flex; }
  .nav-label { display: none; }
  .nav-links a.active,
  .nav-links a:hover {
    background: var(--accent-soft);
    color: var(--accent);
  }
  #theme-toggle {
    width: 38px;
    height: 38px;
    border: 1px solid var(--border);
  }
  #theme-toggle:hover { transform: none; }

  /* Side-rail (social) hidden — bottom pill takes its real estate. Social
     icons remain accessible inside the About + Contact sections. */
  .side-rail { display: none; }

  /* Section anchor scroll-margin-top isn't needed for top nav anymore;
     give a tiny breathing room from viewport top. */
  .section, .section-projects, .section-experience, .hero {
    scroll-margin-top: 0.5rem;
  }

  /* Contact gets bottom padding so the form's submit button doesn't sit
     directly under the floating bottom-pill nav. */
  #contact .section-inner { padding-bottom: 5.5rem; }
}

/* --- 640 and below: phones ---
   Hide the hero rail — at this width it overlaps the centered avatar +
   text and stops feeling like atmosphere. */
@media (max-width: 640px) {
  .hero-rail { display: none; }
}

/* --- 480 and below: small phones ---
   Terminal tightens font + padding so `python reveal_skills.py` fits
   without horizontal overflow. */
@media (max-width: 480px) {
  .terminal { font-size: 0.78rem; }
  .terminal-body { padding: 0.9rem 1rem; min-height: 220px; }
  .terminal-prompt-line { row-gap: 0.1rem; }
  .terminal-bar-title { font-size: 0.66rem; }
  .lede { font-size: 0.98rem; line-height: 1.5; }

  /* Tighten the bottom pill on very small phones. */
  .site-nav { padding: 0.3rem; gap: 0.15rem; }
  .nav-links a, #theme-toggle { width: 34px; height: 34px; }
  .nav-icon { font-size: 0.88rem; }
}

/* ============================================================
   MOBILE DENSITY PASS (≤768px)
   Goal: each section fits in ~1 viewport instead of 1.5–2. We
   drop min-height: 100svh (the desktop "fill-the-screen" rule
   that wastes scroll on phones), tighten section padding, and
   lock down a few specific bugs (squashed contact form, etc.).
   ============================================================ */
@media (max-width: 768px) {
  /* Sections grow to content; no more forced viewport height. */
  .section,
  #about.section,
  #skills.section {
    min-height: 0;
    padding-block: clamp(2rem, 7vw, 3rem);
    justify-content: flex-start;
  }
  /* Hero keeps min-height (it's the landing impression). */
  .hero { min-height: 100svh; }

  /* Section heads tighten — eyebrow + h2 + sub trio. */
  .section-eyebrow { font-size: 0.7rem; }
  .section h2, .hero h1 { line-height: 1.15; }
  .section-sub { font-size: 0.95rem; }

  /* About: model_card row spacing, status-grid stays 2-up
     instead of falling to 1-col (less ribbon scroll). */
  .mc-row { padding-block: 0.45rem; }
  .status-grid { grid-template-columns: repeat(3, 1fr) !important; gap: 0.5rem; }
  .status-grid .stat-box { padding: 0.6rem 0.65rem; }
  .status-grid .stat-box .stat-value { font-size: clamp(1.1rem, 5vw, 1.6rem); }
  .status-grid .stat-box h4 { font-size: 0.6rem; }

  /* Contact: force single-column form, kill any inherited
     2-col grid. The 820px rule was being shadowed somewhere. */
  .contact-grid { grid-template-columns: 1fr !important; gap: 1.2rem; }
  .contact-form { grid-template-columns: 1fr !important; gap: 0.8rem; padding: 1.1rem; }
  .contact-form .field { grid-column: 1 / -1 !important; }
  .contact-form button { width: 100%; justify-self: stretch; }
  .contact-form textarea { min-height: 100px; }
  .contact-info { gap: 0.9rem; }

  /* Experience timeline: tighten card padding. */
  .timeline-card { padding: 1rem 1.1rem; }
  .timeline-card .role-tag { font-size: 0.65rem; }

  /* Skills: terminal smaller, cards more compact. */
  .skills-terminal-wrap { margin-bottom: 1.5rem; }
  .terminal-body { max-height: 32vh; min-height: 180px; }
  .skill-group { padding: 0.9rem 1rem; }
  .skill-group h3 { font-size: 0.92rem; margin-bottom: 0.6rem; }

  /* Live-stats already handles <700; just tighten margin. */
  .live-stats { margin-top: 1rem; margin-bottom: 1rem; }
}

/* ============================================================
   PHONE-SPECIFIC (≤480px) — even tighter to prevent ribbon scroll.
   ============================================================ */
@media (max-width: 480px) {
  .status-grid { grid-template-columns: repeat(3, 1fr) !important; gap: 0.4rem; }
  .status-grid .stat-box { padding: 0.5rem 0.4rem; }
  .status-grid .stat-box h4 { font-size: 0.55rem; line-height: 1.25; }
  .section-head { margin-bottom: 1.2rem; }
  .skill-groups { gap: 0.6rem; }
}

/* --------- Selection --------- */
::selection { background: var(--accent); color: #fff; }
