   /* =====================================================================
   SHARED PAGE STYLES
   Loaded on every page (see app/views/layouts/application.html.erb),
   before each page's own stylesheet_link_tag, so per-page CSS still
   wins the cascade wherever it needs to override something here.

   Contains only rules verified to be duplicated verbatim (ignoring
   whitespace/formatting) across 3+ of the 11 page stylesheets in
   app/assets/stylesheets/pages/. Anything that differs between pages
   (even slightly) was left in its own page file — see the per-file
   overrides noted inline below for the handful of cases where a page
   is 95% identical to the shared rule but tweaks one property.
   ===================================================================== */

/* ---------------------------------------------------------------------
   FAMILY A — "Listing" pages
   about.css, blogs_index.css, contact.css, events_index.css, home.css,
   products_index.css
   --------------------------------------------------------------------- */

:root {
  --bg: #ffffff;
  --bg-2: #f5f8fc;
  --bg-3: #eef3f9;
  --surface: #ffffff;
  --line: #e3eaf3;
  --line-strong: #d4dde9;
  --text: #0b1e3f;
  --text-dim: #5a6a82;
  --text-mute: #8a96aa;
  --accent: #0d5cf5;
  --accent-dark: #0942b8;
  --accent-2: #1ea7ff;
  --accent-soft: rgba(13, 92, 245, 0.08);
  --dark: #0b1e3f;
  --dark-2: #122c54;
  --radius: 14px;
  --container: 1280px;
  --t: cubic-bezier(.65,.05,.36,1);
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; transition: color .25s var(--t); }
ul { list-style: none; }

/* body: common subset only — home.css overrides line-height/font-weight.
   `overflow-x: clip` (not `hidden`) — `hidden` makes body a scroll container on both axes per
   the CSS Overflow spec, which silently breaks `position: sticky` on every descendant (sidebar
   nav, sticky headers) across the site. `clip` blocks horizontal overflow the same way without
   that side effect. */
body {
  font-family: 'Inter', sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }

h1, h2, h3, h4, h5, h6 { font-family: 'Archivo', sans-serif; font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; color: var(--text); }
.section-title { font-size: clamp(2rem, 4vw, 3.4rem); font-weight: 900; }

/* section-eyebrow: common subset — home.css overrides font-family (Manrope) */
.section-eyebrow { display: inline-flex; align-items: center; gap: 12px; font-family: 'Archivo', sans-serif; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.18em; color: var(--accent); text-transform: uppercase; margin-bottom: 18px; }
.section-eyebrow .line { width: 32px; height: 2px; background: var(--accent); }
.section-eyebrow--light { color: var(--accent-2); }
.section-eyebrow--light .line { background: var(--accent-2); }
.section-eyebrow--center { justify-content: center; }

.section-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 32px; margin-bottom: 56px; flex-wrap: wrap; }
.section-head--center { justify-content: center; text-align: center; }

/* Buttons: common subset — about.css and home.css add position:relative;overflow:hidden to .btn */
.btn { display: inline-flex; align-items: center; gap: 12px; padding: 14px 26px; font-family: 'Archivo', sans-serif; font-weight: 700; font-size: 0.9rem; letter-spacing: 0.05em; text-transform: uppercase; border-radius: 50px; border: none; cursor: pointer; transition: all .35s var(--t); }
.btn--primary { background: var(--accent); color: #ffffff; }
.btn--primary:hover { background: var(--accent-dark); transform: translateY(-2px); box-shadow: 0 14px 30px rgba(13, 92, 245, 0.35); }
.btn--ghost { background: transparent; color: var(--text); border: 1px solid var(--line-strong); }
.btn--ghost:hover { background: var(--text); color: #ffffff; border-color: var(--text); }
.btn--ghost-light { background: rgba(255,255,255,0.08); color: #ffffff; border: 1px solid rgba(255,255,255,0.25); backdrop-filter: blur(10px); }
.btn--ghost-light:hover { background: #ffffff; color: var(--accent); }
.btn--lg { padding: 18px 34px; font-size: 0.95rem; }

/* Topbar */
.topbar { background: var(--dark); font-size: 0.8rem; color: rgba(255,255,255,0.75); }
.topbar__inner { display: flex; justify-content: space-between; align-items: center; padding: 10px 24px; flex-wrap: wrap; gap: 8px; }
.topbar__left, .topbar__right { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.topbar__sep { color: rgba(255,255,255,0.2); }
.topbar i { color: var(--accent-2); margin-right: 6px; }
.topbar__social { display: flex; gap: 10px; }
.topbar__social a { width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: rgba(255,255,255,0.08); font-size: 0.7rem; }
.topbar__social a i { color: inherit; margin: 0; }

/* Topbar — mobile responsiveness. Centralized here (rather than duplicated per
   page) so every page and subpage gets identical topbar behavior on small
   screens: shrink the text, and hide everything in .topbar__left except the
   first item (plus the separator) so it doesn't wrap or crowd the header. */
@media (max-width: 768px) {
  .topbar__left, .topbar__right { font-size: 0.72rem; gap: 8px; }
  .topbar__left span:not(:first-child),
  .topbar__sep { display: none; }
}

/* Header brand — mobile responsiveness. Centralized here (rather than duplicated per page)
   so every page gets identical behavior on small screens: shrink the logo and cap the
   wordmark's width so it truncates with an ellipsis instead of colliding with — or, with a
   broken/unreachable logo image, pushing off-screen — the .menu-toggle hamburger button. */
@media (max-width: 480px) {
  .header__inner { padding: 12px 16px; gap: 12px; }
  .brand { gap: 8px; }
  .brand__logo { width: 3rem; height: 3rem; }
  .site-header .brand__logo { margin: 0; }
  .brand__text { max-width: 46vw; }
  .brand__name { font-size: 0.92rem; }
}

/* Header / Nav */
/* Custom properties on :root are global, and several page stylesheets
   (product_category.css, product_detail.css, blog_detail.css, blog_author.css,
   industries_detail.css, event_detail.css) declare their own `:root { --accent: ...;
   --text: ...; --line: ...; --t: ...; }` for their own page content, reusing the same
   names as shared.css's tokens above but different values (e.g. --accent is #1ea7ff on
   those pages vs #0d5cf5 here). Because :root wins globally regardless of which
   stylesheet loads second, the header/nav -- including the mega menu's heading color
   and hover underline, both set via var(--accent) -- silently inherited whichever
   page's accent happened to be declared, so the same nav rendered a different color on
   different pages. Re-declaring the tokens the header subtree actually uses directly on
   `.site-header` pins them for every descendant (.nav, .mega, .brand, ...) via normal
   inheritance from the nearest ancestor that sets them, regardless of any page-level
   :root redefinition or load order -- so the header looks identical everywhere. */
.site-header {
  --line: #e3eaf3;
  --text: #0b1e3f;
  --text-dim: #5a6a82;
  --accent: #0d5cf5;
  --accent-soft: rgba(13, 92, 245, 0.08);
  --t: cubic-bezier(.65,.05,.36,1);
}
.site-header { position: sticky; top: 0; z-index: 100; background: rgba(255,255,255,0.92); backdrop-filter: blur(16px); border-bottom: 1px solid var(--line); transition: all .3s var(--t); }
.site-header.scrolled { background: rgba(255,255,255,0.98); box-shadow: 0 8px 30px rgba(11, 30, 63, 0.08); }
.header__inner { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; gap: 24px; }
/* `min-width: 0` lets .brand actually shrink inside the flex row below — without it a flex
   item's default `min-width: auto` floors its shrink at its content's natural width, so on
   narrow viewports .brand (logo + full company name) refuses to shrink and pushes
   .menu-toggle's hamburger tap target partly off-screen instead. */
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* `overflow: hidden` clips the fallback alt-text/broken-image glyph browsers render in place
   of an `<img>` that fails to load, so a broken logo URL degrades to an empty box instead of
   multi-line alt text blowing out the header's height and width. */
/* `font-size: 0` hides the fallback alt-text glyph browsers render when the `src` fails to
   load (Chrome renders it as inline text content, which `overflow: hidden` alone doesn't
   reliably clip) — the `alt` attribute is still exposed to the accessibility tree regardless
   of font-size, so this doesn't affect screen readers. */
.brand__logo { display: block; width: 4.5rem; height: 4.5rem; object-fit: contain; overflow: hidden; flex-shrink: 0; font-size: 0; }
.site-header .brand__logo { margin: -10px 0; }
.brand__text { display: flex; flex-direction: column; line-height: 1; min-width: 0; }
/* Canonical header/nav chrome, matching home.css's look (the reference for every page).
   .brand__mark uses a literal color rather than var(--accent): "Family B" detail pages
   (event_detail.css etc.) redefine --accent to a different value (#1ea7ff, their own
   lighter highlight color) for their own content, which would make the logo mark drift
   from home's if this used the variable. */
.brand__mark {
  width: 44px; height: 44px;
  background: #0d5cf5;
  color: #ffffff;
  font-family: 'Montserrat', sans-serif;
  font-weight: 900;
  font-size: 1.05rem;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  letter-spacing: -0.02em;
  position: relative;
}
.brand__mark::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 8px;
  border: 2px solid #0d5cf5;
  transform: translate(4px, 4px);
  opacity: 0.25;
  pointer-events: none;
}
.brand__sub { font-size: 0.65rem; font-weight: 600; letter-spacing: 0.32em; color: var(--text-dim); margin-top: 4px; font-family: 'Montserrat', sans-serif; }
/* Header wordmark: stacked two-line style referencing the uploaded logo's own lockup — bold
   accent-colored first line (every word but the last), smaller wide-tracked uppercase second
   line (the last word) underneath. `.brand__name` itself stays the flex column + base font so
   the footer's plain single-span usage (no -primary/-secondary children there) is unaffected. */
.brand__name { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; font-family: 'Montserrat', sans-serif; font-weight: 900; font-size: 1.05rem; letter-spacing: 0.04em; color: #000000; }
.brand__name-primary {
  color: #000000; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand__name-secondary {
  font-size: 0.62em; font-weight: 700; letter-spacing: 0.28em; text-transform: uppercase;
  color: inherit; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand--light .brand__logo { background: #ffffff; border-radius: 8px; padding: 0 2px; box-sizing: border-box; height: 3rem; }
.brand--light .brand__name { color: #ffffff; }
.brand--light .brand__name-primary { color: #ffffff; }
.brand--light .brand__sub { color: rgba(255,255,255,0.5); }
.nav > ul { display: flex; gap: 4px; }
.nav li { position: relative; }
/* .has-mega opts back out of that relative positioning so .mega's nearest positioned
   ancestor is .site-header (position: sticky) instead of the trigger <li> -- that's what
   lets the panel span the full header width edge-to-edge rather than floating as a small
   card centered under the trigger link. */
.nav .has-mega { position: static; }
.nav a { display: inline-flex; align-items: center; gap: 6px; padding: 10px 14px; font-weight: 600; font-size: 0.92rem; color: var(--text-dim); border-radius: 50px; transition: all .25s var(--t); font-family: 'Montserrat', sans-serif; }
.nav a:hover, .nav a.active { color: var(--accent); background: var(--accent-soft); }
/* :focus-within keeps the panel open via Tab: it re-matches as focus moves from the trigger
   link onto the links inside .mega itself, so keyboard users can tab through the whole
   dropdown rather than it disappearing the instant focus leaves the trigger. */
.nav .has-mega:hover > .mega,
.nav .has-mega:focus-within > .mega { opacity: 1; visibility: visible; transform: translateY(0); }
/* Full-bleed flat panel attached to the header (FirstCry-style mega menu): edge-to-edge
   under the header rather than a floating rounded card, with columns left-aligned starting
   at the same padding as the header/container instead of centered under the trigger.
   grid-template-columns: repeat(5, ...) caps every row at exactly 5 columns -- grid
   auto-placement wraps a 6th item to the next row on its own, so the cap holds regardless
   of how wide the panel itself is (it no longer depends on a max-width trick). Kept tight
   (compact gaps/padding, no big card shadow) rather than airy, to match the reference.
   Each of the 5 tracks is a bounded minmax(140px, 220px) -- NOT max-content. max-content
   would size a track to its widest *unwrapped* line, but every column index is one shared
   track down the whole grid: with 10+ categories (2 rows of 5), a long nowrap line in
   row 2 forced that whole column wider than the panel had room for, and since the tracks
   still had to fit inside the panel's own width, the grid compressed them below that
   line's actual (unwrapped) width -- with nowrap set, the overflow had nowhere to go but
   to spill across the neighboring column instead of wrapping. Bounding the track and
   letting headings/links wrap within it (below) fixes that: every column has a
   predictable, non-overlapping width regardless of how many rows or how long any one
   line is. */
/* CSS multi-column (not grid) so each .mega__col keeps its own natural height and the
   next category starts right under the shortest column, matching the FirstCry-style
   reference -- a grid with shared row tracks stretches every column in a row to the
   tallest one, leaving large empty gaps under short categories (e.g. a 3-item category
   sitting in the same row band as an 8-item one). column-fill: auto lets columns fill
   to the panel's max-height/overflow-y before balancing across the remaining columns,
   so the source-order list still reads top-to-bottom then left-to-right.
   column-count can't just be dropped in favor of column-width alone: with the panel's
   height capped by max-height/overflow-y (right above), an unconstrained column-count
   lets the browser spill content into *extra* column boxes to avoid clipping it
   vertically -- verified this pushes the panel wider than its own container and forces
   a page-level horizontal scrollbar on narrower desktop widths (~1024-1150px), which is
   worse than the stretch it was meant to fix. column-count has to stay as a hard cap on
   how many tracks can ever be created. What it doesn't need is to stay pinned at 5 --
   the padding above centers content within `--container` (1280px), so past ~1330px
   viewport width the panel's actual content area is fixed at 1280px regardless of
   monitor size, which fits a 6th ~160px column (1280 / (160+24) ~= 6.9) with no
   overflow risk. Below that, at the narrower end of the desktop range, 5 stays the safe
   ceiling (1024px viewport already only just fits 5). This is why the cap steps from 5
   to 6 at the media query below instead of just being raised outright -- raising it
   unconditionally reintroduces the same horizontal-overflow bug on smaller desktops. */
.mega { position: absolute; top: 100%; left: 0; right: 0; width: 100%; transform: translateY(10px); max-height: min(520px, calc(100vh - 160px)); overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(11,30,63,0.15) transparent; display: block; column-count: 5; column-width: 160px; column-fill: auto; column-gap: 24px; background: #ffffff; border: none; border-top: 1px solid var(--line); border-radius: 0; padding: 24px max(24px, calc((100vw - var(--container)) / 2)); box-shadow: 0 16px 32px rgba(11, 30, 63, 0.08); opacity: 0; visibility: hidden; transition: all .3s var(--t); }
@media (min-width: 1150px) {
  .mega { column-count: 6; }
}
.mega::-webkit-scrollbar { width: 6px; }
.mega::-webkit-scrollbar-track { background: transparent; }
.mega::-webkit-scrollbar-thumb { background: rgba(11,30,63,0.15); border-radius: 3px; }
.mega::-webkit-scrollbar-thumb:hover { background: rgba(11,30,63,0.25); }
/* A column stacks vertically: shared/mega_group can nest an arbitrary number of
   labeled sections (heading + links) inside one column, one under the other, rather
   than a column being limited to a single heading. */
.mega__col { display: flex; flex-direction: column; text-align: left; min-width: 0; break-inside: avoid-column; margin-bottom: 20px; }
/* Only spaces sibling sections stacked inside the same column -- the gap between
   columns themselves already comes from the grid's own `gap`. */
.mega__col > .mega__col--group + .mega__col--group,
.mega__col > .mega__col--group + a,
.mega__col > a + .mega__col--group { margin-top: 18px; }
.mega__col h6 { font-size: 0.82rem; color: var(--accent); letter-spacing: 0.02em; text-transform: uppercase; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--line); font-family: 'Montserrat', sans-serif; font-weight: 700; overflow-wrap: break-word; word-break: break-word; transition: border-color .2s var(--t), border-bottom-width .2s var(--t); }
.mega__col--group:hover > h6 { border-bottom-width: 2px; border-bottom-color: var(--accent); padding-bottom: 7px; }
/* Nested sections (a heading inside another column section, depth > 0) read as
   sub-headings rather than repeating the outer divider at every level. */
.mega__col--group--nested { margin-top: 14px; }
.mega__col--group--nested > h6 { font-size: 0.78rem; border-bottom: none; padding-bottom: 0; margin-bottom: 6px; }
/* Desktop reveals the whole mega panel on :hover (line 148 above), so the per-category
   accordion toggle has nothing to do there — only shown back inside the mobile media
   query below, where shared.js wires up the tap-to-expand behavior. */
.mega__col-toggle { display: none; }
.mega__col a { display: block; padding: 4px 0; font-size: 0.86rem; color: var(--text-dim); background: none !important; border-radius: 0; font-family: 'Montserrat', sans-serif; overflow-wrap: break-word; word-break: break-word; }
.mega__col a:hover { color: var(--accent); }

/* Mobile mega-menu toggle. The mega panel is hover-only above (line 148), which is
   unreachable on touch, and every page's own mobile nav block sets `.mega { display:
   none; }` unconditionally (e.g. home.css:887) — so a `.has-mega` item like "Products"
   had no way to ever reveal its dropdown on a phone. Centralized here (rather than
   patched into all 12 page CSS files) using a selector specific enough
   (.nav.open .has-mega.open > .mega, at 0-5-0) to beat each page's `.mega { display:
   none }` regardless of load order. Toggled via shared.js's "MOBILE MEGA MENU" handler.
   Single-column + explicit width/box-sizing/word-break on every descendant avoids the
   horizontal-overflow/clipping bug a naive `display: block` here previously caused. */
@media (max-width: 1024px) {
  .nav.open .has-mega.open > a i.fa-chevron-down { transform: rotate(180deg); }
  .nav.open .has-mega > a i.fa-chevron-down { transition: transform .25s var(--t); }
  .nav.open .has-mega.open > .mega {
    display: block;
    column-count: 1;
    /* Desktop's `column-width: 160px` (line 222) isn't reset by `column-count: 1` alone --
       with both set, the used column count is min(column-count, floor(available-width /
       (column-width + gap))), so leaving column-width at 160px still lets the browser
       pack a second, narrower column instead of collapsing to exactly 1. */
    column-width: auto;
    /* Desktop's `max-height: min(520px, calc(100vh - 160px))` + `overflow-y: auto` (line
       222) also isn't reset here. Per the multicol spec, when a multicol box has a
       constrained (non-auto) height and its content is taller than that height, the
       overflow doesn't just scroll -- the browser spills it into an *extra column box*
       laid out beside the first one (this is how multicol pagination is defined to work),
       so a tall accordion with `column-count: 1` still silently grows a second, off-screen
       column full of categories 9+ that the user can never reach. `.nav.open` (the drawer,
       not `.mega`) is what actually scrolls on mobile -- shared.js sets its inline
       max-height live to the real space under the header -- so `.mega` itself must be
       height-unconstrained here. */
    max-height: none;
    overflow-y: visible;
    position: static;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    opacity: 1;
    visibility: visible;
    transform: none;
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    padding: 4px 0 12px 16px;
  }
  .nav.open .has-mega.open > .mega .mega__col {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }
  .nav.open .has-mega.open > .mega .mega__col + .mega__col { margin-top: 0; }
  .nav.open .has-mega.open > .mega .mega__col h6 {
    /* Same size as `.nav a` above (0.92rem) so the accordion heading reads as a
       continuation of the top-level list rather than a smaller sub-list. */
    font-size: 0.92rem;
    border-bottom: none;
    margin-bottom: 0;
    /* Same 14px vertical rhythm as `.nav.open a` above, so the accordion reads as a
       continuation of the top-level list rather than a cramped sub-list. */
    padding: 14px 0;
    white-space: normal;
    overflow-wrap: break-word;
    word-break: break-word;
  }
  .nav.open .has-mega.open > .mega .mega__col a {
    font-size: 0.92rem;
    padding: 14px 0;
    white-space: normal;
    overflow-wrap: break-word;
    word-break: break-word;
  }

  /* Nested per-category accordion — collapsed by default so a "Products" dropdown with
     several categories doesn't dump every link at once; toggled by shared.js. Only
     .mega__col--group (a column with its own h6 heading) collapses — an ungrouped
     single link column (no heading to tap) is unaffected. */
  .nav.open .has-mega.open > .mega .mega__col--group h6 {
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
  }
  .nav.open .has-mega.open > .mega .mega__col--group .mega__col-toggle {
    display: inline-block;
    font-size: 0.6rem;
    transition: transform .25s var(--t);
  }
  .nav.open .has-mega.open > .mega .mega__col--group.open .mega__col-toggle { transform: rotate(180deg); }
  .nav.open .has-mega.open > .mega .mega__col--group:not(.open) a { display: none; }

  /* Each page's own `.nav.open { position: absolute; top: 100%; ... }` (e.g.
     home.css:877) sizes itself relative to the sticky header — with no bottom bound, a
     tall open panel (especially with a mega dropdown + several accordion categories
     expanded) just overflows past the viewport with nowhere of its own to scroll, so the
     touch-scroll gesture falls through to the page behind it instead. A fixed
     `calc(100vh - 90px)` isn't reliable either, since the topbar's contact info wraps to
     2 lines on narrow screens, changing the header's real height.
     `position: fixed` + `bottom: 0` was tried here to pin the panel exactly to the
     viewport, but `.site-header` has `backdrop-filter: blur(16px)` — and a
     `backdrop-filter`/`transform`/`filter` ancestor becomes the *containing block* for any
     `position: fixed` descendant (same as it would for `position: absolute`), so the panel
     was actually being fixed relative to the ~90px-tall header box, not the viewport,
     and effectively vanished off-screen. Staying on `position: absolute` (inherited from
     the page CSS) sidesteps that trap entirely — shared.js measures the real available
     height live (`window.innerHeight - header.getBoundingClientRect().bottom`) and sets
     it as an inline `max-height` each time the panel opens or the viewport resizes. */
  .nav.open {
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
}
/* Scoped to `.site-header` (not plain `.header__cta`) so this beats the `.btn` reset that
   every "detail page family" stylesheet (product_detail.css, event_detail.css,
   industries_detail.css, blog_detail.css, blog_author.css, product_category.css) declares for
   its own in-page buttons — those load after pages/shared.css, so a same-specificity `.btn`
   there would otherwise win the cascade and reskin the shared header's CTA (no more uppercase,
   a stray 2px border, wrong padding/font) on every page that has its own button styling.
   Deliberately omits `display`: each page's own `@media (max-width: 1024px) { .header__cta {
   display: none; } }` rule (which toggles it in favor of the hamburger menu) has the same
   specificity as a plain `.btn`/`.header__cta` selector — if this rule set `display` too, its
   higher specificity would beat that media query at every width and the CTA would never hide
   on mobile, overflowing the header instead. */
.site-header .header__cta {
  gap: 12px;
  padding: 11px 22px; font-size: 0.82rem; font-family: 'Montserrat', sans-serif;
  font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  border-radius: 50px; border: none; cursor: pointer; transition: all .35s var(--t);
}
.menu-toggle { display: none; background: none; border: none; width: 40px; height: 40px; flex-shrink: 0; flex-direction: column; gap: 5px; justify-content: center; align-items: center; cursor: pointer; }
.menu-toggle span { width: 24px; height: 2px; background: var(--text); transition: all .3s var(--t); }
.menu-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle.open span:nth-child(2) { opacity: 0; }
.menu-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.breadcrumb a:hover { color: var(--accent-2); }

/* Stat / stats-strip block (about.css, events_index.css, home.css, products_index.css) */
.stat { text-align: left; border-left: 3px solid var(--accent); padding-left: 24px; }
.stat__num { font-family: 'Bebas Neue', sans-serif; font-size: 4.5rem; line-height: 1; margin-bottom: 8px; color: #ffffff; }
.stat__num::after { content: "+"; font-size: 3rem; color: var(--accent-2); }
.stat__label { font-family: 'Archivo', sans-serif; font-weight: 700; font-size: 0.95rem; line-height: 1.4; color: rgba(255,255,255,0.85); }
.stats-strip { background: var(--dark); color: #ffffff; padding: 70px 0; position: relative; overflow: hidden; }
.stats-strip::before { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 80% 50%, rgba(13, 92, 245, 0.25), transparent 60%), repeating-linear-gradient(45deg, transparent, transparent 30px, rgba(255,255,255,0.02) 30px, rgba(255,255,255,0.02) 60px); pointer-events: none; }
.stats-strip__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 40px; position: relative; }

/* Hero meta block (blogs_index.css, events_index.css, products_index.css) */
.hero__meta { display: flex; align-items: center; gap: 0; }
.hero__meta-item { padding: 0 40px 0 0; }
.hero__meta-item:first-child { padding-left: 0; }
.hero__meta-num { font-family: 'Bebas Neue', sans-serif; font-size: 3rem; color: #ffffff; line-height: 1; display: block; }
.hero__meta-label { font-family: 'Archivo', sans-serif; font-size: 0.78rem; font-weight: 600; color: rgba(255,255,255,0.5); letter-spacing: 0.08em; text-transform: uppercase; }
.hero__meta-div { width: 1px; height: 50px; background: rgba(255,255,255,0.15); margin-right: 40px; }
.page-hero__content .section-eyebrow { color: var(--accent-2); }
.page-hero__content .section-eyebrow .line { background: var(--accent-2); }

/* Filter bar (blogs_index.css, events_index.css, products_index.css) */
.filter-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 52px; padding: 6px; background: var(--bg); border: 1px solid var(--line); border-radius: 50px; width: fit-content; max-width: 100%; }
.filter-pill:hover { color: var(--accent); background: var(--accent-soft); }

.cta__actions { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
.cta__title em { color: var(--accent-2); }

.footer__col ul li { margin-bottom: 10px; }
.reveal.visible { opacity: 1; transform: translateY(0); }

/* Footer variant 1 (about.css, contact.css, home.css) */
.footer__bottom a { color: rgba(255,255,255,0.5); }
.footer__bottom a:hover { color: var(--accent-2); }
.footer__bottom span { margin: 0 6px; }
.footer__col h5::after { content: ""; position: absolute; left: 0; bottom: 0; width: 28px; height: 2px; background: var(--accent); }
.footer__col ul li a:hover { color: var(--accent-2); padding-left: 5px; }

/* Footer variant 2 (blogs_index.css, events_index.css, products_index.css) */
.footer__col ul a { font-size: 0.88rem; color: rgba(255,255,255,0.5); transition: color .25s var(--t); }
.footer__col ul a:hover { color: var(--accent-2); }

/* ---------------------------------------------------------------------
   FAMILY B — "Detail" pages with sticky sidebar layout
   blog_author.css, blog_detail.css, event_detail.css, product_detail.css
   --------------------------------------------------------------------- */

/* reset, img, a, ul, .header__inner, .brand*, .nav > ul, .nav li,
   .nav .has-mega:hover > .mega, .menu-toggle*, .site-header.scrolled,
   .topbar__inner, .topbar__left/.topbar__right, .topbar__sep,
   .topbar__social*: identical to the Family A copies above — not
   repeated here to avoid two same-specificity rules for the same
   selector fighting over source order. */
.header__cta:hover { background: #0942b8; transform: translateY(-2px); box-shadow: 0 14px 30px rgba(13,92,245,.35); }

/* .breadcrumb a:hover and .footer__col ul li a:hover genuinely differ
   from Family A's colors — kept page-local (see the "shared.css
   collision" override block appended to each of blog_author.css,
   blog_detail.css, event_detail.css, product_detail.css) instead of
   living here, where they'd silently win over Family A's values on
   every page since they'd share one selector name at equal specificity. */
.breadcrumb span { color: rgba(255,255,255,.85); font-weight: 500; }

/* Buttons: .btn--primary/:hover also genuinely differ from Family A's
   accent-blue — same reasoning, kept page-local in the 4 files above. */
.btn--outline { background: transparent; color: var(--blue); border-color: var(--blue); }
.btn--outline:hover { background: var(--blue-light); }
.btn--white { background: var(--white); color: var(--blue-dark); border-color: var(--white); }
.btn--ghost-white { background: transparent; color: var(--white); border-color: rgba(255,255,255,.4); }
.btn--ghost-white:hover { background: rgba(255,255,255,.12); border-color: var(--white); }
.btn--full { width: 100%; justify-content: center; }

/* Sticky sidebar detail-page layout */
.page-body { background: var(--gray-50); padding: 48px 0 64px; }
.page-body__inner { display: grid; grid-template-columns: var(--sidebar-w) 1fr; gap: 32px; align-items: start; }
/* Capped to the viewport (minus the sticky header offset), with its own scroll, so a sidebar
   taller than the screen never runs off past the bottom edge while pinned in place. */
.sidebar {
  position: sticky;
  top: var(--sticky-top);
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-height: calc(100vh - var(--sticky-top) - 24px);
  overflow-y: auto;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* legacy Edge/IE */
}
.sidebar::-webkit-scrollbar { display: none; } /* Chrome/Safari */
.sidebar-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 20px; box-shadow: var(--shadow-sm); }
.sidebar-card--cta { background: linear-gradient(160deg, #0d1e40 0%, #1a3a6e 100%); border-color: rgba(13,92,245,.3); display: flex; flex-direction: column; gap: 12px; text-align: center; }
.sidebar-cta__icon { width: 40px; height: 40px; border-radius: 50%; background: rgba(13,92,245,.3); display: flex; align-items: center; justify-content: center; font-size: 1rem; color: var(--accent); margin: 0 auto; border: 1px solid rgba(30,167,255,.3); }
.sidebar-cta__heading { font-family: var(--font-heading); font-size: .95rem; font-weight: 700; color: var(--white); }
.sidebar-cta__text { font-size: .78rem; color: rgba(255,255,255,.6); line-height: 1.5; }

/* Sidebar in-page nav (blog_detail.css, event_detail.css, product_detail.css) */
.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar-nav__item i { font-size: 0.4rem; color: var(--gray-300); transition: all var(--transition); flex-shrink: 0; }
.sidebar-nav__item:hover { color: var(--blue); background: var(--blue-light); border-left-color: var(--blue); }
.sidebar-nav__item:hover i { color: var(--blue); }
.sidebar-nav__item.active { color: var(--blue); background: var(--blue-light); border-left-color: var(--blue); font-weight: 600; }
.sidebar-nav__item.active i { color: var(--blue); font-size: 0.5rem; }

/* Section header / spec table / mini-stat (blog_detail.css, event_detail.css, product_detail.css) */
.section-header { display: flex; align-items: center; gap: 14px; margin-bottom: 8px; }
.section-num { font-family: var(--font-display); font-size: 2rem; line-height: 1; color: var(--blue-light); letter-spacing: 1px; min-width: 40px; }
/* .section-title also genuinely differs from Family A's clamp()-sized
   version — kept page-local (see the 4 detail files' override block). */
.section-body:last-child { margin-bottom: 0; }

.mini-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 28px; }
.mini-stat { background: var(--gray-50); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 20px; text-align: center; transition: all var(--transition); }
.mini-stat:hover { border-color: var(--blue); background: var(--blue-light); transform: translateY(-2px); box-shadow: var(--shadow); }
.mini-stat__icon { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(135deg, var(--blue) 0%, var(--accent) 100%); display: flex; align-items: center; justify-content: center; font-size: 0.95rem; color: var(--white); margin: 0 auto 10px; }
.mini-stat__value { font-family: var(--font-display); font-size: 1.8rem; letter-spacing: 1px; color: var(--blue-dark); line-height: 1; margin-bottom: 4px; }

.spec-table-wrapper { border-radius: var(--radius-lg); border: 1px solid var(--gray-200); overflow-x: auto; -webkit-overflow-scrolling: touch; }
.spec-table { width: 100%; min-width: 480px; border-collapse: collapse; font-size: 0.875rem; }
.spec-table thead th { background: var(--blue-dark); color: var(--white); padding: 12px 20px; text-align: left; font-family: var(--font-heading); font-weight: 700; font-size: 0.78rem; letter-spacing: 1px; text-transform: uppercase; }
.spec-table thead th:last-child { border-radius: 0 var(--radius-lg) 0 0; }
.spec-table tbody tr { border-bottom: 1px solid var(--gray-100); transition: background var(--transition); }
.spec-table tbody tr:last-child { border-bottom: none; }
.spec-table tbody tr:not(.spec-group-header):hover { background: var(--blue-light); }
.spec-table tbody td { padding: 11px 20px; color: var(--gray-700); vertical-align: middle; }
.spec-group-header td i { margin-right: 8px; color: var(--accent); }

.tag { display: inline-flex; align-items: center; padding: 4px 12px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.18); border-radius: 20px; font-size: 0.75rem; font-family: var(--font-heading); font-weight: 600; letter-spacing: 0.5px; color: rgba(255,255,255,.85); transition: all var(--transition); }
.tag:hover { background: rgba(13,92,245,.4); border-color: var(--accent); color: var(--white); }

/* CTA section (blog_author.css, blog_detail.css, event_detail.css, product_detail.css) */
.cta-section { position: relative; padding: 80px 0; overflow: hidden; }
.cta-section__bg { position: absolute; inset: 0; background: linear-gradient(135deg, var(--blue-dark) 0%, var(--blue-mid) 50%, #0d2a55 100%); }
.cta-section__inner { position: relative; z-index: 2; text-align: center; }
.cta-section__badge { display: inline-flex; align-items: center; gap: 6px; padding: 5px 14px; background: rgba(30,167,255,.15); border: 1px solid rgba(30,167,255,.3); border-radius: 20px; font-size: .72rem; font-family: var(--font-heading); font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--accent); margin-bottom: 20px; }
.cta-section__title { font-family: var(--font-display); font-size: clamp(2rem,4vw,3rem); letter-spacing: 1px; color: var(--white); margin-bottom: 16px; line-height: 1.1; }
.cta-section__desc { font-size: .95rem; color: rgba(255,255,255,.85); max-width: 560px; margin: 0 auto 32px; line-height: 1.7; }
.cta-section__actions { display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; margin-bottom: 48px; }
.cta-section__stats { display: flex; justify-content: center; gap: 40px; flex-wrap: wrap; }
.cta-stat { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.cta-stat__value { font-family: var(--font-display); font-size: 1.8rem; letter-spacing: 2px; color: var(--white); line-height: 1; }
.cta-stat__label { font-size: .72rem; font-family: var(--font-heading); font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: rgba(255,255,255,.5); }

/* Footer */
.footer__grid { display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 40px; padding-bottom: 48px; }
.footer__brand { flex: 0 1 240px; min-width: 200px; }
.footer__col { flex: 1 1 160px; min-width: 140px; }
@media (max-width: 1024px) {
  .footer__grid { flex-wrap: wrap; gap: 40px; }
  .footer__brand { flex: 1 1 100%; }
  .footer__col { flex: 1 1 calc(50% - 20px); min-width: 200px; }
}
@media (max-width: 640px) {
  .footer__grid { flex-direction: column; }
  .footer__brand, .footer__col { flex: 1 1 auto; width: 100%; min-width: 0; }
}
.footer__brand p { font-size: .85rem; color: rgba(255,255,255,.5); line-height: 1.7; margin: 20px 0; }
.footer__social { display: flex; gap: 8px; }
.footer__social a { width: 34px; height: 34px; border-radius: 50%; background: rgba(255,255,255,.08); display: flex; align-items: center; justify-content: center; font-size: .75rem; color: rgba(255,255,255,.5); transition: all var(--transition); }
.footer__social a:hover { background: var(--blue); color: var(--white); transform: translateY(-2px); }
/* color matches the listing pages' (Family A) .footer__col h5 for cross-page consistency —
   the detail-family static references specify a dim rgba(255,255,255,.4) here, but that reads
   as washed-out next to the listing pages' bold white, so this intentionally diverges from
   the per-page reference to keep the header/nav/footer chrome visually consistent site-wide. */
.footer__col h5 { font-family: var(--font-heading); font-size: .72rem; font-weight: 700; letter-spacing: 2.5px; text-transform: uppercase; color: #ffffff; margin-bottom: 16px; }
.footer__col ul { display: flex; flex-direction: column; gap: 8px; }
.footer__col ul li a { font-size: .85rem; color: rgba(255,255,255,.55); transition: color var(--transition); }
/* .footer__col ul li a:hover also genuinely differs from Family A's
   accent-2 + padding-left hover effect — kept page-local. */
.footer__contact p { font-size: .83rem; color: rgba(255,255,255,.55); line-height: 1.6; margin-bottom: 12px; }
.footer__contact a { display: flex; align-items: center; gap: 10px; font-size: .83rem; color: rgba(255,255,255,.55); margin-bottom: 10px; transition: color var(--transition); }
.footer__contact a i { color: var(--accent); flex-shrink: 0; width: 14px; }
.footer__contact a:hover { color: var(--white); }
.footer__bottom { padding: 20px 0; border-top: 1px solid rgba(255,255,255,.08); }
.footer__bottom-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
.footer__bottom-inner div { display: flex; gap: 20px; }
.footer__bottom-inner p { font-size: .8rem; color: rgba(255,255,255,.35); }
.footer__bottom-inner a { font-size: .8rem; color: rgba(255,255,255,.35); transition: color var(--transition); }
.footer__bottom-inner a:hover { color: var(--white); }

/* font-size/border/cursor/visibility left page-local: Family A's
   back-to-top is an <a> hidden with opacity/transform only (no
   visibility toggle, so a leaked `visibility: hidden` here would never
   get reset back to visible on those pages); Family B's is a <button>
   that does use a visibility toggle (`.back-to-top.visible`) and needs
   the border/cursor reset — see the override block appended to each of
   the 4 detail-page files. */
.back-to-top { position: fixed; bottom: 28px; right: 28px; width: 44px; height: 44px; border-radius: 50%; background: var(--blue); color: var(--white); display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 16px rgba(13,92,245,.4); opacity: 0; transform: translateY(12px); transition: all var(--transition); z-index: 500; }
.back-to-top.visible { opacity: 1; visibility: visible; transform: translateY(0); }

/* =================== HERO IMAGE CAROUSEL ===================
   Shared by every `.product-hero__carousel` consumer (products/show_sections/_hero.html.erb,
   events/show.html.erb, ...) so the carousel looks and sizes identically wherever it's embedded,
   instead of each page keeping its own near-duplicate copy. Loaded on every page via
   layouts/application.html.erb's "pages/shared" stylesheet_link_tag — page-specific CSS files
   should not redeclare these selectors. */
.product-hero__carousel { flex-shrink: 0; width: 380px; align-self: center; }
.hero-carousel { position: relative; border-radius: 20px; overflow: hidden; box-shadow: 0 24px 64px rgba(0,0,0,.45); background: #ffffff; }
.hero-carousel__track { display: flex; transition: transform .5s cubic-bezier(.65,.05,.36,1); }
.hero-carousel__slide { min-width: 100%; }
.hero-carousel__slide .slide-visual__image { width: 100%; height: 100%; aspect-ratio: 4/3; object-fit: contain; object-position: center center; display: block; }
.product-hero__carousel--featured .hero-carousel__slide .slide-visual__image { box-sizing: border-box; padding: 16px; }
/* .featured__image: the products hero's single always-shown image (see
   products/show_sections/_hero.html.erb) — zoomed to fill the card edge-to-edge
   (object-fit: cover) instead of the letterboxed/padded .slide-visual__image look
   used by the multi-slide carousel and events/show.html.erb's featured fallback. */
.hero-carousel__slide .featured__image { width: 100%; height: 100%; aspect-ratio: 4/3; object-fit: contain; object-position: center center; display: block; box-sizing: border-box; padding: 16px; }
.slide-visual { aspect-ratio: 4/3; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; position: relative; overflow: hidden; }
.slide-visual--1 { background: linear-gradient(135deg, #071441 0%, #0050CC 60%, #0088EE 100%); }
.slide-visual--2 { background: linear-gradient(135deg, #061233 0%, #003399 55%, #0066CC 100%); }
.slide-visual--3 { background: linear-gradient(135deg, #082055 0%, #0044BB 50%, #00CCEF 100%); }
.slide-visual--4 { background: linear-gradient(135deg, #051025 0%, #00389A 55%, #2EE090 100%); }
.slide-visual__icon { width: 80px; height: 80px; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2); border-radius: 18px; display: flex; align-items: center; justify-content: center; font-size: 2.2rem; color: #ffffff; backdrop-filter: blur(6px); }
.slide-visual__label { font-family: 'Archivo', sans-serif; font-weight: 700; font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255,255,255,.75); text-align: center; padding: 0 24px; }
.carousel-btn { position: absolute; top: 50%; transform: translateY(-50%); width: 36px; height: 36px; border: 1px solid rgba(0,0,0,.08); border-radius: 50%; background: #ffffff; box-shadow: 0 2px 10px rgba(0,0,0,.25); color: #0B1220; font-size: 0.75rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background .25s; z-index: 2; }
.carousel-btn:hover { background: #f1f3f6; }
.carousel-btn--prev { left: 12px; }
.carousel-btn--next { right: 12px; }
.hero-carousel__dots { position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%); display: flex; gap: 7px; z-index: 2; }
.carousel-dot { width: 8px; height: 8px; border-radius: 50%; border: none; background: rgba(255,255,255,.35); cursor: pointer; padding: 0; transition: all .25s; }
.carousel-dot.active { background: #ffffff; width: 22px; border-radius: 4px; }

/* Responsive behavior for .product-hero__carousel stays page-local (product_detail.css /
   event_detail.css) — the two pages hide/resize it at different breakpoints on purpose. */
/* .reveal.visible: identical to the Family A copy above. */
