/* ==================================================
   HOMEPAGE HERO SLIDER
   Purpose:
   The three-slide homepage hero — slide layout, the
   layered aurora backdrop, arrows, pagination dots and
   the autoplay progress indicator. Behaviour, autoplay,
   swipe and keyboard control live in js/slider.js.
================================================== */

.hero-section {
  position: relative;
  background: var(--gradient-night);
  color: var(--color-on-dark-muted);
  isolation: isolate;
  overflow: hidden;
}

/* ---- Ambient backdrop -----------------------------------------------
   Two blurred brand-blue fields plus a faint grid, all drawn in CSS so
   the hero costs no image request and never shifts layout. */
.hero-section::before,
.hero-section::after {
  content: "";
  position: absolute;
  z-index: -2;
  border-radius: 50%;
  pointer-events: none;
}

.hero-section::before {
  top: -22%;
  right: -8%;
  width: min(760px, 76%);
  aspect-ratio: 1;
  background: radial-gradient(circle, var(--brand-glow), transparent 64%);
  filter: blur(24px);
}

.hero-section::after {
  bottom: -34%;
  left: -14%;
  width: min(620px, 62%);
  aspect-ratio: 1;
  background: radial-gradient(circle, var(--brand-glow-deep), transparent 66%);
  filter: blur(28px);
}

.hero-section__grid {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 30%, transparent 100%);
  pointer-events: none;
}

/* ==================================================
   SLIDER SHELL
   Slides are stacked and cross-faded rather than
   translated, which keeps the markup order meaningful
   for screen readers and avoids a horizontal overflow.
================================================== */

.hero-slider {
  position: relative;
}

.hero-slider__track {
  display: grid;
  /* Every slide occupies the same cell; the tallest sets the height so the
     hero never changes size between slides. */
  grid-template-areas: "slide";
}

/*
   All three slides share one grid cell so the hero never changes height
   between them — that keeps cumulative layout shift at zero.

   Sharing a cell does mean the slides are physically stacked, so the
   cross-fade has to be sequenced in TIME or two headlines are legible at
   once and the banner reads as overlapping text. The outgoing slide is
   therefore given a short, delay-free fade out, and the incoming slide waits
   for that to finish before it begins. The handover is invisible; what it
   prevents is two sets of large type printed over each other.
*/

.hero-slide {
  grid-area: slide;
  /* Asymmetric on purpose: the controls row sits directly underneath and
     supplies its own breathing room, so repeating it here left a visibly
     empty band between the slide and the dots. */
  padding-top: clamp(1.25rem, 1rem + 1.2vw, 2rem);
  padding-bottom: clamp(0.5rem, 0.35rem + 0.6vw, 1rem);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(10px);
  /* Leaving: quick fade, no delay. */
  transition: opacity 200ms ease-in,
              transform 200ms ease-in,
              visibility 0s linear 200ms;
}

.hero-slide.is-active {
  position: relative;
  z-index: 1;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  /* Arriving: waits for the outgoing slide to clear before fading in. */
  transition: opacity 380ms var(--ease-out-expo) 200ms,
              transform 380ms var(--ease-out-expo) 200ms,
              visibility 0s linear 200ms;
}

.hero-slide__inner {
  display: grid;
  gap: clamp(2rem, 1.5rem + 2.4vw, 3.25rem);
  align-items: center;
}

@media (min-width: 992px) {
  .hero-slide__inner { grid-template-columns: 1.06fr 0.94fr; }
}

/* ==================================================
   SLIDE CONTENT
================================================== */

.hero-slide__content { max-width: 620px; }

.hero-slide__eyebrow { margin-bottom: var(--s-5); }

.hero-slide__title {
  font-size: var(--fs-display);
  line-height: 1.12;
  color: #FFFFFF;
  margin-bottom: var(--s-5);
  /* Holds the headline to a sensible line length so it breaks two or three
     times rather than five, and balances the last line. */
  max-width: 21ch;
  text-wrap: balance;
}

@media (max-width: 991px) {
  .hero-slide__title { max-width: 24ch; }
}

.hero-slide__title em {
  font-style: normal;
  background: linear-gradient(105deg, var(--brand-300), var(--brand-500));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-slide__text {
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--color-on-dark-muted);
  max-width: 56ch;
  margin-bottom: var(--s-6);
}

.hero-slide__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-bottom: var(--s-6);
}

.hero-slide__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.hero-slide__meta-item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  color: var(--color-on-dark-muted);
}

.hero-slide__meta-icon {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  background-color: var(--brand-400);
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
}

/* ==================================================
   SLIDE VISUAL
   Each slide carries a small diagrammatic panel rather
   than stock photography, so the hero says something
   concrete about the work.
================================================== */

.hero-slide__visual {
  position: relative;
  display: none;
}

@media (min-width: 992px) {
  .hero-slide__visual { display: block; }
}

.hero-panel {
  position: relative;
  padding: var(--s-6);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 28px 64px rgba(2, 6, 20, 0.5);
}

.hero-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-5);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.hero-panel__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: #FFFFFF;
  letter-spacing: var(--tracking-snug);
}

.hero-panel__dots {
  display: flex;
  gap: 6px;
}

.hero-panel__dots span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.22);
}

.hero-panel__dots span:first-child { background-color: rgba(78, 155, 255, 0.75); }

/* ---- Compact diagrams inside the hero panel --------------------------
   All three slides share one grid cell, so the tallest panel sets the height
   of the whole banner on every slide. The layered stack diagram on slide two
   was 610px against a 509px content column, single-handedly adding a hundred
   pixels to the hero.

   Inside the panel the diagram is supporting illustration, not the page's
   main content — the panel header already names it — so it drops its
   description and connectors and tightens its nodes. The full-size treatment
   is untouched everywhere else. */

.hero-panel .infographic {
  padding: 0;
  border: none;
  background: none;
}

.hero-panel .infographic__header {
  margin-bottom: var(--s-4);
}

.hero-panel .infographic__description {
  display: none;
}

.hero-panel .infographic__title {
  font-size: var(--fs-h4);
  margin-bottom: 0;
}

.hero-panel .infographic__node {
  padding: var(--s-3) var(--s-4);
}

/* One step per row, each with its line of explanation.
   Two-across, label-only cards left the panel about half the height of the
   headline column beside it, and because the two are vertically centred that
   difference showed up as a large void under the panel — the empty space in
   the banner. A single column of four described steps fills the same space
   with something worth reading, and the hero stops looking half-finished. */
.hero-panel .infographic--flow.infographic--short .infographic__visual,
.hero-panel .infographic--flow .infographic__visual,
.hero-panel .infographic__visual {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-3);
}

.hero-panel .infographic__content {
  margin-top: 2px;
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--color-on-dark-muted);
}

.hero-panel .infographic--stack .infographic__visual {
  gap: var(--s-2);
}

.hero-panel .infographic--stack .infographic__connector {
  display: none;
}

.hero-panel .infographic__footer {
  display: none;
}

/* ==================================================
   SLIDER CONTROLS
================================================== */

/*
   One cluster, not two islands.

   These controls were previously pushed to opposite ends of a container that
   is up to 1280px wide, which left roughly a thousand pixels of nothing
   between the pagination and the arrows and made the foot of the banner read
   as empty space rather than as a control bar. Grouping them at the start
   keeps the whole set within a hand's width of each other, which is also
   where a mouse already is after clicking a dot.
*/
.hero-controls {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  padding-top: var(--s-2);
  padding-bottom: clamp(0.75rem, 0.6rem + 0.6vw, 1.125rem);
}

.hero-controls__arrows {
  display: none;
  gap: var(--s-2);
}

@media (min-width: 768px) {
  .hero-controls__arrows { display: flex; }
}

.hero-arrow {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background-color: rgba(255, 255, 255, 0.05);
  color: #FFFFFF;
  transition: background-color var(--transition-fast),
              border-color var(--transition-fast),
              transform var(--transition-fast);
}

.hero-arrow:hover {
  background-color: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.42);
  transform: scale(1.06);
}

.hero-arrow__glyph {
  width: 18px;
  height: 18px;
  background-color: currentColor;
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
}

/* ---- Pagination ------------------------------------------------------ */

.hero-pagination {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

.hero-pagination__dot {
  position: relative;
  width: 46px;
  height: 4px;
  border-radius: var(--radius-pill);
  background-color: rgba(255, 255, 255, 0.2);
  overflow: hidden;
  transition: background-color var(--transition-fast);
}

.hero-pagination__dot:hover { background-color: rgba(255, 255, 255, 0.34); }

/* The fill doubles as the autoplay progress bar. Its animation is driven by
   the --hero-interval custom property set in js/slider.js. */
.hero-pagination__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background-color: var(--brand-400);
  border-radius: inherit;
}

.hero-pagination__dot[aria-current="true"]::after {
  animation: hero-progress var(--hero-interval, 7000ms) linear forwards;
}

/* When autoplay is paused the active dot simply stays filled. */
.hero-slider.is-paused .hero-pagination__dot[aria-current="true"]::after,
.hero-slider.is-static .hero-pagination__dot[aria-current="true"]::after {
  animation: none;
  transform: scaleX(1);
}

@keyframes hero-progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-pagination__dot[aria-current="true"]::after {
    animation: none;
    transform: scaleX(1);
  }
}

/* Play / pause control for the autoplay, required for WCAG 2.2.2. */
.hero-autoplay-toggle {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #FFFFFF;
  flex-shrink: 0;
  transition: background-color var(--transition-fast);
}

.hero-autoplay-toggle:hover { background-color: rgba(255, 255, 255, 0.12); }

.hero-autoplay-toggle__glyph {
  width: 15px;
  height: 15px;
  background-color: currentColor;
  mask: url("../assets/icons/ui/pause.svg") no-repeat center / contain;
  -webkit-mask: url("../assets/icons/ui/pause.svg") no-repeat center / contain;
}

.hero-autoplay-toggle[aria-pressed="true"] .hero-autoplay-toggle__glyph {
  mask-image: url("../assets/icons/ui/play.svg");
  -webkit-mask-image: url("../assets/icons/ui/play.svg");
}

/* ==================================================
   TRUST / TECHNOLOGY STRIP
   Sits directly beneath the hero and names the stack the
   team actually builds on.
================================================== */

.trust-strip {
  padding-block: var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background-color: rgba(255, 255, 255, 0.02);
}

.trust-strip__inner {
  display: grid;
  gap: var(--s-6);
  align-items: center;
}

@media (min-width: 900px) {
  .trust-strip__inner { grid-template-columns: auto 1fr; gap: var(--s-10); }
}

.trust-strip__label {
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--ink-300);
  max-width: 20ch;
}

/* ==================================================
   TECHNOLOGY MARQUEE
   Purpose:
   A continuously scrolling strip of technology chips.

   The chip list is rendered twice in the markup and the
   track is animated by exactly -50%, so the second copy
   arrives precisely where the first began and the loop is
   seamless with no JavaScript involved. The duplicate is
   aria-hidden, so assistive technology reads the list once.
================================================== */

.tech-marquee {
  position: relative;
  overflow: hidden;
  min-width: 0;
  /* Fade the strip out at both ends so chips enter and leave the frame
     rather than being visibly clipped by the container edge. */
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.tech-marquee__track {
  display: flex;
  width: max-content;
  gap: var(--s-3);
}

.tech-marquee__group {
  display: flex;
  gap: var(--s-3);
  flex-shrink: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .tech-marquee__track {
    animation: tech-marquee-scroll 46s linear infinite;
  }

  /* Pause so a visitor can read a chip, or tab to one, without it moving. */
  .tech-marquee:hover .tech-marquee__track,
  .tech-marquee:focus-within .tech-marquee__track {
    animation-play-state: paused;
  }
}

@keyframes tech-marquee-scroll {
  from { transform: translate3d(0, 0, 0); }
  /* Half the track is one full copy of the list. */
  to   { transform: translate3d(calc(-50% - (var(--s-3) / 2)), 0, 0); }
}

/* Without animation the strip becomes an ordinary scrollable row, and the
   duplicate copy is removed so nothing is listed twice. */
@media (prefers-reduced-motion: reduce) {
  .tech-marquee {
    overflow-x: auto;
    mask-image: none;
    -webkit-mask-image: none;
  }

  .tech-marquee__group[aria-hidden="true"] { display: none; }
}

/* ---- Chip ------------------------------------------------------------- */

.tech-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0.55rem 1.1rem 0.55rem 0.7rem;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.12);
  background-color: rgba(255, 255, 255, 0.05);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: #E7EEF9;
  white-space: nowrap;
  transition: border-color var(--transition-fast),
              background-color var(--transition-fast),
              color var(--transition-fast);
}

a.tech-chip:hover {
  border-color: rgba(78, 155, 255, 0.55);
  background-color: rgba(22, 104, 255, 0.14);
  color: #FFFFFF;
}

.tech-chip__icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.08);
  /* Each product's own colour, supplied by the data-brand attribute. */
  color: var(--brand-tint, var(--brand-300));
  font-size: 0.95rem;
}

.tech-chip__label { line-height: 1; }
