/* ==========================================================================
   Stone Bridge Tech — homepage
   Design reference: /design/Stone Bridge Tech Homepage.dc.html
   Radius is 0 everywhere except the two rects in the hosting icon. No shadows.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Fonts
   -------------------------------------------------------------------------- */

/* IBM Plex is self-hosted rather than pulled from Google Fonts: a third-party
   stylesheet blocks first paint and then costs a second round trip for the
   files themselves. Latin and Latin Extended only — the unicode-range means a
   browser fetches the -ext file solely if the page actually uses those glyphs.
   Regenerate with the URLs in fonts/README.md. */

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-sans-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-sans-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-sans-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-sans-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-sans-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-sans-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-mono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-mono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ibm-plex-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Brand palette (Brand Guidelines, page 03) */
  --ink-navy:        #0A1220;
  --deep-blue:       #1E3E7B;
  --signal-blue:     #2A5099;
  --sky:             #6E94D6;
  --paper:           #FBFAF8;

  /* Surfaces */
  --white:           #FFFFFF;
  --footer-navy:     #070D17;
  --form-navy:       #101B2E;
  --grey-field:      #F2F3F5;
  --media-placeholder: #E8EAEE;

  /* Text on light */
  --body-grey:       #46536B;
  --lede-grey:       #3D4A61;

  /* Text on dark */
  --dark-text-1:     #B9C3D4;
  --dark-text-2:     #C4CDDC;
  --dark-text-3:     #8593AB;
  --dark-text-4:     #E8EBF0;

  /* Borders on light */
  --border:          #E4E7EC;
  --border-strong:   #DDE1E8;
  --border-light:    #EDEFF2;
  --border-dashed:   #C9D0DA;

  /* Borders on dark */
  --dark-border-1:   #24314A;
  --dark-border-2:   #2C3B57;
  --dark-border-3:   #1E2A40;
  --dark-border-4:   #1A2438;

  /* Type */
  --sans: 'IBM Plex Sans', Helvetica, Arial, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Layout */
  --container: 1180px;
  --gutter: 40px;
  --header-height: 71px;

  /* Motion */
  --hover-ease: 130ms ease;
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-navy);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, dl, dd, figure, fieldset { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
fieldset { border: 0; padding: 0; min-width: 0; }
legend { padding: 0; }

a {
  color: var(--deep-blue);
  text-decoration: none;
  transition: color var(--hover-ease), border-color var(--hover-ease), background-color var(--hover-ease);
}
a:hover { color: var(--ink-navy); }

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

::selection {
  background: var(--sky);
  color: var(--ink-navy);
}

:focus-visible {
  outline: 2px solid var(--sky);
  outline-offset: 2px;
}

/* Anchor targets clear the sticky header. */
[id] { scroll-margin-top: 80px; }

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

.skip-link {
  position: absolute;
  left: 0; top: 0;
  z-index: 40;
  transform: translateY(-110%);
  background: var(--ink-navy);
  color: var(--paper);
  padding: 12px 20px;
  font-size: 14px;
  font-weight: 500;
}
.skip-link:focus {
  transform: translateY(0);
  color: var(--paper);
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* --------------------------------------------------------------------------
   3. Shared section patterns
   -------------------------------------------------------------------------- */

.section {
  padding-block: 104px;
  border-bottom: 1px solid var(--border);
}
.section--light { background: var(--paper); }
.section--field { background: var(--grey-field); }

.section-head {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 40px 72px;
  align-items: start;
  margin-bottom: 56px;
}
.section-head--tight { gap: 32px 72px; }

.section-head__lead {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--deep-blue);
}
.eyebrow__rule {
  width: 22px;
  height: 1px;
  background: currentColor;
  flex: none;
}

.section-title {
  font-size: clamp(34px, 3.7vw, 47px);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.032em;
  text-wrap: balance;
}

.section-lede {
  border-top: 1px solid var(--border-strong);
  padding-top: 24px;
  font-size: 17.5px;
  line-height: 1.72;
  color: var(--lede-grey);
  max-width: 34rem;
  text-wrap: pretty;
}

/* Dark variants */
.section-head--dark .eyebrow { color: var(--sky); }
.section-head--dark .section-title { color: var(--paper); }
.section-head--dark .section-lede {
  border-top-color: var(--dark-border-1);
  color: var(--dark-text-1);
}

/* Buttons */
.btn {
  font-size: 15px;
  font-weight: 500;
  font-family: var(--sans);
  display: inline-block;
}
.btn--primary {
  background: var(--deep-blue);
  color: var(--white);
  padding: 15px 28px;
}
.btn--primary:hover {
  background: var(--signal-blue);
  color: var(--white);
}
.btn--quiet {
  color: var(--dark-text-1);
  border-bottom: 1px solid var(--dark-border-2);
  padding-bottom: 3px;
}
.btn--quiet:hover {
  color: var(--paper);
  border-bottom-color: var(--sky);
}

/* --------------------------------------------------------------------------
   4. Header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(251, 250, 248, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

.site-header__inner {
  padding-block: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ink-navy);
}
.brand:hover { color: var(--ink-navy); }
.brand__mark { flex: none; }
.brand__name {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 14px 26px;
  flex-wrap: wrap;
}
.site-nav__link {
  font-size: 14px;
  font-weight: 500;
  color: var(--body-grey);
}
.site-nav__link:hover { color: var(--ink-navy); }

/* Matches the hero's primary button: deep blue, lifting to signal blue. */
.site-nav__cta {
  font-size: 14px;
  font-weight: 500;
  background: var(--deep-blue);
  color: var(--white);
  padding: 11px 20px;
}
.site-nav__cta:hover {
  background: var(--signal-blue);
  color: var(--white);
}

/* Burger — hidden until the mobile breakpoint (see §14). */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-navy);
  cursor: pointer;
  transition: border-color var(--hover-ease), background-color var(--hover-ease);
}
.nav-toggle:hover { border-color: var(--deep-blue); }
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

/* --------------------------------------------------------------------------
   5. Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  background: var(--ink-navy);
  color: var(--paper);
}

.hero__media,
.hero__scrim {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 340px;
}
/* <picture> is inline by default, so the img's height: 100% would resolve
   against an auto-height box instead of the 340px media band. */
.hero__media picture,
.work-card__media picture {
  display: block;
  width: 100%;
  height: 100%;
}
.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero__scrim {
  pointer-events: none;
  background: linear-gradient(
    180deg,
    #0A1220 0%,
    rgba(10, 18, 32, 0.72) 22%,
    rgba(10, 18, 32, 0.30) 58%,
    rgba(10, 18, 32, 0.30) 100%
  );
}

.hero__inner {
  position: relative;
  padding-top: 124px;
  padding-bottom: 340px;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  gap: 30px;
  max-width: 44rem;
}

.hero__title {
  font-size: clamp(44px, 5.6vw, 68px);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

/* Sits inside the h1 so the heading states what the company does, not only the
   line it leads with. Styled as an eyebrow so the big line stays dominant. */
.hero__title-sub {
  display: block;
  margin-top: 20px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sky);
  text-wrap: pretty;
}

.hero__lede {
  max-width: 30rem;
  font-size: 18px;
  line-height: 1.6;
  color: var(--dark-text-1);
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   6. Trusted by
   -------------------------------------------------------------------------- */

.clients {
  background: var(--paper);
  border-bottom: 1px solid var(--border);
}
.clients__inner {
  padding-block: 40px;
  display: flex;
  align-items: center;
  gap: 48px;
  flex-wrap: wrap;
}
.clients__label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--body-grey);
  white-space: nowrap;
}
.clients__grid {
  flex: 1;
  min-width: 280px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 20px;
  align-items: center;
}
.clients__logo {
  height: 34px;
  border: 1px dashed var(--border-dashed);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--body-grey);
}

/* --------------------------------------------------------------------------
   7. Services
   -------------------------------------------------------------------------- */

/* Column counts are set explicitly per breakpoint in section 14 so the odd
   card left alone on the last row can be centred. */
.service-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
}

.service-card {
  background: var(--white);
  border: 1px solid var(--border);
  padding: 40px;
  display: flex;
  flex-direction: column;
  gap: 24px;
  transition: border-color var(--hover-ease);
}
.service-card:hover { border-color: var(--deep-blue); }

.service-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.service-card__num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--body-grey);
}
.service-card__title {
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -0.025em;
}
.service-card__body {
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--body-grey);
  text-wrap: pretty;
}

.card-list { border-top: 1px solid var(--border-light); }
.card-list__item {
  padding: 13px 0;
  border-bottom: 1px solid var(--border-light);
  font-size: 14.5px;
  color: var(--ink-navy);
}
.card-list__item:last-child { border-bottom: 0; }

/* --------------------------------------------------------------------------
   8. Stats
   -------------------------------------------------------------------------- */

.stats {
  background: var(--ink-navy);
  color: var(--paper);
  padding-block: 84px;
}
.stats__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 44px 40px;
}
.stat {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.stat__figure {
  font-family: var(--mono);
  font-size: 46px;
  font-weight: 400;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--paper);
}
.stat__rule {
  height: 3px;
  width: 34px;
  background: var(--sky);
}
.stat__label {
  font-size: 15px;
  line-height: 1.55;
  color: var(--dark-text-1);
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   9. Portfolio
   -------------------------------------------------------------------------- */

.work-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}
.work-card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--border-strong);
  display: flex;
  flex-direction: column;
  transition: border-color var(--hover-ease);
}
.work-card:hover,
.work-card:focus-within { border-color: var(--deep-blue); }
.work-card__media {
  position: relative;
  height: 200px;
  background: var(--media-placeholder);
  overflow: hidden;
}
.work-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Screenshots of landing pages: the logo and headline sit at the left, so
     anchor the crop there rather than losing them to a centred crop. */
  object-position: left center;
}
/* Hovering (or tabbing to) a card tints the screenshot and names the live site. */
.work-card__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: rgba(10, 18, 32, 0.78);
  color: var(--paper);
  opacity: 0;
  transition: opacity var(--hover-ease);
}
.work-card:hover .work-card__overlay,
.work-card:focus-within .work-card__overlay { opacity: 1; }
.work-card__overlay-icon {
  transform: translateY(4px);
  transition: transform var(--hover-ease);
}
.work-card:hover .work-card__overlay-icon,
.work-card:focus-within .work-card__overlay-icon { transform: translateY(0); }
.work-card__overlay-url {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dark-text-4);
}
/* No hover on touch: keep the icon visible so the card reads as a link. */
@media (hover: none) {
  .work-card__overlay {
    opacity: 1;
    background: linear-gradient(to top, rgba(10, 18, 32, 0.82), rgba(10, 18, 32, 0) 62%);
    justify-content: flex-end;
    padding-bottom: 16px;
    gap: 8px;
  }
  .work-card__overlay-icon { display: none; }
}
.work-card__body {
  padding: 30px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1;
}
.work-card__category {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--body-grey);
}
.work-card__title {
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
/* The title carries the link; its pseudo-element covers the whole card so any
   part of the card opens the site, while screen readers get one clear link. */
.work-card__link { color: inherit; }
.work-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.work-card:hover .work-card__link { color: var(--deep-blue); }
.work-card__text {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--body-grey);
  text-wrap: pretty;
  flex: 1;
}

/* --------------------------------------------------------------------------
   10. Technologies
   -------------------------------------------------------------------------- */

.tech {
  background: var(--ink-navy);
  color: var(--paper);
  padding-top: 84px;
  overflow: hidden;
}
.tech .section-head { margin-bottom: 44px; }

.marquee {
  --marquee-bleed: 84px;
  position: relative;
  padding-bottom: var(--marquee-bleed);
}
/* The edge fade was a mask on .marquee. A mask puts its whole subtree on one render
   surface, so the scrolling strip had to be rasterised as a single oversized texture;
   painting the fade as an overlay instead leaves the tracks on cheap layers. Sits on
   .marquee, not the rail, so the rail's hairline borders fade out with everything else
   (overflow: hidden clips a child at the padding box, short of those borders). */
.marquee::before,
.marquee::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: var(--marquee-bleed);
  width: 9%;
  z-index: 1;
  pointer-events: none;
}
.marquee::before {
  left: 0;
  background: linear-gradient(90deg, var(--ink-navy), transparent);
}
.marquee::after {
  right: 0;
  background: linear-gradient(270deg, var(--ink-navy), transparent);
}
.marquee__rail {
  --marquee-pad: 24px;
  position: relative;
  border-top: 1px solid var(--dark-border-3);
  border-bottom: 1px solid var(--dark-border-3);
  padding: var(--marquee-pad) 0;
  overflow: hidden;
}
/* One set per track, the two half a cycle apart: A slides 0 → -100% while B slides
   100% → 0, so one of them always covers the rail. Holding both sets in a single track
   made it 9670px wide, past the size the compositor rasterises in one piece, which is
   what left blank stretches and stalls until the cycle wrapped; a track is now half that.
   Each translates 100% of itself (one set, 4835px) per cycle, so the duration scales with
   a set's width, not the item count — 86s keeps the original 13-item pace across 29. */
.marquee__track {
  display: flex;
  width: max-content;
  align-items: center;
  animation: marquee-a 86s linear infinite;
}
.marquee__track--b {
  position: absolute;
  top: var(--marquee-pad);
  left: 0;
  animation-name: marquee-b;
}
.marquee__set {
  display: flex;
  align-items: center;
}
.marquee__item {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 30px;
  border-right: 1px solid var(--dark-border-3);
}
/* Logos are single-path SVGs used as masks, so one file serves every colour the
   marquee needs. The mask paints in --dark-text-4, matching the label beside it.
   The default --logo is an empty SVG: until tech-logos.css arrives the box masks
   away to nothing, rather than showing the bare background as a solid rectangle. */
.marquee__logo {
  flex: none;
  --logo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E");
  -webkit-mask: var(--logo) center / contain no-repeat;
  mask: var(--logo) center / contain no-repeat;
}
@supports ((mask-image: url("")) or (-webkit-mask-image: url(""))) {
  .marquee__logo { background: var(--dark-text-4); }
}

/* Each glyph paints into a box cropped to its own aspect ratio at a constant optical
   area (22x22), so the wide wordmarks (Odoo is 3.2:1) match the pictorial marks
   instead of being scaled to a third their height. The boxes are sized here, in the
   render-blocking stylesheet, so the rail reaches its final width on first paint. The
   glyphs themselves are 51kB of data URIs and live in tech-logos.css, which main.js
   fetches once the section nears the viewport. */
.marquee__logo[data-tech="mariadb"] { width: 28px; height: 18px; }
.marquee__logo[data-tech="postgresql"] { width: 21px; height: 22px; }
.marquee__logo[data-tech="redis"] { width: 23px; height: 21px; }
.marquee__logo[data-tech="rabbitmq"] { width: 22px; height: 22px; }
.marquee__logo[data-tech="kafka"] { width: 17px; height: 28px; }
.marquee__logo[data-tech="typescript"] { width: 22px; height: 22px; }
.marquee__logo[data-tech="javascript"] { width: 22px; height: 22px; }
.marquee__logo[data-tech="angular"] { width: 22px; height: 23px; }
.marquee__logo[data-tech="react"] { width: 24px; height: 21px; }
.marquee__logo[data-tech="tailwind"] { width: 28px; height: 17px; }
.marquee__logo[data-tech="flutter"] { width: 19px; height: 24px; }
.marquee__logo[data-tech="ios"] { width: 20px; height: 24px; }
.marquee__logo[data-tech="android"] { width: 29px; height: 17px; }
.marquee__logo[data-tech="claude"] { width: 22px; height: 22px; }
.marquee__logo[data-tech="openrouter"] { width: 24px; height: 20px; }
.marquee__logo[data-tech="odoo"] { width: 38px; height: 12px; }
.marquee__logo[data-tech="shopify"] { width: 20px; height: 23px; }
.marquee__logo[data-tech="wordpress"] { width: 22px; height: 22px; }
.marquee__logo[data-tech="sap"] { width: 30px; height: 15px; }
.marquee__logo[data-tech="sapui5"] { width: 22px; height: 23px; }
.marquee__logo[data-tech="aws"] { width: 28px; height: 17px; }
.marquee__logo[data-tech="azure"] { width: 22px; height: 21px; }
.marquee__logo[data-tech="googlecloud"] { width: 25px; height: 20px; }
.marquee__logo[data-tech="linux"] { width: 20px; height: 24px; }
.marquee__logo[data-tech="windows"] { width: 22px; height: 22px; }
.marquee__logo[data-tech="proxmox"] { width: 24px; height: 21px; }
.marquee__logo[data-tech="docker"] { width: 26px; height: 19px; }
.marquee__logo[data-tech="kubernetes"] { width: 23px; height: 22px; }
.marquee__logo[data-tech="git"] { width: 22px; height: 22px; }

.marquee__label {
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--dark-text-4);
  white-space: nowrap;
}

@keyframes marquee-a {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-100%, 0, 0); }
}
@keyframes marquee-b {
  from { transform: translate3d(100%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* --------------------------------------------------------------------------
   11. About
   -------------------------------------------------------------------------- */

.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
}
.about-card {
  border: 1px solid var(--border);
  background: var(--white);
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.about-card__title {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-navy);
}
.about-card__rule {
  height: 1px;
  background: var(--border-light);
}
.about-card__body {
  font-size: 15px;
  line-height: 1.6;
  color: var(--body-grey);
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   12. Contact
   -------------------------------------------------------------------------- */

.contact {
  background: var(--ink-navy);
  color: var(--paper);
}
.contact__inner {
  padding-block: 104px;
  display: grid;
  /* min() so the 340px track collapses to the container width on small phones
     instead of forcing the section wider than the viewport. */
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 56px 80px;
  align-items: start;
}

.contact__intro {
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.contact__intro .eyebrow { color: var(--sky); }
.contact__title {
  font-size: clamp(34px, 3.9vw, 49px);
  font-weight: 600;
  line-height: 1.03;
  letter-spacing: -0.032em;
  text-wrap: balance;
}
.contact__lede {
  font-size: 17px;
  line-height: 1.72;
  color: var(--dark-text-2);
  max-width: 27rem;
  text-wrap: pretty;
}

.contact__details {
  border-top: 1px solid var(--dark-border-1);
  margin-top: 8px;
}
.contact__row {
  padding: 16px 0;
  border-bottom: 1px solid var(--dark-border-1);
  display: flex;
  justify-content: space-between;
  gap: 20px;
  font-size: 15px;
}
.contact__row dt { color: var(--dark-text-3); }
.contact__row dd { margin: 0; }
.contact__email {
  color: var(--paper);
  overflow-wrap: anywhere;
}
.contact__email:hover { color: var(--sky); }
.contact__mono { font-family: var(--mono); color: var(--paper); }

/* Form panel */
.form {
  min-width: 0;
  background: var(--form-navy);
  border: 1px solid var(--dark-border-1);
  padding: 36px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.form__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.field {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.field__label {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dark-text-3);
}
.field__input {
  width: 100%;
  min-width: 0;
  background: var(--ink-navy);
  border: 1px solid var(--dark-border-2);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 15px;
  padding: 13px 14px;
  transition: border-color var(--hover-ease);
}
.field__input::placeholder { color: var(--dark-text-3); }
.field__input:focus {
  outline: none;
  border-color: var(--sky);
}
/* Keyboard users still get the ring; pointer users get the border change only. */
.field__input:focus-visible {
  outline: 2px solid var(--sky);
  outline-offset: 2px;
}
.field__input--area {
  line-height: 1.6;
  resize: vertical;
}
.field__input[aria-invalid="true"] { border-color: #C46A6A; }

/* Chip group — radios styled as chips, so it stays keyboard operable. */
.chips {
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.chips__group {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.chip { cursor: pointer; }
.chip input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  margin: 0;
}
.chip__box {
  display: block;
  font-size: 13.5px;
  font-weight: 500;
  padding: 10px 16px;
  background: transparent;
  color: var(--dark-text-1);
  border: 1px solid var(--dark-border-2);
  transition: background-color var(--hover-ease), border-color var(--hover-ease), color var(--hover-ease);
}
.chip:hover .chip__box { border-color: var(--sky); }
.chip input:checked + .chip__box {
  background: var(--deep-blue);
  color: var(--white);
  border-color: var(--deep-blue);
}
.chip input:focus-visible + .chip__box {
  outline: 2px solid var(--sky);
  outline-offset: 2px;
}

.form__submit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.btn--submit {
  background: var(--deep-blue);
  color: var(--white);
  border: 0;
  padding: 15px 30px;
  cursor: pointer;
  transition: background-color var(--hover-ease);
}
.btn--submit:hover { background: var(--signal-blue); }
.btn--submit[disabled] { cursor: default; opacity: 0.8; }

.form__status {
  font-size: 13px;
  color: var(--dark-text-3);
}

/* --------------------------------------------------------------------------
   13. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--footer-navy);
  color: var(--dark-text-3);
  border-top: 1px solid var(--dark-border-4);
}
.site-footer__inner {
  padding-block: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  flex-wrap: wrap;
}
.site-footer__brand {
  display: flex;
  align-items: center;
  gap: 14px;
}
.site-footer__name {
  font-size: 15px;
  font-weight: 600;
  color: var(--dark-text-4);
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.site-footer__links {
  display: flex;
  align-items: center;
  gap: 28px;
  font-size: 13.5px;
  flex-wrap: wrap;
}
.site-footer__links a {
  color: var(--dark-text-3);
  white-space: nowrap;
}
.site-footer__links a:hover { color: var(--dark-text-4); }
.site-footer__icon {
  display: flex;
  align-items: center;
  justify-content: center;
}
.site-footer__copy {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dark-text-3);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   14. Responsive
   -------------------------------------------------------------------------- */

/* Card grids: one column on phones, two on medium screens, three on desktop.
   In the two-column range an odd item count leaves the last card alone on its
   row, so it spans the row and is pulled back to one column's width, centred.
   The breakpoints keep the previous auto-fit card widths (340 / 320 / 260px). */
@media (min-width: 800px) and (max-width: 1159.98px) {
  .service-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .service-grid > :last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: calc((100% - 24px) / 2);
    justify-self: center;
  }
}
@media (min-width: 1160px) {
  .service-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 760px) and (max-width: 1099.98px) {
  .work-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .work-grid > :last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: calc((100% - 20px) / 2);
    justify-self: center;
  }
}
@media (min-width: 1100px) {
  .work-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 640px) and (max-width: 919.98px) {
  .about-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .about-grid > :last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: calc((100% - 24px) / 2);
    justify-self: center;
  }
}
@media (min-width: 920px) {
  .about-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Mobile navigation: the nav collapses behind the burger and, when open,
   wraps onto a second row inside the sticky header. */
@media (max-width: 860px) {
  .nav-toggle { display: flex; }

  .site-nav {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-top: 4px;
    padding-bottom: 4px;
  }
  .site-nav.is-open { display: flex; }

  .site-nav__link {
    padding: 15px 0;
    border-top: 1px solid var(--border);
    font-size: 15px;
  }
  .site-nav__cta {
    margin-top: 16px;
    padding: 14px 20px;
    text-align: center;
    font-size: 15px;
  }
}

/* Two-up name/email row is too tight on small phones. */
@media (max-width: 560px) {
  .form__row { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 480px) {
  :root { --gutter: 24px; }

  .section { padding-block: 72px; }
  .contact__inner { padding-block: 72px; }
  .hero__inner { padding-top: 88px; }
  .form { padding: 24px; }
  .service-card { padding: 28px; }
  .about-card { padding: 24px; }
  .work-card__body { padding: 24px; }
  .site-footer__inner { gap: 28px; }
  .site-footer__links { gap: 16px 20px; }
}

/* --------------------------------------------------------------------------
   15. Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .marquee__track { animation: none; }
  /* Unanimated, the trailing track would sit exactly on top of the leading one. */
  .marquee__track--b { display: none; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
