/* ByteCode.News brand over PUDL. Any change must keep raised/sunken/flat distinct and meet
   WCAG 2.2 AA contrast; the theme workbench (/_specimen, dev profile) checks every scheme. */
:root {
  --accent: #9f3c1b;
  --accent-hover: #86331a;
}

[data-theme="dark"] {
  --accent: #f08a5d;
  --accent-hover: #f5a57f;
}

.article {
  max-width: 72ch;
  margin: 0 auto;
  padding: var(--space-5) var(--space-4);
}

.article-meta,
.article-tags {
  color: var(--text-muted);
}

.board-title {
  margin: 0;
  font-size: var(--text-md);
}

/* Popular Reads: up to three columns when the stage is wide, one on top of another when narrow.
   Each column is at least 16rem, and never narrower than a third of the row. */
.popular {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(16rem, calc((100% - 2 * var(--space-3)) / 3)), 1fr));
  gap: var(--space-3);
  padding: var(--space-4);
}

.popular h2 {
  grid-column: 1 / -1;
  margin: 0;
}

/* Each card's dek under its title (#150), as the dispatches show theirs, cut to three lines. */
.popular .card-dek {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

/* The detail pane hosts the article windows, as in PUDL's article-reader sample. */
.board-stage {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

/* One pane at a time on a narrow layout (#85): PUDL hides .md-detail on the list pane, but the
   stage's own display above would show it beside the list. */
@container md (max-width: 640px) {
  .md-layout:not([data-md-pane="detail"]) .board-stage { display: none; }
}

/* A phone's front page (#92): the board rests on the stage, so the masthead is shorter and the
   list is a link away, at the top and after More Stories. PUDL's back link, which minimises the
   windows, only shows while one covers the stage. Neither link shows on a wide layout, where the
   list is beside the stage. */
.front-to-list, .front-all { display: none; }
@container md (max-width: 640px) {
  .md-layout[data-stage-covered="false"] .md-back[data-win-back],
  .md-layout[data-stage-covered="true"] .front-to-list { display: none; }
  .front-to-list { display: inline-flex; margin: var(--space-3) var(--space-4) var(--space-2); }
  .front-all { display: block; margin: 0; padding: var(--space-3) var(--space-4) var(--space-4); font-weight: 600; }
  .masthead { min-height: 6rem; margin-bottom: var(--space-3); }
  .masthead-text { padding: var(--space-3) var(--space-4); }
  .masthead-date { margin-bottom: var(--space-1); }
  .masthead-tagline { margin-top: var(--space-1); }
}

/* A phone's top bar (#85): the feeds show their icons alone, their names still heard. PUDL
   does this for a pill with a .glyph, but a glyph is one colour, and the feed icon is orange. */
@media (max-width: 40rem) {
  .feed-pill { padding-inline: 8px; }
  .feed-label {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

.board-stage .md-back {
  margin: var(--space-3) var(--space-4) var(--space-1);
  align-self: flex-start;
}

/* The host stays put and the stage's content scrolls inside it, as PUDL has it, so the windows
   float over the visible stage (#92). The content ends with room for the Site window's strip,
   the bottom 22% of the host but never shorter than PUDL's smallest window, so its last lines
   can scroll clear of it. */
.board-stage .win-host {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.stage-scroll { position: absolute; inset: 0; overflow: auto; }
.stage-scroll:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--focus-ring); }
/* The stage's end scrolls clear of the Site window: its docked strip (#131), its title bar when
   collapsed there, or, from an older address, the strip it floated in. */
.win-host:has(> .win-layer > .win[data-win="site"]:not([hidden])) > .stage-scroll::after {
  content: "";
  display: block;
  height: max(22%, min(var(--win-min-h, 200px), 100%));
}
.win-host:has(> .win-layer > .win[data-win="site"][data-win-edge="bottom"]:not([hidden])) > .stage-scroll::after {
  height: 22%;
}
.win-host:has(> .win-layer > .win[data-win="site"].win-collapsed:not([hidden])) > .stage-scroll::after {
  height: calc(var(--win-head-docked, 30px) + 1px);
}
@media print {
  .stage-scroll { position: static; overflow: visible; }
}

.win .article {
  padding: var(--space-2) var(--space-2) var(--space-6);
}

.comments {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}

.comment-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.comment-list .comment-list {
  margin-left: var(--space-5);
  padding-left: var(--space-4);
  border-left: 1px solid var(--border);
}

.comment {
  margin: var(--space-4) 0;
}

.comment-meta,
.comments-none,
.comment-deleted {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* Reply, Edit and an admin's Remove (#112) share a row; an open form takes the row's width. */
.comment-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
}

.comment-actions > details[open] {
  flex-basis: 100%;
}

.tag-page {
  max-width: 72ch;
  margin: 0 auto;
  padding: var(--space-5) var(--space-4);
}


.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.launcher-icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.error-page {
  padding: var(--space-6) var(--space-4);
}

/* The Site window (#23): the site's own pages. Hidden until pudl-windows.js removes it when the
   reader closed it before, so it doesn't flash on load. */
.bcn-site-closed .win[data-win="site"] {
  display: none;
}

.site-list {
  list-style: none;
  margin: 0;
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
}

/* Entries sit side by side, each description on one line, so every page shows in the strip. */
.site-list li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 14rem;
  max-width: 22rem;
  min-width: 0;
}

.site-desc {
  color: var(--text-muted);
  font-size: var(--text-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The Site window's body stacks its pages over the System line, which it keeps at the bottom. */
section.win[data-win="site"] .win-body { display: flex; flex-direction: column; }

/* The System line (#82): the API's and ui-pudl's versions, as ui-nextjs's footer, tucked into the
   window's lower right corner. */
.site-system {
  margin: 0;
  padding: 0 var(--space-4) var(--space-3);
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-top: auto;
  gap: var(--space-1) var(--space-4);
  font: var(--text-xs) var(--mono);
  color: var(--text-muted);
}
.site-system-label { color: var(--accent); text-transform: uppercase; letter-spacing: 0.12em; }

.login-page {
  max-width: 28rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4);
}

.login-form {
  display: grid;
  gap: var(--space-4);
  margin: var(--space-4) 0;
}

/* A field's help text, tied to it by aria-describedby. PUDL has .form-error but no hint. */
.form-hint {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
}

/* The profile: a readable column like sign-in, a little wider for the dialog's text. */
.profile-page {
  max-width: 36rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4);
}

.profile-section {
  margin-top: var(--space-6);
}

.profile-section h2 {
  font-size: var(--text-lg);
}

/* Submitting a post (#36): a wider column for writing. */
.submit-page {
  max-width: 48rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4);
}

.submit-form { display: grid; gap: var(--space-2); }

.submit-tags { display: flex; gap: var(--space-2); }
.submit-tags .form-input { flex: 1; }

.form-optional { font-weight: 400; color: var(--text-muted); }

/* Text that's written as markup reads best in PUDL's monospace face, as in ui-nextjs. */
.form-mono { font-family: var(--mono); font-size: var(--text-sm); line-height: 1.6; }

/* The spam trap: off-screen rather than display:none, which some bots skip. */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The emailed sign-in code (#48): set like a code, so six digits are plainly what's wanted. */
.form-input.otp-input {
  height: auto;
  padding: var(--space-3) var(--space-4);
  font-family: var(--mono);
  font-size: 1.75rem;
  letter-spacing: 0.4em;
  text-align: center;
}

/* The site's own feeds in the topbar (#54): the standard feed icon marks them as subscriptions,
   not navigation. The icon is decorative; the label says which feed. */
.feed-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.feed-icon { flex: none; }

/* === Post and comment content (#35) =======================================
   Posts and comments are Markdown the API renders (streampack's
   MarkdownRenderingService: flexmark with tables, task lists, strikethrough and
   subscript, footnotes, asides, admonitions and factoid wiki links). PUDL styles
   an application, not prose, so the text is set here from PUDL's tokens, and
   admonitions borrow PUDL's notices. /_specimen shows every construct as the
   API renders it. */
:is(.article-body, .comment-body) {
  font-size: var(--text-base);
  line-height: 1.65;
  overflow-wrap: break-word;
}

:is(.article-body, .comment-body) :is(p, ul, ol, blockquote, pre, table, aside, .adm-block) {
  margin: 0 0 var(--space-4);
}

:is(.article-body, .comment-body) > :last-child,
:is(.article-body, .comment-body) :is(blockquote, aside, li, .adm-body) > :last-child {
  margin-bottom: 0;
}

:is(.article-body, .comment-body) :is(h2, h3, h4, h5, h6) {
  margin: var(--space-6) 0 var(--space-3);
  line-height: 1.3;
  font-weight: 700;
}
:is(.article-body, .comment-body) h2 { font-size: var(--text-2xl); }
:is(.article-body, .comment-body) h3 { font-size: var(--text-xl); }
:is(.article-body, .comment-body) h4 { font-size: var(--text-lg); }
:is(.article-body, .comment-body) h5 { font-size: var(--text-base); }
:is(.article-body, .comment-body) h6 {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

:is(.article-body, .comment-body) a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
:is(.article-body, .comment-body) a:hover { text-decoration-thickness: 2px; }

/* Inline code, and code blocks like PUDL's pre.code: monospace, flat, scrolling. */
:is(.article-body, .comment-body) code {
  font-family: var(--mono);
  font-size: 0.9em;
  padding: 0.1em 0.35em;
  border-radius: 4px;
  background: var(--surface-alt);
  overflow-wrap: anywhere;
}
:is(.article-body, .comment-body) pre {
  padding: var(--space-3) var(--space-4);
  overflow-x: auto;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  font: var(--text-sm)/1.55 var(--mono);
  tab-size: 4;
}
:is(.article-body, .comment-body) pre code {
  padding: 0;
  background: none;
  font-size: inherit;
  overflow-wrap: normal;
}

:is(.article-body, .comment-body) blockquote {
  padding-inline-start: var(--space-4);
  border-inline-start: 3px solid var(--border);
  color: var(--text-muted);
}

:is(.article-body, .comment-body) hr {
  margin: var(--space-6) 0;
  border: 0;
  border-top: 1px solid var(--border);
}

:is(.article-body, .comment-body) :is(ul, ol) { padding-inline-start: 1.5em; }
:is(.article-body, .comment-body) :is(ul, ol) :is(ul, ol) { margin: var(--space-1) 0 0; }
:is(.article-body, .comment-body) li + li { margin-top: var(--space-1); }

/* Task lists: the box is the marker. */
:is(.article-body, .comment-body) li.task-list-item {
  list-style: none;
  margin-inline-start: -1.5em;
}
:is(.article-body, .comment-body) .task-list-item-checkbox {
  margin: 0 0.4em 0 0;
  vertical-align: -0.1em;
  accent-color: var(--accent);
}

/* Tables: ruled like PUDL's data table, and scrolling inside the text when wide. */
:is(.article-body, .comment-body) table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: var(--text-md);
}
:is(.article-body, .comment-body) :is(th, td) {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  text-align: start;
  vertical-align: top;
}
:is(.article-body, .comment-body) :is(th, td)[align="center"] { text-align: center; }
:is(.article-body, .comment-body) :is(th, td)[align="right"] { text-align: end; }
:is(.article-body, .comment-body) thead th {
  background: var(--surface-alt);
  font-weight: 600;
}

:is(.article-body, .comment-body) img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

/* An aside: a note set off from the main text. */
:is(.article-body, .comment-body) aside {
  padding: var(--space-3) var(--space-4);
  border-inline-start: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
  font-size: var(--text-md);
}

/* Footnotes: small references, and the notes below the text. */
:is(.article-body, .comment-body) sup { line-height: 0; }
:is(.article-body, .comment-body) a.footnote-ref { text-decoration: none; padding: 0 0.1em; }
:is(.article-body, .comment-body) .footnotes {
  margin-top: var(--space-6);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
:is(.article-body, .comment-body) .footnotes hr { margin: 0 0 var(--space-3); }
/* The return arrow follows the note's last paragraph (only the last: a note of several stays in them). */
:is(.article-body, .comment-body) .footnotes li > p:last-of-type { display: inline; }
:is(.article-body, .comment-body) a.footnote-backref { margin-inline-start: 0.3em; }

/* Admonitions, as PUDL notices: a coloured edge and the glyph of their kind. The
   renderer puts an icon sprite (.adm-hidden) at the top of every post and points
   each icon into it, but the API's sanitizer strips those references, so the
   sprite is hidden and PUDL's glyphs stand in for the empty icons. Collapsible
   ones (??? and ???+) stay open, as on bytecode.news. */
:is(.article-body, .comment-body) .adm-hidden,
:is(.article-body, .comment-body) .adm-icon { display: none; }
:is(.article-body, .comment-body) .adm-block {
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
  border-inline-start: 4px solid var(--accent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 9%, var(--surface));
  font-size: var(--text-md);
}
:is(.article-body, .comment-body) .adm-heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4) 0;
  font-weight: 700;
}
:is(.article-body, .comment-body) .adm-heading::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  background: var(--accent);
  -webkit-mask: var(--glyph-info) center / contain no-repeat;
  mask: var(--glyph-info) center / contain no-repeat;
}
:is(.article-body, .comment-body) .adm-body {
  display: block;
  padding: var(--space-1) var(--space-4) var(--space-3);
}
/* Each kind's colour and glyph, written out: brand.css may only set PUDL's theme tokens. */
.article-body :is(.adm-tip, .adm-hint, .adm-success, .adm-faq, .adm-question), .comment-body :is(.adm-tip, .adm-hint, .adm-success, .adm-faq, .adm-question) {
  border-color: color-mix(in srgb, var(--positive) 45%, var(--border));
  border-inline-start-color: var(--positive);
  background: color-mix(in srgb, var(--positive) 9%, var(--surface));
}
.article-body :is(.adm-tip, .adm-hint, .adm-success, .adm-faq, .adm-question) .adm-heading::before, .comment-body :is(.adm-tip, .adm-hint, .adm-success, .adm-faq, .adm-question) .adm-heading::before {
  background: var(--positive);
  -webkit-mask-image: var(--glyph-check);
  mask-image: var(--glyph-check);
}
.article-body :is(.adm-warning, .adm-caution, .adm-attention), .comment-body :is(.adm-warning, .adm-caution, .adm-attention) {
  border-color: color-mix(in srgb, var(--warn) 45%, var(--border));
  border-inline-start-color: var(--warn);
  background: color-mix(in srgb, var(--warn) 9%, var(--surface));
}
.article-body :is(.adm-warning, .adm-caution, .adm-attention) .adm-heading::before, .comment-body :is(.adm-warning, .adm-caution, .adm-attention) .adm-heading::before {
  background: var(--warn);
  -webkit-mask-image: var(--glyph-warning);
  mask-image: var(--glyph-warning);
}
.article-body :is(.adm-danger, .adm-error, .adm-fail, .adm-failure, .adm-bug), .comment-body :is(.adm-danger, .adm-error, .adm-fail, .adm-failure, .adm-bug) {
  border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
  border-inline-start-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 9%, var(--surface));
}
.article-body :is(.adm-danger, .adm-error, .adm-fail, .adm-failure, .adm-bug) .adm-heading::before, .comment-body :is(.adm-danger, .adm-error, .adm-fail, .adm-failure, .adm-bug) .adm-heading::before {
  background: var(--danger);
  -webkit-mask-image: var(--glyph-stop);
  mask-image: var(--glyph-stop);
}
.article-body :is(.adm-example, .adm-quote, .adm-abstract), .comment-body :is(.adm-example, .adm-quote, .adm-abstract) {
  border-color: color-mix(in srgb, var(--text-muted) 45%, var(--border));
  border-inline-start-color: var(--text-muted);
  background: color-mix(in srgb, var(--text-muted) 9%, var(--surface));
}
.article-body :is(.adm-example, .adm-quote, .adm-abstract) .adm-heading::before, .comment-body :is(.adm-example, .adm-quote, .adm-abstract) .adm-heading::before {
  background: var(--text-muted);
}

/* The specimen's post: a readable column, as on an article page. */
.specimen-post { max-width: 46rem; }

/* The knowledge base (#34): the list is PUDL's data table, a factoid its attributes. */
.factoids-page {
  max-width: 60rem;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4);
}
.factoids-summary, .factoid-meta { color: var(--text-muted); font-size: var(--text-sm); }
.factoids-intro { padding: var(--space-5); max-width: 40rem; }
.factoids-intro h2 { font-size: var(--text-xl); margin: 0 0 var(--space-2); }
.factoid-attributes { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-3) var(--space-5); margin: var(--space-5) 0; }
.factoid-attributes dt { font-weight: 600; color: var(--text-muted); font-size: var(--text-sm); }
.factoid-attributes dd { margin: 0; overflow-wrap: anywhere; line-height: 1.6; }
.factoid-attributes dd .chip { margin-inline-end: var(--space-1); }
@media (max-width: 40rem) {
  .factoid-attributes { grid-template-columns: 1fr; gap: var(--space-1); }
  .factoid-attributes dd { margin-bottom: var(--space-3); }
}
/* Changing a factoid (#170): its form folded under Edit, teaching one under the board's intro. */
.factoid-edit, .factoid-teach { margin: var(--space-4) 0; max-width: 40rem; }
.factoid-edit > summary, .factoid-teach > summary { cursor: pointer; font-weight: 600; }
.factoid-form { margin-top: var(--space-3); }
.factoid-form-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: space-between; }
.factoid-lock { margin: var(--space-3) 0; }
.factoid-locked-note, .factoid-sign-in-note { color: var(--text-muted); font-size: var(--text-sm); }

/* The RSS Reader (#64): items as a plain list, each linking out. */
.rss-latest, .rss-feed { padding: var(--space-4) var(--space-5); }
.rss-latest h2 { font-size: var(--text-xl); margin: 0 0 var(--space-3); }
/* Refresh, and how fresh the list is (#172). */
.rss-freshness { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--text-muted); }
.md-toolbar .rss-refresh { flex: none; }
/* A board's tools as one region (the RSS reader's filter and Refresh): laid out as the toolbar's own. */
.board-tools { display: contents; }
.rss-latest[aria-busy="true"] .rss-items { opacity: 0.6; }
.rss-page { max-width: 48rem; margin: 0 auto; padding: var(--space-6) var(--space-4); }
/* The reader's feed filter (#147), beside the title search: as wide as a feed's name, not the bar. */
.md-filter-feed { width: auto; max-width: 14rem; flex: none; }
.rss-items { list-style: none; margin: 0; padding: 0; }
.rss-item { padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.rss-item:last-child { border-bottom: 0; }
.rss-item-title { display: block; font-weight: 600; overflow-wrap: anywhere; }
.rss-item-meta, .rss-feed-meta, .rss-none { color: var(--text-muted); font-size: var(--text-sm); }
/* A line or two of the feed's own summary under each item (#140), cut with an ellipsis. */
.rss-item-summary {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* Channel logs (#65): a day of lines, time and sender then what was said. */
.logs-intro, .log-day-window { padding: var(--space-4) var(--space-5); }
.logs-intro { max-width: 40rem; }
.logs-intro h2 { font-size: var(--text-xl); margin: 0 0 var(--space-2); }
.logs-page { max-width: 60rem; margin: 0 auto; padding: var(--space-6) var(--space-4); }
.log-days { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-3); font-size: var(--text-sm); }
.log-day { color: var(--text-muted); }
.log-lines { list-style: none; margin: 0; padding: 0; font: var(--text-sm)/1.55 var(--mono); }
.log-lines li { padding: 1px 0; overflow-wrap: anywhere; }
.log-time { color: var(--text-muted); text-decoration: none; }
.log-time:hover { text-decoration: underline; }
/* A line opened by its permalink (#72). */
.log-lines li { scroll-margin-top: var(--space-6); }
.log-lines li:target, .log-lines li.log-landed { background: color-mix(in srgb, var(--accent) 16%, transparent); outline: 1px solid var(--accent); }
.log-content a { color: var(--accent); overflow-wrap: anywhere; }
/* Nicks in colour, the same every time (#72): PUDL's syntax colours, checked in both themes. */
.nick-0 { color: var(--syntax-keyword); }
.nick-1 { color: var(--syntax-string); }
.nick-2 { color: var(--syntax-number); }
.nick-3 { color: var(--syntax-name); }
.nick-4 { color: var(--syntax-tag); }
.nick-5 { color: var(--syntax-attr); }
.nick-6 { color: var(--syntax-error); }
.log-sender { font-weight: 700; }
.log-outbound .log-content, .log-system .log-content { color: var(--text-muted); }
.log-system .log-content { font-style: italic; }
.log-none { color: var(--text-muted); }
/* Searching a channel's logs (#171): the form atop the channel list, and its results in place of it. */
.log-search { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); }
.log-search .md-filter-group { display: flex; }
.log-search > .md-filter, .log-search .md-filter-group .md-filter { width: auto; }
.log-search-summary { margin: 0; padding: 0 var(--space-3) var(--space-2); font-size: var(--text-sm); color: var(--text-muted); }
.log-hit .log-content { overflow-wrap: anywhere; }
.log-hit.log-outbound .log-content { color: var(--text-muted); }
.logs-page .log-search { flex-direction: row; flex-wrap: wrap; padding: 0; margin-bottom: var(--space-4); }

/* Tags as a board (#66): the cloud on the stage, a tag's posts in its window. */
.tag-stage { padding: var(--space-4) var(--space-5); }
.tag-posts { padding: var(--space-4) var(--space-5); }
.tag-post-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.tag-post-list li { padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.tag-post-list li:last-child { border-bottom: 0; }
.tag-post-list a { font-weight: 600; }
.tag-factoids-heading { margin: var(--space-3) 0 var(--space-1); font-size: var(--text-sm); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.tag-post-list time, .tag-posts-none { display: block; color: var(--text-muted); font-size: var(--text-sm); }

/* The karma leaderboard (#67): highest and lowest side by side, stacked when narrow. */
/* The admin windows (#107, PUDL-MDI-PLAN phase 3): working first, in PUDL's own cards, tables and
   chips. The admin pages are the admin board with one of them open; admins reach it from a topbar
   button beside Submit, marked while they're in it. */
.admin-window { display: grid; gap: var(--space-4); padding: var(--space-3) var(--space-4); }
.admin-window h3 { margin: 0 0 var(--space-2); font-size: var(--text-md); }
.admin-window .admin-stats { margin-bottom: 0; }
.user-tabs { margin: 0; }
.user-actions { white-space: normal; }
.user-actions .btn { margin: 0 var(--space-1) var(--space-1) 0; }
.admin-stage { padding: var(--space-5) var(--space-4); color: var(--text-muted); max-width: 40rem; }
/* The admin console (#169): a transcript of lines and what came back, and the input at its foot.
   Monospace, as the bots' channels are read; kinds are told by a mark as well as colour. */
.console-pane { display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }
.win-body .console-pane { height: 100%; padding: var(--space-3); box-sizing: border-box; }
.console-status { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }
.console-pane[data-console-state="closed"] .console-status { color: var(--danger); }
.console-transcript { flex: 1; min-height: 6rem; overflow: auto; margin: 0; padding: var(--space-2) var(--space-3); list-style: none; font: var(--text-sm)/1.5 var(--mono); background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.console-entry { padding: var(--space-1) 0; }
.console-entry + .console-entry { border-top: 1px dashed color-mix(in srgb, var(--border) 70%, transparent); }
.console-line { color: var(--text); font-weight: 600; white-space: pre-wrap; overflow-wrap: anywhere; }
.console-line::before { content: "> "; color: var(--text-muted); }
.console-output { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text); }
.console-output::before { content: "\2190  "; color: var(--text-muted); }
.console-error { color: var(--danger); }
.console-error::before { content: "\2715  "; }
.console-unhandled, .console-waiting, .console-note { color: var(--text-muted); font-style: italic; }
.console-unasked .console-output::before { content: "\2022  "; }
.console-output a { color: var(--accent); }
.console-form { display: flex; align-items: center; gap: var(--space-2); }
.console-prompt { font: 600 var(--text-md) var(--mono); color: var(--text-muted); }
.console-input { flex: 1; min-width: 0; font-family: var(--mono); }
.console-hint { margin: 0; }
.admin-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); gap: var(--space-3); margin-bottom: var(--space-6); }
.admin-stat { padding: var(--space-4); }
.admin-stat-value { margin: 0; font-size: var(--text-3xl); font-weight: 700; font-variant-numeric: tabular-nums; }
.admin-stat-label { display: block; margin: var(--space-1) 0 0; color: var(--text-muted); }
a.admin-stat-label { color: var(--accent); }
.admin-panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); gap: var(--space-6); align-items: start; }
.admin-panels h2 { margin-top: 0; }
.admin-tags { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); }
.admin-tags .num { color: var(--text-muted); font-size: var(--text-sm); }
.admin-unavailable { color: var(--text-muted); }

/* The review queue (#108): a window listing drafts, each opening as a window of its own. */
.pending-list { display: grid; gap: var(--space-3); }
.pending-summary, .pending-none { margin: 0; color: var(--text-muted); }
.pending-rows { list-style: none; margin: 0; padding: 0; }
.pending-rows li { padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.pending-rows a { font-weight: 600; }
.pending-meta { display: block; font-size: var(--text-sm); color: var(--text-muted); }
.pending-pages { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); }
/* The moderation window (#189): abuse reports listed, and one opened with its excerpt. */
.moderation-list, .moderation-report { display: grid; gap: var(--space-3); padding: var(--space-3) var(--space-4); }
.moderation-bans, .moderation-summary, .moderation-none, .moderation-meta, .moderation-no-verdict { margin: 0; color: var(--text-muted); font-size: var(--text-sm); }
.moderation-rows { list-style: none; margin: 0; padding: 0; }
.moderation-rows li { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-2); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.moderation-rows li > a { font-weight: 600; }
.moderation-rows li > a.moderation-review { font-weight: inherit; margin-left: auto; }
.moderation-rows .moderation-status { font-weight: 600; }
.moderation-rows .moderation-meta, .moderation-rows .moderation-verdict { flex-basis: 100%; }
.moderation-verdict { font-size: var(--text-sm); }
.moderation-signals { display: flex; flex-wrap: wrap; gap: var(--space-1); flex-basis: 100%; }
.moderation-pages { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); }
/* Pending's and Moderation's other views, to open beside this one (PUDL-MDI-PLAN phase 4, bcn-beside.js):
   small, after the tabs, so the tabs stay the way to move between views. */
.beside-links { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }
.beside-links a { margin-inline-start: var(--space-1); }
.moderation-facts { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-3); margin: 0; font-size: var(--text-sm); }
.moderation-facts dt { color: var(--text-muted); }
.moderation-facts dd { margin: 0; }
.moderation-report h3 { font-size: var(--text-sm); margin: 0 0 var(--space-2); }
.moderation-days { margin: 0 0 var(--space-2); font-size: var(--text-sm); }
.moderation-lines { margin-bottom: var(--space-3); }
.moderation-lines li { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-2); padding: 2px var(--space-1); }
.moderation-lines .log-content { flex: 1 1 12rem; }
.report-signals { display: inline-flex; flex-wrap: wrap; gap: var(--space-1); }
.report-flagged { background: color-mix(in srgb, var(--warn) 12%, transparent); }
.moderation-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.moderation-history ul { margin: 0; padding-left: var(--space-5); font-size: var(--text-sm); }
/* A line hidden from the public log, as only an admin sees it (#189). */
.log-lines li.log-hidden { box-shadow: inset 3px 0 0 var(--danger); padding-left: var(--space-2); }
.log-hidden .log-content { color: var(--text-muted); }
.log-unhide { display: inline; margin-left: var(--space-2); }
.draft-notice { margin: 0 0 var(--space-4); }
.draft-actions { margin-top: var(--space-5); padding-top: var(--space-3); border-top: 1px solid var(--border); }

/* The editor (#46): the form beside a preview of the post as it will read. */
.editor-page { max-width: 90rem; margin: 0 auto; padding: var(--space-6) var(--space-4); }
.editor-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.editor-links { margin: 0; }
.editor-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(28rem, 100%), 1fr)); gap: var(--space-6); align-items: start; }
.editor-categories, .editor-admin { border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-3) var(--space-4); }
.editor-categories .check { display: inline-flex; align-items: center; gap: var(--space-1); margin: 0 var(--space-4) var(--space-2) 0; }
.editor-actions { display: flex; gap: var(--space-2); margin-top: var(--space-4); }
.editor-preview { position: sticky; top: var(--space-4); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-4); background: var(--surface); }
.editor-preview-label { margin: 0 0 var(--space-3); font-size: var(--text-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }

/* Approving and deleting (#109): beside the form, asked first. */
.editor-lifecycle { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.editor-confirm { max-width: 36rem; margin: 0 auto; padding: var(--space-6) var(--space-4); }
.confirm-form { margin-top: var(--space-4); }

.article-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-3); }

.admin-feeds-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.karma-page { max-width: 64rem; margin: 0 auto; padding: var(--space-5) var(--space-4); }
.karma-intro { color: var(--text-muted); margin: 0; padding: var(--space-3) var(--space-4) 0; }
.karma-limit { margin: 0; }
.karma-boards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); gap: var(--space-5); align-items: start; }
.karma-boards caption { text-align: start; font-weight: 700; padding: 0 0 var(--space-2); }
.karma-window { display: grid; gap: var(--space-4); padding: var(--space-3) var(--space-4); }
.karma-window caption { text-align: start; font-weight: 700; padding: 0 0 var(--space-2); }
.karma-none { color: var(--text-muted); }

/* The front page's masthead (#78): the date, the name and the tagline over an ambient animation,
   as the landing content of the board's stage, above Popular. Windows opened over the board
   cover it, and its animation pauses while they do. Colours are PUDL's accent, faint. */
.masthead {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 13rem;
  display: grid;
  place-items: center;
  margin: 0 0 var(--space-4);
  border-top: 3px solid var(--accent);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
}
/* The art and its animations are streampack-dev/masthead's (#161), styled by its masthead.css in
   PUDL's colours, faint behind the name. */
.masthead {
  --masthead-accent: var(--accent);
  --masthead-bg: var(--bg);
  --masthead-border: var(--border);
  --masthead-surface: var(--surface-alt);
  --masthead-mono: var(--mono);
  --masthead-strength: 0.55;
}
.masthead-text { text-align: center; padding: var(--space-5) var(--space-4); }
.masthead-date {
  margin: 0 0 var(--space-3);
  font: var(--text-xs) var(--mono);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.masthead-name {
  margin: 0;
  font-size: clamp(2.5rem, 7vw, 4.75rem);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.04em;
}
.masthead-name a { color: var(--text); text-decoration: none; }
.masthead-dot { color: var(--accent); }
.masthead-tagline {
  margin: var(--space-3) 0 0;
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
@media (max-width: 40rem) {
  .masthead { min-height: 9rem; }
}

/* Latest Dispatches (#84), under the masthead as on bytecode.news: the lead beside the next two,
   and More Stories in columns under them. Laid out by the stage's width, not the viewport's. */
.dispatches {
  container-type: inline-size;
  padding: 0 var(--space-4) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.dispatches-label,
.dispatch-more-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  font: 600 var(--text-xs) var(--font);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.dispatches-label::after,
.dispatch-more-label::after { content: ""; flex: 1; border-top: 1px solid var(--border); }
.dispatch-more-label { margin-top: var(--space-5); }
.dispatches article { min-width: 0; }
.dispatch-byline,
.dispatch-author {
  margin: 0 0 var(--space-2);
  font: var(--text-xs) var(--mono);
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.dispatch-author { margin: var(--space-2) 0 0; }
.dispatch-sep { color: var(--border); }
.dispatch-title { margin: 0; font-weight: 700; line-height: 1.2; }
.dispatch-title a { color: var(--text); text-decoration: none; }
.dispatch-title a:hover,
.dispatch-title a:focus-visible { color: var(--accent); text-decoration: underline; }
.dispatch-lead .dispatch-title { font-size: var(--text-2xl); letter-spacing: -0.02em; }
.dispatch-secondary .dispatch-title { font-size: var(--text-xl); }
.dispatch-more .dispatch-title { font-size: var(--text-base); }
.dispatch-excerpt {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.dispatch-lead .dispatch-excerpt { font-size: var(--text-base); max-width: 42rem; margin-top: var(--space-3); }
.dispatch-secondary .dispatch-excerpt { -webkit-line-clamp: 3; line-clamp: 3; }
.dispatch-more .dispatch-excerpt { -webkit-line-clamp: 2; line-clamp: 2; }
.dispatch-more .dispatch-byline { margin: var(--space-2) 0 0; }
.dispatch-tags { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: var(--space-3) 0 0; }
.dispatch-tags a { color: inherit; text-decoration: none; }
.dispatch-read {
  display: inline-block;
  margin-top: var(--space-3);
  font: 600 var(--text-xs) var(--font);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.dispatches-top { display: grid; gap: var(--space-5); }
.dispatch-secondary { display: grid; gap: var(--space-4); }
.dispatch-secondary article + article { border-top: 1px solid var(--border); padding-top: var(--space-4); }
.dispatch-more { display: grid; gap: var(--space-4) var(--space-5); }
@container (min-width: 40rem) {
  .dispatch-lead .dispatch-title { font-size: var(--text-3xl); }
  .dispatches-top { grid-template-columns: 3fr 2fr; }
  .dispatch-lead { padding-right: var(--space-5); border-right: 1px solid var(--border); }
  .dispatch-more { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container (min-width: 60rem) {
  .dispatch-more { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ?ambientDebug=1 names the running animation and its seed in the masthead's corner (#97). */
.masthead-debug { color: var(--text-muted); }

/* The small lines keep a halo of the page's background where they cross a flap or a branch. */
.masthead:is([data-masthead="solari"], [data-masthead="fractal"]) :is(.masthead-date, .masthead-tagline) {
  text-shadow: 0 0 3px var(--bg), 0 0 6px var(--bg), 0 0 10px var(--bg);
}

/* A helper's word (a derived summary, suggested tags), beside its button. */
.helper-word { margin: var(--space-1) 0 0; }

/* Factoids while writing (#179, #180). */
.editor-factoid-tools { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.editor-factoid-tools .form-input { flex: 1 1 14rem; width: auto; }
.factoid-check-label { font-size: var(--text-sm); margin: var(--space-3) 0 var(--space-1); }
.factoid-check-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.factoid-check-list li { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: baseline; }
.factoid-def { color: var(--text-muted); flex: 1 1 16rem; }
.factoid-count, .factoid-linked { color: var(--text-muted); font-size: var(--text-xs); }
.factoid-draft { border: 1px solid var(--border, currentColor); border-radius: var(--radius, 6px); padding: var(--space-3); margin-top: var(--space-3); }
.factoid-draft-actions { display: flex; gap: var(--space-2); }

/* The factoid graph window (streampack#133). */
.factoid-graph { display: grid; gap: var(--space-4); padding: var(--space-3) var(--space-4); }
.factoid-graph-section h3 { display: inline; font-size: var(--text-sm); margin: 0; }
.factoid-graph-section > h3 { display: block; margin-bottom: var(--space-1); }
.factoid-graph-count { color: var(--text-muted); font-weight: normal; }
.factoid-graph-list { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: grid; gap: var(--space-2); }
.factoid-graph-list li { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: baseline; }
.factoid-graph-fix { display: inline; margin-left: auto; }
.factoid-graph-detail, .factoid-graph-none { color: var(--text-muted); }

/* An attention count on a window's entry in the taskbar ("Open windows"), as a Pending view opened
   beside another has (PUDL-MDI-PLAN phase 4): PUDL 0.55 draws it in the warn colour on its own tint,
   which fails contrast in light. Mixed toward the text colour, as PUDL does for its status bar's badges, but further: a raised entry's darker ground needs it. */
[data-win-dock] [data-win-tab] > .badge.win-item-attention:is(.warn, .danger) {
  color: color-mix(in srgb, var(--badge-color) 35%, var(--text));
}

/* PUDL 0.56.0 draws each dock tab's window-menu button at 18px, under the 24px a touch target
   needs (axe target-size). Its script places it for 18px, so it grows by 3px each way around the
   same centre. (pudl-windows.css loads after this file on boards, hence the group.) */
.win-dock-group .win-dock-menu { width: 24px; height: 24px; margin: -3px 0 0 -3px; }

/* The Atlas (ui-pudl#184): a map of the site's tags on the board's stage. What's found at a place
   is told by shape first (a disc for articles only, a ring for factoids only, a diamond for both),
   and by colour as well; the colours are only a second cue, each at least 4.5:1 on the stage in
   both themes, written out here because a theme sets only PUDL's tokens. Labels keep their size in pixels at any zoom: --u is one screen pixel in world
   units, set by bcn-atlas.js (the server guesses it first). */
.board-stage .stage-scroll:has(> .front > .atlas) { overflow: hidden; }
.atlas { position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden; }
.atlas .front-to-list { position: relative; z-index: 1; }
.atlas-hud {
  position: absolute; top: var(--space-3); left: var(--space-3); z-index: 1;
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: center;
  max-width: calc(100% - 2 * var(--space-3)); pointer-events: none;
}
.atlas-hud > * { pointer-events: auto; }
.atlas-key-box { display: flex; align-items: flex-start; gap: var(--space-2); }
.atlas-key-box > summary {
  padding: var(--space-1) var(--space-3); font-size: var(--text-sm); cursor: pointer; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface) 90%, transparent); border: 1px solid var(--border);
}
.atlas-legend {
  display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); margin: 0; padding: var(--space-1) var(--space-3);
  list-style: none; font-size: var(--text-sm); color: var(--text);
  background: color-mix(in srgb, var(--surface) 90%, transparent); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.atlas-legend li { display: inline-flex; align-items: center; gap: var(--space-1); }
.atlas-legend-shape { color: var(--text-muted); }
.atlas-zoom { display: inline-flex; gap: var(--space-1); }
.atlas-zoom .btn { min-width: 2rem; }
.atlas-missed { position: absolute; bottom: var(--space-3); left: var(--space-3); z-index: 1; margin: 0; padding: var(--space-1) var(--space-3);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.atlas-map { flex: 1; width: 100%; height: 100%; min-height: 0; display: block; touch-action: none; cursor: grab; user-select: none; }
.atlas-map.dragging { cursor: grabbing; }
.atlas-map .region { fill: color-mix(in srgb, var(--text) 3%, transparent); stroke: color-mix(in srgb, var(--text-muted) 45%, transparent); stroke-width: calc(1 * var(--u, 1px)); stroke-dasharray: calc(4 * var(--u, 1px)) calc(5 * var(--u, 1px)); }
.atlas-map .region-name {
  fill: var(--text-muted); font-size: calc(12 * var(--u, 1px)); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  text-anchor: middle; paint-order: stroke; stroke: var(--bg); stroke-width: calc(3 * var(--u, 1px)); stroke-linejoin: round; pointer-events: none;
}
/* From afar a region's name sits across its middle, a tag a line, over its unnamed places; closer
   in, it moves above the region and fades, and the places are named. */
.atlas-map .region-name.above { display: none; }
.atlas-map:not([data-zoom="far"]) .region-name.across { display: none; }
/* So far out (a phone's whole map) that only the bigger regions are named. */
.atlas-map[data-tiny] .region-name.across.small { display: none; }
.atlas-map:not([data-zoom="far"]) .region-name.above { display: inline; opacity: 0.55; }
/* A name that would overlap a bigger region's at this zoom (bcn-atlas.js); closer in it returns.
   As specific as the rules above that show names, so it wins over them. */
.atlas-map:is([data-zoom]) .region-name.crowded,
.atlas-map:not([data-zoom="far"]) .region-name.above.crowded { display: none; }
.atlas-map .mark { stroke: var(--bg); stroke-width: calc(1.5 * var(--u, 1px)); }
.atlas-map .place-articles .mark-disc, .atlas-key .mark-disc { fill: #a24a06; }
.atlas-map .place-factoids .mark-ring, .atlas-key .mark-ring { fill: var(--bg); stroke: #0d6e66; }
.atlas-map .place-shared .mark-diamond, .atlas-key .mark-diamond { fill: #6a2fc9; }
[data-theme="dark"] .atlas-map .place-articles .mark-disc, [data-theme="dark"] .atlas-key .mark-disc { fill: #f0a050; }
[data-theme="dark"] .atlas-map .place-factoids .mark-ring, [data-theme="dark"] .atlas-key .mark-ring { stroke: #4fc1b2; }
[data-theme="dark"] .atlas-map .place-shared .mark-diamond, [data-theme="dark"] .atlas-key .mark-diamond { fill: #b89cf2; }
.atlas-map .label {
  fill: var(--text); font-size: calc(var(--fs, 12) * var(--u, 1px)); text-anchor: middle;
  paint-order: stroke; stroke: var(--bg); stroke-width: calc(3 * var(--u, 1px)); stroke-linejoin: round; pointer-events: none;
}
/* Names by zoom: only the regions' from afar, then the bigger places', then every one close up. */
.atlas-map[data-zoom="far"] .place:not(.here) .label,
.atlas-map[data-zoom="mid"] .place.minor:not(.here) .label { display: none; }
.atlas-map .place:hover .label, .atlas-map .place:focus-visible .label { display: inline; font-weight: 700; }
.atlas-map .place { cursor: pointer; text-decoration: none; }
.atlas-map .place:focus { outline: none; }
.atlas-map .place:focus-visible .mark, .atlas-map .place.here .mark { stroke: var(--text); stroke-width: calc(3 * var(--u, 1px)); }
.atlas-map .place.here .mark-ring { stroke: #0d6e66; }
[data-theme="dark"] .atlas-map .place.here .mark-ring { stroke: #4fc1b2; }
.atlas-map .place.here .label { font-weight: 700; }
/* Pins, close up: a square for an article, a triangle for a factoid, around their place. */
/* Close up, the pins of the place framed, pointed at or opened show; closer still, every place's. */
.atlas-map .pins { display: none; }
.atlas-map[data-zoom="near"] .pins:is(.here, .shown), .atlas-map[data-close] .pins { display: inline; }
.atlas-map .pin { cursor: pointer; }
.atlas-map .pin-mark { stroke: var(--bg); stroke-width: calc(1 * var(--u, 1px)); }
.atlas-map .pin-mark-article, .atlas-key .pin-mark-article { fill: #a24a06; }
.atlas-map .pin-mark-factoid, .atlas-key .pin-mark-factoid { fill: #0d6e66; }
[data-theme="dark"] .atlas-map .pin-mark-article, [data-theme="dark"] .atlas-key .pin-mark-article { fill: #f0a050; }
[data-theme="dark"] .atlas-map .pin-mark-factoid, [data-theme="dark"] .atlas-key .pin-mark-factoid { fill: #4fc1b2; }
.atlas-map .pin:hover .pin-mark { stroke: var(--text); stroke-width: calc(1.5 * var(--u, 1px)); }
/* What's new (phase 5d): a place holding something new has a dot and a bright, slow glow; one
   holding only changes, a small ring and a quiet, dashed one. The dot and the ring say it, and the
   place's name says "2 new, 1 changed"; the glow is only a third cue. Badges and glows keep their
   size on screen at any zoom. */
.atlas-map .glow { fill: none; pointer-events: none; r: max(calc(var(--gr, 10) * 1px), calc(11 * var(--u, 1px))); }
.atlas-map .fresh-new .glow { stroke: var(--text); stroke-width: calc(3 * var(--u, 1px)); animation: atlas-glow 3.2s ease-in-out infinite; }
.atlas-map .fresh-changed .glow { stroke: var(--text-muted); stroke-width: calc(1.5 * var(--u, 1px)); stroke-dasharray: calc(3 * var(--u, 1px)) calc(3 * var(--u, 1px)); opacity: 0.6; }
@keyframes atlas-glow { 0%, 100% { stroke-opacity: 0.3; } 50% { stroke-opacity: 0.95; } }
@media (prefers-reduced-motion: reduce) { .atlas-map .fresh-new .glow { animation: none; stroke-opacity: 0.8; } }
.atlas-map .badge { r: calc(4.5 * var(--u, 1px)); }
.atlas-map .badge-changed { r: calc(3.6 * var(--u, 1px)); }
.atlas-map .badge-new, .atlas-key .badge-new { fill: var(--text); stroke: var(--bg); stroke-width: calc(1.5 * var(--u, 1px)); }
.atlas-map .badge-changed, .atlas-key .badge-changed { fill: var(--bg); stroke: var(--text); stroke-width: calc(1.8 * var(--u, 1px)); }
.atlas-key .badge-changed { stroke-width: 1.8; }
.atlas-key .badge-new { stroke-width: 1; }
.whats-new { padding: var(--space-2) var(--space-3) var(--space-4); }
.whats-new-since { margin: 0 0 var(--space-2); color: var(--text-muted); font-size: var(--text-sm); }
.whats-new-list { list-style: none; margin: 0; padding: 0; }
.whats-new-item { padding: var(--space-2) 0; border-bottom: 1px solid var(--border); font-size: var(--text-sm); }
.whats-new-item:last-child { border-bottom: 0; }
.whats-new-title { display: block; font-weight: 600; font-size: var(--text-md); }
.whats-new-kind, .whats-new-meta { color: var(--text-muted); }
.whats-new-meta { display: block; }
.fresh-badge { display: inline-flex; align-items: center; gap: 0.35em; margin-right: 0.4em; font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.fresh-badge::before { content: ""; display: inline-block; width: 0.6em; height: 0.6em; border-radius: 50%; box-sizing: border-box; }
.fresh-badge-new::before { background: var(--text); }
.fresh-badge-changed::before { border: 2px solid var(--text); }
.whats-new-none { color: var(--text-muted); }
.atlas-kind { display: inline-block; width: 0.7em; height: 0.7em; margin-right: 0.4em; vertical-align: baseline; }
.atlas-kind-articles { border-radius: 50%; background: #a24a06; }
.atlas-kind-factoids { border-radius: 50%; border: 2px solid #0d6e66; }
.atlas-kind-shared { background: #6a2fc9; transform: rotate(45deg) scale(0.85); }
[data-theme="dark"] .atlas-kind-articles { background: #f0a050; }
[data-theme="dark"] .atlas-kind-factoids { border-color: #4fc1b2; }
[data-theme="dark"] .atlas-kind-shared { background: #b89cf2; }
@container md (max-width: 640px) {
  .atlas-hud { top: auto; bottom: var(--space-3); }
  .atlas-legend { font-size: var(--text-xs); }
}
