/**
 * Jarvis theme overrides — DXPR-style look via Bootstrap 5 CSS custom properties.
 * ponytail: theme at the variable level; add a SCSS pipeline only if this can't reach it.
 */
:root {
  --bs-primary: #2d6cdf;
  --bs-primary-rgb: 45, 108, 223;
  --bs-secondary: #1b2a4a;
  --bs-body-font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --bs-body-color: #1b2130;
  --bs-border-radius: 0.65rem;
  --bs-border-radius-lg: 1rem;
  --jarvis-section-gap: 4rem;
}

body {
  -webkit-font-smoothing: antialiased;
}

/* Responsive media floor. Bootstrap 5 has no global rule for this — its reboot
   only sets `img,svg{vertical-align:middle}` and responsiveness is opt-in via
   .img-fluid. Jarvis SDCs opt in themselves (image.twig uses img-fluid w-100,
   card.css sets width:100%), so anything rendered OUTSIDE a component —
   default field templates on a non-Canvas content type, CKEditor body content,
   pasted tables and code blocks — keeps its native size and overflows the
   viewport (a 2000px hero pushed the whole page sideways).
   Element selectors (0,0,1) so every existing class rule still wins:
   .jarvis-image--match-height's height:100% and Bootstrap's .h-100 are unaffected. */
img, svg, video, iframe, table, pre {
  max-width: 100%;
}
img, video {
  height: auto;
}

/* Blockquotes. Bootstrap's reboot only strips the default margin and leaves the
   rest to an opt-in .blockquote class, so a blockquote typed in CKEditor came
   out as plain unindented text on the rendered page — while css/ckeditor5.css
   HAS styled it inside the editor since day one. WYSIWYG that only holds while
   you are editing is worse than no styling, so these values deliberately mirror
   that rule; change the two together.
   Bare element selector (0,0,1) so Bootstrap's .blockquote class, and any
   component that styles its own quotes, still win. */
blockquote {
  margin: 1.5rem 0;
  padding: 0.5rem 0 0.5rem 1.25rem;
  border-inline-start: 4px solid var(--bs-primary, #2d6cdf);
  font-style: italic;
}
/* The padding already sets the bottom gap, so drop the trailing paragraph
   margin that would otherwise leave the rule overhanging the text. */
blockquote > :last-child {
  margin-bottom: 0;
}

/* Page title bold by default — scoped to beat Bootstrap's heading weight. */
.jarvis-page-title h1,
.jarvis-page-title .page-title {
  font-weight: 700;
}

.btn-primary {
  --bs-btn-bg: var(--bs-primary);
  --bs-btn-border-color: var(--bs-primary);
  --bs-btn-hover-bg: #245ac0;
  --bs-btn-hover-border-color: #245ac0;
  --bs-btn-padding-x: 1.6rem;
  --bs-btn-padding-y: 0.7rem;
  font-weight: 600;
}

/* Jarvis spacing utilities — exact px, driven by the padding/margin SDC props.
   Bootstrap's rem scale can't hit 10/20/30px, so these are bespoke.
   small=10px, medium=20px, large=30px. */
.jp-p-all-small { padding: 10px; }
.jp-p-all-medium { padding: 20px; }
.jp-p-all-large { padding: 30px; }
.jp-p-top-small { padding-top: 10px; }
.jp-p-top-medium { padding-top: 20px; }
.jp-p-top-large { padding-top: 30px; }
.jp-p-bottom-small { padding-bottom: 10px; }
.jp-p-bottom-medium { padding-bottom: 20px; }
.jp-p-bottom-large { padding-bottom: 30px; }
.jp-p-left-small { padding-left: 10px; }
.jp-p-left-medium { padding-left: 20px; }
.jp-p-left-large { padding-left: 30px; }
.jp-p-right-small { padding-right: 10px; }
.jp-p-right-medium { padding-right: 20px; }
.jp-p-right-large { padding-right: 30px; }

.jp-m-all-small { margin: 10px; }
.jp-m-all-medium { margin: 20px; }
.jp-m-all-large { margin: 30px; }
.jp-m-top-small { margin-top: 10px; }
.jp-m-top-medium { margin-top: 20px; }
.jp-m-top-large { margin-top: 30px; }
.jp-m-bottom-small { margin-bottom: 10px; }
.jp-m-bottom-medium { margin-bottom: 20px; }
.jp-m-bottom-large { margin-bottom: 30px; }
.jp-m-left-small { margin-left: 10px; }
.jp-m-left-medium { margin-left: 20px; }
.jp-m-left-large { margin-left: 30px; }
.jp-m-right-small { margin-right: 10px; }
.jp-m-right-medium { margin-right: 20px; }
.jp-m-right-large { margin-right: 30px; }

/* Vertical padding button: 30px top + bottom. */
.jp-vpad { padding-top: 30px; padding-bottom: 30px; }

/* No-padding toggle: overrides jp-vpad's top/bottom so rows can touch
   vertically. !important because it must beat jp-vpad above. */
.jp-nopad { padding-top: 0 !important; padding-bottom: 0 !important; }

/* Site logo: cap at 400px, pin left. Same rule whether branding sits in the
   header region or the primary-menu (nav) region. */
.jarvis-header [id*="branding"],
.jarvis-primary-menu [id*="branding"] { text-align: left; }
.jarvis-header [id*="branding"] img,
.jarvis-primary-menu [id*="branding"] img { width: 400px; max-width: 100%; height: auto; }

/* Canvas renders the primary-menu blocks with random UUID ids, so the Twig
   split by block id never matches; js/nav-branding.js moves the logo link out
   of the offcanvas drawer into .jarvis-branding-wrap so it stays visible on
   mobile (the drawer is hidden until the hamburger is tapped). */
/* Break the nav row out of the centered .container so it spans the viewport;
   100px left pad pins the logo near the browser's left edge — desktop only,
   on mobile it would eat a quarter of the screen from the logo/hamburger row. */
.jarvis-primary-menu { max-width: none; }
@media (min-width: 992px) {
  .jarvis-primary-menu { padding-left: 100px; }
}
/* Logo left (capped 400px, shrinks on narrow screens), menu 50px to its right. */
.jarvis-branding-wrap { min-width: 0; }
.jarvis-branding-wrap img { width: 400px; max-width: 100%; height: auto; }
.jarvis-primary-menu .offcanvas-body > div { display: flex; align-items: center; }
.jarvis-primary-menu .offcanvas-body nav { margin-left: 50px; }

/* Full-width columns: kill container-fluid gutter, row negative margins, AND
   the Bootstrap col padding so the section reaches the screen edge. Without the
   last rule the col's --bs-gutter-x padding leaves a white strip on each side
   (shows as left padding on the hero). Trade-off: full-width multi-column
   sections lose their inter-column gutter — use the gap/padding props for that.
   ponytail: single-column full-bleed is the common case; revisit if multi-col
   full-width needs a between-columns gap. */
.jarvis-columns .container-fluid { padding-left: 0; padding-right: 0; }
.jarvis-columns .container-fluid > .row { margin-left: 0; margin-right: 0; }
.jarvis-columns .container-fluid > .row > [class*="col"] { padding-left: 0; padding-right: 0; }

/* Bootstrap's vertical gutter puts margin-top:calc(-1 * var(--bs-gutter-y)) on
   .row and a matching POSITIVE margin-top on every col. 5.3 uses margin there,
   not padding — zeroing padding-top was a no-op, so every g-4 row kept 1.5rem
   of dead space above it and rows never touched no matter what the padding and
   margin props said. The negative margin also escapes .jarvis-columns' padding
   box, pulling the grid up so the wrapper's vertical padding AND bottom margin
   read as ignored (sections have no .row, so they were fine). Zero both sides
   and let row-gap carry the spacing: same gap when columns wrap on mobile, no
   negative margin, and gap: None (g-0) collapses to a true zero. */
.jarvis-columns .row { margin-top: 0; row-gap: var(--bs-gutter-y); }
.jarvis-columns .row > * { margin-top: 0; }

/* 3 Columns (custom widths): each col carries its own share as --jarvis-col-w,
   already normalised to sum to 100% in custom-columns.twig. Gutters are col
   padding, so the percentages add up exactly. Stacked (col-12) below lg. */
@media (min-width: 992px) {
  .jarvis-col-pct { flex: 0 0 var(--jarvis-col-w); max-width: var(--jarvis-col-w); }
}

/* Primary menu. templates/menu--main.html.twig emits Bootstrap navbar markup,
   so the dropdown panel and its open/close, keyboard navigation, Escape and
   click-outside dismissal all come from the already-loaded bundle. What is left
   here is only the theme's typography and spacing on top of .nav-link /
   .dropdown-item. Replaces the former pure-CSS hover fly-outs and the
   hand-rolled js/menu-touch.js. */
.jarvis-primary-menu nav ul { list-style: none; margin: 0; padding: 0; }

/* Top level = horizontal bar. */
/* flex-direction is explicit so it pairs visibly with the column override in
   the mobile block below, and so no Bootstrap list class can flip it. */
.jarvis-primary-menu nav > ul { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; }

.jarvis-primary-menu li { position: relative; }
/* <nolink> items render as <span>, not <a> — style both identically so they sit
   on the bar like real links. li > span matches only a span that IS the item:
   spans inside a link (extlink's .extlink-nobreak) or inside the split toggle
   (.visually-hidden) stay inline. The split toggle is included so it matches
   its sibling link. */
.jarvis-primary-menu nav a,
.jarvis-primary-menu nav li > span,
.jarvis-primary-menu nav .jarvis-menu__toggle {
  display: block;
  padding: 0.75rem 1rem;
  color: var(--bs-body-color);
  text-decoration: none;
  white-space: nowrap;
  font-weight: 600;
}
.jarvis-primary-menu nav a:hover,
.jarvis-primary-menu nav a:focus,
.jarvis-primary-menu nav .jarvis-menu__toggle:hover,
.jarvis-primary-menu nav .jarvis-menu__toggle:focus { color: var(--bs-primary); }

/* Split toggle sits tight against the parent link it belongs to. Bootstrap's
   .dropdown-toggle draws the caret, so there is no ::after of our own. */
.jarvis-primary-menu nav .jarvis-menu__toggle {
  border: 0;
  background: transparent;
  cursor: pointer;
}
.jarvis-primary-menu nav .dropdown-toggle-split { padding-inline: 0.25rem 0.75rem; }
.jarvis-primary-menu nav .nav-item.dropdown { display: flex; align-items: center; }
/* The link half of a split parent must not double the gap before the caret. */
.jarvis-primary-menu nav .nav-item.dropdown > a { padding-right: 0.25rem; }

/* Dropdown panel: square, unpadded edges so items sit flush, with the theme's
   shadow; Bootstrap positions and toggles it. */
.jarvis-primary-menu .dropdown-menu {
  min-width: 220px;
  padding: 0;
  border: 0;
  border-radius: 0;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  /* Current-page item: white on the theme secondary instead of Bootstrap's
     stock blue. */
  --bs-dropdown-link-active-bg: var(--bs-secondary);
  --bs-dropdown-link-active-color: #fff;
}
.jarvis-primary-menu .dropdown-item { font-weight: 500; white-space: normal; }
/* The nav a:hover/:focus primary colour above outranks Bootstrap's
   .dropdown-item.active and :active (pressed), which put primary text on the
   active background. These selectors outrank it in every hover/focus state. */
.jarvis-primary-menu nav .dropdown-item.active,
.jarvis-primary-menu nav .dropdown-item:active { color: var(--bs-dropdown-link-active-color); }

/* Hamburger: 44px touch target. Visibility handled by .d-lg-none in markup. */
.jarvis-menu-toggle {
  display: inline-flex;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--bs-border-color, #ccc);
  border-radius: var(--bs-border-radius);
  background: transparent;
  cursor: pointer;
}
.jarvis-menu-toggle__bar,
.jarvis-menu-toggle__bar::before,
.jarvis-menu-toggle__bar::after {
  content: "";
  display: block;
  width: 22px;
  height: 2px;
  background: var(--bs-body-color);
}
.jarvis-menu-toggle__bar { position: relative; }
.jarvis-menu-toggle__bar::before { position: absolute; top: -7px; left: 0; }
.jarvis-menu-toggle__bar::after { position: absolute; top: 7px; left: 0; }

/* Desktop (>=992px): menu sits left, 100px after the logo; the responsive
   offcanvas renders inline (bootstrap resets its panel styles). */
@media (min-width: 992px) {
  /* Logo now lives inside .jarvis-primary-nav, so no extra left offset here —
     the region's 100px pad positions the logo; the 50px logo→menu gap is on nav. */
  .jarvis-primary-nav { margin-left: 0; }
  .jarvis-primary-menu .offcanvas-body { padding: 0; }
}

/* Mobile (<992px): menu lives in the slide-out offcanvas drawer; stack it and
   keep submenus static + always open so every item is tappable. */
@media (max-width: 991.98px) {
  .jarvis-primary-menu nav > ul { flex-direction: column; align-items: stretch; }
  /* Force Bootstrap's panel open and inline: inside the drawer there is nowhere
     to pop to, and collapsing it would hide items behind a second tap. */
  .jarvis-primary-menu .dropdown-menu {
    display: block;
    position: static;
    min-width: 0;
    padding: 0 0 0 1rem;
    background: transparent;
    box-shadow: none;
    transform: none;
  }
  /* Panel is always visible here, so the toggle is redundant — and announcing a
     collapsed state that is not real would be a lie to screen readers. */
  .jarvis-primary-menu nav .jarvis-menu__toggle { display: none; }
  .jarvis-primary-menu nav .nav-item.dropdown { display: block; }
  .jarvis-primary-menu nav .nav-item.dropdown > a { padding-right: 1rem; }
}

/* Theme-settings colors: regions consume the vars set by hook_preprocess_html.
   An unset var makes the property invalid -> ignored, so the default look holds.
   Text rules also cover headings inside the region (specificity 0,0,1,1) so a
   region's own text color wins over the global heading color. */
/* Title bg/text also target the page-title block by id, since the block can be
   placed in any region (here it lives in `highlighted`, not `page_title`).
   ponytail: id couples to the jarvis_page_title block machine name; rename the
   block -> update this selector. */
/* 100px left pad aligns the title with the logo — desktop only. */
.jarvis-page-title { padding: 20px; }
@media (min-width: 992px) {
  .jarvis-page-title { padding-left: 100px; }
}
.jarvis-page-title,
#block-jarvis-page-title { background: var(--jarvis-title-bg); }
.jarvis-page-title,
.jarvis-page-title :is(h1, h2, h3, h4, h5, h6),
#block-jarvis-page-title,
#block-jarvis-page-title :is(h1, h2, h3, h4, h5, h6) { color: var(--jarvis-title-color); }

.jarvis-footer { background: var(--jarvis-footer-bg); margin-top: 50px; }
.jarvis-footer,
.jarvis-footer :is(h1, h2, h3, h4, h5, h6) { color: var(--jarvis-footer-color); }
/* Links follow the footer text color (not Bootstrap's link blue) so they stay
   legible on a dark footer bg. Falls back to the inherited region color when the
   footer text color isn't set. ADA contrast still depends on picking a light
   text color for a dark background. */
.jarvis-footer a,
.jarvis-footer a:hover,
.jarvis-footer a:focus { color: var(--jarvis-footer-color, inherit); }

.jarvis-header { background: var(--jarvis-header-bg); }
.jarvis-header,
.jarvis-header :is(h1, h2, h3, h4, h5, h6) { color: var(--jarvis-header-color); }
.jarvis-header a { color: var(--jarvis-header-link-color); }

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

/* Font sizes from theme settings. The --jarvis-fs-* variables are emitted by
   jarvis_preprocess_html (desktop on :root, mobile overrides under 768px).
   Base is px on <html> so the rem-based headings scale with it. The .h*
   utility classes are included so Bootstrap's responsive calc() sizes don't
   reassert themselves. */
html { font-size: var(--jarvis-fs-base, 100%); }
h1, .h1 { font-size: var(--jarvis-fs-h1, 2.5rem); }
h2, .h2 { font-size: var(--jarvis-fs-h2, 2rem); }
h3, .h3 { font-size: var(--jarvis-fs-h3, 1.75rem); }
h4, .h4 { font-size: var(--jarvis-fs-h4, 1.5rem); }
h5, .h5 { font-size: var(--jarvis-fs-h5, 1.25rem); }
h6, .h6 { font-size: var(--jarvis-fs-h6, 1rem); }

/* Canvas/editor: h2-h4 bold (Bootstrap defaults them to 500). */
h2, .h2, h3, .h3, h4, .h4 { font-weight: 700; }

/* Media-manager document table (core file_table formatter).
   Icon per file type + 20px gap between file name and size cell. */
:root {
  --jarvis-file-generic: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M6%202h8l4%204v16H6z%27%20fill%3D%27%23fff%27%20stroke%3D%27%23757575%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Cpath%20d%3D%27M14%202v4h4%27%20fill%3D%27none%27%20stroke%3D%27%23757575%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3C%2Fsvg%3E");
  --jarvis-file-pdf: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M6%202h8l4%204v16H6z%27%20fill%3D%27%23fff%27%20stroke%3D%27%23E53935%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Cpath%20d%3D%27M14%202v4h4%27%20fill%3D%27none%27%20stroke%3D%27%23E53935%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Crect%20x%3D%275%27%20y%3D%2712.4%27%20width%3D%2714%27%20height%3D%277%27%20rx%3D%271.2%27%20fill%3D%27%23E53935%27%2F%3E%3Ctext%20x%3D%2712%27%20y%3D%2718.1%27%20font-family%3D%27Arial%2CHelvetica%2Csans-serif%27%20font-size%3D%275%27%20font-weight%3D%27700%27%20fill%3D%27%23fff%27%20text-anchor%3D%27middle%27%3EPDF%3C%2Ftext%3E%3C%2Fsvg%3E");
  --jarvis-file-doc: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M6%202h8l4%204v16H6z%27%20fill%3D%27%23fff%27%20stroke%3D%27%231E88E5%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Cpath%20d%3D%27M14%202v4h4%27%20fill%3D%27none%27%20stroke%3D%27%231E88E5%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Crect%20x%3D%275%27%20y%3D%2712.4%27%20width%3D%2714%27%20height%3D%277%27%20rx%3D%271.2%27%20fill%3D%27%231E88E5%27%2F%3E%3Ctext%20x%3D%2712%27%20y%3D%2718.1%27%20font-family%3D%27Arial%2CHelvetica%2Csans-serif%27%20font-size%3D%275%27%20font-weight%3D%27700%27%20fill%3D%27%23fff%27%20text-anchor%3D%27middle%27%3EDOC%3C%2Ftext%3E%3C%2Fsvg%3E");
  --jarvis-file-xls: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M6%202h8l4%204v16H6z%27%20fill%3D%27%23fff%27%20stroke%3D%27%2343A047%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Cpath%20d%3D%27M14%202v4h4%27%20fill%3D%27none%27%20stroke%3D%27%2343A047%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Crect%20x%3D%275%27%20y%3D%2712.4%27%20width%3D%2714%27%20height%3D%277%27%20rx%3D%271.2%27%20fill%3D%27%2343A047%27%2F%3E%3Ctext%20x%3D%2712%27%20y%3D%2718.1%27%20font-family%3D%27Arial%2CHelvetica%2Csans-serif%27%20font-size%3D%275%27%20font-weight%3D%27700%27%20fill%3D%27%23fff%27%20text-anchor%3D%27middle%27%3EXLS%3C%2Ftext%3E%3C%2Fsvg%3E");
  --jarvis-file-ppt: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%3E%3Cpath%20d%3D%27M6%202h8l4%204v16H6z%27%20fill%3D%27%23fff%27%20stroke%3D%27%23FB8C00%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Cpath%20d%3D%27M14%202v4h4%27%20fill%3D%27none%27%20stroke%3D%27%23FB8C00%27%20stroke-width%3D%271.6%27%20stroke-linejoin%3D%27round%27%2F%3E%3Crect%20x%3D%275%27%20y%3D%2712.4%27%20width%3D%2714%27%20height%3D%277%27%20rx%3D%271.2%27%20fill%3D%27%23FB8C00%27%2F%3E%3Ctext%20x%3D%2712%27%20y%3D%2718.1%27%20font-family%3D%27Arial%2CHelvetica%2Csans-serif%27%20font-size%3D%275%27%20font-weight%3D%27700%27%20fill%3D%27%23fff%27%20text-anchor%3D%27middle%27%3EPPT%3C%2Ftext%3E%3C%2Fsvg%3E");
}
span.file {
  display: inline-flex;
  align-items: center;
}
span.file::before {
  content: "";
  flex: 0 0 auto;
  width: 1.15em;
  height: 1.15em;
  margin-right: 0.4em;
  background: var(--jarvis-file-generic) center / contain no-repeat;
}
span.file.file--application-pdf::before { background-image: var(--jarvis-file-pdf); }
span.file.file--x-office-document::before { background-image: var(--jarvis-file-doc); }
span.file.file--x-office-spreadsheet::before { background-image: var(--jarvis-file-xls); }
span.file.file--x-office-presentation::before { background-image: var(--jarvis-file-ppt); }
/* 20px gap between the name column and the size column. */
td:has(> span.file) { padding-right: 20px; }

/* oEmbed video: fill container width, native aspect-ratio height.
   Target the iframe directly — CKEditor media embeds render it with no
   .field--name-field-media-oembed-video wrapper and fixed width/height attrs
   (e.g. width="200"). width:100% + aspect-ratio is self-contained. */
.media-oembed-content {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  display: block;
  border: 0;
}

/* Section background colours (1/2/3-column components).
   Text + Bootstrap colour vars are overridden so ANY child component inherits
   ADA-compliant text. Fixed brand backgrounds use hardcoded #000/#fff text;
   the arbitrary Background 1/2 colours use a text colour computed for WCAG AA in
   jarvis_preprocess_html(). */
.jarvis-bg {
  padding-block: 2rem; /* breathing room so text isn't flush to the colour band edge */
}
/* One foreground contract for every surface below. Each variant declares only
   what it IS — its background and its safe text colour as --jarvis-on /
   --jarvis-on-rgb — and this rule wires that into every colour var the theme
   and Bootstrap read. Links follow the text colour unless a surface overrides
   them with --jarvis-link*.

   Custom properties resolve per element, so a nested surface (the card reset at
   the end of this block) re-declares --jarvis-on and wins on its own element
   while still inheriting everything else. */
.jarvis-bg--primary,
.jarvis-bg--secondary,
.jarvis-bg--dark,
.jarvis-bg--light,
.jarvis-bg--bg1,
.jarvis-bg--bg2,
.jarvis-bg--image,
.jarvis-columns .jarvis-person--card,
.jarvis-columns .jarvis-card:not(.jarvis-card--background) {
  color: var(--jarvis-on);
  --bs-body-color: var(--jarvis-on);
  --bs-body-color-rgb: var(--jarvis-on-rgb);
  --bs-heading-color: var(--jarvis-on);
  --jarvis-heading-color: var(--jarvis-on); /* theme headings read this, not --bs-heading-color */
  --bs-emphasis-color: var(--jarvis-on);
  --bs-link-color: var(--jarvis-link, var(--jarvis-on));
  --bs-link-color-rgb: var(--jarvis-link-rgb, var(--jarvis-on-rgb));
  --bs-link-hover-color: var(--jarvis-link-hover, var(--jarvis-on));
}

/* Fixed brand backgrounds: white text, slightly dimmed link hover. */
.jarvis-bg--primary {
  background: var(--bs-primary, #2d6cdf);
  --jarvis-on: #fff;
  --jarvis-on-rgb: 255, 255, 255;
  --jarvis-link-hover: #e6e6e6;
}
.jarvis-bg--secondary {
  background: var(--bs-secondary, #1b2a4a);
  --jarvis-on: #fff;
  --jarvis-on-rgb: 255, 255, 255;
  --jarvis-link-hover: #e6e6e6;
}
.jarvis-bg--dark {
  background: #1a1a1a;
  --jarvis-on: #fff;
  --jarvis-on-rgb: 255, 255, 255;
  --jarvis-link-hover: #e6e6e6;
}
.jarvis-bg--light {
  background: #f5f5f5;
  --jarvis-on: #000;
  --jarvis-on-rgb: 0, 0, 0;
  --jarvis-link-hover: #333333;
}
/* Background 1/2: arbitrary theme-setting colours, so the safe text colour is
   computed per background in jarvis_preprocess_html() rather than hardcoded. */
.jarvis-bg--bg1 {
  background: var(--jarvis-bg-1);
  --jarvis-on: var(--jarvis-bg-1-text);
  --jarvis-on-rgb: var(--jarvis-bg-1-text-rgb);
}
.jarvis-bg--bg2 {
  background: var(--jarvis-bg-2);
  --jarvis-on: var(--jarvis-bg-2-text);
  --jarvis-on-rgb: var(--jarvis-bg-2-text-rgb);
}
/* Media image background: cover the section, darken with an adjustable overlay
   so light text stays ADA-readable regardless of the photo. */
.jarvis-bg--image {
  position: relative;
  background-size: cover;
  background-position: center;
  --jarvis-on: #fff;
  --jarvis-on-rgb: 255, 255, 255;
  --jarvis-link-hover: #e6e6e6;
}
.jarvis-bg--image > .jarvis-bg__overlay {
  position: absolute;
  inset: 0;
  background: #000;
  pointer-events: none;
}
/* Light overlay: used when the section's text is dark, so dark text stays
   readable over a bright image (mirror of the default dark overlay). */
.jarvis-bg--image > .jarvis-bg__overlay--light {
  background: #fff;
}
/* Keep the content above the overlay. */
.jarvis-bg--image > .container,
.jarvis-bg--image > .container-fluid {
  position: relative;
  z-index: 1;
}

/* Components with their own (light) background must keep dark text even inside a
   coloured section — otherwise the inherited white text is invisible on them.
   Only the inputs are restated; the shared rule above wires them up. Links go
   brand-coloured here rather than following the text. */
.jarvis-columns .jarvis-person--card,
.jarvis-columns .jarvis-card:not(.jarvis-card--background) {
  --jarvis-on: #1a1a1a;
  --jarvis-on-rgb: 26, 26, 26;
  --jarvis-link: var(--bs-primary);
  --jarvis-link-rgb: var(--bs-primary-rgb);
  --jarvis-link-hover: var(--bs-primary);
}

/* Site-wide: links have no underline. */
a {
  text-decoration: none;
}

/* ADA (WCAG 1.4.1): inside prose, color alone can't mark a link — the colour-
   variable system even forces links to the body colour in coloured sections
   (.jarvis-bg--*, footer), where an un-underlined link is invisible as a link.
   Restore underlines in prose contexts; nav/buttons stay clean. */
.jarvis-text a:not(.btn),
.jarvis-wysiwyg a:not(.btn),
.card-text a:not(.btn),
.jarvis-cta__text a:not(.btn),
.jarvis-footer a:not(.btn) {
  text-decoration: underline;
}

/* Section text-colour override: cascades to every child component (text, wysiwyg,
   etc.) via the colour vars. Components with their own background (person card,
   standard card) reset above under .jarvis-columns, so they are unaffected.
   Manual override — NOT auto-checked for ADA contrast against the section bg. */
.jarvis-text-color--primary {
  color: var(--bs-primary);
  --bs-body-color: var(--bs-primary);
  --bs-heading-color: var(--bs-primary);
  --jarvis-heading-color: var(--bs-primary);
  --bs-emphasis-color: var(--bs-primary);
  --bs-link-color: var(--bs-primary);
  --bs-link-color-rgb: var(--bs-primary-rgb);
  --bs-link-hover-color: var(--bs-primary);
}
.jarvis-text-color--secondary {
  color: var(--bs-secondary);
  --bs-body-color: var(--bs-secondary);
  --bs-heading-color: var(--bs-secondary);
  --jarvis-heading-color: var(--bs-secondary);
  --bs-emphasis-color: var(--bs-secondary);
  --bs-link-color: var(--bs-secondary);
  --bs-link-color-rgb: var(--bs-secondary-rgb);
  --bs-link-hover-color: var(--bs-secondary);
}
.jarvis-text-color--black {
  color: #000;
  --bs-body-color: #000;
  --bs-heading-color: #000;
  --jarvis-heading-color: #000;
  --bs-emphasis-color: #000;
  --bs-link-color: #000;
  --bs-link-color-rgb: 0, 0, 0;
  --bs-link-hover-color: #000;
}
.jarvis-text-color--white {
  color: #fff;
  --bs-body-color: #fff;
  --bs-heading-color: #fff;
  --jarvis-heading-color: #fff;
  --bs-emphasis-color: #fff;
  --bs-link-color: #fff;
  --bs-link-color-rgb: 255, 255, 255;
  --bs-link-hover-color: #fff;
}

/* ADA matrix for the stat number_color prop (base classes in stat.css).
   Deny-by-default on every coloured/auto/image background: the pick falls
   back to the section's contrast-safe text colour. The allowlist below
   re-enables combinations that pass WCAG for 3rem large text with the
   default palette — mirrors the columns text_color matrix philosophy.
   bg1/bg2/image stay deny-only (user/image colours are unknowable here). */
.jarvis-bg--primary .jarvis-stat__number,
.jarvis-bg--secondary .jarvis-stat__number,
.jarvis-bg--dark .jarvis-stat__number,
.jarvis-bg--bg1 .jarvis-stat__number,
.jarvis-bg--bg2 .jarvis-stat__number,
.jarvis-bg--image .jarvis-stat__number {
  color: inherit;
}
/* Allowlist: near-white passes on primary, secondary and dark sections. */
.jarvis-bg--primary .jarvis-stat__number--light,
.jarvis-bg--secondary .jarvis-stat__number--light,
.jarvis-bg--dark .jarvis-stat__number--light {
  color: #f8f9fa;
}

/* ADA matrix for the Text component's own colour prop (.jarvis-text--*,
   base classes in text.css). The columns' text_color override is matrix-
   gated in Twig, but a child Text component's colour pick bypassed it —
   primary text inside a primary section rendered invisible. Same deny-by-
   default approach as the stat number: unsafe picks fall back to the
   section's contrast-safe text colour (body small text, so the allowlist
   mirrors the columns AA matrix, not the large-text one). Heading vars are
   reset too — the base classes repaint headings via --jarvis-heading-color. */
.jarvis-bg--primary :is(.jarvis-text--primary, .jarvis-text--secondary, .jarvis-text--black, .jarvis-text--white),
.jarvis-bg--secondary :is(.jarvis-text--primary, .jarvis-text--secondary, .jarvis-text--black, .jarvis-text--white),
.jarvis-bg--dark :is(.jarvis-text--primary, .jarvis-text--secondary, .jarvis-text--black, .jarvis-text--white),
.jarvis-bg--bg1 :is(.jarvis-text--primary, .jarvis-text--secondary, .jarvis-text--black, .jarvis-text--white),
.jarvis-bg--bg2 :is(.jarvis-text--primary, .jarvis-text--secondary, .jarvis-text--black, .jarvis-text--white),
.jarvis-bg--image :is(.jarvis-text--primary, .jarvis-text--secondary, .jarvis-text--black, .jarvis-text--white),
.jarvis-bg--light :is(.jarvis-text--primary, .jarvis-text--white) {
  color: inherit;
  --jarvis-heading-color: inherit;
  --bs-heading-color: inherit;
}
/* Allowlist: white passes AA on primary/secondary/dark sections. */
.jarvis-bg--primary .jarvis-text--white,
.jarvis-bg--secondary .jarvis-text--white,
.jarvis-bg--dark .jarvis-text--white {
  color: #fff;
  --jarvis-heading-color: #fff;
  --bs-heading-color: #fff;
}

/* ADA: the person name's .text-primary (Bootstrap, !important) goes invisible
   when the surrounding section is painted primary — ride the section's
   contrast-safe text colour on coloured/auto/image backgrounds instead. */
.jarvis-bg--primary .jarvis-person__name,
.jarvis-bg--secondary .jarvis-person__name,
.jarvis-bg--dark .jarvis-person__name,
.jarvis-bg--bg1 .jarvis-person__name,
.jarvis-bg--bg2 .jarvis-person__name,
.jarvis-bg--image .jarvis-person__name {
  color: inherit !important;
}

/* ADA (WCAG 2.4.1): core's skip link ships classes `visually-hidden focusable`
   (verified in D11 markup — no .skip-link class), but the un-hide-on-focus
   rules live in Drupal's system.base.css, which this base-theme-false theme
   doesn't load — Bootstrap's .visually-hidden (all !important) would keep the
   link clipped even while focused. Reveal it explicitly; !important is
   required to beat Bootstrap's clip rules. */
.visually-hidden.focusable:focus {
  position: fixed !important;
  top: 0;
  left: 0;
  z-index: 2000;
  width: auto !important;
  height: auto !important;
  margin: 0 !important;
  padding: 0.75rem 1.25rem !important;
  overflow: visible !important;
  clip: auto !important;
  clip-path: none !important;
  white-space: normal !important;
  background: #1b2a4a;
  color: #fff;
  text-decoration: underline;
}

/* ADA (WCAG 2.4.7 / 2.4.11): explicit, high-visibility focus indicator.
   currentColor tracks each section's computed (contrast-safe) text colour, so
   the ring stays visible on dark heroes and coloured bands alike. */
:is(a, button, [tabindex], input, select, textarea, summary):focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* ADA (WCAG 2.3.3): honour the user's reduced-motion preference — kills the
   menu/card transitions and CSS animations; js guards (stat count-up) check
   the same media query. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Blog block view: the "Read More" row reads smaller than the teaser above it.
   80% of inherited size, so it still tracks the theme's base font setting.
   .blog-block is the CSS class set on the view's block display, so this is
   scoped to that view rather than to every views_field-view-node on the site. */
.blog-block .views-field-view-node {
  font-size: 80%;
}
