/* ═══════════════════════════════════════════════════════════════
   BASE STYLES - Shared across all themes
   Reset, Typography Base, Layout, Animations Core
   ═══════════════════════════════════════════════════════════════ */

/* ─── Shared Design Tokens ─── */
:root {
    /* Spacing Scale */
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 2rem;
    --spacing-2xl: 3rem;
    --spacing-3xl: 4rem;

    /* Border Radius */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --radius-full: 9999px;

    /* Transitions */
    --transition-fast: 150ms ease;
    --transition-normal: 300ms ease;
    --transition-slow: 500ms ease;
    --ease-out: cubic-bezier(0.33, 1, 0.68, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

    /* Z-Index Scale */
    --z-base: 1;
    --z-elevated: 10;
    --z-overlay: 100;
    --z-modal: 1000;
    --z-tooltip: 9999;

    /* Breakpoints (for reference in JS) */
    --breakpoint-sm: 640px;
    --breakpoint-md: 768px;
    --breakpoint-lg: 1024px;
    --breakpoint-xl: 1280px;

    /* Default Font Stacks */
    --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace;
    --font-display: var(--font-sans);

    /* Default Colors (themes override these) */
    --color-bg: #f8f7f4;
    --color-bg-secondary: #ffffff;
    --color-bg-tertiary: rgba(128, 128, 128, 0.1);
    --color-bg-hover: rgba(128, 128, 128, 0.1);
    --color-text: #1a1a1a;
    --color-text-secondary: #666666;
    --color-accent: #0f766e;
    --color-accent-hover: #0d9488;
    --color-border: rgba(0, 0, 0, 0.1);
}

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

html {
  scroll-behavior: smooth;
  font-size: 16px;
}

body {
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
  position: relative;
}

/* ─── Base Layout ─── */
#main-content {
  position: relative;
  z-index: 1;
}

/* ─── Section Base ─── */
/* Centralized section styling - themes should NOT override padding */
section,
.projects,
.about,
.contact,
.blog,
.timeline {
  position: relative;
  z-index: 10;
  padding: var(--section-padding-y, 4rem) var(--section-padding-x, 2rem);
  max-width: var(--section-max-width, 1200px);
  margin: 0 auto;
}

/* Git timeline section - full width, no horizontal padding for the graph */
.git-timeline-section {
  padding-left: 0;
  padding-right: 0;
  max-width: 100%;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
  box-sizing: border-box;
}

/* Mobile responsive padding for all sections */
@media (max-width: 768px) {
  section,
  .projects,
  .about,
  .contact,
  .blog,
  .timeline {
    padding: var(--section-padding-y-mobile, 2.5rem) var(--section-padding-x-mobile, 1rem);
  }

  .git-timeline-section {
    padding-left: 0;
    padding-right: 0;
  }
}

.hero {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
}

/* ─── Header Base ─── */
.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 100;
  transition: all 0.3s ease;
}

.header-brand {
  display: flex;
  align-items: center;
}

.brand-link {
  text-decoration: none;
  color: inherit;
  display: flex;
  align-items: center;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.nav {
  display: flex;
}

.nav a {
  text-decoration: none;
  transition: all 0.3s ease;
}

/* ─── Projects Grid Base ─── */
.projects-grid {
  display: grid;
}

.projects-grid-loading {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* ─── Project Card Base ─── */
.project-card {
  position: relative;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  display: block;
  transition: all 0.4s ease;
}

.project-media-container {
  position: relative;
  aspect-ratio: 16/9;
  overflow: hidden;
}

.project-image,
.project-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: filter 0.5s ease;
}

/* ─── Carousel Base ─── */
.project-carousel {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.carousel-slides {
  position: relative;
  width: 100%;
  height: 100%;
}

.carousel-slide {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.carousel-slide.active {
  opacity: 1;
}

.carousel-slide .project-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.carousel-btn {
  position: absolute;
  top: 50%;
  cursor: pointer;
  transition: all 0.3s ease;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
}

.project-card:hover .carousel-btn {
  opacity: 1;
}

.carousel-btn.prev { left: 8px; }
.carousel-btn.next { right: 8px; }

.carousel-dots {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  z-index: 10;
}

.carousel-dot {
  cursor: pointer;
  transition: all 0.3s ease;
}

/* ─── Tags Base ─── */
.tags {
  display: flex;
  flex-wrap: wrap;
}

.tag {
  transition: all 0.3s ease;
}

/* ─── Contact Base ─── */
.email-link {
  text-decoration: none;
  transition: all 0.3s ease;
}

.social-links {
  display: flex;
}

.social-links a {
  text-decoration: none;
  transition: all 0.3s ease;
}

/* ─── Footer Base ─── */
.footer {
  position: relative;
  z-index: 10;
  text-align: center;
}

/* ─── Focus States (Accessibility) ─── */
:focus {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* ─── Hover States ─── */
a, button {
  cursor: pointer;
}

/* ─── Base Animations ─── */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(8px); }
}

@keyframes pulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.fade-in-up {
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.8s ease;
}

.fade-in-up.visible {
  opacity: 1;
  transform: translateY(0);
}

/* No-JS safety net: if scripting is unavailable the reveal never fires, so the
   content would stay invisible. Show it outright in that case. (When JS runs,
   GSAP or the IntersectionObserver fallback drives the reveal as normal.) */
@media (scripting: none) {
  .fade-in-up { opacity: 1; transform: none; }
}

/* ─── Loading State ─── */
body.loading * {
  animation-play-state: paused !important;
}

/* ─── Hamburger Menu Button ─── */
.hamburger-menu {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  z-index: 101;
  margin-left: 0.5rem;
}

.hamburger-line {
  display: block;
  width: 22px;
  height: 2px;
  background-color: var(--color-text, #1a1a1a);
  border-radius: 2px;
  transition: all 0.3s ease;
}

/* Hamburger animation when open */
.hamburger-menu.open .hamburger-line:nth-child(1) {
  transform: rotate(45deg) translate(5px, 5px);
}

.hamburger-menu.open .hamburger-line:nth-child(2) {
  opacity: 0;
}

.hamburger-menu.open .hamburger-line:nth-child(3) {
  transform: rotate(-45deg) translate(5px, -5px);
}

/* Header controls container (theme + language switchers) */
.header-controls {
  display: flex;
  align-items: center;
}

/* ─── Base Responsive ─── */
@media (max-width: 768px) {
  .header {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0;
    padding: 0.75rem 1rem;
  }

  .header-brand {
    flex: 0 0 auto;
  }

  .header-right {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0;
  }

  /* Hide nav by default on mobile */
  .nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    background: var(--color-bg-secondary, var(--color-bg, #f8f7f4));
    padding: 0;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
    border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.1));
    z-index: 99;
  }

  /* Show nav when menu is open */
  .nav.mobile-open {
    display: flex;
  }

  .nav .nav-link {
    padding: 1rem 1.25rem;
    width: 100%;
    text-align: center;
    border-bottom: 1px solid var(--color-border, rgba(0, 0, 0, 0.05));
    min-height: 3.5rem;
    height: 3.5rem;
    line-height: 1.4;
    display: flex;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
  }

  .nav .nav-link:last-child {
    border-bottom: none;
  }

  /* Show hamburger menu on mobile */
  .hamburger-menu {
    display: flex;
  }

  /* Header controls - already visible via base styles */

  /* Move theme and language switchers into controls */
  .theme-switcher,
  .language-switcher {
    margin-left: 0.25rem;
  }

  .projects-grid {
    grid-template-columns: 1fr !important;
  }

  .social-links {
    flex-direction: column;
  }
}

/* ─── Custom Scrollbar Base ─── */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

/* ─── Theme-specific elements: hidden by default ─── */
.hero-ascii,
.hero-terminal,
.hero-stats,
.hero-blueprint-svg,
.contact-blueprint-svg,
.hero-annotation,
.section-number,
.section-prompt,
.section-divider,
.code-comment,
.email-prefix,
.cursor-blink,
.contact-prompt,
.footer-line,
.footer-exit,
.redline-note,
.stamp,
.coord-marker,
.footer-scale,
.cursor-coord,
/* 90s Retro elements - hidden by default */
.retro-marquee,
.hit-counter,
.under-construction,
.retro-badge,
.guestbook-cta,
.color-squares,
.best-viewed {
  display: none;
}

/* ─── About Card ─── */
.about-content {
  width: 100%;
  max-width: 100%;
}

.about-card,
.contact-card {
  position: relative;
  width: 100%;
}

.card-body {
  padding: 1rem;
}

/* ─── Section Header ─── */
.section-label {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* ─── Tech Grid (legacy, kept for back-compat) ─── */
.tech-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* ─── Craft block (replaces tech grid) ─── */
.craft-stack {
  margin-top: 1rem;
}

.craft-block {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem 1.25rem;
  border-left: 2px solid currentColor;
  border-color: var(--accent, currentColor);
  opacity: 0.95;
}

.craft-title {
  margin: 0;
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--accent, inherit);
}

.craft-description {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  opacity: 0.85;
}

/* ─── /now paragraph (replaces 4-bucket list) ─── */
.now-paragraph {
  margin: 0;
  line-height: 1.65;
  font-size: 1rem;
}

.now-inline-link {
  text-decoration: underline;
  text-underline-offset: 2px;
  color: inherit;
}

.now-paragraph-loading {
  opacity: 0.5;
  font-style: italic;
}

/* ─── Compact (no-image) project cards: 2-up grid in same row ─── */
.project-card.no-image {
  grid-column: span 1;
  position: relative;
}

.project-card.no-image .project-media-container {
  display: none;
}

/* Small type badge in the top-right so the card reads as an intentional
   "text mission" tile instead of a broken image card */
.project-card.no-image::before {
  content: attr(data-card-type);
  position: absolute;
  top: 0.85rem;
  right: 0.85rem;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border: 1px dashed currentColor;
  border-radius: 999px;
  opacity: 0.55;
  pointer-events: none;
}

/* ─── Responsive social links fix ─── */
@media (max-width: 768px) {
  .social-links {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1rem;
  }
}

/* ─── Blog Section Base ─── */
.blog-grid {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.blog-grid-loading {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem 0;
}

.skeleton-card {
  display: flex;
  gap: 1rem;
  padding: 1rem;
  background: rgba(128, 128, 128, 0.1);
  border-radius: 4px;
  animation: skeleton-pulse 1.5s ease-in-out infinite;
}

.skeleton-card::before {
  content: '';
  flex-shrink: 0;
  width: 180px;
  height: 120px;
  background: rgba(128, 128, 128, 0.2);
  border-radius: 4px;
}

.skeleton-card::after {
  content: '';
  flex: 1;
  height: 80px;
  background: rgba(128, 128, 128, 0.15);
  border-radius: 4px;
}

@keyframes skeleton-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.blog-card {
  display: flex;
  text-decoration: none;
  color: inherit;
  transition: all 0.3s ease;
  overflow: hidden;
}

.blog-card-image {
  flex-shrink: 0;
  width: 200px;
  height: 150px;
  overflow: hidden;
}

.blog-card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.blog-card:hover .blog-card-image img {
  transform: scale(1.05);
}

.blog-card-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1rem 1.5rem;
  min-width: 0;
}

.blog-card-title {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
  line-height: 1.3;
}

.blog-card-excerpt {
  font-size: 0.95rem;
  opacity: 0.8;
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.blog-card-meta {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 0.75rem;
  font-size: 0.85rem;
  opacity: 0.6;
}

.blog-footer {
  display: flex;
  justify-content: center;
  padding: 2rem 0;
}

.view-all-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  transition: all 0.3s ease;
}

.no-articles {
  text-align: center;
  padding: 2rem;
  opacity: 0.6;
}

/* Blog Responsive */
@media (max-width: 768px) {
  .blog-card {
    flex-direction: column;
  }

  .blog-card-image {
    width: 100%;
    height: 200px;
  }

  .blog-card-excerpt {
    white-space: normal;
    -webkit-line-clamp: 2;
    display: -webkit-box;
    -webkit-box-orient: vertical;
  }
}

/* ─── Global Visitor Counter ─── */
.visitor-counter {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  margin: 1rem auto;
  font-family: inherit;
  font-size: 0.9rem;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.visitor-counter:hover {
  background: rgba(255, 255, 255, 0.08);
}

.visitor-icon {
  font-size: 1.1rem;
}

.visitor-label {
  opacity: 0.7;
}

.visitor-count {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  min-width: 4ch;
  text-align: center;
}

.visitor-count.loading {
  animation: pulse 1.5s infinite;
}

/* ─── Writing Section ─── */
.writing-intro {
  margin-bottom: 1.75rem;
  opacity: 0.75;
  font-size: 0.95rem;
  max-width: 38rem;
}

.projects-grid-hidden {
  display: none !important;
}

/* Cards without URL (e.g. internal mission descriptions) */
.project-card.no-url {
  cursor: default;
}

/* ─── /Now Section (current status) ─── */
/* Force the /now card-header to render even in themes that hide .card-header globally */
#now .card-header,
.now-card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* Code comment markers around the intro — hidden by default, shown only in terminal */
.code-comment-marker {
  display: none;
}
body[data-theme="terminal"] .code-comment-marker {
  display: inline;
  opacity: 0.55;
}

.now-date {
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
  font-size: 0.875em;
  letter-spacing: 0.02em;
}

.now-intro {
  margin-bottom: 1.25rem;
}

.now-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.now-list-loading {
  opacity: 0.5;
  font-style: italic;
}

.now-item {
  display: grid;
  grid-template-columns: 1.5rem 7rem 1fr;
  gap: 0.75rem;
  align-items: baseline;
  line-height: 1.55;
}

@media (max-width: 640px) {
  .now-item {
    grid-template-columns: 1.5rem 1fr;
  }
  .now-item .now-label {
    grid-column: 2;
  }
  .now-item .now-value {
    grid-column: 1 / -1;
    padding-left: 2.25rem;
  }
}

.now-arrow {
  opacity: 0.6;
}

.now-label {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.85em;
  opacity: 0.75;
}

.now-value {
  opacity: 0.95;
}

.now-link {
  text-decoration: underline;
  text-underline-offset: 2px;
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
}

.now-link-arrow {
  font-size: 0.85em;
  opacity: 0.7;
}

/* ─── Hero Quote (intro paragraph, left-aligned) ─── */
.hero-quote {
  display: block;
  max-width: 640px;
  margin: 0 auto var(--spacing-lg);
  text-align: left;
  position: relative;
}

.hero-quote-paragraph {
  margin: 0;
  line-height: 1.7;
  font-size: inherit;
  color: inherit;
}

/* Legacy multi-line rules kept for back-compat with any cached HTML */
.hero-quote-line {
  margin: 0;
  line-height: 1.6;
  font-size: inherit;
  color: inherit;
}

.hero-quote-final {
  margin-top: 0.6rem;
  font-weight: 600;
  font-style: italic;
}

/* ── Interactive 3D heart (lazy-loaded, theme-aware) ─────────────────── */
.heart-experiment {
  position: relative;
  width: 100%;
  /* Reserve space up-front so lazy-loading causes no layout shift (CLS). */
  height: clamp(380px, 64vh, 640px);
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
}
/* The heart lives inside a centred "box" (a glass display case). The box gives
   the bloom/explosion a defined frame to dissolve into (see the edge fade in the
   shader) so it never clips into an ugly rectangle, and makes the surrounding
   margin read as intentional framing rather than a too-small heart. */
.heart-stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: min(620px, 88vw);
  align-self: center;
  margin: 0 auto;
  border-radius: 14px;
  overflow: hidden;
}
/* The frame itself — a subtle bevelled case, tinted by the current theme. */
.heart-stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, currentColor 6%, transparent),
    inset 0 0 40px color-mix(in srgb, currentColor 7%, transparent);
}
/* Corner ticks for a precise, "specimen mounted in a case" feel. */
.heart-stage::after {
  content: "";
  position: absolute;
  inset: 9px;
  z-index: 2;
  pointer-events: none;
  border-radius: 8px;
  background:
    linear-gradient(currentColor, currentColor) left   top    / 14px 1px no-repeat,
    linear-gradient(currentColor, currentColor) left   top    / 1px 14px no-repeat,
    linear-gradient(currentColor, currentColor) right  top    / 14px 1px no-repeat,
    linear-gradient(currentColor, currentColor) right  top    / 1px 14px no-repeat,
    linear-gradient(currentColor, currentColor) left   bottom / 14px 1px no-repeat,
    linear-gradient(currentColor, currentColor) left   bottom / 1px 14px no-repeat,
    linear-gradient(currentColor, currentColor) right  bottom / 14px 1px no-repeat,
    linear-gradient(currentColor, currentColor) right  bottom / 1px 14px no-repeat;
  opacity: 0.28;
}
.heart-experiment canvas {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
  /* Allow normal page scrolling over the canvas on touch devices while a
     horizontal drag spins the heart. */
  touch-action: pan-y;
  cursor: grab;
}
.heart-experiment canvas.grabbing {
  cursor: grabbing;
}

/* ── Per-theme framing flavour ──────────────────────────────────────── */
/* terminal: a crisp green CRT bezel with a faint glow + square corners. */
body[data-theme="terminal"] .heart-stage { border-radius: 3px; }
body[data-theme="terminal"] .heart-stage::before {
  border-color: rgba(73, 255, 73, 0.45);
  box-shadow:
    0 0 16px rgba(73, 255, 73, 0.14),
    inset 0 0 36px rgba(73, 255, 73, 0.08);
}
body[data-theme="terminal"] .heart-stage::after { border-radius: 1px; opacity: 0.5; }

/* blueprint: a precise cyan technical frame. */
body[data-theme="blueprint"] .heart-stage { border-radius: 2px; }
body[data-theme="blueprint"] .heart-stage::before {
  border-color: rgba(118, 230, 255, 0.5);
  box-shadow: inset 0 0 0 1px rgba(118, 230, 255, 0.12);
}
body[data-theme="blueprint"] .heart-stage::after {
  opacity: 0.6;
  background:
    linear-gradient(#76e6ff, #76e6ff) left   top    / 18px 1px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) left   top    / 1px 18px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) right  top    / 18px 1px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) right  top    / 1px 18px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) left   bottom / 18px 1px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) left   bottom / 1px 18px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) right  bottom / 18px 1px no-repeat,
    linear-gradient(#76e6ff, #76e6ff) right  bottom / 1px 18px no-repeat;
}

/* retro90s: a chunky beige bevelled "window" case. */
body[data-theme="retro90s"] .heart-stage {
  border-radius: 0;
  border: 3px solid;
  border-color: #ffffff #808080 #808080 #ffffff;   /* outset bevel */
  background: #c0c0c0;
}
body[data-theme="retro90s"] .heart-stage::before {
  border-color: #000;
  box-shadow: inset 1px 1px 0 #dfdfdf, inset -1px -1px 0 #808080;
}
body[data-theme="retro90s"] .heart-stage::after { display: none; }
.heart-experiment-caption {
  position: relative;
  z-index: 1;
  align-self: center;
  margin: 0 0 1.2rem;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: inherit;
  opacity: 0.55;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .heart-experiment canvas { cursor: default; }
  .heart-experiment-caption { opacity: 0.4; }
}

