/* Bigger base font for readability on a wider canvas. */
html { font-size: 16.5px; }

/* Widen the navigation sidebar AND realign the main content next to it.
 *
 * Framework's layout.css does two things we have to defeat:
 *   - #observablehq-sidebar width is hardcoded as `calc(272px + ...)` —
 *     bumping --observablehq-sidebar-width alone is not enough; we set
 *     `width` on the selector explicitly.
 *   - #observablehq-center reserves room for the sidebar via
 *     `--observablehq-inset-left: calc(272px + 1rem)` and applies it as
 *     `padding-left`. That value is also hardcoded to 272px and does NOT
 *     pick up our wider sidebar. We override the inset to match.
 *
 * #observablehq-center also has `margin: 2rem` by default; the right 2rem
 * shrinks the usable content width and shows up as a visible gap on the
 * right edge. We collapse the horizontal margin to 0 and let padding handle
 * the gutter, so the map and other content extend close to the right edge.
 */
:root {
  --observablehq-sidebar-width: 309px;
}
#observablehq-sidebar {
  width: var(--observablehq-sidebar-width);
}
/* Desktop layout rules. Gated behind min-width: 769px so the mobile block
 * further down owns the small-viewport layout (sidebar-as-drawer, no left
 * inset on main, etc.) without fighting the desktop padding-left math. */
@media (min-width: 769px) {
  #observablehq-sidebar-toggle:checked ~ #observablehq-center,
  #observablehq-sidebar-toggle:indeterminate ~ #observablehq-center {
    --observablehq-inset-left: calc(var(--observablehq-sidebar-width) + 1.625rem);
    padding-left: var(--observablehq-inset-left);
    padding-right: 1rem;
  }
  /* When the sidebar is collapsed, Framework's default drops the left inset
   * to ~0, which puts the expand-toggle button on top of the page H1 and
   * body prose. Reserve a small left gutter so the toggle has its own. */
  #observablehq-sidebar-toggle:not(:checked):not(:indeterminate) ~ #observablehq-center {
    padding-left: 2.5rem;
    padding-right: 1rem;
  }
}
#observablehq-center {
  margin: 1rem 0;
}

/* The site title is the first <li> in the sidebar's first <ol>. Framework's
 * default puts the collapse arrow (#observablehq-sidebar-close) at the
 * top-right of the sidebar, crowding the title and forcing it to wrap into
 * a narrow column. Move the arrow to the vertical middle of the sidebar's
 * right edge — that frees the full sidebar width for the title and makes
 * the toggle easier to reach mid-page anyway.
 *
 * #observablehq-sidebar-close is anchored to the sidebar (which has
 * `position: sticky` from layout.css, establishing a containing block), so
 * `position: absolute` honors that anchor. We pin it to viewport vertical
 * center via `position: fixed` with `top: 50%` so it stays mid-screen even
 * if the sidebar nav is long enough to scroll. */
#observablehq-sidebar > ol:first-of-type {
  padding-right: 0;
}
#observablehq-sidebar > ol:first-of-type > li:first-child > a {
  font-size: 1em;
  line-height: 1.25;
}
#observablehq-sidebar-close {
  position: fixed;
  top: 50%;
  left: calc(var(--observablehq-sidebar-width) - 1.75rem);
  right: auto;
  transform: translateY(-50%);
  z-index: 5;
}

/* Headings sized to match the wider content area. clamp() lets the H1
 * shrink on narrow viewports without breaking the desktop appearance:
 * 5vw resolves to ~64px on a 1280px window which is well above the 2.2rem
 * upper bound, so desktop always renders at 2.2rem = 36.3px (identical to
 * the previous `2.2em` rule given the 16.5px html root). On a 390px phone,
 * 5vw = 19.5px and the min kicks in, giving a readable 1.5rem ≈ 24.75px. */
#observablehq-main h1 { font-size: clamp(1.5rem, 5vw, 2.2rem); line-height: 1.15; margin: 0.4em 0 0.4em; }
#observablehq-main h2 { font-size: 1.5em; line-height: 1.2; margin-top: 1.2em; }
#observablehq-main h3 { font-size: 1.1em; }

/* Equal-height cards in 3-column rows. minmax(0, 1fr) prevents column overflow
   when content forces a child wider than its cell; align-items: stretch makes
   every card in a row match the tallest; flex-column on .card lets inner
   content fill vertical space. */
.grid-cols-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  align-items: stretch;
}
.grid-cols-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  align-items: stretch;
}
.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* Vertical spacing when consecutive grid rows stack on the same page. */
.grid-cols-2 + .grid-cols-2,
.grid-cols-3 + .grid-cols-3,
.grid-cols-2 + .grid-cols-3,
.grid-cols-3 + .grid-cols-2 {
  margin-top: 1rem;
}

/* Pop-up info panel for metric definitions. */
.info-popover {
  display: none;
  position: relative;
  margin: 0.6rem 0;
  padding: 0.85rem 1.1rem;
  border-left: 3px solid #6ee7b7;
  background: rgba(110, 231, 183, 0.10);
  border-radius: 0.25rem;
  font-size: 0.95em;
  line-height: 1.45;
}
.info-popover.open { display: block; }
.info-popover .info-close {
  float: right;
  cursor: pointer;
  opacity: 0.5;
  font-size: 1.1em;
  line-height: 1;
  margin-left: 1rem;
  background: transparent;
  border: none;
  color: inherit;
}
.info-popover .info-close:hover { opacity: 1; }

.info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6em;
  height: 1.6em;
  margin-left: 0.4em;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 0.85em;
  font-weight: bold;
  font-style: italic;
  font-family: serif;
  opacity: 0.55;
  vertical-align: middle;
  padding: 0;
  line-height: 1;
}
.info-btn:hover { opacity: 1; }
.info-btn.active {
  opacity: 1;
  background: rgba(110, 231, 183, 0.15);
  border-color: #6ee7b7;
  color: #6ee7b7;
}

/* Page-intro paragraph below the H1. */
.page-intro {
  opacity: 0.85;
  margin-top: -0.4em;
}

/* H1 that clips long titles cleanly. */
.h1-clip {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Card-header row: title + info button on the same line. */
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
}
.card-header h3 { margin: 0; }

/* Compact card variant used on the county profile family cards. */
.card-tight { padding: 0.7rem 0.9rem; }
.card-tight h3 { margin: 0 0 0.3rem 0; }

/* County-profile header card. */
.county-title { padding: 0.5rem 1rem; }
.county-title h2 { margin: 0; }
.county-fips-suffix { color: #888; font-weight: normal; font-size: 0.7em; }
.county-bridge-note { color: #888; font-weight: normal; font-size: 0.75em; }

/* County-profile metric family layout. */
.family-block { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 12px; margin-bottom: 18px; }
.family-block h3 { margin: 0 0 4px 0; opacity: 0.75; }
.family-label {
  font-size: 0.78em;
  opacity: 0.75;
  margin-bottom: 4px;
  line-height: 1.2;
  display: flex;
  align-items: center;
}

/* Sparkline legend on the county profile (focal vs national median vs IQR). */
.sparkline-legend {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  font-size: 0.85em;
  opacity: 0.85;
  margin: 0.6rem 0 0.4rem 0;
  padding: 0.4rem 0.75rem;
  border-left: 3px solid var(--theme-foreground-faintest, #444);
  background: rgba(255, 255, 255, 0.02);
  border-radius: 0.25rem;
}
.sparkline-legend .legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sparkline-legend svg { vertical-align: middle; }

/* By-employer-type help line on county profile. */
.employer-help-line {
  font-size: 0.8em;
  opacity: 0.7;
  margin: -0.2rem 0 0.4rem 0;
}

/* Heading variant that removes its default top margin (used inside cards
   that already have their own padding). */
h3.h3-flush { margin-top: 0; }

/* Toolbar row above charts (year slider + play button, etc). */
.toolbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.4rem;
}
.toolbar-row {
  display: flex;
  align-items: center;
  gap: 0;
}

/* Map legend swatches row below the choropleth. */
.legend-row {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  font-size: 0.85em;
  opacity: 0.85;
  margin-top: 0.4rem;
}
.legend-swatch {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

/* Suppress-toggle row beneath the legend (in its own cell). */
.suppress-row {
  margin-top: 0.6rem;
  font-size: 0.9em;
}

/* Status / annotation lines above charts. */
.muted-note { opacity: 0.7; }
.muted-note-strong { opacity: 0.85; }
.tiny-note { font-size: 0.85em; color: #6b7280; margin-top: 8px; }

/* County profile two-tier renderers. */
.tier-row { font-size: 12px; margin-bottom: 6px; }
.tier-row-empty { color: #9ca3af; }
.tier-row-shared { margin-top: 2px; }

/* Featured-pair list on the scatter page. */
.feature-list { margin: 0; padding-left: 1.4rem; }
.feature-list li { margin-bottom: 0.7rem; }
.feature-list .feature-blurb {
  font-size: 0.86em;
  opacity: 0.8;
  margin-top: 0.15rem;
}

/* Compact stats line beneath the scatter chart. */
.scatter-stats { padding: 0.5rem 1rem; margin-top: 0.5rem; }
.scatter-stats p { margin: 0; }

/* Controls panel layout below the scatter. Three cards in a grid. */
.scatter-controls { margin-top: 1rem; }
.scatter-controls .card-tight { gap: 0.5rem; }
.scatter-controls .ctl-row {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.15rem 0;
}

/* Peer-table details disclosure on the scatter page. */
.peer-details { margin-top: 0.7rem; }
.peer-details summary {
  cursor: pointer;
  font-weight: 600;
  opacity: 0.85;
}
.peer-hint { opacity: 0.6; font-weight: normal; }
.peer-list {
  margin: 0.6rem 0 0.2rem 1.4rem;
  padding: 0;
  font-size: 0.92em;
}
.peer-list li { margin-bottom: 0.15rem; }
.peer-footnote {
  margin: 0.5rem 0 0 0;
  font-size: 0.82em;
  opacity: 0.65;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * MOBILE LAYOUT
 * Breakpoints: 768 (layout), 700 (controls/grids/charts), 640 (stacked
 * controls), 480 (touch targets). Each rule is scoped to one breakpoint.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Mobile banner under the choropleth H1. Hidden on desktop, shown on small
 * viewports. Lives on index.md as <div class="mobile-only-banner">. */
.mobile-only-banner { display: none; }

/* Mobile scatter fallback (under 700px the chart is replaced with a stub
 * that points users to Rankings & trends). */
.scatter-mobile-fallback { display: none; }

/* Mobile tooltip overlay for touch devices. Hidden by default; the JS in
 * index.md / scatter.md toggles .mobile-tooltip.open. */
.mobile-tooltip {
  display: none;
  position: fixed;
  z-index: 1000;
  max-width: min(320px, calc(100vw - 24px));
  padding: 0.6rem 0.8rem;
  background: var(--observablehq-background-base, #16161d);
  color: var(--observablehq-foreground, #f7f7f7);
  border: 1px solid #6ee7b7;
  border-radius: 0.35rem;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.6);
  font-size: 0.9rem;
  line-height: 1.35;
  pointer-events: auto;
}
.mobile-tooltip.open { display: block; }
.mobile-tooltip .mobile-tooltip-close {
  float: right;
  background: transparent;
  border: none;
  color: inherit;
  font-size: 1.1em;
  line-height: 1;
  cursor: pointer;
  margin-left: 0.6rem;
  opacity: 0.6;
}
.mobile-tooltip .mobile-tooltip-close:hover { opacity: 1; }

@media (max-width: 768px) {
  /* Sidebar becomes an overlay drawer; no left inset on the main column so
   * page content fills the viewport. Framework's drawer mechanics (the
   * #observablehq-sidebar-toggle checkbox + #observablehq-sidebar-backdrop
   * label) still drive show/hide. */
  #observablehq-center {
    padding-left: 1rem;
    padding-right: 1rem;
  }
  #observablehq-sidebar { width: 100%; max-width: 320px; }
}

@media (max-width: 700px) {
  /* Collapse all multi-column grids to single column. Applies to:
   *   - county.md family-card grid (.grid-cols-3)
   *   - county.md sparkline grid (.family-block)
   *   - scatter.md controls panel (.grid-cols-3.scatter-controls)
   *   - scatter.md featured-pair list (.grid-cols-2)
   *   - county.md total/YoY pair (.grid-cols-2) */
  .grid-cols-3, .grid-cols-2 { grid-template-columns: 1fr; }
  .family-block { grid-template-columns: 1fr; }

  /* Sticky metric/year toolbar on the map page. Solid background and z-index
   * so it stays legible while the choropleth scrolls underneath. The negative
   * margins + matching padding extend the background to the viewport edges
   * so there's no transparent gutter. */
  #observablehq-main .toolbar,
  #observablehq-main .toolbar-row {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--observablehq-background-base, #16161d);
    margin-left: -1rem;
    margin-right: -1rem;
    padding: 0.4rem 1rem;
  }

  /* Mobile banner on the map page (Tier 2 item 7). */
  .mobile-only-banner {
    display: block;
    padding: 0.6rem 0.85rem;
    margin: 0.5rem 0 0.8rem 0;
    background: rgba(110, 231, 183, 0.10);
    border-left: 3px solid #6ee7b7;
    border-radius: 0.25rem;
    font-size: 0.92em;
    line-height: 1.4;
  }
  .mobile-only-banner a { font-weight: 600; }

  /* Hide the scatter chart container and the peer-table; show the fallback
   * stub instead. The Controls panel still renders so users can see what
   * the scatter was about, but the chart itself is the small-screen-killer. */
  .scatter-chart-container,
  .scatter-stats,
  .peer-details {
    display: none;
  }
  .scatter-mobile-fallback {
    display: block;
    padding: 0.9rem 1rem;
    margin: 0.8rem 0;
    background: rgba(110, 231, 183, 0.10);
    border-left: 3px solid #6ee7b7;
    border-radius: 0.25rem;
    font-size: 0.95em;
    line-height: 1.45;
  }
  .scatter-mobile-fallback a { font-weight: 600; }

  /* Rankings table: hide selection, state, FIPS, and total-postings columns
   * so the county name + selected-metric value pair fits on a phone without
   * horizontal scroll. Inputs.table always renders a selection column at
   * position 1 (checkbox / radio / empty <td>); the data columns start at
   * position 2. Indices: 1=selection, 2=name, 3=state, 4=fips, 5=value,
   * 6=postings. Keep 2 and 5. */
  .rankings-table-card th:nth-child(1),
  .rankings-table-card td:nth-child(1),
  .rankings-table-card th:nth-child(3),
  .rankings-table-card td:nth-child(3),
  .rankings-table-card th:nth-child(4),
  .rankings-table-card td:nth-child(4),
  .rankings-table-card th:nth-child(6),
  .rankings-table-card td:nth-child(6) {
    display: none;
  }
  /* Let the county-name column take whatever width is left after the
   * value column renders. nth-child(2) is the County column since
   * position 1 is the (hidden) selection column. */
  .rankings-table-card th:nth-child(2),
  .rankings-table-card td:nth-child(2) {
    white-space: normal;
    word-break: break-word;
  }
}

@media (max-width: 640px) {
  /* Stack the year slider and Play button vertically. Defensive: the JS in
   * index.md should have already swapped the slider for a <select> at <700px
   * and dropped the Play button, but if matchMedia detection failed (older
   * browser, edge case) this keeps the controls legible. */
  .toolbar-row {
    flex-direction: column;
    align-items: stretch;
    gap: 0.4rem;
  }
}

@media (max-width: 480px) {
  /* Touch-target sizing per WCAG 2.5.5: minimum 44x44 px for tap targets. */
  html { font-size: 15px; }
  .info-btn {
    width: 44px;
    height: 44px;
    font-size: 1.1em;
  }
  select,
  input[type="checkbox"],
  input[type="range"] {
    min-height: 44px;
  }
  input[type="range"]::-webkit-slider-thumb {
    height: 28px;
    width: 28px;
  }
  input[type="range"]::-moz-range-thumb {
    height: 28px;
    width: 28px;
  }
  /* Inputs.range wraps its label + input in a horizontal layout; on a
   * narrow phone the label gets squeezed. Let it stack. */
  form[class*="oi-"] {
    flex-wrap: wrap;
  }
}
