:root {
  --page: #f9f9f7;
  --surface-1: #fcfcfb;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --text-muted: #898781;
  --grid: #e1e0d9;
  --baseline: #c3c2b7;
  --border: rgba(11, 11, 11, 0.10);
  /* Link text, kept separate from --series-1: the chart blue is only 4.2:1 on
     this background, under the 4.5:1 needed for body-size text. */
  --link: #2470cc;
  --series-1: #2a78d6;
  --series-2: #1baf7a;
  --series-3: #4a3aa7;
  --warning-bg: #fdf3dc;
  --warning-ink: #6b4e00;
  --delta-down: #006300; /* queue shrank (applications decided) */
  --delta-up: #a83c10;   /* queue grew (backdated registrations) */
  --delta-down-bg: rgba(0, 99, 0, 0.10);
  --delta-up-bg: rgba(168, 60, 16, 0.10);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --page: #0d0d0d;
    --surface-1: #1a1a19;
    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --text-muted: #898781;
    --grid: #2c2c2a;
    --baseline: #383835;
    --border: rgba(255, 255, 255, 0.10);
    --link: #3987e5;
    --series-1: #3987e5;
    --series-2: #199e70;
    --series-3: #9085e9;
    --warning-bg: #3a2f10;
    --warning-ink: #f0d590;
    --delta-down: #0ca30c;
    --delta-up: #eb6834;
    --delta-down-bg: rgba(12, 163, 12, 0.16);
    --delta-up-bg: rgba(235, 104, 52, 0.16);
  }
}

:root[data-theme="dark"] {
  --page: #0d0d0d;
  --surface-1: #1a1a19;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --text-muted: #898781;
  --grid: #2c2c2a;
  --baseline: #383835;
  --border: rgba(255, 255, 255, 0.10);
  --link: #3987e5;
  --series-1: #3987e5;
  --series-2: #199e70;
  --series-3: #9085e9;
  --warning-bg: #3a2f10;
  --warning-ink: #f0d590;
  --delta-down: #0ca30c;
  --delta-up: #eb6834;
  --delta-down-bg: rgba(12, 163, 12, 0.16);
  --delta-up-bg: rgba(235, 104, 52, 0.16);
}

* { box-sizing: border-box; }

body {
  margin: 0 auto;
  max-width: 1440px;
  padding: 24px 20px 40px;
  background: var(--page);
  color: var(--text-primary);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.45;
}

/* Links were only ever styled per context (.nav a, .prose a, .intro a), so any
   link in a context without its own rule fell through to the browser's default
   blue and visited-purple -- unreadable on the dark page. This is the floor;
   every rule below still overrides it. */
a { color: var(--link); }
a:hover { color: var(--text-primary); }

.header-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
header h1 { margin: 0 0 4px; font-size: 26px; font-weight: 650; }
.subtitle { margin: 0 0 20px; color: var(--text-secondary); font-size: 14px; }

/* Grouped so .header-row's space-between keeps pushing the controls as one unit
   to the right, rather than spreading them across the row. */
.header-actions { display: flex; align-items: center; gap: 8px; flex: none; }

/* Shared chrome for the small square header controls -- a <button> and an <a>,
   so the box properties are set here rather than on either element type. */
.header-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  padding: 0;
  font-size: 17px;
  line-height: 1;
  color: var(--text-primary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  text-decoration: none;
  cursor: pointer;
}
.header-btn:hover { border-color: var(--baseline); }

/* The tip link carries its label like the footer one, so it drops the square
   box and sizes to its text. The label goes at the body size rather than the
   17px the emoji needs. */
.header-btn-wide { width: auto; gap: 7px; padding: 0 12px; }
.header-btn-label { font-size: 13.5px; }

/* Narrow viewports put the label back in the tooltip -- the h1 needs the row. */
@media (max-width: 560px) {
  .header-btn-wide { width: 38px; gap: 0; padding: 0; }
  .header-btn-label { display: none; }
}

#themeToggle .icon-sun { display: none; }
#themeToggle .icon-moon { display: inline; }
:root[data-theme="dark"] #themeToggle .icon-sun { display: inline; }
:root[data-theme="dark"] #themeToggle .icon-moon { display: none; }

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 22px;
}
.nav a {
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 13px;
  text-decoration: none;
  color: var(--text-secondary);
  border: 1px solid transparent;
}
.nav a:hover { color: var(--text-primary); background: var(--surface-1); }
.nav a[aria-current="page"] {
  color: var(--text-primary);
  background: var(--surface-1);
  border-color: var(--border);
  font-weight: 550;
}

.prose { max-width: 720px; }
.prose h2 {
  font-size: 18px;
  font-weight: 600;
  margin: 30px 0 8px;
}
.prose h3 {
  font-size: 15px;
  font-weight: 600;
  margin: 20px 0 4px;
}
.prose p, .prose li { color: var(--text-secondary); font-size: 14.5px; }
.prose p { margin: 0 0 12px; }
.prose ul { margin: 0 0 12px; padding-left: 20px; }
.prose li { margin-bottom: 6px; }
.prose strong { color: var(--text-primary); }
.prose a { color: var(--link); }
.prose code {
  font-size: 12.5px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--surface-1);
  border: 1px solid var(--border);
}

.callout {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-left: 3px solid var(--series-1);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 8px;
  font-size: 14px;
  color: var(--text-secondary);
}
.callout--notice {
  background: var(--warning-bg);
  color: var(--warning-ink);
  border-color: transparent;
  border-left-color: var(--warning-ink);
}
.callout--notice strong, .callout--notice code { color: inherit; }

/* Text blocks take the column, so the page has one left edge and one right edge:
   the paragraphs, the tiles and the tables all start and stop together. On the
   prose pages .prose still holds them to 720. */
.intro {
  margin: 0 0 20px;
  font-size: 14.5px;
  color: var(--text-secondary);
}
.intro a { color: var(--link); }

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 20px;
}
.controls label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--text-secondary); }
.controls select {
  min-width: 180px;
  /* Right padding leaves room for the arrow drawn below. */
  padding: 8px 32px 8px 10px;
  font-size: 14px;
  font-family: inherit;
  color: var(--text-primary);
  background-color: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 8px;

  /* The native control draws its own arrow, which on Windows takes the OS accent
     colour and clashes with the dark theme. Draw ours instead. A data URI cannot
     read a CSS variable, so the stroke is a fixed grey chosen to clear 4:1 on
     both the light and dark select backgrounds -- one asset, no theme swap. */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%237d7b75' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 12px 8px;
}
.controls select:focus-visible { outline: 2px solid var(--link); outline-offset: 1px; }

/* The settling-months explanation, as a marker beside the picker rather than a
   full-width banner. Deliberately no `display` on .info-wrap, so the `hidden`
   attribute still works when every month is selectable. */
.info-wrap {
  position: relative;
  align-self: flex-end;
  margin-bottom: 8px;
}
.info-btn {
  width: 20px;
  height: 20px;
  padding: 0;
  font-size: 12px;
  font-weight: 650;
  font-family: inherit;
  line-height: 1;
  color: var(--text-secondary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 50%;
  cursor: pointer;
}
.info-btn:hover { color: var(--text-primary); border-color: var(--baseline); }

.info-pop {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 8px);
  z-index: 5;
  width: max-content;
  max-width: min(380px, calc(100vw - 60px));
  padding: 10px 12px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--warning-ink);
  background: var(--warning-bg);
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}
/* Hover for mice, focus for keyboards, and .is-open for taps -- a touch device
   has no hover, so the button toggles the class as well. */
.info-wrap:hover .info-pop,
.info-btn:focus-visible ~ .info-pop,
.info-pop.is-open { display: block; }

.stats {
  display: grid;
  /* Five tiles above the charts, four in the whole-queue strip: one row each
     on desktop rather than auto-fit leaving a sixth empty track. */
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
.stats--balance { grid-template-columns: repeat(4, 1fr); }
.stat-tile {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
}
.stat-label { font-size: 12px; color: var(--text-muted); margin-bottom: 4px; }
.stat-value { font-size: 24px; font-weight: 550; }
/* IRCC's strings are words, not a number, and run to three of them. */
.stat-value--text { font-size: 18px; line-height: 1.3; }
.stat-sub { margin-top: 3px; font-size: 12px; color: var(--text-muted); }
.stats--balance { margin-bottom: 0; }
/* Narrower than a five-across row: two columns, and the fifth tile takes a
   row of its own rather than being orphaned. */
@media (max-width: 900px) {
  .stats, .stats--balance { grid-template-columns: 1fr 1fr; }
  .stat-tile--wide { grid-column: 1 / -1; }
}

/* The selected cohort on its own, next to the queue-based estimates. The
   sentence carries everything the chart shows, so the chart is aria-hidden and
   simply absent when there is nothing to draw. */
.cohort-card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  margin-bottom: 24px;
}
.cohort-trend { margin: 0; font-size: 14px; color: var(--text-secondary); }
.cohort-trend b { color: var(--text-primary); font-weight: 600; }
.ct-chart { margin-top: 14px; }
.ct-chart:empty { display: none; }

.ct-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-bottom: 12px; font-size: 12px; color: var(--text-secondary); }
.ct-legend span { display: flex; align-items: center; gap: 6px; }
.ct-key-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--series-1); }
.ct-key-pace, .ct-key-fit { width: 18px; border-top: 2px dashed var(--series-1); }
.ct-key-fit { border-top-color: var(--text-muted); }

.bl-plot.ct-plot { height: 150px; }
.ct-area { position: absolute; top: 0; bottom: 0; left: 44px; right: 0; }
.ct-area svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ct-area svg * { fill: none; stroke-width: 2px; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; }
.ct-line { stroke: var(--series-1); }
.ct-pace { stroke: var(--series-1); stroke-dasharray: 5 4; }
.ct-fit { stroke: var(--text-muted); stroke-dasharray: 5 4; }

.ct-floor { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--series-3); }
.ct-floor > i {
  position: absolute;
  left: 4px;
  bottom: 2px;
  font-style: normal;
  font-size: 11px;
  color: var(--series-3);
  white-space: nowrap;
}

.ct-dot, .ct-end {
  position: absolute;
  width: 10px;
  height: 10px;
  margin: 0 0 -5px -5px;
  border-radius: 50%;
  background: var(--series-1);
  box-shadow: 0 0 0 2px var(--surface-1);
}
.ct-end { background: var(--surface-1); border: 2px solid var(--series-1); box-shadow: none; }
.ct-end-label, .ct-value {
  position: absolute;
  margin-bottom: 10px;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}
/* Above the latest reading and ending at it, so it stays inside the card even
   when that reading sits at the right-hand edge. */
.ct-value { transform: translateX(-100%); margin-left: 4px; }
/* High enough that the dashed line coming down into the ring passes beneath it. */
.ct-end-label { transform: translateX(-100%); margin: 0 0 26px 4px; }
/* The same instant tooltip as the backlog bars, on a target wide enough to find. */
.ct-dot::before { content: ""; position: absolute; inset: -8px; }
.ct-dot::after {
  content: attr(data-tip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  margin-bottom: 8px;
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-1);
  color: var(--text-primary);
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  display: none;
}
.ct-dot:hover::after { display: block; }

.ct-ahead { margin: 12px 0 0; font-size: 12.5px; color: var(--text-secondary); }
.ct-ahead b { color: var(--text-primary); font-weight: 600; }
.ct-item { white-space: nowrap; }
.ct-fall { color: var(--delta-down); font-variant-numeric: tabular-nums; }
.ct-dot.tip-l::after { left: 0; transform: none; }
.ct-dot.tip-r::after { left: auto; right: 0; transform: none; }

/* One column, plus a rail only where there is a rail to put in it -- the ad
   units are pulled while AdSense reviews the site, and a fixed 300px track with
   nothing in it would leave the page laid out around an absence.

   The column is capped near the width it had when the rail was beside it. Left
   to run the full 1440, the stat tiles and the tables stretched to twice the
   width they were drawn for. Everything inside now shares one measure, set at
   the column width, and a page whose paragraphs stopped short of its tables read
   as broken rather than as roomy. Anything wider scrolls inside .table-scroll. */
.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  max-width: 1160px;
}
.layout:has(.ad-rail) {
  grid-template-columns: minmax(0, 1fr) 300px;
  max-width: none;
}
.main-col { min-width: 0; }

.ad-rail { position: sticky; top: 20px; }

/* Dormant while the ad units are pulled, and kept so restoring one is a paste
   of the markup rather than a rewrite of the styles.

   No frame, no flex, no overflow clipping: ad scripts set their own dimensions
   and may deliberately break out to the viewport edge on mobile. Fighting them
   with a flex container squashes the unit or clips the creative. The
   min-heights reserve space so the page doesn't jump when an ad loads. */
.ad-slot {
  position: relative;
  padding-top: 18px;
  text-align: center;
}
.ad-slot--rail { min-height: 618px; }
.ad-slot--bottom { min-height: 118px; margin-top: 16px; }
.ad-label {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* The rail unit is a fixed 300x600 at every width, so its reserved height
   doesn't change here -- only its position. */
@media (max-width: 1040px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .ad-rail { position: static; }
}

.charts {
  display: grid;
  /* min() keeps the track from forcing overflow on very narrow viewports. */
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 16px;
}
.panel {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  min-width: 0;
}
.panel h2 { margin: 0 0 2px; font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.swatch.s1 { background: var(--series-1); }
.swatch.s2 { background: var(--series-2); }
.swatch.s3 { background: var(--series-3); }
.panel-desc { margin: 0 0 10px; font-size: 12.5px; color: var(--text-secondary); }
.panel-eta { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.eta-label { font-size: 12px; color: var(--text-muted); }
.eta-value { font-size: 20px; font-weight: 600; }

.chart-wrap { position: relative; width: 100%; height: 220px; }
.chart-wrap canvas { width: 100%; height: 100%; display: block; cursor: crosshair; }

.tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  padding: 6px 9px;
  font-size: 12px;
  color: var(--text-primary);
  white-space: nowrap;
  z-index: 2;
}
.tooltip .t-month { color: var(--text-muted); }

.panel-foot { font-size: 12.5px; color: var(--text-secondary); margin-top: 8px; }
.panel-foot b { color: var(--text-primary); font-weight: 600; }

details { margin-top: 10px; font-size: 12.5px; }
details summary { cursor: pointer; color: var(--text-muted); }
details table { width: 100%; border-collapse: collapse; margin-top: 8px; }
details th, details td {
  text-align: right;
  padding: 4px 8px;
  border-bottom: 1px solid var(--grid);
  font-variant-numeric: tabular-nums;
}
details th:first-child, details td:first-child { text-align: left; }
details th { color: var(--text-muted); font-weight: 500; }

/* ---- monthly updates ------------------------------------------------------ */

.post { margin: 0 0 34px; }
.post + .post { border-top: 1px solid var(--border); padding-top: 22px; }
.post-meta {
  margin: -6px 0 14px;
  font-size: 12.5px;
  color: var(--text-muted);
}
.post-table {
  width: 100%;
  max-width: 520px;
  border-collapse: collapse;
  margin: 0 0 14px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.post-table th, .post-table td {
  text-align: right;
  padding: 5px 10px;
  border-bottom: 1px solid var(--grid);
}
.post-table thead th { color: var(--text-muted); font-weight: 500; }
.post-table th:first-child, .post-table td:first-child {
  text-align: left;
  font-weight: 500;
  color: var(--text-secondary);
}
.post-table tbody th { color: var(--text-secondary); }
.post-table td:last-child { color: var(--text-primary); }

/* ---- the archived feeds, as collapsible JSON ------------------------------- */

.json-file { margin: 0 0 18px; }
.json-file h3 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.feed-meta { font-size: 12px; font-weight: 400; color: var(--text-muted); }

.json-tree {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.55;
  /* Keys run long and are not worth wrapping mid-token; let the box scroll. */
  overflow-x: auto;
}
/* Undoes the global `details` chrome, which is tuned for the chart tables. */
.json-tree details { margin: 0; font-size: inherit; }
.json-tree summary { color: var(--text-secondary); }
.json-tree summary:hover { color: var(--text-primary); }
.jt-body {
  padding-left: 14px;
  margin-left: 3px;
  border-left: 1px solid var(--grid);
}
.jt-leaf { white-space: nowrap; }
.jt-key { color: var(--series-1); }
.jt-str { color: var(--text-secondary); }
.jt-lit { color: var(--series-3); }
.jt-brace { color: var(--text-muted); }
.jt-count {
  margin: 0 4px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--grid);
  color: var(--text-muted);
  font-size: 11px;
}
.jt-note { color: var(--text-muted); white-space: normal; padding: 2px 0; }
.jt-error { color: var(--warning-ink); }
.jt-body.is-loading .jt-note::after { content: " Loading…"; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.snapshot { margin-top: 24px; }
.snapshot h2 { font-size: 17px; font-weight: 600; margin: 0 0 4px; }

/* A heading with a quiet escape hatch beside it. Baseline-aligned rather than
   centred so the link sits with the heading's text, not its box, and wrapping to
   its own line on narrow screens instead of squeezing the heading. */
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.section-link {
  flex: none;
  font-size: 12.5px;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
}
.section-link:hover { color: var(--text-primary); text-decoration: underline; }
.snapshot-desc {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--text-secondary);
}

/* Wide tables scroll inside their own container, never the page. */
.table-scroll {
  overflow-x: auto;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.snapshot-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.snapshot-table th, .snapshot-table td {
  padding: 6px 14px;
  text-align: right;
  white-space: nowrap;
  border-bottom: 1px solid var(--grid);
  vertical-align: top;
}
/* Row labels align to the value line, not the delta line below it. */
.snapshot-table th[scope="row"] { padding-top: 6px; text-align: left; font-weight: 400; color: var(--text-primary); }
.snapshot-table thead th {
  position: sticky;
  top: 0;
  background: var(--surface-1);
  color: var(--text-muted);
  font-weight: 500;
  text-align: right;
  border-bottom: 1px solid var(--baseline);
}
.snapshot-table thead th:first-child { text-align: left; }
.snapshot-table tbody td { color: var(--text-secondary); }
.snapshot-table tbody tr:hover td,
.snapshot-table tbody tr:hover th { background: var(--page); }

.snapshot-table tr.is-selected th,
.snapshot-table tr.is-selected td {
  background: var(--page);
  color: var(--text-primary);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--series-1);
}
/* Months the feed is still re-dating: kept visible as the evidence for excluding
   them, but recessed so they do not read as comparable to the rest. */
.snapshot-table tr.is-settling th,
.snapshot-table tr.is-settling td { color: var(--text-muted); }

/* Sign carries the meaning; colour only reinforces it. */
.snapshot-table .cell-value { display: block; line-height: 1.35; }
.snapshot-table .cell-delta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.4;
  white-space: nowrap;
}
/* The pill's own edge separates the count from the percentage beside it. */
.snapshot-table .badge {
  padding: 1px 6px;
  border-radius: 999px;
  font-weight: 550;
  font-variant-numeric: tabular-nums;
}
.snapshot-table .badge.delta-down { color: var(--delta-down); background: var(--delta-down-bg); }
.snapshot-table .badge.delta-up { color: var(--delta-up); background: var(--delta-up-bg); }
.snapshot-table .badge-flat { color: var(--text-muted); background: var(--grid); font-weight: 400; }
/* The percentage is context for the count beside it, so it stays quieter. */
.snapshot-table .delta-pct { color: var(--text-muted); }
.snapshot-table .delta-down { color: var(--delta-down); }
.snapshot-table .delta-up { color: var(--delta-up); }
.snapshot-table .no-data { color: var(--text-muted); }

.snapshot-table tfoot th, .snapshot-table tfoot td {
  border-bottom: none;
  border-top: 1px solid var(--baseline);
  font-weight: 600;
  color: var(--text-primary);
}

/* Back to top, injected by theme.js. Kept out of the flow and out of the way:
   invisible until scrolled, and it hides itself over the bottom ad slot. */
.to-top {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  font-size: 17px;
  line-height: 1;
  color: var(--text-secondary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { color: var(--text-primary); border-color: var(--baseline); }

/* An ad rail is sticky 20px from the top and 618px tall, so on a short desktop
   window it reaches the corner. Step inside the rail there. Dormant with the
   units pulled and never matched by a page without one, hence :has() -- where it
   is unsupported the button simply stays in the corner, which is the behaviour
   every page gets today anyway. */
@media (min-width: 1041px) and (max-height: 720px) {
  body:has(.ad-rail) .to-top { right: calc(300px + 24px + 20px); }
}

@media (prefers-reduced-motion: reduce) {
  .to-top { transition: none; }
}

footer { margin-top: 28px; font-size: 12.5px; color: var(--text-secondary); max-width: 900px; }
footer p { margin: 0 0 8px; }

/* Footer tip link. Deliberately quiet: the audience is anxious about an
   application this cannot affect, and the pages carried ad slots besides. Kept
   clearly distinct from .ad-slot so it does not read as another ad. */
.tip-line {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
}
.tip-link {
  flex: none;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-1);
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
}
.tip-link:hover { color: var(--text-primary); border-color: var(--baseline); }
.tip-note { color: var(--text-muted); }

/* ---- backlog shape ---------------------------------------------------------

   Bars as plain elements rather than a canvas: the figures are already in the
   HTML everywhere else on this page, and a chart that needs a script to appear
   would be the one thing here that does not. Heights are percentages of the
   tallest bar shown, so nothing has to be recomputed on resize, and the tooltip
   is a :hover rule rather than a listener for the same reason. */
.bl-plot {
  position: relative;
  height: 190px;
  padding-left: 44px;
  border-bottom: 1px solid var(--baseline);
}
.bl-bars { display: flex; align-items: flex-end; gap: 2px; height: 100%; }
.bl-col {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  height: 100%;
}
/* A floor, so a month holding 400 against a tallest bar of 24,000 still reads as
   a mark rather than as nothing at all. */
.bl-col > i { width: 100%; min-height: 3px; background: var(--series-1); border-radius: 2px 2px 0 0; }
.bl-col.is-you > i { background: var(--series-3); }

/* The whole column lights up rather than just the bar, so a 7px-wide month is
   still findable with the pointer. */
.bl-col:hover { background: var(--grid); }
.bl-col::after {
  content: attr(data-tip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  margin-bottom: 6px;
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-1);
  color: var(--text-primary);
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  /* display rather than visibility: a hidden-but-laid-out tooltip on the last
     bar still counted toward the page width and pushed 18px of horizontal
     scroll onto narrow screens. */
  display: none;
}
.bl-col:hover::after { display: block; }
/* Centred, a tooltip on the end bars would hang past the page. Anchor the last
   few to their own edge instead. */
.bl-col:nth-child(-n+3)::after { left: 0; transform: none; }
.bl-col:nth-last-child(-n+3)::after { left: auto; right: 0; transform: none; }

.bl-grid { position: absolute; left: 44px; right: 0; border-top: 1px solid var(--grid); }
.bl-grid > i {
  position: absolute;
  right: 100%;
  top: -8px;
  padding-right: 8px;
  font-style: normal;
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.bl-ticks { position: relative; height: 16px; margin: 6px 0 0 44px; }
.bl-ticks span {
  position: absolute;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Thirty bars in 335px leaves about 7px each, and the year labels collide with
   the two at the ends. Keep the range, drop the rest. */
@media (max-width: 560px) {
  .bl-ticks .bl-year { display: none; }
  .bl-plot { padding-left: 34px; }
  .bl-grid { left: 34px; }
  .bl-ticks { margin-left: 34px; }
  .ct-area { left: 34px; }
}
