/* =========================================================
   Debajyoti Deb — portfolio stylesheet
   Dark-first design system that also holds up fully in light.
   Theme switches via [data-theme] on <html>.
   ========================================================= */

/* ---------------------------------------------------------
   1. Tokens
   --------------------------------------------------------- */
:root {
  /* Light theme — warm paper */
  --bg:        #fbfaf7;
  --bg-2:      #f2f1ec;
  --panel:     rgba(16, 24, 20, 0.035);
  --panel-2:   rgba(16, 24, 20, 0.06);
  --line:      rgba(16, 30, 24, 0.11);
  --line-2:    rgba(16, 30, 24, 0.2);

  --ink:       #12160f;      /* 17.5:1 on --bg */
  --ink-2:     rgba(18, 22, 15, 0.72);  /* 7.2:1  */
  --ink-3:     rgba(18, 22, 15, 0.62);  /* 4.9:1 — keeps small labels AA-legible */

  --accent:      #0c7d55;   /* emerald — the field's colour · 4.9:1 */
  --accent-2:    #0a6444;
  --accent-tint: rgba(12, 125, 85, 0.12);
  --on-accent:   #ffffff;   /* 5.2:1 on --accent */

  --ember:      #9a5410;    /* Journal's warm counterpoint · 5.3:1 */
  --ember-2:    #7d4409;
  --ember-tint: rgba(154, 84, 16, 0.12);

  --shadow-lift: 0 24px 50px -28px rgba(12, 40, 28, 0.45);

  /* Non-colour tokens (shared) */
  --disp: "Newsreader", Georgia, "Iowan Old Style", serif;
  --body: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --r:    20px;
  --r-sm: 12px;
  --max:  1180px;
}

:root[data-theme="dark"] {
  --bg:        #0b0d10;
  --bg-2:      #11151a;
  --panel:     rgba(255, 255, 255, 0.04);
  --panel-2:   rgba(255, 255, 255, 0.07);
  --line:      rgba(228, 248, 238, 0.1);
  --line-2:    rgba(228, 248, 238, 0.19);

  --ink:       #f2f5f3;
  --ink-2:     rgba(242, 245, 243, 0.7);
  --ink-3:     rgba(242, 245, 243, 0.5);   /* 5.0:1 — AA for small labels */

  --accent:      #2fd396;
  --accent-2:    #5ee7b5;
  --accent-tint: rgba(47, 211, 150, 0.14);
  --on-accent:   #04231a;

  --ember:      #f0a94a;
  --ember-2:    #ffc47a;
  --ember-tint: rgba(240, 169, 74, 0.14);

  --shadow-lift: 0 30px 60px -30px rgba(0, 0, 0, 0.9);
}

/* Safety net for first paint before the inline head script runs */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --bg: #0b0d10; --bg-2: #11151a;
    --panel: rgba(255,255,255,.04); --panel-2: rgba(255,255,255,.07);
    --line: rgba(228,248,238,.10); --line-2: rgba(228,248,238,.19);
    --ink: #f2f5f3; --ink-2: rgba(242,245,243,.70); --ink-3: rgba(242,245,243,.50);
    --accent: #2fd396; --accent-2: #5ee7b5; --accent-tint: rgba(47,211,150,.14);
    --on-accent: #04231a;
    --ember: #f0a94a; --ember-2: #ffc47a; --ember-tint: rgba(240,169,74,.14);
    --shadow-lift: 0 30px 60px -30px rgba(0,0,0,.9);
  }
}

/* ---------------------------------------------------------
   2. Base
   --------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  color-scheme: light dark;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16.5px;
  line-height: 1.65;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background 0.35s var(--ease), color 0.35s var(--ease);
}

img { max-width: 100%; display: block; }

h1, h2, h3, h4 {
  margin: 0 0 0.5em;
  line-height: 1.08;
  letter-spacing: -0.025em;
  font-weight: 600;
}
h1 { font-family: var(--disp); font-size: clamp(2.6rem, 6.5vw, 4.6rem); font-weight: 400; }
h2 { font-family: var(--disp); font-size: clamp(1.9rem, 4vw, 3rem); font-weight: 400; }
h3 { font-size: clamp(1.1rem, 2vw, 1.35rem); font-weight: 700; letter-spacing: -0.015em; }

p { margin: 0 0 1.1em; color: var(--ink-2); }
strong { color: var(--ink); font-weight: 600; }

a { color: var(--accent); text-decoration: none; transition: color 0.25s var(--ease); }
a:hover { color: var(--accent-2); }

::selection { background: var(--accent); color: var(--on-accent); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

.muted { color: var(--ink-2); }
.dim   { color: var(--ink-3); }

.container { max-width: var(--max); margin: 0 auto; padding: 0 1.5rem; }
.narrow    { max-width: 760px; }

/* Vertical padding only. These classes are routinely combined with .container
   on the SAME element (e.g. `class="section container"`), and a
   `padding: <vertical> 0` shorthand silently wipes out the container's side
   gutters — leaving text flush against the screen edge on mobile. */
.section {
  padding-top: clamp(3.5rem, 9vw, 7rem);
  padding-bottom: clamp(3.5rem, 9vw, 7rem);
}
.section-alt { background: var(--bg-2); }

/* Single-page site: keep anchored sections clear of the sticky header when
   jumped to, and give the CV sub-headings their own scale. */
section[id] { scroll-margin-top: 78px; }
.cv-h {
  font-size: clamp(1.1rem, 2vw, 1.3rem);
  font-family: var(--body);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding-bottom: 0.6rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}

/* Kicker — small uppercase label above a heading */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 1rem;
}
.kicker::before {
  content: "";
  width: 22px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}

.lede {
  font-size: clamp(1.02rem, 1.7vw, 1.2rem);
  color: var(--ink-2);
  max-width: 58ch;
}

/* ---------------------------------------------------------
   3. Custom cursor  (the ring that trails and swells)
   --------------------------------------------------------- */
#cursor-dot, #cursor-ring {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  z-index: 9998;
  transform: translate3d(-50%, -50%, 0);
  will-change: transform;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
body.cursor-live #cursor-dot,
body.cursor-live #cursor-ring { opacity: 1; }

#cursor-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  z-index: 9999;
  transition: opacity 0.3s var(--ease), width 0.3s var(--ease), height 0.3s var(--ease);
}

/* The ring is painted in a FIXED near-white and composited with
   `difference`, so it inverts whatever sits beneath it rather than
   painting a colour of its own. That single constant reads correctly
   in both themes — against the light page it resolves to near-black,
   against the dark page to near-white — and over a coloured button it
   flips to that colour's opposite. Do not swap it per theme: a
   theme-flipped value cancels itself out and the ring disappears. */
#cursor-ring {
  width: 26px; height: 26px;
  border-radius: 50%;
  border: 1.5px solid rgba(246, 243, 242, 0.75);
  opacity: 0;
  mix-blend-mode: difference;
  transition:
    width 0.4s var(--ease),
    height 0.4s var(--ease),
    background 0.35s var(--ease),
    border-color 0.35s var(--ease),
    opacity 0.3s var(--ease);
}
body.cursor-live #cursor-ring { opacity: 1; }

/* Swollen state over interactive things — the "magnify" moment.
   Keeps the difference blend so the blob inverts the button under it. */
body.cursor-live #cursor-ring.grow {
  width: 62px; height: 62px;
  background: rgba(246, 243, 242, 0.92);
  border-color: transparent;
}
body.cursor-live #cursor-dot.hide { opacity: 0; }

/* Hide entirely on touch / narrow / reduced-motion */
@media (max-width: 1024px), (pointer: coarse) {
  #cursor-dot, #cursor-ring { display: none !important; }
}

/* ---------------------------------------------------------
   3a. Ambient scroll gradient
   A fixed layer of soft radial washes sitting behind all content.
   motion.js writes --sp (scroll progress, 0..1) onto <html>, and the
   blobs drift and cross-fade against it, so the page changes colour
   as you move down. Pointer-events off; purely decorative.
   --------------------------------------------------------- */
#ambient {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}
#ambient span {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(70px);
  will-change: transform, opacity;
  transition: transform 0.6s linear, opacity 0.6s linear;
}
/* emerald — leads at the top of the page */
#ambient .a1 {
  width: 60vw; height: 60vw;
  max-width: 780px; max-height: 780px;
  top: -12%; right: -8%;
  background: radial-gradient(circle, var(--accent) 0%, transparent 68%);
  opacity: calc(0.20 - (var(--sp, 0) * 0.10));
  transform: translate3d(0, calc(var(--sp, 0) * 34vh), 0);
}
/* ember — rises through the middle */
#ambient .a2 {
  width: 55vw; height: 55vw;
  max-width: 700px; max-height: 700px;
  top: 32%; left: -14%;
  background: radial-gradient(circle, var(--ember) 0%, transparent 68%);
  opacity: calc(0.05 + (var(--sp, 0) * 0.16));
  transform: translate3d(calc(var(--sp, 0) * 16vw), calc(var(--sp, 0) * -26vh), 0);
}
/* deep accent — arrives towards the bottom */
#ambient .a3 {
  width: 50vw; height: 50vw;
  max-width: 640px; max-height: 640px;
  bottom: -18%; right: 18%;
  background: radial-gradient(circle, var(--accent-2) 0%, transparent 70%);
  opacity: calc(0.04 + (var(--sp, 0) * 0.13));
  transform: translate3d(calc(var(--sp, 0) * -20vw), calc(var(--sp, 0) * -18vh), 0);
}
/* Light mode needs a lighter touch — the washes read much stronger on paper. */
:root:not([data-theme="dark"]) #ambient span { filter: blur(85px); }
:root:not([data-theme="dark"]) #ambient .a1 { opacity: calc(0.13 - (var(--sp, 0) * 0.06)); }
:root:not([data-theme="dark"]) #ambient .a2 { opacity: calc(0.03 + (var(--sp, 0) * 0.10)); }
:root:not([data-theme="dark"]) #ambient .a3 { opacity: calc(0.03 + (var(--sp, 0) * 0.08)); }

@media (prefers-reduced-motion: reduce) {
  #ambient span { transition: none; transform: none !important; }
}

/* ---------------------------------------------------------
   3b. Loading curtain
   Sits in the HTML (not injected) so there is no flash of
   unstyled page. JS lifts it on load; the CSS animation below
   is a safety net that dismisses it even if JS never runs, so
   a script failure can never trap a visitor behind it.
   --------------------------------------------------------- */
#curtain {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1.5rem;
  background: var(--bg);
  animation: curtainSafety 0s linear 4.5s forwards;
}
#curtain.lift {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.55s var(--ease), visibility 0s linear 0.55s;
}
@keyframes curtainSafety {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}

.curtain-inner {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}
.curtain-avatar {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--panel-2);
  flex: none;
}
/* Uses the pre-cropped circular icon, so no CSS zoom is needed here. */
.curtain-avatar img { width: 100%; height: 100%; object-fit: cover; }

.curtain-name {
  font-size: 1.35rem;
  letter-spacing: -0.02em;
  color: var(--ink-3);
  white-space: nowrap;
}
.curtain-name strong { color: var(--ink); font-weight: 700; }

.curtain-bar {
  width: min(240px, 60vw);
  height: 2px;
  border-radius: 2px;
  background: var(--line-2);
  overflow: hidden;
}
.curtain-bar i {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  animation: curtainFill 1.15s var(--ease) forwards;
}
@keyframes curtainFill {
  0%   { transform: scaleX(0); }
  65%  { transform: scaleX(0.7); }
  100% { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  #curtain { display: none; }
}

/* ---------------------------------------------------------
   4. Scroll progress
   --------------------------------------------------------- */
#progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  z-index: 9990;
  will-change: transform;
}

/* ---------------------------------------------------------
   5. Header / nav
   --------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 900;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.35s var(--ease), background 0.35s var(--ease);
}
.site-header.stuck { border-bottom-color: var(--line); }

.nav {
  max-width: var(--max);
  margin: 0 auto;
  padding: 1rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* Brand: circular thumbnail + name. Both shrink slightly once scrolled,
   so the header tightens up as you move down the page. */
.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink);
  white-space: nowrap;
  line-height: 1;
}
.nav-brand:hover { text-decoration: none; }

.brand-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  overflow: hidden;
  flex: none;
  background: var(--panel-2);
  border: 1px solid var(--line);
  transition: width 0.35s var(--ease), height 0.35s var(--ease);
}
.brand-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.brand-name {
  font-size: 1.08rem;
  letter-spacing: -0.015em;
  color: var(--ink-3);
  transition: font-size 0.35s var(--ease);
}
.brand-name strong { color: var(--ink); font-weight: 700; }
.nav-brand:hover .brand-name strong { color: var(--accent); }

.site-header.stuck .brand-avatar { width: 30px; height: 30px; }
.site-header.stuck .brand-name { font-size: 0.97rem; }

.nav-links {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-links a {
  position: relative;
  display: block;
  padding: 0.5rem 0.85rem;
  border-radius: 999px;
  color: var(--ink-2);
  font-size: 0.9rem;
  font-weight: 500;
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.nav-links a:hover { color: var(--ink); background: var(--panel); }
.nav-links a.active { color: var(--accent); }
.nav-links a.active::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 2px;
  width: 4px; height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: currentColor;
}
.nav-links .journal-link { color: var(--ember); }
.nav-links .journal-link:hover { color: var(--ember-2); background: var(--ember-tint); }

.nav-right { display: flex; align-items: center; gap: 0.6rem; }

.theme-toggle {
  width: 40px; height: 40px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
  font-size: 0;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease), transform 0.3s var(--ease);
}
.theme-toggle:hover { border-color: var(--line-2); background: var(--panel-2); transform: translateY(-2px); }
.theme-toggle svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.theme-toggle .i-sun  { display: none; }
:root[data-theme="dark"] .theme-toggle .i-sun  { display: block; }
:root[data-theme="dark"] .theme-toggle .i-moon { display: none; }

.nav-toggle {
  display: none;
  width: 42px; height: 42px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--panel);
  cursor: pointer;
  padding: 0;
  place-items: center;
}
.nav-toggle i {
  display: block;
  width: 18px; height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  position: relative;
  transition: background 0.2s var(--ease);
}
.nav-toggle i::before, .nav-toggle i::after {
  content: "";
  position: absolute; left: 0;
  width: 18px; height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.35s var(--ease);
}
.nav-toggle i::before { top: -6px; }
.nav-toggle i::after  { top: 6px; }
.nav-toggle[aria-expanded="true"] i { background: transparent; }
.nav-toggle[aria-expanded="true"] i::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] i::after  { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav-toggle { display: grid; }
  .nav-links {
    position: fixed;
    inset: 0 0 auto 0;
    top: 68px;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0 1rem;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.45s var(--ease), padding 0.45s var(--ease);
  }
  .nav-links.open { max-height: 70vh; padding: 0.75rem 1rem 1.25rem; }
  .nav-links a { padding: 0.9rem 1rem; font-size: 1rem; border-radius: var(--r-sm); }
}

/* ---------------------------------------------------------
   6. Buttons
   --------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55em;
  padding: 0.85em 1.6em;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.94rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease),
              background 0.3s var(--ease), border-color 0.3s var(--ease), color 0.3s var(--ease);
}
/* sheen sweep */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255,255,255,0.28) 50%, transparent 80%);
  transform: translateX(-120%);
  transition: transform 0.75s var(--ease);
}
.btn:hover::before { transform: translateX(120%); }

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
}
.btn-primary:hover {
  color: var(--on-accent);
  transform: translateY(-3px);
  box-shadow: 0 18px 42px -14px var(--accent);
}
.btn-ghost {
  background: var(--panel);
  color: var(--ink);
  border-color: var(--line);
}
.btn-ghost:hover {
  color: var(--ink);
  background: var(--panel-2);
  border-color: var(--line-2);
  transform: translateY(-3px);
}
.btn-sm { padding: 0.6em 1.15em; font-size: 0.85rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 2rem; }

/* Arrow link */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-weight: 600;
  font-size: 0.92rem;
}
.arrow-link span { transition: transform 0.35s var(--ease); }
.arrow-link:hover span { transform: translateX(5px); }

/* ---------------------------------------------------------
   7. Hero
   --------------------------------------------------------- */
.hero {
  position: relative;
  /* vertical only — see .section above */
  padding-top: clamp(3rem, 8vw, 6.5rem);
  padding-bottom: clamp(3rem, 7vw, 5.5rem);
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 2.5rem; }
  .hero-portrait { order: -1; justify-self: center; }
}

/* soft accent glow behind the hero */
.hero::before {
  content: "";
  position: absolute;
  top: -10%; left: 45%;
  width: 60vw; height: 60vw;
  max-width: 720px; max-height: 720px;
  background: radial-gradient(circle, var(--accent-tint), transparent 62%);
  filter: blur(30px);
  pointer-events: none;
  z-index: -1;
}

.hero h1 { margin-bottom: 1.2rem; }
.hero h1 em {
  font-style: italic;
  color: var(--accent);
}

.hero-portrait {
  position: relative;
  width: min(340px, 78vw);
  aspect-ratio: 4 / 5;
  border-radius: calc(var(--r) + 6px);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--shadow-lift);
  transform-style: preserve-3d;
  transition: transform 0.5s var(--ease);
}
.hero-portrait img {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(1.06);
  filter: saturate(0.96) contrast(1.03);
  transition: transform 1.3s var(--ease), filter 0.7s var(--ease);
}
.hero-portrait:hover img { transform: scale(1.13); filter: saturate(1.05) contrast(1.06); }

/* duotone wash so any photo sits in the palette */
.hero-portrait::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  mix-blend-mode: soft-light;
  background: linear-gradient(150deg, var(--accent) 0%, transparent 48%, var(--ember) 100%);
  opacity: 0.5;
}

/* availability chip */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.4em 0.95em;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: 1.5rem;
}
.chip .pulse {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-tint); }
  70%  { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ---------------------------------------------------------
   8. Cards + light-follow glow  (the "magnification" family)
   --------------------------------------------------------- */
.grid { display: grid; gap: 1.4rem; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 680px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }

/* Two-column content + sidebar that collapses cleanly */
.split {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.split .sticky-side { position: sticky; top: 6rem; }
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  .split .sticky-side { position: static; }
}

.card {
  position: relative;
  padding: 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
  overflow: hidden;
  transition: transform 0.5s var(--ease), border-color 0.4s var(--ease),
              background 0.4s var(--ease), box-shadow 0.5s var(--ease);
}
/* pointer-following highlight, driven by --mx/--my from JS */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%), var(--accent-tint), transparent 65%);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}
.card:hover::before { opacity: 1; }
.card:hover {
  transform: translateY(-6px);
  border-color: var(--line-2);
  background: var(--panel-2);
  box-shadow: var(--shadow-lift);
}
.card > * { position: relative; z-index: 1; }

.card-num {
  font-family: var(--disp);
  font-size: 0.95rem;
  color: var(--accent);
  letter-spacing: 0.04em;
  margin-bottom: 0.9rem;
  display: block;
}

.tag {
  display: inline-block;
  padding: 0.3em 0.8em;
  border-radius: 999px;
  background: var(--accent-tint);
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

/* ---------------------------------------------------------
   9. Stats
   --------------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}
.stat {
  background: var(--bg);
  padding: 1.75rem 1.4rem;
  transition: background 0.4s var(--ease);
}
.stat:hover { background: var(--panel); }
.stat-num {
  font-family: var(--disp);
  font-size: clamp(1.9rem, 4vw, 2.7rem);
  line-height: 1;
  color: var(--ink);
  margin-bottom: 0.35rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
}
.stat-label {
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: var(--ink-3);
  font-weight: 600;
}
/* Institution marks. Sized by height so the two logos sit on a common
   baseline despite different aspect ratios. */
.stat-logo {
  height: 38px;
  width: auto;
  max-width: 92px;
  object-fit: contain;
  flex: none;
}
/* Crest-style marks (BUET) carry more detail than a wordmark, so they need
   more height to stay legible. */
.stat-logo-lg { height: 54px; max-width: 60px; }
/* Institution name set smaller than the stat figures, so the logo leads. */
.stat-word { font-size: 0.66em; letter-spacing: -0.01em; }
/* On dark backgrounds render the LSU wordmark in solid white — that is the
   brand-approved reversed treatment. A plain invert() would shift its purple
   to a colour LSU does not use. Light mode keeps the original purple. */
:root[data-theme="dark"] .stat-logo.invertible { filter: brightness(0) invert(1); }
/* On phones the three cards fall into a 2x2 grid and leave a dead cell in the
   corner. Give the last card (LSU) the full width and centre its contents so
   the block reads as finished. Above 500px all three fit on one row; below
   350px they already stack one per row — so this only applies in between. */
@media (min-width: 350px) and (max-width: 499px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat:last-child { grid-column: 1 / -1; }
  .stat:last-child .stat-num { justify-content: center; }
  .stat:last-child .stat-label { text-align: center; }
}

/* ---------------------------------------------------------
   10. Publications
   --------------------------------------------------------- */
.pub {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.5rem;
  padding: 1.6rem 1.2rem;
  border-radius: var(--r-sm);
  border-bottom: 1px solid var(--line);
  transition: background 0.4s var(--ease), transform 0.4s var(--ease);
}
.pub:last-child { border-bottom: none; }
.pub:hover { background: var(--panel); transform: translateX(5px); }
.pub-index {
  font-family: var(--disp);
  font-size: 0.9rem;
  color: var(--accent);
  padding-top: 0.25rem;
}
.pub-title { font-weight: 600; font-size: 1.05rem; color: var(--ink); margin-bottom: 0.3rem; line-height: 1.35; }
.pub-meta  { font-size: 0.9rem; color: var(--ink-3); margin-bottom: 0.6rem; }
.pub-links { display: flex; gap: 1.1rem; flex-wrap: wrap; }
.pub-links a { font-size: 0.85rem; font-weight: 600; }
@media (max-width: 600px) {
  .pub { grid-template-columns: 1fr; gap: 0.5rem; padding: 1.4rem 0.6rem; }
}

/* ---------------------------------------------------------
   11. Gallery
   --------------------------------------------------------- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 1.4rem;
}
.embed-slot {
  border-radius: var(--r);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--panel);
  transition: transform 0.5s var(--ease), border-color 0.4s var(--ease), box-shadow 0.5s var(--ease);
}
.embed-slot:hover {
  transform: translateY(-5px);
  border-color: var(--line-2);
  box-shadow: var(--shadow-lift);
}
/* Section header for each gallery platform */
.gallery-section { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.gallery-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-bottom: 0.9rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}
/* h3 on the single-page site; h2 kept so either level styles the same.
   Deliberately NOT uppercased — brand names are set the way each brand
   writes them (Instagram, Facebook, LinkedIn). */
.gallery-head h2,
.gallery-head h3 {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--body);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
}
/* No fill here — the glyphs carry their own brand colours. */
.gallery-head h2 svg,
.gallery-head h3 svg { width: 20px; height: 20px; flex: none; }
.gallery-head .handle { font-size: 0.9rem; color: var(--ink-3); }

/* A photo the site hosts itself (from assets/img/gallery/) */
.photo-card {
  margin: 0;
  border-radius: var(--r);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--panel);
  transition: transform 0.5s var(--ease), border-color 0.4s var(--ease),
              box-shadow 0.5s var(--ease);
}
.photo-card img {
  width: 100%;
  height: 270px;
  object-fit: cover;
  display: block;
  transition: transform 1.1s var(--ease);
}
.photo-card:hover {
  transform: translateY(-5px);
  border-color: var(--line-2);
  box-shadow: var(--shadow-lift);
}
.photo-card:hover img { transform: scale(1.05); }
.photo-card figcaption {
  padding: 0.85rem 1rem;
  font-size: 0.88rem;
  color: var(--ink-2);
  border-top: 1px solid var(--line);
}

/* The three profile cards, side by side */
.profile-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
}
@media (max-width: 820px) { .profile-row { grid-template-columns: 1fr; } }

/* Profile card linking out to one network */
.gallery-link-card {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  gap: 0.75rem;
  text-align: center;
  padding: 2.25rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
  color: var(--ink-2);
  transition: border-color 0.35s var(--ease), background 0.35s var(--ease),
              transform 0.45s var(--ease), box-shadow 0.45s var(--ease);
}
.gallery-link-card:hover { box-shadow: var(--shadow-lift); }
.gallery-link-card:hover {
  text-decoration: none;
  color: var(--ink-2);
  border-color: var(--accent);
  background: var(--panel-2);
  transform: translateY(-4px);
}
.gallery-link-card strong { color: var(--ink); font-size: 1rem; }
.gallery-link-card span { font-size: 0.88rem; color: var(--ink-3); }
.gallery-link-card .glc-handle {
  font-size: 0.86rem;
  color: var(--accent);
  font-weight: 600;
  margin-top: -0.5rem;
}

/* Profile photo with the platform's mark badged onto it */
.glc-avatar {
  position: relative;
  width: 72px;
  height: 72px;
  flex: none;
  margin-bottom: 0.2rem;
}
.glc-avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--line-2);
  transition: border-color 0.35s var(--ease);
}
.gallery-link-card:hover .glc-avatar img { border-color: var(--accent); }

.glc-badge {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--bg);
  border: 2px solid var(--bg);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
}
.glc-badge svg { width: 17px; height: 17px; display: block; }

.embed-placeholder {
  min-height: 280px;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 2rem;
  color: var(--ink-3);
  font-size: 0.9rem;
  line-height: 1.7;
  border: 1.5px dashed var(--line);
  border-radius: var(--r);
  background: var(--panel);
}
.embed-placeholder code {
  color: var(--accent);
  font-size: 0.85em;
  background: var(--accent-tint);
  padding: 0.15em 0.45em;
  border-radius: 5px;
}

/* ---------------------------------------------------------
   11b. CV
   --------------------------------------------------------- */
.cv-section { margin-top: 3rem; }
.cv-section > h2 {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  font-family: var(--body);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding-bottom: 0.6rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}
.cv-entry { margin-bottom: 1.75rem; }
.cv-entry:last-child { margin-bottom: 0; }
.cv-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
}
.cv-role { font-weight: 700; color: var(--ink); }
.cv-when {
  font-size: 0.82rem;
  color: var(--ink-3);
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.cv-where { color: var(--accent); font-size: 0.94rem; font-weight: 600; margin-top: 0.1rem; }
.cv-entry ul { margin: 0.6rem 0 0; padding-left: 1.1rem; }
.cv-entry li { color: var(--ink-2); margin-bottom: 0.35rem; font-size: 0.95rem; }
/* Closing call-to-action at the end of the CV — offered after reading */
.cv-footer-cta {
  margin-top: 3.5rem;
  padding: 2.25rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
  text-align: center;
}

.course-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: 0.5rem 2rem;
}
.course-grid span {
  position: relative;
  padding-left: 1.1rem;
  color: var(--ink-2);
  font-size: 0.94rem;
  line-height: 1.5;
}
.course-grid span::before {
  content: "";
  position: absolute;
  left: 0; top: 0.6em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.cv-skills { display: grid; gap: 0.9rem; }
.cv-skill-row { display: grid; grid-template-columns: 170px 1fr; gap: 1rem; }
@media (max-width: 600px) { .cv-skill-row { grid-template-columns: 1fr; gap: 0.2rem; } }
.cv-skill-label {
  font-size: 0.75rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.09em; color: var(--ink-3); padding-top: 0.15rem;
}

/* ---------------------------------------------------------
   12. Forms
   --------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 0.45rem; margin-bottom: 1.2rem; }
.field label {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-3);
}
.field input, .field textarea {
  padding: 0.85em 1em;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--bg);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.95rem;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease), background 0.3s var(--ease);
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-tint);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-3); }

/* ---------------------------------------------------------
   13. Journal — informal side, ember accent
   --------------------------------------------------------- */
.journal-scope {
  --accent:      var(--ember);
  --accent-2:    var(--ember-2);
  --accent-tint: var(--ember-tint);
  --on-accent:   #ffffff;   /* white on the deep light-mode ember · 5.8:1 */
}
/* Dark-mode ember is a bright amber, so it needs dark text instead. */
:root[data-theme="dark"] .journal-scope { --on-accent: #241505; }

.journal-hero {
  /* vertical only — see .section above */
  padding-top: clamp(3rem, 7vw, 5rem);
  padding-bottom: 2.5rem;
  border-bottom: 1px dashed var(--line);
}
.journal-hero h1 { font-style: italic; }

.post-card {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
  color: inherit;
  position: relative;
  overflow: hidden;
  transition: transform 0.5s var(--ease), border-color 0.4s var(--ease),
              background 0.4s var(--ease), box-shadow 0.5s var(--ease);
}
.post-card::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%), var(--ember-tint), transparent 65%);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}
.post-card:hover::before { opacity: 1; }
.post-card:hover {
  transform: translateY(-6px);
  border-color: var(--line-2);
  background: var(--panel-2);
  box-shadow: var(--shadow-lift);
  color: inherit;
}
.post-card > * { position: relative; z-index: 1; }
.post-card h3 { transition: color 0.3s var(--ease); }
.post-card:hover h3 { color: var(--ember); }

/* Journal section headers */
.journal-section { margin-top: clamp(2.75rem, 6vw, 4rem); }
.journal-section-head {
  padding-bottom: 0.9rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}
.journal-section-head h2 {
  font-family: var(--body);
  font-size: 1.05rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 0.3rem;
}
.journal-section-head p { margin: 0; font-size: 0.9rem; color: var(--ink-3); }
.journal-empty {
  padding: 1.75rem;
  border: 1.5px dashed var(--line);
  border-radius: var(--r);
  color: var(--ink-3);
  font-size: 0.92rem;
}

/* ---- IMDb ratings ---- */
.imdb-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  margin-bottom: 1.75rem;
}
.imdb-stat { background: var(--bg); padding: 1.15rem 1rem; }
.imdb-stat b {
  display: block;
  font-family: var(--disp);
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink);
  margin-bottom: 0.3rem;
  font-variant-numeric: tabular-nums;
}
.imdb-stat span {
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  font-weight: 600;
}

/* Toggle between the top-rated list and the recent list */
.imdb-tabs { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.imdb-tab {
  padding: 0.5em 1.1em;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink-2);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.25s var(--ease), background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.imdb-tab:hover { color: var(--ink); border-color: var(--line-2); }
.imdb-tab[aria-selected="true"] {
  background: var(--accent);
  border-color: transparent;
  color: var(--on-accent);
}

.rating-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0 1.1rem;
  align-items: center;
  padding: 0.85rem 1.1rem;
  border-radius: var(--r-sm);
  border-bottom: 1px solid var(--line);
  color: inherit;
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.rating-row:last-child { border-bottom: none; }
.rating-row:hover {
  background: var(--panel);
  transform: translateX(4px);
  text-decoration: none;
  color: inherit;
}
/* His own score — the headline number on each row */
.rating-mine {
  font-family: var(--disp);
  font-size: 1.45rem;
  line-height: 1;
  width: 2.4ch;
  text-align: right;
  color: var(--ember);
  font-variant-numeric: tabular-nums;
}
.rating-title { font-weight: 600; color: var(--ink); }
.rating-title .yr { color: var(--ink-3); font-weight: 400; margin-left: 0.45rem; font-size: 0.9em; }
.rating-note { font-size: 0.85rem; color: var(--ink-3); margin-top: 0.15rem; }
/* IMDb's own average, kept quiet so his score leads */
.rating-imdb {
  font-size: 0.8rem;
  color: var(--ink-3);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.rating-imdb b { color: var(--ink-2); font-weight: 600; }
@media (max-width: 560px) {
  .rating-row { grid-template-columns: auto 1fr; }
  .rating-imdb { grid-column: 2; margin-top: 0.2rem; }
}

.post-meta {
  font-size: 0.78rem;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-weight: 600;
}

.post-body {
  font-family: var(--disp);
  font-size: 1.16rem;
  line-height: 1.75;
  color: var(--ink-2);
}
.post-body p { margin-bottom: 1.3em; color: inherit; }
.post-body p:first-of-type::first-letter {
  font-size: 3.4em;
  float: left;
  line-height: 0.82;
  padding: 0.06em 0.1em 0 0;
  color: var(--ember);
}

/* ---------------------------------------------------------
   13b. Social icon links
   --------------------------------------------------------- */
.social-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  align-items: center;
}
.social-btn {
  --brand: var(--accent);
  position: relative;
  width: 42px;
  height: 42px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink-2);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease), transform 0.35s var(--ease);
}
.social-btn svg { width: 18px; height: 18px; fill: currentColor; display: block; }
.social-btn:hover {
  color: var(--brand);
  border-color: var(--brand);
  background: var(--panel-2);
  transform: translateY(-3px);
  text-decoration: none;
}
/* Per-network hover colour. Kept subtle — the ring and glyph tint only. */
.social-btn[data-net="linkedin"]  { --brand: #0a66c2; }
.social-btn[data-net="instagram"] { --brand: #d62976; }
.social-btn[data-net="facebook"]  { --brand: #1877f2; }
.social-btn[data-net="scholar"]   { --brand: #4285f4; }
.social-btn[data-net="email"]     { --brand: var(--accent); }
:root[data-theme="dark"] .social-btn[data-net="linkedin"]  { --brand: #4d9fe8; }
:root[data-theme="dark"] .social-btn[data-net="facebook"]  { --brand: #5c9dfa; }
:root[data-theme="dark"] .social-btn[data-net="scholar"]   { --brand: #7aa9f7; }
:root[data-theme="dark"] .social-btn[data-net="instagram"] { --brand: #f56aa4; }

/* Wider labelled variant, used on the Contact page */
.social-btn.labelled {
  width: auto;
  height: auto;
  border-radius: 999px;
  padding: 0.6em 1.15em;
  gap: 0.55em;
  grid-auto-flow: column;
  font-size: 0.88rem;
  font-weight: 600;
}

/* ---------------------------------------------------------
   14. Footer
   --------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 3.5rem 0 2.5rem;
  margin-top: 3rem;
  background: var(--bg-2);
}
.footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 2rem;
}
.footer-brand { font-family: var(--disp); font-size: 1.5rem; margin-bottom: 0.4rem; }
.footer-links { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.footer-links a {
  color: var(--ink-3);
  font-size: 0.88rem;
  font-weight: 500;
  transition: color 0.3s var(--ease), transform 0.3s var(--ease);
  display: inline-block;
}
.footer-links a:hover { color: var(--accent); transform: translateY(-2px); }

/* ---------------------------------------------------------
   15. Reveal on scroll
   --------------------------------------------------------- */
/* Hidden ONLY once motion.js has confirmed it is running (`.js-motion` on
   <html>). Without JS the content just renders — it can never be stranded
   at opacity 0. */
.js-motion [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
  transition-delay: var(--d, 0s);
}
.js-motion [data-reveal].in { opacity: 1; transform: none; }

/* ---------------------------------------------------------
   16. Reduced motion
   --------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .js-motion [data-reveal] { opacity: 1; transform: none; }
  #cursor-dot, #cursor-ring { display: none !important; }
}
