/* ==========================================================================
   query-widget.css — the SINGLE, BLOG-OWNED stylesheet for the chart widget.

   ONE component, THEMEABLE by surface. Every colour is a CSS variable whose FALLBACK is a
   DARK default, so the widget renders dark even with no theme applied — that is what the
   shared renderer (apps/shared/static/result-renderer.js) expects when it is dropped onto
   an unstyled page. This site opts into a LIGHT skin by putting `theme-light` on <body>;
   the `.theme-light { --q-*: … }` block below then supplies the light palette, which
   inherits to every widget element (panel, table, inline value chip, and — via
   result-renderer.js reading the --q-chart-* vars — the chart itself). Restyle here and
   EVERY post changes; override the variables rather than editing the dark defaults, so a
   restyle can never break the renderer's standalone appearance.

   Covers: the chart PANEL frame (.blog-query*), the inline {{q:...}} value chip
   (.blog-val*), the no-JS fallback table (.blog-fallback-table), and the chrome the shared
   renderer draws (.strasmore-artifact / .sr-* / .data-grid*). `.strasmore-artifact` is a
   historical class name emitted by that VENDORED script — the selector must keep matching
   it, so do not rename it here without re-cutting the asset.
   ========================================================================== */

/* ---- LIGHT skin (blog): applied via `theme-light` on <body>; inherits to all widgets ---- */
.theme-light {
  --q-bg: #FFFFFF;
  --q-panel: #F8FAFC;
  --q-surface: #F1F5F9;
  --q-border: #E7E5E4;
  --q-line: #EEEDEB;
  --q-accent: #2563EB;
  --q-muted: #78716C;
  --q-text: #1C1917;
  --q-cell: #292524;
  --q-cell-1: #57534E;
  --q-row-even: #FFFFFF;
  --q-row-odd: #FAFAF9;
  --q-hover-bg: #EFF6FF;
  --q-hover-text: #0C0A09;
  --q-code-bg: #F8FAFC;
  --q-code-text: #292524;
  --q-red: #DC2626;
  --q-error-bg: #FEF2F2;
  /* chart (read by result-renderer.js via getComputedStyle) */
  --q-chart-axis: #57534E;
  --q-chart-grid: #E7E5E4;
  --q-chart-legend: #44403C;
  --q-chart-tt-bg: #FFFFFF;
  --q-chart-tt-border: #E7E5E4;
  --q-chart-tt-text: #1C1917;
}

/* Font (not themed). */
.blog-query, .strasmore-artifact, .blog-val, .blog-val-missing, .blog-fallback-table, .blog-query-empty {
  --q-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ---- The query PANEL: a labelled data unit, consistent on every post ---- */
.blog-query {
  margin: 1.75rem 0;
  border: 1px solid var(--q-border, #27272A);
  border-left: 3px solid var(--q-accent, #3B82F6);
  background: var(--q-bg, #000000);
}
/* In LIGHT, drop the terminal accent-stripe for a uniform card-grey border (card sibling). */
.theme-light .blog-query { border-left: 1px solid var(--q-border, #E7E5E4); }

.blog-query-cap {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.75rem;
  background: var(--q-panel, #09090B);
  border-bottom: 1px solid var(--q-border, #27272A);
}
.blog-query-kicker {
  font-family: var(--q-mono);
  font-size: 9px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase;
  color: #fff; background: var(--q-accent, #3B82F6); padding: 2px 6px;
}
.blog-query-title {
  font-family: var(--q-mono);
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--q-muted, #71717A);
}
.blog-query-notice {
  padding: 0.75rem 1rem; font-family: var(--q-mono); font-size: 12px;
  color: var(--q-cell-1, #A1A1AA); background: var(--q-panel, #09090B);
}

/* The always-visible SQL — the repeated trust element ("the query behind the number"). */
.blog-query-sql {
  border-top: 1px solid var(--q-border, #27272A);
  background: var(--q-code-bg, #050505);
  font-family: var(--q-mono); font-size: 12px; color: var(--q-cell-1, #A1A1AA);
}
.blog-query-sql summary {
  cursor: pointer; padding: 0.5rem 0.75rem;
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--q-muted, #71717A); user-select: none; list-style: none;
}
.blog-query-sql summary::before { content: "▸ "; color: var(--q-accent, #3B82F6); }
.blog-query-sql[open] summary::before { content: "▾ "; }
.blog-query-sql summary:hover { color: var(--q-text, #F4F4F5); }
.blog-query-sql pre {
  margin: 0; padding: 0 0.75rem 0.75rem; white-space: pre-wrap;
  color: var(--q-code-text, #D4D4D8); line-height: 1.55;
  /* `pre-wrap` breaks on whitespace only, so an unbreakable 50+ char SQL token
     (arrayStringConcat(arraySort(groupArray(concat(toString(id),) runs past the panel and is
     CLIPPED by the .blog-query ancestor's overflow:hidden — the reader sees the token sliced
     mid-word with no way to scroll to the rest. Measured on iPhone 13: 425px of content in a
     340px box, on 6 of 12 panels of the microstructure deep-dive. The SQL is the flagship
     trust element of every post ("here is the exact query behind the number"), so it has to
     be readable on the device most readers hold. */
  overflow-wrap: anywhere;
}

/* ---- Inline value chip: signals "this number came from the query above" ---- */
.blog-val {
  font-family: var(--q-mono); font-variant-numeric: tabular-nums;
  color: var(--q-text, #F4F4F5); border-bottom: 1px dotted var(--q-accent, #3B82F6); cursor: help;
}
.blog-val-missing { font-family: var(--q-mono); color: var(--q-red, #EF4444); }

/* ---- No-JS fallback table (generated from stored data) ---- */
.blog-fallback-table { width: 100%; border-collapse: collapse; font-family: var(--q-mono); font-size: 11px; }
.blog-fallback-table th, .blog-fallback-table td { border: 1px solid var(--q-line, #1a1a1a); padding: 4px 8px; text-align: right; color: var(--q-cell, #D4D4D8); }
.blog-fallback-table th { background: var(--q-panel, #09090B); color: var(--q-cell-1, #A1A1AA); text-transform: uppercase; }
.blog-fallback-table caption { color: var(--q-muted, #71717A); font-size: 10px; margin-bottom: 4px; }
.blog-query-empty { color: var(--q-muted, #71717A); font-family: var(--q-mono); font-size: 12px; padding: 0.5rem 0.75rem; }

/* ==========================================================================
   Live renderer output (apps/shared/result-renderer.js). Table + chart chrome.
   ========================================================================== */
.strasmore-artifact {
  background: var(--q-bg, #000000);
  display: flex; flex-direction: column; width: 100%; max-width: 100%; min-width: 0;
  overflow: hidden; font-family: var(--q-mono);
}
.strasmore-artifact .sr-toolbar {
  background: var(--q-panel, #09090B); border-bottom: 1px solid var(--q-border, #27272A);
  display: flex; justify-content: space-between; align-items: stretch; min-width: 0; width: 100%; overflow: hidden;
}
.strasmore-artifact .sr-tag {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 1rem; border-right: 1px solid var(--q-border, #27272A); background: var(--q-surface, #111114);
  font-size: 10px; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--q-accent, #3B82F6); white-space: nowrap;
}
.strasmore-artifact .sr-tag::before { content: ""; width: 6px; height: 6px; background: var(--q-accent, #3B82F6); display: inline-block; }
.strasmore-artifact .sr-btns { display: flex; align-items: stretch; flex-shrink: 0; }
.strasmore-artifact .sr-btn {
  font-family: inherit; font-size: 9px; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase;
  padding: 0.375rem 0.75rem; border: none; border-left: 1px solid var(--q-border, #27272A);
  background: transparent; color: var(--q-muted, #71717A); cursor: pointer; transition: color 0.15s, background 0.15s;
}
.strasmore-artifact .sr-btn:hover { color: var(--q-text, #F4F4F5); }
.strasmore-artifact .sr-btn.active { background: var(--q-accent, #3B82F6); color: #fff; }

.strasmore-artifact .sr-chart { position: relative; width: 100%; height: 300px; padding: 1rem; border-bottom: 1px solid var(--q-border, #27272A); background: var(--q-bg, #000); }
.strasmore-artifact .sr-chart canvas { width: 100% !important; height: 100% !important; }
.strasmore-artifact .sr-chart-fault { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--q-red, #EF4444); font-size: 10px; }

.strasmore-artifact .sr-json { padding: 1rem; background: var(--q-bg, #000); border-bottom: 1px solid var(--q-border, #27272A); max-height: 300px; overflow-y: auto; }
.strasmore-artifact .sr-json pre { font-size: 10px; color: var(--q-cell-1, #A1A1AA); margin: 0; }
.strasmore-artifact .sr-error { padding: 1rem; font-size: 10px; color: var(--q-red, #EF4444); background: var(--q-error-bg, #110000); border-bottom: 1px solid var(--q-border, #27272A); }

/* Data grid */
.strasmore-artifact .data-grid-container { display: block; overflow: auto; max-height: 450px; background: var(--q-bg, #000000); border-top: 1px solid var(--q-border, #27272A); }
.strasmore-artifact .data-grid { width: max-content; min-width: 100%; border-collapse: collapse; font-family: var(--q-mono); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.strasmore-artifact .data-grid th {
  position: sticky; top: 0; z-index: 10; background-color: var(--q-panel, #09090B); padding: 8px 12px; text-align: right;
  color: var(--q-cell-1, #A1A1AA); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  border-bottom: 1px solid var(--q-border, #27272A); border-right: 1px solid var(--q-line, #111114); white-space: nowrap;
}
.strasmore-artifact .data-grid th:first-child { text-align: left; }
.strasmore-artifact .data-grid td { padding: 6px 12px; text-align: right; color: var(--q-cell, #D4D4D8); white-space: nowrap; border-bottom: 1px solid var(--q-line, #111114); border-right: 1px solid var(--q-line, #111114); }
.strasmore-artifact .data-grid td:first-child { text-align: left; color: var(--q-cell-1, #A1A1AA); }
.strasmore-artifact .data-grid tr:nth-child(even) td { background-color: var(--q-row-even, #000000); }
.strasmore-artifact .data-grid tr:nth-child(odd) td { background-color: var(--q-row-odd, #050505); }
.strasmore-artifact .data-grid tr:hover td { background-color: var(--q-hover-bg, #111114); color: var(--q-hover-text, #FFF); cursor: crosshair; }
.strasmore-artifact .data-grid .sr-truncated td { text-align: center; color: var(--q-muted, #71717A); font-size: 10px; padding: 12px; border-top: 1px solid var(--q-border, #27272A); background: var(--q-panel, #09090B); }

/* ------------------------------------------------------------------ *
 * MOBILE (added 2026-07-14). This file previously had ZERO media queries: every data panel
 * rendered at its desktop size on a phone. A mobile audit (real device emulation, iPhone 13 /
 * Pixel 5 / 360x640) measured three defects that make the data unreadable on the device most
 * readers are holding. Rendering was otherwise clean — no page overflow, LCP ~1s, CLS ~0 —
 * so these are READING bugs, not ranking bugs, and are fixed as such.
 * ------------------------------------------------------------------ */
@media (max-width: 640px) {
  /* 1. The tables rendered at 10.5px against 20px body prose — 52% the size of the
     surrounding text, and 328 sub-12px cells on a single post. */
  .strasmore-artifact .data-grid { font-size: 13px; }
  .strasmore-artifact .data-grid th,
  .strasmore-artifact .data-grid td { padding: 7px 10px; }
  /* The 10px .sr-truncated rule below OUTSPECIFIES the bump above, so it must be restated
     or the "N more rows" footer stays tiny. */
  .strasmore-artifact .data-grid .sr-truncated td { font-size: 13px; }
  .blog-query-kicker { font-size: 12px; }
  .blog-query-sql summary { font-size: 12px; }
  .blog-fallback-table { font-size: 12px; }

  /* 2. Nested-scroll trap: a 450px-tall inner scroller inside a ~640px viewport meant a
     finger landing on a table scrolled the TABLE, not the page — measured at 6 gestures and
     ~2,400px of travel to escape one 78-row panel. On a phone the page itself is the
     scroller; let the table flow. (Deliberately NOT `overscroll-behavior: contain`, which
     measured WORSE — a permanent trap — and not `overflow-y: visible`, which the spec
     computes back to `auto` next to `overflow-x: auto`, i.e. a no-op.) */
  .strasmore-artifact .data-grid-container { max-height: none; }

  /* 3. Wide tables scroll horizontally with NO affordance: mobile overlay scrollbars paint
     nothing at rest, and because cells are right-aligned a clipped column renders BLANK — it
     reads as a broken table rather than a scrollable one (measured: 25 columns, 3255px of
     content in a 310px box, 3 columns visible). Two-layer scroll shadow: the `local` layers
     are painted in the scroll box's content space and so slide away exactly when the reader
     reaches an edge, extinguishing the hint instead of lying about it. */
  .strasmore-artifact .data-grid-container {
    background-image:
      linear-gradient(to right, var(--q-bg, #000) 30%, rgba(0, 0, 0, 0)),
      linear-gradient(to left,  var(--q-bg, #000) 30%, rgba(0, 0, 0, 0)),
      linear-gradient(to right, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0)),
      linear-gradient(to left,  rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-repeat: no-repeat;
    background-size: 28px 100%, 28px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
  }
}
