/* ====================================================================
   Grid Maker Pro — editorial heading rhythm   (2026-06-16)
   --------------------------------------------------------------------
   Fixes section titles sticking to the paragraph above them — a bug seen
   across hubs, tool pages, and every bespoke marketing template
   (about-us, faq, methodology, features, ...).

   Root cause
     The base templates set section headings with NO top margin, e.g.
       .gm-section  h2 { margin: 0 0 18px !important; }   (inline, 14 files)
       .gmp-section h2 { margin: 0 0 var(--s-5); }        (components.css)
       .ftp-h2         { margin: 0 0 ...; }               (bespoke pages)
     So whenever a heading follows a paragraph (stacked sections in one
     container) it butts straight up against the text above it.

   The fix — container-agnostic by design
     Each template family uses its OWN container classes (.gm-studio-inner,
     .gmp-faq-group, .ftp-road-head, ...), so scoping by container would be
     an endless, fragile enumeration. Instead we key off the ONE thing they
     all share: a heading that DIRECTLY FOLLOWS running text. The
     adjacent-sibling combinator (`text + heading`) never matches a
     container's FIRST heading, so a section's own padding-top is never
     doubled — no `:first-child` reset needed.

   Why it never touches cards / stats / CTAs
     · The preceding-element list is running-text only (p/ul/ol/dl/
       blockquote). Card titles sit after a <figure>/<div>/<img> thumb, so
       `text + heading` can't fire on them.
     · Class guards skip the few headings that DO follow a <p>-like label
       inside a component (title/card/stat/num/eyebrow/cta/close/value/
       label/meta naming).

   Why the id-level :not(#_) bump
     The per-page `.gm-section h2 { ...!important }` rules live in inline
     <style> blocks that load in <body>, AFTER this file. To beat an
     equal-specificity !important from a later sheet we need HIGHER
     specificity. `:not(#_)` matches every element (nothing has id="_") and
     adds one id-level of weight — lifting these rules above all the
     (0,1,1) base rules without naming a single container class.

   Why rem, not var(--s-*)
     Several pages REDEFINE the --s-* spacing scale locally (gmp.css sets
     --s-8 to 32px, not the global 4rem), so token names give inconsistent
     gaps per page. Fixed rem values stay consistent everywhere and still
     scale with the big-screen root-font bump in responsive.css.
   ==================================================================== */

/* The preceding-element list is intentionally BROAD: a section heading
   sticks to whatever sits above it whether that's running text OR a block
   component (the .gm-cite-list references box, a *-kit panel, a CTA strip,
   the .gm-faq-list, a <figure>, a <table>, a wrapper <div>/<section>, …).
   We key off the ONE structural fact they share — the heading has a
   PRECEDING SIBLING — via the adjacent-sibling combinator. That combinator
   never matches a container's FIRST heading, so a section's own padding-top
   is never doubled; no `:first-child` reset needed. Block predecessors that
   open with their own heading (`.gm-cta-strip > h2`, `.gm-cite-list > h2`)
   are therefore safe — that heading is first-child, so nothing fires on it.

   NOTE: the :not() chain on each heading MUST stay on one line with no
   whitespace — a line break there becomes a descendant combinator and the
   rule silently stops matching the heading itself. */
html :is(p, ul, ol, dl, blockquote, div, section, article, figure, figcaption, table, details, aside, hr) + h2:not(#_):not([class*="title"]):not([class*="card"]):not([class*="cta"]):not([class*="close"]):not([class*="eyebrow"]):not([class*="label"]) {
  margin-top: 3rem !important;     /* major section break */
}

html :is(p, ul, ol, dl, blockquote, div, section, article, figure, figcaption, table, details, aside, hr) + :is(h3, h4):not(#_):not([class*="title"]):not([class*="card"]):not([class*="stat"]):not([class*="num"]):not([class*="eyebrow"]):not([class*="label"]):not([class*="value"]):not([class*="meta"]):not([class*="cta"]) {
  margin-top: 1.75rem !important;  /* sub-section break */
}
