/* Structural layout: containers, grids, header/footer shells, section rhythm */

.container {
  width: 100%;
  max-width: var(--container-w);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section {
  padding-block: var(--section-pad-y);
}

.section-alt {
  background: var(--bg-alt);
}

.section-inverse {
  background: var(--bg-inverse);
  color: var(--text-inverse);
}
.section-inverse p {
  color: var(--text-inverse-muted);
}
.section-inverse h1,
.section-inverse h2,
.section-inverse h3,
.section-inverse h4 {
  color: var(--text-inverse);
}

.section-head {
  max-width: 640px;
  margin-bottom: var(--space-2xl);
}

.section-head.center {
  margin-inline: auto;
  text-align: center;
}

.grid {
  display: grid;
  gap: var(--space-lg);
}

.grid-2 {
  grid-template-columns: repeat(2, 1fr);
}
.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}
.grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 960px) {
  .grid-3,
  .grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }
}

.cluster {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.stack {
  display: flex;
  flex-direction: column;
}

.split {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--space-3xl);
  align-items: center;
}

@media (max-width: 900px) {
  .split {
    grid-template-columns: 1fr;
    gap: var(--space-xl);
  }
}

/* Two-column card layout (label + description), e.g. the segment cards
   on industries.html. Was previously inline styles with no mobile
   breakpoint, which caused horizontal overflow on phones — grid items
   don't shrink below their content's intrinsic width by default, so a
   fixed 1fr/2fr split just pushed the card wider than the viewport
   instead of wrapping. */
.segment-card {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: var(--space-xl);
}

@media (max-width: 640px) {
  .segment-card {
    grid-template-columns: 1fr;
    gap: var(--space-sm);
  }
}

/* ---- Site header ---- */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom: 1px solid var(--surface-border);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  height: 76px;
}

.primary-nav {
  display: flex;
  align-items: center;
  gap: var(--space-2xl);
}

.primary-nav ul {
  display: flex;
  gap: var(--space-xl);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Element-qualified selector (button.nav-toggle, not just .nav-toggle) is
   deliberate: this button also carries the .btn-icon class, which sets
   `display: inline-grid` unconditionally. Both rules are equal-specificity
   single-class selectors otherwise, so whichever stylesheet happens to be
   linked later in <head> wins — components.css (btn-icon) loads after
   layout.css, so it silently overrode this at every screen width, not just
   mobile, leaving the hamburger button visible (and inert, since the
   mobile-nav-open CSS only exists inside the media query below) on desktop
   too. The extra element-type selector raises specificity just enough to
   win regardless of file order. */
button.nav-toggle {
  display: none;
}

@media (max-width: 900px) {
  .primary-nav {
    position: fixed;
    top: 76px;
    left: 0;
    right: 0;
    /* An explicit height (not `bottom: 0` + auto height) — a fixed-position
       flex container with both top and bottom offsets set should stretch
       to fill the gap between them per spec, but in practice this combination
       (position:fixed + display:flex + inset shorthand) collapsed to the
       padding's height only, with zero content height, in testing. Height
       computed directly from the viewport sidesteps that entirely and is
       also more correct on mobile, where 100dvh tracks the actual visible
       area as the browser's address bar shows/hides (100vh does not). */
    height: calc(100vh - 76px);
    height: calc(100dvh - 76px);
    background: var(--bg);
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-xl) var(--container-pad);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease), transform var(--dur-base) var(--ease);
    overflow-y: auto;
  }

  .primary-nav[data-open="true"] {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }

  .primary-nav ul {
    flex-direction: column;
    gap: 0;
  }

  .primary-nav a {
    display: block;
    padding: var(--space-md) 0;
    font-size: var(--fs-lg);
    border-bottom: 1px solid var(--surface-border);
  }

  .nav-cta {
    margin-top: var(--space-xl);
  }

  button.nav-toggle {
    display: inline-flex;
  }
}

/* ---- Site footer ---- */

/* The footer always has a fixed dark background regardless of the
   page's light/dark theme, so its text uses fixed brand tokens
   (--ink-100 / --white) instead of the theme-relative --text-inverse-*
   tokens, which flip meaning in dark mode and would go near-invisible
   here. */
.site-footer {
  background: var(--ink-950);
  color: var(--ink-100);
  padding-block: var(--space-3xl) var(--space-xl);
}

.site-footer p {
  color: var(--ink-300);
}

.site-footer a {
  color: var(--ink-100);
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--white);
}

/* Same fixed-dark-background reasoning applies to the social icon
   badges: don't use the theme-reactive --surface-alt/--surface-border
   tokens here, or they wash out against the dark footer in light mode. */
.site-footer .btn-icon {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--ink-100);
}

.site-footer .btn-icon:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--white);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: var(--space-2xl);
  padding-bottom: var(--space-2xl);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

@media (max-width: 900px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 560px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

.footer-col h4 {
  color: var(--white);
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-md);
}

.footer-col ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-md);
  padding-top: var(--space-lg);
  font-size: var(--fs-sm);
}

/* ---- Page hero shell ---- */

.hero {
  position: relative;
  padding-block: clamp(4rem, 3rem + 5vw, 8rem) var(--space-3xl);
  overflow: hidden;
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gradient-hero);
  z-index: -1;
}

.page-hero {
  padding-block: clamp(3.5rem, 3rem + 3vw, 6rem) var(--space-2xl);
  position: relative;
  overflow: hidden;
}

.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gradient-hero);
  z-index: -1;
  opacity: 0.7;
}
