/* ============================================================
   Solar System — components.css
   Reusable primitives: glass panel, pill button, nav, orbit ring,
   planet node, readout label, planet selector, source tag,
   section heading, return control.
   ============================================================ */

/* ── glass panel (floating card) ────────────────────────── */
.panel {
  position: relative; width: 100%; max-width: var(--maxw);
  display: flex; flex-direction: column;
  padding: clamp(20px, 2.6vw, 40px);
  border-radius: var(--r-card);
  background: linear-gradient(150deg, rgba(18,65,74,.42) 0%, rgba(10,30,38,.6) 44%, rgba(8,17,15,.78) 100%);
  border: 1px solid var(--glass-brd);
  box-shadow: var(--shadow-card);
  backdrop-filter: blur(22px) saturate(1.1);
  -webkit-backdrop-filter: blur(22px) saturate(1.1);
  overflow: hidden;
}
.panel::before { /* top edge sheen */
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  background: linear-gradient(180deg, var(--glass-hi), transparent 22%); opacity:.5;
}
.panel > * { position: relative; z-index: 1; }

.glass {
  background: var(--glass-fill); border: 1px solid var(--glass-brd);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}

/* ── nav ────────────────────────────────────────────────── */
.nav { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.brand { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 700; letter-spacing: -.02em; }
.brand__mark { color: var(--accent); display: inline-flex; filter: drop-shadow(0 0 10px rgba(245,185,66,.45)); }
.brand__word { font-size: 1.05rem; }
.nav__links { display: flex; gap: 4px; }
.nav__links a { padding: 8px 14px; border-radius: var(--r-pill); color: var(--text-mid); font-weight: 500; font-size: .94rem; transition: color .2s, background .2s; }
/* attribute-presence, not ="true": js/reveal.js writes aria-current="true" on the
   landing, while the article pages hand-author the semantically correct
   aria-current="page". Matching only "true" left the current page unhighlighted. */
.nav__links a:hover, .nav__links a[aria-current] { color: var(--text-hi); background: rgba(255,255,255,.05); }

/* ── buttons / pills ────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid transparent; border-radius: var(--r-pill);
  font-family: var(--font-ui); font-weight: 600; font-size: .95rem;
  padding: 11px 18px; transition: transform .25s var(--ease), background .25s, border-color .25s, box-shadow .25s, color .25s;
}
.btn__chev { transition: transform .25s var(--ease); flex: none; }
.btn:hover .btn__chev { transform: translateX(3px); }
.btn--lg { padding: 14px 24px; font-size: 1rem; }
.btn--primary {
  background: linear-gradient(180deg, var(--accent), var(--accent-warm));
  color: var(--accent-ink);
  box-shadow: 0 10px 26px -10px rgba(245,155,61,.6), 0 1px 0 rgba(255,255,255,.35) inset;
}
.btn--primary:hover { transform: translateY(-2px); box-shadow: 0 16px 32px -12px rgba(245,155,61,.68), 0 1px 0 rgba(255,255,255,.4) inset; }
.btn--ghost { background: var(--glass-fill); border-color: var(--glass-brd); color: var(--text-hi); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.btn--ghost:hover { border-color: var(--glass-brd-strong); background: rgba(255,255,255,.05); transform: translateY(-2px); }
.btn--sm { padding: 8px 14px; font-size: .88rem; }

/* ── orrery ─────────────────────────────────────────────── */
/* --size is the ONLY dimension ever set (base + every breakpoint/state) —
   width/height simply read it, so it can be transitioned as one typed
   custom property (registered in main.css) without distorting into an oval. */
.orrery {
  --size: min(48vw, 600px);
  position: relative; width: var(--size); height: var(--size);
  transition: --size .5s var(--ease);
}
.orrery__stage { position: absolute; inset: 0; }

/* sun (visual anchor) — layered plasma gradient + restrained bloom.
   A slow-rotating low-opacity mottle (::before) suggests granulation even
   at this small scale, without the cost of the full feature treatment
   (see .sun-visual in sections.css for the large, textured Sun). */
.sun { --sun-size: clamp(52px, 8%, 78px); position: absolute; top: 50%; left: 50%; width: var(--sun-size); height: var(--sun-size); aspect-ratio: 1; padding: 0; line-height: 0; transform: translate(-50%,-50%); border-radius: 50%; z-index: 5; }
.sun__core {
  position: relative; display: block; width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  isolation: isolate;
  background: radial-gradient(circle at 40% 36%, #fffaf0 0%, #ffe6ad 12%, var(--accent) 40%, var(--accent-warm) 72%, #9a4a10 100%);
  box-shadow: 0 0 26px 5px rgba(245,185,66,.5), 0 0 80px 20px rgba(255,155,61,.24), inset 0 0 16px 2px rgba(154,74,16,.4);
  animation: sun-pulse 6s ease-in-out infinite;
}
.sun__core::before {
  content: ""; position: absolute; inset: -35%; border-radius: 50%;
  background:
    radial-gradient(circle at 20% 25%, rgba(255,255,255,.8) 0 6%, transparent 8%),
    radial-gradient(circle at 65% 15%, rgba(255,255,255,.6) 0 5%, transparent 7%),
    radial-gradient(circle at 80% 55%, rgba(255,255,255,.7) 0 6%, transparent 8%),
    radial-gradient(circle at 35% 70%, rgba(255,255,255,.55) 0 5%, transparent 7%);
  background-size: 46% 46%;
  mix-blend-mode: overlay; opacity: .5;
  animation: sun-churn 22s linear infinite;
}
.sun:hover .sun__core, .sun:focus-visible .sun__core, .sun.is-active .sun__core { box-shadow: 0 0 36px 8px rgba(245,185,66,.66), 0 0 110px 26px rgba(255,155,61,.32), inset 0 0 16px 2px rgba(154,74,16,.4); }
@keyframes sun-pulse { 0%,100%{ transform: scale(1);} 50%{ transform: scale(1.045);} }
@keyframes sun-churn { to { transform: rotate(360deg); } }

/* orbit rings (structural guides — subtle) */
.orbit { position: absolute; top: 50%; left: 50%; width: var(--d); height: var(--d); transform: translate(-50%,-50%); border-radius: 50%; border: 1px solid var(--glass-brd); pointer-events: none; transition: border-color .3s, box-shadow .3s; }
.orbit--hot { border-color: var(--glass-brd-strong); box-shadow: 0 0 26px -8px rgba(42,125,140,.45) inset; }
.orbit__spin { position: absolute; inset: 0; border-radius: 50%; animation: spin var(--period) linear infinite; }
.orbit__arm { position: absolute; inset: 0; transform: rotate(var(--start, 0deg)); }
@keyframes spin { to { transform: rotate(360deg); } }

/* planet node (real link — navigates; hover/focus previews) */
.planet { position: absolute; top: 0; left: 50%; width: var(--pd); height: var(--pd); transform: translate(-50%, -50%); border-radius: 50%; pointer-events: auto; z-index: 4; display: block; }
.planet::after { content:""; position:absolute; inset:-10px; border-radius:50%; } /* expanded hit target */
.planet__body {
  position: absolute; inset: 0; border-radius: 50%; isolation: isolate;
  background:
    radial-gradient(circle at 33% 30%, rgba(255,255,255,.55), rgba(255,255,255,0) 42%),
    radial-gradient(circle at 70% 76%, rgba(0,0,0,.45), rgba(0,0,0,0) 58%),
    radial-gradient(circle at 50% 50%, transparent 62%, rgba(0,0,0,.28) 100%),
    var(--c);
  box-shadow: 0 4px 10px -3px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.06) inset;
  animation: spin-rev var(--period) linear infinite;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
@keyframes spin-rev { to { transform: rotate(-360deg); } }

/* per-planet character — small CSS-only cues by family, no images
   (small nodes stay pure CSS; textures are reserved for the large
   planet-page orb). Sits above the shading, below hover/focus scaling. */
.planet__body::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  pointer-events: none; mix-blend-mode: overlay; opacity: .65;
}
.planet[data-planet="mercury"] .planet__body::after,
.planet[data-planet="mars"] .planet__body::after {
  background-image:
    radial-gradient(circle at 26% 62%, rgba(0,0,0,.5) 0 9%, transparent 10%),
    radial-gradient(circle at 62% 28%, rgba(0,0,0,.4) 0 7%, transparent 8%),
    radial-gradient(circle at 78% 66%, rgba(255,255,255,.3) 0 5%, transparent 6%);
}
.planet[data-planet="venus"] .planet__body::after,
.planet[data-planet="earth"] .planet__body::after {
  background-image:
    radial-gradient(circle at 38% 72%, rgba(255,255,255,.4), transparent 42%),
    radial-gradient(circle at 72% 24%, rgba(255,255,255,.3), transparent 36%);
}
.planet[data-planet="jupiter"] .planet__body::after,
.planet[data-planet="saturn"] .planet__body::after {
  background-image: repeating-linear-gradient(4deg,
    rgba(255,255,255,.16) 0 8%, transparent 8% 16%, rgba(0,0,0,.14) 16% 22%, transparent 22% 32%);
}
.planet[data-planet="uranus"] .planet__body::after,
.planet[data-planet="neptune"] .planet__body::after {
  background-image: radial-gradient(circle at 68% 32%, rgba(255,255,255,.32), transparent 48%);
}
.planet:hover .planet__body,
.planet:focus-visible .planet__body,
.planet.is-active .planet__body {
  transform: scale(1.3);
  box-shadow: 0 6px 16px -3px rgba(0,0,0,.6), 0 0 16px 2px var(--c), 0 0 0 1px rgba(255,255,255,.16) inset;
}
/* loading + disabled states */
.planet.is-loading .planet__body { animation: pulse-load 1s ease-in-out infinite; }
@keyframes pulse-load { 0%,100%{ opacity:.5 } 50%{ opacity:1 } }
.planet[aria-disabled="true"] { pointer-events: none; opacity: .4; }

/* saturn ring */
.planet--ringed .planet__body::before {
  content:""; position:absolute; top:50%; left:50%; width:212%; height:64%;
  transform: translate(-50%,-50%) rotate(-18deg); border-radius:50%;
  border:2px solid rgba(230,206,150,.8); box-shadow: 0 0 8px rgba(230,206,150,.32);
}

/* persistent planet name tags — so the map is never eight anonymous dots.
   Two counter-rotating wrappers keep each label upright and screen-below
   its node without swinging: .planet__tagspin cancels the orbital spin,
   .planet__tagstart cancels the arm's fixed start angle (--start inherited
   from .orbit__arm). Non-interactive; frozen with the orrery when paused. */
.planet__tagspin, .planet__tagstart { position: absolute; inset: 0; pointer-events: none; }
.planet__tagspin { animation: spin-rev var(--period) linear infinite; }
.planet__tagstart { transform: rotate(calc(var(--start, 0deg) * -1)); }
.planet__label {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%); margin-top: 7px;
  white-space: nowrap; pointer-events: none;
  font-family: var(--font-ui); font-weight: 600; font-size: .72rem; letter-spacing: .02em;
  color: var(--text-mid); text-shadow: 0 1px 3px rgba(0,0,0,.72), 0 0 2px rgba(0,0,0,.6);
  opacity: .76; transition: opacity .25s var(--ease), color .25s var(--ease);
}
.planet:hover .planet__label,
.planet:focus-visible .planet__label,
.planet.is-active .planet__label { color: var(--text-hi); opacity: 1; }

/* pause the system while the visitor reads/interacts, or when it is
   scrolled off-screen (is-paused toggled by IntersectionObserver) */
.orrery__stage:hover .orbit__spin,
.orrery__stage:hover .planet__body,
.orrery__stage:hover .planet__tagspin,
.orrery__stage:focus-within .orbit__spin,
.orrery__stage:focus-within .planet__body,
.orrery__stage:focus-within .planet__tagspin,
.orrery__stage.is-paused .orbit__spin,
.orrery__stage.is-paused .planet__body,
.orrery__stage.is-paused .planet__tagspin { animation-play-state: paused; }

/* ── readout (frosted preview — name, type, one fact, explore) ──
   The panel is a pass-through overlay: the container takes NO pointer events
   (pointer-events: none) so moving the cursor across it still reaches the
   planets behind — it informs, it never traps. Only its own controls
   (Open / Return / arrows, below) opt back in to the pointer. */
.readout {
  position: absolute; left: -4%; bottom: -3%; width: min(300px, 68%);
  padding: 17px 19px; border-radius: var(--r-lg);
  background: linear-gradient(160deg, rgba(20,70,80,.5), rgba(9,24,30,.64));
  border: 1px solid var(--glass-brd); box-shadow: var(--shadow-float);
  backdrop-filter: blur(16px) saturate(1.1); -webkit-backdrop-filter: blur(16px) saturate(1.1);
  transition: box-shadow .3s var(--ease), border-color .3s var(--ease);
  pointer-events: none;
  z-index: 6;
}
.readout:has(#readoutBody:not([hidden])) { border-color: var(--glass-brd-strong); }
.readout__hint { color: var(--text-lo); font-size: .86rem; }
.readout__body { display: grid; gap: 10px; }
.readout__head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.readout__dot { width: 12px; height: 12px; border-radius: 50%; background: var(--c, var(--accent)); box-shadow: 0 0 10px 1px var(--c, var(--accent)); flex: none; }
.readout__name { font-family: var(--font-display); font-weight: 700; font-size: 1.2rem; letter-spacing: -.02em; }
.readout__type { color: var(--text-lo); font-size: .76rem; margin-left: auto; }
.readout__fact { color: var(--text-mid); font-size: .9rem; }
.readout__fact b { color: var(--text-hi); font-weight: 600; }
.readout__explore { align-self: start; }
/* Return control + fun-facts appear only in Explorer mode (toggled hidden
   by js/explorer.js); compact single-column facts inside the panel. */
.readout__exit { align-self: start; margin-bottom: 10px; }
.readout__facts { grid-template-columns: 1fr; gap: 8px; margin-bottom: 2px; }
.readout__facts .fact-item { padding: 10px 12px 10px 32px; font-size: .9rem; }
.readout__facts .fact-item::before { left: 12px; top: 15px; }

/* only the controls opt back in to the pointer (parent is pass-through) */
.readout__explore, .readout__exit, .readout__arrow { pointer-events: auto; }

/* prev / next planet stepper — injected by js/solar-system.js. With the
   selector list hidden under JS (see sections.css), these arrows + the orbit
   itself are the planet navigation; they cycle the previewed planet in orbit
   order and drive the same shared readout. */
.readout__nav { display: flex; gap: 8px; margin-top: 12px; }
.readout__arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--r-pill);
  background: var(--glass-fill); border: 1px solid var(--glass-brd); color: var(--text-hi);
  transition: border-color .2s var(--ease), background .2s var(--ease), transform .2s var(--ease);
}
.readout__arrow:hover,
.readout__arrow:focus-visible { border-color: var(--glass-brd-strong); background: rgba(255,255,255,.06); transform: translateY(-1px); }
.readout__arrow:active { transform: translateY(0); }
.readout__arrow svg { width: 16px; height: 16px; }

/* ── planet selector / legend strip (semantic nav + no-JS fallback) ── */
.selector {
  display: flex; align-items: center; gap: clamp(12px, 3vw, 34px); flex-wrap: wrap;
  padding-top: 22px; margin-top: auto; border-top: 1px solid rgba(150,205,210,.12);
}
.selector__label { font-family: var(--font-display); font-weight: 600; font-size: .82rem; color: var(--text-mid); white-space: nowrap; }
.selector__list { display: flex; flex-wrap: wrap; gap: 4px 6px; flex: 1; }
.selector__list a { display: inline-flex; align-items: center; gap: 7px; padding: 6px 12px; border-radius: var(--r-pill); font-size: .86rem; color: var(--text-mid); transition: color .2s, background .2s; }
.selector__list a::before { content:""; width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--text-lo)); box-shadow: 0 0 8px var(--c, transparent); flex: none; }
.selector__list a:hover, .selector__list a.is-active { color: var(--text-hi); background: rgba(255,255,255,.05); }

/* ── data-source indicator ──────────────────────────────── */
.source-tag { display: inline-flex; align-items: center; gap: 6px; color: var(--text-lo); font-size: .74rem; white-space: nowrap; }
.source-tag a { color: var(--text-mid); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--glass-brd-strong); }
.source-tag a:hover { color: var(--text-hi); }

/* ── section heading + return control (planet pages) ────── */
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.section-head h2 { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; letter-spacing: -.02em; }
.back { display: inline-flex; align-items: center; gap: 8px; color: var(--text-mid); font-weight: 500; font-size: .92rem; padding: 8px 14px; border-radius: var(--r-pill); transition: color .2s, background .2s; }
.back:hover { color: var(--text-hi); background: rgba(255,255,255,.05); }
.back svg { transition: transform .25s var(--ease); }
.back:hover svg { transform: translateX(-3px); }

/* ── landing hero (restrained lede; the orrery dominates) ── */
.hero { flex: 1; display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); align-items: center; gap: clamp(24px, 4vw, 64px); padding: clamp(18px, 3vw, 44px) 0; }
.hero__lede { max-width: 32ch; }
/* proportional lift — more sure of itself, but still clearly subordinate
   to the intro peak and the orrery it introduces (deliberately << 6rem). */
.hero__title { font-family: var(--font-display); font-weight: 800; font-size: clamp(1.9rem, 3.6vw, 3rem); line-height: 1.02; letter-spacing: -.035em; text-wrap: balance; }
.hero__title .accent { color: var(--accent); }
.hero__sub { margin-top: 18px; color: var(--text-mid); font-size: clamp(.98rem, 1.1vw, 1.08rem); max-width: 44ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }
.hero__orrery { display: grid; place-items: center; }

/* entrance (one authored moment, exponential ease from visible-safe default) */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.panel { animation: rise .7s var(--ease) both; }
.hero    { animation: rise .8s var(--ease) .05s both; }
.selector { animation: rise .8s var(--ease) .12s both; }

/* ── mission rows as buttons (landing only) ─────────────────
   .mission-item itself lives in planet.css and stays a plain <div> on the planet
   pages. These rules are element+class (0,1,1) so they win over that file's
   class-only rules regardless of load order. */
button.mission-item {
  width: 100%; text-align: left; color: inherit; cursor: pointer;
  grid-template-columns: auto auto 1fr;
}
button.mission-item:hover,
button.mission-item:focus-visible {
  border-color: var(--glass-brd-strong); background: rgba(255,255,255,.06);
}
.mission-item__more {
  grid-column: 3; justify-self: end; align-self: center;
  color: var(--accent); font-size: .8rem; font-weight: 600; white-space: nowrap;
  opacity: .72; transition: opacity .2s var(--ease), transform .2s var(--ease);
}
button.mission-item:hover .mission-item__more,
button.mission-item:focus-visible .mission-item__more { opacity: 1; transform: translateX(2px); }

/* ── mission detail dialog ──────────────────────────────────
   A native <dialog>: focus trapping, Escape, the backdrop and returning focus to
   the trigger are all the browser's job here, not ours. */
.mission-dialog {
  width: min(620px, calc(100vw - 32px));
  max-height: min(82vh, 760px);
  padding: clamp(20px, 3vw, 32px);
  border: 1px solid var(--glass-brd-strong);
  border-radius: var(--r-card);
  background: linear-gradient(155deg, rgba(18,65,74,.97), rgba(8,17,15,.99));
  color: var(--text-hi);
  box-shadow: var(--shadow-card);
  overflow: auto;
}
.mission-dialog::backdrop { background: rgba(4,10,9,.72); backdrop-filter: blur(4px); }
.mission-dialog__title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.4rem, 3vw, 1.9rem); letter-spacing: -.025em;
}
.mission-dialog__meta {
  margin-top: 7px; color: var(--accent); font-size: .8rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
.mission-dialog__note { margin-top: 14px; color: var(--text-mid); font-size: 1.02rem; }
.mission-dialog__facts { margin-top: 18px; grid-template-columns: 1fr; }
.mission-dialog__links {
  margin-top: 20px; padding-top: 16px; display: grid; gap: 10px;
  border-top: 1px solid rgba(150,205,210,.14);
}
.mission-dialog__linkrow { display: flex; flex-wrap: wrap; gap: 8px; }
.mission-dialog__close { margin-top: 22px; }

/* ── liquid-chrome primary CTA (JS-enhanced; amber pill otherwise) ── */
.btn.has-liquid { position: relative; overflow: hidden; background: #0a1512; border-color: var(--glass-brd-strong); color: var(--text-hi); box-shadow: 0 10px 26px -12px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.05) inset; }
.btn.has-liquid:hover { transform: translateY(-2px); box-shadow: 0 16px 34px -14px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.09) inset; }
.liquid-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; border-radius: inherit; }
.liquid-label { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 8px; }
