/* ===========================================================================
   Components — the reusable kit shared by every page.
   Large one-off page compositions (hero, ecosystem, bento, insights)
   live in sections.css.
   =========================================================================== */

/* =========================================================== 1. buttons == */

.btn {
  --btn-py: 0.72rem;
  --btn-px: 1.4rem;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55em;
  padding: var(--btn-py) var(--btn-px);
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.01em;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out);
}

.btn:active {
  transform: translateY(1px) scale(0.985);
}

.btn__icon {
  width: 1em;
  height: 1em;
  flex: none;
  transition: transform var(--dur) var(--ease-spring);
}

.btn:hover .btn__icon {
  transform: translateX(3px);
}

/* Primary — solid brand teal.
   There was a sheen pseudo-element here that swept across on hover. It is
   gone: parked off-screen at translateX(-120%) with nothing clipping it, it
   was permanently visible as a grey smear to the left of every primary
   button. The lift, colour shift and shadow below carry the hover on their
   own, and read calmer besides. */
.btn--primary {
  background: var(--brand-teal);
  color: var(--brand-ink);
  box-shadow: var(--shadow-brand);
}

.btn--primary:hover {
  background: #12c9a8;
  transform: translateY(-2px);
  box-shadow: 0 18px 40px -14px rgba(10, 178, 151, 0.6);
}

/* Gold — reserved for the single most important action on a dark band. */
.btn--gold {
  background: var(--brand-gold);
  color: #3a2a00;
  box-shadow: 0 12px 32px -12px rgba(255, 198, 46, 0.5);
}

.btn--gold:hover {
  background: var(--brand-gold-bright);
  transform: translateY(-2px);
  box-shadow: 0 18px 40px -14px rgba(255, 198, 46, 0.6);
}

/* Outline — secondary weight, borrows the surface so it works on any band.
   The inset hairline along the top edge is what stops it reading as a flat
   dark rectangle next to the solid primary; on hover the whole thing warms
   to a brand tint rather than only swapping its border colour. */
.btn--outline {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--text-primary) 6%, var(--bg-surface)) 0%,
    var(--bg-surface) 100%
  );
  border-color: var(--border-strong);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm), inset 0 1px 0 color-mix(in srgb, var(--text-primary) 10%, transparent);
}

.btn--outline:hover {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--brand-teal) 16%, var(--bg-surface)) 0%,
    color-mix(in srgb, var(--brand-teal) 6%, var(--bg-surface)) 100%
  );
  border-color: var(--brand-teal);
  color: var(--color-primary);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -14px color-mix(in srgb, var(--brand-teal) 55%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--text-primary) 14%, transparent);
}

.btn--outline:active {
  box-shadow: none;
}

/* Ghost — lowest weight, for tertiary links that still need a hit area. */
.btn--ghost {
  color: var(--text-secondary);
}

.btn--ghost:hover {
  background: var(--bg-brand-subtle);
  color: var(--color-primary);
}

.btn--lg {
  --btn-py: 0.95rem;
  --btn-px: 1.85rem;
  font-size: 1rem;
}

.btn--sm {
  --btn-py: 0.55rem;
  --btn-px: 1rem;
  font-size: var(--fs-xs);
}

.btn--block {
  width: 100%;
}

/* Secondary action sitting on a permanently-dark band, where --bg-surface
   would be the wrong base. */
.btn--on-ink {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(150, 220, 208, 0.3);
  color: #eaf5f2;
  box-shadow: none;
}

.btn--on-ink:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: var(--brand-teal);
  color: #ffffff;
  transform: translateY(-2px);
}

.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.5;
  pointer-events: none;
}

/* Text link with a sliding arrow. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-primary);
  transition: gap var(--dur) var(--ease-spring);
}

.link-arrow svg {
  width: 1.05em;
  height: 1.05em;
  transition: transform var(--dur) var(--ease-spring);
}

.link-arrow:hover {
  gap: 0.75em;
}

.link-arrow:hover svg {
  transform: translateX(2px);
}

/* A link-arrow closing a copy block, rather than sitting inline in a row. */
.link-arrow--block {
  margin-top: var(--sp-8);
}

/* ============================================================ 2. pills === */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.42em 0.9em;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  white-space: nowrap;
}

.pill--brand {
  border-color: var(--border-brand);
  background: var(--bg-brand-subtle);
  color: var(--color-primary);
}

.pill--gold {
  border-color: rgba(255, 198, 46, 0.4);
  background: var(--bg-gold-subtle);
  color: var(--color-accent-text);
}

.pill__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

/* Live indicator — the pulse marks the hero badge as "active network". */
.pill__dot--live {
  position: relative;
  background: var(--brand-teal);
}

.pill__dot--live::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 1.5px solid var(--brand-teal);
  animation: ping 2.4s var(--ease-out) infinite;
}

/* ============================================================ 3. cards === */

.card {
  position: relative;
  padding: clamp(1.35rem, 2.4vw, 2rem);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out);
}

/* Gradient hairline that only appears on hover. Painted into the border box
   with a mask so it stays a true 1px edge at any radius. */
.card--interactive::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(140deg, var(--brand-teal), transparent 42%, transparent 62%, var(--brand-gold));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}

.card--interactive:hover,
.card--interactive:focus-within {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
}

.card--interactive:hover::before,
.card--interactive:focus-within::before {
  opacity: 1;
}

.card__icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-md);
  background: var(--bg-brand-subtle);
  border: 1px solid var(--border-brand);
  margin-bottom: var(--sp-5);
  flex: none;
  transition: transform var(--dur) var(--ease-spring), background-color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out);
}

.card__icon img,
.card__icon svg {
  width: 24px;
  height: 24px;
  color: var(--color-primary);
  transition: color var(--dur) var(--ease-out), transform var(--dur) var(--ease-spring);
}

/* Hover: the tile warms to amber and the glyph zooms. An earlier version
   rotated the tile a few degrees, which read as the icon slipping rather than
   responding. */
.card--interactive:hover .card__icon,
.card--interactive:focus-within .card__icon {
  background: var(--bg-gold-subtle);
  border-color: rgba(255, 198, 46, 0.55);
  transform: scale(1.08);
}

.card--interactive:hover .card__icon svg,
.card--interactive:hover .card__icon img,
.card--interactive:focus-within .card__icon svg,
.card--interactive:focus-within .card__icon img {
  color: var(--color-accent);
  transform: scale(1.14);
}

.card__title {
  font-size: var(--fs-h4);
  margin-bottom: var(--sp-3);
}

.card__text {
  color: var(--text-secondary);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
}

.card__foot {
  margin-top: var(--sp-5);
}

.glass-panel {
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  backdrop-filter: blur(var(--glass-blur)) saturate(140%);
  box-shadow: var(--shadow-md);
}

.surface {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
}

/* Grid presets used by card collections. */
.grid {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
}

/* Explicitly three columns, not auto-fit. auto-fit let a "grid--3" become
   four columns once the container grew, which is what split a six-card
   section into 4 + 2. Every grid on the site holds a multiple of three, so
   this keeps every row full. Stepped down at the breakpoints in
   responsive.css. */
.grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* =========================================================== 4. header === */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out), backdrop-filter var(--dur) var(--ease-out);
}

/* Scrolled state — added by navigation.js. */
.site-header.is-scrolled {
  background: var(--header-bg);
  border-bottom-color: var(--header-border);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  box-shadow: 0 1px 24px -8px rgba(0, 0, 0, 0.18);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  width: 100%;
}

.brand {
  display: flex;
  align-items: center;
  flex: none;
  transition: opacity var(--dur) var(--ease-out);
}

.brand:hover {
  opacity: 0.82;
}

/* The mark is a stacked lockup — dot pyramid over the wordmark — so it needs
   real height before the "VITRAK Extendreach" type is legible at all. The
   header grows with it (--header-h), rather than the logo being squeezed to
   fit a chrome bar sized for a horizontal lockup. */
.brand img {
  height: clamp(46px, 4.8vw, 64px);
  width: auto;
}

/* Two real exports rather than a filter. The primary logo is dark-ink type
   for light backgrounds; the footer export is the same mark in brighter teal
   and gold, drawn for dark ones. Inverting the first would have flattened the
   brand to white and thrown the gold apex away. */
.brand__dark {
  display: none;
}

[data-theme='dark'] .brand__light {
  display: none;
}

[data-theme='dark'] .brand__dark {
  display: block;
}

/* ------------------------------------------------------------ desktop nav */

.nav {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

.nav__link {
  position: relative;
  padding: 0.62rem 1rem;
  border-radius: var(--radius-sm);
  font-size: clamp(0.9375rem, 1vw, 1.0625rem);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
  transition: color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}

.nav__link::after {
  content: '';
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 0.3rem;
  height: 2px;
  border-radius: 2px;
  background: var(--color-primary-fill);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.nav__link:hover {
  color: var(--text-primary);
}

.nav__link:hover::after {
  transform: scaleX(1);
}

.nav__link[aria-current='page'] {
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}

.nav__link[aria-current='page']::after {
  transform: scaleX(1);
}

/* The auto margin lives here, not on .brand — that puts the nav immediately
   after the logo (left-aligned) and pushes only the login / app buttons to
   the far right. */
.header-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex: none;
  margin-left: auto;
}

/* The header pair sits between --sm and the default size: --sm was too slight
   against a 94px bar and the enlarged logo. */
.header-actions .btn {
  --btn-py: 0.72rem;
  --btn-px: 1.4rem;
  font-size: 0.9375rem;
}

/* -------------------------------------------------- 6. mobile nav drawer */

.nav-toggle {
  display: none;
  width: 42px;
  height: 42px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  place-items: center;
  flex: none;
}

.nav-toggle__bars {
  position: relative;
  width: 18px;
  height: 12px;
}

.nav-toggle__bars span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: var(--text-primary);
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}

.nav-toggle__bars span:nth-child(1) {
  top: 0;
}
.nav-toggle__bars span:nth-child(2) {
  top: 5px;
}
.nav-toggle__bars span:nth-child(3) {
  top: 10px;
}

.nav-toggle[aria-expanded='true'] .nav-toggle__bars span:nth-child(1) {
  transform: translateY(5px) rotate(45deg);
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bars span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bars span:nth-child(3) {
  transform: translateY(-5px) rotate(-45deg);
}

.drawer-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-drawer) - 1);
  background: var(--scrim);
  opacity: 0;
  visibility: hidden;
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  /* visibility flips instantly on the way in and is delayed on the way out,
     so the scrim is never a transparent click-blocker mid-fade. */
  transition: opacity var(--dur) var(--ease-out), visibility 0s linear var(--dur);
}

.drawer-scrim.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--dur) var(--ease-out), visibility 0s;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  width: min(400px, 88vw);
  display: flex;
  flex-direction: column;
  background: var(--bg-page);
  border-left: 1px solid var(--border-color);
  box-shadow: var(--shadow-lg);
  transform: translateX(100%);
  visibility: hidden;
  /* Interpolating visibility would leave it computing as `hidden` for the
     first frame of the opening transition, and .focus() on a hidden subtree
     is silently dropped — which stranded keyboard focus on the burger. It is
     switched instantly on open and delayed only on close. */
  transition: transform var(--dur-slow) var(--ease-out), visibility 0s linear var(--dur-slow);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: max(var(--sp-8), env(safe-area-inset-bottom));
}

.drawer.is-open {
  transform: translateX(0);
  visibility: visible;
  transition: transform var(--dur-slow) var(--ease-out), visibility 0s;
}

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  min-height: var(--header-h);
  border-bottom: 1px solid var(--border-color);
}

.drawer__close {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-color);
  color: var(--text-secondary);
  flex: none;
}

.drawer__close:hover {
  color: var(--text-primary);
  background: var(--bg-page-alt);
}

.drawer__close svg {
  width: 18px;
  height: 18px;
}

.drawer__nav {
  padding: var(--sp-5);
  display: grid;
  gap: var(--sp-1);
}

.drawer__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-4) var(--sp-4);
  border-radius: var(--radius-md);
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-heading);
  color: var(--text-primary);
  /* staggered entrance, driven by --d set inline per item */
  opacity: 0;
  transform: translateX(18px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.drawer.is-open .drawer__link {
  opacity: 1;
  transform: translateX(0);
  transition-delay: calc(var(--d, 0) * 45ms + 90ms);
}

.drawer__link:hover,
.drawer__link:focus-visible {
  background: var(--bg-brand-subtle);
  color: var(--color-primary);
}

.drawer__link svg {
  width: 16px;
  height: 16px;
  opacity: 0.4;
}

.drawer__link[aria-current='page'] {
  color: var(--color-primary);
}

.drawer__foot {
  margin-top: auto;
  padding: var(--sp-5);
  border-top: 1px solid var(--border-color);
  display: grid;
  gap: var(--sp-3);
}

/* ============================================================= 7. tabs === */

/* The track is deliberately the darkest surface so the thumb has something to
   read against. */
.tabs {
  display: inline-flex;
  padding: 5px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-color);
  background: var(--bg-sunken);
  position: relative;
  max-width: 100%;
}

/* A solid brand fill, same language as .btn--primary. The previous version
   used --bg-surface on --bg-page-alt, which on the dark theme are four values
   apart — the selected tab was effectively invisible. */
.tabs__thumb {
  position: absolute;
  top: 5px;
  bottom: 5px;
  border-radius: var(--radius-pill);
  background: var(--brand-teal);
  box-shadow: 0 8px 20px -8px rgba(10, 178, 151, 0.65);
  /* left/width are written by main.js from the active tab's box */
  transition: transform var(--dur) var(--ease-spring), width var(--dur) var(--ease-spring);
  pointer-events: none;
}

.tabs__btn {
  position: relative;
  z-index: 1;
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius-pill);
  font-size: clamp(0.9375rem, 1vw, 1.0625rem);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  white-space: nowrap;
  transition: color var(--dur) var(--ease-out);
}

.tabs__btn:hover {
  color: var(--text-primary);
}

.tabs__btn[aria-selected='true'] {
  color: var(--text-on-brand);
  font-weight: var(--fw-bold);
}

.tab-panel[hidden] {
  display: none;
}

/* ======================================================== 8. accordion === */

.accordion {
  display: grid;
  gap: var(--sp-3);
}

.acc-item {
  border-radius: var(--radius-md);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.acc-item.is-open {
  border-color: var(--border-brand);
  box-shadow: var(--shadow-md);
}

.acc-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  width: 100%;
  padding: clamp(1rem, 2vw, 1.35rem) clamp(1.1rem, 2.4vw, 1.6rem);
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-heading);
  color: var(--text-primary);
  transition: color var(--dur) var(--ease-out);
}

.acc-trigger:hover {
  color: var(--color-primary);
}

.acc-icon {
  position: relative;
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  transition: background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-spring);
}

.acc-icon::before,
.acc-icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 1.5px;
  border-radius: 2px;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}

.acc-icon::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.acc-item.is-open .acc-icon {
  background: var(--bg-brand-subtle);
  border-color: var(--border-brand);
  transform: rotate(180deg);
}

.acc-item.is-open .acc-icon::after {
  opacity: 0;
}

/* grid-template-rows 0fr→1fr animates to auto height without measuring. */
.acc-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-out);
}

.acc-item.is-open .acc-body {
  grid-template-rows: 1fr;
}

.acc-body > div {
  overflow: hidden;
}

.acc-body p {
  padding: 0 clamp(1.1rem, 2.4vw, 1.6rem) clamp(1.1rem, 2.2vw, 1.5rem);
  color: var(--text-secondary);
  max-width: 68ch;
}

/* ============================================================ 9. forms === */

.form {
  display: grid;
  gap: var(--sp-4);
}

.form__row {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}

.field {
  display: grid;
  gap: var(--sp-2);
}

/* A radio group is a fieldset, which carries UA borders and padding. */
fieldset.field {
  border: 0;
  padding: 0;
  min-inline-size: 0;
}

fieldset.field legend {
  padding: 0;
  margin-bottom: var(--sp-1);
}

.field__label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
}

.field__label .req {
  color: var(--color-accent-text);
}

.field__control {
  width: 100%;
  padding: 0.85rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-size: var(--fs-sm);
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.field__control::placeholder {
  color: var(--text-muted);
}

.field__control:focus {
  outline: none;
  border-color: var(--brand-teal);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-teal) 18%, transparent);
}

textarea.field__control {
  min-height: 96px;
  resize: vertical;
}

select.field__control {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%236b8681' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px;
  padding-right: 2.5rem;
}

.field__error {
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: #e0524f;
  min-height: 1em;
}

[data-theme='dark'] .field__error {
  color: #ff8b88;
}

.field.has-error .field__control {
  border-color: #e0524f;
}

.field.has-error .field__control:focus {
  box-shadow: 0 0 0 3px rgba(224, 82, 79, 0.18);
}

/* Radio group rendered as selectable chips. */
.choice-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.choice {
  position: relative;
}

.choice input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.choice span {
  display: block;
  padding: 0.6rem 1.05rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-color);
  background: var(--bg-surface);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
  transition: all var(--dur) var(--ease-out);
}

.choice input:hover + span {
  border-color: var(--border-strong);
}

.choice input:checked + span {
  border-color: var(--brand-teal);
  background: var(--bg-brand-subtle);
  color: var(--color-primary);
  font-weight: var(--fw-semibold);
}

.choice input:focus-visible + span {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Submission feedback. */
.form__status {
  display: none;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}

.form__status.is-visible {
  display: flex;
}

.form__status--ok {
  background: var(--bg-brand-subtle);
  border: 1px solid var(--border-brand);
  color: var(--color-primary);
}

.form__status--err {
  background: rgba(224, 82, 79, 0.1);
  border: 1px solid rgba(224, 82, 79, 0.35);
  color: #c0403d;
}

[data-theme='dark'] .form__status--err {
  color: #ff9b98;
}

.form__status svg {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 1px;
}

/* Spinner shown while a submit is in flight. */
.btn.is-loading {
  pointer-events: none;
  color: transparent;
}

.btn.is-loading::after {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(4, 16, 14, 0.25);
  border-top-color: var(--brand-ink);
  animation: spin 0.7s linear infinite;
}

/* =========================================================== 10. quote === */

.quote {
  position: relative;
  padding-left: clamp(1.5rem, 4vw, 3rem);
}

.quote::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.35em;
  bottom: 0.35em;
  width: 3px;
  border-radius: 3px;
  background: var(--grad-brand);
}

.quote__text {
  font-family: var(--font-display);
  font-size: var(--fs-quote);
  font-weight: var(--fw-medium);
  line-height: 1.45;
  letter-spacing: var(--ls-heading);
  color: var(--text-primary);
  text-wrap: balance;
}

.quote__by {
  margin-top: var(--sp-5);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--color-primary);
}

/* ========================================================= 11. marquee === */
/* Two identical tracks translated -50% give a seamless loop with no JS. */

/* The vertical padding is load-bearing: overflow is hidden for the loop, and
   without it the chips' hover lift and shadow were being clipped off at the
   top and bottom edges. */
.marquee {
  position: relative;
  overflow: hidden;
  padding-block: 0.9rem;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
  display: flex;
  width: max-content;
  gap: clamp(0.7rem, 1.2vw, 1rem);
}

/* The -50% loop needs two identical copies of the track; main.js makes the
   clone and then adds .is-ready. Until (or unless) that happens the strip is
   a static complete row rather than a half-empty one. */
.marquee.is-ready .marquee__track {
  animation: marquee var(--marquee-dur, 46s) linear infinite;
}

.marquee.is-ready:hover .marquee__track {
  animation-play-state: paused;
}

.marquee--reverse .marquee__track {
  animation-direction: reverse;
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7em;
  min-width: clamp(180px, 15vw, 232px);
  padding: 1rem 1.75rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-color);
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--brand-teal) 7%, var(--bg-surface)) 0%,
    var(--bg-surface) 62%
  );
  box-shadow: var(--shadow-sm), inset 0 1px 0 color-mix(in srgb, var(--text-primary) 7%, transparent);
  font-size: clamp(0.9375rem, 1vw, 1.0625rem);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  white-space: nowrap;
  transition: border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

/* The leading dot echoes the logo's dot vocabulary, with a soft halo. */
.marquee__item::before {
  content: '';
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--color-primary-fill);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-teal) 16%, transparent);
}

.marquee__item:hover {
  border-color: var(--border-brand);
  color: var(--color-primary);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

/* ==================================================== 12. logo strip ===== */

/* Client marks are dark artwork on transparency. On this near-black page
   their own colours would be invisible, and knocking them out to white
   silhouettes threw those colours away — so each sits on a light chip and
   keeps the brand exactly as its owner drew it. */
.logo-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: center;
  gap: clamp(0.75rem, 1.8vw, 1.25rem);
}

/* Equal-sized chips with the logo fitted inside. The four marks have wildly
   different aspect ratios (Loyaltree is 5:1, Krunchillo nearly square), so
   sizing them by height alone made some tower over others — capping both
   axes inside a fixed box evens them out optically. */
.logo-chip {
  flex: 1 1 210px;
  max-width: 300px;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 7;
  padding: clamp(0.5rem, 1vw, 0.8rem);
  border-radius: var(--radius-lg);
  background: #f4f7f6;
  border: 1px solid rgba(150, 220, 208, 0.14);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.logo-chip:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

/* Each mark fills whichever axis constrains it first — a 5:1 wordmark goes
   edge to edge, a squarer one fills top to bottom — so the chips read as one
   optical size instead of one bounding box. */
.logo-chip img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* ============================================================ 13. stat === */

.stat {
  display: grid;
  gap: var(--sp-2);
}

.stat__value {
  font-family: var(--font-display);
  font-size: var(--fs-numeral);
  font-weight: var(--fw-bold);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.stat__label {
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  line-height: var(--lh-snug);
}

/* ====================================================== 14. checklist ==== */

.checklist {
  display: grid;
  gap: var(--sp-4);
}

.checklist li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  color: var(--text-secondary);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}

.checklist li svg {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 1px;
  color: var(--color-primary);
}

.checklist--spaced {
  margin-top: var(--sp-8);
}

/* ========================================================= 15. footer ==== */

.site-footer {
  position: relative;
  overflow: hidden;
  background: var(--brand-ink);
  color: #cfe3df;
  padding-top: clamp(3.5rem, 7vw, 6rem);
  isolation: isolate;
}

.site-footer::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 70% 100% at 50% 0%, rgba(10, 178, 151, 0.16), transparent 62%);
}

/* The city line-art anchors the footer to the "reach across India" idea. */
.site-footer__scene {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: -1;
  width: 100%;
  opacity: 0.14;
  filter: invert(74%) sepia(46%) saturate(480%) hue-rotate(122deg) brightness(95%);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 60%);
  mask-image: linear-gradient(180deg, transparent, #000 60%);
  pointer-events: none;
}

.footer-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: minmax(260px, 1.4fr) repeat(3, minmax(140px, 1fr));
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

/* This export is already the dark-background variant — teal dots, gold apex.
   It was being inverted to flat white, which threw the brand colours away on
   the one surface it was drawn for. */
.footer-brand img {
  height: clamp(52px, 5vw, 68px);
  width: auto;
  margin-bottom: var(--sp-5);
}

.footer-brand p {
  color: #9ab8b2;
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  max-width: 38ch;
}

.footer-col__title {
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--brand-teal-bright);
  margin-bottom: var(--sp-5);
}

.footer-col ul {
  display: grid;
  gap: var(--sp-3);
}

.footer-col a {
  font-size: var(--fs-sm);
  color: #9ab8b2;
  transition: color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
  display: inline-block;
}

.footer-col a:hover {
  color: #ffffff;
  transform: translateX(3px);
}

.footer-socials {
  display: flex;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}

/* place-items centres the glyph in the circle in both axes; the old version
   relied on the img's own box and sat a pixel high. */
.footer-socials a {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid rgba(150, 220, 208, 0.2);
  background: rgba(255, 255, 255, 0.04);
  color: #b9d4cf;
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

/* The brand glyphs are drawn edge-to-edge in their own viewBox, so they can
   fill much more of the circle than a padded icon would. */
.footer-socials svg {
  width: 24px;
  height: 24px;
  display: block;
}

.footer-socials a:hover {
  border-color: var(--brand-teal);
  background: rgba(10, 178, 151, 0.16);
  color: #ffffff;
  transform: translateY(-2px);
}

.footer-contact {
  display: grid;
  gap: var(--sp-4);
  font-size: var(--fs-sm);
  color: #9ab8b2;
}

.footer-contact a {
  color: inherit;
}

.footer-contact a:hover {
  color: #ffffff;
}

/* Each address on its own line; the pair joined by "/" stays together. */
.footer-mails {
  display: grid;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.footer-contact strong {
  display: block;
  color: #eaf5f2;
  font-weight: var(--fw-semibold);
}

.footer-apps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}

.footer-apps img {
  height: 42px;
  width: auto;
  border-radius: 7px;
  transition: transform var(--dur) var(--ease-out), opacity var(--dur) var(--ease-out);
}

.footer-apps a:hover img {
  transform: translateY(-2px);
}

.footer-apps .is-soon {
  position: relative;
  opacity: 0.42;
  cursor: default;
}

/* Second footer row — addresses, people and app badges. Auto-fit rather than
   the fixed 4-column grid above, because these blocks vary in width. */
.footer-contacts {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  padding-block: clamp(2rem, 4vw, 3rem);
}

.rule--footer {
  opacity: 0.2;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: var(--sp-6);
  border-top: 1px solid rgba(150, 220, 208, 0.12);
  font-size: var(--fs-xs);
  color: #7e9b96;
}

.footer-bottom nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
}

.footer-bottom a:hover {
  color: #ffffff;
}
