/* ============================================================
   mv2 — NEW Hero section (additive, isolated)
   Design ref: dark near-black + purple accents, text left,
   portrait right with purple eclipse glow, square outlines,
   dot grids, floating code panel. No dependencies.
   All classes prefixed mv2- to avoid any collision.
   ============================================================ */

.mv2-hero {
  /* local palette (does not touch site vars) */
  --mv2-accent: #8B5CF6;
  --mv2-accent-2: #7C3AED;
  --mv2-text: #F5F4F8;
  --mv2-muted: #9CA3AF;
  --mv2-bg0: #050308;
  --mv2-bg1: #0B0612;
  --mv2-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Cascadia Mono", "Liberation Mono", monospace;
  --mv2-display: var(--font-red-hat-display, "Red Hat Display"), "Segoe UI", Arial, sans-serif;

  position: relative;
  z-index: 3;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  /* TASK (user, responsive): COLUMN, not row. As a row flex container the
     .mv2-marker (position:static at <=860px) became a SECOND flex item that
     stole ~209px and squeezed .mv2-hero__inner to its min-content (181px
     inside a 390px viewport). A column with stretch makes the inner always
     span the real viewport width; justify-content keeps the old vertical
     centring on desktop. */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  /* ADDITIVE-EDIT (user): no hero background — the site's own dot-field +
     gradient canvases show through (transparent) */
  background: transparent;
  color: var(--mv2-text);
}

/* faint ambient purple bleed, right half */
.mv2-hero__bleed {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(55% 60% at 82% 55%, rgba(139, 92, 246, 0.07), transparent 70%);
}

/* ── layout ─────────────────────────────────────────────────── */
.mv2-hero__inner {
  position: relative;
  width: 100%;
  max-width: 1500px;
  margin-inline: auto;
  padding: clamp(3rem, 7vh, 5.5rem) clamp(1.5rem, 5vw, 72px);
  display: grid;
  grid-template-columns: minmax(0, 46%) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4.5rem);
  align-items: center;
  /* TASK (user): grid children must be allowed to shrink below their
     content's min-content width. Without this the wide code panel forced
     the whole hero to ~969px inside a 390px viewport. */
  min-width: 0;
}

.mv2-hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(1.05rem, 2.4vh, 1.6rem);
  z-index: 4;
  min-width: 0;
}

/* ── eyebrow ────────────────────────────────────────────────── */
.mv2-eyebrow {
  margin: 0;
  font-family: var(--mv2-mono);
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  font-weight: 500;
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  gap: 14px;
}
.mv2-eyebrow__dash {
  width: clamp(56px, 6vw, 92px);
  height: 2px;
  background: linear-gradient(90deg, var(--mv2-accent), transparent);
}

/* ── name ───────────────────────────────────────────────────── */
.mv2-name {
  margin: 0;
  font-family: var(--mv2-display);
  font-weight: 800;
  font-size: clamp(2.9rem, 7.2vw, 5.6rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
}
.mv2-name__white { color: var(--mv2-text); }
.mv2-name__accent { color: var(--mv2-accent); }

/* ── role / subtitle ────────────────────────────────────────── */
.mv2-role {
  margin: 0;
  font-family: var(--mv2-mono);
  font-weight: 600;
  font-size: clamp(1.2rem, 2.1vw, 1.85rem);
  line-height: 1.35;
  color: var(--mv2-text);
}
.mv2-role__accent { color: var(--mv2-accent); }

/* ── lede ───────────────────────────────────────────────────── */
.mv2-lede {
  margin: 0;
  max-width: 46ch;
  font-family: var(--mv2-mono);
  font-size: clamp(0.92rem, 1.05vw, 1.02rem);
  line-height: 1.8;
  color: var(--mv2-muted);
}

/* ── CTA ────────────────────────────────────────────────────── */
.mv2-cta {
  margin-top: clamp(0.6rem, 2vh, 1.4rem);
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 13px 22px;
  font-family: var(--mv2-mono);
  font-size: 1rem;
  font-weight: 500;
  color: var(--mv2-text);
  background: rgba(139, 92, 246, 0.04);
  border: 1px solid var(--mv2-accent);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}
.mv2-cta:hover {
  background: rgba(139, 92, 246, 0.12);
  box-shadow: 0 0 28px rgba(139, 92, 246, 0.25);
  transform: translateY(-1px);
}
.mv2-cta__arrow { width: 18px; height: 18px; flex: none; }

/* ── visual side ────────────────────────────────────────────── */
.mv2-hero__visual {
  position: relative;
  height: min(78vh, 740px);
  min-height: 460px;
  z-index: 2;
  min-width: 0;
}

/* ADDITIVE-EDIT (user): the portrait comes back as PARTICLE DOTS
   (the site's own js/mina-hero.js canvas, untouched) — so the new
   hero's flat img portrait, eclipse halo and grain are display-off.
   Their code stays here; flip display back to restore. */
.mv2-eclipse { display: none; }
.mv2-portrait { display: none; }
.mv2-hero__visual::after { content: none !important; }
.mv2-hero__bleed { display: none; }

/* purple eclipse glow behind the head */
.mv2-eclipse {
  position: absolute;
  top: 4%;
  left: 50%;
  transform: translateX(-50%);
  width: min(36vw, 480px);
  aspect-ratio: 1;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle,
    rgba(139, 92, 246, 0.50) 0%,
    rgba(124, 58, 237, 0.26) 34%,
    rgba(124, 58, 237, 0.10) 55%,
    transparent 70%);
  filter: blur(2px);
}

/* portrait — the provided asset, bottom melts into the section */
.mv2-portrait {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  height: 96%;
  width: auto;
  max-width: none;
  user-select: none;
  -webkit-user-drag: none;
  filter: contrast(1.08) brightness(0.97) saturate(0.82);
  -webkit-mask-image: linear-gradient(180deg, #000 68%, transparent 97%);
  mask-image: linear-gradient(180deg, #000 68%, transparent 97%);
}

/* stipple/grain illusion over the portrait area */
.mv2-hero__visual::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.14;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  -webkit-mask-image: radial-gradient(70% 82% at 50% 46%, #000 55%, transparent 90%);
  mask-image: radial-gradient(70% 82% at 50% 46%, #000 55%, transparent 90%);
}

/* ── TASK 3: glass code card BEHIND the dots portrait ─────────
   Provided CSS used verbatim as base; size/pos tuned only enough
   to sit centered behind the particle portrait (not over face). */
.mv2-glass-card {
  /* TASK (user, final pass): "glass box slightly smaller, proportionate to
     the portrait". Desktop was hitting the 480px cap (480x480 card around a
     478px portrait) — a visibly larger frame than the image it holds. 420px
     keeps the same square glassmorphism, same position, same portrait
     containment, just a tighter frame. The <=860px rule already capped the
     card at 420px, so mobile is unchanged; only the >=1280px sizes move. */
  width: min(100%, 420px);
  aspect-ratio: 1 / 1;
  height: auto;
  background: rgba(15, 10, 24, 0.72);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 20px;
  border: 1px solid rgba(139, 92, 246, 0.35);
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.55),
    0 0 42px rgba(124, 58, 237, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -1px 0 rgba(255, 255, 255, 0.1),
    inset 0 0 2px 1px rgba(255, 255, 255, 0.1);
  /* EDIT (final): anchored to the TOP OF THE DOCUMENT (absolute, not
     fixed) so it sits ON the portrait and scrolls WITH the page; up and
     left of its previous screen position, tucked behind the portrait. */
  position: absolute;
  overflow: hidden;
  left: auto;
  right: 0;     /* inside .mv2-hero__visual, not the viewport */
  top: 0;
  transform: none;
  z-index: 3;
}
.mv2-glass-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.8), transparent);
}
.mv2-glass-card::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 100%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.8), transparent, rgba(255, 255, 255, 0.3));
}

/* ── TASK 1: VengeanceUI FlipText (ported 1:1 from flip-text.json) ──
   The registry item ships the TSX only; this is its consumer-side CSS:
   chars flip on X, honoring the component's own --flip-* variables. */
.mv2-flip {
  display: inline-block;
  line-height: 1;
  perspective: 1000px;
}
.mv2-flip .word {
  display: inline-block;
  white-space: nowrap;
  transform-style: preserve-3d;
}
.mv2-flip .flip-char {
  display: inline-block;
  position: relative;
  transform-style: preserve-3d;
  animation: mv2-flip-char var(--flip-duration, 2.2s) var(--flip-delay, 0s) var(--flip-iteration, infinite);
}
@keyframes mv2-flip-char {
  0% { transform: rotateX(0deg); }
  50% { transform: rotateX(360deg); }
  100% { transform: rotateX(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .mv2-flip .flip-char { animation: none; }
}
/* (old role-prefix/slot rules removed — replaced by MorphText component) */

/* ── MorphText (VengeanceUI, copy-paste values) ──
   Keyframes from the component's own <style> block, verbatim.
   The rotator keeps height:1.2em + word spans absolutely centered. */
.mv2-morph {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;  /* EDIT (final): left-aligned — one line with the rest */
  font-weight: 700;
  filter: url(#mv2-morph-goo);
}
.mv2-morph .morph-text-container {
  position: relative;
  user-select: none;
  /* EDIT (final): bigger typography for the morph word */
  font-size: clamp(1.7rem, 3vw, 2.6rem);
  line-height: 1.2;
}
.mv2-morph .morph-word-rotator {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 1.2em;
  min-width: 14ch;
}
.mv2-morph .morph-word {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
  white-space: nowrap;
  animation-name: morph-word-rotate;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-fill-mode: both;
}
/* EDIT (final): the fixed capital "A" sits before the morph slot on the
   same line, matching the morph color/weight. */
.mv2-morph__prefix {
  margin-right: 10px;
  line-height: 1.2;
}
@keyframes morph-word-rotate {
  0% { opacity: 0; filter: blur(20px); transform: translate(-50%, -50%) scale(0.8); }
  5% { opacity: 0.5; filter: blur(10px); }
  15%, 35% { opacity: 1; filter: blur(0px); transform: translate(-50%, -50%) scale(1); }
  45% { opacity: 0.5; filter: blur(10px); }
  50%, 100% { opacity: 0; filter: blur(20px); transform: translate(-50%, -50%) scale(1.2); }
}
@keyframes morph-fade-up {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── TASK 2: SocialFlipButton — VERBATIM from the pasted component
   (light-mode class resolution, unmodified values) ── */
.mv2-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;             /* gap-4 */
  padding: 16px;         /* p-4 */
}
.mv2-social__pill {
  position: relative;    /* group relative */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;              /* gap-2 */
  border-radius: 16px;   /* rounded-2xl */
  /* EDIT (final): dark glass look (was bg-white) */
  background: rgba(15, 10, 24, 0.6);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(139, 92, 246, 0.35);
  padding: 16px;         /* p-4 */
  margin-left: -2.5ch;   /* EDIT (user-tuned) */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 0 30px rgba(124, 58, 237, 0.10);
}
.mv2-social__lines {
  position: absolute;
  inset: -1px;           /* -inset-[1px] */
  border-radius: 16px;
  overflow: hidden;
  pointer-events: none;
}
.mv2-social__line {
  position: absolute;
  left: 0;
  height: 1px;           /* h-[1px] */
  width: 100%;
  background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.5), transparent); /* via-black/50 */
}
.mv2-social__line--top { top: 0; animation: mv2-line-r 2.5s linear infinite; }
.mv2-social__line--bot { bottom: 0; animation: mv2-line-l 2.5s linear infinite; }
@keyframes mv2-line-r { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes mv2-line-l { from { transform: translateX(100%); } to { transform: translateX(-100%); } }
.mv2-node {
  position: relative;
  width: 40px;           /* h-10 w-10 */
  height: 40px;
  cursor: pointer;
  perspective: 1000px;
}
.mv2-node__tip {
  position: absolute;
  left: 50%;
  top: 0;
  z-index: 50;
  white-space: nowrap;
  border-radius: 8px;    /* rounded-lg */
  background: #171717;   /* bg-neutral-900 (light-mode resolution) */
  padding: 6px 12px;     /* px-3 py-1.5 */
  font-size: 12px;       /* text-xs */
  font-weight: 600;      /* font-semibold */
  color: #ffffff;        /* text-white */
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2), 0 8px 10px -6px rgba(0, 0, 0, 0.2); /* shadow-xl */
  opacity: 0;
  transform: translate(-50%, 10px) scale(0.8);
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
  pointer-events: none;
}
.mv2-node__tip::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 50%;
  width: 8px;            /* h-2 w-2 */
  height: 8px;
  transform: translateX(-50%) rotate(45deg);
  background: #171717;   /* bg-neutral-900 (light-mode resolution) */
}
.mv2-node:hover .mv2-node__tip { opacity: 1; transform: translate(-50%, -50px) scale(1); }
.mv2-flipper {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.8s cubic-bezier(0.34, 1.3, 0.64, 1);
}
/* EDIT (user round 2): hover on the PILL flips ALL nodes together
   (component behavior: isHovered lives on the container) */
.mv2-social__pill.is-flipped .mv2-flipper { transform: rotateY(180deg); }
.mv2-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.mv2-face--front {
  /* EDIT (final): dark glass faces (was light neutral-100) */
  background: rgba(23, 23, 23, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: #e5e5e5;
  font-size: 18px;       /* text-lg */
  font-weight: 700;      /* font-bold */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);  /* shadow-sm */
}
.mv2-face--back {
  /* EDIT (final): dark icon face to match */
  background: rgba(10, 6, 16, 0.85);
  color: #A78BFA;        /* violet accent keeps brand icons readable */
  transform: rotateY(180deg);
}
.mv2-face--back svg { width: 18px; height: 18px; fill: currentColor; }

/* ── TASK 6: BottomNavBar (provided component, ported values) ── */
.mv2-navbar {
  position: fixed;
  left: 50%;
  top: 16px;          /* EDIT (user): navbar at the TOP, not bottom */
  bottom: auto;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px;
  height: 52px;
  min-width: 320px;
  max-width: 95vw;
  width: fit-content;
  background: rgba(15, 10, 24, 0.72);   /* EDIT (user): same glass as .mv2-glass-card */
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(139, 92, 246, 0.35);
  border-radius: 9999px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55), 0 0 42px rgba(124, 58, 237, 0.12);
  animation: mv2-nav-in 0.6s cubic-bezier(0.22, 1.2, 0.36, 1) both;
}
@keyframes mv2-nav-in {
  from { transform: translateX(-50%) scale(0.9); opacity: 0; }
  to { transform: translateX(-50%) scale(1); opacity: 1; }
}
.mv2-navbar__btn {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  height: 40px;
  min-width: 44px;
  padding: 8px 12px;
  border: 0;
  border-radius: 9999px;
  background: transparent;
  color: #9CA3AF;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}
.mv2-navbar__btn:hover { background: rgba(255, 255, 255, 0.06); }
.mv2-navbar__btn svg {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
  transition: color 0.2s;
}
.mv2-navbar__btn.is-active { background: rgba(139, 92, 246, 0.15); color: #A78BFA; }
.mv2-navbar__btn:active { transform: scale(0.97); }
.mv2-navbar__label {
  overflow: hidden;
  display: flex;
  align-items: center;
  max-width: 72px;
  width: 0;
  opacity: 0;
  margin-left: 0;
  white-space: nowrap;
  font-family: var(--mv2-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.9;
  transition: width 0.35s cubic-bezier(0.34, 1.3, 0.64, 1), margin-left 0.19s, opacity 0.19s;
}
.mv2-navbar__btn.is-active .mv2-navbar__label { width: 72px; opacity: 1; margin-left: 8px; color: #A78BFA; }
.mv2-navbar__label span { overflow: hidden; text-overflow: ellipsis; }
@media (prefers-reduced-motion: reduce) {
  .mv2-social__line--top, .mv2-social__line--bot, .mv2-navbar { animation: none; }
  .mv2-flipper, .mv2-node__tip { transition: none; }
}

/* ── geometric square outlines ──────────────────────────────── */
.mv2-square {
  position: absolute;
  border: 1px solid rgba(139, 92, 246, 0.48);
  pointer-events: none;
}
.mv2-square--a { width: 112px; height: 112px; left: 4%; top: 34%; }
.mv2-square--b { width: 86px; height: 86px; left: calc(4% + 58px); top: calc(34% + 44px); border-color: rgba(139, 92, 246, 0.30); }
.mv2-square--c { width: 64px; height: 64px; right: 2%; bottom: 6%; border-color: rgba(139, 92, 246, 0.35); }
.mv2-square--d { width: 44px; height: 44px; right: calc(2% + 44px); bottom: calc(6% + 34px); border-color: rgba(139, 92, 246, 0.25); }

/* ── dot grids ──────────────────────────────────────────────── */
.mv2-dots {
  position: absolute;
  pointer-events: none;
  background-image: radial-gradient(rgba(139, 92, 246, 0.55) 1.6px, transparent 1.7px);
  background-size: 22px 22px;
}
.mv2-dots--tr { width: 148px; height: 132px; right: 6%; top: 7%; }
.mv2-dots--bl { width: 96px; height: 96px; left: 3%; bottom: 8%; }

/* ── floating code panel (vertical card, v2) ────────────────── */
.mv2-code {
  position: absolute;
  right: clamp(8px, 4vw, 56px);
  bottom: 4%;
  /* v2 (TASK 4): narrower + taller — vertical code card, not a wide strip */
  /* v3 (5-task round): slightly narrower still + noticeably taller, with an
     internal scroll area so code can never spill outside the card. */
  display: flex;
  flex-direction: column;
  width: clamp(200px, 15.5vw, 234px);
  min-width: 0;
  max-width: 100%;
  z-index: 5;
  background: rgba(11, 7, 18, 0.84);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(139, 92, 246, 0.35);
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55), 0 0 42px rgba(124, 58, 237, 0.12);
  /* v2 (TASK 4): subtle float — up ~10px + slight vertical expand, then back */
  animation: mv2-float 6s ease-in-out infinite;
  transform-origin: 50% 100%;
  will-change: transform;
}
@keyframes mv2-float {
  0%, 100% { transform: translateY(0) scaleY(1); }
  50% { transform: translateY(-10px) scaleY(1.025); }
}
@media (prefers-reduced-motion: reduce) {
  .mv2-code { animation: none; }
}
.mv2-code__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid rgba(139, 92, 246, 0.18);
}
.mv2-code__icon {
  font-family: var(--mv2-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--mv2-accent);
}
.mv2-code__dots { display: flex; gap: 6px; }
.mv2-code__dot { width: 8px; height: 8px; border-radius: 50%; }
.mv2-code__dot--teal { background: #2DD4BF; }
.mv2-code__dot--purple { background: #8B5CF6; }
.mv2-code__dot--pink { background: #EC4899; }
.mv2-code__body {
  margin: 0;
  min-width: 0;
  padding: 14px 16px 16px;
  font-family: var(--mv2-mono);
  font-size: 12.5px;
  line-height: 1.7;
  color: #E5E7EB;
  /* v3 (5-task round): taller editor body. The code scrolls INSIDE the card
     (vertical when it does not fit, horizontal only when a line is too wide);
     nothing can spill outside the container. */
  /* v4 (final round): the code must continue DOWNWARD, not sideways. Each
     logical line is an inline <code>, so they used to run together on one long
     row (scrollWidth 967px vs 232px of box). A block line + pre-wrap makes
     every line its own row and wraps the long ones inside the box, so nothing
     extends horizontally any more. Box size/height untouched. */
  height: 156px;
  max-height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.mv2-code__body > code { display: block; }
.mv2-code__body > code > code {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.mv2-tok-kw { color: #A78BFA; }
.mv2-tok-id { color: #F9FAFB; }
.mv2-tok-str { color: #67E8F9; }
.mv2-tok-val { color: #FBBF24; }
.mv2-tok-p { color: #9CA3AF; }

/* ── bottom-right marker ────────────────────────────────────── */
.mv2-marker {
  position: absolute;
  right: clamp(1.5rem, 5vw, 72px);
  bottom: clamp(16px, 3.2vh, 30px);
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mv2-mono);
  font-size: 13px;
  color: var(--mv2-muted);
  z-index: 4;
}
.mv2-marker__line {
  width: 70px;
  height: 1px;
  background: linear-gradient(90deg, var(--mv2-accent), transparent);
}

/* ── entrance (self-contained; no site animations touched) ──── */
@keyframes mv2-rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: translateY(0); }
}
.mv2-rise { opacity: 0; animation: mv2-rise 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) forwards; }
.mv2-rise:nth-child(1) { animation-delay: 0.05s; }
.mv2-rise:nth-child(2) { animation-delay: 0.13s; }
.mv2-rise:nth-child(3) { animation-delay: 0.21s; }
.mv2-rise:nth-child(4) { animation-delay: 0.29s; }
.mv2-rise:nth-child(5) { animation-delay: 0.37s; }
.mv2-hero__visual.mv2-rise { animation-delay: 0.2s; }
@media (prefers-reduced-motion: reduce) {
  .mv2-rise { animation: none; opacity: 1; }
}

/* ── integration guards (ADDITIVE ONLY: hide, never remove) ────
   The site's previous hero (data-home-hero) and its portrait
   layer (js/mina-hero.js) remain in the DOM fully intact; the
   new mv2 hero takes the first slot, so these are display-gated
   to avoid a double hero. Remove these two rules to restore.

   ADDITIVE-EDIT (user): the particle portrait layer is BACK.
   (Its up+right position is set inside js/mina-hero.js — inline
   styles there beat this stylesheet, so only display is managed
   here.) */
main[data-page-content] > section[data-home-hero] { display: none; }
.mv2-glass-card > .mina-hero-portrait { display: block; }

/* ── tablet ─────────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .mv2-hero__inner { grid-template-columns: minmax(0, 50%) minmax(0, 1fr); }
  /* TASK (user, responsive): the clamped 64vh collapsed the grid row at
     ~1024x768, pushing the visual column (and with it the glass card +
     portrait host) out of the rendered flow — at 1024x768 the card showed
     a scaled 420px box with NO portrait in it. The visual must be able to
     grow to its content here instead of being height-capped. */
  .mv2-hero__visual { min-height: min(64vh, 600px); height: auto; }
  .mv2-code { width: clamp(280px, 32vw, 400px); }
}

/* ── mobile: stack, don't shrink ────────────────────────────── */
@media (max-width: 860px) {
  .mv2-hero { min-height: auto; }
  .mv2-hero__inner {
    /* minmax(0, 1fr): the single column must be able to shrink below the
       code panel's min-content width (plain 1fr kept it at 969px). */
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    padding-top: 5.5rem;   /* clear the fixed site header */
    padding-bottom: 4.5rem;
  }
  .mv2-hero__copy { align-items: flex-start; min-width: 0; }
  .mv2-hero__visual {
    /* auto height: the glass card + code panel now stack IN FLOW here, so
       the hero grows naturally instead of clipping them */
    height: auto;
    min-height: 0;
    min-width: 0;
    order: 2;
  }
  /* glass card stacks BELOW the copy, centred, always inside the viewport */
  .mv2-glass-card {
    position: relative;
    left: auto;
    right: auto;
    top: auto;
    margin-inline: auto;
    /* plain 100% + max-width (NOT min(100%,…)): a percentage inside min()
       resolves against a parent this element itself sizes — a cyclic
       dependency that collapsed the card to ~148px on a 390px viewport. */
    width: 100%;
    max-width: 420px;
  }
  .mv2-eclipse { width: min(72vw, 380px); }
  .mv2-portrait { height: 94%; }
  .mv2-square--a { width: 72px; height: 72px; left: 2%; top: 26%; }
  .mv2-square--b { width: 54px; height: 54px; left: calc(2% + 38px); top: calc(26% + 30px); }
  .mv2-dots--tr { width: 110px; height: 96px; right: 4%; }
  .mv2-dots--bl { width: 72px; height: 72px; }
  .mv2-code {
    position: relative;
    right: auto;
    bottom: auto;
    width: min(100%, 380px);
    margin: 1.25rem auto 0;
  }
  /* the contact pill must wrap instead of overflowing the narrow column */
  .mv2-social { padding: 16px 0; justify-content: flex-start; min-width: 0; }
  .mv2-social__pill {
    margin-left: 0;
    max-width: 100%;
    flex-wrap: wrap;
    justify-content: center;
  }
  .mv2-marker { position: static; justify-content: flex-end; padding: 1.2rem clamp(1.5rem, 5vw, 72px) 0; margin-left: auto; }
  /* NOTE: the morph rotator's own 14ch floor (~209-247px) is NO LONGER an
     offender now that the column is genuinely full width (342px at 390) —
     and it MUST keep a real width: its words are absolutely centred at
     left:50%, so collapsing it to 0 throws them off-screen. Left as-is. */
}

/* ============================================================
   TASK (user, final responsive pass) — NAVBAR ON PHONES
   Desktop keeps this navbar exactly as it looks today. On a phone
   the pill was 344px wide on a 390px screen: a hard min-width:320px
   floor plus the 72px active label, so every button was padded out
   and the bar ate the full width. Below, the pill is allowed to
   shrink to its icons (min-width:0), the label expansion — a desktop
   affordance with no room on a phone — is dropped, and the buttons
   tighten. All 5 items stay; active state still reads via the
   background + colour. The site's own header bar is tightened too
   (not removed) so the two nav layers stop crowding each other.
   ============================================================ */
@media (max-width: 640px) {
  nav.mv2-navbar {
    min-width: 0;
    height: 46px;
    padding: 5px;
    gap: 2px;
  }
  nav.mv2-navbar .mv2-navbar__btn {
    min-width: 40px;
    padding: 7px 9px;
  }
  nav.mv2-navbar .mv2-navbar__label { display: none; }

  /* the site header: 80px tall with 32px gutters is desktop chrome —
     tightened for phones, desktop untouched (media-scoped) */
  header.h-navbar-height {
    height: 56px;
    padding-left: 16px;
    padding-right: 16px;
  }
}
