/* ============================================================
   projects.css — PROJECTS section (THE LAB)
   SPECIMEN pass: the giant section head is a mono specimen eyebrow
   ([ PROJECT_DB ✦ 4 ENTRIES ]); the flagship panel wears codename +
   hairline + two-sentence brief + mono readout. Its interactive demo
   (stage window, ask-my-brain, note card) was harvested from the
   retired standalone second-brain section; demo classes keep the
   .sb__* prefix, panel chrome uses .proj-feature__*.
   Below it: 3 placeholder lab cards (.glass, tilt + glare, status
   readout line).
   ============================================================ */

.proj {
  width: min(1200px, 100% - 3rem);
  margin-inline: auto;
  padding-block: clamp(5rem, 14vh, 9rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ---------- Header ---------- */
.proj__head {
  max-width: 46rem;
}

/* The head is a single mono eyebrow now — no display heading, no lede.
   Spacing under the eyebrow comes from .eyebrow's own margin. */

/* ============================================================
   Featured flagship panel — SECOND BRAIN
   Glass-LOOK panel without backdrop-filter: the stage inside is a
   transparent window onto the fixed universe canvas, and a frosted
   ancestor would blur the 3D scene away (same rule as the old
   second-brain section). Translucent fill + hairline only.
   ============================================================ */

.proj-feature {
  position: relative;
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
  padding: clamp(1.5rem, 3.2vw, 3rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
  background: rgba(14, 30, 66, 0.45); /* --bg-2 @ 45% */
  border: 1px solid rgba(143, 163, 200, 0.18); /* .glass border token */
  border-radius: 24px;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.08);
}

/* ---------- Featured: story column ---------- */

.proj-feature__top {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
  margin-bottom: clamp(1.25rem, 2.5vh, 2rem);
}

.proj-feature__name {
  /* specimen codename — .spec-label supplies family/size/tracking/color */
  margin: 0;
}

.proj-feature__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.4em 0.95em;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pop);
  border: 1px solid rgba(198, 245, 63, 0.4);
  border-radius: 999px;
  white-space: nowrap;
}

.proj-feature__badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pop);
  animation: proj-badge-pulse 2.2s ease-in-out infinite;
}

.proj-feature__rule {
  margin-bottom: clamp(1.25rem, 2.5vh, 1.75rem);
}

.proj-feature__para {
  color: var(--muted);
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.1rem);
  line-height: 1.65;
  max-width: 56ch;
  text-shadow: 0 1px 14px rgba(10, 22, 51, 0.75); /* stays legible over the halo */
}

/* Mono readout block: NODES/EDGES + STATUS/AI rows, lime values */
.proj-feature__readout {
  display: grid;
  gap: 0.15rem;
  margin-top: clamp(1.25rem, 2.5vh, 1.75rem);
}

.proj-feature__readout-row {
  display: block;
}

/* ---------- Featured: demo column ---------- */

.proj-feature__demo {
  display: grid;
  gap: 1.25rem;
  min-width: 0; /* keep grid column from blowing out */
}

/* Transparent window onto the constellation: the fixed #universe
   canvas renders behind all DOM, so the stage stays unfrosted —
   glass-style border only. */
.sb__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 640px;
  background: rgba(14, 30, 66, 0.12);
  border: 1px solid rgba(143, 163, 200, 0.18); /* .glass border token */
  border-radius: 20px;
  overflow: hidden;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y; /* vertical page scroll still works on touch */
}

.sb__stage.is-hovering-node {
  cursor: pointer;
}

.sb__stage.is-dragging {
  cursor: grabbing;
}

/* subtle corner glow on the stage frame */
.sb__stage::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 85% 0%, rgba(198, 245, 63, 0.06), transparent 55%);
  pointer-events: none;
}

/* Static fallback (body.universe-static → .is-static, synced by JS):
   a faint CSS star-dust stands in for the 3D constellation, and the
   sr note index becomes a visible, clickable list so every note is
   reachable. */
.sb__stage.is-static {
  background:
    radial-gradient(1.5px 1.5px at 22% 34%, rgba(242, 245, 255, 0.8), transparent 100%),
    radial-gradient(1px 1px at 68% 22%, rgba(242, 245, 255, 0.6), transparent 100%),
    radial-gradient(1px 1px at 81% 63%, rgba(242, 245, 255, 0.55), transparent 100%),
    radial-gradient(1.5px 1.5px at 42% 74%, rgba(242, 245, 255, 0.7), transparent 100%),
    radial-gradient(1px 1px at 12% 82%, rgba(242, 245, 255, 0.5), transparent 100%),
    radial-gradient(90% 90% at 55% 45%, rgba(107, 79, 187, 0.16), transparent 62%),
    rgba(14, 30, 66, 0.35);
}

.sb__stage.is-static .sb__sr {
  position: absolute;
  inset: 0;
  width: auto;
  height: auto;
  margin: 0;
  padding: 1.25rem 1.5rem;
  overflow: auto;
  clip: auto;
  clip-path: none;
  white-space: normal;
  border: 0;
  list-style: none;
  display: grid;
  gap: 0.35rem;
  align-content: center;
}

.sb__stage.is-static .sb__sr button {
  padding: 0.2em 0;
  background: none; /* override the base.css lime-pill button default */
  border-radius: 0;
  color: var(--ink);
  font-size: 0.95rem;
  font-weight: 400;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
  transition: color 0.2s ease;
}

.sb__stage.is-static .sb__sr button::before {
  content: '\2726'; /* ✦ */
  margin-right: 0.6em;
  color: var(--pop);
  font-size: 0.7em;
  vertical-align: 0.15em;
}

.sb__stage.is-static .sb__sr button:hover {
  color: var(--pop);
}

/* hover tooltip (positioned by JS, in stage coordinates) */
.sb__tooltip {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 220px;
  padding: 0.45em 0.8em;
  background: var(--pop);
  color: var(--bg);
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1.25;
  border-radius: 10px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 3;
}

.sb__tooltip.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Constellation callout tags (live universe only) ----------
   8 tiny mono tags ('01'..'08') projected onto the constellation nodes
   by js/sections/projects.js (rAF, group-local → world → NDC → stage px).
   The layer ignores pointer events; each tag is hoverable and shows the
   same tooltip as a node raycast hit. Never rendered in static mode. */
.sb-tags {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.sb-tag {
  position: absolute;
  left: 0;
  top: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 9px;
  letter-spacing: 0.22em;
  color: var(--muted);
  text-shadow: 0 1px 8px rgba(10, 22, 51, 0.9);
  pointer-events: auto;
  cursor: pointer;
  will-change: transform;
  transition: color 0.2s ease;
}

/* hairline stub anchoring the tag to its node */
.sb-tag::before {
  content: '';
  width: 10px;
  height: 1px;
  background: rgba(143, 163, 200, 0.55);
}

.sb-tag:hover {
  color: var(--pop);
}

.sb-tag.is-off {
  display: none;
}

.sb__stage.is-static .sb-tags {
  display: none;
}

/* ---------- Note card overlay ---------- */

.sb__note {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* display:flex above beats the UA [hidden] rule — restore it, or the
   (empty) card + backdrop show on load and block the stage. */
.sb__note[hidden] {
  display: none;
}

.sb__note-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 22, 51, 0.62);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Frosting + hairline ring come from .glass (base.css); keep the drop
   shadow for depth over the backdrop, merged with the glass inner light. */
.sb__note-card {
  position: relative;
  width: min(340px, calc(100% - 3rem));
  padding: 1.75rem 1.75rem 1.5rem;
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.08),
    0 24px 60px rgba(0, 0, 0, 0.45);
}

.sb__note-title {
  font-size: 1.35rem;
  margin-bottom: 0.75rem;
  padding-right: 2rem;
}

.sb__note-line {
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.5;
}

.sb__note-line + .sb__note-line {
  margin-top: 0.35em;
}

.sb__note-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 1px solid rgba(143, 163, 200, 0.45);
  border-radius: 50%;
  color: var(--ink);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.25s ease, color 0.25s ease, transform 0.25s ease;
}

.sb__note-close:hover {
  border-color: var(--pop);
  color: var(--pop);
  transform: rotate(90deg);
}

/* ---------- Ask my brain ---------- */

/* Panel chrome (frost, ring, radius) comes from .glass (base.css). */
.sb__ask {
  display: grid;
  gap: 0.6rem;
  padding: 1.25rem;
}

.sb__ask-label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: 0.01em;
}

.sb__ask-row {
  display: flex;
  gap: 0.75rem;
}

.sb__ask-input {
  flex: 1;
  min-width: 0;
  padding: 0.85em 1.1em;
  background: var(--bg-2);
  border: 1px solid rgba(143, 163, 200, 0.3);
  border-radius: 999px;
  color: var(--ink);
  font-size: 0.95rem;
  outline: none;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.sb__ask-input::placeholder {
  color: rgba(143, 163, 200, 0.6);
}

.sb__ask-input:focus {
  border-color: var(--pop);
  box-shadow: 0 0 0 3px rgba(198, 245, 63, 0.15);
}

.sb__ask-btn {
  flex-shrink: 0;
  padding: 0.85em 1.6em;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--bg);
  background: var(--pop);
  border-radius: 999px;
  cursor: pointer;
  transition: transform 0.25s ease;
}

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

.sb__answer {
  position: relative;
  min-height: 3.4em; /* reserve space so the layout doesn't jump */
  padding-left: 1.4em;
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.55;
}

.sb__answer::before {
  content: '\2192'; /* → */
  position: absolute;
  left: 0;
  top: 0;
  color: var(--pop);
  font-weight: 700;
}

.sb__answer:empty::before {
  content: none;
}

/* typewriter caret while an answer is printing */
.sb__answer.is-typing::after {
  content: '\258D'; /* ▍ */
  margin-left: 2px;
  color: var(--pop);
  animation: sb-caret-blink 0.85s steps(2, start) infinite;
}

@keyframes sb-caret-blink {
  to { visibility: hidden; }
}

/* ---------- Visually hidden (screen readers) ---------- */

.sb__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   Lab card grid (placeholder projects)
   ============================================================ */

.proj__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.75rem);
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
}

/* The li supplies the 3D perspective; JS reveals + hovers it. */
.proj-card {
  perspective: 1000px;
  min-width: 0;
}

/* Rotating panel (JS writes rotationX/rotationY here).
   Frosted glass + hairline border come from .glass (base.css) so the
   cards float over the 3D scene; the lime hover border overrides it. */
.proj-card__tilt {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  border-radius: 20px; /* chunkier than .glass default; glare inherits */
  padding: clamp(1.5rem, 2.4vw, 2.25rem);
  transform-style: preserve-3d;
  transition: border-color 0.3s ease;
  will-change: transform;
}

.proj-card:hover .proj-card__tilt {
  border-color: rgba(198, 245, 63, 0.55);
}

/* ---------- Card content (layered in 3D) ---------- */
.proj-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  transform-style: preserve-3d;
}

.proj-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  transform: translateZ(30px);
}

.proj-card__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  color: rgba(143, 163, 200, 0.55);
}

.proj-card__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.4em 0.95em;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pop);
  border: 1px solid rgba(198, 245, 63, 0.4);
  border-radius: 999px;
  white-space: nowrap;
}

.proj-card__badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pop);
  animation: proj-badge-pulse 2.2s ease-in-out infinite;
}

@keyframes proj-badge-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.2; }
}

.proj-card__name {
  font-size: clamp(1.9rem, 3vw, 2.7rem);
  letter-spacing: -0.01em;
  transform: translateZ(55px);
}

.proj-card__line {
  flex: 1;
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.55;
  transform: translateZ(40px);
}

/* Mono status readout under the one-liner (lime value via .text-pop) */
.proj-card__status {
  transform: translateZ(35px);
}

/* ---------- Tag chips (lime outline) ---------- */
.proj-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  transform: translateZ(30px);
}

.proj-card__tag {
  padding: 0.42em 0.95em;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pop);
  border: 1px solid rgba(198, 245, 63, 0.45);
  border-radius: 999px;
  white-space: nowrap;
}

/* ---------- Glare / sheen (position driven by JS via --gx/--gy) ---------- */
.proj-card__glare {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    420px circle at var(--gx, 50%) var(--gy, 50%),
    rgba(198, 245, 63, 0.14),
    rgba(242, 245, 255, 0.05) 40%,
    transparent 65%
  );
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
  transform: translateZ(2px);
}

.proj-card:hover .proj-card__glare {
  opacity: 1;
}

/* ---------- Responsive: stack on mobile ---------- */
@media (max-width: 900px) {
  .proj-feature {
    grid-template-columns: 1fr;
    gap: 2.25rem;
  }

  .proj-feature__para {
    max-width: none;
  }

  .sb__stage {
    aspect-ratio: 1 / 1;
    max-height: none;
  }

  .proj__grid {
    grid-template-columns: 1fr;
    max-width: 34rem;
  }

  .proj-card__name {
    font-size: clamp(1.8rem, 7vw, 2.4rem);
  }
}

@media (max-width: 480px) {
  .sb__ask-row {
    flex-direction: column;
  }

  .sb__ask-btn {
    align-self: flex-start;
  }
}

/* ---------- Reduced motion: no tilt, no glare — plain hover border ---------- */
@media (prefers-reduced-motion: reduce) {
  .proj-card__tilt {
    transform: none !important;
    will-change: auto;
  }

  .proj-card__glare {
    display: none;
  }

  .proj-card__badge-dot,
  .proj-feature__badge-dot {
    animation: none;
  }
}
