/* ============================================================
   AXL's Game Lab — the SHARED DESIGN SYSTEM.

   This is the generic half of the approved Episode 001 design: the primitives
   (card, heading, icon row, tile, button, field) and the "core bridge" that makes
   them work with core-block markup. Nothing in here is about episodes.

   SCOPE — every rule is prefixed `:is(.axl-ui, .axl-episode)`:

     .axl-ui       the scope for all NEW work. Put it on the outermost group of a
                   section pattern and the section is styled anywhere it lands —
                   a Page, an archive, another CPT.
     .axl-episode  the original scope, kept as an alias so every episode and crew
                   page (and every post already saved with it) keeps working with
                   no migration. `:is()` takes the specificity of one class, so the
                   alias costs nothing.

   The scope is mandatory, not tidiness: this file is also loaded as an editor
   style (functions.php), where styles are global, and generic-class rules like
   .card / .btn / .badge would otherwise leak over the whole admin canvas.

   Episode-only sections (mission log, discoveries, teaser, hero) live in
   episode.css, which loads after this file. Crew-only additions live in crew.css.
   ============================================================ */

/* ============================================================
   1. RESET
   ============================================================ */

/* Scoped reset so Bootstrap Reboot margins don't shift the pixel layout. */
:is(.axl-ui, .axl-episode) { font-size: 15px; line-height: 1.45; color: #1A2547; }
:is(.axl-ui, .axl-episode) * { box-sizing: border-box; margin: 0; }
:is(.axl-ui, .axl-episode) img { display: block; max-width: 100%; }

/* --- core-block reset ---------------------------------------------------------
   These neutralise wp-block-library defaults and MUST stay above the design
   rules: they share the same specificity, so anything below overrides them. Put
   a core-block reset here; put anything that styles the design below. */

/* This theme is classic (no theme.json), so WordPress restores the legacy
   .wp-block-group__inner-container wrapper inside every core/group on the FRONT
   END (wp_restore_group_inner_container()) — the editor renders children
   directly. Without this, every flex/grid card would collapse to a single child. */
/* Both forms again: on a composed page the ROOT group carries the scope class
   itself, so its own inner container has no `.axl-ui` ancestor and a descendant
   selector skips exactly the one container that matters — leaving the root's
   children wrapped in a single block box, which is what silently defeats a flex
   `.stack` gap between sections. */
:is(.axl-ui, .axl-episode).wp-block-group > .wp-block-group__inner-container,
:is(.axl-ui, .axl-episode) .wp-block-group > .wp-block-group__inner-container { display: contents; }

/* In the EDITOR, classic.min.css centres every block inside a flow container with
   `margin-left/right: auto`. Its selector is the same weight as the `*` reset, so
   that reset does not reliably win, and card headings, lists and tile captions
   float to the middle of the canvas while the front end has them flush left. This
   is one class heavier. Every block in the canvas carries .wp-block, including
   list items — which are flex items here, so auto margins centre them one by one.
   It sits in the reset block on purpose: `.stamp` genuinely wants
   `margin: 16px auto`, and its design rule in episode.css re-applies that. */
:is(.axl-ui, .axl-episode) .wp-block,
:is(.axl-ui, .axl-episode) .block-editor-block-list__block { margin-left: 0; margin-right: 0; }

/* Core's own margins are single-class, so they need beating with two. */
:is(.axl-ui, .axl-episode) .wp-block-group,
:is(.axl-ui, .axl-episode) .wp-block-columns,
:is(.axl-ui, .axl-episode) .wp-block-column,
:is(.axl-ui, .axl-episode) .wp-block-buttons,
:is(.axl-ui, .axl-episode) .wp-block-list,
:is(.axl-ui, .axl-episode) .wp-block-table,
:is(.axl-ui, .axl-episode) .wp-block-image,
:is(.axl-ui, .axl-episode) figure { margin: 0; }

/* NB: core prints `.wp-block-columns { align-items: normal !important }` inline, so
   align-items on a columns block cannot be overridden from here at all. For grids
   `normal` behaves as stretch, which is what the card rows want anyway; where the
   design needs "start" (the page layout), set align-self on the column instead —
   a different property, so no !important arms race. See .layout below. */

/* Equal-height columns.
   A columns block here always defines a layout row, so its columns stretch to the
   tallest one. Two things are needed that a plain columns block does not give you:
   the column must stretch (core's `align-items: normal !important` on the columns
   block leaves this to the item), and the card INSIDE the column must fill it —
   core/columns puts a .wp-block-column between the grid and the card, so without
   this the card is only as tall as its own content.
   :only-child matters: it means "this card IS the column's content", which is the
   card-per-cell rows. A column holding a STACK of cards must not stretch the first
   of them, or it pushes the rest out of the page. */
:is(.axl-ui, .axl-episode) .wp-block-columns > .wp-block-column { align-self: stretch; }
:is(.axl-ui, .axl-episode) .wp-block-columns > .wp-block-column > .card:only-child { height: 100%; }

/* ============================================================
   2. PRIMITIVES
   ============================================================ */

:is(.axl-ui, .axl-episode) .card { background: #fff; border: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 16px; padding: 19px; }
/* The larger card radius used by full-width feature panels. */
:is(.axl-ui, .axl-episode) .card--lg { border-radius: 20px; }
/* A card with no chrome — for sections that want the padding but not the box. */
:is(.axl-ui, .axl-episode) .card--plain { background: none; border: 0; padding: 0; }
:is(.axl-ui, .axl-episode) .card--tint { background: #F3F4F8; border-color: transparent; }

/* Content an editor adds inside a card flows on its own bottom margin.
   The scope's `*` reset (section 1) zeroes every margin, so a card that isn't
   built from a gapped container had two paragraphs sitting flush against each
   other — this is the declared spacing that replaces what the reset took.

   `.card--flow` is excluded on purpose: it spaces its children with a `gap`, and
   a margin on top of that would double every gap in the rusty-style cards.

   BOTH SELECTOR FORMS, for the reason spelled out in section 1: on the FRONT END
   WordPress wraps a core/group's children back up in
   `.wp-block-group__inner-container` (the editor renders them directly), so a
   bare `>` would match in the canvas and silently miss on the published page.
   `display: contents` makes the wrapper invisible to layout but NOT to selectors.

   The list is block-level CONTENT only. Placed here among the primitives so the
   design rules further down (`.card .cover`'s negative bleed, the `.cardgrid`
   rules) still win on source order at equal specificity. */
:is(.axl-ui, .axl-episode) .card:not(.card--flow) > :is(p, h1, h2, h3, h4, h5, h6, blockquote, table, pre),
:is(.axl-ui, .axl-episode) .card:not(.card--flow) > .wp-block-group__inner-container > :is(p, h1, h2, h3, h4, h5, h6, blockquote, table, pre) { margin-bottom: 14px; }

/* …except immediately before a component that already declares its own top
   margin. `.dotlist`, `.btn-row` and the icon rows all space themselves, and a
   `.cardgrid` card is a FLEX column — where margins do not collapse — so
   leaving both would double the gap rather than set it (measured: a paragraph
   above a `.dotlist` went 14px -> 28px). Dropping this side keeps each
   component's own value authoritative, which is where that number is designed.
   In a plain block-flow card the two would have collapsed to the same 14px
   anyway, so nothing moves there either. */
:is(.axl-ui, .axl-episode) .card:not(.card--flow) > :has(+ :is(.dotlist, .btn-row, .iconrow, .checkrow, .themerow, .linklist, .tiles, .center, .hr, .fld, .aside, .cover, .tabs)),
:is(.axl-ui, .axl-episode) .card:not(.card--flow) > .wp-block-group__inner-container > :has(+ :is(.dotlist, .btn-row, .iconrow, .checkrow, .themerow, .linklist, .tiles, .center, .hr, .fld, .aside, .cover, .tabs)) { margin-bottom: 0; }
/* The last thing in a card never adds to the card's own padding. */
:is(.axl-ui, .axl-episode) .card:not(.card--flow) > :last-child,
:is(.axl-ui, .axl-episode) .card:not(.card--flow) > .wp-block-group__inner-container > :last-child { margin-bottom: 0; }

:is(.axl-ui, .axl-episode) .grid2 { display: grid; grid-template-columns: 1fr; gap: 18px; }
:is(.axl-ui, .axl-episode) .center { display: flex; justify-content: center; margin-top: 22px; }
:is(.axl-ui, .axl-episode) .ic { flex: none; }
:is(.axl-ui, .axl-episode) .hide { display: none !important; }
/* The same hairline a card draws around itself, so a divider inside one reads as
   part of the same system — and follows the accent line where a section tints it. */
:is(.axl-ui, .axl-episode) .hr { border: 0; border-top: 1px solid var(--axl-accent-line, #E3E7F0); opacity: 1; margin: 20px 0; }
:is(.axl-ui, .axl-episode) .vdiv { display: block; width: 1px; align-self: stretch; background: #EAEDF3; flex: none; }

/* type */
:is(.axl-ui, .axl-episode) .h1 { font-size: 33px; font-weight: 800; letter-spacing: -.01em; color: #151D40; margin: 16px 0 14px; text-wrap: balance; }
/* The hero cap, as a modifier. `.introsplit__copy .h1` has always uppercased the
   heading inside a split hero; the Contact banner is a centred card with no split,
   and this is that same rule made reachable from outside one. */
:is(.axl-ui, .axl-episode) .h1--up { text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .h2 { font-size: 26px; font-weight: 800; letter-spacing: -.01em; color: #151D40; text-wrap: balance; margin-top: 10px; }
/* The step below .h2 — a title for one thing inside a section (a video, a panel),
   sized just above the tracked-caps heading rather than competing with it. */
:is(.axl-ui, .axl-episode) .h3 { font-size: 18px; font-weight: 700; letter-spacing: -.01em; color: #151D40; margin-top: 14px; }
/* The scoped reset zeroes every margin, so flow spacing is declared, never
   inherited. Only .h2/.h3 are listed: .h1 already carries its own bottom margin
   and adding to it would move the banner and hero. */
:is(.axl-ui, .axl-episode) :is(.h2, .h3) + p { margin-top: 16px; }
/* Body copy at reading size. The scope's base is 15px, which is right for card
   furniture — labels, rows, tile captions — but tight for a paragraph someone is
   expected to actually read. Anything that is prose rather than UI takes this. */
:is(.axl-ui, .axl-episode) .prose { font-size: 16px; line-height: 1.7; }
:is(.axl-ui, .axl-episode) .prose + .prose { margin-top: 12px; }
/* A muted line under a figure or media block. The episode has .vidcap and .cap
   for the same job, but both are episode-only. */
:is(.axl-ui, .axl-episode) .caption { margin-top: 8px; color: #6B7484; font-size: 13px; line-height: 1.6; }
:is(.axl-ui, .axl-episode) .lede { font-size: 15.5px; color: #333D5C; line-height: 1.7; max-width: 56ch; }
:is(.axl-ui, .axl-episode) .badge { display: inline-block; border: 1px solid #9DB4E8; border-radius: 8px; color: #1245C4; font-weight: 700; font-size: 14px; letter-spacing: .05em; padding: 8px 15px; background: #fff; }
:is(.axl-ui, .axl-episode) .pill { background: #ECEDF2; border-radius: 99px; font-size: 9px; font-weight: 700; letter-spacing: .05em; padding: 5px 11px; white-space: nowrap; }
:is(.axl-ui, .axl-episode) .crumbs { display: flex; gap: 9px; align-items: center; color: #6B7484; font-size: 13px; margin-bottom: 20px; flex-wrap: wrap; }

/* The design's own button, for hand-written markup (legacy partials, forms).
   Core/button markup uses .axl-btn below — same shape, different element. */
:is(.axl-ui, .axl-episode) .btn { display: inline-flex; align-items: center; justify-content: center; gap: 9px; border: 1px solid #1245C4; border-radius: 8px; color: #fff; font-weight: 700; font-size: 13px; letter-spacing: .04em; padding: 11px 26px; background: #1245C4; white-space: nowrap; cursor: pointer; }
:is(.axl-ui, .axl-episode) .btn--sm { font-size: 12px; padding: 10px 24px; }
/* Hover / focus / press darken the blue a step at a time — the same states
   as .axl-btn below. The solid colour buttons carry their own fills. */
:is(.axl-ui, .axl-episode) .btn:not(.btn-orange, .btn-green, .btn-red, .btn-cyan):is(:hover, :focus-visible) { background: #0f3aa8; border-color: #0f3aa8; }
:is(.axl-ui, .axl-episode) .btn:not(.btn-orange, .btn-green, .btn-red, .btn-cyan):active { background: #0d3396; border-color: #0d3396; }
/* Keep the blue label when pressed — Bootstrap's :active would otherwise swap in
   .btn-primary's white ink. The outline colours keep their own label colour. */
:is(.axl-ui, .axl-episode) .btn:not(.btn-orange, .btn-green, .btn-red, .btn-cyan, .btn-outline-orange, .btn-outline-green, .btn-outline-red, .btn-outline-cyan):active { color: #fff; }

/* ============================================================
   3. PAGE LAYOUT — main + sidebar
   ============================================================ */

:is(.axl-ui, .axl-episode) .layout { display: block; }
:is(.axl-ui, .axl-episode) .aside { display: grid; grid-template-columns: 1fr; gap: 18px; margin-top: 18px; }
/* A stretched column must not stretch the stack of cards inside it: the sidebar's
   cards keep their natural heights and pack to the top of the column. */
:is(.axl-ui, .axl-episode) .aside { align-content: start; }

/* ---- .layout--nav-left — the legal pages' shape --------------------------
   The sidebar is an "On This Page" nav (axl/page-nav) on the LEFT that sticks
   as the policy scrolls past. The markup stays main → aside, so screen readers
   meet the content first; only the visual order changes.
   Below 1080px the nav comes first, as a single card above the content (a
   sticky list would cover the text on a phone), and does not stick. The extra
   `.layout` in each selector out-ranks the base .layout / .aside rules and
   their 640px and 1080px media overrides without depending on file order. */
:is(.axl-ui, .axl-episode) .layout.layout--nav-left { display: flex; flex-direction: column; gap: 18px; }
:is(.axl-ui, .axl-episode) .layout.layout--nav-left > .aside { order: -1; grid-template-columns: 1fr; margin-top: 0; }

@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .layout.layout--nav-left { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 30px; }
  :is(.axl-ui, .axl-episode) .layout.layout--nav-left > .main { grid-column: 2; grid-row: 1; }
  /* Sticky only for a nav that fits the screen (see .is-sticky below); a taller
     one sits at the top of its column and scrolls away with the page. */
  :is(.axl-ui, .axl-episode) .layout.layout--nav-left > .aside {
    grid-column: 1;
    grid-row: 1;
    align-self: start;
  }
  /* site.js adds .is-sticky only when the nav fits the screen. */
  :is(.axl-ui, .axl-episode) .layout.layout--nav-left > .aside.is-sticky { position: sticky; top: 24px; }
}

/* Smooth-scroll to a section — only on a page that has the nav, and never for
   anyone who has asked for reduced motion. The headings stop short of the top
   edge so they are not flush against it. */
html:has(.pagenav) { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html:has(.pagenav) { scroll-behavior: auto; }
}
:is(.axl-ui, .axl-episode) :is(h2, h3)[id] { scroll-margin-top: 24px; }

/* The nav card (axl/page-nav). A <details>, so it folds away on a phone; from
   1080px it is always open and the summary is only its title. */
:is(.axl-ui, .axl-episode) .pagenav { padding: 14px 10px 10px; }
:is(.axl-ui, .axl-episode) .pagenav__title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 0 6px; list-style: none; cursor: pointer;
  font-size: 12.5px; font-weight: 700; letter-spacing: .05em; color: #6B7484;
}
:is(.axl-ui, .axl-episode) .pagenav__title::-webkit-details-marker { display: none; }
:is(.axl-ui, .axl-episode) .pagenav__title::after {
  content: ""; width: 8px; height: 8px; margin-right: 4px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px); transition: transform .15s ease;
}
:is(.axl-ui, .axl-episode) .pagenav__details[open] > .pagenav__title::after { transform: rotate(-135deg) translateY(-2px); }
:is(.axl-ui, .axl-episode) .pagenav__title:focus-visible { outline: 2px solid #1245C4; outline-offset: 2px; border-radius: 4px; }
:is(.axl-ui, .axl-episode) .pagenav__list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
:is(.axl-ui, .axl-episode) .pagenav__link {
  display: block; padding: 5px 10px 5px 12px;
  border-left: 2px solid transparent; border-radius: 0 8px 8px 0;
  color: #1A2547; font-size: 14px; line-height: 1.3; text-decoration: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
:is(.axl-ui, .axl-episode) .pagenav__item--h3 .pagenav__link { padding-left: 24px; font-size: 13px; color: #6B7484; }
:is(.axl-ui, .axl-episode) .pagenav__link:hover { background: #F3F4F8; color: #1245C4; }
:is(.axl-ui, .axl-episode) .pagenav__link:focus-visible { outline: 2px solid #1245C4; outline-offset: -2px; }
/* The section in view (site.js). */
:is(.axl-ui, .axl-episode) .pagenav__link[aria-current="true"] { border-left-color: #1245C4; background: #EEF2FC; color: #1245C4; font-weight: 700; }
@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .pagenav__title { cursor: default; pointer-events: none; }
  :is(.axl-ui, .axl-episode) .pagenav__title::after { display: none; }
}

/* The policy itself: reading-size copy, each section ruled off from the last. */
:is(.axl-ui, .axl-episode) .legal .legal__h { font-size: 22px; margin: 14px 0 0; padding-top: 22px; border-top: 1px solid #EAEDF3; }
:is(.axl-ui, .axl-episode) .legal .h1 { margin: 0; }
:is(.axl-ui, .axl-episode) .legal__updated { color: #6B7484; font-size: 13px; margin: 0; }

/* Page gutter. A section dropped straight onto a Page is a direct child of
   `.axl-page` (page.php) and needs the same side padding the theme's `.pad`
   utility gives the episode template — Bootstrap-based blocks get theirs from
   `.container`, but AXL sections are full-bleed by design. Scoped to the direct
   child so a section NESTED inside a composed page is not padded twice. */
.axl-page > :is(.axl-ui, .axl-episode) { padding-left: 16px; padding-right: 16px; }

/* Top gutter for a page that opens with a section rather than a hero (the AXL &
   Rusty page's first block is a framed card). Without it the first card sits flush
   against the header. Same steps as the theme's `.pad` top padding, so it lines up
   with the episode template. A leading acf/hero is never `.axl-ui`, so pages that
   open with one are untouched. */
.axl-page > :is(.axl-ui, .axl-episode):first-child { padding-top: 16px; }
@media (min-width: 640px) { .axl-page > :is(.axl-ui, .axl-episode):first-child { padding-top: 20px; } }
@media (min-width: 1080px) { .axl-page > :is(.axl-ui, .axl-episode):first-child { padding-top: 24px; } }

/* A vertical stack of sections with the page's standard rhythm. Use on the root
   group of a composed page so sections don't have to carry their own top margin.

   Both selectors are needed. `.stack` normally goes on the SAME element as the
   scope class — `class="axl-ui stack"` on a page's root group — and a plain
   descendant selector cannot match that, because the element has no `.axl-ui`
   ancestor. Any class meant to sit on the scope element itself needs this pair. */
:is(.axl-ui, .axl-episode).stack,
:is(.axl-ui, .axl-episode) .stack { display: flex; flex-direction: column; gap: 18px; }

/* ============================================================
   4. ICON HEADING / ICON ROW  (block axl/section-heading)
   ============================================================ */

:is(.axl-ui, .axl-episode) .bighead { display: flex; align-items: center; gap: 11px; color: var(--axl-accent, #1245C4); font-weight: 700; font-size: 24px; letter-spacing: .04em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) :is(h1, h2, h3, h4, h5, h6):is(.bighead, .iconrow) { margin: 0; line-height: inherit; }
:is(.axl-ui, .axl-episode) .bighead svg { flex: none; }

:is(.axl-ui, .axl-episode) .axl-ih__icon { display: inline-flex; flex: none; color: var(--axl-accent, #1245C4); }
:is(.axl-ui, .axl-episode) .axl-ih__text:empty { display: none; }
:is(.axl-ui, .axl-episode) .axl-ih__note { display: block; margin-top: 2px; font-size: 13px; font-weight: 400; letter-spacing: 0; text-transform: none; color: #6B7484; }

:is(.axl-ui, .axl-episode) .bighead--ink .axl-ih__icon { color: var(--axl-accent, #131C3F); }
:is(.axl-ui, .axl-episode) .bighead--muted .axl-ih__icon { color: var(--axl-accent, #3E4A66); }
:is(.axl-ui, .axl-episode) .bighead--green .axl-ih__icon { color: var(--axl-accent, #16A34A); }
/* The size scale: five steps at 16 / 20 / 24 / 30 / 36px, with the DEFAULT in the
   middle — a heading that sets no size is the 24px step, not the smallest one.
   The old scale ran 13.5 / 14 / 15 / 16: four steps inside three pixels, which is
   less a scale than a rounding error, and left `--xl` with no size of its own at
   all (it set a bigger icon and inherited the base's 15px text). */
:is(.axl-ui, .axl-episode) .bighead--sm { font-size: 16px; }
:is(.axl-ui, .axl-episode) .bighead--md { font-size: 20px; }
:is(.axl-ui, .axl-episode) .bighead--lg { font-size: 30px; }
:is(.axl-ui, .axl-episode) .bighead--xl { font-size: 36px; }

/* The icon now tracks its text rather than being pinned per step. 1.5em is the
   ratio the old scale already used almost everywhere — 13.5→20, 15→22 and 16→24 are
   all ~1.48 — so the pairing keeps its proportion and holds at 36px too, where a
   fixed 26px icon would have been left stranded beside the text.
   Sections that pin their own icon size are untouched: `.callout` (30px),
   `.iconstrip` (36px, 30px compact) and `.dlband__icon` (40px) each out-rank this
   rule on specificity or come later in the file. */
/* ONE rule sizes every icon in the system, and it reads a custom property.
   `--axl-ih-icon-size` unset means "track the text" at 1.5em — the ratio the old
   per-step sizes already used (13.5→20, 15→22, 16→24 are all ~1.48). A section that
   wants a different icon sets the PROPERTY (see .callout, .iconstrip, .dlband__icon,
   .factlist below), and the block writes it inline when an editor picks a size.
   Setting the property rather than `width` is what makes that hierarchy work: those
   section rules out-rank this one on specificity, so if they set `width` directly an
   editor's explicit choice could never beat them. Inline style beats them all. */
:is(.axl-ui, .axl-episode) .axl-ih__icon svg { width: var(--axl-ih-icon-size, 1.5em); height: var(--axl-ih-icon-size, 1.5em); }
:is(.axl-ui, .axl-episode) .bighead--stack { align-items: flex-start; }
:is(.axl-ui, .axl-episode) .bighead--split .pill,
:is(.axl-ui, .axl-episode) .iconrow--split .pill { margin-left: auto; }
/* Centred heading, for the middle-aligned landing sections. */
:is(.axl-ui, .axl-episode) .bighead--center { justify-content: center; text-align: center; }

/* The plain icon row — themes, checklists, feature bullets, support items. */
:is(.axl-ui, .axl-episode) .iconrow { display: flex; gap: 13px; align-items: center; margin-top: 15px; font-size: 14px; color: #1A2547; }
:is(.axl-ui, .axl-episode) .iconrow .axl-ih__icon { color: var(--axl-accent, #3E4A66); }
:is(.axl-ui, .axl-episode) .iconrow--brand .axl-ih__icon { color: var(--axl-accent, #1245C4); }
:is(.axl-ui, .axl-episode) .iconrow--ink .axl-ih__icon { color: var(--axl-accent, #131C3F); }
:is(.axl-ui, .axl-episode) .iconrow--green .axl-ih__icon { color: var(--axl-accent, #16A34A); }
/* A centred icon row — the `.bighead--center` of the row variant, for a single
   closing line that is the whole content of its card. The zeroed margin is part of
   the modifier on purpose: an icon row normally follows something and spaces itself
   off it, but when it IS the card's content that margin is an asymmetric gap
   against the card's own padding. Same reasoning as `.dlband__body .h3`. */
:is(.axl-ui, .axl-episode) .iconrow--center { justify-content: center; text-align: center; margin-top: 0; }
:is(.axl-ui, .axl-episode) .iconrow--stack { align-items: flex-start; margin-top: 16px; }
:is(.axl-ui, .axl-episode) .iconrow--stack .axl-ih__text { color: var(--axl-accent, #1245C4); font-size: 13.5px; font-weight: 600; }
:is(.axl-ui, .axl-episode) .iconrow--stack .axl-ih__note { font-size: 12.5px; }

/* ============================================================
   5. LABEL / VALUE FIELDS AND ROWS
   ============================================================ */

:is(.axl-ui, .axl-episode) .fld { margin-top: 16px; }
:is(.axl-ui, .axl-episode) .fld label { font-size: 11px; font-weight: 600; letter-spacing: .06em; color: #5A6478; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .fld div { margin-top: 5px; font-size: 15px; line-height: 1.6; }
/* Core-block form of the same two lines. */
:is(.axl-ui, .axl-episode) .fld__label { font-size: 11px; font-weight: 600; letter-spacing: .06em; color: #5A6478; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .fld__value { margin-top: 5px; font-size: 15px; line-height: 1.6; }
/* The status row reads as the design's green ".status" line. */
:is(.axl-ui, .axl-episode) .fld .iconrow--green { margin-top: 6px; gap: 9px; color: #16A34A; font-weight: 700; letter-spacing: .02em; }

:is(.axl-ui, .axl-episode) .status { display: flex; gap: 9px; align-items: center; margin-top: 6px; color: #16A34A; font-weight: 700; letter-spacing: .02em; }
:is(.axl-ui, .axl-episode) .checkrow { display: flex; gap: 13px; align-items: center; margin-top: 14px; font-size: 14px; }
:is(.axl-ui, .axl-episode) .themerow { display: flex; gap: 13px; align-items: center; margin-top: 15px; font-size: 14px; }
:is(.axl-ui, .axl-episode) .linkrow { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid #EAEDF3; font-size: 14px; }
:is(.axl-ui, .axl-episode) .linkrow:last-child { border-bottom: 0; padding-bottom: 0; }

/* Core/list form of the link rows: a chevroned, hairline-separated link list. */
:is(.axl-ui, .axl-episode) .linklist { list-style: none; padding: 0; margin-top: 8px; }
:is(.axl-ui, .axl-episode) .linklist li { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 14px 0; border-bottom: 1px solid #EAEDF3; font-size: 14px; }
:is(.axl-ui, .axl-episode) .linklist li:last-child { border-bottom: 0; padding-bottom: 0; }
:is(.axl-ui, .axl-episode) .linklist li::after { content: "\203A"; font-weight: 700; color: #1A2547; }
:is(.axl-ui, .axl-episode) .linklist a { color: inherit; text-decoration: none; }

/* ============================================================
   6. TILES — the 4-across icon/label grid
   ============================================================ */

:is(.axl-ui, .axl-episode) .tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 22px; }
:is(.axl-ui, .axl-episode) .tile { text-align: center; font-size: 13.5px; }
:is(.axl-ui, .axl-episode) .tile .box { background: #F1F2F5; border-radius: 8px; height: 96px; display: flex; align-items: center; justify-content: center; margin-bottom: 12px; }
/* The outlined variant — a white box with the card's hairline. */
:is(.axl-ui, .axl-episode) .tile.dl .box { background: #fff; border: 1px solid #E3E7F0; border-radius: 10px; height: 84px; }
:is(.axl-ui, .axl-episode) .tile b { display: block; font-weight: 600; }
:is(.axl-ui, .axl-episode) .tile span { color: #6B7484; font-size: 12.5px; }
:is(.axl-ui, .axl-episode) .tile .box .bighead { justify-content: center; gap: 0; }
:is(.axl-ui, .axl-episode) .tile__title { display: block; font-weight: 600; }
:is(.axl-ui, .axl-episode) .tile__title a { color: inherit; text-decoration: none; }
:is(.axl-ui, .axl-episode) .tile__cat { color: #6B7484; font-size: 12.5px; }
:is(.axl-ui, .axl-episode) .tiles--dl .tile__title { font-size: 11.5px; }
/* Three across instead of four, for feature rows. */
:is(.axl-ui, .axl-episode) .tiles--3 { grid-template-columns: 1fr; }

/* ============================================================
   7. TABS
   ============================================================ */

:is(.axl-ui, .axl-episode) .tabs { display: flex; border-bottom: 1px solid #E3E7F0; margin-top: 24px; gap: 0; align-items: stretch; }
:is(.axl-ui, .axl-episode) .tab { padding: 13px 18px; font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) button.tab { background: none; border: 0; font-family: inherit; cursor: pointer; color: #7A8496; }
:is(.axl-ui, .axl-episode) .tab.on { color: #1245C4; box-shadow: inset 0 -3px 0 #1245C4; }
:is(.axl-ui, .axl-episode) .tab.off { background: #F5F6F9; color: #7A8496; border-radius: 0 10px 0 0; }
:is(.axl-ui, .axl-episode) .tab:focus-visible { outline: 2px solid #1245C4; outline-offset: -2px; }

/* Tabs built from core/buttons: the box lives on the inner link.
   Only the core/button form hands its padding to the inner link — the legacy
   partials render `<button class="tab">`, which IS the control and keeps the
   design's own padding, hence .wp-block-button here rather than a bare .tab. */
:is(.axl-ui, .axl-episode) .tab.wp-block-button { padding: 0; }
:is(.axl-ui, .axl-episode) .tab > .wp-block-button__link { display: block; background: none; border: 0; border-radius: 0; padding: 13px 18px; color: #7A8496; font-size: 11.5px; line-height: 1.45; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
:is(.axl-ui, .axl-episode) .tab.on > .wp-block-button__link { color: #1245C4; box-shadow: inset 0 -3px 0 #1245C4; }
:is(.axl-ui, .axl-episode) .tab.off > .wp-block-button__link { background: #F5F6F9; color: #7A8496; border-radius: 0 10px 0 0; }

/* ============================================================
   8. BUTTONS — core/buttons form
   ============================================================ */

:is(.axl-ui, .axl-episode) .btn-row { display: flex; justify-content: center; margin-top: 22px; gap: 12px; flex-wrap: wrap; }
:is(.axl-ui, .axl-episode) .btn-row--start { justify-content: flex-start; margin-top: 20px; }
/* Labels wrap on phones and hold to one line from 640px up. A long call to
   action — "Start an Education & Outreach Conversation" on Education & Outreach —
   is wider than a card at phone width, and `nowrap` sent it straight out of the
   card. */
:is(.axl-ui, .axl-episode) .axl-btn > .wp-block-button__link { display: inline-flex; align-items: center; justify-content: center; gap: 9px; max-width: 100%; border: 1px solid #1245C4; border-radius: 8px; background: #1245C4; padding: 11px 26px; color: #fff; font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; white-space: normal; text-align: center; }
:is(.axl-ui, .axl-episode) .axl-btn--sm > .wp-block-button__link { font-size: 12px; padding: 8px 20px; }
/* The plain button is brand-blue solid (it was white until the client asked for
   blue everywhere); it darkens on hover and keyboard focus, and a step further
   when pressed. The solid and colour variants are left out —
   they carry their own hover fills below. */
:is(.axl-ui, .axl-episode) .axl-btn > .wp-block-button__link { transition: background-color .15s ease, border-color .15s ease, color .15s ease; }
:is(.axl-ui, .axl-episode) .axl-btn:not(.axl-btn--solid, .axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey) > .wp-block-button__link:is(:hover, :focus-visible) { background: #0f3aa8; border-color: #0f3aa8; }
:is(.axl-ui, .axl-episode) .axl-btn:not(.axl-btn--solid, .axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey) > .wp-block-button__link:active { background: #0d3396; border-color: #0d3396; }
/* Focus ring on every variant: a white gap then a blue ring, so it reads on a
   white card and on the dark cosmic page alike. The transparent outline keeps a
   ring in Windows high-contrast mode, where box-shadow is dropped. */
:is(.axl-ui, .axl-episode) .axl-btn > .wp-block-button__link:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px #1245C4; }
/* The filled counterpart — brand fill, white ink. The primary call to action. */
:is(.axl-ui, .axl-episode) .axl-btn--solid > .wp-block-button__link { background: #1245C4; border-color: #1245C4; color: #fff; }
:is(.axl-ui, .axl-episode) .axl-btn--solid > .wp-block-button__link:hover { background: #0f3aa8; border-color: #0f3aa8; }
/* Colour buttons — Orange / Green / Red / Cyan. The colours are tokens set on
   the class in button-colours.css (--axl-btn-fill, -hover, -active, --axl-btn-ink). Solid
   by default; add .axl-btn--outline for the coloured-border-on-white version.
   The same colours are wired onto Bootstrap-class buttons (.btn-orange,
   .btn-outline-orange …) here too, because the .btn rule above paints its
   background directly and would otherwise leave them white. */
:is(.axl-ui, .axl-episode) :is(.axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey) > .wp-block-button__link,
:is(.axl-ui, .axl-episode) .btn:is(.btn-orange, .btn-green, .btn-red, .btn-cyan) { background: var(--axl-btn-fill); border-color: var(--axl-btn-fill); color: var(--axl-btn-ink); }
:is(.axl-ui, .axl-episode) :is(.axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey) > .wp-block-button__link:hover,
:is(.axl-ui, .axl-episode) .btn:is(.btn-orange, .btn-green, .btn-red, .btn-cyan):hover { background: var(--axl-btn-fill-hover); border-color: var(--axl-btn-fill-hover); color: var(--axl-btn-ink); }
:is(.axl-ui, .axl-episode) :is(.axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey).axl-btn--outline > .wp-block-button__link,
:is(.axl-ui, .axl-episode) .btn:is(.btn-outline-orange, .btn-outline-green, .btn-outline-red, .btn-outline-cyan) { background: #fff; border-color: var(--axl-btn-fill); color: var(--axl-btn-fill); }
/* Outline colours darken their white like the plain white button, keeping the
   coloured border and label, rather than filling solid. */
:is(.axl-ui, .axl-episode) :is(.axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey).axl-btn--outline > .wp-block-button__link:is(:hover, :focus-visible),
:is(.axl-ui, .axl-episode) .btn:is(.btn-outline-orange, .btn-outline-green, .btn-outline-red, .btn-outline-cyan):is(:hover, :focus-visible) { background: #E1E6F2; }
:is(.axl-ui, .axl-episode) :is(.axl-btn--orange, .axl-btn--green, .axl-btn--red, .axl-btn--cyan, .axl-btn--grey).axl-btn--outline > .wp-block-button__link:active,
:is(.axl-ui, .axl-episode) .btn:is(.btn-outline-orange, .btn-outline-green, .btn-outline-red, .btn-outline-cyan):active { background: #D3DAED; }
/* Cyan's light fill is unreadable as text on white — outline label in a deeper cyan. */
:is(.axl-ui, .axl-episode) .axl-btn--cyan.axl-btn--outline > .wp-block-button__link,
:is(.axl-ui, .axl-episode) .btn.btn-outline-cyan { color: #0E7490; }
/* Same for orange (#F47A20) — outline label in a deeper orange. */
:is(.axl-ui, .axl-episode) .axl-btn--orange.axl-btn--outline > .wp-block-button__link,
:is(.axl-ui, .axl-episode) .btn.btn-outline-orange { color: #B4530A; }
/* core/button cannot carry an SVG, so the design's map pin is drawn as a mark on
   the link. Same path as axl_icon('map-pin'), in brand blue. */
:is(.axl-ui, .axl-episode) .axl-btn--pin > .wp-block-button__link::before {
  content: ""; flex: none; width: 16px; height: 16px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'%3E%3Cpath d='M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z' fill='%231245C4'/%3E%3Ccircle cx='12' cy='10' r='3' fill='%23fff'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* "Opens elsewhere" mark, trailing the label as it does on the footer's social
   rows. Same path as axl_icon('external-link'), but painted as a mask rather than
   a background image so it takes the link's own colour — this modifier has to
   read on the white .axl-btn and the filled .axl-btn--solid alike. */
:is(.axl-ui, .axl-episode) .axl-btn--ext > .wp-block-button__link::after {
  content: ""; flex: none; width: 14px; height: 14px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpath d='M15 3h6v6M10 14 21 3'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpath d='M15 3h6v6M10 14 21 3'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ============================================================
   9. COUNTDOWN  (block axl/episode-countdown)
   ============================================================ */

:is(.axl-ui, .axl-episode) .cdz { flex: 1 1 240px; min-width: 0; }
:is(.axl-ui, .axl-episode) .cdhead { text-align: center; font-size: 12.5px; font-weight: 700; letter-spacing: .06em; color: #1245C4; margin-bottom: 14px; }
:is(.axl-ui, .axl-episode) .cd { display: flex; gap: 9px; justify-content: center; }
:is(.axl-ui, .axl-episode) .cd div { background: #F1F2F4; border-radius: 10px; width: 70px; padding: 12px 0 10px; text-align: center; }
:is(.axl-ui, .axl-episode) .cd b { display: block; font-size: 24px; font-weight: 800; color: #151D40; font-variant-numeric: tabular-nums; }
:is(.axl-ui, .axl-episode) .cd span { font-size: 10px; font-weight: 600; letter-spacing: .04em; color: #6B7484; }
/* The clock is sized for a full-width row (80px cells at ≥1080). In a sidebar the
   four units share whatever the column gives them instead of overflowing it, and
   `.cdz`'s 240px flex basis — meant for the old side-by-side teaser band — would
   become HEIGHT in the card's column flow, so it sizes to its content there.
   Here rather than in episode.css so any page's sidebar gets it (Downloads). */
:is(.axl-ui, .axl-episode) .aside .cd { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
:is(.axl-ui, .axl-episode) .aside .cd div { width: auto; padding: 11px 0 9px; }
:is(.axl-ui, .axl-episode) .aside .cd b { font-size: 21px; }
:is(.axl-ui, .axl-episode) .aside .cdz { flex: 0 0 auto; }
/* The countdown block prints nothing when no date is set or it has passed, which
   would leave its card empty. Hide any countdown card with no clock inside (front
   end only; the editor shows its own placeholder). */
body:not(.editor-styles-wrapper) .cdcard:not(:has([data-axl-countdown])) { display: none; }

/* ============================================================
   10. NEWSLETTER BAND  (block axl/newsletter-form)

   A horizontal row at every width, wrapping on narrow screens. `.sub` is the
   band (heading + copy + form); the form itself is styled by its own block class
   so a bare newsletter block is correct outside the band too.
   ============================================================ */

:is(.axl-ui, .axl-episode) .sub { margin-top: 18px; display: flex; flex-direction: row; flex-wrap: wrap; gap: 22px; align-items: center; }
:is(.axl-ui, .axl-episode) .sub .bighead { flex: none; }
/* Flex bases, not `flex: 1`: with a 0 basis these two shrink to ~67px on a phone
   instead of wrapping, which is the "wraps on narrow screens" the row is meant to
   do. A real basis makes them wrap onto their own lines below ~640px. */
:is(.axl-ui, .axl-episode) .sub .subtext { flex: 1 1 200px; }

/* The form renders with class "row", which collides with Bootstrap's grid:
   `.row > *` sets width:100% + gutter padding, stacking the field above the
   button. Zero the gutter VARIABLES rather than the padding itself — Bootstrap's
   padding then computes to 0 and the controls keep their own 11px/26px padding. */
:is(.axl-ui, .axl-episode) .sub .row,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form { display: flex; flex-direction: row; gap: 10px; flex: 1 1 260px; min-width: 0; max-width: 480px; margin-top: 0; --bs-gutter-x: 0; --bs-gutter-y: 0; }
:is(.axl-ui, .axl-episode) .sub .row > *,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form > * { width: auto; max-width: none; margin-top: 0; }

/* The field and button are hand-written markup, so they get the button system's
   geometry explicitly: the same 11px/26px padding, 13px/700 type, 8px radius and
   1px border box as .btn. Both carry the same border width and line-height, so
   the two controls compute to exactly the same height and share a baseline. */
:is(.axl-ui, .axl-episode) .sub input,
:is(.axl-ui, .axl-episode) .sub button,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form input,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 11px 16px;
  font-family: inherit;
  font-size: 13px;
  line-height: 1.45;
}
:is(.axl-ui, .axl-episode) .sub input,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form input { flex: 1; min-width: 0; border-color: var(--axl-input-line, #D9DDE6); background: #fff; color: var(--axl-ink, #1A2547); }
:is(.axl-ui, .axl-episode) .sub input::placeholder,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form input::placeholder { color: #98A1B3; }
:is(.axl-ui, .axl-episode) .sub input:focus-visible,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form input:focus-visible { outline: 2px solid #1245C4; outline-offset: -1px; }

/* The filled counterpart of .btn — same shape, brand fill, .btn-primary's states. */
:is(.axl-ui, .axl-episode) .sub button,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px 26px;
  border-color: var(--axl-blue, #1245C4);
  background: var(--axl-blue, #1245C4);
  color: #fff;
  font-weight: 700;
  letter-spacing: .04em;
  white-space: nowrap;
  cursor: pointer;
}
:is(.axl-ui, .axl-episode) .sub button:hover,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form button:hover { background: #0f3aa8; border-color: #0f3aa8; }
:is(.axl-ui, .axl-episode) .sub button:active,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form button:active { background: #0d3396; border-color: #0d3396; }
:is(.axl-ui, .axl-episode) .sub button:focus-visible,
:is(.axl-ui, .axl-episode) .wp-block-axl-newsletter-form button:focus-visible { outline: 2px solid #131C3F; outline-offset: 2px; }

/* ============================================================
   11. LANDING-PAGE SECTIONS

   Built from the same primitives, for pages assembled out of the generic
   section patterns (inc/patterns.php → axl_generic_section_patterns()).
   ============================================================ */

/* --- banner: headline + copy + buttons beside an image ------------------- */
:is(.axl-ui, .axl-episode) .banner { display: flex; flex-direction: column; gap: 22px; }
:is(.axl-ui, .axl-episode) .banner .banner__copy { flex: 1 1 320px; min-width: 0; }
:is(.axl-ui, .axl-episode) .banner .banner__media { flex: 1 1 320px; min-width: 0; }
:is(.axl-ui, .axl-episode) .banner .banner__media img { max-width: 100%; height: auto; border-radius: 16px; }
:is(.axl-ui, .axl-episode) .banner .h1 { margin-top: 12px; }

/* --- split: two equal halves, text one side, media the other ------------- */
:is(.axl-ui, .axl-episode) .split { display: grid; grid-template-columns: 1fr; gap: 20px; align-items: center; }
:is(.axl-ui, .axl-episode) .split img { max-width: 100%; height: auto; border-radius: 16px; }

/* --- stats: big number over a label ------------------------------------- */
:is(.axl-ui, .axl-episode) .statrow { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 18px; text-align: center; }
:is(.axl-ui, .axl-episode) .stat__num { font-size: 30px; font-weight: 800; color: #1245C4; font-variant-numeric: tabular-nums; line-height: 1.1; }
:is(.axl-ui, .axl-episode) .stat__label { margin-top: 6px; font-size: 12.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: #6B7484; }

/* --- cta: a centred panel that closes a page ----------------------------- */
:is(.axl-ui, .axl-episode) .cta { text-align: center; }
:is(.axl-ui, .axl-episode) .cta .bighead { justify-content: center; }
:is(.axl-ui, .axl-episode) .cta .lede { margin: 12px auto 0; }
:is(.axl-ui, .axl-episode) .cta .h2 { margin-top: 10px; }

/* --- media card: image on top of a card, flush to its corners ------------ */
:is(.axl-ui, .axl-episode) .card .cover { margin: -19px -19px 16px; }
/* A hairline closes the image off. Every cover is the same 170px box, but art
   that fades to white at its lower edge blends into the card and reads as a
   shorter image; the rule makes the boundary explicit whatever the artwork. */
:is(.axl-ui, .axl-episode) .card .cover img { width: 100%; height: 170px; object-fit: cover; border-radius: 16px 16px 0 0; border-bottom: 1px solid var(--axl-accent-line, #E3E7F0); }
/* A linked cover: the anchor has to fill the figure, or an inline box leaves the
   pills sitting over dead space at the card's edges. */
:is(.axl-ui, .axl-episode) .card .cover a { display: block; }
/* Standing in for missing artwork with the site logo: `cover` would crop a
   wordmark to its middle, so the fallback is framed in the same 170px box
   instead — contained, centred and given air on a tinted ground. */
:is(.axl-ui, .axl-episode) .card .cover .cover__logo img { object-fit: contain; padding: 26px; background: #F5F6F9; }
:is(.axl-ui, .axl-episode) .card .body p + p { margin-top: 10px; }

/* A .pill sitting on top of a cover image needs its own contrast, since the
   photo behind it can be any tone — a dark, semi-transparent chip reads over
   anything. The corner it sits in is a separate modifier, so a future card
   can drop a pill top-right or bottom-left without a new pair of rules. */
:is(.axl-ui, .axl-episode) .card .cover { position: relative; }
:is(.axl-ui, .axl-episode) .pill--onimg { position: absolute; background: rgba(21, 29, 64, .72); color: #fff; }
:is(.axl-ui, .axl-episode) .pill--tl { top: 12px; left: 12px; }
:is(.axl-ui, .axl-episode) .pill--br { bottom: 12px; right: 12px; }

/* --- download band: icon panel + copy + a button pinned to the far edge --- */
/* ON A PHONE the band is ONE COLUMN: the icon on its own line, the title under
   it, then the copy and the button — every part full width and left aligned.

   The desktop band is three things in a row: a 96px media slot, the copy, the
   button. Under 640px that slot wraps onto a line by itself but keeps its 96px
   width, so the glyph sits centred in a box half a phone wide with the title
   starting beneath it — a column of empty space the narrow screen cannot pay for.
   Here the box shrinks to the glyph and left-aligns with everything below it.

   The tinted panel goes too; nothing else in the design system boxes an icon at
   this size, and on one line of its own the fill reads as a stray swatch rather
   than a media slot. cosmic-site.css scopes its glass version to 640px for the
   same reason. Both come back with the row at 640px.

   Block layout, not flex or grid: a single column of full-width blocks is what
   normal flow already does, and the body's flex `gap` becomes a margin between
   its children so the spacing carries over unchanged. */
:is(.axl-ui, .axl-episode) .dlband { display: block; }
:is(.axl-ui, .axl-episode) .dlband__icon { width: auto; margin-bottom: 10px; display: flex; align-items: center; justify-content: flex-start; background: none; border-radius: 0; }
:is(.axl-ui, .axl-episode) .dlband__icon .axl-ih__icon { --axl-ih-icon-size: 40px; }
/* A job's own uploaded icon, in place of the drawn one. */
:is(.axl-ui, .axl-episode) .dlband__icon .dlband__img { margin: 0; }
:is(.axl-ui, .axl-episode) .dlband__icon .dlband__img img { display: block; width: 56px; height: 56px; object-fit: contain; }
:is(.axl-ui, .axl-episode) .dlband__body { display: block; }
/* The 6px the body's flex `gap` gives it from 640px up, as a margin. */
:is(.axl-ui, .axl-episode) .dlband__body > * + * { margin-top: 6px; }
/* A careers vacancy's meta row sits flush against the title. There is no flex gap
   to cancel down here, so it zeroes the margin above rather than going negative —
   the 640px band keeps the negative value that cancels the gap. */
:is(.axl-ui, .axl-episode) .dlband__body > .checkrow { margin-top: 0; }
/* The .h3/paragraph primitives carry their own top margin for normal flow use;
   this stack already spaces itself with `gap`, so both would double up. */
:is(.axl-ui, .axl-episode) .dlband__body .h3 { margin-top: 0; }
:is(.axl-ui, .axl-episode) .dlband__body :is(.h2, .h3) + p { margin-top: 0; }
/* Pinned to the far right once the band is one row; on a narrow screen the
   button wraps onto its own line below the icon/copy, where a right margin
   would just shove it off to the edge instead of reading as its own row.

   `display: flex` is what makes the centring bite. The column is already full
   height — `.dlband` stretches its children — but the button is a block child, so
   without a flex context it simply sits at the top of that height and an
   `align-items` here is a no-op. As a COLUMN flex parent, `justify-content`
   centres the button against the copy beside it, which is how every wireframe
   draws these bands. */
:is(.axl-ui, .axl-episode) .dlband__cta { margin-top: 20px; flex: none; display: flex; flex-direction: column; justify-content: center; }
/* The button row carries `.btn-row--start`'s 20px top margin for normal flow use.
   Centring counts that margin as part of the item, so it pushed the button below
   the middle of the band; the column has nothing above it to clear. */
:is(.axl-ui, .axl-episode) .dlband__cta .btn-row { margin-top: 0; }

/* A band whose body is split in two rather than run as one line of copy: text on
   the left, media over a button on the right. It goes INSIDE .dlband__body, which
   already takes everything the 96px icon panel leaves, so such a band uses no
   .dlband__cta — its button belongs to the right half.

   The halves are deliberately plain columns, not cards: nested cards would read as
   another card row rather than as one closing panel. */
:is(.axl-ui, .axl-episode) .bandsplit { display: grid; grid-template-columns: 1fr; gap: 20px; align-items: center; }
:is(.axl-ui, .axl-episode) .bandsplit img { max-width: 100%; height: auto; border-radius: 16px; }

/* Gap above the downloads band, so it doesn't sit flush under the card grid
   above it. Same rhythm as `.stack` (18/22/26), scoped to this one section
   rather than the shared class so other `.card--lg` panels are unaffected. */
:is(.axl-ui, .axl-episode) .archive-downloads { margin-top: 18px; }

/* --- card grid: a row of equal-height cards, one per cell ---------------- */
:is(.axl-ui, .axl-episode) .cardgrid { display: grid; grid-template-columns: 1fr; gap: 18px; margin-top: 18px; }

/* Cards in a grid run as flex columns so a trailing button row can be pinned to
   the card's bottom edge with `margin-top: auto`. Without it each button simply
   follows its own description and a row of cards ends up ragged. The padding-top
   is the floor: `auto` collapses to nothing when the card has no slack. */
:is(.axl-ui, .axl-episode) .cardgrid .card { display: flex; flex-direction: column; }
:is(.axl-ui, .axl-episode) .cardgrid .card .btn-row { margin-top: auto; padding-top: 16px; }
/* Air between a card's icon heading and its description. Scoped to the card grid
   rather than set on .bighead + p globally: the newsletter band and the CTA panel
   both put a paragraph straight after a .bighead and already space it themselves. */
:is(.axl-ui, .axl-episode) .cardgrid .card .bighead + p { margin-top: 12px; }
/* The cover, the title and the button of an episode card all lead to the same
   episode, so the title carries the card's own ink rather than link blue and
   only picks up brand colour on hover. */
:is(.axl-ui, .axl-episode) .cardgrid .card .h3 a { color: inherit; text-decoration: none; }
:is(.axl-ui, .axl-episode) .cardgrid .card .h3 a:hover,
:is(.axl-ui, .axl-episode) .cardgrid .card .h3 a:focus-visible { color: var(--axl-accent, #1245C4); text-decoration: underline; }
/* A card in a 5-up row is ~145px of usable width at 1080px, and .axl-btn is
   `white-space: nowrap` — so a two-word label like "Explore Downloads" simply ran
   out of the card. Inside a card grid the label wraps and the generous 26px side
   padding drops to 16px, which is what buys the room. */
:is(.axl-ui, .axl-episode) .cardgrid .card .axl-btn > .wp-block-button__link {
  white-space: normal;
  text-align: center;
  padding-left: 16px;
  padding-right: 16px;
}

/* --- tile grid: label-only cards, the icon OVER the word ------------------
   The Creators & Communities formats and the Education skills list are the same
   object — a short label in a box with nothing under it to read — and the
   wireframes draw both as a large icon with the word beneath it, not the
   icon-beside-title of an ordinary icon card.

   That stacking is also what buys the columns. Beside the icon a label gets
   roughly two words of room, so four boxed cards inside a HALF-width card ran
   past its right edge and the row had to settle for two across; above the icon
   the label has the whole cell.

   Tracks are `minmax(0, 1fr)`, not the plain `1fr` the other counts use: `1fr`'s
   floor is min-content — the longest word — which is the other half of that same
   overflow. Each band restates the tracks because `.cardgrid`'s own 2-up and 3-up
   come later in the file at equal specificity and would otherwise win.

   The label is sentence case at label size: it names a thing rather than heading a
   card, which is how the wireframe tells these apart from the icon cards above
   them. The brand colour stays, so they still read as part of the icon-card family
   — and the dark skin still repaints them along with every other heading. */
:is(.axl-ui, .axl-episode) .cardgrid--tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
:is(.axl-ui, .axl-episode) .cardgrid--tiles .card { align-items: center; justify-content: center; text-align: center; padding: 16px 10px; }
:is(.axl-ui, .axl-episode) .cardgrid--tiles .bighead { flex-direction: column; gap: 10px; font-size: 13.5px; line-height: 1.3; letter-spacing: 0; text-transform: none; }
:is(.axl-ui, .axl-episode) .cardgrid--tiles .bighead .axl-ih__icon { --axl-ih-icon-size: 36px; }
/* A tile has no description. Rows inserted before this modifier existed wrote an
   empty paragraph into post_content for the missing text, and an empty <p> in a
   flex column is still a row of height. */
:is(.axl-ui, .axl-episode) .cardgrid--tiles .card p:empty { display: none; }

/* `.cardgrid--media`: a horizontal card — a square thumbnail on the left, the
   title and text on the right (Media & Press Assets' category cards). The card is
   a row instead of the grid's usual column; the thumbnail is 30% of the card (a
   third at most, whatever the column width) and the body group takes the rest of the
   width and `min-width: 0` lets long words wrap rather than push the card wide. */
:is(.axl-ui, .axl-episode) .cardgrid--media .card { flex-direction: row; align-items: center; gap: 16px; }
:is(.axl-ui, .axl-episode) .cardgrid--media .card .ph { flex: 0 0 30%; width: 30%; max-width: 30%; min-width: 0; margin: 0; }
:is(.axl-ui, .axl-episode) .cardgrid--media .card .ph img { display: block; width: 100%; max-width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 10px; }
:is(.axl-ui, .axl-episode) .cardgrid--media .mediacard__body { flex: 1; min-width: 0; }
:is(.axl-ui, .axl-episode) .cardgrid--media .mediacard__body .h3 { margin: 0; }
:is(.axl-ui, .axl-episode) .cardgrid--media .mediacard__body p { margin: 6px 0 0; }

/* --- generic bulleted list, dot-marked like the discovery cards ---------- */
:is(.axl-ui, .axl-episode) .dotlist { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 9px; font-size: 13.5px; margin-top: 14px; }
:is(.axl-ui, .axl-episode) .dotlist li { display: flex; gap: 10px; align-items: center; }
:is(.axl-ui, .axl-episode) .dotlist li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: #1A2547; flex: none; }
/* Rich-text lists (job descriptions) can hold bold / links inside an item, which
   would become separate flex children — so inside a `.copy` the item is a block
   with the dot hung in its left padding. */
:is(.axl-ui, .axl-episode) .copy .dotlist { margin-top: 0; } /* .copy's own gap spaces it, like a paragraph */
:is(.axl-ui, .axl-episode) .copy .dotlist li { display: block; position: relative; padding-left: 15px; }
:is(.axl-ui, .axl-episode) .copy .dotlist li::before { position: absolute; left: 0; top: .6em; }

/* ---------- ≥640px ---------- */
@media (min-width: 640px) {
  /* Past phone width every label in the set fits on its line again. */
  :is(.axl-ui, .axl-episode) .axl-btn > .wp-block-button__link { white-space: nowrap; }
  :is(.axl-ui, .axl-episode) .card { padding: 22px; }
  :is(.axl-ui, .axl-episode) .card .cover { margin: -22px -22px 16px; }
  :is(.axl-ui, .axl-episode) .h1 { font-size: 44px; }
  :is(.axl-ui, .axl-episode) .h2 { font-size: 30px; }
  :is(.axl-ui, .axl-episode) .h3 { font-size: 20px; }
  :is(.axl-ui, .axl-episode) .lede { font-size: 17px; }
  :is(.axl-ui, .axl-episode) .aside { grid-template-columns: 1fr 1fr; gap: 20px; }
  /* The early-splitting .grid2. Use it when both halves are text or small media
     and survive a ~250px column — a 50/50 that turns at 640px like the rest of
     the design. The gutter is 24px here rather than the default's 5rem, which at
     this width would eat most of the row; the 1080px rule below is not repeated
     for the modifier, so it inherits the full 5rem once there is room for it. */
  :is(.axl-ui, .axl-episode) .grid2--early { grid-template-columns: 1fr 1fr; gap: 24px; }
  :is(.axl-ui, .axl-episode) .tiles { grid-template-columns: repeat(4, 1fr); gap: 22px; }
  :is(.axl-ui, .axl-episode) .tiles--3 { grid-template-columns: repeat(3, 1fr); }
  :is(.axl-ui, .axl-episode) .cardgrid { grid-template-columns: 1fr 1fr; gap: 20px; }
  :is(.axl-ui, .axl-episode) .cardgrid--tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  :is(.axl-ui, .axl-episode) .bandsplit { grid-template-columns: 1fr 1fr; gap: 24px; }
  :is(.axl-ui, .axl-episode) .archive-downloads { margin-top: 22px; }
  /* The band goes back to a row: the 96px media slot, the copy taking what is
     left, the button pinned to the far edge. Every value the phone grid above
     replaced is restated here rather than left to be inherited — the two layouts
     are different box models, not a tweak of one another. */
  :is(.axl-ui, .axl-episode) .dlband { display: flex; align-items: stretch; flex-wrap: wrap; gap: 20px; }
  :is(.axl-ui, .axl-episode) .dlband__icon { flex: none; width: 96px; margin-bottom: 0; justify-content: center; background: #F1F2F5; border-radius: 14px; }
  /* The icon on its own, with no tinted panel behind it. The 96px column stays, so
     the left gutter and the icon's centring are unchanged — only the fill goes.
     It lives in this band because below it NO band has a panel to remove.

     Two selectors, deliberately. The modifier is the explicit opt-in. The `:has()`
     rule is what makes it apply to content ALREADY SAVED: a pattern is copied into
     post_content when it is inserted, so editing the pattern file never reaches a
     page built from an earlier version of it. `.bandsplit` only exists in the band
     that wants the bare icon, which makes it a reliable stand-in for the modifier.
     The archive's Free Resources band has no `.bandsplit` and keeps its panel. */
  :is(.axl-ui, .axl-episode) .dlband__icon--bare,
  :is(.axl-ui, .axl-episode) .dlband:has(.bandsplit) .dlband__icon { background: none; border-radius: 0; }
  :is(.axl-ui, .axl-episode) .dlband__body { flex: 1 1 240px; display: flex; flex-direction: column; justify-content: center; gap: 6px; }
  /* The flex `gap` spaces the body again, so the phone's margin stand-in goes. */
  :is(.axl-ui, .axl-episode) .dlband__body > * + * { margin-top: 0; }
  /* The meta row a careers vacancy puts under its title sits flush against it.
     Dropping `.checkrow`'s own 14px top margin gets it down to the column's 6px
     `gap`; the negative margin cancels that last 6px, since the `gap` is set on
     the shared `.dlband__body` and still has to space the summary below. */
  :is(.axl-ui, .axl-episode) .dlband__body .checkrow { margin-top: -6px; }
  :is(.axl-ui, .axl-episode) .dlband__cta { margin-top: 0; margin-left: auto; }
  :is(.axl-ui, .axl-episode) .tab { padding: 14px 30px; font-size: 13px; }
  :is(.axl-ui, .axl-episode) .tab > .wp-block-button__link { padding: 14px 30px; font-size: 13px; }
  :is(.axl-ui, .axl-episode) .cd { gap: 14px; }
  :is(.axl-ui, .axl-episode) .cd div { width: 80px; }
  :is(.axl-ui, .axl-episode) .cd b { font-size: 28px; }
  :is(.axl-ui, .axl-episode) .statrow { grid-template-columns: repeat(4, 1fr); gap: 22px; }
  :is(.axl-ui, .axl-episode) .stat__num { font-size: 36px; }
  :is(.axl-ui, .axl-episode) .split { grid-template-columns: 1fr 1fr; gap: 28px; }
  :is(.axl-ui, .axl-episode) .banner { flex-direction: row; align-items: center; gap: 28px; }
  :is(.axl-ui, .axl-episode).stack,
  :is(.axl-ui, .axl-episode) .stack { gap: 22px; }
  .axl-page > :is(.axl-ui, .axl-episode) { padding-left: 24px; padding-right: 24px; }
}

/* ---------- ≥1080px ---------- */
/* The welcome card (copy beside a video) splits at 980px rather than 1080px, so
   a landscape tablet gets two columns. Keyed on structure — a .grid2 inside a
   .card that holds a video — because pattern markup is frozen into saved pages
   and cannot take a new class. Other .grid2s keep the 1080px split. The gutter
   is 3rem until 1080px, where the 5rem rule below takes over. */
@media (min-width: 980px) {
  :is(.axl-ui, .axl-episode) .card .grid2:has(.axl-video) { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 980px) and (max-width: 1079px) {
  :is(.axl-ui, .axl-episode) .card .grid2:has(.axl-video) { column-gap: 3rem; }
}

@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 30px; align-items: start; }
  :is(.axl-ui, .axl-episode) .aside { grid-template-columns: 1fr; gap: 24px; margin-top: 0; }
  :is(.axl-ui, .axl-episode) .h1 { font-size: 48px; }
  /* .grid2 splits at 1080px, not 640px. With a 5rem gutter the two halves are
     only ~250px each on a tablet — too narrow for a video beside a paragraph —
     so it stays stacked through that range. The base `gap: 18px` governs the
     stacked layout, where this is a VERTICAL gap and 80px would push the second
     half off the screen. */
  :is(.axl-ui, .axl-episode) .grid2 { grid-template-columns: 1fr 1fr; gap: 5rem; }
  :is(.axl-ui, .axl-episode) .h2 { font-size: 34px; }
  :is(.axl-ui, .axl-episode) .cardgrid { grid-template-columns: repeat(3, 1fr); margin-top: 22px; }
  :is(.axl-ui, .axl-episode) .archive-downloads { margin-top: 26px; }
  /* Five across only once there is room: at 1080px these are ~190px each, which
     is already tight for an image over a heading, a description and a button.
     Below this they inherit .cardgrid's 2-up, then 1-up on a phone. */
  :is(.axl-ui, .axl-episode) .cardgrid--5 { grid-template-columns: repeat(5, 1fr); }
  /* Four across — the step the set was missing. `--5` and `--2` existed because the
     wireframes asked for them; the base grid already gives three at this width, so
     `--3` would be dead code and is deliberately absent.
     Like `--5`, this only engages at 1080px: below it the row inherits `.cardgrid`'s
     two-up, then one-up on a phone. At 1080px four cards are ~240px each, which is
     roomier than the ~190px `--5` gets and comfortable for an image over a heading,
     a description and a button. */
  :is(.axl-ui, .axl-episode) .cardgrid--4 { grid-template-columns: repeat(4, 1fr); }
  /* Two across all the way up, where the base grid would otherwise go to three.
     Below 640px it inherits .cardgrid's single column like everything else. */
  :is(.axl-ui, .axl-episode) .cardgrid--2 { grid-template-columns: repeat(2, 1fr); }
  /* Four across at full desktop width — ten tiles then fall 4 / 4 / 2, which is
     how the Creators & Communities wireframe draws them. */
  :is(.axl-ui, .axl-episode) .cardgrid--tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
  :is(.axl-ui, .axl-episode) .sub { gap: 22px; margin-top: 22px; }
  :is(.axl-ui, .axl-episode) .split { gap: 40px; }
  :is(.axl-ui, .axl-episode) .banner { gap: 40px; }
  :is(.axl-ui, .axl-episode).stack,
  :is(.axl-ui, .axl-episode) .stack { gap: 26px; }
  .axl-page > :is(.axl-ui, .axl-episode) { padding-left: 28px; padding-right: 28px; }
}

@media (min-width: 1480px) {
    .axl-page > :is(.axl-ui, .axl-episode) {
        padding-left: 0px;
        padding-right: 0px;
    }
}
/* ============================================================
   11b. CHARACTER PAGE  (patterns/rusty-*.php)

   The AXL & Rusty page: prose-heavy cards in two-up rows. Nothing below names a
   character, so any of it can be reused on another page.

   EVEN SPACING is the rule this block exists to keep: `.cardrow` uses exactly the
   gaps `.stack` uses (18 / 22 / 26px), so the space between two rows and the space
   between two cards in a row are always the same number. Cards in a row are equal
   height through the `.card:only-child` rule in section 1.

   Text colours are inherited, never set, wherever the dark site's glass card must
   be able to recolour them without a rule of its own.
   ============================================================ */

/* --- rows ------------------------------------------------------------------ */
:is(.axl-ui, .axl-episode) .cardrow.wp-block-columns { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; }

/* Air between a section's heading and the row it introduces.
   `.cardrow` carries no top margin of its own — a rusty-page section is usually a
   row on its own, where the `.stack` gap above it is the whole spacing story. A row
   that FOLLOWS a heading is the other case, and it was sitting flush against it.
   `.cardgrid` has had its own `margin-top` for exactly this since the beginning;
   this is the same relationship expressed for the row builder, in the same
   `:is(.h2, .h3) + p` idiom section 2 uses.
   The value stays BELOW the `.stack` gap (18/22/26) at every breakpoint, so the
   space inside a section is always smaller than the space between two — otherwise a
   heading reads as floating between its neighbours rather than belonging to its row. */
:is(.axl-ui, .axl-episode) :is(.h1, .h2, .h3, .bighead) + .cardrow.wp-block-columns { margin-top: 16px; }

/* Two rows in the same section. A rusty-page section is one row, spaced off its
   neighbours by the `.stack` gap, so until the About v2 Explorers section put a
   full-width row under a two-up one, consecutive rows never occurred — and they sat
   flush against each other.
   The value is not a judgement call: the note at the head of this section sets the
   rule that "the space between two rows and the space between two cards in a row are
   always the same number", so this tracks `.cardrow`'s own gap at every breakpoint. */
:is(.axl-ui, .axl-episode) .cardrow.wp-block-columns + .cardrow.wp-block-columns { margin-top: 18px; }
/* ...unless the rows are direct children of a `.stack`, which already spaces them
   with its own `gap` (the same 18/22/26). Both together made the Careers job rows
   sit twice as far apart as every other gap on the page. Higher specificity than the
   breakpoint overrides above, so one reset covers all three. */
:is(.axl-ui, .axl-episode) .stack > .cardrow.wp-block-columns + .cardrow.wp-block-columns,
:is(.axl-ui, .axl-episode).stack > .cardrow.wp-block-columns + .cardrow.wp-block-columns { margin-top: 0; }

/* --- card furniture -------------------------------------------------------- */
/* A card whose children flow on one gap instead of per-element margins. */
:is(.axl-ui, .axl-episode) .card--flow { display: flex; flex-direction: column; gap: 16px; }
:is(.axl-ui, .axl-episode) .cardhead { display: flex; flex-direction: column; gap: 6px; }
:is(.axl-ui, .axl-episode) .cardhead:has(> .wp-block-image) { flex-direction: row; align-items: center; gap: 14px; }
:is(.axl-ui, .axl-episode) .cardhead > .wp-block-image { margin: 0; flex: none; }
:is(.axl-ui, .axl-episode) .cardhead > .wp-block-image img { display: block; width: 40px; height: auto; border-radius: 3px; }
:is(.axl-ui, .axl-episode) .cardtitle { font-size: 22px; font-weight: 800; line-height: 1.15; letter-spacing: -.005em; text-transform: uppercase; color: #151D40; text-wrap: balance; }
:is(.axl-ui, .axl-episode) .strap { font-size: 12.5px; font-weight: 700; line-height: 1.4; letter-spacing: .05em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .caps { text-transform: uppercase; letter-spacing: .03em; }
:is(.axl-ui, .axl-episode) .copy { display: flex; flex-direction: column; gap: 10px; font-size: 14.5px; line-height: 1.6; }
/* Reading-size copy. `.copy` above is card FURNITURE size — right for a fact row or
   a caption, tight for a paragraph somebody is expected to actually read. This is
   `.prose`'s metrics (section 2) offered as a `.copy` modifier, so a card's copy
   block opts in without changing its structure. Added for the About v2 sections;
   nothing existing carries the class, so nothing existing moves. */
:is(.axl-ui, .axl-episode) .copy--prose { font-size: 16px; line-height: 1.7; }

/* --- copy beside an image -------------------------------------------------- */
:is(.axl-ui, .axl-episode) .introsplit { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
:is(.axl-ui, .axl-episode) .introsplit__copy { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
:is(.axl-ui, .axl-episode) .introsplit__copy .h1 { margin: 0; line-height: 1; text-transform: uppercase; }
/* A .badge is inline-block, but a flex column would stretch it to the full width. */
:is(.axl-ui, .axl-episode) .introsplit__copy .badge { align-self: flex-start; }
:is(.axl-ui, .axl-episode) .herosub { font-size: 20px; font-weight: 800; line-height: 1.2; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .rule.wp-block-separator { width: 48px; margin: 2px 0; border: 0; border-top: 3px solid currentColor; opacity: 1; }
/* The hero's image sits in flow at its uploaded size, like every other content
   image; the copy and image centre on each other so the shorter one doesn't hang
   off the top of the card. */
:is(.axl-ui, .axl-episode) .introsplit--hero { align-items: center; }

/* --- image placeholders ---------------------------------------------------- */
/* Every wireframe image box. A real image, once an editor picks one, shows at its
   uploaded size and shape — never cropped, only scaled down to fit its column.
   Only the packaged placeholder is held to the box's shape (4:3, or the
   portrait / wide / square modifier), so an unfilled wireframe keeps its layout. */
:is(.axl-ui, .axl-episode) .ph img { max-width: 100%; height: auto; border-radius: 12px; }
:is(.axl-ui, .axl-episode) .ph img[src$="placeholder.svg"] { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: #EEF0F5; }
:is(.axl-ui, .axl-episode) .ph--portrait img[src$="placeholder.svg"] { aspect-ratio: 4 / 5; }
:is(.axl-ui, .axl-episode) .ph--wide img[src$="placeholder.svg"] { aspect-ratio: 16 / 9; }
:is(.axl-ui, .axl-episode) .ph--square img[src$="placeholder.svg"] { aspect-ratio: 1; }

/* --- callouts -------------------------------------------------------------- */
:is(.axl-ui, .axl-episode) .callout { display: flex; align-items: center; gap: 14px; padding: 12px 16px; border: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 12px; font-size: 13.5px; line-height: 1.5; }
:is(.axl-ui, .axl-episode) .callout .bighead { flex: none; }
:is(.axl-ui, .axl-episode) .callout .bighead .axl-ih__icon { --axl-ih-icon-size: 30px; }
:is(.axl-ui, .axl-episode) .callout__copy { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
:is(.axl-ui, .axl-episode) .callout--dashed { border-style: dashed; }
:is(.axl-ui, .axl-episode) .callout--center { justify-content: center; text-align: center; }

/* --- fact rows ("at a Glance") ---------------------------------------------- */
:is(.axl-ui, .axl-episode) .factlist .iconrow { margin-top: 0; padding: 11px 0; gap: 16px; }
:is(.axl-ui, .axl-episode) .factlist .iconrow:first-child { padding-top: 0; }
:is(.axl-ui, .axl-episode) .factlist .iconrow + .iconrow { border-top: 1px solid var(--axl-accent-line, #E3E7F0); }
:is(.axl-ui, .axl-episode) .factlist .axl-ih__icon { --axl-ih-icon-size: 28px; }
:is(.axl-ui, .axl-episode) .factlist .iconrow--stack .axl-ih__text { color: inherit; font-size: 12.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .factlist .axl-ih__note { color: inherit; font-size: 13.5px; line-height: 1.5; letter-spacing: 0; text-transform: none; }

/* --- ticked list ------------------------------------------------------------ */
:is(.axl-ui, .axl-episode) .checks { display: flex; flex-direction: column; gap: 9px; }
:is(.axl-ui, .axl-episode) .checks .iconrow { margin-top: 0; gap: 10px; font-size: 14px; }

/* --- divided icon strip ------------------------------------------------------ */
/* A core/columns block laid out as a grid. Two across on a phone (a divider only
   between the pair), five across from 640px (a divider before every column but the
   first). */
:is(.axl-ui, .axl-episode) .iconstrip.wp-block-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 0; }
:is(.axl-ui, .axl-episode) .iconstrip > .wp-block-column { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 0 12px; text-align: center; border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
:is(.axl-ui, .axl-episode) .iconstrip > .wp-block-column:nth-child(2n+1) { border-left: 0; }
/* The deferred strip is a SINGLE column on a phone. Its items carry a full
   paragraph each, where the base strip's carry a line or two — and two ~170px
   columns of body copy is a column of single words. The dividers go with the
   second column; the 640px block restores both. */
:is(.axl-ui, .axl-episode) .iconstrip--late.wp-block-columns { grid-template-columns: minmax(0, 1fr); }
:is(.axl-ui, .axl-episode) .iconstrip--late > .wp-block-column { border-left: 0; }
/* A SIX-ITEM strip — four of the partnership wireframes run six items where the
   base strip runs five (Where Partnerships Could Take Us, What We Look For, More
   Than a YouTube Series, More Than a Series). Six divides where five does not, so
   these rows do NOT borrow the base strip's track counts: they halve cleanly the
   whole way down, 6 → 3×2 → 2×3 → 1×6, and never leave an orphan on the last row
   the way the base strip's five-across does with a sixth item.

     <480px   one column      (1×6)
     ≥480px   two columns     (2×3)
     ≥640px   three columns   (3×2)
     ≥1080px  six columns

   The ladder is keyed on the ITEM COUNT as well as on `.iconstrip--6`, because a
   pattern's markup is COPIED into post_content when an editor inserts it and never
   updated again. Pages built before the modifier existed carry a bare `.iconstrip`
   with six columns in them, and no edit to patterns/*.php reaches those pages — so
   a class-only ladder leaves exactly the orphan it was written to prevent. The
   `:has()` clause matches a strip whose sixth column is also its last, which is the
   same six rows the modifier names; keep the modifier for markup an editor writes
   by hand, and so the intent stays readable in the pattern source.

   Each band restates BOTH divider rules — every column, then the row-start
   exception — and writes them at the same specificity, with `:nth-child(n)`
   standing in for "every column" purely to match the exception's weight. That is
   what keeps the bands independent: whichever block comes last in the file wins
   outright, instead of a narrower band's `nth-child` leaking a stray hairline into
   a wider one. Keep the pair together, in that order, if you add a band. */
:is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)).wp-block-columns { grid-template-columns: minmax(0, 1fr); }
:is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(n) { border-left: 0; }
/* Below 480px a LABEL-ONLY six keeps the base strip's two-across. The ladder's
   single column is drawn for items carrying a paragraph over an image (More Than a
   Series); `--compact` items are an icon over one word — YouTube, Instagram — and
   a full-width row each is a column of mostly empty space.

   Both rules fold the modifier INTO the `:is()` rather than hanging it off the
   outside, which keeps them at the same specificity as the ladder they follow.
   That is the whole trick: equal weight means source order decides, so this wins
   the base band (it comes later) and loses to the 480/640/1080 bands (they come
   later still) — where a compact six ladders like any other. Hung on the outside
   it would out-weigh every band and pin these strips at two across for good. */
:is(.axl-ui, .axl-episode) :is(.iconstrip--6.iconstrip--compact, .iconstrip--compact:has(> .wp-block-column:nth-child(6):last-child)).wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
:is(.axl-ui, .axl-episode) :is(.iconstrip--6.iconstrip--compact, .iconstrip--compact:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
:is(.axl-ui, .axl-episode) :is(.iconstrip--6.iconstrip--compact, .iconstrip--compact:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(2n+1) { border-left: 0; }
/* A THREE-ITEM strip. The base strip's two-across would leave an orphan on the second
   row, so on a phone it is one column; from 640px it is three across (see the 640px
   band). Keyed on the item count as well as `.iconstrip--3`, for the same reason as
   `--4` and `--6`: post_content is frozen and never sees pattern edits. A LABEL-ONLY
   three (`--compact`: an icon over one word) keeps all three across on a phone, where
   a full-width row each would be mostly empty space. */
:is(.axl-ui, .axl-episode) :is(.iconstrip--3, .iconstrip:has(> .wp-block-column:nth-child(3):last-child)).wp-block-columns { grid-template-columns: minmax(0, 1fr); }
:is(.axl-ui, .axl-episode) :is(.iconstrip--3, .iconstrip:has(> .wp-block-column:nth-child(3):last-child)) > .wp-block-column:nth-child(n) { border-left: 0; }
:is(.axl-ui, .axl-episode) :is(.iconstrip--3.iconstrip--compact, .iconstrip--compact:has(> .wp-block-column:nth-child(3):last-child)).wp-block-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
:is(.axl-ui, .axl-episode) :is(.iconstrip--3.iconstrip--compact, .iconstrip--compact:has(> .wp-block-column:nth-child(3):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
:is(.axl-ui, .axl-episode) :is(.iconstrip--3.iconstrip--compact, .iconstrip--compact:has(> .wp-block-column:nth-child(3):last-child)) > .wp-block-column:first-child { border-left: 0; }
:is(.axl-ui, .axl-episode) .iconstrip .bighead { justify-content: center; }
:is(.axl-ui, .axl-episode) .iconstrip .bighead .axl-ih__icon { --axl-ih-icon-size: 36px; }
:is(.axl-ui, .axl-episode) .iconstrip--compact .bighead .axl-ih__icon { --axl-ih-icon-size: 30px; }
:is(.axl-ui, .axl-episode) .strip__title { margin-top: 4px; font-size: 20px; font-weight: 800; line-height: 1.25; letter-spacing: .03em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .strip__sub { font-size: 12.5px; font-weight: 700; line-height: 1.35; }
:is(.axl-ui, .axl-episode) .strip__text { font-size: 15px; line-height: 1.5; }
:is(.axl-ui, .axl-episode) .iconstrip--compact .strip__title { font-size: 12px; }
:is(.axl-ui, .axl-episode) .iconstrip--compact .strip__text { font-size: 12px; }
/* Pinned to the column's foot, so the images line up whatever the copy length. */
:is(.axl-ui, .axl-episode) .iconstrip .ph { width: 100%; margin-top: auto; padding-top: 10px; }

/* --- three inner panels ----------------------------------------------------- */
:is(.axl-ui, .axl-episode) .trio.wp-block-columns { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; }
:is(.axl-ui, .axl-episode) .trio > .wp-block-column > .subpanel:only-child { height: 100%; }
:is(.axl-ui, .axl-episode) .subpanel { display: flex; flex-direction: column; border: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 12px; overflow: hidden; }
:is(.axl-ui, .axl-episode) .subpanel__title { padding: 10px 14px; background: #F3F4F8; border-bottom: 1px solid var(--axl-accent-line, #E3E7F0); text-align: center; font-size: 13.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .subpanel__body { display: flex; flex: 1; flex-direction: column; gap: 14px; padding: 14px 16px 16px; }
:is(.axl-ui, .axl-episode) .subpanel__body .ph:last-child { margin-top: auto; }
/* The image under the middle panel's title runs edge to edge. */
:is(.axl-ui, .axl-episode) .subpanel__bleed img { border-radius: 0; }

/* --- small inset panel: image beside three lines ------------------------------ */
:is(.axl-ui, .axl-episode) .mini { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 14px; align-items: center; padding: 12px; border: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 12px; }
:is(.axl-ui, .axl-episode) .mini .ph img { border-radius: 8px; }
:is(.axl-ui, .axl-episode) .mini__copy { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; line-height: 1.5; }

/* --- placeholder gallery ----------------------------------------------------- */
:is(.axl-ui, .axl-episode) .phgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
:is(.axl-ui, .axl-episode) .phgrid .ph img { border-radius: 6px; }

/* --- closing band ------------------------------------------------------------ */
:is(.axl-ui, .axl-episode) .band__copy { display: flex; flex-direction: column; gap: 14px; }
:is(.axl-ui, .axl-episode) .band__media .btn-row { margin-top: 14px; }
/* The big outline call to action, full width of its column. */
:is(.axl-ui, .axl-episode) .axl-btn--lg { flex: 1 1 auto; }
:is(.axl-ui, .axl-episode) .axl-btn--lg > .wp-block-button__link { width: 100%; padding: 14px 28px; border-width: 2px; font-size: 15px; }
/* Trailing arrow, painted as a mask like .axl-btn--ext so it takes the link colour. */
:is(.axl-ui, .axl-episode) .axl-btn--arrow > .wp-block-button__link::after {
  content: ""; flex: none; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h16M14 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h16M14 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ---------- ≥640px ---------- */
/* ---------- ≥480px ---------- */
/* The six-strip's first step up: two columns, a divider between the pair only. The
   base strip is already two across below this, so only `--6` has anything to say
   here — hence a breakpoint of its own rather than a line in the shared blocks. */
@media (min-width: 480px) {
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)).wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(2n+1) { border-left: 0; }
}

@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .cardrow.wp-block-columns { gap: 22px; }
  :is(.axl-ui, .axl-episode) :is(.h1, .h2, .h3, .bighead) + .cardrow.wp-block-columns { margin-top: 20px; }
  :is(.axl-ui, .axl-episode) .cardrow.wp-block-columns + .cardrow.wp-block-columns { margin-top: 22px; }
  /* Card-count rows go two-up on a tablet, the way `.cardgrid` does. Without this
     they would inherit `.cardrow`'s single column and a seven-card row would be a
     very long stack at this width. `--cards-1` is deliberately absent: it stays
     one column everywhere. */
  :is(.axl-ui, .axl-episode) .cardrow--cards-2.wp-block-columns,
  :is(.axl-ui, .axl-episode) .cardrow--cards-3.wp-block-columns,
  :is(.axl-ui, .axl-episode) .cardrow--cards-4.wp-block-columns,
  :is(.axl-ui, .axl-episode) .cardrow--cards-5.wp-block-columns,
  :is(.axl-ui, .axl-episode) .cardrow--cards-6.wp-block-columns,
  :is(.axl-ui, .axl-episode) .cardrow--cards-7.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .card--flow { gap: 18px; }
  :is(.axl-ui, .axl-episode) .cardtitle { font-size: 24px; }
  :is(.axl-ui, .axl-episode) .herosub { font-size: 24px; }
  :is(.axl-ui, .axl-episode) .strap { font-size: 13px; }
  :is(.axl-ui, .axl-episode) .introsplit { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 24px; }
  :is(.axl-ui, .axl-episode) .iconstrip.wp-block-columns { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .iconstrip > .wp-block-column:nth-child(2n+1) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) .iconstrip > .wp-block-column:first-child { border-left: 0; }
  /* A FOUR-ITEM strip (job-perks) fills the row instead of leaving the fifth track empty.
     Keyed on the item count as well as `.iconstrip--4`, so pages built before the modifier
     existed are fixed too — their post_content is frozen and never sees pattern edits. */
  :is(.axl-ui, .axl-episode) :is(.iconstrip--4, .iconstrip:has(> .wp-block-column:nth-child(4):last-child)).wp-block-columns { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--4, .iconstrip:has(> .wp-block-column:nth-child(4):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--4, .iconstrip:has(> .wp-block-column:nth-child(4):last-child)) > .wp-block-column:first-child { border-left: 0; }
  /* A THREE-ITEM strip: three across, dividers before every column but the first. */
  :is(.axl-ui, .axl-episode) :is(.iconstrip--3, .iconstrip:has(> .wp-block-column:nth-child(3):last-child)).wp-block-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--3, .iconstrip:has(> .wp-block-column:nth-child(3):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--3, .iconstrip:has(> .wp-block-column:nth-child(3):last-child)) > .wp-block-column:first-child { border-left: 0; }

  /* Three across — the six-strip's middle step, and the reason it stops inheriting
     the base strip here. Five tracks would put five items on the first row and a
     lone sixth on the second; three puts them in an even 3×2. */
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)).wp-block-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(3n+1) { border-left: 0; }

  /* A strip that waits for real width before going five across. The base strip
     turns at 640px, which suits the short titles it was built for ("Compass",
     "Notebook"); a strip whose items are titled in full sentences gets ~140px a
     column in the 640–1080 band and stacks every title three lines deep. This
     modifier holds the two-up — and its divider pattern — until 1080px, where the
     rule below takes over. */
  :is(.axl-ui, .axl-episode) .iconstrip--late.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Restores what the phone rule above took off — it is later in the file than the
     base strip's own border, so it wins at every width until this puts it back. */
  :is(.axl-ui, .axl-episode) .iconstrip--late > .wp-block-column { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) .iconstrip--late > .wp-block-column:nth-child(2n+1) { border-left: 0; }
  :is(.axl-ui, .axl-episode) .iconstrip--compact > .wp-block-column { padding: 0 8px; }
}

/* ---------- ≥1080px ---------- */
/* Two-up rows only once each half can hold copy beside an image. */
@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .cardrow.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px; }
  :is(.axl-ui, .axl-episode) :is(.h1, .h2, .h3, .bighead) + .cardrow.wp-block-columns { margin-top: 24px; }
  :is(.axl-ui, .axl-episode) .cardrow.wp-block-columns + .cardrow.wp-block-columns { margin-top: 26px; }
  :is(.axl-ui, .axl-episode) .cardrow--wide.wp-block-columns { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }

  /* Row presets (patterns/row-*.php). The ratio of a preset row IS a modifier
     class, the same way `--wide` is — a grid ignores the per-column widths core's
     width control writes, so the ratio has to live here. fr units rather than
     percentages: they divide the row exactly, so 33/67 is a true third, and the
     gap comes out of the tracks instead of out of the ratio. Only this breakpoint
     carries a ratio; below it every preset inherits `.cardrow`'s single column. */
  :is(.axl-ui, .axl-episode) .cardrow--100.wp-block-columns   { grid-template-columns: minmax(0, 1fr); }
  :is(.axl-ui, .axl-episode) .cardrow--50-50.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .cardrow--33-67.wp-block-columns { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
  :is(.axl-ui, .axl-episode) .cardrow--67-33.wp-block-columns { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
  :is(.axl-ui, .axl-episode) .cardrow--40-60.wp-block-columns { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); }
  :is(.axl-ui, .axl-episode) .cardrow--60-40.wp-block-columns { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
  :is(.axl-ui, .axl-episode) .cardrow--25-75.wp-block-columns { grid-template-columns: minmax(0, 1fr) minmax(0, 3fr); }
  :is(.axl-ui, .axl-episode) .cardrow--75-25.wp-block-columns { grid-template-columns: minmax(0, 3fr) minmax(0, 1fr); }

  /* Card-count layouts (patterns/cards-*.php). Equal tracks, so the row reads as
     "N cards" rather than as a ratio. Every count stays on ONE row at this
     breakpoint, six and seven included.

     Those two are deliberately dense. A section is full-bleed with a 28px gutter,
     so the row is ~1024px at the 1080px floor: ~149px a card at six across and
     ~124px at seven, against the ~184px that `--5` above calls tight. They open up
     on a real desktop — ~209px and ~175px at 1440px — so the squeeze is confined to
     the 1080–1200px band, where a card's 22px padding leaves seven across about
     80px of content. Trim the padding for these two rows if that proves too tight
     in use; do not reintroduce wrapping, the single row is the point. */
  :is(.axl-ui, .axl-episode) .cardrow--cards-1.wp-block-columns { grid-template-columns: minmax(0, 1fr); }
  :is(.axl-ui, .axl-episode) .cardrow--cards-2.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .cardrow--cards-3.wp-block-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .cardrow--cards-4.wp-block-columns { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .cardrow--cards-5.wp-block-columns { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .cardrow--cards-6.wp-block-columns { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .cardrow--cards-7.wp-block-columns { grid-template-columns: repeat(7, minmax(0, 1fr)); }

  /* At six and seven across a card is ~150px and ~125px wide, and `.bighead` is a
     flex ROW — so the icon eats a third of the first line and the title wraps around
     it in two- and three-word fragments. Stacking and centring it gives the title the
     whole width, which is how the wireframes draw these dense rows (Where the
     Opportunities Could Be, What Could We Explore Together?, Who We Could Work With).
     Scoped to this breakpoint on purpose: below it the same rows are one or two cards
     across, where the inline icon reads correctly and should stay. */
  :is(.axl-ui, .axl-episode) :is(.cardrow--cards-6, .cardrow--cards-7) .card > .bighead {
    flex-direction: column; align-items: center; gap: 8px; text-align: center;
  }
  :is(.axl-ui, .axl-episode) :is(.cardrow--cards-6, .cardrow--cards-7) .card > .bighead .axl-ih__icon { --axl-ih-icon-size: 30px; }
  :is(.axl-ui, .axl-episode) .cardtitle { font-size: 26px; }
  :is(.axl-ui, .axl-episode) .herosub { font-size: 28px; }
  :is(.axl-ui, .axl-episode) .introsplit--hero { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 40px; }
  :is(.axl-ui, .axl-episode) .trio.wp-block-columns { grid-template-columns: minmax(0, 1fr) minmax(0, 1.45fr) minmax(0, 1fr); gap: 20px; }

  /* The deferred strip catches up here, where five columns are ~250px each. */
  :is(.axl-ui, .axl-episode) .iconstrip--late.wp-block-columns { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .iconstrip--late > .wp-block-column:nth-child(2n+1) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) .iconstrip--late > .wp-block-column:first-child { border-left: 0; }

  /* Six across — the top of the ladder, on the same 1080px floor the five-column
     strip uses. A full-bleed section is ~1024px here, so a column is ~170px against
     the base strip's ~205px: tight but workable for a two-word title over a short
     paragraph, which is all these six-item rows carry. If it reads too tight in
     use, raise this band's floor to 1200px and let the 3×2 above hold the gap — the
     two bands already cover each other. */
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)).wp-block-columns { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) :is(.iconstrip--6, .iconstrip:has(> .wp-block-column:nth-child(6):last-child)) > .wp-block-column:nth-child(6n+1) { border-left: 0; }
}

/* ============================================================
   11c. DOWNLOADS PAGE  (patterns/dl-*.php)
   ============================================================ */

/* --- filter bar: two labelled selects and the result count ---------------
   Visual only for now (see dl-filters.php). The selects are real <select>s in a
   core/html block, so they are drawn here from scratch: `appearance: none` drops
   the platform chrome, and the chevron is the same stroke as the icon set. */
:is(.axl-ui, .axl-episode) .dlfilters__bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 16px; }
:is(.axl-ui, .axl-episode) .dlfilter { display: flex; flex-direction: column; gap: 6px; flex: 1 1 200px; min-width: 0; }
:is(.axl-ui, .axl-episode) .dlfilter__label { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #5A6478; }
:is(.axl-ui, .axl-episode) .dlfilter__select {
  -webkit-appearance: none; appearance: none; width: 100%;
  border: 1px solid #9DB4E8; border-radius: 8px; padding: 10px 38px 10px 12px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m6 9 6 6 6-6' stroke='%231245C4' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right 12px center / 14px no-repeat;
  color: #151D40; font: inherit; font-size: 14px; font-weight: 600; line-height: 1.3; cursor: pointer;
}
:is(.axl-ui, .axl-episode) .dlfilter__select:focus-visible { outline: 2px solid #1245C4; outline-offset: 2px; }
/* The count takes a line of its own on a phone and sits at the far end of the
   bar, level with the selects, once they fit side by side. */
:is(.axl-ui, .axl-episode) .dlfilters__count { flex: 1 0 100%; font-size: 13px; }

/* --- resource grid ---------------------------------------------------------
   `.cardgrid` owns the card (flex column, button row pinned to the bottom). What
   is specific here: the PNG / PDF pair share their row evenly, and the grid stays
   two-up beside the sidebar until the main column is wide enough for three —
   `.cardgrid` goes three-up at 1080px on the VIEWPORT, which beside a 320px
   sidebar leaves each card too narrow for two buttons side by side. */
:is(.axl-ui, .axl-episode) .dlbtns { flex-wrap: nowrap; gap: 8px; }
/* `.cardgrid` brings its own top margin for use under a heading; in the page
   `.stack` the stack's gap already spaces it from the filter bar. */
:is(.axl-ui, .axl-episode) .dlgrid.wp-block-columns { margin-top: 0; }
:is(.axl-ui, .axl-episode) .dlbtns > .axl-btn { flex: 1 1 0; min-width: 0; }
:is(.axl-ui, .axl-episode) .dlbtns > .axl-btn > .wp-block-button__link { width: 100%; }

/* Level pills: the three levels keep the wireframe's colours (green, blue,
   purple) so a card's level reads at a glance over any thumbnail. */
:is(.axl-ui, .axl-episode) .dllevel--starter { background: rgba(22, 163, 74, .92); }
:is(.axl-ui, .axl-episode) .dllevel--explorer { background: rgba(18, 69, 196, .92); }
:is(.axl-ui, .axl-episode) .dllevel--advanced { background: rgba(124, 58, 237, .92); }

/* --- permissions band ------------------------------------------------------
   The whole band opens the guidelines popup (site.js), so it says so on hover.
   Its strip holds four items; `.iconstrip` is built for five or six, so it is
   given four even tracks from 640px, with a divider before every item but the
   first. */
:is(.axl-ui, .axl-episode) .dlperms { cursor: pointer; }
:is(.axl-ui, .axl-episode) .dlperms .btn-row { margin-top: 0; }

/* --- guidelines (the popup's content) --------------------------------------
   Hidden in the page on the front end, on any template; site.js lifts it into a
   <dialog>, which is what shows it again. `.axl-front` is a body class the
   editor canvas never has, so the section stays visible there to edit. */
.axl-front :not(.axl-dialog__body) > .dlmodal { display: none; }

:is(.axl-ui, .axl-episode) .dlguide.wp-block-columns { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
:is(.axl-ui, .axl-episode) .dlguide__col { display: flex; flex-direction: column; gap: 14px; }
:is(.axl-ui, .axl-episode) .dlguide__col .checks .iconrow { align-items: flex-start; }
:is(.axl-ui, .axl-episode) .dlguide__col .checks .iconrow + .iconrow { padding-top: 9px; border-top: 1px solid var(--axl-accent-line, #E3E7F0); }
:is(.axl-ui, .axl-episode) .dlguide__col--welcome :is(.bighead, .iconrow) .axl-ih__icon { color: #16A34A; }
:is(.axl-ui, .axl-episode) .dlguide__col--dont :is(.bighead, .iconrow) .axl-ih__icon { color: #DC2626; }
:is(.axl-ui, .axl-episode) .dlguide__col .callout { margin-top: 6px; }
:is(.axl-ui, .axl-episode) .dlguide__cta a { color: #1245C4; font-weight: 700; }
/* The "Need special permission?" contact button sits close under its copy. */
:is(.axl-ui, .axl-episode) .dlguide__cta .btn-row { margin-top: 8px; }

@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .dlfilter { flex: 0 1 240px; }
  :is(.axl-ui, .axl-episode) .dlfilters__count { flex: none; margin-left: auto; padding-bottom: 10px; }

  :is(.axl-ui, .axl-episode) .dlperms .iconstrip.wp-block-columns { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlperms .iconstrip > .wp-block-column:nth-child(n) { border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) .dlperms .iconstrip > .wp-block-column:first-child { border-left: 0; }

  :is(.axl-ui, .axl-episode) .dlguide--2.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
  :is(.axl-ui, .axl-episode) .dlguide.wp-block-columns:not(.dlguide--2) { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; }
  :is(.axl-ui, .axl-episode) .dlguide:not(.dlguide--2) > .wp-block-column { padding: 0 22px; border-left: 1px solid var(--axl-accent-line, #E3E7F0); }
  :is(.axl-ui, .axl-episode) .dlguide:not(.dlguide--2) > .wp-block-column:first-child { padding-left: 0; border-left: 0; }
  :is(.axl-ui, .axl-episode) .dlguide:not(.dlguide--2) > .wp-block-column:last-child { padding-right: 0; }
}

/* Two-up beside the sidebar from 1080px (see above); three-up once the main
   column has the room. */
@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .dlgrid.wp-block-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1280px) {
  :is(.axl-ui, .axl-episode) .dlgrid.wp-block-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- the popup itself -------------------------------------------------------
   A native <dialog> built by site.js: `showModal()` gives the focus trap, Esc to
   close and the ::backdrop for free. The dialog does not scroll — its body does —
   so the close button stays in the corner however long the content runs. */
.axl-dialog { width: min(1100px, calc(100vw - 24px)); max-width: none; max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); padding: 0; border: 0; border-radius: 20px; background: #fff; overflow: hidden; box-shadow: 0 30px 80px -20px rgba(11, 14, 45, .6); }
.axl-dialog[open] { display: flex; flex-direction: column; }
.axl-dialog::backdrop { background: rgba(11, 14, 45, .72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.axl-dialog__body { overflow-y: auto; overscroll-behavior: contain; }
.axl-dialog__body .card--lg { border: 0; border-radius: 0; padding: 24px 20px; }
/* Keeps the title clear of the close button in the corner. */
.axl-dialog__body .cardhead { padding-right: 44px; }
.axl-dialog__close { position: absolute; top: 12px; right: 12px; z-index: 1; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 1px solid #9DB4E8; border-radius: 50%; background: #fff; color: #1245C4; cursor: pointer; }
.axl-dialog__close:hover { background: #F3F4F8; }
.axl-dialog__close:focus-visible { outline: 2px solid #1245C4; outline-offset: 2px; }
/* The page behind a modal should not scroll under it. */
html:has(.axl-dialog[open]) { overflow: hidden; }
@media (min-width: 640px) {
  .axl-dialog__body .card--lg { padding: 32px; }
}

/* ============================================================
   11e. DOWNLOADS BLOCKS  (plugin axl-downloads: episode-downloads, library)
   ============================================================ */

/* The blocks render the same vocabulary as the Downloads page patterns
   (§11c) and the episode Activity Pack (`.dlpack`, section 6) from real
   download posts, so most of their look is already above. What is here is
   what the patterns never needed: the grids are plain divs rather than
   core/columns, a card can lack artwork, a file link carries a size, the
   filter bar gains a submit/reset pair, and an editor's preview of an
   unreleased download is marked as such. The plugin ships no site CSS. */

/* --- grids: the block grids are not .wp-block-columns ----------------------
   `.cardgrid` already supplies the 1/2/3-up steps; `.dlgrid` beside the
   sidebar should hold at two until 1280px exactly as §11c does for the
   pattern, and the block's column setting overrides from 1080px up. */
/* The block wrapper carries `.stack` so its filter card, grid and pager keep
   the page rhythm the pattern got from being three separate blocks. */
:is(.axl-ui, .axl-episode) .dlib > .cardgrid { margin-top: 0; }
:is(.axl-ui, .axl-episode) .dlgrid:not(.wp-block-columns) { margin-top: 0; }
:is(.axl-ui, .axl-episode) .tiles--cols-1 { grid-template-columns: 1fr; }
:is(.axl-ui, .axl-episode) .tiles--list { grid-template-columns: 1fr; gap: 10px; }
:is(.axl-ui, .axl-episode) .tiles--list .tile { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 4px 14px; align-items: center; text-align: left; }
:is(.axl-ui, .axl-episode) .tiles--list .tile .box { grid-row: 1 / span 4; height: 64px; margin-bottom: 0; }
:is(.axl-ui, .axl-episode) .tiles--list .tile .box .bighead { font-size: 22px; }
:is(.axl-ui, .axl-episode) .tiles--list .tile__files { justify-content: flex-start; }

/* --- tiles: the real Activity Pack --------------------------------------
   The pattern linked the whole tile label; the block puts one link per file
   under the title, small and centred, with the size as a quieter run-on. */
:is(.axl-ui, .axl-episode) .tile .box .tile__img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
:is(.axl-ui, .axl-episode) .tile.dl .box { overflow: hidden; }
:is(.axl-ui, .axl-episode) .tile__excerpt { margin-top: 4px; color: #6B7484; font-size: 12px; line-height: 1.4; }
:is(.axl-ui, .axl-episode) .tile__files { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 12px; margin-top: 6px; font-size: 12.5px; font-weight: 600; }
:is(.axl-ui, .axl-episode) .tile__files a { color: #1245C4; text-decoration: none; }
:is(.axl-ui, .axl-episode) .tile__files a:is(:hover, :focus-visible) { text-decoration: underline; }
/* The block's tile title is a real heading (h2–h6 per the block setting),
   so it sheds the heading margins and keeps the tile's 13.5px label type. */
:is(.axl-ui, .axl-episode) .tiles--dl .tile__title { margin: 0 0 4px; line-height: 1.35; letter-spacing: 0; }

/* --- file links -------------------------------------------------------- */
:is(.axl-ui, .axl-episode) .tile .axl-download__size,
:is(.axl-ui, .axl-episode) .axl-download__size { margin-left: 4px; color: #6B7484; font-size: .85em; font-weight: 500; }
:is(.axl-ui, .axl-episode) .axl-btn > .wp-block-button__link .axl-download__size { color: inherit; opacity: .8; }
:is(.axl-ui, .axl-episode) a.axl-download__file:focus-visible { outline: 2px solid #1245C4; outline-offset: 2px; border-radius: 4px; }

/* --- cards: missing artwork, the meta line --------------------------------
   The placeholder is the same 170px box a cover image fills, on the tinted
   ground the logo fallback uses, with the format's document icon centred. */
:is(.axl-ui, .axl-episode) .card .cover .dlcard__placeholder { display: flex; align-items: center; justify-content: center; height: 170px; background: var(--axl-surface-2, #F5F6F9); border-bottom: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 16px 16px 0 0; color: var(--axl-ink, #1A2547); }
:is(.axl-ui, .axl-episode) .dlcard__placeholder svg { width: 48px; height: 48px; opacity: .55; }
/* Several levels share the cover's bottom-right corner as one group: the
   group takes the pill's corner offset, the pills inside flow in a row. */
:is(.axl-ui, .axl-episode) .card .cover .dlcard__levels { position: absolute; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; max-width: calc(100% - 24px); margin: 0; }
:is(.axl-ui, .axl-episode) .dlcard__levels .pill--onimg { position: static; }
:is(.axl-ui, .axl-episode) .dlcard__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; font-size: 12.5px; }
/* A plain pill keeps its light ground in both themes (see cosmic-site.css),
   so it carries its own ink rather than inheriting the card's text colour. */
:is(.axl-ui, .axl-episode) .dlcard__meta .pill { color: #151D40; }
:is(.axl-ui, .axl-episode) .dlcard__meta .dllevel { color: #fff; }
:is(.axl-ui, .axl-episode) .dlcard__episode { color: #1245C4; font-weight: 600; text-decoration: none; }
:is(.axl-ui, .axl-episode) .dlcard__episode:is(:hover, :focus-visible) { text-decoration: underline; }
:is(.axl-ui, .axl-episode) .dlcard .h3 + .dlcard__meta { margin-top: 10px; }
:is(.axl-ui, .axl-episode) .dlcard__meta + p { margin-top: 10px; }
:is(.axl-ui, .axl-episode) .dlgrid__empty { margin: 0; padding: 24px; text-align: center; border: 1px dashed var(--axl-accent-line, #E3E7F0); border-radius: 16px; }

/* --- filter bar: submit and reset ---------------------------------------
   The pattern's bar was visual only; the block's is a form. The pair sits
   level with the selects. The submit is a <button> in .axl-btn clothing, so
   it needs the font reset a link never did. */
:is(.axl-ui, .axl-episode) .dlfilters__form { display: contents; }
:is(.axl-ui, .axl-episode) .dlfilters__actions { display: flex; gap: 8px; align-items: flex-end; }
:is(.axl-ui, .axl-episode) .dlfilters__actions .axl-btn { margin: 0; }
:is(.axl-ui, .axl-episode) .dlfilters__actions button.wp-block-button__link { font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; }
:is(.axl-ui, .axl-episode) .dlfilters__count:focus-visible { outline: 2px solid #1245C4; outline-offset: 4px; border-radius: 4px; }

/* --- unreleased (editor preview of an episode only) ---------------------
   Red from the brand guide's embargo treatment; the word carries the meaning,
   the dashed outline only draws the eye. `.tile span` would otherwise shrink
   and grey the pill, hence the extra weight on the tile form. */
:is(.axl-ui, .axl-episode) .pill--embargo,
:is(.axl-ui, .axl-episode) .tile .pill.pill--embargo { display: inline-block; margin: 4px 0 2px; background: #DC2626; color: #fff; font-size: 9px; }
:is(.axl-ui, .axl-episode) .dlcard__flag { margin-top: 8px; }
:is(.axl-ui, .axl-episode) :is(.dlcard--unreleased, .dl--unreleased) { outline: 2px dashed #DC2626; outline-offset: 3px; }

@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .tiles--cols-2 { grid-template-columns: repeat(2, 1fr); }
  :is(.axl-ui, .axl-episode) .tiles--cols-3 { grid-template-columns: repeat(3, 1fr); }
  :is(.axl-ui, .axl-episode) .tiles--cols-1, :is(.axl-ui, .axl-episode) .tiles--list { grid-template-columns: 1fr; }
  :is(.axl-ui, .axl-episode) .dlgrid--cols-1:not(.wp-block-columns) { grid-template-columns: 1fr; }
}

@media (min-width: 1080px) {
  /* Two-up beside the sidebar, as §11c; the column setting takes over. */
  :is(.axl-ui, .axl-episode) .dlgrid:not(.wp-block-columns) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlgrid--cols-1:not(.wp-block-columns) { grid-template-columns: 1fr; }
  :is(.axl-ui, .axl-episode) .dlgrid--cols-4:not(.wp-block-columns) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (min-width: 1280px) {
  :is(.axl-ui, .axl-episode) .dlgrid:not(.wp-block-columns) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlgrid--cols-1:not(.wp-block-columns) { grid-template-columns: 1fr; }
  :is(.axl-ui, .axl-episode) .dlgrid--cols-2:not(.wp-block-columns) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlgrid--cols-4:not(.wp-block-columns) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ============================================================
   11f. DOWNLOADS PAGE: LEVEL CHOOSER AND EPISODE GROUPS
   (plugin axl-downloads: level-chooser and library blocks)
   ============================================================ */

/* The wireframe's page: three level cards up top, then one card per episode
   holding a level strip and that episode's download cards, or dashed
   "coming soon" tiles. The strip is the theme's `.tabs` (section 7); the
   download cards are `.dlcard` (11c / 11e). What is new is the level card,
   the group header, the tiles and the "more episodes" band. */

/* --- level chooser ------------------------------------------------------- */
:is(.axl-ui, .axl-episode) .dlevels__title { margin: 0 0 12px; font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #151D40; }
:is(.axl-ui, .axl-episode) .dlevels__list { display: grid; grid-template-columns: 1fr; gap: 12px; margin: 0; padding: 0; list-style: none; }
:is(.axl-ui, .axl-episode) .dlevels__list > li { margin: 0; }
:is(.axl-ui, .axl-episode) .dlevels__list > li > .dlevel { height: 100%; box-sizing: border-box; }
:is(.axl-ui, .axl-episode) .dlevel {
  --dlevel-color: #1245C4;
  position: relative; display: grid; grid-template-columns: 52px minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 14px; row-gap: 4px; align-items: center;
  min-height: 44px; padding: 16px 44px 16px 16px; border: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 16px; background: #fff;
  color: #151D40; text-decoration: none; transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
:is(.axl-ui, .axl-episode) .dlevel--starter { --dlevel-color: #16A34A; }
:is(.axl-ui, .axl-episode) .dlevel--explorer { --dlevel-color: #1245C4; }
:is(.axl-ui, .axl-episode) .dlevel--advanced { --dlevel-color: #7C3AED; }
:is(.axl-ui, .axl-episode) .dlevel__icon { grid-row: 1 / span 2; display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: color-mix(in srgb, var(--dlevel-color) 12%, #fff); color: var(--dlevel-color); }
:is(.axl-ui, .axl-episode) .dlevel__icon svg { width: 28px; height: 28px; }
:is(.axl-ui, .axl-episode) .dlevel__name { font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .dlevel__desc { font-size: 13.5px; line-height: 1.4; color: #6B7484; }
:is(.axl-ui, .axl-episode) .dlevel__check { position: absolute; top: 12px; right: 12px; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--dlevel-color); color: #fff; opacity: 0; transform: scale(.6); transition: opacity .15s ease, transform .15s ease; }
:is(.axl-ui, .axl-episode) .dlevel:hover { border-color: #9DB4E8; }
:is(.axl-ui, .axl-episode) .dlevel.is-active { border-color: var(--dlevel-color); box-shadow: inset 0 0 0 1px var(--dlevel-color); background: color-mix(in srgb, var(--dlevel-color) 7%, #fff); }
:is(.axl-ui, .axl-episode) .dlevel.is-active .dlevel__check { opacity: 1; transform: scale(1); }
:is(.axl-ui, .axl-episode) .dlevel:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--dlevel-color); }
:is(.axl-ui, .axl-episode) .dlevels__all { margin: 10px 0 0; font-size: 13px; }
:is(.axl-ui, .axl-episode) .dlevels__all a { color: #1245C4; font-weight: 700; }

/* --- "every download starts with an adventure" band ---------------------- */
:is(.axl-ui, .axl-episode) .dladventure .introsplit--media-first { align-items: center; }
:is(.axl-ui, .axl-episode) .dladventure .introsplit--media-first > .introsplit__media { order: -1; }
:is(.axl-ui, .axl-episode) .dladventure__title { margin: 0; text-transform: uppercase; }

/* --- episode group ------------------------------------------------------- */
:is(.axl-ui, .axl-episode) .dlgroup__head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 10px 18px; }
:is(.axl-ui, .axl-episode) .dlgroup__intro { flex: 1 1 320px; min-width: 0; }
:is(.axl-ui, .axl-episode) .dlgroup__title { margin: 0; font-size: 19px; font-weight: 800; letter-spacing: .02em; text-transform: uppercase; color: #151D40; }
:is(.axl-ui, .axl-episode) .dlgroup__sub { margin: 6px 0 0; font-size: 14px; }
:is(.axl-ui, .axl-episode) .dlgroup__watch { flex: none; margin: 0; }
:is(.axl-ui, .axl-episode) .dlgroup__watch > .wp-block-button__link { gap: 8px; }
:is(.axl-ui, .axl-episode) .dlgroup__watch svg { width: 18px; height: 18px; flex: none; }
/* The strip scrolls sideways on a phone rather than being clipped by the
   page's overflow-x: hidden. */
:is(.axl-ui, .axl-episode) .dlgroup__tabs { margin-top: 16px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; white-space: nowrap; }
:is(.axl-ui, .axl-episode) .dlgroup__tabs::-webkit-scrollbar { display: none; }
:is(.axl-ui, .axl-episode) .dlgroup__tabs .tab { flex: none; text-decoration: none; color: #7A8496; }
:is(.axl-ui, .axl-episode) .dlgroup__tabs .tab.on { color: #1245C4; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid).cardgrid { margin-top: 18px; gap: 14px; }
/* The strip hides cards with the hidden attribute; `.cardgrid .card`'s
   display: flex would otherwise outrank the browser's [hidden] rule. */
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .dlcard[hidden],
:is(.axl-ui, .axl-episode) .dlgroup__soon[hidden] { display: none; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card { padding: 15px; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card .cover { margin: -15px -15px 14px; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card .cover img,
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card .cover .dlcard__placeholder { height: 140px; }
/* Download artwork is A4 portrait, so its cover keeps that shape instead of
   the shared 170px strip. The plugin's `axl-download-card` size is cropped
   to the same 210:297; `cover` only trims art that predates it. */
:is(.axl-ui, .axl-episode) .card.dlcard .cover img,
:is(.axl-ui, .axl-episode) .card.dlcard .cover .dlcard__placeholder { height: auto; aspect-ratio: 210 / 297; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card .h3 { font-size: 15px; margin-top: 0; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card .dlcard__meta { margin-top: 8px; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .card p { font-size: 13px; }
/* Four-up cards are narrow: two file buttons share a row while they fit,
   and stack when they would otherwise break "PDF" across lines. */
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .dlbtns { flex-wrap: wrap; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .dlbtns > .axl-btn { flex: 1 1 calc(50% - 4px); min-width: 96px; }
:is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid) .dlbtns > .axl-btn > .wp-block-button__link { padding-left: 10px; padding-right: 10px; white-space: nowrap; }

/* --- episode page: the Downloads card (Episode Downloads block) ---------- */
/* The episode page wireframe: heading, two intro lines, the three level
   cards (a strip without an "All": choose one, choose it again to clear),
   the four-up cards, and a how-to strip along the foot. */
:is(.axl-ui, .axl-episode) .dlpack__intro { margin: 10px 0 0; font-size: 14px; color: #151D40; }
:is(.axl-ui, .axl-episode) .dlpack__intro--levels { margin-top: 4px; color: #6B7484; }
:is(.axl-ui, .axl-episode) .dlpack__levels { margin-top: 14px; }
:is(.axl-ui, .axl-episode) .dlpack__levels .dlevel { padding: 14px 40px 14px 14px; border-radius: 14px; }
:is(.axl-ui, .axl-episode) .dlpack__levels .dlevel__icon { width: 44px; height: 44px; }
:is(.axl-ui, .axl-episode) .dlpack__levels .dlevel__icon svg { width: 24px; height: 24px; }
:is(.axl-ui, .axl-episode) .dlpack__levels .dlevel__desc { font-size: 13px; }
:is(.axl-ui, .axl-episode) .dlpack__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px; margin-top: 18px; padding: 12px 16px; border-radius: 12px; background: var(--axl-surface-2, #F3F4F8); }
:is(.axl-ui, .axl-episode) .dlpack__how { flex: 1 1 320px; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0; font-size: 13px; line-height: 1.45; color: #151D40; }
:is(.axl-ui, .axl-episode) .dlpack__how-icon { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: #151D40; color: #fff; }
:is(.axl-ui, .axl-episode) .dlpack__how-icon svg { width: 16px; height: 16px; }
:is(.axl-ui, .axl-episode) .dlpack__how-label { font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .dlpack__how-text { flex: 1 1 220px; min-width: 0; }
:is(.axl-ui, .axl-episode) .dlpack__free { flex: none; display: flex; align-items: center; gap: 8px; margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #16A34A; }
:is(.axl-ui, .axl-episode) .dlpack__free svg { width: 22px; height: 22px; }

/* --- "coming soon" tiles ------------------------------------------------- */
:is(.axl-ui, .axl-episode) .dlgroup__soon { display: grid; grid-template-columns: 1fr; gap: 14px; margin-top: 18px; }
:is(.axl-ui, .axl-episode) .dlsoon { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; min-height: 150px; padding: 18px 14px; border: 1px dashed #C9D0DE; border-radius: 16px; background: #FAFBFD; color: #6B7484; text-align: center; }
:is(.axl-ui, .axl-episode) .dlsoon__icon { color: #9DB4E8; }
:is(.axl-ui, .axl-episode) .dlsoon__icon svg { width: 36px; height: 36px; }
:is(.axl-ui, .axl-episode) .dlsoon__text { font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; line-height: 1.4; }
:is(.axl-ui, .axl-episode) .dlsoon__lock { color: #9DB4E8; }
:is(.axl-ui, .axl-episode) .dlsoon__lock svg { width: 16px; height: 16px; }

/* --- "more episodes" band ------------------------------------------------ */
/* Bootstrap's .card is a column flex box; the band is a row. */
:is(.axl-ui, .axl-episode) .dlmore { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
:is(.axl-ui, .axl-episode) .dlmore__icon { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; background: var(--axl-surface-2, #F3F4F8); color: #1245C4; }
:is(.axl-ui, .axl-episode) .dlmore__body { flex: 1 1 240px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
:is(.axl-ui, .axl-episode) .dlmore__link { font-size: 14px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: #1245C4; text-decoration: none; }
:is(.axl-ui, .axl-episode) a.dlmore__link:is(:hover, :focus-visible) { text-decoration: underline; }
:is(.axl-ui, .axl-episode) .dlmore__link--static { color: #151D40; }
:is(.axl-ui, .axl-episode) .dlmore__text { font-size: 13px; }
:is(.axl-ui, .axl-episode) .dlmore__newer { font-size: 13px; font-weight: 700; color: #1245C4; }
:is(.axl-ui, .axl-episode) .dlmore__chev { flex: none; width: 24px; height: 24px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m6 9 6 6 6-6' stroke='%231245C4' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat; }

@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .dlevels__list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
  :is(.axl-ui, .axl-episode) .dlgroup__soon { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlgroup__soon.dlgrid--cols-1 { grid-template-columns: 1fr; }
}

@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .dladventure .introsplit--media-first { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 32px; }
  :is(.axl-ui, .axl-episode) .dlgroup__soon { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlgroup__soon.dlgrid--cols-1 { grid-template-columns: 1fr; }
  :is(.axl-ui, .axl-episode) .dlgroup__soon.dlgrid--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .dlgroup__soon.dlgrid--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Inside a group card the 4-up grid takes over from the sidebar-aware
     2-up of §11e, because the page is the downloads page itself. */
  :is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid).dlgrid--cols-4:not(.wp-block-columns) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) :is(.dlgroup__grid, .dlpack__grid).dlgrid--cols-3:not(.wp-block-columns) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ============================================================
   11d. PRESS RELEASES  (home.php, archive.php, single.php)

   Core Posts, drawn with the Media & Press page's cards. The archive is a
   `.stack` of an intro card, the episode archive's `.cardgrid` and the press
   band; a single release is the episode page's `.layout`. Only what those
   primitives have no answer for is here: the post card's category line, the
   pager, and `.entry` — reading rhythm for content written freely in the block
   editor rather than built from pattern classes.
   ============================================================ */

/* The `.stack` gap already spaces the grid from the intro card. */
:is(.axl-ui, .axl-episode) .axl-blog .stack > .cardgrid { margin-top: 0; }
/* Crumbs inside the intro card sit on the copy column's own gap. */
:is(.axl-ui, .axl-episode) .introsplit__copy .crumbs { margin-bottom: 0; }
:is(.axl-ui, .axl-episode) .crumbs a { color: inherit; text-decoration: none; }
:is(.axl-ui, .axl-episode) .crumbs a:hover { color: #1245C4; text-decoration: underline; }

/* The feed block: grid, then page links, on the page's own rhythm. */
:is(.axl-ui, .axl-episode) .postfeed { display: flex; flex-direction: column; gap: 18px; }
/* Landing on #releases from a page link: stop short of the top edge. */
:is(.axl-ui, .axl-episode) .postfeed { scroll-margin-top: 24px; }
:is(.axl-ui, .axl-episode) .postfeed > .cardgrid { margin-top: 0; }

/* ---- the card ----------------------------------------------------------- */
:is(.axl-ui, .axl-episode) .postcard__cat { color: var(--axl-accent, #1245C4); }
:is(.axl-ui, .axl-episode) .postcard__cat + .h3 { margin-top: 6px; }
/* A cardgrid card is a flex column, so its paragraph gets no flow margin. */
:is(.axl-ui, .axl-episode) .cardgrid .card .h3 + p { margin-top: 10px; }

/* ---- pager (axl_post_pager() in functions.php) --------------------------
   Newer / Older are the site's own buttons — outline and solid, 8px radius,
   tracked caps, the arrow mark .axl-btn--arrow uses — pinned to either end.
   The numbers sit between them in one rounded track, the current page filled.
   On a phone the track gives way to "Page 2 of 3" and the buttons keep their
   ends, so the row never wraps. */
:is(.axl-ui, .axl-episode) .pagerbar {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
  padding: 6px 0;
}
:is(.axl-ui, .axl-episode) .pagerbar__step {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 46px; padding: 0 22px; border: 1px solid #9DB4E8; border-radius: 8px;
  background: #fff; color: #1245C4;
  font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .15s ease;
}
:is(.axl-ui, .axl-episode) .pagerbar__step--prev { justify-self: start; }
:is(.axl-ui, .axl-episode) .pagerbar__step--next { justify-self: end; background: #1245C4; border-color: #1245C4; color: #fff; }
:is(.axl-ui, .axl-episode) .pagerbar__step::before,
:is(.axl-ui, .axl-episode) .pagerbar__step::after {
  content: none; flex: none; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h16M14 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h16M14 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform .15s ease;
}
:is(.axl-ui, .axl-episode) .pagerbar__step--prev::before { content: ""; transform: scaleX(-1); }
:is(.axl-ui, .axl-episode) .pagerbar__step--next::after { content: ""; }
:is(.axl-ui, .axl-episode) a.pagerbar__step--prev:is(:hover, :focus-visible) { background: #E1E6F2; }
:is(.axl-ui, .axl-episode) a.pagerbar__step--next:is(:hover, :focus-visible) { background: #0F3AA8; border-color: #0F3AA8; }
/* The arrow leans the way the button goes. */
:is(.axl-ui, .axl-episode) a.pagerbar__step--prev:hover::before { transform: scaleX(-1) translateX(3px); }
:is(.axl-ui, .axl-episode) a.pagerbar__step--next:hover::after { transform: translateX(3px); }
:is(.axl-ui, .axl-episode) .pagerbar__step.is-disabled { opacity: .35; cursor: default; }

:is(.axl-ui, .axl-episode) .pagerbar__pages {
  display: none; align-items: center; gap: 4px; padding: 5px;
  border: 1px solid var(--axl-accent-line, #E3E7F0); border-radius: 999px; background: #fff;
}
:is(.axl-ui, .axl-episode) .pagerbar__num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 999px;
  color: #1A2547; font-size: 14px; font-weight: 700; text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
:is(.axl-ui, .axl-episode) a.pagerbar__num:is(:hover, :focus-visible) { background: #EEF2FC; color: #1245C4; }
:is(.axl-ui, .axl-episode) .pagerbar__num.is-current { background: #1245C4; color: #fff; box-shadow: 0 6px 16px -6px rgba(18, 69, 196, .6); }
:is(.axl-ui, .axl-episode) .pagerbar__gap { width: 22px; text-align: center; color: #6B7484; }
:is(.axl-ui, .axl-episode) .pagerbar__count { color: #6B7484; font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; }
:is(.axl-ui, .axl-episode) :is(.pagerbar__step, .pagerbar__num):focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px #1245C4; }

/* Narrow phones: the labels go, the arrows stay. */
@media (max-width: 419px) {
  :is(.axl-ui, .axl-episode) .pagerbar__step { padding: 0 14px; font-size: 0; gap: 0; }
}
@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .pagerbar__pages { display: inline-flex; }
  :is(.axl-ui, .axl-episode) .pagerbar__count { display: none; }
}

/* ---- a single release --------------------------------------------------- */
:is(.axl-ui, .axl-episode) .axl-blog > .crumbs { margin-bottom: 18px; }
:is(.axl-ui, .axl-episode) .postsingle__meta { display: flex; flex-wrap: wrap; gap: 8px; color: var(--axl-accent, #1245C4); }
:is(.axl-ui, .axl-episode) .postsingle__meta a { color: inherit; text-decoration: none; }
:is(.axl-ui, .axl-episode) .postsingle__meta a:hover { text-decoration: underline; }
/* A release headline runs to two or three lines, which the hero's uppercase at
   line-height 1 was never drawn for. Same weight and colour, sentence case. */
:is(.axl-ui, .axl-episode) .postsingle .introsplit__copy .h1 { font-size: 30px; line-height: 1.15; text-transform: none; }
:is(.axl-ui, .axl-episode) .postsingle__standfirst { max-width: none; }
:is(.axl-ui, .axl-episode) .postsingle__image img { width: 100%; height: auto; border-radius: 12px; }
/* The closing boilerplate, ruled off from the release above it. */
:is(.axl-ui, .axl-episode) .postsingle__about { display: flex; flex-direction: column; gap: 12px; padding-top: 20px; border-top: 1px solid var(--axl-accent-line, #E3E7F0); }

/* `.entry`: whatever the block editor writes. The scope's reset zeroes every
   margin, so the flow is declared here — one rhythm between blocks, more above
   a heading. Direct children only, so a block's own inner layout is untouched. */
:is(.axl-ui, .axl-episode) .entry > * + * { margin-top: 1em; }
:is(.axl-ui, .axl-episode) .entry > :is(h2, h3, h4) { margin-top: 1.6em; color: #151D40; font-weight: 800; line-height: 1.25; letter-spacing: -.005em; }
:is(.axl-ui, .axl-episode) .entry > h2 { font-size: 22px; text-transform: uppercase; }
:is(.axl-ui, .axl-episode) .entry > h3 { font-size: 19px; }
:is(.axl-ui, .axl-episode) .entry > h4 { font-size: 17px; }
:is(.axl-ui, .axl-episode) .entry a { color: #1245C4; text-decoration: underline; text-underline-offset: 2px; }
:is(.axl-ui, .axl-episode) .entry :is(ul, ol) { padding-left: 1.4em; }
:is(.axl-ui, .axl-episode) .entry li + li { margin-top: .35em; }
:is(.axl-ui, .axl-episode) .entry blockquote { border-left: 3px solid var(--axl-accent, #1245C4); padding: 4px 0 4px 18px; font-size: 18px; font-style: italic; }
:is(.axl-ui, .axl-episode) .entry blockquote cite { display: block; margin-top: 8px; font-size: 14px; font-style: normal; font-weight: 700; }
:is(.axl-ui, .axl-episode) .entry img { height: auto; border-radius: 12px; }
:is(.axl-ui, .axl-episode) .entry figcaption { margin-top: 8px; color: #6B7484; font-size: 13px; line-height: 1.6; }
:is(.axl-ui, .axl-episode) .entry hr { border: 0; border-top: 1px solid var(--axl-accent-line, #E3E7F0); opacity: 1; }

/* ---- sidebar: more releases -------------------------------------------- */
:is(.axl-ui, .axl-episode) .postlist { list-style: none; padding: 0; display: flex; flex-direction: column; }
:is(.axl-ui, .axl-episode) .postlist li { display: flex; flex-direction: column; gap: 3px; padding: 11px 0; border-bottom: 1px solid #EAEDF3; }
:is(.axl-ui, .axl-episode) .postlist li:first-child { padding-top: 0; }
:is(.axl-ui, .axl-episode) .postlist a { color: #151D40; font-weight: 700; line-height: 1.35; text-decoration: none; }
:is(.axl-ui, .axl-episode) .postlist a:hover { color: #1245C4; text-decoration: underline; }
:is(.axl-ui, .axl-episode) .postlist time { font-size: 12.5px; }

@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .postsingle .introsplit__copy .h1 { font-size: 38px; }
  :is(.axl-ui, .axl-episode) .axl-blog > .crumbs { margin-bottom: 22px; }
}
@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .postsingle.card--lg { padding: 32px; }
  :is(.axl-ui, .axl-episode) .postsingle .introsplit__copy .h1 { font-size: 42px; }
  :is(.axl-ui, .axl-episode) .axl-blog > .crumbs { margin-bottom: 26px; }
}

/* ============================================================
   11g. WORLD RULES  (patterns/section-world-rules.php)
   ============================================================ */

/* Story beside the three rules. `.grid2` does the split; this only spaces it
   from the title and narrows the 5rem desktop gutter, which is sized for a
   video and leaves the callouts looking detached from the copy. */
:is(.axl-ui, .axl-episode) .worldrules__split { margin-top: 20px; align-items: start; }
:is(.axl-ui, .axl-episode) .worldrules__rules { display: flex; flex-direction: column; gap: 12px; }
/* Callouts here are a feature, not a footnote: reading size and more padding
   than the 13.5px furniture default. */
:is(.axl-ui, .axl-episode) .worldrules .callout { gap: 18px; padding: 16px 20px; border-radius: 14px; font-size: 15px; }
:is(.axl-ui, .axl-episode) .worldrules .callout p { margin: 0; }

/* The five laws. Placeholder tint matches `.ph` so an unpicked image reads as a
   slot, not a broken image. */
:is(.axl-ui, .axl-episode) .worldrules .cardgrid { margin-top: 26px; }
:is(.axl-ui, .axl-episode) .worldrules .cover img[src$="placeholder.svg"] { background: #EEF0F5; }
:is(.axl-ui, .axl-episode) .worldrules__law { margin: 0; font-size: 15px; line-height: 1.35; }

/* Closing statement, centred under a rule. */
:is(.axl-ui, .axl-episode) .worldrules .hr { margin: 28px 0 22px; }
:is(.axl-ui, .axl-episode) .worldrules__close { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; }
/* The statement is a heading, sized on the .h2 scale (26 / 30 / 34) one step
   under the section title; the strapline steps up from tracked-caps furniture
   to body-copy size, bold. */
:is(.axl-ui, .axl-episode) .worldrules__close .h3 { margin: 0; max-width: 30em; font-size: 24px; font-weight: 800; line-height: 1.25; text-wrap: balance; }
:is(.axl-ui, .axl-episode) .worldrules__close .strap { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: .04em; }
@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .worldrules__close .h3 { font-size: 28px; }
}

/* The five tiles step down 5 → 3 / 2 → 2 / 2 / 1 → stacked.
   Each step runs on twice as many tracks as tiles per row, every tile spanning
   two, so a short last row can be centred by starting it one track in: a pair
   under three starts at track 2, a single under two at track 2, a single under
   three at track 3. Keyed on `.worldrules` rather than a modifier class, so it
   reaches sections already inserted (see the note on pattern classes). */
@media (min-width: 480px) and (max-width: 767.98px) {
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid > * { grid-column: span 2; }
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid > :nth-child(odd):last-child { grid-column: 2 / span 2; }
}
@media (min-width: 768px) and (max-width: 1079.98px) {
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid > * { grid-column: span 2; }
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid > :nth-child(3n+1):nth-last-child(2) { grid-column: 2 / span 2; }
  :is(.axl-ui, .axl-episode) .worldrules .cardgrid > :nth-child(3n+1):last-child { grid-column: 3 / span 2; }
}
@media (min-width: 1080px) {
  :is(.axl-ui, .axl-episode) .worldrules__split { gap: 3rem; }
  :is(.axl-ui, .axl-episode) .worldrules__close .h3 { font-size: 30px; }
}

/* ============================================================
   12. ACCENTS  (Group block style: Blue / Green / Red / Purple)
   ============================================================ */

/* Two custom properties carry an accent, and only two:

     --axl-accent       icons and headings — the ink of the group
     --axl-accent-line  the card hairline, a pale wash of the same hue

   Every rule that used to hard-code one of those colours now reads the property
   with its own colour as the fallback, so an un-accented page renders exactly as
   before and each tone (--ink, --muted, --green) keeps its own default. Adding a
   colour is one line here plus one entry in axl_group_accents().

   They inherit, which is the whole design: set an accent on a section's root
   group and every card, heading and icon inside follows; set it on one card and
   only that card moves.

   Both selector forms again — a section's root group carries `.axl-ui` AND the
   style class on the same element, so a descendant selector alone would miss
   exactly the case that matters most (see the note in section 1). */

:is(.axl-ui, .axl-episode).is-style-axl-blue,
:is(.axl-ui, .axl-episode) .is-style-axl-blue { --axl-accent: #1245C4; --axl-accent-line: #CBD6F2; }

:is(.axl-ui, .axl-episode).is-style-axl-green,
:is(.axl-ui, .axl-episode) .is-style-axl-green { --axl-accent: #16A34A; --axl-accent-line: #CCEBD7; }

:is(.axl-ui, .axl-episode).is-style-axl-red,
:is(.axl-ui, .axl-episode) .is-style-axl-red { --axl-accent: #DC2626; --axl-accent-line: #F7CFCF; }

:is(.axl-ui, .axl-episode).is-style-axl-purple,
:is(.axl-ui, .axl-episode) .is-style-axl-purple { --axl-accent: #7C3AED; --axl-accent-line: #E2D4FB; }

/* ============================================================
   13. EDITOR ONLY

   Because this is a classic theme (no theme.json), WordPress caps EVERY block in
   the canvas at 840px — `html :where(.wp-block)` in classic.min.css. These are
   full-width designs whose two-column layout needs 1080px, so the canvas always
   fell back to the tablet breakpoints however big the screen was. The cap has to
   come off the whole subtree, not just the root: leave it on the nested blocks
   and the layout renders 840px wide inside a full-width root.
   (`:where()` contributes no specificity, so two classes beat it easily.)
   ============================================================ */
:is(.axl-ui, .axl-episode).wp-block,
:is(.axl-ui, .axl-episode) .wp-block,
:is(.axl-ui, .axl-episode).block-editor-block-list__block,
:is(.axl-ui, .axl-episode) .block-editor-block-list__block { max-width: none; }

/* ============================================================
   Forms — .axl-form
   ------------------------------------------------------------
   One set of field styles for every form on the site (contact, enquiries, job
   applications). Everything is driven by the --f-* tokens set on .axl-form, so
   the dark skin (cosmic-site.css) only has to reassign tokens, not restyle each
   control. Light paper is the default; put the form inside a .card.

   Markup contract (see patterns/form-test.php for every element):
     .axl-form__field   label + control + optional .axl-form__hint / __error
     .axl-form__row     two fields side by side from 640px
     .axl-form__group   a fieldset: legend + a stack of .axl-form__choice
     .axl-form__choice  one checkbox / radio / switch with its label
     .is-invalid / .is-valid on the control for validation state
     .axl-form__btn     native buttons (--secondary, --ghost)
   ============================================================ */
:is(.axl-ui, .axl-episode) .axl-form {
  --f-ink: #1A2547;
  --f-label: #1A2547;
  --f-muted: #6B7484;
  --f-bg: #fff;
  --f-bg-disabled: #F3F4F8;
  --f-line: #D9DDE6;
  --f-line-hover: #B4BCCD;
  --f-focus: #1245C4;
  --f-focus-ring: rgba(18, 69, 196, .18);
  --f-accent: #1245C4;
  --f-accent-ink: #fff;
  --f-error: #C2253D;
  --f-ok: #17803D;
  --f-ok-ink: #fff;
  --f-track: #D9DDE6;
  --f-placeholder: #98A1B3;
  --f-radius: 8px;
  --f-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='m6 9 6 6 6-6' stroke='%231245C4' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --f-tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m3.5 8.5 3 3 6-7' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  display: flex; flex-direction: column; gap: 20px;
  color: var(--f-ink); font-size: 14px; line-height: 1.45; text-align: left;
}
:is(.axl-ui, .axl-episode) .axl-form *,
:is(.axl-ui, .axl-episode) .axl-form *::before,
:is(.axl-ui, .axl-episode) .axl-form *::after { box-sizing: border-box; }

/* Layout. */
:is(.axl-ui, .axl-episode) .axl-form__field { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0; }
:is(.axl-ui, .axl-episode) .axl-form__row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
@media (min-width: 640px) {
  :is(.axl-ui, .axl-episode) .axl-form__row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
:is(.axl-ui, .axl-episode) .axl-form__group { margin: 0; padding: 0; border: 0; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
:is(.axl-ui, .axl-episode) .axl-form__section { margin: 0; padding: 18px 0 0; border: 0; border-top: 1px solid var(--f-line); min-width: 0; display: flex; flex-direction: column; gap: 20px; }
:is(.axl-ui, .axl-episode) .axl-form__section > legend { padding: 0 10px 0 0; float: left; width: 100%; margin-bottom: 2px; font-size: 12.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--f-muted); }
:is(.axl-ui, .axl-episode) .axl-form__section > legend + * { clear: both; }
:is(.axl-ui, .axl-episode) .axl-form__actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* Labels, legends, hints, errors. */
:is(.axl-ui, .axl-episode) .axl-form label,
:is(.axl-ui, .axl-episode) .axl-form__label { font-size: 13px; font-weight: 700; color: var(--f-label); }
:is(.axl-ui, .axl-episode) .axl-form__group > legend { padding: 0; margin-bottom: 8px; font-size: 13px; font-weight: 700; color: var(--f-label); }
:is(.axl-ui, .axl-episode) .axl-form__req { color: var(--f-error); margin-left: 2px; font-weight: 700; }
:is(.axl-ui, .axl-episode) .axl-form__opt { color: var(--f-muted); font-weight: 400; margin-left: 4px; }
:is(.axl-ui, .axl-episode) .axl-form__hint { margin: 0; font-size: 12.5px; color: var(--f-muted); }
:is(.axl-ui, .axl-episode) .axl-form__error { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--f-error); }
:is(.axl-ui, .axl-episode) .axl-form__ok { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--f-ok); }

/* Text-like controls. */
:is(.axl-ui, .axl-episode) .axl-form :is(
  input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="reset"], [type="button"], [type="image"], [type="hidden"]),
  textarea, select
) {
  width: 100%; min-width: 0; margin: 0;
  border: 1px solid var(--f-line); border-radius: var(--f-radius);
  background-color: var(--f-bg); color: var(--f-ink);
  padding: 11px 14px; font: inherit; font-size: 14px; line-height: 1.45;
  appearance: none; -webkit-appearance: none;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
:is(.axl-ui, .axl-episode) .axl-form textarea { min-height: 140px; resize: vertical; }
:is(.axl-ui, .axl-episode) .axl-form ::placeholder { color: var(--f-placeholder); opacity: 1; }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select):hover:not(:disabled, :focus) { border-color: var(--f-line-hover); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select):focus { outline: none; border-color: var(--f-focus); box-shadow: 0 0 0 3px var(--f-focus-ring); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select):focus-visible { outline: 2px solid transparent; }

/* Select: a drawn chevron in place of the platform arrow. */
:is(.axl-ui, .axl-episode) .axl-form select:not([multiple], [size]) {
  padding-right: 40px; cursor: pointer;
  background-image: var(--f-chevron); background-repeat: no-repeat; background-position: right 14px center; background-size: 14px;
}
:is(.axl-ui, .axl-episode) .axl-form select[multiple],
:is(.axl-ui, .axl-episode) .axl-form select[size] { padding: 6px; min-height: 120px; }
:is(.axl-ui, .axl-episode) .axl-form select option,
:is(.axl-ui, .axl-episode) .axl-form select optgroup { color: #151D40; background: #fff; }
/* A list box draws its options on the field itself, so they take its ink and the
   selected ones a tint of the accent; the dropdown version above stays on white. */
:is(.axl-ui, .axl-episode) .axl-form select:is([multiple], [size]) option { padding: 6px 8px; border-radius: 5px; background: transparent; color: var(--f-ink); }
:is(.axl-ui, .axl-episode) .axl-form select:is([multiple], [size]) option:checked { background: var(--f-accent) linear-gradient(0deg, var(--f-accent), var(--f-accent)); color: var(--f-accent-ink); }

/* Date and time: keep the native picker, tint its icon to the ink. */
:is(.axl-ui, .axl-episode) .axl-form :is(input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"]) { min-height: 44px; }
:is(.axl-ui, .axl-episode) .axl-form input::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .7; }
:is(.axl-ui, .axl-episode) .axl-form input[type="search"]::-webkit-search-cancel-button { cursor: pointer; }

/* States. */
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select):is(:disabled, [readonly]) { background-color: var(--f-bg-disabled); color: var(--f-muted); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select):disabled { cursor: not-allowed; opacity: .7; }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select).is-invalid,
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select)[aria-invalid="true"] { border-color: var(--f-error); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select).is-invalid:focus,
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select)[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--f-error) 22%, transparent); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select).is-valid { border-color: var(--f-ok); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select).is-valid:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--f-ok) 22%, transparent); }

/* Checkbox, radio and switch share one row layout. */
:is(.axl-ui, .axl-episode) .axl-form__choice { display: flex; align-items: flex-start; gap: 10px; margin: 0; }
:is(.axl-ui, .axl-episode) .axl-form__choice label { font-weight: 400; font-size: 14px; color: var(--f-ink); cursor: pointer; padding-top: 1px; }
:is(.axl-ui, .axl-episode) .axl-form__choice :is(input:disabled) + label { color: var(--f-muted); cursor: not-allowed; }
:is(.axl-ui, .axl-episode) .axl-form__choices--inline { flex-direction: row; flex-wrap: wrap; gap: 10px 24px; }

:is(.axl-ui, .axl-episode) .axl-form :is(input[type="checkbox"], input[type="radio"]) {
  flex: 0 0 auto; width: 20px; height: 20px; margin: 0; padding: 0;
  border: 1.5px solid var(--f-line-hover); background-color: var(--f-bg);
  appearance: none; -webkit-appearance: none; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
:is(.axl-ui, .axl-episode) .axl-form input[type="checkbox"]:not([role="switch"]) { border-radius: 5px; background-position: center; background-repeat: no-repeat; background-size: 14px; }
:is(.axl-ui, .axl-episode) .axl-form input[type="radio"] { border-radius: 50%; }
:is(.axl-ui, .axl-episode) .axl-form input[type="checkbox"]:not([role="switch"]):checked { background-color: var(--f-accent); border-color: var(--f-accent); background-image: var(--f-tick); }
:is(.axl-ui, .axl-episode) .axl-form input[type="checkbox"]:not([role="switch"]):indeterminate { background-color: var(--f-accent); border-color: var(--f-accent); background-image: linear-gradient(var(--f-accent-ink), var(--f-accent-ink)); background-size: 10px 2px; }
:is(.axl-ui, .axl-episode) .axl-form input[type="radio"]:checked { border-color: var(--f-accent); background-color: var(--f-accent); box-shadow: inset 0 0 0 4px var(--f-bg); }
:is(.axl-ui, .axl-episode) .axl-form :is(input[type="checkbox"], input[type="radio"]):hover:not(:disabled, :checked) { border-color: var(--f-accent); }
:is(.axl-ui, .axl-episode) .axl-form :is(input[type="checkbox"], input[type="radio"]):focus-visible { outline: none; box-shadow: 0 0 0 3px var(--f-focus-ring); border-color: var(--f-focus); }
:is(.axl-ui, .axl-episode) .axl-form input[type="radio"]:checked:focus-visible { box-shadow: inset 0 0 0 4px var(--f-bg), 0 0 0 3px var(--f-focus-ring); }
:is(.axl-ui, .axl-episode) .axl-form :is(input[type="checkbox"], input[type="radio"]):disabled { opacity: .5; cursor: not-allowed; }
:is(.axl-ui, .axl-episode) .axl-form :is(input[type="checkbox"], input[type="radio"]).is-invalid { border-color: var(--f-error); }

/* Switch: a checkbox with role="switch". */
:is(.axl-ui, .axl-episode) .axl-form input[type="checkbox"][role="switch"] {
  width: 40px; height: 22px; border-radius: 999px; border-color: transparent; background-color: var(--f-track);
  background-image: radial-gradient(circle at center, #fff 0 8px, transparent 8.5px); background-repeat: no-repeat; background-size: 22px 22px; background-position: left center;
  transition: background-color .15s ease, background-position .15s ease, box-shadow .15s ease;
}
:is(.axl-ui, .axl-episode) .axl-form input[type="checkbox"][role="switch"]:checked { background-color: var(--f-accent); background-position: right center; }

/* Range. */
:is(.axl-ui, .axl-episode) .axl-form input[type="range"] { width: 100%; height: 22px; margin: 0; padding: 0; background: none; cursor: pointer; }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]::-webkit-slider-runnable-track { height: 6px; border-radius: 999px; background: var(--f-track); }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]::-moz-range-track { height: 6px; border-radius: 999px; background: var(--f-track); }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -7px; border: 2px solid #fff; border-radius: 50%; background: var(--f-accent); box-shadow: 0 1px 4px rgba(0, 0, 0, .35); }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]::-moz-range-thumb { width: 16px; height: 16px; border: 2px solid #fff; border-radius: 50%; background: var(--f-accent); box-shadow: 0 1px 4px rgba(0, 0, 0, .35); }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]:focus-visible { outline: none; }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--f-focus-ring); }
:is(.axl-ui, .axl-episode) .axl-form input[type="range"]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--f-focus-ring); }
:is(.axl-ui, .axl-episode) .axl-form output { font-weight: 700; color: var(--f-accent); }

/* Colour swatch. */
:is(.axl-ui, .axl-episode) .axl-form input[type="color"] { width: 56px; height: 44px; padding: 4px; border: 1px solid var(--f-line); border-radius: var(--f-radius); background: var(--f-bg); cursor: pointer; }
:is(.axl-ui, .axl-episode) .axl-form input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
:is(.axl-ui, .axl-episode) .axl-form input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 5px; }
:is(.axl-ui, .axl-episode) .axl-form input[type="color"]::-moz-color-swatch { border: 0; border-radius: 5px; }

/* File upload: the native button restyled as a secondary button. */
:is(.axl-ui, .axl-episode) .axl-form input[type="file"] { width: 100%; padding: 8px; border: 1px dashed var(--f-line-hover); border-radius: var(--f-radius); background: var(--f-bg); color: var(--f-muted); font: inherit; font-size: 13px; cursor: pointer; }
:is(.axl-ui, .axl-episode) .axl-form input[type="file"]::file-selector-button { margin-right: 12px; border: 1px solid var(--f-accent); border-radius: 6px; background: transparent; color: var(--f-accent); padding: 7px 14px; font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; cursor: pointer; transition: background-color .15s ease, color .15s ease; }
:is(.axl-ui, .axl-episode) .axl-form input[type="file"]::file-selector-button:hover { background: var(--f-accent); color: var(--f-accent-ink); }
:is(.axl-ui, .axl-episode) .axl-form input[type="file"]:focus-visible { outline: none; border-color: var(--f-focus); box-shadow: 0 0 0 3px var(--f-focus-ring); }

/* Progress and meter, for upload / strength read-outs. */
:is(.axl-ui, .axl-episode) .axl-form :is(progress, meter) { width: 100%; height: 10px; border: 0; border-radius: 999px; background: var(--f-track); overflow: hidden; appearance: none; -webkit-appearance: none; }
:is(.axl-ui, .axl-episode) .axl-form progress::-webkit-progress-bar,
:is(.axl-ui, .axl-episode) .axl-form meter::-webkit-meter-bar { background: var(--f-track); border: 0; border-radius: 999px; }
:is(.axl-ui, .axl-episode) .axl-form progress::-webkit-progress-value { background: var(--f-accent); border-radius: 999px; }
:is(.axl-ui, .axl-episode) .axl-form progress::-moz-progress-bar { background: var(--f-accent); border-radius: 999px; }
:is(.axl-ui, .axl-episode) .axl-form meter::-webkit-meter-optimum-value { background: var(--f-ok); border-radius: 999px; }
:is(.axl-ui, .axl-episode) .axl-form meter::-moz-meter-bar { background: var(--f-ok); border-radius: 999px; }

/* Buttons: the same 8px / 13px-700-caps shape as .axl-btn, on native elements. */
:is(.axl-ui, .axl-episode) .axl-form__btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  border: 1px solid #1245C4; border-radius: 8px; background: #1245C4; color: #fff;
  padding: 11px 26px; font: inherit; font-size: 13px; font-weight: 700; line-height: 1.45;
  letter-spacing: .04em; text-transform: uppercase; text-decoration: none; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
}
:is(.axl-ui, .axl-episode) .axl-form__btn:hover { background: #0f3aa8; border-color: #0f3aa8; }
:is(.axl-ui, .axl-episode) .axl-form__btn:active { background: #0d3396; border-color: #0d3396; }
:is(.axl-ui, .axl-episode) .axl-form__btn:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px var(--f-bg), 0 0 0 4px var(--f-focus); }
:is(.axl-ui, .axl-episode) .axl-form__btn--secondary { background: transparent; color: var(--f-accent); border-color: var(--f-accent); }
:is(.axl-ui, .axl-episode) .axl-form__btn--secondary:hover { background: var(--f-accent); border-color: var(--f-accent); color: var(--f-accent-ink); }
:is(.axl-ui, .axl-episode) .axl-form__btn--ghost { background: transparent; border-color: transparent; color: var(--f-muted); padding-inline: 14px; }
:is(.axl-ui, .axl-episode) .axl-form__btn--ghost:hover { background: var(--f-bg-disabled); border-color: transparent; color: var(--f-ink); }
:is(.axl-ui, .axl-episode) .axl-form__btn:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }

/* Form-level message (submit result). */
:is(.axl-ui, .axl-episode) .axl-form__notice { margin: 0; padding: 12px 14px; border: 1px solid; border-radius: var(--f-radius); font-size: 13.5px; }
:is(.axl-ui, .axl-episode) .axl-form__notice--error { color: var(--f-error); border-color: var(--f-error); background: color-mix(in srgb, var(--f-error) 8%, transparent); }
:is(.axl-ui, .axl-episode) .axl-form__notice--ok { color: var(--f-ok); border-color: var(--f-ok); background: color-mix(in srgb, var(--f-ok) 8%, transparent); }

/* ---- Contact Form 7 on .axl-form -------------------------------------------
   Put html_class="axl-form" on the [contact-form-7] shortcode so the <form> itself
   is the .axl-form flex column; CF7's own response box then sits in the same gap.
   CF7 wraps each control in span.wpcf7-form-control-wrap and, when a field fails,
   adds .wpcf7-not-valid to the control and span.wpcf7-not-valid-tip after it.
   Colours stay on the --f-* tokens, so the dark skin needs nothing extra. */
:is(.axl-ui, .axl-episode) .axl-form .hidden-fields-container { display: none; }
:is(.axl-ui, .axl-episode) .axl-form .wpcf7-form-control-wrap { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
:is(.axl-ui, .axl-episode) .axl-form .wpcf7-not-valid-tip { display: block; margin: 0; font-size: 12.5px; font-weight: 600; line-height: 1.4; color: var(--f-error); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select).wpcf7-not-valid { border-color: var(--f-error); }
:is(.axl-ui, .axl-episode) .axl-form :is(input, textarea, select).wpcf7-not-valid:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--f-error) 22%, transparent); }
:is(.axl-ui, .axl-episode) .axl-form .wpcf7-spinner { margin: 0 0 0 4px; }

/* The form-level result. Out-ranks CF7's own stylesheet (.wpcf7 form.sent ...). */
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form .wpcf7-response-output {
  margin: 0; padding: 12px 14px; border: 1px solid var(--f-line); border-radius: var(--f-radius);
  font-size: 13.5px; color: var(--f-ink);
}
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form:is(.init, .resetting) .wpcf7-response-output,
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form .wpcf7-response-output:empty { display: none; }
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form:is(.invalid, .unaccepted, .failed, .aborted, .spam, .payment-required) .wpcf7-response-output {
  color: var(--f-error); border-color: var(--f-error); background: color-mix(in srgb, var(--f-error) 8%, transparent);
}
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form.sent .wpcf7-response-output {
  color: var(--f-ok); border-color: var(--f-ok); background: color-mix(in srgb, var(--f-ok) 8%, transparent);
  padding: 28px 24px; text-align: center; font-size: 19px; font-weight: 600; line-height: 1.5;
}
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form.sent .wpcf7-response-output::before {
  content: "\2713"; display: grid; place-items: center; width: 48px; height: 48px; margin: 0 auto 12px;
  border-radius: 50%; background: var(--f-ok); color: var(--f-ok-ink); font-size: 24px; line-height: 1;
}
:is(.axl-ui, .axl-episode) .wpcf7 form.axl-form.sent .wpcf7-response-output:focus { outline: none; }

/* Once sent, the form gives way to its message. CF7 sets .sent in the browser only,
   so a refresh brings the form back. Not scoped to .axl-form, so it holds even if a
   shortcode is missing html_class. site.js scrolls the message into view. */
.wpcf7 form.sent > :not(.wpcf7-response-output) { display: none; }

/* wp-admin's forms.css caps its own dashboard panels with `.card { max-width:
   520px }`, and that sheet reaches the canvas. A pattern's card IS a block, so
   the rule above already frees it; a card rendered INSIDE a dynamic block (the
   axl-downloads filter card and Activity Pack) is not, and would shrink to the
   admin width. Editor only: on the site there is no such cap to undo. */
.editor-styles-wrapper :is(.axl-ui, .axl-episode) .card { max-width: none; }
