/* ==========================================================================
   HITCO — homepage sections
   ========================================================================== */

/* ---------------------------------------------------------------- HERO */
.hero {
  position: relative;
  background: var(--c-band);
  color: rgba(255, 255, 255, 0.8);
  overflow: hidden;
  isolation: isolate;
}
.hero::before {
  /* A single quiet gradient anchored to the logo's blue — not decoration
     for its own sake, it keeps the headline legible over the image. */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(
      120% 90% at 78% 15%,
      rgba(15, 127, 184, 0.34) 0%,
      transparent 58%
    ),
    radial-gradient(
      80% 70% at 12% 90%,
      rgba(52, 155, 71, 0.18) 0%,
      transparent 60%
    ),
    var(--c-ink);
}
.hero__inner {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: var(--s-16);
  align-items: center;
  padding-block: clamp(72px, 10vw, 140px);
}
@media (max-width: 960px) {
  .hero__inner {
    grid-template-columns: 1fr;
    gap: var(--s-10);
    padding-block: 64px;
  }
}
.hero__text {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  max-width: 58ch;
}
.hero .eyebrow {
  color: #7fcbee;
}
.hero .eyebrow::before {
  background: var(--c-green);
}
.hero h1 {
  color: #fff;
}
.hero__lede {
  font-size: var(--t-md);
  color: rgba(255, 255, 255, 0.74);
  line-height: var(--lh-body);
  max-width: 54ch;
}
.hero__cta {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-block-start: var(--s-2);
}

.hero__figure {
  position: relative;
  aspect-ratio: 4/3;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.hero__figure img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.hero__figure--empty {
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--s-10);
  color: rgba(255, 255, 255, 0.4);
  font-size: var(--t-sm);
}

/* trust strip under the hero */
.hero__strip {
  border-block-start: 1px solid rgba(255, 255, 255, 0.12);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 760px) {
  .hero__strip {
    grid-template-columns: repeat(2, 1fr);
  }
}
.hero__strip div {
  padding: var(--s-6) var(--s-4);
  border-inline-end: 1px solid rgba(255, 255, 255, 0.12);
}
.hero__strip div:last-child {
  border-inline-end: 0;
}
@media (max-width: 760px) {
  .hero__strip div:nth-child(2n) {
    border-inline-end: 0;
  }
  .hero__strip div:nth-child(-n + 2) {
    border-block-end: 1px solid rgba(255, 255, 255, 0.12);
  }
}
/* The strip sits on the dark hero, so the stat tokens must invert here —
   without this they inherit --c-ink and vanish into the background. */
.hero__strip .stat__value {
  color: #fff;
}
.hero__strip .stat__suffix {
  color: var(--c-green);
}
.hero__strip .stat__label {
  color: rgba(255, 255, 255, 0.62);
}

/* ---------------------------------------------------------- WHO WE ARE */
/* Two beats, not one: an intro row (copy | photograph) and a pillar row that
   spans the full width underneath. The pillars used to live INSIDE the copy
   column as a 34px-bullet list, which made that column tall against a
   landscape figure and reduced the section's three actual claims to footnotes. */
.who {
  display: flex;
  flex-direction: column;
  gap: var(--s-16);
}
.who__intro {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-16);
  align-items: center;
}
@media (max-width: 900px) {
  .who {
    gap: var(--s-10);
  }
  .who__intro {
    grid-template-columns: 1fr;
    gap: var(--s-10);
  }
}
.who__text {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}
/* .who__figure {
  aspect-ratio: 1/1;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--c-wash);
  border: 1px solid var(--c-line);
  display: grid;
  place-items: center;
  color: var(--c-muted);
  font-size: var(--t-sm);
  text-align: center;
  padding: var(--s-8);
} */
/* The `.reveal.is-in` qualifier is deliberately NOT repeated here: `.reveal` is
   the scroll-in hook and `is-in` is added by hitco.js, so a rule that depends on
   both leaves the image square-cornered until it scrolls into view — and never
   rounds it at all when JS is off. */
.who__figure img {
  border-radius: var(--radius-card);
  inline-size: 100%;
  block-size: auto;
}
/* ---- the three pillars -------------------------------------------------
   Not links, so there is no hover state to carry the colour — the accent rule
   and the plate are permanent instead. The section ground is white
   (`section--surface`), so the cards take a faint paper wash to separate;
   a white-on-white card would need a heavier border and read as a table again. */
.who__pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
}
@media (max-width: 860px) {
  .who__pillars {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 600px) {
  /* The compact homepage keeps the intro and figure; the three explanatory
     cards are desktop/tablet supporting content and are omitted on phones. */
  .who__pillars {
    display: none;
  }
}
.who__pillar {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--c-paper), var(--c-surface) 60%);
  padding: var(--s-6);
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: var(--s-4);
  row-gap: var(--s-2);
}
/* Full-width accent rule. The colour alternates so the row is not three
   identical objects — the flatness complaint was as much about repetition
   as about contrast. */
.who__pillar::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  background: var(--c-primary);
}
.who__pillar:nth-child(2)::before {
  background: var(--c-green);
}
.who__pillar:nth-child(3)::before {
  background: var(--c-primary-deep);
}
.who__plate {
  grid-row: 1 / span 1;
  inline-size: 52px;
  block-size: 52px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: var(--c-primary-soft);
  color: var(--c-primary-deep);
}
.who__pillar:nth-child(2) .who__plate {
  background: var(--c-green-soft);
  color: var(--c-green);
}
.who__plate svg {
  inline-size: 26px;
  block-size: 26px;
  stroke-width: 1.5;
}
.who__idx {
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--c-line-strong);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  justify-self: end;
  align-self: start;
}
.who__pillar h3 {
  grid-column: 1 / -1;
  font-size: var(--t-md);
  line-height: var(--lh-snug);
  margin-block-start: var(--s-2);
}
.who__pillar p {
  grid-column: 1 / -1;
  font-size: var(--t-sm);
  color: var(--c-body);
}

/* --------------------------------------------------------- ECOSYSTEM */
/* Cards that are objects, not cells.
   ⚠️ This was a 1px-gap grid on a `--c-line` ground — a hairline TABLE, which
   is exactly what made the section read as «بی‌روح»: eight white rectangles
   welded together, each holding two lines of text and a 5%-opacity watermark.
   Three things changed and all three matter: the cells became separated cards
   with their own radius and border, the watermark became a real coloured icon
   on a plate, and every card gained a fact (how many companies are behind it).
   Keep them together — restoring any one of them alone brings the flatness
   back. */
.eco {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-4);
}
@media (max-width: 1000px) {
  .eco {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .eco {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.eco__card {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  position: relative;
  min-block-size: 244px;
  overflow: hidden;
  transition: transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}
/* The accent that appears on hover. A `scaleX` on a pseudo-element rather than
   a border, so nothing in the card shifts by a pixel when it arrives.
   `transform-origin` is LOGICAL: the wipe has to start at the reading edge, or
   it runs the wrong way in one of the two locales. */
.eco__card::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  background: linear-gradient(
    to left,
    var(--c-primary) 0%,
    var(--c-green) 100%
  );
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease);
}
[dir="rtl"] .eco__card::before {
  transform-origin: right center;
}
.eco__card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2);
  border-color: var(--c-line-strong);
}
.eco__card:hover::before {
  transform: scaleX(1);
}
@media (prefers-reduced-motion: reduce) {
  .eco__card,
  .eco__card::before {
    transition: none;
  }
  .eco__card:hover {
    transform: none;
  }
}

.eco__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}
/* The glyph, on a plate, at a size you can actually read. It replaced a 132px
   watermark at 5.5% opacity — which is to say, nothing. */
.eco__plate {
  flex: none;
  inline-size: 52px;
  block-size: 52px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: var(--c-primary-soft);
  color: var(--c-primary-deep);
  transition: background var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.eco__plate svg {
  inline-size: 27px;
  block-size: 27px;
  stroke-width: 1.5;
}
.eco__card:hover .eco__plate {
  background: var(--c-primary);
  color: #fff;
}
.eco__num {
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--c-line-strong);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
}
.eco__card h3 {
  font-size: var(--t-md);
  line-height: var(--lh-snug);
  margin-block-start: var(--s-2);
}
.eco__card p {
  font-size: var(--t-sm);
  color: var(--c-body);
}

/* Pinned to the bottom so every card's baseline row lines up across the grid,
   however long its blurb runs. */
.eco__foot {
  margin-block-start: auto;
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--c-line);
  display: flex;
  align-items: center;
  /* `flex-end`, not `space-between`: the sector cards carry only the arrow now
     (the company count was dropped), and space-between would park a lone child
     at the reading edge instead of the trailing one. The CTA card has two
     children and still reads label → arrow. */
  justify-content: space-between;
  gap: var(--s-3);
}
.eco__card:not(.eco__card--cta) .eco__foot {
  justify-content: flex-end;
}
.eco__cta-label {
  font-size: var(--t-xs);
  font-weight: 700;
  color: #fff;
}
.eco__card .arw {
  inline-size: 18px;
  block-size: 18px;
  flex: none;
  color: var(--c-primary);
  transition: transform var(--dur-2) var(--ease);
}
[dir="rtl"] .eco__card .arw {
  transform: scaleX(-1);
}
.eco__card:hover .arw {
  transform: translateX(4px);
}
[dir="rtl"] .eco__card:hover .arw {
  transform: scaleX(-1) translateX(4px);
}
/* Keeps the whole card clickable over the pseudo-elements above. */
.eco__card::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* Trailing cell — the sector count rarely fills the grid exactly, so the
   remainder becomes a deliberate call to action instead of a dead cell. */
.eco__card--cta {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: rgba(255, 255, 255, 0.72);
}
.eco__card--cta:hover {
  border-color: var(--c-ink);
}
.eco__card--cta .eco__plate {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}
.eco__card--cta:hover .eco__plate {
  background: var(--c-green);
  color: var(--c-ink);
}
/* Bottom-weighted: plate at the top, title sitting on the foot rule. With no
   blurb to fill the middle, centring the text would just look like a card that
   lost its copy. */
.eco__card--cta h3 {
  color: #fff;
  margin-block-start: auto;
}
.eco__card--cta p {
  color: rgba(255, 255, 255, 0.6);
}
.eco__card--cta .eco__foot {
  border-block-start-color: rgba(255, 255, 255, 0.16);
}
.eco__card--cta .arw {
  color: #fff;
}

/* ---------------------------------------------------------- COMPANIES */
/* ------------------------------------------------- COMPANY CAROUSEL -----
   Photo-led cards in a horizontal scroller. Native scroll + scroll-snap does
   the work, so touch/trackpad gestures behave correctly and the arrows are a
   progressive enhancement rather than the only way to move. */
.scroller {
  position: relative;
}

/* The cards are separated objects now (border + radius + hover lift), so the
   gutter has to be big enough to read as a gap rather than a seam. It was 6px
   while they were edge-to-edge photographic tiles. */
.scroller {
  --co-gap: 14px;
}

.scroller__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - (4 * var(--co-gap))) / 5);
  gap: var(--co-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.scroller__track::-webkit-scrollbar {
  display: none;
}
.scroller__track > * {
  scroll-snap-align: start;
}

@media (prefers-reduced-motion: reduce) {
  .scroller__track {
    scroll-behavior: auto;
  }
}
/* 5 desktop · 3 tablet · ~1.15 mobile, so the cut-off card signals scrollability. */
@media (max-width: 1100px) {
  .scroller__track {
    grid-auto-columns: calc((100% - (2 * var(--co-gap))) / 3);
  }
}
@media (max-width: 720px) {
  .scroller__track {
    grid-auto-columns: calc((100% - var(--co-gap)) / 2);
  }
}
@media (max-width: 560px) {
  .scroller__track {
    grid-auto-columns: 80%;
  }
}

.scroller__btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  inline-size: 44px;
  block-size: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: #fff;
  color: var(--c-ink);
  border: 0;
  box-shadow: 0 4px 16px -4px rgba(14, 31, 39, 0.22),
    0 1px 3px rgba(14, 31, 39, 0.08);
  z-index: 3;
  transition: background var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease), opacity var(--dur-2) var(--ease),
    transform var(--dur-1) var(--ease);
}
.scroller__btn:hover {
  background: var(--c-primary);
  color: #fff;
}
.scroller__btn[disabled] {
  opacity: 0;
  pointer-events: none;
}
/* Sits over the last visible card rather than outside the strip. */
.scroller__btn--prev {
  inset-inline-start: 16px;
}
.scroller__btn--next {
  inset-inline-end: 16px;
}
.scroller__btn svg {
  inline-size: 18px;
  block-size: 18px;
}
/* The base `arrow` glyph points right. Each button needs its OWN rule —
   a blanket [dir="rtl"] flip turns both the same way, which is the bug where
   prev and next both pointed left. Prev always points back along the reading
   direction, next always points forward. */
.scroller__btn--prev svg {
  transform: scaleX(-1);
} /* LTR: ← */
.scroller__btn--next svg {
  transform: none;
} /* LTR: → */
[dir="rtl"] .scroller__btn--prev svg {
  transform: none;
} /* RTL: → */
[dir="rtl"] .scroller__btn--next svg {
  transform: scaleX(-1);
} /* RTL: ← */
@media (max-width: 560px) {
  .scroller__btn {
    inline-size: 38px;
    block-size: 38px;
  }
  .scroller__btn--prev {
    inset-inline-start: 8px;
  }
  .scroller__btn--next {
    inset-inline-end: 8px;
  }
}

/* ---- the card ----------------------------------------------------------
   A CARD, not a photographic tile. The tile treatment (picture bleeding to all
   four edges, a white gradient fading over its lower third, the name floating
   on that fade) was built for `companies.cover_image` — and NOT ONE of the 15
   subsidiaries has one, so what it actually rendered was a grey-blue blob with
   a logo adrift in it and no edge anywhere. `.co-card__fade` went with it.
   The card now follows the same object language as `.eco__card`: its own
   border and radius, a bordered logo plate on top, an identity block below,
   and a hover state that lifts and wipes in a brand accent. */
.co-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  background: var(--c-surface);
  isolation: isolate;
  transition: transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}
/* Same wipe as the sector cards. `transform-origin` is per-direction or it
   runs the wrong way in one of the two locales. */
.co-card::before {
  content: "";
  position: absolute;
  z-index: 3;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  pointer-events: none;
  background: linear-gradient(to left, var(--c-primary) 0%, var(--c-green) 100%);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease);
}
[dir="rtl"] .co-card::before {
  transform-origin: right center;
}
.co-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2);
  border-color: var(--c-line-strong);
}
.co-card:hover::before {
  transform: scaleX(1);
}

.co-card__media {
  position: relative;
  z-index: 0;
  aspect-ratio: 16 / 10;
  display: grid;
  place-items: center;
  padding: var(--s-5);
  border-block-end: 1px solid var(--c-line);
  background: linear-gradient(155deg, #f4f8fa 0%, #e4edf2 100%);
}
/* px, not %, for the height cap — the percentage trap is md/frontend.md
   gotcha 6.
   ⚠️ The source logos are 300×300 squares with the mark centred inside
   generous internal padding, so the rendered mark comes out a good deal
   smaller than the box you give it — this is why the number looks too large
   and is not. */
.co-card__media img {
  inline-size: auto;
  block-size: auto;
  max-inline-size: 74%;
  max-block-size: 92px;
  object-fit: contain;
  transition: transform var(--dur-3) var(--ease);
}
.co-card:hover .co-card__media img {
  transform: scale(1.05);
}
@media (prefers-reduced-motion: reduce) {
  .co-card,
  .co-card::before,
  .co-card__media img {
    transition: none;
  }
  .co-card:hover,
  .co-card:hover .co-card__media img {
    transform: none;
  }
}

/* Fallback when a company has no logo file on disk. */
.co-card__media--empty {
  color: #b3c5ce;
}
.co-card__media--empty svg {
  inline-size: 40px;
  block-size: 40px;
}

.co-card__id {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-4);
}
/* The company's name, always — it used to appear only as a stand-in for a
   missing logo, but the logo is the card's picture now, so this is the card's
   label rather than its fallback. */
.co-card__name {
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--c-ink);
  line-height: 1.35;
}
/* Pinned to the bottom so the chip and the arrow line up across the whole rail
   whether the name above ran to one line or three. */
.co-card__foot {
  margin-block-start: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
}
.co-card__sector {
  font-size: 11px;
  line-height: 1.4;
  color: var(--c-primary-deep);
  background: var(--c-primary-soft);
  border-radius: 999px;
  padding: 3px 9px;
}
/* `margin-inline-start:auto` and not `justify-content` alone: three companies
   have no sector on record, and without it their lone arrow would sit at the
   reading edge instead of the trailing one. */
.co-card .arw {
  inline-size: 16px;
  block-size: 16px;
  flex: none;
  margin-inline-start: auto;
  color: var(--c-primary);
  transition: transform var(--dur-2) var(--ease);
}
[dir="rtl"] .co-card .arw {
  transform: scaleX(-1);
}
.co-card:hover .arw {
  transform: translateX(4px);
}
[dir="rtl"] .co-card:hover .arw {
  transform: scaleX(-1) translateX(4px);
}

@media (max-width: 1100px) {
  .co-card__media {
    aspect-ratio: 3 / 2;
  }
}
@media (max-width: 560px) {
  .co-card__media img {
    max-block-size: 78px;
  }
}

/* ------------------------------------------------------------- BRANDS */
/* --------------------------------------------------------- BRAND MARQUEE */
/* Continuous auto-scrolling loop. The track holds the logo set twice and
   translates by exactly -50%, so the seam is invisible and the loop never
   resets visibly. Pauses on hover/focus and stops entirely under
   prefers-reduced-motion, where it becomes a normal scrollable row. */
/* The panel the marquee runs inside. The strip used to be two hairlines on the
   page ground with the marks floating between them — 118 logos of every colour
   and weight loose on white, which is the definition of texture rather than a
   designed rail. The band gives them a ground and a top-and-tail; the plates
   below give each mark its own object. */
.brand-band {
  position: relative;
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  /* Darker than the page ground on purpose: the plates inside are white, and a
     white-on-white band gave them nothing to stand on. */
  background: linear-gradient(180deg, var(--c-wash), var(--c-paper));
  padding-block: var(--s-4);
  overflow: hidden;
}
.brand-slider {
  position: relative;
  overflow: hidden;
  /* Room for a plate's hover lift and its shadow. `.brand-slider` is the
     clipping box, so without this the lift is sliced off at the track's own
     edges — the band's padding is outside the clip and does not help. */
  padding-block: 12px;
  /* Fade the edges so logos enter and leave rather than being chopped. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 90px,
    #000 calc(100% - 90px),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 90px,
    #000 calc(100% - 90px),
    transparent 100%
  );
}
.brand-slider__track {
  display: flex;
  inline-size: max-content;
  animation: brand-marquee 46s linear infinite;
}
/* RTL needs its own keyframes, NOT animation-direction:reverse.
   Under `direction:rtl` the flex track lays out right-to-left, so its content
   extends LEFT of the container's right edge. Translating negatively pushes it
   past the visible window and the strip renders empty; `reverse` merely made it
   start empty and fill only at the very end of the cycle. Travelling positively
   scrolls the duplicated set into view the same way -50% does in LTR. */
[dir="rtl"] .brand-slider__track {
  animation-name: brand-marquee-rtl;
}

.brand-slider:hover .brand-slider__track,
.brand-slider:focus-within .brand-slider__track {
  animation-play-state: paused;
}

@keyframes brand-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}
@keyframes brand-marquee-rtl {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(50%);
  }
}

/* ⚠️ `margin-inline`, NOT `gap` on the track. The loop translates by exactly
   -50%, which is only the seam if the two halves are the same width. Symmetric
   per-item margins keep them equal (2N × (w + 2m)); a track `gap` does not —
   it lays down (2N − 1) gaps, so half the track lands one gap short and the
   strip visibly jumps every cycle. */
.brand-slider__item {
  flex: 0 0 auto;
  inline-size: 218px;
  min-block-size: 132px;
  margin-inline: 7px;
  display: grid;
  place-items: center;
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  background: var(--c-surface);
  font-size: var(--t-md);
  color: var(--c-body);
  font-weight: 600;
  text-align: center;
  transition: transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}
.brand-slider__item:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2);
  border-color: var(--c-primary);
}
/* Brand recognition is the whole point of this strip, so the marks get real
   size rather than being treated as decorative texture. */
.brand-slider__item img {
  max-block-size: 96px;
  max-inline-size: 100%;
  inline-size: auto;
  object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
  .brand-slider {
    overflow-x: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .brand-slider__track {
    animation: none;
  }
  .brand-slider__item {
    transition: none;
  }
  .brand-slider__item:hover {
    transform: none;
  }
}
@media (max-width: 600px) {
  .brand-slider__item {
    inline-size: 168px;
    min-block-size: 108px;
    padding-inline: var(--s-4);
  }
  .brand-slider__item img {
    max-block-size: 74px;
  }
}

/* ------------------------------------------------------- PRODUCT CARDS */
/* Horizontal split: copy leads, packshot sits on a soft tinted field to the
   trailing edge. Mirrors automatically in RTL via logical properties. */
/* 3 × 3 grid — not a carousel. The card keeps its wide showcase treatment;
   only the container differs. */
.prod-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
}
@media (max-width: 1000px) {
  .prod-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 620px) {
  .prod-grid {
    grid-template-columns: 1fr;
  }
}

.prod-card {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 46%;
  align-items: stretch;
  aspect-ratio: 305/180; /* wider than tall, per the reference */
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  /* Was a bespoke 18px. Every card on this page (sector, company, brand plate,
     pillar) is `--radius-card`, and one 18px object in the middle of them read
     as a different design rather than a different card. */
  border-radius: var(--radius-card);
  overflow: hidden;
  isolation: isolate;
  transition: box-shadow var(--dur-2) var(--ease),
    transform var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
/* The shared hover accent. `transform-origin` is per-direction — a `left`
   origin wipes the wrong way in RTL. */
.prod-card::before {
  content: "";
  position: absolute;
  z-index: 3;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  pointer-events: none;
  background: linear-gradient(to left, var(--c-primary) 0%, var(--c-green) 100%);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease);
}
[dir="rtl"] .prod-card::before {
  transform-origin: right center;
}
.prod-card:hover {
  border-color: var(--c-line-strong);
  box-shadow: var(--shadow-2);
  transform: translateY(-3px);
}
.prod-card:hover::before {
  transform: scaleX(1);
}
@media (max-width: 620px) {
  .prod-card {
    aspect-ratio: 330/190;
  }
}

.prod-card__body {
  padding: var(--s-5) var(--s-5) var(--s-4);
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  z-index: 2;
}
/* `.card__link` is an <a>, so without this it takes the global link blue and
   all nine names on the grid come out brand-coloured — which spends the card's
   only accent on its longest string and leaves the actual action looking
   secondary. */
.prod-card__name .card__link {
  color: inherit;
}
.prod-card__name {
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--c-ink);
  line-height: 1.2;
  letter-spacing: -0.008em;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* A chip, not a grey caption line. It is the only place the card names what the
   product IS, and as plain `--c-body` text under a bold name it read as a
   subtitle nobody looks at. `align-self:start` keeps the pill hugging its own
   text instead of stretching across the column. */
.prod-card__cat {
  align-self: start;
  margin-block-start: var(--s-2);
  max-inline-size: 100%;
  font-size: 11px;
  font-weight: 600;
  color: var(--c-primary-deep);
  background: var(--c-primary-soft);
  border-radius: 999px;
  padding: 3px 9px;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.prod-card__desc {
  margin-block-start: 8px;
  font-size: var(--t-xs);
  color: var(--c-muted);
  line-height: 1.6;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Same foot rule as `.eco__foot`: it pins the action to the bottom so every
   card's baseline row lines up across the grid however long the name ran. */
.prod-card__cta {
  margin-block-start: auto;
  padding-block-start: var(--s-3);
  border-block-start: 1px solid var(--c-line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--c-ink);
}
/* The arrow became an affordance rather than a 13px tick: a plate that inverts
   to solid brand blue on hover, which is what makes the whole card read as
   clickable at a glance. Padding on an inline SVG needs the border box. */
.prod-card__cta .arw {
  flex: none;
  box-sizing: border-box;
  inline-size: 26px;
  block-size: 26px;
  padding: 5px;
  border-radius: 50%;
  background: var(--c-primary-soft);
  color: var(--c-primary-deep);
  transition: transform var(--dur-1) var(--ease),
    background var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
[dir="rtl"] .prod-card__cta .arw {
  transform: scaleX(-1);
}
.prod-card:hover .prod-card__name {
  color: var(--c-primary-deep);
}
.prod-card:hover .prod-card__cta {
  color: var(--c-primary-deep);
}
.prod-card:hover .prod-card__cta .arw {
  background: var(--c-primary);
  color: #fff;
  transform: translateX(3px);
}
[dir="rtl"] .prod-card:hover .prod-card__cta .arw {
  transform: scaleX(-1) translateX(3px);
}

.prod-card__media {
  position: relative;
  display: grid;
  place-items: center;
  padding: var(--s-3) var(--s-3) var(--s-3) 0;
}
/* The soft organic sweep behind the packshot: one oversized ellipse in a
   near-white grey. Kept very low contrast so the packaging supplies the only
   real colour on the card. */
.prod-card__media::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset-block: -22% -18%;
  inset-inline-start: -14%;
  inset-inline-end: -25%;
  border-radius: 50%;
  background: linear-gradient(160deg, #f7f9fb 0%, #eff3f6 55%, #e9eff3 100%);
}
/* Absolute max-height rather than a percentage: a % max-height resolves
   against an indeterminate container height and is simply ignored, letting
   tall packshots set the row height inconsistently.

   NOTE: mix-blend-mode:multiply drops the white box around packshots that are
   isolated on white. It does NOT suit the handful of products whose image is a
   full-bleed dark marketing graphic (ThermoFuel V9, Micellar Casein) — those
   render as a dark slab. Kept because it flatters the majority; the real fix is
   re-shooting those few images on white. */
.prod-card__media img {
  position: relative;
  z-index: 1;
  max-inline-size: 100%;
  max-block-size: 170px;
  inline-size: auto;
  block-size: auto;
  object-fit: contain;
  mix-blend-mode: multiply;
  transition: transform var(--dur-3) var(--ease);
}
@media (max-width: 1000px) {
  .prod-card__media img {
    max-block-size: 150px;
  }
}
@media (max-width: 620px) {
  .prod-card__media img {
    max-block-size: 135px;
  }
}
.prod-card:hover .prod-card__media img {
  transform: scale(1.03);
}
@media (prefers-reduced-motion: reduce) {
  .prod-card,
  .prod-card::before,
  .prod-card__media img {
    transition: none;
  }
  .prod-card:hover {
    transform: none;
  }
  .prod-card:hover .prod-card__media img {
    transform: none;
  }
}
.prod-card__media--empty {
  color: #c6d3da;
}
.prod-card__media--empty svg {
  position: relative;
  z-index: 1;
  inline-size: 34px;
  block-size: 34px;
}

/* ------------------------------------------------------ NEWS & INSIGHTS */
/* A segmented control, not an underlined tab strip. The strip was one more
   hairline in a page already made of hairlines, and the only thing marking the
   active tab was a 2px rule — on a `--wash` ground that is nearly invisible.
   The selected pill is solid brand blue, so which tab you are on is legible
   from across the room. */
.tabs {
  display: inline-flex;
  gap: var(--s-1);
  padding: 4px;
  border: 1px solid var(--c-line);
  border-radius: 999px;
  background: var(--c-surface);
  margin-block-end: var(--s-10);
  /* The control is `inline-flex` inside a block wrapper, so it hugs its two
     pills; without this it would stretch the full container width. */
  max-inline-size: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar {
  display: none;
}
.tabs__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 18px;
  border-radius: 999px;
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--c-muted);
  transition: color var(--dur-1) var(--ease),
    background var(--dur-1) var(--ease);
  white-space: nowrap;
}
.tabs__btn:hover {
  color: var(--c-ink);
  background: var(--c-paper);
}
.tabs__btn[aria-selected="true"] {
  color: #fff;
  background: var(--c-primary);
}
.tabs__count {
  font-size: 11px;
  font-weight: 700;
  color: var(--c-muted);
  background: var(--c-wash);
  border-radius: 20px;
  padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}
.tabs__btn[aria-selected="true"] .tabs__count {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}

.tabpanel[hidden] {
  display: none;
}

.tabs__empty {
  padding: var(--s-16) var(--s-6);
  text-align: center;
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--radius-card);
  color: var(--c-muted);
  font-size: var(--t-sm);
}

.news-layout {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: var(--s-8);
  align-items: stretch;
}
@media (max-width: 900px) {
  .news-layout {
    grid-template-columns: 1fr;
  }
}

/* Hug the content. As a stretched grid item the lead matched the height of the
   six-row list beside it, and `.card__foot`'s `margin-block-start:auto` then
   pushed "read more" to the bottom of whatever slack was left — a post with no
   image and a short excerpt rendered as a mostly empty white slab. */
.news-lead {
  align-self: stretch;
  block-size: 100%;
}
.news-lead .card__media {
  aspect-ratio: 12/9;
}
.news-lead .card__title {
  font-size: var(--t-lg);
  line-height: var(--lh-snug);
}
/* The lead is a `.card`, whose hover is deliberately quiet because that class
   is shared with every listing on the site. Here it is one of two objects in a
   whole section, so it gets the page's accent wipe and the deeper lift. */
.news-lead::before {
  content: "";
  position: absolute;
  z-index: 3;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  pointer-events: none;
  background: linear-gradient(to left, var(--c-primary) 0%, var(--c-green) 100%);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease);
}
[dir="rtl"] .news-lead::before {
  transform-origin: right center;
}
.news-lead:hover::before {
  transform: scaleX(1);
}
.news-lead:hover {
  box-shadow: var(--shadow-2);
  transform: translateY(-3px);
}

/* The secondary headlines are a panel, not loose rows. On the `--wash` ground
   they used to be six hairline-separated lines floating beside a bordered card,
   which left the column looking unfinished next to it. */
.news-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  padding: var(--s-5);
  align-self: stretch;
  block-size: 100%;
}

/* Compact rows so more headlines fit beside the lead story. */
.news-item {
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: var(--s-4);
  align-items: center;
  position: relative;
  padding-block-end: var(--s-3);
  border-block-end: 1px solid var(--c-line);
}
.news-item:last-of-type {
  border-block-end: 0;
  padding-block-end: 0;
}
.news-item__thumb {
  aspect-ratio: 4/3;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--c-line);
}
/* A flat `--c-line` rectangle where a photo should be reads as a broken image.
   Several migrated posts have none. */
.news-item__thumb--empty {
  display: grid;
  place-items: center;
  background: var(--c-wash);
  color: var(--c-line-strong);
}
.news-item__thumb--empty svg {
  inline-size: 20px;
  block-size: 20px;
}
.news-item__thumb img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-3) var(--ease);
}
.news-item:hover .news-item__thumb img {
  transform: scale(1.05);
}
.news-item__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-inline-size: 0;
}
.news-item__title {
  font-size: var(--t-sm);
  font-weight: 700;
  line-height: var(--lh-snug);
  color: var(--c-ink);
}
/* Same reason as `.card__title .card__link` in hitco.css — six blue headlines
   stacked in a panel read as a link list, not as news. */
.news-item__title .card__link {
  color: inherit;
}
.news-item:hover .news-item__title {
  color: var(--c-primary);
}
@media (max-width: 420px) {
  .news-item {
    grid-template-columns: 84px 1fr;
  }
}

.news-insights {
  border-block-start: 1px solid var(--c-line);
  padding-block-start: var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.news-insight {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  font-size: var(--t-sm);
  color: var(--c-body);
  padding-block: 5px;
}
.news-insight .arw {
  inline-size: 15px;
  block-size: 15px;
  flex: none;
  margin-block-start: 5px;
  color: var(--c-green);
}
[dir="rtl"] .news-insight .arw {
  transform: scaleX(-1);
}
.news-insight:hover {
  color: var(--c-primary);
}

/* ------------------------------------------------------- CAPABILITIES */
.cap {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-6);
}
@media (max-width: 800px) {
  .cap {
    grid-template-columns: 1fr;
  }
}
.cap__item {
  border: 1px solid var(--c-line);
  border-radius: var(--radius-card);
  background: var(--c-surface);
  padding: var(--s-8);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  border-inline-start: 3px solid var(--c-green);
}
.cap__item h3 {
  font-size: var(--t-md);
}
.cap__item p {
  font-size: var(--t-sm);
  color: var(--c-body);
}

/* --------------------------------------------------------------- CSR */
.csr {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-16);
  align-items: center;
}
@media (max-width: 900px) {
  .csr {
    grid-template-columns: 1fr;
    gap: var(--s-10);
  }
}
.csr__stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-8);
}

/* --------------------------------------------------------- FINAL CTA */
/* The closing block was flat `--c-ink` with no light in it at all. It now
   carries the same two brand washes as the hero, which also bookends the page:
   the visitor leaves on the colour they arrived on. The gradients go on the
   SECTION, not on `.final-cta` — that element is the (padded) container, so a
   background there would stop at the text column instead of filling the band. */
.cta-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
/* ⚠️ THE WASHES MUST FADE TO NOTHING AT THE BOTTOM EDGE, and the mask is what
   does it. The footer is the SAME `--c-ink` as this band, so the two are meant
   to read as one dark tail — but the green wash is anchored at `10% 100%`, i.e.
   at full strength exactly on the bottom edge, and it used to stop dead there.
   That drew a hard horizontal seam across the full width and made the band and
   the footer look like two different colours. Masking the whole layer out over
   the last quarter means the band arrives at the footer as pure ink.
   ⚠️ Do NOT "fix" this by re-colouring the footer — it is locked (CLAUDE.md
   rule 4) and it was never the thing that was wrong. */
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
      90% 120% at 78% 8%,
      rgba(15, 127, 184, 0.34) 0%,
      transparent 60%
    ),
    radial-gradient(
      70% 90% at 10% 100%,
      rgba(52, 155, 71, 0.2) 0%,
      transparent 62%
    );
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}
.final-cta {
  position: relative;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-6);
}
.final-cta .eyebrow {
  color: #7fcbee;
  justify-content: center;
}
.final-cta p {
  max-width: 56ch;
  color: rgba(255, 255, 255, 0.72);
}
.final-cta .hero__cta {
  justify-content: center;
}

/* ------------------------------------------------------------ CAREERS */
/* The one full-colour block on the page. It was a white box with a hairline
   border on a near-white ground — invisible, and the last thing the visitor
   sees before the footer. Brand blue rather than `--c-ink`, deliberately: the
   final CTA directly below it IS ink, and two near-black slabs in a row read as
   one long dark tail. */
.careers-teaser {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--s-8);
  align-items: center;
  border-radius: var(--radius-card);
  padding: var(--s-12);
  color: rgba(255, 255, 255, 0.82);
  background: linear-gradient(
    118deg,
    var(--c-primary-deep) 0%,
    var(--c-primary) 62%,
    #1a92c9 100%
  );
}
/* A single green wash in one corner so the panel is not one flat sheet of blue
   — the same two-colour logic as the hero. The position is PHYSICAL, so it
   lands behind the copy in fa and behind the button in en; both were checked
   and both work, which is why it is not mirrored. */
.careers-teaser::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    72% 120% at 92% 108%,
    rgba(52, 155, 71, 0.42) 0%,
    transparent 62%
  );
}
.careers-teaser .h2 {
  color: #fff;
}
.careers-teaser .lede {
  color: rgba(255, 255, 255, 0.78);
}
/* `.eyebrow` is brand blue by default, which is invisible on brand blue. */
.careers-teaser .eyebrow {
  color: rgba(255, 255, 255, 0.9);
}
.careers-teaser .eyebrow::before {
  background: #fff;
}
.careers-teaser__plate {
  flex: none;
  inline-size: 64px;
  block-size: 64px;
  border-radius: 18px;
  display: grid;
  place-items: center;
  color: #fff;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.2);
}
.careers-teaser__plate svg {
  inline-size: 30px;
  block-size: 30px;
  stroke-width: 1.5;
}
@media (max-width: 760px) {
  .careers-teaser {
    grid-template-columns: 1fr;
    justify-items: start;
    padding: var(--s-8);
    gap: var(--s-6);
  }
}

/* ---------------------------------------------------------------- a11y */
.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- justified body copy · centred blocks keep their centring ------------
   The `:where(p, blockquote, dd)` rule in hitco.css declares alignment ON the
   paragraph, and a direct declaration outranks the `text-align: center` these
   containers pass DOWN to it by inheritance. Re-inheriting restores them.
   Add a centred container that holds a paragraph and it belongs in this list. */
.hero__figure--empty :where(p, blockquote, dd),
.brand-slider__item :where(p, blockquote, dd),
.tabs__empty :where(p, blockquote, dd),
.final-cta :where(p, blockquote, dd) {
  text-align: inherit;
}
