/* ============================================================
   NISHCHAY PORTFOLIO — style.css
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:           #080808;
  --surface:      rgba(255,255,255,0.035);
  --surface-2:    rgba(255,255,255,0.07);
  --border:       rgba(255,255,255,0.07);
  --border-2:     rgba(255,255,255,0.13);
  --text:         #f0ede8;
  --text-dim:     rgba(240,237,232,0.45);
  --text-dimmer:  rgba(240,237,232,0.22);
  --accent:       #e8d5b7;
  --gold:         #c9a96e;
  --gold-dim:     rgba(201,169,110,0.15);
  --gold-glow:    rgba(201,169,110,0.22);
  --gold-glow2:   rgba(201,169,110,0.06);
  --radius:       14px;
  --radius-sm:    9px;

  /* Motion. `--ease` is the house curve: a decisive start that
     settles without overshoot — the critically-damped default.
     `--ease-soft` is its symmetric counterpart, used on the
     return leg of reversible transitions so out mirrors in. */
  --ease:         cubic-bezier(0.22,1,0.36,1);
  --ease-soft:    cubic-bezier(0.4,0,0.2,1);
  --ease-out:     cubic-bezier(0.16,1,0.3,1);
  --t:            0.5s var(--ease);
  --tf:           0.22s var(--ease);
  --tp:           0.1s ease-out;   /* press feedback — must feel instant */

  /* z-index scale — every layer names itself here, nowhere else. */
  --z-bg:         0;
  --z-page:       1;
  --z-glow:       2;
  --z-chrome:     100;
  --z-backdrop:   399;
  --z-panel:      400;
  --z-loader:     9999;
}

/* Registered so the hover offset can be interpolated. Without
   @property a custom property is a string and cannot transition;
   browsers without support simply snap, which is an acceptable
   degradation rather than a break. */
@property --hover-x {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

html { font-size: 16px; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Syne', sans-serif;
  overflow-x: hidden;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body.chat-open { overflow: hidden; }

.mono { font-family: 'DM Mono', monospace; }
a { color: inherit; text-decoration: none; }

/* Keyboard users get a visible ring everywhere; pointer users
   never see it. Declared once, up front, so no component has to
   remember. */
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 4px;
}
:focus:not(:focus-visible) { outline: none; }

/* Icons: one sizing contract for the whole sprite. */
.ico { width: 1em; height: 1em; display: block; flex-shrink: 0; }
.ico--sm { width: 14px; height: 14px; }
.ico--md { width: 18px; height: 18px; }

/* Screen-reader-only, for labels that shouldn't render. */
.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;
}

/* ── MAGNETIC COMPOSITION ────────────────────────────────
   The pointer offset (--mx/--my, written by script.js each
   frame) and the hover offset (--hover-x, owned by CSS) compose
   into one transform. Keeping them separate is what lets a
   magnetic element also have its own hover motion — assigning
   `style.transform` directly would clobber one with the other. */
.magnetic {
  transform: translate3d(calc(var(--mx, 0px) + var(--hover-x, 0px)), var(--my, 0px), 0);
  transition: --hover-x var(--tf);
}

/* ── LOADER ─────────────────────────────────────────── */
#loader {
  position: fixed; inset: 0;
  background: var(--bg);
  z-index: var(--z-loader);
  display: flex; align-items: center; justify-content: center;
  transition: opacity 0.6s var(--ease-soft), visibility 0.6s var(--ease-soft);
}
#loader.hidden { opacity: 0; visibility: hidden; pointer-events: none; }

.loader-inner { display: flex; flex-direction: column; align-items: center; gap: 22px; }

.loader-name {
  font-size: clamp(4rem, 12vw, 7rem);
  font-weight: 800;
  letter-spacing: -0.05em;
  color: var(--gold);
  animation: glow-pulse 1.6s var(--ease-soft) infinite alternate;
}
@keyframes glow-pulse {
  from { text-shadow: 0 0 20px var(--gold-glow); }
  to   { text-shadow: 0 0 70px var(--gold-glow), 0 0 140px var(--gold-glow2); }
}

.loader-bar {
  width: 100px; height: 1px;
  background: var(--border);
  border-radius: 2px; overflow: hidden;
}
.loader-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--gold), var(--accent));
  width: 0;
  animation: fill 1.4s var(--ease) forwards;
}
@keyframes fill { to { width: 100%; } }

/* ── BACKGROUND ──────────────────────────────────────── */
.bg-canvas {
  position: fixed; inset: 0;
  pointer-events: none; z-index: var(--z-bg); overflow: hidden;
}
#particle-canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.45; }

.bg-orb {
  position: absolute; border-radius: 50%;
  filter: blur(90px); opacity: 0.1;
  animation: orb 22s ease-in-out infinite alternate;
  will-change: transform;
}
.orb-1 {
  width: clamp(280px,48vw,580px); height: clamp(280px,48vw,580px);
  background: radial-gradient(circle, #c9a96e, transparent 70%);
  top: -12%; left: -8%; animation-duration: 19s;
}
.orb-2 {
  width: clamp(180px,30vw,380px); height: clamp(180px,30vw,380px);
  background: radial-gradient(circle, #3e2c1a, transparent 70%);
  bottom: 8%; right: 4%; animation-duration: 26s; animation-delay: -9s;
}
.orb-3 {
  width: clamp(120px,20vw,260px); height: clamp(120px,20vw,260px);
  background: radial-gradient(circle, #1c3328, transparent 70%);
  top: 52%; left: 48%; animation-duration: 24s; animation-delay: -5s;
}
@keyframes orb {
  0%   { transform: translate(0,0) scale(1); }
  50%  { transform: translate(4%,7%) scale(1.06); }
  100% { transform: translate(-3%,-5%) scale(0.94); }
}

.cursor-glow {
  position: fixed; top: 0; left: 0;
  width: 260px; height: 260px;
  border-radius: 50%;
  pointer-events: none;
  z-index: var(--z-glow);
  background: radial-gradient(circle, rgba(201,169,110,0.055) 0%, transparent 70%);
  transition: opacity 0.4s var(--ease-soft);
  will-change: transform;
}

/* ── PAGE SYSTEM ─────────────────────────────────────────
   Enter and exit run along the same axis, so a page leaves the
   way it arrived. Forward navigation moves up the stack; going
   back reverses it. */
.page {
  position: fixed; inset: 0;
  overflow-y: auto; overflow-x: hidden;
  z-index: var(--z-page);
  opacity: 0; visibility: hidden;
  transition: opacity 0.34s var(--ease-soft), transform 0.34s var(--ease), visibility 0.34s;
  will-change: opacity, transform;
}
.page.active { opacity: 1; visibility: visible; transform: none; }

.page.enter        { opacity: 0; transform: translateY(16px) scale(0.994); }
.page.enter-back   { opacity: 0; transform: translateY(-14px) scale(1.006); }
.page.exit         { opacity: 0; transform: translateY(-14px) scale(1.006); visibility: visible; }
.page.exit-back    { opacity: 0; transform: translateY(16px) scale(0.994); visibility: visible; }

/* ── HOME ─────────────────────────────────────────────── */
#page-home { display: flex; flex-direction: column; min-height: 100dvh; }

/* Header */
.home-header {
  position: sticky; top: 0; z-index: var(--z-chrome);
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: clamp(14px,2.8vw,26px) clamp(20px,6vw,72px);
  backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%);
  border-bottom: 1px solid transparent;
  background: rgba(8,8,8,0.55);
  transition: border-color var(--tf), background var(--tf);
}
/* The divider only appears once content is actually passing
   under the chrome — a hairline over empty space is noise. */
.home-header.is-scrolled,
.sub-header.is-scrolled { border-bottom-color: var(--border); }

.logo { font-size: clamp(1.3rem,2.8vw,1.9rem); font-weight: 800; letter-spacing: -0.05em; }
.logo-dot { color: var(--gold); }

.header-center {
  font-size: clamp(0.58rem,1.1vw,0.72rem);
  color: var(--text-dimmer);
  letter-spacing: 0.06em;
  text-align: center;
  flex: 1;
}
.header-socials { display: flex; gap: 8px; align-items: center; }

/* Home main */
.home-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(32px,6vw,100px);
  padding: clamp(44px,8vw,110px) clamp(20px,6vw,72px);
  min-height: calc(100dvh - 70px);
}

/* Name block */
.home-left { flex: 1 1 auto; min-width: 0; }

.name-label {
  font-size: 0.68rem; color: var(--text-dimmer);
  letter-spacing: 0.14em; margin-bottom: 14px;
  display: block;
}

/* Tracking tightens as the type grows — a single letter-spacing
   value cannot be right at both 2.8rem and 7.5rem. */
.name-title {
  font-size: clamp(2.8rem, 8vw, 7.5rem);
  font-weight: 800;
  letter-spacing: -0.055em;
  line-height: 0.98;
  color: var(--text);
  margin-bottom: 28px;
  white-space: nowrap;
  /* inline-block is required for background-clip:text to size to
     the glyphs rather than the block. */
  display: inline-block;
}
.name-title:focus { outline: none; }

.name-tagline {
  font-size: clamp(0.82rem,1.4vw,0.98rem);
  color: var(--text-dim);
  line-height: 1.75;
  /* A fixed 380px is wider than the content box on a 375px phone,
     which pushed the whole column past the viewport. */
  max-width: min(380px, 100%);
}

/* The wrapper carries the entrance so it never fights the button's
   own hover/press transform. */
.hero-cta-wrap {
  margin-top: clamp(22px, 3vw, 30px);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.hero-cta { letter-spacing: 0.12em; font-weight: 700; }

/* Handwritten-feeling annotation pointing at the button. DM Mono's italic
   is already loaded, and set small and gold it reads as a margin note
   rather than another piece of UI. */
.hero-cta-note {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--gold);
  font-family: 'DM Mono', monospace;
  font-style: italic;
  font-size: 0.72rem;
  letter-spacing: 0.01em;
}
.hero-cta-note-text { white-space: nowrap; }

.hero-cta-arrow {
  width: 58px;
  height: 27px;
  flex-shrink: 0;
  opacity: 0.85;
  transition: transform var(--tf), opacity var(--tf);
}

/* Nudges twice on entrance to catch the eye, then stops. A permanently
   looping arrow would compete with the content for the whole visit. */
.hero-cta-wrap.entered .hero-cta-arrow {
  animation: cta-nudge 1.5s var(--ease-soft) 0.6s 2;
}
@keyframes cta-nudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(-5px); }
}
.hero-cta-wrap:hover .hero-cta-arrow { transform: translateX(-4px); opacity: 1; }

/* Staggered entrance. The delay is a custom property so the
   order lives in one place and the curve lives here. */
.name-label, .name-title, .name-tagline, .hero-cta-wrap, .nav-btn {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.6s var(--ease-out) var(--enter-delay, 0ms),
    transform 0.6s var(--ease-out) var(--enter-delay, 0ms);
}
.nav-btn { transform: translateX(14px); }

.name-label.entered, .name-title.entered, .name-tagline.entered,
.hero-cta-wrap.entered, .nav-btn.entered {
  opacity: 1;
  transform: none;
}
/* Once in, the nav button hands its transform back to the
   magnetic/hover composition. */
.nav-btn.entered {
  transform: translate3d(calc(var(--mx, 0px) + var(--hover-x, 0px)), var(--my, 0px), 0);
  transition:
    background var(--tf), border-color var(--tf), box-shadow var(--tf),
    --hover-x var(--tf), opacity 0.6s var(--ease-out);
}

/* Vertical nav */
.vertical-nav {
  display: flex; flex-direction: column;
  gap: clamp(7px,1.2vw,11px);
  flex: 0 0 auto;
  width: clamp(240px, 30vw, 360px);
}

.nav-btn {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  padding: clamp(13px,2.2vw,19px) clamp(16px,2.8vw,26px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  cursor: pointer;
  font-family: 'Syne', sans-serif;
  font-size: clamp(0.88rem,1.6vw,1.05rem);
  font-weight: 600;
  text-align: left;
  overflow: hidden;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.nav-btn::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(120deg, rgba(201,169,110,0.1) 0%, transparent 55%);
  opacity: 0;
  transition: opacity var(--tf);
  pointer-events: none;
}
.nav-btn:hover {
  --hover-x: 7px;
  background: var(--surface-2);
  border-color: var(--border-2);
  box-shadow: -4px 0 0 var(--gold), 0 0 30px var(--gold-glow2);
}
.nav-btn:hover::after { opacity: 1; }
.nav-btn:active { --hover-x: 4px; transition-duration: var(--tp); }

.nav-num { font-size: 0.62rem; color: var(--text-dimmer); letter-spacing: 0.08em; min-width: 18px; }
.nav-label { flex: 1; }
.nav-arrow {
  color: var(--gold);
  display: flex; align-items: center;
  opacity: 0; transform: translateX(-6px);
  transition: opacity var(--tf), transform var(--tf);
}
.nav-btn:hover .nav-arrow, .nav-btn:focus-visible .nav-arrow { opacity: 1; transform: translateX(0); }

.nav-cv {
  border-color: rgba(201,169,110,0.25);
  background: rgba(201,169,110,0.04);
}
.nav-cv:hover { box-shadow: -4px 0 0 var(--gold), 0 0 40px rgba(201,169,110,0.18); }

/* ── CONTACT ─────────────────────────────────────────── */
.home-contact {
  padding: clamp(48px,8vw,100px) clamp(20px,6vw,72px);
  border-top: 1px solid var(--border);
}
.contact-inner { max-width: 940px; margin: 0 auto; }
.contact-heading {
  font-size: clamp(1.7rem,4vw,3rem);
  font-weight: 800; letter-spacing: -0.04em;
  margin-bottom: 10px;
}
.contact-sub {
  font-size: 0.88rem; color: var(--text-dim); line-height: 1.7;
  max-width: 46ch;
  margin-bottom: clamp(28px,5vw,48px);
}
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.5fr;
  gap: clamp(24px,5vw,60px);
  align-items: start;
}
.contact-links { display: flex; flex-direction: column; gap: 10px; }
.contact-link {
  display: flex; align-items: center; gap: 13px;
  padding: 14px 18px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: clamp(0.77rem,1.3vw,0.88rem);
  color: var(--text-dim);
  transition: background var(--tf), border-color var(--tf), color var(--tf), --hover-x var(--tf);
  transform: translate3d(var(--hover-x, 0px), 0, 0);
  overflow-wrap: anywhere;
}
.contact-link:hover {
  --hover-x: 4px;
  background: var(--surface-2); border-color: var(--border-2); color: var(--text);
}
.cl-icon { color: var(--gold); flex-shrink: 0; display: flex; }

/* Form */
.contact-form { display: flex; flex-direction: column; gap: 14px; }
.form-group { display: flex; flex-direction: column; gap: 6px; }

.form-label {
  font-size: 0.66rem;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.1em;
  color: var(--text-dimmer);
  text-transform: uppercase;
}

.form-group input,
.form-group textarea {
  width: 100%;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 13px 17px;
  color: var(--text);
  font-family: 'Syne', sans-serif;
  /* 16px min on mobile: anything smaller makes iOS zoom on focus. */
  font-size: 1rem;
  outline: none; resize: vertical;
  transition: border-color var(--tf), background var(--tf), box-shadow var(--tf);
}
.form-group textarea { min-height: 110px; }
.form-group input::placeholder,
.form-group textarea::placeholder { color: var(--text-dimmer); }
.form-group input:focus,
.form-group textarea:focus {
  border-color: rgba(201,169,110,0.4);
  background: var(--surface-2);
  box-shadow: 0 0 0 3px rgba(201,169,110,0.09);
}
.form-group input.is-invalid,
.form-group textarea.is-invalid {
  border-color: rgba(226,116,110,0.55);
  box-shadow: 0 0 0 3px rgba(226,116,110,0.09);
}

/* Error text sits next to the field it belongs to, not in a
   summary somewhere else on the page. */
.form-err {
  font-size: 0.72rem;
  color: #e2746e;
  min-height: 1em;
  line-height: 1.4;
}
.form-err:empty { min-height: 0; }

/* The honeypot must be genuinely unreachable — off-screen rather
   than display:none, which some bots detect. */
.cf-hp {
  position: absolute !important;
  left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

.form-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

.form-status {
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-dim);
}
.form-status[data-tone="success"] { color: #7ecba0; }
.form-status[data-tone="error"]   { color: #e2746e; }
.form-status[data-tone="warn"]    { color: var(--gold); }
.form-status[data-tone="pending"] { color: var(--text-dim); }

/* Fallback compose panel — shown only if the server cannot send,
   so a message is never silently lost. */
.cf-fallback {
  margin-top: 6px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid rgba(201,169,110,0.22);
  border-radius: var(--radius-sm);
  display: flex; flex-direction: column; gap: 12px;
}
.cf-fallback[hidden] { display: none; }
.cf-fallback-body {
  font-family: 'DM Mono', monospace;
  font-size: 0.72rem;
  line-height: 1.7;
  color: var(--text-dim);
  white-space: pre-wrap;
  max-height: 160px;
  overflow-y: auto;
}
.cf-fallback-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ── HOME FOOTER ─────────────────────────────────────── */
.home-footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
  padding: clamp(18px,2.8vw,30px) clamp(20px,6vw,72px);
  border-top: 1px solid var(--border);
}
.footer-copy { font-size: 0.75rem; color: var(--text-dimmer); }
.footer-socials { display: flex; gap: 22px; }
.footer-socials a { font-size: 0.75rem; color: var(--text-dim); transition: color var(--tf); }
.footer-socials a:hover { color: var(--gold); }

/* ── SUB PAGES ───────────────────────────────────────── */
.sub-page { display: flex; flex-direction: column; min-height: 100dvh; }

.sub-header {
  position: sticky; top: 0; z-index: var(--z-chrome);
  display: flex; align-items: center; gap: 18px;
  padding: clamp(12px,2.2vw,20px) clamp(20px,6vw,72px);
  backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%);
  border-bottom: 1px solid transparent;
  background: rgba(8,8,8,0.65);
  flex-wrap: wrap;
  transition: border-color var(--tf);
}
.back-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 18px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 40px;
  color: var(--text-dim); cursor: pointer;
  font-family: 'Syne', sans-serif; font-size: 0.82rem; font-weight: 600;
  transition: background var(--tf), color var(--tf), border-color var(--tf), --hover-x var(--tf);
  white-space: nowrap;
}
.back-btn:hover { --hover-x: -3px; background: var(--surface-2); border-color: var(--border-2); color: var(--text); }
.back-btn:active { transition-duration: var(--tp); }

.sub-crumb { display: flex; align-items: center; gap: 7px; font-size: 0.72rem; }
.crumb-home { color: var(--text-dimmer); cursor: pointer; transition: color var(--tf); }
.crumb-home:hover { color: var(--text-dim); }
.crumb-sep  { color: var(--text-dimmer); }
.crumb-cur  { color: var(--gold); letter-spacing: 0.06em; }

.sub-content {
  flex: 1;
  padding: clamp(40px,7vw,80px) clamp(20px,6vw,72px);
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
}

.sub-intro { margin-bottom: clamp(36px,6vw,64px); }
.sub-num { font-size: 0.66rem; color: var(--text-dimmer); letter-spacing: 0.14em; display: block; margin-bottom: 10px; }
.section-heading {
  font-size: clamp(2rem,5.5vw,4.2rem);
  font-weight: 800; letter-spacing: -0.055em;
  line-height: 1; margin-bottom: 14px;
}
.section-heading:focus { outline: none; }
.section-sub { font-size: clamp(0.82rem,1.4vw,0.96rem); color: var(--text-dim); line-height: 1.7; max-width: 56ch; }

.sub-footer {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px;
  padding: clamp(16px,2.5vw,24px) clamp(20px,6vw,72px);
  border-top: 1px solid var(--border);
  font-size: 0.62rem; color: var(--text-dimmer); letter-spacing: 0.04em;
}

/* ── PROJECTS ─────────────────────────────────────────── */
.projects-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%,300px),1fr));
  gap: clamp(14px,2.5vw,24px);
}
.project-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform var(--tf), border-color var(--tf), box-shadow var(--tf);
}
.project-card:hover {
  transform: translateY(-6px);
  border-color: var(--border-2);
  box-shadow: 0 20px 50px rgba(0,0,0,0.45);
}

/* Card header: a quiet tinted field with a fine dot grid and a
   single line-art mark. Replaces the emoji-on-a-gradient
   treatment, which reads as placeholder art. */
.project-img {
  height: clamp(110px,18vw,170px);
  display: flex; align-items: center; justify-content: center;
  position: relative; overflow: hidden;
  border-bottom: 1px solid var(--border);
}
.project-img::before {
  content: '';
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,0.075) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: 0.55;
}
.project-img::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(160deg, rgba(255,255,255,0.05), transparent 55%);
}

.proj-img-1 { background: linear-gradient(135deg, #14141f 0%, #101827 100%); }
.proj-img-2 { background: linear-gradient(135deg, #0c1519 0%, #16303a 100%); }
.proj-img-3 { background: linear-gradient(135deg, #101722 0%, #182838 100%); }
.proj-img-4 { background: linear-gradient(135deg, #14141f 0%, #1d1440 100%); }
.proj-img-5 { background: linear-gradient(135deg, #0a1019 0%, #12283c 100%); }
.proj-img-6 { background: linear-gradient(135deg, #121a12 0%, #1e301e 100%); }
.proj-img-7 { background: linear-gradient(135deg, #131313 0%, #1f1f2c 100%); }
.proj-img-8 { background: linear-gradient(135deg, #0a1c11 0%, #133525 100%); }
.proj-img-ec1 { background: linear-gradient(135deg, #1c110b 0%, #351e13 100%); }
.proj-img-ec2 { background: linear-gradient(135deg, #140f22 0%, #281d40 100%); }

.proj-icon {
  position: relative;
  width: clamp(34px,6vw,44px);
  height: clamp(34px,6vw,44px);
  color: var(--gold);
  opacity: 0.9;
  transition: transform 0.4s var(--ease), opacity var(--tf);
}
.project-card:hover .proj-icon { transform: scale(1.06); opacity: 1; }

.project-body { padding: clamp(16px,3vw,24px); display: flex; flex-direction: column; flex: 1; }
.project-body h3 { font-size: clamp(0.95rem,1.8vw,1.15rem); font-weight: 700; letter-spacing: -0.025em; margin-bottom: 10px; }

.tech-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 12px; }
.tech-tags span {
  padding: 3px 9px;
  background: var(--gold-dim); border: 1px solid rgba(201,169,110,0.2);
  border-radius: 20px; font-size: 0.63rem;
  font-family: 'DM Mono', monospace; color: var(--gold); letter-spacing: 0.04em;
}

.project-body p { font-size: 0.82rem; color: var(--text-dim); line-height: 1.7; margin-bottom: 18px; flex: 1; }

.project-links { margin-top: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.project-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 18px;
  background: transparent; border: 1px solid var(--border-2);
  border-radius: 40px; font-size: 0.76rem;
  font-family: 'Syne', sans-serif; font-weight: 600;
  color: var(--text-dim); cursor: pointer;
  transition: background var(--tf), color var(--tf), border-color var(--tf), --hover-x var(--tf);
  transform: translate3d(var(--hover-x, 0px), 0, 0);
}
.project-btn:hover {
  --hover-x: 3px;
  background: var(--surface-2); color: var(--text); border-color: rgba(201,169,110,0.4);
}
.project-btn:active { transition-duration: var(--tp); }

/* ── EXPERIENCE ───────────────────────────────────────── */
.timeline { position: relative; padding-left: 28px; }
.timeline::before {
  content: ''; position: absolute;
  left: 0; top: 10px; bottom: 0;
  width: 1px;
  background: linear-gradient(to bottom, var(--border-2) 0%, transparent 100%);
}
.timeline--single { max-width: 820px; padding-left: 28px; }

.tl-item { position: relative; padding-bottom: 38px; }
.tl-item:last-child { padding-bottom: 0; }

.tl-dot {
  position: absolute; left: -32px; top: 8px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--gold); border: 2px solid var(--bg);
  box-shadow: 0 0 12px rgba(201,169,110,0.55);
}
.tl-date { font-size: 0.65rem; color: var(--text-dimmer); letter-spacing: 0.07em; display: block; margin-bottom: 6px; }
.tl-item h4 { font-size: clamp(0.9rem,1.7vw,1.05rem); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 3px; }
.tl-org { font-size: 0.75rem; color: var(--gold); margin-bottom: 10px; }
.tl-item > .tl-body > p { font-size: 0.8rem; color: var(--text-dim); line-height: 1.72; margin-bottom: 12px; max-width: 68ch; }

.tl-top-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}

.tl-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.tl-tags span {
  padding: 3px 9px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 20px; font-size: 0.6rem;
  font-family: 'DM Mono', monospace; color: var(--text-dimmer); letter-spacing: 0.05em;
}

.tl-type-badge {
  padding: 4px 13px; border-radius: 20px;
  font-size: 0.62rem; font-family: 'DM Mono', monospace;
  letter-spacing: 0.07em; white-space: nowrap;
  flex-shrink: 0; margin-top: 2px;
}
.tl-badge--work    { background: rgba(201,169,110,0.12); border: 1px solid rgba(201,169,110,0.3); color: var(--gold); }
.tl-badge--vol     { background: rgba(100,180,140,0.1);  border: 1px solid rgba(100,180,140,0.25); color: #7ecba0; }
.tl-badge--mentor  { background: rgba(160,140,255,0.1);  border: 1px solid rgba(160,140,255,0.28); color: #b3a3ff; }
.tl-badge--virtual { background: rgba(120,180,255,0.1);  border: 1px solid rgba(120,180,255,0.28); color: #8fbcff; }

/* ── EDUCATION ────────────────────────────────────────── */
.edu-cards { display: flex; flex-direction: column; gap: 20px; }

.edu-card {
  display: flex; gap: clamp(20px,4vw,40px);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: clamp(22px,4vw,36px);
  transition: border-color var(--tf), box-shadow var(--tf), --hover-x var(--tf);
  transform: translate3d(var(--hover-x, 0px), 0, 0);
  align-items: flex-start;
}
.edu-card:hover { --hover-x: 6px; border-color: var(--border-2); box-shadow: -3px 0 0 var(--gold); }
.edu-card--active { border-color: rgba(201,169,110,0.2); background: rgba(201,169,110,0.03); }

.edu-card-left { flex-shrink: 0; }
.edu-year-block { display: flex; flex-direction: column; align-items: center; gap: 4px; padding-top: 4px; }
.edu-year { font-size: 0.62rem; color: var(--text-dimmer); letter-spacing: 0.06em; }
.edu-year-line { width: 1px; height: 30px; background: var(--border-2); }

.edu-card-right { flex: 1; min-width: 0; }
.edu-top-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.edu-top-row h3 { font-size: clamp(1rem,2.2vw,1.35rem); font-weight: 700; letter-spacing: -0.03em; }
.edu-school { font-size: 0.76rem; color: var(--gold); }
.edu-badge {
  padding: 3px 11px;
  background: var(--gold-dim); border: 1px solid rgba(201,169,110,0.3);
  border-radius: 20px; font-size: 0.6rem;
  font-family: 'DM Mono', monospace; color: var(--gold); letter-spacing: 0.08em;
  white-space: nowrap; flex-shrink: 0;
}
.edu-desc { font-size: 0.82rem; color: var(--text-dim); line-height: 1.72; margin: 12px 0 16px; max-width: 68ch; }

.edu-subjects-block { margin-bottom: 18px; }
.edu-subjects-label { font-size: 0.62rem; color: var(--text-dimmer); letter-spacing: 0.1em; display: block; margin-bottom: 8px; }
.edu-subjects { display: flex; flex-wrap: wrap; gap: 6px; }
.edu-subjects span {
  padding: 4px 12px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 20px; font-size: 0.68rem;
  font-family: 'DM Mono', monospace; color: var(--text-dim);
}

.edu-highlights { display: flex; gap: clamp(16px,4vw,36px); flex-wrap: wrap; }
.edu-highlight { display: flex; flex-direction: column; gap: 3px; }
.eh-num {
  font-size: clamp(1.1rem,2.5vw,1.6rem); font-weight: 800;
  letter-spacing: -0.04em; color: var(--text);
  display: flex; align-items: center; min-height: 1.6rem;
}
.eh-num .ico { width: clamp(1.1rem,2.5vw,1.6rem); height: clamp(1.1rem,2.5vw,1.6rem); color: var(--gold); }
.eh-label { font-size: 0.62rem; color: var(--text-dimmer); font-family: 'DM Mono', monospace; letter-spacing: 0.06em; }

/* ── CERTIFICATES ─────────────────────────────────────── */
.cert-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%,260px),1fr));
  gap: clamp(12px,2.2vw,20px);
  /* Each card sizes to its own content. Without this, grid stretches every
     card to the tallest in its row, so a card with no scan gets a large
     empty void below its text next to one that has an image. */
  align-items: start;
}
.cert-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  transition: border-color var(--tf), transform var(--tf), box-shadow var(--tf);
}
.cert-card:hover { border-color: rgba(201,169,110,0.28); transform: translateY(-5px); box-shadow: 0 14px 42px rgba(0,0,0,0.35); }

/* Optional scan of the certificate, as the card's first child:
     <div class="cert-media"><img src="certs/x.jpg" alt="" loading="lazy" width="1600" height="1000"></div>
   Sized with `contain` rather than `cover` because certificates come in
   unpredictable aspect ratios and cropping one is worse than letterboxing
   it. Cards without an image are a complete design, not a gap. */
.cert-media {
  aspect-ratio: 16 / 10;
  width: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 10px;
  border: 0;
  border-radius: 0;
  cursor: zoom-in;
  font: inherit;
  -webkit-appearance: none;
  appearance: none;
  background:
    linear-gradient(160deg, rgba(255,255,255,0.045), transparent 60%),
    rgba(255,255,255,0.02);
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.cert-media img {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
  display: block;
  border-radius: 4px;
  transition: transform 0.5s var(--ease);
}
.cert-card:hover .cert-media img { transform: scale(1.03); }

/* ── CERTIFICATE LIGHTBOX ─────────────────────────────────
   A certificate is unreadable at card size, so the scan opens
   full-view. Materialises with blur and scale together rather than
   a flat opacity fade, so it reads as a surface arriving. */
.cert-lightbox {
  position: fixed; inset: 0;
  z-index: var(--z-panel);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(16px, 4vw, 48px);
  background: rgba(6,6,6,0.86);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  opacity: 0;
  transition: opacity 0.26s var(--ease-soft);
  cursor: zoom-out;
}
.cert-lightbox.open { opacity: 1; }

.cert-lightbox img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 30px 90px rgba(0,0,0,0.7);
  transform: scale(0.96);
  transition: transform 0.32s var(--ease);
  cursor: default;
}
.cert-lightbox.open img { transform: scale(1); }

.cert-lightbox-close {
  position: absolute;
  top: clamp(12px, 2vw, 24px);
  right: clamp(12px, 2vw, 24px);
  width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  color: var(--text);
  cursor: pointer;
  transition: background var(--tf), transform var(--tf);
}
.cert-lightbox-close:hover { background: rgba(255,255,255,0.14); transform: rotate(90deg); }

.cert-lightbox-caption {
  position: absolute;
  bottom: clamp(12px, 3vw, 28px);
  left: 50%;
  transform: translateX(-50%);
  max-width: min(90%, 620px);
  text-align: center;
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.cert-card-inner { padding: clamp(18px,3vw,26px); display: flex; flex-direction: column; flex: 1; gap: 8px; }
.cert-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.cert-icon-wrap {
  width: 38px; height: 38px; border-radius: 10px;
  background: var(--gold-dim); border: 1px solid rgba(201,169,110,0.2);
  display: flex; align-items: center; justify-content: center;
  color: var(--gold);
}
.cert-icon-wrap .ico { width: 18px; height: 18px; }
.cert-year { font-size: 0.62rem; color: var(--text-dimmer); letter-spacing: 0.07em; }

.cert-card h4 { font-size: clamp(0.88rem,1.7vw,1rem); font-weight: 700; letter-spacing: -0.02em; }
.cert-org { font-size: 0.73rem; color: var(--gold); }
.cert-desc { font-size: 0.78rem; color: var(--text-dim); line-height: 1.68; flex: 1; }

/* ── SCROLL INDICATOR ─────────────────────────────────── */
.scroll-indicator {
  position: fixed; bottom: 32px; left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  opacity: 1;
  transition: opacity 0.6s var(--ease-soft);
  pointer-events: none; user-select: none;
}
.scroll-indicator.hidden { opacity: 0; }

.scroll-text {
  font-size: 0.64rem;
  color: rgba(240,237,232,0.55);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-family: 'DM Mono', monospace;
}

.scroll-chevrons { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.chevron {
  width: 12px; height: 12px;
  border-right: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  transform: rotate(45deg);
  opacity: 0;
  animation: chevron-fall 1.8s var(--ease-soft) infinite;
}
.chevron:nth-child(1) { animation-delay: 0s; }
.chevron:nth-child(2) { animation-delay: 0.18s; }
.chevron:nth-child(3) { animation-delay: 0.36s; }

@keyframes chevron-fall {
  0%   { opacity: 0;   transform: rotate(45deg) translate(-3px,-3px); }
  30%  { opacity: 1; }
  60%  { opacity: 0.6; }
  100% { opacity: 0;   transform: rotate(45deg) translate(3px,3px); }
}

/* ── HEADER SOCIAL BUTTONS ────────────────────────────── */
.header-social-btn {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 15px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 40px;
  font-size: 0.72rem;
  font-family: 'Syne', sans-serif; font-weight: 600;
  color: var(--text-dim);
  transition: background var(--tf), border-color var(--tf), color var(--tf), box-shadow var(--tf), transform var(--tf);
  white-space: nowrap; cursor: pointer;
}
.header-social-btn .ico { opacity: 0.75; transition: opacity var(--tf); }
.header-social-btn:hover {
  background: var(--surface-2);
  border-color: rgba(201,169,110,0.35);
  color: var(--text);
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(201,169,110,0.12);
}
.header-social-btn:hover .ico { opacity: 1; }
.header-social-btn:active { transform: translateY(0) scale(0.97); transition-duration: var(--tp); }

/* AI chat trigger.
   The previous treatment ran an infinite glow plus a repeating
   sparkle sweep. Perpetual decorative motion competes with the
   content and is the loudest "template" tell on the page — the
   sweep now fires once on load and again on intent (hover or
   focus), which is when it actually communicates something. */
.header-ai-btn {
  position: relative;
  overflow: hidden;
  border-color: rgba(201,169,110,0.4);
  background: rgba(201,169,110,0.08);
  color: var(--gold);
  box-shadow: 0 0 0 0 rgba(201,169,110,0);
}
.header-ai-btn .ico { color: var(--gold); opacity: 1; }
.header-ai-btn::before {
  content: '';
  position: absolute; top: 0; left: -120%;
  width: 55%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.28), transparent);
  transform: skewX(-22deg);
  pointer-events: none;
}
.header-ai-btn.intro::before { animation: ai-sweep 1.1s var(--ease-soft) 1; }
.header-ai-btn:hover::before,
.header-ai-btn:focus-visible::before { animation: ai-sweep 0.85s var(--ease-soft) 1; }

@keyframes ai-sweep {
  from { left: -120%; }
  to   { left: 220%; }
}

.header-ai-btn:hover {
  background: rgba(201,169,110,0.16);
  border-color: var(--gold);
  color: var(--accent);
  box-shadow: 0 4px 22px rgba(201,169,110,0.28);
}
.header-ai-btn.active {
  background: rgba(201,169,110,0.16);
  border-color: rgba(201,169,110,0.6);
  color: var(--gold);
}
.header-ai-btn.active::before { display: none; }

@media (max-width: 560px) {
  .header-social-btn span { display: none; }
  .header-social-btn { padding: 9px 11px; }
  .header-center { display: none; }
  /* The glass pills carry text labels too — drop to icon-only or the
     row runs past the edge on a 320px screen. */
  .header-socials .lq-btn .lq-btn__content span { display: none; }
  .header-socials .lq-btn--sm { padding: 0 12px; }
}

/* ── REVEAL ───────────────────────────────────────────── */
.reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ── COLLAB BADGE ─────────────────────────────────────── */
.project-collab-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px;
  background: rgba(120,160,255,0.08);
  border: 1px solid rgba(120,160,255,0.22);
  border-radius: 20px;
  font-size: 0.62rem; font-family: 'DM Mono', monospace;
  color: #a0b8ff; letter-spacing: 0.05em;
  margin-bottom: 10px;
}

/* ── AI CHAT WIDGET ───────────────────────────────────── */
.ai-chat-backdrop {
  position: fixed; inset: 0;
  background: rgba(8,8,8,0.55);
  backdrop-filter: blur(3px);
  z-index: var(--z-backdrop);
  opacity: 0; visibility: hidden;
  transition: opacity 0.3s var(--ease-soft), visibility 0.3s;
}
.ai-chat-backdrop.visible { opacity: 1; visibility: visible; }

/* The panel scales out of its trigger in the top-right rather
   than materialising from nowhere, so the link between button
   and panel stays obvious. Blur and scale animate together so it
   reads as glass arriving, not a rectangle fading in. */
.ai-chat-panel {
  position: fixed;
  bottom: 24px; right: 24px;
  width: clamp(320px, 90vw, 420px);
  height: clamp(480px, 70vh, 620px);
  z-index: var(--z-panel);
  display: flex; flex-direction: column;
  background: rgba(12,10,8,0.92);
  backdrop-filter: blur(28px) saturate(150%); -webkit-backdrop-filter: blur(28px) saturate(150%);
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 18px;
  box-shadow: 0 32px 80px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.04), inset 0 1px 0 rgba(255,255,255,0.06);
  overflow: hidden;
  opacity: 0; visibility: hidden;
  transform: translateY(14px) scale(0.96);
  transform-origin: top right;
  transition:
    opacity 0.28s var(--ease-soft),
    transform 0.36s var(--ease),
    visibility 0.36s;
}
.ai-chat-panel.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }

.ai-chat-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid rgba(201,169,110,0.12);
  background: rgba(201,169,110,0.04);
  flex-shrink: 0;
}
.ai-chat-header-left { display: flex; align-items: center; gap: 12px; }

.ai-chat-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: linear-gradient(135deg, #c9a96e 0%, #8c6d3f 100%);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1rem; color: #0c0a07;
  flex-shrink: 0;
  box-shadow: 0 0 16px rgba(201,169,110,0.35);
}

.ai-chat-header-info { display: flex; flex-direction: column; gap: 2px; }
.ai-chat-name { font-size: 0.9rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.ai-chat-status { display: flex; align-items: center; gap: 5px; font-size: 0.62rem; color: var(--text-dimmer); letter-spacing: 0.05em; }
.ai-status-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #4caf7d;
  box-shadow: 0 0 6px rgba(76,175,125,0.7);
  animation: status-pulse 2.8s var(--ease-soft) infinite;
}
@keyframes status-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } }

.ai-chat-close {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-dim); cursor: pointer;
  transition: background var(--tf), color var(--tf), border-color var(--tf), transform var(--tf);
  flex-shrink: 0;
}
.ai-chat-close:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-2); transform: rotate(90deg); }

.ai-chat-messages {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 18px 16px;
  display: flex; flex-direction: column; gap: 12px;
  scroll-behavior: smooth;
}
.ai-chat-messages::-webkit-scrollbar { width: 3px; }
.ai-chat-messages::-webkit-scrollbar-track { background: transparent; }
.ai-chat-messages::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 3px; }

.ai-msg { display: flex; animation: msg-in 0.3s var(--ease-out) both; }
.ai-msg--user { justify-content: flex-end; }
.ai-msg--bot  { justify-content: flex-start; }
@keyframes msg-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.ai-msg-bubble { max-width: 80%; padding: 10px 14px; border-radius: 14px; font-size: 0.83rem; line-height: 1.6; }
.ai-msg--user .ai-msg-bubble {
  background: rgba(201,169,110,0.14);
  border: 1px solid rgba(201,169,110,0.25);
  color: var(--text);
  border-bottom-right-radius: 4px;
}
.ai-msg--bot .ai-msg-bubble {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-bottom-left-radius: 4px;
}

.ai-typing-indicator { display: flex; align-items: center; gap: 4px; padding: 12px 14px; }
.ai-typing-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold); opacity: 0.5;
  animation: typing-bounce 1.2s var(--ease-soft) infinite;
}
.ai-typing-dot:nth-child(2) { animation-delay: 0.18s; }
.ai-typing-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-6px); opacity: 1; }
}

.ai-chat-form {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px;
  border-top: 1px solid rgba(255,255,255,0.06);
  background: rgba(8,8,8,0.4);
  flex-shrink: 0;
}
.ai-chat-input {
  flex: 1;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 40px; padding: 11px 16px;
  color: var(--text);
  font-family: 'Syne', sans-serif; font-size: 1rem;
  outline: none;
  transition: border-color var(--tf), background var(--tf);
}
.ai-chat-input::placeholder { color: var(--text-dimmer); }
.ai-chat-input:focus { border-color: rgba(201,169,110,0.4); background: var(--surface-2); }
.ai-chat-send {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex-shrink: 0;
  background: var(--gold); border: none; border-radius: 50%;
  color: #0c0a07; cursor: pointer;
  transition: background var(--tf), transform var(--tf), box-shadow var(--tf);
}
.ai-chat-send:hover { background: var(--accent); transform: scale(1.07); box-shadow: 0 4px 16px rgba(201,169,110,0.35); }
.ai-chat-send:active { transform: scale(0.95); transition-duration: var(--tp); }
.ai-chat-send:disabled { background: var(--surface-2); color: var(--text-dimmer); cursor: not-allowed; transform: none; box-shadow: none; }

@media (max-width: 500px) {
  .ai-chat-panel {
    bottom: 0; right: 0; left: 0;
    width: 100%; height: 85dvh;
    border-radius: 20px 20px 0 0;
    transform-origin: bottom center;
  }
}

/* ── RESPONSIVE ───────────────────────────────────────── */
@media (max-width: 820px) {
  .home-main {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding-top: clamp(36px,8vw,60px);
    padding-bottom: clamp(36px,8vw,60px);
    min-height: auto;
    gap: clamp(36px,8vw,56px);
  }
  .name-title { font-size: clamp(2.4rem, 12vw, 5rem); }
  .vertical-nav { width: 100%; }
  .contact-grid { grid-template-columns: 1fr; }
  .edu-card { flex-direction: column; gap: 12px; }
  .edu-card-left { flex-direction: row; align-items: center; gap: 10px; }
  .edu-year-block { flex-direction: row; }
  .edu-year-line { width: 20px; height: 1px; }
  .home-footer { flex-direction: column; align-items: flex-start; }
  /* Below this width the layout stacks, so the contact section sits
     inside the first viewport and the fixed cue lands on top of it.
     Scrolling is the default expectation on touch anyway. */
  .scroll-indicator { display: none; }
}

/* Below this the note cannot sit beside the button, so it drops underneath
   and the arrow swings up to keep pointing at it. */
@media (max-width: 660px) {
  .hero-cta-wrap { flex-direction: column; align-items: flex-start; gap: 8px; }
  /* The arrow is drawn pointing left and slightly down (about 165°). With the
     note stacked underneath, it has to point back up at the button, so it is
     rotated the 105° that lands its head at straight up. */
  .hero-cta-arrow { width: 46px; transform: rotate(105deg); margin-left: 6px; }
  /* The nudge translates on the same property as the rotation, so it is
     dropped here rather than fighting it. */
  .hero-cta-wrap.entered .hero-cta-arrow { animation: none; }
  .hero-cta-wrap:hover .hero-cta-arrow { transform: rotate(105deg) translateX(-3px); }
}

@media (max-width: 540px) {
  /* "Nishchay" sets ~7.1em wide in Syne 800 and never wraps, so the
     viewport coefficient has to leave room for the page gutters —
     14vw overflowed a 375px screen by ~36px. */
  .name-title { font-size: clamp(2rem, 11vw, 3.4rem); }
  .cert-grid { grid-template-columns: 1fr 1fr; }
  .sub-footer { flex-direction: column; }
}

@media (max-width: 380px) {
  .cert-grid { grid-template-columns: 1fr; }
  .projects-grid { grid-template-columns: 1fr; }
}

/* ── SCROLLBAR ───────────────────────────────────────── */
::-webkit-scrollbar { width: 3px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 3px; }
::selection { background: rgba(201,169,110,0.22); color: var(--text); }

/* ── REDUCED MOTION ───────────────────────────────────────
   Not "no feedback" — the same states, reached by cross-fade
   instead of travel. Ambient loops stop entirely; they carry no
   information and are the parts that actually cause discomfort. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.16s !important;
    scroll-behavior: auto !important;
  }

  .bg-orb, .chevron, .ai-status-dot, .loader-name, .header-ai-btn::before {
    animation: none !important;
  }

  .page, .page.enter, .page.enter-back, .page.exit, .page.exit-back,
  .reveal, .reveal.visible,
  .name-label, .name-title, .name-tagline, .hero-cta-wrap, .nav-btn,
  .name-label.entered, .name-title.entered, .name-tagline.entered,
  .hero-cta-wrap.entered, .nav-btn.entered {
    transform: none !important;
  }

  .magnetic { transform: none !important; }
  .project-card:hover, .cert-card:hover, .header-social-btn:hover { transform: none !important; }
  .cursor-glow { display: none !important; }
  .reveal { opacity: 1 !important; }
}

/* ── REDUCED TRANSPARENCY ────────────────────────────── */
@media (prefers-reduced-transparency: reduce) {
  .home-header, .sub-header {
    background: #0c0c0c;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    border-bottom-color: var(--border-2);
  }
  .ai-chat-panel {
    background: #101010;
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .ai-chat-backdrop { backdrop-filter: none; background: rgba(0,0,0,0.8); }
  .bg-canvas { display: none; }
}

/* ── HIGH CONTRAST ───────────────────────────────────── */
@media (prefers-contrast: more) {
  :root {
    --border:   rgba(255,255,255,0.28);
    --border-2: rgba(255,255,255,0.45);
    --text-dim: rgba(240,237,232,0.78);
    --text-dimmer: rgba(240,237,232,0.6);
  }
  .bg-canvas { opacity: 0.3; }
}

/* ── PRINT ───────────────────────────────────────────── */
@media print {
  .bg-canvas, .cursor-glow, #loader, .scroll-indicator,
  .ai-chat-panel, .ai-chat-backdrop, .home-header, .sub-header {
    display: none !important;
  }
  .page { position: static !important; opacity: 1 !important; visibility: visible !important; overflow: visible !important; }
  body { background: #fff; color: #000; }
}
