/* Igneous zircon prototype ---------------------------------------------------
 *
 * A single fixed globe with UI floating over it. Copied from
 * ../plate-boundaries/css/story.css -- same dark palette as the other story
 * maps, same layout. Nothing here is zircon-specific; only index.html's IDs
 * and js/story.js's use of them changed.
 */

:root {
  --ink: #e8f0f8;
  --ink-dim: rgba(232, 240, 248, 0.62);
  --bg: #070c16;
  --panel: rgba(9, 16, 28, 0.82);
  --edge: rgba(143, 212, 240, 0.22);
  --accent: #8fd4f0;

  /* The slider thumb's width, and therefore the chart's plot inset.
   *
   * A range input puts its thumb CENTRE at left + W/2 + fraction * (width - W), because the
   * thumb has to stay inside the track at both ends. The chart above the slider insets its
   * plot by W/2 so its marker lands on the thumb. That only works if W is KNOWN, which is
   * why the thumb is styled here rather than left native -- native widths differ between
   * browsers. Change this and js/story.js must change with it. */
  --thumb: 14px;

  /* The chart's plot gutters -- left clears the rotated axis caption and its tick
   * labels, right is symmetry. The slider and the tick row below it are inset by the
   * SAME amounts so that one time axis runs down the whole panel: without this the
   * chart's 0 Ma and the slider's 0 Ma are ~66px apart and the marker only appears to
   * track the thumb.
   *
   * js/chart.js reads these two values off the computed style rather than repeating
   * them, so there is exactly one place to change them. */
  --chart-pad-left: 66px;
  --chart-pad-right: 14px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
}

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

.stage-layer { position: absolute; inset: 0; }

.stage-globe canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.globe-overlay { pointer-events: none; }

/* ---- chrome ------------------------------------------------------------- */

.titlecard {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
  max-width: 26rem;
  padding: 1.6rem 1.8rem;
  pointer-events: none;
}

.kicker {
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.titlecard h1 {
  margin: 0 0 0.5rem;
  font-size: 1.7rem;
  font-weight: 600;
  line-height: 1.2;
}

.standfirst {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink-dim);
}

/* ---- time scrubber ------------------------------------------------------ */

.timebar {
  position: fixed;
  left: 1.8rem;
  bottom: 1.4rem;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  width: min(46rem, calc(100vw - 22rem));
  padding: 0.7rem 1rem;
  border: 1px solid var(--edge);
  border-radius: 10px;
  background: var(--panel);
  backdrop-filter: blur(8px);
}

.timebar button {
  flex: none;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--edge);
  border-radius: 50%;
  background: transparent;
  color: var(--accent);
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
}

.timebar button:hover { background: rgba(143, 212, 240, 0.12); }

/* Play button + timestack, everything the collapse toggle hides. Its own flex row so
 * the toggle (a sibling, not a child) keeps the same round-icon size the play button
 * has regardless of how the body's content wraps. */
.timebar-body {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex: 1;
  min-width: 0;
}

/* Collapsed: shrink the whole bar down to just the toggle button, rather than leaving
 * an empty bar-shaped void where the body used to be. */
.timebar.is-collapsed {
  width: auto;
  padding: 0.5rem;
}

.timebar.is-collapsed .timebar-body { display: none; }

/* Chart and slider stacked in one column, so they are the same width with the same left
 * edge. Without that the marker cannot line up with the thumb. */
.timestack {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.timebar input[type="range"] {
  /* Inset to match the chart's plot area -- see --chart-pad-left. */
  width: calc(100% - var(--chart-pad-left) - var(--chart-pad-right));
  margin: 0 var(--chart-pad-right) 0 var(--chart-pad-left);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  height: var(--thumb);
  background: transparent;
}

/* The track and the thumb are drawn explicitly rather than left to accent-color, because
 * the chart's geometry depends on knowing the thumb's width. */
.timebar input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: rgba(143, 212, 240, 0.22);
}

.timebar input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--thumb);
  height: var(--thumb);
  margin-top: calc((4px - var(--thumb)) / 2);
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}

.timebar input[type="range"]::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: rgba(143, 212, 240, 0.22);
}

.timebar input[type="range"]::-moz-range-thumb {
  width: var(--thumb);
  height: var(--thumb);
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
}

.timebar input[type="range"]:focus-visible { outline: 1px solid var(--accent); }

.timebar .ticks {
  margin: 0 var(--chart-pad-right) 0 var(--chart-pad-left);
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.7rem;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

/* ---- time series -------------------------------------------------------- */

.timeseries {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.ts-canvas {
  display: block;
  width: 100%;
  cursor: crosshair;
  touch-action: none;
}

/* Mode buttons above the chart, not below it: the chart is the thing, and controls that
 * sit between the chart and the slider would break the visual join between them. */
.ts-modes {
  order: -1;
  display: flex;
  gap: 0.25rem;
  justify-content: flex-end;
}

.ts-modes button {
  width: auto;
  height: auto;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--edge);
  border-radius: 4px;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.ts-modes button:hover { color: var(--ink); border-color: var(--accent); }

.ts-modes button.is-on {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}

.legend {
  position: fixed;
  right: 1.4rem;
  bottom: 1.4rem;
  z-index: 2;
  width: 17rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--edge);
  border-radius: 10px;
  background: var(--panel);
  backdrop-filter: blur(8px);

  /* Boundary types plus two zircon rows can still run off a short window, so cap it and
   * let the panel scroll rather than the page. */
  max-height: calc(100vh - 9rem);
  overflow-y: auto;
}

/* Round icon button, matching .timebar button's own size/style. Scoped to .legend
 * specifically (not a bare .panel-toggle rule) -- the timebar's own toggle shares the
 * same class for its collapse/expand behaviour in JS, but sits inline as a flex item
 * there (styled for free by the existing ".timebar button" rule above) rather than
 * pinned to a corner the way it needs to be here, where the legend is a block-stacked
 * aside, not a flex row. */
.legend .panel-toggle {
  position: absolute;
  top: 0.7rem;
  right: 0.8rem;
  width: 1.6rem;
  height: 1.6rem;
  border: 1px solid var(--edge);
  border-radius: 50%;
  background: transparent;
  color: var(--accent);
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
}

.legend .panel-toggle:hover { background: rgba(143, 212, 240, 0.12); }

/* Collapsed: shrink the whole panel down to just the toggle button (now back in normal
 * flow, not pinned to a corner that would otherwise be floating in an empty box), rather
 * than leaving a panel-shaped void with nothing in it. This is the direct fix for the
 * legend swallowing a narrow window -- collapsing gets it out of the way entirely,
 * rather than relying on the max-height cap below to leave enough of the globe visible. */
.legend.is-collapsed {
  width: auto;
  max-height: none;
  padding: 0.4rem;
  overflow: visible;
}

.legend.is-collapsed .legend-body { display: none; }
.legend.is-collapsed .panel-toggle { position: static; }

.legend h2 {
  margin: 0 0 0.6rem;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  font-weight: 600;
}

.legend ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.legend li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.22rem 0;
  font-size: 0.86rem;
  cursor: pointer;
  user-select: none;
}

/* Toggling a type off dims the row rather than hiding it, so the legend keeps a
 * stable height and the reader can see what has been switched away. */
.legend li.is-off { opacity: 0.38; }

.legend .swatch {
  flex: none;
  width: 26px;
  height: 3px;
  border-radius: 2px;
}

.legend-sub {
  margin-top: 0.9rem !important;
  padding-top: 0.7rem;
  border-top: 1px solid var(--edge);
}

/* Velocity swatch: a miniature of the map arrow. */
.legend .swatch-arrow {
  position: relative;
  height: 2px;
  background: rgba(190, 228, 255, 0.9);
}

.legend .swatch-arrow::after {
  content: "";
  position: absolute;
  right: -1px;
  top: -2.5px;
  border-left: 6px solid rgba(190, 228, 255, 0.9);
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
}

/* Length reference for the arrows -- an arrow field without a scale says nothing
 * quantitative, and the drawn length is proportional to speed. */
.scalebar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0 0;
  font-size: 0.74rem;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.scalebar svg { flex: none; overflow: visible; }
.scalebar line { stroke: rgba(190, 228, 255, 0.9); stroke-width: 1.6; }
.scalebar polygon { fill: rgba(190, 228, 255, 0.9); }

/* Triangle sitting on the subduction swatch, matching the map symbol. */
.legend .swatch-sz { position: relative; }

.legend .swatch-sz i {
  position: absolute;
  left: 9px;
  bottom: 2px;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 7px solid currentColor;
}

.legend .caveat {
  margin: 0.9rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--edge);
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--ink-dim);
}

.legend .caveat + .caveat { border-top: 0; margin-top: 0.5rem; padding-top: 0; }

/* ---- zircon symbols ------------------------------------------------------ */

/* Zircon rows carry a drawn symbol rather than a plain colour chip, matching the
 * base-metal legend's convention even though there are only two types here (colour
 * alone would already distinguish them). */
.legend .swatch-sym {
  width: 26px;
  height: 14px;
  border-radius: 0;
  background: none;
  display: grid;
  place-items: center;
}

.legend .swatch-sym svg { display: block; overflow: visible; }

.legend-sub .legend-action {
  float: right;
  margin-top: -1px;
  padding: 0 0.35rem;
  border: 1px solid var(--edge);
  border-radius: 4px;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: none;
  cursor: pointer;
}

.legend-sub .legend-action:hover { color: var(--ink); border-color: var(--accent); }

.legend .hint {
  margin: 0.5rem 0 0;
  font-size: 0.72rem;
  color: var(--ink-dim);
}

/* ---- zircon popup -------------------------------------------------------- */

.point-popup {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
  max-width: 17rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--edge);
  border-radius: 8px;
  background: var(--panel);
  backdrop-filter: blur(8px);
  font-size: 0.78rem;
  line-height: 1.45;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;

  /* Click-through while merely hovering. A popup that accepts pointer events under the
   * cursor steals the hover from the canvas beneath it, which makes it flicker between
   * shown and hidden as the pointer crosses the boundary. */
  pointer-events: none;
}

.point-popup.is-visible { opacity: 1; visibility: visible; }

/* Pinned: now it is a panel the reader is reading, so it accepts the pointer. */
.point-popup.is-pinned {
  pointer-events: auto;
  border-color: var(--accent);
}

.point-popup h3 {
  margin: 0 0 0.3rem;
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.25;
}

.point-popup .pp-type {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

.point-popup dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.1rem 0.6rem;
  margin: 0;
}

.point-popup dt { color: var(--ink-dim); }
.point-popup dd { margin: 0; font-variant-numeric: tabular-nums; }

.point-popup .pp-ref {
  margin: 0.45rem 0 0;
  padding-top: 0.4rem;
  border-top: 1px solid var(--edge);
  font-size: 0.68rem;
  color: var(--ink-dim);
}

.point-popup .pp-pin {
  margin: 0.4rem 0 0;
  font-size: 0.66rem;
  color: var(--ink-dim);
}

/* ---- loading ------------------------------------------------------------ */

.loading {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  background: var(--bg);
  color: var(--ink-dim);
  font-size: 0.9rem;
  transition: opacity 0.8s ease;
}

.loading.is-done {
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 900px) {
  /* Full width here (rather than the desktop 17rem) means the legend, expanded, would
   * otherwise inherit the desktop max-height of calc(100vh - 9rem) -- on a narrow-but-
   * tall window that is most of the screen, with the globe reduced to a sliver behind
   * it. Capped tighter here so the globe stays the majority of the view even expanded;
   * the collapse toggle (see .panel-toggle) is there for getting it out of the way
   * entirely. */
  .legend { left: 1rem; right: 1rem; width: auto; bottom: 5.5rem; max-height: 42vh; }
  .timebar { left: 1rem; right: 1rem; width: auto; }
  /* Both left AND right are set above, so width:auto alone won't shrink the box (the
   * browser fills the gap between them instead) -- right:auto lets each shrink to
   * content while staying anchored to its existing left edge, rather than jumping
   * across to the opposite side of the screen when collapsed. */
  .legend.is-collapsed { right: auto; width: auto; }
  .timebar.is-collapsed { right: auto; width: auto; }
  .titlecard { max-width: none; }

  /* Four stacked rows plus the mode buttons is most of a phone screen, and the globe is
   * the point of the page. The chart goes rather than shrinking to illegibility. */
  .timeseries { display: none; }
}

/* ==========================================================================
 * tectonic-co2 additions
 *
 * Everything above is inherited from ../zircons/css/story.css. This block adds
 * the four things this page has that its siblings do not: the knob panel, the
 * strand chart, the latitude histogram beside the map, and the projection
 * toggle.
 * ========================================================================== */

/* The chart replaces the sibling pages' .timeseries in the same slot, so it
 * inherits the shared time axis and the thumb inset that keeps the marker on
 * the slider thumb. Taller than a sparkline row: it carries a bundle of
 * strands plus the measured record below them. */
.chart {
  position: relative;
  /* 150px + the glaciation strip added beneath the record row. */
  height: 176px;
  width: 100%;
}
.chart canvas { display: block; width: 100%; height: 100%; cursor: crosshair; }

/* Latitude histogram, down the left edge of the map.
 *
 * In Robinson its bars line up with the sutures they count, because the page
 * maps latitude to y through the projection itself. In orthographic a parallel
 * is a curve rather than a row, so it falls back to a linear axis and reads as
 * a summary instead of an aligned marginal. */
.lat-hist {
  position: absolute;
  left: 0.6rem;
  /* Offset clear of the title card, which occupies the top-left of the stage on
   * every page in this family. Full height minus that block, not 100%. */
  top: 12rem;
  width: 96px;
  height: calc(100% - 24rem);
  pointer-events: none;
}

.proj-toggle {
  position: absolute;
  right: 1rem;
  top: 1rem;
  z-index: 3;
  padding: 0.3rem 0.7rem;
  font: inherit;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: 999px;
  cursor: pointer;
}
.proj-toggle:hover { color: var(--ink); border-color: var(--accent); }

/*
 * Shown over the empty ocean when the selected model has no rotations for the time on the
 * slider. Deliberately plain: it is a statement about the data, not a warning.
 */
.out-of-range {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 3;
  transform: translate(-50%, -50%);
  max-width: 24rem;
  margin: 0;
  padding: 0.9rem 1.15rem;
  text-align: center;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--ink-dim);
  background: rgba(14, 22, 33, 0.86);
  border: 1px solid var(--edge);
  border-radius: 8px;
  pointer-events: none;
}
.out-of-range[hidden] { display: none; }
.out-of-range strong { color: var(--ink); font-weight: 500; }

/* ---- knobs ------------------------------------------------------------- */

.knob { margin: 0 0 0.85rem; }
.knob h3 {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin: 0 0 0.2rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* Provenance marker. A page objecting to unexamined parameter choices cannot
 * quietly make its own, so every knob says whether its RANGE came from the
 * source dataset or from us. 'sourced' is the quiet default colour; 'mixed'
 * is warm so it catches the eye, because that is the one the reader should
 * discount. */
.prov {
  flex: none;
  font-size: 0.6rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  border: 1px solid transparent;
}
.prov-sourced { color: rgba(126, 232, 200, 0.85); border-color: rgba(126, 232, 200, 0.3); }
.prov-mixed   { color: rgba(255, 196, 92, 0.9);  border-color: rgba(255, 196, 92, 0.35); }

.knob-note {
  margin: 0 0 0.4rem;
  font-size: 0.68rem;
  line-height: 1.35;
  color: var(--ink-dim);
}

.knob-options { display: flex; flex-wrap: wrap; gap: 0.25rem; }

.knob-opt {
  flex: 1 1 auto;
  min-width: 4.2rem;
  text-align: left;
  padding: 0.3rem 0.45rem;
  font: inherit;
  font-size: 0.7rem;
  color: var(--ink-dim);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--edge);
  border-radius: 5px;
  cursor: pointer;
}
.knob-opt span { display: block; }
.knob-opt em {
  display: block;
  margin-top: 0.1rem;
  font-style: normal;
  font-size: 0.6rem;
  line-height: 1.3;
  opacity: 0.7;
}
.knob-opt:hover { color: var(--ink); border-color: var(--accent); }
.knob-opt.is-on {
  color: #06121f;
  background: rgba(126, 232, 200, 0.9);
  border-color: rgba(126, 232, 200, 0.9);
}
/* Options this page invented rather than took from the source keep a warm
 * dashed edge whether or not they are selected. */
.knob-opt.is-ours { border-style: dashed; border-color: rgba(255, 196, 92, 0.5); }
.knob-opt.is-ours.is-on { background: rgba(255, 196, 92, 0.9); }

/* ---- strand hover ------------------------------------------------------ */

.strand-hover {
  position: fixed;
  z-index: 20;
  display: none;
  max-width: 20rem;
  padding: 0.4rem 0.55rem;
  font-size: 0.7rem;
  line-height: 1.35;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: 6px;
  pointer-events: none;
}
.strand-hover.is-on { display: block; }
.strand-hover strong { display: block; font-weight: 600; }
.strand-hover span { display: block; color: var(--ink-dim); }
.strand-hover em { font-style: normal; opacity: 0.7; }

/* Provenance and caveats under a glaciation's dates: present, but subordinate to them. */
.strand-hover .hover-note {
  margin-top: 0.3rem;
  font-size: 0.64rem;
  line-height: 1.4;
  opacity: 0.72;
}

/* ---- coverage ---------------------------------------------------------- */

.coverage {
  margin: 0 0 0.4rem;
  padding: 0;
  list-style: none;
  font-size: 0.68rem;
  line-height: 1.4;
  color: var(--ink-dim);
}
/* The inherited `.legend li` is a flex row built for swatch+label legend entries;
 * applied to a sentence it lays the <strong> and the prose out as two columns. These
 * rows are prose, so they opt out. */
.coverage li {
  display: block;
  margin-bottom: 0.25rem;
  padding: 0;
  font-size: 0.68rem;
  cursor: default;
}
.coverage strong { color: var(--ink); font-weight: 600; }

@media (max-width: 900px) {
  .chart { height: 136px; }
  .lat-hist { display: none; }
}

/* ---- suture popup ------------------------------------------------------- */

.suture-popup {
  position: fixed;
  z-index: 21;
  display: none;
  width: 21rem;
  max-width: calc(100vw - 2rem);
  padding: 0.6rem 0.7rem;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: 7px;
  backdrop-filter: blur(6px);
  pointer-events: none;
}
.suture-popup.is-on { display: block; }
.suture-popup h3 {
  margin: 0 0 0.2rem;
  font-size: 0.86rem;
  font-weight: 600;
}
.suture-popup .pp-blocks {
  margin: 0 0 0.1rem;
  font-size: 0.74rem;
  line-height: 1.35;
  color: rgba(255, 196, 92, 0.95);
}
.suture-popup .pp-blocks em { font-style: normal; opacity: 0.6; }
.suture-popup .pp-sub {
  margin: 0 0 0.4rem;
  font-size: 0.62rem;
  line-height: 1.3;
  color: var(--ink-dim);
}
.suture-popup dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.1rem 0.6rem;
  margin: 0 0 0.4rem;
  font-size: 0.72rem;
}
.suture-popup dt { color: var(--ink-dim); }
.suture-popup dd { margin: 0; font-variant-numeric: tabular-nums; }
/* The interval the activity control is currently reading is marked, so the popup shows
 * what is in force as well as what else was available. */
.suture-popup dt.is-live, .suture-popup dd.is-live {
  color: rgba(126, 232, 200, 1);
  font-weight: 600;
}
.suture-popup .pp-dim { color: var(--ink-dim); }
.suture-popup .pp-ref {
  margin: 0 0 0.3rem;
  font-size: 0.66rem;
  line-height: 1.35;
  color: var(--ink-dim);
  font-style: italic;
}
