/* Prelo's @font-face declarations live in styles/fonts.css, which head.html
   loads alongside this file. Do not re-declare them here — a duplicate set
   lived in this file until 2026-09-01 and meant edits to fonts.css did nothing. */

:root {
  /* grid — the rail is 90% between 992 and 1440, 1280px from 1440 (below), and
     `calc(100% - 20px)` under 992 (the media rule after this block, ISS-509). */
  --grid-container-width: 90%;
  --grid-column-width: calc(var(--grid-container-width) / 12);
  --grid-gutter-width: 5%;

  /* spacing */
  --spacing-none: 0;
  --spacing-xxl: 48px;
  --spacing-xl: 32px;
  --spacing-l: 20px;
  --spacing-m: 14px;
  --spacing-s: 8px;
  --spacing-xs: 4px;

  /* Authored line-break token (see .line-break). Deliberately NOT --spacing-l,
     which happens to share its value: section spacing and an author's in-copy
     gap are different knobs, and one must not resize the other. Shared by
     .line-break and .line-break-token so the pre-paint stand-in and the real
     spacer can never drift apart. */
  --line-break-size: 20px;

  /* color schemes */
  color-scheme: light;

  /* color tokens */
  --color-primary-white: #fff;
  --color-primary-green: #3f9c35;
  --color-primary-light-green: #d9ebd7;
  --color-primary-blue: #009cde;
  --color-primary-light-blue: #ccebf8;
  --color-primary-light-grey: #888b8d;
  --color-primary-medium-grey: #63666a;
  --color-primary-dark-grey: #515356;
  --color-primary-hover-green: #2b6c25;
  --color-high-contrast: #777;
  --color-dark-navy: #00153d;
  --color-accent-green: #00a94f;
  --color-section-grey: #f0f0f0;
  /* primary brand colors — author-facing palette; library-sync reads the
     --color-* names in this block to build the DA options color-token list */
  --color-green: var(--color-primary-green);
  --color-light-green: var(--color-primary-light-green);
  --color-blue: var(--color-primary-blue);
  --color-light-blue: var(--color-primary-light-blue);
  --color-navy: var(--color-dark-navy);
  --color-white: var(--color-primary-white);
  --color-grey: var(--color-primary-light-grey);
  --color-medium-grey: var(--color-primary-medium-grey);
  --color-dark-grey: var(--color-primary-dark-grey);
  --color-light-grey: var(--color-section-grey);
  --color-light-grey-2: #CDCECF;

  /* secondary palette */
  --color-secondary-cyan: #38a798;
  --color-secondary-magenta: #9f5cc0;
  --color-secondary-yellow: #f1b434;
  --color-secondary-pink: #e40046;
  --color-secondary-yellow-green: #a2a569;
  --color-secondary-orange: #e87722;

  /* high-contrast palette */
  --color-hc-primary-blue: #007eb4;
  --color-hc-primary-green: #36872e;
  --color-hc-primary-grey: #515356;

  /* transitions */
  --transition-base: 0.3s ease-in-out;
  --color-gray-100: #f1f1f1;
  --color-gray-200: #d3d3d3;
  --color-gray-300: #b5b5b5;
  --color-gray-400: #999;
  --color-gray-500: #7d7d7d;
  --color-gray-600: #636363;
  --color-gray-700: #494949;
  --color-gray-800: #313131;
  --color-gray-900: #1b1b1b;
  --color-green-100: #e1f5e3;
  --color-green-200: #a3e1a8;
  --color-green-300: #60cb6a;
  --color-green-400: #24b032;
  --color-green-500: #1e9029;
  --color-green-600: #187220;
  --color-green-700: #115418;
  --color-green-800: #0c3910;
  --color-green-900: #072009;
  --color-teal-100: #e4f3f5;
  --color-teal-200: #acdbdf;
  --color-teal-300: #71c1c9;
  --color-teal-400: #36a7b3;
  --color-teal-500: #108a96;
  --color-teal-600: #0d6d77;
  --color-teal-700: #0a5158;
  --color-teal-800: #06363b;
  --color-teal-900: #041e21;
  --color-blue-100: #eaf2ff;
  --color-blue-200: #b9d4ff;
  --color-blue-300: #88b6ff;
  --color-blue-400: #5898ff;
  --color-blue-500: #2176ff;
  --color-blue-600: #0058e4;
  --color-blue-700: #0041a9;
  --color-blue-800: #002c74;
  --color-blue-900: #001942;
  --color-purple-100: #f4edfb;
  --color-purple-200: #dfcbf2;
  --color-purple-300: #c9a7ea;
  --color-purple-400: #b385e1;
  --color-purple-500: #9d60d8;
  --color-purple-600: #843ccb;
  --color-purple-700: #622c98;
  --color-purple-800: #421e66;
  --color-purple-900: #251139;
  --color-magenta-100: #ffebf9;
  --color-magenta-200: #ffc0ec;
  --color-magenta-300: #ff8fde;
  --color-magenta-400: #ff53cc;
  --color-magenta-500: #eb00a5;
  --color-magenta-600: #bd0084;
  --color-magenta-700: #8e0064;
  --color-magenta-800: #630045;
  --color-magenta-900: #3b002a;
  --color-red-100: #ffecea;
  --color-red-200: #ffc4be;
  --color-red-300: #ff9990;
  --color-red-400: #ff6759;
  --color-red-500: #f81400;
  --color-red-600: #c71000;
  --color-red-700: #950c00;
  --color-red-800: #670800;
  --color-red-900: #3c0500;
  --color-orange-100: #ffeddc;
  --color-orange-200: #ffc895;
  --color-orange-300: #ff9e43;
  --color-orange-400: #f37500;
  --color-orange-500: #c76000;
  --color-orange-600: #9e4c00;
  --color-orange-700: #753800;
  --color-orange-800: #4f2600;
  --color-orange-900: #2d1500;
  --color-yellow-100: #fff48e;
  --color-yellow-200: #ebd400;
  --color-yellow-300: #cab600;
  --color-yellow-400: #ab9a00;
  --color-yellow-500: #8c7e00;
  --color-yellow-600: #6e6400;
  --color-yellow-700: #514a00;
  --color-yellow-800: #373100;
  --color-yellow-900: #1e1b00;

  /* named colors */
  --color-light-base: 255 255 255;
  --color-dark-base: 0 0 0;
  --color-light: rgb(255 255 255);
  --color-dark: rgb(0 0 0);
  --color-text: var(--color-primary-dark-grey);
  --color-link: var(--color-primary-green);
  --color-brand: var(--color-purple-500);
  --color-accent: light-dark(var(--color-magenta-600), var(--color-yellow-100));
  --color-shaded: light-dark(#f9f9f9, #000);

  /* fonts */
  --font-family: prelo, "Trebuchet MS", sans-serif;

  /* headings */
  --heading-font-size-xxl: 48px;
  --heading-font-size-xl: 36px;
  --heading-font-size-l: 24px;
  --heading-font-size-m: 20px;
  --heading-font-size-s: 18px;
  --heading-font-size-xs: 16px;

  /* h2-h6 ONLY — h1 is not in the rule this feeds (see the h2..h6 block below), and
     legacy genuinely differs by level. Measured on rsmus.com at 1440 across three
     pages, 56 headings: h1 1.2 (3/3), h2 1.3 (16 of 17, one 1.5 outlier), h3 1.3
     (18/18), h4 1.3 (18/18).

     Was 1.2, sourced from rsm.global — a DIFFERENT property — and set from an h1
     measurement, which is the one level where 1.2 is right. Every h2-h6 on the site
     therefore rendered 8% tighter than legacy: 36px copy at 43.2px leading instead of
     46.8px. Surfaced as "legacy is taller" on the global-enterprise-strategy CTA
     panel (194px vs 196px), where the 2px box difference is the symptom and the
     leading is the cause. */
  --heading-line-height: 1.3;

  /* body */
  --body-font-size-xxxl: 27px;
  --body-font-size-xxl: 24px;
  --body-font-size-xl: 22px;
  --body-font-size-l: 20px;
  --body-font-size-m: 18px;
  --body-font-size-s: 14px;
  --body-font-size-xs: 12px;
  --body-line-height: 1.3;

  /* misc */
  --header-height: 100px;
  --preheader-height: 38px;
  --breadcrumb-height: 24px;

  /* Font weights — THESE FIVE VALUES ARE THE ONLY ONES THAT EXIST.
     Prelo ships here as one file per weight/style (see styles/fonts.css). A
     font-weight the family has no face for does NOT fall back to something
     sane — CSS font matching silently snaps it to the nearest available face,
     and between 500 and 800 that is always Bold:
       550 → Bold   600 → Bold   650 → Bold   800 → Black   200 → Light
     So `font-weight: 600` renders identically to 700, with no warning anywhere.
     There is no semibold in this family, so 600 can never be honoured.
     Prefer these vars over raw numbers; a var cannot name a missing face.

     WATCH OUT when porting CSS from legacy (RSMUS_ACM
     ui.frontend/src/main/webpack/site/base/font.scss): legacy mapped the SAME
     four files to DIFFERENT numbers — Book was 500 and Medium was 600 there,
     against 400 and 500 here. A weight copied from legacy therefore reads one
     step too heavy, and 600 in particular lands on Bold instead of Medium.

     Black (900) is a special case: legacy shipped the file but declared it under
     the WRONG family name ('HurmeGeometric') with a typo'd URL, so legacy's own
     `font-weight: 900` fell back to Bold. Anything ported from legacy that says
     900 was Bold on the live page — it is deliberately written 700 here. Use 900
     only where Black is genuinely wanted (e.g. the net-new Seahawks template). */
  --font-weight-black: 900;     /* Prelo-Black  — see the note above: NOT what legacy showed */
  --font-weight-bold: 700;      /* Prelo-Bold   — legacy called this 700 too */
  --font-weight-medium: 500;    /* Prelo-Medium — legacy called this 600 */
  --font-weight-regular: 400;   /* Prelo-Book   — legacy called this 500 */
  --font-weight-light: 300;     /* Prelo-Light  — legacy called this 300 too */
}

/* Mobile bar sizes. Overridden on :root so the header/preheader heights, the
   body's top padding (calc of both), and the desktop menu offset all track the
   actual bar heights. The preheader block also mirrors --preheader-height. */
@media (width < 992px) {
  :root {
    --preheader-height: 44px;
    --header-height: 51px;

    /* ISS-509 (ruled 2026-09-25): below 992 the section rail keeps a FIXED 10px gutter
       each side, which is legacy's (390 -> 372 content, 768 -> 748), measured two-sided
       on 9 of 9 control pages. It used to be 90% of the viewport (20px @390, 38px @768),
       set in #63 (83.4% -> 90%) relative to the previous EDS value, not to legacy.
       992-1440 keeps 90% and >=1440 keeps 1280px. */
    --grid-container-width: calc(100% - 20px);
  }
}

@media (width < 992px) {
  :root {
    --heading-font-size-xxl: 30px;
    --heading-font-size-xl: 30px;
  }
}

.light-scheme {
  color-scheme: light;
}

.dark-scheme {
  color-scheme: dark;
}

/* high-contrast mode — re-points the primary palette at the HC values.
   Every block using var(--color-primary-*) inherits these automatically.
   Triggered by the manual .high-contrast toggle OR the OS prefers-contrast
   setting; .no-high-contrast lets the toggle opt out of the system preference. */
body.high-contrast {
  --color-primary-blue: var(--color-hc-primary-blue);
  --color-primary-green: var(--color-hc-primary-green);
  --color-primary-light-grey: var(--color-hc-primary-grey);
}

@media (prefers-contrast: more) {
  body:not(.no-high-contrast) {
    --color-primary-blue: var(--color-hc-primary-blue);
    --color-primary-green: var(--color-hc-primary-green);
    --color-primary-light-grey: var(--color-hc-primary-grey);
  }
}

html {
  /* An anchor jump has to clear everything pinned over the top of the viewport,
     or the target heading lands underneath it and reads as missing text. That
     stack is the fixed header, the preheader above it when present (see the
     :has() rule below), and the secondary-nav once it pins — which publishes
     --secondary-nav-height from blocks/secondary-nav/secondary-nav.js.
     The nav height counts even before the bar pins: the browser resolves
     scroll-padding-top when the jump STARTS, and the bar pins during the scroll
     that follows, so a stuck-only value would always arrive too late. */
  scroll-padding-top: calc(
    var(--header-height) + var(--secondary-nav-height, 0px) + 1rem
  );

  /* Silver canvas only shows outside the 1920px body on very wide viewports. */
  background-color: silver;
}

/* The preheader is fixed at top: 0 with the header offset below it, so it
   occludes an anchor target too. scroll-padding-top has to live on <html>,
   which is why the body class is read through :has(). */
html:has(body.has-preheader) {
  scroll-padding-top: calc(
    var(--preheader-height) + var(--header-height) +
      var(--secondary-nav-height, 0px) + 1rem
  );
}

/* Magic line-break token (bold "<br>" authored anywhere).
   A block-level spacer that breaks the line and adds a fixed vertical gap,
   matching the 20px spacing between the h2/h3 in the site's text CTAs. */
.line-break {
  display: block;
  height: var(--line-break-size);
}

/* The SAME spacer, worn by the raw token itself between first paint and the
   moment scripts.js can swap it for a real .line-break — see markLineBreakTokens.
   Without this the literal text "<br>" is visible for as long as the blocks take
   to load. Geometry is identical to .line-break (one --line-break-size per <br>,
   no inherited margins), so the swap is invisible: nothing moves, nothing
   reflows. font-size:0 hides the text without display:none, which would collapse
   the box we are holding open. */
.line-break-token {
  display: block;
  height: calc(var(--line-break-size) * var(--line-break-count, 1));
  margin: 0;
  font-size: 0;
  line-height: 0;
}


body {
  margin: 0 auto;
  max-width: 1920px;
  background-color: var(--color-primary-white);
  color: var(--color-text);
  font-family: var(--font-family);
  font-size: var(--body-font-size-m);
  line-height: var(--body-line-height);
  padding: var(--header-height) 0 0;

  &.has-preheader {
    padding-top: calc(var(--header-height) + var(--preheader-height));
  }

  &.has-breadcrumb {
    margin: calc(var(--header-height) + var(--breadcrumb-height)) 0 0;
  }

  &.no-header {
    --header-height: 0;

    margin: 0;
  }
  p{
    margin: 1rem 0;
  }

}

header {
  display: none;
  height: var(--header-height);
  position: fixed;
}

body.has-preheader header {
  top: var(--preheader-height);
}

/* While the mobile/tablet mega menu is open the preheader is hidden (see
   blocks/preheader/preheader.css), so the header must reclaim the top of the
   viewport instead of keeping the --preheader-height offset above. Same file,
   later source order, higher specificity than the rule above — so it wins
   regardless of block-CSS load order. */
body.has-preheader header.is-mobile-open {
  top: 0;
}

a {
  color: var(--color-link);
  font-weight: 500;

  /* A bolded link (DA emits <strong><a>…</a></strong>) must still read bold —
     the anchor's own 500 would otherwise override the strong's weight — and
     shows its underline at rest instead of only fading in on hover. */
  strong &:not(.btn) {
    font-weight: var(--font-weight-bold);
    text-decoration-color: currentColor;
  }

  /* Regular links: no visible underline by default, fade one in on hover.
     text-decoration-color (unlike text-decoration) is transitionable. */
  &:not(.btn) {
    text-decoration: underline;
    text-decoration-color: transparent;
    text-underline-offset: 0.15em;
    transition: text-decoration-color var(--transition-base);
  }

  &:not(.btn):hover {
    text-decoration-color: currentColor;
  }

  &.btn {
    display: inline-block;
    font-weight: 500;
    border-radius: 0;
    cursor: pointer;
    outline: none;
    padding: 14px 30px;
    position: relative;
    text-decoration: none;
    -webkit-transition: all .3s ease-out;
    transition: all .3s ease-out;

    /* The `outline: none` above is legacy's own (_button.scss `.cmp-button`), but legacy
       puts the ring straight back on every variant with `&:focus-visible { outline: auto; }`
       and the port carried only the first half. Without this a keyboard user tabbing
       through any CTA saw no focus at all — 0 of 16 buttons on both eds-prd homepages
       vs 21 of 21 on rsmus.com, measured 2026-10-22 (WCAG 2.4.7). `auto` is the
       browser's two-tone ring, so it reads on the white and the dark bands alike. */
    &:focus-visible {
      outline: auto;
    }

    &.btn-outline {
      background: transparent;
    }
  }

  &.btn-accent {
    color: var(--color-primary-dark-grey);
    background: var(--color-primary-white);
    border: 0px solid var(--color-primary-green);
    transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

    &:hover {
      background: var(--color-primary-blue);
      color: var(--color-primary-white);
    }

    /* The white OUTLINE — legacy `.cmp-button.secondary._white`: transparent,
       white label, 1px white border. The width is restated because the base
       .btn-accent border is 0px, which left this variant's white border-color
       with nothing to paint. */
    &.btn-outline {
      color: var(--color-primary-white);
      background: transparent;
      border-width: 1px;
      border-color: var(--color-primary-white);
      transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

      &:hover {
        color: var(--color-primary-green);
        background: var(--color-primary-white);
        border-color: var(--color-primary-white);
      }
    }
  }

  &.btn-primary {
    color: var(--color-primary-white);
    background-color: var(--color-primary-green);
    border: 1px solid var(--color-primary-green);
    transition: background-color var(--transition-base), border-color var(--transition-base);

    &:hover {
      background-color: var(--color-primary-hover-green);
      border-color: var(--color-primary-hover-green);
    }

    &.btn-outline {
      color: var(--color-primary-green);
      background: transparent;
      border-color: var(--color-primary-green);
      transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

      &:hover {
        color: var(--color-primary-white);
        background-color: var(--color-primary-hover-green);
        border-color: var(--color-accent-green);
      }
    }
  }

  &.btn-secondary {
    color: var(--color-primary-dark-grey);
    background-color: var(--color-primary-white);
    border: 0px solid var(--color-primary-dark-grey);
    transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

    &:hover {
      color: var(--color-primary-white);
      background-color: var(--color-primary-hover-green);
      border-color: var(--color-primary-green);
    }

    &.btn-outline {
      color: var(--color-primary-dark-grey);
      background: var(--color-primary-white);
      border-color: var(--color-primary-dark-grey);
      border: 1px solid var(--color-primary-dark-grey);
      transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

      &:hover {
        color: var(--color-primary-white);
        background-color: var(--color-primary-hover-green);
        border-color: var(--color-primary-hover-green);
      }
    }
  }

  &.btn-secondary-outline-variant-1 {
    color: var(--color-primary-green);
    background: var(--color-primary-white);
    border: 1px solid var(--color-primary-dark-grey);
    transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

    &:hover {
      color: var(--color-primary-white);
      background-color: var(--color-primary-hover-green);
      border-color: var(--color-primary-hover-green);
    }
  }

  &.btn-negative {
    color: var(--color-primary-white);
    background-color: var(--color-primary-light-grey);
    border: 1px solid var(--color-primary-light-grey);
    transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

    &:hover {
      color: var(--color-primary-white);
      background-color: var(--color-primary-dark-grey);
      border-color: var(--color-primary-dark-grey);
    }

    &.btn-outline {
      display: flex;
      align-items: center;
      justify-content: space-between;
      text-align: left;
      color: var(--color-primary-white);
      background: transparent;
      border-color: var(--color-primary-white);
      transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base);

      &::after {
        content: '\203A';
        margin-left: 1em;
        font-weight: var(--font-weight-bold);
        line-height: 1;
      }

      &:hover {
        color: var(--color-primary-green);
        background-color: var(--color-primary-white);
        border-color: var(--color-primary-white);
      }
    }
  }
}

/* Tablet & mobile (≤991px): buttons span the full width of their container.
   .btn has padding (14px 30px) but no global box-sizing, so border-box keeps
   that padding inside the width instead of overflowing by 60px. text-align
   centres the label, since .btn is inline-block and would otherwise sit left
   once stretched. */
@media (max-width: 991px) {
  a.btn {
    display: block;
    width: 100%;
    box-sizing: border-box;
    text-align: center;
  }
}

/* section-metadata `button-span | true`: reproduce the legacy rsmus.com button
   grid. On the live site that grid is a centered block capped at 1280px, three
   equal columns (~32px gaps → ~405px buttons), and — crucially — every button is
   the SAME height: long labels wrap to two lines and the short ones grow to
   match. We mirror that exactly rather than trying to force one line.
     • cap + center the grid at the live 1280px (shrink with a 40px side margin
       on narrower viewports, as the live layout does);
     • reclaim the per-column side padding as button width and use an even grid
       gap between columns;
     • give every button a min-height of exactly two text lines (2lh + the
       28px vertical padding, box-sizing:border-box) so a one-line label grows to
       the two-line height — uniform boxes, no magic numbers.
   Text-align stays owned by the button variant, so the .btn-negative.btn-outline
   layout (left label + right chevron) is unaffected. */
main .section.button-span .cta .cta-content {
  max-width: 1280px;
  width: calc(100% - 80px);
  margin-inline: auto;
}

main .section.button-span .cta-columns {
  gap: var(--spacing-xl, 32px);
}

main .section.button-span .cta-column {
  padding-left: 0;
  padding-right: 0;
}

main .section.button-span a.btn {
  width: 100%;
  box-sizing: border-box;
  min-height: calc(2lh + 32px);
}

/* The wrapper fragment.js builds around a loaded fragment. It needs its own
   `display` for the same cascade reason `.section` does: it is a direct child of
   `main` whenever a fragment link sits at the top level of a document, and the
   `main > div` guard further down hides every such child until something
   out-points it. `.fragment-content` never carries `.section`, so without this
   rule nothing ever does and the fragment stays hidden forever.

   That was ISS-259: `404.html` is the one page whose fragment link is a direct
   child of `main`, and rsm-us's `/fragments/404` holds three sections, so
   fragment.js keeps the wrapper instead of hoisting a lone section. Every rsm-us
   404 rendered a blank body — `main` 0px tall, the copy present in the DOM at
   0x0 — while returning HTTP 404 with a resolved fragment and correct
   `.plain.html`. Nothing that stops short of measuring layout can see that.

   This cannot flash undecorated: the wrapper is script-created after `loadArea`
   has run on its contents and is never present in the served HTML. */
.fragment-content {
  display: block;
}

/* sections */
.section {
  display: block;
  background-color: var(--color-primary-white);

  > .default-content {
    max-width: var(--grid-container-width);
    margin: 0 auto;

    img {
      width: auto;
      max-width: 100%;
      display: block;
      margin: 0 auto;
    }
  }
}

/* A FRAGMENT'S section loaded in BLOCK position — fragment.js puts the fragment's own
   section inside the host section's `.block-content` — paints nothing of its own unless
   it authors a fill. Legacy's XF containers are transparent, so the host band shows
   through. The rule above made it a white slab on the host's fill: rsm-us
   /events/2025-events/whats-next-for-ipos-in-2025/thank-you-whats-next-for-ipos-2025
   hosts the undeliverable-protocol fragment inside its #F0F0F0 cardlist band, and at
   1440 legacy draws that copy on rgb(240,240,240) while ours drew it on white (C45).
   `:where()` keeps this at the specificity of `.section`, so any authored fill — a
   class rule or the inline colour decorateSectionData sets — still wins. */
:where(main .section .block-content) > .section {
  background-color: transparent;
}

/* Authored body copy — match rsm.global computed paragraph metrics
   (line-height 1.333, margin-bottom 10px). Scoped to default-content so it
   does not disturb the global body line-height, tables, forms, or block CSS. */
main .section > .default-content p {
  line-height: 1.333;
  margin-bottom: 10px;
}

/* Emphasis INSIDE an authored heading — `<h3><b>Stay alert: …</b></h3>`.
   Legacy leaves that `<b>` entirely to the UA, whose default is the RELATIVE
   `font-weight: bolder`; against a heading at 300 the bolder table resolves it to
   400. This repo's global `strong { font-weight: var(--font-weight-bold) }` (below)
   is ABSOLUTE, so the same authored heading landed two steps heavier than the
   source. Measured at 1440px on rsm-us /careers/experienced/audit-careers —
   legacy `<b>` computes 400, ours computed 600 — reported by the client as
   "the heading shouldn't be bolded".
   `bolder` rather than a literal 400 so the relationship survives a heading that
   sets its own weight, exactly as the UA rule it restores would.

   Scoped to `.default-content`, which scripts/ak.js groupChildren() makes the exact
   analogue of legacy's `.cmp-text` (see the blockquote note below). A block that
   styles emphasis in its own headings therefore keeps its own rule — `event-hero`
   pins the same construct to `inherit` for its kicker, and carries the font-matching
   trap behind 600 in full. */
main .section > .default-content :is(h1, h2, h3, h4, h5, h6) :is(strong, b) {
  font-weight: bolder;
}

/* The same restoration for the LIGHT headings inside blocks (ISS-595). The importer
   (cleanRichText) now keeps an authored <b> in h1–h3 — column cells, table cells,
   cards, article bodies — because legacy draws it: rsmus.com/industries/health-care's
   stat `<h3><b>3,500+</b></h3>` computes 400 in a 300 h3 @1440 and @390, while ours
   drew 300. Without this rule the global `strong { 700 }` would jump it to 700.

   h4–h6 are left out: the importer still strips <strong> there, because legacy's
   bolder against their 700 requests the Black face it never loads.

   `:where()` keeps this at (0,0,2), just above the global `strong`, so a block that
   sets its own heading-emphasis weight still wins (event-hero pins it to `inherit`,
   and columns does the same where it had pinned the heading at 400 to stand in for
   the <b> the importer used to strip). */
main :where(h1, h2, h3) :is(strong, b) {
  font-weight: bolder;
}


/* In-flow blockquote — the legacy pull-quote a news release authors INSIDE its
   body copy. Legacy styles every rich-text blockquote globally
   (`.cmp-text blockquote` in clientlib-site.css, flat at all viewports):

     border-top/bottom: 1px solid #d9dada; color: var(--primary-dark-grey);
     font-size: 24px; font-style: italic; font-weight: 700; padding: 20px 0;

   so a bare <blockquote> that carries no block wrapper still renders as a
   bold-italic quote framed by hairline rules. EDS had no equivalent, so those
   blockquotes inherited plain body copy: right words, wrong weight, and no
   divider bars. Measured across the published corpus: 389 such quotes on 358
   pages (100 on 86 rsm-ca, 289 on 272 rsm-us).

   `.default-content` is the exact analogue of `.cmp-text`: groupChildren() in
   scripts/ak.js puts every NON-div child (p, headings, blockquote) there and
   every div (i.e. every block) in `.block-content`. Scoping here therefore
   cannot reach a blockquote a block owns — `quote` builds its own in
   `.quote-body` (see quote.css `quote-inline`, the opt-in variant that renders
   this same treatment when the quote IS authored as a block), and
   `rsm100-section` styles `.rsm100-section-content blockquote` itself.

   #d9dada is legacy's literal hairline and has no `--color-*` token — the
   nearest, `--color-light-grey-2` (#cdcecf), is a shade darker. Kept in sync
   with quote.css `quote-inline` by hand; both cite this same legacy rule. */
main .section > .default-content blockquote {
  margin: 0;
  padding: 20px 0;
  border-block: 1px solid #d9dada;
  color: var(--color-primary-dark-grey);
  font-size: 24px;
  font-style: italic;
  font-weight: 700;
}

/* The legacy blockquote holds raw text; DA wraps it in a <p>, whose own margin
   would otherwise stack on top of the 20px padding above and pull the rules
   apart. Zero it so the framed height matches legacy. */
main .section > .default-content blockquote p {
  margin: 0;
}

main .section > .default-content blockquote p + p {
  margin-top: 10px;
}

/* full-width: release the section's content from the centered 90% rail so it
   stretches to the full section width (up to the 1920px body cap). Authored via
   Section Metadata › Style: full-width. Lives here (not section-metadata.css)
   because EDS can strip that sheet. */
main .section.full-width > .default-content,
main .section.full-width > .block-content {
  max-width: 100%;
}

/* card-width | full-width (Section Metadata) — force the card grid in this
   section to span the full section width, like the featured cards atop
   rsmus.com/insights.html. A `card` block is double-capped: the section's
   block-content rail AND the block's own --grid-container-width (see card.css).
   This releases the block-content wrapper so the grid can stretch edge-to-edge
   (up to the 1920px body cap); the per-block cap and the desktop 4-up column
   layout are released in card.css. Only .block-content is released (NOT
   .default-content), so sibling headings/text in the section stay on the normal
   centered rail — this widens cards, not copy. Lives here (not
   section-metadata.css) because EDS can strip that sheet. */
main .section.card-width-full-width > .block-content {
  max-width: 100%;
}

/* section style variants (authored via Section Metadata › Style field) */
main .section.text-light {
  color: var(--color-white);

  h1, h2, h3, h4, h5, h6 { color: var(--color-white); }

  a:any-link:not(.btn) { color: var(--color-white); }
}

/* Heading highlight (C77, ISS-593 / ISS-607) — Section Metadata › Style:
   heading-highlight-blue | heading-highlight-navy. Legacy authors it as
   `<h2><span style="background-color:…">…</span></h2>`: a block heading with
   one inline run, so a colour box sits behind each LINE of text. DA unwraps
   every span, so the importer hoists a span that wraps a WHOLE h1–h3 to this
   section style, and section-metadata.js restores the run as
   `.heading-highlight-run` (the heading stays a block: alignment and margins
   unchanged). Measured on legacy (rsmcanada.com agentic-ai-xf, @1440 + @390):
   the run is inline, padding 0, box-decoration-break slice — so nothing but
   the colour is set here. Section-wide by design: the importer applies it only
   when EVERY h1–h3 in the section was highlighted. */
main .section.heading-highlight-blue :is(h1, h2, h3) > .heading-highlight-run { background-color: var(--color-primary-blue); }
main .section.heading-highlight-navy :is(h1, h2, h3) > .heading-highlight-run { background-color: var(--color-dark-navy); }

/* Author aid — Section Metadata → Style: link-<color> recolors a section's
   default-content links (e.g. a trailing "See all …" link). Scoped to
   .default-content so block links (cards, etc.) are unaffected; covers plain
   links and DA button links, and overrides the hover colour too. To add a
   colour: set --section-link-color in a new rule and add the class to the
   :is() list below.
   NOTE: this color-only helper is DISTINCT from the `link | dark` key
   (data-link, further below) — that one is the full legacy-sitemap link-list
   treatment (chevron, bulletless, reaches .block-content). */
main .section:is(
    .link-dark, .link-white, .link-green, .link-blue,
    .link-grey, .link-gray, .link-medium-grey, .link-light-grey
  ) .default-content a:any-link,
main .section:is(
    .link-dark, .link-white, .link-green, .link-blue,
    .link-grey, .link-gray, .link-medium-grey, .link-light-grey
  ) .default-content a:any-link:hover {
  color: var(--section-link-color);
}

main .section.link-dark { --section-link-color: #000; }
main .section.link-white { --section-link-color: var(--color-white); }
main .section.link-green { --section-link-color: var(--color-green); }
main .section.link-blue { --section-link-color: var(--color-blue); }
main .section.link-grey,
main .section.link-gray { --section-link-color: var(--color-dark-grey); }
main .section.link-medium-grey { --section-link-color: var(--color-medium-grey); }
main .section.link-light-grey { --section-link-color: var(--color-light-grey); }

/* bg-* section backgrounds — background-color and base text contrast come from
   the global bg-* rules above; only section-specific overrides live here. */
main .section.bg-navy {
  background-color: var(--color-navy);
  color: var(--color-white);

  h1, h2, h3, h4, h5, h6 { color: var(--color-white); }

  a:any-link:not(.btn) { color: var(--color-white); }
}

main .section.bg-light-grey {
  background-color: var(--color-light-grey);
  color: var(--color-primary-dark-grey);
}

main .section.bg-accent-green {
  background-color: var(--color-accent-green);
  color: var(--color-white);

  h1, h2, h3, h4, h5, h6 { color: var(--color-white); }

  a:any-link:not(.btn) { color: var(--color-white); }

  a.btn { border-color: var(--color-white); }
}

main .section.bg-blue {
  background-color: var(--color-blue);
  color: var(--color-white);

  h1, h2, h3, h4, h5, h6 { color: var(--color-white); }

  a:any-link:not(.btn) { color: var(--color-white); }
}

/* Global bg-* block background variants.
   Authored as Block (bg-green), Block (bg-navy), etc. in Document Authoring.
   Light backgrounds keep default dark text; dark backgrounds flip to white.
   Block-specific link-colour overrides (e.g. navy links) stay in block CSS. */
.bg-white { background-color: var(--color-white); }
.bg-light-green { background-color: var(--color-light-green); }
.bg-light-blue { background-color: var(--color-light-blue); }
.bg-light-grey { background-color: var(--color-light-grey); }
.bg-green { background-color: var(--color-green); }
.bg-blue { background-color: var(--color-blue); }
.bg-accent-green { background-color: var(--color-accent-green); }
.bg-navy { background-color: var(--color-navy); }
.bg-grey { background-color: var(--color-grey); }
.bg-medium-grey { background-color: var(--color-medium-grey); }
.bg-dark-grey { background-color: var(--color-dark-grey); }

:is(.bg-green, .bg-blue, .bg-accent-green, .bg-navy,
    .bg-grey, .bg-medium-grey, .bg-dark-grey) {
  color: var(--color-white);

  h1, h2, h3, h4, h5, h6, p { color: var(--color-white); }

  a:any-link:not(.btn) { color: var(--color-white); }
}

/* Section background images (data-background-image). decorateSectionData adds
   .has-background globally, but section-metadata.css only loads when that block
   is present — so size/center the image here in the always-loaded global sheet. */
/* Section backgrounds. These rules live in the always-loaded global sheet
   because section-metadata.css only loads when the section-metadata block is
   present — so the block CSS can't be relied on in production. */
main .section.has-background {
  position: relative;
  min-height: 300px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* An IMAGE banner is a fixed-height band in legacy; ours was content-sized, so
   `background-size: cover` cropped the subject (f-260920-pqjm: "the image of the
   man and woman is getting cropped").

   Measured on the render pair at 1440/1280/1024/992, rsm-us /careers/experienced
   vs rsmus.com/careers/experienced.html — legacy's CTA banner (`.desktop-background`
   after the first) is a FLAT 480px at every one of those widths, on 9 of 9 sampled
   pages and 13 of 13 CTA-banner instances: /careers/experienced (2),
   /careers/experienced/audit-careers (1), /services/audit-services (2),
   /industries/retail (1), /about/year-in-review (1), /technologies/dayforce (1),
   /offers/finance-accounting-outsourcing (1), /industries/asset-management (3),
   /industries/private-equity (1). The asset-management page is the sharpest of
   them: legacy 480/480/480, ours 380/380/395 before and 480/480/480 after.
   Ours came out 380px, and 424px where the copy ran longer — same 1440 width and
   the same `cover`, so 100px more of the image was cropped away vertically.

   Count the CTA banners only. The FIRST `.desktop-background` on each of those
   pages is the hero, and it is 450px, not 480 — so an element count over that
   class reads 14 instances at two different heights and averages into a number
   neither component has.

   Three things this is deliberately NOT:
   - NOT keyed on `.has-background` alone. That class is also on colour-only bands
     (861 pages / 1935 `background-color` section rows in the staged corpus vs 141
     pages / 168 `background-image` rows), and a flat 480px floor is wrong for a
     band with no image to crop. `[data-background-image]` selects the image class
     and only it.
   - NOT applied below 992px. There, legacy HIDES the desktop background outright
     (measured `display:none`, height 0 at 768) and so do we, two rules down — a
     floor under a band with no image would just be a tall empty box.
   - NOT `min-height: 480px` on its own. `min-height` sizes the CONTENT box, and
     this section carries 40px of block padding each side, so the bare value
     renders 560px. Same content-box trap as `.section.box`. `border-box` makes the
     number in this rule the number on the screen.

   The hero is a different component (`.hero`) and is untouched: legacy's hero is
   450/400/426px across those widths, not a constant, and ours already matches.

   One page in the sample does NOT have a legacy counterpart to match, and it is
   recorded rather than dropped: rsm-us /industries/financial-services renders an
   image band here (380 -> 480) where legacy shows a hero and no CTA banner at all.
   That is a content-shape difference, not evidence about the height, so it neither
   supports nor contradicts the 480 — but the band is real on our side, and 480 is
   what every measured legacy banner does. */
@media (width >= 992px) {
  main .section.has-background[data-background-image] {
    box-sizing: border-box;
    min-height: 480px;
  }
}

/* The same floor for a BOXED panel whose background is the picture form
   (`background-image` / `background-image-mobile` section-metadata keys →
   <picture class="section-background">), which never carries the attribute the
   rule above keys on. It is the same legacy component: `.has-desktopBg`, a
   `min-height: 480px` on any container that paints a desktop background.
   Measured 2026-10-08 on rsm-ca …/persistent-cybersecurity-threats-require-
   protective-strategies (nine chapter banners): legacy 940x480 @1440 and 370x480
   @390, ours 853x300 at both — the 300 is `.has-background`'s own floor, and the
   cover-fit art lost its icon to the crop.

   Below 992px only WITH a mobile picture: legacy keeps the 480 there because it
   swaps in `cyber_break_mob.jpg`; without one the desktop picture hides (the
   `:not(.has-mobile-background)` rules below) and a floor would be an empty box.
   `.section.box` is already border-box, so the number is the number on screen.

   BOTH background forms, below 992px. The published page does not keep the
   picture form: the pipeline delivers the section-metadata background as the
   ATTRIBUTE form (`data-background-image` / `-mobile`, painted inline), so on the
   CDN the desktop floor above already applies — and this mobile rule, written
   for the picture form only, matched nothing. Measured 2026-10-08 on that page on
   eds-prd.rsmcanada.com after re-stage: 853x480 @1440 (right), 370x300 @390
   (legacy 370x480). Still scoped to `.box`: an unboxed CTA banner's mobile height
   has not been measured, so it is left alone. */
@media (width >= 992px) {
  main .section.box.has-background:has(> picture.section-background) {
    min-height: 480px;
  }
}

main .section.box.has-mobile-background:is(:has(> picture.section-background.mobile), [data-background-image-mobile]) {
  min-height: 480px;
}

/* …and the UNBOXED band with a mobile picture, below 992px, which the note above left
   unmeasured. It is the same legacy rule (`.cmp-container.has-mobileBg { min-height:
   480px }` below `desktop`, RSMUS_ACM _container.scss), not a box-only one. Measured
   2026-10-13 @390, rsm-us …/aimbridge-case-study-hospitality-company-focuses-on-process-
   integration, the "Ready to modernize your finance function?" CTA band
   (/fragments/digital-transformation, mobile picture digital_data_binary_abs_ctamob.jpg
   on both sides): legacy 480 tall, ours 380 (f-260624-i161). border-box because an
   unboxed section is content-box with block padding, which would render 560. */
@media (width < 992px) {
  main .section.has-mobile-background:is(:has(> picture.section-background.mobile), [data-background-image-mobile]) {
    box-sizing: border-box;
    min-height: 480px;
  }
}

/* Content sits above the background image and stays within the grid width. */
main .section.has-background > :is(.default-content, .block-content) {
  position: relative;
  z-index: 2;
  width: 100%;
}

/* Picture-based backgrounds (background-image / background-image-mobile keys →
   <picture class="section-background desktop|mobile">). */
main .section picture.section-background {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
}

main .section .section-background img {
  object-fit: cover;
  height: 100%;
  width: 100%;
}

/* A mobile background hides until the breakpoint, where it swaps in. */
main .section.has-mobile-background .section-background.mobile {
  display: none;
}

@media (width < 992px) {
  main .section.has-mobile-background .section-background.desktop {
    display: none;
  }

  main .section.has-mobile-background .section-background.mobile {
    display: block;
  }

  /* Attribute form (inline CSS background via --section-bg, no <picture>): swap
     the desktop URL for the mobile one below 992px. --section-bg is set as an
     INLINE custom property by the JS, which normally out-specifies a stylesheet
     rule — so !important is required here for the reassignment to win. */
  main .section.has-mobile-background {
    --section-bg: var(--section-bg-mobile) !important;
  }

  /* No mobile background authored: below 992px drop the image so the section's
     background-color shows instead (a desktop banner image often doesn't crop
     well on narrow screens). This covers BOTH background paths:
       - picture form   → hide the .section-background.desktop element
       - attribute form (data-background-image → inline CSS background-image on
         the section) → null the inline image via a custom property fallback.
     Sections with no background-color simply show no image here. */
  main .section.has-background:not(.has-mobile-background) .section-background.desktop {
    display: none;
  }

  main .section.has-background:not(.has-mobile-background) {
    background-image: none !important;
  }

  /* background-color-mobile (section-metadata option): below 992px, override
     the section background-color with the authored mobile value. Typically used
     where a desktop background-image is hidden on mobile and a flat colour
     should replace it. The value is set inline by section-metadata.js. */
  main .section.has-mobile-bg-color {
    background-color: var(--background-color-mobile) !important;
  }

  /* Copy on the flat fallback above takes white or dark, whichever passes 4.5:1
     (CAM-033, RSM ruling Q14 2026-09-25). section-metadata.js marks only the
     elements that sit directly on the band AND fail against its fallback colour,
     and picks the colour; this applies it. Same selector as the image drop, so it
     can only act where the image is actually gone. !important because the copy's
     own colour comes from rules of every specificity (text-light, panel-text-light,
     .default-content.dark-scheme). Desktop is untouched: this is the only rule. */
  main .section.has-background:not(.has-mobile-background) .mobile-fallback-text {
    color: var(--mobile-fallback-text) !important;
  }

  main .section.has-background:not(.has-mobile-background) a.btn.mobile-fallback-text {
    border-color: var(--mobile-fallback-text) !important;
  }
}

/* Per-tag text centering via data-text-center="h1,p" etc. (set by section-metadata) */
main .section[data-text-center*="h1"] :is(.default-content, .block-content) h1,
main .section[data-text-center*="h2"] :is(.default-content, .block-content) h2,
main .section[data-text-center*="h3"] :is(.default-content, .block-content) h3,
main .section[data-text-center*="h4"] :is(.default-content, .block-content) h4,
main .section[data-text-center*="h5"] :is(.default-content, .block-content) h5,
main .section[data-text-center*="h6"] :is(.default-content, .block-content) h6,
main .section[data-text-center*="p"] :is(.default-content, .block-content) p,
main .section[data-text-center*="li"] :is(.default-content, .block-content) li {
  text-align: center;
}

main .section[data-text-right*="h1"] :is(.default-content, .block-content) h1,
main .section[data-text-right*="h2"] :is(.default-content, .block-content) h2,
main .section[data-text-right*="h3"] :is(.default-content, .block-content) h3,
main .section[data-text-right*="h4"] :is(.default-content, .block-content) h4,
main .section[data-text-right*="h5"] :is(.default-content, .block-content) h5,
main .section[data-text-right*="h6"] :is(.default-content, .block-content) h6,
main .section[data-text-right*="p"] :is(.default-content, .block-content) p,
main .section[data-text-right*="li"] :is(.default-content, .block-content) li {
  text-align: right;
}

main .section[data-text-left*="h1"] :is(.default-content, .block-content) h1,
main .section[data-text-left*="h2"] :is(.default-content, .block-content) h2,
main .section[data-text-left*="h3"] :is(.default-content, .block-content) h3,
main .section[data-text-left*="h4"] :is(.default-content, .block-content) h4,
main .section[data-text-left*="h5"] :is(.default-content, .block-content) h5,
main .section[data-text-left*="h6"] :is(.default-content, .block-content) h6,
main .section[data-text-left*="p"] :is(.default-content, .block-content) p,
/* `li` (T-C7 round 3): a list in a left-governed fragment is copy too — see
   engine scripts/lib/fragment-align.mjs › unclaimedTags. */
main .section[data-text-left*="li"] :is(.default-content, .block-content) li {
  text-align: left;
}

/* POSITIONAL alignment (ISS-550): one element whose legacy alignment differs from its tag's,
   stamped by section-metadata.js from `text-center | h2:2`. (0,4,1) outranks the (0,3,2) tag
   rules above, so an explicit per-element value wins over the tag-wide one. ISS-562 extends it
   to block content (`b:p:4~fp`): the tag rows reach .block-content too, and a block element
   legacy aligns differently from its row is stamped the same way. :is() keeps (0,4,1). */
main .section[data-text-pos] :is(.default-content, .block-content) [data-text-align="center"] { text-align: center; }
main .section[data-text-pos] :is(.default-content, .block-content) [data-text-align="right"] { text-align: right; }
main .section[data-text-pos] :is(.default-content, .block-content) [data-text-align="left"] { text-align: left; }

/* MOBILE alignment (`text-left-mobile`, set by section-metadata.js): legacy's one responsive
   alignment rule, `.ta-center.mobile-left` = centre >=992px, LEFT below (RSMUS_ACM
   _container.scss, `media("<desktop")`, desktop = 992px). Legacy's rule also forces its own
   centred titles left, so this has to beat a desktop POSITIONAL stamp (0,4,1), not just the
   desktop tag rows (0,3,2): the `:is(hN, hN[data-text-align])` lifts each tag rule to (0,4,2).
   The mobile positional stamp is (0,4,1) and comes after the desktop one, so it wins below 992px.
   A section without the key renders exactly as before. */
@media (width < 992px) {
  main .section[data-text-left-mobile*="h1"] :is(.default-content, .block-content) :is(h1, h1[data-text-align]),
  main .section[data-text-left-mobile*="h2"] :is(.default-content, .block-content) :is(h2, h2[data-text-align]),
  main .section[data-text-left-mobile*="h3"] :is(.default-content, .block-content) :is(h3, h3[data-text-align]),
  main .section[data-text-left-mobile*="h4"] :is(.default-content, .block-content) :is(h4, h4[data-text-align]),
  main .section[data-text-left-mobile*="h5"] :is(.default-content, .block-content) :is(h5, h5[data-text-align]),
  main .section[data-text-left-mobile*="h6"] :is(.default-content, .block-content) :is(h6, h6[data-text-align]),
  main .section[data-text-left-mobile*="p"] :is(.default-content, .block-content) :is(p, p[data-text-align]),
  main .section[data-text-left-mobile*="li"] :is(.default-content, .block-content) :is(li, li[data-text-align]) {
    text-align: left;
  }

  main .section[data-text-pos] :is(.default-content, .block-content) [data-text-align-mobile="left"] { text-align: left; }
}

/* A standalone GRAPHIC is not body copy. The EDS pipeline wraps a lone image in
   its own <p>, so it inherits the 10px body-paragraph margin above and sits half
   as far from the heading that follows as legacy puts it. Measured 2026-08-26 at
   1440 on /technologies/microsoft/services/managed-services/managed-applications,
   both full-width graphics on the page:

     legacy   mas-pillars-infographic (840x792)   20px before the next H2
              mas-focus-areas-graphic (840x587)   20px
     EDS      both                                10px

   Scoped to a <p> whose ONLY child is the picture, so an inline image sitting
   alongside text keeps the body-copy margin it should have. A LINKED graphic
   (`<p><a><picture>`, C50 / ISS-531 — legacy's cmp-image__link) is the same
   graphic, so each of these three rules names both shapes. */
main .section > .default-content p:has(> picture:only-child, > a:only-child > picture:only-child) {
  margin-bottom: 20px;
}

/* …EXCEPT in a section that declares `spacing: none`, where the whole point is that
   the artwork meets what is above and below it with nothing between. The rule above
   is for a CONTENT graphic sitting in the copy rail; a bare section-level image is a
   full-bleed band whose ground is baked into the raster, so any margin on its own <p>
   reads as a white stripe across the band's edge.

   f-260819-g7ae, measured 2026-09-08 at 1440 on the reported page: with the section
   padding already zeroed by `spacing: none`, the <p> still carried margin 16px/20px,
   and `main` ended 20px above the footer — a white bar under the navy badge strip,
   which is exactly what `spacing: none` promises not to leave. Legacy has none.

   Scoped to the section that OPTED IN, so a picture in any normally-spaced section
   keeps the 20px the rule above measured for it. */
main .section.spacing-none > .default-content > p:has(> picture:only-child, > a:only-child > picture:only-child) {
  margin-block: 0;
}

/* Same, for the separate below-992px scale (see the mobile-spacing block further
   down): a section can be spaced on desktop and flush on mobile, or the reverse. */
@media (width < 992px) {
  main .section.mobile-spacing-none > .default-content > p:has(> picture:only-child, > a:only-child > picture:only-child) {
    margin-block: 0;
  }
}

/* link | dark (section-metadata `link` key → data-link) — legacy sitemap
   link-list styling: dark-grey links, no underline until hover, each followed by
   a chevron. Mirrors rsmus.com .cmp-linklist__item a (color #515356 =
   --color-primary-dark-grey) + its em.fa-chevron-right (›). Distinct from the
   color-only `style: link-<color>` class helper above: this is the full
   link-list treatment and reaches .block-content links (the sitemap's `columns`
   lists), not just .default-content. Scoped off buttons so they keep styling. */
main .section[data-link~="dark"] :is(.default-content, .block-content) ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* stylelint-disable-next-line no-descending-specificity */
main .section[data-link~="dark"] :is(.default-content, .block-content) a:not(.button) {
  display: inline-block;
  padding-block: 0.1rem;
  color: var(--color-primary-dark-grey);
  text-decoration: none;
}

main .section[data-link~="dark"] :is(.default-content, .block-content) a:not(.button):hover,
main .section[data-link~="dark"] :is(.default-content, .block-content) a:not(.button):focus {
  text-decoration: underline;
}

main .section[data-link~="dark"] :is(.default-content, .block-content) a:not(.button)::after {
  content: "\203a"; /* › — the legacy fa-chevron-right glyph */
  display: inline-block;
  margin-left: 0.4rem;
  font-size: 1.1em;
  font-weight: 400;
  line-height: 1;
  text-decoration: none;
}

/* container-N (N = column count out of 12) — constrains section content width.
   Usage: style: container-8 → 8/12 of grid container width, centered.
   Only applies at >=900px; on mobile / tablet the content fills the grid
   container so narrow column counts don't smoosh content into a tiny strip. */
@media (width >= 992px) {
  main .section.container-1,
  main .section.container-2,
  main .section.container-3,
  main .section.container-4,
  main .section.container-5,
  main .section.container-6,
  main .section.container-7,
  main .section.container-8,
  main .section.container-9,
  main .section.container-10,
  main .section.container-11,
  main .section.container-12 {
    .default-content,
    .block-content {
      max-width: calc(var(--grid-column-width) * var(--container-cols));
      margin-inline: auto;
    }
  }
}

/* …and RELEASE the block's own rail cap inside that wrapper.

   28 blocks (accordion, cardlist, divider, bio-card-list, columns, card, cta,
   carousel, key-takeaways, table, …) cap themselves at
   `max-width: var(--grid-container-width)` with an auto inline margin, because
   outside a container-N section `.block-content` has NO cap and the block is what
   puts itself on the grid rail. Inside a container-N section the wrapper above
   already IS the rail, so that cap applies it a SECOND time — 90% of an
   already-narrowed wrapper — and the auto margin centres the remainder, insetting
   the block from the section's own heading.

   Only bites between 992 and 1440px. Below 992 the container-N rule above does not
   apply at all; at >= 1440 --grid-container-width is the fixed 1280px, which is
   wider than any container-N rail, so the wrapper's max-width already wins and
   nothing changes. That is why the defect reads as "fine on my monitor, broken on
   a laptop".

   Measured 2026-09-04 on rsm-ca /industries/technology at 1280px — every block in
   the page was inset, not just the reported one:
     container-8  wrapper 768 → block 691, inset 38px  (both accordions, both
                  dividers, bio-card-list, both column rows)
     container-12 wrapper 1152 → cardlist 1037, inset 58px
   Legacy renders each of those flush with its heading at every width (measured
   1920/1600/1440/1280/1200/1024/900/768: delta 0 on rsmcanada.com, 38px here).

   Scoped to `> *` — the block root — not to descendants, so a block's INTERNAL
   caps (carousel's `.carousel-slide-content`, card's grid) are untouched. Sections
   with NO container-N are untouched too: there the block's own cap IS the rail and
   removing it would go full-bleed. `.section.carousel` already solved this for
   itself in carousel.css with a per-block copy of the same calc; this is that fix
   done once, for every block. */
@media (width >= 992px) and (width < 1440px) {
  main .section:is(
    .container-1, .container-2, .container-3, .container-4,
    .container-5, .container-6, .container-7, .container-8,
    .container-9, .container-10, .container-11, .container-12
  ) > :is(.default-content, .block-content) > * {
    max-width: 100%;
  }
}

main .section.container-1 { --container-cols: 1; }
main .section.container-2 { --container-cols: 2; }
main .section.container-3 { --container-cols: 3; }
main .section.container-4 { --container-cols: 4; }
main .section.container-5 { --container-cols: 5; }
main .section.container-6 { --container-cols: 6; }
main .section.container-7 { --container-cols: 7; }
main .section.container-8 { --container-cols: 8; }
main .section.container-9 { --container-cols: 9; }
main .section.container-10 { --container-cols: 10; }
main .section.container-11 { --container-cols: 11; }
main .section.container-12 { --container-cols: 12; }

/* container-9 IS legacy's rem17 rail — to the pixel (CAM-038, Q01 Group C).

   RSM ruling 2026-09-26 (plans/rsm-decisions/Q01, Group C): "match the current
   site to the pixel … adding a width step if no standard width lands there".

   Legacy has exactly two rail tokens, `p-l/r-rem17` and `p-l/r-rem20` (RSMUS_ACM
   structure/container/_container.scss, applied from `tablet`), inside a content
   box of `min(1280px, viewport - 2 x 20px gutter)` (`$gutter` below desktopLg,
   `$padding-sides` above it, which pins 1280 at >= 1440). So a rem17 band is
   `min(1280px, 100% - 40px) - 340px`: 940 at 1440, 900 at 1280, 612 at 992 —
   measured on rsmus.com /insights/economics/margin-pressure-…-profitability and
   /about/the-rsm-classic, 2026-09-30, every rem17 text block at all three widths.
   No 12th of our rail lands there: container-9 is 960 at 1440 (+20) and 864 at
   1280 (-36), container-8 is 853. This is the width step.

   It retunes container-9 rather than adding a token because legacy NEVER renders
   960 anywhere — every emitter path that writes container-9 is approximating
   this rail: containerFromPadding's rem17-on-rail (ISS-430/437, the ~890-page
   class this ruling is about), the two-up panel band widened from container-8
   (column-panel.mjs, whose legacy card measured 352 against container-9's 360 —
   this moves it to ~352), and the rail-cache snap of a ~940 legacy rail. A new
   token would also have needed a re-stage to reach any page; this ships on
   deploy to every page already carrying container-9. Pages still on the
   pre-ISS-437 container-10 (e.g. /industries/automotive) change only when they
   are re-staged.

   Not changed: below 992, where container-N has never applied (legacy does
   narrow a rem17 band from 768, to 408px at 768 — that is a separate question
   and not what Group C measured); and container-8 (rem20, 853 vs legacy 880),
   which is not the ~890-page class the ruling sized. See ISS-586. */
@media (width >= 992px) {
  main .section.container-9 > :is(.default-content, .block-content) {
    max-width: calc(min(1280px, 100% - 40px) - 340px);
  }

  main .section:is(.box, .layout-box).container-9 {
    max-width: calc(min(1280px, 100% - 40px) - 340px);
  }
}

/* em-inset-2 (+ em-inset-outer): legacy's article body nested TWO deep in containers
   that each author m-l/m-r-em20 AND p-l/p-r-em20 (ISS-540 shape 6; f-260920-hp31,
   f-260920-5n5f). Emitted ON container-8 (insights-article-us bodyKv, lib nestedEmInset),
   so a page whose CSS predates these tokens renders as container-8 did.

   Each em20 container takes 36px margin + 36px padding a side, so the pair takes 288px
   off legacy's content box, `min(1280px, viewport - 2 x 20px gutter)` (the same box the
   container-9 rule above models). When the section root is ALSO an em20 container on
   the viewport (`em-inset-outer`), its 144px comes off as well below 1440; from 1440 the
   rail is pinned at 1280 ($padding-sides) and absorbs it. Measured on rsmus.com
   …/ransomware-as-a-service-… body copy: 1920 992@464, 1600 992@304, 1440 992@224,
   1280 808@236, 1024 552@236 — 992 = 1280 - 288, 808 = 1280 - 184 - 288,
   552 = 1024 - 184 - 288. Below 992 container-N never applies and legacy matches ours
   (372 at 390). */
@media (width >= 992px) {
  main .section.em-inset-2 > :is(.default-content, .block-content) {
    max-width: calc(min(1280px, 100% - 40px) - 288px);
  }

  main .section.em-inset-2.em-inset-outer > :is(.default-content, .block-content) {
    max-width: calc(min(1280px, 100% - 184px) - 288px);
  }
}

@media (width >= 1440px) {
  main .section.em-inset-2 > :is(.default-content, .block-content),
  main .section.em-inset-2.em-inset-outer > :is(.default-content, .block-content) {
    max-width: 992px;
  }
}

/* Layout: box — confine the section (and its authored background color) to a
   centered, container-width panel. Body is white so the sides show white rather
   than silver. Authored via section-metadata "style: box" / "layout: box", or
   a data-layout="box" attr. */
main .section.box,
main .section.layout-box {
  /* border-box, NOT the document default. There is no global `* { box-sizing }`
     in this sheet (see the .btn note above, which says so explicitly), so this
     element would otherwise size its CONTENT to max-width and add the 32px
     inline padding OUTSIDE it — the panel then sits 32px PROUD of the content
     rail on each side, and the text inside it lands on the rail instead.

     Legacy is the other way round, and that is the whole defect: its panel edge
     is flush with the body copy above and the text is inset by the panel's own
     padding. Measured 2026-09-11 on rsm-us /services/audit-services against the
     legacy control at four viewports — legacy `.cmp-container` (#f0f0f0,
     `p-l-em16`/`p-r-em16` = 28.8px) is x250 w940 @1440 while the copy above it
     is x250 w940, i.e. identical; ours was x155 w1131 against a x187 w1067 rail.
     With this line the panel lands x187 w1067 — delta to the rail -32px -> +0px,
     exactly legacy's relationship. Reported by the user as "the grey section
     width isn't in line with the page and text above it".

     Blast radius, measured over every published page rather than estimated:
     4,193 of 6,890 pages carry a box section, 12,311 sections in all, 12,194 of
     them paired with container-8. Sampled A/B at 1280 and 1440 across 9 pages
     (8 random container-8 + the reported container-10 page), rendering each with
     and without this line against its legacy control: every comparable panel
     moved CLOSER to legacy, none moved away (917->853 against legacy 880;
     1131->1067 against 940), and no page gained horizontal overflow at either
     width. See ISS-425 for the separate, content-level question this uncovered —
     several sampled pages carry a grey `box` panel where legacy paints none. */
  box-sizing: border-box;
  max-width: var(--grid-container-width);
  margin-inline: auto;
  padding: var(--spacing-xl);

  > .default-content,
  > .block-content { max-width: 100%; }
}

/* When combined with container-N, narrow the panel to that column count. */
@media (width >= 992px) {
  main .section.box,
  main .section.layout-box {
    max-width: calc(var(--grid-column-width) * var(--container-cols, 12));
  }
}

/* …and RELEASE the block's own rail cap inside that panel, at EVERY width.

   Same double-rail mechanism as the container-N release above: 28 blocks cap
   themselves at `max-width: var(--grid-container-width)` (90%) with an auto
   inline margin, because outside a rail-establishing wrapper the block IS what
   puts itself on the grid rail. A `box` panel already IS the rail — it caps
   itself and then releases its own `.default-content` / `.block-content` to
   100% — so that per-block cap applies the rail a SECOND time and centres the
   remainder, insetting the block 5% from the body copy beside it.

   Unlike container-N, `box` is NOT media-scoped, so this bites BELOW 992 as
   well, which is exactly where the container-N release does not reach. Measured
   2026-09-07 on rsm-us
   /insights/economics/why-the-dollar-remains-the-worlds-reserve-currency at
   390px — panel content 32..358, and inside it:
     tag-list          48.3..341.7  (inset 16.3px)   f-260806-uuxq
     contributors-list 48.3..341.7  (inset 16.3px)   f-260901-z5o5
   Legacy renders both flush with the body copy (10..380 for the copy, the tag
   band and the contributor list alike). At 1200 and 1440 both are already flush
   (240..960 / 293.3..1146.7), which is why the desktop wording in those two
   reports never reproduced.

   Above 1440 this is a no-op — `--grid-container-width` becomes the fixed
   1280px, wider than any box panel, so the per-block cap never bound. Between
   992 and 1440 it duplicates the container-N release for a `box.container-N`
   section and covers a `box` with no container-N, which that rule misses.

   Scoped to `> *` — the block ROOT — so a block's INTERNAL caps are untouched,
   and only inside `box`, so a plain section (where the block's own cap IS the
   rail) is unaffected. Blocks that inset themselves by MARGIN rather than by a
   rail cap (quote's `margin-inline: 16px` below 768) are deliberately not
   touched here: that is a different mechanism and a different decision. */
main .section:is(.box, .layout-box) > :is(.default-content, .block-content) > * {
  max-width: 100%;
}

/* …and at phone widths, express the panel's inline gutter as the RAIL'S OWN
   percentage instead of a fixed 32px, so boxed content lands on exactly the same
   rail as identical content in an unboxed section.

   The panel's outer box is unaffected. `max-width: var(--grid-container-width)`
   (90%) applies to the CONTENT box, so the panel is full-bleed exactly while
   `viewport - 64px <= 0.9 x viewport`, i.e. at and below 640px. Above that the
   90% cap wins and the panel is already inset; below it the 32px padding is the
   only thing setting the gutter, and 32px is a bigger share of a phone than the
   rail's 5% — so boxed content is inset FURTHER than unboxed content, and only
   there. Measured on eds-prd at 390px (f-260708-i085, f-260806-fcyh):

     boxed section   body copy 326px @ 32   infogram 326px @ 32
     unboxed section content    351px @ 20   (--grid-container-width, centred)
     legacy rsmus.com body copy 370px @ 10   infogram 370px @ 10

   So the embed was never inset RELATIVE TO ITS OWN TEXT — legacy and EDS both
   render the chart at exactly the paragraph width (ratio 1.000 on both sides, at
   both breakpoints). What the design review saw as "the embed has large
   left/right padding" is this double inset, applied to the whole boxed section.
   5% is the same gutter the rail already uses, and 5% of 640px IS 32px, so this
   rule is continuous with the one above at its own breakpoint — nothing moves at
   640px, and at 390px the gutter goes 32px -> 19.5px (content 326px -> 351px).

   The residual 351 vs legacy's 370 was --grid-container-width itself (90% vs
   legacy's fixed ~10px gutter). ISS-509 (2026-09-25) moved the rail to
   `calc(100% - 20px)` below 992. The rail alone now supplies legacy's 10px, so the
   panel needs NO inline padding of its own there. Measured on the branch preview:
   a 10px panel padding PLUS the 10px rail inset boxed article copy to x=20 (352px)
   @390 against legacy's 12 (372px) — the same double inset this rule exists to stop.
   With 0 the content box is the viewport, the rail centres at viewport − 20, and
   boxed copy lands on the unboxed rail. The whole < 992 range is covered, because at
   640–992 a 32px padding would otherwise beat a 10px rail. */
@media (width < 992px) {
  main .section.box,
  main .section.layout-box {
    padding-inline: 0;
  }
}

/* `pad-*` / `copy-*` (f-261015-6kiv): a box panel that spans its rail and takes its insets
   from the containers inside it, as legacy does. Legacy's pads are fixed lengths from
   `>=tablet` (RSMUS_ACM structure/container/_container.scss): rem17/rem20 = 17rem/20rem at its
   10px rem, emNN = NN/10 em at its 18px container font. `pad-*` is the panel's inline padding;
   `copy-*` holds its COPY further in when the copy sits in a rem container and its blocks in an
   em one. Measured on rsm-us …/security-alert-using-iam-… @1440: panel x80 w1280, copy x280
   w880, the four-stage columns from x102. The importer emits them with `box, container-12`
   (panelChildInsets). (0,3,1) and up, so they beat the box's own inline padding at every width,
   including its `padding-inline: 0` below 992. */
main .section.box.pad-em12 { --box-pad: 21.6px; }
main .section.box.pad-em14 { --box-pad: 25.2px; }
main .section.box.pad-em16 { --box-pad: 28.8px; }
main .section.box.pad-em18 { --box-pad: 32.4px; }
main .section.box.pad-em20 { --box-pad: 36px; }

/* The em pads hold at phone width too (the four-stage column at x32 @390, legacy); the rem
   pads and the copy inset only from 768, as legacy's `>=tablet`. */
main .section.box:is(.pad-em12, .pad-em14, .pad-em16, .pad-em18, .pad-em20) {
  padding-inline: var(--box-pad);
}

@media (width >= 768px) {
  main .section.box.pad-rem20 { --box-pad: 200px; }
  main .section.box.pad-rem17 { --box-pad: 170px; }

  main .section.box:is(.pad-rem20, .pad-rem17) {
    padding-inline: var(--box-pad);
  }

  main .section.box.copy-rem20 { --copy-pad: 200px; }
  main .section.box.copy-rem17 { --copy-pad: 170px; }

  main .section.box:is(.copy-rem20, .copy-rem17) > .default-content {
    margin-inline: calc(var(--copy-pad) - var(--box-pad, 0px));
  }
}

/* Below 768 legacy's rem container has no pad, so the COPY sits on the panel's own edge while
   the em-padded blocks keep their inset. Pull the copy back out by the panel's pad.
   rsm-us/ca …/security-alert-using-iam-… @390: heading x32 w327, legacy x10 w370. */
@media (width < 768px) {
  main .section.box:is(.copy-rem20, .copy-rem17) > .default-content {
    max-width: calc(100% + 2 * var(--box-pad, 0px));
    margin-inline: calc(-1 * var(--box-pad, 0px));
  }
}

/* `band-pad-*` (f-261015-6kiv): the same child pad on a panel that paints FULL-BLEED (a
   `fullWidth` wrapper encloses it). The fill runs edge to edge; the content keeps the rail
   less legacy's fixed pad on each side. rsm-us …/enhancing-financial-management-with-dynamics-gp
   @1440: grey x0 w1440, copy x280 w880. From 768, as legacy's `>=tablet`. */
@media (width >= 768px) {
  main .section.band-pad-rem20 { --band-pad: 200px; }
  main .section.band-pad-rem17 { --band-pad: 170px; }

  main .section:is(.band-pad-rem20, .band-pad-rem17) > :is(.default-content, .block-content) {
    max-width: calc(var(--grid-container-width) - 2 * var(--band-pad));
    margin-inline: auto;
  }
}

/* `band-emNN` (f-261001-etfo): the band also absorbed a panel of its own colour, whose em pad
   holds the content in a little further. Like every legacy pad class it applies from 768
   (clientlib-site: `@media (min-width:768px) { .cmp-container.p-l-em16 { padding-left: 1.6em } }`);
   below that the content sits on the rail, as legacy's does.
   rsm-ca/us …/strategies-for-growing-saas-companies-apr-reporting-challenges, `band-pad-rem17,
   band-em16`: copy x279 @1440 (80 + 170 + 28.8), as legacy. */
@media (width >= 768px) {
  main .section.band-em12 { --band-em: 21.6px; }
  main .section.band-em14 { --band-em: 25.2px; }
  main .section.band-em16 { --band-em: 28.8px; }
  main .section.band-em18 { --band-em: 32.4px; }
  main .section.band-em20 { --band-em: 36px; }

  main .section:is(.band-em12, .band-em14, .band-em16, .band-em18, .band-em20) > :is(.default-content, .block-content) {
    max-width: calc(var(--grid-container-width) - 2 * (var(--band-pad, 0px) + var(--band-em)));
    margin-inline: auto;
  }
}

/* Spacing overrides for box layout. The box default (var(--spacing-xl)) has
   specificity (0,2,1); adding the spacing class raises it to (0,3,1) so these
   win over the base box rule. Only padding-block varies; inline padding stays xl. */
main .section.box.spacing-xs, main .section.layout-box.spacing-xs { padding-block: calc(var(--spacing-xs) * 2); }
main .section.box.spacing-s,  main .section.layout-box.spacing-s  { padding-block: calc(var(--spacing-s) * 2); }
main .section.box.spacing-m,  main .section.layout-box.spacing-m  { padding-block: calc(var(--spacing-m) * 2); }
main .section.box.spacing-l,  main .section.layout-box.spacing-l  { padding-block: calc(var(--spacing-l) * 2); }
main .section.box.spacing-xl, main .section.layout-box.spacing-xl { padding-block: calc(var(--spacing-xl) * 2); }
main .section.box.spacing-xxl,main .section.layout-box.spacing-xxl{ padding-block: calc(var(--spacing-xxl) * 2); }

/* Grid layout: tile the consecutive blocks in a section into an even N-column
   grid of equal-size cells — e.g. a text intro + three cards as a 2×2. The
   blocks share one .block-content wrapper, so the grid lives there, and items
   auto-flow into rows (no divider needed). grid-auto-rows: 1fr makes every row
   the same height as the tallest, and minmax(0, 1fr) columns keep every cell
   the same width — so a short text cell and image cards line up as equal tiles.
   Authored via section-metadata "Grid: 2", which sets data-grid="2" on the
   section. Lives here (not section-metadata.css) because EDS can strip that
   sheet. Stacks below 992px. */
@media (width >= 992px) {
  main .section[data-grid] .block-content {
    display: grid;
    gap: var(--spacing-xxl);
    grid-auto-rows: 1fr;
    align-items: stretch;
  }

  /* …and the RAIL, which is a SEPARATE rule because it must not apply inside a
     section that already establishes the rail.

     Container-aware, so a grid section can carry `container-N` like every other
     section. This used to be a flat var(--grid-container-width), which pinned a
     grid to all 12 columns and left `box` as the ONLY way to narrow grid content
     — and `box` by design also confines the authored background to a centred
     panel (see its comment above). A legacy full-bleed grey band with contained
     content was therefore unauthorable: you got the right width with a boxed
     background, or a full-bleed background at 12 columns. Measured on
     /insights/economics/global-economic-outlook-for-2025, whose "Global outlook
     reports" band is edge-to-edge #f0f0f0 on rsmus.com with its copy on the
     8-column rail (f-260811-g1ba).
     NOT a behaviour change without container-N: --grid-column-width is defined as
     --grid-container-width / 12, so the default of 12 makes this calc
     byte-identical to the value it replaces.

     WHY `:not(.box, .layout-box)` — f-260911-mf2j. A `box` panel IS the rail: it
     caps itself and then releases its own `> .default-content`/`> .block-content`
     to `max-width: 100%`. This rule and that release are BOTH specificity (0,3,1),
     and this one is ~110 lines later, so on a section carrying `box` AND a `grid`
     key source order handed the win to this rule and the rail applied TWICE —
     the panel capped at the rail, then the content capped at the rail again
     INSIDE it, with the auto margin centring the remainder.

     Measured 2026-09-11 on the published rsm-us
     /middle-market/cybersecurity-mmbi/cloud-security, whose "Cloud adoption
     solutions" band is `box container-8 col-5-7` + data-grid=2:
       1024  section x205 w614 (grey)   content x347 w330  — 54% of its own panel
       1440  section x293 w853 (grey)   content x325 w789
     Legacy paints THAT band contained (x220 w584 @1024, x280 w880 @1440), so
     `box` is correct there and dropping it would break the fill — which is why
     this had to be fixed in CSS and could not be fixed by authoring. Contrast
     f-260811-g1ba, where legacy is full-bleed and dropping `box` was right.

     Bites only 992–1440: at >=1440 --grid-container-width becomes a fixed 1280px,
     wider than any container-N rail, so the second cap never bound and the defect
     was invisible on a large monitor.

     `container-N` is deliberately NOT excluded. For a container-N section without
     `box` the container-N rule sets `.block-content` to the SAME
     calc(--grid-column-width * --container-cols), so this rule is redundant there
     rather than harmful — excluding it would change nothing and would widen the
     selector for no reason. Only `box` releases its children, and only `box`
     therefore conflicts. */
  main .section[data-grid="2"] .block-content {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  main .section[data-grid="3"] .block-content {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* Legacy's `c-quarters` 4-up row (C39). RSMUS_ACM _columncontainer.scss makes
     the quarters 25% from `desktop` (992), so four across here — NOT the 2×2 that
     section-metadata.css computes for `.grid-4` below 1280 (this selector is
     (0,3,1) against its (0,3,0)). Legacy's gutter is ~22px (rsm-us
     /careers/el-salvador @1440: four 298px videos on a 320px pitch), so the
     4-up takes --spacing-l instead of the 48px grid gap, which would shrink each
     cell to 284px. Below 992 it stacks like every other grid (legacy keeps a
     shrunken 4-up from 768; the shared <992 stack is a known residue, the same
     one grid 2/3 carry against c-half/c-thirds). The importer emits `grid: 4`
     only for four cells on c-quarters (column-panel.mjs QUARTERS_CELLS).
     Both forms, like the col-<a>-<b> rules below: the pipeline turns the
     section-metadata key into data-grid, while a client-decorated
     section-metadata block (handleLayout) adds `grid grid-4` instead — measured
     on a composed render, where only the class form existed and this rule
     missed, leaving section-metadata.css's 2×2 at 1024. */
  main .section[data-grid="4"] .block-content,
  main .section.grid-4 .block-content {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--spacing-l);
  }

  main .section[data-grid]:not(.box, .layout-box) .block-content {
    max-width: calc(var(--grid-column-width) * var(--container-cols, 12));
    margin-inline: auto;
  }

  /* Asymmetric two-up splits on the 12-grid, for a panel whose two cells are
     SIBLING BLOCKS (e.g. a card beside a text `columns` cell) laid out by the
     section rather than by a block — the only shape that satisfies "no block
     inside a block". Opt-in via section Style: col-<a>-<b>.

     The set mirrors columns.mjs RATIO_TO_COLUMNS one-for-one, so every legacy
     width split an author can pick has a section-level equivalent and no panel
     ever falls back to an equal 2-up it wasn't authored as. That map's comment
     records the measurement: across the 10,220 author-cache dumps / 16,558
     columncontainers the only active values are its eight keys plus `c-full`,
     so this list is TOTAL, not a sample.
       c-40-60 → 5-7   c-60-40 → 7-5   c-25-75 → 3-9   c-75-25 → 9-3
       c-30-70 → 4-8   c-70-30 → 8-4   c-80-20 → 10-2  c-half  → (no class,
     the plain [data-grid="2"] equal split above already is 6-6).

     `col-5-7` predates the others (the blessed c-40-60 promo panel) and kept a
     hand-written rule; all seven now resolve through --col-tracks so the ratio
     table lives in ONE place and a new split is one declaration, not a new
     selector pair. Computed value for col-5-7 is byte-identical to the rule
     this replaced. Class-based selector (0,4,1) beats the [data-grid="2"] rule
     above. Lives here (not section-metadata.css, which EDS can strip). */
  main .section.col-5-7  { --col-tracks: minmax(0, 5fr)  minmax(0, 7fr); }
  main .section.col-7-5  { --col-tracks: minmax(0, 7fr)  minmax(0, 5fr); }
  main .section.col-3-9  { --col-tracks: minmax(0, 3fr)  minmax(0, 9fr); }
  main .section.col-9-3  { --col-tracks: minmax(0, 9fr)  minmax(0, 3fr); }
  main .section.col-4-8  { --col-tracks: minmax(0, 4fr)  minmax(0, 8fr); }
  main .section.col-8-4  { --col-tracks: minmax(0, 8fr)  minmax(0, 4fr); }
  main .section.col-10-2 { --col-tracks: minmax(0, 10fr) minmax(0, 2fr); }

  main .section.grid-2.col-5-7 .block-content,
  main .section.col-5-7[data-grid="2"] .block-content,
  main .section.grid-2.col-7-5 .block-content,
  main .section.col-7-5[data-grid="2"] .block-content,
  main .section.grid-2.col-3-9 .block-content,
  main .section.col-3-9[data-grid="2"] .block-content,
  main .section.grid-2.col-9-3 .block-content,
  main .section.col-9-3[data-grid="2"] .block-content,
  main .section.grid-2.col-4-8 .block-content,
  main .section.col-4-8[data-grid="2"] .block-content,
  main .section.grid-2.col-8-4 .block-content,
  main .section.col-8-4[data-grid="2"] .block-content,
  main .section.grid-2.col-10-2 .block-content,
  main .section.col-10-2[data-grid="2"] .block-content {
    grid-template-columns: var(--col-tracks);
    align-items: center;
    gap: var(--spacing-xl);
  }

  /* `grid-top` (f-261015-wc8b): the tracks start at the band top when legacy's columns
     author `vertical-ta-top`. The grid above centres them, which suits a photo beside
     copy but floats a short copy column halfway down a tall lead form. (0,4,1), as the
     rule above, and later in the file. */
  main .section.grid-top:is(.grid, [data-grid]) .block-content {
    align-items: start;
  }

  /* aside-form (C79, ISS-597, ruled 2026-10-02): a main track of several sibling
     blocks beside ONE form that spans all of them — legacy `wrap c-60-40` with copy,
     an icon row and a video in the left column and the lead form in the right.
     Measured @1440 on rsm-us …/a-customer-experience-workshop-customized-for-your-business:
     left track x80 w743 (h2, icons, brightcove, paragraph), form x891 w447 from the
     top of the band. The emitter (column-panel.mjs classifyAsideForm) puts every
     unit in one .block-content with exactly one marketo-form, LAST: the form is
     track 2 and every other child is track 1. The rule keys on `.marketo-form`,
     not :last-child, so an element the emitter did not write (a decorate-time
     error box after the form, say) cannot pull the form back into track 1.

     The row template is a fixed run of `auto` rows plus a trailing `1fr`, and the
     form spans all of them (1 / -1). An unused `auto` row sizes to 0, and an item
     spanning a flexible track puts its excess into that track only, so a form
     taller than the main track grows the last row rather than opening gaps
     between the main blocks. row-gap stays 0 for the same reason: every empty
     explicit row would otherwise add one. 16 main blocks is far past anything
     authored (the measured band has 4).

     Pairs with a `col-<a>-<b>` token for the track ratio and for its `.columns
     .col` inset release; no grid key, so the [data-grid] rules above never fire.
     Below 992 nothing applies and the blocks stack in document order — legacy's
     @390 order. */
  main .section.aside-form > .block-content {
    display: grid;
    grid-template-columns: var(--col-tracks, minmax(0, 7fr) minmax(0, 5fr));
    grid-template-rows: repeat(16, auto) 1fr;
    gap: 0 var(--spacing-xl);
    align-items: start;
  }

  main .section.aside-form > .block-content > * {
    grid-column: 1;
    min-width: 0;
  }

  main .section.aside-form > .block-content > .marketo-form {
    grid-column: 2;
    grid-row: 1 / -1;
  }
}

/* aside-form's FORM track takes the form column's own fill (f-260901-mdbx, reopened
   2026-10-08: "there needs to be a grey background behind the form"). Legacy paints the
   c-60-40's form column, not the band: rgb(240,240,240) from the band top, the h2 20px
   below it (its margin), 36px under the form (p-b-em20); 21.6px a side @1440 (x870 w490),
   none @390 (x10 w370). The emitter (about-section emitAsideFormSection) writes
   `aside-fill-<alias>` only when that column authors a fill; light-grey is the one the
   corpus holds (C79 reach: 1 page).
   The [copy | form] col-<a>-<b> grid carries the same token (f-261015-wc8b, insights-
   article-us panel path): rsm-us …/global-enterprise-strategy authors the same column
   (#F0F0F0, p-l/p-r-em12, p-b-em20), so the rule is keyed on the token, not the layout. */
main .section.aside-fill-light-grey > .block-content > .marketo-form {
  background-color: var(--color-light-grey);
  padding: 20px 0 36px;
}

@media (width >= 992px) {
  main .section.aside-fill-light-grey > .block-content > .marketo-form {
    padding-inline: 22px;
  }
}

/* The text cell of a col-<a>-<b> panel is a .columns block whose .col adds 40px
   side padding; that narrows the usable text width (~399px in container-8) enough
   to wrap the heading onto a second line. Live rsmus.com has no such inset (text
   fills the full ~456px column), so drop the horizontal padding here to match.
   Only the text cell is a .columns block — the other cell is a card/quote/video.

   Applies to EVERY ratio, not just col-5-7: the inset comes from the .columns
   block being used as a cell, which is identical in all seven splits, so scoping
   the fix to one class would ship the same wrap bug on the other six. */
main .section.col-5-7 .columns .col,
main .section.col-7-5 .columns .col,
main .section.col-3-9 .columns .col,
main .section.col-9-3 .columns .col,
main .section.col-4-8 .columns .col,
main .section.col-8-4 .columns .col,
main .section.col-10-2 .columns .col {
  padding-inline: 0;
}

/* A boxed (layout-box) asymmetric panel confines its background to a centred box,
   so section `spacing-*` only pads inside that box. Add an outside margin so a gap
   shows between the panel and the full-bleed section that follows it. */
main .section.col-5-7.layout-box,
main .section.col-7-5.layout-box,
main .section.col-3-9.layout-box,
main .section.col-9-3.layout-box,
main .section.col-4-8.layout-box,
main .section.col-8-4.layout-box,
main .section.col-10-2.layout-box {
  margin-bottom: var(--spacing-xl);
}

/* Below 992px the tiles stack one per row. A flex column (not plain block) so
   the gap between stacked tiles survives, and max-width/margin gives the same
   side gutter as the rest of the site so nothing touches the screen edges.
   Explicit (rather than relying on the >=990 grid rules simply not applying) so
   it overrides the section-metadata.css grid rules, which would otherwise start
   gridding at 567px when that sheet is present. */
@media (width < 992px) {
  main .section[data-grid] .block-content {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-l);
    max-width: var(--grid-container-width);
    margin-inline: auto;
  }
}

/* section padding — defaults to xl, but the section-metadata "spacing" key
   (xs|s|m|l|xl|xxl) overrides it via the --top-bottom-spacing variable. These
   live here (not section-metadata.css) because this sheet's `main .section`
   rule out-specifies the block sheet's `.section`, and EDS can strip the block
   sheet entirely. Mirrors the calc(... * 2) scale used in section-metadata.css. */
main .section {
  --top-bottom-spacing: var(--spacing-xl);
  padding: var(--top-bottom-spacing) 0;
}

main .section.spacing-none { --top-bottom-spacing: var(--spacing-none); }
main .section.spacing-xs  { --top-bottom-spacing: calc(var(--spacing-xs) * 2); }
main .section.spacing-s   { --top-bottom-spacing: calc(var(--spacing-s) * 2); }
main .section.spacing-m   { --top-bottom-spacing: calc(var(--spacing-m) * 2); }
main .section.spacing-l   { --top-bottom-spacing: calc(var(--spacing-l) * 2); }
main .section.spacing-xl  { --top-bottom-spacing: calc(var(--spacing-xl) * 2); }
main .section.spacing-xxl { --top-bottom-spacing: calc(var(--spacing-xxl) * 2); }

/* An UNPAINTED section-style accordion keeps no top pad (f-260926-aioo, us
   .../artificial-intelligence-solutions "AI solutions for businesses:" legacy 32, ours
   97 @1440 / 129 @390). Its `spacing: xl` is the emitter's accordion KIND constant, not a
   reading of legacy (ISS-497): legacy's container around it authors nothing, so the
   heading shows only its own 20px (Q5) after the copy above. Painted ones keep the token.
   Trial 2026-10-02, Playwright, every TRS page with such a section (3), legacy vs main
   aem.live at 1440 and 390, rule injected into the same load: the section's first
   heading 5 closer / 1 further (us /about "Our history" @390, 153 -> 89 vs legacy 123).
   Thin: three pages. */
main .section.accordion.spacing-xl:not(.has-background, [style*="background"], .box) {
  padding-top: 0;
}

/* mobile-spacing — section-metadata "mobile-spacing" key overrides the padding
   below 992px only. Sits in the media query so it out-orders the desktop
   spacing rule above regardless of which spacing class is also present. */
@media (width < 992px) {
  main .section.mobile-spacing-none { --top-bottom-spacing: var(--spacing-none); }
  main .section.mobile-spacing-xs   { --top-bottom-spacing: calc(var(--spacing-xs) * 2); }
  main .section.mobile-spacing-s    { --top-bottom-spacing: calc(var(--spacing-s) * 2); }
  main .section.mobile-spacing-m    { --top-bottom-spacing: calc(var(--spacing-m) * 2); }
  main .section.mobile-spacing-l    { --top-bottom-spacing: calc(var(--spacing-l) * 2); }
  main .section.mobile-spacing-xl   { --top-bottom-spacing: calc(var(--spacing-xl) * 2); }
  main .section.mobile-spacing-xxl  { --top-bottom-spacing: calc(var(--spacing-xxl) * 2); }
}

/* spacing-top / spacing-bottom — section-metadata keys that pad ONE side, on the
   same scale as `spacing`. Legacy authors a band's vertical padding per side
   (`p-b-em14` with no top token on 222 published rsm-us insights sections, all of
   them flex containers whose first child's own margin paints ~20px above), so a
   symmetric `spacing: l` put 40px on a side legacy paints at 20 (f-260811-rlc6,
   measured at 1440 and 390 on crowdstrike-downtime 20/36 and
   guide-to-changing-your-auditor 20/32). These set the LONGHAND, not the
   --top-bottom-spacing variable, so one side can differ from the other and the
   `spacing` / `mobile-spacing` rules above are untouched: a section carrying
   neither new key renders byte-for-byte as before. Specificity (0,2,1) beats the
   `main .section` shorthand; it does NOT beat `.box.spacing-*` (0,3,1) — a band
   never carries `box`, by the box-vs-band policy in the importer. */
main .section.spacing-top-none { padding-top: var(--spacing-none); }
main .section.spacing-top-xs   { padding-top: calc(var(--spacing-xs) * 2); }
main .section.spacing-top-s    { padding-top: calc(var(--spacing-s) * 2); }
main .section.spacing-top-m    { padding-top: calc(var(--spacing-m) * 2); }
main .section.spacing-top-l    { padding-top: calc(var(--spacing-l) * 2); }
main .section.spacing-top-xl   { padding-top: calc(var(--spacing-xl) * 2); }
main .section.spacing-top-xxl  { padding-top: calc(var(--spacing-xxl) * 2); }
main .section.spacing-bottom-none { padding-bottom: var(--spacing-none); }
main .section.spacing-bottom-xs   { padding-bottom: calc(var(--spacing-xs) * 2); }
main .section.spacing-bottom-s    { padding-bottom: calc(var(--spacing-s) * 2); }
main .section.spacing-bottom-m    { padding-bottom: calc(var(--spacing-m) * 2); }
main .section.spacing-bottom-l    { padding-bottom: calc(var(--spacing-l) * 2); }
main .section.spacing-bottom-xl   { padding-bottom: calc(var(--spacing-xl) * 2); }
main .section.spacing-bottom-xxl  { padding-bottom: calc(var(--spacing-xxl) * 2); }

/* Legacy container MARGIN (C20 round 4, f-260926-gagt): `margin-top` / `margin-bottom`
   section-metadata, value = legacy's own suffix. RSMUS_ACM _container.scss defines
   m-t-em## / m-b-em## as 1.2em..2em on an 18px container, so the px are fixed here
   rather than inherited from our section font. Measured on rsm-us /services/business-tax:
   legacy leaves 21.6px of page between two painted bands at 1440 AND 390. A margin is
   outside the fill, which is the whole point: spacing-* pads inside it. */
/* Any emNN (round 4d): section-metadata.js applyLegacyMargin sets the class and the px. */
main .section[class*="margin-top-em"] { margin-top: var(--section-margin-top, 0); }
main .section[class*="margin-bottom-em"] { margin-bottom: var(--section-margin-bottom, 0); }

/* An EMPTY section shell paints a 64px dead band (f-260901-nkgb).
 *
 * The recipe emits a bare `<div></div>` section on some pages — nothing in it, no
 * section-metadata, no block. It still matches `main .section` above, so it takes
 * the default 32px a side and paints 64px of whitespace around nothing. It passes
 * every structural gate (there is no content to be missing) and no authored value
 * can remove it, because a `spacing` key needs a section-metadata block and this
 * section has no children at all.
 *
 * Measured at 1440 and 390 on rsm-us /insights/topics/talent-management, the page
 * the finding names, both sides rendered: the last content ("Contact RSM") ends at
 * 7928 and the footer starts at 8040 = a 112px tail, of which the trailing empty
 * shell is exactly 64 (section index 13, height 64, padding 32/32, zero children).
 * Legacy rsmus.com/insights/topics/talent-management paints 25px there ("CONTACT
 * RSM" 7712 → footer 7737). So this is a FIDELITY fix and it cannot overshoot:
 * 112 → 48 still sits above legacy's 25, and the remaining 23px is the section's
 * own band padding, which is a per-band authoring question, not this rule's.
 *
 * Class size, sampled from the ledger's published rows and read off each page's
 * .plain.html on the aem.live origin: 10 of 765 rsm-us pages (1.3%) and 13 of 472
 * rsm-ca pages (2.8%) carry at least one, 24 shells in all — roughly 68 + 76 ≈ 144
 * pages across the two sites. It concentrates in events-template-2 (10 of 53
 * sampled on rsm-us, 11 of 39 on rsm-ca) and also appears on industry-page,
 * locations and insights-template-4.
 *
 * Specificity is (0,1,1), the same as the `main .section` shorthand it follows, so
 * order decides and it wins. It does NOT need to beat `.spacing-*` (0,2,1): those
 * classes come from a section-metadata block, which is a child, so a section with
 * no children can never carry one. The one rule it does lose to is the first-child
 * padding-top restore below (0,3,1) — every one of the 24 shells measured sat at
 * index >= 2, so no page in the corpus hits that, and a speculative guard for a
 * case that does not occur would be harder to read than this note. */
main .section:not(:has(*)) {
  padding-block: 0;
}

main .section:first-child {
  padding-top: 0;
}

/* Restore top padding when the first section doesn't lead with a hero —
   otherwise the content sits flush against the fixed header. bio-hero is a
   full-bleed hero band, so it's excluded like .hero/.event-hero. */
main .section:first-child:not(:has(.hero, .event-hero, .bio-hero)) {
  padding-top: var(--spacing-xl);
}

/* …but an explicit `Spacing: none` must win over that restore. The recipe emits a
   hairline `divider` as the first section on ~760 pages (parity backlog item 1);
   legacy renders that rule 2px tall under the header, while the restore rule above
   silently added 32px of dead space that no authored value could remove. Same
   specificity as the rule above, so this has to stay after it. */
main .section:first-child.spacing-none {
  padding-top: 0;
}

/* A hero is full-bleed; don't add section padding around it. Both sides: the top
   used to be covered only by the `:first-child` rule above, so a hero that is NOT
   the first section — every page where the importer emitted a leading `divider`
   band (parity backlog item 1) — picked up 32px of white above the hero that
   legacy does not have. rsm-ca /events measured hero y=171 vs legacy y=140. */
main .section:has(.hero, .event-hero, .bio-hero) {
  padding-block: 0;
}

/* Reduce the top gap on the section directly after a hero — the default 48px
   section padding creates a large white gap between the hero and the content below.
   Remove it entirely so the block's own internal padding controls the spacing. */
body:has(.card.news-release) main .section:has(.hero, .event-hero) + .section {
  padding-top: 0;
}

/* Press-release contact-info bar (section.container directly after the hero).
   Override both top AND bottom to match rsmus.com box-model: ~22px each side,
   20px inline — matches reference's 1.2em/2rem at 18px/10px-root. */
body:has(.card.news-release) main .section:has(.hero, .event-hero) + .section.container {
  padding: 22px 20px;
}

/* bio-hero also sheds the top padding so the green band sits flush under the
 fixed header, like the other full-bleed heroes. */
main .section:has(.bio-hero) {
  padding-top: 0;
}

/* blog-feed supplies its OWN band padding, so the section must not add a second
   helping above it (f-260920-pxkn, "there should be no white space above the
   'The Real Economy Blog' section"). Same shape as the hero rules above — the
   block's internal padding controls the spacing.

   TOP ONLY, and that is measured rather than assumed. blog-feed.css pads its
   content 56px top (48 under 992px) and its see-more 64px bottom (48 mobile);
   the section's default 32px lands on BOTH sides, and only the top side is
   wrong. Legacy's `.cmp-blog-feed__container` pads 40/95 and sits in no padded
   container, so its heading sits 60px below the band top (40 + the 20px h2
   margin-top EDS zeroes) while the bottom already matches:

     band-top -> "The Real Economy Blog", rsmus.com vs main--rsm-us, n=2 renders
       1440   legacy 60   EDS 88 (+28)   with this rule 56 (-4)
        390   legacy 40   EDS 80 (+40)   with this rule 48 (+8)
     band padding-bottom   EDS 96 (64 + 32) vs legacy 95 — parity, left alone.

   The BOTTOM side, corrected 2026-10-02 (f-260920-s0yh). The "parity" reading above
   counted the section's 32px as band, but the section is white and only the block
   paints, so it shows as a 32px white strip between the band and the grey footer
   (legacy: none). Padding-bottom goes to 0 too, and blog-feed.css trims the desktop
   see-more pad 64 -> 47 so the band ends where legacy's does. Instrument: Playwright,
   legacy vs main aem.live, last blog-feed text -> band bottom / next content, the rule
   injected into the same load, every TRS page that renders a blog-feed:
     rsm-us /            text -> footer   1440 legacy 49  ours 98 -> 49 | 390 49  81 -> 49
     rsm-ca /            text -> footer   1440 legacy 49  ours 97 -> 48 | 390 49 110 -> 78
     rsm-us /technologies/microsoft (mid-page)
                         text -> band     1440 legacy 49  ours 65 -> 48 | 390 49  49 -> 49
                         band -> next     1440 legacy 48  ours 84 -> 52 | 390 255 328 -> 296
   7 closer, 0 further, 1 same (+-2px). Blind to: pages outside the TRS. */
main .section:has(.blog-feed) {
  padding-top: 0;
  padding-bottom: 0;
}

/* A `none` side must keep its children's margins INSIDE the section's own paint.
 *
 * With zero padding on a side, a block section lets its first (or last) child's
 * margin collapse straight through that edge. The margin then lands BETWEEN two
 * sections, where nothing paints, and the white `main` shows through as a stripe.
 * The importer emits exactly this shape when it splits one legacy band into a
 * heading section and a block section and joins them with `spacing-bottom-none` /
 * `spacing-top-none`. Legacy paints that band as one box, so the stripe cuts a
 * continuous band in two.
 *
 * Measured at 1440 on rsm-ca /about/innovation (f-260926-90vu, f-260926-5q1v), aem.live
 * vs rsmcanada.com. `.card-grid`'s 40px margin-top escaped the navy card section and left
 * a 40px white gap under the navy heading section. A `<p>`'s 10px margin-bottom escaped
 * the grey heading section and left a 10px white gap above the grey cardlist. Legacy
 * paints both bands edge to edge. With this rule both bands are contiguous, and the grey
 * one reads paragraph → first card 42px against legacy's 41.6px.
 *
 * `flow-root` contains the margins and changes nothing else about a block box. The
 * selector stays narrow for three reasons:
 *  - it matches only a section that carries a `none` token, and a padded side cannot
 *    collapse anyway;
 *  - `.has-background` sections are already flex, which contains margins, and
 *    `display: flow-root` would break their centring;
 *  - `[data-status]` is excluded, so the loading re-hide (`div[data-status]`, later in
 *    this file) still wins.
 * The empty-block hide `main .section:has(> .block-content:only-child:empty)`, later in
 * this file, out-specifies this rule (0,4,1 vs 0,3,1) and still hides.
 *
 * It sits after the section-padding rules on purpose. Those set only `padding-*`, and
 * this sets only `display`, so no two of them can override each other; the disable
 * below is for source order alone. */
/* stylelint-disable-next-line no-descending-specificity */
main .section:is(.spacing-none, .spacing-top-none, .spacing-bottom-none, .mobile-spacing-none):not(.has-background, [data-status]) {
  display: flow-root;
}

/* List indent is legacy's, and it is RESPONSIVE: 20px below 992px, 40px at and above,
   with every nested level a further 20px at all widths (C17 / ISS-504 §5, ruled "match
   legacy" by Bryce 2026-09-28).

   RSMUS_ACM components/content/text/_text.scss:9-22 —
     .cmp-text > ul, > ol { margin-left: 2rem }   @media (>= desktop) { margin-left: 4rem }
     nested ul, ol        { margin-left: 2rem; padding: 0 }
   with remBase 10px and desktop = 992px. Legacy ships one bundle for both brands, so a
   global rule here reproduces legacy on rsm-us and rsm-ca alike.

   Measured before, text left edge from the parent's content box, ours aem.live + eds-prd
   vs rsmus.com / rsmcanada.com, every authored list on each page:
                                     1440          390
     legacy                           40            20
     ours (flat 24 / nested 12)       24            24
   on rsm-ca /events/2025-events/blackline-beyondtheblack-2025 (f-260920-swlb), rsm-us
   /technologies/blackline/has-your-blackline-implementation-met-your-goals (f-260926-h62k)
   and the CTA band of rsm-us /offers/payroll-services (f-260920-a8o2).

   Legacy indents with margin, ours with padding. The two paint the same text edge here,
   because no list draws a background or a border. Keeping padding means every block that
   already overrides a list's padding (card tags, header, footer, breadcrumbs, tag-list…)
   is untouched; only lists that inherited the old 24px move.

   The 992px step applies to the top-level list only: the nested rule below is `main ul ul`
   (0,0,3), which out-specifies `main :is(ul, ol)` (0,0,2) inside the media query. */
main {
  /* Legacy copy often joins whole phrases with &nbsp;, which makes one
     unbreakable run wider than a phone column, so the page scrolled sideways
     (C12). break-word breaks such a run only when it would overflow its line;
     unlike `anywhere` it leaves min-content alone, so no table, flex or grid
     track shrinks. Legacy clips the same runs off screen instead. */
  overflow-wrap: break-word;

  ul,
  ol {
    padding-inline-start: 20px;

    ul,
    ol {
      padding-inline-start: 20px;
    }
  }
}

@media (width >= 992px) {
  main :is(ul, ol) {
    padding-inline-start: 40px;
  }
}

button {
  cursor: pointer;
}

/* stylelint-disable-next-line no-descending-specificity -- margin only; cannot collide with the per-tag text-align `li` rules above */
li {
  margin-block: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  line-height: var(--heading-line-height);
}

/* h1-h3 are Light; h4, h5 and h6 are Bold, as legacy draws them (h5/h6 below).

   RSMUS_ACM site/base/typography.scss sets h4 `font-weight: bold`, and the render
   agrees: 65 rsm-us page pairs at 1440 (rsmus.com vs main aem.live, 2026-09-23),
   82 text-matched h4 pairs, legacy 700 on all 82. Of the 70 h4s on OUR side with no
   legacy h4 twin, legacy draws 42 of the same strings as an h4 at 700 (the /about
   history accordion's "In 2005".. titles among them, hidden in collapsed panels, so
   a visible-only sweep misses them) and 10 as a <b> at 900. The only ones legacy
   draws light are cardlist subtitles, which cardlist.css pins itself.

   This was tried once on 2026-09-15 (d275aa9c) and backed out (c72fafea) because it
   moved 15 of the 16 h4s on /about. That was an ours-vs-ours pixel count, and those
   15 moved TOWARD legacy. UAT: f-260920-s7xw, f-260920-gdf3, f-260920-3ccp.

   Not changed here, and still divergent: blocks that set their own h4 weight (columns
   has-divider draws 400). h5/h6 are bold on legacy too but near-inert: zero in the
   content area of /, /about, /careers.

   h4 SIZE is 18px, as legacy draws it (C14). RSMUS_ACM typography.scss is
   `h4 { @include setTypo(1.8rem) }` — one argument, so 18px at every width — and the
   render agrees: 82/82 text-matched h4 pairs in the 2026-09-23 sweep, and on
   2026-09-27 every h4 pair still divergent on 5 UAT pages read ours 20px / legacy 18px
   at 1440 (and at 390, where the hero eyebrow falls through to this rule too).
   It reads `-s`, NOT a retuned `-m`: `--heading-font-size-m` was set to 20px in the
   2026-06-16 whole-scale retune (bd1c9ff9, boilerplate 26px -> 20px), not as an h4
   ruling, and card/cardlist/header name `-m` directly for genuine 20px text that must
   not move. UAT: f-260910-w32w and the "eyebrow and image headlines" reports. */

/* h1 is the ONE heading level where legacy is 1.2, not 1.3 (f-260910-7rs5), so it
   overrides --heading-line-height here rather than being excluded from the rule above
   (keeping it in that rule is what keeps the h2-h6 selector list intact).

   The token was restored to 1.3 on 2026-09-12, which was right for h2-h6 and is
   confirmed: across 40 text-matched heading pairs on 5 rsm-us page pairs at 1440 and
   390, zero h2/h3/h4 diverge in line-height. That commit reasoned it need not treat h1
   separately because "h1 is deliberately not in it" — but h1 was already in the
   selector above, then and now, so the token did reach it.

   It stayed invisible because blocks/hero/hero.css pins line-height 1.2 on the hero h1
   and nearly every page leads with a hero. It only shows on a page with NO hero, where
   the h1 falls through: /locations/alabama has no .cmp-hero on either side, and its h1
   measured lh 1.3 against legacy's 1.2 at both 1440 and 390.

   Legacy h1 measured 1.2 in every sample taken — 3/3 in the 2026-09-12 measurement and
   every h1 in the 5-page pair sample here. */
h1 {
  font-size: var(--heading-font-size-xxl);
  font-weight: var(--font-weight-light);
  line-height: 1.2;
}

h2 {
  font-size: var(--heading-font-size-xl);
  font-weight: var(--font-weight-light);
}

h3 {
  font-size: var(--heading-font-size-l);
  font-weight: var(--font-weight-light);
}

h4 {
  font-size: var(--heading-font-size-s);
  font-weight: var(--font-weight-bold);
}

/* h5 / h6 are legacy's, through the GLOBAL scale so no block has to patch them (Q6,
   ruled 2026-10-06). RSMUS_ACM site/base/typography.scss: h5 `setTypo(1.4rem)`,
   `line-height: 1.7`, bold; h6 `setTypo(1.2rem)`, bold (line-height from the shared
   heading rule, 1.3). Measured on renders 2026-10-06, 6 pages per level, legacy vs ours:
   h5 14/700/23.8 vs 18/300/23.4 (24 headings), h6 12/700/15.6 vs 16/300/20.8 (32), the
   same at 1440 and 390. h4 already matched (18/700, 135 headings), the control. */
h5 {
  font-size: 14px;
  font-weight: var(--font-weight-bold);
  line-height: 1.7;
}

h6 {
  font-size: 12px;
  font-weight: var(--font-weight-bold);
}

h1, h2, h3, h4, h5, h6 {
  color: #53565a;
  margin: 0;
}

/* Two authored headings in a row — a band title followed by its subtitle — render
   FLUSH, because the rule above zeroes every heading margin and a heading (unlike a
   paragraph) then contributes none of its own. Legacy's `.cmp-text` gives every
   heading `margin: 20px 0 7px`, so the same pair collapses to a 20px gap there.

   Measured 2026-09-21 on rsm-ca /events/2025-events/blackline-beyondtheblack-2025,
   render pair (eds-prd CDN vs rsmcanada.com), at BOTH viewports the testers used —
   768 and 390: all four adjacent heading pairs on the page read legacy 20px /
   ours 0px, at both widths. Control on the same page with the same probe: the
   event-hero `h4 -> h1` pair reads 20px on OUR side too, because that block sets its
   own margin — so a 0 here is the defect and not the instrument. Reported as
   f-260920-1ypo / f-260920-y1tc, "no space between title and subtitle on form".

   NOT a new judgement. blocks/columns/columns.css already makes exactly this
   restoration for `.col > h2 + h3`, at the same 20px, added for f-260901-9kbd with
   the same legacy reading (20px at 1440 AND 390, EDS 0px at both) — and its comment
   already names the cause as this global heading reset, restoring it "only inside the
   block the finding names". The testers have now reported the same defect on plain
   authored content, where no block owns the spacing, so the same number applies in the
   container that is legacy's `.cmp-text`. The two scopes cannot overlap — `.col` is
   inside a block, this is the plain authored run — so nothing is spaced twice.

   The reset itself IS a ruling, and a narrower one than it looks: it had no margin at
   all until #77 (2026-06-22) gave it `7px 0 0 0`, and #124 (2026-07-02) zeroed it "so
   hero heading spacing is driven by the block, not the global rule". That is about
   letting BLOCKS own their heading spacing; this rule is scoped outside every block,
   so it does not reverse it.

   Scoped to the DIRECT children of `.default-content`, which groupChildren() in
   scripts/ak.js makes the exact analogue of legacy's `.cmp-text` (same scoping as the
   paragraph-metrics and blockquote rules above), so a block that stacks headings of
   its own keeps its own spacing. Only `margin-top` is restored, not legacy's 7px
   bottom: a bottom margin would also move every heading -> paragraph gap on every
   page, which nothing measured here asked for. */
main .section > .default-content > :is(h1, h2, h3, h4, h5, h6) + :is(h1, h2, h3, h4, h5, h6) {
  margin-top: 20px;
}

/* Q5: an authored h2/h3 gets back legacy's 20px top margin (C20 round 6, ISS-533, ruled
   2026-10-02). Legacy's `.cmp-text` gives every heading `margin: 20px 0 7px` and its
   containers are flex, so the 20 always shows. Ours zeroed it, which is the residue of
   f-260928-zjo3, f-261001-i0zz, f-261001-l4bt and part of f-261001-l9wr.

   NOT restored on the FIRST heading of a section in two cases, because there something
   else already stands in for it, and a measured trial showed restoring it there makes
   the page worse:
   - a PAINTED section (a fill, a background image or a `box`). Its spacing token was
     calibrated against a zero heading margin: `bandSpacingKv`'s top table reads "em + the
     20px heading margin", the unpadded side is `s` for the same reason, and the two-sided
     em20 band is `xl` because nothing else could make 56. Adding the margin there is
     +20 on every band;
   - a section whose top padding is the UNAUTHORED default (no top spacing class: legacy
     authored nothing on that side, and option B kept the default because the neighbour
     paints). That 32px stands in for the heading's room.
   A section whose top is authored (A's per-side token) or collapsed (B's `join` settled
   to `none`, including under a hero) gets it, because legacy's 20 then has nothing else
   to come from.

   Trial, 2026-10-02: every h2/h3 on the 334-page TRS (667 page renders), rsmus.com /
   rsmcanada.com vs main aem.live at 1440 and 390, the rule injected into the same load,
   gap from the nearest visible content above, headings paired by text.
     restored everywhere   headings 1,266 closer / 1,135 further; page renders 215 / 273
     scoped as here        headings 1,130 closer /   188 further; page renders 311 /  43
   On joins with no painted edge between, 1,093 closer and 32 further, median distance to
   legacy now -9.4px (legacy's 7px margin-bottom stays unported). The "further" left are
   mostly headings already 80-150px from legacy, where ours and legacy differ in shape. */
main .section > .default-content > :is(h2, h3) {
  margin-top: 20px;
}

main .section:not(.spacing-none, .spacing-xs, .spacing-s, .spacing-m, .spacing-l, .spacing-xl, .spacing-xxl, [class*="spacing-top-"]) > :is(.default-content:first-child, picture:first-child + .default-content) > :is(h2, h3):first-child,
main .section:is(.has-background, [style*="background"], .box) > :is(.default-content:first-child, picture:first-child + .default-content) > :is(h2, h3):first-child {
  margin-top: 0;
}

/* ...except a painted band whose TOP is `none` (f-260920-il2k, us /newsroom "Media
   contacts": band edge -> heading legacy 20, ours 0). A `none` top means legacy authored
   no pad on that side, so no token stands in for the heading's 20px and it has nothing
   else to come from: the exclusion above was written for bands whose token counts it.
   `.key-takeaways-section` pads its own 20px top regardless of the token, so it stays out.
   A `none`-top section that is not `.has-background` is `flow-root` (rule above), so the
   margin stays inside the paint.

   Trial, 2026-10-02: Playwright, every heading on the TRS (validation-sample.json, 668 of
   672 renders), legacy vs main aem.live at 1440 and 390, this rule injected into the same
   load, gap from the nearest visible mark above (text, media, painted edge):
     first h2/h3 of a painted band with a `none` top   61 closer / 7 further / 2 same
     every other heading                               17 closer / 5 further
   5 of the 7 "further" were legacy rows reading -0.4 (a filter bar above the heading that
   ours does not render) or key-takeaways, now excluded. Restoring the margin in EVERY
   painted band was trialled alongside and rejected: 147 closer / 391 further. */
main .section:is(.has-background, [style*="background"], .box):is(.spacing-none:not([class*="spacing-top-"]), .spacing-top-none):not(.key-takeaways-section) > :is(.default-content:first-child, picture:first-child + .default-content) > :is(h2, h3):first-child {
  margin-top: 20px;
}

@media (width < 992px) {
  main .section:is(.has-background, [style*="background"], .box).mobile-spacing-none:not(.key-takeaways-section) > :is(.default-content:first-child, picture:first-child + .default-content) > :is(h2, h3):first-child {
    margin-top: 20px;
  }
}

/* One-off oversized H1: tag the section with `Style: heading-xxl` */
main .section.heading-xxl h1 {
  font-size: clamp(10rem, 16vw, 14rem);
  line-height: 1;
  margin: 0;
}

@media (width < 767px) {
  main .section.heading-xxl h1 {
    font-size: 120px;
  }
}

main .button-container { display: inline; }

/* A paragraph whose only content is a button link (DA .button-container, or
   legacy .btn markup) gets the base `p { margin: 1rem 0 }`. Keep the top
   margin for spacing above the button, drop the bottom. */
main .default-content p:has(> a.button:only-child),
main .default-content p:has(> a.btn:only-child) {
  margin-bottom: 0;
}

/* Multiple buttons on one line (link + bold/italic grouped): space them out
   and let them wrap/stack onto new rows when there isn't enough width. */
main .btn-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* Preserve section-metadata centering (flex ignores text-align). */
main .section[data-text-center*="p"] :is(.default-content, .block-content) p.btn-group {
  justify-content: center;
}

/* Newsroom "RSM news releases" section (rsmus.com parity). */
/* Spread the three "See all 20XX" year buttons evenly (rsmus.com), with equal
   space around each — including margins from the section edges — rather than
   grouped centered (or pinned to the edges by space-between). */
main .section:has(.card.news-release) :is(.default-content, .block-content) p.btn-group {
  justify-content: space-around;
}

/* "View more news releases" turns its text + outline blue on hover (rsmus.com),
   rather than the default green fill of btn-secondary. */
main .section:has(.card.news-release) a.btn.btn-secondary.btn-outline:hover {
  color: var(--color-primary-blue);
  background: transparent;
  border-color: var(--color-primary-blue);
}

/* Newsroom "RSM US in the news" quote (rsmus.com parity). Text size comes from
   the quote-size-s variant (24px, set via section-metadata style) — no hardcoded
   font override here. */
@media (width >= 768px) {
  /* Wider vertical rhythm between the blue top/bottom rules, matching live (~80px). */
  body:has(.card.news-release) main .section .quote.border-primary-blue {
    padding-block: 80px;
  }

  /* Constrain the photo+text row to a narrower, centred column like live
     (the blue top/bottom rules still span the full section width). */
  body:has(.card.news-release) main .section .quote.border-primary-blue > div {
    max-width: 660px;
    margin-inline: auto;
    gap: 20px;
  }

  /* Left-align the quote + attribution, overriding the section's text-center. */
  body:has(.card.news-release) main .section[data-text-center] :is(.default-content, .block-content) .quote.border-primary-blue :is(blockquote p, .quote-attribution) {
    text-align: left;
  }
}

/* ── Section style: link-list ─────────────────────────────────────────────────
   Sitemap-shaped navigation: runs of one-link-per-paragraph default content that
   legacy renders as a `cmp-linklist__items twocol`. Measured on
   rsmcanada.com/sitemap at 1440: two columns in the 880 rail, links 18px/24px
   weight 400 in text grey (NOT the green body-link colour), a 12px chevron 5px
   after the label, and headings that span both columns with 20px/7px margins.

   `column-span: all` on the headings is what makes one wrapper hold several
   groups: each heading interrupts the column flow, so its links start a fresh
   two-column run underneath — the same shape as legacy's separate lists without
   restructuring the authored content. `p > strong` is a group sub-heading
   ("Work with us").

   The accordion `link-list` VARIANT covers the same treatment inside accordion
   panels (see blocks/accordion/accordion.css); this rule is scoped to
   `.default-content` so the two never overlap. */
main .section.link-list > .default-content {
  column-count: 2;
  column-gap: 18px;
}

main .section.link-list > .default-content > :is(h1, h2, h3, h4, p:has(> strong:only-child)) {
  column-span: all;
  margin: 20px 0 7px;
}

main .section.link-list > .default-content > p:has(> a) {
  margin: 0;
  break-inside: avoid;
}

main .section.link-list > .default-content a:any-link:not(.btn) {
  color: var(--color-text);
  font-weight: 400;
}

@media (width < 768px) {
  main .section.link-list > .default-content {
    column-count: 1;
  }
}

/* Newsroom "Media fact sheet" navy band (rsmus.com parity). */
/* The pipeline points the section background at a token-gated eds-prd media URL
   (401s on the preview); use the working rsmus.com source directly. !important
   is required to beat the inline background-image set by the section handler. */
body:has(.card.news-release) main .section.bg-navy:has(.columns.divider) {
  background-image: url("https://rsmus.com/content/dam/rsm/1_real-world/people/cta/business_people_22_rw_cta.jpg") !important;
}

/* Equal-height stat columns so every divider is the same length (live), instead
   of each column sizing to its content (which left the last divider short). */
body:has(.card.news-release) main .section.bg-navy:has(.columns.divider) .columns.divider .row {
  align-items: stretch;
}

/* Newsroom "Media contacts": NO rule is painted here, deliberately.
   This section used to carry `border-bottom: 1px solid var(--color-light-grey-2)`
   (added 7a81243f, PR #230, to reproduce "rsmus.com's <hr>"). The DA content
   already ends that section with a real `divider` block, so the page painted
   TWO lines where legacy paints ONE, and the invented one was full-bleed where
   legacy's is inset to the rail. Measured @1440 on the CDN before removal:
   legacy `hr.cmp-divider` x=80 w=1280 (one line); ours `.divider` x=293 w=853
   PLUS this border x=0 w=1440 (two lines). f-260920-u7z1. Do not re-add it —
   the content divider is the element legacy has. */

/* The "*These numbers…" footnote is small and left-aligned on live, not the
   section's centered 18px body text. Targets the loose note paragraph (no link),
   leaving the "Learn more" button paragraph centered. */
body:has(.card.news-release) main .section.bg-navy:has(.columns.divider) .default-content > p:not(:has(a)) {
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  margin-inline: 0;
}

/* "Learn more about our firm" button. Production styles it as `_green secondary`
   (an outline button); on this navy band — a dark, light-text container — RSM's
   own CSS flips `--button-green-color` to white, so it renders as a WHITE outline
   that fills green on hover, not the solid green btn-primary that <strong>
   produces. Match that here (authoring keeps the <strong> button markup). */
body:has(.card.news-release) main .section.bg-navy:has(.columns.divider) .default-content a.btn {
  background: transparent;
  border: 1px solid var(--color-primary-white);
  color: var(--color-primary-white);
}

body:has(.card.news-release) main .section.bg-navy:has(.columns.divider) .default-content a.btn:hover {
  background-color: var(--color-primary-hover-green);
  color: var(--color-primary-white);
}

/* Tertiary "See all <topic> insights" CTA — the legacy `linklist` arrow shape.
   `formatButton`'s `tertiary` variant deliberately emits a BARE `<p><a>…:chevron-right-solid-full:</a></p>`
   with no `<strong>`/`<em>` wrapper, so ak.js never decorates it and it falls through
   to the body-link defaults: `--color-link` green, weight 500, underlined, and the
   section's own (left) alignment. Legacy's `.cmp-linklist a` is none of those.

   Measured @1440, ours vs `rsmus.com/industries/asset-management.html` as the control:
     before  x=80  w=280  rgb(63,156,53)  w500  underline
     after   x=583 w=275  rgb(83,86,90)   w400  none
     legacy  x=580 w=281  rgb(83,86,90)   w400  none
   Colour, weight and decoration match exactly; position is 3px out on font metrics.

   `#53565a` is the literal legacy value and the one h1–h6 already use above — NOT
   `--color-text`, which is `--color-primary-dark-grey` `#515356`, a different grey.

   The two halves are scoped differently ON PURPOSE. Colour/weight/decoration is what
   legacy's linklist does everywhere, so it applies to every arrow link in default
   content. CENTERING is not: legacy centres this CTA by putting the whole container
   in `ta-center`, which is a per-band authoring choice, and the fragment path emits
   the same arrow shape where centring has not been measured. So centring is scoped
   to a section that also holds a cardlist — the "See all <topic> insights" pattern
   both findings describe — rather than applied to all 156 arrow linklists blind.
   Refs f-260901-ukpp, f-260824-jgqp. */
/* stylelint-disable no-descending-specificity -- these three sit beside the
   button/link rules they belong with; hoisting them above `a:any-link:not(.btn)`
   (line ~724) to satisfy the rule would move them out of that cascade for no
   rendering gain. The file already carries 58 of this same class (deferred lint
   backlog); this keeps the count from growing. */
main .default-content a:has(> .icon-chevron-right-solid-full),
main .default-content a:has(> .icon-chevron-right-green) {
  font-weight: 400;
  text-decoration: none;
}

/* The GREY is the linklist's alone. A legacy `button style=tertiary theme=_green`
   is emitted as the same arrow link with its own icon, `:chevron-right-green:`
   (formatButton), because legacy draws it `.cmp-button.tertiary._green`: rgb(63,156,53),
   the body link's own green. Keyed on the shared icon, this rule greyed 164 of them
   on 35 published pages (render-measured, f-260926-g98m). */
main .default-content a:has(> .icon-chevron-right-solid-full) {
  color: #53565a;
}

main .default-content a:has(> .icon-chevron-right-solid-full):hover,
main .default-content a:has(> .icon-chevron-right-green):hover {
  text-decoration: underline;
}

main .section:has(.cardlist) .default-content p:has(> a:only-child > .icon-chevron-right-solid-full),
main .section:has(.cardlist) .default-content p:has(> a:only-child > .icon-chevron-right-green) {
  text-align: center;
  margin-top: 8px;
}

/* The same tertiary arrow link inside a `columns` cell (f-261001-s8j6). Legacy
   renders it as `a.cmp-button._green.tertiary`: weight 400. The rule above only
   reaches `.default-content`, so a column cell fell to the body link's 500.
   WEIGHT ONLY, on purpose: legacy's colour here is `_green` (rgb(63,156,53)),
   which the body link already matches, not the linklist grey above. Measured on
   rsm-us /insights/technology/microsoft/dynamics-365-buyers-guide @1440 (6 links
   in the gold-partner fragment): legacy w400, ours w500. The "underline" a style
   read reports on ours is `text-decoration-line` with a TRANSPARENT colour — not
   visible at rest, same as legacy — so decoration is left alone. */
main .columns a:has(> .icon-chevron-right-solid-full),
main .columns a:has(> .icon-chevron-right-green) {
  font-weight: 400;
}
/* stylelint-enable no-descending-specificity */

main a.button:any-link {
  background: none;
  border: none;
  border-radius: 0;
  color: var(--color-link);
  font-size: inherit;
  font-weight: inherit;
  padding: 0;
  margin: 0;
  text-decoration: underline;
  white-space: normal;
}

strong {
  font-weight: var(--font-weight-bold);
}

input,
textarea,
select,
button {
  font: inherit;
}

img {
  width: 100%;
  height: auto;
}

svg {
  width: 20px;
  height: 20px;
}

svg.icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  vertical-align: middle;
}

a svg.icon {
  width: 10px;
  height: 10px;
}

/* Legacy's linklist chevron sits 5px off its text (`.cmp-linklist em`, margin-left 5px)
   wherever it appears, not only in a `link-list` section. Measured @1440 on rsm-ca
   /insights/services/audit/guide-to-changing-your-auditor (a `box` TOC, C67):
   text-to-glyph gap legacy 8px, ours 0px; with this, the glyph's own side bearing
   makes up the other ~3px. */
a svg.icon-chevron-right-solid-full,
a svg.icon-chevron-right-green {
  margin-left: 5px;
}

/* …but a link-list chevron is legacy's 12px glyph, not the 10px inline default
   (see the `link-list` section style above). */
main .section.link-list > .default-content a svg.icon {
  width: 12px;
  height: 12px;
  margin-left: 5px;
}

/*
 * Canonical breakpoints (RSMUS_ACM-aligned — media queries cannot use CSS vars):
 *   phoneL   567px   @media (width >= 567px)
 *   tablet   768px   @media (width >= 768px)
 *   desktop  992px   @media (width >= 992px)
 *   desktopMx 1280px @media (width >= 1280px)
 *   desktopS  1440px @media (width >= 1440px)
 */

@media (width >= 1440px) {
  :root {
    --grid-container-width: 1280px;
  }
}

/* Hide authored sections until they are decorated, so nothing flashes undecorated.
   The reveal is pure cascade: decoration adds `.section`, and the `.section`
   rule's `display: block` (0,1,0) out-points `main > div` (0,0,2) because one
   class beats any number of element selectors. `div[data-status]` re-hides a
   section while its blocks load, until ak.js deletes the attribute.

   DO NOT write the fragment exemption below as `main > div:not(.fragment-content)`.
   `:not()` takes the specificity of its argument, so that selector is (0,1,2) —
   which then out-points `.section` (0,1,0) and hides EVERY section on EVERY page.
   The exemption has to be a separate rule that wins on its own, which is why it
   sits beside the `.section` rule rather than as an exception here. */
main > div,
.has-template,
div[data-status] {
  display: none;
}

/* A hero that never decorated: hero.js failed to load twice (ak.js retries once), or
   decorate() threw before it built `.cmp-hero`. The reveal above happens anyway, and
   the raw table renders both background pictures at full width with the key names
   as text. Keep the heading on the rail and drop the rest. This has to live here, not
   in hero.css, which rides the same connection that just failed.
   `.cmp-hero` in the :not() keeps the decorated root out: hero.js adds the authored
   `type` to it as a class, so a `type: hero` root (both homepages) is itself `.hero`
   with no `.cmp-hero` child. Without it the root matched, was capped at the rail, and
   its background div (no h1) was hidden. */
main .hero:not(.cmp-hero, :has(> .cmp-hero)) {
  max-width: 1280px;
  margin-inline: auto;
  padding: 32px 20px;
}

main .hero:not(.cmp-hero, :has(> .cmp-hero)) > div:not(:has(h1)),
main .hero:not(.cmp-hero, :has(> .cmp-hero)) > div > div:first-child:not(:only-child) {
  display: none;
}

aem-sidekick {
  opacity: 0;

  &[open="true"].is-ready {
    opacity: 1;
  }
}
/* Newsroom welcome column (rsmus.com parity). Scoped via the section-metadata
   style token `newsroom-welcome` (authored classes on a <p> are stripped by the
   pipeline, but section-metadata style values survive as section classes). */

/* Match rsmus.com's wider columns: trim the block's 40px side gutter so the
   promo image (and intro text) fill the column like live — the image renders
   ~512px, matching live, instead of 453px inside the default padding. */
main .section.newsroom-welcome .columns .col {
  padding-inline: 10px;
}

/* The RSM100 promo image is the column's first child, so the columns block's
   `.col > p:first-child img` icon rule shrinks it to 80px — restore full width. */
main .section.newsroom-welcome .columns .col > p:first-child img {
  width: 100%;
  height: auto;
  max-width: none;
}

/* "Follow RSM:" label inline with the social icons on one row (rsmus.com):
   bold 700 label (matches live), ~18px dark-grey icons spaced ~26px apart,
   right-aligned to the column's right edge (under the promo image's edge). */
main .section.newsroom-welcome .columns .col p:has(> a > .icon, > a > svg) {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  align-items: center;
  justify-content: flex-end;
  margin-top: 16px;
  font-weight: 700;
}

main .section.newsroom-welcome .columns .col p a:has(> .icon, > svg) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  color: var(--color-primary-dark-grey, #515356);
  transition: color 0.2s ease;
}

main .section.newsroom-welcome .columns .col p a:has(> .icon, > svg):hover {
  color: var(--color-primary-green);
}

main .section.newsroom-welcome .columns .col :is(.icon, svg) {
  width: 24px;
  height: 24px;
  fill: currentColor;
}

/* Tablet+ (>= 768px): keep the welcome intro (left) and RSM100 promo (right)
   side-by-side, overriding the global sub-992 columns stack (columns.css). The
   7-5 ratio lives in --col-template (set by columns.js); align content to the
   top so the intro copy and the promo image share a top edge (rsmus.com). */
@media (width >= 768px) {
  main .section.newsroom-welcome .columns .row {
    grid-template-columns: var(--col-template, 7fr 5fr);
    align-items: start;
    column-gap: var(--spacing-m);
  }
}

/* Media-contact band — the "…for media use only / Follow RSM:" row that opens
   /newsroom. It is authored as a `columns` block whose trailing paragraph is a
   run of icon-only links. `span.icon` is swapped for a bare <svg> by ak.js on
   EVERY section, but until now the only rules that SIZED those <svg>s were the
   `newsroom-welcome` ones above. A band whose section does not carry that token
   (rsm-ca /newsroom, styled `full-width`) fell through to the columns defaults:
   icons at their intrinsic ~10x20, centred text, and the block's 20px/30px
   column padding on top of the section's 32px — roughly double live's band
   height. Key the treatment off the CONTENT SHAPE (a link whose entire content
   is an icon) so it cannot regress when a content re-stage drops a style token.

   That shape test lives in `columns.js` (`decorateIconLinkRows`), NOT in a
   `:has()` selector, and these rules key off the classes it adds:
     .has-icon-link-row  on the section and the block
     .icon-link-row      on each run's parent — the `<p>` (rsm-us) or the `.col`
                         itself when EDS unwrapped a single-paragraph cell (rsm-ca)
     .icon-link          on each icon-only link
   The first cut of this used `a:has(> .icon:only-child)`, but `:only-child`
   counts ELEMENT children only — text nodes are invisible to it — so the
   ordinary RSM text-plus-chevron link matched too and every one inside a
   `columns` block went #63666a (/locations/*, /about, /careers). Whether the
   link has label TEXT is the real signal and CSS cannot see it.

   `newsroom-welcome` is excluded throughout: rsmus.com sizes the same row
   differently (24px icons, 28px gap) and that section is already tuned to it.

   Live reference — rsmcanada.com/newsroom @1440, measured (rem = 10px there):
     band     15px top / 0 bottom padding on a 1280px rail
     columns  60/40, text-align:left, no column padding
     row      flex, justify-content:flex-end, align-items:center
     label    18px / 700 / #63666a
     link     padding-inline:15px, #63666a, hover --primary-blue
     glyph    18px tall; the last link sits flush with the column's right edge */
main .section:not(.newsroom-welcome) .columns.has-icon-link-row .col {
  text-align: left;
  padding-block: 0;
}

/* Only claim the section's vertical rhythm when the author has NOT set an
   explicit spacing token — an authored `Spacing:` always wins. */
main .section:not(.newsroom-welcome, [class*="spacing-"]).has-icon-link-row {
  --top-bottom-spacing: 15px;

  padding-bottom: 0;
}

main .section:not(.newsroom-welcome) .columns .icon-link-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  align-items: center;
  justify-content: flex-end;
  font-weight: 700;
  color: var(--color-primary-medium-grey);
}

main .section:not(.newsroom-welcome) .columns .icon-link-row .icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-inline: 15px;
  color: var(--color-primary-medium-grey);
  transition: color 0.2s ease;
}

/* Live puts 30px between the label and the first icon — 15px of the ul's own
   margin plus the link's 15px padding. */
main .section:not(.newsroom-welcome) .columns .icon-link-row .icon-link:first-of-type {
  margin-left: 15px;
}

main .section:not(.newsroom-welcome) .columns .icon-link-row .icon-link:last-of-type {
  padding-right: 0;
}

main .section:not(.newsroom-welcome) .columns .icon-link-row .icon-link:hover {
  color: var(--color-primary-blue);
}

main .section:not(.newsroom-welcome) .columns .icon-link-row .icon-link .icon {
  width: 18px;
  height: 18px;
  fill: currentcolor;
}

/* social-share FOUC guard (eager) — keep the sticky share rail hidden until its
   JS decorate() finishes and adds .social-share-ready. This lives in the EAGER
   stylesheet (not the block's own lazy CSS) so the dark panel can never flash as
   a grey bar on the right while the block's CSS is loading late/stale from the
   CDN. JS module execution is independent of the block CSS, so the reveal is
   reliable. visibility (not display) keeps the fixed rail out of layout flow. */
.social-share:not(.social-share-ready) {
  visibility: hidden;
}

/* ── Auto-contrast for dark section backgrounds ───────────────────────────────
   section-metadata.js measures the section's real WCAG relative luminance and
   tags its children `.dark-scheme`. That signal used to drive nothing but the
   `color-scheme` property, which restyles form controls and scrollbars — NOT
   text — so authored copy kept the default grey body colour and landed on the
   dark panel. On --color-primary-blue that is #515356 on #009CDE: 2.6:1, under
   the 4.5:1 WCAG AA needs, where legacy renders the same copy white.

   Scoped to .default-content deliberately — blocks own their colours (quote
   bg-blue already forces white), so this rescues only plain authored text,
   which has nothing else to react to the background with. A section whose
   author set the `text-light` style already looked right; this makes it
   automatic when they didn't. Lives at the END of the file so it is not
   followed by lower-specificity rules for the same elements. */
main .section > .default-content.dark-scheme {
  color: var(--color-white);

  h1, h2, h3, h4, h5, h6 { color: var(--color-white); }

  /* Ranks below the newsroom icon-link rule purely by position; the two never
     match the same anchor, so there is nothing to override. */
  /* stylelint-disable-next-line no-descending-specificity */
  a:any-link:not(.btn) { color: var(--color-white); }
}

/* ── An emptied section collapses (Bryce 2026-08-12) ──────────────────────────
   A block that resolves to nothing REMOVES itself rather than render an empty
   shell — contributors-list with no authored `Contributor` ids, or with ids that
   no longer resolve against the bios sheet, is the case that surfaced this. What
   stays behind is the `.block-content` wrapper groupChildren() built for it in
   scripts/ak.js, and the section keeps its own vertical padding, so the page
   shows a band of dead space exactly where the block would have been. Measured
   on rsm-us /insights/economics/economic-outlook-for-2026: FOUR emptied
   contributors-list sections, 32px each (`spacing-s`, 16px top + 16px bottom).

   Deliberately narrow. `:empty` matches only after a block has removed ITSELF —
   before decoration the wrapper still holds the block element, and a block that
   populates asynchronously keeps its element there throughout, so there is no
   window in which a live section collapses and re-expands. `:only-child` keeps a
   section that still holds authored default content (or a second block that did
   render) fully visible: only a section whose entire remaining content is the
   emptied wrapper is hidden. An authored spacer section never matches either,
   because a section with no block children gets no `.block-content` wrapper at
   all.

   Lives at the END of the file for the same reason as the rule above: it is
   higher-specificity than the plain `.section` / `main .section` rules up in the
   sections group, so it has to follow them. That in turn puts it after the much
   higher-specificity news-release rules near line 1182, which is what the
   disable below is for — those set `padding-top` / `padding`, never `display`,
   so the two can never override each other. */
/* stylelint-disable-next-line no-descending-specificity */
main .section:has(> .block-content:only-child:empty) {
  display: none;
}
