/* =============================================================================
   cxlogiq.css — the CXLogiq brand for plain HTML sites. GENERATED FILE.
   Source: the cxlogiq-design-system repo -> pnpm site-kit. Do not edit here;
   edit the design system and regenerate.
   ========================================================================== */

/* ---- from fonts ---- */
/* =============================================================================
   @uclogiq/tokens/fonts.css — the CXLogiq typefaces, self-hosted.
   -----------------------------------------------------------------------------
   Import this ONCE in an app's main.ts, alongside tokens.css:

     import '@uclogiq/tokens/fonts.css';

   Faces:
     Inter    the workhorse UI/body face (--cx-font), weights 400/600/700/800
     Sora     the display face (--cx-font-display) — geometric, quietly
              futuristic; hero + section headings. Weights 700/800.
     Bangers  the impact face (--cx-font-impact) — loud comic-poster energy.
              Loaded and available but applied to NOTHING by default; call it
              deliberately (.cx-impact) for a rare statement heading.

   The .woff2 files ship inside this package (fonts/) so nothing loads from a
   CDN at runtime. All fonts are SIL Open Font License. To refresh the files:
   they're copied from the @fontsource/inter, @fontsource/sora and
   @fontsource/bangers dev dependencies of this package (see CONTRIBUTING.md).
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('./fonts/inter-latin-400-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('./fonts/inter-latin-600-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('./fonts/inter-latin-700-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('./fonts/inter-latin-800-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Sora';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('./fonts/sora-latin-700-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Sora';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('./fonts/sora-latin-800-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Bangers';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('./fonts/bangers-latin-400-normal.woff2') format('woff2');
}

/* ---- from tokens ---- */
/* =============================================================================
   @uclogiq/tokens — GENERATED FILE, do not edit by hand.
   Source of truth: packages/tokens/src/index.ts  →  pnpm build regenerates this.
   ========================================================================== */

/* Dark is the default theme (no attribute needed). .cx-theme-dark makes a
   dark island inside a light page — see the header comment in build-css.mjs. */
:root,
[data-theme="dark"],
.cx-theme-dark {
  /* Not a --cx- token: tells the browser to render native UI (form controls,
     scrollbars) to match the theme. */
  color-scheme: dark;
  --cx-canvas: #060c16;
  --cx-bg-canvas: radial-gradient(1200px 600px at 80% -10%, rgba(0, 174, 239, 0.10), transparent 60%), radial-gradient(900px 500px at -10% 10%, rgba(15, 39, 64, 0.55), transparent 55%), #060c16;
  --cx-surface: #0e1826;
  --cx-surface-2: #13202f;
  --cx-surface-3: #18293b;
  --cx-border: rgba(41, 198, 255, 0.14);
  --cx-border-strong: rgba(41, 198, 255, 0.32);
  --cx-text: #e6eef6;
  --cx-text-muted: #ccd8e7;
  --cx-text-dim: #5d6e83;
  --cx-accent: #00aeef;
  --cx-accent-bright: #29c6ff;
  --cx-accent-deep: #0288c4;
  --cx-accent-contrast: #060c16;
  --cx-pop: #f0512a;
  --cx-good: #34d399;
  --cx-warn: #f0512a;
  --cx-info: #00aeef;
  --cx-skip: #b9c4d0;
  --cx-tag-doc: #6db4ff;
  --cx-tag-text: #34d399;
  --cx-tag-data: #ffb454;
  --cx-grad-button: linear-gradient(135deg, #0b7fc4 0%, #16b6f0 100%);
  --cx-grad-header: linear-gradient(180deg, #0c2c4d 0%, #0a1322 72%);
  --cx-masthead-text: #f4f8fb;
  --cx-grad-hero: radial-gradient(95% 90% at 0% 0%, #0c2c4d 0%, rgba(12, 44, 77, 0.45) 48%, transparent 74%), #060c16;
  --cx-glow: 0 0 22px rgba(0, 174, 239, 0.35);
  --cx-focus-ring: rgba(0, 174, 239, 0.45);
}

[data-theme="light"] {
  color-scheme: light;
  --cx-canvas: #eef3f8;
  --cx-bg-canvas: radial-gradient(1200px 600px at 80% -10%, rgba(0, 174, 239, 0.08), transparent 60%), radial-gradient(900px 500px at -10% 10%, rgba(220, 231, 240, 0.7), transparent 55%), #eef3f8;
  --cx-surface: #ffffff;
  --cx-surface-2: #f4f8fb;
  --cx-surface-3: #e9f1f7;
  --cx-border: rgba(2, 136, 196, 0.20);
  --cx-border-strong: rgba(2, 136, 196, 0.40);
  --cx-text: #122438;
  --cx-text-muted: #3c556e;
  --cx-text-dim: #7a8fa3;
  --cx-accent: #00aeef;
  --cx-accent-bright: #29c6ff;
  --cx-accent-deep: #0288c4;
  --cx-accent-contrast: #ffffff;
  --cx-pop: #f0512a;
  --cx-good: #0e9f6e;
  --cx-warn: #d64524;
  --cx-info: #0288c4;
  --cx-skip: #5c6b7a;
  --cx-tag-doc: #2f6fb8;
  --cx-tag-text: #0e9f6e;
  --cx-tag-data: #b26a00;
  --cx-grad-button: linear-gradient(135deg, #0b7fc4 0%, #16b6f0 100%);
  --cx-grad-header: linear-gradient(180deg, #0c2c4d 0%, #0a1322 72%);
  --cx-masthead-text: #f4f8fb;
  --cx-grad-hero: radial-gradient(95% 90% at 0% 0%, #0a1322 0%, #0c2c4d 30%, rgba(12, 44, 77, 0.85) 45%, rgba(12, 44, 77, 0.28) 60%, transparent 74%), radial-gradient(1200px 600px at 85% 15%, rgba(0, 174, 239, 0.08), transparent 60%), #eef3f8;
  --cx-glow: 0 0 22px rgba(0, 174, 239, 0.22);
  --cx-focus-ring: rgba(2, 136, 196, 0.45);
}

/* Theme-agnostic tokens. */
:root {
  --cx-radius: 14px;
  --cx-radius-sm: 9px;
  --cx-font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --cx-font-mono: 'SF Mono', ui-monospace, 'Cascadia Code', Consolas, monospace;
  --cx-font-display: 'Sora', 'Inter', system-ui, sans-serif;
  --cx-font-impact: 'Bangers', 'Inter', system-ui, sans-serif;
}

/* ---- from base ---- */
/* =============================================================================
   @uclogiq/ui/base.css — page basics every CXLogiq app starts from.
   Import AFTER @uclogiq/tokens/tokens.css (this file uses those variables).
   ========================================================================== */

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--cx-font);
  color: var(--cx-text);
  background: var(--cx-bg-canvas);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* The standard centred content column (matches the masthead's inner width). */
.cx-container {
  width: min(1080px, 92vw);
  margin: 0 auto;
}

/* ---- from components ---- */
/* =============================================================================
   @uclogiq/ui/components.css — the CXLogiq component classes, as plain CSS.
   -----------------------------------------------------------------------------
   THE single source of truth for how the brand primitives look. Two consumers:

     1. The Vue components in src/components/ — thin templates over these
        classes (they deliberately have NO <style> blocks of their own).
     2. Plain HTML sites (e.g. the CXLogiq landing page) — write the markup
        with these classes directly; no framework needed. See the site kit
        (`pnpm site-kit` at the repo root) for a ready-made bundle + example.

   Import AFTER tokens.css and base.css (everything here uses --cx- tokens).
   Rule: edit styles HERE, never re-add <style scoped> to the six primitives —
   that would fork the look between Vue apps and plain HTML sites.

   Components: .cx-masthead  .cx-wordmark  .cx-panel  .cx-btn  .cx-chip  .cx-badge
   Landing-page components (plain HTML sites; no Vue counterparts yet):
               .cx-hero  .cx-section  .cx-grid  .cx-band  .cx-form  .cx-footer
   ========================================================================== */

/* ----- Masthead: navy brand bar with the swoosh ---------------------------- */
/* Plain-HTML usage (animated swoosh is optional — see cx-masthead.js):

     <header class="cx-masthead">
       <canvas class="cx-masthead__mesh" id="hero-mesh"></canvas>
       <img class="cx-masthead__swoosh-fallback" src="assets/swoosh.png" alt="" />
       <div class="cx-masthead__inner">
         <div class="cx-masthead__lockup">
           <img id="hero-logo" src="assets/mission-control.png" alt="Mission Control" />
           <div> …wordmark… </div>
         </div>
       </div>
     </header>

   Without the canvas + script, the fallback <img> shows the static swoosh.   */
.cx-masthead {
  position: relative;
  overflow: hidden;
  background: var(--cx-grad-header);
  border-bottom: 1px solid var(--cx-border);
}
.cx-masthead__mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.cx-masthead__swoosh-fallback {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  width: 100%;
  opacity: 0.5;
  pointer-events: none;
  user-select: none;
}
.cx-masthead__inner {
  position: relative;
  z-index: 2;
  width: min(1080px, 92vw);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 26px 0 40px;
}
.cx-masthead__lockup {
  display: flex;
  align-items: center;
  gap: 18px;
}
.cx-masthead__lockup img {
  height: 50px;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.45));
}
.cx-masthead__brand img {
  height: 33px;
  opacity: 0.92;
}
@media (max-width: 720px) {
  .cx-masthead__brand {
    display: none;
  }
}

/* ----- Wordmark: two-tone app name (designed for the masthead) ------------- */
.cx-wordmark {
  margin: 0;
  font-size: 34px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.01em;
}
.cx-wordmark__first {
  color: var(--cx-accent);
}
.cx-wordmark__second {
  color: var(--cx-masthead-text);
  margin-left: 7px;
}
.cx-wordmark__tagline {
  margin: 8px 0 0;
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--cx-text-dim);
}

/* ----- Panel: the numbered step card --------------------------------------- */
.cx-panel {
  background: linear-gradient(180deg, var(--cx-surface) 0%, var(--cx-surface-2) 100%);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius);
  padding: 22px 24px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28);
}
.cx-panel.is-disabled {
  opacity: 0.55;
  filter: saturate(0.6);
}
.cx-panel__head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.cx-panel__titles {
  flex: 1;
}
.cx-panel__num {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 14px;
  color: var(--cx-accent-contrast);
  background: var(--cx-accent);
  box-shadow: var(--cx-glow);
}
.cx-panel__title {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
}
.cx-panel__hint {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--cx-text-muted);
}

/* ----- Button: default / primary / ghost · md / lg ------------------------- */
/* Works as <button> or as a link: <a class="cx-btn" href="…"> (no underline). */
.cx-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 11px 18px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  color: var(--cx-text);
  background: var(--cx-surface-3);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-sm);
  transition: transform 0.08s, box-shadow 0.15s, border-color 0.15s, background 0.15s;
}
.cx-btn:hover {
  border-color: var(--cx-border-strong);
}
.cx-btn:active {
  transform: translateY(1px);
}
.cx-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.cx-btn:focus-visible {
  outline: 2px solid var(--cx-focus-ring);
  outline-offset: 2px;
}
.cx-btn--primary {
  color: #fff;
  background: var(--cx-grad-button);
  border: none;
  box-shadow: var(--cx-glow);
}
.cx-btn--primary:hover {
  box-shadow: 0 0 28px rgba(0, 174, 239, 0.55);
}
.cx-btn--ghost {
  background: transparent;
}
.cx-btn--lg {
  padding: 14px 26px;
  font-size: 15px;
}

/* ----- Chip: status with the glowing dot (idle / busy / ok / error) -------- */
.cx-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--cx-border);
}
.cx-chip__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cx-text-dim);
}
.cx-chip.is-ok {
  color: var(--cx-good);
  border-color: color-mix(in srgb, var(--cx-good) 40%, transparent);
}
.cx-chip.is-ok .cx-chip__dot {
  background: var(--cx-good);
  box-shadow: 0 0 10px var(--cx-good);
}
.cx-chip.is-error {
  color: var(--cx-warn);
  border-color: color-mix(in srgb, var(--cx-warn) 40%, transparent);
}
.cx-chip.is-error .cx-chip__dot {
  background: var(--cx-warn);
}
.cx-chip.is-busy {
  color: var(--cx-accent-bright);
}
.cx-chip.is-busy .cx-chip__dot {
  background: var(--cx-accent-bright);
  animation: cx-chip-pulse 1s infinite;
}
@keyframes cx-chip-pulse {
  50% {
    opacity: 0.3;
  }
}

/* ----- Badge: small uppercase tag, colour-coded by family ------------------ */
.cx-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 6px;
  border: 1px solid var(--cx-border);
  color: var(--cx-text-muted);
}
.cx-badge--doc {
  color: var(--cx-tag-doc);
  border-color: color-mix(in srgb, var(--cx-tag-doc) 40%, transparent);
}
.cx-badge--text {
  color: var(--cx-tag-text);
  border-color: color-mix(in srgb, var(--cx-tag-text) 40%, transparent);
}
.cx-badge--data {
  color: var(--cx-tag-data);
  border-color: color-mix(in srgb, var(--cx-tag-data) 40%, transparent);
}
.cx-badge--warn {
  color: var(--cx-warn);
  border-color: color-mix(in srgb, var(--cx-warn) 40%, transparent);
}

/* =============================================================================
   Landing-page components — used by the plain-HTML CXLogiq site.
   ========================================================================== */

/* ----- Hero: full-height landing splash ------------------------------------ */
/* The dark brand corner (navy + swoosh + constellation canvas) sits top-left
   and dissolves down/right into the light canvas (--cx-grad-hero does the
   fade). The page stays data-theme="light"; text ON the dark corner uses
   --cx-masthead-text (light in both themes), everything else uses normal
   light-theme tokens. Plain-HTML usage:

     <header class="cx-hero">
       <canvas class="cx-hero__mesh" id="hero-mesh"></canvas>
       <div class="cx-hero__media"><!-- hero artwork, mask-dissolved --></div>
       <div class="cx-hero__inner">
         <nav class="cx-hero__nav">
           <div class="cx-hero__lockup"> …logo + tagline… </div>
           <div class="cx-hero__nav-links"> …links… </div>
         </nav>
         <div class="cx-hero__copy">
           <h1 class="cx-hero__title">…</h1>
           <p class="cx-hero__lede">…</p>
           <div class="cx-hero__actions"> …cx-btns… </div>
         </div>
       </div>
     </header>

   cx-hero.js (optional) animates the constellation + reveals; without it the
   hero is static but complete.                                                */
.cx-hero {
  position: relative;
  overflow: hidden;
  background: var(--cx-grad-hero);
  min-height: clamp(540px, 82vh, 800px);
  display: flex;
  flex-direction: column;
}
.cx-hero__mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 1; /* above the media image — the dots read on top of the artwork */
  /* Belt-and-braces with the JS's own top-left weighting: the constellation
     dissolves along the same diagonal as the background gradient. */
  -webkit-mask-image: linear-gradient(135deg, #000 30%, transparent 75%);
  mask-image: linear-gradient(135deg, #000 30%, transparent 75%);
}
/* Hero photo slot: fills the dark corner and DISSOLVES into the gradient on
   its outward edges (radial mask anchored top-left — same shape as
   --cx-grad-hero), so there are no hard seams. Ships empty — the gradient
   alone must look finished. Artwork should itself fade to dark navy at its
   edges; see the hero-image brief. */
.cx-hero__media {
  position: absolute;
  top: 0;
  left: 0;
  width: min(60%, 780px);
  height: 80%;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(115% 115% at 0% 0%, #000 45%, transparent 77%);
  mask-image: radial-gradient(115% 115% at 0% 0%, #000 45%, transparent 77%);
  opacity: 0.92;
}
.cx-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cx-hero__inner {
  position: relative;
  z-index: 2;
  width: min(1080px, 92vw);
  margin: 0 auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 22px 0 72px;
}
.cx-hero__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}
.cx-hero__nav-links {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
}
.cx-hero__nav-links a {
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  color: var(--cx-text);
}
.cx-hero__nav-links a:hover {
  color: var(--cx-accent-deep);
}
/* Sun/moon theme toggle — last item in .cx-hero__nav-links. Shows the icon of
   the theme you'd switch TO (dark page → sun, light page → moon). Pairs with
   the head bootstrap snippet + toggleTheme() in the site-kit template page.
   Keyed off [data-theme] on <html> — don't place one inside a .cx-theme-dark
   island (the island stays dark either way, so the icon would mislead). */
.cx-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--cx-border);
  border-radius: 999px;
  background: transparent;
  color: var(--cx-text);
  cursor: pointer;
}
.cx-theme-toggle:hover {
  color: var(--cx-accent-deep);
  border-color: var(--cx-accent-deep);
}
.cx-theme-toggle:focus-visible {
  outline: 2px solid var(--cx-focus-ring);
  outline-offset: 2px;
}
.cx-theme-toggle svg {
  width: 18px;
  height: 18px;
}
.cx-theme-toggle__moon {
  display: none; /* dark is the default theme → offer the sun */
}
[data-theme="light"] .cx-theme-toggle__sun {
  display: none;
}
[data-theme="light"] .cx-theme-toggle__moon {
  display: block;
}
/* Brand lockup on the dark corner (lives at the nav's left) — masthead-text
   keeps it light-on-navy. */
.cx-hero__lockup {
  display: flex;
  align-items: center;
  gap: 18px;
}
.cx-hero__lockup img {
  height: 54px;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.45));
}
/* Headline block: lower half of the hero. Pick a position with a modifier —
     __copy--left    copy on the left  (artwork/screenshot on the right)
     __copy--center  centred, text centred too (brand statement pages)
     __copy--right   copy on the right (artwork in the left corner)
   Default (no modifier) = centred block, left-aligned text. */
.cx-hero__copy {
  margin-top: auto;
  align-self: center;
  max-width: 660px;
  padding-top: 48px;
}
.cx-hero__copy--left {
  align-self: flex-start;
}
.cx-hero__copy--right {
  align-self: flex-end;
}
.cx-hero__copy--center {
  align-self: center;
  text-align: center;
}
.cx-hero__copy--center .cx-hero__lede {
  margin-left: auto;
  margin-right: auto;
}
.cx-hero__copy--center .cx-hero__actions {
  justify-content: center;
}
.cx-hero__title {
  margin: 0 0 14px;
  font-family: var(--cx-font-display); /* Sora — geometric display face */
  font-weight: 800;
  font-size: clamp(34px, 4.6vw, 54px); /* Sora runs wider than the old Bangers
                                          — sizes tuned to the 660px copy box */
  line-height: 1.08;
  letter-spacing: -0.015em;            /* geometric sans tighten at display sizes */
  color: var(--cx-text);
}
.cx-hero__title span {
  color: var(--cx-accent-deep); /* optional accent word(s) in the headline */
}
.cx-hero__lede {
  margin: 0 0 26px;
  font-size: 17px;
  line-height: 1.6;
  max-width: 56ch;
  color: var(--cx-text-muted);
}
.cx-hero__actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
@media (max-width: 720px) {
  .cx-hero {
    min-height: 0;
  }
  .cx-hero__media {
    width: 88%;
    height: 34%;
  }
  .cx-hero__lockup img {
    height: 42px;
  }
  .cx-hero__copy {
    align-self: stretch;
    max-width: none;
    padding-top: 64px;
  }
}

/* ----- Section: the scrolling-page rhythm ---------------------------------- */
/* <section class="cx-section"><div class="cx-container"> … </div></section>
   Add class="cx-reveal" to any block cx-hero.js should fade-and-rise into
   view on scroll (pure marker class — no styles, content is fully visible
   without JS).                                                                */
.cx-section {
  padding: 64px 0;
}
.cx-section__kicker {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cx-accent-deep);
}
.cx-section__title {
  margin: 0 0 12px;
  font-family: var(--cx-font-display); /* Sora — the only other display call site */
  font-weight: 700;
  font-size: clamp(26px, 3vw, 36px);
  line-height: 1.12;
  letter-spacing: -0.01em;
}
.cx-section__lede {
  margin: 0 0 30px;
  font-size: 16px;
  line-height: 1.65;
  max-width: 64ch;
  color: var(--cx-text-muted);
}

/* ----- Impact: the Bangers opt-in ------------------------------------------ */
/* Nothing uses Bangers by default any more (customer feedback: too comic for
   everyday headings). Add .cx-impact to a heading you WANT to shout —
   sparingly, one statement per page at most. The metrics below are the old
   Bangers tuning. */
.cx-impact {
  font-family: var(--cx-font-impact);
  font-weight: 400; /* Bangers ships one weight */
  letter-spacing: 0.015em;
  line-height: 1.02;
}

/* ----- Grid: responsive card rows ------------------------------------------ */
.cx-grid {
  display: grid;
  gap: 18px;
}
.cx-grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.cx-grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.cx-grid--4 {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

/* ----- Panel as a link: clickable CTA / product cards ---------------------- */
/* <a class="cx-panel cx-panel--link" href="…"> … </a>                         */
.cx-panel--link {
  display: block;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.12s;
}
.cx-panel--link:hover {
  border-color: var(--cx-border-strong);
  box-shadow: var(--cx-glow);
  transform: translateY(-2px);
}
.cx-panel--link:focus-visible {
  outline: 2px solid var(--cx-focus-ring);
  outline-offset: 2px;
}

/* ----- Band: full-bleed tinted strip between sections ---------------------- */
/* Navy variant pairs with the theme island: class="cx-band cx-band--navy
   cx-theme-dark" — everything inside gets dark-theme tokens automatically.    */
.cx-band {
  padding: 64px 0;
  border-top: 1px solid var(--cx-border);
  border-bottom: 1px solid var(--cx-border);
  background: var(--cx-surface-2);
}
.cx-band--navy {
  background: var(--cx-grad-header);
}

/* ----- Form: the enquiry form (fields, inputs, status line) ---------------- */
/* Two columns on desktop, one on mobile; add cx-field--wide to span both
   (message textarea, submit row, status line).                                */
.cx-form {
  display: grid;
  /* minmax(0, …): a plain 1fr track refuses to shrink below its content's
     intrinsic width (a select with a long option pushed the whole form off
     the right edge on phones). */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
}
@media (max-width: 720px) {
  .cx-form {
    grid-template-columns: minmax(0, 1fr);
  }
}
.cx-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0; /* same story at the grid-item level */
}
.cx-field--wide {
  grid-column: 1 / -1;
}
.cx-field__label {
  font-size: 13px;
  font-weight: 600;
  color: var(--cx-text-muted);
}
.cx-input {
  font-family: inherit;
  font-size: 14px;
  min-width: 0; /* let selects/inputs shrink to the field, not their content */
  color: var(--cx-text);
  background: var(--cx-surface);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-sm);
  padding: 11px 14px;
}
.cx-input:focus-visible {
  outline: 2px solid var(--cx-focus-ring);
  outline-offset: 1px;
  border-color: var(--cx-border-strong);
}
textarea.cx-input {
  min-height: 120px;
  resize: vertical;
}
.cx-form__status {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 14px;
  color: var(--cx-text-muted);
}
.cx-form__status.is-ok {
  color: var(--cx-good);
}
.cx-form__status.is-error {
  color: var(--cx-warn);
}

/* ----- Footer --------------------------------------------------------------- */
.cx-footer {
  margin-top: 48px;
  padding: 28px 0 36px;
  border-top: 1px solid var(--cx-border);
}
.cx-footer__inner {
  width: min(1080px, 92vw);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.cx-footer__fineprint {
  margin: 0;
  font-size: 13px;
  color: var(--cx-text-dim);
}
.cx-footer a {
  color: var(--cx-text-muted);
}
