/* ===== SONIKOSMOS: SOL-ω SPHAERA — page-only styling ===== */
/* Everything here is scoped under .sphaera-wrap so it never touches the
   shared .btn/.wrap rules in style.css used by every other page — the
   pill-shaped controls are a deliberate SPHAERA-only identity, not a
   site-wide restyle. Uses the same CSS custom properties
   (--bg/--fg/--accent/--mono/--line/--panel) already defined in
   style.css, so it stays visually part of the same family. */

.sphaera-wrap .btn { border-radius: 999px; padding: 10px 22px; }
.sphaera-wrap .btn:hover { box-shadow: 0 0 0 1px var(--fg); }

.sphaera-section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.15em;
  color: var(--accent); margin: 28px 0 10px;
}

/* ---------- Connection: one box, Request -> Input/Output -> Connect,
   with the two MIDI device pickers visually distinct (squared, boxed)
   from the pill-shaped action buttons around them ---------- */
.sphaera-connect-box {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 16px 18px;
  margin-bottom: 20px;
}
.midi-io-group { display: flex; gap: 10px; flex-wrap: wrap; }
.io-slot {
  display: flex; flex-direction: column; gap: 4px;
  border: 1px solid var(--line);
  background: #050505;
  padding: 6px 10px;
  min-width: 180px;
}
.io-slot-label {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--muted);
}
.io-slot select {
  background: transparent; border: none; color: var(--fg);
  font-family: var(--mono); font-size: 12px; padding: 0;
}

/* ---------- Mode switch: the two most important decisions on the page,
   always both visible, centered, sized to feel like the real controls
   they are rather than a settings dropdown ---------- */
.mode-switch {
  display: flex; justify-content: center; gap: 16px; flex-wrap: wrap;
  margin: 30px 0 8px;
}
.mode-btn {
  font-family: var(--mono);
  font-size: 14px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 18px 34px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #0a0a0a;
  color: var(--muted);
  cursor: pointer;
  transition: all .2s ease;
}
.mode-btn:hover { border-color: var(--fg); color: var(--fg); }
.mode-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #000;
  box-shadow: 0 0 28px -4px var(--accent);
  transform: scale(1.04);
}
.mode-status {
  text-align: center; font-family: var(--mono);
  font-size: 13px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin: 6px 0 8px;
  text-shadow: 0 0 18px rgba(47,167,201,0.35);
}

/* ---------- Heliocentric view ---------- */
.sphaera-scene-wrap {
  position: relative;
  height: 400px;
  transition: box-shadow .4s;
}
.sphaera-scene-wrap.single-planet-focus {
  box-shadow: 0 0 50px -6px var(--tune, transparent) inset;
}

/* Date controls float directly over the scene, no box/border — just
   the controls themselves, legible via their own solid backgrounds
   (buttons already have one) plus text-shadow on plain text. */
.scene-controls {
  position: absolute; top: 12px; left: 14px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  z-index: 5;
}
/* A plain datetime-local input doesn't read as "you can change this" at
   a glance — the label + chevron make the affordance explicit, and the
   ::-webkit- rule below makes Chrome's own picker icon visible against
   a dark background instead of rendering as a near-invisible dark mark. */
.scene-date-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--accent); text-shadow: 0 1px 3px rgba(0,0,0,0.9);
  display: flex; align-items: center; gap: 4px;
}
.scene-controls input[type="datetime-local"] {
  background: rgba(0,0,0,0.6); border: 1px solid var(--accent); color: var(--fg);
  font-family: var(--mono); font-size: 11px; padding: 8px 12px;
  cursor: pointer;
}
.scene-controls input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  filter: invert(1);
  cursor: pointer;
}
.live-btn { font-size: 11px; padding: 8px 18px; }
.live-btn.live-active { background: #c0392b; border-color: #c0392b; color: #fff; }
.live-btn.live-inactive { background: #2a2a2a; border-color: #444; color: #aaa; }
.live-btn.live-inactive:hover { border-color: var(--fg); color: var(--fg); }

.sphaera-scene-caption {
  position: absolute; bottom: 10px; left: 14px;
  font-size: 11px; color: var(--muted); letter-spacing: .04em;
  text-shadow: 0 1px 4px rgba(0,0,0,0.9), 0 0 8px rgba(0,0,0,0.9);
  z-index: 4;
}

/* Single-Planet Tuning's celestial-body picker: a right-aligned list
   inside the heliocentric view (not a dropdown, not grouped with the
   date controls — picking WHICH BODY is a different kind of decision
   than picking WHEN). Each row shows that body's own real note+cents;
   clicking selects it. */
.planet-picker-list {
  display: none;
  position: absolute; top: 12px; right: 14px; bottom: 12px;
  width: 176px;
  flex-direction: column; gap: 4px;
  overflow-y: auto;
  z-index: 5;
}
.planet-picker-list.open { display: flex; }
.planet-picker-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  background: rgba(0,0,0,0.6);
  border: 1px solid var(--line);
  font-family: var(--mono); font-size: 10.5px;
  cursor: pointer;
  color: var(--fg);
  transition: border-color .15s, background .15s;
}
.planet-picker-item:hover { border-color: var(--fg); }
.planet-picker-item.selected {
  border-color: currentColor;
  background: rgba(255,255,255,0.1);
}
.planet-picker-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.planet-picker-name { flex: 1; }
.planet-picker-note { color: var(--muted); font-size: 9.5px; white-space: nowrap; }

/* ---------- Keyboard visualizer: one octave, horizontal, squared ---------- */
.keyboard-viz {
  position: relative;
  height: 400px;
  width: 100%;
  background: linear-gradient(180deg, #161616 0%, #060606 100%);
  border: 1px solid var(--line);
  overflow: hidden;
  user-select: none;
}
.kb-white {
  position: absolute; top: 0; bottom: 0;
  width: calc(100% / 7);
  background: linear-gradient(180deg, #f6f6f6 0%, #dcdcdc 65%, #c4c4c4 100%);
  border-right: 1px solid rgba(0,0,0,0.25);
  box-shadow: inset 0 -8px 14px rgba(0,0,0,0.18), inset 0 2px 0 rgba(255,255,255,0.75);
  transition: background .3s ease, box-shadow .3s ease, filter .15s ease, opacity .3s ease;
}
.kb-white:last-child { border-right: none; }
.kb-black {
  position: absolute; top: 0;
  height: 60%;
  background: linear-gradient(180deg, #4a4a4a 0%, #161616 55%, #000 100%);
  box-shadow: inset 0 -6px 10px rgba(0,0,0,0.7), inset 0 2px 0 rgba(255,255,255,0.18), 0 5px 8px rgba(0,0,0,0.55);
  z-index: 2;
  transition: background .3s ease, box-shadow .3s ease, filter .15s ease, opacity .3s ease;
}
/* The 3 unused pitch classes (Db, Eb, Gb) in Planetary Keyboard mode —
   visually recede so the 9 that actually do something read as the ones
   that matter. Full opacity in Single-Planet Tuning, where every key
   is live. */
.keyboard-viz:not(.single-tint) .kb-black:not(.assigned) {
  opacity: 0.32;
}

/* Note on top, cents below — two lines, ALWAYS at the top of the key,
   in both modes. Planetary Keyboard shows each assigned body's ACTUAL
   current note (which may differ from the key's own letter — see
   sphaera.js's getPlanetaryKeyboardInfo comment); Single-Planet Tuning
   shows the plain letter + the one shared cents value every key gets
   once the keyboard is tuned to that body's real frequency. */
.kb-note-cents {
  display: none;
  position: absolute; top: 10px; left: 0; right: 0;
  flex-direction: column; align-items: center; gap: 1px;
  font-family: var(--mono);
  color: #2a2a2a; pointer-events: none;
}
.kb-note-line { font-size: 11px; font-weight: 700; }
.kb-cents-line { font-size: 9.5px; opacity: .82; }
.kb-black .kb-note-cents { color: #ddd; top: 7px; }
.kb-black .kb-note-line { font-size: 9.5px; }
.kb-black .kb-cents-line { font-size: 8.5px; }
/* Both assigned-white and assigned-black show it (the earlier version
   only listed white here, which is why Saturn/Neptune's text silently
   vanished — a real bug, not a style choice). */
.kb-white.assigned .kb-note-cents,
.kb-black.assigned .kb-note-cents,
.keyboard-viz.single-tint .kb-note-cents {
  display: flex;
}
.kb-black.assigned .kb-note-cents { color: var(--pc); }

/* A small colored circle "drawn on" the Single-Planet Tuning root key —
   literally the planet, as a dot, sitting in its real note. */
.kb-planet-dot {
  display: none;
  position: absolute; top: 30px; left: 50%; transform: translateX(-50%);
  width: 13px; height: 13px; border-radius: 50%;
  box-shadow: 0 0 8px rgba(255,255,255,0.5), inset 0 -2px 3px rgba(0,0,0,0.4);
}
.keyboard-viz.single-tint .kb-white.root-key .kb-planet-dot,
.keyboard-viz.single-tint .kb-black.root-key .kb-planet-dot {
  display: block;
}

/* Vertical planet name. The OUTER element is a normal horizontal flex
   box — justify-content:center reliably centers its content
   horizontally regardless of writing-mode, which is applied only to
   the INNER span. (Centering with flex directly on a vertical-writing-
   mode element is unreliable across browsers — its own axes get
   reinterpreted — so the vertical text lives one level down instead.) */
.kb-planet-name {
  display: none;
  position: absolute; top: 50px; left: 0; right: 0; bottom: 14px;
  align-items: center; justify-content: center;
}
.kb-planet-name-inner {
  writing-mode: vertical-rl; text-orientation: upright;
  font-family: var(--mono); font-weight: 700;
  font-size: 19px; letter-spacing: .32em; text-transform: uppercase;
  color: rgba(0,0,0,0.75); pointer-events: none;
}
.kb-black .kb-planet-name-inner { color: rgba(255,255,255,0.88); font-size: 14px; letter-spacing: .26em; }
.kb-black.assigned .kb-planet-name-inner { color: var(--pc); }
.kb-white.assigned .kb-planet-name,
.kb-black.assigned .kb-planet-name,
.keyboard-viz.single-tint .kb-white.root-key .kb-planet-name,
.keyboard-viz.single-tint .kb-black.root-key .kb-planet-name {
  display: flex;
}

/* Planetary Keyboard mode: each assigned WHITE key tinted with that
   body's own color (lighter/darker shades computed in JS as --pc/
   --pc-light/--pc-dark custom properties per key). Assigned BLACK keys
   stay visually black (see .kb-black base rule) — only their text
   above is colored, so they still read as black keys. */
.kb-white.assigned {
  background: linear-gradient(180deg, var(--pc-light) 0%, var(--pc) 68%, var(--pc-dark) 100%);
}

/* Single-Planet Tuning: the WHOLE keyboard washes to one color (--tune*
   custom properties set on .keyboard-viz itself), and the one key
   nearest the chosen planet's real pitch gets a distinct outline. */
.keyboard-viz.single-tint .kb-white {
  background: linear-gradient(180deg, var(--tune-light) 0%, var(--tune) 68%, var(--tune-dark) 100%);
}
.keyboard-viz.single-tint .kb-black {
  background: linear-gradient(180deg, var(--tune) 0%, var(--tune-dark) 55%, #000 100%);
}
.keyboard-viz .kb-white.root-key,
.keyboard-viz .kb-black.root-key {
  outline: 3px solid #fff;
  outline-offset: -3px;
}

/* Highlight lasts exactly as long as the key is actually held — the
   existing `filter .15s ease` transition on .kb-white/.kb-black (above)
   is what animates this in both directions, so adding/removing .held is
   enough: it stays lit for however long the class is present and only
   starts fading the instant it's removed, instead of a fixed-length
   @keyframes flash that used to fade back after one timeout whether or
   not the note was still sounding. */
.kb-white.held { filter: brightness(1.55); }
.kb-black.held { filter: brightness(2.3); }

/* ---------- Single-Planet Tuning info panel ---------- */
.sphaera-single-card {
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 20px;
  text-align: center;
}
.sphaera-single-card .big-note {
  font-size: 48px; font-weight: 700; font-family: var(--mono);
}
.sphaera-single-card .big-cents { font-size: 15px; color: var(--muted); margin-top: 4px; }

/* ---------- Compositional System / Orbital Notation ---------- */
.sphaera-notation-hero {
  margin: 48px 0 26px; text-align: center;
}
.sphaera-notation-kicker {
  /* No text-transform here on purpose: the source text is already typed
     in caps ("SONIKOSMOS: SOL-ω"), except the omega, which is
     deliberately lowercase — that's the project's one canonical
     spelling everywhere (see docs/MANIFESTO.md). CSS `text-transform:
     uppercase` doesn't just visually stretch a letter, it swaps in the
     Unicode UPPERCASE OMEGA codepoint (Ω) instead — an entirely
     different, arch-shaped glyph, not the "w"-like lowercase ω used
     everywhere else on the site (main page tagline/footer, etc.).
     Applying it here silently replaced the brand glyph with a different
     one. */
  font-size: 12px; letter-spacing: 0.35em;
  color: var(--muted); margin-bottom: 10px;
}
.sphaera-notation-title {
  font-size: clamp(28px, 4.2vw, 46px); font-weight: 700; line-height: 1.15;
  letter-spacing: -0.01em; margin: 0 auto; color: var(--fg);
  text-shadow: 0 0 32px rgba(47, 167, 201, 0.35);
  max-width: 820px;
}
.sphaera-notation-title .accent-word { color: var(--accent); }
.sphaera-notation-rule {
  width: 140px; height: 2px; margin: 22px auto 0;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}

.sphaera-notation-intro {
  border-left: 2px solid var(--accent);
  padding-left: 18px;
  margin: 4px 0 22px;
}
.sphaera-notation-intro p {
  font-size: 14.5px; line-height: 1.7; color: var(--fg);
  max-width: 780px; margin: 0 0 16px;
}
.sphaera-notation-intro p:last-child { margin-bottom: 0; }
.sphaera-notation-intro strong { color: var(--accent); }

/* the "in time vs. at a time" insight — deliberately set apart from the
   surrounding prose so it reads as the section's central claim, not
   another paragraph among several */
.sphaera-notation-callout {
  margin: 8px 0 28px; padding: 22px 26px;
  border: 1px solid var(--accent);
  background: linear-gradient(180deg, rgba(47, 167, 201, 0.08), rgba(47, 167, 201, 0.02));
  box-shadow: 0 0 40px rgba(47, 167, 201, 0.08);
  max-width: 780px;
}
.sphaera-notation-callout p {
  font-size: 15.5px; line-height: 1.75; color: var(--fg); margin: 0 0 14px;
}
.sphaera-notation-callout p:last-child { margin-bottom: 0; }
.sphaera-notation-callout strong { color: var(--accent); }
.sphaera-notation-callout em {
  color: var(--fg); font-style: normal; border-bottom: 1px dotted var(--accent);
}

.sphaera-clef-figure {
  margin: 8px auto 30px; text-align: center;
}
.sphaera-clef-figure img {
  width: 150px; background: #fff; border: 1px solid var(--line);
  padding: 18px 22px 10px;
}
.sphaera-clef-figure figcaption {
  font-size: 12px; color: var(--muted); max-width: 420px; margin: 12px auto 0;
  line-height: 1.6;
}

/* ---------- Staff / example plates — each gets its own full-width row,
   framed like an archival astronomical plate rather than a thumbnail
   gallery ---------- */
.sphaera-staff-figures {
  display: flex; flex-direction: column; gap: 40px;
  margin: 8px 0 30px;
}
.sphaera-plate {
  margin: 0 auto; max-width: 860px; width: 100%;
}
.sphaera-plate-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.3em;
  color: var(--muted); text-align: left; margin-bottom: 8px;
}
.sphaera-staff-figure {
  margin: 0; border: 1px solid var(--line); background: #fff;
}
.sphaera-staff-figure img { width: 100%; display: block; }
.sphaera-staff-figure figcaption {
  background: var(--panel); color: var(--muted);
  font-size: 13px; line-height: 1.6; padding: 16px 20px 18px;
}
.sphaera-staff-figure figcaption a { color: var(--accent); }

/* ---------- Harmonic Ephemerides highlights table ---------- */
/* Reuses table.readout (style.css) for the base row/border/padding and
   .ohc-badge/.ohc-badge-* (style.css, shared with the main page's
   Harmonic Ephemeris preview cards) for the kind pill — no new badge
   colors invented here, same visual language as everywhere else these
   events are shown. */
.sphaera-ephem-table-wrap {
  border: 1px solid var(--line); background: var(--panel);
  padding: 4px 16px; margin-bottom: 8px; max-height: 420px; overflow-y: auto;
}
.sphaera-ephem-table { font-size: 12.5px; }
.sphaera-ephem-table .ephem-date-cell {
  color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.sphaera-ephem-table .ephem-desc-cell { color: var(--fg); }
.sphaera-ephem-table tr.ephem-row { cursor: pointer; transition: background .15s ease; }
.sphaera-ephem-table tr.ephem-row:hover { background: rgba(47, 167, 201, 0.08); }
.sphaera-ephem-table tr.ephem-row:hover .ephem-play { color: var(--accent); border-color: var(--accent); }
.ephem-play {
  font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 10px; background: transparent; white-space: nowrap;
  transition: color .15s ease, border-color .15s ease;
}
