/* ===== PINNED CELL STAGE =====
   The stage is 240vh tall and pins a 100vh viewport. The 3D cell renders
   into #cell-canvas; labels + connectors layer over the canvas in DOM/SVG.

   No site-wide grain overlay covers the stage -- grain is applied only
   to topbar / footer / main, none of which the stage belongs to. The
   candy plastic look stays clean. */

.stage {
  position: relative;
  /* Pull the stage up under the sticky topbar so .stage-pin can stick
     to viewport top from the very first pixel of scroll. Without this
     the stage starts ~62px down in the document, so the cell rides up
     with the page for that first ~62px before sticky kicks in --
     which read as "the page moves 1-2cm before the dissect starts".
     getStageProgress() in scroll.js subtracts the same topbar height
     so explode still begins at 0 on scroll=0. */
  margin-top: -62px;
  /* Tall enough to give the dissect ~220vh of scroll travel (about 30%
     more than before), plus a ~70vh "hold" zone at the end where the
     cell sits fully exploded so the user can read the labels without
     accidentally scrolling past. The explode formula in scene.js
     caps at 100% well before progress = 1, leaving the tail as hold. */
  height: 320vh;
  background: var(--paper);
}

/* Mobile keeps a tighter version of the same shape. */
@media (max-width: 760px) {
  .stage { height: 230vh; margin-top: -58px; }
}
@media (max-width: 420px) {
  .stage { margin-top: -50px; }
}
.stage-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  width: 100%;
  overflow: hidden;
}

#cell-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  cursor: grab;
  /* Desktop: pan-y so vertical scroll passes through OrbitControls.
     Mobile: auto -- let the browser handle scroll + page pinch-zoom
     with zero JS in the touch path. See controls.js mobile branch. */
  touch-action: pan-y;
}
@media (max-width: 760px) {
  #cell-canvas { touch-action: auto; cursor: default; }
}
#cell-canvas:active { cursor: grabbing; }

.connectors {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 2;
}
.connectors line {
  stroke-width: 1.5;
  stroke-dasharray: 3 4;
  stroke-linecap: round;
}

.labels { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.label {
  position: absolute; top: 0; left: 0;
  will-change: transform, opacity;
  pointer-events: auto;
}

/* ----- Mixed glassy + riso label cards -----
   Frosted-glass body (candy world), but a small pink "stamp" dot with
   green misregistration shadow on the meta row + a faint grain overlay
   at low opacity so they read as part of the same printed booklet. */
.label-card {
  display: inline-flex; flex-direction: column; gap: 6px;
  padding: 12px 16px 14px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(12px);
  border: 1.5px solid var(--ink);
  border-radius: 16px;
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
  white-space: nowrap;
  min-width: 210px;
  box-shadow:
    2.5px 2.5px 0 var(--riso-pink),
    0 4px 16px rgba(24, 40, 58, 0.07);
  position: relative;
  overflow: hidden;
}
.label-card::after {
  /* Subtle riso grain overlay, lower than tab pages so the candy still reads */
  content: "";
  position: absolute; inset: 0;
  background-image: url("/img/grain.svg");
  background-repeat: repeat;
  mix-blend-mode: multiply;
  opacity: 0.15;
  pointer-events: none;
  border-radius: inherit;
}
.label-card > * { position: relative; z-index: 1; }
.label-card:hover {
  transform: translateY(-2px);
  box-shadow:
    2.5px 2.5px 0 var(--riso-green),
    0 10px 28px rgba(24, 40, 58, 0.12);
}
.label-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex; gap: 8px; align-items: center;
}
.label-meta .dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--accent, var(--riso-pink));
  box-shadow: 1.5px 1.5px 0 var(--riso-green);
}
.label-meta .num { color: var(--ink); font-weight: 500; }
.label-meta .organelle { color: var(--accent, var(--ink-dim)); font-weight: 500; }
.label-title {
  font-size: 19px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--ink);
}
.label-arrow {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-dim);
}

/* ----- Hero overlay text ----- */
.stage-text {
  position: absolute;
  left: 5vw;
  /* Min 160px from bottom so the hero never overlaps the progress
     rail + scroll hint (which together occupy ~100px from the bottom).
     Scales up on tall viewports. */
  bottom: max(160px, 14vh);
  max-width: 560px;
  z-index: 4;
  pointer-events: none;
}
.kicker {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-bottom: 18px;
  display: flex; gap: 10px; align-items: center;
}
.kicker::before {
  content: ""; width: 28px; height: 2px;
  background: var(--riso-pink); border-radius: 2px;
  box-shadow: 0 2.5px 0 var(--riso-green);
}
.stage-text h1 {
  font-family: var(--font-display);
  font-size: clamp(46px, 5.8vw, 92px);
  line-height: 0.96;
  letter-spacing: -0.035em;
  font-weight: 600;
  margin-bottom: 22px;
  color: var(--ink);
}
.stage-text h1 em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--riso-pink);
  text-shadow: 2.5px 2px 0 var(--riso-green);
  letter-spacing: -0.02em;
}
.stage-text p {
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-dim);
  max-width: 460px;
}

/* ----- Scroll hint ----- */
.scroll-hint {
  position: absolute;
  left: 50%; bottom: 56px;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  display: flex; align-items: center; gap: 10px;
  z-index: 4;
  pointer-events: none;
  animation: bob 2.4s ease-in-out infinite;
}
@keyframes bob {
  0%, 100% { transform: translate(-50%, 0); opacity: 0.7; }
  50%      { transform: translate(-50%, 6px); opacity: 1; }
}

/* ----- Drag pill (one-time hint) ----- */
.drag-pill {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  padding: 8px 14px;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s;
  z-index: 4;
  box-shadow: 2px 2px 0 var(--riso-pink);
}
.drag-pill.visible { opacity: 1; }

/* ----- Recenter pill ----- */
.recenter-pill {
  position: absolute;
  top: 80px; right: 28px;
  z-index: 5;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 14px 9px 12px;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(10px);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--ink);
  cursor: pointer;
  box-shadow: 2px 2px 0 var(--riso-green);
  transition: transform 0.15s, box-shadow 0.15s, background 0.15s;
}
.recenter-pill:hover {
  transform: translateY(-1px);
  background: white;
  box-shadow: 2px 2px 0 var(--riso-pink), 0 10px 22px rgba(24, 40, 58, 0.14);
}
.recenter-pill .ico {
  width: 16px; height: 16px;
  display: inline-grid; place-items: center;
  border-radius: 50%;
  background: var(--riso-pink);
  color: var(--ink);
  font-size: 12px; font-weight: 700;
  line-height: 1;
  box-shadow: 1px 1px 0 var(--riso-green);
}

/* ----- Progress rail ----- */
.progress-rail {
  position: absolute;
  left: 50%; bottom: 16vh;
  transform: translateX(-50%);
  width: min(560px, 60vw);
  z-index: 4;
  pointer-events: none;
  transition: opacity 0.3s;
  display: flex; flex-direction: column; gap: 6px;
  align-items: stretch;
}
.rail-label {
  display: flex; justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  align-items: center;
}
.rail-label .pct {
  color: var(--ink);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  background: var(--paper-white);
  padding: 3px 8px;
  border-radius: 999px;
  border: 1.5px solid var(--ink);
  box-shadow: 1.5px 1.5px 0 var(--riso-pink);
  letter-spacing: 0.04em;
  min-width: 44px; text-align: center;
}
.rail-track {
  position: relative;
  height: 6px; border-radius: 999px;
  background: rgba(24, 40, 58, 0.10);
  overflow: visible;
}
.rail-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 0%; border-radius: 999px;
  background: linear-gradient(90deg,
    #ffd24a, #ff8763, #9be04a, #ff8fae, #8a5cd9);
  background-size: 200% 100%;
  transition: width 0.12s linear;
}
.rail-thumb {
  position: absolute; top: 50%; left: 0%;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--paper-white);
  border: 2px solid var(--ink);
  transform: translate(-50%, -50%);
  box-shadow: 2px 2px 0 var(--riso-pink);
  transition: left 0.12s linear;
}
.rail-thumb::after {
  content: ""; position: absolute;
  inset: 3px; border-radius: 50%;
  background: linear-gradient(135deg,
    #ffd24a, #ff8763 25%, #9be04a 50%, #ff8fae 75%, #8a5cd9);
}
.rail-ticks {
  position: relative; height: 14px;
  margin-top: 2px;
}
.rail-ticks .tick {
  position: absolute; top: 0;
  width: 8px; height: 8px; border-radius: 50%;
  transform: translateX(-50%);
  background: var(--c);
  border: 1.5px solid var(--ink);
}
.rail-ticks .tick-label {
  position: absolute;
  top: 14px;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

@media (max-width: 760px) {
  /* Hero text moves higher and shrinks so it stays readable above the
     scroll-hint and progress rail on small screens. */
  .stage-text { left: 6vw; right: 6vw; bottom: max(140px, 18vh); max-width: none; }
  .stage-text h1 { font-size: clamp(36px, 9vw, 56px); line-height: 1; }
  .stage-text p { font-size: 15px; line-height: 1.5; }
  .stage-text .kicker { margin-bottom: 12px; font-size: 10px; }

  /* Compact labels: smaller card, smaller text. Keep the arrow line --
     on mobile the whole card navigates (cutaway is desktop-only), so
     showing "view section ->" is the right affordance. */
  .label-card {
    min-width: 0;
    padding: 8px 12px 10px;
    box-shadow:
      2px 2px 0 var(--riso-pink),
      0 2px 8px rgba(24, 40, 58, 0.06);
  }
  .label-title { font-size: 14px; letter-spacing: -0.005em; }
  .label-meta { font-size: 9px; }
  .label-arrow { font-size: 10px; }

  .recenter-pill {
    top: 64px; right: 12px;
    padding: 7px 11px 7px 9px;
    font-size: 10px;
  }
  .recenter-pill .ico { width: 14px; height: 14px; font-size: 10px; }

  .drag-pill { font-size: 10px; padding: 7px 12px; letter-spacing: 0.10em; }

  .progress-rail { width: calc(100vw - 32px); bottom: 12vh; }
  .rail-label { font-size: 9px; letter-spacing: 0.08em; }
  .rail-label .pct { padding: 2px 6px; min-width: 36px; }
  .rail-ticks .tick-label { display: none; }

  .scroll-hint { bottom: 76px; font-size: 10px; letter-spacing: 0.12em; }
}

@media (max-width: 420px) {
  .stage-text { bottom: 16vh; }
  .stage-text h1 { font-size: clamp(30px, 9vw, 44px); }
  .stage-text p { font-size: 14px; }
  .recenter-pill .icon-text { display: none; }
}

/* ── Organelle click card ───────────────────────────────────
   Click any organelle in the 3D scene and this riso card slides in
   from the right with its name, blurb, and links. Built by
   /js/cell/organelle-clicks.js. Hidden by default, slides in on
   .is-open. The cell underneath stays put -- scroll dissection
   keeps working. */
.org-card {
  position: fixed;
  top: 86px;                  /* clear the sticky topbar */
  right: 0;
  width: min(380px, 92vw);
  max-height: calc(100vh - 110px);
  overflow: auto;
  z-index: 160;               /* above topbar (z:150) */
  background: var(--paper-white);
  border: 1.5px solid var(--ink);
  border-right: none;
  border-radius: 18px 0 0 18px;
  padding: 26px 28px 22px;
  box-shadow: -6px 6px 0 var(--riso-pink), 0 16px 36px rgba(0, 0, 0, 0.16);
  transform: translateX(110%);
  transition: transform 0.32s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.org-card.is-open { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
  .org-card { transition: none; }
}

.org-card-close {
  position: absolute;
  top: 12px; right: 14px;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--paper-white);
  border: 1.5px solid var(--ink);
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: grid; place-items: center;
  box-shadow: 2px 2px 0 var(--riso-green);
  padding: 0;
  font-family: inherit;
  transition: transform 0.12s, box-shadow 0.12s;
}
.org-card-close:hover {
  transform: translateY(-1px);
  box-shadow: 2px 2px 0 var(--riso-pink);
}

.org-card-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  text-transform: uppercase;
}
.org-card-dot {
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--accent, var(--riso-pink));
  box-shadow: 2px 2px 0 var(--riso-green);
}
.org-card-num { color: var(--ink-faint); }
.org-card-organelle { color: var(--ink-dim); }

.org-card-name {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
  margin-bottom: 12px;
  text-wrap: balance;
}

.org-card-blurb {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-dim);
  margin-bottom: 20px;
}

.org-card-links {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.org-card-link {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 16px;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: var(--paper-white);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-decoration: none;
  box-shadow: 3px 3px 0 var(--accent, var(--riso-pink));
  transition: transform 0.12s, box-shadow 0.12s;
}
.org-card-link:hover {
  transform: translateY(-2px);
  box-shadow: 3px 3px 0 var(--riso-green);
}
.org-card-link .arr { transition: transform 0.18s; }
.org-card-link:hover .arr { transform: translateX(3px); }

@media (max-width: 540px) {
  .org-card {
    top: auto;
    bottom: 0;
    right: 0; left: 0;
    width: auto;
    max-height: 60vh;
    border-radius: 18px 18px 0 0;
    border-right: 1.5px solid var(--ink);
    border-left: 1.5px solid var(--ink);
    border-bottom: none;
    box-shadow: 0 -6px 0 var(--riso-pink), 0 -16px 36px rgba(0, 0, 0, 0.16);
    transform: translateY(110%);
  }
  .org-card.is-open { transform: translateY(0); }
}

/* ── Mobile flat-SVG cell ─────────────────────────────────────
   Shown only on mobile (≤760px). The 3D stage is hidden at the
   same breakpoint so the two never overlap. */
.mobile-cell { display: none; }

@media (max-width: 760px) {
  .stage { display: none; }

  .mobile-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    padding: 28px 5vw 40px;
    background: var(--paper);
  }

  .mobile-cell-head {
    width: 100%;
    max-width: 480px;
  }
  .mobile-cell-head .kicker {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-dim);
    margin-bottom: 14px;
    display: flex; gap: 10px; align-items: center;
  }
  .mobile-cell-head h1 {
    font-size: clamp(36px, 10vw, 52px);
    font-weight: 600;
    letter-spacing: -0.03em;
    line-height: 1;
    color: var(--ink);
    margin-bottom: 14px;
  }
  .mobile-cell-head h1 em {
    font-family: var(--font-serif);
    font-style: italic;
    font-weight: 400;
    color: var(--riso-coral);
    text-shadow: 2px 1px 0 var(--riso-green);
  }
  .mobile-cell-head p {
    font-size: 14px;
    color: var(--ink-dim);
    line-height: 1.55;
    max-width: 44ch;
  }

  .mobile-cell-svg {
    width: 100%;
    max-width: 420px;
    height: auto;
    display: block;
  }

  /* Organelle tap states */
  .cell-organ { outline: none; }
  .cell-organ:focus-visible .org-hover-ring { opacity: 1 !important; }
}
