:root {
  color-scheme: light;
  --bg:          #f7f4ef;
  --surface:     #fffdf9;
  --surface-2:   #efe9df;
  --text:        #1a1814;
  --muted:       #6b6459;
  --line:        #e0d8cb;
  --accent:      #0f5f8a;
  --accent-2:    #b4451f;
  --accent-soft: #e3eef4;
  --rule:        #c9402a;
  --s1: #2a78d6;  --s2: #eb6834;  --s3: #1baf7a;
  --measure: 44rem;
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --bg:          #15161a;
    --surface:     #1c1e23;
    --surface-2:   #24272d;
    --text:        #ece9e3;
    --muted:       #9a978f;
    --line:        #2e3139;
    --accent:      #5ab4e0;
    --accent-2:    #f08a5d;
    --accent-soft: #19303c;
    --rule:        #e0603f;
    --s1: #3987e5;  --s2: #d95926;  --s3: #199e70;
  }
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 400 17px/1.7 ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 1.5rem; }

/* header */
.site-head { background: var(--surface); border-bottom: 1px solid var(--line); padding: 1.4rem 0; margin-bottom: 3.5rem; }
.site-head .wrap { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.site-name { font-family: ui-serif, Georgia, "Times New Roman", serif; font-weight: 600; font-size: 1.12rem; letter-spacing: -0.01em; text-decoration: none; color: var(--text); }
.site-nav { display: flex; gap: 1.4rem; }
.site-nav a { font-size: 0.9rem; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; padding-bottom: 2px; }
.site-nav a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* type */
h1, h2, h3 { font-family: ui-serif, Georgia, "Times New Roman", serif; line-height: 1.22; letter-spacing: -0.015em; font-weight: 600; margin: 2.8rem 0 0.9rem; }
h1 { font-size: 2.3rem; margin-top: 0; letter-spacing: -0.025em; }
h2 { font-size: 1.45rem; margin-top: 3.2rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
h3 { font-size: 1.1rem; }
p, ul, ol { margin: 0 0 1.3rem; }
a { color: var(--accent); text-underline-offset: 2px; }
strong { font-weight: 650; color: var(--text); }
hr { border: 0; border-top: 1px solid var(--line); margin: 3rem 0; }
blockquote {
  margin: 2rem 0; padding: 1.2rem 1.4rem;
  background: var(--accent-soft); border-left: 4px solid var(--accent);
  border-radius: 0 6px 6px 0; font-size: 1.02rem;
}
blockquote p:last-child { margin-bottom: 0; }
code { font-size: 0.88em; background: var(--surface-2); padding: 0.14em 0.4em; border-radius: 4px; }

.post-content > p:first-of-type { font-size: 1.2rem; line-height: 1.6; }
.post-content.longform > p:first-of-type::first-letter { font-family: ui-serif, Georgia, serif; font-size: 3.1rem; float: left; line-height: 0.82; padding: 0.08em 0.1em 0 0; color: var(--rule); font-weight: 600; }
.post-meta { color: var(--muted); font-size: 0.86rem; margin: 0 0 2.6rem; letter-spacing: 0.02em; text-transform: uppercase; }
.subtitle { font-family: ui-serif, Georgia, serif; color: var(--muted); font-size: 1.22rem; line-height: 1.45; margin: -0.4rem 0 1.5rem; font-style: italic; }

/* figures */
figure { margin: 2.4rem 0; padding: 1.4rem 1.3rem 1rem; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; }
/* Charts must not shrink into illegibility.
   The SVGs use a 640-unit viewBox and scale with the column. At a 320px
   viewport that put the smallest label at 4.4px against 19.2px body text —
   present, labelled, and unreadable. An earlier attempt kept the SVG and let
   the figure scroll, which reached 10.1px and was still half the size of the
   prose beside it. So below 640px the SVG is replaced rather than shrunk, by
   the column chart below: ordinary HTML text at 15.2px, no scrolling, and
   generated from the same spec as the SVG so the two cannot disagree. */
.chart-mobile { display: none; }
.cm-title { font-size: 1.02rem; font-weight: 600; margin: 0 0 0.15rem; line-height: 1.3; }
.cm-sub { font-size: 0.84rem; color: var(--muted); margin: 0 0 1rem; }
.cm-cols { display: flex; align-items: flex-end; gap: 0.6rem; margin: 0.4rem 0 0; }
.cm-col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center;
  justify-content: flex-end; min-width: 0; }
.cm-col i { display: block; width: 100%; max-width: 72px; background: var(--s1);
  border-radius: 5px 5px 0 0; }
.cm-val { font-size: 0.84rem; font-weight: 600; font-variant-numeric: tabular-nums;
  margin: 0 0 0.3rem; text-align: center; line-height: 1.25; }
.cm-name { font-size: 0.86rem; color: var(--muted); margin: 0.45rem 0 0; text-align: center;
  overflow-wrap: anywhere; }
.cm-note { font-size: 0.82rem; color: var(--muted); margin: 1rem 0 0; }
figure svg { display: block; width: 100%; height: auto; }
/* Below the site's existing breakpoint the SVG is replaced rather than shrunk.
   Scaled into a phone column its labels reach 4.4px against 19.2px body text.
   Must sit after the base rule above, which is unconditional and would
   otherwise win at every width — it did, and both presentations rendered at
   once. */
@media (max-width: 640px) {
  figure > svg { display: none; }
  .chart-mobile { display: block; }
}
/* At 320px the columns are 54px and 'Proxmox' wraps to a second line while the
   other three do not, which reads as a wonky chart rather than a long word.
   Smaller type on the narrowest phones, rather than a different layout. */
@media (max-width: 359px) {
  .cm-name { font-size: 0.8rem; }
  .cm-cols { gap: 0.45rem; }
}
figcaption { font-size: 0.82rem; color: var(--muted); margin-top: 0.9rem; padding-top: 0.8rem; border-top: 1px solid var(--line); }

/* tables */
.table-scroll { overflow-x: auto; margin: 2rem 0; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; }
table { border-collapse: collapse; width: 100%; font-size: 0.9rem; }
th, td { text-align: left; padding: 0.65rem 0.95rem; border-bottom: 1px solid var(--line); }
th { font-weight: 600; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); white-space: nowrap; background: var(--surface-2); }
tbody tr:last-child td { border-bottom: none; }
td:not(:first-child), th:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }

/* post list */
.post-list { list-style: none; padding: 0; }
.post-list li { padding: 1.5rem; margin-bottom: 1rem; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; }
.post-list h2 { margin: 0 0 0.35rem; font-size: 1.22rem; border: 0; padding: 0; }
.post-list h2 a { text-decoration: none; color: var(--text); }
.post-list h2 a:hover { color: var(--accent); }
.post-list time { font-size: 0.78rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.post-list p { margin: 0.5rem 0 0; color: var(--muted); font-size: 0.95rem; }

.site-foot { background: var(--surface); border-top: 1px solid var(--line); margin-top: 5rem; padding: 2.2rem 0 3rem; color: var(--muted); font-size: 0.84rem; }
.site-foot a { color: var(--muted); }
.disclaimer { font-size: 0.85rem; color: var(--muted); font-style: italic; padding: 1rem 1.2rem; background: var(--surface-2); border-radius: 6px; }

@media (max-width: 640px) {
  body { font-size: 16px; }
  h1 { font-size: 1.75rem; }
  h2 { font-size: 1.25rem; }
  figure { padding: 1rem 0.8rem 0.8rem; }
}

/* ---- research metadata line ---- */
.research-meta {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.4rem;
  font-size: 0.78rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 2rem; padding-bottom: 1rem;
  border-bottom: 1px solid var(--line);
}
.research-meta b { font-weight: 600; color: var(--text); text-transform: none; letter-spacing: 0; }

/* ---- key findings strip ---- */
.findings {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden; margin: 2.2rem 0;
}
.findings div { background: var(--surface); padding: 1rem 0.9rem; }
.findings .n {
  display: block; font-family: ui-serif, Georgia, serif; font-size: 1.6rem;
  font-weight: 600; line-height: 1.1; color: var(--accent); font-variant-numeric: tabular-nums;
}
.findings .l { display: block; font-size: 0.76rem; color: var(--muted); margin-top: 0.35rem; line-height: 1.35; }
.findings .q { grid-column: 1 / -1; background: var(--accent-soft); font-size: 0.93rem; color: var(--text); }
.findings .q b { color: var(--accent); }

/* ---- evidence section ---- */
.evidence { background: var(--surface-2); border-radius: 10px; padding: 0.2rem 1.4rem 1.4rem; margin-top: 3rem; }
.evidence h2 { border-top: 0; margin-top: 1.6rem; }
.evidence .table-scroll { background: var(--surface); }
.evidence .table-scroll::after { content: ""; }
.data-links { display: flex; flex-wrap: wrap; gap: 0.7rem; margin: 1.4rem 0 0; }
.data-links a {
  display: inline-block; padding: 0.55rem 0.9rem; background: var(--surface);
  border: 1px solid var(--line); border-radius: 6px; font-size: 0.86rem; text-decoration: none;
}
.data-links a:hover { border-color: var(--accent); }
@media (max-width: 640px) {
  .table-scroll { position: relative; }
  .findings .n { font-size: 1.4rem; }
}

/* ---- correction notice: must never be mistaken for a live claim ---- */
.correction {
  margin: 1.6rem 0; padding: 0.85rem 1.1rem;
  background: var(--surface-2); border-left: 4px solid var(--accent-2);
  border-radius: 0 6px 6px 0; font-size: 0.88rem; color: var(--muted);
}
.correction b { color: var(--accent-2); text-transform: uppercase; letter-spacing: 0.06em; font-size: 0.78rem; }
.correction s { opacity: 0.75; }

/* ---- nothing may push the page sideways ---- */
html, body { max-width: 100%; overflow-x: hidden; }
.post-content { min-width: 0; }
.table-scroll { max-width: 100%; -webkit-overflow-scrolling: touch; }

/* ---- contract table: scrolls on desktop, restacks on mobile ---- */
.contracts a { text-decoration: none; font-variant-numeric: tabular-nums; }

@media (max-width: 700px) {
  .contracts, .contracts thead, .contracts tbody,
  .contracts tr, .contracts th, .contracts td { display: block; }
  .contracts thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .contracts { font-size: 0.9rem; }
  .contracts tr {
    padding: 0.85rem 0.95rem; border-bottom: 1px solid var(--line);
    display: grid; grid-template-columns: auto 1fr; gap: 0.15rem 0.9rem;
  }
  .contracts tr:last-child { border-bottom: 0; }
  .contracts td { padding: 0; border: 0; text-align: left !important; display: contents; }
  .contracts td::before {
    content: attr(data-l); color: var(--muted); font-size: 0.72rem;
    text-transform: uppercase; letter-spacing: 0.05em; align-self: center;
  }
  .contracts td[data-l="Agency"] { font-weight: 600; }
  .contracts td[data-l="Value"] { font-variant-numeric: tabular-nums; }
  /* the whole row no longer needs to scroll */
  .table-scroll:has(.contracts) { overflow-x: visible; }
  .evidence { padding: 0.2rem 0.9rem 1.1rem; }
}

/* ---- forecast registry: six columns, two of them prose ----
   A second restack, not a copy of the contracts one. That table carries short
   facts and pairs label beside value; this one carries two long sentences, and
   a 1fr value column next to a label leaves them 220px wide. So the mechanism
   is shared below (hidden thead, label from data-l) and the layout is not.
   The markdown table this replaces measured 626px inside a 375px viewport with
   no scroll container, so body's overflow-x:hidden clipped the last two
   columns away with no way to reach them. */
.forecasts td[data-l] { text-align: left; }
/* th is globally nowrap, which is right for short headers. "Leading indicator"
   held the column open and pushed the table 30px past the measure, so the two
   sentence columns lost the width to a header that could simply wrap. */
.forecasts th { text-align: left; white-space: normal; }
.forecasts td[data-l="Made"], .forecasts td[data-l="Resolves"] { white-space: nowrap; font-variant-numeric: tabular-nums; }
.forecasts td[data-l="Confidence"] { font-variant-numeric: tabular-nums; }
.forecasts a { text-decoration: none; }
/* Six columns inside a 44rem measure spend 180px of it on cell padding alone,
   and the four short columns then leave the two sentences ~130px each — three
   words to a line. The percentages below are a request, not a guarantee: the
   short columns' content sets their real width, so the padding and the header
   tracking have to come down for the request to be grantable. */
.forecasts th, .forecasts td { padding-left: 0.55rem; padding-right: 0.55rem; }
.forecasts th { font-size: 0.7rem; letter-spacing: 0.03em; }
.forecasts th:nth-child(1) { width: 1.5rem; }
.forecasts th:nth-child(3) { width: 34%; }
.forecasts th:nth-child(5) { width: 30%; }

@media (max-width: 700px) {
  .forecasts, .forecasts tbody, .forecasts tr, .forecasts td { display: block; }
  .forecasts thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  /* 0.9rem is fine for a grid of dates; these are sentences, and the charts
     taught the same lesson — body text on a phone must not shrink to decoration */
  .forecasts { font-size: 0.95rem; }
  .forecasts tr {
    display: grid; grid-template-columns: 1fr 1fr; gap: 0.85rem 0.9rem;
    padding: 1.1rem 1rem; border-bottom: 1px solid var(--line);
  }
  .forecasts tr:last-child { border-bottom: 0; }
  .forecasts td { padding: 0; border: 0; min-width: 0; }
  .forecasts td::before {
    content: attr(data-l); display: block; margin-bottom: 0.2rem;
    color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
  }
  /* Placed explicitly, because auto-placement does not do what it looks like it
     does: the full-width sentence after Confidence starts a new row, so
     Confidence sat alone with an empty half beside it and Resolves — last in
     document order — ended up stranded under the leading indicator, far from
     the confidence it belongs next to. */
  .forecasts td[data-l="#"]                 { grid-area: 1 / 1; }
  .forecasts td[data-l="Made"]              { grid-area: 1 / 2; }
  .forecasts td[data-l="Forecast"]          { grid-area: 2 / 1 / 3 / -1; }
  .forecasts td[data-l="Confidence"]        { grid-area: 3 / 1; }
  .forecasts td[data-l="Resolves"]          { grid-area: 3 / 2; }
  .forecasts td[data-l="Leading indicator"] { grid-area: 4 / 1 / 5 / -1; }
  /* "# 1" says nothing standing alone, so the number becomes the card's title */
  .forecasts td[data-l="#"] { font-weight: 600; }
  .forecasts td[data-l="#"]::before { content: "Forecast "; display: inline; margin: 0; }
  /* and with that title directly above it, labelling the sentence "Forecast" twice reads as a fault */
  .forecasts td[data-l="Forecast"]::before { content: none; }
  .table-scroll:has(.forecasts) { overflow-x: visible; }
}
