/*
Theme Name: TX Data Center Tracker
Theme URI: https://txdcm.abovepublicaffairs.com
Author: Above Public Affairs
Author URI: https://abovepublicaffairs.com
Description: Public-facing tracker of data center-related government action across all 254 Texas counties, plus statewide elected-official activity. Design system documented in .gitdocs/design-language.md — read that before changing any of this.
Version: 1.6.0
Text Domain: txdcm
*/

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }

body {
  font-size: 16px;
  line-height: 1.5;
}

.container {
  max-width: 1120px;
  margin-inline: auto;
  padding-inline: 24px;
}

/* Skip link — the map alone is 254 tab stops, so bypassing the header and
   getting into (or past) the content matters more here than on a normal page.
   Visible only when focused. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  background: var(--color-ink);
  color: var(--color-paper);
  font-weight: 700;
  border-radius: 0 0 4px 0;
}
.skip-link:focus {
  left: 0;
}
#txdcm-main:focus,
#txdcm-map-end:focus { outline: none; }

.tag-link { color: var(--color-terracotta); }
.tag-link:hover { color: var(--color-terracotta-deep); }

/* ---------- Header ---------- */
.site-header {
  border-bottom: 1px solid var(--color-line);
  background: var(--color-paper);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 20px;
  gap: 24px;
}
.site-header__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-weight: 900;
  font-size: 15px;
  letter-spacing: -0.01em;
}
.site-header__brand svg { width: 28px; height: 28px; flex-shrink: 0; }
.site-header__nav {
  display: flex;
  gap: 24px;
  font-weight: 700;
  font-size: 14px;
  color: var(--color-slate);
}
.site-header__nav a:hover { color: var(--color-terracotta); }

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--color-line);
  margin-top: 80px;
  padding-block: 32px;
}
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  color: var(--color-slate-mute);
}
.site-footer a { color: var(--color-slate); font-weight: 700; }
.site-footer a:hover { color: var(--color-terracotta); }

/* ---------- Hero ---------- */
.hero { padding-block: 56px 40px; }
.hero h1 {
  font-weight: 900;
  font-size: clamp(2.5rem, 5vw, 4rem);
  letter-spacing: -0.03em;
  line-height: 1.05;
  max-width: 18ch;
  margin-bottom: 20px;
}
.hero h1 em {
  font-style: normal;
  color: var(--color-terracotta);
}
.hero p.lede {
  max-width: 60ch;
  font-size: 18px;
  color: var(--color-slate);
}

/* ---------- Featured stat panel ---------- */
.stat-panel {
  background: var(--color-ink);
  color: var(--color-paper);
  border-radius: 12px;
  padding: 32px;
  margin-top: 32px;
  box-shadow: var(--shadow-lift);
}
.stat-panel__number {
  font-weight: 900;
  font-size: clamp(2.75rem, 6vw, 5.5rem);
  letter-spacing: -0.02em;
  line-height: 1;
}
.stat-panel__number small {
  font-size: 0.4em;
  font-weight: 700;
  opacity: 0.7;
  margin-left: 6px;
}
.stat-panel__label {
  margin-top: 8px;
  font-size: 14px;
  opacity: 0.75;
}
.proportion-bar {
  display: flex;
  width: 100%;
  height: 12px;
  border-radius: 6px;
  overflow: hidden;
  margin-top: 24px;
  background: rgba(250, 246, 239, 0.1);
}
.proportion-bar__segment { height: 100%; }

/* ---------- Tier filter tiles ---------- */
.tier-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-top: 32px;
}
@media (min-width: 640px) { .tier-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .tier-grid { grid-template-columns: repeat(5, 1fr); } }

.tier-tile {
  position: relative;
  background: var(--color-paper-raised);
  border-radius: 8px;
  padding: 16px;
  box-shadow: var(--shadow-panel);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.tier-tile:hover { transform: translateY(-1px); box-shadow: var(--shadow-lift); }
.tier-tile[aria-current]::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--color-terracotta-fill);
  border-radius: 8px 8px 0 0;
  transform-origin: left;
}
.tier-tile__count {
  font-weight: 900;
  font-size: 2.25rem;
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
  gap: 8px;
}
.tier-dot {
  /* display is load-bearing: width/height do not apply to a non-replaced
     inline box. .legend__item, .headline-row__meta-left and .tier-badge are
     all flex containers, which blockified the dot for free — .tier-tile__label
     is not, so on the five stat tiles the dot computed to 0x16 and only its
     box-shadow ring rendered, as a grey sliver. */
  display: inline-block;
  vertical-align: middle;
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  /* Neutral ink halo, not the warm brown it used to be (rgba(74,53,33,.2)).
     That brown was tuned when every dot was terracotta and it tinted its own
     hue; around the teal and slate dots of the three-family palette it reads
     as a muddy fringe. Ink at .18 is hue-agnostic and does the same job of
     lifting a dot off a tinted row background. */
  box-shadow: 0 0 0 3px rgba(42, 47, 55, 0.18);
}
/* Legend key for the one tier the map hatches — the key has to match the map.
   The stripe is --tier-hatch-stripe, NOT a borrowed tier colour: this used to
   reuse --tier-pending_action, which worked only while every tier was the same
   terracotta. pending_action is gold now, and gold stripes over a slate swatch
   key nothing. See txdcm_patterned_tiers(), txdcm_render_map_defs() and
   txdcm_hatch_stripe_color(). */
.tier-dot--hatched {
  border-radius: 2px;
  background-image: repeating-linear-gradient(
    45deg,
    var(--tier-hatch-stripe) 0 1.5px,
    transparent 1.5px 4px
  );
}
.tier-tile__label {
  margin-top: 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-slate);
}
/* The flex call sites get their spacing from the parent's `gap`; this one is
   an inline context, so the dot needs its own. */
.tier-tile__label .tier-dot { margin-right: 6px; }

/* ---------- Dashboard grid: map + headlines ---------- */
.dashboard-grid {
  display: grid;
  gap: 40px;
  margin-top: 48px;
  align-items: start;
}
@media (min-width: 1024px) {
  .dashboard-grid { grid-template-columns: 1.7fr 1fr; }
}

.map-panel {
  /* Positioning context for the "Skip the county map" link inside it. */
  position: relative;
  background: var(--color-paper-raised);
  border-radius: 12px;
  padding: 24px;
  box-shadow: var(--shadow-panel);
}
.map-panel svg { width: 100%; height: auto; }

.county-picker {
  margin-top: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.county-picker select {
  flex: 1;
  padding: 10px 12px;
  border-radius: 4px;
  border: 1px solid var(--color-line);
  background: var(--color-paper);
  color: var(--color-ink);
  font: inherit;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 20px;
  font-size: 12px;
  color: var(--color-slate);
}
.legend__item { display: flex; align-items: center; gap: 6px; }
/* Separation between the three palette families — opposition / courting /
   no signal. See txdcm_tier_group() and txdcm_status_legend().

   This is EXTRA SPACE, not a rule, and that is not an aesthetic preference.
   The legend wraps (it does so at 760px and at every phone width), and a
   wrapped row can put a group's first item at the start of a line. A
   border-inline-start then renders hard against the left edge with nothing
   before it — a stray tick mark, not a separator. CSS cannot ask "am I first
   on my line?", so no border/padding combination fixes it; it was tried and
   it produced exactly that mark. Extra leading space has the same grouping
   effect on a full line and degrades to nothing visible on a wrapped one. */
.legend__item--group-start { margin-inline-start: 18px; }

.headlines {
  position: sticky;
  top: 24px;
}
@media (max-width: 1023px) { .headlines { position: static; } }
.headlines h2 { font-size: 13px; }
.headlines__subtitle { font-size: 12px; color: var(--color-slate-mute); margin-bottom: 16px; }
.headline-row {
  display: block;
  padding: 14px 0;
  border-bottom: 1px solid var(--color-line);
}
.headline-row:hover .headline-row__title { color: var(--color-terracotta); }
.headline-row__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--color-slate-mute);
  margin-bottom: 4px;
}
.headline-row__meta-left { display: flex; align-items: center; gap: 6px; }
.headline-row__title {
  font-weight: 700;
  font-size: 14px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.headline-row__type { font-size: 12px; color: var(--color-slate-mute); margin-top: 2px; }
.empty-note { font-size: 14px; color: var(--color-slate-mute); padding: 16px 0; }

/* ---------- Buttons ---------- */
.btn-primary {
  /* --color-terracotta-fill (#cc6a3c) under --color-paper is 3.42:1, which
     fails 4.5:1 for this 16px bold label — and this is the gate's only CTA.
     The deep tone is 6.68:1; hover presses one step further, preserving the
     existing hover direction. */
  padding: 12px 20px;
  border-radius: 4px;
  border: none;
  background: var(--color-terracotta-deep);
  color: var(--color-paper);
  font-weight: 700;
  min-height: 44px;
  transition: background 0.15s ease;
}
.btn-primary:hover { background: var(--color-terracotta-press); }

/* Quieter companion for the county picker's submit. */
.btn-secondary {
  padding: 8px 14px;
  border-radius: 4px;
  border: 1px solid var(--color-line);
  background: var(--color-paper);
  color: var(--color-slate);
  font-weight: 700;
  font-size: 13px;
  min-height: 34px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.btn-secondary:hover { background: var(--color-paper-raised); border-color: var(--color-slate-mute); }

/* ---------- Email gate ----------
   The gate is applied by JS adding .txdcm-gated to <html> (see
   txdcm_print_gate_script() in functions.php), never by PHP: the homepage
   sits behind WP Engine's Varnish, where a per-visitor cookie can't vary the
   response. Default state below is therefore UNGATED — with JS off, the
   content stays readable rather than locking out no-JS visitors. */

.gate-overlay { display: none; }
.gate-welcome { display: none; }

.txdcm-gated .txdcm-gate-region { position: relative; }

.txdcm-gated .map-panel,
.txdcm-gated .headlines {
  pointer-events: none;
  user-select: none;
}

/* Blur the panels' contents, not the panels themselves: filtering the panel
   would smear its own paper-raised background and shadow, leaving two
   soft-edged smudges instead of two crisp cards with obscured contents.
   5px keeps Texas's silhouette readable — you should be able to see what
   you're being offered, or there's no reason to sign up. */
.txdcm-gated .map-panel > *,
.txdcm-gated .headlines > * {
  filter: blur(5px);
}

.txdcm-gated .gate-overlay {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 2;
}

.gate-card {
  /* Sticky rather than centred: the grid is tall at desktop and much taller
     stacked on mobile, so a centred card scrolls out of view mid-page. */
  position: sticky;
  top: 96px;
  max-width: 420px;
  margin: 0 auto;
  background: var(--color-paper);
  border-radius: 12px;
  padding: 28px;
  box-shadow: var(--shadow-lift);
  text-align: center;
}
.gate-card h2 {
  font-size: 22px;
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-top: 6px;
}
.gate-card__lede {
  font-size: 14px;
  line-height: 1.55;
  color: var(--color-slate);
  margin-top: 10px;
}
.gate-card__error {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-tier-active);
  margin-top: 12px;
}
.gate-card__form {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 20px;
}
.gate-card__form input[type="email"] {
  flex: 1 1 200px;
  min-width: 0;
  padding: 12px 14px;
  border-radius: 4px;
  border: 1px solid var(--color-line);
  background: var(--color-paper);
  color: var(--color-ink);
  font: inherit;
}
.gate-card__fine {
  font-size: 12px;
  color: var(--color-slate-mute);
  margin-top: 12px;
}
/* The reset sets `a { color: inherit; text-decoration: none }`, so a link in
   body copy inherits its paragraph's colour and renders as plain text. The
   privacy link sits mid-sentence here and has to read as a link.
   Underlined as well as recoloured: colour alone is not a distinguishing cue,
   and terracotta against slate-mute is a hue shift a red-green colourblind
   reader may not register at 12px. Terracotta on Paper is 5.17:1. */
.gate-card__fine a {
  color: var(--color-terracotta);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.gate-card__fine a:hover { color: var(--color-terracotta-deep); }

/* Shown once, right after signing up (5-minute cookie). */
.txdcm-gate-welcome .gate-welcome {
  display: block;
  margin-top: 48px;
  margin-bottom: -24px;
  padding: 12px 16px;
  border-radius: 8px;
  background: var(--color-paper-raised);
  font-size: 14px;
  font-weight: 700;
  color: var(--color-terracotta);
}

/* ---------- County dossier ---------- */
.dossier-header { margin-bottom: 32px; }
.dossier-back {
  font-size: 13px;
  color: var(--color-slate-mute);
  display: inline-block;
  margin-bottom: 16px;
}
.dossier-back:hover { color: var(--color-terracotta); }
.dossier-header h1 {
  font-weight: 900;
  font-size: clamp(2rem, 4vw, 2.75rem);
  letter-spacing: -0.02em;
  margin-bottom: 12px;
}
.dossier-header__meta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

.tier-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
}

.item-card {
  background: var(--color-paper-raised);
  border-radius: 8px;
  padding: 24px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-panel);
}
.item-card__meta {
  font-size: 12px;
  color: var(--color-slate-mute);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
/* h2, not h3: the county page went h1 -> h3 with no h2 in between, which
   is a broken outline on all 254 county pages. The size stays as it was. */
.item-card h2 { font-size: 20px; font-weight: 900; margin-bottom: 8px; }
.item-card__summary { color: var(--color-slate); margin-bottom: 12px; }
.item-card__source { font-size: 13px; color: var(--color-terracotta); }
.item-card__source:hover { color: var(--color-terracotta-deep); }
.moratorium-window {
  display: inline-block;
  margin-top: 12px;
  padding: 6px 12px;
  border-radius: 4px;
  background: var(--color-paper);
  font-size: 12px;
  font-weight: 700;
}

.timeline { margin-top: 20px; border-left: 2px solid var(--color-line); padding-left: 0; }
.timeline-item {
  position: relative;
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 16px;
  padding: 12px 0 12px 20px;
  margin-left: -2px;
  border-left: 2px solid var(--color-line);
}
.timeline-item:first-child { border-color: var(--color-terracotta); }
.timeline-item::before {
  content: "";
  position: absolute;
  left: -7px;
  top: 18px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--color-terracotta);
  box-shadow: 0 0 0 3px var(--color-paper-raised), 0 0 0 4px rgba(180, 85, 42, 0.2);
}
.timeline-item__date { font-size: 12px; color: var(--color-slate-mute); }
.timeline-item__type { font-weight: 700; font-size: 14px; }
.timeline-item__notes { font-size: 14px; color: var(--color-slate); margin-top: 4px; }
.timeline-item__source { font-size: 12px; color: var(--color-terracotta); margin-top: 4px; display: inline-block; }

/* ---------- Contact CTA ----------
   The tail panel on the county dossiers and /state/. A feature panel (12px,
   28px padding) rather than another .item-card (8px, 24px): it follows a run of
   item cards on a populated county and has to read as a different kind of
   thing, and on the ~240 counties with no recorded action it is the only block
   on the page. Paper-raised ground + tinted shadow, no border — surfaces rule
   2 then 3 in design-language.md, never the border-plus-shadow combo. */

.cta-contact {
  background: var(--color-paper-raised);
  border-radius: 12px;
  padding: 28px;
  /* Between-sections rhythm (56-80). Collapses against the last .item-card's
     20px bottom margin rather than adding to it, which is the intent. */
  margin-top: 56px;
  box-shadow: var(--shadow-panel);
}
.cta-contact__title {
  font-size: 22px;
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-top: 6px;
}
.cta-contact__body {
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-slate);
  margin-top: 10px;
  max-width: 58ch;
}
/* See the note at the call site in inc/template-helpers.php: this only adds
   what an anchor needs to honour .btn-primary's min-height. */
.cta-contact__btn {
  display: inline-flex;
  align-items: center;
  margin-top: 20px;
}

/* ---------- State actions page ---------- */
.filter-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 32px; }
.filter-chip {
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--color-paper-raised);
  font-size: 13px;
  font-weight: 700;
  color: var(--color-slate);
  transition: background 0.15s ease, color 0.15s ease;
}
.filter-chip:hover { background: var(--color-line); }
.filter-chip[aria-current] {
  background: var(--color-ink);
  color: var(--color-paper);
}
.filter-chip__count { opacity: 0.6; margin-left: 4px; }

.state-timeline { margin-top: 8px; }
.state-timeline-item {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 16px;
  padding: 20px 0;
  border-bottom: 1px solid var(--color-line);
}
.state-timeline-item__date { font-size: 12px; color: var(--color-slate-mute); }
.state-timeline-item__office { font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; color: var(--color-terracotta); }
.state-timeline-item h3 { font-size: 18px; font-weight: 900; margin: 4px 0 6px; }
.state-timeline-item__actor { font-size: 13px; color: var(--color-slate-mute); margin-bottom: 6px; }
.state-timeline-item__summary { font-size: 14px; color: var(--color-slate); }
.state-timeline-item__source { font-size: 12px; color: var(--color-terracotta); margin-top: 6px; display: inline-block; }

.big-empty {
  text-align: center;
  padding: 64px 24px;
}
.big-empty__number { font-weight: 900; font-size: 5rem; color: var(--color-line); line-height: 1; }
.big-empty__text { color: var(--color-slate-mute); margin-top: 8px; }

/* ---------- Map hover tooltip (populated by js/map.js) ---------- */
.map-tooltip {
  position: absolute;
  z-index: 50;
  width: max-content;
  max-width: 240px;
  pointer-events: none;
  background: var(--color-ink);
  color: var(--color-paper);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 12px;
  max-width: 240px;
  box-shadow: var(--shadow-lift);
  opacity: 0;
  transition: opacity 0.1s ease;
}
.map-tooltip.is-visible { opacity: 1; }
.map-tooltip__name { font-weight: 900; font-size: 13px; margin-bottom: 4px; }
.map-tooltip__tier { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.map-tooltip__item {
  color: rgba(250, 246, 239, 0.75);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---------- 404 ---------- */
.not-found { padding-block: 96px; text-align: center; }
.not-found h1 { font-size: 3rem; font-weight: 900; margin-bottom: 12px; }

/* ---------- Accessibility utility ---------- */
.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  white-space: nowrap;
}

/* ---------- Coverage disclosure ----------
   What the tracker cannot see, stated plainly. Separated from the dashboard by
   a hairline and whitespace rather than being boxed as a warning: this is
   methodology, not an error state, and styling it as an alert would read as an
   apology. No semantic red/amber anywhere in here for the same reason. */

.coverage {
  margin-top: 64px;
  padding-top: 40px;
  border-top: 1px solid var(--color-line);
  display: grid;
  gap: 24px;
  align-items: start;
}
/* Asymmetric at desktop — title column against a wider prose column — so the
   section reads editorially instead of as one more centered block. */
@media (min-width: 900px) {
  .coverage { grid-template-columns: 1fr 2fr; gap: 48px; }
}

.coverage__title {
  font-size: 28px;
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: 8px;
}

.coverage__body > p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-slate);
  max-width: 68ch;
}
.coverage__body > p + p { margin-top: 16px; }
.coverage__body strong { color: var(--color-ink); font-weight: 700; }

.coverage__fineprint {
  font-size: 13px !important;
  color: var(--color-slate-mute) !important;
  margin-top: 24px !important;
}

.map-footnote {
  margin-top: 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--color-slate-mute);
}
.map-footnote a { color: var(--color-terracotta); font-weight: 700; }
.map-footnote a:hover { color: var(--color-terracotta-press); }
