/* Wire — house stylesheet.
   No inline style attributes anywhere in the templates, so the Content-Security
   Policy can stay strict. Anything dynamic uses a class from the ramp below. */

:root {
  /* Every colour and face below resolves to a variable set by the Appearance
     panel, which is emitted in a nonce'd <style> block ahead of this file.
     The fallbacks are the shipped defaults, so the stylesheet still stands up
     on its own if the theme block is ever absent. The derived shades use
     color-mix rather than being stored separately, so choosing one primary
     colour produces a coherent set instead of sixteen fields to fill in. */
  --paper:    var(--bg, #ffffff);
  --ink-soft: color-mix(in srgb, var(--ink, #14171a) 84%, var(--bg, #fff));
  --wash-2:   color-mix(in srgb, var(--wash, #eff2f1) 82%, var(--rule, #d6dcda));
  --spruce:   var(--primary, #12564b);
  --spruce-d: color-mix(in srgb, var(--primary, #12564b) 76%, #000);
  --spruce-l: color-mix(in srgb, var(--primary, #12564b) 11%, #fff);
  --amber:    var(--accent, #8a4b0f);
  --amber-l:  color-mix(in srgb, var(--accent, #8a4b0f) 10%, #fff);
  --crimson:  var(--danger, #8c2f2f);

  --shadow: 0 1px 2px rgba(20, 23, 26, .06), 0 8px 24px -16px rgba(20, 23, 26, .3);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  font-feature-settings: "cv05" 1, "ss03" 1;
}

a { color: var(--spruce); text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { color: var(--spruce-d); }

:focus-visible {
  outline: 2px solid var(--spruce);
  outline-offset: 2px;
  border-radius: 2px;
}

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 20px; }
.wrap-narrow { max-width: 760px; margin: 0 auto; padding: 0 20px; }

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--ink); color: #fff;
  padding: .6rem 1rem; z-index: 100;
}
.skip:focus { left: 0; }

.hp-field { position: absolute !important; left: -9999px !important; opacity: 0; height: 0; }

/* ---------------------------------------------------------------- masthead */

.masthead { border-bottom: 1px solid var(--rule); background: var(--paper); }
.masthead-inner {
  display: flex; align-items: center; gap: 1.5rem;
  padding: 1rem 0; flex-wrap: wrap;
}
.wordmark {
  font-family: var(--font-display);
  font-size: 2rem; line-height: 1; letter-spacing: -.01em;
  color: var(--ink); text-decoration: none; white-space: nowrap;
}
.wordmark span { color: var(--spruce); }
.masthead nav { display: flex; gap: 1.4rem; flex: 1; flex-wrap: wrap; }
.masthead nav a {
  font-size: .82rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-soft); text-decoration: none; font-weight: 500;
}
.masthead nav a:hover, .masthead nav a[aria-current="page"] { color: var(--spruce); }
.masthead-actions { display: flex; gap: .6rem; align-items: center; }

/* The dispatch rail: the wire's own status line, always visible. */
.rail {
  background: var(--ink); color: #cfd8d5;
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .06em;
  padding: .45rem 0; overflow: hidden; white-space: nowrap;
}
.rail-inner { display: flex; align-items: center; gap: 1.4rem; }
.rail b { color: #fff; font-weight: 500; }
.rail .live::before {
  /* A recording light, not a status LED. Red, slightly larger, with a halo
     that pulses with it — green reads as "everything is fine", red reads as
     "this is happening now", which is what a live wire is saying. */
  content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--action, #c0392b); margin-right: .5rem; vertical-align: middle;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--action, #c0392b) 70%, transparent);
  animation: recording 2s ease-in-out infinite;
}
@keyframes recording {
  0%, 100% { opacity: 1;  box-shadow: 0 0 0 0 color-mix(in srgb, var(--action, #c0392b) 60%, transparent); }
  50%      { opacity: .45; box-shadow: 0 0 0 5px color-mix(in srgb, var(--action, #c0392b) 0%, transparent); }
}
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
@media (prefers-reduced-motion: reduce) {
  .rail .live::before { animation: none; }
}
.rail-scroll { flex: 1; overflow: hidden; }
.rail-scroll ul {
  display: flex; gap: 3rem; margin: 0; padding: 0; list-style: none;
  animation: tape 90s linear infinite;
}
.rail-scroll a { color: #cfd8d5; text-decoration: none; }
.rail-scroll a:hover { color: #fff; }
@keyframes tape { from { transform: translateX(0) } to { transform: translateX(-50%) } }

/* ------------------------------------------------- the signature: slug line */

.slug {
  font-family: var(--font-mono);
  font-size: .72rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--spruce-d); background: var(--spruce-l);
  border-left: 3px solid var(--spruce);
  padding: .5rem .75rem; display: flex; flex-wrap: wrap; gap: .75rem;
  align-items: center; margin-bottom: 1rem;
}
.slug .sep { color: var(--spruce); opacity: .5; }
.slug--embargo { color: var(--amber); background: var(--amber-l); border-left-color: var(--amber); }
.slug--muted { color: var(--muted); background: var(--wash); border-left-color: var(--rule); }
.slug-caret::after {
  content: "▌"; margin-left: .1rem; animation: blink 1.1s step-end infinite; color: var(--spruce);
}
@keyframes blink { 50% { opacity: 0 } }

/* ------------------------------------------------------------------ typography */

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 400; letter-spacing: -.008em; line-height: 1.15; }
h1 { font-size: clamp(2rem, 4.6vw, 3.1rem); margin: 0 0 .6rem; }
h2 { font-size: 1.7rem; margin: 2.2rem 0 .7rem; }
h3 { font-size: 1.3rem; margin: 1.6rem 0 .5rem; }

.eyebrow {
  font-family: var(--font-mono); font-size: .7rem; text-transform: uppercase;
  letter-spacing: .12em; color: var(--muted); margin-bottom: .4rem;
}
.standfirst { font-size: 1.18rem; color: var(--ink-soft); line-height: 1.55; }
.lede { font-size: 1.3rem; line-height: 1.5; color: var(--ink-soft); }
.meta { font-family: var(--font-mono); font-size: .74rem; color: var(--muted); letter-spacing: .04em; }

/* -------------------------------------------------------------------- cards */

.grid { display: grid; gap: 1.6rem 2rem; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }

/* The card itself is defined once, further down. What used to be here was an
   earlier version of it, and the two were both applying: the old padding-top
   was the unexplained gap above every photograph, and the old h3 and p sizes
   were quietly overriding .card-title and .card-summary. One definition. */
.card h3 a { color: var(--ink); text-decoration: none; }
.card h3 a:hover { color: var(--primary); text-decoration: underline; }

.lead-card {
  display: grid; grid-template-columns: 1.15fr 1fr; gap: 2rem; align-items: start;
  padding: 1.8rem 0 2.2rem; border-bottom: 2px solid var(--ink);
}
.lead-card h2 { font-size: clamp(1.9rem, 3.6vw, 2.7rem); margin: .2rem 0 .6rem; }
.lead-card h2 a { color: var(--ink); text-decoration: none; }
.lead-card h2 a:hover { color: var(--spruce); }
.lead-card img { width: 100%; border-radius: var(--radius); }
@media (max-width: 780px) { .lead-card { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ badges */

.badge {
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .08em;
  text-transform: uppercase; padding: .18rem .45rem; border-radius: 2px;
  background: var(--wash-2); color: var(--ink-soft); white-space: nowrap;
}
.badge--verified { background: var(--spruce-l); color: var(--spruce-d); }
.badge--embargo  { background: var(--amber-l); color: var(--amber); }
.badge--live     { background: var(--spruce); color: #fff; }
.badge--draft    { background: var(--wash-2); color: var(--muted); }
.badge--queue    { background: #fdf3d7; color: #7a5a08; }
.badge--warn     { background: #fbe9e9; color: var(--crimson); }

/* ------------------------------------------------------------------ article */

.article-body { font-size: 1.09rem; line-height: 1.72; }
.article-body p { margin: 0 0 1.15rem; }
.article-body h2 { font-size: 1.45rem; margin: 2rem 0 .6rem; }
.article-body h3 { font-size: 1.2rem; }
.article-body blockquote {
  margin: 1.6rem 0; padding: .2rem 0 .2rem 1.3rem;
  border-left: 3px solid var(--spruce);
  font-family: var(--font-display); font-size: 1.35rem; line-height: 1.4; color: var(--ink-soft);
}
.article-body img { max-width: 100%; height: auto; border-radius: var(--radius); }
.article-body table { width: 100%; border-collapse: collapse; margin: 1.4rem 0; font-size: .95rem; }
.article-body th, .article-body td { border: 1px solid var(--rule); padding: .5rem .7rem; text-align: left; }
.article-body th { background: var(--wash); font-weight: 600; }
.article-body ul, .article-body ol { padding-left: 1.3rem; margin: 0 0 1.15rem; }
.article-body li { margin-bottom: .4rem; }

.panel {
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.5rem 1.7rem; background: var(--paper);
}
.panel--wash { background: var(--wash); border-color: var(--wash-2); }
.panel--amber { background: var(--amber-l); border-color: #e8d4b6; }
.panel--spruce { background: var(--spruce-l); border-color: #c3ded6; }
.panel h3, .panel h4 { margin-top: 0; }

.notice-correction {
  border-left: 3px solid var(--amber); background: var(--amber-l);
  padding: .8rem 1rem; margin: 1.4rem 0; font-size: .95rem;
}

/* ------------------------------------------------------------------- forms */

label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: .3rem; color: var(--ink-soft); }
.hint { font-size: .78rem; color: var(--muted); font-weight: 400; margin-top: .25rem; }

input[type=text], input[type=email], input[type=password], input[type=url],
input[type=date], input[type=datetime-local], input[type=number], select, textarea {
  width: 100%; padding: .58rem .7rem; font: inherit; font-size: .95rem;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); color: var(--ink);
}
textarea { line-height: 1.6; resize: vertical; min-height: 120px; }
input:focus, select:focus, textarea:focus { border-color: var(--spruce); outline: 2px solid var(--spruce-l); outline-offset: 0; }
.field { margin-bottom: 1.1rem; }
.field-row { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  font: inherit; font-size: .88rem; font-weight: 600; letter-spacing: .01em;
  padding: .6rem 1.1rem; border-radius: var(--radius); border: 1px solid transparent;
  cursor: pointer; text-decoration: none; background: var(--spruce); color: #fff;
  transition: background .12s ease;
}
.btn:hover { background: var(--spruce-d); color: #fff; }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn--ghost:hover { background: var(--wash); color: var(--ink); }
.btn--danger { background: var(--crimson); }
.btn--danger:hover { background: #6f2222; }
.btn--sm { padding: .35rem .7rem; font-size: .78rem; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.check { display: flex; gap: .6rem; align-items: flex-start; margin-bottom: .7rem; }
.check input { margin-top: .3rem; width: auto; }
.check label { margin: 0; font-weight: 500; }

/* ------------------------------------------------------------------ tables */

.table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.table th {
  text-align: left; font-family: var(--font-mono); font-size: .68rem;
  text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  border-bottom: 1px solid var(--rule); padding: .5rem .6rem; font-weight: 500;
}
.table td { padding: .65rem .6rem; border-bottom: 1px solid var(--wash-2); vertical-align: top; }
.table tr:hover td { background: var(--wash); }
.table-scroll { overflow-x: auto; }

/* ------------------------------------------------------------------ layout */

.shell { display: grid; grid-template-columns: 220px 1fr; gap: 2.2rem; align-items: start; }
@media (max-width: 820px) { .shell { grid-template-columns: 1fr; } }

.sidenav { position: sticky; top: 1.2rem; }
.sidenav a {
  display: block; padding: .45rem .6rem; border-radius: var(--radius);
  color: var(--ink-soft); text-decoration: none; font-size: .9rem;
}
.sidenav a:hover { background: var(--wash); }
.sidenav a[aria-current="page"] { background: var(--spruce-l); color: var(--spruce-d); font-weight: 600; }
.sidenav .group {
  font-family: var(--font-mono); font-size: .66rem; text-transform: uppercase;
  letter-spacing: .1em; color: var(--muted); margin: 1.2rem 0 .35rem .6rem;
}

.stat-row { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.stat { border: 1px solid var(--rule); border-radius: var(--radius); padding: .9rem 1rem; }
.stat b { display: block; font-family: var(--font-display); font-size: 2rem; line-height: 1; }
.stat span { font-family: var(--font-mono); font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }

/* Width ramp, so bar charts need no inline styles. */
.bar { height: 8px; background: var(--spruce); border-radius: 99px; }
.bar-track { background: var(--wash-2); border-radius: 99px; overflow: hidden; }
.w0{width:0}.w5{width:5%}.w10{width:10%}.w15{width:15%}.w20{width:20%}.w25{width:25%}
.w30{width:30%}.w35{width:35%}.w40{width:40%}.w45{width:45%}.w50{width:50%}.w55{width:55%}
.w60{width:60%}.w65{width:65%}.w70{width:70%}.w75{width:75%}.w80{width:80%}.w85{width:85%}
.w90{width:90%}.w95{width:95%}.w100{width:100%}

/* ------------------------------------------------------------------- flash */

.flash { padding: .7rem 1rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: .92rem; }
.flash--success { background: var(--spruce-l); color: var(--spruce-d); }
.flash--error   { background: #fbe9e9; color: var(--crimson); }
.flash--info    { background: var(--wash); color: var(--ink-soft); }

/* -------------------------------------------------------------- pagination */

.pager { display: flex; gap: .5rem; align-items: center; justify-content: center; margin: 2.4rem 0; flex-wrap: wrap; }
.pager a, .pager span {
  padding: .4rem .75rem; border: 1px solid var(--rule); border-radius: var(--radius);
  text-decoration: none; color: var(--ink-soft); font-size: .85rem;
}
.pager .current { background: var(--ink); color: #fff; border-color: var(--ink); }

/* ------------------------------------------------------------------ footer */

.footer { border-top: 1px solid var(--rule); margin-top: 4rem; padding: 2.4rem 0 3rem; background: var(--wash); }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.footer h4 { font-family: var(--font-mono); font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 0 0 .6rem; }
.footer a { display: block; color: var(--ink-soft); text-decoration: none; font-size: .9rem; padding: .18rem 0; }
.footer a:hover { color: var(--spruce); }
.footer-note { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--rule); font-size: .8rem; color: var(--muted); }

/* ---------------------------------------------------------------- utilities */

.stack > * + * { margin-top: 1rem; }
.row { display: flex; gap: .7rem; align-items: center; flex-wrap: wrap; }
.spread { display: flex; gap: 1rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.mono { font-family: var(--font-mono); }
.right { text-align: right; }
.mt0 { margin-top: 0 } .mb0 { margin-bottom: 0 }
.mt2 { margin-top: 2rem } .mb2 { margin-bottom: 2rem }
.mt1 { margin-top: 1rem } .mb1 { margin-bottom: 1rem }
.divider { border: 0; border-top: 1px solid var(--rule); margin: 2rem 0; }
.tag-list { display: flex; gap: .4rem; flex-wrap: wrap; }
.tag-list a {
  font-family: var(--font-mono); font-size: .72rem; padding: .2rem .5rem;
  background: var(--wash); border-radius: 2px; text-decoration: none; color: var(--ink-soft);
}
.tag-list a:hover { background: var(--spruce-l); color: var(--spruce-d); }
.check-ok  { color: var(--spruce); font-weight: 600; }
.check-bad { color: var(--amber); font-weight: 600; }
.captcha-img { border: 1px solid var(--rule); border-radius: var(--radius); display: block; }

@media print {
  .masthead, .rail, .footer, .btn, .no-print { display: none !important; }
  body { font-size: 11pt; }
  .article-body a::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}


/* ---------------------------------------------------------------- captcha */

.captcha-img {
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--wash);
  display: block;
  max-width: 100%;
  height: auto;
  /* The image carries fine, low-contrast detail on purpose; smoothing it on a
     high-density screen would do the attacker's denoising for him. */
  image-rendering: pixelated;
}

.challenge-question {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  background: var(--wash);
  border-left: 3px solid var(--primary);
  padding: 0.7rem 0.9rem;
  margin: 0 0 0.6rem;
  border-radius: 0 3px 3px 0;
}

/* ------------------------------------------------------- reveal password */

.check--reveal {
  margin-top: 0.45rem;
  font-size: 0.85rem;
}

.check--reveal label {
  color: var(--muted);
  font-weight: 400;
  cursor: pointer;
}

.check--reveal input:focus-visible + label {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}


/* ================================================================ theme ==
   Where the Appearance settings actually take effect. Kept at the end so a
   themed value wins over the shipped default without either being !important. */

.wrap        { max-width: var(--container, 1120px); }
.wrap-narrow { max-width: var(--measure, 760px); }

body { background: var(--bg, #fff); color: var(--ink, #14171a); }

.masthead { background: var(--header-bg, #fff); border-bottom-color: color-mix(in srgb, var(--header-bg, #fff) 78%, var(--rule)); }
.masthead nav a, .masthead .wordmark { color: var(--header-text, #14171a); }
.masthead nav a:hover,
.masthead nav a[aria-current="page"] { color: color-mix(in srgb, var(--header-text, #14171a) 70%, var(--primary)); }

.wordmark {
  font-family: var(--font-wordmark, var(--font-display));
  font-size: var(--wordmark-size, 1.6rem);
  text-transform: var(--wordmark-case, none);
}

.footer { background: var(--footer-bg, #14171a); color: var(--footer-text, #b9c2bf); }
.footer a { color: color-mix(in srgb, var(--footer-text, #b9c2bf) 82%, #fff); }

h1, h2, h3, h4 { font-weight: var(--heading-weight, 400); }

.article-body { font-size: var(--body-size, 1.09rem); line-height: var(--body-leading, 1.72); }
.article-body a { color: var(--link, var(--spruce)); }
.article-body img { border-radius: var(--img-radius, var(--radius)); }


/* ========================================================= editor output ==
   The markup the rich text editor produces, on the public page. Alignment and
   placement are classes, never inline styles, so the Content-Security-Policy
   stays strict and the sanitiser can check every one of them against a fixed
   list. */

.article-body .ql-align-center  { text-align: center; }
.article-body .ql-align-right   { text-align: right; }
.article-body .ql-align-justify { text-align: justify; }
.article-body .ql-indent-1 { padding-left: 2rem; }
.article-body .ql-indent-2 { padding-left: 4rem; }
.article-body .ql-indent-3 { padding-left: 6rem; }
.article-body .ql-indent-4 { padding-left: 8rem; }

/* A pull quote is a blockquote with a class, so it degrades to an ordinary
   quotation in a feed reader, an email, or plain-text extraction. */
.article-body blockquote.pullquote {
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.3;
  color: var(--pullquote, var(--spruce));
  border-left: 3px solid var(--pullquote, var(--spruce));
  padding: .2rem 0 .2rem 1.2rem;
  margin: 1.8rem 0;
  font-style: normal;
}
.article-body blockquote.pullquote p { margin: 0 0 .4rem; }

.article-body hr.wire-hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.2rem auto;
  width: 40%;
}

.article-body pre.ql-syntax {
  background: var(--wash);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: .9rem 1rem;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: .88rem;
}

/* Image placement. Floats collapse to full width on a narrow screen, because a
   30% float on a phone is a postage stamp. */
.article-body img.img-full   { width: 100%; display: block; margin: 1.4rem 0; }
.article-body img.img-medium { width: 50%; }
.article-body img.img-small  { width: 30%; }
.article-body img.img-left   { float: left;  margin: .4rem 1.4rem 1rem 0; }
.article-body img.img-right  { float: right; margin: .4rem 0 1rem 1.4rem; }
.article-body img.img-centre { display: block; margin: 1.4rem auto; }
.article-body::after { content: ""; display: block; clear: both; }

@media (max-width: 640px) {
  .article-body img.img-medium,
  .article-body img.img-small {
    width: 100%; float: none; margin: 1.2rem 0;
  }
  .article-body .ql-indent-1, .article-body .ql-indent-2,
  .article-body .ql-indent-3, .article-body .ql-indent-4 { padding-left: 1.2rem; }
}


/* =============================================================== gallery ==
   Supporting images, shown after the release. Presented as a plain grid of
   links to the full-size file rather than a lightbox: a journalist wants the
   original to download, not a viewer to click through. */

.gallery { margin: 2.4rem 0; }
.gallery h2 {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 .8rem;
  border-top: 1px solid var(--rule); padding-top: .8rem;
}
.gallery-grid {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.gallery-grid a { display: block; border-radius: var(--img-radius, var(--radius)); overflow: hidden; line-height: 0; }
.gallery-grid img { width: 100%; height: 130px; object-fit: cover; transition: transform .25s ease; }
.gallery-grid a:hover img { transform: scale(1.04); }
.gallery-note { font-size: .8rem; color: var(--muted); margin: .6rem 0 0; }

/* The editing strip. */
.gallery-strip {
  display: flex; flex-wrap: wrap; gap: .6rem;
  padding: .7rem; border: 1px dashed var(--rule);
  border-radius: var(--radius); background: var(--wash);
  min-height: 92px; align-content: flex-start;
}
.gallery-tile { position: relative; width: 96px; height: 72px; cursor: grab; }
.gallery-tile img { width: 100%; height: 100%; object-fit: cover; border-radius: 2px; }
.gallery-tile.is-dragging { opacity: .4; }
.gallery-remove {
  position: absolute; top: -7px; right: -7px;
  width: 20px; height: 20px; line-height: 18px; padding: 0;
  border-radius: 50%; border: 1px solid var(--rule);
  background: var(--paper); color: var(--crimson);
  font-size: .85rem; cursor: pointer;
}
.gallery-empty { color: var(--muted); font-size: .85rem; margin: 0; }


/* ================================================= editor, admin surface ==
   Quill is served from this application, so its stylesheet is same-origin and
   the CSP needs no third-party allowance. */

.editor-shell .ql-toolbar {
  border-color: var(--rule); border-radius: var(--radius) var(--radius) 0 0;
  background: var(--wash);
}
.editor-shell .ql-container {
  border-color: var(--rule); border-radius: 0 0 var(--radius) var(--radius);
  font-family: var(--font-body); font-size: 1rem; min-height: 420px;
}
.editor-shell .ql-editor { line-height: 1.65; padding: 1.1rem 1.2rem; }
.editor-shell .ql-editor blockquote.pullquote {
  border-left: 3px solid var(--pullquote, var(--spruce));
  color: var(--pullquote, var(--spruce));
  font-family: var(--font-display); font-size: 1.3rem; padding-left: 1rem;
}
.editor-shell .ql-editor img.img-medium { width: 50%; }
.editor-shell .ql-editor img.img-small  { width: 30%; }
.editor-shell .ql-editor img.img-left   { float: left;  margin: .3rem 1rem .6rem 0; }
.editor-shell .ql-editor img.img-right  { float: right; margin: .3rem 0 .6rem 1rem; }
.editor-shell .ql-editor img.img-centre { display: block; margin: 1rem auto; }
.editor-shell .ql-editor hr.wire-hr { border: 0; border-top: 1px solid var(--rule); margin: 1.4rem auto; width: 40%; }
.editor-shell .ql-toolbar button { width: 26px; }


/* ============================================================ appearance ==
   The Appearance panel. Swatches are real colour inputs; the preview is a
   handful of elements carrying the same variables as the live site. */

.swatch-grid {
  display: grid; gap: .8rem 1.2rem;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.swatch { display: flex; align-items: center; gap: .6rem; }
.swatch input[type="color"] {
  width: 40px; height: 30px; padding: 0; border: 1px solid var(--rule);
  border-radius: 3px; background: none; cursor: pointer; flex: none;
}
.swatch label { font-size: .85rem; margin: 0; }
.swatch .hint { font-size: .72rem; }

.preset-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.2rem; }

/* The mail log: a record, not a design feature. */
.maillog {
  background: var(--wash); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: .7rem .9rem; font-family: var(--font-mono); font-size: .74rem;
  white-space: pre-wrap; word-break: break-word; max-height: 15rem; overflow-y: auto;
  margin: 0 0 .6rem;
}

/* A logo replaces the wordmark text; the site name survives as alt text. */
.wordmark--logo { display: inline-flex; align-items: center; padding: .2rem 0; }
.wordmark--logo img { display: block; width: auto; max-height: 60px; }
.logo-preview { max-height: 60px; width: auto; background: var(--wash); padding: .4rem; border-radius: var(--radius); }

/* Video embeds keep a 16:9 box so the page does not jump as they load. */
.video-embed {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  margin: 1.6rem 0; background: var(--wash);
  border-radius: var(--img-radius, var(--radius)); overflow: hidden;
}
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Tier editing sits inside a details element so the table stays readable. */
.tier-form { border: 1px solid var(--rule); border-radius: var(--radius); padding: .9rem; margin: .6rem 0; text-align: left; }
details > summary.btn { display: inline-block; cursor: pointer; list-style: none; }
details > summary.btn::-webkit-details-marker { display: none; }

/* Message text is rendered as escaped plain text, never as markup. */
.message-body { white-space: pre-wrap; word-break: break-word; margin: .6rem 0 0; }

/* The review action bar: the three things a desk does, before the detail. */
.action-bar {
  align-items: center; gap: .5rem; padding: .7rem .9rem;
  background: var(--wash); border: 1px solid var(--rule); border-radius: var(--radius);
}
.action-bar form { margin: 0; }


/* ================================================================ images ==
   One rule that matters more than the rest: nothing is ever stretched. Every
   image that fills a fixed box is cropped to fit, never squashed to fit, so a
   portrait photograph in a landscape slot loses its edges rather than its
   proportions. */

img { max-width: 100%; height: auto; }
.card img, .lead-card img, .gallery-grid img, .newsroom-logo img { object-fit: cover; }


/* =============================================================== gallery ==
   A uniform row height with natural widths. Each image keeps its own aspect
   ratio and the row stays level, which is what makes a gallery read as a set
   rather than a pile. */

.gallery-grid {
  display: flex; flex-wrap: wrap; gap: .7rem;
  grid-template-columns: none;
}
.gallery-grid .gallery-item {
  display: block; height: 190px; flex: 0 0 auto;
  border-radius: var(--img-radius, var(--radius)); overflow: hidden;
  background: var(--wash); line-height: 0; position: relative;
}
.gallery-grid .gallery-item img {
  height: 100%; width: auto; max-width: none; display: block;
  object-fit: cover; transition: transform .3s ease;
}
.gallery-grid .gallery-item:hover img { transform: scale(1.03); }
.gallery-grid .gallery-item::after {
  content: ""; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgba(20, 23, 26, .08); border-radius: inherit;
}
@media (max-width: 560px) {
  .gallery-grid .gallery-item { height: 130px; }
}


/* ============================================================== lightbox ==*/

.lightbox {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  background: rgba(12, 14, 16, .93); padding: 1rem;
}
.lightbox[hidden] { display: none; }
body.lightbox-open { overflow: hidden; }

.lightbox-stage {
  margin: 0; display: flex; flex-direction: column; align-items: center;
  gap: .8rem; max-width: 100%; max-height: 100%;
}
.lightbox-stage img {
  max-width: min(1200px, 92vw); max-height: 82vh;
  width: auto; height: auto; object-fit: contain;   /* never cropped in the viewer */
  border-radius: 2px; background: #0c0e10;
}
.lightbox-stage figcaption {
  color: #cfd6d3; font-size: .82rem; font-family: var(--font-mono);
  text-align: center; max-width: 60ch;
}

.lightbox-nav, .lightbox-close {
  background: rgba(255, 255, 255, .09); color: #fff; border: 0;
  cursor: pointer; border-radius: 50%; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s ease;
}
.lightbox-nav { width: 48px; height: 48px; font-size: 2rem; flex: none; }
.lightbox-close { position: absolute; top: 1rem; right: 1rem; width: 40px; height: 40px; font-size: 1.6rem; }
.lightbox-nav:hover, .lightbox-close:hover { background: rgba(255, 255, 255, .2); }
.lightbox-nav:focus-visible, .lightbox-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

@media (max-width: 560px) {
  .lightbox-nav { width: 40px; height: 40px; font-size: 1.6rem; }
  .lightbox-stage img { max-height: 70vh; }
}


/* ================================================================= share ==*/

.share {
  display: flex; align-items: center; flex-wrap: wrap; gap: .4rem;
  margin: 1.8rem 0; padding: .7rem 0;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.share-label {
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin-right: .4rem;
}
.share-btn {
  width: 34px; height: 34px; padding: 0; border: 1px solid var(--rule);
  border-radius: 50%; background: none; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.share-btn svg { width: 16px; height: 16px; fill: currentColor; }
.share-btn:hover { color: var(--primary-ink, #fff); background: var(--primary); border-color: var(--primary); }
.share-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }


/* ============================================================== tag cloud ==*/

.tagcloud { margin: 2.6rem 0 1rem; border-top: 1px solid var(--rule); padding-top: 1rem; }
.tagcloud h2 {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 .8rem;
}
.tagcloud-list { display: flex; flex-wrap: wrap; gap: .45rem; }
.tagcloud .tag {
  display: inline-flex; align-items: baseline; gap: .35rem;
  padding: .28rem .6rem; border: 1px solid var(--rule); border-radius: 999px;
  text-decoration: none; color: var(--ink); background: var(--paper);
  transition: border-color .15s ease, color .15s ease;
}
.tagcloud .tag:hover { border-color: var(--primary); color: var(--primary); }
.tagcloud .tag-n { font-family: var(--font-mono); font-size: .68rem; color: var(--muted); }
.tagcloud .tag--w1 { font-size: .82rem; }
.tagcloud .tag--w2 { font-size: .9rem; }
.tagcloud .tag--w3 { font-size: 1rem; font-weight: 500; }
.tagcloud .tag--w4 { font-size: 1.12rem; font-weight: 600; }


/* ================================================================= print ==
   The printer view. A release printed from this site should read like a press
   release on a desk: the text, the dateline, the contact, and the address it
   came from. Navigation, sharing and search boxes are furniture for a screen
   and are removed. */

@media print {
  .no-print, .masthead, .footer, .rail, .share, .tagcloud,
  .pager, .related, .gallery-note, .lightbox, .flash, .search-form { display: none !important; }

  body { background: #fff; color: #000; font-size: 11.5pt; }
  .wrap, .wrap-narrow { max-width: 100%; margin: 0; padding: 0; }

  h1 { font-size: 20pt; margin: 0 0 .4rem; }
  h2 { font-size: 13pt; page-break-after: avoid; }
  .standfirst, .lede { font-size: 12pt; }
  .article-body { font-size: 11.5pt; line-height: 1.45; }
  .article-body p, blockquote, figure, .panel { page-break-inside: avoid; }

  /* A printed page loses the browser's address bar, so links say where they go. */
  .article-body a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; word-break: break-all; }

  .slug { border: 0; padding: 0; color: #000; }
  .panel { border: 1px solid #999; background: none; }
  img { max-width: 60% !important; page-break-inside: avoid; }
  .gallery-grid .gallery-item { height: auto; }
  .gallery-grid .gallery-item img { height: auto; width: 100%; max-width: 220px; }

  a { color: #000; text-decoration: none; }
}


/* ============================================================== release ==
   The reading order: sector, headline, standfirst, then the administrative
   line. A reader should know the beat before the words and know who is
   speaking before deciding whether to read on. */

.release-eyebrow {
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .14em;
  text-transform: uppercase; margin: 2rem 0 .6rem;
}
.release-eyebrow a { color: var(--accent); text-decoration: none; }
.release-eyebrow a:hover { text-decoration: underline; }
.release-eyebrow .sep { color: var(--muted); margin: 0 .3rem; }

.release-title {
  font-family: var(--font-display); font-weight: var(--heading-weight, 700);
  font-size: clamp(2rem, 4.6vw, 3.1rem); line-height: 1.08;
  letter-spacing: -.015em; margin: 0 0 1rem;
}
.release-standfirst {
  font-size: 1.16rem; line-height: 1.5; color: var(--ink-soft);
  margin: 0 0 1.4rem; max-width: 40em;
}

/* The administrative line, ruled top and bottom so it reads as apparatus
   rather than as part of the release. */
.release-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: .7rem 0; margin: 0 0 2rem;
  font-size: .86rem; color: var(--muted);
}
.release-meta-item { display: inline-flex; align-items: center; gap: .4rem; }
.release-meta-item a { color: var(--ink); font-weight: 500; }
.release-meta-sep { color: var(--rule); }
.release-meta .ico { width: 15px; height: 15px; fill: var(--accent); flex: none; }
.release-meta-item:first-child .ico { fill: var(--accent); }

.release-hero { margin: 0 0 1.8rem; }
.release-hero img {
  width: 100%; height: auto; display: block;
  border-radius: var(--img-radius, var(--radius));
}
.release-hero figcaption {
  margin-top: .6rem; padding-left: .7rem;
  border-left: 3px solid var(--accent);
  font-size: .82rem; color: var(--muted);
}

/* The dateline opens the first paragraph, and is set in the mono face so the
   origin of a release is distinguishable from its prose at a glance — which is
   the whole reason a wire sets it apart. The place is capitalised in the markup
   rather than by text-transform, so it stays capitalised when the text is
   copied into somebody else's system. */
.dateline {
  font-family: var(--font-mono);
  font-size: .84em;
  letter-spacing: .04em;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.dateline-dash { color: var(--muted); }

@media (max-width: 480px) {
  /* A long place name plus a date will not fit on one line on a phone. */
  .dateline { white-space: normal; }
}

@media print {
  .dateline { font-weight: 700; }
}

.release-gallery { margin: 1.8rem 0; }

.notice-embargo {
  background: var(--amber-l); border-left: 3px solid var(--amber);
  padding: .8rem 1rem; margin: 0 0 1.4rem; font-size: .9rem;
}


/* -------------------------------------------- boilerplate and contact --
   Both are reference material, not copy. Boxing them tells a sub-editor
   lifting the text exactly where the release stops. */

.boilerplate {
  background: var(--wash); border-left: 4px solid var(--ink);
  padding: 1.6rem 1.8rem; margin: 2.4rem 0 1.4rem;
}
.boilerplate h2 {
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .12em;
  text-transform: uppercase; margin: 0 0 .7rem;
}
.boilerplate-body { font-size: .95rem; line-height: 1.6; }
.boilerplate-body p:last-child { margin-bottom: 0; }
.boilerplate-link {
  display: inline-flex; align-items: center; gap: .45rem; margin-top: .9rem;
  font-size: .85rem; font-weight: 600; color: var(--ink); text-decoration: none;
}
.boilerplate-link:hover { color: var(--primary); }
.boilerplate-link .ico { width: 16px; height: 16px; fill: currentColor; }

.contact-card {
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.6rem 1.8rem; margin: 0 0 2rem;
}
.contact-card h2 {
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .12em;
  text-transform: uppercase; margin: 0 0 .9rem;
  border-bottom: 1px solid var(--rule); padding-bottom: .7rem;
}
.contact-card dl { margin: 0; }
.contact-card dt {
  font-size: .78rem; font-weight: 600; color: var(--muted); margin-top: .8rem;
}
.contact-card dt:first-child { margin-top: 0; }
.contact-card dd { margin: .1rem 0 0; font-size: .98rem; }
.contact-card dd a { color: var(--accent); }


/* ------------------------------------------------- tags and disclaimer --*/

.release-tags { display: flex; align-items: center; flex-wrap: wrap; gap: .6rem; margin: 1.4rem 0; }
.release-tags-label {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}

.disclaimer {
  background: var(--wash); border-left: 4px solid var(--ink);
  padding: 1.2rem 1.5rem; margin: 1.6rem 0;
  font-size: .84rem; line-height: 1.55; color: var(--ink-soft);
}
.disclaimer .mono { word-break: break-all; }


/* ---------------------------------------------------- related releases --
   A full-width band, so the release visibly ends before the suggestions
   begin rather than trailing off into them. */

.related-band {
  background: var(--wash); border-top: 1px solid var(--rule);
  margin-top: 3rem; padding: 2.4rem 0 3rem;
}
.related-heading {
  font-family: var(--font-display); font-size: 1.5rem; margin: 0 0 1.4rem;
  padding-bottom: .7rem; border-bottom: 2px solid var(--ink);
}


/* ================================================================= card ==*/

.card {
  display: flex; flex-direction: column; background: var(--paper);
  border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden;
}
.card-media { display: block; line-height: 0; margin: 0; padding: 0; }
.card-thumb {
  width: 100%; height: 190px; object-fit: cover; display: block;
  background: var(--wash); border-radius: 0;
}
.card-body { padding: 1.4rem 1.5rem 1rem; flex: 1; }

/* A safety net. The padding belongs on .card-body, but a card built without
   that wrapper used to render with its text against the border — twice now, on
   two different pages. Anything placed directly in a card gets the padding
   instead of nothing. */
.card > :not(.card-body):not(.card-foot):not(.card-media) {
  padding-left: 1.5rem; padding-right: 1.5rem;
}
.card > :not(.card-body):not(.card-foot):not(.card-media):first-child { padding-top: 1.4rem; }
.card > :not(.card-body):not(.card-foot):not(.card-media):last-child  { padding-bottom: 1.4rem; }
.card-eyebrow {
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .14em;
  text-transform: uppercase; margin: 0 0 .45rem; line-height: 1.4;
}
.card-eyebrow a { color: var(--accent); text-decoration: none; }
.card-title {
  font-family: var(--font-display); font-size: 1.12rem; line-height: 1.25;
  margin: 0 0 .5rem; font-weight: var(--heading-weight, 600);
}
.card-title a { color: var(--ink); text-decoration: none; }
.card-title a:hover { color: var(--primary); }
.card-summary { font-size: .88rem; line-height: 1.5; color: var(--ink-soft); margin: 0; }
.card-foot {
  display: flex; justify-content: space-between; align-items: center; gap: .6rem;
  border-top: 1px solid var(--rule); padding: .8rem 1.5rem;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.card-issuer { color: var(--muted); text-decoration: none; }
.card-issuer:hover { color: var(--primary); }
.card-date { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }


/* =========================================================== masthead ==*/

.masthead-actions { display: flex; align-items: center; gap: .5rem; }
.masthead-search {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; color: inherit; opacity: .8;
}
.masthead-search svg { width: 18px; height: 18px; fill: currentColor; }
.masthead-search:hover { opacity: 1; }

/* The one action the site is asking for. */
.btn--submit {
  background: var(--action, #c0392b); border-color: var(--action, #c0392b); color: #fff;
  display: inline-flex; align-items: center; gap: .45rem;
  font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.btn--submit svg { width: 15px; height: 15px; fill: currentColor; }
.btn--submit:hover {
  background: color-mix(in srgb, var(--action, #c0392b) 85%, #000);
  border-color: color-mix(in srgb, var(--action, #c0392b) 85%, #000); color: #fff;
}

@media (max-width: 720px) {
  .release-meta { font-size: .8rem; gap: .4rem; }
  .release-meta-sep { display: none; }
  .release-meta-item { flex: 0 0 auto; }
  .masthead-actions .btn--ghost { display: none; }
}

/* ================================================================ follow ==
   Scoped to whatever the reader is on: the wire, one sector, one newsroom. */

.follow {
  background: var(--wash); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 1.7rem 1.9rem; margin: 2.6rem 0;
}
.follow-text h2 {
  font-family: var(--font-display); font-size: 1.35rem; margin: 0 0 .3rem;
}
.follow-text p { margin: 0 0 1rem; color: var(--ink-soft); font-size: .92rem; }
.follow-form { display: flex; flex-wrap: wrap; gap: .5rem; align-items: stretch; }
.follow-form input[type="email"] { flex: 1 1 15rem; min-width: 0; }
.follow-form select { flex: 0 1 12rem; }
.follow-alt { margin: .8rem 0 0; font-size: .82rem; color: var(--muted); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
@media (max-width: 620px) {
  .follow-form input[type="email"], .follow-form select, .follow-form .btn { flex: 1 1 100%; }
}

/* The share row appears twice on a release. The upper one sits between the
   administrative line and the picture, so it needs no rule above it — the meta
   line already has one — and less air beneath. */
.share--top {
  border-top: 0;
  margin: -1.4rem 0 1.6rem;
  padding-top: 0;
}
@media (max-width: 620px) {
  .share--top { margin-top: -1rem; }
}

/* Shown only to the desk and the issuing newsroom, never to a reader. */
.boilerplate--empty { border-left-color: var(--amber); background: var(--amber-l); font-size: .9rem; }


/* ========================================================= mobile header ==
   On a phone the masthead is three cells: menu, wordmark, search. The wordmark
   is centred between the two, which only works reliably as a grid — a flex row
   centres the wordmark in the space left over, so it drifts as the buttons
   change width. */

.burger {
  display: none;
  background: none; border: 0; padding: .4rem;
  color: inherit; cursor: pointer;
  align-items: center; justify-content: center;
}
.burger-bars { display: block; width: 22px; }
.burger-bars span {
  display: block; height: 2px; margin: 4px 0;
  background: currentColor; border-radius: 2px;
  transition: transform .2s ease, opacity .2s ease;
}
/* The bars become a cross while the panel is open, so the button says what it
   will do next rather than what it did last. */
body.nav-open .burger-bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.nav-open .burger-bars span:nth-child(2) { opacity: 0; }
body.nav-open .burger-bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav-actions { display: none; }

@media (max-width: 860px) {
  .masthead { position: relative; z-index: 200; }

  .masthead-inner {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .6rem;
  }

  .burger { display: inline-flex; justify-self: start; }
  .wordmark { grid-column: 2; justify-self: center; text-align: center; }
  .masthead-actions { grid-column: 3; justify-self: end; }

  /* Submit PR stays in the bar on a phone. It is the one action the site is
     asking for, and burying it behind a menu on the device most people arrive
     on would be a strange thing to do. Only Sign in moves into the panel. */
  .masthead-actions .btn--ghost { display: none; }
  .masthead-actions .btn--submit { display: inline-flex; padding: .45rem .7rem; }
  .masthead-search { display: inline-flex; }

  /* The menu itself. Absolutely positioned so opening it does not push the
     page down and move whatever the reader was looking at. */
  #site-nav { display: none; }
  /* The open panel.
   *
   * Every value here is written so that a missing custom property cannot make
   * the panel transparent. It did: the background was a bare var(--header-bg)
   * with no fallback, and when that resolved to nothing the whole declaration
   * was dropped — leaving the menu drawn straight over the article underneath,
   * both readable and neither usable. A menu is one of the few things that
   * must never depend on a theme value being present.
   *
   * max-height is in vh rather than calc(100vh - 100%): a percentage of the
   * parent inside a viewport calculation is not valid, so that declaration was
   * being discarded too, and a long menu had nothing stopping it. */
  body.nav-open #site-nav {
    display: flex; flex-direction: column; align-items: stretch; gap: 0;
    position: absolute; top: 100%; left: 0; right: 0; width: 100%;
    box-sizing: border-box; z-index: 200;
    background-color: #ffffff;
    background-color: var(--header-bg, var(--paper, #ffffff));
    color: var(--header-text, var(--ink, #14171a));
    border-top: 1px solid rgba(0, 0, 0, .12);
    box-shadow: 0 12px 28px rgba(12, 14, 16, .22);
    padding: .4rem 0 .8rem;
    max-height: 78vh; overflow-y: auto; overscroll-behavior: contain;
  }

  /* A scrim, so the page behind reads as inactive rather than as a second
     layer of text competing with the menu. Tapping it closes the menu, which
     the script already handles. */
  body.nav-open::after {
    content: ""; position: fixed; inset: 0; z-index: 150;
    background: rgba(12, 14, 16, .38);
  }
  body.nav-open .masthead { z-index: 200; }
  body.nav-open { overflow: hidden; }
  body.nav-open #site-nav a {
    display: block; width: 100%; box-sizing: border-box;
    padding: .9rem 1.2rem; margin: 0;
    border-bottom: 1px solid rgba(0, 0, 0, .08);
    color: inherit; text-align: left;
  }
  body.nav-open #site-nav a[aria-current="page"] { font-weight: 600; }

  .nav-actions {
    display: flex; gap: .6rem; padding: .9rem 1.2rem 0;
  }
  .nav-actions .btn { display: inline-flex; flex: 1; justify-content: center; }
  body.nav-open #site-nav .nav-actions a { border-bottom: 0; padding: .5rem .9rem; }
}

@media (max-width: 420px) {
  .wordmark { font-size: calc(var(--wordmark-size, 1.6rem) * .8); }
  .wordmark--logo img { max-height: 30px; }
}


/* ========================================================== review queue ==*/

.queue-table th.tick, .queue-table td.tick { width: 2.2rem; text-align: center; }
.queue-table th.grip, .queue-table td.grip { width: 2rem; text-align: center; }
.queue-table td.grip {
  cursor: grab; color: var(--muted); font-size: 1.1rem; user-select: none;
}
.queue-table td.grip:active { cursor: grabbing; }
.queue-table tr.is-dragging { opacity: .45; background: var(--wash); }
.queue-table tbody tr:hover { background: var(--wash); }

/* The action bar appears only once something is selected, so the page is not
   carrying a row of buttons that cannot do anything. */
.bulk-bar {
  position: sticky; bottom: 0; z-index: 20;
  background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 1.2rem 1.4rem; margin-top: .6rem;
}
.bulk-bar[hidden] { display: none; }
.bulk-count {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 .8rem;
}
.bulk-count b { color: var(--ink); font-size: 1rem; }


/* ============================================================== home page ==
   A front page, not a list: one release given room, then a three-column grid,
   the sector tiles, and a rail of things a reader might do next. */

.lead-slab {
  display: grid; grid-template-columns: 1.15fr 1fr; gap: 0;
  border: 1px solid var(--rule); border-radius: var(--radius);
  overflow: hidden; margin: 1.6rem 0 2.4rem; background: var(--paper);
}
.lead-media { display: block; line-height: 0; height: 100%; }
.lead-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lead-text {
  padding: 2rem 2.2rem; display: flex; flex-direction: column;
}
.lead-title {
  font-family: var(--font-display); font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1.15; margin: 0 0 .8rem;
}
.lead-title a { color: var(--ink); text-decoration: none; }
.lead-title a:hover { color: var(--primary); }
.lead-summary { color: var(--ink-soft); margin: 0 0 1.4rem; }
.lead-foot {
  margin-top: auto; padding-top: 1rem; border-top: 1px solid var(--rule);
  display: flex; justify-content: space-between; gap: .6rem;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.lead-foot a { color: var(--muted); text-decoration: none; }

.home-split { display: grid; grid-template-columns: 1fr 20rem; gap: 2.4rem; align-items: start; }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  border-bottom: 2px solid var(--ink); padding-bottom: .5rem; margin: 0 0 1.4rem;
}
.section-head h2 {
  font-family: var(--font-display); font-size: 1.35rem; margin: 0;
  text-transform: uppercase; letter-spacing: .02em;
}
.section-head a {
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); text-decoration: none; white-space: nowrap;
}
.section-head a:hover { color: var(--primary); }
.mt3 { margin-top: 2.8rem; }

.grid--3 { grid-template-columns: repeat(3, 1fr); }

/* Sector tiles: the icon carries the colour, the tile stays neutral. A grid of
   coloured boxes is a toy; a grid of coloured marks is a contents page. */
.sector-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .8rem;
}
.sector-tile {
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  padding: 1.5rem 1rem; text-align: center; text-decoration: none;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--paper); color: var(--ink);
  transition: border-color .15s ease, transform .15s ease;
}
.sector-tile:hover { border-color: var(--primary); transform: translateY(-2px); }
.sector-icon svg { width: 26px; height: 26px; fill: currentColor; display: block; }
.sector-name { font-family: var(--font-display); font-weight: 600; font-size: 1rem; }
.sector-count { font-family: var(--font-mono); font-size: .68rem; color: var(--muted); }

/* More headlines: thumbnail, eyebrow, headline, standfirst, ruled foot. */
.headline-list { display: flex; flex-direction: column; }
.headline {
  display: grid; grid-template-columns: 9rem 1fr; gap: 1.2rem;
  padding: 1.4rem 0; border-bottom: 1px solid var(--rule);
}
.headline:first-child { padding-top: 0; }
.headline-media { display: block; line-height: 0; }
.headline-media img {
  width: 100%; height: 6rem; object-fit: cover; display: block;
  border-radius: var(--img-radius, var(--radius));
}
.headline-text h3 { font-family: var(--font-display); font-size: 1.1rem; line-height: 1.25; margin: 0 0 .4rem; }
.headline-text h3 a { color: var(--ink); text-decoration: none; }
.headline-text h3 a:hover { color: var(--primary); }
.headline-summary { font-size: .88rem; color: var(--ink-soft); margin: 0 0 .6rem; }
.headline-foot { border-top: 0; padding: 0; }

/* The rail. */
.home-rail { display: flex; flex-direction: column; gap: 1.4rem; }
.rail-box {
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.4rem 1.5rem; background: var(--paper);
}
.rail-box h2 {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; margin: 0 0 1rem;
  border-bottom: 2px solid var(--action, #c0392b); padding-bottom: .5rem;
}
.rail-box p { font-size: .9rem; color: var(--ink-soft); }
.rail-box .btn { width: 100%; justify-content: center; }

.most-read { list-style: none; margin: 0; padding: 0; }
.most-read li {
  display: grid; grid-template-columns: 1.6rem 1fr; gap: .7rem;
  padding: .8rem 0; border-bottom: 1px solid var(--rule);
}
.most-read li:last-child { border-bottom: 0; padding-bottom: 0; }
.most-read-n {
  font-family: var(--font-display); font-size: 1.3rem; font-weight: 700;
  color: var(--action, #c0392b); line-height: 1;
}
.most-read a { color: var(--ink); text-decoration: none; font-weight: 500; font-size: .92rem; line-height: 1.3; }
.most-read a:hover { color: var(--primary); }

@media (max-width: 1000px) {
  .home-split { grid-template-columns: 1fr; }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  .lead-slab { grid-template-columns: 1fr; }
  .lead-media img { height: 14rem; }
  .lead-text { padding: 1.4rem 1.5rem; }
  .grid--3 { grid-template-columns: 1fr; }
  .sector-grid { grid-template-columns: repeat(2, 1fr); }
  .headline { grid-template-columns: 6rem 1fr; gap: .9rem; }
  .headline-media img { height: 4.5rem; }
}

/* A headline row with no picture should not leave a column of empty space. */
.headline:has(.headline-text--wide) { grid-template-columns: 1fr; }
.headline-text--wide { grid-column: 1 / -1; }

/* ================================================================== tags ==
   Uniform chips, not a weighted word cloud. A cloud is decoration; a reader
   scanning for a subject wants a list they can read, with the count as a quiet
   aside rather than as the thing setting the type size. */

.tag-chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.tag-chip {
  display: inline-flex; align-items: baseline; gap: .4rem;
  padding: .5rem .75rem;
  background: var(--wash); border: 1px solid transparent; border-radius: 3px;
  color: var(--ink); text-decoration: none;
  font-size: .92rem; line-height: 1.2;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.tag-chip:hover { background: var(--paper); border-color: var(--primary); color: var(--primary); }
.tag-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.tag-chip-n { color: var(--muted); font-size: .82rem; }

/* Beneath an archive it is a full-width box rather than a rail item. */
.tagbox { margin: 2.6rem 0 1rem; }
@media (max-width: 620px) {
  .tag-chip { font-size: .86rem; padding: .45rem .65rem; }
}

/* ============================================================== pricing ==*/

.price-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.2rem; margin: 2rem 0;
}
.price-card {
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.7rem 1.8rem; background: var(--paper);
  display: flex; flex-direction: column;
}
.price-card h2 { font-family: var(--font-display); font-size: 1.3rem; margin: 0 0 .3rem; }
.price {
  font-family: var(--font-display); font-size: 2rem; font-weight: 700;
  margin: 0 0 .8rem; color: var(--action, #c0392b);
}
.price-blurb { font-size: .92rem; color: var(--ink-soft); margin: 0 0 1rem; }
.price-list { list-style: none; margin: 0 0 1.4rem; padding: 0; font-size: .9rem; }
.price-list li { padding: .4rem 0 .4rem 1.5rem; position: relative; border-bottom: 1px solid var(--rule); }
.price-list li::before { position: absolute; left: 0; font-weight: 700; }
.price-list li.yes::before { content: "\2713"; color: var(--spruce, #1f7a5a); }
/* An excluded feature is shown, not hidden. A reader comparing tiers needs to
   see what they would be giving up, and a list that only ever says yes tells
   them nothing. */
.price-list li.no { color: var(--muted); }
.price-list li.no::before { content: "\2014"; color: var(--rule); }
.price-card .btn { margin-top: auto; justify-content: center; }

/* Two panels side by side on the desk overview, stacking on a narrow screen. */
.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem; align-items: start; }
@media (max-width: 860px) { .two-up { grid-template-columns: 1fr; } }

/* The autosave line. Quiet on purpose: an autosave that announces itself is one
   people learn to distrust. It only raises its voice when something is wrong. */
.autosave-status {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .04em;
  color: var(--muted); align-self: center;
}
.autosave-status--bad { color: var(--action, #c0392b); font-weight: 600; }

.gallery-tile.is-dragging { opacity: .45; }
.gallery-strip { min-height: 3rem; }

.gallery-heading {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
  border-bottom: 1px solid var(--rule); padding-bottom: .5rem;
  margin: 2.4rem 0 1rem;
}
.gallery-count {
  font-size: .68rem; color: var(--muted); margin-left: .4rem;
}
.gallery-count::before { content: "\2014 "; }


/* What is currently attached to a release, shown in the editor. */
.current-media {
  display: grid; grid-template-columns: 7rem 1fr; gap: 1rem; align-items: start;
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: .8rem; margin-bottom: .8rem; background: var(--wash);
}
.current-media--file { grid-template-columns: 1fr; }
.current-media img {
  width: 100%; height: 5rem; object-fit: cover; display: block;
  border-radius: 3px; background: var(--paper);
}

/* Lists in a release body. There was no rule for these at all, so they fell
   back to the browser's defaults — flush left, cramped against the paragraphs
   around them, and at odds with everything else on the page. */
.article-body ul,
.article-body ol,
.boilerplate-body ul,
.boilerplate-body ol { margin: 0 0 1.4rem; padding-left: 1.6rem; }
.article-body ul, .boilerplate-body ul { list-style: disc; }
.article-body ol, .boilerplate-body ol { list-style: decimal; }
.article-body li, .boilerplate-body li { margin-bottom: .5rem; padding-left: .3rem; }
.article-body li:last-child { margin-bottom: 0; }
.article-body ul ul { list-style: circle; margin: .5rem 0 0; }
.article-body ol ol { list-style: lower-alpha; margin: .5rem 0 0; }
