/* ============================================================
   blocks.css — shared section chrome. Loaded LAST of the sitewide
   layers (fonts → tokens → global → components → blocks), so it is
   the right place for the few rules that must win a tie.
   ------------------------------------------------------------
   MOBILE-FIRST per DECISIONS D3. Base rules are the 390px artboard
   and the only queries permitted are min-width at 480 / 768 / 1024
   / 1200. This file previously carried two desktop-first breakpoint
   overrides (one at 768px, one at 1080px); both are gone, and the
   only width queries permitted here now open with min-width.

   RECONCILIATION — global.css OWNS the section chrome.
   The starter kit defined .sectionpt / .sectionpb / .section-compact
   / .section-spacious / .has-bg-* / .light-bg / .dark-bg in BOTH
   global.css and here, with different values. Because this file
   loads second, the kit's copies silently won, and three decisions
   were being reverted every page load:

     · padding was 92 / 56 / 128px hardcoded, defeating global.css's
       token-driven var(--m434-section-y) rhythm — i.e. the whole
       44 → 56 → 76 mobile-first step (D3 UPDATE, §3.2, §10.9);
     · .has-bg-accent painted var(--red), a full-bleed orange band
       the design does not contain, instead of the crimson §10.3
       decided on;
     · .dark-bg a painted flat white, discarding the split-by-surface
       link color §10.2 decided on (--m434-accent-lt / #ffab5e).

   Those duplicates are DELETED rather than re-tuned. global.css is
   the single definition; this file now only adds what global.css
   cannot express on its own.
   ============================================================ */

/* ---------- Default vertical rhythm for un-chromed sections ----------
   m434_section_classes() returns '' for a block with no background
   and default spacing, so its <section> carries neither .section nor
   .sectionpt/pb and would have zero padding. The blocks that land
   here are the ones whose wrapper class is their own name — .hero,
   .m434-steps, .cta — plus any future part that follows suit.

   :where() is load-bearing. It contributes no specificity, so the
   whole selector weighs (0,0,1) and a single class beats it. The kit
   wrote this as `section:not([class*="sectionp"])`, which weighs
   (0,1,1) and therefore overrode every per-block section rule that
   came after it — proof-bar.css's `.m434-proof { padding: 32px 0 }`
   among them, silently restoring 92px there. */
section:not(:where(.section, [class*="sectionp"])) {
  padding-top: var(--m434-section-y);
  padding-bottom: var(--m434-section-y);
}

/* ---------- Dark-ground legibility ----------
   global.css already whitens h1–h4 and sets the link color on
   .dark-bg. These are the gaps it leaves. */

/* .grad-text sets -webkit-text-fill-color:transparent and clips a
   background gradient to the glyphs. A plain `color:#fff` cannot
   undo that, so an <h2 class="grad-text"> on a dark band would keep
   painting the ink→orange gradient — unreadable over --navy. Resets
   the fill and covers h5/h6, which global.css does not list.
   (.grad-text in VSMA markup is defect §10.6. F-39 took it out of
   every block part and the root templates dropped it in the same
   round, so nothing emits it now; the guard is kept as a net for a
   stray usage. See the note on .grad-text in global.css for the
   four files that have to be retired together.) */
.dark-bg :is(h1, h2, h3, h4, h5, h6, .grad-text) {
  color: var(--white);
  -webkit-text-fill-color: currentColor;
}

/* ---------- Buttons on dark grounds ----------
   NOTHING IS NEEDED HERE ANY MORE, and that is the point of the note.

   This file used to carry four label-color restatements
   (`.dark-bg .btn-primary/.btn-red/.btn-crimson/.btn-white`) plus the
   entire definition of `.btn-white`, because global.css's `.dark-bg a`
   was repainting solid-fill button labels — accent-orange on
   accent-orange, and near-black lost on crimson. The restatements were
   also subtly broken: at (0,2,0) they lost to `.dark-bg a:hover` at
   (0,2,1), so the bug came back the instant the pointer landed.

   Both halves are now fixed at the source in global.css:
     · `.dark-bg a` is scoped `a:not(.btn)`, so no surface rule reaches
       a button label at any specificity;
     · every dark ground (.dark-bg / .has-bg-navy / .has-bg-accent /
       .cta:has(> .bg)) redefines --m434-btn-ink / -ring / -ring-hover /
       -wash plus --m434-accent-ink and --m434-focus-ring, which is how
       .btn-secondary adapts to the surface with no `-light` variant;
     · .btn-white moved into global.css's deprecated-alias block, beside
       its replacement .btn-inverse.

   If a NEW dark surface class ever appears that is neither .dark-bg nor
   a .cta photo band, add it to that custom-property block in global.css
   — do not restate button colors here.
   ------------------------------------------------------------ */

/* .prose hardcodes color:var(--ink) in global.css, which goes nearly
   black-on-navy inside a dark band. rich_text, text_image and faq all
   render body copy through it, so the fix belongs in the chrome layer
   rather than in each block.

   figcaption was rgba(255,255,255,.6), which is 6.38:1 on --navy but
   only 4.11:1 on --m434-crimson — under 4.5:1 at 12px. .72 is 5.26:1
   there and still reads as a caption against .8 body copy. */
.dark-bg .prose { color: rgba(255, 255, 255, 0.8); }
.dark-bg .prose strong { color: var(--white); }
.dark-bg .prose figcaption { color: rgba(255, 255, 255, 0.72); }

/* ============================================================
   LIGHT ISLANDS — a light CARD sitting on a dark BAND
   ------------------------------------------------------------
   Every block in this theme clones group_m434_block_settings, so
   "Navy" and "Accent" are editor-selectable on ALL of them. Most
   card-shaped blocks keep `background: var(--white)` regardless — the
   hairline-grid trick needs an opaque cell to paint over the container
   rule — so choosing a dark band produces a WHITE CARD on a DARK
   SECTION, and every `.dark-bg <descendant>` rule in the theme walks
   straight into it.

   Measured before this block existed, on a program_cards block set to
   Navy or Accent:

     .m434-program-title    #ffffff on #ffffff   1.00:1   (invisible)
     .icon-card-title       #ffffff on #ffffff   1.00:1
     .m434-event-title      #ffffff on #ffffff   1.00:1
     .tc-item blockquote    #ffffff on #ffffff   1.00:1
     .tc-item .cite .name   #ffffff on #ffffff   1.00:1
     .tc-item .cite .role   #ffffff on #ffffff   1.00:1
     .m434-program-link     #ff963c on #ffffff   2.17:1 (1.87 on hover)

   The cause is always the same shape — a selector hung off the SECTION
   painting text on a surface the section does not own — so the fix is
   one shared list rather than N per-block guards. components.css
   already carried two hand-written instances (`.dark-bg .wstep
   .wstep-title`, `.dark-bg .case-card h3`); they are harmless
   duplicates of what this block now does for every card.

   PART 1 — the surface tokens. Unconditional, because these elements
   are light on EVERY band: nothing here is scoped to .dark-bg, so a
   card in a light section re-declares the same values it already had.
   This is what stops a dark band's link/accent/focus ink from reaching
   inside, with no specificity contest at all.

   If a new light card ships, add it here. If a card ADAPTS to the band
   instead of staying light — the rich-text callout darkens — it does NOT
   belong here.

   `.stat` USED TO BE THE OTHER EXAMPLE ON THIS LINE, and is not any
   more. FB-037 moved the stat band's hairline off the container and onto
   each cell (components.css, `.stats > .stat`), which meant the dark-band
   wash had to move with it: a stat cell now paints --white on a light
   band and an explicit rgba wash under .dark-bg, so it no longer "goes
   transparent" and the old wording described something that had stopped
   being true. It still does not belong in the list below — it adapts —
   but for the new reason, not the old one.

   `.m434-member` IS LABELED "the staff card" BELOW, NOT `team_cards`,
   which is the block it shipped for. FB-028 deleted that block and the
   SELECTOR IS VERY MUCH ALIVE: parts/staff-card.php emits
   `<div class="m434-member m434-staff">` and three surfaces draw it
   through that one renderer — the `staff_cards` block, the /our-team/
   archive (archive-staff.php) and single-staff.php. Do not read the row
   as dead and delete it with the block's name.
   ============================================================ */
.m434-program,          /* program_cards        */
.wstep,                 /* process_steps        */
.icon-card,             /* icon_cards           */
.downloads,             /* downloads            */
.case-card,             /* case_study_cards     */
.post-card,             /* posts_feed           */
.posts-feed-grid article,
.team-card,             /* team_grid            */
.m434-member,           /* the staff card       */
.tc-item,               /* testimonial_carousel */
.m434-events,           /* roadshow_schedule    */
.m434-network-list,     /* network_map          */
.m434-network-frame,
.m434-network-readout {
  --m434-surface-ink:      var(--ink);
  --m434-muted-ink:        var(--m434-slate-strong);
  --m434-link-ink:         var(--m434-accent-text);
  --m434-link-ink-hover:   #86430f;   /* global.css, "HOVER on a light ground" */
  --m434-accent-ink:       var(--m434-accent-text);
  --m434-accent-ink-hover: #86430f;
  --m434-accent-ring:      var(--red);
  --m434-btn-ink:          var(--ink);
  --m434-btn-ring:         rgba(48, 48, 48, .55);
  --m434-btn-ring-hover:   rgba(48, 48, 48, .7);
  --m434-btn-wash:         rgba(48, 48, 48, .05);
}

/* --m434-focus-ring is set on the card's DESCENDANTS, not on the card,
   and the `*` is load-bearing. outline-offset draws the ring OUTSIDE
   the element it belongs to, so:
     · a link inside the card  → ring lands on the CARD's white  → #111
     · the card itself (.case-card and .post-card are <a>) → ring lands
       on the SECTION's dark ground → must stay --white
   Setting the token on the card element got the second case wrong and
   drew a #111 ring on --navy: 1.25:1, measured by tabbing the real
   focus order on a case_study_cards block set to Navy. Because the
   selector matches descendants directly at (0,1,0), the card itself
   simply inherits the section's value and needs no rule of its own. */
:is(.m434-program, .wstep, .icon-card, .downloads, .case-card,
    .post-card, .posts-feed-grid article, .team-card, .m434-member,
    .tc-item, .m434-events, .m434-network-list, .m434-network-frame,
    .m434-network-readout) * {
  --m434-focus-ring: #111111;
}

/* PART 2 — the colors the surface rules above cannot express, because
   the rules being undone name a literal color rather than a token.
   Specificity is the whole point of each line:
     .dark-bg :is(…)                     (0,2,1) > .dark-bg           (0,1,0)
     .dark-bg :is(…) :is(h1…h6)          (0,3,1) > .dark-bg :is(h1…)  (0,2,0)
     .dark-bg :is(…) .prose              (0,3,1) > .dark-bg .prose    (0,2,0)
     .dark-bg :is(…) .prose figcaption   (0,3,2) > .dark-bg … caption (0,2,1)
   :is() takes the specificity of its MOST SPECIFIC argument. Every list
   here weighs (0,1,1) rather than (0,1,0) because of the one descendant
   selector in it, `.posts-feed-grid article` — worth knowing before
   adding or removing entries, since dropping that one entry would lower
   the specificity of every other. */
.dark-bg :is(.m434-program, .wstep, .icon-card, .downloads, .case-card,
             .post-card, .posts-feed-grid article, .team-card, .m434-member,
             .tc-item, .m434-events, .m434-network-list, .m434-network-frame,
             .m434-network-readout) {
  color: var(--ink);
}

/* -webkit-text-fill-color is restated for the same reason blocks.css
   sets it on the dark side: a .grad-text heading inside a card would
   otherwise keep clipping a gradient to transparent glyphs. Inside a
   card it resolves to solid --ink, which is legible; the gradient is
   defect §10.6 markup anyway. */
.dark-bg :is(.m434-program, .wstep, .icon-card, .downloads, .case-card,
             .post-card, .posts-feed-grid article, .team-card, .m434-member,
             .tc-item, .m434-events, .m434-network-list, .m434-network-frame,
             .m434-network-readout) :is(h1, h2, h3, h4, h5, h6, .grad-text) {
  color: var(--ink);
  -webkit-text-fill-color: currentColor;
}

.dark-bg :is(.m434-program, .wstep, .icon-card, .downloads, .case-card,
             .post-card, .posts-feed-grid article, .team-card, .m434-member,
             .tc-item, .m434-events, .m434-network-list, .m434-network-frame,
             .m434-network-readout) .prose {
  color: var(--ink);
}
.dark-bg :is(.m434-program, .wstep, .icon-card, .downloads, .case-card,
             .post-card, .posts-feed-grid article, .team-card, .m434-member,
             .tc-item, .m434-events, .m434-network-list, .m434-network-frame,
             .m434-network-readout) .prose strong {
  color: var(--ink);
}
.dark-bg :is(.m434-program, .wstep, .icon-card, .downloads, .case-card,
             .post-card, .posts-feed-grid article, .team-card, .m434-member,
             .tc-item, .m434-events, .m434-network-list, .m434-network-frame,
             .m434-network-readout) .prose figcaption {
  color: var(--m434-slate-strong);
}

/* ---------- Light BANDS that are not white ----------
   .grad-text clips --grad (ink → ink 42% → --red) to the glyphs, so
   its terminal stop is --red as TEXT. #E5761E is 3.03:1 on #ffffff —
   which scrapes the 3:1 large-text floor these headings qualify for —
   but 2.77:1 on --bg-soft and 2.67:1 on --bg-cool, so the same heading
   FAILS the moment an editor picks Soft or Cool. Measured on the
   shipped /blocks/ page at 44px/700.

   The stop moves to --m434-accent-text #a34f0e (5.23:1 on --bg-soft,
   5.03:1 on --bg-cool), which is precisely the token tokens.css
   defines for accent-colored TEXT on light grounds (F-16). White
   bands keep the design's --red tail untouched.

   The override is on --grad, NOT on .grad-text's background, and that
   distinction is load-bearing. Restating the background at (0,2,0)
   beat `.stat-val { background: none }` (0,1,0) — the stat numeral
   opts OUT of the gradient precisely so it can set its own color —
   and repainted the gradient as a solid DARK BOX behind every numeral
   on a Soft or Cool band, because .stat-val had also reset
   background-clip to border-box. Caught by screenshotting the block on
   all four bands; every ratio still measured clean, since the numbers
   cannot see a box. Redefining the token instead leaves every opt-out
   working and changes only what the gradient is made of.

   The real fix is markup — .grad-text is §10.6, it should not be in
   VSMA parts at all — so this is a guard, not an endorsement. */
.has-bg-soft,
.has-bg-cool {
  --grad: linear-gradient(100deg,
    var(--ink) 0%, var(--ink) 42%, var(--m434-accent-text) 100%);
}

/* ============================================================
   CTA banner — "Contained to the page width" (FB-027)
   ------------------------------------------------------------
   The client reported that she "can't choose to make the ribbon
   CTAs contained anymore, so they're stretching across the
   entire width of the screen". The control she remembers is
   real, but it belonged to the PREVIOUS accel434 build — this
   theme has never had a per-block background-width option. So
   this is a port, not a revert, and it is deliberately scoped to
   this one block: the shared group_m434_block_settings clone
   would hand the same control to all 22 blocks, and the Content
   block's full-bleed color (FB-022) has been ruled intended.

   WHAT THE OLD THEME ACTUALLY DID — read from the reference tree
   rather than reinvented:
     · acf-json/group_593ee2fb3ff3c.json ("Flex - Ribbon CTA") —
       a true_false named `contained_bar`, label "Contained Bar",
       default 0, i.e. full bleed unless asked otherwise. Its CTA
       Section group carried the same idea under the name
       `contained` (group_593ee00c4c148.json), so what follows is
       that build's answer twice over, not a one-off.
     · partials/sections/ribbon_cta.php:8-11 — contained put
       `contained sectionmt sectionmb` on the <section> and left
       the color OFF it; the bar's background moved to an inner
       block inside `.wrap` (max-width 1200px, width 90%). Not
       contained put `bg-<color>` on the section itself.
     · assets/styles/sections/_ribbon-cta.scss:19-26 — the only
       other difference: `.contained .ribbon-content` restores
       5rem (80px) of side padding from min-width 1024px, where
       the full-bleed variant runs its copy to the container edge
       (padding-left/right: 0).
     · NO radius, NO shadow, no inset frame, no max-width on the
       section — confirmed against the compiled dist/front.css.
       Containment there was width plus white space, nothing else.

   THE TRANSLATION — three properties for those three things:
     · width / max-width / margin-inline. This theme has no 90%
       `.wrap`; its equivalent box is "the page container" —
       capped at --maxw, inset from the viewport by one
       --m434-gutter each side. That lands within a couple of
       pixels of the old 90% at every tier (936px vs 921.6px at a
       1024 viewport, 350px vs 351px at 390), so the band's edges
       sit on the page's own text column exactly as they used to.
     · margin-block. The old `sectionmt sectionmb` (64px mobile /
       100px desktop); our one rhythm token is --m434-section-y
       (44 / 56 / 76). Load-bearing, not decorative: this band's
       vertical padding is INSIDE the color, so with no outer
       margin a contained box butts straight against the next
       section with zero gap and reads as a rendering fault.
     · padding-inline on the inner .wrap from lg. The 80px above.
       Two gutters (88px at lg) rather than a literal 80 so the
       inset stays a multiple of the gutter it is measured from;
       `.cta.m434-ctab--contained > .wrap` is (0,3,0) and so
       clears global.css's `.wrap` padding at (0,1,0).

   THE DEFAULT IS UNTOUCHED BY CONSTRUCTION. No stored row carries
   `bg_width`, cta-banner.php emits this class only for an
   explicit 'contained', and nothing below matches a band without
   it — so all three live CTA bands render byte for byte as they
   did before the field existed.

   `.cta.m434-ctab--contained` is (0,2,0), which clears
   components.css's single-class `.cta` rules without leaning on
   load order. The rule sits in this file rather than beside the
   rest of .m434-ctab in components.css only because that file
   was outside this change's ownership — the same displacement,
   for the same reason, as parts/block-chrome.php.

   The 1024 query below is the first @media in this file: a
   min-width at a permitted breakpoint, per the header rule.
   ============================================================ */
.cta.m434-ctab--contained {
  width: calc(100% - var(--m434-gutter) * 2);
  max-width: var(--maxw);
  margin-inline: auto;
  margin-block: var(--m434-section-y);
}

@media (min-width: 1024px) {
  .cta.m434-ctab--contained > .wrap { padding-inline: calc(var(--m434-gutter) * 2); }
}
