* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.shell {
  height: 100%;
  display: grid;
  grid-template-rows: auto auto auto 1fr;
}

/* ---------- Masthead ---------- */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 28px 14px;
  border-bottom: 1px solid var(--line);
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.wordmark h1 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 400;
  letter-spacing: -0.01em;
  margin: 0;
}

.wordmark .dot {
  color: var(--magma);
}

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 3px 9px 3px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
}

.status-chip .pulse {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--magma-strong);
  box-shadow: 0 0 0 0 rgba(232, 80, 31, 0.5);
  animation: pulse-ring 2.4s ease-out infinite;
}

/* A stalled feed must not look like a calm one: stop the pulse and switch
   to a warning colour, since a steady dot reads as "nothing to report". */
.status-chip.is-stale {
  color: var(--sulphur);
  border-color: color-mix(in srgb, var(--sulphur) 45%, transparent);
}

.status-chip.is-stale .pulse {
  background: var(--sulphur);
  box-shadow: none;
  animation: none;
}

@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 rgba(232, 80, 31, 0.45); }
  70% { box-shadow: 0 0 0 7px rgba(232, 80, 31, 0); }
  100% { box-shadow: 0 0 0 0 rgba(232, 80, 31, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .status-chip .pulse { animation: none; }
}

.masthead-right {
  display: flex;
  align-items: center;
  gap: 14px;
}

.reading {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-soft);
  white-space: nowrap;
}

.reading strong {
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
}

.theme-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px;
  gap: 2px;
  background: var(--bg-sunken);
}

.theme-toggle button {
  border: 0;
  background: transparent;
  color: var(--ink-faint);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  padding: 5px 11px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.theme-toggle button.active {
  background: var(--bg-raised);
  color: var(--ink);
  box-shadow: var(--shadow);
}

.theme-toggle button:focus-visible {
  outline: 2px solid var(--magma-strong);
  outline-offset: 2px;
}

/* ---------- Seismograph strip (signature element) ---------- */

.seismo-strip {
  position: relative;
  height: 46px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-sunken);
  overflow: hidden;
}

/* Short windows: the 3D view is height-limited, and every pixel the chrome
   gives back makes the scene meaningfully larger. */
@media (max-height: 860px) {
  .masthead { padding: 10px 28px 8px; }
  .seismo-strip { height: 28px; }
  .view-nav { padding: 6px 28px; }
}

.seismo-strip canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.seismo-label {
  position: absolute;
  left: 28px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: linear-gradient(90deg, var(--bg-sunken) 60%, transparent);
  padding-right: 30px;
  pointer-events: none;
}

/* ---------- Nav tabs ---------- */

.view-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 10px 28px;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}

.view-tab {
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 7px 13px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.view-tab:hover {
  color: var(--ink);
  background: var(--bg-sunken);
}

.view-tab.active {
  color: var(--ink);
  background: var(--bg-raised);
  border-color: var(--line);
  box-shadow: var(--shadow);
  font-weight: 600;
}

.view-tab:focus-visible {
  outline: 2px solid var(--magma-strong);
  outline-offset: 2px;
}

/* ---------- Stage ---------- */

.stage {
  position: relative;
  min-height: 0;
  overflow: auto;
  background: var(--bg);
  display: grid;
}

.view-panel {
  display: none;
  grid-area: 1 / 1;
  min-height: 100%;
  padding: 24px 28px 40px;
}

.view-panel.active {
  display: flex;
  flex-direction: column;
}

/* The live panel keeps its toolbar and stat tiles fixed and scrolls only
   the table, so it must be bounded by the stage rather than growing to fit
   its rows. Other panels keep the default grow-and-scroll behaviour. */
#panel-live.view-panel.active {
  min-height: 0;
  height: 100%;
  overflow: hidden;
}

/* ---------- Quake list (Live view) ---------- */

.quake-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

.quake-toolbar h2 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 400;
  margin: 0;
}

.range-select {
  display: flex;
  gap: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 2px;
  background: var(--bg-sunken);
}

.range-select button {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-faint);
  background: transparent;
  border: 0;
  border-radius: 4px;
  padding: 5px 10px;
  cursor: pointer;
}

.range-select button.active {
  background: var(--bg-raised);
  color: var(--ink);
  box-shadow: var(--shadow);
}

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 22px;
}

.stat-tile {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
}

.stat-tile .label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: block;
  margin-bottom: 6px;
}

.stat-tile .value {
  font-family: var(--font-mono);
  font-size: 24px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.stat-tile .value.accent { color: var(--magma-strong); }

.stat-sub {
  display: block;
  margin-top: 3px;
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stat-sub:empty { display: none; }

/* The list can run to hundreds of rows, so it scrolls inside its own box
   rather than being clipped. min-height:0 is required for a flex child to
   be allowed to shrink below its content and actually scroll. */
.quake-table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: auto;
  background: var(--bg-raised);
  flex: 1;
  min-height: 0;
}

table.quake-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.quake-table thead th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 500;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-sunken);
  position: sticky;
  top: 0;
}

.quake-table tbody td {
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

.quake-table tbody tr:last-child td { border-bottom: none; }
.quake-table tbody tr:hover td { background: var(--bg-sunken); }

.quake-table td.region {
  font-family: var(--font-ui);
  color: var(--ink);
}

.mag-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 12.5px;
}

.mag-pill.low { background: var(--bg-sunken); color: var(--ink-soft); }
.mag-pill.mid { background: color-mix(in srgb, var(--sulphur) 18%, transparent); color: var(--sulphur); }
.mag-pill.high { background: color-mix(in srgb, var(--magma) 18%, transparent); color: var(--magma-strong); }

.empty-state {
  padding: 60px 20px;
  text-align: center;
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 13px;
}

/* ---------- Map view ---------- */

#panel-map.view-panel.active {
  padding: 0;
}

.map-frame {
  position: relative;
  flex: 1;
  min-height: 0;
}

#quakeMap {
  width: 100%;
  height: 100%;
  background: var(--bg-sunken);
}

.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
  background: var(--bg-raised);
  color: var(--ink);
}

.leaflet-popup-content {
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.5;
}

.map-controls {
  position: absolute;
  top: 16px;
  left: 60px;   /* clear of Leaflet's zoom control */
  /* Reserves the top-right corner for the event-list handle. */
  right: 104px;
  z-index: 500;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  pointer-events: none;
}

.map-controls > * { pointer-events: auto; }

.map-controls .range-select {
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.map-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 5px 10px;
  box-shadow: var(--shadow);
  white-space: nowrap;
}

.map-legend {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 500;
  display: flex;
  gap: 14px;
  padding: 8px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-soft);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.legend-item .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}

/* ---------- GPS uplift view ---------- */

#panel-gps.view-panel.active {
  padding: 0;
}

.gps-layout {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 260px 1fr;
}

.gps-sidebar {
  border-right: 1px solid var(--line);
  padding: 20px 16px;
  min-height: 0;
  overflow-y: auto;
  background: var(--bg-sunken);
}

.gps-sidebar h2 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 400;
  margin: 0 0 14px;
}

.station-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.station-btn {
  display: flex;
  align-items: baseline;
  gap: 8px;
  text-align: left;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-ui);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.station-btn:hover { background: var(--bg-raised); }

.station-btn.active {
  background: var(--bg-raised);
  border-color: var(--line);
  box-shadow: var(--shadow);
}

.station-btn .station-code {
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}

.station-btn .station-name {
  font-size: 12px;
  color: var(--ink-soft);
  flex: 1;
}

.station-btn .station-count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-faint);
}

.station-btn .station-region {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Stations with no solutions in the selected window stay selectable but
   read as secondary, so the list doesn't hide them outright. */
.station-btn.is-stale .station-code,
.station-btn.is-stale .station-name {
  color: var(--ink-faint);
}

.station-search {
  width: 100%;
  margin-bottom: 12px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 12.5px;
}

.station-search::placeholder { color: var(--ink-faint); }

.station-search:focus-visible {
  outline: 2px solid var(--magma-strong);
  outline-offset: 1px;
}

.gps-main {
  min-width: 0;
  min-height: 0;
  padding: 24px 28px;
  overflow-y: auto;
}

.gps-charts {
  display: grid;
  gap: 14px;
  align-content: start;
}

.gps-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.gps-title {
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 600;
  margin: 0;
  letter-spacing: 0.01em;
}

.gps-meta {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--ink-soft);
}

.gps-span {
  margin: -4px 0 2px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
}

.gps-chart-card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px 10px;
}

.gps-chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}

.gps-stat {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.gps-stat.is-positive { color: var(--magma-strong); }
.gps-stat.is-negative { color: var(--fjord); }

.gps-chart-card canvas {
  display: block;
  width: 100%;
  height: 130px;
}

.gps-footnote {
  margin: 2px 0 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ink-faint);
  max-width: 70ch;
}

/* ---------- Seismometer view ---------- */

#panel-seismo.view-panel.active {
  padding: 0;
}

.seismo-plots {
  display: grid;
  gap: 16px;
}

.seismo-plots-label {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-faint);
  margin: 0;
}

.seismo-plots-label strong {
  color: var(--ink);
}

.plot-card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
}

.plot-card .plot-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 10px;
}

.plot-card img {
  display: block;
  width: 100%;
  height: auto;
  min-height: 80px;
  border-radius: var(--radius-sm);
  background: var(--bg-sunken);
}

.plot-card.plot-unavailable {
  position: relative;
}

.plot-card.plot-unavailable::after {
  content: 'Plot unavailable';
  display: flex;
  align-items: center;
  justify-content: center;
  height: 80px;
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
}

/* ---------- 3D depth view ---------- */

#panel-depth3d.view-panel.active {
  padding: 0;
}

.d3-layout {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 268px 1fr;
}

.d3-sidebar {
  border-right: 1px solid var(--line);
  background: var(--bg-sunken);
  padding: 20px 16px;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.d3-sidebar h2 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 400;
  margin: 0;
}

.d3-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.d3-field > span {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.d3-field output {
  font-size: 11px;
  color: var(--ink);
  text-transform: none;
  letter-spacing: 0;
}

.d3-field select {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 12.5px;
}

.d3-field input[type="range"] {
  width: 100%;
  accent-color: var(--magma-strong);
}

.d3-field select:focus-visible,
.d3-field input:focus-visible {
  outline: 2px solid var(--magma-strong);
  outline-offset: 1px;
}

.d3-buttons {
  display: flex;
  gap: 6px;
}

.d3-buttons button {
  flex: 1;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.d3-buttons button:hover { color: var(--ink); }

.d3-buttons button.active {
  color: var(--magma-strong);
  border-color: var(--magma-strong);
}

.d3-buttons button:focus-visible {
  outline: 2px solid var(--magma-strong);
  outline-offset: 2px;
}

.d3-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin: 0;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.d3-stats div { min-width: 0; }

.d3-stats dt {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.d3-stats dd {
  margin: 2px 0 0;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.d3-list-title {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 500;
  margin: 0;
}

.d3-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
}

.d3-row {
  display: grid;
  grid-template-columns: 38px 1fr auto;
  align-items: baseline;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-ui);
}

.d3-row:hover { background: var(--bg-raised); }

.d3-row.active {
  background: var(--bg-raised);
  border-color: var(--magma-strong);
}

.d3-row .d3-mag {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.d3-row .d3-region {
  font-size: 12px;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.d3-row .d3-depth {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
}

/* On a very wide window the stage becomes 3:1 or wider. Fitting the block's
   height then leaves ~70% of the width empty no matter what the camera does
   — that is geometry, not framing. Capping the canvas to a moderate aspect
   keeps the scene large and genuinely centred, with the surplus width
   absorbed by the panel rather than by dead space inside the render. */
.d3-stage {
  position: relative;
  min-width: 0;
  /* Grid items default to min-height:auto, which lets the stage grow past
     the panel; the canvas then measures taller than it really is and the
     camera fits to a viewport that does not exist. */
  min-height: 0;
  overflow: hidden;
  /* Deliberately darker than the surrounding panel: the 3D scene is drawn
     in pale greys, and on a near-white stage it washed out completely. */
  background: radial-gradient(circle at 50% 35%, #2b3540, #1a2128);
}

/* The canvas always fills the stage. An earlier max-width cap (meant to
   avoid letterboxing on ultrawide screens) left a large dead region beside
   the canvas on short viewports, which read as a broken/blank view. Wide
   aspect ratios are handled by the camera fit instead. */
#depth3dCanvas {
  width: 100%;
  height: 100%;
  cursor: grab;
}

#depth3dCanvas:active { cursor: grabbing; }

.d3-detail {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 500;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  max-width: 260px;
}

.d3-detail-mag {
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 600;
  color: var(--magma-strong);
}

.d3-detail-region {
  font-size: 13.5px;
  color: var(--ink);
}

.d3-detail-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
}

.legend-scale {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.legend-bar {
  display: block;
  width: 96px;
  height: 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
}

.legend-end {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.d3-status {
  position: absolute;
  top: 50px;
  right: 16px;
  margin: 0;
  padding: 5px 11px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
  pointer-events: none;
}

.d3-status:empty { display: none; }

.d3-scale {
  position: absolute;
  top: 16px;
  right: 16px;
  margin: 0;
  padding: 6px 12px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
  pointer-events: none;
}

@media (max-width: 860px) {
  .d3-layout { grid-template-columns: 1fr; }
  .d3-sidebar { border-right: 0; border-bottom: 1px solid var(--line); }
  .d3-stage { min-height: 60vh; }
}

.globe-hint {
  position: absolute;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  margin: 0;
  padding: 6px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
  pointer-events: none;
}

/* ---------- Placeholder panels (other views) ---------- */

.placeholder-panel {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 8px;
  color: var(--ink-faint);
  text-align: center;
}

.placeholder-panel h2 {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--ink-soft);
  font-weight: 400;
  margin: 0;
}

.placeholder-panel p {
  font-family: var(--font-mono);
  font-size: 12.5px;
  max-width: 42ch;
  margin: 0;
}

/* ---------- Responsive ---------- */

@media (max-width: 720px) {
  .masthead { padding: 14px 16px 12px; flex-wrap: wrap; }
  .view-nav { padding: 8px 16px; }
  .view-panel { padding: 18px 16px 32px; }
  .reading { display: none; }
}

/* ---- map overlays (plate boundaries, fissures, landmarks) ---- */

/* Disabled while a layer's GeoJSON is in flight; .failed flashes on error. */
.range-select button:disabled {
  opacity: 0.5;
  cursor: progress;
}

.range-select button.failed {
  color: var(--negative, #dc3545);
}

/* Landmark markers use a zero-size divIcon anchored on the point, so the
   dot and its label are positioned relative to that origin. */
.landmark-label {
  position: relative;
  width: 0;
  height: 0;
}

.landmark-label .landmark-dot {
  position: absolute;
  left: -4px;
  top: -4px;
  width: 8px;
  height: 8px;
  background: #fff;
  border: 1px solid #000;
  border-radius: 50%;
}

.landmark-label .landmark-name {
  position: absolute;
  left: 8px;
  top: -9px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: #fff;
  background: rgba(0, 0, 0, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: 3px;
  padding: 3px 6px;
}

/* ---- map event list (slide-out, hidden by default) ---- */

.map-list-handle {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1000; /* above Leaflet panes (400) and its controls (800) */
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 6px 11px;
  cursor: pointer;
  box-shadow: var(--shadow);
}

.map-list-handle.active {
  background: var(--ink);
  color: var(--bg-raised);
  border-color: var(--ink);
}

.map-list-panel {
  position: absolute;
  top: 48px;
  right: 12px;
  /* Stops above the magnitude legend pinned at the bottom-right. */
  bottom: 60px;
  z-index: 1000;
  width: 348px;
  max-width: calc(100% - 24px);
  display: flex;
  flex-direction: column;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.35);
  overflow: hidden;
}

/* [hidden] alone loses to the flex display above. */
.map-list-panel[hidden] { display: none; }

.map-list-head,
.map-list-row {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 7px 9px;
}

.map-list-head {
  flex-shrink: 0;
  background: #475569;
  color: #fff;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.map-list-rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px;
}

.map-list-row {
  width: 100%;
  margin-bottom: 2px;
  border: 0;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  color: #fff;
  cursor: pointer;
}

.map-list-row:hover { filter: brightness(1.18); }

.map-list-head .col-time,
.map-list-row .col-time { width: 66px; flex-shrink: 0; }

.map-list-head .col-mag,
.map-list-row .col-mag { width: 78px; flex-shrink: 0; white-space: nowrap; }

.map-list-head .col-depth,
.map-list-row .col-depth { width: 68px; flex-shrink: 0; white-space: nowrap; }

/* Numeric cells split into a right-aligned figure and a left-aligned unit, so
   the digits line up down the column whatever the sign or width. */
.map-list-row .col-mag,
.map-list-row .col-depth {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}

.map-list-row .col-mag .num { width: 34px; text-align: right; }
.map-list-row .col-depth .num { width: 34px; text-align: right; }

.map-list-row .col-mag .unit,
.map-list-row .col-depth .unit {
  font-size: 11px;
  font-weight: 500;
  opacity: 0.85;
}

.map-list-head .col-area,
.map-list-row .col-area {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Row colours track the marker magnitude bands. The yellow and orange bands
   need dark text to stay readable; the rest carry white. */
.map-list-row.mag-band-0 { background: #17a2b8; }
.map-list-row.mag-band-1 { background: #28a745; }
.map-list-row.mag-band-2 { background: #155724; }
.map-list-row.mag-band-3 { background: #ffc107; color: #000; }
.map-list-row.mag-band-4 { background: #fd7e14; color: #000; }
.map-list-row.mag-band-5 { background: #dc3545; }
.map-list-row.mag-band-6 { background: #6f42c1; }

.map-list-empty {
  font-family: var(--font-mono);
  font-size: 12px;
  color: #94a3b8;
  padding: 14px 10px;
  margin: 0;
}

@media (max-width: 640px) {
  .map-list-panel { width: auto; left: 12px; }
}

/* ---- pulsing ring on the most recent quake ---- */

@keyframes latest-pulse-ring {
  0%   { transform: translate(-50%, -50%) scale(0.3); opacity: 1; }
  80%  { transform: translate(-50%, -50%) scale(3);   opacity: 0; }
  100% { transform: translate(-50%, -50%) scale(3);   opacity: 0; }
}

/* Zero-size divIcon: the ring is centred on the anchor point via translate,
   so it tracks the marker position at any zoom. */
.latest-pulse {
  width: 0;
  height: 0;
  pointer-events: none;
}

.latest-pulse .ring {
  position: absolute;
  top: 0;
  left: 0;
  width: 34px;
  height: 34px;
  border: 3px solid #ff4444;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  animation: latest-pulse-ring 2s ease-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .latest-pulse .ring { animation: none; opacity: 0.85; transform: translate(-50%, -50%) scale(1.4); }
}

/* ---- map area selector ---- */

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

.map-area-select {
  display: inline-flex;
  align-items: center;
}

.map-area-select select {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 6px 9px;
  max-width: 168px;
  cursor: pointer;
  box-shadow: var(--shadow);
}

.map-area-select select:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

/* ---- terrain basemap (shaded relief) ---- */

/* Esri imagery, desaturated and dimmed so quake markers stay the brightest
   thing on the map. Contrast rises as brightness drops, which stops the
   coastline sinking into the ocean at this exposure. */
.map-terrain-base {
  filter: grayscale(1) brightness(0.26) contrast(1.15);
}

/* The hillshade tiles are opaque grey, so soft-light is what turns them into
   relief over the imagery instead of a flat sheet covering it. */
.map-hillshade {
  mix-blend-mode: soft-light;
  filter: grayscale(1);
  pointer-events: none;
}
