/* ============================================================
   ARRAY Innovation — site styles
   Dark theme base. Built on Spectrum AI tokens.
   ============================================================ */

* {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
}
body {
  font-family: var(--font-sans);
  background: var(--bg-app);
  color: var(--fg-1);
  margin: 0;
  overflow-x: hidden;
}
::selection {
  background: var(--prism-stop-violet);
  color: white;
}

/* Global scrollbar theming ---------------------------------------------
   Thin navy thumb on a transparent track, so every scrollable surface
   (page, textareas, overflow panels) reads as part of the dark theme
   rather than the OS default. Token-driven — retuning the border tokens
   moves every scrollbar at once. Elements that intentionally hide their
   scrollbar (e.g. .ess-thumbs) override these with more specific rules. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-2) transparent;
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--border-2);
  /* inset via a transparent border so the thumb sits off the edge */
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--border-strong);
  background-clip: padding-box;
}
::-webkit-scrollbar-corner {
  background: transparent;
}

/* layout primitives ---------------------------------------------------- */
/* Single source of truth for the page side gutter. Both container widths
   read it, so the mobile value below adjusts every gutter site-wide at once
   and any future .container inherits it automatically. */
:root {
  --gutter: 32px;
  /* Card internal padding. Standard cards use --card-pad; large feature panels
     use --card-pad-feature; solution panels use --card-pad-sol (slightly
     tighter than the other feature panels). On phones all collapse to the
     gutter so card content lines up with adjacent page/section content. */
  --card-pad: 28px;
  --card-pad-feature: 48px;
  --card-pad-sol: 36px;
}
@media (max-width: 767px) {
  :root {
    --gutter: 20px;
    --card-pad: var(--gutter);
    --card-pad-feature: var(--gutter);
    --card-pad-sol: var(--gutter);
  }
}
@media (min-width: 768px) and (max-width: 1024px) {
  :root {
    --card-pad: var(--gutter);
    --card-pad-feature: var(--gutter);
    --card-pad-sol: var(--gutter);
  }
}

.container {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}
/* Obra ds-eyebrow: 12 / 600 / 0.12em uppercase, fg-3 */
.eyebrow {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-3);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  line-height: 1.33;
}
.eyebrow::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 99px;
  background: var(--prism);
  box-shadow: 0 0 8px
    color-mix(in srgb, var(--prism-stop-violet) 70%, transparent);
}
/* ============================================================
   NAV
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid var(--border-1);
}

.nav::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb, var(--neutral-750) 97%, transparent);
  pointer-events: none;
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--fg-1);
}
.footer .brand {
  display: inline-flex;
  margin-bottom: 16px;
}
.brand-mark {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.brand-mark img {
  height: 100%;
  width: auto;
  object-fit: contain;
  display: block;
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
}
.nav-links a {
  color: var(--fg-2);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 16px;
  border-radius: var(--r-sm);
  transition:
    color 120ms ease,
    background 120ms ease;
}
.nav-links a:hover {
  color: var(--fg-1);
  background: rgba(255, 255, 255, 0.04);
}
.nav-cta {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Dropdown nav items ---------------------------------------- */
.nav-item {
  position: relative;
  display: flex;
  align-items: center;
}
.nav-item > a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--fg-2);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 16px;
  border-radius: var(--r-sm);
  transition:
    color 120ms ease,
    background 120ms ease;
}
.nav-item > a:hover,
.nav-item.is-active > a {
  color: var(--fg-1);
  background: rgba(255, 255, 255, 0.04);
}
.nav-item > a .caret {
  display: inline-flex;
  opacity: 0.55;
  transition: transform 160ms ease;
}
.nav-item > a .caret svg {
  width: 12px;
  height: 12px;
}
.nav-item:hover > a .caret,
.nav-item:focus-within > a .caret {
  transform: rotate(180deg);
}

/* hover bridge so the gap between trigger and panel stays hoverable */
.nav-item::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 12px;
}
.nav-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  min-width: 248px;
  /* Descends from the nav bar, so it shares the nav's navy ground
     (--neutral-750) — just more opaque, since it floats over arbitrary
     page content and must stay legible. Keeps the dropdown on-palette
     instead of the old off-palette warm near-black. */
  background: color-mix(in srgb, var(--neutral-750) 97%, transparent);
  border: 1px solid var(--border-1);
  border-radius: var(--r-lg);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 160ms ease,
    transform 160ms ease,
    visibility 160ms;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.55);
  z-index: 200;
}
.nav-item:hover .nav-dropdown,
.nav-item:focus-within .nav-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.nav-dropdown a {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px;
  border-radius: var(--r-md);
  text-decoration: none;
  transition: background 120ms ease;
}
.nav-dropdown a:hover {
  background: rgba(255, 255, 255, 0.05);
}
.nav-dropdown .dd-title {
  font-size: 13px;
  font-weight: 500;
  color: var(--fg-1);
  letter-spacing: -0.01em;
}
.nav-dropdown .dd-sub {
  font-size: 11px;
  color: var(--fg-3);
  line-height: 1.35;
}

/* hamburger toggle — hidden on desktop */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  background: transparent;
  border: 1px solid var(--border-2);
  color: var(--fg-1);
  cursor: pointer;
  padding: 0;
}
.nav-toggle svg {
  width: 20px;
  height: 20px;
}
.nav-toggle .icon-close {
  display: none !important;
}
.nav.open .nav-toggle .icon-open {
  display: none !important;
}
.nav.open .nav-toggle .icon-close {
  display: inline-flex !important;
}

@media (max-width: 1024px) {
  .nav-toggle {
    display: inline-flex;
  }
  .nav-cta {
    display: none;
  }

  .nav-links {
    position: fixed;
    top: 64px;
    left: 0;
    right: 0;
    bottom: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--bg-app);
    padding: 12px 16px 48px;
    overflow-y: auto;
    z-index: 150;
    border-top: 1px solid var(--border-1);
    display: flex;
    opacity: 0;
    pointer-events: none;
    transform: translateY(-8px);
    transition:
      opacity 200ms ease,
      transform 200ms ease;
  }
  .nav.open .nav-links {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }

  .nav-item {
    flex-direction: column;
    align-items: stretch;
  }
  .nav-item::after {
    display: none;
  }
  .nav-item > a {
    justify-content: space-between;
    padding: 16px 4px;
    font-size: 16px;
    border-bottom: 1px solid var(--border-1);
    border-radius: 0;
    color: var(--fg-1);
  }
  .nav-item > a .caret {
    transform: rotate(-90deg);
    opacity: 0.45;
    transition: transform 200ms ease;
  }
  .nav-item.is-open > a .caret {
    transform: rotate(0deg);
    opacity: 0.7;
  }

  /* kill the desktop :hover rule on touch — opacity/max-height only, no visibility */
  .nav-item:hover .nav-dropdown,
  .nav-item:focus-within .nav-dropdown {
    opacity: 0;
    max-height: 0;
  }

  /* accordion: max-height slide */
  .nav-dropdown {
    position: static !important;
    transform: none !important;
    opacity: 0;
    visibility: visible;
    max-height: 0;
    overflow: hidden;
    box-shadow: none;
    border: none;
    background: transparent;
    min-width: 0;
    padding: 0 4px;
    border-radius: 0;
    transition:
      opacity 200ms ease,
      max-height 250ms ease;
  }
  .nav-item.is-open .nav-dropdown {
    opacity: 1;
    visibility: visible;
    max-height: 400px;
    padding: 8px 4px 16px;
  }
  .nav-dropdown a {
    padding: 12px 8px;
    border-radius: var(--r-sm);
  }
  .nav-dropdown .dd-title {
    font-size: 14px;
  }
  .nav-dropdown .dd-sub {
    font-size: 12px;
    color: var(--fg-3);
  }

  .nav-mobile-cta {
    display: flex;
    margin-top: 24px;
  }
  .nav-mobile-cta .btn {
    width: 100%;
    justify-content: center;
  }
}

/* mobile-only CTA inside the drawer */
.nav-mobile-cta {
  display: none;
}

/* ============================================================
   HOMEPAGE — area highlights + case teaser
   ============================================================ */
.home-highlights {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
/* Stack the "What we do" cards on tablet + mobile; the 3-up row is a
   laptop/desktop-only layout. */
@media (max-width: 1024px) {
  .home-highlights {
    grid-template-columns: 1fr;
  }
}

.hl-card {
  background: var(--surface-card-gradient);
  border: 1px solid var(--border-1);
  border-radius: 24px;
  /* Standard card padding token: 28px desktop/tablet, gutter on phones. */
  padding: var(--card-pad);
  display: flex;
  flex-direction: column;
  position: relative;
  isolation: isolate;
  transition:
    border-color 200ms ease,
    transform 200ms ease;
}
.hl-card:hover {
  border-color: color-mix(in srgb, var(--prism-stop-violet) 40%, transparent);
  transform: translateY(-2px);
}
.hl-eyebrow {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-bottom: 20px;
}
.hl-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--prism-stop-violet) 12%, transparent);
  border: 1px solid
    color-mix(in srgb, var(--prism-stop-violet) 30%, transparent);
  color: var(--fg-1);
  margin-bottom: 20px;
}
.hl-icon svg {
  width: 22px;
  height: 22px;
}
.hl-card h3 {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 12px;
  color: var(--fg-1);
}
.hl-desc {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg-3);
  margin: 0 0 24px;
}
.hl-list {
  list-style: none;
  padding: 0;
  margin: 0 0 28px;
  display: grid;
  gap: 12px;
}
.hl-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  color: var(--fg-2);
  letter-spacing: -0.01em;
}
.hl-list li svg {
  width: 15px;
  height: 15px;
  color: var(--prism-stop-teal);
  flex-shrink: 0;
}
#apart {
  background: var(--bg-hero-navy);
  border-top: 1px solid var(--border-1);
  border-bottom: 1px solid var(--border-1);
}
.apart-inner {
  margin: 0;
}
#apart .hl-card:nth-child(1) .hl-icon {
  color: var(--accent-pink);
  background: color-mix(in srgb, var(--prism-stop-pink) 12%, transparent);
  border-color: color-mix(in srgb, var(--prism-stop-pink) 30%, transparent);
}
#apart .hl-card:nth-child(2) .hl-icon {
  color: var(--accent-violet);
  background: color-mix(in srgb, var(--prism-stop-violet) 12%, transparent);
  border-color: color-mix(in srgb, var(--prism-stop-violet) 30%, transparent);
}
#apart .hl-card:nth-child(3) .hl-icon {
  color: var(--accent-teal);
  background: color-mix(in srgb, var(--prism-stop-teal) 12%, transparent);
  border-color: color-mix(in srgb, var(--prism-stop-teal) 30%, transparent);
}

/* case teaser footer link */

/* ============================================================
   SUBPAGE — page hero header
   ============================================================ */
.page-hero {
  position: relative;
  padding: var(--hero-top) 0 56px;
  border-bottom: 1px solid var(--border-1);
  overflow: hidden;
}
.page-hero .container {
  position: relative;
}
/* 404: nothing follows the hero, so double its vertical padding based on feedback from UX/UI designer */
.page-hero--error {
  padding-top: calc(var(--hero-top) * 2);
  padding-bottom: 112px;
}
/* Keep the copy above the .page-hero-globe background layer (z-index:0). */
.page-hero--globe > .container {
  z-index: 1;
}
.page-hero-inner {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 48px;
  align-items: center;
}
/* R&D hero: full-bleed globe video anchored right, overscanned so the hero's
   own overflow:hidden clips it. Decorative and inert (pointer-events:none),
   below the copy. Three tricks make it fuse with the page rather than sit in a
   visible box: screen blend drops the footage's near-black backdrop into the
   navy, a radial alpha mask feathers all four edges, and the ::after recolours
   to brand blue via a 'color' blend (hue from the overlay, luminance from the
   video) so the look holds whatever the source grade. */
.page-hero-globe {
  position: absolute;
  top: 50%;
  right: -6%;
  transform: translateY(-50%);
  width: 60%;
  height: 128%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.6;
  filter: saturate(0.9) brightness(1.02);
  mix-blend-mode: screen;
  /* Soft radial vignette centred on the globe's visible core. Feathers the layer
     into the navy on every side (not just the copy-side edge) with an eased,
     multi-stop falloff, so there is no hard ramp line or clipped edge — the video
     dissolves seamlessly into the hero ground. */
  -webkit-mask-image: radial-gradient(
    ellipse 56% 72% at 52% 50%,
    #000 20%,
    rgba(0, 0, 0, 0.5) 50%,
    transparent 86%
  );
  mask-image: radial-gradient(
    ellipse 56% 72% at 52% 50%,
    #000 20%,
    rgba(0, 0, 0, 0.5) 50%,
    transparent 86%
  );
}
.page-hero-globe-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Scale the footage down a touch to zoom out; the revealed edges are
     transparent and simply let the hero ground show through the screen blend. */
  transform: scale(0.86);
  transform-origin: center;
}
.page-hero-globe::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgb(38, 92, 230);
  mix-blend-mode: color;
  opacity: 0.7;
}
/* Below the two-column breakpoint the copy stacks full-width; drop the globe to
   a faint, centred backdrop so it never crowds the text. */
@media (max-width: 1024px) {
  .page-hero-globe {
    width: 100%;
    opacity: 0.4;
    -webkit-mask-image: radial-gradient(
      ellipse 70% 70% at 70% 50%,
      #000 40%,
      transparent 100%
    );
    mask-image: radial-gradient(
      ellipse 70% 70% at 70% 50%,
      #000 40%,
      transparent 100%
    );
  }
}
@media (max-width: 1024px) {
  .page-hero-inner {
    grid-template-columns: 1fr;
  }
}
.page-hero .eyebrow {
  margin-bottom: 16px;
}
.page-hero h1 {
  font-size: clamp(36px, 4.4vw, 56px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 0 0 24px;
  color: var(--fg-1);
  max-width: 16ch;
}
/* Constrain a page hero heading to one 1fr column - half the container, matching
   the home .section-head 2-col grid - so it wraps like a section head. Type scale
   is inherited from the base .page-hero h1 above (shared by every hero). Applied to
   Solutions, Services and Wires; Solutions also repeats the home "One engine" section
   heading, so the two wrap identically. */
.page-hero.page-hero--section-title h1 {
  max-width: calc((100% - 64px) / 2);
}
@media (max-width: 1024px) {
  .page-hero.page-hero--section-title h1 {
    max-width: none;
  }
}
/* ---- Lahja cultural-initiative card (R&D) — mirrors the .rnd team card ---- */
.lahja-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: center;
  padding: var(--card-pad-feature);
  border-radius: 24px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
}
.lahja-copy .eyebrow {
  margin-bottom: 16px;
}
.lahja-copy h2 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(32px, 3.4vw, 46px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0 0 24px;
}
.lahja-copy p {
  font-size: 16px;
  line-height: 1.65;
  color: var(--fg-2);
  margin: 0 0 16px;
}
.lahja-copy p:last-child {
  margin-bottom: 0;
}
.lahja-media {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  aspect-ratio: 16 / 10;
}
.lahja-media img {
  width: calc(100% * var(--lahja-zoom, 1.12));
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
  margin: 0 auto;
}

@media (max-width: 949px) {
  .lahja-card {
    grid-template-columns: 1fr;
    gap: 32px;
  }
}

.page-hero .page-lede {
  font-family: var(--font-sans);
  font-size: 18px;
  line-height: 1.55;
  color: var(--fg-2);
  max-width: 620px;
  margin: 0;
  letter-spacing: -0.005em;
}
.page-hero .page-hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 40px;
  margin-top: 40px;
}
.page-hero .page-hero-meta .ds-kpi {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.page-hero .page-hero-meta .ds-caption {
  font-size: 12px;
  color: var(--fg-3);
  margin-top: 2px;
}

/* R&D hero-meta reuses the home-page value-prop items. Scoped via
   .page-hero--globe so contact's KPI row, which shares .page-hero-meta, is
   untouched. The gap and mobile stacking are safe; the width tuning below is
   hand-fit to THIS copy — read its warning before editing text. */
.page-hero--globe .page-hero-meta {
  gap: 20px; /* was 40px — reclaims the width the copy needs for 2 lines each */
}

/* ⚠️ COPY-SPECIFIC, FRAGILE — read before editing rnd hero-meta.
   Equal columns wrap the three descriptions to 2/3/2 lines; these weights
   hand-tune the widths so all three land on 2. It's a knife-edge — "Client
   Advantage" sits ~183px against a ~180–185px threshold. Editing any
   description, reordering or adding a card (selectors are positional), or
   changing the font will break it and need a retune. Better: balance the copy
   lengths so equal columns suffice. :first-child keeps the default grow of 1. */
.page-hero--globe .page-hero-meta .hero-meta-item:nth-child(2) {
  flex-grow: 1.2;
} /*Cutting-edge Research — longest copy, needs the most width*/
.page-hero--globe .page-hero-meta .hero-meta-item:nth-child(3) {
  flex-grow: 1.05;
} /*Client Advantage — small nudge so it holds 2 lines, not 3*/

/* Wrap "Client Advantage" to two lines so all three headings match; min-content
   shrinks it to its widest word. Desktop only — one line reads better once the
   hero goes single-column.
   ⚠️ Copy-specific: works only while the label is exactly two words, and the
   nth-child(3) target is positional. */
@media (min-width: 1025px) {
  .page-hero--globe
    .page-hero-meta
    .hero-meta-item:nth-child(3)
    .hero-meta-label {
    max-width: min-content;
  }
}
@media (max-width: 767px) {
  .page-hero--globe .page-hero-meta {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
  }
}

/* divider used between stacked subpage sections */
.sub-divider {
  border: none;
  border-top: 1px solid var(--border-1);
  margin: 0;
}

/* ------------------------------------------------------------
   legal / long-form pages (disclaimer, terms, privacy, copyright)

   Nothing page-specific — compose a new page from .legal (wrapper),
   .legal-meta, .legal-block, .legal-toc, .legal-bullets and
   .legal-contact. The base .legal h2/h3/p/a rules apply throughout,
   so every block matches without per-page overrides.
   ------------------------------------------------------------ */
.legal {
  max-width: 820px;
}
.legal > * + * {
  margin-top: 24px;
}

.legal h2 {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
  color: var(--fg-1);
  margin: 0 0 16px;
}
.legal h3 {
  font-size: 16px;
  font-weight: 600;
  color: var(--fg-1);
  margin: 24px 0 12px;
}
.legal p {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.7;
  color: var(--fg-2);
  margin: 0 0 16px;
}
.legal :last-child {
  margin-bottom: 0;
}
.legal a {
  color: var(--prism-stop-teal);
  text-decoration: none;
  transition: color 160ms ease;
}
.legal a:hover {
  text-decoration: underline;
}

.legal-meta {
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--fg-3);
}

.legal-note {
  padding: 20px 24px;
  border: 1px solid var(--border-1);
  border-radius: 14px;
}

/* table of contents — auto-numbered anchors; the column count
   follows the available width, so it collapses to one on mobile
   with no media query. */
.legal-toc {
  counter-reset: toc;
  list-style: none;
  margin: 0;
  padding: 24px 28px;
  border: 1px solid var(--border-1);
  border-radius: 14px;
  columns: 260px;
  column-gap: 40px;
}
.legal-toc li {
  counter-increment: toc;
  break-inside: avoid;
}
.legal-toc li + li {
  margin-top: 12px;
}
.legal-toc a {
  display: flex;
  gap: 0.6em;
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  color: var(--fg-2);
}
.legal-toc a:hover {
  color: var(--fg-1);
  text-decoration: none;
}
.legal-toc a::before {
  content: counter(toc) '.';
  color: var(--fg-3);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

/* numbered body — the counter lives on the list, the number is
   printed by the section heading, so wrapped copy needs no
   hanging indent. */

/* un-numbered sub-list inside a section */
.legal-bullets {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}
.legal-bullets li {
  position: relative;
  padding-left: 1.4em;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.7;
  color: var(--fg-2);
}
.legal-bullets li + li {
  margin-top: 8px;
}
.legal-bullets li::before {
  content: '';
  position: absolute;
  left: 0.2em;
  top: 0.7em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--fg-3);
}

/* contact / address block */
.legal-contact {
  font-style: normal;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.9;
  color: var(--fg-2);
}

/* ============================================================
   R&D — white papers
   ============================================================ */
.paper-list {
  display: grid;
  gap: 16px;
}
.paper {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 24px;
  align-items: center;
  padding: var(--card-pad);
  background: var(--surface-card-gradient);
  border: 1px solid var(--border-1);
  border-radius: 14px;
  text-decoration: none;
  transition:
    border-color 180ms ease,
    transform 180ms ease,
    background 180ms ease;
}
.paper:hover {
  border-color: color-mix(in srgb, var(--prism-stop-violet) 40%, transparent);
  transform: translateY(-1px);
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--prism-stop-violet) 6%, transparent),
    rgba(255, 255, 255, 0.01)
  );
}
.paper-doc {
  width: 46px;
  height: 46px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--neutral-600) 12%, transparent);
  opacity: 70%;
  border: 1px solid var(--neutral-600);
  color: var(--fg-1);
  flex-shrink: 0;
}
.paper-doc svg {
  width: 20px;
  height: 20px;
}

/* Author chip. One base class; each author only sets --author-hue, so adding or
   renaming an author is a one-line change (here + the map in rnd.js) instead of a
   whole copied rule. Alphas are unified at 18%/42% across all authors. */
.paper-author {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.5;
  padding: 2px 8px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--author-hue) 18%, transparent);
  color: var(--fg-2);
  border: 1px solid color-mix(in srgb, var(--author-hue) 42%, transparent);
  margin-bottom: 8px;
}
.paper-author--ali {
  --author-hue: color-mix(in srgb, var(--prism-stop-violet), white 20%);
}
.paper-author--sabbir {
  --author-hue: color-mix(in srgb, var(--prism-stop-indigo), black 15%);
}
.paper-author--reem {
  --author-hue: var(--prism-stop-pink);
}

.paper-title {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--fg-1);
  margin: 0 0 8px;
  line-height: 1.3;
}
.paper-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--fg-3);
}
.paper-meta span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.paper-meta svg {
  width: 14px;
  height: 14px;
  opacity: 0.7;
}
.paper-action {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--fg-1);
  white-space: nowrap;
}
.paper-action svg {
  width: 15px;
  height: 15px;
  transition: transform 160ms ease;
}
.paper:hover .paper-action svg {
  transform: translateY(-2px) translateX(2px);
}
@media (max-width: 767px) {
  .paper {
    grid-template-columns: auto 1fr;
  }
  .paper-action {
    grid-column: 2;
    justify-self: start;
  }
}

/* ============================================================
   R&D — global event contributions (timeline)
   ============================================================ */
.events-list {
  display: grid;
  gap: 0;
}
.event-row {
  display: grid;
  grid-template-columns: 156px 14px 1fr auto;
  gap: 28px;
  align-items: start;
  padding: 24px 0;
  border-bottom: 1px solid var(--border-1);
}
.event-row:last-child {
  border-bottom: none;
}
.event-when {
  font-family: var(--font-mono), monospace;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--fg-3);
  padding-top: 2px;
}
.event-pin-col {
  padding-top: 3px;
  color: var(--fg-3);
}
.event-pin-icon svg {
  width: 14px;
  height: 14px;
}
.event-name {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--fg-1);
  margin: 0 0 8px;
}
.event-talk {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--fg-2);
  margin: 0 0 12px;
}
.event-loc {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--fg-3);
}
.event-loc svg {
  width: 14px;
  height: 14px;
  opacity: 0.7;
}
.event-badge {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.5;
  padding: 3px 12px;
  border-radius: var(--r-pill);
  background: transparent;
  border: 1px solid var(--border-1);
  color: var(--fg-2);
  white-space: nowrap;
}
/* Inline per-event "Show more" — hidden by default (desktop and short
   descriptions). JS adds .has-overflow to the row only when the clamped
   text is genuinely cut off, which the mobile rule below reveals. */
.event-more-btn {
  display: none;
}
/* ============================================================
   Events list — progressive disclosure
   Capped at the first 10 rows at every size, behind the "Show
   more" toggle wired in app.js.
   ============================================================ */
.events-list.is-collapsible.is-collapsed > :nth-child(n + 11) {
  display: none;
}
/* Shared "Show more" toggle — one appearance; contexts below opt in. */
.show-more-btn {
  display: none;
  align-items: center;
  gap: 8px;
  justify-self: start;
  margin-top: 20px;
  padding: 12px 16px;
  border-radius: var(--r-pill);
  background: transparent;
  border: 1px solid var(--border-2);
  color: var(--fg-1);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition:
    background 140ms ease,
    border-color 140ms ease;
}
.show-more-btn:hover {
  background: rgba(255, 255, 255, 0.04);
}
.show-more-btn svg {
  width: 16px;
  height: 16px;
  opacity: 0.8;
}
/* Events is capped at every size, so its toggle shows at every size. */
.events-split > .show-more-btn {
  display: inline-flex;
  grid-column: 2;
}
@media (max-width: 1024px) {
  .events-split > .show-more-btn {
    grid-column: 1;
  }
}

@media (max-width: 767px) {
  .event-row {
    grid-template-columns: auto 1fr;
    grid-template-areas:
      'when pin'
      'detail detail'
      'badge badge';
    gap: 4px 8px;
  }
  .event-when {
    grid-area: when;
  }
  .event-pin-col {
    grid-area: pin;
    padding-top: 0;
  }
  .event-detail {
    grid-area: detail;
    margin-top: 4px;
  }
  .event-badge {
    grid-area: badge;
    justify-self: start;
    margin-top: 4px;
  }

  /* Long descriptions clamp to a few lines until the reader expands them.
     Skipping .is-expanded lifts the clamp; the button height is unaffected
     so toggling never shifts the surrounding layout. */
  .event-detail:not(.is-expanded) .event-talk {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
  }
  .event-detail.has-overflow .event-talk {
    margin-bottom: 4px;
  }
  /* Keep the location on its own line at the bottom of the block: as an
     inline element it would otherwise sit beside the inline toggle. */
  .event-loc {
    display: flex;
  }
  .event-detail.has-overflow .event-more-btn {
    display: inline-flex;
    align-items: center;
    margin: 0 0 12px;
    padding: 0;
    background: none;
    border: none;
    color: var(--fg-1);
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
  }
  .event-detail.has-overflow .event-more-btn:hover {
    text-decoration: underline;
  }
}

/* ============================================================
   Line clamp (shared) — long card copy behind a "show more"
   A context can raise the line count by setting --clamp-lines. .is-open
   un-clamps by leaving the -webkit-box context line-clamp needs.
   ============================================================ */
.clamp {
  --clamp-lines: 3;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--clamp-lines);
  line-clamp: var(--clamp-lines);
  overflow: hidden;
}
.clamp.is-open {
  display: block;
}
.clamp-btn {
  display: block;
  align-self: start;
  margin-top: 8px;
  padding: 0;
  background: none;
  border: none;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--fg-1);
  cursor: pointer;
}
.clamp-btn:hover {
  text-decoration: underline;
}

/* ============================================================
   Progressive disclosure — collapse long lists below laptop
   The cap and the toggle exist only up to this breakpoint, so
   laptop/desktop always show the full list. Item type-agnostic: any
   direct children past the cap are hidden, so new papers/events flow
   through without touching this. Cap (first 3) mirrors SHOW_MORE_LIMIT
   in app.js.
   ============================================================ */
@media (max-width: 1024px) {
  .is-collapsible.is-collapsed > :nth-child(n + 4) {
    display: none;
  }
  /* initShowMore only inserts the toggle after a list it capped, so the
     sibling pair is the opt-in. */
  .is-collapsible + .show-more-btn {
    display: inline-flex;
  }
}

/* Tablets bump the tech-hubs matrix from the shared cap of 3 to 4 by re-showing
   just the 4th card; 5+ stay hidden by the shared rule, so adding cards needs
   nothing here. The extra .is-collapse-4 class wins on specificity alone, and
   `revert` returns the card to its normal grid-flow display. */
@media (min-width: 768px) and (max-width: 1024px) {
  .is-collapse-4.is-collapsible.is-collapsed > :nth-child(4) {
    display: revert;
  }
}

/* ============================================================
   WIRES — filterable blog feed
   ============================================================ */
.feed-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 36px;
}
.feed-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 16px;
  border-radius: var(--r-pill);
  background: transparent;
  border: 1px solid var(--border-1);
  color: var(--fg-2);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition:
    background 140ms ease,
    color 140ms ease,
    border-color 140ms ease;
}
.feed-chip:hover {
  color: var(--fg-1);
  border-color: var(--border-2);
}
.feed-chip.is-active {
  background: var(--fg-1);
  color: var(--bg-panel);
  border-color: var(--fg-1);
}
.feed-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
@media (max-width: 1024px) {
  .feed-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 767px) {
  .feed-grid {
    grid-template-columns: 1fr;
  }
}

/* single-column feed grid (e.g. Culture page's LinkedIn/Instagram columns) */
.social-feed.feed-grid {
  grid-template-columns: 1fr;
}

.feed-card {
  display: flex;
  flex-direction: column;
  background: var(--surface-card-gradient);
  border: 1px solid var(--border-1);
  border-radius: 16px;
  overflow: hidden;
  text-decoration: none;
  transition:
    border-color 180ms ease,
    transform 180ms ease;
}
.feed-card:hover {
  border-color: color-mix(in srgb, var(--prism-stop-violet) 40%, transparent);
  transform: translateY(-2px);
}

/* media area — gradient banner; videos add a play button */
.feed-media {
  position: relative;
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  background:
    radial-gradient(
      circle at 30% 30%,
      color-mix(in srgb, var(--prism-stop-violet) 28%, transparent),
      transparent 60%
    ),
    radial-gradient(
      circle at 75% 70%,
      color-mix(in srgb, var(--prism-stop-teal) 22%, transparent),
      transparent 60%
    ),
    var(--surface-well);
  overflow: hidden;
}

.feed-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.feed-media-photo {
  position: absolute;
  inset: 0;
}

/* opt-in per image: crop tight instead of letterboxing (set image.fit = "cover").
   Optionally set image.position (e.g. "center 30%") to choose which part of
   the image survives the crop — defaults to centered. */
.feed-media-photo.is-cover img {
  object-fit: cover;
}

.feed-media .feed-grain {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 28px 28px;
  mask-image: radial-gradient(ellipse at center, #000 0%, transparent 75%);
  -webkit-mask-image: radial-gradient(
    ellipse at center,
    #000 0%,
    transparent 75%
  );
}
.feed-media .feed-media-icon {
  position: relative;
  color: rgba(255, 255, 255, 0.55);
}
.feed-media .feed-media-icon svg {
  width: 30px;
  height: 30px;
}
.feed-play {
  position: relative;
  width: 54px;
  height: 54px;
  border-radius: 99px;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: var(--neutral-0);
  transition:
    transform 180ms ease,
    background 180ms ease;
}
.feed-card:hover .feed-play {
  transform: scale(1.08);
  background: var(--prism);
  border-color: transparent;
}
.feed-play svg {
  width: 20px;
  height: 20px;
  margin-left: 3px;
}
.feed-dur {
  position: absolute;
  bottom: 10px;
  right: 10px;
  font-family: var(--font-mono), monospace;
  font-size: 11px;
  color: var(--neutral-0);
  background: rgba(0, 0, 0, 0.65);
  padding: 2px 8px;
  border-radius: 5px;
}

.feed-body {
  padding: 20px 24px 24px;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.feed-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.feed-type {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
}
.feed-type::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 99px;
  background: currentColor;
}
.feed-type.t-press {
  color: var(--accent-teal);
  background: color-mix(in srgb, var(--prism-stop-teal) 12%, transparent);
}
.feed-type.t-announce {
  color: var(--accent-violet);
  background: color-mix(in srgb, var(--prism-stop-violet) 14%, transparent);
}
.feed-type.t-news {
  color: var(--accent-pink);
  background: color-mix(in srgb, var(--prism-stop-pink) 12%, transparent);
}
.feed-type.t-video {
  color: var(--accent-indigo);
  background: color-mix(in srgb, var(--prism-stop-indigo) 16%, transparent);
}
.feed-type.t-article {
  color: var(--accent-mint);
  background: color-mix(in srgb, var(--prism-stop-teal) 12%, transparent);
}
.feed-date {
  font-family: var(--font-mono), monospace;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  white-space: nowrap;
}
.feed-title {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.3;
  color: var(--fg-1);
  margin: 0 0 12px;
}
.feed-excerpt {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--fg-3);
  margin: 0 0 16px;
  white-space: pre-line;
}
.feed-excerpt.clamp + .clamp-btn {
  margin: -8px 0 16px;
}
.feed-action {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--fg-1);
}
.feed-action svg {
  width: 14px;
  height: 14px;
  transition: transform 160ms ease;
}
.feed-card:hover .feed-action svg {
  transform: translateX(3px);
}

.feed-empty {
  display: none;
  padding: 48px 0;
  text-align: center;
  color: var(--fg-3);
  font-size: 14px;
}

/* featured lead wire (sits above the filter, never filtered) */
.feed-featured {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 0;
  border: 1px solid var(--border-1);
  border-radius: 20px;
  overflow: hidden;
  margin-bottom: 32px;
  text-decoration: none;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.045),
    rgba(255, 255, 255, 0.012)
  );
  transition:
    border-color 200ms ease,
    transform 200ms ease;
}
.feed-featured:hover {
  border-color: color-mix(in srgb, var(--prism-stop-violet) 45%, transparent);
  transform: translateY(-2px);
}
.ff-media {
  position: relative;
  min-height: 340px;
  display: grid;
  place-items: center;
  background:
    radial-gradient(
      circle at 28% 30%,
      color-mix(in srgb, var(--prism-stop-violet) 40%, transparent),
      transparent 60%
    ),
    radial-gradient(
      circle at 78% 72%,
      color-mix(in srgb, var(--prism-stop-teal) 30%, transparent),
      transparent 60%
    ),
    radial-gradient(
      circle at 60% 20%,
      color-mix(in srgb, var(--prism-stop-pink) 18%, transparent),
      transparent 55%
    ),
    var(--surface-well);
  overflow: hidden;
}
.ff-media .feed-grain {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: radial-gradient(ellipse at center, #000 0%, transparent 78%);
  -webkit-mask-image: radial-gradient(
    ellipse at center,
    #000 0%,
    transparent 78%
  );
}
.ff-body {
  padding: 40px 40px 40px 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.ff-top {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.ff-featured-label {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-2);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-1);
}
.ff-featured-label::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 99px;
  background: var(--prism);
  box-shadow: 0 0 8px
    color-mix(in srgb, var(--prism-stop-violet) 70%, transparent);
}
.ff-title {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--fg-1);
  margin: 0 0 16px;
}
.ff-excerpt {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.6;
  color: var(--fg-2);
  margin: 0 0 24px;
  max-width: 46ch;
  --clamp-lines: 5;
}
.ff-excerpt.clamp + .clamp-btn {
  margin: -16px 0 24px;
  font-size: 14px;
}
.ff-foot {
  display: flex;
  align-items: center;
  gap: 16px;
}
.ff-date {
  font-family: var(--font-mono), monospace;
  font-size: 12px;
  color: var(--fg-3);
  letter-spacing: 0.04em;
}

@media (max-width: 949px) {
  .feed-featured {
    grid-template-columns: 1fr;
  }
  .ff-media {
    min-height: 220px;
  }
  .ff-body {
    padding: 32px;
  }
  .ff-title {
    font-size: 24px;
  }
}

/* featured lead wire using a static image instead of a video thumbnail —
   kept as a small fixed-width column so the tall infographic doesn't
   dominate the card */
.feed-featured-image {
  grid-template-columns: 460px 1fr;
}
.feed-featured-image .ff-media {
  min-height: 0;
}
.feed-featured-image .ff-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
@media (max-width: 949px) {
  .feed-featured-image {
    grid-template-columns: 1fr;
  }
  .feed-featured-image .ff-media {
    aspect-ratio: 1280 / 1599;
    width: 100%;
    height: auto;
  }
}

/* ============================================================
   Buttons — Obra shadcn spec
   md (default) h36 / sm h32 / lg h40
   radius 8 (var(--r-md))
   typography 14 / 500 / -0.025em letter-spacing
   primary uses theme-aware --btn-primary-* tokens
   outline-style ("ghost" in this site's vocabulary) uses --btn-outline-*
   prism is the AI affordance — 1px prism outline on a translucent fill
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 36px;
  padding: 0 16px;
  border-radius: var(--r-md);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition:
    background 140ms ease,
    transform 80ms ease,
    color 140ms ease,
    border-color 140ms ease;
  white-space: nowrap;
  vertical-align: middle;
}
.btn:active {
  transform: translateY(1px);
}
.btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.btn-primary {
  background: var(--btn-primary-bg);
  color: var(--btn-primary-fg);
}
.btn-primary:hover {
  background: var(--btn-primary-bg-hover);
}
.btn-primary:active {
  background: var(--btn-primary-bg-active);
}

.btn-ghost {
  background: var(--btn-outline-bg);
  color: var(--fg-1);
  border-color: var(--border-2);
}
.btn-ghost:hover {
  background: var(--btn-outline-bg-hover);
}
.btn-ghost:active {
  background: var(--btn-outline-bg-active);
}

.btn-prism {
  position: relative;
  isolation: isolate;
  background: rgba(255, 255, 255, 0.05);
  color: var(--fg-1);
  border-color: transparent;
}
.btn-prism::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--prism);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.btn-prism:hover {
  background: color-mix(in srgb, var(--prism-stop-violet) 12%, transparent);
}
.btn-prism:active {
  background: color-mix(in srgb, var(--prism-stop-violet) 18%, transparent);
}

/* small/large size modifiers (Obra) */
.btn.btn-sm {
  height: 32px;
  padding: 0 12px;
  font-size: 14px;
  gap: 8px;
}
.btn svg,
.btn [data-icon] {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.btn [data-icon] svg {
  width: 100%;
  height: 100%;
}

/* ============================================================
   HERO
   ============================================================ */
/* Shared top gap below the sticky nav — single source of truth for every
   top-of-page block (.hero, .page-hero, and the lead section on hero-less
   pages). Overridden once for mobile in the max-width:640px block below. */
:root {
  --hero-top: 80px;
}

.hero {
  position: relative;
  background: var(--bg-hero-navy);
  padding: var(--hero-top) 0 80px;
  overflow: hidden;
}
/* Hero atmospherics — moved to marketing-components.css (M-01). */

.hero-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 48px;
  align-items: stretch;
}
@media (max-width: 1024px) {
  .hero-inner {
    grid-template-columns: 1fr;
  }
}

/* Hero tag — outer wrapper styled like an Obra outline badge (round),
   inner chip is an Obra primary badge with prism fill. */
.hero-tag {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 4px 12px 4px 4px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border-1);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.025em;
  color: var(--fg-2);
  margin-bottom: 24px;
  line-height: 1.5;
}
.hero-tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 12px;
  border-radius: var(--r-pill);
  background: var(--prism);
  color: var(--fg-on-prism);
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: -0.025em;
  line-height: 1.5;
}
.hero-tag-chip svg,
.hero-tag-chip [data-icon] {
  width: 12px;
  height: 12px;
}

.hero h1 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(36px, 4.4vw, 56px);
  line-height: 0.98;
  letter-spacing: -0.025em;
  margin: 0 0 24px;
  color: var(--fg-1);
}

.hero p.lede {
  font-size: 18px;
  line-height: 1.55;
  color: var(--fg-2);
  max-width: 560px;
  margin: 0 0 32px;
}

.hero-ctas {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.hero-meta {
  margin-top: 56px;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 28px;
  max-width: 720px;
}
.hero-meta-item {
  flex: 1 1 0;
  min-width: 150px;
}
/* Hand-tuned so each column wraps to the intended line count; positional, so
   rebalance these weights if the copy or card order changes. Same fragility as
   the rnd hero-meta above. */
.hero-meta .hero-meta-item:first-child {
  flex-grow: 2;
} /*Integrity*/
.hero-meta .hero-meta-item:nth-child(2) {
  flex-grow: 1.4;
} /*Trust*/
.hero-meta .hero-meta-item:nth-child(3) {
  flex-grow: 1;
} /*Productivity*/
.hero-meta-label {
  font-family: var(--font-sans);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--fg-1);
  margin-bottom: 8px;
}
.hero-meta-desc {
  color: var(--fg-3);
  font-size: 14px;
  line-height: 1.35;
  text-align: left;
}

@media (max-width: 767px) {
  :root {
    --hero-top: 48px;
  }
  .hero-tag {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 0;
    background: none;
    border: none;
  }
  .hero-ctas {
    flex-direction: column;
    align-items: stretch;
  }
  .hero-ctas .btn {
    width: 100%;
  }
  .hero-meta {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
  }
}

/* ---- Hero right: RAG pipeline embed --------------------------------- */
/* The embedded animation (/_components/RAG2.html) is width-fluid down to a
   ~480px floor and a fixed ~668px tall; narrower than --rag-w it clips its
   own sides and its controls. On desktop it sits in the two-column hero grid,
   vertically centered against the text column (which can run taller) and
   enlarged slightly. The design dimensions below are the single source of
   truth shared with the resize script. */
.hero-rag {
  /* Kept unitless as well so aspect-ratio below can consume them; the px
     values derive from these, so the design size stays defined in one place. */
  --rag-w-n: 480; /* embed's minimum comfortable layout width */
  --rag-h-n: 668; /* embed's fixed natural height */
  --rag-w: calc(var(--rag-w-n) * 1px);
  --rag-h: calc(var(--rag-h-n) * 1px);
  position: relative;
  width: 100%;
  height: var(--rag-h);
  min-height: 480px;
  border-radius: 16px;
  overflow: hidden;
  transform: scale(1.19);
  align-self: center;
}
.hero-rag-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  border-radius: 16px;
}
.hero-rag.media-skeleton::after {
  inset: calc(40px * var(--rag-scale, 1)) 0 auto;
  margin-inline: auto;
  width: calc(460px * var(--rag-scale, 1));
  height: calc(500px * var(--rag-scale, 1));
  border-radius: 16px;
}

/* Single-column layout (tablet + mobile): drop the desktop enlargement and
   pin the box to the embed's natural height so its controls stay in view.
   Where the column is still >= --rag-w the embed simply fills it fluidly. */
@media (max-width: 1024px) {
  .hero-rag {
    transform: none;
    min-height: 0;
    height: var(--rag-h);
  }
}

/* Phones: the column is narrower than --rag-w, where the embed would clip its
   own sides. Instead render it at its full design size and scale the whole
   thing down to fit. The resize script adds .is-scaled and sets --rag-scale
   (= column width / --rag-w) only while that shrink is needed.

   The scaled height is always width x (--rag-h / --rag-w), so express it as a
   ratio and let layout derive it from the width. Deriving it here rather than
   computing it from --rag-scale in the script matters: the script then writes
   nothing that changes this box's size, so measuring the width can never be
   disturbed by the script's own output. */
.hero-rag.is-scaled {
  height: auto;
  aspect-ratio: var(--rag-w-n) / var(--rag-h-n);
}
.hero-rag.is-scaled .hero-rag-frame {
  width: var(--rag-w);
  height: var(--rag-h);
  transform: scale(var(--rag-scale));
  transform-origin: 0 0;
}

/* ============================================================
   FOOTER VIDEO STRIP
   ============================================================ */
/* Full-bleed video band at the top of the footer, replacing the
   former prism accent strip. object-fit:cover keeps the clip filling
   the band at any viewport width; height is the one knob to tune. */
.footer-strip {
  position: relative;
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
  height: 16px;
  margin-bottom: 64px;
  overflow: hidden;
}
.footer-strip video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ============================================================
   SECTION CHROME
   ============================================================ */
section {
  position: relative;
}
.section {
  /* Fluid rhythm: ~64px on phones, scales up to 120px on desktop. */
  padding: clamp(64px, 9vw, 120px) 0;
}
.section-tight {
  padding: clamp(48px, 6vw, 80px) 0;
}
/* legal / long-form pages sit right under a hero — trim the section rhythm */
.section--legal {
  padding: 64px 0;
}
/* trims only the top of the section rhythm; keeps the normal bottom gap */
.section--flush-top {
  padding-top: 48px;
}
/* Lead section on pages with no hero — normalize its top gap to --hero-top
   while keeping the normal 120px bottom rhythm to the next section. */
.section-head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: end;
  margin-bottom: clamp(32px, 4vw, 56px);
}
@media (max-width: 1024px) {
  .section-head {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}
.section-head h2 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(36px, 4.4vw, 56px);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 12px 0 0;
}
.section-head p.lede {
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg-2);
  margin: 0;
  max-width: 480px;
}

/* ============================================================
   QUANT / signature card
   ============================================================ */
.quant {
  display: grid;
  grid-template-columns: 1fr;
  gap: 56px;
  align-items: center;
  /* Feature card padding token: 48px desktop/tablet, gutter on phones. */
  padding: var(--card-pad-feature);
  border-radius: 24px;
  background: var(--surface-card-gradient);
  border: 1px solid var(--border-1);
  position: relative;
  overflow: hidden;
}
.quant::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 600px 300px at 80% 100%,
    color-mix(in srgb, var(--prism-stop-violet) 16%, transparent),
    transparent 60%
  );
  pointer-events: none;
}
.quant > * {
  position: relative;
}
.quant h3 {
  font-family: var(--font-sans);
  font-weight: 700;
  /* Fluid heading: ~28px on phones (keeps it to ~3 lines like desktop),
     up to 40px on wider screens — same clamp pattern as the hero h1. */
  font-size: clamp(28px, 7vw, 40px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 12px 0 16px;
}
.quant p {
  color: var(--fg-2);
  line-height: 1.6;
  font-size: 16px;
  margin: 0 0 24px;
}
.quant ul {
  list-style: none;
  padding: 0;
  margin: 0 0 32px;
  display: grid;
  gap: 12px;
}
.quant ul li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 14px;
  color: var(--fg-2);
  line-height: 1.5;
}
.quant ul li svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--prism-stop-teal);
}
@media (max-width: 767px) {
  /* Full-width CTA on phones, same as the hero's "See our solutions" button. */
  .quant .btn {
    width: 100%;
  }
}
/* ============================================================
   SOLUTIONS
   ============================================================ */
.sol-tabs {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 32px;
  align-items: start;
}
@media (max-width: 1024px) {
  .sol-tabs {
    grid-template-columns: 1fr;
  }
}
.sol-tab-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sol-tab {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 16px;
  border-radius: 12px;
  background: transparent;
  border: 1px solid transparent;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  color: var(--fg-2);
  transition:
    background 140ms ease,
    border-color 140ms ease,
    color 140ms ease;
  position: relative;
}
.sol-tab:hover {
  background: rgba(255, 255, 255, 0.04);
  color: var(--fg-1);
}
.sol-tab[aria-selected='true'] {
  background: rgba(255, 255, 255, 0.05);
  border-color: transparent;
  color: var(--fg-1);
}
.sol-tab[aria-selected='true']::before {
  content: '';
  position: absolute;
  inset: 0;
  padding: 1px;
  border-radius: inherit;
  background: var(--prism);
  opacity: 0.55;
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.sol-tab-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  color: var(--fg-1);
}
.sol-tab[aria-selected='true'] .sol-tab-icon {
  background: var(--prism);
  color: white;
}
.sol-tab svg {
  width: 18px;
  height: 18px;
}
.sol-tab-meta {
  flex: 1;
  min-width: 0;
}
.sol-tab-meta .name {
  font-weight: 600;
  font-size: 14px;
  display: block;
}
.sol-tab-meta .domain {
  font-size: 11px;
  color: var(--fg-3);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-top: 2px;
  display: block;
}

.sol-panel {
  padding: var(--card-pad-sol);
  border-radius: 20px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 36px;
  /* Both columns fill the panel's full height (the taller of the two). The
     media card absorbs its slack by growing the image/quote viewport (see the
     carousel rules); the text column absorbs its slack by pushing the metrics
     footer to the bottom (.sol-metrics margin-top:auto below). So whichever
     column is shorter, its content still reaches the bottom edge — no empty
     band, and nothing forced onto the image itself. */
  align-items: stretch;
}
/* Text column as a flex column so its metrics row can be pinned to the bottom
   (below). The child widths are unaffected — every child already spans the
   column, and the eyebrow is a background-less inline-flex pill, so stretching
   it changes nothing visible. */
.sol-panel > div {
  display: flex;
  flex-direction: column;
}
@media (max-width: 767px) {
  .sol-panel {
    grid-template-columns: 1fr;
  }
}
/* Tablet only: quote+image panels (currently Job Matching) give the media
   column more width so its image sits larger against the quote-driven box.
   Scoped to the two-column tablet range via :has(), so it never overrides the
   mobile single-column layout below 768px. */
@media (min-width: 768px) and (max-width: 949px) {
  .sol-panel:has(.photo-carousel.has-quote) {
    grid-template-columns: 0.8fr 1.2fr;
  }
}
/* Quote-only panels (a standalone testimonial aside, no image carousel) have no
   image ratio to set their height, so short vs long quotes would render at
   different heights. Give just those asides a shared floor so they read at a
   consistent size — the panel already stretches them to the row height. From
   tablet up only; on mobile the fixed floor made quotes take too much space, so
   phones size to their content. */
@media (min-width: 768px) {
  .sol-panel > .testimonial:not(.photo-carousel) {
    min-height: 540px;
  }
}
.sol-panel h3 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 36px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 16px 0 16px;
}
.sol-panel .lede {
  color: var(--fg-2);
  font-size: 15px;
  line-height: 1.6;
  margin: 0 0 24px;
}
.sol-features {
  display: grid;
  gap: 8px;
  margin-bottom: 32px;
}
.sol-features li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 13px;
  color: var(--fg-2);
  line-height: 1.5;
  list-style: none;
}
.sol-features svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  margin-top: 4px;
  color: var(--prism-stop-teal);
}
.sol-features ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}
.sol-metrics {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
  padding-top: 24px;
  border-top: 1px solid var(--border-1);
  /* Pin to the bottom of the text column: when the media column is the taller
     one, the trailing slack collects above this footer row rather than below
     it, so the text column reaches the same bottom edge as the media card. When
     the text column is the taller one there is no slack and this is inert. */
  margin-top: auto;
}
.sol-metrics > div .kpi {
  font-family: var(--font-sans);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.sol-metrics > div .label {
  font-size: 10px;
  color: var(--fg-3);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-top: 2px;
}

/* ---- Mobile bottom-sheet selector --------------------------------------
   Desktop keeps the vertical tab list; these parts are inert until the
   mobile breakpoint below activates them. Kept as an additive layer so the
   desktop layout and the JS render logic are untouched. */
.sol-select-trigger,
.sol-sheet-handle,
.sol-sheet-backdrop {
  display: none;
}
.sol-tab-check {
  display: none;
}

@media (max-width: 1024px) {
  /* The list leaves normal flow and becomes an overlay, so the container is
     just trigger-card + panel stacked. */
  .sol-tabs {
    display: block;
  }

  /* The trigger card already shows the solution name + domain, so the panel's
     own eyebrow (domain) and title repeat it — hide them on mobile to cut noise. */
  .sol-panel > div > .eyebrow,
  .sol-panel > div > h3 {
    display: none;
  }

  /* Trigger card — shows the active solution + a chevron. */
  .sol-select-trigger {
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    margin-bottom: 24px;
    padding: 16px 16px;
    border-radius: 14px;
    border: 1px solid transparent;
    background: var(--bg-elevated);
    font-family: inherit;
    color: var(--fg-1);
    text-align: left;
    cursor: pointer;
    position: relative;
  }
  .sol-select-trigger::before {
    content: '';
    position: absolute;
    inset: 0;
    padding: 1px;
    border-radius: inherit;
    background: var(--prism);
    opacity: 0.55;
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
  }
  .sol-select-trigger .sol-tab-icon {
    background: var(--prism);
    color: #fff;
  }
  .sol-select-chevron {
    margin-left: auto;
    color: var(--fg-3);
    transition: transform 200ms ease;
  }
  .sol-tabs.sheet-open .sol-select-chevron {
    transform: rotate(180deg);
  }

  /* Dimmed backdrop behind the sheet. */
  .sol-sheet-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(0, 0, 0, 0.6);
    opacity: 0;
    pointer-events: none;
    transition: opacity 240ms ease;
  }
  .sol-tabs.sheet-open .sol-sheet-backdrop {
    opacity: 1;
    pointer-events: auto;
  }

  /* The same tab list, now anchored to the bottom as a sheet. */
  .sol-tab-list {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 201;
    margin-inline: auto;
    max-width: 560px;
    max-height: 82vh;
    overflow-y: auto;
    gap: 2px;
    padding: 8px 12px calc(16px + env(safe-area-inset-bottom));
    background: var(--bg-panel);
    border: 1px solid var(--border-1);
    border-radius: 22px 22px 0 0;
    box-shadow: var(--shadow-3);
    transform: translateY(100%);
    visibility: hidden;
    transition:
      transform 300ms cubic-bezier(0.32, 0.72, 0, 1),
      visibility 0s linear 300ms;
  }
  .sol-tabs.sheet-open .sol-tab-list {
    transform: translateY(0);
    visibility: visible;
    transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  .sol-sheet-handle {
    display: block;
    width: 40px;
    height: 4px;
    margin: 8px auto 12px;
    border-radius: 99px;
    background: var(--border-2);
  }

  /* Rows inside the sheet: highlight the active one + reveal its check. */
  .sol-tab {
    border-radius: 12px;
  }
  .sol-tab[aria-selected='true'] {
    background: color-mix(in srgb, var(--prism-stop-violet) 16%, transparent);
    border-color: transparent;
  }
  .sol-tab[aria-selected='true']::before {
    display: none;
  }
  .sol-tab[aria-selected='true'] .sol-tab-check {
    display: flex;
    align-items: center;
    margin-left: auto;
    color: var(--prism-stop-teal);
  }
}

.testimonial {
  position: relative;
  padding: var(--card-pad);
  border-radius: 16px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--border-1);
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.testimonial::before {
  content: '';
  position: absolute;
  inset: 0;
  padding: 1px;
  border-radius: inherit;
  background: var(--prism);
  opacity: 0.4;
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.testimonial-quote-mark {
  font-family: var(--font-sans);
  font-size: 56px;
  line-height: 1;
  background: var(--prism);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-style: italic;
}
.testimonial-quote {
  font-family: var(--font-sans);
  font-size: 18px;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--fg-1);
  font-weight: 500;
  flex: 1;
}
.testimonial-attr {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid var(--border-1);
}
/* Name/role block: grow to fill the row, and min-width:0 lets long text
   truncate inside the flex row instead of overflowing. */
.testimonial-attr-text {
  flex: 1;
  min-width: 0;
}
.testimonial-avatar {
  width: 40px;
  height: 40px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.06);
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 13px;
  color: var(--fg-1);
  border: 1px solid var(--border-2);
}
.testimonial-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--fg-1);
}
.testimonial-role {
  font-size: 11px;
  color: var(--fg-3);
  letter-spacing: 0.04em;
}
.testimonial-source {
  font-size: 11px;
  color: var(--fg-3);
  opacity: 0.7;
  margin-top: 2px;
  font-style: italic;
}

.photo-carousel {
  padding: 16px;
  gap: 16px;
}
/* ---- Carousel viewport sizing ------------------------------------------
   Takes the active image's ratio (--photo-ratio, set by JS) but floors it at
   --sol-min-ratio, so portrait phone shots (~0.5) don't tower over the wider
   dashboards (~0.72). A floored box letterboxes into the transparent ground;
   the 72vh cap guards short viewports.

   Raise --sol-min-ratio to the widest image to make every box identical;
   lower it toward 0 to let tall shots run full height. */
.carousel-viewport {
  position: relative;
  width: 100%;
  /* Touch (mobile/tablet): let the press-and-hold pause gesture work without
     triggering the browser's native image long-press (callout menu, drag,
     text selection), which would otherwise swallow the next tap. */
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  --sol-min-ratio: 0.72;
  /* Tablet box shape (see the tablet rule below). Smaller number = taller box
     = the image renders BIGGER and fills more of the cell. ~0.62 fills most of
     the image column; raise toward --sol-min-ratio for a shorter box. */
  --sol-tablet-ratio: 0.62;
  aspect-ratio: max(var(--photo-ratio, 0.75), var(--sol-min-ratio));
  max-height: 75vh;
  min-height: 0;
  border-radius: 12px;
  overflow: hidden;
  background: transparent;
}
/* Tablet: same "floor" logic as the base rule, but a taller floor. It only
   reins in the very tall phone screenshots (ratio ~0.5) — pulling them up to
   --sol-tablet-ratio so they render big without towering — while the wider
   dashboards (Vendor/Banking, ~0.72+) stay above the floor and keep their own
   native ratio, so they're never stretched too long. Not a uniform box (which
   would distort one group), but each image renders at a shape that suits it.
   Scoped to the two-column tablet range; quote-only panels are unaffected. */
@media (min-width: 768px) and (max-width: 1024px) {
  .carousel-viewport {
    aspect-ratio: max(var(--photo-ratio, 0.75), var(--sol-tablet-ratio));
  }
}
/* Fill-to-bottom for the dashboard carousels. The media box is sized by the
   image's own ratio (above), so when the text column is the taller one the card
   (stretched to the panel height by the grid) would leave the image floating at
   the top. Letting the viewport grow into that extra space (flex-basis auto
   keeps the ratio-derived height as its natural size, so tall images still push
   the panel — only the leftover gap is absorbed) centres the contained image in
   the taller box: no letterbox floor beyond --sol-min-ratio, no crop, nothing
   forced. Scoped away from .has-quote, which drives its own height from the
   quote card and is handled below. From tablet up only — on mobile the panel is
   a single column, so there is no sibling column to match. */
@media (min-width: 768px) {
  .sol-panel > .photo-carousel:not(.has-quote) .carousel-viewport {
    flex: 1 1 auto;
  }
}
/* Quote-led carousel: a quote slide has no image ratio, so let the quote sit in
   normal flow and define the shared viewport height — the photos fill it. This
   overrides the ratio box above (which would otherwise clip a long quote and
   its "Source:" attribution). */
.photo-carousel.has-quote .carousel-viewport {
  aspect-ratio: auto;
  height: auto;
  min-height: 0;
  max-height: none;
}
.photo-carousel.has-quote .carousel-slide--quote {
  position: relative;
  height: auto;
  inset: auto;
}
/* Stretch the quote+image box to fill the panel cell instead of sitting at the
   top with an empty band below when the text column is the taller one. The grid
   row is already at least as tall as the quote's natural height, so stretching
   never clips the quote — when the quote is the taller column this is a no-op.
   The viewport becomes a flex column so the quote card grows to the bottom. From
   tablet up (same floor as the dashboard carousels); on mobile the panel is a
   single column, so there is no sibling to match. The card is stretched to the
   row height by the grid; these rules let the quote card grow into it. */
@media (min-width: 768px) {
  .photo-carousel.has-quote .carousel-viewport {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  .photo-carousel.has-quote .carousel-slide--quote {
    flex: 1;
  }
}
.carousel-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  opacity: 0;
  z-index: 0;
  /* The touch gesture is handled on the viewport; the image itself shouldn't
     be independently draggable/selectable on touch. */
  -webkit-user-drag: none;
  pointer-events: none;
}
.carousel-slide.is-active.is-loaded {
  opacity: 1;
}
/* object-fit mirrors the photo's `fit` value (emitted as data-fit in app.js).
   Each solution's `fit` in the data is the single control for its image:
   'contain' letterboxes, 'cover' crops to fill, 'fill' stretches to fill. */
.carousel-slide[data-fit='contain'] {
  object-fit: contain;
  object-position: center;
}
.carousel-slide[data-fit='cover'] {
  object-fit: cover;
}
.carousel-slide[data-fit='fill'] {
  object-fit: fill;
}
/* Quote card rendered as a carousel slide (e.g. a partner testimonial shown
   before the product screenshot), at the same size/font as the standalone
   testimonials. It fills the viewport like any other slide; the flex:1 on the
   quote body pushes the attribution to the bottom. */
.carousel-slide--quote {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: var(--card-pad);
  background: var(--surface-well);
  object-fit: unset;
}
/* Mobile: tighten the quote and image container frames. Once the solutions
   panel drops to a single column, the desktop padding crowds these boxes.
   .photo-carousel is listed after .testimonial so its tighter image frame
   still wins (equal specificity, later rule). */
@media (max-width: 767px) {
  .photo-carousel {
    padding: 8px;
  }
}
/* Shimmer loading placeholder for the solutions carousel — a standalone element
   sized by JS. Uses the same opaque --surface-well base as .media-skeleton so
   both skeletons read as one navy well; the white-alpha border-token shimmer
   then sweeps over that navy rather than over the translucent viewport backdrop
   (which would wash it out to a greyer, darker tone). */
.carousel-skeleton {
  pointer-events: none;
  background-color: var(--surface-well);
  background-image: linear-gradient(
    100deg,
    transparent 30%,
    var(--border-2) 50%,
    transparent 70%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
  position: absolute;
  inset: 0;
  z-index: 1;
}
.carousel-skeleton.is-hidden {
  opacity: 0;
}
@keyframes skeleton-shimmer {
  0% {
    background-position: 150% 0;
  }
  100% {
    background-position: -50% 0;
  }
}

/* Reusable image/video/iframe skeleton. Add .media-skeleton to an
   already-positioned, overflow-clipped media wrapper; initMediaSkeletons()
   (app.js) adds .is-loaded when the media settles, .is-error on failure. The
   media stays hidden until fully loaded so a half-decoded frame never shows
   beside the shimmer, and the ::after fill must stay opaque or the tinted wells
   behind it bleed through. `isolation` keeps it under sibling overlays (play
   buttons, badges). No app.js on the page means no reveal — don't use it there. */
.media-skeleton {
  isolation: isolate;
}
.media-skeleton > img,
.media-skeleton > video,
.media-skeleton > iframe {
  opacity: 0;
  transition: opacity 300ms ease;
}
.media-skeleton.is-loaded > img,
.media-skeleton.is-loaded > video,
.media-skeleton.is-loaded > iframe {
  opacity: 1;
}
.media-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-color: var(--surface-well);
  background-image: linear-gradient(
    100deg,
    transparent 30%,
    var(--border-2) 50%,
    transparent 70%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
  transition: opacity 300ms ease;
}
.media-skeleton.is-loaded::after {
  opacity: 0;
}
.carousel-attr {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding-top: 4px;
}
.carousel-dots {
  display: flex;
  gap: 8px;
}
.carousel-dot {
  position: relative;
  width: 6px;
  height: 6px;
  border-radius: 99px;
  border: none;
  background: var(--border-2);
  cursor: pointer;
  padding: 0;
  transform: scale(var(--dot-scale, 1));
  transform-origin: center;
  transition:
    transform 90ms ease-out,
    background 100ms ease,
    width 50ms ease;
}

.carousel-dot::before {
  content: '';
  position: absolute;
  inset: -9px;
  border-radius: inherit;
}
.carousel-dot:hover {
  background: var(--fg-2);
}
.carousel-dot.is-active {
  background: var(--prism-stop-teal, var(--fg-1));
  width: 16px;
}
@media (prefers-reduced-motion: reduce) {
  .carousel-dot {
    transform: none;
    transition: background 100ms ease;
  }
}

/* ============================================================
   PARTNERS + CERTS
   ============================================================ */
.split-pc {
  display: grid;
  grid-auto-rows: auto;
  gap: 16px;
  margin-top: 28px;
}
@media (max-width: 1024px) {
  .split-pc {
    grid-template-columns: 1fr;
  }
}
/* Fine-print note under the partners/certs tiles (de-inlined from HTML). */
.partner-note {
  margin-top: 16px;
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.55;
}
.partner-note strong {
  color: var(--fg-2);
}
.tile {
  padding: var(--card-pad);
  border-radius: 20px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
  position: relative;
  overflow: hidden;
}
.tile h3 {
  font-family: var(--font-sans);
  font-size: 26px;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}
.tile > .sub {
  color: var(--fg-2);
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 24px;
  max-width: 400px;
}
.partner-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
@media (max-width: 1024px) {
  .partner-grid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 767px) {
  .partner-grid {
    grid-template-columns: 1fr;
  }
}
.partner {
  padding: 16px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--border-1);
  transition:
    border-color 180ms ease,
    background 180ms ease;
}
.partner:hover {
  border-color: var(--border-2);
}
.partner-name {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.005em;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.partner-name .tier {
  margin-left: auto;
  /* Obra primary badge */
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.5;
  padding: 2px 8px;
  border-radius: var(--r-md);
  background: var(--fg-1);
  color: var(--bg-panel);
}
.partner-desc {
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.5;
  margin-top: 16px;
}
.cert-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.cert-grid + .cert-grid-5 {
  margin-top: 12px;
}
.cert-grid-5 {
  grid-template-columns: repeat(5, 1fr);
}
.cert-top-row {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-bottom: 12px;
}
.cert-top-row .cert {
  width: calc((100% - 12px) / 2);
}

@media (max-width: 1024px) {
  .cert-grid {
    grid-template-columns: 1fr 1fr;
  }
  .cert-grid-5 {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 767px) {
  .cert-grid,
  .cert-grid-5 {
    grid-template-columns: 1fr;
  }
  .cert-top-row {
    flex-direction: column;
  }
  .cert-top-row .cert {
    width: 100%;
  }
}
.cert {
  padding: 16px 16px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--border-1);
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 92px;
}
.cert-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.06);
  font-family: var(--font-mono), monospace;
  font-weight: 700;
  font-size: 11px;
  color: var(--fg-1);
}
.cert-text {
  min-width: 0;
}
.cert-name {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.2;
}
.cert-meta {
  font-size: 11px;
  color: var(--fg-3);
  letter-spacing: 0.04em;
  margin-top: 2px;
}
.cert-progress {
  /* Obra warning status badge */
  display: inline-flex;
  align-items: center;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.5;
  padding: 2px 8px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--warning) 18%, transparent);
  color: var(--warning);
  margin-left: auto;
  flex-shrink: 0;
  border: 1px solid transparent;
}

/* ============================================================
   TECH HUBS / SKILLS MATRIX
   ============================================================ */
.tech-matrix {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}
@media (max-width: 767px) {
  .tech-matrix {
    grid-template-columns: 1fr;
  }
}
.tech-cat {
  padding: var(--card-pad);
  border-radius: 16px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
  position: relative;
}
.tech-cat-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}
.tech-cat-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  display: grid;
  place-items: center;
  color: var(--prism-stop-teal);
}
.tech-cat-icon svg {
  width: 18px;
  height: 18px;
}
.tech-cat h4 {
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0;
}
.tech-cat > .meta {
  font-size: 11px;
  color: var(--fg-3);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 20px 48px;
}

/* tech hub content + sidebar "we provide" */
.tech-hubs-layout {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 40px;
  align-items: stretch;
}
@media (max-width: 1024px) {
  .tech-hubs-layout {
    grid-template-columns: 1fr;
  }
}

.provide-panel {
  display: flex;
  flex-direction: column;
  padding: var(--card-pad-feature);
  border-radius: 20px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
}
.provide-panel h3 {
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 700;
  margin: 0 0 24px;
  color: var(--fg-1);
}
.provide-list {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1;
  gap: 24px;
}
/* On tablet the tech-hubs layout stacks, so this panel spans the full width
   and its single column would run tall. Flow the items into two columns to
   fill both sides. Phones stay single-column (too narrow to split). */
@media (min-width: 768px) and (max-width: 1024px) {
  .provide-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-content: start;
    column-gap: 40px;
    row-gap: 24px;
  }
}
.provide-item {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}
.provide-icon {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.05);
  color: var(--prism-stop-teal);
}
.provide-icon svg {
  width: 16px;
  height: 16px;
}
.provide-text h5 {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 4px;
  color: var(--fg-1);
}
.provide-text p {
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.55;
  color: var(--fg-3);
  margin: 0;
}

/* ============================================================
   SERVICES (Run / Managed)
   ============================================================ */
.svc-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
@media (max-width: 1024px) {
  .svc-grid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 767px) {
  .svc-grid {
    grid-template-columns: 1fr;
  }
}

.svc {
  padding: var(--card-pad);
  border-radius: 16px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
  position: relative;
  overflow: hidden;
  transition:
    border-color 200ms ease,
    transform 200ms ease;
}
.svc:hover {
  border-color: var(--border-2);
  transform: translateY(-2px);
}
.svc.featured {
  grid-column: span 2;
  background:
    radial-gradient(
      ellipse 500px 240px at 0% 100%,
      color-mix(in srgb, var(--prism-stop-violet) 18%, transparent),
      transparent 70%
    ),
    linear-gradient(
      180deg,
      rgba(255, 255, 255, 0.05),
      rgba(255, 255, 255, 0.01)
    );
}
@media (max-width: 767px) {
  .svc.featured {
    grid-column: span 1;
  }
}
.svc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 24px;
}
.svc-num-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.svc-num {
  /* Obra ghost badge — the SRV / NN counter */
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.025em;
  color: var(--fg-3);
}
.svc-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background:
    linear-gradient(var(--bg-panel), var(--bg-panel)) padding-box,
    var(--prism) border-box;
  border: 1.5px solid transparent;
  display: grid;
  place-items: center;
  color: var(--fg-1);
}
.svc-icon svg {
  width: 20px;
  height: 20px;
}
.svc h4 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.015em;
  line-height: 1.15;
  margin: 16px 0 8px;
}
.svc.featured h4 {
  font-size: 28px;
}
.svc-tag {
  /* Obra secondary badge */
  display: inline-flex;
  align-items: center;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.5;
  padding: 3px 8px;
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  color: var(--fg-1);
  margin-bottom: 12px;
  text-transform: none;
}
.svc-grid .svc .svc-tag {
  background: rgba(126, 40, 245, 0.14);
  border: 1px solid rgba(126, 40, 245, 0.4);
  color: var(--fg-1);
}
.svc p {
  font-size: 13px;
  color: var(--fg-2);
  line-height: 1.55;
  margin: 0 0 16px;
}

/* ============================================================
   LOCAL IMPACT
   ============================================================ */
.impact-grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 32px;
  align-items: stretch;
}
@media (max-width: 1024px) {
  .impact-grid {
    grid-template-columns: 1fr;
  }
}

.impact-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  height: 100%;
}
@media (max-width: 767px) {
  .impact-cards {
    grid-template-columns: 1fr;
  }
}
.impact-card {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding: var(--card-pad);
  border-radius: 16px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
}
.impact-card-num {
  font-family: var(--font-sans);
  font-size: 40px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--fg-1);
  margin-bottom: 16px;
}
.impact-card-label {
  font-size: 16px;
  font-weight: 600;
  color: var(--fg-1);
  margin-bottom: 8px;
}
.impact-card-sub {
  font-size: 13px;
  color: var(--fg-3);
  line-height: 1.55;
  letter-spacing: 0.02em;
}
.impact-card--feature {
  background:
    radial-gradient(
      ellipse 320px 220px at 100% 100%,
      color-mix(in srgb, var(--prism-stop-violet) 22%, transparent),
      transparent 70%
    ),
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--prism-stop-violet) 10%, transparent),
      color-mix(in srgb, var(--prism-stop-violet) 3%, transparent)
    );
  border-color: color-mix(in srgb, var(--prism-stop-violet) 30%, transparent);
}
.impact-card-icon {
  color: var(--prism-stop-violet);
  margin-bottom: 16px;
}
.impact-card-icon svg,
.impact-card-icon i {
  width: 26px;
  height: 26px;
}

.impact-manifesto {
  padding: var(--card-pad);
  border-radius: 20px;
  border: 1px solid var(--border-1);
  background: var(--surface-card-gradient);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: stretch;
  gap: 24px;
}
.impact-manifesto::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 400px 200px at 100% 0%,
    color-mix(in srgb, var(--prism-stop-teal) 18%, transparent),
    transparent 60%
  );
  pointer-events: none;
}
.impact-manifesto > * {
  position: relative;
}
@media (max-width: 767px) {
  .impact-manifesto {
    flex-direction: column;
  }
}
.impact-manifesto-content {
  flex: 1 1 56%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  padding-bottom: 48px;
}
.impact-manifesto h3 {
  font-family: var(--font-sans);
  font-size: 28px;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 12px 0 12px;
}
.impact-manifesto p {
  color: var(--fg-2);
  font-size: 14px;
  line-height: 1.65;
  margin: 0 0 16px;
}
.impact-manifesto p:last-of-type {
  margin-bottom: 0;
}

.impact-quote {
  margin: 4px 0 16px;
  padding: 16px 16px;
  border-left: 2px solid var(--prism-stop-violet);
  background: rgba(255, 255, 255, 0.03);
  border-radius: 0 10px 10px 0;
}
.impact-quote p {
  font-style: italic;
  color: var(--fg-1);
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 8px;
}
.impact-quote cite {
  font-style: normal;
  font-size: 12px;
  color: var(--fg-3);
}

.impact-manifesto-meta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--fg-3);
  display: flex;
  align-items: center;
  gap: 12px;
}
.impact-manifesto-meta-icon {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  flex-shrink: 0;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: rgba(36, 178, 179, 0.12);
  border: 1px solid rgba(36, 178, 179, 0.35);
  color: #24b2b3 !important;
}
.impact-manifesto-meta-icon svg,
.impact-manifesto-meta-icon i {
  width: 14px;
  height: 14px;
}

.impact-video {
  flex: 1 1 38%;
  max-width: 300px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--border-1);
  background: var(--neutral-950);
}
.impact-video video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--neutral-950);
}

@media (max-width: 767px) {
  .impact-video {
    flex: none;
    max-width: 100%;
  }
  .impact-video video {
    height: auto;
  }
}

/* ----- R&D / Researchers ----- */
.rnd {
  margin-top: 56px;
  padding: var(--card-pad-feature);
  border-radius: 24px;
  border: 1px solid var(--border-1);
  background:
    radial-gradient(
      ellipse 600px 280px at 0% 0%,
      color-mix(in srgb, var(--prism-stop-pink) 10%, transparent),
      transparent 60%
    ),
    radial-gradient(
      ellipse 600px 280px at 100% 100%,
      color-mix(in srgb, var(--prism-stop-teal) 10%, transparent),
      transparent 60%
    ),
    var(--surface-card-gradient);
  position: relative;
  overflow: hidden;
}
.rnd-list {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 16px;
}
@media (max-width: 1024px) {
  .rnd-list {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 767px) {
  .rnd-list {
    grid-template-columns: 1fr;
  }
}

/* Standalone researcher card below the team grid (de-inlined spacer). */
.researcher-solo {
  margin-top: 16px;
}
.researcher {
  padding: var(--card-pad);
  border-radius: 14px;
  border: 1px solid var(--border-1);
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition:
    border-color 200ms ease,
    transform 200ms ease;
}
.researcher:hover {
  border-color: color-mix(in srgb, var(--prism-stop-violet) 40%, transparent);
  transform: translateY(-2px);
}
.researcher-avatar {
  width: 48px;
  height: 48px;
  border-radius: 99px;
  padding: 1px;
  background: var(--prism);
  display: flex;
  align-items: center;
  justify-content: center;
}
.researcher-avatar img {
  width: 100%;
  height: 100%;
  border-radius: inherit;
  object-fit: cover;
  display: block;
}
.researcher-avatar [data-icon] {
  width: 22px;
  height: 22px;
  color: var(--neutral-0);
}
.researcher-avatar [data-icon] svg {
  width: 100%;
  height: 100%;
}

.researcher-solo-head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.researcher-avatar-icon {
  border: 1px solid transparent;
  background:
    linear-gradient(var(--neutral-750), var(--neutral-750)) padding-box,
    var(--prism) border-box;
}
.researcher-name {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.researcher-role {
  font-size: 11px;
  color: var(--prism-stop-teal);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
}
.researcher-bio {
  font-size: 12px;
  color: var(--fg-2);
  line-height: 1.55;
}

.rnd-conf {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--border-1);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  font-size: 12px;
  color: var(--fg-3);
}
.rnd-conf-label {
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
}
.rnd-conf-pill {
  /* Obra outline badge — round */
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.5;
  padding: 3px 12px;
  border-radius: var(--r-pill);
  background: transparent;
  border: 1px solid var(--border-1);
  color: var(--fg-2);
}

/* Expertise cloud collapses on mobile behind an inline "+N more" pill.
   The toggle reuses .rnd-conf-pill so it looks identical to the badges;
   only its collapse visibility and click affordance live here. Both the
   overflow hide and the toggle only take effect at the mobile breakpoint,
   so desktop shows the full cloud with no override. The cap is owned by
   rnd.js (which tags overflow pills); CSS carries no count. */
.rnd-conf-toggle {
  display: none;
}
@media (max-width: 767px) {
  .rnd-conf.is-clamped .rnd-conf-pill--overflow {
    display: none;
  }
  .rnd-conf-toggle {
    font-family: var(--font-sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: -0.025em;
    line-height: 1.5;
    padding: 3px 12px;
    border-radius: var(--r-pill);
    background: transparent;
    border: none;
    color: var(--prism-stop-teal);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    transition: background 140ms ease;
  }
  .rnd-conf-toggle:hover {
    background: transparent;
  }
}

/* ============================================================
   CTA / footer
   ============================================================ */
.cta-block {
  margin: 80px 0 0;
  padding: 80px 56px;
  border-radius: 32px;
  border: 1px solid var(--border-1);
  position: relative;
  overflow: hidden;
  text-align: center;
  background:
    radial-gradient(
      ellipse 600px 300px at 50% 100%,
      color-mix(in srgb, var(--prism-stop-violet) 28%, transparent),
      transparent 70%
    ),
    radial-gradient(
      ellipse 800px 400px at 50% 0%,
      color-mix(in srgb, var(--prism-stop-teal) 16%, transparent),
      transparent 70%
    ),
    rgba(0, 0, 0, 0.4);
}
@media (max-width: 767px) {
  .cta-block {
    padding: 56px 24px;
  }
}
.cta-block::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(
    ellipse 400px 200px at 50% 50%,
    transparent 30%,
    #000 90%
  );
  -webkit-mask-image: radial-gradient(
    ellipse 400px 200px at 50% 50%,
    transparent 30%,
    #000 90%
  );
  opacity: 0.6;
  pointer-events: none;
}
.cta-block > * {
  position: relative;
}
.cta-block h2 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 12px 0 16px;
}
.cta-block p {
  color: var(--fg-2);
  margin: 0 auto 32px;
  max-width: 550px;
  font-size: 16px;
  line-height: 1.6;
}
.cta-block .ctas {
  display: inline-flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

.footer {
  padding: 0 0 32px;
  /* Fluid: ~48px on phones, up to 80px on desktop — matches section rhythm. */
  margin-top: clamp(48px, 6vw, 80px);
}
/* Brand takes the left, the two short link columns sit close together in
   the middle (content-width, one gap apart), and the trailing 1fr track
   plus justify-self:end pushes Certified out to the right edge — the wide
   gap the design calls for, without a hard-coded margin. */
.footer-grid {
  display: grid;
  grid-template-columns: minmax(300px, 360px) auto auto 1fr;
  gap: 40px;
  margin-bottom: 40px;
}
.footer-col--certified {
  justify-self: end;
}
/* Tablet / mobile: the brand block sits full-width on top, the two short
   link columns (Let's Connect / Follow Us) share a row, and the wider
   Certified column drops full-width beneath them. Spanning the brand and
   certified columns keeps the middle pair evenly sized without per-column
   width overrides. */
@media (max-width: 1024px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
    gap: 32px 40px;
  }
  .footer-col--brand,
  .footer-col--certified {
    grid-column: 1 / -1;
  }
  .footer-col--certified {
    justify-self: start;
  }
}

.footer-col h5 {
  font-size: 11px;
  color: var(--fg-3);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin: 0 0 16px;
  font-weight: 600;
}
.footer-col a {
  display: block;
  color: var(--fg-2);
  text-decoration: none;
  font-size: 13px;
  padding: 4px 0;
  transition: color 120ms ease;
}
.footer-col a:hover {
  color: var(--fg-1);
}
.footer-blurb {
  color: var(--fg-3);
  font-size: 13px;
  line-height: 1.6;
  margin: 16px 0 24px;
  max-width: 340px;
}
.footer-address {
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.6;
}

/* Follow Us — circular icon buttons. The <a> is the sized target; the
   hydrated SVG inherits currentColor, so hover only needs to shift color. */
.footer-social {
  display: flex;
  gap: 12px;
}
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border-1);
  color: var(--fg-2);
  transition:
    color 120ms ease,
    background 120ms ease,
    border-color 120ms ease;
}
.footer-social a:hover {
  color: var(--fg-1);
  background: rgba(255, 255, 255, 0.1);
  border-color: var(--border-2, var(--border-1));
}

/* Certified — badge artwork sits on its own light backing, so it renders
   flat with matched visual heights rather than the seal being oversized. */
.footer-badges {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.footer-badge {
  display: block;
  width: auto;
}
.footer-badge--iso {
  height: 72px;
}
.footer-badge--cmmi {
  height: 64px;
}

/* Acknowledgment line + policy links share one row above the divider; the
   copyright meta closes the footer beneath. */
.footer-legal {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px 48px;
  flex-wrap: wrap;
  margin-bottom: 20px;
  padding-top: 28px;
  border-top: 1px solid var(--border-1);
}
.footer-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--fg-3);
}
.footer-note a {
  color: var(--fg-2);
  text-decoration: none;
  transition: color 120ms ease;
}
.footer-note a:hover {
  color: var(--fg-1);
}
.footer-policies {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 20px;
  flex-shrink: 0;
}
.footer-policies a {
  color: var(--fg-2);
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 120ms ease;
}
.footer-policies a:hover {
  color: var(--fg-1);
}
.footer-meta {
  font-size: 12px;
  color: var(--fg-3);
}
@media (max-width: 767px) {
  .footer-legal {
    flex-direction: column;
    gap: 16px;
  }
}

/* ============================================================
   utility, animations
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 700ms ease,
    transform 700ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
.reveal.in {
  opacity: 1;
  transform: none;
}
/* ============================================================
   COOKIE CONSENT
   A dismissible bottom banner injected once by app.js on every page.
   It is position:fixed, so it overlays the layout without displacing
   any other element — nothing else needs to know it exists, and new
   pages/sections inherit it for free. Styling reuses the shared tokens
   and the .btn system, so no overrides or !important are required.
   ============================================================ */
/* While the banner is shown, app.js publishes its measured height here and
   the page reserves that much space at the bottom, so fixed-position banner
   never overlaps the footer (Terms of Use et al.). The var resets to 0 on
   dismiss, releasing the space. Transitioned so it moves with the slide-out. */
body {
  padding-bottom: var(--cookie-consent-height, 2px);
  transition: padding-bottom 260ms ease;
}

.cookie-consent {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300; /* above page content + sticky nav (100), below full-screen modals (9999) */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s-4) var(--s-6);
  padding: var(--s-4) var(--s-5) calc(var(--s-4) + env(safe-area-inset-bottom));
  background: var(--bg-panel);
  border-top: 1px solid var(--border-1);
  box-shadow: var(--shadow-3);
  /* Resting (hidden) state — revealed when app.js adds .is-visible on the
     next frame so the entry transition (slide up + fade) actually plays. */
  opacity: 0;
  transform: translateY(100%);
  transition:
    opacity 260ms ease,
    transform 260ms ease;
}
.cookie-consent.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.cookie-consent__text {
  flex: 1 1 420px;
  max-width: 760px;
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--fg-2);
  margin: 0;
}
/* Deliberately understated link — muted foreground, revealed on hover/focus. */
.cookie-consent__link {
  color: var(--fg-3);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 140ms ease;
}
.cookie-consent__link:hover,
.cookie-consent__link:focus-visible {
  color: var(--fg-1);
}
.cookie-consent__actions {
  display: flex;
  gap: var(--s-2);
  flex-shrink: 0;
}

@media (prefers-reduced-motion: reduce) {
  .cookie-consent,
  .cookie-consent.is-visible {
    transition: opacity 260ms ease;
    transform: none;
  }
  body {
    transition: none;
  }
}
