/* Compact, Hacker News layout. */
:root {
  --bg: #fafafa;
  --surface: #ffffff;
  --fg: #1c1917;          /* stone-900 */
  --muted: #78716c;       /* stone-500 */
  --accent: #ef4444;      /* red */
  --accent-strong: #dc2626;
  --accent-tint: #fef2f2;
  --rule: rgba(0, 0, 0, 0.08);
  --content: 740px;       /* shared centered column width */
  /* Sentiment (outlook for Indonesia). Green good, red bad, grey neutral. */
  --pos: #15803d;  --pos-bg: rgba(21, 128, 61, 0.10);
  --neg: #dc2626;  --neg-bg: rgba(220, 38, 38, 0.10);
  --neu: #78716c;  --neu-bg: rgba(120, 113, 108, 0.10);
  /* Highlighter for a key sentence in an article body (==text==). */
  --mark-bg: rgba(250, 204, 21, 0.45);
}
/* Light is the default theme. Dark applies only when the visitor opts in
   via the toggle (persisted as data-theme="dark"). */
:root[data-theme="dark"] {
  --bg: #18181b;
  --surface: #1f1f23;
  --fg: #fafafa;
  --muted: #a1a1aa;
  --accent: #ef4444;
  --accent-strong: #f87171;
  --accent-tint: rgba(239, 68, 68, 0.12);
  --rule: rgba(255, 255, 255, 0.09);
  --pos: #4ade80;  --pos-bg: rgba(74, 222, 128, 0.14);
  --neg: #f87171;  --neg-bg: rgba(248, 113, 113, 0.14);
  --neu: #a1a1aa;  --neu-bg: rgba(161, 161, 170, 0.14);
  --mark-bg: rgba(250, 204, 21, 0.28);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 14px/1.5 "Inter", system-ui, -apple-system, sans-serif;
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden; /* the /topics/ graph breaks out to 100vw; this stops that from adding a horizontal scrollbar */
}
a { color: var(--fg); text-decoration: none; }
a:hover { color: var(--accent); }

/* Centered column shared by header, content and footer. */
.bar {
  max-width: var(--content);
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}
.topbar {
  background: var(--surface);
  padding: 11px 0;
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar .bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap; /* nav drops below the brand on very narrow screens rather than overflowing */
  row-gap: 8px;
}
.topbar .brand { display: flex; }
.topbar .logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--fg);
}
.topbar .logo-img {
  /* Sized to the two-line wordmark+tagline stack beside it, not just the
     wordmark, so it reads as one balanced unit. */
  height: 28px;
  width: auto;
  flex-shrink: 0;
  display: block;
}
.topbar .logo-eye-outline {
  /* Delineates the white lower half from the white topbar. */
  stroke: rgba(28, 25, 23, 0.38);
}
:root[data-theme="dark"] .topbar .logo-eye-outline {
  /* The white/red halves already read clearly against the dark topbar. */
  stroke: transparent;
}
/* Wordmark + tagline stacked vertically, sharing the wordmark's left edge —
   the icon sits beside the stack, not above the tagline. */
.topbar .logo-stack { display: flex; flex-direction: column; gap: 1px; }
.topbar .logo-text {
  /* Same serif as article titles (.post h1 / .line .title), so the header,
     tagline, and nav all read as one masthead typeface. */
  font-family: "IBM Plex Serif", Georgia, serif;
  font-size: 18px;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.topbar .logo-mark { color: var(--accent); }
.topbar .logo:hover { color: var(--fg); }
.topbar .logo:hover .logo-mark { color: var(--accent-strong); }
.topbar .tagline {
  font-family: "IBM Plex Serif", Georgia, serif;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.15;
}
.topbar nav { display: flex; align-items: center; gap: 8px; margin-left: auto; }
/* Chip styling matches the month-picker cells on the homepage (.mcell) —
   same border/radius language, same accent ring for "you are here". */
.navlink {
  font-family: "IBM Plex Serif", Georgia, serif;
  color: var(--muted); font-size: 13px;
  padding: 5px 12px; border: 1px solid transparent; border-radius: 999px;
}
.navlink:hover { color: var(--accent); border-color: var(--rule); }
.navlink.is-current {
  color: var(--accent); font-weight: 600;
  background: var(--accent-tint); border-color: var(--accent);
}
/* "The Big Picture" is the site's key destination, so its nav link is a filled
   accent chip — always emphasized, distinct from the muted page links. It stays
   red on its own page: hover and the current-page state just deepen the shade
   (these override the lighter .is-current tint via later, equal specificity). */
.navlink-cta {
  color: #fff; background: var(--accent); border-color: var(--accent-strong);
}
.navlink-cta:hover,
.navlink-cta.is-current {
  color: #fff; background: var(--accent-strong); border-color: var(--accent-strong);
}
/* Icon-only buttons (theme toggle) */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  color: var(--muted);
  background: none;
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0;
  cursor: pointer;
}
.icon-btn:hover { color: var(--accent); border-color: var(--accent); }
.icon-btn svg { display: block; }
.topbar .menu-toggle { display: none; margin-left: auto; }

/* Below this width the pill nav doesn't fit beside the (now two-line) brand,
   so swap it for a hamburger button that drops the same links down as a
   full-width panel — instead of letting the pills wrap onto their own,
   awkwardly right-shoved row (nav's margin-left:auto, needed to push it
   flush right when it shares the row with the brand, was carrying over). */
@media (max-width: 599px) {
  .topbar .bar { flex-wrap: nowrap; }
  .topbar .menu-toggle { display: inline-flex; }
  .topbar nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    margin-left: 0;
    padding: 12px 16px 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--rule);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
  }
  .topbar nav.is-open { display: flex; }
}

main { max-width: var(--content); margin: 0 auto; padding: 20px 16px 40px; }

/* Article list */
ol.items { list-style: none; margin: 0; padding: 0; }
ol.items > li {
  padding: 9px 0 9px 28px;
  position: relative;
  border-bottom: 1px solid var(--rule);
}
ol.items > li:last-child { border-bottom: 0; }
/* Month separators in the article list */
ol.items > li.month-sep {
  padding: 22px 0 7px;
  border-bottom: 0;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
ol.items > li.month-sep:first-child { padding-top: 2px; }

.line { line-height: 1.35; }
.line .title { font-family: "IBM Plex Serif", Georgia, serif; font-size: 15px; font-weight: 500; }
.line .title:hover { color: var(--accent); }

/* Read / unread state (set client-side from localStorage). Read rows dim; no extra dot. */
ol.items > li.is-read { opacity: 0.42; }
ol.items > li.is-read .line .title { color: var(--muted); font-weight: 400; }
ol.items > li.is-read:hover { opacity: 0.75; }
.host { color: var(--muted); font-size: 12px; margin-left: 5px; }
/* Source-country flag: emoji keeps its own color; nudge size/baseline. */
.flag { font-size: 13px; line-height: 1; vertical-align: -1px; }
/* Sentiment: outlook for Indonesia. Icon leads the headline, badge on the article. */
.senti { font-weight: 600; white-space: nowrap; }
.senti.s-pos { color: var(--pos); }
.senti.s-neg { color: var(--neg); }
.senti.s-neu { color: var(--neu); }
/* Leading outlook icon sits in the left gutter, colored by sentiment, so the
   arrows form a rail down the list and the title + meta share one clean left
   edge. The box is pinned to the title's first line (top = li padding-top,
   height = title font-size × line-height) and the glyph is centered within it. */
.senti.lead {
  position: absolute;
  left: 0;
  top: 9px;
  height: calc(15px * 1.35);
  width: 22px;
  display: flex;
  align-items: center;
  font-size: 12px;
  line-height: 1;
  letter-spacing: -0.06em;
}
.senti-badge {
  display: inline-flex; align-items: baseline; gap: 6px;
  font-size: 12px; font-weight: 600; white-space: nowrap;
  max-width: 100%; padding: 4px 11px; border-radius: 999px;
  margin: -12px 0 22px;
}
.senti-badge .senti-arrow { font-weight: 700; }
.senti-badge .senti-reason { color: var(--muted); font-weight: 400; white-space: normal; }
.senti-badge.s-pos { color: var(--pos); background: var(--pos-bg); }
.senti-badge.s-neg { color: var(--neg); background: var(--neg-bg); }
.senti-badge.s-neu { color: var(--neu); background: var(--neu-bg); }
.sub { color: var(--muted); font-size: 12px; margin-top: 2px; }
.sub a { color: var(--muted); }
.sub a:hover { color: var(--accent); }
.sub .cat { font-weight: 600; color: var(--accent-strong); }

/* Article page */
.post h1 {
  font-family: "IBM Plex Serif", Georgia, serif;
  font-size: 26px; font-weight: 500;
  line-height: 1.25; margin: 4px 0 6px;
}
.post .meta { color: var(--muted); font-size: 12px; margin: 0 0 22px; }
.post .meta a { color: var(--muted); }
.post .meta a:hover { color: var(--accent); }
.post .meta .cat { color: var(--accent-strong); font-weight: 600; }
.post .lead-img { margin: 0 0 22px; }
.post .lead-img img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--rule); border-radius: 6px;
}
.post .lead-img figcaption { color: var(--muted); font-size: 12px; margin-top: 6px; }
.post .lead-img figcaption a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.post .lead-img figcaption a:hover { color: var(--accent); }
.post .body { font-family: "Source Serif 4", Georgia, serif; font-size: 16px; line-height: 1.72; }
.post .body p, .post .body ul, .post .body ol { margin: 0 0 14px; }
.post .body h2 {
  font-family: "IBM Plex Serif", Georgia, serif;
  font-size: 19px; font-weight: 500; margin: 26px 0 8px;
}
.post .body h3 { font-size: 16px; font-weight: 600; margin: 20px 0 8px; }
.post .body a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.post .body a:hover { color: var(--accent-strong); }
/* Highlighter pen over the one key sentence. box-decoration-break keeps the
   rounded ends when the highlight wraps across lines. */
.post .body mark {
  background: var(--mark-bg);
  color: inherit;
  padding: 0.05em 0.2em;
  margin: 0 -0.05em;
  border-radius: 3px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.post .body img { max-width: 100%; height: auto; border-radius: 4px; }
.post .body pre {
  background: var(--surface); border: 1px solid var(--rule);
  padding: 12px; overflow: auto; font-size: 13px; border-radius: 6px;
}
.post .body code {
  font-size: 13px;
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
.post .body blockquote {
  margin: 0 0 14px; padding: 2px 0 2px 14px;
  border-left: 3px solid var(--accent); color: var(--muted);
}
.post .tags { margin: 24px 0 0; font-size: 12px; }
.post .tags a {
  display: inline-block; color: var(--muted);
  border: 1px solid var(--rule); background: var(--surface);
  padding: 2px 9px; margin: 0 6px 6px 0; border-radius: 999px;
}
.post .tags a:hover {
  color: var(--accent-strong); border-color: var(--accent);
  background: var(--accent-tint);
}
.back { margin-top: 24px; font-size: 13px; }
.back a { color: var(--muted); }
.back a:hover { color: var(--accent); }
/* Article back link sits above the title instead of after the body. */
.back-top { margin-top: 0; margin-bottom: 18px; }

/* Month picker: one square per month, one row per year (never wraps — the row
   scrolls horizontally if too narrow). Neutral cells with a small sentiment
   mark; the current month is ringed. */
.mgrid { margin: 2px 0 26px; }
.myear + .myear { margin-top: 14px; }
.mgrid-year {
  display: block;
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}
.mrow {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(48px, 1fr);
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 2px;
}
.mcell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 10px 4px;
  border: 1px solid var(--rule);
  border-radius: 7px;
  background: var(--surface);
  color: var(--fg);
}
.mcell-mon {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
}
.mcell-dot { font-size: 12px; line-height: 1; font-weight: 700; }
a.mcell:hover { border-color: var(--accent); }
a.mcell:hover .mcell-mon { color: var(--fg); }
.mcell.is-current {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
  background: var(--accent-tint);
}
.mcell.is-current .mcell-mon { color: var(--accent); }
/* Future and empty months: non-clickable placeholders. */
.mcell.is-empty {
  background: transparent;
  border-style: dashed;
  cursor: default;
}
.mcell.is-empty .mcell-mon { color: var(--muted); opacity: 0.4; }

/* Current month heading */
.month-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 8px;
}
.month-title { font-size: 18px; font-weight: 600; margin: 0; }

/* Homepage teaser for /the-big-picture/: a computed streak fact (not
   authored prose, unlike the "In brief" card below) above the month grid,
   current month only (see mo.isLatest in index.njk). Styled as a slim
   divider strip, not a bordered card, so it doesn't visually twin with the
   "In brief" card further down. The CTA link stays visible even while the
   text is typing. */
.bigpic-teaser {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin: 4px 0 22px;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--rule);
}
.bigpic-teaser-text {
  margin: 0;
  font-family: "Source Serif 4", Georgia, serif;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--fg);
}
.bigpic-teaser-cta {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  white-space: nowrap;
}
.bigpic-teaser-cta:hover { color: var(--accent-strong); }

/* Month in review: a distinct card above the list — a thin stat header and a
   few short bullets, so it reads as an editor's note, not another news row. */
.msum {
  margin: 8px 0 24px;
  padding: 12px 16px 14px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 10px;
}
.msum-stat {
  margin: 0 0 11px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--rule);
  color: var(--muted);
  font-size: 12px;
}
.msum-eyebrow {
  color: var(--fg);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 11px;
}
.msum-outlook { font-weight: 600; text-decoration: none; }
.msum-outlook:hover { text-decoration: underline; }
.msum-trend { font-weight: 600; white-space: nowrap; }
.msum-trend.t-up { color: var(--pos); }
.msum-trend.t-down { color: var(--neg); }
.msum-trend.t-flat { color: var(--muted); }
.msum-updated { color: var(--muted); }
.msum-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.msum-list li {
  position: relative;
  padding-left: 17px;
  font-family: "Source Serif 4", Georgia, serif;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--fg);
}
.msum-list li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 7px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}
.msum-link {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.msum-link:hover { color: var(--accent-strong); }
/* Casual aside on the month's overall mood, unlabeled, right under the stat
   line so it resolves the outlook number before the bullets even start —
   like a friend summing up the month over coffee. */
.msum-sentiment {
  margin: 0 0 12px;
  font-family: "Source Serif 4", Georgia, serif;
  font-size: 14px;
  line-height: 1.6;
  color: var(--fg);
}
/* Hide typewriter-driven lines until the script in base.njk starts revealing
   them, so visitors never see the full text flash in before it clears and
   retypes. visibility (not display) keeps the layout stable. The <noscript>
   override in base.njk restores this for visitors without JS. Not scoped to
   .msum — the homepage teaser above the month grid uses this too. */
[data-typewriter] { visibility: hidden; }
/* Blinking caret while a typed line (the homepage teaser, a "Month in
   review" mood aside, a bullet, or "why it matters") is being typed out in
   sequence (see base.njk); it disappears the moment .is-typing is removed. */
[data-typewriter].is-typing::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  background: currentColor;
  vertical-align: text-bottom;
  animation: msum-caret 0.8s steps(1) infinite;
}
@keyframes msum-caret {
  50% { opacity: 0; }
}
/* Closing "Why it matters" takeaway: what the month means for the reader. */
.msum-why {
  margin: 12px 0 0;
  padding-top: 11px;
  border-top: 1px solid var(--rule);
  font-family: "Source Serif 4", Georgia, serif;
  font-size: 14px;
  line-height: 1.6;
  color: var(--fg);
}
.msum-why-label {
  margin-right: 5px;
  color: var(--accent-strong);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.msum-why .msum-link { color: var(--accent); }

/* Older / newer month nav */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 28px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  font-size: 13px;
}
.pager > a { color: var(--muted); }
.pager > a:hover { color: var(--accent); }
.pager .is-off { color: var(--rule); pointer-events: none; }

h1 { font-size: 18px; font-weight: 600; margin: 4px 0 18px; }

footer {
  padding: 18px 0 36px;
  border-top: 1px solid var(--rule);
  color: var(--muted); font-size: 12px; text-align: center;
}
footer a { color: var(--muted); }
footer a:hover { color: var(--accent); }

/* Topic map (on the /topics/ page). Breaks out of the shared 740px column
   to full viewport width — a force-directed graph needs the extra room a
   reading-width column can't give it. */
.graph-breakout {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: 0 16px;
}
#cy {
  width: 100%; height: 78vh; min-height: 480px;
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--surface); touch-action: none;
}
.graph-meta {
  color: var(--muted); font-size: 12px; margin: 10px 0 0; text-align: center;
}
.graph-meta a { color: var(--muted); }
.graph-meta a:hover { color: var(--accent); }

/* Newsletter slide-in (see content/_includes/newsletter.njk). A docked card in
   the bottom-right on desktop, full-width along the bottom on small screens.
   Hidden until JS reveals it; .is-in animates it up into place. */
.nl {
  position: fixed;
  right: 16px; bottom: 16px;
  z-index: 50;
  width: 360px; max-width: calc(100vw - 32px);
  padding: 18px 18px 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.14), 0 2px 8px rgba(0, 0, 0, 0.08);
  opacity: 0; transform: translateY(12px);
  transition: opacity 0.28s ease, transform 0.28s ease;
}
.nl.is-in { opacity: 1; transform: translateY(0); }
:root[data-theme="dark"] .nl {
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.4);
}
.nl-x {
  position: absolute; top: 8px; right: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  color: var(--muted); background: none; border: none; border-radius: 999px;
  cursor: pointer;
}
.nl-x:hover { color: var(--fg); background: var(--accent-tint); }
.nl-eyebrow {
  margin: 0 0 6px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent);
}
.nl-title {
  margin: 0 0 6px;
  font-family: "IBM Plex Serif", Georgia, serif;
  font-size: 17px; font-weight: 500; line-height: 1.3; letter-spacing: -0.01em;
}
.nl-desc { margin: 0 0 12px; font-size: 13px; line-height: 1.5; color: var(--muted); }
.nl-row { display: flex; gap: 8px; }
.nl-email {
  flex: 1 1 auto; min-width: 0;
  padding: 9px 11px; font: inherit; font-size: 14px;
  color: var(--fg); background: var(--bg);
  border: 1px solid var(--rule); border-radius: 8px;
}
.nl-email:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.nl-submit {
  flex: 0 0 auto;
  padding: 9px 16px; font: inherit; font-size: 14px; font-weight: 600;
  color: #fff; background: var(--accent);
  border: 1px solid var(--accent-strong); border-radius: 8px; cursor: pointer;
}
.nl-submit:hover { background: var(--accent-strong); }
.nl-submit:disabled { opacity: 0.6; cursor: default; }
.nl-consent {
  display: flex; gap: 8px; align-items: flex-start;
  margin-top: 10px; font-size: 12px; line-height: 1.45; color: var(--muted);
}
.nl-consent input { flex: 0 0 auto; margin-top: 2px; accent-color: var(--accent); }
.nl-consent a { color: var(--accent); text-decoration: underline; }
.nl-error { margin: 8px 0 0; font-size: 12px; color: var(--neg); }
/* Honeypot: off-screen, out of the tab order. */
.nl-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

/* Inline end-of-article CTA (newsletter-cta.njk). Reuses the shared .nl-* form
   styles; only the container differs from the fixed popup: an accent-tinted card
   in the reading column. */
.nl-inline {
  margin: 32px 0 4px;
  padding: 20px;
  background: var(--accent-tint);
  border: 1px solid var(--rule);
  border-radius: 14px;
}
.nl-inline .nl-desc:last-child { margin-bottom: 12px; }

@media (max-width: 480px) {
  .nl { right: 8px; left: 8px; bottom: 8px; width: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .nl { transition: none; transform: none; }
}
