/* ============================================================================
   Release + roadmap pages — components (ver-, rmp-)

   Layout for /roadmap and the /version/<release> pages. One file because the
   two share the release-card component (.ver-hub*): /roadmap ends on it as
   "recently shipped". Also because wm_header()'s $extra slot emits before
   wm-dark.css, so a second stylesheet loaded that way would land ahead of the
   design system rather than after it.
   Builds on css/wm-dark.css (tokens, bands, wm- primitives), loaded first by
   wm_header() via wm_theme('dark'). A ver- component that turns out useful
   elsewhere should be promoted to css/wm-dark.css and renamed wm-.

   Loaded with a cache-busting query (controllers/version.php passes
   css/version-dark.css?v=N) — bump N when editing this file.
   ============================================================================ */

/* ---- Series page header ----
   The spec line is authored orientation (build range, when it ran), not live
   data — see the header of app/site/views/version_dark.php. */
.ver-head__lede { max-width: 70ch; margin-top: 14px; }

.ver-spec {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  margin: 22px 0 0;
  font-family: var(--wm-font-mono);
  font-size: 13px;
  color: var(--wm-earth-300);
}
.ver-spec span + span { padding-left: 22px; border-left: 1px solid var(--wm-earth-700); }

.ver-head__links { display: flex; flex-wrap: wrap; gap: 14px; margin: 26px 0 0; }

/* ---- Hub ----
   A curated set of releases we have something to say about, so each entry gets
   a picture and a sentence rather than being a row in a table. The full history
   is the help centre's job and is linked, not reproduced. */
.ver-hub__lede { max-width: 76ch; margin-bottom: 32px; }

.ver-hub { display: flex; flex-direction: column; gap: 22px; }
.ver-hub__item {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 28px;
  padding: 22px;
  align-items: center;
}
.ver-hub__item--now { border-color: var(--wm-sand-gold); }
.ver-hub__shot { display: block; border-radius: 10px; overflow: hidden; }
.ver-hub__shot img { display: block; width: 100%; height: 100%; max-height: 210px; object-fit: cover; }
.ver-hub__when {
  font-family: var(--wm-font-display);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wm-earth-400);
  margin: 0 0 6px;
}
.ver-hub__item--now .ver-hub__when { color: var(--wm-sand-gold); }
.ver-hub__name {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 27px;
  margin: 0 0 10px;
}
.ver-hub__name a { color: var(--wm-earth-50); }
.ver-hub__name a:hover { color: var(--wm-sand-gold); }
.ver-hub__blurb { color: var(--wm-earth-200); font-size: 16px; line-height: 1.55; margin: 0 0 18px; max-width: 62ch; }
.ver-hub__links { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; }
.ver-hub__foot { margin-top: 30px; font-size: 15px; color: var(--wm-earth-300); }

/* ---- Copy beside media ----
   .ver-hero leads a section (media slightly wider); .ver-row is the repeating
   body row. --flip swaps the columns so consecutive rows don't stack all their
   text down one side. Both collapse to copy-then-media, which keeps the reading
   order equal to the source order. */
.ver-hero, .ver-row {
  display: grid;
  gap: 44px;
  align-items: start;
  margin-bottom: 40px;
}
.ver-hero { grid-template-columns: 1fr 1.05fr; }
.ver-row  { grid-template-columns: 1.15fr 1fr; }
/* The trailing row's margin stacks on top of the band's own bottom padding,
   which on a page that ends several sections on a row reads as a dropout. */
.wm-wrap > .ver-row:last-child, .wm-wrap > .ver-hero:last-child { margin-bottom: 0; }
.ver-row--flip .ver-row__copy  { order: 2; }
.ver-row--flip .ver-row__media { order: 1; }

/* Clearance after a callout tile.

   .wm-callout carries a top margin but no bottom one, and .ver-row has no top
   margin, so a row following a callout started about 12px under its border —
   the heading and the image both landing hard against the tile. Space only, no
   rule: the tile already has a border of its own, and a hairline directly below
   it reads as a doubled line. Contrast .ver-row--sub below, which separates two
   sub-topics that have no edge between them and does want the rule. */
.wm-callout + .ver-row,
.wm-callout + .ver-prose { margin-top: 56px; }
@media (max-width: 900px) {
  .wm-callout + .ver-row,
  .wm-callout + .ver-prose { margin-top: 40px; }
}

/* A SECOND sub-topic inside one band, under its own h3.

   The water half of the weathering band was running straight on from the
   thermal bullets above it with only a paragraph gap. That is not enough: the
   row opens with an h3 AND a media column, so the image top-aligns with the
   heading and lands hard against the list above. A paragraph break says "next
   paragraph"; this needs to say "next subject".

   Rule plus space rather than space alone. Two h3s in one band are otherwise
   indistinguishable from an h3 and a long list, and the band's own heading
   ("Weathering and water") names two subjects without saying where one ends.
   The alternative was a separate band per subject, which is cleaner but adds a
   band and so inverts the deep/mid parity of every section below it. */
.ver-row--sub {
  margin-top: 54px;
  padding-top: 44px;
  border-top: 1px solid var(--wm-earth-700);
}
@media (max-width: 900px) { .ver-row--sub { margin-top: 40px; padding-top: 34px; } }

/* A PORTRAIT screenshot beside body copy.

   content/dragontail/ParameterRail.jpg is 376x1080 — a vertical strip of the
   parameter panel, about 1:2.9. The standard .ver-row media column is roughly
   640px wide, so wm_media_cap() would have had to shrink the image to a 167px
   thumbnail to keep its height inside the 480px budget. Sizing the COLUMN to
   the strip instead lets the image stay legible and gives the copy the rest of
   the band, so this row takes no wm_media_cap() call at all.

   The copy then needs its own measure: against a 240px media column the text
   would otherwise run the best part of 1200px, well past a readable line. Every
   other row on these pages gets its measure from a roughly even two-column
   split; this one has to ask, the same way .ver-prose does.

   A 1:2.9 strip is also taller than any single paragraph beside it, so the
   whole section goes in the copy column — heading, cards and all — rather than
   one sub-topic. Two earlier tries were worse: top-aligned against one short
   paragraph the row left a 500px void under the text, and centring it to
   absorb that void stranded the h3 halfway down the band with nothing above
   it. Give the column enough content and neither happens. */
.ver-row--rail { grid-template-columns: minmax(0, 1fr) 240px; }
.ver-row--rail .wm-head,
.ver-row--rail .ver-prose > * { max-width: 78ch; }
/* Same rule-plus-space as .ver-row--sub, but between two blocks inside one
   column rather than between two rows. */
.ver-row--rail .ver-cards + .ver-prose {
  margin-top: 40px;
  padding-top: 34px;
  border-top: 1px solid var(--wm-earth-700);
}

/* Section headings in a narrow column wrap badly: "Drawing what you want where
   you want / it" and "Four macros that do the texturing for / you" both dropped
   a single word onto line two. balance evens the lines instead. Headings only —
   it is capped at a few lines in browsers and is wrong for body copy. */
.ver-row__copy .wm-h2, .ver-hero__copy .wm-h2,
.ver-row__copy .wm-h3, .ver-card__h, .ver-grant__h { text-wrap: balance; }

.ver-hero__copy p, .ver-row__copy p { color: var(--wm-earth-200); font-size: 16px; line-height: 1.6; }
.ver-hero__copy .wm-lede, .ver-row__copy .wm-lede { margin-bottom: 18px; }
.ver-row__copy .wm-h3 { margin-top: 30px; }
.ver-row__copy .wm-h3:first-child { margin-top: 0; }

.ver-points li { margin-bottom: 12px; font-size: 16px; line-height: 1.6; }
.ver-points b { color: var(--wm-earth-50); }

/* Body copy in a full-width band, where there is no .ver-row__copy wrapper to
   inherit the reading colour and size from. */
.ver-body { color: var(--wm-earth-200); font-size: 16px; line-height: 1.6; }

/* Measure for a band with no media column beside it.

   .wm-wrap--tight is NOT this: it trims a band's VERTICAL padding and leaves
   the width alone, so a text-only section still ran the full 1536px content
   width — around 190 characters a line on a desktop display. Every other
   section on these pages gets its measure for free by sitting in a two-column
   row; the full-width ones have to ask. */
.ver-prose > * { max-width: 84ch; }
.ver-prose > .wm-h2 { max-width: none; }

.ver-shot { margin: 0; }
.ver-shot img { width: 100%; height: auto; border-radius: 12px; border: 1px solid var(--wm-earth-700); }
.ver-shot figcaption { margin-top: 10px; font-size: 14px; color: var(--wm-earth-300); }
/* A figure that stands on its own under a card grid rather than beside copy.
   wm_media_cap() already caps its width; this only supplies the top margin and
   centres the caption under it. */
.ver-shot--wide { margin-top: 30px; }
.ver-shot--wide figcaption { text-align: center; }

/* A panoramic figure carrying a band, set between a standfirst and the detail
   below it. Distinct from --wide, which trails a card grid: the caption stays
   left-aligned and measured, because it is a sentence explaining the image
   rather than a label under it.

   The top margin is smaller than the bottom on purpose. The figure belongs to
   the paragraph above it — that paragraph is what tells the reader what they
   are looking at — and the larger gap below separates it from the detail that
   follows.

   Use for sources wider than about 2:1. Anything squarer belongs in a media
   column beside the copy: full width, a 1.5:1 image is over 1000px tall and
   pushes the section it illustrates off the screen. */
.ver-shot--lead { margin: 26px 0 40px; }
.ver-shot--lead figcaption { max-width: 84ch; }

/* Even up a wm_image_pair() whose two sources have different aspect ratios.

   .wm-pair sizes each image by its own ratio, which is right when the pair was
   shot as a pair. The Hurricane Ridge erosion images are 1.54:1 and 1.34:1, so
   at ~760px they differ by about 70px of height: the captions sit at different
   heights and the shorter tile stretches to the row, leaving a dead strip below
   its caption. Cropping a little off a terrain render costs nothing; a ragged
   pair looks like a mistake.

   Wrap the wm_image_pair() call in this class. Do NOT reach for it on a matched
   pair — the crop is a real loss when there is nothing to fix. */
.ver-pair-even .wm-pair__item img { aspect-ratio: 3 / 2; object-fit: cover; }

/* A video in a row's media column, where a .ver-shot figure would otherwise be.
   The column sets the width; .wm-embed holds the 16:9 box. */
.ver-video { margin: 0; }
/* A self-hosted clip standing on its own between two blocks of a band (the
   VDM walk-through under the Dragontail hero). Full content width: the clip
   is a 2520px-wide UI capture, so at any page width it is being scaled DOWN
   and every pixel of column helps legibility. (It was capped at 1280px while
   the source was 1280px, to stop it upscaling.) The markup sets the embed's
   aspect-ratio inline to the clip's own 2520/1080, overriding .wm-embed's
   16:9, so the box fits the frame rather than letterboxing it. Same clearance
   below as a row, so the callout after it does not land on the caption. */
.ver-video--lead { margin: 0 0 40px; }
.ver-video figcaption {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--wm-earth-300);
}

/* An honest limitation set inside a run of claims: quieter than the sentences
   around it, and marked so a skimmer doesn't read it as another feature. */
.ver-caveat {
  margin-top: 20px;
  padding-left: 14px;
  border-left: 2px solid var(--wm-earth-600);
  font-size: 15px;
  color: var(--wm-earth-300) !important;
}

/* A closing note under a band: the dated or qualifying detail that belongs with
   the section but would weaken its opening paragraph. */
.ver-plat__note {
  max-width: 76ch;
  margin: 26px 0 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--wm-earth-300);
}

/* ---- Card grid for the shorter points ---- */
.ver-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
}
.ver-card { padding: 26px; }
.ver-card__h {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 20px;
  color: var(--wm-earth-50);
  margin: 0 0 10px;
}
.ver-card p { color: var(--wm-earth-200); font-size: 15px; line-height: 1.6; margin: 0; }
/* Four cards in the default auto-fit grid lay out as three plus an orphan at
   desktop widths, which reads as a card that failed to load. --pairs pins the
   grid to two columns so an even count stays even. Use it for 4 (or 6) cards;
   leave 3, 5 and 9 on the default grid, which fits them without a gap. */
.ver-cards--pairs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) { .ver-cards--pairs { grid-template-columns: 1fr; } }
/* An in-flight qualifier inside a card: present, quieter than the claim. */
.ver-card__caveat { display: block; margin-top: 8px; color: var(--wm-earth-300); font-size: 14px; }

/* A callout head carrying more than one paragraph.

   .wm-callout__head p is margin: 0 in wm-dark.css, which is right for the
   single-paragraph case it was written for. The disclosure callout in the
   saving section holds two — the licence and the usage-data note — and without
   this they butt together as one block of text. Kept page-local for now;
   promote it to wm-dark.css if a second page needs it. */
.wm-callout__head p + p { margin-top: 12px; }

/* Same problem one level up: .wm-callout__foot is margin: 0 because it normally
   follows .wm-callout__list, which brings its own bottom margin. The
   compatibility callout in the platforms band has no list between the two, so
   the foot lands directly against the head. */
.wm-callout__head + .wm-callout__foot { margin-top: 14px; }

/* ---- Roadmap ----
   Gold-edged because "not finished yet" is information the reader needs, not
   fine print to be buried. */
.ver-roadmap { border-color: var(--wm-earth-600); margin-top: 0; }
.ver-roadmap .wm-callout__h { color: var(--wm-sand-gold); }

/* ---- Entitlement strip ----
   "You may already own this release", directly under the page head on
   /version/hurricane-ridge.

   It was a wm-callout tile at the foot of the page and moved to the top, where
   a tile was the wrong shape: full-width, same border and padding as the
   feature callouts further down, it read as the page's first SECTION and put a
   licensing footnote ahead of the release it is about.

   So: a tinted strip rather than a tile. No border of any kind, band padding
   cut to about a third. It sits close enough to the title to belong to it, and
   a reader scanning for the sales copy scrolls past it in one movement instead
   of reading a card.

   The wash and the gold heading carry it on their own — an earlier version had
   a gold rule down the leading edge as well, which Stephen cut. Don't put it
   back. */
.ver-grantband > .wm-wrap { padding-top: 0; padding-bottom: 34px; }
/* .wm-pagehead + .wm-band sets a 48px top pad for the section that normally
   follows the head. This strip is head furniture and overrides it above, but
   the real first section now follows THIS band, so restore the rule for it. */
.ver-grantband + .wm-band > .wm-wrap { padding-top: 48px; }

/* On the legacy page the grant panel closes the Hurricane band, directly after
   the "rest of that release" callout tile. The tile carries no bottom margin
   and the panel no top one, so without this they touch. */
.wm-callout + .ver-grant { margin-top: 28px; }
.ver-grant {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 20px 40px;
  align-items: center;
  padding: 22px 26px;
  border-radius: 4px;
  background: rgba(201,167,90,0.09);
}
.ver-grant__h {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 21px;
  color: var(--wm-sand-gold);
  margin: 0 0 8px;
}
.ver-grant__copy p { color: var(--wm-earth-200); font-size: 15px; line-height: 1.6; margin: 0; max-width: 74ch; }
.ver-grant__action { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.ver-grant__note { font-size: 13px; color: var(--wm-earth-400); margin: 0; text-align: center; }

@media (max-width: 820px) {
  /* The action stops being a column and becomes the line after the copy. */
  .ver-grant { grid-template-columns: 1fr; gap: 18px; }
  .ver-grant__action { align-items: flex-start; }
  .ver-grant__note { text-align: left; }
}

/* Two callouts that admit something rather than sell it: the analytics
   disclosure on Dragontail, and the erosion re-parameterisation on Hurricane
   Ridge. Deliberately NOT gold — gold means "read this, it's good news", and
   borrowing it for a confession would be the wrong kind of loud. They keep the
   default tile border and take a heading in ordinary text colour. */
.ver-privacy, .ver-reparam { margin-top: 30px; }
.ver-privacy .wm-callout__h, .ver-reparam .wm-callout__h { color: var(--wm-earth-50); }

/* ---- Closing band ----
   The rule at the top is not decoration. Series pages alternate deep/mid down
   the page, and this band is emitted by a shared helper that cannot know what
   colour the section above it ended on — remove one content section and the
   parity flips, putting two --mid bands against each other with no seam. That
   happened: /version/hurricane-ridge briefly ran 1,900px of unbroken --mid
   because the deep band that used to sit here was folded into this one. The
   page's own alternation is fixed, and the rule means the next edit that
   changes the section count cannot reintroduce it.

   .ver-foot__lead is the optional page-specific sentence above the buy block
   (ver_series_foot's $lead). It carries NO rule of its own: with the band rule
   above it, a second hairline 60px lower read as two dividers arguing. Spacing
   separates it from the CTA instead. */
/* Bracketed top AND bottom. The site footer already carries a border-top, but
   at --wm-divider (#23272F) against --wm-band-mid (#161A22) it is nearly
   invisible, so the band read as fading into the footer rather than ending.
   --wm-earth-600 is two steps lighter and actually draws. */
.ver-foot-band {
  border-top: 1px solid var(--wm-divider);
  border-bottom: 1px solid var(--wm-earth-600);
}

.ver-foot__lead {
  color: var(--wm-earth-200);
  font-size: 16px;
  line-height: 1.6;
  max-width: 80ch;
  margin: 0 0 40px;
}

.ver-foot { display: grid; grid-template-columns: 1.4fr 1fr; gap: 40px; align-items: center; }
.ver-foot__copy .wm-lede { margin-top: 14px; }
.ver-foot__note { margin-top: 12px; font-size: 15px; color: var(--wm-earth-300); }
.ver-foot__actions { display: flex; flex-direction: column; gap: 12px; }

@media (max-width: 900px) {
  .ver-hero, .ver-row { grid-template-columns: 1fr; gap: 28px; margin-bottom: 32px; }
  /* Source order wins on one column: the copy introduces the picture. */
  .ver-row--flip .ver-row__copy, .ver-row--flip .ver-row__media { order: 0; }
  .ver-foot { grid-template-columns: 1fr; gap: 24px; }
  .ver-hub__item { grid-template-columns: 1fr; gap: 18px; }
  .ver-hub__shot img { max-height: 180px; }
}

/* ---- Platform band ----
   Cross-platform is a marquee feature of Dragontail Peak, so it gets a band
   near the top rather than a card among the technical detail. Three equal
   tiles, one per platform: the point is that all three are first-class, and
   equal weight is what says so. */
.ver-plat__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
}
.ver-plat__item { padding: 26px; }
.ver-plat__h {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 22px;
  color: var(--wm-sand-gold);
  margin: 0 0 10px;
}
.ver-plat__item p { color: var(--wm-earth-200); font-size: 15px; line-height: 1.6; margin: 0; }
.ver-plat .wm-lede { max-width: 76ch; margin-top: 14px; }


/* ============================================================================
   Roadmap page (rmp-)
   ============================================================================ */

.rmp-lede { max-width: 72ch; margin-top: 14px; }
/* Freshness, stated plainly. Quiet, but a reader looking for it finds it. */
.rmp-reviewed { margin: 18px 0 0; font-size: 14px; color: var(--wm-earth-400); }
.rmp-more { margin-top: 26px; font-size: 15px; color: var(--wm-earth-300); }

.rmp-inflight { max-width: 82ch; }
.rmp-inflight li { margin-bottom: 12px; font-size: 16px; line-height: 1.6; }

/* ---- Planned: cards, because each one carries a sentence of its own ---- */
.rmp-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}
/* Count-aware columns for the upcoming band. auto-fit lays out however many
   280px columns fit, without knowing how many cards there are, so four cards
   went 3+1 between about 1000px and 1340px and three went 2+1 between about
   660px and 1000px — one card orphaned on a row of its own. The view emits
   --n2/--n3/--n4 from count(), and each count only ever uses a divisor of
   itself: 4 -> 2 -> 1, 3 -> 1, 2 -> 1.

   Breakpoints derive from the 280px minimum, the 20px gap and the fluid
   gutter (clamp(24px, 6vw, 80px) each side): four columns need 1180px of
   content, which is a ~1340px viewport; three need 880px, ~1000px; two need
   580px, ~660px. Re-derive if the card minimum or the gutter changes. */
.rmp-cards--n2 { grid-template-columns: repeat(2, 1fr); }
.rmp-cards--n3 { grid-template-columns: repeat(3, 1fr); }
.rmp-cards--n4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1339px) { .rmp-cards--n4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 999px)  { .rmp-cards--n3 { grid-template-columns: 1fr; } }
@media (max-width: 659px)  { .rmp-cards--n2, .rmp-cards--n4 { grid-template-columns: 1fr; } }
.rmp-card { padding: 24px; }
.rmp-card__h {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 19px;
  color: var(--wm-earth-50);
  margin: 0 0 10px;
}
.rmp-card p { color: var(--wm-earth-200); font-size: 15px; line-height: 1.6; margin: 0; }

/* ---- The feature board: one ranked list, accepted requests badged ----
   Deliberately plainer than a card grid. Planned and merely-wanted sit together
   so the reader can see requests moving from one to the other; the badge is the
   only thing separating them, which is what makes voting look worth doing. */
.rmp-board {
  list-style: none;
  margin: 0 0 30px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 0 40px;
}
.rmp-board__row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid var(--wm-earth-700);
}
.rmp-board__row:last-child { border-bottom: 0; }
.rmp-board__votes {
  font-family: var(--wm-font-mono);
  font-size: 15px;
  color: var(--wm-earth-400);
  min-width: 3ch;
  text-align: right;
  flex-shrink: 0;
}
.rmp-board__name { color: var(--wm-earth-200); font-size: 16px; }
/* An accepted request reads brighter across the whole row, not just the badge —
   otherwise the badge is a decoration rather than a status. */
.rmp-board__row--planned .rmp-board__votes { color: var(--wm-sand-gold); }
.rmp-board__row--planned .rmp-board__name { color: var(--wm-earth-50); }
.rmp-board__badge {
  flex-shrink: 0;
  margin-left: auto;
  font-family: var(--wm-font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wm-sand-gold);
  border: 1px solid rgba(201,167,90,0.45);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

/* ---- Take part ---- */
.rmp-parts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px;
}
.rmp-part { padding: 28px; display: flex; flex-direction: column; }
.rmp-part__h {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 20px;
  color: var(--wm-earth-50);
  margin: 0 0 12px;
}
.rmp-part p { color: var(--wm-earth-200); font-size: 15px; line-height: 1.6; flex: 1 1 auto; margin: 0 0 20px; }

/* Closing line: the way out for someone whose build predates everything above.
   It lives at the page foot rather than beside the recent releases — up there it
   offered an exit before the reader had seen any roadmap. */
.rmp-foot { margin: 0; font-size: 15px; color: var(--wm-earth-300); }


/* ============================================================================
   Legacy / "come back" page (upg-)   — /version/legacy

   Merged in from the standalone css/upgrade-dark.css when the page moved under
   /version. That filename collided with reference/update/upgrade-dark.css, an
   unrelated Update Center stylesheet, which is half the reason the page moved.
   ============================================================================ */

.upg-lede { max-width: 76ch; margin-bottom: 32px; }

/* ---- Release-series timeline ----
   Three cards, oldest first, so the reader can place their own build before
   reading anything else. The current series is marked in gold rather than by
   position, because position alone doesn't say which end is now. */
.upg-series {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
}
/* The <li> is only the grid cell now; the tile inside it is either an <a>
   (release with a page) or a <div> (the reader's own vintage). Stretching the
   tile keeps the row even whichever it is. */
.upg-series__cell { display: flex; }
.upg-series__item { padding: 22px 24px; flex: 1 1 auto; }
.upg-series__name { padding-right: 26px; }   /* clear of the corner arrow */
.upg-series__item--now { border-color: var(--wm-sand-gold); }
.upg-series__when {
  font-family: var(--wm-font-display);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wm-earth-400);
  margin: 0 0 6px;
}
.upg-series__item--now .upg-series__when { color: var(--wm-sand-gold); }
.upg-series__name {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 24px;
  color: var(--wm-earth-50);
  margin: 0 0 4px;
}
.upg-series__builds {
  font-family: var(--wm-font-mono);
  font-size: 13px;
  color: var(--wm-earth-300);
  margin: 0 0 12px;
}
.upg-series__note { font-size: 15px; color: var(--wm-earth-200); margin: 0; }
.wm-page a.upg-series__item:hover { border-color: var(--wm-sand-gold); }

/* ---- Copy beside media ----
   Text column first by default; --flip puts the media on the left so two
   consecutive rows don't stack into one wall of text on the same side. Both
   collapse to copy-then-media on narrow screens, which keeps the reading order
   the same as the source order. */
.upg-split {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 44px;
  align-items: start;
  margin-bottom: 40px;
}
.upg-split--flip .upg-split__copy { order: 2; }
.upg-split--flip .upg-split__media { order: 1; }
.upg-split__copy .wm-lede { margin-bottom: 18px; }
.upg-split__copy .wm-h3 { margin-top: 28px; }
.upg-split__copy .wm-h3:first-child { margin-top: 0; }
.upg-split__copy p { color: var(--wm-earth-200); font-size: 16px; line-height: 1.6; }

.upg-points li { margin-bottom: 12px; font-size: 16px; line-height: 1.6; }
.upg-points b { color: var(--wm-earth-50); }

/* An honest caveat, set quieter than the claims above it but not hidden. */
.upg-caveat {
  margin-top: 20px;
  padding-left: 14px;
  border-left: 2px solid var(--wm-earth-600);
  font-size: 15px;
  color: var(--wm-earth-300) !important;
}

/* The platform tiles on the legacy page reuse .ver-plat__row/__item from the
   Dragontail band; this wrapper only supplies the heading measure and the
   clearance to the next block, which the tile grid does not carry itself. */
.upg-plat { margin: 0 0 44px; }
.upg-plat__lede { max-width: 76ch; color: var(--wm-earth-200); font-size: 16px; line-height: 1.6; margin: 0 0 22px; }
.upg-shot { margin: 0; }
.upg-shot img { width: 100%; height: auto; border-radius: 12px; border: 1px solid var(--wm-earth-700); }
.upg-shot figcaption { margin-top: 10px; font-size: 14px; color: var(--wm-earth-300); }

/* ---- The three catch-up paths ----
   Equal-height cards with the button pinned to the bottom, so three answers of
   different lengths still present one row of actions rather than a ragged one. */
.upg-paths {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin-top: 32px;
}
.upg-path { padding: 28px; display: flex; flex-direction: column; }
.upg-path__h {
  font-family: var(--wm-font-display);
  font-weight: 700;
  font-size: 21px;
  color: var(--wm-earth-50);
  margin: 0 0 12px;
}
.upg-path p { color: var(--wm-earth-200); font-size: 15px; line-height: 1.6; }
.upg-path > p:first-of-type { flex: 1 1 auto; margin-bottom: 20px; }
.upg-path__alt { margin: 12px 0 0; font-size: 14px; text-align: center; }

.upg-lostkey { margin-top: 28px; font-size: 15px; color: var(--wm-earth-300); }

.upg-compat { margin-top: 0; }

@media (max-width: 900px) {
  .upg-split { grid-template-columns: 1fr; gap: 28px; margin-bottom: 32px; }
  /* Source order wins on one column: the copy introduces the picture. */
  .upg-split--flip .upg-split__copy,
  .upg-split--flip .upg-split__media { order: 0; }
}

/* Sub-headings inside the in-progress band: "Landed recently" / "Still to come".
   The two lists are the same shape, so without a label a reader cannot tell
   which items are done from which are promised — the one distinction that band
   exists to make. */
.rmp-subhead { margin: 0 0 12px; }
.rmp-subhead + .rmp-inflight { margin-bottom: 30px; }
