/* 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);
}

/* minmax(0, 1fr) rather than bare 1fr throughout this file is
   deliberate, not decorative: a bare `fr` track's minimum size defaults
   to `auto`, which means it refuses to shrink narrower than its content's
   longest unbreakable run (a long word, an un-wrapping tag/button) —
   that's what silently causes "impossible" horizontal overflow on narrow
   screens even when every explicit width in a layout looks correct and a
   breakpoint exists. minmax(0, 1fr) removes that floor so tracks actually
   honor the fr ratio and content wraps/shrinks instead of forcing the
   grid wider than its container. */
.grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

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

@media (max-width: 640px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: minmax(0, 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: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: var(--space-3xl);
  align-items: center;
}

/* Use when one column is much taller than the other (e.g. a long article
   next to a short sidebar card) — keeps the shorter column pinned to the
   top instead of floating in the vertical middle of the tall one. */
.split-top {
  align-items: start;
}

@media (max-width: 900px) {
  .split {
    grid-template-columns: minmax(0, 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: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--space-xl);
}

@media (max-width: 640px) {
  .segment-card {
    grid-template-columns: minmax(0, 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);
  /* Bottom padding clears the fixed chatbot bubble (56px tall, offset
     --space-lg from the viewport bottom) so the last footer row never
     sits behind it once the page is scrolled all the way down. */
  padding-block: var(--space-3xl) calc(var(--space-lg) * 2 + 56px);
}

.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: minmax(0, 1.4fr) repeat(3, minmax(0, 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: minmax(0, 1fr) minmax(0, 1fr);
  }
}

@media (max-width: 560px) {
  .footer-grid {
    grid-template-columns: minmax(0, 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;
}
