/* theme.css — EMD grid-cells page.
   Uses only --emd-* variables defined in stylesheets/custom.css.
   No colour or font definitions here — those live in the shared stylesheet. */

/* ============================================================
   REDUCED MOTION
   The page animates a fair amount — row pulse, spinner, node
   transitions, smooth scrolling. Honour the OS-level preference:
   vestibular disorders make the pulse + auto-scroll combination
   genuinely unpleasant.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .emd-page *,
  .emd-page *::before,
  .emd-page *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto !important; }
}

/* ============================================================
   DARK MODE TOGGLE
   ============================================================ */
#gc-dark-toggle {
  position: absolute; top: 0; right: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  background: none; border: 1px solid var(--emd-border);
  border-radius: 6px; cursor: pointer; color: var(--emd-text-secondary);
  transition: border-color .15s, color .15s, background .15s;
}
#gc-dark-toggle:hover { border-color: var(--emd-primary); color: var(--emd-primary); }
#gc-dark-toggle svg { width: 16px; height: 16px; }

/* ============================================================
   PAGE WRAPPER
   ============================================================ */
.emd-page {
  font-family: "Inter", "Noto Sans", ui-sans-serif, system-ui, sans-serif;
  color: var(--emd-text);
  line-height: 1.5;
  /* was a flat 1180px — the table has many columns and was needlessly
     cramped. Still capped so the scatter square and auto-fill filter grid
     don't sprawl on ultrawide displays. */
  max-width: min(96vw, 1800px);
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
  background: var(--emd-bg-secondary);
}
.emd-page *, .emd-page *::before, .emd-page *::after { box-sizing: border-box; }
.emd-page code { font-family: "JetBrains Mono", ui-monospace, monospace; }

/* ============================================================
   HEADER
   ============================================================ */
.gc-header { margin-bottom: 1.25rem; position: relative; }
.eyebrow { margin: 0; font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--emd-text-tertiary); font-weight: 600; }
a.eyebrow-home { text-decoration: none; color: var(--emd-text-tertiary); transition: color .15s; }
a.eyebrow-home:hover { color: var(--emd-primary); }
.gc-title { margin: .2rem 0 0; font-size: 1.8rem; font-weight: 700; letter-spacing: -.02em; color: var(--emd-text); }

/* ============================================================
   SHELL
   ============================================================ */
.gc-shell { display: flex; flex-direction: column; gap: .75rem; }

/* ============================================================
   LOADING / ERROR
   ============================================================ */
.page-spinner { display: flex; flex-direction: column; align-items: center; gap: .9rem; padding: 5rem 0; color: var(--emd-text-secondary); }
.spinner-ring { width: 32px; height: 32px; border-radius: 50%; border: 2px solid var(--emd-border); border-top-color: var(--emd-primary); animation: spin .75s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.page-error { padding: 1rem 1.25rem; color: #991b1b; background: #fef2f2; border: 1px solid #fecaca; border-radius: 6px; font-size: .875rem; }

/* ============================================================
   SIMILARITY MAP (PCoA scatter with kNN graph, collapsible)
   ============================================================ */
/* Reset any site-wide <details> styling so we can restyle from scratch. */
details.gc-scatter-card {
  background: linear-gradient(180deg, var(--emd-bg) 0%, var(--emd-bg-secondary) 100%);
  border: 1px solid var(--emd-border);
  border-radius: 8px;
  padding: .75rem .95rem;
  margin: 0;
  overflow: hidden;
}
details.gc-scatter-card[open] { padding-bottom: .85rem; }

/* Custom <summary> — click target for collapse. Hosts the caret and status
   line only (no figure title), so both sit together at the left rather than
   being pushed apart. */
.gc-scatter-summary {
  list-style: none;                     /* hide default disclosure marker */
  cursor: pointer;
  display: flex; align-items: baseline; justify-content: flex-start;
  gap: .5rem;
  padding: 0;
  margin: 0;
  background: transparent;              /* override site-wide details styling */
  border-radius: 0;
  border-bottom: none;
  user-select: none;
}
.gc-scatter-summary::-webkit-details-marker { display: none; }
.gc-scatter-summary::after { content: none; }   /* override site-wide caret pseudo */
.gc-scatter-summary:hover .gc-scatter-status,
.gc-scatter-summary:hover .gc-scatter-caret { color: var(--emd-primary); }

.gc-scatter-caret {
  display: inline-block;
  font-size: .7rem; color: var(--emd-text-tertiary);
  transition: transform .15s ease;
  transform-origin: center;
  width: .8rem;
}
details.gc-scatter-card[open] .gc-scatter-caret { transform: rotate(90deg); }

.gc-scatter-status {
  font-size: .72rem; color: var(--emd-text-tertiary);
  font-variant-numeric: tabular-nums;
  transition: color .15s;
}

/* Body (plot + legend) only visible when open. Add a small top margin so it
   isn't glued to the summary. */
details.gc-scatter-card > .gc-scatter-body { margin-top: .5rem; }

.gc-scatter-svg { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; overflow: visible; user-select: none; -webkit-user-select: none; touch-action: none; }

/* three-column layout: plot flush left, legend centered between the two ends,
   detail flush right. With justify-content: space-between on exactly three
   items, the middle item sits with equal space on either side. */
.gc-scatter-body { display: flex; align-items: stretch; justify-content: space-between; gap: 1.5rem; }
/* Plot is a 1:1 square, so width == height.
   Rules: at least 45% of the card width, but never taller than 70vh
   (so it can't dominate short viewports). Hard upper bound at 560px. */
.gc-scatter-plot {
  flex: 0 0 auto;
  min-width: min(45%, 70vh);
  max-width: min(560px, 70vh);
}

/* edges: subtle links between kNN neighbours in the projection */
.gc-edge {
  stroke: var(--emd-text-tertiary);
  fill: none;
  transition: stroke-opacity .15s, stroke-width .15s, stroke .15s;
  pointer-events: none;
}
.gc-edge.linked { stroke: var(--emd-primary); stroke-opacity: .55 !important; stroke-width: 1.4 !important; }
.gc-edge.muted  { stroke-opacity: .04 !important; }
.gc-edge.filtered-out { stroke-opacity: 0 !important; }

/* glow: hidden by default, appears behind the active node */
.gc-glow { opacity: 0; transition: opacity .18s; pointer-events: none; }
.gc-glow.visible { opacity: 1; }
.gc-glow.filtered-out { opacity: 0 !important; }

.gc-node {
  cursor: pointer;
  stroke: var(--emd-bg);
  stroke-width: 1.5;
  /* NB: r is updated every frame during rotation; do not transition it here.
     Use only class-based state transitions on stroke/opacity. */
  transition: opacity .15s, stroke-width .15s, stroke .15s;
  filter: url(#gc-node-shadow);
}
.gc-node:hover { stroke-width: 2.5; }
.gc-node.active { stroke: var(--emd-text); stroke-width: 2.5; }
.gc-node.linked { stroke-width: 2; }
.gc-node.muted  { opacity: .16; }
.gc-node.filtered-out { opacity: .06; pointer-events: none; }

/* Legend: minimal by default (dot + count only) so the aside column can be
   wide enough for the filter controls. Toggling .expanded reveals the names. */
.gc-scatter-legend {
  display: flex; flex-direction: column; gap: .3rem;
  flex: 0 0 auto; min-width: 0;
  padding-top: .2rem;
  padding-bottom: .1rem;
}
.gc-legend-list { display: flex; flex-direction: column; gap: .4rem; }
.gc-legend-item { display: inline-flex; align-items: center; gap: .45rem; font-size: .74rem; color: var(--emd-text-secondary); cursor: default; }
.gc-legend-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; box-shadow: 0 0 0 1px rgba(0,0,0,.06); }
.gc-legend-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
/* Acronym stand-in shown while the legend is collapsed. Monospace and a
   min-width so the counts stay aligned across rows of differing length. */
.gc-legend-acr {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: .68rem; font-weight: 600; letter-spacing: .02em;
  color: var(--emd-text-secondary);
  min-width: 2.4em;
}
.gc-legend-count { color: var(--emd-text-tertiary); font-variant-numeric: tabular-nums; font-size: .7rem; }

/* collapsed: hide the names, keep dot + count hard against the left */
.gc-scatter-legend:not(.expanded) .gc-legend-label { display: none; }
.gc-scatter-legend.expanded .gc-legend-acr { display: none; }
.gc-scatter-legend:not(.expanded) .gc-legend-count { margin-left: auto; }
.gc-scatter-legend.expanded .gc-legend-list { min-width: 140px; max-width: 200px; }

.gc-legend-toggle {
  align-self: flex-start;
  display: inline-flex; align-items: center; justify-content: center;
  padding: .18rem .4rem;
  font: inherit; line-height: 1;
  color: var(--emd-text-tertiary);
  background: none; border: 1px solid var(--emd-border); border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
  transition: color .12s, border-color .12s, background .12s;
}
.gc-legend-toggle:hover { color: var(--emd-primary); border-color: var(--emd-primary); background: var(--emd-primary-light); }
.gc-legend-toggle:focus-visible { outline: 2px solid var(--emd-primary); outline-offset: 2px; }
/* Word label ("Expand" / "Hide") rather than a chevron, so the control reads
   unambiguously. Deliberately not rotated — that would garble the text. */
.gc-legend-caret {
  display: inline-block;
  font-size: .6rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  line-height: 1;
}

/* restart-rotation button — sits at the bottom of the legend column */
.gc-restart-rotate {
  margin-top: auto;    /* pushes to the bottom of the flex column */
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .3rem .55rem;
  font: inherit; font-size: .72rem; font-weight: 500;
  color: var(--emd-text-secondary);
  background: var(--emd-bg);
  border: 1px solid var(--emd-border);
  border-radius: 5px;
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
  white-space: nowrap;
}
.gc-restart-rotate:hover { color: var(--emd-primary); border-color: var(--emd-primary); background: var(--emd-primary-light); }
.gc-restart-rotate:focus-visible { outline: 2px solid var(--emd-primary); outline-offset: 2px; }
.gc-restart-icon { font-size: .95rem; line-height: 1; display: inline-block; }
.gc-restart-rotate:hover .gc-restart-icon { animation: gc-spin-once .5s ease-out; }
@keyframes gc-spin-once { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* Aside column — dual purpose: filter controls at rest, cell details while a
   node is hovered or pinned. Capped to the plot's height and scrolled
   internally so a tall stack of active filters can't stretch the card. */
.gc-scatter-detail {
  flex: 1 1 420px;
  min-width: 300px;
  padding: .7rem .85rem;
  background: var(--emd-bg-secondary);
  border: 1px solid var(--emd-border);
  border-radius: 6px;
  font-size: .78rem;
  color: var(--emd-text-secondary);
  align-self: stretch;
  max-height: min(560px, 70vh);
  overflow-y: auto;
  overflow-x: hidden;
}
.gc-detail-filters[hidden], .gc-detail-node[hidden] { display: none; }
.gc-detail-placeholder { margin: 0; font-size: .74rem; color: var(--emd-text-tertiary); font-style: italic; }
.gc-detail-head { display: flex; align-items: baseline; gap: .45rem; margin-bottom: .4rem; }
.gc-detail-id { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .82rem; font-weight: 600; color: var(--emd-primary); }
.gc-detail-alias { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .7rem; color: var(--emd-text-tertiary); }
.gc-detail-type { display: inline-flex; align-items: center; gap: .4rem; font-size: .72rem; color: var(--emd-text-secondary); margin-bottom: .45rem; }
.gc-detail-ui-label { margin: 0 0 .3rem 0; font-size: .78rem; color: var(--emd-text); font-style: italic; }
.gc-detail-description { margin: 0 0 .5rem 0; font-size: .74rem; line-height: 1.45; color: var(--emd-text-secondary); display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.gc-detail-fields { display: grid; grid-template-columns: max-content 1fr; gap: .2rem .6rem; margin: 0; font-size: .72rem; }
.gc-detail-fields dt { color: var(--emd-text-tertiary); font-weight: 600; font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; align-self: baseline; }
.gc-detail-fields dd { margin: 0; color: var(--emd-text); }

/* ---- compact filters, as hosted inside the aside column ----
   Stacked single-column layout with tightened type and padding. All rules are
   scoped to .gc-filters-compact so the standalone (phone) filter card keeps
   its original wide layout. */
.gc-filters-heading {
  font-size: .62rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--emd-text-tertiary);
}
.gc-filters-compact { gap: .5rem; }
.gc-filters-compact .gc-control-row { flex-wrap: wrap; gap: .3rem .5rem; }
.gc-filters-compact .gc-search-row { flex: 1 1 100%; max-width: none; }
.gc-filters-compact .gc-search-input { font-size: .8rem; padding: .34rem .55rem .34rem 1.85rem; }
.gc-filters-compact .gc-search-input::placeholder { font-size: .75rem; }
.gc-filters-compact .gc-search-icon { left: .5rem; width: 13px; height: 13px; }
.gc-filters-compact .gc-clear-link { margin-left: auto; font-size: .72rem; }

/* Pills are individually bordered here rather than forming a seamless
   segmented group, so the column count can change freely at breakpoints.
   JS sets no inline grid-template-columns in compact mode. */
.gc-filters-compact .gc-pill-row {
  width: 100%;
  grid-template-columns: 1fr;
  gap: .3rem;
  border: none; border-radius: 0; background: none; overflow: visible;
}
.gc-filters-compact .gc-pill {
  justify-content: flex-start;
  padding: .3rem .55rem;
  font-size: .74rem;
  border: 1px solid var(--emd-border);
  border-radius: 5px;
}

/* active panels stack vertically instead of tiling */
.gc-filters-compact .gc-panel-area { grid-template-columns: 1fr; gap: .4rem; }
.gc-filters-compact .gc-panel::before { padding: .26rem .55rem .22rem; font-size: .6rem; }
.gc-filters-compact .gc-panel-body { padding: .45rem .55rem .5rem; gap: .35rem; }
.gc-filters-compact .gc-check-list { max-height: 132px; }
.gc-filters-compact .gc-check-row { font-size: .76rem; padding: .15rem; }
.gc-filters-compact .gc-check-search { font-size: .76rem; padding: .26rem .4rem; }
.gc-filters-compact .gc-check-count { font-size: .66rem; }
.gc-filters-compact .gc-num-input { font-size: .76rem; padding: .24rem .3rem; }
.gc-filters-compact .gc-num-label { font-size: .6rem; }
.gc-filters-compact .gc-range-wrap { height: 20px; }

/* Larger screens: the aside is wide enough to run two filters abreast.
   Declared after the single-column defaults above so it wins on source order
   (media queries add no specificity of their own). */
@media (min-width: 1200px) {
  .gc-filters-compact .gc-pill-row { grid-template-columns: 1fr 1fr; }
  .gc-filters-compact .gc-panel-area { grid-template-columns: 1fr 1fr; }
}

/* row highlighted because its scatter node is hovered */
.gc-row-linked { background: var(--emd-primary-light) !important; box-shadow: inset 3px 0 0 var(--emd-primary); }

/* row-pulse: brief flash when a scatter node is clicked and its row is revealed */
@keyframes gc-row-pulse {
  0%   { background: var(--emd-primary-light); box-shadow: inset 3px 0 0 var(--emd-primary); }
  100% { background: transparent; box-shadow: inset 3px 0 0 transparent; }
}
.gc-row-pulse { animation: gc-row-pulse 1.4s ease-out; }

/* ============================================================
   FILTER CARD
   ============================================================ */
.gc-filter-card {
  background: var(--emd-bg);
  border: 1px solid var(--emd-border);
  border-radius: 6px;
  padding: .85rem 1rem .9rem;
}
.gc-filters { display: flex; flex-direction: column; gap: .7rem; }

/* search + clear */
.gc-control-row { display: flex; align-items: center; gap: .65rem; }
.gc-search-row { position: relative; flex: 1 1 220px; max-width: 380px; display: flex; align-items: center; }
.gc-search-icon { position: absolute; left: .6rem; width: 15px; height: 15px; color: var(--emd-text-tertiary); pointer-events: none; }
.gc-search-icon svg { width: 100%; height: 100%; }
.gc-search-input {
  font: inherit; font-size: .875rem;
  padding: .42rem .65rem .42rem 2rem; width: 100%;
  border: 1px solid var(--emd-border);
  border-radius: 6px;
  background: var(--emd-bg);
  color: var(--emd-text);
  transition: border-color .15s, box-shadow .15s;
}
.gc-search-input:focus { outline: none; border-color: var(--emd-primary); box-shadow: 0 0 0 3px var(--emd-primary-light); }
.gc-search-input::placeholder { color: var(--emd-text-tertiary); font-size: .83rem; }
.gc-clear-link { font: inherit; font-size: .78rem; color: var(--emd-text-tertiary); background: none; border: none; cursor: pointer; padding: 0; margin-left: auto; transition: color .15s; white-space: nowrap; }
.gc-clear-link:hover { color: var(--emd-text); }

/* ---- pill toggles: uniform segmented group ---- */
.gc-pill-row {
  display: grid; /* columns set inline by JS for equal-count rows */
  border: 1px solid var(--emd-border);
  border-radius: 6px; overflow: hidden;
  background: var(--emd-bg);
  width: fit-content; max-width: 100%;
}
.gc-pill {
  display: flex; align-items: center; justify-content: center;
  font: inherit; font-size: .78rem; font-weight: 500;
  padding: .38rem .75rem;
  border: none;
  border-right: 1px solid var(--emd-border-light);
  border-bottom: 1px solid var(--emd-border-light);
  background: var(--emd-bg); color: var(--emd-text-secondary);
  cursor: pointer; white-space: nowrap; user-select: none;
  transition: background .12s, color .12s;
  text-align: center;
}
/* remove right border on last column, bottom border on last row */
.gc-pill:last-child { border-right: none; }
.gc-pill:hover:not(.active) { background: var(--emd-bg-secondary); color: var(--emd-text); }
.gc-pill.active { background: var(--emd-primary); color: #fff; font-weight: 600; }
.gc-pill:focus-visible { outline: 2px solid var(--emd-primary); outline-offset: -2px; z-index: 1; }
.gc-pill-label { line-height: 1; }

/* ---- filter panels ---- */
.gc-panel-area { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: .5rem; }
.gc-panel[hidden] { display: none; }
.gc-panel-enter { animation: panel-in .13s ease; }
@keyframes panel-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }

.gc-panel { border: 1px solid var(--emd-border); border-left-width: 3px; border-radius: 6px; background: var(--emd-bg); overflow: hidden; }
.gc-panel-category { border-left-color: var(--emd-primary); }
.gc-panel-numeric  { border-left-color: #059669; }
.gc-panel-text     { border-left-color: #d97706; }

.gc-panel::before {
  content: attr(data-label);
  display: block; font-size: .64rem; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--emd-text-tertiary); padding: .32rem .65rem .28rem;
  border-bottom: 1px solid var(--emd-border-light); background: var(--emd-bg-secondary);
}

.gc-panel-body { padding: .55rem .65rem .6rem; display: flex; flex-direction: column; gap: .4rem; }

/* category checklist */
.gc-check-search { font: inherit; font-size: .8rem; padding: .3rem .45rem; border: 1px solid var(--emd-border); border-radius: 4px; background: var(--emd-bg-secondary); color: var(--emd-text); width: 100%; transition: border-color .15s; }
.gc-check-search:focus { outline: none; border-color: var(--emd-primary); box-shadow: 0 0 0 2px var(--emd-primary-light); }
.gc-check-list { display: flex; flex-direction: column; max-height: 160px; overflow-y: auto; }
.gc-check-row { display: flex; align-items: center; gap: .4rem; font-size: .8rem; padding: .2rem .2rem; border-radius: 3px; cursor: pointer; }
.gc-check-row:hover { background: var(--emd-bg-tertiary); }
.gc-check-row input { accent-color: var(--emd-primary); flex: none; width: 13px; height: 13px; cursor: pointer; }
.gc-check-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gc-check-count { font-size: .7rem; color: var(--emd-text-tertiary); }

/* numeric range */
.gc-range-wrap { position: relative; height: 24px; display: flex; align-items: center; margin: 0 .15rem; }
.gc-range-track { position: absolute; left: 0; right: 0; height: 3px; background: var(--emd-border); border-radius: 2px; }
.gc-range-fill { position: absolute; top: 0; bottom: 0; background: #059669; border-radius: 2px; }
.gc-range { position: absolute; left: 0; right: 0; width: 100%; margin: 0; background: none; pointer-events: none; -webkit-appearance: none; appearance: none; height: 24px; }
.gc-range::-webkit-slider-thumb { -webkit-appearance: none; pointer-events: auto; width: 13px; height: 13px; border-radius: 3px; background: #059669; border: none; cursor: pointer; }
.gc-range::-moz-range-thumb { pointer-events: auto; width: 13px; height: 13px; border-radius: 3px; background: #059669; border: none; cursor: pointer; }
.gc-range::-webkit-slider-runnable-track, .gc-range::-moz-range-track { background: none; }
.gc-num-row { display: flex; gap: .4rem; }
.gc-num-label { display: flex; flex-direction: column; gap: .1rem; font-size: .64rem; color: var(--emd-text-tertiary); flex: 1; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.gc-num-input { font: inherit; font-size: .8rem; padding: .28rem .35rem; border: 1px solid var(--emd-border); border-radius: 4px; background: var(--emd-bg-secondary); color: var(--emd-text); width: 100%; transition: border-color .15s; }
.gc-num-input:focus { outline: none; border-color: #059669; box-shadow: 0 0 0 2px rgba(5,150,105,.12); }

/* ============================================================
   TABLE
   ============================================================ */
.gc-table-card { background: var(--emd-bg); border: 1px solid var(--emd-border); border-radius: 6px; overflow: hidden; }

.gc-table-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .65rem 1rem; border-bottom: 1px solid var(--emd-border); }
.gc-table-title { margin: 0; font-size: .875rem; font-weight: 600; color: var(--emd-text); }
.gc-count-pill { font-size: .72rem; color: var(--emd-text-tertiary); }

.gc-table-wrap { overflow-x: auto; }

/* ============================================================
   VIEW TOGGLE (graph / table)
   ============================================================ */
.gc-view-toggle { display: inline-flex; align-self: flex-start; }
.gc-view-btn {
  background: var(--emd-bg); color: var(--emd-text-secondary);
  border: 1px solid var(--emd-border);
  padding: .3rem .85rem; font: inherit; font-size: .78rem; font-weight: 600;
  cursor: pointer; margin-left: -1px;
  transition: color .12s, border-color .12s, background .12s;
}
.gc-view-btn:first-child { margin-left: 0; border-radius: 5px 0 0 5px; }
.gc-view-btn:last-child { border-radius: 0 5px 5px 0; }
.gc-view-btn:hover { color: var(--emd-primary); }
.gc-view-btn[aria-pressed="true"] {
  color: var(--emd-primary); border-color: var(--emd-primary);
  background: var(--emd-primary-light); z-index: 1;
}

/* ============================================================
   PAGER + CSV TOOLBAR
   ============================================================ */
.gc-table-outer { display: flex; flex-direction: column; }

.gc-pager {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .5rem .75rem;
  border-top: 1px solid var(--emd-border);
  background: var(--emd-bg-secondary);
  font-size: .75rem;
}
.gc-pager-spacer { flex: 1 1 auto; }
.gc-page-info { color: var(--emd-text-tertiary); font-variant-numeric: tabular-nums; }
.gc-page-pos {
  color: var(--emd-text); font-variant-numeric: tabular-nums;
  min-width: 4.5em; text-align: center;
}
.gc-page-btns { display: flex; align-items: center; gap: .15rem; }

.gc-page-btn, .gc-csv-btn {
  background: var(--emd-bg); color: var(--emd-text-secondary);
  border: 1px solid var(--emd-border); border-radius: 5px;
  padding: .25rem .5rem; font: inherit; cursor: pointer;
  transition: border-color .12s, color .12s, background .12s;
}
.gc-page-btn { min-width: 1.9rem; line-height: 1.2; }
.gc-csv-btn { font-weight: 600; padding: .28rem .7rem; }
.gc-page-btn:hover:not(:disabled),
.gc-csv-btn:hover:not(:disabled) { border-color: var(--emd-primary); color: var(--emd-primary); }
.gc-page-btn:disabled, .gc-csv-btn:disabled { opacity: .4; cursor: not-allowed; }

.gc-page-size-label {
  display: inline-flex; align-items: center; gap: .35rem;
  color: var(--emd-text-tertiary);
}
.gc-page-size {
  background: var(--emd-bg); color: var(--emd-text);
  border: 1px solid var(--emd-border); border-radius: 5px;
  padding: .2rem .35rem; font: inherit; cursor: pointer;
}
/* one page of results → hide paging controls, keep the count and CSV */
.gc-pager.single-page .gc-page-btns,
.gc-pager.single-page .gc-page-size-label { display: none; }

/* zoom reset lives on the scatter summary bar */
.gc-zoom-reset {
  margin-left: auto;
  background: var(--emd-bg); color: var(--emd-text-secondary);
  border: 1px solid var(--emd-border); border-radius: 5px;
  padding: .2rem .55rem; font-size: .7rem; font-family: inherit;
  cursor: pointer; transition: border-color .12s, color .12s, opacity .12s;
}
.gc-zoom-reset:hover:not(:disabled) { border-color: var(--emd-primary); color: var(--emd-primary); }
.gc-zoom-reset:disabled { opacity: .35; cursor: default; }

/* the plot is draggable once zoomed */
.gc-scatter-svg { cursor: grab; touch-action: none; }
.gc-scatter-svg:active { cursor: grabbing; }

/* Sortable headers are focusable (tabindex=0) — they need a visible ring,
   and a general fallback so no interactive element focuses invisibly. */
.gc-th:focus-visible {
  outline: 2px solid var(--emd-primary);
  outline-offset: -2px;
}
.emd-page a:focus-visible,
.emd-page button:focus-visible,
.emd-page [tabindex]:focus-visible {
  outline: 2px solid var(--emd-primary);
  outline-offset: 2px;
}
/* Auto layout so column widths follow content and the table fills the card.
   Previously `fixed` with hard ch widths, which cramped long category values
   (e.g. atmosphere-hybrid-sigma-pressure-coordinate) on collections with few
   columns while leaving horizontal space unused. */
.gc-table { border-collapse: collapse; width: 100%; font-size: .82rem; table-layout: auto; }

.gc-th {
  position: sticky; top: 0; z-index: 2;
  background: var(--emd-bg-secondary);
  text-align: left; padding: .4rem .5rem;
  font-size: .63rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--emd-text-tertiary); font-weight: 700;
  cursor: pointer; border-bottom: 1px solid var(--emd-border);
  user-select: none; transition: color .12s; vertical-align: bottom;
}
.gc-th:hover { color: var(--emd-primary); }
.gc-th.sorted { color: var(--emd-primary); }
.gc-th-label { display: inline-block; overflow-wrap: break-word; }
.gc-sort-arrow { font-size: .55rem; }

/* Numeric columns shrink to their content (`width:1%` under auto layout is the
   standard "as narrow as possible" trick) so the slack goes to the text-heavy
   category columns instead of padding out number columns. */
.gc-th-numeric,
.gc-td-numeric { width: 1%; min-width: 8ch; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.gc-num { font-variant-numeric: tabular-nums; font-size: .8rem; }
.gc-num.has-tip { cursor: help; }

/* Category columns absorb the remaining width — no hard cap, so long CV
   labels wrap over two lines rather than being squeezed into 10ch. */
.gc-th-category,
.gc-td-category { min-width: 10ch; }

.gc-row { border-bottom: 1px solid var(--emd-border-light); }
/* Each visible row is paired with a hidden detail row, so step by 4 in the DOM
   (2 DOM rows per data row) to get alternating stripes on every other data row. */
.gc-row:nth-child(4n+1) { background: var(--emd-bg-secondary); }
.gc-row:hover { background: var(--emd-bg-tertiary) !important; }
.gc-row.expanded { background: var(--emd-bg-tertiary) !important; }
.gc-td { padding: .42rem .5rem; vertical-align: top; overflow-wrap: break-word; }

/* id cell — sized to its content (id + optional alias subtitle) rather than a
   hard 4ch, which under auto layout would squeeze the alias to one char/line. */
.gc-td-id { width: 1%; min-width: 12ch; white-space: nowrap; }
.gc-expand { display: inline-flex; flex-direction: column; align-items: flex-start; gap: .12rem; background: none; border: none; cursor: pointer; font: inherit; padding: 0; color: var(--emd-text); text-align: left; width: 100%; }
.gc-id-head { display: inline-flex; align-items: center; gap: .35rem; }
.gc-caret { font-size: .48rem; color: var(--emd-text-tertiary); flex: none; }
.gc-id { font-size: .82rem; font-weight: 600; color: var(--emd-primary); font-family: "JetBrains Mono", ui-monospace, monospace; }
.gc-expand:hover .gc-id { text-decoration: underline; }
.gc-id-sub { padding-left: .8rem; }
.gc-alias { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .67rem; color: var(--emd-text-tertiary); }

/* term chips */
.gc-terms { display: inline-flex; flex-wrap: wrap; gap: .2rem; }
.gc-term { display: inline-block; font-size: .8rem; line-height: 1.3; }
.gc-term.has-tip { border-bottom: 1px dotted var(--emd-border); cursor: help; transition: border-color .12s, color .12s; }
.gc-term.has-tip:hover { border-bottom-color: var(--emd-primary); color: var(--emd-primary); }
.gc-empty { color: var(--emd-border); }

/* expanded detail */
.gc-detail-row > .gc-detail-cell { padding: 0; background: var(--emd-bg-secondary); border-bottom: 1px solid var(--emd-border); }
.gc-detail { padding: .85rem 1rem .9rem 2rem; display: flex; flex-direction: column; gap: .6rem; }
.gc-detail-desc { margin: 0; font-size: .84rem; color: var(--emd-text-secondary); font-style: italic; max-width: 68ch; }
.gc-detail-grid { display: grid; grid-template-columns: max-content 1fr; gap: .3rem .85rem; margin: 0; }
.gc-detail-grid dt { font-size: .61rem; text-transform: uppercase; letter-spacing: .06em; color: var(--emd-text-tertiary); font-weight: 700; align-self: baseline; }
.gc-detail-grid dd { margin: 0; font-size: .82rem; }
.gc-detail-link { align-self: flex-start; font-size: .73rem; font-weight: 600; color: var(--emd-primary); text-decoration: none; border: 1px solid var(--emd-border); border-radius: 4px; padding: .2rem .55rem; transition: background .15s, color .15s, border-color .15s; }
.gc-detail-link:hover { background: var(--emd-primary); color: #fff; border-color: var(--emd-primary); }

.gc-norows { text-align: center; padding: 2.5rem 1rem; color: var(--emd-text-tertiary); font-size: .875rem; }

/* floating tooltip */
.gc-tooltip { position: fixed; z-index: 1000; max-width: 260px; padding: .4rem .6rem; background: var(--emd-text); color: var(--emd-bg); font-size: .75rem; line-height: 1.45; border-radius: 5px; box-shadow: 0 4px 14px rgba(0,0,0,.2); pointer-events: none; opacity: 0; transition: opacity .1s; }
.gc-tooltip.visible { opacity: 1; }

/* Tablet band: plot + legend + aside all still fit as three columns, but need
   tightening. Shrinking the plot's floor keeps the aside usable for filters. */
@media (max-width: 900px) {
  .gc-scatter-body { gap: 1rem; }
  .gc-scatter-plot { min-width: min(38%, 70vh); }
  .gc-scatter-detail { min-width: 230px; flex-basis: 280px; }
  /* keep the legend collapsed-narrow here even if expanded */
  .gc-scatter-legend.expanded .gc-legend-list { max-width: 130px; }
}

@media (max-width: 640px) {
  .emd-page { padding: 1.5rem .9rem 3rem; }
  .gc-title { font-size: 1.45rem; }
  .gc-pill-row { width: 100%; border-radius: 6px; }
  .gc-panel-area { grid-template-columns: 1fr; }
  .gc-td-id { width: 4ch; }
  .gc-scatter-body { flex-direction: column; }
  .gc-scatter-legend { flex-direction: row; flex-wrap: wrap; gap: .35rem 1rem; max-width: none; min-width: 0; padding-top: 0; }
  /* stacked, so the aside no longer needs to match the plot's height */
  .gc-scatter-detail { max-height: none; flex-basis: auto; }
}
