/* ==========================================================================
   Auxiluna Inc. — corporate site stylesheet
   Plain modern CSS: no build step and no script. The accent is the product
   site's teal (seed #006A6A); the body face is the product site's Inter,
   self-hosted.

   The look — editorial and painted. Headlines are set in a serif, labels in
   small letter-spaced mono, text in Inter, on warm paper with a fine grain.
   Each page opens on a painted panel: a quiet field with three soft blooms
   of colour drifting across it, nothing depicted. The brand mark is the
   favicon itself, a round badge holding a calligraphic A on a crescent, set
   before both wordmarks.

   Underneath, Material 3 Expressive's corner scale, one library shape
   (Cookie-12) that morphs into a circle when a contact link is reached for,
   and its spring motion tokens sampled into CSS linear() easings. Liquid
   Glass, after Apple's rule, appears in one place only: the floating
   navigation capsule.

   Motion rules. Nothing loops; motion that starts on its own is over within
   2 seconds (WCAG 2.2.2). Colour, shadow and opacity changes run for
   everyone; anything that moves, scales, rotates or changes shape runs only
   under prefers-reduced-motion: no-preference, and the end state of every
   interaction applies either way. Scroll-driven motion is progressive
   enhancement behind @supports: without it the page is static and complete.

   Order: fonts → registered properties → tokens → base → utilities →
   components in page order (each with its motion beside it) → view
   transitions → user preferences.
   ========================================================================== */

/* ---- Fonts (self-hosted, Latin subset, variable) -------------------------- */
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  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;
}

/* Metric-matched local fallback, so the swap to Inter does not reflow. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  ascent-override: 90.44%;
  descent-override: 22.52%;
  line-gap-override: 0%;
  size-adjust: 107.12%;
}

/* ---- Registered properties (animatable custom properties) ----------------- */
/* How materialized the glass is: 0 at the top of the page, 1 once content
   scrolls under it. 1 is also the static fallback. */
@property --glass-k {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

/* ---- Design tokens ------------------------------------------------------ */
:root {
  color-scheme: light dark;

  /* Ink and paper: warm neutrals, light | dark. */
  --surface: light-dark(#f6f4ee, #0c1113);
  /* Neither the footer sheet nor the cards carry an outline, so on dark the
     fill alone has to lift them off their ground — tonal elevation rather
     than a hairline. The sheet needs the larger step of the two: it has no
     shadow under it, and an equal numeric delta reads as far less separation
     on a dark ground than on a light one. Its lift leans teal, as the light
     sheet's leans warm. */
  --surface-container: light-dark(#eeeae1, #1b2d2e);
  --card: light-dark(#fffdf9, #1b2427);
  --card-hover: light-dark(#f3f0e8, #232d30);
  --on-surface: light-dark(#1a1f1f, #e7e5de);
  --on-surface-variant: light-dark(#4b504e, #b8bcb7);
  --outline: light-dark(#7a7e7a, #8a908c);
  --hairline: color-mix(in srgb, var(--on-surface) 14%, transparent);

  /* The accent — the product site's teal. */
  --primary: light-dark(#006a6a, #80d5d4);
  --on-primary: light-dark(#ffffff, #003737);

  /* Quiet tonal fills, each with its own ink: sage, sky and sand. */
  --sage: light-dark(#dbe9e3, #1d3431);
  --on-sage: light-dark(#1f4540, #cfe9e2);
  --sky: light-dark(#e1e9f2, #1d2a3d);
  --on-sky: light-dark(#263d5c, #d6e2f5);
  --sand: light-dark(#efe5d4, #372f24);
  --on-sand: light-dark(#5a4526, #efe0c4);

  /* The hero panel: a quiet field with three soft blooms drifting across it
     — the accent teal, a cool blue and a warm one. Nothing is depicted. */
  --panel-base: light-dark(#efece3, #101718);
  --bloom-1: light-dark(rgb(0 106 106 / 0.17), rgb(0 154 151 / 0.22));
  --bloom-2: light-dark(rgb(122 156 196 / 0.15), rgb(84 116 186 / 0.15));
  --bloom-3: light-dark(rgb(226 176 112 / 0.2), rgb(176 118 58 / 0.11));
  /* One cool tint, for the far corner of the product card. On dark it stays
     above the page tone: with no outline, a corner darker than its ground
     would read as a hole rather than a card. */
  --card-tint: light-dark(#d5e1e9, #16323a);
  --grain: url("/assets/grain.svg");

  /* Glass — the navigation layer only. */
  --glass-fill: light-dark(rgb(255 253 249 / 0.74), rgb(19 26 27 / 0.8));
  --glass-solid: light-dark(#fffdf9, #1a2223);
  --glass-rim-hi: light-dark(rgb(255 255 255 / 0.9), rgb(255 255 255 / 0.16));
  --glass-rim-lo: light-dark(rgb(255 255 255 / 0.2), rgb(255 255 255 / 0.04));
  --edge-tint: light-dark(rgb(246 244 238 / 0.6), rgb(12 17 19 / 0.6));

  /* Elevation: soft and warm on paper, plain black on dark. */
  --shadow-key: light-dark(rgb(40 36 26 / 0.1), rgb(0 0 0 / 0.5));
  --shadow-amb: light-dark(rgb(40 36 26 / 0.06), rgb(0 0 0 / 0.3));
  --elev-1: 0 1px 2px var(--shadow-key), 0 8px 24px -12px var(--shadow-amb);
  --elev-2: 0 1px 2px var(--shadow-key), 0 12px 32px -12px var(--shadow-key);

  /* Type: a serif for headlines, Inter for text and controls, mono for labels.
     The serif is the platform's own — New York or Iowan Old Style on Apple
     devices, Palatino or Georgia elsewhere — so nothing extra is loaded. */
  --font-serif: ui-serif, "New York", "Iowan Old Style", "Palatino Linotype", Palatino,
    Georgia, Cambria, serif;
  --font-body: "Inter", "Inter Fallback", system-ui, -apple-system, "Segoe UI", Roboto,
    sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", Menlo, Consolas,
    monospace;

  /* Shape — the M3 Expressive corner scale (the steps in use), and two
     library shapes as 96-point polygons so one can morph into the other. */
  --r-xs: 4px;
  --r-m: 12px;
  --r-xl: 28px;
  --r-xl-plus: 32px;
  --r-2xl: 48px;
  --r-full: 999px;
  --shape-circle: polygon(50% 0%, 53.3% 0.1%, 56.5% 0.4%, 59.8% 1%, 62.9% 1.7%, 66.1% 2.7%, 69.1% 3.8%, 72.1% 5.2%, 75% 6.7%, 77.8% 8.4%, 80.4% 10.3%, 83% 12.4%, 85.4% 14.6%, 87.6% 17%, 89.7% 19.6%, 91.6% 22.2%, 93.3% 25%, 94.8% 27.9%, 96.2% 30.9%, 97.3% 33.9%, 98.3% 37.1%, 99% 40.2%, 99.6% 43.5%, 99.9% 46.7%, 100% 50%, 99.9% 53.3%, 99.6% 56.5%, 99% 59.8%, 98.3% 62.9%, 97.3% 66.1%, 96.2% 69.1%, 94.8% 72.1%, 93.3% 75%, 91.6% 77.8%, 89.7% 80.4%, 87.6% 83%, 85.4% 85.4%, 83% 87.6%, 80.4% 89.7%, 77.8% 91.6%, 75% 93.3%, 72.1% 94.8%, 69.1% 96.2%, 66.1% 97.3%, 62.9% 98.3%, 59.8% 99%, 56.5% 99.6%, 53.3% 99.9%, 50% 100%, 46.7% 99.9%, 43.5% 99.6%, 40.2% 99%, 37.1% 98.3%, 33.9% 97.3%, 30.9% 96.2%, 27.9% 94.8%, 25% 93.3%, 22.2% 91.6%, 19.6% 89.7%, 17% 87.6%, 14.6% 85.4%, 12.4% 83%, 10.3% 80.4%, 8.4% 77.8%, 6.7% 75%, 5.2% 72.1%, 3.8% 69.1%, 2.7% 66.1%, 1.7% 62.9%, 1% 59.8%, 0.4% 56.5%, 0.1% 53.3%, 0% 50%, 0.1% 46.7%, 0.4% 43.5%, 1% 40.2%, 1.7% 37.1%, 2.7% 33.9%, 3.8% 30.9%, 5.2% 27.9%, 6.7% 25%, 8.4% 22.2%, 10.3% 19.6%, 12.4% 17%, 14.6% 14.6%, 17% 12.4%, 19.6% 10.3%, 22.2% 8.4%, 25% 6.7%, 27.9% 5.2%, 30.9% 3.8%, 33.9% 2.7%, 37.1% 1.7%, 40.2% 1%, 43.5% 0.4%, 46.7% 0.1%);
  --shape-cookie12: polygon(50% 0%, 53.2% 1%, 56.1% 3.4%, 58.8% 6%, 61.4% 7.5%, 64.4% 7.5%, 68% 6.6%, 71.7% 5.9%, 75% 6.7%, 77.3% 9.2%, 78.6% 12.7%, 79.6% 16.3%, 81.1% 18.9%, 83.7% 20.4%, 87.3% 21.4%, 90.8% 22.7%, 93.3% 25%, 94.1% 28.3%, 93.4% 32%, 92.5% 35.6%, 92.5% 38.6%, 94% 41.2%, 96.6% 43.9%, 99% 46.8%, 100% 50%, 99% 53.2%, 96.6% 56.1%, 94% 58.8%, 92.5% 61.4%, 92.5% 64.4%, 93.4% 68%, 94.1% 71.7%, 93.3% 75%, 90.8% 77.3%, 87.3% 78.6%, 83.7% 79.6%, 81.1% 81.1%, 79.6% 83.7%, 78.6% 87.3%, 77.3% 90.8%, 75% 93.3%, 71.7% 94.1%, 68% 93.4%, 64.4% 92.5%, 61.4% 92.5%, 58.8% 94%, 56.1% 96.6%, 53.2% 99%, 50% 100%, 46.8% 99%, 43.9% 96.6%, 41.2% 94%, 38.6% 92.5%, 35.6% 92.5%, 32% 93.4%, 28.3% 94.1%, 25% 93.3%, 22.7% 90.8%, 21.4% 87.3%, 20.4% 83.7%, 18.9% 81.1%, 16.3% 79.6%, 12.7% 78.6%, 9.2% 77.3%, 6.7% 75%, 5.9% 71.7%, 6.6% 68%, 7.5% 64.4%, 7.5% 61.4%, 6% 58.8%, 3.4% 56.1%, 1% 53.2%, 0% 50%, 1% 46.8%, 3.4% 43.9%, 6% 41.2%, 7.5% 38.6%, 7.5% 35.6%, 6.6% 32%, 5.9% 28.3%, 6.7% 25%, 9.2% 22.7%, 12.7% 21.4%, 16.3% 20.4%, 18.9% 18.9%, 20.4% 16.3%, 21.4% 12.7%, 22.7% 9.2%, 25% 6.7%, 28.3% 5.9%, 32% 6.6%, 35.6% 7.5%, 38.6% 7.5%, 41.2% 6%, 43.9% 3.4%, 46.8% 1%);

  /* Motion — M3 Expressive springs sampled into linear() easings. A spring's
     curve depends only on its damping; stiffness sets the duration.
     spatial-fast = expressive fast spatial (damping 0.6, stiffness 800):
                    ≈ 350ms, ~9% overshoot — small moves and the badge only
     spatial      = expressive default | slow spatial (damping 0.8):
                    ≈ 420 | 570ms, ~1.5% overshoot
     effects      = effects springs (damping 1): no overshoot, for colour,
                    opacity and the press shape (as Material's own button) */
  --ease-spatial-fast: linear(0, 0.043, 0.149, 0.291, 0.446, 0.597, 0.733, 0.848, 0.94, 1.007, 1.053, 1.081, 1.093, 1.094, 1.087, 1.075, 1.061, 1.047, 1.033, 1.021, 1.011, 1.003, 0.997, 0.994, 0.992, 0.991, 0.991, 0.992, 0.993, 0.995, 0.996, 0.997, 1);
  --ease-spatial: linear(0, 0.029, 0.1, 0.196, 0.302, 0.411, 0.514, 0.609, 0.693, 0.765, 0.825, 0.875, 0.914, 0.945, 0.969, 0.986, 0.998, 1.006, 1.011, 1.014, 1.015, 1.015, 1.014, 1.013, 1.011, 1.01, 1.008, 1.006, 1.005, 1.004, 1.003, 1.002, 1);
  --ease-effects: linear(0, 0.072, 0.219, 0.379, 0.524, 0.644, 0.739, 0.811, 0.865, 0.905, 0.933, 0.953, 0.968, 0.978, 0.985, 0.99, 0.993, 0.995, 0.997, 0.998, 1);
  --ease-emph-decel: cubic-bezier(0.05, 0.7, 0.1, 1);
  --dur-spatial-fast: 350ms;
  --dur-spatial: 420ms;
  --dur-spatial-slow: 570ms;
  --dur-effects-fast: 140ms;
  --dur-effects: 210ms;
  --dur-effects-slow: 300ms;
  --press-scale: 0.97;

  /* Layout, on a 4px grid. The hero is a panel inset from the page edges by
     --frame; the header capsule floats inside it. */
  --page-max: 68rem;
  --page-pad: clamp(1rem, 0.5rem + 2.5vw, 2.5rem);
  --measure: 62ch;
  --section-y: clamp(4rem, 2.5rem + 6vw, 8rem);
  --frame: clamp(0.5rem, 0.25rem + 1vw, 1rem);
  --frame-r: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  --item-h: 2.75rem;
  --bar-inset: calc(var(--frame) + clamp(0.5rem, 0.25rem + 1vw, 0.875rem));
  --bar-pad: clamp(0.25rem, 0.1rem + 0.6vw, 0.375rem);
  --header-h: calc(var(--bar-inset) + var(--item-h) + 2 * var(--bar-pad));
}

/* Touch presses get more emphasis than a trackpad's. */
@media (pointer: coarse) {
  :root {
    --press-scale: 0.95;
  }
}

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

/* The padding keeps a focused element clear of the floating capsule when the
   page scrolls to it (WCAG 2.4.11). */
html {
  scroll-padding-block-start: calc(var(--header-h) + 1.5rem);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* On phones the capsule can wrap to two rows (with larger text, or the
   text-spacing adjustments of WCAG 1.4.12), so reserve room for both. The
   rem query widens along with text zoom. */
@media (width < 30rem) {
  html {
    scroll-padding-block-start: calc(var(--header-h) + var(--item-h) + 1.75rem);
  }
}

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

/* Warm paper with a fine grain. */
body {
  margin: 0;
  min-block-size: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--grain) 0 0 / 220px repeat, var(--surface);
  color: var(--on-surface);
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.6;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Keeps the footer at the foot of short pages, such as the 404. */
main {
  flex: 1 0 auto;
}

/* Headlines: a serif at a regular weight, tightly set. */
h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-serif);
  font-weight: 400;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.625rem, 1.5rem + 5vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
}

h2 {
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3.5rem);
  line-height: 1.06;
  letter-spacing: -0.015em;
}

p {
  margin: 0;
  max-inline-size: var(--measure);
  text-wrap: pretty;
}

a {
  color: var(--primary);
  text-decoration: underline;
  text-decoration-thickness: 0.08em;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 0.22em;
  transition: color var(--dur-effects) var(--ease-effects),
    text-decoration-color var(--dur-effects) var(--ease-effects),
    text-decoration-thickness var(--dur-effects) var(--ease-effects);
}

@media (hover: hover) {
  a:hover {
    text-decoration-color: currentColor;
    text-decoration-thickness: 0.12em;
  }
}

/* One static ring, following each element's own radius. No focus animation:
   focus is an interaction people repeat constantly. */
:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
}

:is(p, li) a:focus-visible {
  border-radius: var(--r-xs);
}

::selection {
  background: var(--sage);
  color: var(--on-sage);
}

/* ---- Utilities ----------------------------------------------------------- */
.wrap {
  max-inline-size: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-pad);
}

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

.skip-link {
  position: fixed;
  inset: 0.75rem auto auto 0.75rem;
  z-index: 100;
  display: inline-flex;
  align-items: center;
  min-block-size: 3rem;
  padding-inline: 1.25rem;
  border-radius: var(--r-full);
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--elev-2);
  translate: 0 calc(-100% - 1.5rem);
}

.skip-link:focus {
  translate: 0 0;
}

.skip-link:focus-visible {
  outline-color: var(--on-surface);
}

/* Shared entrance: a short rise and fade. --rise sets the distance. */
@keyframes rise-in {
  from {
    opacity: 0;
    translate: 0 var(--rise, 1.5rem);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .skip-link {
    transition: translate var(--dur-spatial) var(--ease-spatial);
  }

  /* Sections rise into place as they enter the viewport. animation-timeline
     and -range come after the animation shorthand, which resets them. */
  @supports (animation-timeline: view()) {
    .reveal {
      animation: rise-in var(--ease-emph-decel) both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }
  }
}

/* ---- Header: the one piece of Liquid Glass -------------------------------- */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 50;
  margin-block-end: calc(var(--header-h) * -1);
  padding: var(--bar-inset) var(--page-pad) 0;
  pointer-events: none;
}

/* Apple's scroll edge effect, soft style: behind the floating capsule the
   content scrolling up beneath it softens into a blur that fades downward. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0 0 -1.5rem;
  z-index: -1;
  background: linear-gradient(var(--edge-tint), transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  mask-image: linear-gradient(#000 45%, transparent);
  opacity: var(--glass-k);
  pointer-events: none;
}

/* The capsule holds the wordmark and the navigation, fitted to them and
   centred — the floating tab-bar idiom — and concentric with the 44px pills
   inside it.
   Never give .site-header or this capsule a filter, opacity below 1, mask,
   clip-path, will-change or view-transition-name: each makes an element a
   backdrop root, and the capsule's blur would then sample nothing. */
.site-header .wrap {
  position: relative;
  pointer-events: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.25rem clamp(0.25rem, 1.5vw, 1.25rem);
  inline-size: fit-content;
  max-inline-size: 100%;
  margin-inline: auto;
  padding: var(--bar-pad);
  border: 1px solid transparent;
  border-radius: calc(var(--item-h) / 2 + var(--bar-pad));
  background-color: var(--glass-fill);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  box-shadow: inset 0 1px 0 var(--glass-rim-hi),
    0 1px 2px color-mix(in srgb, var(--shadow-key) calc(var(--glass-k) * 100%), transparent),
    0 12px 32px -12px color-mix(in srgb, var(--shadow-key) calc(var(--glass-k) * 100%), transparent);
}

/* The lit edge: a specular hairline, not a second layer of glass. */
.site-header .wrap::after {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(160deg, var(--glass-rim-hi), var(--glass-rim-lo) 45%, var(--glass-rim-hi));
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}

/* The glass materializes as the page moves: its shadow and the scroll edge
   come up over the first 4rem. Shadow and opacity only — not motion — so it
   runs for everyone. */
@supports (animation-timeline: scroll()) {
  .site-header {
    animation: glass-in linear both;
    animation-timeline: scroll(root);
    animation-range: 0 4rem;
  }

  @keyframes glass-in {
    from {
      --glass-k: 0;
    }
  }
}

/* ---- Pressables: wordmark, navigation and buttons ------------------------- */
/* One recipe for every control: a pill with an M3 state layer — the content
   colour washed over the fill at 8% on hover and 10% on focus or press. A
   plain selector list rather than :is(), so each keeps its own specificity. */
.btn,
.wordmark,
.site-nav a {
  --layer: 0%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-block-size: var(--item-h);
  border: 1px solid transparent;
  border-radius: var(--r-full);
  text-decoration: none;
  background-color: color-mix(in srgb, currentColor var(--layer), var(--fill, transparent));
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur-effects) var(--ease-effects),
    color var(--dur-effects) var(--ease-effects),
    border-color var(--dur-effects) var(--ease-effects),
    box-shadow var(--dur-effects) var(--ease-effects);
}

@media (hover: hover) {
  .btn:hover,
  .wordmark:hover,
  .site-nav a:hover {
    --layer: 8%;
  }
}

.btn:focus-visible,
.wordmark:focus-visible,
.site-nav a:focus-visible,
.btn:active,
.wordmark:active,
.site-nav a:active {
  --layer: 10%;
}

/* Press and release are asymmetric: the press goes in quick and damped, the
   release springs back. Shape and scale only animate without a
   reduced-motion request; the pressed shape itself applies either way. */
@media (prefers-reduced-motion: no-preference) {
  .btn,
  .wordmark,
  .site-nav a {
    transition-property: background-color, color, border-color, box-shadow, border-radius, scale;
    transition-duration: var(--dur-effects), var(--dur-effects), var(--dur-effects),
      var(--dur-effects), var(--dur-effects), var(--dur-spatial);
    transition-timing-function: var(--ease-effects), var(--ease-effects), var(--ease-effects),
      var(--ease-effects), var(--ease-effects), var(--ease-spatial);
  }

  .btn:active,
  .wordmark:active,
  .site-nav a:active {
    scale: var(--press-scale);
    transition-duration: var(--dur-effects-fast);
    transition-timing-function: var(--ease-effects);
  }
}

/* The wordmark leads with the brand mark (see the glyph below). */
.wordmark {
  gap: 0.4em;
  padding-inline: 0.5rem 0.875rem;
  color: var(--on-surface);
  font-family: var(--font-serif);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.01em;
}

.site-nav {
  display: flex;
  gap: 0.125rem;
}

.site-nav a {
  padding-inline: clamp(0.625rem, 0.4rem + 1vw, 1rem);
  color: var(--on-surface-variant);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.25;
}

@media (hover: hover) {
  .site-nav a:hover {
    color: var(--on-surface);
  }
}

/* The current page wears the active-indicator pill: a tonal fill, not glass
   on glass. */
.site-nav a[aria-current="page"] {
  --fill: var(--sage);
  color: var(--on-sage);
  font-weight: 600;
}

/* The narrowest phones (below ~368px): the wordmark drops its glyph so the
   capsule stays on one line. */
@media (width < 23rem) {
  .wordmark {
    padding-inline: 0.625rem;
    font-size: 1.125rem;
  }

  .wordmark::before {
    display: none;
  }
}

/* ---- Buttons: pills ---------------------------------------------------------- */
/* 48px tall. The radius is a real half-height, so the press morph to the
   12px medium corner shows from its first frame (from 999px it would not). */
.btn {
  --btn-h: 3rem;
  min-block-size: var(--btn-h);
  padding: 0.5rem 1.375rem;
  border-radius: calc(var(--btn-h) / 2);
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.005em;
  text-align: center;
}

.btn:active {
  border-radius: var(--r-m);
}

/* The one prominent action per view: the teal pill. */
.btn-primary {
  --fill: var(--primary);
  color: var(--on-primary);
  box-shadow: 0 1px 2px var(--shadow-key), 0 8px 20px -10px color-mix(in srgb, var(--primary) 60%, transparent);
}

@media (hover: hover) {
  .btn-primary:hover {
    box-shadow: 0 2px 4px var(--shadow-key), 0 14px 28px -12px color-mix(in srgb, var(--primary) 70%, transparent);
  }
}

.btn-primary:active {
  box-shadow: 0 1px 2px var(--shadow-key);
}

/* The secondary action is a ghost pill: a hairline and a faint wash, so it
   reads on the painted panel and on paper alike. */
.btn-quiet {
  --fill: light-dark(rgb(255 255 255 / 0.4), rgb(255 255 255 / 0.05));
  border-color: color-mix(in srgb, var(--on-surface) 28%, transparent);
  color: var(--on-surface);
}

/* The primary button's arrow says where it goes: ↓ within the page, ↗ to
   another site, ← back home (leading), → anywhere else. */
.btn-primary::after {
  content: "";
  flex: none;
  inline-size: 1.125rem;
  aspect-ratio: 1;
  background-color: currentColor;
  mask: url("/assets/icons/arrow.svg") center / contain no-repeat;
  rotate: var(--turn, 0deg);
}

.btn-primary[href^="#"] {
  --turn: 90deg;
  --nudge: 0 0.1875rem;
}

.btn-primary[href^="https:"] {
  --turn: -45deg;
  --nudge: 0.125rem -0.125rem;
}

.btn-primary[href="/"] {
  --turn: 180deg;
  --nudge: -0.1875rem 0;
}

.btn-primary[href="/"]::after {
  order: -1;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-block-start: 2.25rem;
}

@media (width < 40rem) {
  .cta-row > .btn {
    flex: 1 1 auto;
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* The arrow leans the way it points. */
  .btn-primary::after {
    transition: translate var(--dur-spatial-fast) var(--ease-spatial-fast);
  }

  .btn-primary:focus-visible::after {
    translate: var(--nudge, 0.1875rem 0);
  }

  @media (hover: hover) {
    .btn-primary:hover::after {
      translate: var(--nudge, 0.1875rem 0);
    }
  }
}

/* ---- Labels: small letter-spaced mono ------------------------------------- */
.eyebrow {
  margin: 0 0 1.25rem;
  color: var(--on-surface-variant);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.25rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* A quiet tag, not a live indicator: nothing here may suggest the app is
   already available. */
.status-pill {
  display: inline-flex;
  align-items: center;
  min-block-size: 1.75rem;
  margin-block-end: 1.5rem;
  padding: 0.25rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--on-surface-variant);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.25rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---- The brand glyph ------------------------------------------------------ */
/* Identical before both wordmarks and sized to its text: the favicon file
   itself, drawn in as a background image, so the mark in the page and the
   mark in the tab bar are literally the same asset and can never drift. It
   is a round badge — a calligraphic A centred on a crescent — sized to
   1.125em of the wordmark and left round at every size. The artwork carries
   its own colours and flips them in dark mode from inside the SVG, so
   nothing here paints it; the A is outlined as a path, so it needs no font
   and no optical nudge. */
.wordmark::before,
.footer-brand::before {
  content: "";
  flex: none;
  inline-size: 1.125em;
  aspect-ratio: 1;
  border-radius: 50%;
  background: url("/assets/favicon.svg?v=2") center / 100% 100% no-repeat;
}

/* ---- Hero: a painted panel -------------------------------------------------- */
/* Inset from the page edges and rounded, like a framed picture: a quiet
   field with three soft blooms of colour drifting across it, under a fine
   grain. Nothing is depicted — the blooms are the whole of it. The words
   clear the floating capsule above them. */
.hero {
  position: relative;
  overflow: clip;
  margin: var(--frame) var(--frame) 0;
  padding-block: calc(var(--header-h) + clamp(3rem, 6vw, 5.5rem))
    clamp(3.5rem, 2rem + 5vw, 6.5rem);
  border-radius: var(--frame-r);
  background:
    var(--grain) 0 0 / 220px repeat,
    radial-gradient(ellipse 65% 60% at 15% 12%, var(--bloom-1), transparent 70%),
    radial-gradient(ellipse 55% 55% at 88% 24%, var(--bloom-2), transparent 68%),
    radial-gradient(ellipse 95% 65% at 55% 108%, var(--bloom-3), transparent 72%),
    var(--panel-base);
}

/* Home and not-found: the words are centred in the panel. */
.hero.centered {
  text-align: center;
}

.hero.centered .wrap > * {
  margin-inline: auto;
}

.hero.centered .cta-row {
  justify-content: center;
}

/* Wide screens: left-aligned heroes hold their words to a column rather
   than letting them run the full width of the panel. */
@media (width >= 60rem) {
  .hero:not(.centered) .wrap > * {
    max-inline-size: 40rem;
  }
}

/* The contact cards sit in the hero, under the words, on the painted field. */
.hero .wrap > .card-grid {
  max-inline-size: none;
  margin-block-start: clamp(2rem, 1.5rem + 2vw, 3rem);
}

.hero h1 {
  max-inline-size: 16ch;
}

.hero.centered h1 {
  max-inline-size: 18ch;
}

.lede {
  margin-block-start: 1.5rem;
  max-inline-size: 34em;
  color: var(--on-surface-variant);
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  line-height: 1.6;
  letter-spacing: -0.011em;
}

/* Arrival, once: the words settle one after another. Fill mode is backwards,
   not both — an animation still filling forwards would sit above later hover
   transitions. */
@media (prefers-reduced-motion: no-preference) {
  .hero .wrap > * {
    --rise: 1rem;
    animation: rise-in var(--dur-spatial-slow) var(--ease-spatial) backwards;
    animation-delay: 120ms;
    animation-delay: calc(60ms + sibling-index() * 70ms);
  }
}

/* ---- Sections ------------------------------------------------------------ */
.section {
  padding-block: var(--section-y);
}

.section + .section {
  padding-block-start: 0;
}

.section-head {
  max-inline-size: 42rem;
  margin-block-end: clamp(2rem, 1.25rem + 2.5vw, 3.25rem);
}

.section-head h2 {
  max-inline-size: 20ch;
}

/* Who it's for: the audiences set as one editorial line in the headline
   serif, every other one in italic, divided by slashes that screen readers
   skip (empty alt text). */
.audience {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  row-gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--on-surface);
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 1.2rem + 2.4vw, 3.25rem);
  line-height: 1.2;
  letter-spacing: -0.015em;
}

.audience li:nth-child(even) {
  font-style: italic;
}

.audience li:not(:last-child)::after {
  content: "/";
  content: "/" / "";
  margin-inline: 0.4em;
  color: var(--primary);
  font-style: normal;
}

/* A statement: its heading on the left and one large passage on the right,
   under a hairline. */
.statement {
  display: grid;
  gap: 1rem 3rem;
  padding-block-start: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  border-top: 1px solid var(--hairline);
}

@media (width >= 48rem) {
  .statement {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr);
    align-items: start;
  }
}

.statement .lede {
  margin-block-start: 0;
  max-inline-size: 36em;
  color: var(--on-surface);
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
  line-height: 1.5;
}

/* ---- Product spotlight ---------------------------------------------------- */
.spotlight {
  position: relative;
  overflow: clip;
  display: grid;
  justify-items: start;
  padding: clamp(1.75rem, 1rem + 3.5vw, 4rem);
  border: 1px solid transparent;
  border-radius: var(--r-xl-plus);
  background:
    var(--grain) 0 0 / 220px repeat,
    linear-gradient(135deg, var(--card) 35%, var(--card-tint));
  box-shadow: var(--elev-1);
}

@media (width >= 60rem) {
  .spotlight {
    border-radius: var(--r-2xl);
  }

  .spotlight > * {
    max-inline-size: 34rem;
  }
}

/* The product's own name, in serif italic. */
.product-name {
  font-size: clamp(2.5rem, 1.6rem + 3.6vw, 4.5rem);
  font-style: italic;
  line-height: 1.02;
  letter-spacing: -0.02em;
}

.spotlight h2 {
  font-size: clamp(2.25rem, 1.5rem + 3vw, 4rem);
  line-height: 1.04;
}

.spotlight .lede {
  margin-block-start: 1.25rem;
}

.spotlight .cta-row {
  justify-self: stretch;
  margin-block-start: 2.25rem;
}

/* ---- Badges: one expressive shape, a quiet tone, an icon or a number ------- */
/* Cookie-12 from the M3 Expressive shape library. On contact cards it morphs
   into a circle when the card's link is reached for; elsewhere it is still. */
.callout {
  --badge-size: 2.75rem;
  --glyph: 1.375rem;
  --badge: var(--on-sky);
  --badge-ink: var(--sky);
  --icon: url("/assets/icons/info.svg");
}

.card {
  --badge-size: 3.25rem;
  --glyph: 1.375rem;
}

.card:has(a[href^="mailto:"]) {
  --badge: var(--sage);
  --badge-ink: var(--on-sage);
  --icon: url("/assets/icons/mail.svg");
}

.card:has(a[href^="tel:"]) {
  --badge: var(--sky);
  --badge-ink: var(--on-sky);
  --icon: url("/assets/icons/call.svg");
}

.card:has(address) {
  --badge: var(--sand);
  --badge-ink: var(--on-sand);
  --icon: url("/assets/icons/office.svg");
}

:is(.card:has(a, address), .callout)::before,
:is(.card:has(a, address), .callout)::after {
  content: "";
  grid-area: 1 / 1;
  inline-size: var(--badge-size);
  aspect-ratio: 1;
}

:is(.card:has(a, address), .callout)::before {
  background: var(--badge);
  clip-path: var(--shape-cookie12);
}

:is(.card:has(a, address), .callout)::after {
  background: var(--badge-ink);
  mask: var(--icon) center / var(--glyph) no-repeat;
}

.card::before,
.card::after {
  margin-block-end: 1.25rem;
}

/* ---- Callout: the complements-emergency-services note ----------------------- */
/* A quiet tinted note with an info badge; it holds still beyond the shared
   reveal. */
.callout {
  display: grid;
  grid-template-columns: var(--badge-size) minmax(0, 1fr);
  gap: 1rem 1.25rem;
  align-items: start;
  max-inline-size: 48rem;
  padding: clamp(1.25rem, 1rem + 1vw, 1.75rem) clamp(1.25rem, 1rem + 1.5vw, 2rem);
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  background: var(--sky);
  color: var(--on-sky);
}

.callout p {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.6;
}

.callout a {
  color: inherit;
  text-decoration-color: currentColor;
  text-decoration-thickness: 0.08em;
}

@media (hover: hover) {
  .callout a:hover {
    text-decoration-thickness: 0.14em;
  }
}

@media (width < 30rem) {
  .callout {
    grid-template-columns: minmax(0, 1fr);
  }

  .callout p {
    grid-column: 1;
    grid-row: 2;
  }
}

/* ---- Cards: contact details ------------------------------------------------ */
.card-grid {
  display: grid;
  gap: clamp(0.75rem, 0.5rem + 1vw, 1.25rem);
}

@media (width >= 40rem) {
  .card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .card-grid > .card:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

@media (width >= 64rem) {
  .card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .card-grid > .card:last-child:nth-child(odd) {
    grid-column: auto;
  }
}

/* Paper cards: no outline — a fill and the lightest shadow do the work. The
   border is kept at 1px transparent so forced colours still gets an edge to
   paint, as the buttons, the capsule and the callout already do. */
.card {
  container-type: inline-size;
  display: grid;
  row-gap: 0.625rem;
  align-content: start;
  padding: clamp(1.5rem, 1.25rem + 1vw, 2rem);
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  background-color: var(--card);
  box-shadow: var(--elev-1);
  transition: background-color var(--dur-effects) var(--ease-effects);
}

.card h3 {
  color: var(--on-surface-variant);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.25rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.card p {
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
  line-height: 1.65;
}

/* A contact card reacts only when its link is reached for: it steps up one
   tone and its badge becomes a circle. The office card has no link, so it
   stays still. */
.card:has(a:focus-visible) {
  background-color: var(--card-hover);
}

.card:has(a:focus-visible)::before {
  clip-path: var(--shape-circle);
}

@media (hover: hover) {
  .card:has(a:hover) {
    background-color: var(--card-hover);
  }

  .card:has(a:hover)::before {
    clip-path: var(--shape-circle);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .card::before {
    transition: clip-path var(--dur-spatial-fast) var(--ease-spatial-fast),
      rotate var(--dur-spatial-fast) var(--ease-spatial-fast);
  }

  /* One lobe of roll as the cookie becomes the circle. */
  .card:has(a:is(:hover, :focus-visible))::before {
    rotate: 30deg;
  }
}

/* The contact value itself, in the headline serif, sized to its card so the
   address never has to break mid-word. */
.contact-email {
  font-family: var(--font-serif);
  font-size: clamp(1.25rem, 8.5cqi, 1.75rem);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.card .contact-email {
  color: var(--on-surface);
}

.contact-email a {
  color: inherit;
  text-decoration-color: color-mix(in srgb, var(--primary) 45%, transparent);
  text-decoration-thickness: 1.5px;
}

@media (hover: hover) {
  .contact-email a:hover {
    color: var(--primary);
    text-decoration-color: var(--primary);
  }
}

address {
  color: var(--on-surface);
  font-size: 1.0625rem;
  font-style: normal;
  line-height: 1.6;
}

/* ---- Footer: a sheet below the painted panel ------------------------------ */
.site-footer {
  margin: clamp(1rem, 0.5rem + 2vw, 2rem) var(--frame) var(--frame);
  padding-block: clamp(2.5rem, 2rem + 3vw, 4rem) 2rem;
  border: 1px solid transparent;
  border-radius: var(--frame-r);
  background: var(--surface-container);
  color: var(--on-surface-variant);
  font-size: 0.9375rem;
}

.footer-grid {
  display: grid;
  gap: 2rem;
}

@media (width >= 40rem) {
  .footer-grid {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
  }
}

/* The brand line, led by the same glyph as the header's wordmark. */
.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  color: var(--on-surface);
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.015em;
}

.footer-label {
  margin-block-end: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.25rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

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

.footer-grid a {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
  color: var(--on-surface);
  text-decoration-color: transparent;
}

@media (hover: hover) {
  .footer-grid a:hover {
    color: var(--primary);
    text-decoration-color: currentColor;
  }
}

.footer-legal {
  margin-block-start: 2.5rem;
  padding-block-start: 1.25rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* On the 404 page the legal line is the footer's only content — no second rule. */
.footer-legal:first-child {
  margin-block-start: 0;
  padding-block-start: 0;
  border-top: 0;
}

/* ---- Cross-page view transitions ------------------------------------------- */
/* The root cross-fade is opacity only, which is safe for everyone. With no
   reduced-motion request, the current page's pill also glides from one nav
   item to the next. */
@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation-duration: var(--dur-effects-fast);
  animation-timing-function: var(--ease-effects);
}

::view-transition-new(root) {
  animation-duration: var(--dur-effects-slow);
  animation-timing-function: var(--ease-effects);
}

@media (prefers-reduced-motion: no-preference) {
  .site-nav a[aria-current="page"] {
    view-transition-name: nav-current;
  }

  ::view-transition-group(nav-current) {
    animation-duration: var(--dur-spatial);
    animation-timing-function: var(--ease-spatial);
  }
}

/* ==========================================================================
   User preferences
   ========================================================================== */

/* Reduced transparency (Chromium only) and browsers without backdrop-filter:
   the glass turns solid. The translucent glass stays the default because it
   is legible on its own — never gate it behind not (…), which Safari and
   Firefox would never match. */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --glass-fill: var(--glass-solid);
    --edge-tint: var(--surface);
  }

  .site-header .wrap,
  .site-header::before {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root {
    --glass-fill: var(--glass-solid);
    --edge-tint: var(--surface);
  }
}

/* More contrast: a deeper accent, full-strength secondary text and hairlines,
   solid glass, and the panel's blooms put away. */
@media (prefers-contrast: more) {
  :root {
    --primary: light-dark(#004f4f, #9cf1f0);
    --on-surface-variant: var(--on-surface);
    --hairline: var(--outline);
    --glass-fill: var(--glass-solid);
    --bloom-1: transparent;
    --bloom-2: transparent;
    --bloom-3: transparent;
  }

  .site-header .wrap {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border-color: var(--outline);
  }

  /* The outline-less surfaces go back to a visible edge here: they rely on a
     fill difference, which is the thing this query exists to stop trusting. */
  .btn-quiet,
  .site-nav a[aria-current="page"],
  .card,
  .spotlight,
  .site-footer {
    border-color: var(--outline);
  }
}

/* Forced colours: the decorative layers go; glyphs and icons stay in system
   ink. The transparent 1px borders on the buttons, the capsule, the callout,
   the cards and the footer become visible boundaries on their own. */
@media (forced-colors: active) {
  body,
  .hero,
  .spotlight {
    background: Canvas;
  }

  .site-header::before,
  .site-header .wrap::after,
  .card::before,
  .callout::before {
    display: none;
  }

  :is(.card:has(a, address), .callout)::after {
    forced-color-adjust: none;
    background: CanvasText;
  }

  /* The badge is artwork, not text: keep its own colours rather than let
     them be forced to the system pair, which would flatten the A into its
     ground. */
  .wordmark::before,
  .footer-brand::before {
    forced-color-adjust: none;
  }

  .btn-primary::after {
    forced-color-adjust: none;
    background: LinkText;
  }

  .site-nav a[aria-current="page"] {
    forced-color-adjust: none;
    background: SelectedItem;
    color: SelectedItemText;
  }

  :focus-visible {
    outline-color: Highlight;
  }
}
