/* Design tokens. Dark is the default theme; [data-theme="light"] overrides colours and shadows only.
   Every text/background pair used on the site is checked by site/test/contrast.test.mjs. */
:root {
  /* Backgrounds */
  --bg-primary: #0A0A0B;
  --bg-secondary: #111113;
  --bg-tertiary: #18181B;
  --bg-elevated: #1F1F23;
  --bg-hover: #27272A;

  /* Text */
  --text-primary: #FAFAFA;
  --text-secondary: #A1A1AA;
  --text-tertiary: #8A8A93;
  --text-muted: #7E7E87;

  /* Violet, the brand */
  --accent-primary: #8B5CF6;
  --accent-text: #A78BFA;
  --accent-solid: #7C3AED;
  --accent-secondary: #A78BFA;
  --accent-tertiary: #C4B5FD;
  --accent-muted: #6D28D9;
  --accent-pink: #EC4899;
  --accent-pink-light: #F472B6;
  --accent-blue: #3B82F6;
  --accent-blue-light: #60A5FA;

  /* Status */
  --success: #22C55E;
  --warning: #F59E0B;
  --error: #EF4444;
  --error-text: #F87171;

  /* Forms and dialogs */
  --field-bg: #18181B;
  --field-border: #6B6B75;
  --scrim: rgba(10, 10, 11, 0.6);

  /* Borders */
  --border-default: rgba(255, 255, 255, 0.08);
  --border-hover: rgba(255, 255, 255, 0.15);
  --border-active: rgba(255, 255, 255, 0.25);
  --border-accent: rgba(139, 92, 246, 0.5);

  /* The orbs (site/partials/orbs.mjs) */
  --orb-1: rgba(139, 92, 246, 0.7);
  --orb-2: rgba(236, 72, 153, 0.5);
  --orb-3: rgba(59, 130, 246, 0.4);
  --orb-4: rgba(139, 92, 246, 0.35);
  --orb-5: rgba(17, 17, 19, 0.8);
  --orb-blend: hard-light;
  --orb-bg-1: #0D0A1A;
  --orb-bg-2: #1A1033;
  --dot-color: rgba(255, 255, 255, 0.03);

  /* Depth: five shadows, the glow only under the primary button */
  --glow-accent: rgba(139, 92, 246, 0.4);
  --glow-pink: rgba(236, 72, 153, 0.4);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -2px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.5);
  --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.5);
  --shadow-glow: 0 8px 32px -8px var(--glow-accent);

  --gradient-primary: linear-gradient(90deg, var(--accent-primary) 0%, var(--accent-pink) 100%);

  /* Type: Inter, then its metric-matched fallbacks so the swap doesn't reflow text */
  --font-sans: 'Inter', "Inter Fallback: Segoe UI", "Inter Fallback: Arial", "Inter Fallback: BlinkMacSystemFont", "Inter Fallback: Helvetica Neue", "Inter Fallback: Noto Sans", system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, 'SF Mono', Consolas, monospace;

  /* Scale (px): 14, 16, 18, 20, 24, 30, 36, 48, 56 */
  --text-xs: 0.875rem;
  --text-sm: clamp(0.875rem, 0.85rem + 0.125vw, 0.9375rem);
  --text-base: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  --text-lg: clamp(1.125rem, 1.05rem + 0.375vw, 1.25rem);
  --text-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem);
  --text-2xl: clamp(1.5rem, 1.3rem + 1vw, 1.875rem);
  --text-3xl: clamp(1.875rem, 1.6rem + 1.25vw, 2.25rem);
  --text-4xl: clamp(2.25rem, 1.8rem + 2vw, 3rem);
  --text-5xl: clamp(2.25rem, 1.5rem + 3vw, 3.5rem);

  --leading-none: 1;
  --leading-tight: 1.15;
  --leading-snug: 1.3;
  --leading-normal: 1.5;
  --leading-relaxed: 1.6;

  --tracking-tighter: -0.04em;
  --tracking-tight: -0.02em;
  --tracking-wide: 0.02em;

  /* Spacing (px): 4, 8, 12, 16, 24, 32, 48, 64, 96, 128 */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;
  --space-32: 8rem;

  /* Radii: fields and small buttons 8, buttons and pills 12, cards 16, hero and section panels 24 */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-2xl: 1.5rem;
  --radius-full: 9999px;

  --duration-fast: 150ms;
  --duration-normal: 250ms;
  --duration-slow: 400ms;
  --ease-default: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out: cubic-bezier(0, 0, 0.2, 1);

  --z-dropdown: 100;
  --z-sticky: 200;
  --z-modal: 500;

  --nav-height: 72px;
  --gutter: var(--space-6);
}

[data-theme="light"] {
  --bg-primary: #FAFAFA;
  --bg-secondary: #F5F5F7;
  --bg-tertiary: #EBEBEF;
  --bg-elevated: #FFFFFF;
  --bg-hover: #E8E8EC;

  --text-primary: #1A1A1A;
  --text-secondary: #4A4A4A;
  --text-tertiary: #5E5E5E;
  --text-muted: #6E6E6E;

  --accent-primary: #7C3AED;
  --accent-text: #7C3AED;
  --accent-solid: #7C3AED;
  --accent-secondary: #6D28D9;
  --accent-tertiary: #8B5CF6;
  --accent-muted: #A78BFA;
  --accent-pink: #DB2777;
  --accent-pink-light: #BE185D;
  --accent-blue: #2563EB;
  --accent-blue-light: #1D4ED8;

  --error-text: #B91C1C;

  --field-bg: #FFFFFF;
  --field-border: #8A8A95;
  --scrim: rgba(26, 26, 26, 0.35);

  --border-default: rgba(0, 0, 0, 0.1);
  --border-hover: rgba(0, 0, 0, 0.18);
  --border-active: rgba(0, 0, 0, 0.28);
  --border-accent: rgba(124, 58, 237, 0.4);

  /* Light orbs on a light page, so the text over them stays dark (audit H1) */
  --orb-1: rgba(139, 92, 246, 0.4);
  --orb-2: rgba(236, 72, 153, 0.35);
  --orb-3: rgba(59, 130, 246, 0.35);
  --orb-4: rgba(139, 92, 246, 0.45);
  --orb-5: rgba(255, 255, 255, 0.4);
  --orb-blend: multiply;
  --orb-bg-1: #FAF9FE;
  --orb-bg-2: #F3F0FB;
  --dot-color: rgba(0, 0, 0, 0.04);

  --glow-accent: rgba(124, 58, 237, 0.3);
  --glow-pink: rgba(219, 39, 119, 0.25);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 1px rgba(0, 0, 0, 0.03);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
  --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.03);
}

@media (max-width: 640px) {
  :root { --gutter: var(--space-4); }
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: block;
  src: url(/fonts/inter/inter-latin-ext-300-800.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;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: block;
  src: url(/fonts/inter/inter-latin-300-800.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:"Inter Fallback: BlinkMacSystemFont";src:local("BlinkMacSystemFont");size-adjust:114.6542%;ascent-override:84.4932%;descent-override:21.0381%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback: Segoe UI";src:local("Segoe UI");size-adjust:107.7093%;ascent-override:89.9412%;descent-override:22.3946%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback: Helvetica Neue";src:local("Helvetica Neue");size-adjust:106.1198%;ascent-override:91.2883%;descent-override:22.7301%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback: Arial";src:local("Arial");size-adjust:107.1194%;ascent-override:90.4365%;descent-override:22.518%;line-gap-override:0%}
@font-face{font-family:"Inter Fallback: Noto Sans";src:local("Noto Sans");size-adjust:100.7466%;ascent-override:96.1571%;descent-override:23.9423%;line-gap-override:0%}

/* Reset, typography and accessibility basics. */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html {
  color-scheme: dark light;
  background-color: var(--bg-primary);
  scrollbar-width: thin;
  scrollbar-color: var(--bg-hover) var(--bg-secondary);
  /* the scrollbar's room is always kept, so the page doesn't move sideways when a dialog or the menu stops it
     scrolling */
  scrollbar-gutter: stable;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
[data-theme="dark"] { color-scheme: dark; }
[data-theme="light"] { color-scheme: light; }
body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--text-primary);
  background-color: var(--bg-primary);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overscroll-behavior: none;
}
img, picture, video, canvas, svg { display: block; max-width: 100%; }
img, video { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }
table { border-collapse: collapse; }

h1, h2, h3, h4, h5, h6 {
  font-weight: 700;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--text-primary);
  text-wrap: balance;
  overflow-wrap: break-word;
}
h1 { font-size: var(--text-5xl); letter-spacing: var(--tracking-tighter); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-xl); }
p { max-width: 65ch; text-wrap: pretty; }
/* Short text that isn't a paragraph never ends on a lone word either */
li, dd, figcaption, button { text-wrap: pretty; }
strong, b { font-weight: 600; }

a {
  color: var(--accent-text);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-default);
}
a:hover { color: var(--accent-secondary); }

:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}
::selection { background-color: var(--accent-primary); color: #FFFFFF; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--bg-secondary); }
::-webkit-scrollbar-thumb { background: var(--bg-hover); border-radius: var(--radius-full); }

/* White logos turn dark on the light theme */
[data-theme="light"] .logo-white { filter: brightness(0) saturate(100%); }

.visually-hidden:not(:focus):not(:active) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: var(--space-4);
  left: 50%;
  z-index: 9999;
  padding: var(--space-3) var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--accent-solid);
  color: #FFFFFF;
  font-weight: 600;
  transform: translate(-50%, -200%);
}
.skip-link:focus { transform: translate(-50%, 0); color: #FFFFFF; }

/* Text appears already in Inter: the faces use font-display: block (css/fonts/*.css) and Inter is preloaded, so the
   page never flashes the fallback face. (The Nuxt site hid the whole page until the fonts were ready; that also hid
   it from Chrome's LCP, which then reported nothing.) */
.app-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media print {
  body { background: #FFFFFF !important; color: #000000 !important; }
  a { text-decoration: underline; }
}

/* Anything scrolled to (a #link, a field that takes focus) lands below the fixed header, not under it. */
[id], input:not([type="radio"]):not([type="checkbox"]), textarea { scroll-margin-top: calc(var(--nav-height) + var(--space-4)); }

/* Page structure. */
.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container-narrow { max-width: 760px; }

/* A section's vertical rhythm: more space above a heading than below it. */
.section { padding-block: var(--space-24); }
.section-head { margin-bottom: var(--space-12); }
.section-head p { margin-top: var(--space-4); color: var(--text-secondary); font-size: var(--text-lg); }
.section-head.centered { text-align: center; }
.section-head.centered p { margin-inline: auto; }
@media (max-width: 768px) {
  .section { padding-block: var(--space-16); }
  .section-head { margin-bottom: var(--space-8); }
}

main { flex: 1; }
main:focus { outline: none; }

/* Buttons: primary is solid violet with the one glow on the site, secondary is outlined, tertiary reads as a link.
   Every button is at least 44 px tall. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default),
    color var(--duration-fast) var(--ease-default), box-shadow var(--duration-normal) var(--ease-default), transform var(--duration-fast) var(--ease-default);
}
.btn svg { width: 1.125em; height: 1.125em; flex: none; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.btn-lg { min-height: 52px; padding: var(--space-4) var(--space-8); font-size: var(--text-base); }

.btn-primary { background: var(--accent-solid); color: #FFFFFF; box-shadow: var(--shadow-glow); }
.btn-primary:hover:not(:disabled) { background: var(--accent-muted); color: #FFFFFF; transform: translateY(-1px); }
.btn-primary:active:not(:disabled) { transform: none; box-shadow: var(--shadow-sm); }
[data-theme="light"] .btn-primary:hover:not(:disabled) { background: var(--accent-secondary); }

.btn-secondary { background: transparent; color: var(--text-primary); border-color: var(--border-active); }
.btn-secondary:hover:not(:disabled) { background: var(--bg-hover); border-color: var(--text-muted); color: var(--text-primary); }

.btn-link {
  min-height: 44px;
  padding-inline: 0;
  background: none;
  color: var(--accent-text);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.25em;
}
.btn-link:hover { color: var(--accent-secondary); text-decoration-color: currentColor; }

@media (forced-colors: active) {
  .btn-primary { border: 2px solid ButtonText; }
}

/* Product cards: whole-card links. The heading's link stretches over the card (audit M6), so the card is one tab
   stop with a real link text. */
.wcard { position: relative; }
.wcard-name a::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }
.wcard-name a { display: inline-block; min-width: 44px; padding-block: 9px; margin-block: -9px; color: inherit; }

/* Project cards (projects page) share these */
.card-title { margin-bottom: var(--space-2); font-size: var(--text-lg); font-weight: 600; letter-spacing: var(--tracking-tight); }
.card-description { flex: 1; color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-relaxed); }

/* Product cards: a 16:9 scene per product, then status, name, tagline */
.wcard {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  transition: border-color 200ms ease, transform 200ms ease;
}
.wcard:hover { border-color: var(--accent-primary); transform: translateY(-2px); }
.wcard-art { aspect-ratio: 16 / 9; overflow: hidden; border-bottom: 1px solid var(--border-default); background: var(--art-bg); }
.wcard-art svg { display: block; width: 100%; height: 100%; }
.wc-icon { transform-box: fill-box; transform-origin: center; transition: translate 320ms cubic-bezier(.2, .8, .2, 1); }
.wcard:hover .wc-icon, .wcard:has(a:focus-visible) .wc-icon { translate: 0 -4px; }
.wcard-body { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); padding: var(--space-6); }
.wcard-name { font-size: var(--text-2xl); font-weight: 700; letter-spacing: var(--tracking-tight); }
.wcard-tagline { color: var(--text-secondary); }
.wcard-meta { color: var(--text-secondary); font-size: var(--text-sm); }

[data-world="clockdoc"] { --art-bg: radial-gradient(120% 120% at 50% 40%, #221D52, #14122E 62%); }
[data-world="clockdoc"] .cd-bezel { fill: none; stroke: #A7ACC0; stroke-width: 1.5; opacity: .85; }
[data-world="clockdoc"] .cd-tick { stroke: #5D6178; stroke-width: 1; }
[data-world="clockdoc"] .cd-tick--hour { stroke: #EFECFF; stroke-width: 2.4; }
[data-world="clockdoc"] .cd-pip { fill: #E5484D; }
[data-world="eva"] { --art-bg: #181818; }
[data-world="eva"] .ev-ripple { fill: none; stroke: #DC2626; stroke-width: 1.5; opacity: 0; transform-box: fill-box; transform-origin: center; }
[data-world="doberplan"] { --art-bg: #FCFDFD; }
[data-world="doberplan"] .dp-rule { stroke: #C4D6EE; stroke-width: 1; }
[data-world="doberplan"] .dp-margin { stroke: #E5727C; stroke-width: 1.5; }
[data-world="doberplan"] .dp-hi { fill: #FFF27A; opacity: .85; }
[data-world="doberplan"] .dp-ink { fill: none; stroke: #1D3A8F; stroke-width: 2; stroke-linecap: round; }
[data-world="doberplan"] .dp-stamp { fill: none; stroke: #23804E; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
[data-world="doberplan"] .dp-shadow { fill: rgba(15, 25, 50, .32); }
[data-world="doberplan"] .dp-tape { fill: rgba(122, 178, 214, .6); }
[data-theme="dark"] [data-world="doberplan"] { --art-bg: #161E31; }
[data-theme="dark"] [data-world="doberplan"] .dp-rule { stroke: #27355A; }
[data-theme="dark"] [data-world="doberplan"] .dp-margin { stroke: #8F3E4C; }
[data-theme="dark"] [data-world="doberplan"] .dp-hi { fill: rgba(240, 222, 80, .38); }
[data-theme="dark"] [data-world="doberplan"] .dp-ink { stroke: #B9CBFF; }
[data-theme="dark"] [data-world="doberplan"] .dp-stamp { stroke: #6FD19A; }
[data-theme="dark"] [data-world="doberplan"] .dp-shadow { fill: rgba(0, 0, 0, .55); }
[data-theme="dark"] [data-world="doberplan"] .dp-tape { fill: rgba(122, 178, 214, .38); }
[data-world="publeague"] { --art-bg: #2A1D14; }
[data-world="publeague"] .pl-board { fill: #1F2C27; stroke: #6B4427; stroke-width: 7; }
[data-world="publeague"] .pl-ring { fill: none; stroke: #EEF0EA; stroke-width: 2.2; stroke-linecap: round; stroke-dasharray: 210 7 70 5 30 400; opacity: .85; }
[data-world="publeague"] .pl-chalk { fill: #EEF0EA; opacity: .85; }
[data-world="publeague"] .pl-chalk path { fill: none; stroke: #EEF0EA; stroke-width: 2.4; stroke-linecap: round; }
@media (prefers-reduced-motion: no-preference) {
  [data-world="eva"] .ev-ripple { animation: ev-ripple 2.6s ease-out infinite; }
  .cd-orbit { transform-origin: 160px 90px; animation: orbit 60s linear infinite; }
}
@keyframes ev-ripple { from { transform: scale(.9); opacity: .7; } to { transform: scale(1.9); opacity: 0; } }
@keyframes orbit { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .wcard, .wcard:hover, .wc-icon { transition: none; transform: none; translate: none; }
}

/* The closing call to action (site/partials/cta.mjs). */
.cta-band { padding-block: var(--space-16) var(--space-24); }
.cta-panel {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding: var(--space-16) var(--space-8);
  overflow: hidden;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  text-align: center;
  view-timeline: --cta-panel block;
}
.cta-panel h2 { max-width: 24ch; }
.cta-panel p { max-width: 50ch; color: var(--text-secondary); font-size: var(--text-lg); }
.cta-panel .btn { margin-top: var(--space-4); }
@media (max-width: 640px) {
  .cta-band { padding-block: var(--space-12) var(--space-16); }
  .cta-panel { padding: var(--space-12) var(--space-6); }
}

/* The conversation in the corners: the visitor's message top left, our reply bottom right, typing. Wide panels
   only, so the bubbles never come near the text. */
.cta-bubble { position: absolute; display: none; width: 116px; fill: none; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.cta-bubble--in { top: var(--space-10); left: var(--space-10); rotate: -6deg; stroke: var(--text-muted); stroke-width: 2; }
.cta-bubble--out { right: var(--space-10); bottom: var(--space-10); rotate: 5deg; stroke: var(--accent-primary); stroke-width: 2; }
.cta-bubble--out > path { fill: color-mix(in srgb, var(--accent-primary) 12%, transparent); }
.cta-dots circle { fill: var(--accent-text); stroke: none; transform-box: fill-box; transform-origin: center; }
@media (min-width: 1000px) {
  .cta-bubble { display: block; }
}

/* The button: on hover or focus the arrow slides away and three dots type in its place */
.cta-talk .talk-icon { position: relative; display: inline-block; width: 1.125em; height: 1.125em; }
.cta-talk .talk-icon > svg { position: absolute; inset: 0; transition: transform var(--duration-normal) var(--ease-default), opacity var(--duration-fast) var(--ease-default); }
.cta-talk .talk-dots { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 2px; opacity: 0; transition: opacity var(--duration-fast) var(--ease-default); }
.cta-talk .talk-dots i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
.cta-talk:is(:hover, :focus-visible) .talk-icon > svg { opacity: 0; transform: translateX(10px); }
.cta-talk:is(:hover, :focus-visible) .talk-dots { opacity: 1; transition-delay: 80ms; }

@media (prefers-reduced-motion: no-preference) {
  .cta-talk:is(:hover, :focus-visible) .talk-dots i { animation: talk-dot 1s ease-in-out infinite; }
  .cta-talk .talk-dots i:nth-child(2), .cta-dots circle:nth-child(2) { animation-delay: 0.16s; }
  .cta-talk .talk-dots i:nth-child(3), .cta-dots circle:nth-child(3) { animation-delay: 0.32s; }
  .cta-dots circle { animation: cta-dot 1.4s ease-in-out infinite; }
}
/* Where the browser can tie animation to scrolling, the message draws itself as the panel comes into view, then
   the reply. Elsewhere both are simply there. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .cta-bubble path { stroke-dasharray: 1; animation: cta-draw linear both; animation-timeline: --cta-panel; animation-range: entry 15% cover 40%; }
    .cta-bubble--out path { animation-range: cover 30% cover 50%; }
    .cta-bubble--out > path { animation-name: cta-draw, cta-fill; }
    .cta-dots { animation: cta-show linear both; animation-timeline: --cta-panel; animation-range: cover 45% cover 52%; }
  }
}
/* the stroke fades in at the start, so the round caps of a not-yet-drawn line never show as stray dots */
@keyframes cta-draw { from { stroke-dashoffset: 1; opacity: 0; } 10% { opacity: 1; } to { stroke-dashoffset: 0; } }
@keyframes cta-fill { 0%, 60% { fill: transparent; } }
@keyframes cta-show { from { opacity: 0; } }
@keyframes cta-dot { 0%, 60%, 100% { opacity: 0.35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-4px); } }
@keyframes talk-dot { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-3px); } }

/* Site footer. */
.site-footer {
  margin-top: auto;
  border-top: 1px solid var(--border-default);
  background: var(--bg-secondary);
}
.site-footer ul { list-style: none; padding: 0; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(4, 1fr);
  gap: var(--space-8);
  padding-block: var(--space-16) var(--space-12);
}
.footer-brand p { max-width: 32ch; margin-top: var(--space-3); color: var(--text-secondary); font-size: var(--text-sm); }
.social-links { display: flex; gap: var(--space-2); margin-top: var(--space-6); }
.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
}
.social-link:hover { border-color: var(--border-hover); background: var(--bg-hover); color: var(--text-primary); }

.footer-heading { margin-bottom: var(--space-1); color: var(--text-primary); font-size: var(--text-sm); font-weight: 600; letter-spacing: 0; }
.footer-link, .footer-text {
  display: inline-flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.35;
  text-wrap: balance;
}
.footer-link:hover { color: var(--text-primary); }
.footer-text { color: var(--text-tertiary); }

.footer-bottom { padding-block: var(--space-6); border-top: 1px solid var(--border-default); }
.footer-bottom p { color: var(--text-tertiary); font-size: var(--text-sm); }

@media (max-width: 1023.98px) {
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 640px) {
  .footer-grid { gap: var(--space-6) var(--space-4); padding-block: var(--space-12) var(--space-8); }
}

/* Form fields: labels above, fields that stand off the card (audit M10), one error style (audit H3), radio pills
   instead of native dropdowns (audit H2). */
.field { display: grid; gap: var(--space-2); min-width: 0; margin: 0; padding: 0; border: 0; }
.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; gap: var(--space-4); }
/* three short fields side by side (name, e-mail, company), the e-mail a little wider; one under another on phones */
.field-row--3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr) minmax(0, 1fr); }
.field label, .field legend { padding: 0; color: var(--text-primary); font-size: var(--text-sm); font-weight: 600; }
.field .optional { color: var(--text-tertiary); font-weight: 400; }
.field input:not([type="radio"]):not([type="checkbox"]), .field textarea {
  width: 100%;
  min-height: 48px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-md);
  background: var(--field-bg);
  color: var(--text-primary);
  font-size: var(--text-base);
  transition: border-color var(--duration-fast) var(--ease-default), box-shadow var(--duration-fast) var(--ease-default);
}
.field textarea { min-height: 150px; resize: vertical; line-height: var(--leading-normal); }
.field input::placeholder, .field textarea::placeholder { color: var(--text-muted); }
.field input:hover:not(:focus), .field textarea:hover:not(:focus) { border-color: var(--text-tertiary); }
.field input:focus-visible, .field textarea:focus-visible { border-color: var(--accent-primary); outline: none; box-shadow: 0 0 0 3px var(--glow-accent); }
.field input:-webkit-autofill { -webkit-text-fill-color: var(--text-primary); box-shadow: 0 0 0 100px var(--field-bg) inset; }
.field [aria-invalid="true"] { border-color: var(--error-text) !important; }
.field-error { min-height: 0; color: var(--error-text); font-size: var(--text-sm); }
.field-error:empty { display: none; }

/* Radio pills */
.pills-field { gap: var(--space-3); }
.pills-field[aria-invalid="true"] .pill span { border-color: var(--error-text); }
.pill-group { display: grid; gap: var(--space-2); }
.pill-group-label { color: var(--text-tertiary); font-size: var(--text-xs); }
.pills { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pill { position: relative; display: inline-flex; }
.pill input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.pill span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-full);
  background: var(--field-bg);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 500;
  transition: border-color var(--duration-fast) var(--ease-default), background-color var(--duration-fast) var(--ease-default), color var(--duration-fast) var(--ease-default);
}
.pill:hover span { border-color: var(--text-tertiary); color: var(--text-primary); }
.pill input:checked + span { border-color: var(--accent-solid); background: var(--accent-solid); color: #FFFFFF; }
.pill input:focus-visible + span { outline: 2px solid var(--accent-primary); outline-offset: 2px; }

@media (max-width: 560px) {
  .field-row { grid-template-columns: 1fr; }
}

/* Site header. Desktop from 1024 px: logo, links, language, theme, contact. Below: logo, contact, menu button and a
   modal sheet. Without JS (no .js on <html>) the links wrap onto a second row and the menu button stays hidden. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: var(--z-sticky);
  padding: var(--space-3);
  transition: transform var(--duration-normal) var(--ease-default), opacity var(--duration-normal) var(--ease-default);
}
.site-header.is-hidden { transform: translateY(-110%); opacity: 0; pointer-events: none; }
.site-header:focus-within { transform: none; opacity: 1; pointer-events: auto; }

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 1200px;
  margin-inline: auto;
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  background: color-mix(in srgb, var(--bg-secondary) 88%, transparent);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
}
.site-nav ul { list-style: none; padding: 0; }

.nav-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  margin-right: auto;
  color: var(--text-primary);
  font-size: var(--text-xl);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
}
.nav-logo:hover { color: var(--text-primary); }
.nav-logo img { width: 32px; height: 32px; }

.nav-links { display: flex; align-items: center; gap: var(--space-1); }
.nav-link, .menu-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-lg);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-default), background-color var(--duration-fast) var(--ease-default);
}
.nav-link:hover, .menu-toggle:hover, .menu-toggle[aria-expanded="true"] { color: var(--text-primary); background: var(--bg-hover); }
.nav-link[aria-current="page"] { color: var(--text-primary); background: var(--bg-tertiary); }
.menu-toggle svg { opacity: 0.6; transition: transform var(--duration-fast) var(--ease-default); }
.menu-toggle[aria-expanded="true"] svg { transform: rotate(180deg); opacity: 1; }
.js .nojs-only, html:not(.js) .menu-toggle, html:not(.js) .theme-toggle, html:not(.js) .nav-toggle { display: none; }

/* Services and Products panels: opaque, so the hero never reads through them (audit L1) */
.nav-menu { position: relative; }
.menu-panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 50%;
  z-index: var(--z-dropdown);
  width: 380px;
  padding: var(--space-2);
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-xl);
  background: var(--bg-elevated);
  box-shadow: var(--shadow-xl);
  transform: translateX(-50%);
  animation: panel-in 160ms var(--ease-out);
}
@keyframes panel-in { from { opacity: 0; transform: translateX(-50%) translateY(-4px); } }
.menu-panel ul { display: grid; gap: 2px; }

.menu-item {
  --item-accent: var(--accent-primary);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
}
.menu-item:hover, .menu-item:focus-visible { background: color-mix(in srgb, var(--item-accent) 12%, transparent); color: var(--text-primary); }
.menu-item[aria-current="page"] { background: var(--bg-tertiary); }
.menu-item-text { display: grid; flex: 1; min-width: 0; }
.menu-item-name { font-size: var(--text-sm); font-weight: 600; }
.menu-item-desc { color: var(--text-secondary); font-size: var(--text-xs); line-height: 1.4; }

.plogo { display: block; flex: none; width: var(--plogo-size, 40px); height: var(--plogo-size, 40px); }
.plogo img { width: 100%; height: 100%; object-fit: contain; }
.plogo--square img { border-radius: 22.5%; }

.status-badge {
  flex: none;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.5;
}
.status-badge.live { background: rgba(16, 185, 129, 0.15); color: #34D399; }
.status-badge.beta { background: rgba(139, 92, 246, 0.18); color: #C4B5FD; }
.status-badge.testing { background: rgba(245, 158, 11, 0.15); color: #FBBF24; }
.status-badge.development { background: rgba(148, 163, 184, 0.16); color: #CBD5E1; }
[data-theme="light"] .status-badge.live { background: #D1FAE5; color: #065F46; }
[data-theme="light"] .status-badge.beta { background: #EDE9FE; color: #5B21B6; }
[data-theme="light"] .status-badge.testing { background: #FEF3C7; color: #92400E; }
[data-theme="light"] .status-badge.development { background: #E2E8F0; color: #334155; }

.menu-all {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  margin-top: var(--space-1);
  border-top: 1px solid var(--border-default);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  font-size: var(--text-sm);
  font-weight: 600;
}
.menu-all:hover { background: var(--bg-hover); }

/* Actions: language, theme, contact, menu */
.nav-actions { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
.lang-switch { display: inline-flex; padding: 0; border-radius: var(--radius-lg); background: var(--bg-tertiary); }
.lang-switch a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: var(--radius-lg);
  color: var(--text-secondary);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
}
.lang-switch a:hover { color: var(--text-primary); }
.lang-switch a[aria-current="true"] { color: var(--text-primary); background: var(--bg-hover); box-shadow: inset 0 0 0 1px var(--border-active); }

.theme-toggle, .nav-toggle, .nav-sheet-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-lg);
  color: var(--text-secondary);
  transition: color var(--duration-fast) var(--ease-default), background-color var(--duration-fast) var(--ease-default);
}
.theme-toggle:hover, .nav-toggle:hover, .nav-sheet-close:hover { color: var(--text-primary); background: var(--bg-hover); }
.nav-toggle { color: var(--text-primary); background: var(--bg-tertiary); }
[data-theme="dark"] .theme-icon-moon, [data-theme="light"] .theme-icon-sun { display: none; }
.theme-toggle span { display: contents; }

.nav-toggle { display: none; }

@media (max-width: 1023.98px) {
  .js .nav-links, .js .nav-actions > .lang-switch, .js .nav-actions > .theme-toggle { display: none; }
  .js .nav-toggle { display: inline-flex; }
  /* Without JS the links take a second row */
  html:not(.js) { --nav-height: 128px; }
  html:not(.js) .site-nav { flex-wrap: wrap; }
  html:not(.js) .nav-links { order: 3; flex-wrap: wrap; justify-content: center; width: 100%; }
}
@media (max-width: 639.98px) {
  .nav-actions > .nav-cta { display: none; }
}

/* Mobile sheet */
.nav-sheet {
  width: calc(100% - var(--space-4));
  max-width: 480px;
  max-height: calc(100dvh - 4.5rem);
  margin: var(--space-2) auto auto;
  padding: 0;
  overflow-y: auto;
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-xl);
  background: var(--bg-elevated);
  color: var(--text-primary);
  box-shadow: var(--shadow-xl);
  overscroll-behavior: contain;
}
.nav-sheet::backdrop { background: var(--scrim, rgba(10, 10, 11, 0.6)); }
/* Opens and closes smoothly: it fades and settles into place, and back out. While it fades out it stays in the top
   layer (overlay and display, allow-discrete); a browser without that closes it at once. */
@media (prefers-reduced-motion: no-preference) {
  .nav-sheet { transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), overlay 200ms allow-discrete, display 200ms allow-discrete; }
  .nav-sheet::backdrop { transition: opacity 200ms var(--ease-out), overlay 200ms allow-discrete, display 200ms allow-discrete; }
  .nav-sheet:not([open]) { opacity: 0; transform: translateY(-8px); }
  .nav-sheet:not([open])::backdrop { opacity: 0; }
  @starting-style {
    .nav-sheet[open] { opacity: 0; transform: translateY(-8px); }
    .nav-sheet[open]::backdrop { opacity: 0; }
  }
}
html:has(.nav-sheet[open]) { overflow: hidden; }
.nav-sheet ul { list-style: none; padding: 0; }
.nav-sheet-body { padding: var(--space-2) var(--space-3) var(--space-4); }
.nav-sheet-top { display: flex; align-items: center; justify-content: space-between; padding-left: var(--space-2); }
.sheet-links { display: grid; gap: 2px; padding-block: var(--space-2); }
.sheet-link {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  font-size: var(--text-lg);
  font-weight: 600;
}
.sheet-link:hover { background: var(--bg-hover); color: var(--text-primary); }
.sheet-link[aria-current="page"] { background: var(--bg-tertiary); }
.sheet-group { display: grid; gap: 2px; padding-block: var(--space-2); border-top: 1px solid var(--border-default); }
.sheet-prefs { padding-block: var(--space-2); border-top: 1px solid var(--border-default); }
.sheet-pref { display: flex; align-items: center; justify-content: space-between; min-height: 48px; padding-inline: var(--space-3); color: var(--text-secondary); font-size: var(--text-sm); }
/* The main button stays in view at the foot of the sheet on short screens, with the sheet's colour around it so
   what scrolls under it doesn't show at its edges. */
.sheet-cta { position: sticky; bottom: var(--space-3); width: 100%; margin-top: var(--space-2); box-shadow: 0 0 0 var(--space-3) var(--bg-elevated); }

/* The gooey orbs (site/partials/orbs.mjs). The stage fades into the page at the bottom (audit M1). */
.gradient-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: linear-gradient(135deg, var(--orb-bg-1), var(--orb-bg-2));
  -webkit-mask-image: linear-gradient(to bottom, #000 65%, transparent);
  mask-image: linear-gradient(to bottom, #000 65%, transparent);
  pointer-events: none;
}
.gradient-bg .filter-defs { position: absolute; width: 0; height: 0; }
.gradients-container { width: 100%; height: 100%; filter: url(#goo) blur(40px); }
@media (max-width: 768px) {
  .gradients-container { filter: blur(40px); }
}
.dot-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: radial-gradient(circle, var(--dot-color) 1px, transparent 1px);
  background-size: 32px 32px;
}
.gradients-container > div {
  position: absolute;
  width: 80%;
  height: 80%;
  top: 10%;
  left: 10%;
  mix-blend-mode: var(--orb-blend);
  transform-origin: center center;
}
.gradients-container > .g1 { background: radial-gradient(circle at center, var(--orb-1) 0, transparent 50%) no-repeat; animation: orb-vertical 30s ease infinite; }
.gradients-container > .g2 { background: radial-gradient(circle at center, var(--orb-2) 0, transparent 50%) no-repeat; transform-origin: calc(50% - 400px); animation: orb-circle 20s reverse infinite; }
.gradients-container > .g3 {
  background: radial-gradient(circle at center, var(--orb-3) 0, transparent 50%) no-repeat;
  top: calc(10% + 200px);
  left: calc(10% - 500px);
  transform-origin: calc(50% + 400px);
  animation: orb-circle 40s linear infinite;
}
.gradients-container > .g4 { background: radial-gradient(circle at center, var(--orb-4) 0, transparent 50%) no-repeat; transform-origin: calc(50% - 200px); animation: orb-horizontal 40s ease infinite; opacity: 0.7; }
.gradients-container > .g5 {
  background: radial-gradient(circle at center, var(--orb-5) 0, transparent 50%) no-repeat;
  width: 160%;
  height: 160%;
  top: -30%;
  left: -30%;
  transform-origin: calc(50% - 800px) calc(50% + 200px);
  animation: orb-circle 20s ease infinite;
}
@keyframes orb-circle { 0% { transform: rotate(0deg); } 50% { transform: rotate(180deg); } 100% { transform: rotate(360deg); } }
@keyframes orb-vertical { 0% { transform: translateY(-50%); } 50% { transform: translateY(50%); } 100% { transform: translateY(-50%); } }
@keyframes orb-horizontal { 0% { transform: translateX(-50%) translateY(-10%); } 50% { transform: translateX(50%) translateY(10%); } 100% { transform: translateX(-50%) translateY(-10%); } }
@media (prefers-reduced-motion: reduce) {
  .gradients-container > div { animation: none; }
}

/* The orb stage at the top of inner pages (site/partials/page-hero.mjs), and gradient text. */
.page-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44vh;
  padding: calc(var(--nav-height) + var(--space-16)) var(--gutter) var(--space-16);
  overflow: hidden;
  isolation: isolate;
  text-align: center;
}
.page-hero-content { position: relative; z-index: 1; display: grid; justify-items: center; gap: var(--space-4); max-width: 780px; }
.page-hero-content::before {
  content: '';
  position: absolute;
  inset: -20% -20%;
  z-index: -1;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--bg-primary) 62%, transparent), transparent);
}
.page-hero .lede { max-width: 52ch; color: var(--text-secondary); font-size: var(--text-lg); }
@media (prefers-reduced-motion: no-preference) {
  .page-hero-content > * { animation: hero-rise 600ms var(--ease-out) both; }
  .page-hero-content > :nth-child(2) { animation-delay: 80ms; }
  .page-hero-content > :nth-child(3) { animation-delay: 160ms; }
}
/* The heading only moves, it doesn't fade: text that first paints at opacity 0 can't be Chrome's LCP. */
@media (prefers-reduced-motion: no-preference) {
  .page-hero-content > h1 { animation-name: hero-settle; }
}
@keyframes hero-rise { from { opacity: 0; transform: translateY(12px); } }
@keyframes hero-settle { from { transform: translateY(12px); } }
@media (max-width: 640px) {
  .page-hero { min-height: auto; padding: calc(var(--nav-height) + var(--space-12)) var(--gutter) var(--space-12); }
}
/* A band: the page's own content starts on the first screen */
.page-hero--compact { min-height: 0; padding: calc(var(--nav-height) + var(--space-16)) var(--gutter) var(--space-10); }
@media (max-width: 640px) {
  .page-hero--compact { padding: calc(var(--nav-height) + var(--space-10)) var(--gutter) var(--space-8); }
}

.text-gradient {
  background: var(--gradient-primary);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent-text);
}
