/* Pyramis Rental Stats — deliberately small.
   No reset, no grid framework, no webfont. The theme owns typography, page
   background and text colour; this styles only what the shortcodes emit.

   ───────────────────────────────────────────────────────────────────────────
   TEXT COLOUR IS INHERITED, NEVER ASSERTED
   ───────────────────────────────────────────────────────────────────────────
   v1.0.1 set text to its own ink variable AND honoured
   @media (prefers-color-scheme: dark). The theme does not support dark mode,
   so on a dark-mode OS the plugin flipped to white ink over the theme's
   unchanged light-grey background — white on light grey, unreadable, and only
   for the subset of visitors whose machines are set that way.

   A plugin cannot know what the page behind it looks like. So text here uses
   `inherit` and lets the theme decide, and the only colours asserted are the
   ones a chart genuinely needs: series hues, gridlines, and the surface used
   for mark rings.

   Dark mode is now SELECTED, never automatic — add data-theme="dark" on <html>
   or .pyr-dark on a container if the theme ever gains a dark palette.

   ───────────────────────────────────────────────────────────────────────────
   PALETTE
   ───────────────────────────────────────────────────────────────────────────
   The two series hues are slots 1 and 2 of a validated categorical palette.
   They clear every colourblind-safety gate in both modes with a wide margin —
   worst pair ΔE 24.7 under protanopia against a floor of 8. Do not edit them
   to match a brand colour without re-validating: two hues that look distinct
   to you can be the same colour to ~8% of men. */

.pyr-stat,
.pyr-stat-row,
.pyr-chart-figure,
.pyr-table-wrap,
.pyr-freshness,
.pyr-scope-note {
  --pyr-series-1: #2a78d6;
  --pyr-series-2: #eb6834;
  --pyr-surface:  #fcfcfb;
  --pyr-muted:    #898781;
  --pyr-grid:     #e1e0d9;
  --pyr-rule:     rgba(128, 128, 128, .28);
  --pyr-warn:     #8a5300;
  --pyr-alert:    #8a2b2b;
}

:root[data-theme="dark"] .pyr-stat,
:root[data-theme="dark"] .pyr-stat-row,
:root[data-theme="dark"] .pyr-chart-figure,
:root[data-theme="dark"] .pyr-table-wrap,
:root[data-theme="dark"] .pyr-freshness,
:root[data-theme="dark"] .pyr-scope-note,
.pyr-dark .pyr-stat,
.pyr-dark .pyr-stat-row,
.pyr-dark .pyr-chart-figure,
.pyr-dark .pyr-table-wrap,
.pyr-dark .pyr-freshness,
.pyr-dark .pyr-scope-note {
  --pyr-series-1: #3987e5;
  --pyr-series-2: #d95926;
  --pyr-surface:  #1a1a19;
  --pyr-grid:     #2c2c2a;
  --pyr-warn:     #fab219;
  --pyr-alert:    #e66767;
}

/* ── Stat callouts ──────────────────────────────────────────────────────── */

/* Seven callouts written one after another flow as inline text and collide,
   with long notes wrapping under their neighbours. A grid gives each one its
   own cell and a shared baseline, and reflows on narrow screens without a
   media query. Wrap the callouts in [pyr_stat_row]…[/pyr_stat_row]. */
.pyr-stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
  gap: 1.5rem 1.75rem;
  align-items: stretch;
  margin: 1.25rem 0 2rem;
}

/* cols="N" — an explicit count, because auto-fit orphans the last item when
   the available width disagrees with the editorial intent. Collapses to two
   columns on narrow screens and one on a phone, so a fixed count never forces
   a horizontal scroll. */
.pyr-stat-row--fixed { grid-template-columns: repeat(var(--pyr-cols, 4), minmax(0, 1fr)); }
@media (max-width: 48rem) {
  .pyr-stat-row--fixed { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 30rem) {
  .pyr-stat-row--fixed { grid-template-columns: 1fr; }
}

.pyr-stat {
  display: block;
  color: inherit;          /* the theme owns text colour */
  min-width: 0;            /* let long labels wrap instead of blowing out the grid */
}

/* A hairline above each figure gives the row structure without drawing boxes.
   Cards would be heavier than the content warrants — these are seven numbers,
   not seven panels. */
.pyr-stat-row > .pyr-stat {
  padding-top: .7rem;
  border-top: 2px solid var(--pyr-series-1);
}

/* Outside a row, keep the old inline behaviour but with real spacing. */
.pyr-stat-row > .pyr-stat { margin: 0; }
:not(.pyr-stat-row) > .pyr-stat {
  display: inline-block;
  vertical-align: top;
  margin: 0 2rem 1.5rem 0;
  max-width: 16rem;
}

.pyr-stat__value {
  font-size: clamp(1.5rem, 1.1rem + 1.1vw, 2rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.015em;
}
.pyr-stat__label {
  font-size: .8125rem;
  font-weight: 600;
  line-height: 1.3;
  margin-top: .3rem;
  opacity: .9;
}
.pyr-stat__note {
  font-size: .75rem;
  line-height: 1.4;
  margin-top: .2rem;
  opacity: .55;
  text-wrap: pretty;
}

/* An unavailable figure must not look like a small one. */
.pyr-stat__value--empty { opacity: .45; font-weight: 400; }

/* ── Freshness ──────────────────────────────────────────────────────────── */

.pyr-freshness {
  font-size: .875rem;
  color: inherit;
  opacity: .85;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .4rem;
  margin-bottom: 1rem;
}
.pyr-freshness--stale { opacity: 1; font-weight: 600; color: var(--pyr-warn); }
.pyr-freshness--stale::before { content: "⚠"; }
.pyr-freshness--unavailable { color: var(--pyr-alert); font-weight: 600; }
.pyr-freshness__built { opacity: .7; }

/* ── Charts ─────────────────────────────────────────────────────────────── */

.pyr-chart-figure { margin: 0 0 2.5rem; color: inherit; }
.pyr-chart__title {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: .75rem;
}
.pyr-chart { position: relative; width: 100%; }
.pyr-chart canvas { max-width: 100%; }

.pyr-chart__table { margin-top: .75rem; font-size: .875rem; }
.pyr-chart__table > summary { cursor: pointer; opacity: .7; }
.pyr-chart__table > summary:hover { opacity: 1; }

/* ── Tables ─────────────────────────────────────────────────────────────── */

.pyr-table-wrap { overflow-x: auto; }
.pyr-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .9375rem;
  color: inherit;
}
.pyr-table th,
.pyr-table td { padding: .45rem .5rem; border-bottom: 1px solid var(--pyr-rule); }
.pyr-table th { text-align: left; font-weight: 600; }

/* Headers WRAP. They used to be nowrap, which made every column as wide as its
   longest header — "Rented, last 6 months" setting the width of a column of
   three-digit numbers. Eleven columns of that overflows any normal content
   width and the table scrolled sideways.
   Wrapping lets each column shrink to its data. `balance` splits the label
   evenly across two lines instead of leaving one orphaned word. */
.pyr-table thead th {
  white-space: normal;
  vertical-align: bottom;
  font-size: .8125rem;
  line-height: 1.25;
  text-wrap: balance;
  hyphens: none;
}

/* The zip column is an identifier, not a measurement — it never wraps and
   never needs more room than five digits. */
.pyr-table--zip tbody th,
.pyr-table--zip thead th:first-child { white-space: nowrap; width: 1%; }

/* Numbers are short; stop the browser giving them column width they do not
   need at the expense of the ones that do. */
.pyr-table--zip td.pyr-num { width: 1%; }

/* Tabular figures ONLY in columns, where digits must line up vertically. The
   large standalone stat values keep proportional figures. */
.pyr-table td.pyr-num,
.pyr-table th.pyr-num { text-align: right; font-variant-numeric: tabular-nums; }

.pyr-table tbody tr:hover { background: rgba(128, 128, 128, .08); }

.pyr-sortable { cursor: pointer; user-select: none; }
.pyr-sortable:hover { background: rgba(128, 128, 128, .12); }
.pyr-sortable[aria-sort="ascending"]::after  { content: " ▲"; font-size: .7em; opacity: .6; }
.pyr-sortable[aria-sort="descending"]::after { content: " ▼"; font-size: .7em; opacity: .6; }
.pyr-sortable:focus-visible { outline: 2px solid var(--pyr-series-1); outline-offset: -2px; }

/* The excluded-row count travels with the figure it affects — small, present,
   not hidden in a tooltip. A denominator that silently drops rows is what
   produced a zip reading 8.82% when the truth was 97%. */
.pyr-excluded { font-size: .75rem; opacity: .6; white-space: nowrap; }

.pyr-scope-note {
  font-size: .8125rem;
  color: inherit;
  opacity: .75;
  margin-top: 1rem;
  line-height: 1.55;
  max-width: 80ch;
}

@media (prefers-reduced-motion: reduce) {
  .pyr-chart canvas { transition: none !important; }
}

/* Ordinal ramp for the donut views. Ordered bands are magnitude, not identity,
   so this is one hue light→dark rather than five categorical colours. Five
   steps, validated: monotone lightness, adjacent gaps >= 0.06, light end
   clears 2:1 against the surface, single hue. */
.pyr-chart-figure {
  --pyr-ordinal: #86b6ef, #3987e5, #256abf, #184f95, #0d366b;
}
:root[data-theme="dark"] .pyr-chart-figure,
.pyr-dark .pyr-chart-figure {
  --pyr-ordinal: #184f95, #256abf, #3987e5, #6da7ec, #9ec5f4;
}
.pyr-chart-figure--donut .pyr-chart { max-width: 34rem; }

/* The theme justifies body text, which stretches short labels into
   "Homes    Available    Now" with rivers of space between the words. These
   are labels and figures, not prose — they get left alignment and normal word
   spacing regardless of what the surrounding content does. */
.pyr-stat,
.pyr-stat__value,
.pyr-stat__label,
.pyr-stat__note,
.pyr-freshness,
.pyr-chart__title,
.pyr-scope-note,
.pyr-table th,
.pyr-table td {
  text-align: left;
  word-spacing: normal;
  hyphens: none;
}
.pyr-table td.pyr-num,
.pyr-table th.pyr-num { text-align: right; }
