/* ============================================================
   articles.css
   ------------------------------------------------------------
   Article body styling only. The header, navigation, sidebar and
   footer come from the shared shell in /inc/, so this file is
   what styleblog.css used to be minus everything the shell now
   provides.

   Every colour is a theme token. The old file hardcoded #ca8d1c
   borders and #f0e6d2 panels, which is why articles stayed on a
   parchment ground while the rest of the site moved to the night
   sky.
   ============================================================ */

/* ---- the page it is written on ------------------------------
   Every layer from <main> down to the paragraph was transparent, so
   article prose was painted straight onto the starfield - stars drifting
   behind the running text, and nothing holding the column. It was the
   one section with no surface of its own.

   This is the same vellum the rules chapters sit on: a lit navy panel on
   the darker page ground, a faint gold weave, and one warm bloom at the
   top edge.

   The panel used to cap itself at 68ch inside a column the page grid had
   already made ~850px wide, so ~190px of that column sat empty beside
   every article. It now fills the column, and its side padding - a share
   of the column, not of the viewport - is what sets the line length:
   about 75 characters at full width, shrinking with the column.

   Everything inside shares ONE left edge and ONE right edge. An earlier
   pass centred the prose while letting image sections run full width,
   and together with the inline indents in the content that gave four
   different left edges on a single page.

   Measured on the panel's darker end #111a37: body text #f0e3c4 is
   13.36:1 and the gold #e8c670 is 10.39:1.
   ------------------------------------------------------------ */

.article-body {
  --a-panel:  #111a37;
  --a-panel-2:#17223f;
  --a-line:   #2c3a63;

  padding: clamp(1.5rem, 5%, 3rem) clamp(1.25rem, 8.5%, 4.5rem);
  background:
    repeating-linear-gradient(105deg, rgba(232,198,112,.028) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(15deg,  rgba(232,198,112,.020) 0 1px, transparent 1px 6px),
    radial-gradient(ellipse at 50% 0%, rgba(232,198,112,.07), transparent 62%),
    linear-gradient(180deg, var(--a-panel-2), var(--a-panel));
  border: 1px solid var(--a-line);
  border-top: 3px solid var(--gold);
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(3, 7, 20, .55);

  font-family: var(--font-prose);
  color: var(--text-primary);
  font-size: 1.1rem;
  line-height: 1.75;
}

/* header.php draws the eyebrow inside the plate, and article.php now skips
   the plate to stop the title printing twice - so the eyebrow is rendered
   by the page itself and styled to match .bico-eyebrow. */
.article-eyebrow {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-eyebrow);
  margin: 0 0 .55rem;
}

/* ---- normalising the authored markup ------------------------
   The article HTML comes out of an editor and carries its own spacing and
   alignment, which is most of what made pages look scattered. CSS cannot
   rewrite it, so these neutralise it instead. A content cleanup would let
   most of this block go.

   <br> as a spacer between blocks: margins do that job now. Only direct
   children of the known wrappers are hidden - a <br> inside a <p> is a
   deliberate line break and is left alone. */
.article-body > br,
.article-body .Article-text-right-container > br,
.article-body .Article-Text > br,
.article-body .Article-Text-left > br,
.article-body .section > br { display: none; }

/* Inline style="padding-left: 2em" on paragraphs and lists. An inline
   declaration outranks any stylesheet rule, so !important is the only
   lever. Paragraphs return to the shared left edge; lists keep just the
   room their bullets need. */
.article-body p[style*="padding-left"] { padding-left: 0 !important; }
.article-body ul[style*="padding-left"],
.article-body ol[style*="padding-left"] { padding-left: 1.4rem !important; }

/* <center> around headings put some titles in the middle and most on the
   left. */
.article-body center { text-align: start; }

/* ---- running text ------------------------------------------ */

.article-body > :first-child { margin-top: 0; }

.article-body h1,
.article-body h2,
.article-body h3,
.article-body h4 {
  font-family: var(--font-display);
  color: var(--text-primary);
  line-height: 1.2;
  /* pretty avoids a lone last word without balance's habit of squeezing a
     two-line heading into a narrow block under a full-width rule. */
  text-wrap: pretty;
  margin: 2.25rem 0 .75rem;
}

/* flow-root on headings: beside a floated image a heading becomes its own
   block formatting context and shrinks into the space left, instead of
   running its underline behind the picture. Elsewhere it is an ordinary
   full-width block. */
.article-body h2 {
  display: flow-root;
  font-size: 1.5rem;
  color: var(--gold);
  padding-bottom: .35rem;
  border-bottom: 1px solid var(--border);
}
.article-body h3 { display: flow-root; font-size: 1.2rem; margin-top: 1.75rem; }
.article-body h4 { font-size: 1.05rem; color: var(--text-secondary); }

/* The content often stacks an introducing heading directly on the first
   item under it ("The 6 grand categories" then "Politics"). Two full
   section gaps in a row read as a hole. */
.article-body h2 + h2 { margin-top: 1.1rem; }

.article-body p { margin: 0 0 1.1rem; }

/* ---- illuminated opening ------------------------------------
   The article's first paragraph gets a drop cap. Two shapes of content
   are covered: a title inside the opening image-text section, and a bare
   title at the top. ~ rather than + because the editor tends to leave a
   <br> between the title and the paragraph. ::first-letter reaches through
   the <strong> the text often opens with.
   ------------------------------------------------------------ */
/* The paragraph contains its own drop cap. Several articles open with a
   one-line tagline ("The start of a great adventure!"), and an uncontained
   three-line capital hangs out of it and indents the next paragraph too. */
.article-body > .Article-Image-Text-section:first-child
  .Article-text-right-container > h1 ~ p:first-of-type,
.article-body > h1:first-child ~ p:first-of-type { display: flow-root; }

.article-body > .Article-Image-Text-section:first-child
  .Article-text-right-container > h1 ~ p:first-of-type::first-letter,
.article-body > h1:first-child ~ p:first-of-type::first-letter {
  float: left;
  font-family: var(--font-display);
  font-size: 3.2em;
  line-height: .82;
  margin: .06em .1em 0 0;
  color: var(--gold);
}

@media (max-width: 560px) {
  .article-body > .Article-Image-Text-section:first-child
    .Article-text-right-container > h1 ~ p:first-of-type::first-letter,
  .article-body > h1:first-child ~ p:first-of-type::first-letter {
    font-size: 2.6em;
  }
}

.article-body a {
  color: var(--gold);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.article-body a:hover { color: var(--text-primary); }

.article-body ul,
.article-body ol { margin: 0 0 1.2rem; padding-left: 1.4rem; }
.article-body li { margin: 0 0 .4rem; }

.article-body blockquote {
  margin: 1.4rem 0;
  padding: .1rem 0 .1rem 1.1rem;
  border-left: 3px solid var(--gold-soft);
  color: var(--text-secondary);
  font-style: italic;
}

.article-body code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .88em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: .08em .35em;
}

.article-body hr {
  border: 0;
  height: 1px;
  background: var(--border);
  margin: 2rem 0;
}

.article-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.2rem 0;
  font-size: .95rem;
}
.article-body th,
.article-body td {
  text-align: left;
  padding: .5rem .7rem;
  border-bottom: 1px solid var(--border);
}
.article-body th {
  font-family: var(--font-display);
  color: var(--gold);
  font-weight: 600;
}

/* Wide content must scroll in its own box rather than pushing the page. */
.article-body .scroll-x { overflow-x: auto; }

/* On a phone the costs table is ~460px inside a ~275px column and pushed
   the whole page sideways. Tables arrive bare, with no .scroll-x wrapper,
   so the table becomes its own scroller - only on narrow screens, because
   display:block stops it stretching to full width on a desktop. */
@media (max-width: 640px) {
  .article-body table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* ---- images ------------------------------------------------- */

.article-body img {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
}

.Article-Image-left,
.Article-Image-right {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
  margin: 1.4rem 0;
}
.Article-Image-left  { justify-content: flex-start; }
.Article-Image-right { flex-direction: row-reverse; }

.Article-Image-left img,
.Article-Image-right img {
  max-width: 260px;
  min-width: 120px;
  border: 2px solid var(--gold-soft);
  border-radius: 8px;
  cursor: zoom-in;
}

@media (max-width: 640px) {
  .Article-Image-left,
  .Article-Image-right { flex-direction: column; gap: .9rem; }
  .Article-Image-left img,
  .Article-Image-right img { max-width: 100%; }
}

/* ---- image + text sections ----------------------------------
   .Article-Image-Text-section never had a layout rule, so the picture
   stacked above the words it belongs beside.

   The image floats rather than taking a grid column. A column left a
   narrow strip of text beside the picture and an empty well underneath
   it once the picture ended; a float lets the text wrap alongside and
   then return to the full width, on the same edges as everything else.

   Not scoped to direct children: some articles nest these sections
   inside tab panels (.glossary-section) and wrappers.
   ------------------------------------------------------------ */

.article-body .Article-Image-Text-section {
  display: flow-root;   /* contains the float */
  margin: 0 0 1.5rem;
}

.article-body .Article-image-Left-container {
  float: left;
  width: min(40%, 300px);
  margin: .35rem clamp(1.1rem, 3%, 1.9rem) .9rem 0;
}

/* The content sets image widths inline - style="width: 550px" on the flag
   - and an inline declaration beats any stylesheet `width`, so the size is
   capped with max-width, which constrains a specified width rather than
   fighting it. max-height plus object-fit:cover keeps a tall picture from
   running the length of the section; clicking still opens it whole. */
.article-body .Article-image-Left-container img {
  display: block;
  max-width: 100%;
  height: auto;
  max-height: 340px;
  object-fit: cover;
  border: 2px solid var(--gold-soft);
  border-radius: 8px;
  cursor: zoom-in;
}

.article-body .Article-text-right-container > :first-child { margin-top: 0; }

/* Image on the right. The article editor's renderer (inc/ArticleBlocks.php)
   marks the section .Article-Image-right and keeps the image first in the
   DOM, so a screen reader still meets it before the text either way. */
.article-body .Article-Image-Text-section.Article-Image-right .Article-image-Left-container {
  float: right;
  margin: .35rem 0 .9rem clamp(1.1rem, 3%, 1.9rem);
}

/* A picture on its own, with no text beside it: nothing to wrap around,
   so it takes the full width instead of floating at 40% next to a gap.
   Without :has() support it falls back to the floated look above. */
.article-body .Article-Image-Text-section:not(:has(.Article-text-right-container)) .Article-image-Left-container {
  float: none;
  width: auto;
  margin: 0;
}
.article-body .Article-Image-Text-section:not(:has(.Article-text-right-container)) .Article-image-Left-container img {
  margin-inline: auto;
  max-height: 70vh;
  object-fit: contain;
}

.article-body .Article-caption {
  margin: .5rem 0 0;
  font-size: .92rem;
  font-style: italic;
  text-align: center;
  color: var(--text-secondary);
}

/* A list beside the float would draw its bullets over the picture: list
   markers live in the padding, which runs underneath a float. */
.article-body .Article-Image-Text-section ul,
.article-body .Article-Image-Text-section ol { display: flow-root; }

@media (max-width: 640px) {
  .article-body .Article-image-Left-container {
    float: none;
    width: 100%;
    margin: 0 0 1rem;
  }
}

/* ---- embedded map ------------------------------------------- */

.map-embed {
  position: relative;
  width: 100%;
  height: 70vh;
  min-height: 420px;
  margin: 1.2rem 0;
  border: 2px solid var(--gold-soft);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-0);
}
.map-embed iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---- glossary tabs ------------------------------------------ */

#glossary-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin: 1.2rem 0 1.4rem;
}
#glossary-tabs button {
  font-family: var(--font-display);
  font-size: .9rem;
  padding: .45rem .9rem;
  background: var(--surface-2);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
#glossary-tabs button:hover {
  border-color: var(--gold-soft);
  color: var(--text-primary);
}
#glossary-tabs button.active,
#glossary-tabs button[aria-selected="true"] {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--surface-0);
  font-weight: 600;
}

/* ---- image zoom overlay ------------------------------------- */

#image-zoom-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(4, 6, 16, .88);
  justify-content: center;
  align-items: center;
  padding: 3vmin;
}
#image-zoom-overlay.active { display: flex; }

#zoom-image-wrapper { position: relative; max-width: 94vw; max-height: 94vh; }
#zoomed-img {
  max-width: 94vw;
  max-height: 94vh;
  border-radius: 8px;
  border: 2px solid var(--gold-soft);
  display: block;
}
#zoom-close-button {
  position: absolute;
  top: -.4rem;
  right: -.4rem;
  width: 2.2rem;
  height: 2.2rem;
  font-size: 1.4rem;
  line-height: 1;
  background: var(--surface-2);
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  cursor: pointer;
}
#zoom-close-button:hover { border-color: var(--gold); color: var(--gold); }

@media (prefers-reduced-motion: reduce) {
  #glossary-tabs button { transition: none; }
}

/* ---- the article's own title --------------------------------
   With the plate gone this h1 is the page's only one, so it carries the
   page title rather than reading as another body heading. Same gold
   lettering as the front page wordmark and the rules hero.

   The gradient only applies where background-clip:text is supported, and
   the plain colour is declared first - so the failure mode is a duller
   heading, never an invisible one. That trap has been sprung here before.
   ------------------------------------------------------------ */

.article-body h1 {
  font-size: clamp(1.9rem, 4vw, 2.45rem);
  color: #f2e0b0;
  letter-spacing: .012em;
  margin: 0 0 1.4rem;
  padding-bottom: .55rem;
  position: relative;
  text-shadow: 0 0 30px rgba(232, 198, 112, .2);
  border-bottom: 1px solid var(--a-line, #2c3a63);
}
.article-body h1::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 64px;
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--gold), transparent);
}

@supports (-webkit-background-clip: text) or (background-clip: text) {
  .article-body h1 {
    width: max-content;
    max-width: 100%;
    background: linear-gradient(176deg, #fff6dd 0%, #f4dfa6 46%, #e8c670 72%, #cba24d 100%);
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
  }
}

/* ---- previous / next ----------------------------------------
   A section is a numbered course and every article used to dead-end, so
   the sidebar was the only way onward. Mirrors the rules pager.

   Laid out so a lone "Next" still sits on the right: margin-left:auto on
   the next link handles the first article, where there is no previous.
   The row spans the same column as the panel above it.
   ------------------------------------------------------------ */

.article-pager {
  display: flex;
  gap: 1rem;
  margin: 2.2rem 0 0;
}

.article-pager a {
  display: inline-flex;
  flex-direction: column;
  gap: .15rem;
  max-width: 47%;
  padding: .65rem 1.05rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text-primary);
  text-decoration: none;
  box-shadow: 0 6px 20px rgba(3, 7, 20, .4);
  transition: border-color .13s ease, transform .13s ease, box-shadow .13s ease;
}
.article-pager a:hover {
  border-color: var(--gold);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(3, 7, 20, .4), 0 0 20px rgba(232, 198, 112, .14);
}

.article-pager-next {
  margin-left: auto;
  text-align: right;
  align-items: flex-end;
}

.article-pager-dir {
  font-family: var(--font-display);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gold-soft);
}
.article-pager-t {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
}

@media (max-width: 640px) {
  .article-pager { flex-direction: column; }
  .article-pager a { max-width: 100%; }
  .article-pager-next { margin-left: 0; text-align: left; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  .article-pager a { transition: none; }
  .article-pager a:hover { transform: none; }
}
