/* Claratech — site styles
   Identity: a building blueprint. Drawing-set blue, white linework,
   one high-vis yellow. Archivo throughout: wide and heavy for
   headlines, condensed for diagram callouts.
   Order: tokens, base, type, buttons, nav, hero, sections, motion. */

:root {
  /* Brand colours: the same in both themes. */
  --blue: #1439f0;
  --blue-hi: #3b5bff;
  --blue-lo: #0c27c4;
  --navy: #0a0f2c;
  --white: #ffffff;
  --yellow: #ffd23f;
  --yellow-hi: #ffe07a;

  /* Theme colours: the light values. The dark ones follow below. */
  --page: #ffffff;
  --ink: #0a0f2c;
  --ink-soft: #4b5273;
  --unlit: #868eae; /* still 3:1 on the page, the minimum for large text */
  --mist: #eef1f9;
  --rule: #d6dbea;
  --accent: var(--blue); /* blue used as text */
  --focus: var(--blue);
  --nav-bg: rgb(10 15 44 / 0.7);
  --nav-bg-stuck: rgb(10 15 44 / 0.88);
  --nav-solid: var(--navy);
  --contact-bg: var(--navy);
  --contact-soft: rgb(255 255 255 / 0.72);
  --contact-hint: rgb(255 255 255 / 0.6);
  /* Form controls: white fields on the contact panel, the same in both
     themes. Only the error text changes, to stay readable on blue. */
  --field-bg: var(--white);
  --field-ink: var(--navy);
  --field-soft: #5b6388; /* placeholder and option hints, 5.9:1 on white */
  --field-halo: rgb(255 255 255 / 0.26); /* hover ring around a field */
  --field-hover: #eef1f9; /* the option under the pointer or the arrow keys */
  --field-error: #d4283a; /* border of a field that needs fixing */
  --field-error-bg: #fff3f2;
  --field-error-ink: #ffb4ab; /* error text on the navy panel */
  color-scheme: light;

  --font: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --measure: 74rem;
  --edge: 0.75rem; /* gap between the viewport and the inset panels */
  --panel-max: 100rem; /* widest a coloured panel gets; on a bigger screen it stays this wide, centred */
  --panel-edge: max(var(--edge), calc((100% - var(--panel-max)) / 2));
  --r-panel: clamp(1.25rem, 2.4vw, 2rem);
  --r-tile: clamp(1rem, 2vw, 1.5rem);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* Dark theme: the drawing set at night. The page goes near-black navy,
   the blue panels and the yellow keep their colour, and the contact
   panel turns blue so it still stands apart from the page.
   assets/js/theme.js sets data-theme before the first paint, from the
   header toggle if it was used, otherwise from the system setting.
   Screen only, so a printed page is always the light one. */
@media screen {
  :root[data-theme="dark"] {
    --page: #070a1d;
    --ink: #f1f3fc;
    --ink-soft: #a7afd0;
    --unlit: #5c648c; /* 3:1 on the page, as in the light theme */
    --mist: #10163a;
    --rule: #262e58;
    --accent: #8094ff;
    --focus: var(--yellow);
    --nav-bg: rgb(24 32 78 / 0.72);
    --nav-bg-stuck: rgb(24 32 78 / 0.92);
    --nav-solid: #171f4c;
    --contact-bg: radial-gradient(90% 80% at 100% 100%, var(--blue-lo) 0%, transparent 60%), var(--blue);
    --contact-soft: rgb(255 255 255 / 0.86);
    --contact-hint: rgb(255 255 255 / 0.82);
    --field-halo: rgb(255 255 255 / 0.34);
    --field-error-ink: #ffd6d0; /* error text on the blue panel */
    color-scheme: dark;
  }
}

/* ---------- Font ----------
   Archivo, self-hosted (SIL Open Font License, see assets/fonts/OFL.txt).
   One variable file covers width 75-125% and weight 400-800. */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 75% 125%;
  font-display: swap;
  src: url("../fonts/archivo-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: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 75% 125%;
  font-display: swap;
  src: url("../fonts/archivo-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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Base ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
p,
ul,
ol,
dl,
dd,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

svg {
  display: block;
}

[hidden] {
  display: none !important;
}

/* The skip link lands here; no ring for a programmatic focus. */
main:focus {
  outline: none;
}

a {
  color: inherit;
}

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

:focus-visible {
  outline: 2.5px solid var(--focus);
  outline-offset: 3px;
}

.nav :focus-visible,
.hero :focus-visible,
.contact :focus-visible {
  outline-color: var(--yellow);
}

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

.skip-link {
  position: fixed;
  left: 1rem;
  top: -5rem;
  z-index: 30;
  padding: 0.7rem 1.1rem;
  border-radius: 999px;
  background: var(--yellow);
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
}

.skip-link:focus {
  top: 1rem;
}

.container {
  width: 100%;
  max-width: calc(var(--measure) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- Type ---------- */

h1,
h2,
h3 {
  font-stretch: 120%;
  font-weight: 720;
  line-height: 1;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

h2 {
  font-size: clamp(2rem, 4.8vw, 3.75rem);
}

.lead {
  max-width: 36rem;
  margin-top: 1.1rem;
  color: var(--ink-soft);
  font-size: clamp(1.125rem, 1.5vw, 1.25rem);
  line-height: 1.5;
}

/* Condensed annotation type, as on a drawing. */
.callout {
  font-size: 0.875rem;
  font-stretch: 78%;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.015em;
}

/* Archivo's ampersand reads as a 3 at small sizes; use the system one. */
.amp {
  font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
}

/* ---------- Buttons ---------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3.25rem;
  padding: 0 1.6rem;
  border: 1.5px solid transparent;
  border-radius: 999px;
  background: var(--blue);
  color: var(--white);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s, transform 0.25s var(--ease);
}

.button:hover {
  background: var(--blue-lo);
  transform: translateY(-1px);
}

.button:active {
  transform: scale(0.98);
}

.button--yellow {
  background: var(--yellow);
  color: var(--navy);
}

.button--yellow:hover {
  background: var(--yellow-hi);
}

.button--ghost {
  border-color: rgb(255 255 255 / 0.5);
  background: transparent;
}

.button--ghost:hover {
  border-color: var(--white);
  background: rgb(255 255 255 / 0.12);
}

.button--small {
  min-height: 2.625rem;
  padding-inline: 1.15rem;
  font-size: 0.9375rem;
}

.button[disabled] {
  opacity: 0.6;
  cursor: progress;
}

/* ---------- Floating nav ---------- */

.nav {
  position: fixed;
  top: calc(var(--edge) + 0.75rem);
  left: 50%;
  z-index: 20;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: min(100% - 2 * (var(--edge) + 0.75rem), 58rem);
  min-height: 3.75rem;
  padding: 0.5rem 0.55rem 0.5rem 1rem;
  border: 1px solid rgb(255 255 255 / 0.14);
  border-radius: 999px;
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  box-shadow: 0 12px 32px -14px rgb(10 15 44 / 0.5);
  color: var(--white);
  transition: top 0.4s var(--ease), background-color 0.3s;
}

.nav.is-stuck {
  top: var(--edge);
  background: var(--nav-bg-stuck);
}

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  text-decoration: none;
}

/* The butterfly stands on the same line as the name, like a tall first
   letter, and its round lower wings dip a little below that line the
   way round letters do. The negative margin stops its height from
   pushing the name off the middle of the header. */
.brand__mark {
  flex: none;
  margin-top: -0.5rem;
  transform: translateY(2px);
}

.brand__name {
  font-size: 1.1875rem;
  font-stretch: 120%;
  font-weight: 720;
  letter-spacing: -0.025em;
}

/* The links and the theme toggle. On phones this is the drop-down menu. */
.nav__menu {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 0.5rem;
}

.nav__links {
  margin-inline: auto;
}

.nav__links ul {
  display: flex;
  gap: 0.15rem;
}

.nav__links a {
  display: block;
  padding: 0.5rem 0.9rem;
  border-radius: 999px;
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.2s;
}

.nav__links a:hover {
  background: rgb(255 255 255 / 0.13);
}

.nav__links a[aria-current] {
  background: rgb(255 255 255 / 0.18);
}

/* Light / dark switch: a circle. It shows the theme it switches to. Only displayed once theme.js has run. */
.nav__theme {
  display: none;
  flex: none;
  place-items: center;
  width: 2.625rem;
  height: 2.625rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.13);
  color: var(--white);
  font: inherit;
  cursor: pointer;
  transition: background-color 0.2s;
}

[data-theme] .nav__theme {
  display: grid;
}

.nav__theme:hover {
  background: rgb(255 255 255 / 0.22);
}

.nav__theme svg {
  width: 1.125rem;
  height: 1.125rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav__theme .icon-sun,
[data-theme="dark"] .nav__theme .icon-moon {
  display: none;
}

[data-theme="dark"] .nav__theme .icon-sun {
  display: block;
}

/* Read out by screen readers here; shown as text in the phone menu. */
.nav__theme-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.nav__toggle {
  display: none;
}

.nav__end {
  margin-left: auto;
}

/* Phones: the links and the theme switch fold into a menu that drops
   below the pill. */
@media (max-width: 46rem) {
  .nav .button {
    margin-left: auto;
  }

  .js .nav__toggle {
    order: 3;
    display: grid;
    place-items: center;
    width: 2.625rem;
    height: 2.625rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgb(255 255 255 / 0.13);
    color: var(--white);
    cursor: pointer;
  }

  .nav__toggle-bars,
  .nav__toggle-bars::before {
    display: block;
    width: 1.05rem;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.3s var(--ease);
  }

  .nav__toggle-bars {
    transform: translateY(-3.5px);
  }

  .nav__toggle-bars::before {
    content: "";
    transform: translateY(7px);
  }

  .nav.is-open .nav__toggle-bars {
    transform: rotate(45deg);
  }

  .nav.is-open .nav__toggle-bars::before {
    transform: rotate(-90deg);
  }

  .nav__menu {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    left: 0;
    display: block;
    visibility: hidden;
    padding: 0.5rem;
    border: 1px solid rgb(255 255 255 / 0.14);
    border-radius: 1.5rem;
    background: var(--nav-solid);
    box-shadow: 0 18px 40px -16px rgb(10 15 44 / 0.6);
    opacity: 0;
    translate: 0 -8px;
    transition: opacity 0.2s, translate 0.3s var(--ease), visibility 0s 0.3s;
  }

  .nav.is-open .nav__menu {
    visibility: visible;
    opacity: 1;
    translate: 0;
    transition-delay: 0s;
  }

  .nav__links {
    margin: 0;
  }

  .nav__links ul {
    flex-direction: column;
    gap: 0;
  }

  .nav__links a {
    padding: 0.9rem 1rem;
    border-radius: 1rem;
    font-size: 1.0625rem;
  }

  /* The theme switch becomes the last row of the menu, with its label. */
  [data-theme] .nav__theme {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.75rem;
    width: 100%;
    height: auto;
    margin-top: 0.35rem;
    padding: 0.9rem 1rem;
    border-radius: 1rem;
    background: rgb(255 255 255 / 0.08);
    font-size: 1.0625rem;
    font-weight: 500;
  }

  .nav__theme-label {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
  }
}

/* Narrow phones: give the pill more room, then drop the name and keep the mark. */
@media (max-width: 26rem) {
  .nav {
    width: calc(100% - 2 * (var(--edge) + 0.35rem));
    gap: 0.35rem;
    padding-left: 0.8rem;
  }

  .brand {
    gap: 0.45rem;
  }

  .brand__name {
    font-size: 1.0625rem;
  }

  .nav .button {
    padding-inline: 0.95rem;
  }
}

@media (max-width: 21.5rem) {
  .brand__name {
    display: none;
  }

  /* On its own, the butterfly sits in the middle of the header. */
  .brand {
    align-items: center;
  }

  .brand__mark {
    margin-top: 0;
    transform: none;
  }
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: min(100svh - 2 * var(--edge), 58rem);
  margin: var(--edge) var(--panel-edge);
  overflow: hidden;
  border-radius: var(--r-panel);
  background:
    radial-gradient(110% 90% at 0% 0%, var(--blue-hi) 0%, transparent 55%),
    radial-gradient(90% 80% at 100% 100%, var(--blue-lo) 0%, transparent 60%),
    var(--blue);
  color: var(--white);
}

/* Drawing grid, strongest behind the trace. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(rgb(255 255 255 / 0.09) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / 0.09) 1px, transparent 1px);
  background-position: center bottom;
  background-size: 3rem 3rem;
  -webkit-mask-image: linear-gradient(to bottom, transparent 15%, #000 80%);
  mask-image: linear-gradient(to bottom, transparent 15%, #000 80%);
}

.hero--full {
  min-height: calc(100svh - 2 * var(--edge));
}

.hero__content {
  padding-top: clamp(7.5rem, 15vh, 10.5rem);
}

.hero__title {
  font-size: clamp(2.5rem, 6.7vw, 5.875rem);
  font-weight: 740;
  line-height: 0.98;
  letter-spacing: -0.035em;
  text-wrap: wrap;
}

/* Each line is a mask the text rises out of. */
.hero__title .line {
  display: block;
  margin-bottom: -0.1em;
  padding-bottom: 0.1em;
  overflow: hidden;
}

.hero__title .line > span {
  display: block;
}

.hero__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.75rem 3rem;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}

.hero__lede {
  max-width: 34rem;
  color: rgb(255 255 255 / 0.86);
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.5;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* The trace: power and water go in rough and come out clean. */

.trace {
  margin-top: auto;
  padding-block: clamp(2.5rem, 6vw, 4rem) clamp(1.25rem, 3vw, 2rem);
}

.trace__stage {
  --inset: max(var(--gutter), calc((100% - var(--measure)) / 2));
  position: relative;
  height: clamp(240px, 34vh, 320px);
}

.trace__svg {
  width: 100%;
  height: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.trace__svg path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.trace__power {
  stroke: var(--yellow);
  stroke-width: 2.5;
}

.trace__glow {
  stroke: var(--yellow);
  stroke-width: 11;
  opacity: 0.16;
}

/* Each streamline gets its own dash rhythm so the four never line up. */
.trace__water path {
  --dash: 62;
  --gap: 10;
  stroke: var(--white);
  stroke-width: 1.75;
  stroke-dasharray: var(--dash) var(--gap);
}

.trace__water path:nth-child(2) {
  --dash: 38;
  --gap: 12;
  opacity: 0.7;
}

.trace__water path:nth-child(3) {
  --dash: 84;
  --gap: 9;
  opacity: 0.85;
}

.trace__water path:nth-child(4) {
  --dash: 50;
  --gap: 14;
  opacity: 0.6;
}

.trace__label {
  position: absolute;
  color: rgb(255 255 255 / 0.8);
}

.trace__label--power-in {
  top: 0;
  left: var(--inset);
}

.trace__label--power-out {
  top: 0;
  right: var(--inset);
}

.trace__label--water-in {
  bottom: 0;
  left: var(--inset);
}

.trace__label--water-out {
  right: var(--inset);
  bottom: 0;
}

/* The two products, drawn as components on their lines. */
.node {
  position: absolute;
  left: 50%;
  translate: -50% -50%;
  display: grid;
  justify-items: center;
  gap: 0.1rem;
  padding: 0.55rem 1.1rem 0.6rem;
  border: 1.5px solid var(--white);
  border-radius: 0.8rem;
  background: var(--blue);
  color: var(--white);
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.node strong {
  font-size: 1.125rem;
  font-stretch: 116%;
  font-weight: 720;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.node .callout {
  font-size: 0.8125rem;
  opacity: 0.85;
}

.node:hover {
  border-color: var(--yellow);
  background: var(--yellow);
  color: var(--navy);
}

.node--power {
  top: 27%;
}

.node--water {
  top: 70%;
}

@media (max-width: 34rem) {
  .node {
    padding: 0.4rem 0.8rem 0.45rem;
    border-radius: 0.7rem;
  }

  .node strong {
    font-size: 1rem;
  }

  .node .callout {
    font-size: 0.75rem;
  }
}

/* ---------- Sections ---------- */

.section {
  padding-block: clamp(4.5rem, 10vw, 8.5rem);
}

.panel {
  margin-inline: var(--panel-edge);
  border-radius: var(--r-panel);
}

.panel--mist {
  background: var(--mist);
}

.section__head {
  margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
}

/* About */

.statement {
  max-width: 23em;
  font-size: clamp(1.625rem, 3.5vw, 3rem);
  font-stretch: 112%;
  font-weight: 620;
  line-height: 1.12;
  letter-spacing: -0.028em;
  text-wrap: pretty;
}

.statement .w {
  color: var(--unlit);
  transition: color 0.35s ease;
}

.statement .w.is-lit {
  color: var(--ink);
}

.points {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2rem clamp(1.5rem, 4vw, 3.5rem);
  margin-top: clamp(3rem, 7vw, 5.5rem);
}

.points li {
  padding-top: 1.25rem;
  border-top: 2px solid var(--ink);
}

.points h3 {
  font-size: 1.25rem;
  font-stretch: 114%;
  font-weight: 680;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.points p {
  margin-top: 0.55rem;
  color: var(--ink-soft);
}

@media (max-width: 50rem) {
  .points {
    grid-template-columns: 1fr;
  }
}

/* Services */

.service {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2.25rem, 5vw, 5rem);
  align-items: center;
}

.service + .service {
  margin-top: clamp(4rem, 9vw, 7rem);
  padding-top: clamp(4rem, 9vw, 7rem);
  border-top: 1px solid var(--rule);
}

.service__name {
  font-size: clamp(2.5rem, 5.8vw, 4.75rem);
  font-weight: 740;
  letter-spacing: -0.04em;
}

.service__lede {
  margin-top: 1.25rem;
  font-size: clamp(1.1875rem, 1.7vw, 1.375rem);
  font-weight: 500;
  line-height: 1.4;
}

.service__copy p + p {
  margin-top: 1rem;
}

.service__copy p:not([class]) {
  color: var(--ink-soft);
}

.service__copy strong {
  color: var(--ink);
  font-weight: 600;
}

.service__copy .service__action {
  margin-top: 1.9rem;
}

.service__figure figcaption {
  margin-top: 0.85rem;
  color: var(--ink-soft);
}

/* The diagram tiles: where each product sits in a building. */

.tile {
  position: relative;
  isolation: isolate;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--r-tile);
}

.tile::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(var(--tile-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--tile-grid) 1px, transparent 1px);
  background-position: center;
  background-size: 2rem 2rem;
}

.tile--blue {
  --tile-bg: var(--blue);
  --tile-grid: rgb(255 255 255 / 0.09);
  --tile-accent: var(--yellow);
  --tile-accent-ink: var(--navy);
  background: var(--blue);
  color: var(--white);
}

.tile--yellow {
  --tile-bg: var(--yellow);
  --tile-grid: rgb(10 15 44 / 0.09);
  --tile-accent: var(--blue);
  --tile-accent-ink: var(--white);
  background: var(--yellow);
  color: var(--navy);
}

.diagram {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.dia-thin {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  opacity: 0.6;
}

.dia-dash {
  stroke-dasharray: 4 5;
}

.dia-run {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 10 7;
}

.dia-bus {
  fill: none;
  stroke: currentColor;
  stroke-width: 5;
  stroke-linecap: round;
}

.dia-lead {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
}

.dia-sym {
  fill: var(--tile-bg);
  stroke: currentColor;
  stroke-width: 2;
}

.dia-sym--open {
  fill: none;
}

.dia-device {
  fill: var(--tile-accent);
}

.dia-device-text {
  fill: var(--tile-accent-ink);
  font-size: 15px;
  font-stretch: 114%;
  font-weight: 720;
  letter-spacing: -0.02em;
  text-anchor: middle;
}

.dia-text {
  fill: currentColor;
  font-size: 13px;
  font-stretch: 78%;
  font-weight: 500;
  letter-spacing: 0.015em;
}

.dia-text--mid {
  text-anchor: middle;
}

.dia-text--end {
  text-anchor: end;
}

.dia-text--bold {
  font-stretch: 100%;
  font-weight: 700;
}

/* Facts under each service */

.facts {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.facts > div {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  gap: 0.6rem;
  padding-inline: clamp(1rem, 2vw, 1.75rem);
  border-left: 1px solid var(--rule);
}

.facts > div:first-child {
  padding-left: 0;
  border-left: 0;
}

.facts dd {
  font-size: clamp(1.625rem, 2.9vw, 2.375rem);
  font-stretch: 120%;
  font-weight: 720;
  line-height: 1;
  letter-spacing: -0.035em;
  white-space: nowrap;
}

.facts dt {
  color: var(--ink-soft);
  font-size: 0.9375rem;
  line-height: 1.4;
}

.service__note {
  grid-column: 1 / -1;
  margin-top: calc(clamp(2.25rem, 5vw, 5rem) * -0.55);
  color: var(--ink-soft);
  font-size: 0.8125rem;
}

@media (max-width: 56rem) {
  .service {
    grid-template-columns: 1fr;
    gap: 2.25rem;
  }

  .facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 1.75rem;
  }

  .facts > div:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }

  .service__note {
    margin-top: -0.75rem;
  }
}

/* On phones the facts become rows: value on the left, what it means on the right. */
@media (max-width: 34rem) {
  .facts {
    grid-template-columns: 1fr;
    row-gap: 0;
    border-bottom: 1px solid var(--rule);
  }

  .facts > div {
    flex-direction: row-reverse;
    align-items: baseline;
    gap: 1rem;
    padding: 0.9rem 0;
    border-top: 1px solid var(--rule);
    border-left: 0;
  }

  .facts dd {
    flex: 0 0 9.5rem;
    font-size: 1.5rem;
  }

  .facts dt {
    flex: 1;
  }

  .service__note {
    margin-top: -1.25rem;
  }
}

@media (min-width: 56.01rem) {
  .service--flip .service__figure {
    order: -1;
  }
}

/* Process */

.steps {
  border-bottom: 1px solid var(--rule);
  counter-reset: step;
}

.steps li {
  display: grid;
  grid-template-columns: clamp(3.5rem, 8vw, 7rem) minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 0.5rem clamp(1.25rem, 3vw, 2.5rem);
  align-items: baseline;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--rule);
  counter-increment: step;
}

.steps li::before {
  content: counter(step);
  color: var(--accent);
  font-size: clamp(2rem, 3.6vw, 3.25rem);
  font-stretch: 120%;
  font-weight: 740;
  line-height: 1;
  letter-spacing: -0.03em;
}

.steps h3 {
  font-size: clamp(1.25rem, 2.1vw, 1.75rem);
  font-stretch: 114%;
  font-weight: 680;
  line-height: 1.1;
  letter-spacing: -0.025em;
}

.steps p {
  color: var(--ink-soft);
}

@media (max-width: 50rem) {
  .steps li {
    grid-template-columns: 3rem minmax(0, 1fr);
  }

  .steps p {
    grid-column: 2;
  }
}

/* Contact */

.contact {
  margin-bottom: var(--edge);
  background: var(--contact-bg);
  color: var(--white);
  color-scheme: dark;
}

.contact .lead {
  color: var(--contact-soft);
}

.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(2.5rem, 7vw, 6rem);
  align-items: start;
}

.contact__direct {
  margin-top: 1.75rem;
  color: var(--contact-soft);
}

.contact__direct a {
  color: var(--yellow);
  font-weight: 600;
  text-underline-offset: 0.3em;
}

/* Form controls.
   The anatomy is shadcn/ui's, written for a page with no framework: a label
   above each control, one control height, a ring on focus, aria-invalid for
   a field that needs fixing with its message underneath, and a select whose
   menu is a listbox the page draws itself. The look is this site's: solid
   white fields with the same round ends as the buttons. */

.form {
  display: grid;
  gap: 1.25rem;
}

.form__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem 1rem;
}

.field {
  display: grid;
  align-content: start;
  gap: 0.5rem;
  min-width: 0;
}

.field label {
  justify-self: start;
  font-size: 0.9375rem;
  font-weight: 600;
}

.field__hint {
  color: var(--contact-hint);
  font-weight: 400;
}

.field input,
.field select,
.field textarea,
.select__trigger {
  display: block;
  width: 100%;
  min-height: 3rem;
  padding: 0.65rem 1.25rem;
  border: 2px solid transparent;
  border-radius: 1.5rem; /* half the height, so one-line fields are pills */
  background-color: var(--field-bg);
  color: var(--field-ink);
  font: inherit;
  line-height: 1.4;
  color-scheme: light;
  transition: box-shadow 0.15s, border-color 0.15s, background-color 0.15s, transform 0.15s var(--ease);
}

.field ::placeholder {
  color: var(--field-soft);
  opacity: 1;
}

.field textarea {
  min-height: 8.5rem;
  padding-block: 0.85rem;
  resize: vertical;
}

/* The plain select, as shown before main.js runs or without scripts. */
.field select {
  padding-right: 3rem;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 6l4.5 4.5L12.5 6' fill='none' stroke='%230a0f2c' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.15rem center;
  background-size: 1rem;
}

.field input:hover,
.field select:hover,
.field textarea:hover,
.select__trigger:hover {
  box-shadow: 0 0 0 4px var(--field-halo);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible,
.select__trigger:focus-visible,
.select__trigger[aria-expanded="true"] {
  outline: 3px solid var(--yellow);
  outline-offset: 2px;
  box-shadow: none;
}

.field [aria-invalid="true"] {
  border-color: var(--field-error);
  background-color: var(--field-error-bg);
}

.field__error {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  color: var(--field-error-ink);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.35;
}

.field__error[hidden] {
  display: none;
}

.field__error::before {
  content: "!";
  flex: none;
  width: 1.15em;
  height: 1.15em;
  border-radius: 50%;
  background: var(--field-error-ink);
  color: var(--navy);
  font-size: 0.8125rem;
  font-weight: 800;
  line-height: 1.15em;
  text-align: center;
}

/* Select: a button that shows the choice, and the list it opens. */

.select {
  position: relative;
}

.select select[hidden] {
  display: none;
}

.select__trigger {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
  text-align: left;
}

.select__value,
.select__option {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
}

.select__value {
  flex: 1;
}

.select__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select__hint {
  color: var(--field-soft);
  font-weight: 400;
  white-space: nowrap;
}

/* Water is blue and power is yellow everywhere on the site, here too. */
.select__dot {
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px rgb(10 15 44 / 0.3);
}

.select__dot[data-tone="water"] {
  background: var(--blue);
  box-shadow: none;
}

.select__dot[data-tone="power"] {
  background: var(--yellow);
}

.select__dot[data-tone="both"] {
  background: linear-gradient(90deg, var(--blue) 50%, var(--yellow) 50%);
}

.select__chevron,
.select__check {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.select__chevron {
  transition: transform 0.2s var(--ease);
}

.select__trigger[aria-expanded="true"] .select__chevron {
  transform: rotate(180deg);
}

.select__list {
  position: absolute;
  z-index: 5;
  top: calc(100% + 0.6rem);
  right: 0;
  left: 0;
  max-height: 18rem;
  margin: 0;
  padding: 0.375rem;
  overflow-y: auto;
  border-radius: 1.5rem;
  background: var(--field-bg);
  color: var(--field-ink);
  box-shadow: 0 1.5rem 3rem rgb(3 6 24 / 0.45), 0 0 0 1px rgb(10 15 44 / 0.1);
  list-style: none;
}

.select__list[hidden] {
  display: none;
}

.select__list[data-side="top"] {
  top: auto;
  bottom: calc(100% + 0.6rem);
}

.select__option {
  min-height: 2.75rem;
  padding: 0.5rem 0.9rem;
  border-radius: 1.125rem;
  cursor: pointer;
}

.select__option.is-active {
  background: var(--field-hover);
}

.select__option[aria-selected="true"] {
  font-weight: 600;
}

.select__check {
  margin-left: auto;
  color: var(--blue);
  visibility: hidden;
}

.select__option[aria-selected="true"] .select__check {
  visibility: visible;
}

.field--trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.25rem;
  margin-top: 0.4rem;
}

.form__note,
.form__status {
  flex: 1 1 14rem;
  color: var(--contact-soft);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.form__note[hidden],
.form__status:empty {
  display: none;
}

/* Form motion. Short and mechanical, like the rest of the page: the focus
   ring snaps out from the edge of the field, the list unrolls from its
   button with the choices arriving in order, and the tick draws itself.
   All of it is off under prefers-reduced-motion, and none of it is needed
   to use the form. */
@media (prefers-reduced-motion: no-preference) {
  .field input:focus-visible,
  .field select:focus-visible,
  .field textarea:focus-visible,
  .select__trigger:focus-visible,
  .select__trigger[aria-expanded="true"] {
    animation: field-ring 0.42s var(--ease);
  }

  @keyframes field-ring {
    from {
      outline-color: transparent;
      outline-offset: -3px;
    }

    55% {
      outline-color: var(--yellow);
      outline-offset: 6px;
    }
  }

  .select__trigger:active {
    transform: scale(0.985);
  }

  /* The value in the button slides in when the choice changes. */
  .select__value > * {
    animation: select-value 0.28s var(--ease);
  }

  @keyframes select-value {
    from {
      opacity: 0;
      transform: translateY(0.35rem);
    }
  }

  /* Opening and closing. "display" waits for the fade when closing; a
     browser that cannot do that drops the whole line and just shows and
     hides the list. */
  .select__list {
    transform-origin: top center;
    transition:
      opacity 0.18s var(--ease),
      transform 0.24s var(--ease),
      display 0.24s allow-discrete;
  }

  .select__list[data-side="top"] {
    transform-origin: bottom center;
  }

  .select__list[hidden] {
    opacity: 0;
    transform: translateY(-0.5rem) scale(0.96);
  }

  .select__list[hidden][data-side="top"] {
    transform: translateY(0.5rem) scale(0.96);
  }

  @starting-style {
    .select__list:not([hidden]) {
      opacity: 0;
      transform: translateY(-0.5rem) scale(0.96);
    }
  }

  .select__option {
    transition: background-color 0.12s;
  }

  .select__list:not([hidden]) .select__option {
    animation: select-option 0.32s var(--ease) backwards;
  }

  .select__option:nth-child(2) { animation-delay: 0.035s; }
  .select__option:nth-child(3) { animation-delay: 0.07s; }
  .select__option:nth-child(4) { animation-delay: 0.105s; }
  .select__option:nth-child(5) { animation-delay: 0.14s; }
  .select__option:nth-child(6) { animation-delay: 0.175s; }
  .select__option:nth-child(n + 7) { animation-delay: 0.21s; }

  @keyframes select-option {
    from {
      opacity: 0;
      transform: translateY(-0.4rem);
    }
  }

  /* The tick on the current choice is drawn along its length. */
  .select__list:not([hidden]) .select__option[aria-selected="true"] .select__check path {
    stroke-dasharray: 15;
    animation: select-tick 0.4s var(--ease) 0.14s backwards;
  }

  @keyframes select-tick {
    from {
      stroke-dashoffset: 15;
    }
  }

  .field__error:not([hidden]) {
    animation: field-error 0.28s var(--ease);
  }

  @keyframes field-error {
    from {
      opacity: 0;
      transform: translateY(-0.35rem);
    }
  }
}

@media (max-width: 56rem) {
  .contact__grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 34rem) {
  .form__row {
    grid-template-columns: 1fr;
  }
}

/* Footer */

.site-footer {
  padding-block: clamp(1.5rem, 3vw, 2.5rem) clamp(1rem, 2.5vw, 2rem);
}

.site-footer__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
}

.site-footer ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
}

.site-footer a {
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
}

.site-footer a:hover {
  text-decoration: underline;
  text-underline-offset: 0.35em;
}

/* The wordmark, stretched to the exact width of the content column. */
.site-footer__mark {
  width: 100%;
  height: auto;
  margin-top: clamp(1.5rem, 4vw, 3.5rem);
  overflow: visible;
  fill: var(--blue);
  font-stretch: 125%;
  font-weight: 800;
}

/* ---------- Motion ----------
   One orchestrated moment on load (the hero), lines that keep
   flowing, a statement that fills in as it is read, and a quiet
   reveal for the larger blocks. All of it is off for visitors whose
   system asks for reduced motion, and nothing is hidden unless the
   script has confirmed it can show it. */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  .hero__title .line > span {
    animation: line-up 0.95s var(--ease) both;
  }

  .hero__title .line:nth-child(2) > span {
    animation-delay: 0.09s;
  }

  .hero__lede,
  .hero__actions {
    animation: rise 0.8s var(--ease) 0.3s both;
  }

  .hero__actions {
    animation-delay: 0.4s;
  }

  .trace__svg {
    animation: sweep 1.8s cubic-bezier(0.6, 0, 0.2, 1) 0.45s both;
  }

  .node {
    animation: pop 0.5s var(--ease) 1.35s both;
  }

  .node--water {
    animation-delay: 1.5s;
  }

  .trace__label {
    animation: fade 0.6s ease 1.8s both;
  }

  .js .trace__water path {
    animation: flow 1.5s linear infinite;
  }

  .trace__water path:nth-child(2) {
    animation-delay: -0.4s;
  }

  .trace__water path:nth-child(3) {
    animation-delay: -0.9s;
  }

  .trace__water path:nth-child(4) {
    animation-delay: -1.2s;
  }

  .js .dia-run {
    animation: march 1.1s linear infinite;
  }

  .tile.is-offscreen .dia-run {
    animation-play-state: paused;
  }

  .nav {
    animation: nav-in 0.8s var(--ease) 0.05s both;
  }

  /* Each diagram assembles in drawing order: context, runs, fittings,
     then the product itself. */
  .js .service__figure .dia-step {
    opacity: 0;
    transition: opacity 0.5s ease 0.3s;
  }

  .js .service__figure .dia-step--2 {
    transition-delay: 0.55s;
  }

  .js .service__figure .dia-step--3 {
    transition-delay: 0.8s;
  }

  .js .service__figure .dia-step--device {
    transform: scale(0.8);
    transform-box: fill-box;
    transform-origin: center;
    transition: opacity 0.35s ease 1.1s, transform 0.55s var(--ease) 1.1s;
  }

  .js .service__figure.is-visible .dia-step {
    opacity: 1;
    transform: none;
  }

  .js .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
  }

  .js .reveal.is-visible {
    opacity: 1;
    transform: none;
  }

  .js .steps li {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
    transition-delay: calc(var(--i, 0) * 0.1s);
  }

  .js .steps.is-visible li {
    opacity: 1;
    transform: none;
  }

  .steps li:nth-child(2) {
    --i: 1;
  }

  .steps li:nth-child(3) {
    --i: 2;
  }

  .steps li:nth-child(4) {
    --i: 3;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dia-run {
    stroke-dasharray: none;
  }
}

@keyframes nav-in {
  from {
    opacity: 0;
    translate: -50% -14px;
  }
}

@keyframes line-up {
  from {
    transform: translateY(108%);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}

@keyframes sweep {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes pop {
  from {
    opacity: 0;
    scale: 0.88;
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
}

@keyframes flow {
  to {
    stroke-dashoffset: calc((var(--dash) + var(--gap)) * -1px);
  }
}

@keyframes march {
  to {
    stroke-dashoffset: -17;
  }
}

/* ---------- Forced colours (Windows high contrast) ----------
   Backgrounds are dropped there, so anything drawn in a brand colour
   switches to the system text colour to stay visible. */

@media (forced-colors: active) {
  .hero::before,
  .tile::before {
    display: none;
  }

  .trace__power,
  .trace__water path {
    stroke: CanvasText;
  }

  .trace__glow {
    display: none;
  }

  .dia-device {
    fill: Highlight;
  }

  .dia-device-text {
    fill: HighlightText;
  }

  .site-footer__mark {
    fill: CanvasText;
  }

  .button,
  .tile,
  .hero,
  .contact {
    border: 1px solid CanvasText;
  }
}

/* ---------- Print ---------- */

@media print {
  .nav,
  .skip-link,
  .trace,
  .hero__actions,
  .form,
  .site-footer__mark {
    display: none;
  }

  .hero,
  .contact {
    min-height: 0;
    background: none;
    color: var(--ink);
  }

  .hero__content {
    padding-top: 0;
  }

  .hero__lede,
  .contact .lead,
  .contact__direct,
  .contact__direct a {
    color: var(--ink);
  }

  .section {
    padding-block: 2rem;
  }

  .service,
  .steps li {
    break-inside: avoid;
  }
}
