.section {
  padding: var(--section-padding-y) var(--page-margin-x);
  max-width: var(--max-width);
  margin: 0 auto;
  position: relative;
}

.section-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-6);
  margin-bottom: var(--space-16);
}

.section-header::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(to right, var(--color-border-strong), transparent);
  transform: translateY(-0.3em);
}

.section-number {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--color-accent-dim);
}

.section-title {
  font-size: var(--fs-xl);
}

/* ---------- Nav ---------- */
.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-6) var(--page-margin-x);
  mix-blend-mode: normal;
  pointer-events: none;
}

.theme-toggle,
.site-nav__list,
.site-nav__toggle {
  pointer-events: auto;
}

/* ---------- Theme toggle (sun/moon pill, PB thumb) ----------
   Track is exactly two 24px slots plus a 2px inset all around
   (2 + 24 + 24 + 2 = 52), and the icons sit dead-center of those
   same two slots — so the opaque thumb, sliding between left:2px
   and left:26px, always fully covers one icon and never overlaps
   the other. Geometry must stay in sync across thumb/icon/[data-theme]. */
.theme-toggle {
  position: relative;
  z-index: 2;
  height: 28px;
  width: 52px;
  background: var(--color-surface-glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out);
}

.theme-toggle:hover {
  border-color: var(--color-border-strong);
}

.theme-toggle__icon {
  position: absolute;
  z-index: 1;
  top: 50%;
  width: 14px;
  height: 14px;
  color: var(--color-text-faint);
  transform: translate(-50%, -50%);
  transition: color var(--duration-fast) var(--ease-out);
}

.theme-toggle__icon--sun {
  left: 14px;
}

.theme-toggle__icon--moon {
  left: 38px;
}

[data-theme='dark'] .theme-toggle__icon--moon,
:root:not([data-theme='dark']) .theme-toggle__icon--sun {
  color: var(--color-text);
}

.theme-toggle__thumb {
  position: absolute;
  z-index: 2;
  top: 2px;
  left: 2px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: #000;
  background: linear-gradient(180deg, #5fffb8, var(--color-accent));
  border-radius: 50%;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 12px var(--color-accent-glow);
  transition: transform var(--duration-base) var(--ease-out);
}

[data-theme='dark'] .theme-toggle__thumb {
  transform: translateX(24px);
}

.site-nav__list {
  display: flex;
  gap: var(--space-2);
  list-style: none;
  background: var(--color-surface-glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: var(--space-2);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
}

.site-nav__link {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--fs-sm);
  color: var(--color-text-dim);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
}

.site-nav__link .num {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--color-text-faint);
  transition: color var(--duration-fast) var(--ease-out);
}

.site-nav__link {
  transition: color var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out);
}

.site-nav__link:hover,
.site-nav__link.is-active {
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-text) 5%, transparent);
}

.site-nav__link:hover .num,
.site-nav__link.is-active .num {
  color: var(--color-accent-dim);
}

.site-nav__toggle {
  display: none;
  width: 32px;
  height: 24px;
  flex-direction: column;
  justify-content: space-between;
  z-index: 2;
}

.site-nav__toggle span {
  display: block;
  height: 1px;
  width: 100%;
  background: var(--color-text);
  transition: transform var(--duration-fast) var(--ease-out), opacity var(--duration-fast) var(--ease-out);
}

/* ---------- Mode switch (floating Professional | Personal) ---------- */
.mode-switch {
  position: fixed;
  bottom: var(--space-8);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-mode-switch);
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--color-surface-glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  transition: opacity var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out);
}

/* Steps out of the way once Contact scrolls into view so it never sits on
   top of the submit button (it's a fixed, viewport-relative control, so it
   would otherwise overlap whatever content happens to rest under it). */
.mode-switch.is-near-footer {
  opacity: 0;
  transform: translateX(-50%) translateY(16px);
  pointer-events: none;
}

.mode-switch__btn {
  position: relative;
  z-index: 1;
  padding: var(--space-2) var(--space-6);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-sm);
  color: var(--color-text-dim);
  border-radius: var(--radius-full);
  transition: color var(--duration-fast) var(--ease-out);
}

.mode-switch__btn:not(.is-active):hover {
  color: var(--color-text);
}

.mode-switch__btn.is-active {
  color: #000;
}

.mode-switch__pill {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc(50% - 4px);
  background: linear-gradient(180deg, #5fffb8, var(--color-accent));
  border-radius: var(--radius-full);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 20px var(--color-accent-glow);
  transition: transform var(--duration-base) var(--ease-out);
}

[data-mode='personal'] .mode-switch__pill {
  transform: translateX(100%);
}

/* ---------- Hero ---------- */
.hero {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-24) var(--page-margin-x) var(--space-16);
  max-width: var(--max-width);
  margin: 0 auto;
  position: relative;
  overflow: hidden;
}

.hero::before,
.hero::after {
  content: '';
  position: absolute;
  z-index: -2;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
}

.hero::before {
  width: min(60vw, 700px);
  height: min(60vw, 700px);
  top: -15%;
  right: -10%;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent) 22%, transparent), transparent 70%);
  animation: heroGlowFloat 14s ease-in-out infinite;
}

.hero::after {
  width: min(40vw, 500px);
  height: min(40vw, 500px);
  bottom: -10%;
  left: -5%;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent) 10%, transparent), transparent 70%);
  animation: heroGlowFloat 18s ease-in-out infinite reverse;
}

@keyframes heroGlowFloat {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-4%, 4%) scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .hero::before,
  .hero::after {
    animation: none;
  }
}

.hero__avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--color-bg);
  box-shadow: 0 0 0 1px var(--color-border), 0 12px 30px -10px rgba(0, 0, 0, 0.25);
  margin-bottom: var(--space-6);
}

.hero__greeting {
  margin-bottom: var(--space-6);
}

.hero__name {
  font-size: var(--fs-3xl);
  max-width: 20ch;
  text-wrap: balance;
  letter-spacing: -0.03em;
}

.hero__role {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  color: var(--color-accent-dim);
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: var(--space-6);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
}

.hero__role::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 8px 1px var(--color-accent-glow);
}

.hero__description {
  max-width: 46ch;
  color: var(--color-text-dim);
  margin-top: var(--space-6);
  font-size: var(--fs-lg);
  line-height: 1.5;
}

.hero__cta {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-12);
  flex-wrap: wrap;
}

/* ---------- About / Timeline ---------- */
.about__bio {
  position: relative;
  max-width: 42ch;
  font-size: var(--fs-2xl);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--color-text);
  margin-bottom: var(--space-24);
}

.timeline {
  position: relative;
  padding-left: var(--space-8);
}

.timeline::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--color-border);
}

.timeline__progress {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 0%;
  background: var(--color-accent);
  box-shadow: 0 0 8px var(--color-accent-glow);
}

.timeline__item {
  position: relative;
  padding-bottom: var(--space-16);
  transition: transform var(--duration-base) var(--ease-out);
}

.timeline__item:hover {
  transform: translateX(6px);
}

.timeline__item:hover .timeline__title {
  color: var(--color-accent-dim);
}

.timeline__item:last-child {
  padding-bottom: 0;
}

.timeline__dot {
  position: absolute;
  left: calc(-1 * var(--space-8) - 4px);
  top: 6px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 1px solid var(--color-border-strong);
  transition: background var(--duration-fast), border-color var(--duration-fast);
}

.timeline__item.is-visible .timeline__dot {
  background: var(--color-accent);
  border-color: var(--color-accent-dim);
  box-shadow: 0 0 10px var(--color-accent-glow);
}

.timeline__year {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--color-accent-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--space-2);
  display: block;
}

.timeline__header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.timeline__logo {
  width: 28px;
  height: 28px;
  object-fit: contain;
  flex: none;
}

.timeline__title {
  font-size: var(--fs-xl);
  font-weight: 700;
  transition: color var(--duration-fast) var(--ease-out);
}

.timeline__description {
  color: var(--color-text-dim);
  max-width: 55ch;
}

/* Personal timeline: a real zigzag timeline — a continuous horizontal
   strip with a dot per item, content alternating above/below (see
   render-about.js) — mixing location entries and blog-linked items,
   horizontally scrollable since the list is unbounded. */
.timeline-horizontal {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: var(--space-8) var(--page-margin-x) var(--space-4);
  margin: 0 calc(var(--page-margin-x) * -1);
  scrollbar-width: none;
}

.timeline-horizontal::-webkit-scrollbar {
  display: none;
}

/* inline-flex, not flex, so this element's own box is exactly as wide as
   its content (not clipped to the viewport) — every .timeline-item__dot-row
   below relies on that: adjacent items' dot-rows have zero gap between
   them, so their bars touch and read as one unbroken line across the
   *entire* scrollable strip, not just whatever's initially visible. */
.timeline-horizontal__track {
  display: inline-flex;
  min-width: 100%;
}

.timeline-item {
  flex: 0 0 min(190px, 50vw);
  scroll-snap-align: start;
}

/* Both are always rendered, one empty — and both get a fixed height
   (not flex-stretch-derived) so every item's dot lands at the exact
   same offset from the item's top regardless of which side has real
   content, or how tall it is. Deliberately not relying on cross-axis
   flex stretch here (a stretched flex item's absolutely-positioned
   descendants — the dot-row line below — render inconsistently across
   browsers); a hard height plus default overflow:visible is simpler
   and fully deterministic instead. */
.timeline-item__above,
.timeline-item__below {
  height: 170px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 var(--space-4);
  box-sizing: border-box;
}

.timeline-item__above {
  justify-content: flex-end;
}

.timeline-item__below {
  justify-content: flex-start;
}

/* No horizontal padding here (unlike above/below) — a plain block
   element is 100% of .timeline-item's width by default, so adjacent
   items' dot-rows sit flush edge to edge with zero gap, reading as one
   continuous line. */
.timeline-item__dot-row {
  position: relative;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.timeline-item__dot-row::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2px;
  background: var(--color-border);
  transform: translateY(-50%);
}

.timeline-item__dot {
  position: relative;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 10px var(--color-accent-glow);
}

.timeline-item__media {
  width: 60px;
  height: 60px;
  flex: none;
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--space-2);
}

.timeline-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.timeline-item__year {
  font-size: var(--fs-xs);
  color: var(--color-accent-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.timeline-item__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  margin-top: var(--space-1);
  transition: color var(--duration-fast) var(--ease-out);
}

.timeline-item--blog {
  cursor: pointer;
}

.timeline-item--blog:hover .timeline-item__title {
  color: var(--color-accent-dim);
}

.timeline-item__description {
  color: var(--color-text-dim);
  font-size: var(--fs-xs);
  line-height: 1.4;
  margin-top: var(--space-1);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.placeholder-panel {
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-24) var(--space-8);
  text-align: center;
  color: var(--color-text-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}

/* ---------- Projects ---------- */
.projects__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-8);
}

@media (max-width: 1080px) {
  .projects__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .projects__grid {
    grid-template-columns: 1fr;
  }
}

.projects__show-more {
  display: flex;
  justify-content: center;
  margin-top: var(--space-12);
}

.project-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--color-bg-elevated);
  transition: border-color var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}

.project-card:hover {
  border-color: var(--color-accent-dim);
  transform: translateY(-6px);
  box-shadow: 0 20px 45px -20px rgba(0, 0, 0, 0.18), 0 0 30px -12px var(--color-accent-glow);
}

.project-card__media {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--color-bg-elevated-2);
}

.project-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-slow) var(--ease-out);
}

.project-card__media::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(10, 10, 10, 0.65), transparent 50%);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
}

.project-card__media::after {
  content: 'View Project ↗';
  position: absolute;
  bottom: var(--space-4);
  left: var(--space-4);
  display: inline-flex;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-sm);
  color: #000;
  background: var(--color-accent);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out);
}

.project-card:hover .project-card__media::before,
.project-card:hover .project-card__media::after {
  opacity: 1;
  transform: translateY(0);
}

.project-card:hover .project-card__media img {
  transform: scale(1.06);
}

.project-card__media--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--color-bg-elevated-2), var(--color-bg-elevated));
}

.project-card__initial {
  font-size: 2.5rem;
  color: var(--color-text-faint);
}

.project-card__featured {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  font-size: 0.7rem;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: var(--radius-full);
  background: rgba(10, 10, 10, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid color-mix(in srgb, var(--color-accent) 40%, transparent);
  color: var(--color-accent-dim);
}

.project-card__body {
  padding: var(--space-6);
}

.project-card__title {
  font-size: var(--fs-md);
  font-weight: 700;
  margin-bottom: var(--space-2);
}

.project-card__summary {
  color: var(--color-text-dim);
  font-size: var(--fs-sm);
  line-height: 1.5;
  margin-bottom: var(--space-4);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.project-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.tag {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 8px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  color: var(--color-text-dim);
  transition: border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}

.project-card:hover .tag {
  border-color: var(--color-accent-dim);
  color: var(--color-text);
}

/* ---------- Full-screen detail (matched-geometry expand) ---------- */
/* Shared by project cards and blog list rows — the full-screen panel starts
   at the source element's exact rect and only ever grows from there, so it
   fully occludes the source for the whole transition. No need to hide it
   too (and doing so via opacity fought with GSAP's own inline opacity from
   the scroll-reveal animation). */
.is-expanded {
  pointer-events: none;
}

.fullscreen-panel {
  background: var(--color-bg);
  z-index: var(--z-overlay);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.35);
  will-change: top, left, width, height;
}

.fullscreen-panel__hero {
  position: relative;
  width: 100%;
  aspect-ratio: 21 / 9;
  overflow: hidden;
  background: var(--color-bg-elevated-2);
}

.fullscreen-panel__hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.fullscreen-panel__hero-caption {
  position: absolute;
  left: var(--space-8);
  right: var(--space-8);
  bottom: var(--space-8);
}

.fullscreen-panel__hero-caption .text-chip {
  font-size: clamp(1.5rem, 4vw, 2.75rem);
}

.fullscreen-panel__close {
  position: fixed;
  top: var(--space-6);
  right: var(--space-6);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-surface-glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--color-border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  font-size: 1.1rem;
  color: var(--color-text);
  transition: transform var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}

.fullscreen-panel__close:hover {
  transform: rotate(90deg);
  border-color: var(--color-accent-dim);
}

.fullscreen-panel__content {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: var(--space-16) var(--page-margin-x) var(--space-32);
}

.fullscreen-panel__content--article {
  max-width: 720px;
}

.blog-byline {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-8);
}

.blog-byline__avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
}

.blog-byline__meta {
  display: flex;
  flex-direction: column;
}

.blog-byline__name {
  font-weight: 600;
  font-size: var(--fs-sm);
}

.blog-byline__date {
  font-size: 0.75rem;
  color: var(--color-text-faint);
}

.project-detail-inline__gallery {
  display: flex;
  gap: var(--space-6);
  overflow-x: auto;
  justify-content: center;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.project-detail-inline__gallery::-webkit-scrollbar {
  display: none;
}

.project-detail-inline__gallery img {
  flex: 0 0 auto;
  max-height: 420px;
  width: auto;
  max-width: 100%;
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px -24px rgba(0, 0, 0, 0.3);
  scroll-snap-align: center;
}

/* Replaces the native scrollbar (hidden above) as the gallery's position
   indicator — dots instead of a scroll thumb. */
.project-detail-inline__gallery-dots {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.project-detail-inline__gallery-dots .gallery-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-border-strong);
  transition: background var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}

.project-detail-inline__gallery-dots .gallery-dot.is-active {
  background: var(--color-accent);
  transform: scale(1.3);
}

.project-detail-inline__video {
  aspect-ratio: 16 / 9;
  max-width: 720px;
  margin: 0 auto;
  border-radius: var(--radius-md);
  overflow: hidden;
}

.project-detail-inline__video iframe {
  width: 100%;
  height: 100%;
}

.project-detail-inline__body {
  max-width: 640px;
  margin: var(--space-8) auto 0;
  text-align: center;
}

.project-detail-inline__body .section-title {
  margin-top: var(--space-3);
  font-size: var(--fs-lg);
}

.project-detail-inline__body p {
  margin-top: var(--space-6);
  color: var(--color-text-dim);
  line-height: 1.65;
}

.project-detail-inline__links {
  display: flex;
  gap: var(--space-4);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-8);
  margin-bottom: var(--space-12);
}

/* ---------- YouTube carousel ---------- */
/* A single row of cards is much shorter than every other section's
   content, so the standard --section-padding-y (up to 9rem top+bottom)
   leaves a disproportionately large gap below it — tightened just here
   rather than changing the shared section rhythm everywhere. */
#youtube.section {
  padding-bottom: var(--space-16);
}

.youtube-carousel {
  display: flex;
  gap: var(--space-8);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-4);
  margin: 0 calc(var(--page-margin-x) * -1);
  padding-left: var(--page-margin-x);
  padding-right: var(--page-margin-x);
  scrollbar-width: none;
}

.youtube-carousel::-webkit-scrollbar {
  display: none;
}

.youtube-card {
  flex: 0 0 min(360px, 82vw);
  scroll-snap-align: start;
}

.youtube-card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg-elevated-2);
  border: 1px solid var(--color-border);
}

.youtube-card__media img,
.youtube-card__media iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: none;
}

.youtube-card__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--color-accent);
  color: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 2px;
  transition: transform var(--duration-fast) var(--ease-out);
}

.youtube-card__play:hover {
  transform: scale(1.08);
}

.youtube-card__title {
  margin-top: var(--space-4);
  font-size: var(--fs-base);
  font-weight: 600;
}

.youtube-channel {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-8);
  padding: var(--space-2) var(--space-6) var(--space-2) var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface-glass);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-sm);
  transition: border-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}

.youtube-channel:hover {
  border-color: var(--color-accent-dim);
  transform: translateY(-2px);
}

.youtube-channel__avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-bg-elevated);
}

/* ---------- Blog (a list — deliberately not a card grid, to read as
   distinct from Projects) ---------- */
.blog-list {
  display: flex;
  flex-direction: column;
}

.blog-list-item {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) 0;
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-out);
}

.blog-list-item:first-child {
  border-top: 1px solid var(--color-border);
}

.blog-list-item:hover {
  opacity: 0.7;
}

.blog-list-item__media {
  flex: none;
  width: 140px;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-bg-elevated-2);
}

.blog-list-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.blog-list-item__media--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.75rem;
  color: var(--color-text-faint);
  background: linear-gradient(135deg, var(--color-bg-elevated-2), var(--color-bg-elevated));
}

.blog-list-item__body {
  flex: 1;
  min-width: 0;
}

.blog-list-item__date {
  color: var(--color-text-faint);
  font-size: 0.75rem;
}

.blog-list-item__title {
  font-size: var(--fs-lg);
  font-weight: 700;
  margin-top: var(--space-2);
}

.blog-list-item__subtitle {
  color: var(--color-text-dim);
  font-size: var(--fs-base);
  line-height: 1.5;
  margin-top: var(--space-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.blog-list-item__arrow {
  flex: none;
  font-size: 1.25rem;
  color: var(--color-text-faint);
  transition: transform var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}

.blog-list-item:hover .blog-list-item__arrow {
  transform: translateX(4px);
  color: var(--color-accent-dim);
}

.blog-list-item-skeleton {
  height: 172px;
  border-radius: var(--radius-md);
  margin-bottom: var(--space-6);
}

/* A caption block that's bold white-on-black, using box-decoration-break so
   a caption wrapping across multiple lines renders as separate stacked
   chips per line instead of one rectangle spanning the whole block. Used
   for hero titles and image captions in both Project and Blog detail views. */
.text-chip {
  display: inline;
  background: var(--chip-bg, #000);
  color: #fff;
  font-weight: 700;
  line-height: 1.6;
  padding: 0.1em 0.4em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.blog-section-block {
  margin-bottom: var(--space-2);
}

.blog-section__chip-heading {
  margin-bottom: var(--space-4);
}

.blog-section__title {
  font-size: var(--fs-xl, 2rem);
  font-weight: 700;
  margin-bottom: var(--space-4);
}

.blog-section__subtitle {
  color: var(--color-text-dim);
  font-size: var(--fs-lg);
  margin-bottom: var(--space-6);
}

.blog-section__text {
  font-size: var(--fs-base);
  line-height: 1.75;
  margin-bottom: var(--space-6);
}

.blog-section__image-wrap {
  position: relative;
  margin-bottom: var(--space-2);
}

.blog-section__image {
  width: 100%;
  border-radius: var(--radius-md);
}

.blog-section__image-caption {
  position: absolute;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
}

.blog-section__item-subtitle {
  font-size: 0.875rem;
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
}

.blog-section__code {
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
  overflow-x: auto;
}

.blog-section__code code {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  line-height: 1.6;
  white-space: pre;
}

.blog-section__map {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--space-6);
}

.blog-section__map iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.blog-section__map-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  border: none;
  background: color-mix(in srgb, var(--color-text) 4%, transparent);
  backdrop-filter: blur(1px);
  color: var(--color-text-dim);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}

.blog-section__map-overlay:hover {
  background: color-mix(in srgb, var(--color-text) 8%, transparent);
}

/* ---------- Custom sections ---------- */
.custom-section__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-12) var(--space-8);
}

.custom-section__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}

.custom-section__icon {
  width: 72px;
  height: 72px;
  padding: 12px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  box-shadow: 0 8px 20px -12px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  transition: transform var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}

.custom-section__item:hover .custom-section__icon {
  transform: translateY(-4px);
  border-color: var(--color-accent-dim);
  box-shadow: 0 16px 28px -14px rgba(0, 0, 0, 0.22);
}

.custom-section__icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.custom-section__emoji {
  font-size: 2rem;
  line-height: 1;
}

.custom-section__label {
  font-size: 0.75rem;
  color: var(--color-text-dim);
}

/* ---------- Contact ---------- */
.contact-panels {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: var(--space-10);
  align-items: stretch;
}

/* Two variants, chosen in JS based on whether a background photo is set:
   --photo (the reference site's dark-photo-with-white-text look) and
   --plain (a light card in the site's own black/white/green language, so
   the panel still looks intentional — not an empty box — when no photo has
   been uploaded, which is the common/default state). Both variants define
   the same set of --contact-* custom properties so every child rule below
   only has to reference the variable once. */
.contact-info-panel {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  min-height: 420px;
  display: flex;
}

.contact-info-panel--photo {
  align-items: flex-end;
  background: radial-gradient(ellipse 120% 80% at 30% 0%, rgba(62, 255, 163, 0.16), transparent 60%), linear-gradient(160deg, #1c1c24, #0e0e12);
  --contact-fg: #fff;
  --contact-fg-dim: rgba(255, 255, 255, 0.7);
  --contact-icon-bg: rgba(255, 255, 255, 0.12);
}

.contact-info-panel--photo .contact-info-panel__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0.55;
}

.contact-info-panel--photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 10, 14, 0.75), rgba(10, 10, 14, 0.4) 45%, rgba(10, 10, 14, 0.92));
}

/* The photo variant bottom-anchors text over a tall image on purpose — that
   layout looks empty and broken without a photo to fill the space, so the
   plain variant instead stretches its content the full card height. */
.contact-info-panel--plain {
  align-items: stretch;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  box-shadow: 0 20px 50px -30px rgba(0, 0, 0, 0.25);
  --contact-fg: var(--color-text);
  --contact-fg-dim: var(--color-text-dim);
  --contact-icon-bg: var(--color-accent-glow);
}

.contact-info-panel--plain::before {
  content: '';
  position: absolute;
  top: -20%;
  right: -20%;
  width: 65%;
  height: 65%;
  border-radius: 50%;
  background: var(--color-accent-glow);
  filter: blur(60px);
  pointer-events: none;
}

.contact-info-panel--plain .contact-info-panel__content {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--space-10) var(--space-8);
}

.contact-info-panel__content {
  position: relative;
  z-index: 1;
  padding: var(--space-10);
  width: 100%;
  color: var(--contact-fg);
}

.contact-info-panel__title {
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--contact-fg);
}

.contact-info-panel__subtitle {
  margin-top: var(--space-3);
  color: var(--contact-fg-dim);
  font-size: var(--fs-base);
  line-height: 1.5;
}

.contact-info-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-10);
}

.contact-info-item {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.contact-info-item__icon {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--contact-icon-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  overflow: hidden;
}

.contact-info-item__icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
}

.contact-info-item__label {
  font-size: var(--fs-base);
  color: var(--contact-fg);
}

.contact-form-panel {
  display: flex;
  flex-direction: column;
}

.contact-form-panel__title {
  font-size: var(--fs-xl);
  font-weight: 700;
}

.contact-form-panel__subtitle {
  margin-top: var(--space-3);
  color: var(--color-text-dim);
  font-size: var(--fs-base);
}

.contact-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: min-content;
  gap: var(--space-6);
  margin-top: var(--space-10);
}

.contact-form-grid .form-field--message {
  grid-column: 2;
  grid-row: 1 / 4;
  display: flex;
  flex-direction: column;
}

.contact-form-grid .form-field--message textarea {
  flex: 1;
  min-height: 160px;
}

.contact-form-grid .btn {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: var(--space-2);
}

.contact-form-grid .contact-form__status {
  grid-column: 1 / -1;
}

.required-mark {
  color: var(--color-accent-dim);
}

.form-field {
  position: relative;
}

.form-field label {
  display: block;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--fs-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-2);
  transition: color var(--duration-fast) var(--ease-out);
}

.form-field:focus-within label {
  color: var(--color-accent-dim);
}

.form-field input,
.form-field textarea {
  width: 100%;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-md);
  color: var(--color-text);
  transition: border-color var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out);
  resize: vertical;
}

.form-field__input-icon {
  position: relative;
  display: flex;
  align-items: center;
}

.form-field__input-icon .form-field__icon {
  position: absolute;
  left: var(--space-4);
  font-size: 0.95rem;
  pointer-events: none;
}

.form-field__input-icon input {
  padding-left: calc(var(--space-4) * 2 + 14px);
}

.form-field input:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--color-accent-dim);
  background: color-mix(in srgb, var(--color-accent) 4%, transparent);
  box-shadow: 0 0 0 3px var(--color-accent-glow);
}

.form-field--honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-form__status {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  min-height: 1.2em;
}

.contact-form__status[data-state='success'] {
  color: var(--color-accent-dim);
}

.contact-form__status[data-state='error'] {
  color: #ff6b6b;
}

/* ---------- Footer ---------- */
.site-footer {
  padding: var(--space-16) var(--page-margin-x) var(--space-32);
  max-width: var(--max-width);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--color-text-faint);
}

.site-footer__socials {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-4);
  align-items: center;
}

.site-footer__social-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  color: var(--color-text-dim);
  font-size: 0.9rem;
  transition: color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}

.site-footer__social-link:hover {
  color: var(--color-accent-dim);
  transform: translateY(-2px);
}

.site-footer__social-link img,
.site-footer__social-link svg {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ---------- Responsive ---------- */
@media (max-width: 860px) {
  .site-nav__list {
    position: fixed;
    inset: 0;
    z-index: 1;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    padding: var(--space-24) var(--page-margin-x);
    background: var(--color-surface-glass-strong);
    backdrop-filter: blur(20px);
    border: none;
    border-radius: 0;
    box-shadow: none;
    gap: var(--space-6);
    transform: translateX(100%);
    transition: transform var(--duration-base) var(--ease-out);
    pointer-events: none;
  }

  .site-nav__list .site-nav__link {
    font-size: var(--fs-lg);
  }

  .site-nav[data-open='true'] .site-nav__list {
    transform: translateX(0);
    pointer-events: auto;
  }

  .site-nav__toggle {
    display: flex;
  }

  .site-nav[data-open='true'] .site-nav__toggle .bar-1 {
    transform: translateY(6px) rotate(45deg);
  }
  .site-nav[data-open='true'] .site-nav__toggle .bar-2 {
    opacity: 0;
  }
  .site-nav[data-open='true'] .site-nav__toggle .bar-3 {
    transform: translateY(-6px) rotate(-45deg);
  }

  .contact-panels {
    grid-template-columns: 1fr;
  }

  .contact-info-panel {
    min-height: 320px;
  }

  .contact-form-grid {
    grid-template-columns: 1fr;
  }

  .contact-form-grid .form-field--message {
    grid-column: auto;
    grid-row: auto;
  }

  .mode-switch {
    bottom: var(--space-6);
  }

  .fullscreen-panel__content {
    padding: var(--space-10) var(--page-margin-x) var(--space-24);
  }

  .fullscreen-panel__close {
    top: var(--space-4);
    right: var(--space-4);
  }

  .fullscreen-panel__hero-caption {
    left: var(--space-4);
    right: var(--space-4);
    bottom: var(--space-4);
  }

  .hero {
    padding-top: var(--space-16);
    min-height: 100svh;
  }

  .hero__cta {
    width: 100%;
  }

  .hero__cta .btn {
    flex: 1;
    justify-content: center;
    /* Matches .mode-switch__btn exactly so the two pill controls the user
       sees stacked on mobile (hero CTAs, mode-switch tabs) read as the same
       size language instead of the CTAs looking oversized next to it. */
    padding: var(--space-2) var(--space-6);
    font-size: var(--fs-sm);
    white-space: nowrap;
  }

  .section-header {
    margin-bottom: var(--space-8);
  }

  .about__bio {
    margin-bottom: var(--space-16);
  }

  .timeline {
    padding-left: var(--space-6);
  }

  .timeline__dot {
    left: calc(-1 * var(--space-6) - 4px);
  }


  .btn--lg {
    padding: var(--space-3) var(--space-6);
    font-size: var(--fs-base);
  }
}

