/* ─── RESET & ROOT ─────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* ── Ink / paper theme tokens ──────────────────────────────────
     Default (no [data-theme] attribute) is the "light theme": the site
     alternates sections between a dark ("ink") band — hero, skills,
     licenses, contact — and light ("paper") bands — about, experience,
     projects, certifications. See the [data-theme="dark"] overrides
     further down, which force the light bands dark too instead of just
     inverting which bands are dark vs light — the dark-band sections
     (hero included) are untouched since they're already dark here. */
  --ink: #0a0a0a;
  /* Space-separated (no commas): lets rgb(var(--ink-rgb) / alpha) use the
     modern slash-alpha syntax below. Mixing comma-separated channels with
     a slash alpha is invalid CSS and silently drops the whole declaration. */
  --ink-rgb: 10 10 10;
  --paper: #ffffff;
  --paper-rgb: 255 255 255;
  --paper-warm: #f5f2eb;
  --font-display: 'Bebas Neue', sans-serif;
  --font-body: 'Playfair Display', serif;
}

body {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-body);
  overflow-x: hidden;
  transition: background-color 0.3s ease, color 0.3s ease;
}

/* Theme-swap crossfade: every element that paints with a themed
   token gets a short color transition instead of snapping instantly.
   Scoped to color-related properties only, so it never fights the
   layout/transform transitions used elsewhere (reveals, tilt, etc). */
*,
*::before,
*::after {
  transition: background-color 0.3s ease, color 0.3s ease,
    border-color 0.3s ease, box-shadow 0.3s ease, fill 0.3s ease, stroke 0.3s ease;
}

/* ─── DARK THEME ─────────────────────────────────────────────────
   Toggled state ([data-theme="dark"]): the whole site goes dark, not
   just an inverted band rhythm. Hero, skills, licenses and contact are
   already dark bands in the default theme so they're left alone here —
   only the light-band sections (about, experience, projects,
   certifications) get their ink/paper tokens swapped, and only within
   their own subtree, so --ink/--paper keep their normal meaning
   everywhere else (the always-dark sections still use --ink as a dark
   background and --paper as light text, unchanged). */
[data-theme="dark"] #about,
[data-theme="dark"] #experience,
[data-theme="dark"] #projects,
[data-theme="dark"] #certifications {
  --ink: #f5f2eb;
  --ink-rgb: 245 242 235;
  --paper: #121316;
  --paper-rgb: 18 19 22;
  --paper-warm: #1c1b22;
}

/* The ink dividers between sections are siblings, not descendants, of
   the sections above — they don't inherit the swap, so each one gets
   just the specific token(s) its inline background/SVG fill reference,
   matching whichever neighboring light band it borrows that color from.
   Dividers between two already-dark sections need no override. */
[data-theme="dark"] #hero + .ink-divider,
[data-theme="dark"] #projects + .ink-divider {
  --paper-warm: #1c1b22;
}

[data-theme="dark"] #about + .ink-divider,
[data-theme="dark"] #experience + .ink-divider {
  --paper: #121316;
  --paper-warm: #1c1b22;
}

[data-theme="dark"] #skills + .ink-divider,
[data-theme="dark"] #certifications + .ink-divider {
  --paper: #121316;
}

/* ─── GRAIN TEXTURE ─────────────────────────────────────────────── */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  mix-blend-mode: overlay;
}

/* ─── SCROLL REVEAL ─────────────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(36px);
  transition: opacity 0.75s ease, transform 0.75s ease;
}

.reveal.visible {
  opacity: 1;
  transform: none;
}

/* ─── DOODLE WIGGLE ─────────────────────────────────────────────── */
@keyframes wiggle {
  0% {
    transform: rotate(-2deg) translateY(0);
  }

  50% {
    transform: rotate(1.5deg) translateY(-4px);
  }

  100% {
    transform: rotate(-1deg) translateY(2px);
  }
}

.doodle-wrap {
  animation: wiggle 3.5s ease-in-out infinite alternate;
  display: inline-block;
  transform-origin: bottom center;
}

/* ─── INK DIVIDER ───────────────────────────────────────────────── */
.ink-divider {
  width: 100%;
  overflow: hidden;
  line-height: 0;
}

.ink-divider svg {
  display: block;
  width: 100%;
}

/* ─── SECTION BASE ──────────────────────────────────────────────── */
section {
  position: relative;
  overflow: hidden;
  padding: clamp(4rem, 8vw, 8rem) clamp(1.5rem, 6vw, 7rem);
}

/* ─── GHOST BG TEXT ─────────────────────────────────────────────── */
.ghost-text {
  position: absolute;
  font-family: var(--font-display);
  font-size: clamp(6rem, 18vw, 16rem);
  letter-spacing: -0.02em;
  line-height: 0.85;
  opacity: 0.055;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  z-index: 0;
}

/* ─── SECTION CONTENT WRAPPER ───────────────────────────────────── */
.section-content {
  position: relative;
  z-index: 1;
}

/* ══════════════════════════════════════════════════════════════════
   HERO
══════════════════════════════════════════════════════════════════ */
#hero {
  min-height: 100vh;
  /* Solid, uninterrupted black so it reads as one surface with the
     photo's own black background instead of a bordered panel. */
  background-color: var(--ink);
  padding-top: clamp(5rem, 10vw, 9rem);
  padding-bottom: clamp(3rem, 6vw, 6rem);
}

/* ─── ANIMATED GRADIENT BLOBS ───────────────────────────────────── */
.hero-gradient-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.hero-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.16;
  will-change: transform;
}

.hero-blob-1 {
  width: 42vw;
  height: 42vw;
  max-width: 620px;
  max-height: 620px;
  top: -12%;
  left: -8%;
  background: radial-gradient(circle, var(--paper-warm) 0%, transparent 70%);
  animation: hero-blob-drift-1 24s ease-in-out infinite alternate;
}

.hero-blob-2 {
  width: 34vw;
  height: 34vw;
  max-width: 500px;
  max-height: 500px;
  bottom: -16%;
  right: -6%;
  background: radial-gradient(circle, var(--paper) 0%, transparent 70%);
  animation: hero-blob-drift-2 28s ease-in-out infinite alternate;
}

.hero-blob-3 {
  width: 24vw;
  height: 24vw;
  max-width: 360px;
  max-height: 360px;
  top: 36%;
  left: 52%;
  opacity: 0.12;
  background: radial-gradient(circle, var(--paper-warm) 0%, transparent 70%);
  animation: hero-blob-drift-3 20s ease-in-out infinite alternate;
}

@keyframes hero-blob-drift-1 {
  0% {
    transform: translate(0, 0) scale(1);
  }

  100% {
    transform: translate(6vw, 8vh) scale(1.12);
  }
}

@keyframes hero-blob-drift-2 {
  0% {
    transform: translate(0, 0) scale(1);
  }

  100% {
    transform: translate(-7vw, -6vh) scale(1.1);
  }
}

@keyframes hero-blob-drift-3 {
  0% {
    transform: translate(0, 0) scale(1);
  }

  100% {
    transform: translate(-5vw, 6vh) scale(1.15);
  }
}

.hero-text-col {
  position: relative;
  /* Sits above the image (z-index 1) so the giant name can spill over
     the photo's left edge instead of forcing the image to shrink for it. */
  z-index: 2;
}

.hero-name {
  font-family: var(--font-display);
  color: var(--paper);
  line-height: 0.88;
  letter-spacing: -0.01em;
  display: block;
}

.hero-name-amit {
  font-size: clamp(5rem, 16vw, 14rem);
}

.hero-name-kumar {
  font-size: clamp(5rem, 20vw, 18rem);
  margin-left: clamp(1rem, 3vw, 4rem);
  display: block;
}

/* Per-letter spans injected by js/text-scramble.js while decoding.
   Each letter eases from a soft blur/dim into sharp focus as it locks
   in, so the resolve reads as smooth rather than an instant snap. */
.scramble-char {
  opacity: 0.55;
  filter: blur(2px);
  transition: opacity 0.4s ease, filter 0.4s ease;
}

.scramble-char-locked {
  opacity: 1;
  filter: blur(0);
}

.hero-role {
  font-family: var(--font-body);
  font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.8rem);
  color: var(--paper-warm);
  margin-top: 1rem;
  opacity: 0.85;
  letter-spacing: 0.04em;
}

.hero-sub {
  font-family: var(--font-body);
  font-size: clamp(0.9rem, 1.5vw, 1.15rem);
  color: rgb(var(--paper-rgb) / 0.55);
  margin-top: 1.6rem;
  max-width: 440px;
  line-height: 1.6;
  /* Reserve space for the full two-line tagline so the typewriter effect
     never shifts the CTAs below it as characters are added. */
  min-height: 3.2em;
}

.typewriter-cursor {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  background: var(--paper-warm);
  vertical-align: text-bottom;
  animation: hero-cursor-blink 1s step-end infinite;
}

@keyframes hero-cursor-blink {

  0%,
  50% {
    opacity: 1;
  }

  50.01%,
  100% {
    opacity: 0;
  }
}

/* ─── VISUALLY HIDDEN (screen-reader only) ─────────────────────── */
.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;
}

.hero-ctas {
  display: flex;
  gap: 1rem;
  margin-top: 2.4rem;
  flex-wrap: wrap;
}

.btn {
  position: relative;
  overflow: hidden;
  font-family: var(--font-display);
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  padding: 0.75rem 2rem;
  border: 2.5px solid var(--paper);
  background: transparent;
  color: var(--paper);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: background 0.2s, color 0.2s, box-shadow 0.15s;
  box-shadow: 3px 3px 0 rgb(var(--paper-rgb) / 0.25);
}

.btn:hover {
  background: var(--paper);
  color: var(--ink);
  box-shadow: 5px 5px 0 rgb(var(--paper-rgb) / 0.4);
}

.btn-filled {
  background: var(--paper);
  color: var(--ink);
  box-shadow: 3px 3px 0 rgb(var(--paper-rgb) / 0.5);
}

.btn-filled:hover {
  background: transparent;
  color: var(--paper);
}

.btn-resume {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.btn-resume svg {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  transition: transform 0.2s;
}

.btn-resume:hover svg {
  transform: translateY(2px);
}

/* ─── BUTTON RIPPLE (click feedback) ───────────────────────────── */
.btn-ripple {
  position: absolute;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.4;
  transform: translate(-50%, -50%) scale(0);
  pointer-events: none;
  animation: btn-ripple-anim 0.6s ease-out forwards;
}

@keyframes btn-ripple-anim {
  to {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}

.hero-image-col {
  /* Full-bleed against the hero section itself (not the grid row) so its
     height always matches the hero's actual height, and so the text
     column's width can never squeeze it during the name decode animation. */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 50%;
  z-index: 1;
  overflow: hidden;
}

.hero-avatar-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.85) contrast(1.08) brightness(0.92);
}

/* Duotone wash + inner-edge fade so the photo reads as part of the
   ink/paper illustration system rather than a pasted-in stock photo. */
.hero-image-col::before,
.hero-image-col::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.hero-image-col::before {
  z-index: 2;
  background: var(--paper-warm);
  mix-blend-mode: color;
  opacity: 0.45;
}

.hero-image-col::after {
  z-index: 3;
  background: linear-gradient(to right, var(--ink) 0%, transparent 20%);
}

/* ══════════════════════════════════════════════════════════════════
   ABOUT
══════════════════════════════════════════════════════════════════ */
#about {
  background: var(--paper-warm);
  color: var(--ink);
}

#about .ghost-text {
  color: var(--ink);
  top: -1rem;
  right: -2rem;
}

.about-grid {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
  margin-top: 2rem;
}

.about-pull-quote {
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(1.4rem, 2.8vw, 2.2rem);
  line-height: 1.3;
  border-left: 4px solid var(--ink);
  padding-left: 1.5rem;
  margin-top: 1rem;
}

.about-doodle-wrap {
  display: flex;
  justify-content: flex-end;
  margin-top: 2rem;
}

.about-bio {
  font-size: clamp(0.95rem, 1.4vw, 1.1rem);
  line-height: 1.75;
  color: rgb(var(--ink-rgb) / 0.82);
}

.about-bio p+p {
  margin-top: 1.2rem;
}

.about-stats {
  display: flex;
  gap: 2.5rem;
  margin-top: 2rem;
  flex-wrap: wrap;
}

.stat-item {
  opacity: 0;
  translate: 0 30px;
  transition: opacity 0.6s ease, translate 0.6s ease;
}

.stat-item.visible {
  opacity: 1;
  translate: 0 0;
}

.stat-item .stat-number {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 4rem);
  line-height: 1;
  display: block;
}

.stat-item .stat-label {
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.6;
}

/* ══════════════════════════════════════════════════════════════════
   EXPERIENCE
══════════════════════════════════════════════════════════════════ */
#experience {
  background: var(--paper);
  color: var(--ink);
}

#experience .ghost-text {
  color: var(--ink);
  bottom: -1rem;
  left: -1rem;
}

.exp-header {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 4rem);
  letter-spacing: 0.05em;
  margin-bottom: 3rem;
}

/* ─── JOURNEY TIMELINE: SCROLL-DRAWN LINE + PULSING DOTS ──────────── */
.exp-timeline {
  position: relative;
  padding-left: 32px;
}

.exp-timeline-track {
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 5px;
  width: 2px;
  background: rgb(var(--ink-rgb) / 0.12);
}

.exp-timeline-fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: var(--ink);
  transform: scaleY(var(--line-progress, 0));
  transform-origin: top center;
  will-change: transform;
}

.exp-entry {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2rem 3rem;
  margin-bottom: 3.5rem;
  padding-bottom: 3.5rem;
  border-bottom: 1.5px solid rgb(var(--ink-rgb) / 0.15);
  align-items: start;
  opacity: 0;
  translate: 0 30px;
  transition: opacity 0.6s ease, translate 0.6s ease;
}

.exp-entry.visible {
  opacity: 1;
  translate: 0 0;
}

.exp-entry:last-child {
  border-bottom: none;
  margin-bottom: 0;
}

.exp-dot {
  position: absolute;
  left: -32px;
  top: 8px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid rgb(var(--ink-rgb) / 0.3);
  z-index: 1;
  transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.exp-dot.active {
  background: var(--ink);
  border-color: var(--ink);
  box-shadow: 0 0 0 4px rgb(var(--ink-rgb) / 0.1);
}

.exp-dot.pulsing {
  animation: exp-dot-pulse 0.7s ease-out 2;
}

@keyframes exp-dot-pulse {
  0% {
    box-shadow: 0 0 0 0 rgb(var(--ink-rgb) / 0.35);
  }

  70% {
    box-shadow: 0 0 0 10px rgb(var(--ink-rgb) / 0);
  }

  100% {
    box-shadow: 0 0 0 0 rgb(var(--ink-rgb) / 0);
  }
}

.exp-chapter {
  font-family: var(--font-display);
  font-size: clamp(4rem, 8vw, 7rem);
  line-height: 0.85;
  color: var(--ink);
  opacity: 0.12;
  min-width: 5rem;
  text-align: right;
}

.exp-role {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  letter-spacing: 0.04em;
  line-height: 1.1;
}

.exp-company {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1rem;
  opacity: 0.6;
  margin-top: 0.3rem;
}

.exp-period {
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-top: 0.25rem;
  margin-bottom: 1rem;
}

.exp-bullets {
  list-style: none;
  padding: 0;
}

.exp-bullets li {
  font-size: clamp(0.9rem, 1.3vw, 1rem);
  line-height: 1.65;
  padding-left: 1.2rem;
  position: relative;
  margin-bottom: 0.5rem;
  color: rgb(var(--ink-rgb) / 0.82);
}

.exp-bullets li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 8px;
  height: 8px;
  background: var(--ink);
  opacity: 0.75;
}

.exp-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 1rem;
}

.exp-tag {
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  padding: 0.2rem 0.65rem;
  border: 1.5px solid var(--ink);
  opacity: 0.6;
}

.exp-doodle {
  display: flex;
  justify-content: center;
  margin-top: 1rem;
}

.exp-bottom-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  margin-top: 1rem;
  flex-wrap: wrap;
}

/* ══════════════════════════════════════════════════════════════════
   PROJECTS
══════════════════════════════════════════════════════════════════ */
#projects {
  background: var(--paper-warm);
  color: var(--ink);
  padding-top: clamp(2.5rem, 4vw, 4rem);
  padding-bottom: clamp(2rem, 3.5vw, 3.5rem);
}

#projects .ghost-text {
  color: var(--ink);
  top: 0;
  left: -1rem;
}

.projects-title-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 1.5rem;
  position: relative;
  z-index: 1;
  flex-wrap: wrap;
}

.projects-header {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 4rem);
  letter-spacing: 0.05em;
  margin-bottom: 0;
}

.projects-carousel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  position: relative;
  z-index: 1;
}

.projects-track-wrap {
  width: 100%;
  overflow: hidden;
}

.projects-track {
  display: flex;
  gap: 2rem;
  transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}

.projects-track .project-card {
  flex-shrink: 0;
  width: calc(50% - 1rem);
}

.carousel-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.2rem;
  padding-top: 0.8rem;
}

.carousel-arrow {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border: 3px solid var(--ink);
  background: var(--paper);
  box-shadow: 4px 4px 0 var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  color: var(--ink);
  padding: 0;
}

.carousel-arrow:hover:not(:disabled) {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--ink);
}

.carousel-arrow:active:not(:disabled) {
  transform: translate(1px, 1px);
  box-shadow: 2px 2px 0 var(--ink);
}

.carousel-arrow:disabled {
  opacity: 0.25;
  cursor: default;
}

.carousel-dots {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.carousel-dot {
  width: 10px;
  height: 10px;
  border: 2px solid var(--ink);
  background: transparent;
  cursor: pointer;
  padding: 0;
  transition: background 0.2s ease;
}

.carousel-dot.active {
  background: var(--ink);
}

.project-card {
  /* Resting state. js/project-tilt.js drives the tilt by setting
     `transform`/`box-shadow` directly as inline styles on hover. Reset
     back to this rule's values on mouseleave.

     transition-delay: 0 !important guards against data-stagger-item's
     inline transition-delay (js/scroll-reveal.js staggers the initial
     reveal per card index) leaking into these hover transitions — inline
     styles otherwise beat any non-!important stylesheet rule, which
     silently delayed the tilt by up to ~500ms on later cards. */
  background: var(--paper);
  border: 3px solid var(--ink);
  box-shadow: 5px 5px 0 var(--ink);
  padding: 1.2rem 1.4rem 2.6rem 1.4rem;
  transition: opacity 0.6s ease, translate 0.6s ease,
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.4s cubic-bezier(0.22, 1, 0.36, 1);
  cursor: default;
  position: relative;
  opacity: 0;
  translate: 0 30px;
}

.project-card.visible {
  opacity: 1;
  translate: 0 0;
}

/* While the cursor is actively moving over the card, transform/shadow
   updates should track it instantly rather than ease — the slower
   transition above only kicks back in on enter/leave for a smooth
   pop-in and reset-to-flat. */
.project-card.tilting {
  /* transition-delay: 0 !important guards against the stagger-reveal delay
     (js/scroll-reveal.js sets an inline transition-delay per card to stagger
     the initial fade/slide-in) leaking into this hover-driven transition —
     inline styles otherwise beat any non-!important rule here. */
  transition: box-shadow 0.1s ease-out, transform 0.1s ease-out;
  transition-delay: 0s !important;
  will-change: transform, box-shadow;
}

.card-github-link {
  position: absolute;
  bottom: 1.2rem;
  right: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  opacity: 0.3;
  transition: opacity 0.2s ease, transform 0.2s ease;
  border-radius: 50%;
}

.card-github-link svg {
  width: 22px;
  height: 22px;
  fill: var(--ink);
}

.project-card:hover .card-github-link,
.project-card.tap-active .card-github-link {
  opacity: 1;
}

.card-github-link:hover {
  opacity: 1 !important;
  transform: scale(1.15);
}

.card-live-link {
  position: absolute;
  bottom: 1.2rem;
  left: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  opacity: 0.3;
  transition: opacity 0.2s ease, transform 0.2s ease;
  border-radius: 50%;
}

.card-live-link svg {
  width: 22px;
  height: 22px;
  stroke: var(--ink);
}

.project-card:hover .card-live-link,
.project-card.tap-active .card-live-link {
  opacity: 1;
}

.card-live-link:hover {
  opacity: 1 !important;
  transform: scale(1.15);
}

/* Card top row: doodle left, preview right */
.card-top-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.7rem;
  height: 120px;
}

.card-top-row .card-doodle {
  margin-bottom: 0;
  flex-shrink: 0;
}

/* Hover preview image + overlay. The frame fills the remaining width of
   .card-top-row; the image/video fills the frame via object-fit so the
   overlay can cover it exactly regardless of the source's aspect ratio. */
.card-preview {
  flex: 1;
  height: 100%;
  position: relative;
  overflow: hidden;
  border-radius: 10px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.card-preview img,
.card-preview video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.project-card:hover .card-preview,
.project-card.tap-active .card-preview {
  opacity: 1;
}

.project-card:hover .card-preview img,
.project-card:hover .card-preview video,
.project-card.tap-active .card-preview img,
.project-card.tap-active .card-preview video {
  transform: scale(1.08);
}

.card-doodle {
  margin-bottom: 0.7rem;
}

.card-title {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.2vw, 1.9rem);
  letter-spacing: 0.04em;
  line-height: 1;
}

.card-period {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-top: 0.3rem;
}

.card-desc {
  font-size: clamp(0.82rem, 1.1vw, 0.92rem);
  line-height: 1.5;
  margin-top: 0.6rem;
  color: rgb(var(--ink-rgb) / 0.82);
}

.card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.7rem;
}

.card-tag {
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  padding: 0.22rem 0.6rem;
  background: var(--ink);
  color: var(--paper);
}

.card-special-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: var(--font-display);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.2rem 0.6rem;
  background: #5b21b6;
  color: #fff;
  margin-bottom: 0.45rem;
}

/* ══════════════════════════════════════════════════════════════════
   SKILLS
══════════════════════════════════════════════════════════════════ */
#skills {
  background: var(--ink);
  color: var(--paper);
}

.skills-header {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 4rem);
  letter-spacing: 0.05em;
  margin-bottom: 3rem;
}

.skills-section-label {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
  margin-bottom: 0.9rem;
  margin-top: 2rem;
}

.skills-section-label:first-of-type {
  margin-top: 0;
}

.skills-tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}

.skill-tag {
  /* --tag-glow defaults to the site's one accent color (matches
     .card-special-badge) and is overridden per tag below for
     recognizable brand colors. */
  --tag-glow: #5b21b6;
  font-family: var(--font-display);
  font-size: clamp(0.9rem, 1.4vw, 1.05rem);
  letter-spacing: 0.06em;
  padding: 0.45rem 1.1rem;
  border: 2px solid var(--paper);
  color: var(--paper);
  transition: background 0.15s, color 0.15s, border-color 0.25s ease,
    box-shadow 0.25s ease, opacity 0.5s ease, translate 0.5s ease,
    scale 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
  opacity: 0;
  translate: 0 20px;
  scale: 0.8;
}

.skill-tag.visible {
  opacity: 1;
  translate: 0 0;
  scale: 1;
}

.skill-tag:nth-child(even) {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
}

.skill-tag:hover {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--tag-glow);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--tag-glow) 70%, transparent),
    0 0 16px 2px color-mix(in srgb, var(--tag-glow) 45%, transparent);
}

/* Brand-color glows for recognizable technologies; everything else
   falls back to the --tag-glow default set above. */
.skill-tag[data-tech='javascript'] { --tag-glow: #f7df1e; }
.skill-tag[data-tech='python'] { --tag-glow: #306998; }
.skill-tag[data-tech='nodejs'] { --tag-glow: #339933; }
.skill-tag[data-tech='git'] { --tag-glow: #f05032; }
.skill-tag[data-tech='docker'] { --tag-glow: #2496ed; }
.skill-tag[data-tech='react'] { --tag-glow: #61dafb; }
.skill-tag[data-tech='fastapi'] { --tag-glow: #009688; }
.skill-tag[data-tech='postgresql'] { --tag-glow: #336791; }
.skill-tag[data-tech='sap'] { --tag-glow: #0faaff; }

.skills-lower {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3rem;
  align-items: end;
}

/* ══════════════════════════════════════════════════════════════════
   ACHIEVEMENTS
══════════════════════════════════════════════════════════════════ */
#certifications {
  background: var(--paper);
  color: var(--ink);
}

.certs-header {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 4rem);
  letter-spacing: 0.05em;
  margin-bottom: 2.5rem;
}

.cert-callout {
  border: 3px solid var(--ink);
  box-shadow: 5px 5px 0 var(--ink);
  padding: 1.8rem 2.2rem;
  margin-bottom: 2.5rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  background: var(--paper-warm);
}

.cert-callout-text {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.5vw, 1.9rem);
  letter-spacing: 0.03em;
  line-height: 1.2;
}

.cert-callout-sub {
  font-family: var(--font-body);
  font-size: 0.9rem;
  opacity: 0.6;
  margin-top: 0.3rem;
}

.cert-list {
  list-style: none;
}

.cert-list li {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid rgb(var(--ink-rgb) / 0.1);
  font-size: clamp(0.9rem, 1.3vw, 1.05rem);
  line-height: 1.5;
  color: rgb(var(--ink-rgb) / 0.82);
}

.cert-list li:last-child {
  border-bottom: none;
}

.cert-icon {
  flex-shrink: 0;
  margin-top: 2px;
}

/* ══════════════════════════════════════════════════════════════════
   CONTACT
══════════════════════════════════════════════════════════════════ */
#contact {
  background: var(--ink);
  color: var(--paper);
  text-align: center;
}

.contact-cta {
  font-family: var(--font-display);
  font-size: clamp(3rem, 10vw, 9rem);
  letter-spacing: -0.01em;
  line-height: 0.9;
  margin-bottom: 2.5rem;
}

.contact-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2rem 3rem;
  margin-bottom: 3rem;
}

.contact-link {
  font-family: var(--font-display);
  font-size: clamp(1rem, 2vw, 1.5rem);
  letter-spacing: 0.06em;
  color: var(--paper);
  text-decoration: none;
  border-bottom: 2.5px solid rgb(var(--paper-rgb) / 0.4);
  padding-bottom: 0.2rem;
  transition: border-color 0.2s;
}

.contact-link:hover {
  border-color: var(--paper);
}

.contact-footer-doodle {
  margin: 2rem auto 1rem;
}

.footer-sign {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 0.88rem;
  opacity: 0.4;
  margin-top: 1.5rem;
  letter-spacing: 0.05em;
}

/* ══════════════════════════════════════════════════════════════════
   CERTIFICATIONS (SCROLLING)
══════════════════════════════════════════════════════════════════ */
#licenses {
  background: var(--ink);
  color: var(--paper);
  padding-left: 0;
  padding-right: 0;
}

#licenses .ghost-text {
  color: var(--paper);
  top: -1rem;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0.04;
}

.licenses-header {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 4rem);
  letter-spacing: 0.05em;
  margin-bottom: 2.5rem;
  padding: 0 clamp(1.5rem, 6vw, 7rem);
  position: relative;
  z-index: 1;
}

@keyframes marquee {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.lc-track-wrap {
  overflow: hidden;
  width: 100%;
  position: relative;
  z-index: 1;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 7%, black 93%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, black 7%, black 93%, transparent 100%);
  padding: 0.5rem 0 1.5rem;
  cursor: grab;
}

.lc-track-wrap.is-dragging {
  cursor: grabbing;
}

.lc-track {
  display: flex;
  gap: 1.4rem;
  width: max-content;
  animation: marquee 55s linear infinite;
}

.lc-track:hover {
  animation-play-state: paused;
}

.lc-track.lc-drag-active {
  animation: none;
}

.license-card {
  flex-shrink: 0;
  width: 260px;
  border: 2px solid rgb(var(--paper-rgb) / 0.5);
  box-shadow: 3px 3px 0 rgb(var(--paper-rgb) / 0.18);
  padding: 1.4rem;
  cursor: pointer;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
  background: rgb(var(--paper-rgb) / 0.05);
  border-radius: 1.2rem;
}

.license-card:hover {
  border-color: rgb(var(--paper-rgb) / 0.85);
  box-shadow: 5px 5px 0 rgb(var(--paper-rgb) / 0.35);
  transform: translateY(-3px);
}

/* ── Certificate Lightbox ─────────────────────────────────────── */
.cert-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(0, 0, 0, 0.82);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: scale(1.04);
  transition: opacity 0.4s ease, transform 0.4s ease, visibility 0s linear 0.4s;
}

.cert-lightbox.active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: scale(1);
  transition: opacity 0.4s ease, transform 0.4s ease, visibility 0s linear 0s;
}

/* Placeholder frame that FLIPs from the clicked card's position/size to its
   centered, expanded position — this is what makes the card feel like it
   grows into the modal instead of the modal just appearing. */
.cert-lightbox-frame {
  position: relative;
  width: min(780px, 92vw);
  height: min(620px, 88vh);
  display: flex;
  align-items: center;
  justify-content: center;
  transform-origin: center center;
  will-change: transform;
  border-radius: 1.2rem;
  /* Fixed white (not themed): this frame sits on the lightbox's own
     fixed dark backdrop, not on the page's themed background. */
  border: 2px solid rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.03);
  box-shadow: 3px 3px 0 rgba(255, 255, 255, 0.1);
  transition: border-radius 0.3s ease, border-color 0.3s ease,
    background 0.3s ease, box-shadow 0.3s ease;
}

.cert-lightbox-frame.flip-animate {
  transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1),
    border-radius 0.3s ease, border-color 0.3s ease,
    background 0.3s ease, box-shadow 0.3s ease;
}

/* Applied once the flip finishes: the card-like placeholder melts into the
   borderless, shadowed modal frame that holds the certificate image. */
.cert-lightbox-frame.expanded {
  border-radius: 16px;
  border-color: transparent;
  background: transparent;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6);
}

.cert-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 16px;
  object-fit: contain;
  opacity: 0;
  transition: opacity 0.25s ease;
}

.cert-lightbox-img.loaded {
  opacity: 1;
}

.cert-lightbox-close {
  position: fixed;
  top: 1.4rem;
  right: 1.6rem;
  /* Fixed white (not themed): sits on the lightbox's fixed dark backdrop. */
  background: rgba(255, 255, 255, 0.12);
  border: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
  z-index: 10000;
}

.cert-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.25);
}

.lc-issuer {
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.45;
  margin-bottom: 0.5rem;
}

.lc-title {
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: 0.03em;
  line-height: 1.15;
  margin-bottom: 0.6rem;
}

.lc-date {
  display: none;
}

.lc-id {
  font-family: monospace;
  font-size: 0.62rem;
  opacity: 0.28;
  margin-bottom: 0.8rem;
  word-break: break-all;
}

.lc-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.6rem;
}

.lc-tag {
  font-family: var(--font-display);
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  padding: 0.18rem 0.5rem;
  border: 1.5px solid rgb(var(--paper-rgb) / 0.35);
  color: var(--paper);
  opacity: 0.75;
}

/* ══════════════════════════════════════════════════════════════════
   RESPONSIVE
══════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  #hero {
    text-align: left;
  }

  .hero-image-col {
    position: relative;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 5;
    margin-top: 2.5rem;
  }

  .hero-image-col::after {
    background: linear-gradient(to bottom, var(--ink) 0%, transparent 20%);
  }

  .hero-blob {
    filter: blur(50px);
  }

  .about-grid {
    grid-template-columns: 1fr;
  }

  .about-doodle-wrap {
    justify-content: flex-start;
  }

  .exp-entry {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }

  .exp-chapter {
    font-size: clamp(3rem, 10vw, 5rem);
    text-align: left;
    opacity: 0.1;
  }

  .projects-track .project-card {
    width: 100%;
  }

  .carousel-arrow {
    width: 36px;
    height: 36px;
  }

  .skills-lower {
    grid-template-columns: 1fr;
  }

  .cert-callout {
    flex-direction: column;
    align-items: flex-start;
  }

  .contact-cta {
    font-size: clamp(2.5rem, 14vw, 6rem);
  }

  .contact-links {
    flex-direction: column;
    align-items: center;
    gap: 1rem;
  }

  .ghost-text {
    display: none;
  }

  .exp-bottom-row {
    justify-content: center;
  }

  .projects-title-row {
    justify-content: flex-start;
  }
}

/* ══════════════════════════════════════════════════════════════════
   REDUCED MOTION
══════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {

  .hero-blob,
  .typewriter-cursor,
  .doodle-wrap {
    animation: none;
  }

  .typewriter-cursor {
    opacity: 1;
  }

  .reveal,
  .stat-item,
  .exp-entry,
  .project-card,
  .skill-tag {
    transition: none !important;
    opacity: 1 !important;
    translate: 0 !important;
    scale: 1 !important;
  }

  /* Hover glow isn't motion — keep its transition alive even though the
     entrance transition above is disabled. */
  .skill-tag:hover {
    transition: background 0.15s, color 0.15s, border-color 0.25s ease,
      box-shadow 0.25s ease !important;
  }

  .project-card {
    transform: none !important;
  }

  .exp-timeline-fill {
    transform: scaleY(1) !important;
  }

  .exp-dot {
    transition: none !important;
    background: var(--ink) !important;
    border-color: var(--ink) !important;
    box-shadow: 0 0 0 4px rgb(var(--ink-rgb) / 0.1) !important;
    animation: none !important;
  }

  /* Certificate lightbox: drop the flip/zoom entirely and just cross-fade. */
  .cert-lightbox {
    transform: none !important;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s !important;
  }

  .cert-lightbox.active {
    transition: opacity 0.2s ease, visibility 0s linear 0s !important;
  }

  .cert-lightbox-frame,
  .cert-lightbox-frame.flip-animate {
    transition: none !important;
    transform: none !important;
    border-radius: 16px !important;
    border-color: transparent !important;
    background: transparent !important;
    box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6) !important;
  }

  .cert-lightbox-img {
    transition: opacity 0.2s ease !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   DARK MODE TOGGLE
   Self-contained: remove this block + the #theme-toggle button in
   index.html + js/theme-toggle.js to disable. The head's inline
   blocking script (sets [data-theme] before first paint) can stay
   even without this — it'd just have nothing to persist a choice to.
══════════════════════════════════════════════════════════════════ */
.theme-toggle {
  position: fixed;
  top: 1.4rem;
  right: 1.6rem;
  z-index: 800;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 2.5px solid var(--paper);
  background: var(--ink);
  color: var(--paper);
  box-shadow: 3px 3px 0 rgb(var(--paper-rgb) / 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease,
    background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}

.theme-toggle:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 rgb(var(--paper-rgb) / 0.5);
}

.theme-toggle:active {
  transform: translate(1px, 1px);
  box-shadow: 1px 1px 0 rgb(var(--paper-rgb) / 0.35);
}

.theme-toggle-icon {
  width: 20px;
  height: 20px;
}

.theme-icon-moon {
  display: none;
}

html[data-theme="dark"] .theme-icon-sun {
  display: none;
}

html[data-theme="dark"] .theme-icon-moon {
  display: block;
}

@media (max-width: 768px) {
  .theme-toggle {
    top: 0.9rem;
    right: 0.9rem;
    width: 40px;
    height: 40px;
  }
}

/* ══════════════════════════════════════════════════════════════════
   CUSTOM CURSOR
   Self-contained: remove this block + the #cursor-dot/#cursor-ring
   elements in index.html + js/cursor.js to disable. Stays fully
   inert unless js/cursor.js adds .has-custom-cursor to <html>, which
   it only does on pointer:fine + non-reduced-motion devices.
══════════════════════════════════════════════════════════════════ */
.cursor-dot,
.cursor-ring {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  border-radius: 50%;
  pointer-events: none;
  z-index: 999999;
  mix-blend-mode: difference;
  transform: translate(-50%, -50%);
  will-change: transform;
}

@media (pointer: fine) {
  html.has-custom-cursor .cursor-dot,
  html.has-custom-cursor .cursor-ring {
    display: block;
  }

  html.has-custom-cursor,
  html.has-custom-cursor a,
  html.has-custom-cursor button,
  html.has-custom-cursor input,
  html.has-custom-cursor textarea,
  html.has-custom-cursor select,
  html.has-custom-cursor .project-card,
  html.has-custom-cursor .license-card {
    cursor: none;
  }
}

.cursor-dot {
  width: 8px;
  height: 8px;
  background: #fff;
}

.cursor-ring {
  width: 34px;
  height: 34px;
  background: transparent;
  border: 1.5px solid #fff;
  opacity: 0.7;
  transition: width 0.2s ease, height 0.2s ease, opacity 0.2s ease,
    border-width 0.2s ease;
}

.cursor-ring.cursor-hover {
  width: 56px;
  height: 56px;
  border-width: 2px;
  opacity: 1;
}

/* ══════════════════════════════════════════════════════════════════
   PAGE LOAD INTRO
   Self-contained: remove this block + #intro-overlay in index.html +
   js/intro.js to disable. If removed, also drop the `afterIntro(...)`
   wrappers around the hero name/typewriter IIFEs further down in
   index.html (or leave them — afterIntro degrades to "run immediately"
   whenever js/intro.js isn't present to define it, see that script).
══════════════════════════════════════════════════════════════════ */
.intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 999998;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ink);
  pointer-events: none;
  transition: opacity 0.35s ease;
}

.intro-overlay.intro-hide {
  opacity: 0;
}

.intro-overlay.intro-done {
  display: none;
}

.intro-name {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 6vw, 4rem);
  letter-spacing: 0.12em;
  color: var(--paper);
  display: flex;
}

.intro-letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}

.intro-letter.intro-letter-visible {
  opacity: 1;
  transform: translateY(0);
}

.intro-letter-space {
  width: 0.5em;
}

@media (prefers-reduced-motion: reduce) {
  .intro-overlay {
    display: none !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   SCROLL PROGRESS BAR
   Self-contained: remove this block + .scroll-progress-bar element in
   index.html + js/scroll-progress.js to disable.
══════════════════════════════════════════════════════════════════ */
.scroll-progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: #5b21b6;
  box-shadow: 0 0 6px rgba(91, 33, 182, 0.6);
  transform: scaleX(0);
  transform-origin: 0 0;
  z-index: 900;
  pointer-events: none;
}
