/* ==========================================================================
   Calanca — design system
   Rebuilt from the DotNetNuke original. Palette, type and section rhythm are
   carried over; markup, responsiveness and accessibility are not.
   ========================================================================== */

:root {
  /* Brand palette */
  --navy-900: #033249;
  --navy-800: #043249;
  --navy-600: #16516F;
  --teal: #1B998B;
  --teal-dark: #157A6F;
  --linkedin: #0A66C2;
  --grey-50: #F2F2F2;
  --grey-200: #E4E8EB;
  --grey-500: #6B7780;
  --ink: #2B3238;
  --ink-muted: #444;
  --white: #fff;

  /* Overlays */
  --overlay-teal: rgba(27, 153, 139, 0.88);
  --overlay-dark: rgba(3, 50, 73, 0.72);

  /* Feedback — the brand palette carries no red, and the contact form needs to
     be able to say a submission failed. Text tone is darkened off the border
     tone so it clears 4.5:1 on its own tint. */
  --error: #b3261e;
  --error-ink: #8c1d18;
  --error-bg: #fceeec;

  /* Type */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;

  /* Fluid type scale */
  --step--1: clamp(0.8125rem, 0.79rem + 0.11vw, 0.875rem);
  --step-0: clamp(0.9375rem, 0.91rem + 0.14vw, 1rem);
  --step-1: clamp(1.0625rem, 1.01rem + 0.28vw, 1.25rem);
  --step-2: clamp(1.25rem, 1.14rem + 0.55vw, 1.625rem);
  --step-3: clamp(1.625rem, 1.42rem + 1.02vw, 2.375rem);
  --step-4: clamp(2rem, 1.6rem + 2vw, 3.25rem);

  /* Spacing */
  --space-xs: 0.5rem;
  --space-s: 1rem;
  --space-m: 1.75rem;
  --space-l: 3rem;
  --space-xl: clamp(3.5rem, 2.5rem + 5vw, 6.5rem);

  --container: 1200px;
  --container-narrow: 820px;
  --nav-height: 88px;

  --radius: 2px;
  --shadow-sm: 0 1px 3px rgba(3, 50, 73, 0.08), 0 4px 12px rgba(3, 50, 73, 0.06);
  --shadow-md: 0 6px 28px rgba(3, 50, 73, 0.14);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------- Reset --- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-height);
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.7;
  color: var(--ink-muted);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.2;
  color: var(--navy-900);
  margin: 0 0 var(--space-s);
}

p {
  margin: 0 0 var(--space-s);
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--teal-dark);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

a:hover {
  color: var(--navy-900);
}

ul {
  margin: 0 0 var(--space-s);
  padding-left: 1.25rem;
}

li {
  margin-bottom: 0.4rem;
}

:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------- Utility --- */

.container {
  width: min(100% - 2.5rem, var(--container));
  margin-inline: auto;
}

.container--narrow {
  width: min(100% - 2.5rem, var(--container-narrow));
  margin-inline: auto;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--teal);
  color: var(--white);
  padding: 0.75rem 1.25rem;
  font-weight: 600;
}

.skip-link:focus {
  left: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Section heading — display serif, uppercase, with the teal rule beneath */
.section-heading {
  font-size: var(--step-3);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  margin-bottom: var(--space-s);
}

.section-heading .accent {
  color: var(--teal);
}

.rule {
  display: block;
  width: 68px;
  height: 3px;
  background: var(--teal);
  border: 0;
  margin: 0 0 var(--space-m);
}

.rule--center {
  margin-inline: auto;
}

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: var(--space-xs);
}

.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85rem 2rem;
  border: 1px solid var(--teal);
  border-radius: var(--radius);
  background: transparent;
  color: var(--teal);
  cursor: pointer;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease),
    border-color 0.25s var(--ease);
}

.btn:hover,
.btn:focus-visible {
  background: var(--teal);
  color: var(--white);
}

.btn--solid {
  background: var(--teal);
  color: var(--white);
}

.btn--solid:hover,
.btn--solid:focus-visible {
  background: var(--white);
  color: var(--teal-dark);
}

/* Solid white on the navy hero. The outlined teal-on-navy version was almost
   invisible against the background image. */
.btn--on-dark {
  background: var(--white);
  border-color: var(--white);
  color: var(--navy-900);
}

.btn--on-dark:hover,
.btn--on-dark:focus-visible {
  background: var(--teal);
  border-color: var(--teal);
  color: var(--white);
}

.section {
  padding-block: var(--space-xl);
}

.section--tight {
  padding-block: var(--space-l);
}

.section--navy {
  background: var(--navy-900);
  color: var(--white);
}

.section--navy h2,
.section--navy h3 {
  color: var(--white);
}

.section--grey {
  background: var(--grey-50);
}

/* ---------------------------------------------------------------- Nav --- */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  background: var(--navy-800);
  transition: padding 0.3s var(--ease), background-color 0.3s var(--ease),
    box-shadow 0.3s var(--ease);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block: 1.15rem;
  transition: padding 0.3s var(--ease);
}

.site-header.is-shrunk {
  background: var(--navy-900);
  box-shadow: 0 2px 18px rgba(0, 0, 0, 0.28);
}

.site-header.is-shrunk .nav {
  padding-block: 0.6rem;
}

.nav__logo img {
  height: 45px;
  width: auto;
  transition: height 0.3s var(--ease);
}

.site-header.is-shrunk .nav__logo img {
  height: 38px;
}

.nav__toggle {
  display: none;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.55rem 0.9rem;
  cursor: pointer;
}

.nav__toggle-bars {
  display: block;
  position: relative;
  width: 18px;
  height: 2px;
  background: currentColor;
}

.nav__toggle-bars::before,
.nav__toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  background: currentColor;
}

.nav__toggle-bars::before {
  top: -6px;
}

.nav__toggle-bars::after {
  top: 6px;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__list li {
  margin: 0;
}

.nav__link {
  display: block;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(255, 255, 255, 0.88);
  padding: 0.5rem 0.85rem;
  border-bottom: 2px solid transparent;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.nav__link:hover,
.nav__link:focus-visible {
  color: var(--teal);
  border-bottom-color: var(--teal);
}

.nav__link[aria-current="page"] {
  color: var(--teal);
  border-bottom-color: var(--teal);
}

@media (max-width: 900px) {
  .nav__toggle {
    display: inline-flex;
  }

  .nav__menu {
    position: absolute;
    inset: 100% 0 auto 0;
    background: var(--navy-900);
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    display: none;
  }

  .nav__menu.is-open {
    display: block;
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-s) 1.25rem var(--space-m);
  }

  .nav__link {
    padding: 0.85rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  }

  .nav__link:hover,
  .nav__link:focus-visible,
  .nav__link[aria-current="page"] {
    border-bottom-color: var(--teal);
  }
}

/* --------------------------------------------------------------- Hero --- */

.hero {
  position: relative;
  display: grid;
  align-items: center;
  min-height: clamp(420px, 72vh, 640px);
  padding-top: var(--nav-height);
  background-color: var(--navy-900);
  background-image: url("../img/banner-img3Color.jpg");
  background-size: cover;
  background-position: center;
  color: var(--white);
  isolation: isolate;
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    100deg,
    rgba(3, 50, 73, 0.82) 0%,
    rgba(3, 50, 73, 0.55) 45%,
    rgba(3, 50, 73, 0.25) 100%
  );
}

.hero__inner {
  max-width: 44rem;
  padding-block: var(--space-xl);
}

.hero__subheading {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: var(--space-xs);
}

.hero__heading {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 400;
  font-style: italic;
  color: rgba(255, 255, 255, 0.9);
  margin-bottom: var(--space-s);
}

.hero__title {
  font-size: var(--step-4);
  color: var(--white);
  margin-bottom: var(--space-m);
}

.hero__lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.92);
  max-width: 34rem;
  margin-bottom: var(--space-m);
}

/* Compact hero used on interior pages */
.page-hero {
  padding-top: calc(var(--nav-height) + var(--space-l));
  padding-bottom: var(--space-l);
  background: var(--navy-900);
  color: var(--white);
}

.page-hero h1 {
  color: var(--white);
  font-size: var(--step-3);
  text-transform: uppercase;
}

.page-hero p {
  color: rgba(255, 255, 255, 0.85);
  max-width: 46rem;
  margin-bottom: 0;
}

/* ------------------------------------------ Split section (text + grid) --- */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--space-l);
  align-items: start;
}

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

.split__intro {
  padding: var(--space-m);
  height: 100%;
}

.split__intro--panel {
  background: var(--navy-600);
  color: var(--white);
}

.split__intro--panel h2,
.split__intro--panel h3 {
  color: var(--white);
}

.split__intro h3 {
  font-size: var(--step-1);
  margin-bottom: var(--space-xs);
}

/* Feature tiles: image with a caption that expands into a teal panel */
.tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px;
}

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

.tile {
  position: relative;
  min-height: 258px;
  overflow: hidden;
  background: var(--navy-900);
  isolation: isolate;
}

.tile__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  transition: transform 0.6s var(--ease);
}

/* Bottom-weighted scrim rather than a flat wash: keeps the label legible while
   leaving the illustration itself bright. A flat 72% navy dimmed the drawings. */
.tile::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(3, 50, 73, 0.88) 0%,
    rgba(3, 50, 73, 0.55) 30%,
    rgba(3, 50, 73, 0.12) 65%,
    rgba(3, 50, 73, 0.04) 100%
  );
  transition: opacity 0.4s var(--ease);
}

.tile__label {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--space-s) var(--space-m);
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  text-transform: uppercase;
  color: var(--white);
  margin: 0;
  transition: opacity 0.35s var(--ease);
}

/* Rises from the bottom of the cell on hover, as the original site did. */
.tile__body {
  position: absolute;
  inset: 5% 3%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-m);
  background: var(--overlay-teal);
  color: var(--white);
  opacity: 0;
  transform: translateY(28%);
  transition: opacity 0.35s var(--ease), transform 0.45s var(--ease);
}

.tile__body h3 {
  font-size: var(--step-1);
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: var(--space-xs);
}

.tile__body p {
  font-size: var(--step--1);
  line-height: 1.6;
  margin: 0;
}

.tile__body strong {
  font-weight: 600;
}

.tile:hover .tile__img,
.tile:focus-within .tile__img {
  transform: scale(1.05);
}

.tile:hover .tile__label,
.tile:focus-within .tile__label {
  opacity: 0;
}

.tile:hover .tile__body,
.tile:focus-within .tile__body {
  opacity: 1;
  transform: translateY(0);
}

/* Between the 2-up grid and full width the tiles are at their narrowest, so the
   longest description needs more room than the 258px the original used. */
@media (min-width: 561px) and (max-width: 1080px) {
  .tile {
    min-height: 296px;
  }

  .tile__body {
    padding: var(--space-s);
  }
}

/* Touch devices can't hover, so the detail has to be visible by default. Any
   overlaid panel — full-bleed or a bottom band — has to sit on top of the
   artwork to do that, and because the illustrations are centred in a cropped
   258px box the band cut straight through the subject. So stop overlaying:
   give the artwork its own row at its native ratio (no crop, nothing hidden)
   and put the description in a solid panel beneath it.

   Also applies to narrow desktop windows, where the tile is too small to hold
   the longest description in an overlay without clipping it. */
@media (hover: none), (max-width: 560px) {
  .tile {
    display: grid;
    /* 1fr on the body so tiles sharing a row keep flush panels when one
       description runs longer than its neighbour's. */
    grid-template-rows: auto 1fr;
    min-height: 0;
    /* The artwork's own background is #F7F7F7, all but identical to the grey
       section behind it, so without this the top of each tile has no edge. */
    border: 1px solid var(--grey-200);
  }

  /* 11/5 trims the dead margin above and below the drawings so they don't float
     in a near-empty band. The centred cover crop starts at y=34 of 300; the
     tightest illustration (strategy-img1a) has ink from y=49, so nothing in the
     set is clipped. Re-measure before changing this ratio. */
  .tile__img {
    position: static;
    z-index: auto;
    aspect-ratio: 11 / 5;
    height: auto;
  }

  /* The scrim and the label only existed to caption the artwork from on top of
     it; the panel below now carries the same heading. */
  .tile::before,
  .tile__label {
    display: none;
  }

  .tile__body {
    position: static;
    padding: var(--space-m);
    /* Solid, and a step down from --teal, so the white body copy clears 4.5:1
       without an image behind it to darken the panel. */
    background: var(--teal-dark);
    opacity: 1;
    transform: none;
  }

  /* Android holds :hover after a tap; without this the artwork would zoom and
     stay zoomed. Matches the hover rule's specificity, so order decides. */
  .tile:hover .tile__img,
  .tile:focus-within .tile__img {
    transform: none;
  }
}

/* --------------------------------------------------------------- Team --- */

/* 186px is the measured floor for a track: the longest name, "Guillaume
   Perquier", renders 159px at the card's type size and the meta box adds 27px of
   side padding. Any narrower and the name wraps, which makes that one card's
   navy bar a line taller than its neighbours' and rides it up over the face.
   The old 172px value was below this, so those names were already wrapping. */
.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  gap: var(--space-m);
}

/* Seven members do not divide into a tidy single row: at the 1200px container
   auto-fit produced six across and left the seventh orphaned on its own row.
   Four across gives a balanced 4+3, matching the involvement grid's 4-column
   rhythm. The home-page teaser is excluded because it sits in the narrow 2fr
   column of a .split, where four 186px tracks will not fit. */
@media (min-width: 900px) {
  .team-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .split .team-grid {
    grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  }
}

/* The home-page teaser. A 2fr column gives the grid 768px, which fits only three
   186px tracks and so orphaned the seventh card. 2.4fr plus the tighter gutter
   takes it to 813px, enough for four, at the cost of ~45px off the intro column.
   The 900px collapse is repeated here because the base .split rule for it sits
   earlier in the file and would otherwise win on source order. */
.split--team {
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr);
  align-items: center;
}

.split--team .split__intro {
  padding-inline: 0;
}

.split--team .team-grid {
  gap: var(--space-s);
}

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

.person-card {
  position: relative;
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--navy-900);
  overflow: hidden;
}

.person-card img {
  width: 100%;
  aspect-ratio: 400 / 554;
  object-fit: cover;
  transition: transform 0.5s var(--ease), opacity 0.3s var(--ease);
}

.person-card:hover img,
.person-card:focus-visible img {
  transform: scale(1.04);
  opacity: 0.85;
}

/* Solid navy, not a translucent wash: over six portraits with different tones the
   translucent version read differently on each. Kept shallow so it clears chins. */
.person-card__meta {
  position: absolute;
  inset: auto 0 0 0;
  padding: 0.5rem 0.85rem 0.55rem;
  background: var(--navy-900);
  color: var(--white);
}

.person-card:hover .person-card__meta,
.person-card:focus-visible .person-card__meta {
  background: var(--teal-dark);
}

/* Sized so the longest name ("Guillaume Perquier") stays on one line in the
   narrowest card the grid produces. If it wraps, that card's bar grows taller
   than its neighbours' and rides up over the face. */
.person-card__meta h3 {
  font-size: 0.75rem;
  line-height: 1.3;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--white);
  margin: 0;
}

.person-card__meta p {
  font-size: 0.6875rem;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.8);
  margin: 0.1rem 0 0;
}

/* Stand-in for team members whose portrait we don't hold yet. Keeps the grid
   even; swap in a real 400x554 photo and delete the element. */
.portrait-placeholder {
  display: grid;
  place-items: center;
  aspect-ratio: 400 / 554;
  background: var(--navy-600);
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.2rem + 4vw, 3.25rem);
  font-weight: 600;
  letter-spacing: 0.06em;
}

.bio__photo .portrait-placeholder {
  width: 100%;
}

/* Full biography blocks */
.bio {
  display: grid;
  grid-template-columns: minmax(0, 280px) minmax(0, 1fr);
  gap: var(--space-l);
  align-items: start;
  padding-block: var(--space-l);
  border-top: 1px solid var(--grey-200);
  scroll-margin-top: calc(var(--nav-height) + 1rem);
}

.bio:first-of-type {
  border-top: 0;
}

@media (max-width: 760px) {
  .bio {
    grid-template-columns: 1fr;
    gap: var(--space-m);
  }
  .bio__photo {
    max-width: 260px;
  }
}

.bio__photo img {
  width: 100%;
  aspect-ratio: 400 / 554;
  object-fit: cover;
}

.bio__name {
  font-size: var(--step-2);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.15rem;
}

.bio__role {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: var(--space-s);
}

.bio__contact {
  list-style: none;
  padding: 0;
  margin: var(--space-s) 0 0;
  font-size: var(--step--1);
}

.bio__contact li {
  margin-bottom: 0.25rem;
}

.bio__contact span {
  display: inline-block;
  min-width: 3.25rem;
  font-weight: 600;
  color: var(--navy-900);
}

/* Mark only, no "LinkedIn" wordmark — the icon carries it. */
.bio__linkedin {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-top: var(--space-s);
  border-radius: 3px;
  background: var(--linkedin);
  color: var(--white);
  text-decoration: none;
  transition: background-color 0.25s var(--ease);
}

.bio__linkedin:hover,
.bio__linkedin:focus-visible {
  background: var(--navy-900);
  color: var(--white);
}

.bio__linkedin svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
  flex: none;
}

/* --------------------------------------------------- Involvement cards --- */

.involvement-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--space-m);
  /* 1fr rather than auto so every row takes the height of the tallest card in
     the grid, not just the tallest in its own row. Rows sized independently left
     the cards visibly different heights from one row to the next. */
  grid-auto-rows: 1fr;
}

/* Column flex so .company__meta can absorb the card's spare height. Grid stretches
   every card in a row to the tallest one; without this the grey box stops at its
   own content and each card ends with a different-sized white gap. */
.company {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--grey-200);
  overflow: hidden;
  transition: box-shadow 0.3s var(--ease), transform 0.3s var(--ease);
}

.company:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-3px);
}

/* Fixed band rather than an aspect ratio. Every logo is capped to the same height
   and bottom-aligned, so artwork of any proportion — a 6:1 wordmark or an upright
   mark — reads at comparable weight and sits the same distance above the grey box. */
.company__logo {
  display: grid;
  /* minmax(0,1fr) so the row is capped by the container's height. A default auto
     row grows to the image's intrinsic height and the cap does nothing. */
  grid-template-rows: minmax(0, 1fr);
  height: 130px;
  /* Hold the band at exactly 130px — as a flex item it would otherwise shrink. */
  flex: none;
  padding: 1.25rem var(--space-m) var(--space-s);
  background: var(--white);
}

/* Fill the panel and let object-fit letterbox the artwork. max-width/max-height
   alone is not enough: it constrains but never scales up, so the SVG logos (whose
   intrinsic widths are only 109-190px) would sit tiny beside the 300px rasters. */
.company__logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* Sit each logo on a common baseline. Centring makes the distance between the
     artwork and the grey meta box a function of the logo's aspect ratio, so a wide
     wordmark floats ~68px clear while a squarer mark sits ~16px off it. */
  object-position: center bottom;
}

/* Fallback for companies whose logo artwork we don't hold yet — renders a
   typographic wordmark in the same footprint so the grid stays even. */
.company__logo--text {
  background: var(--navy-900);
  text-align: center;
}

.company__logo--text span {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.02em;
  color: var(--white);
}

.company__logo--text span::after {
  content: "";
  display: block;
  width: 40px;
  height: 2px;
  margin: 0.75rem auto 0;
  background: var(--teal);
}

.company__meta {
  /* Fill the rest of the card so the grey box bottoms line up across the row. */
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--space-s) var(--space-m) var(--space-m);
  border-top: 1px solid var(--grey-200);
  background: var(--grey-50);
}

/* Two lines reserved (line-height is 1.2, so 2.4em). Several names wrap at the
   230px column — "Boulangerie Thierry", "Nationwide Autocentre" — and without a
   reserved box the sector line below them sits a line lower than its neighbours'. */
.company__name {
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  min-height: 2.4em;
  margin-bottom: 0.3rem;
}

/* Two lines reserved (line-height is the inherited 1.7, so 3.4em). With the tags
   sitting directly under this rather than pinned to the card's foot, the sector
   has to be a fixed-height box or a two-line one — "Healthcare and education
   services" — would push its tags a line below its neighbours'. */
.company__sector {
  font-size: var(--step--1);
  color: var(--ink-muted);
  min-height: 3.4em;
  margin: 0;
}

/* Tags follow the sector directly, so the country box sits on a common line near
   the top of the meta box; the card's spare height falls below them instead.
   Two classes to outrank `p:last-child { margin: 0 }`. */
.company .company__tags {
  display: flex;
  /* Country on its own line above the investment type. align-items keeps each
     tag hugging its text rather than stretching to the card width. */
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  margin-top: 0;
  padding-top: 0.7rem;
  /* Two rows reserved. Every company currently carries both a country and an
     investment-type tag; this keeps the country on the shared top line if one
     ever has only the country, instead of it dropping to the bottom line.
     A row is the 0.6875rem tag font at the inherited 1.7 line-height, plus its
     0.25rem padding top and bottom; the trailing 0.4rem is the gap between. */
  min-height: calc(2 * (0.6875rem * 1.7 + 0.5rem) + 0.4rem);
}

.tag {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius);
  background: var(--navy-900);
  color: var(--white);
}

.tag--country {
  background: transparent;
  border: 1px solid var(--grey-500);
  color: var(--grey-500);
}

/* Once the grid is a single column there is no neighbour to line up with, so the
   matched heights and the reserved second name line are dead space on every card.
   Two columns need 2x230px + a 28px gap = 488px of container, and the container is
   the viewport less 40px, so the grid drops to one column below 528px. */
@media (max-width: 527px) {
  .involvement-grid {
    grid-auto-rows: auto;
  }

  .company__name,
  .company__sector {
    min-height: 0;
  }
}

/* The default 1fr/2fr split gives the logo column ~770px, which stretches a 2x2
   grid into four very wide, very empty tiles. Even columns keep each tile near
   2:1 and give the two intro paragraphs a comfortable measure. */
.split--involvement {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
}

.split--involvement .split__intro {
  padding-inline: 0;
}

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

/* 2x2 logo wall. Tiles share one height so the four sit on a common grid; the
   artwork inside is sized per logo (--logo-w) rather than stretched to fill,
   which is what keeps mixed aspect ratios reading at an even weight. */
.involvement-logos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--white);
  border: 1px solid var(--grey-200);
}

/* Dividers come from the cells' own borders rather than a 1px grid gap over a
   grey background: the gap approach leaves the track rounding visible as an
   uneven 2-3px band between the rows. */
.involvement-logos li {
  display: grid;
  place-items: center;
  min-height: 124px;
  padding: var(--space-s);
  border-right: 1px solid var(--grey-200);
  border-bottom: 1px solid var(--grey-200);
}

.involvement-logos li:nth-child(2n) {
  border-right: 0;
}

.involvement-logos li:nth-last-child(-n + 2) {
  border-bottom: 0;
}

/* height:auto (not a matching --logo-h) so the width/height attributes drive the
   ratio: below --logo-w on narrow screens the logo scales down proportionally
   instead of being letterboxed. */
.involvement-logos img {
  width: min(var(--logo-w, 120px), 100%);
  height: auto;
}

@media (max-width: 480px) {
  .involvement-logos li {
    min-height: 96px;
  }
}

/* -------------------------------------------------------------- Forms --- */

.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
}

@media (max-width: 860px) {
  .contact-layout {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-s);
}

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

.field--full {
  grid-column: 1 / -1;
}

.field label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--navy-900);
  margin-bottom: 0.35rem;
}

.field .req {
  color: var(--teal-dark);
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--step-0);
  color: var(--ink);
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--grey-200);
  border-radius: var(--radius);
  background: var(--white);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px rgba(27, 153, 139, 0.18);
}

.field textarea {
  min-height: 150px;
  resize: vertical;
}

.fieldset {
  grid-column: 1 / -1;
  border: 0;
  padding: 0;
  margin: var(--space-xs) 0 0;
}

.fieldset legend {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--navy-900);
  padding: 0;
  margin-bottom: 0.5rem;
}

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: var(--step--1);
  margin-bottom: 0.45rem;
}

.checkbox input {
  margin-top: 0.35rem;
  accent-color: var(--teal);
  width: 1rem;
  height: 1rem;
}

.form-note {
  grid-column: 1 / -1;
  font-size: var(--step--1);
  color: var(--grey-500);
  line-height: 1.6;
}

/* Result of a form submission. Empty in the markup and hidden until main.js
   writes to it, so nothing reserves space on first paint. */
.form-status {
  margin: var(--space-s) 0 0;
  font-size: var(--step--1);
  line-height: 1.6;
}

.form-status:empty {
  display: none;
}

.form-status--pending {
  color: var(--grey-500);
}

.form-status--ok,
.form-status--error {
  padding: 0.75rem 0.9rem;
  border-left: 3px solid var(--teal);
  background: var(--grey-50);
  color: var(--navy-900);
  font-weight: 600;
}

.form-status--error {
  border-left-color: var(--error);
  background: var(--error-bg);
  color: var(--error-ink);
  font-weight: 400;
}

/* A disabled submit is the in-flight state, so it needs to read as busy rather
   than as the ordinary hover invert. */
.btn[disabled] {
  opacity: 0.55;
  cursor: progress;
  pointer-events: none;
}

.contact-aside {
  padding: var(--space-m);
  background: var(--grey-50);
  border-left: 3px solid var(--teal);
}

.contact-aside h2 {
  font-size: var(--step-2);
}

.contact-aside dl {
  margin: 0;
}

.contact-aside dt {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--teal-dark);
  margin-top: var(--space-s);
}

.contact-aside dd {
  margin: 0.2rem 0 0;
}

/* ---------------------------------------------------------- Long copy --- */

.prose h2 {
  font-size: var(--step-2);
  text-transform: uppercase;
  margin-top: var(--space-l);
}

.prose h2:first-child {
  margin-top: 0;
}

.prose li {
  margin-bottom: 0.5rem;
}

/* ------------------------------------------------------------- Footer --- */

.site-footer {
  background: var(--navy-800);
  color: rgba(255, 255, 255, 0.82);
  padding-block: var(--space-m);
  font-size: var(--step--1);
}

.site-footer a {
  color: rgba(255, 255, 255, 0.82);
  text-decoration: none;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--teal);
  text-decoration: underline;
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1.4fr) auto;
  gap: var(--space-m);
  align-items: center;
}

@media (max-width: 860px) {
  .footer-grid {
    grid-template-columns: 1fr;
    text-align: center;
    justify-items: center;
  }
}

.footer-links {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  justify-content: flex-end;
}

@media (max-width: 860px) {
  .footer-links {
    justify-content: center;
  }
}

/* LinkedIn blue so the mark is recognisable at a glance rather than reading as a
   generic outlined glyph. */
.social {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--linkedin);
  border-radius: 3px;
  background: var(--linkedin);
  color: var(--white);
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.social:hover,
.social:focus-visible {
  background: var(--white);
  border-color: var(--white);
  color: var(--linkedin);
}

.social svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

/* ------------------------------------------------------- Back to top --- */

.to-top {
  position: fixed;
  right: clamp(0.75rem, 2vw, 1.5rem);
  bottom: clamp(0.75rem, 2vw, 1.5rem);
  z-index: 90;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 50%;
  background: var(--teal);
  color: var(--white);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease),
    visibility 0.3s var(--ease), background-color 0.25s var(--ease);
  box-shadow: var(--shadow-md);
}

.to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.to-top:hover,
.to-top:focus-visible {
  background: var(--navy-900);
}

.to-top svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* ------------------------------------------------------ Scroll reveal --- */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
  }
}
