/* ============================================================
   GANTALECT DESIGN SYSTEM
   Direction: "editorial engineering"
     - monochrome photography, ink-and-paper ground, one blue accent
     - dark-first (plugins/theme.js ships dark by default), light fully built
     - one radius rule, one accent, one type family

   Loaded AFTER gantalect-custom.css. It redefines the --gc-* tokens, so
   every existing page inherits the new palette and type immediately.
   Rebuilt sections use the gx-* namespace so they never fight the old CSS.
   ============================================================ */

/* ============================================================
   1. TOKENS
   ============================================================ */

:root {
  /* -- Ground & surfaces (DARK is the default theme) -- */
  --gc-ink:        #08090B;   /* deepest: full-bleed statement bands */
  --gc-bg:         #0B0D11;   /* page ground */
  --gc-surface:    #121519;   /* raised panel */
  --gc-surface-2:  #191D23;   /* panel on panel */
  --gc-line:       #262B33;   /* hairline, visible */
  --gc-line-soft:  #181C22;   /* hairline, quiet */

  /* -- Text (all verified >= WCAG AA on --gc-bg) -- */
  --gc-text:       #EDEFF2;   /* primary        ~17.4:1 */
  --gc-text-dim:   #A2A9B4;   /* secondary       ~8.3:1 */
  --gc-text-mute:  #7B838F;   /* tertiary        ~5.0:1 */

  /* -- Accent: the Gantalect blue, lifted for a dark ground -- */
  --gc-accent:     #4C8DF6;   /*                 ~5.9:1 on --gc-bg */
  --gc-accent-hi:  #6FA5F8;
  --gc-accent-ink: #08090B;   /* label ON a solid accent fill ~5.9:1 */
  --gc-accent-8:   rgba(76, 141, 246, 0.08);
  --gc-accent-14:  rgba(76, 141, 246, 0.14);
  --gc-accent-24:  rgba(76, 141, 246, 0.24);

  /* -- Feedback -- */
  --gc-danger:     #F87171;
  --gc-ok:         #4ADE80;

  /* -- Type: one family. DM Sans across the board. --
     No serif. Emphasis inside a headline is weight + accent in the SAME
     family, never a serif word dropped into a sans headline. */
  --gc-sans:  'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --gc-mono:  'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  --gc-serif: var(--gc-sans);   /* legacy alias, deliberately neutralised */

  --gc-t-display: clamp(38px, 5.2vw, 62px);   /* sized so an 8-word hero headline sets in 2 lines */
  --gc-t-h2:      clamp(28px, 3.6vw, 46px);
  --gc-t-h3:      clamp(19px, 1.5vw, 22px);
  --gc-t-lead:    clamp(16px, 1.25vw, 19px);
  --gc-t-body:    16px;
  --gc-t-sm:      14px;
  --gc-t-xs:      13px;

  /* -- Shape: ONE rule. Interactive elements and containers 3px.
        Images and media frames are square (0). Nothing is a pill. -- */
  --gc-r:    3px;
  --gc-r-img: 0px;

  /* -- Rhythm -- */
  --gc-gutter:  clamp(20px, 5vw, 56px);
  --gc-max:     1280px;
  --gc-sec:     clamp(72px, 9vw, 128px);
  --gc-sec-sm:  clamp(52px, 6vw, 84px);

  /* -- Motion (MOTION_INTENSITY 6) -- */
  --gc-ease:      cubic-bezier(0.16, 1, 0.3, 1);
  --gc-ease-out:  cubic-bezier(0.22, 0.61, 0.36, 1);
  --gc-dur:       0.5s;
  --gc-dur-slow:  0.8s;

  /* -- Elevation: tinted to the ground, never pure black -- */
  --gc-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --gc-shadow:    0 8px 28px rgba(0, 0, 0, 0.45);
  --gc-shadow-lg: 0 24px 64px rgba(0, 0, 0, 0.55);

  /* -- Photography treatment: every photo on this site is monochrome. -- */
  --gc-photo: grayscale(1) contrast(1.06);

  /* -- Z-scale. Documented, finite, no ad-hoc z-50 anywhere. -- */
  --gc-z-base:    1;
  --gc-z-sticky:  100;
  --gc-z-nav:     200;
  --gc-z-overlay: 300;
  --gc-z-modal:   400;
  --gc-z-skip:    500;
}

/* -- LIGHT MODE -- role-for-role parity with dark, not a wash-out. -- */
html[data-theme='light'] {
  --gc-ink:        #FFFFFF;
  --gc-bg:         #FAFAF9;   /* warm-neutral paper, not a blue-tinted grey */
  --gc-surface:    #FFFFFF;
  --gc-surface-2:  #F3F3F1;
  --gc-line:       #E2E2DE;
  --gc-line-soft:  #EDEDE9;

  --gc-text:       #101215;   /* ~17.6:1 on --gc-bg */
  --gc-text-dim:   #4E535B;   /*  ~8.4:1 */
  --gc-text-mute:  #6C727C;   /*  ~5.3:1 */

  --gc-accent:     #1B5FD9;   /*  ~5.5:1 on --gc-bg */
  --gc-accent-hi:  #1247AC;
  --gc-accent-ink: #FFFFFF;   /*  ~5.7:1 on a solid accent fill */
  --gc-accent-8:   rgba(27, 95, 217, 0.06);
  --gc-accent-14:  rgba(27, 95, 217, 0.11);
  --gc-accent-24:  rgba(27, 95, 217, 0.20);

  --gc-danger:     #C42B1C;
  --gc-ok:         #157347;

  --gc-shadow-sm: 0 1px 2px rgba(16, 18, 21, 0.06);
  --gc-shadow:    0 8px 28px rgba(16, 18, 21, 0.08);
  --gc-shadow-lg: 0 24px 64px rgba(16, 18, 21, 0.12);

  --gc-photo: grayscale(1) contrast(1.02);
}

/* Legacy aliases so the not-yet-rebuilt pages keep resolving. */
:root {
  --gc-blue:       var(--gc-accent);
  --gc-blue-lt:    var(--gc-accent-hi);
  --gc-blue-dk:    var(--gc-accent-hi);
  --gc-navy:       var(--gc-text);
  --gc-navy-lt:    var(--gc-text-dim);
  --gc-white:      var(--gc-surface);
  --gc-border:     var(--gc-line);
  --gc-border-lt:  var(--gc-line-soft);
  --gc-text-light: var(--gc-text-mute);
}

/* ============================================================
   2. BASE
   ============================================================ */

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--gc-bg) !important;
  color: var(--gc-text) !important;
  font-family: var(--gc-sans) !important;
  font-size: var(--gc-t-body);
  line-height: 1.6;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.page-wrapper { background: var(--gc-bg) !important; }

::selection { background: var(--gc-accent); color: var(--gc-accent-ink); }

/* Focus: one visible ring everywhere. Never removed. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--gc-accent);
  outline-offset: 2px;
  border-radius: var(--gc-r);
}

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

/* ============================================================
   3. LAYOUT PRIMITIVES
   ============================================================ */

.gx-wrap {
  width: 100%;
  max-width: var(--gc-max);
  margin-inline: auto;
  padding-inline: var(--gc-gutter);
}

/* Legacy containers adopt the new measure so old pages line up. */
.gc-container,
.auto-container {
  width: 100%;
  max-width: var(--gc-max);
  margin-inline: auto;
  padding-inline: var(--gc-gutter);
}

.gx-section { padding-block: var(--gc-sec); position: relative; }
.gx-section--sm { padding-block: var(--gc-sec-sm); }

/* A quiet hairline between sections, used instead of boxing things in cards. */
.gx-rule { border: 0; border-top: 1px solid var(--gc-line-soft); margin: 0; }

/* ============================================================
   4. TYPOGRAPHY
   ============================================================ */

.gx-display,
.gx-h2,
.gx-h3 {
  font-family: var(--gc-sans);
  color: var(--gc-text);
  margin: 0;
  text-wrap: balance;
}

.gx-display {
  font-size: var(--gc-t-display);
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.035em;
  /* Descender reserve: nothing clips, even at leading 1.04. */
  padding-bottom: 0.06em;
}

.gx-h2 {
  font-size: var(--gc-t-h2);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.03em;
  padding-bottom: 0.05em;
}

.gx-h3 {
  font-size: var(--gc-t-h3);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.015em;
}

/* Same-family emphasis: weight + accent. Never a serif word in a sans line. */
.gx-display em,
.gx-h2 em,
.gx-h3 em,
.gc-heading em {
  font-style: normal;
  font-weight: 500;
  color: var(--gc-accent);
}

.gx-lead {
  font-size: var(--gc-t-lead);
  line-height: 1.62;
  color: var(--gc-text-dim);
  max-width: 62ch;
  margin: 0;
}

.gx-body {
  font-size: var(--gc-t-body);
  line-height: 1.68;
  color: var(--gc-text-dim);
  max-width: 65ch;
  margin: 0;
}

.gx-sm { font-size: var(--gc-t-sm); line-height: 1.6; color: var(--gc-text-dim); }

/* Eyebrow. Rationed: at most one per three sections, page-wide. */
.gx-eyebrow {
  display: block;
  font-size: var(--gc-t-xs);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--gc-accent);
  margin: 0 0 14px;
}

/* Old headings inherit the new scale so untouched pages stop looking dated. */
.gc-heading {
  font-family: var(--gc-sans) !important;
  font-size: var(--gc-t-h2) !important;
  font-weight: 500 !important;
  line-height: 1.1 !important;
  letter-spacing: -0.03em !important;
  color: var(--gc-text) !important;
}

h1, h2, h3, h4, h5, h6 { font-family: var(--gc-sans); color: var(--gc-text); }

/* ============================================================
   5. BUTTONS & LINKS
   Contrast verified both modes:
     dark  - accent fill #4C8DF6 + ink label #08090B  = 5.9:1
     light - accent fill #1B5FD9 + white label        = 5.7:1
   Labels are 1-2 words and never wrap at desktop (white-space: nowrap).
   ============================================================ */

.gx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: var(--gc-r);
  font-family: var(--gc-sans);
  font-size: var(--gc-t-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--gc-dur) var(--gc-ease),
              border-color var(--gc-dur) var(--gc-ease),
              color var(--gc-dur) var(--gc-ease),
              transform 0.14s var(--gc-ease-out);
}

.gx-btn svg { flex: none; transition: transform var(--gc-dur) var(--gc-ease); }
.gx-btn:hover svg { transform: translateX(3px); }

.gx-btn--primary {
  background: var(--gc-accent);
  color: var(--gc-accent-ink);
}
.gx-btn--primary:hover  { background: var(--gc-accent-hi); color: var(--gc-accent-ink); }
.gx-btn--primary:active { transform: translateY(1px) scale(0.985); }

.gx-btn--ghost {
  background: transparent;
  color: var(--gc-text);
  border-color: var(--gc-line);
}
.gx-btn--ghost:hover  { border-color: var(--gc-text-mute); color: var(--gc-text); background: var(--gc-surface); }
.gx-btn--ghost:active { transform: translateY(1px) scale(0.985); }

/* On a photographic or ink ground the ghost button needs its own contrast. */
.gx-on-ink .gx-btn--ghost {
  color: #FFFFFF;
  border-color: rgba(255, 255, 255, 0.32);
}
.gx-on-ink .gx-btn--ghost:hover {
  border-color: #FFFFFF;
  background: rgba(255, 255, 255, 0.1);
}

/* Legacy button classes adopt the new look. */
.gc-btn--primary { composes: none; }
.gc-btn--primary,
.gc-btn--ghost,
.gc-btn--white,
.theme-btn,
.btn-style-one {
  display: inline-flex !important;
  align-items: center;
  gap: 8px;
  padding: 13px 22px !important;
  border-radius: var(--gc-r) !important;
  font-family: var(--gc-sans) !important;
  font-size: var(--gc-t-sm) !important;
  font-weight: 600 !important;
  line-height: 1 !important;
  white-space: nowrap;
  text-transform: none !important;
  box-shadow: none !important;
  transition: background var(--gc-dur) var(--gc-ease),
              color var(--gc-dur) var(--gc-ease),
              border-color var(--gc-dur) var(--gc-ease),
              transform 0.14s var(--gc-ease-out);
}

.gc-btn--primary,
.theme-btn,
.btn-style-one {
  background: var(--gc-accent) !important;
  color: var(--gc-accent-ink) !important;
  border: 1px solid var(--gc-accent) !important;
}
.gc-btn--primary:hover,
.theme-btn:hover,
.btn-style-one:hover {
  background: var(--gc-accent-hi) !important;
  border-color: var(--gc-accent-hi) !important;
  color: var(--gc-accent-ink) !important;
}

.gc-btn--ghost {
  background: transparent !important;
  color: var(--gc-text) !important;
  border: 1px solid var(--gc-line) !important;
}
.gc-btn--ghost:hover { border-color: var(--gc-text-mute) !important; background: var(--gc-surface) !important; }

/* .gc-btn--white sat on dark bands: keep it legible without inverting theme. */
.gc-btn--white {
  background: var(--gc-accent) !important;
  color: var(--gc-accent-ink) !important;
  border: 1px solid var(--gc-accent) !important;
}
.gc-btn--white:hover { background: var(--gc-accent-hi) !important; }

.gc-btn--primary:active,
.gc-btn--ghost:active,
.gc-btn--white:active { transform: translateY(1px) scale(0.985); }

/* Inline text link */
.gx-link {
  color: var(--gc-accent);
  text-decoration: none;
  border-bottom: 1px solid var(--gc-accent-24);
  transition: border-color var(--gc-dur) var(--gc-ease);
}
.gx-link:hover { border-bottom-color: var(--gc-accent); color: var(--gc-accent); }

/* ============================================================
   6. MEDIA
   Every photograph on the site is monochrome. That is the art direction,
   and it is also what makes the single blue accent read as a signal.
   ============================================================ */

.gx-figure {
  position: relative;
  overflow: hidden;
  border-radius: var(--gc-r-img);
  background: var(--gc-surface-2);
  /* Reserved ratio prevents layout shift (CLS). */
}

.gx-figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: var(--gc-photo);
  transition: transform var(--gc-dur-slow) var(--gc-ease);
}

a:hover > .gx-figure img,
.gx-figure--zoom:hover img { transform: scale(1.04); }

/* Scrim for type over photography. Guarantees AA on the copy above it. */
.gx-scrim::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 9, 11, 0.35) 0%, rgba(8, 9, 11, 0.82) 100%);
  pointer-events: none;
}

/* ============================================================
   7. MOTION
   Every animation here has a job:
     reveal     - storytelling: content arrives in reading order
     stagger    - hierarchy: headline lands before its supporting copy
     btn press  - feedback: acknowledges the click
     img zoom   - feedback: signals the card is a link
     nav rule   - state transition: the page has scrolled
   Nothing loops forever except the one logo marquee.
   ============================================================ */

/* Content is visible by DEFAULT. The reveal plugin adds .gx-motion to <html>
   only once the observer is actually running, so a JS failure, a crawler, or
   the pre-hydration SSR paint can never leave the page blank. */
html.gx-motion [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--gc-dur-slow) var(--gc-ease),
              transform var(--gc-dur-slow) var(--gc-ease);
  transition-delay: calc(var(--i, 0) * 70ms);
  will-change: opacity, transform;
}

html.gx-motion [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  will-change: auto;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  html.gx-motion [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .gx-nav { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: var(--gc-bg) !important; }
}

/* ============================================================
   8. NAVIGATION
   One line at desktop, 68px tall. Hairline appears on scroll.
   ============================================================ */

.gx-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--gc-z-nav);
  height: 68px;
  display: flex;
  align-items: center;
  gap: 24px;
  padding-inline: var(--gc-gutter);
  background: color-mix(in srgb, var(--gc-bg) 82%, transparent);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border-bottom: 1px solid transparent;
  transition: border-color var(--gc-dur) var(--gc-ease),
              background var(--gc-dur) var(--gc-ease);
}

@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .gx-nav { background: var(--gc-bg); }
}

.gx-nav.is-scrolled { border-bottom-color: var(--gc-line); }

.gx-nav__logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--gc-text);
  flex: none;
}

.gx-nav__logo img { height: 26px; width: auto; display: block; }

.gx-nav__brand {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--gc-text);
}

.gx-nav__links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0 0 0 auto;
  padding: 0;
  list-style: none;
}

.gx-nav__links a {
  display: block;
  padding: 8px 12px;
  border-radius: var(--gc-r);
  font-size: var(--gc-t-sm);
  font-weight: 500;
  color: var(--gc-text-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--gc-dur) var(--gc-ease), background var(--gc-dur) var(--gc-ease);
}

.gx-nav__links a:hover { color: var(--gc-text); background: var(--gc-surface); }
.gx-nav__links a.nuxt-link-exact-active { color: var(--gc-text); }

.gx-nav__actions { display: flex; align-items: center; gap: 8px; flex: none; }

.gx-nav__cta {
  padding: 10px 16px;
  border-radius: var(--gc-r);
  background: var(--gc-accent);
  color: var(--gc-accent-ink) !important;
  font-size: var(--gc-t-sm);
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--gc-dur) var(--gc-ease), transform 0.14s var(--gc-ease-out);
}
.gx-nav__cta:hover  { background: var(--gc-accent-hi); }
.gx-nav__cta:active { transform: translateY(1px) scale(0.985); }

.gx-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  background: transparent;
  color: var(--gc-text-dim);
  cursor: pointer;
  transition: color var(--gc-dur) var(--gc-ease), border-color var(--gc-dur) var(--gc-ease);
}
.gx-iconbtn:hover { color: var(--gc-text); border-color: var(--gc-text-mute); }

/* Hamburger: three rules that become an X. */
.gx-burger { display: none; flex-direction: column; gap: 4px; }
.gx-burger span {
  display: block;
  width: 16px;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--gc-dur) var(--gc-ease), opacity 0.2s linear;
}
.gx-burger.is-open span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.gx-burger.is-open span:nth-child(2) { opacity: 0; }
.gx-burger.is-open span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

.gx-nav__mobile {
  position: fixed;
  inset: 68px 0 auto 0;
  z-index: var(--gc-z-nav);
  background: var(--gc-bg);
  border-bottom: 1px solid var(--gc-line);
  padding: 8px var(--gc-gutter) 20px;
  display: none;
}
.gx-nav__mobile.is-open { display: block; }
.gx-nav__mobile ul { list-style: none; margin: 0; padding: 0; }
.gx-nav__mobile a {
  display: block;
  padding: 14px 0;
  border-bottom: 1px solid var(--gc-line-soft);
  font-size: 17px;
  font-weight: 500;
  color: var(--gc-text);
  text-decoration: none;
}
.gx-nav__mobile .gx-btn { width: 100%; margin-top: 18px; }

@media (max-width: 900px) {
  .gx-nav__links { display: none; }
  .gx-burger { display: inline-flex; }
  .gx-nav__cta { display: none; }
}

@media (min-width: 901px) {
  .gx-nav__mobile { display: none !important; }
}

/* ============================================================
   9. LOGO MARQUEE  (the ONE marquee on the page)
   Breadth without giving each logo individual attention.
   ============================================================ */

.gx-logos { padding-block: var(--gc-sec-sm); border-bottom: 1px solid var(--gc-line-soft); }

.gx-logos__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.gx-logos__track {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(40px, 6vw, 80px);
  row-gap: 28px;
}

/* The marquee only engages when there are enough logos to be worth scrolling.
   With a handful, a still row reads as confidence; a scroller reads as filler. */
.gx-logos__track--marquee {
  flex-wrap: nowrap;
  justify-content: flex-start;
  width: max-content;
  animation: gx-marquee 32s linear infinite;
}
.gx-logos__viewport:hover .gx-logos__track { animation-play-state: paused; }

/* Most client logos are dark artwork on transparency. On the ink ground they
   have to be inverted, not brightened: brightening pure black leaves it black.
   `--logo-scale` gives upright marks the extra height they need to sit at the
   same optical weight as a wide wordmark. */
.gx-logos__item {
  --logo-scale: 1;
  display: flex;
  align-items: center;
}

.gx-logos__art {
  display: block;
  height: calc(30px * var(--logo-scale));
  width: auto;
  max-width: 160px;
  object-fit: contain;
  filter: grayscale(1) invert(1);
  opacity: 0.55;
  transition: opacity var(--gc-dur) var(--gc-ease);
}

.gx-logos__item:hover .gx-logos__art { opacity: 1; }

html[data-theme='light'] .gx-logos__art { filter: grayscale(1); opacity: 0.6; }
html[data-theme='light'] .gx-logos__item:hover .gx-logos__art { opacity: 1; }

/* Brands that supply their own artwork for dark backgrounds: swap the file
   rather than filtering, and never invert artwork already drawn for dark. */
.gx-logos__item--themed .gx-logos__art { filter: grayscale(1); }

.gx-logos__item--themed .gx-logos__art--light { display: none; }
.gx-logos__item--themed .gx-logos__art--dark { display: block; }

html[data-theme='light'] .gx-logos__item--themed .gx-logos__art--light { display: block; }
html[data-theme='light'] .gx-logos__item--themed .gx-logos__art--dark { display: none; }

@keyframes gx-marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .gx-logos__track--marquee {
    animation: none;
    width: 100%;
    flex-wrap: wrap;
    justify-content: center;
  }
}

/* ============================================================
   10. FOOTER
   ============================================================ */

.gx-footer {
  border-top: 1px solid var(--gc-line);
  padding-block: var(--gc-sec-sm) 32px;
  background: var(--gc-bg);
}

.gx-footer__top {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 48px;
}

.gx-footer__brand { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.gx-footer__brand img { height: 26px; width: auto; }
.gx-footer__brand span { font-size: 17px; font-weight: 600; letter-spacing: -0.025em; }

.gx-footer h4 {
  font-size: var(--gc-t-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--gc-text);
  margin: 0 0 14px;
}

.gx-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }

.gx-footer a {
  font-size: var(--gc-t-sm);
  color: var(--gc-text-dim);
  text-decoration: none;
  transition: color var(--gc-dur) var(--gc-ease);
}
.gx-footer a:hover { color: var(--gc-text); }

.gx-footer__bottom {
  border-top: 1px solid var(--gc-line-soft);
  padding-top: 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
  font-size: var(--gc-t-xs);
  color: var(--gc-text-mute);
}

.gx-footer__social { display: flex; gap: 8px; }

@media (max-width: 900px) {
  .gx-footer__top { grid-template-columns: 1fr 1fr; gap: 32px; }
}
@media (max-width: 560px) {
  .gx-footer__top { grid-template-columns: 1fr; }
}

/* ============================================================
   11. FORM CONTROLS
   Label above input. Helper below. Error below that. No placeholder-as-label.
   All four verified >= AA against --gc-surface in both modes.
   ============================================================ */

.gx-field { display: grid; gap: 8px; }

.gx-field label {
  font-size: var(--gc-t-sm);
  font-weight: 500;
  color: var(--gc-text);
}

.gx-field input,
.gx-field textarea,
.gx-field select {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  background: var(--gc-surface);
  color: var(--gc-text);
  font-family: var(--gc-sans);
  font-size: var(--gc-t-body);
  line-height: 1.5;
  transition: border-color var(--gc-dur) var(--gc-ease), background var(--gc-dur) var(--gc-ease);
}

.gx-field input::placeholder,
.gx-field textarea::placeholder { color: var(--gc-text-mute); opacity: 1; }

.gx-field input:focus,
.gx-field textarea:focus,
.gx-field select:focus {
  outline: 2px solid var(--gc-accent);
  outline-offset: 1px;
  border-color: var(--gc-accent);
}

.gx-field__help  { font-size: var(--gc-t-xs); color: var(--gc-text-mute); }
.gx-field__error { font-size: var(--gc-t-xs); color: var(--gc-danger); }

.gx-field.has-error input,
.gx-field.has-error textarea { border-color: var(--gc-danger); }

/* Old template inputs inherit the same treatment. */
.gc-field input,
.gc-field textarea,
input[type='text'],
input[type='email'],
input[type='tel'],
textarea {
  background: var(--gc-surface) !important;
  border: 1px solid var(--gc-line) !important;
  border-radius: var(--gc-r) !important;
  color: var(--gc-text) !important;
  font-family: var(--gc-sans) !important;
}
input::placeholder, textarea::placeholder { color: var(--gc-text-mute) !important; opacity: 1 !important; }

/* ============================================================
   12. STATE PATTERNS  (loading / empty / error)
   ============================================================ */

.gx-skeleton {
  background: linear-gradient(90deg, var(--gc-surface) 0%, var(--gc-surface-2) 50%, var(--gc-surface) 100%);
  background-size: 200% 100%;
  animation: gx-shimmer 1.4s linear infinite;
  border-radius: var(--gc-r);
}
@keyframes gx-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .gx-skeleton { animation: none; background: var(--gc-surface-2); }
}

.gx-empty {
  border: 1px dashed var(--gc-line);
  border-radius: var(--gc-r);
  padding: 40px 28px;
  text-align: center;
  color: var(--gc-text-dim);
}

.gx-note {
  border-left: 2px solid var(--gc-accent);
  padding: 12px 0 12px 16px;
  font-size: var(--gc-t-sm);
  color: var(--gc-text-dim);
}
.gx-note--error { border-left-color: var(--gc-danger); color: var(--gc-danger); }
.gx-note--ok    { border-left-color: var(--gc-ok); color: var(--gc-ok); }

/* ============================================================
   13. RETIRED
   Decoration the overhaul removes wherever it still renders on
   pages not yet rebuilt.
   ============================================================ */

/* Section-number eyebrows, status dots, scroll cues, mono micro-labels. */
.gc-hero__tag-dot,
.gc-products__badge-dot,
.gc-scroll-cue,
.gc-hero__scroll { display: none !important; }

/* The old serif emphasis, everywhere it survives. */
.gc-heading em,
.section-title em,
h1 em, h2 em, h3 em {
  font-family: var(--gc-sans) !important;
  font-style: normal !important;
  font-weight: 500 !important;
  color: var(--gc-accent) !important;
}

/* ============================================================
   14. EVIDENCE LAYER
   ============================================================
   Added after a review of how established software consultancies
   present themselves (Thoughtworks, Railsware, Netguru and others).

   The finding: what separates an engineering firm's site from a design
   studio's is not prettiness, it is INFORMATION. Consultancy sites that
   convert are denser, more structured, and more specific. They show
   named work, measured outcomes, real stacks and real people. The
   recurring failure mode in the literature is described exactly as
   "hidden work" - a site that asserts capability instead of showing it.

   This section adds the vocabulary that carries evidence:
     - a monospace metadata register for genuinely technical data
     - tabular figures, so numbers line up like numbers
     - metrics, stack tags, and structured record surfaces

   Density moves from the airy editorial setting (4) to a working
   engineering setting (6). Space is still generous, but it now has to
   earn its place against content.
   ============================================================ */

:root {
  /* Tighter section rhythm: the page carries more, and reads as busier
     in the way a capable firm's site should. */
  --gc-sec:    clamp(64px, 7vw, 104px);
  --gc-sec-sm: clamp(44px, 5vw, 68px);
}

/* -- Monospace metadata --
   Reserved for data that is actually technical: stack names, versions,
   identifiers, measurements, dates on a record. It is NOT a decorative
   label style, and it never sits above a section heading as an eyebrow. */
.gx-meta {
  font-family: var(--gc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--gc-text-mute);
}

/* Any figure meant to be compared with another figure gets tabular
   numerals, so columns align and digits do not jitter as they change. */
.gx-num,
.gx-metric__value,
.gx-table td,
.gx-record__value {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* -- Metric: one measured outcome --
   The single highest-value unit on a consultancy site. A number a client
   can check beats any adjective. */
.gx-metric {
  display: grid;
  gap: 6px;
  align-content: start;
}

.gx-metric__value {
  font-size: clamp(30px, 3.6vw, 46px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--gc-text);
  padding-bottom: 0.04em;
}

.gx-metric__value em {
  font-style: normal;
  color: var(--gc-accent);
}

.gx-metric__label {
  font-size: var(--gc-t-sm);
  line-height: 1.45;
  color: var(--gc-text-mute);
  max-width: 26ch;
}

.gx-metrics {
  display: grid;
  gap: 28px clamp(24px, 4vw, 56px);
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

/* -- Stack tag --
   Naming the actual technology is a trust signal to a technical
   evaluator. "Django, Postgres, Flutter" reads as competence in a way
   that "modern technologies" never will. */
.gx-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.gx-tag {
  display: inline-flex;
  align-items: center;
  padding: 5px 9px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  background: var(--gc-surface);
  font-family: var(--gc-mono);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--gc-text-dim);
  white-space: nowrap;
}

/* -- Record: a labelled key/value row --
   The structured surface an engineering firm reaches for instead of a
   paragraph. Used for engagement facts, project vitals, spec rows. */
.gx-records {
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--gc-line);
}

.gx-record {
  display: grid;
  gap: 4px;
  padding: 14px 0;
  border-bottom: 1px solid var(--gc-line-soft);
}

.gx-record__key {
  font-family: var(--gc-mono);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--gc-text-mute);
}

.gx-record__value {
  margin: 0;
  font-size: var(--gc-t-sm);
  line-height: 1.55;
  color: var(--gc-text);
}

@media (min-width: 640px) {
  .gx-record {
    grid-template-columns: minmax(120px, 0.28fr) minmax(0, 0.72fr);
    gap: 20px;
    align-items: baseline;
  }
}

/* -- Case study card --
   Outcome-led: the headline states what changed, not what was built.
   The client, sector and stack sit as metadata beneath it. */
.gx-case {
  display: grid;
  gap: 18px;
  padding: 0;
  text-decoration: none;
  color: inherit;
}

.gx-case__figure {
  aspect-ratio: 16 / 10;
}

.gx-case__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
}

.gx-case__client {
  font-family: var(--gc-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--gc-accent);
}

.gx-case__sector {
  font-family: var(--gc-mono);
  font-size: 11.5px;
  color: var(--gc-text-mute);
}

.gx-case__headline {
  margin: 0;
  font-size: clamp(20px, 1.9vw, 26px);
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -0.022em;
  color: var(--gc-text);
  max-width: 24ch;
  transition: color var(--gc-dur) var(--gc-ease);
}

a.gx-case:hover .gx-case__headline {
  color: var(--gc-accent);
}

.gx-case__body {
  margin: 0;
  font-size: var(--gc-t-sm);
  line-height: 1.62;
  color: var(--gc-text-dim);
  max-width: 48ch;
}

/* -- Pending work slot --
   Shown where a case study exists but its facts have not been supplied.
   Deliberately looks unfinished: an empty frame is a prompt to fill it,
   whereas invented content is a lie that looks finished. */
.gx-case--pending {
  border: 1px dashed var(--gc-line);
  border-radius: var(--gc-r);
  padding: 22px;
  background: transparent;
}

.gx-case--pending .gx-case__headline {
  color: var(--gc-text-mute);
}
