/* Template-scoped styles for `1806A - Pillar Page 2026`.
 *
 * Loaded ONLY by templates/library/1806A-PillarPage2026.hubl.html, via the
 * `template_css` hook that templates/layouts/partials/head.hubl.html consumes.
 * Nothing else on the site is affected.
 *
 * `section.showcase-container` is the wrapper components/Wrapper.jsx puts around
 * EVERY module, so these rules would be site-wide if this file were loaded
 * globally. Keeping it on `template_css` is what scopes it.
 *
 * `M18-ContentGroup` / `M16-TableOfContents` / `M103-AnchorNav` are generated by
 * getModuleName() in components/utils/module.js — `M` + the module directory name.
 *
 * ⚠️ Breakpoints here are the THEME's, from tokens.json — md = 960px, NOT 768px.
 *    The site header's hamburger flips at lg = 1280px.
 *
 * ⚠️ TEXT ALIGNMENT IS FIXED IN TWO PLACES, ON PURPOSE.
 *    18-ContentGroup emits the Tailwind utility `text-center` / `text-left`
 *    DIRECTLY onto .c-heading and .c-typography, driven by `styles.layout.center`.
 *    A rule on the container can never beat a utility on the descendant.
 *      - The TEMPLATE sets `center: false`, which fixes every NEW page.
 *      - But `center` is a module FIELD VALUE, so it is baked into pages at
 *        creation and template edits never reach a page that already exists.
 *    Hence the explicit `.text-center` override below, which fixes pages that
 *    were already built. Keep both.
 */

:root {
  /* Offset for anchor landings. #masthead is position:fixed (top:8px) and is
     ~80px tall, ~104px once its sticky padding kicks in. Generous by design:
     landing slightly low is harmless, landing UNDER the header is not. */
  --pillar-anchor-offset: 120px;
  /* ── The measure, in CHARACTERS ──────────────────────────────────────────
     Target: 66–75 characters per line (Aaron, Ntiva). Default 70.

     CSS `ch` is the width of the digit "0" — NOT an average character, so
     `70ch` is not 70 characters. Measured with Inter's real glyph widths
     against the CMMC page's own body copy (12,225 characters):
       1ch ≈ 1.33 characters  (16px: 10.06px vs 7.58px; 18px: 11.29px vs 8.44px)
     so 70 characters ≈ 52.7ch. The old fixed 750px measure was ~99 characters
     at 16px — far too long.

     Preview other values on any page: ?chars=66, ?chars=75, ?size=16,
     and ?measure-debug for a live characters-per-line readout
     (assets/js/pillar-page-2026.js). */
  --pillar-chars: 70;
  --pillar-ch-per-char: 0.752;     /* 1 / 1.33 — re-measure if the body font changes */
  /* Article body size from 768px up. Keep the two in step: scale = size / 16px.
     It is needed because `ch` below resolves against the CONTAINER's 16px
     font, while the copy is set larger. */
  --pillar-text-size: 1.125rem;    /* 18px */
  --pillar-text-scale: 1.125;
}

/* ── Measure ───────────────────────────────────────────────────────────────
   Centre the COLUMN; the prose inside it stays left-aligned (set in the
   template). A ragged left edge is what makes long-form text hard to scan.

   Two things used to keep the text well short of the measure:

   1. 18-ContentGroup places left-aligned text in a 12-column grid as
      `md:col-span-10 lg:col-span-8` — at >= 1280px the copy got 8 of 12
      columns. With the grid's 24px gaps that is ~459px of text inside a 700px
      box, and the last four columns stayed empty. (The split was designed for
      centred text in the middle columns.) The text now spans the full grid.
   2. The max-width sat on the module, so the container's side padding
      (--container-margin, 40px) came out of it. It now sits on the container
      as measure + padding, so the text itself is exactly the measure.

   Images keep their own 750px cap: wider than the ~590px text, on the same
   centre line — a deliberate breakout, standard in long-form layouts. */

section.showcase-container > .M18-ContentGroup {
  margin-inline: auto !important;
}

/* Measure + padding on the container, so the TEXT is exactly the measure. */
section.showcase-container > .M18-ContentGroup > .c-container {
  max-width: calc(
    var(--pillar-chars) * var(--pillar-ch-per-char) * var(--pillar-text-scale) * 1ch
      + 2 * var(--container-margin)
  );
}

/* Long-form body copy at 18px from 768px up; phones keep the theme's 16px
   (~40 characters on a 375px screen, normal for mobile reading).
   18-ContentGroup's typography already reads this variable
   (assets/styles/typography.scss). Headings, tables and CTAs are untouched. */
@media (min-width: 768px) {
  section.showcase-container > .M18-ContentGroup .c-typography {
    --typography-font-size: var(--pillar-text-size);
  }
}

@media (max-width: 767px) {
  :root {
    --pillar-text-scale: 1; /* phones read at 16px */
  }
}

/* Only the single-column layout. The split layout (two children) keeps its own
   6/5 column arrangement. */
section.showcase-container
  > .M18-ContentGroup
  .M18-ContentGroup__grid__inner
  > :only-child {
  grid-column: 1 / -1;
}

/* Beat the `text-center` utility on pages built before the template was fixed.
   Specificity here (3 classes + element scope) plus !important is what it takes
   to override a Tailwind utility sitting on the element itself. */
section.showcase-container .M18-ContentGroup .c-heading.text-center,
section.showcase-container .M18-ContentGroup .c-typography.text-center,
section.showcase-container .M18-ContentGroup .c-headline.text-center,
section.showcase-container .M18-ContentGroup .text-center :is(p, li, h2, h3, h4) {
  text-align: left !important;
}

/* The lead paragraph directly under the hero keeps its centred treatment —
   one deliberate exception, not the accidental mixture the page had before. */
section.showcase-container .M05-HeroSimpleText .c-typography.text-center,
section.showcase-container .M05-HeroSimpleText .c-heading.text-center {
  text-align: center !important;
}

/* ── Type scale ────────────────────────────────────────────────────────────
   The theme's global scale is built for full-bleed marketing sections:
   c-heading--200 is clamp(2.25rem … 3rem) = 36-48px. Over a 750px column that
   shouts. These are tuned down proportionally and kept fluid, so the rhythm
   still feels like the rest of the site, just at reading scale.

   letter-spacing is switched from the theme's fixed -1px/-4px to em units —
   a fixed negative tracking that looks right at 48px is far too tight at 28px. */

section.showcase-container .M18-ContentGroup :is(h1, h2, h3, h4, .c-heading) {
  letter-spacing: -0.02em;
  line-height: 1.25;
  text-wrap: balance; /* avoids a lone trailing word on a heading line */
}

section.showcase-container .M18-ContentGroup .c-heading--100 {
  font-size: clamp(2rem, 1.7rem + 1.5vw, 2.75rem); /* 32 → 44px */
}

section.showcase-container .M18-ContentGroup .c-heading--200 {
  font-size: clamp(1.75rem, 1.5rem + 1.1vw, 2.25rem); /* 28 → 36px */
}

section.showcase-container .M18-ContentGroup .c-heading--300 {
  font-size: clamp(1.375rem, 1.25rem + 0.6vw, 1.625rem); /* 22 → 26px */
}

section.showcase-container .M18-ContentGroup .c-heading--400 {
  font-size: clamp(1.25rem, 1.2rem + 0.25vw, 1.375rem); /* 20 → 22px */
}

/* The template used a hard `fontSize: "48"` on five content groups, which emits
   .text-48. Those overrides are removed, but neutralise the utility here too so
   an editor re-applying it in the page UI cannot blow the scale back up. */
section.showcase-container .M18-ContentGroup .text-48 {
  font-size: clamp(1.75rem, 1.5rem + 1.1vw, 2.25rem);
}

/* Vertical rhythm: headings need more space above them than below, or sections
   read as one undifferentiated block. */
section.showcase-container .M18-ContentGroup .c-headline + .c-typography {
  margin-top: 1rem;
}

/* Body copy: a looser leading than the theme default, which is tuned for short
   marketing blocks rather than a 2,500-word read. */
section.showcase-container .M18-ContentGroup .c-typography {
  line-height: 1.7;
}

section.showcase-container .M18-ContentGroup .c-typography :is(p, ul, ol) + :is(p, ul, ol, h2, h3) {
  margin-top: 1.15em;
}

/* ── Images ────────────────────────────────────────────────────────────────
   Tailwind preflight already sets `img { display: block }`, so `margin: auto`
   does the centring. Sharpness is handled by the srcset in 00-Media, not here —
   this only caps the display box to sit comfortably against the measure. */

section.showcase-container picture > img {
  max-width: 750px !important;
  width: auto !important;
  border-radius: 12px;
  margin: auto !important;
}

/* Phones (the theme's own mobile breakpoint, theme.json: max-width 767px):
   article images run edge to edge with square corners. 00-Media with
   fullWidth already spans the viewport; this lifts the 750px cap and radius. */
@media (max-width: 767px) {
  section.showcase-container picture > img {
    width: 100% !important;
    max-width: 100% !important;
    border-radius: 0;
    margin: 0 !important;
  }
}

/* ── Tables ────────────────────────────────────────────────────────────────
   Rich-text tables are pasted content and arrive with their own inline
   styles. The CMMC glossary is authored with `table-layout: fixed` (three
   EQUAL columns — a one-word initialism column as wide as 22-word
   definitions), every cell `text-align: center`, 1pt black borders, and no
   header cells. The rules below undo that at every width; `!important` is
   what it takes to beat inline styles.

   assets/js/pillar-page-2026.js then promotes the header row to a real
   <thead>, labels every cell, and classifies each table:
     .pillar-table--stack   ≤3 columns, no merged cells → cards on phones
     .pillar-table--scroll  anything wider → keyboard-scrollable region
   Research: NN/g "Mobile Tables"; Adrian Roselli, "Under-Engineered
   Responsive Tables" and "Tables, CSS Display Properties, and ARIA". */

section.showcase-container .c-typography table {
  width: 100% !important;
  table-layout: auto !important; /* columns size to their content */
  border-collapse: collapse;
  margin: 1.5em 0;
  font-size: 16px;
  line-height: 1.5;
  border: 1px solid var(--color-greys-100) !important;
}

section.showcase-container .c-typography :is(th, td) {
  padding: 12px 14px;
  text-align: left !important;
  vertical-align: top;
  border: 1px solid var(--color-greys-100) !important;
}

section.showcase-container .c-typography :is(th, td) p {
  margin: 0;
  text-align: left !important;
}

/* Header row — a real <thead> once the script has run; until then, the
   authored first row is styled the same so nothing jumps. */
section.showcase-container .c-typography thead th,
section.showcase-container .c-typography table:not(.pillar-table) tr:first-child td {
  background-color: var(--color-greys-50);
  font-weight: 600;
  color: var(--color-greys-900);
}

/* Short first column (an initialism, a name): keep it on one line. */
section.showcase-container .c-typography .pillar-table--stack td:first-child {
  white-space: nowrap;
  font-weight: 600;
  color: var(--color-greys-900);
}

/* ── Stack mode on phones: each row becomes a card ─────────────────────── */
@media (max-width: 767px) {
  section.showcase-container .c-typography .pillar-table--stack,
  section.showcase-container .c-typography .pillar-table--stack :is(tbody, tr, td) {
    display: block;
    width: 100% !important;
  }

  section.showcase-container .c-typography .pillar-table--stack {
    border: 0 !important;
  }

  /* Visually hidden, NOT display:none — assistive tech still reads it, and
     the ARIA roles the script re-applies keep the table a table. */
  section.showcase-container .c-typography .pillar-table--stack thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }

  section.showcase-container .c-typography .pillar-table--stack tr {
    padding: 16px;
    background-color: #fff;
    border: 1px solid var(--color-greys-100);
    border-radius: 12px;
  }

  section.showcase-container .c-typography .pillar-table--stack tr + tr {
    margin-top: 12px;
  }

  section.showcase-container .c-typography .pillar-table--stack td {
    padding: 0;
    border: 0 !important;
  }

  /* The first cell is the card's title. */
  section.showcase-container .c-typography .pillar-table--stack td:first-child {
    font-size: 18px;
    font-weight: 700;
    line-height: 1.3;
    white-space: normal;
  }

  section.showcase-container .c-typography .pillar-table--stack td + td {
    margin-top: 12px;
  }

  /* Every other cell is introduced by its column name. */
  section.showcase-container .c-typography .pillar-table--stack td + td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 2px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-greys-700);
  }
}

/* ── Scroll mode (any width): a keyboard-focusable region ──────────────── */
section.showcase-container .pillar-table-scroll {
  margin: 1.5em 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 8px;
  /* Scroll shadows as the "there's more" cue (NN/g: cut-off elements):
     the white covers scroll with the content, the shadows stay put, so a
     shadow shows only on a side that has hidden content. */
  background:
    linear-gradient(to right, #fff 30%, rgb(255 255 255 / 0%)) left / 40px 100% no-repeat local,
    linear-gradient(to left, #fff 30%, rgb(255 255 255 / 0%)) right / 40px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgb(0 0 0 / 14%), transparent) left / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgb(0 0 0 / 14%), transparent) right / 14px 100% no-repeat scroll;
}

section.showcase-container .pillar-table-scroll:focus-visible {
  outline: 2px solid var(--color-primary-500);
  outline-offset: 2px;
}

section.showcase-container .pillar-table-scroll .pillar-table {
  margin: 0;
  min-width: 100%;
  width: max-content !important;
}

/* Lock the first column so every row keeps its label while scrolling. */
section.showcase-container .pillar-table--scroll :is(th, td):first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background-color: #fff;
}

section.showcase-container .pillar-table--scroll thead th:first-child {
  background-color: var(--color-greys-50);
}

/* ── Anchor landings ───────────────────────────────────────────────────────
   Nothing in the theme sets scroll-margin-top, so a native `#topic-2` landing
   (a shared link, or a page load carrying a hash) scrolls the anchor to y=0 —
   underneath the fixed header. The JS click handlers compensate; the browser
   does not. */

section.showcase-container .c-anchor,
section.showcase-container [id]:not([id='']) {
  scroll-margin-top: var(--pillar-anchor-offset);
}

/* The theme sets `html { scroll-behavior: smooth }` globally (general.scss),
   which double-smooths every GSAP ScrollToPlugin animation the anchor nav uses.
   Scoped off for this template only. */
html {
  scroll-behavior: auto;
}

/* ── Table of contents ─────────────────────────────────────────────────────
   One job per viewport:

     < 960px   103-AnchorNav — sticky bar + dropdown (its own mobile UI)
     960-1279  16-TableOfContents — the in-page card grid
     >= 1280px 115-StickyToc — the left rail (styled in its own module sheet)

   103 is left exactly as the theme ships it here; it is also used by
   services.hubl.html, so it is never restyled into a rail. */

section.showcase-container .M16-TableOfContents__grid {
  max-width: 950px !important;
  margin: auto !important;
}

@media (max-width: 959px) {
  .M16-TableOfContents {
    display: none;
  }
}

@media (min-width: 960px) {
  .M103-AnchorNav {
    display: none;
  }
}

/* Mobile anchor bar + its dropdown: frosted glass instead of a solid fill.
   Classes come from 103-AnchorNav/islands: the bar's card is
   `.mx-2.bg-greys-100` (StickyNav.jsx), the dropdown panel is
   `ul.bg-greys-100` (AnchorList.jsx). Scoped to this template's stylesheet
   because services.hubl.html also uses 103.

   ⚠️ Why the bar's glass lives on ::before and not on the bar itself:
   an element with backdrop-filter becomes a "backdrop root" for everything
   inside it. The dropdown is a child of the bar, so if the bar carried the
   filter, the dropdown's own backdrop-filter could only blur what is inside
   the bar — over the page it would be see-through but NOT blurred. Putting
   the bar's glass on a pseudo-element keeps the bar itself a plain box, so
   the dropdown blurs the real page behind it. */
.M103-AnchorNav .mx-2.bg-greys-100 {
  position: relative;
  /* A stacking context so ::before (z-index -1) sits behind the bar's content,
     and z-index 10 — the dropdown's original `z-10` — so the open dropdown
     paints above the sections that follow even before the bar sticks.
     z-index does not create a backdrop root; filters do. */
  z-index: 10;
  background-color: transparent;
}

.M103-AnchorNav .mx-2.bg-greys-100::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-color: rgba(237, 237, 237, 0.65); /* greys-100 at 65% */
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.M103-AnchorNav ul.bg-greys-100 {
  background-color: rgba(237, 237, 237, 0.65);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

/* Without backdrop-filter support a 65% fill over body text hurts
   legibility, so fall back to the solid token. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .M103-AnchorNav .mx-2.bg-greys-100::before,
  .M103-AnchorNav ul.bg-greys-100 {
    background-color: var(--color-greys-100);
  }
}

/* ── Sidebar layout (>= 1280px) ────────────────────────────────────────────
   The rail needs a column of its own. A rail floated in the margin sits ON TOP
   of every section wider than the text — the Resources grids, the form/CTA
   sections and the mid-article banner are ~1240px — so instead each article
   section's content moves into a zone to the right of a reserved rail column:

     | gutter | rail 256 | gap 48 | content zone (~976) ................ |

   Section backgrounds (grey bands, the dark banner) still run full width; only
   their content moves. The hero keeps its full-width layout.

   Scoped with :has(.M115-StickyToc) so pages built before the rail existed do
   not get an empty column. `!important` is required: HubSpot writes each
   section's max-width as `.dnd_main-row-N-max-width-section-centering >
   .row-fluid { max-width: 1240px !important }`, and all rows must share one
   width or the zone's left edge drifts between sections. */

:root {
  --pillar-rail-width: 256px;
  --pillar-rail-gap: 48px;
}

@media (min-width: 1280px) {
  /* Only where the rail exists. Pages created before 115-StickyToc was added
     keep their in-page cards rather than losing the desktop TOC altogether. */
  main:has(.M115-StickyToc) .M16-TableOfContents {
    display: none;
  }

  main:has(.M115-StickyToc)
    .dnd-section:not(:has(.M05-HeroSimpleText)):not(:has(.M115-StickyToc))
    > .row-fluid {
    max-width: var(--container-width) !important;
    margin-left: auto !important;
    margin-right: auto !important;
    padding-left: calc(var(--pillar-rail-width) + var(--pillar-rail-gap));
  }

  /* The rail's own section is a zero-height anchor. */
  main .dnd-section:has(.M115-StickyToc) {
    padding: 0 !important;
    margin: 0 !important;
  }
}

