/* ═══════════════════════════════════════════════════════════════════════════
   TECH-X — CORE
   Design tokens, reset, typography, primitives.
   Palette: "Obsidian & Iris" — deep ink canvas, iris brand, aurum for premium
   moments (contracts, VIP, seals). Every colour is a token; components never
   carry raw hex.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────── 1. TOKENS ─── */

:root {
  /* ── Brand — Iris ───────────────────────────────────────────────────── */
  --iris-50:  #F2F1FF;
  --iris-100: #E4E1FF;
  --iris-200: #C9C4FF;
  --iris-300: #A9A1FF;
  --iris-400: #8B84FF;
  --iris-500: #6C63FF;   /* the Tech-X mark */
  --iris-600: #5A4FE8;
  --iris-700: #4739C4;
  --iris-800: #362B99;
  --iris-900: #251E6B;

  /* ── Premium accent — Aurum. Used sparingly: seals, VIP, signatures ─── */
  --aurum-200: #F6E3BE;
  --aurum-300: #EFD29A;
  --aurum-400: #E4BC76;
  --aurum-500: #D4A857;
  --aurum-600: #B78B3D;

  /* ── Service signatures (the active dots) ───────────────────────────── */
  --sig-web:    #7C6CFF;
  --sig-mobile: #00D4AA;
  --sig-ai:     #FF6A5C;
  --sig-design: #F4C430;
  --sig-uiux:   #3FD0C9;

  /* ── Status ─────────────────────────────────────────────────────────── */
  --ok-500:   #16C784;
  --ok-bg:    rgba(22, 199, 132, .12);
  --warn-500: #F5A524;
  --warn-bg:  rgba(245, 165, 36, .12);
  --err-500:  #F4525E;
  --err-bg:   rgba(244, 82, 94, .12);
  --info-500: #3B9EFF;
  --info-bg:  rgba(59, 158, 255, .12);

  /* ── Type ───────────────────────────────────────────────────────────── */
  --font-display: 'Clash Display', 'Satoshi', system-ui, sans-serif;
  --font-body:    'Satoshi', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Fluid scale — 320px → 1600px viewport.
     The steps below the body size are lifted (small print was landing at 11–12px,
     which is under the comfortable reading floor) and the display steps are
     pulled back hard: a 120px hero pushed the fold nearly two screens down and
     forced tracking so tight the words ran together. A ~1.25 ratio through the
     middle keeps the hierarchy legible without the theatrics. */
  --t-xs:   clamp(0.75rem, 0.735rem + 0.08vw, 0.8125rem);
  --t-sm:   clamp(0.8438rem, 0.82rem + 0.11vw, 0.9375rem);
  --t-base: clamp(0.9688rem, 0.94rem + 0.14vw, 1.0625rem);
  --t-md:   clamp(1.0625rem, 1.02rem + 0.22vw, 1.2188rem);
  --t-lg:   clamp(1.25rem, 1.17rem + 0.4vw, 1.5rem);
  --t-xl:   clamp(1.4375rem, 1.31rem + 0.64vw, 1.875rem);
  --t-2xl:  clamp(1.75rem, 1.53rem + 1.1vw, 2.375rem);
  --t-3xl:  clamp(2.0625rem, 1.72rem + 1.7vw, 3.125rem);
  --t-4xl:  clamp(2.5rem, 1.98rem + 2.6vw, 4rem);
  --t-hero: clamp(2.5rem, 1.9rem + 3vw, 4.25rem);

  /* 1.04 was crushing descenders into the line below at display sizes. */
  --lh-tight: 1.07;
  --lh-snug:  1.2;
  --lh-body:  1.65;
  --lh-loose: 1.75;

  --tr-tight:  -0.022em;
  --tr-snug:   -0.014em;
  --tr-normal: 0;
  --tr-wide:   0.06em;
  --tr-caps:   0.13em;

  /* ── Space — 4px base, spacious marketing rhythm ────────────────────── */
  --s-1:  0.25rem;  --s-2:  0.5rem;   --s-3:  0.75rem;  --s-4:  1rem;
  --s-5:  1.5rem;   --s-6:  2rem;     --s-7:  2.5rem;   --s-8:  3rem;
  --s-9:  4rem;     --s-10: 5rem;     --s-11: 6.5rem;   --s-12: 8rem;
  --s-13: 10rem;

  --section-y: clamp(4.5rem, 3rem + 7vw, 10rem);
  --gutter:    clamp(1.25rem, 0.75rem + 2.4vw, 3rem);
  --measure:   68ch;

  /* ── Radii ──────────────────────────────────────────────────────────── */
  --r-xs: 6px;  --r-sm: 10px; --r-md: 14px; --r-lg: 20px;
  --r-xl: 28px; --r-2xl: 40px; --r-full: 999px;

  /* ── Motion ─────────────────────────────────────────────────────────── */
  --ease-out:  cubic-bezier(.22, 1, .36, 1);        /* expo-ish, for entrances */
  --ease-in:   cubic-bezier(.55, 0, 1, .45);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);
  --ease-back: cubic-bezier(.34, 1.4, .5, 1);
  --d-fast:   160ms;
  --d-base:   280ms;
  --d-slow:   520ms;
  --d-reveal: 900ms;

  /* ── Layout ─────────────────────────────────────────────────────────── */
  --max-w:      1320px;
  --max-w-wide: 1560px;
  --max-w-text: 760px;
  --nav-h:      76px;

  --z-base: 1; --z-sticky: 100; --z-nav: 900; --z-menu: 950;
  --z-notify: 1000; --z-modal: 2000; --z-toast: 3000; --z-cursor: 9999;
}

/* ── Theme: DARK (the house look) ─────────────────────────────────────── */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  --canvas:      #06060C;
  --canvas-deep: #030308;
  --surface:     #0B0B15;
  --surface-2:   #11111F;
  --surface-3:   #17172A;
  --surface-inv: #F7F7FB;

  --ink:      #F6F6FB;
  --ink-2:    #B4B4CC;
  --ink-3:    #7D7D99;
  --ink-4:    #55556E;
  --ink-inv:  #06060C;

  --line:        rgba(255, 255, 255, .07);
  --line-2:      rgba(255, 255, 255, .12);
  --line-strong: rgba(255, 255, 255, .2);

  --brand:      var(--iris-400);
  --brand-deep: var(--iris-500);
  --brand-soft: rgba(108, 99, 255, .14);
  --brand-ring: rgba(139, 132, 255, .45);
  --on-brand:   #0A0A14;

  --gold:      var(--aurum-400);
  --gold-soft: rgba(228, 188, 118, .12);

  /* Glass */
  --glass:        rgba(15, 15, 28, .62);
  --glass-strong: rgba(11, 11, 21, .86);
  --nav-solid:    #08080F;
  --glass-line:   rgba(255, 255, 255, .09);
  /* Backdrop blur is the single most expensive thing a fixed header can do:
     the strip behind it changes on every scrolled frame, so the blur is
     recomputed every frame. 12px reads as glass just as well as 22px at a
     fraction of the fill cost, and dropping saturate() removes a whole
     colour-matrix pass. Phones opt out entirely (see below). */
  --blur:         blur(12px);

  /* Elevation — dark UIs read depth from glow + hairline, not drop shadow */
  --sh-1: 0 1px 2px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.04);
  --sh-2: 0 8px 24px -8px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.05);
  --sh-3: 0 24px 60px -18px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.06);
  --sh-4: 0 44px 110px -28px rgba(0,0,0,.85), 0 0 0 1px rgba(255,255,255,.07);
  --sh-brand: 0 20px 60px -20px rgba(108, 99, 255, .55);
  --sh-gold:  0 20px 60px -20px rgba(212, 168, 87, .35);

  --grid-line: rgba(255, 255, 255, .035);
  --noise-opacity: .045;
  --scrim: linear-gradient(180deg, rgba(6,6,12,0) 0%, rgba(6,6,12,.85) 65%, #06060C 100%);
}

/* ── Theme: LIGHT (warm paper, not office grey) ───────────────────────── */
[data-theme="light"] {
  color-scheme: light;

  --canvas:      #FAFAFC;
  --canvas-deep: #F1F1F6;
  --surface:     #FFFFFF;
  --surface-2:   #F5F5FA;
  --surface-3:   #EDEDF5;
  --surface-inv: #0B0B15;

  --ink:      #0B0B15;
  --ink-2:    #45455C;
  --ink-3:    #6E6E88;
  --ink-4:    #9A9AB0;
  --ink-inv:  #FFFFFF;

  --line:        rgba(11, 11, 21, .08);
  --line-2:      rgba(11, 11, 21, .13);
  --line-strong: rgba(11, 11, 21, .22);

  --brand:      var(--iris-600);
  --brand-deep: var(--iris-700);
  --brand-soft: rgba(108, 99, 255, .09);
  --brand-ring: rgba(90, 79, 232, .38);
  --on-brand:   #FFFFFF;

  --gold:      var(--aurum-600);
  --gold-soft: rgba(183, 139, 61, .1);

  --glass:        rgba(255, 255, 255, .72);
  --glass-strong: rgba(255, 255, 255, .92);
  --nav-solid:    #FCFCFE;
  --glass-line:   rgba(11, 11, 21, .07);

  --sh-1: 0 1px 2px rgba(16, 16, 40, .06), 0 0 0 1px rgba(16, 16, 40, .04);
  --sh-2: 0 10px 24px -10px rgba(16, 16, 40, .16), 0 0 0 1px rgba(16, 16, 40, .05);
  --sh-3: 0 26px 60px -22px rgba(16, 16, 40, .22), 0 0 0 1px rgba(16, 16, 40, .05);
  --sh-4: 0 48px 110px -34px rgba(16, 16, 40, .26), 0 0 0 1px rgba(16, 16, 40, .06);
  --sh-brand: 0 22px 55px -22px rgba(90, 79, 232, .45);
  --sh-gold:  0 22px 55px -22px rgba(183, 139, 61, .35);

  --grid-line: rgba(11, 11, 21, .045);
  --noise-opacity: .028;
  --scrim: linear-gradient(180deg, rgba(250,250,252,0) 0%, rgba(250,250,252,.85) 65%, #FAFAFC 100%);
}

/* Status colours differ per theme for contrast */
[data-theme="light"] {
  --ok-500: #0E9F6E;  --warn-500: #B45309;
  --err-500: #D92D3F; --info-500: #1D6FD8;
}

/* ──────────────────────────────────────────────────────────── 2. RESET ─── */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* No global `scroll-behavior: smooth`. It animates *every* scroll the page
     does not drive — Page Down, Home/End, arrow keys, dragging the scrollbar
     — which reads as lag. Anchor clicks still glide: motion.js passes
     behavior:'smooth' per call, so we get the nice part without the tax. */
  scroll-padding-top: calc(var(--nav-h) + var(--s-6));
}

body {
  min-height: 100dvh;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-base);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
  overflow-x: clip;
  transition: background var(--d-slow) var(--ease-soft),
              color var(--d-slow) var(--ease-soft);
}

img, svg, video, canvas, picture { display: block; max-width: 100%; }
img, video { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
table { border-collapse: collapse; width: 100%; }
hr { border: 0; border-top: 1px solid var(--line); }

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

/* Focus — never removed, only made beautiful */
:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}
:focus:not(:focus-visible) { outline: none; }

/* Scrollbar */
@supports selector(::-webkit-scrollbar) {
  ::-webkit-scrollbar { width: 11px; height: 11px; }
  ::-webkit-scrollbar-track { background: var(--canvas-deep); }
  ::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border-radius: var(--r-full);
    border: 3px solid var(--canvas-deep);
  }
  ::-webkit-scrollbar-thumb:hover { background: var(--brand); }
}
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }

/* ─────────────────────────────────────────────────────── 3. TYPOGRAPHY ─── */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-snug);
  /* Negative tracking shrinks the word gap along with the letter gap, and
     Clash Display already sets a narrow space. Add a little back so headlines
     read as words rather than one long string. */
  word-spacing: 0.045em;
  text-wrap: balance;
  color: var(--ink);
}

/* Tracking is a function of size: negative tracking tightens a 50px headline
   but smears a 17px one, so it is dialled back step by step and reaches 0 by
   the time a heading is body-sized. */
h1 { font-size: var(--t-3xl); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); }
h2 { font-size: var(--t-2xl); line-height: 1.12; letter-spacing: var(--tr-tight); }
h3 { font-size: var(--t-xl);  line-height: 1.18; letter-spacing: var(--tr-snug); }
h4 { font-size: var(--t-lg);  line-height: 1.24; letter-spacing: var(--tr-snug); }
h5 { font-size: var(--t-md);  line-height: 1.3;  letter-spacing: -0.008em; }
h6 { font-size: var(--t-base);line-height: 1.35; letter-spacing: var(--tr-normal); }

p { text-wrap: pretty; }
p, li { max-width: var(--measure); }

strong, b { font-weight: 700; color: var(--ink); }
em { font-style: italic; }

code, kbd, samp, pre { font-family: var(--font-mono); font-size: .92em; }

/* ── Type utilities ───────────────────────────────────────────────────── */
.display     { font-family: var(--font-display); font-weight: 600; letter-spacing: var(--tr-tight); line-height: var(--lh-tight); word-spacing: 0.045em; }
.display-xl  { font-size: var(--t-hero); }
.display-lg  { font-size: var(--t-4xl); }
.display-md  { font-size: var(--t-3xl); }

.lede {
  font-size: var(--t-md);
  line-height: var(--lh-loose);
  color: var(--ink-2);
  max-width: 62ch;
  font-weight: 400;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}
.eyebrow::before {
  content: '';
  width: 22px; height: 1px;
  background: currentColor;
  opacity: .5;
}
.eyebrow--dot::before {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--brand);
  opacity: 1;
  box-shadow: 0 0 0 4px var(--brand-soft);
}

.mono   { font-family: var(--font-mono); letter-spacing: var(--tr-normal); }
.muted  { color: var(--ink-3); }
.dim    { color: var(--ink-2); }
.center { text-align: center; }
.balance{ text-wrap: balance; }

/* Gradient ink — used once or twice per page, never everywhere */
.ink-grad {
  background: linear-gradient(120deg, var(--ink) 0%, var(--ink) 40%, var(--brand) 78%, var(--iris-300) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.ink-gold {
  background: linear-gradient(100deg, var(--aurum-300), var(--aurum-500) 55%, var(--aurum-200));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Numerals that need to line up */
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* ────────────────────────────────────────────────────────── 4. LAYOUT ─── */

.container {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide { max-width: var(--max-w-wide); }
.container--text { max-width: var(--max-w-text); }

.section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: calc(var(--section-y) * .6); }
.section--flush-top { padding-top: 0; }

/* Skip the layout, style and paint work for sections that are nowhere near
   the viewport. The home page carries ~1,400 elements across a dozen
   sections; without this the browser styles and lays out all of them on
   every invalidation, whether or not they are anywhere the reader can see.
   `contain-intrinsic-size: auto` lets each section remember the height it
   last rendered at, so the scrollbar stays put once a section has been
   visited. The hero is excluded — it is always on screen at load, and there
   is nothing to skip. */
main > .section:not(.hero) {
  content-visibility: auto;
  contain-intrinsic-size: auto 720px;
}

.stack > * + * { margin-top: var(--s-4); }
.stack-sm > * + * { margin-top: var(--s-2); }
.stack-lg > * + * { margin-top: var(--s-6); }

.row { display: flex; align-items: center; gap: var(--s-3); }
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }

.grid { display: grid; gap: var(--s-5); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-auto { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }

@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

/* Section heading block, used on every section */
.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  max-width: 720px;
  margin-bottom: var(--s-9);
}
.section-head--center { margin-inline: auto; align-items: center; text-align: center; }
.section-head--center p { margin-inline: auto; }
.section-head--split {
  max-width: none;
  flex-direction: row;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-8);
}
.section-head--split .section-head-copy { max-width: 640px; display: grid; gap: var(--s-4); }
@media (max-width: 860px) {
  .section-head--split { flex-direction: column; align-items: flex-start; }
}

/* ─────────────────────────────────────────────────────────── 5. ATOMS ─── */

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-line: var(--line-2);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 48px;
  padding: 0 var(--s-6);
  border-radius: var(--r-full);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-line);
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  cursor: pointer;
  isolation: isolate;
  overflow: hidden;
  transition: transform var(--d-base) var(--ease-out),
              box-shadow var(--d-base) var(--ease-out),
              border-color var(--d-base) var(--ease-out),
              background var(--d-base) var(--ease-out),
              color var(--d-base) var(--ease-out);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(.985); transition-duration: 80ms; }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45; pointer-events: none; transform: none;
}
.btn .i { width: 18px; height: 18px; flex: none; }

/* Sheen that crosses the button on hover — the "expensive" tell */
.btn::after {
  content: '';
  position: absolute; inset: 0;
  z-index: -1;
  background: linear-gradient(100deg, transparent 20%, rgba(255,255,255,.22) 45%, transparent 70%);
  transform: translateX(-130%);
  transition: transform 700ms var(--ease-out);
}
.btn:hover::after { transform: translateX(130%); }

.btn--primary {
  --btn-bg: linear-gradient(135deg, var(--iris-500) 0%, var(--iris-600) 55%, var(--iris-700) 100%);
  --btn-fg: #FFFFFF;
  --btn-line: transparent;
  box-shadow: var(--sh-brand);
}
.btn--primary:hover { box-shadow: 0 26px 70px -22px rgba(108, 99, 255, .75); }

.btn--gold {
  --btn-bg: linear-gradient(135deg, var(--aurum-300), var(--aurum-500) 60%, var(--aurum-600));
  --btn-fg: #1A1204;
  --btn-line: transparent;
  box-shadow: var(--sh-gold);
}

.btn--solid { --btn-bg: var(--surface-inv); --btn-fg: var(--ink-inv); --btn-line: transparent; }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--ink); --btn-line: var(--line-2); }
.btn--ghost:hover { --btn-line: var(--brand); --btn-bg: var(--brand-soft); }

.btn--glass {
  --btn-bg: var(--glass);
  --btn-line: var(--glass-line);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
}
.btn--glass:hover { --btn-line: var(--line-strong); }

.btn--quiet { --btn-line: transparent; padding-inline: var(--s-3); color: var(--ink-2); }
.btn--quiet:hover { color: var(--ink); background: var(--surface-2); }

.btn--sm { min-height: 40px; padding-inline: var(--s-4); font-size: var(--t-xs); }
.btn--lg { min-height: 58px; padding-inline: var(--s-7); font-size: var(--t-base); }
.btn--block { width: 100%; }
.btn--icon { padding: 0; width: 48px; min-height: 48px; }
.btn--icon.btn--sm { width: 40px; min-height: 40px; }

.btn--danger { --btn-bg: var(--err-bg); --btn-fg: var(--err-500); --btn-line: transparent; }
.btn--danger:hover { --btn-bg: var(--err-500); --btn-fg: #fff; }

/* Text link with an underline that draws itself */
.link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--brand);
  font-weight: 600;
  padding-bottom: 2px;
}
.link::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--d-base) var(--ease-out);
}
.link:hover::after { transform: scaleX(1); transform-origin: left; }
.link .i { transition: transform var(--d-base) var(--ease-out); }
.link:hover .i { transform: translateX(4px); }

/* ── Surfaces ─────────────────────────────────────────────────────────── */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  transition: transform var(--d-base) var(--ease-out),
              border-color var(--d-base) var(--ease-out),
              box-shadow var(--d-base) var(--ease-out),
              background var(--d-base) var(--ease-out);
}
.card--glass {
  background: var(--glass);
  backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur);
  border-color: var(--glass-line);
}
.card--flat { background: var(--surface-2); border-color: transparent; }
.card--lift:hover {
  transform: translateY(-6px);
  border-color: var(--line-2);
  box-shadow: var(--sh-3);
}
.card--pad-lg { padding: var(--s-8); }
.card--pad-sm { padding: var(--s-4); }

/* Hairline panel used for legal / doc pages */
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: clamp(1.5rem, 1rem + 2.5vw, 3.5rem);
}

/* ── Badges, pills, dots ──────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 5px 12px;
  border-radius: var(--r-full);
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
}
.badge--brand { background: var(--brand-soft); border-color: transparent; color: var(--brand); }
.badge--gold  { background: var(--gold-soft);  border-color: transparent; color: var(--gold); }
.badge--ok    { background: var(--ok-bg);   border-color: transparent; color: var(--ok-500); }
.badge--warn  { background: var(--warn-bg); border-color: transparent; color: var(--warn-500); }
.badge--err   { background: var(--err-bg);  border-color: transparent; color: var(--err-500); }
.badge--info  { background: var(--info-bg); border-color: transparent; color: var(--info-500); }

/* The active dot — a live pulse, one per service / status */
.dot {
  position: relative;
  width: 8px; height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--dot-c, var(--brand));
}
.dot--live::before,
.dot--live::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: dot-ping 2.4s var(--ease-out) infinite;
}
.dot--live::after { animation-delay: 1.2s; }
.dot--sm { width: 6px; height: 6px; }
.dot--lg { width: 10px; height: 10px; }

@keyframes dot-ping {
  0%   { transform: scale(1);   opacity: .6; }
  70%  { transform: scale(3.2); opacity: 0; }
  100% { transform: scale(3.2); opacity: 0; }
}

.dot--web    { --dot-c: var(--sig-web);    background: var(--sig-web); }
.dot--mobile { --dot-c: var(--sig-mobile); background: var(--sig-mobile); }
.dot--ai     { --dot-c: var(--sig-ai);     background: var(--sig-ai); }
.dot--design { --dot-c: var(--sig-design); background: var(--sig-design); }
.dot--uiux   { --dot-c: var(--sig-uiux);   background: var(--sig-uiux); }
.dot--ok     { --dot-c: var(--ok-500);     background: var(--ok-500); }
.dot--warn   { --dot-c: var(--warn-500);   background: var(--warn-500); }
.dot--err    { --dot-c: var(--err-500);    background: var(--err-500); }
.dot--idle   { --dot-c: var(--ink-4);      background: var(--ink-4); }

/* ── Icons ────────────────────────────────────────────────────────────── */
.i {
  width: 20px; height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
}
.i--xs { width: 14px; height: 14px; }
.i--sm { width: 16px; height: 16px; }
.i--lg { width: 26px; height: 26px; stroke-width: 1.45; }
.i--xl { width: 34px; height: 34px; stroke-width: 1.35; }

/* Icon in a tinted tile — the service/feature marker */
.i-tile {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  flex: none;
  border-radius: var(--r-md);
  background: var(--tile-bg, var(--brand-soft));
  color: var(--tile-fg, var(--brand));
  border: 1px solid var(--line);
  transition: transform var(--d-base) var(--ease-back),
              background var(--d-base) var(--ease-out);
}
.i-tile--lg { width: 64px; height: 64px; border-radius: var(--r-lg); }
.i-tile--sm { width: 40px; height: 40px; border-radius: var(--r-sm); }

/* ── Forms ────────────────────────────────────────────────────────────── */
.field { display: grid; gap: var(--s-2); }

.label {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-2);
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
}
.label .req { color: var(--brand); font-size: var(--t-xs); }

.hint { font-size: var(--t-xs); color: var(--ink-3); line-height: 1.5; }

.input, .select, .textarea {
  width: 100%;
  min-height: 50px;
  padding: 13px 16px;
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  font-size: var(--t-base);
  transition: border-color var(--d-fast) var(--ease-soft),
              background var(--d-fast) var(--ease-soft),
              box-shadow var(--d-fast) var(--ease-soft);
}
.textarea { min-height: 140px; resize: vertical; line-height: var(--lh-body); }
.input::placeholder, .textarea::placeholder { color: var(--ink-4); }

.input:hover, .select:hover, .textarea:hover { border-color: var(--line-strong); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--brand);
  background: var(--surface);
  box-shadow: 0 0 0 4px var(--brand-soft);
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--err-500);
  box-shadow: 0 0 0 4px var(--err-bg);
}

.select {
  appearance: none;
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237D7D99' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  cursor: pointer;
}

.error-text {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-xs);
  color: var(--err-500);
  font-weight: 500;
}

/* Checkbox / radio — custom, 44px hit area */
.check {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3);
  margin: calc(var(--s-3) * -1);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--d-fast) var(--ease-soft);
}
.check:hover { background: var(--surface-2); }
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check-box {
  position: relative;
  width: 20px; height: 20px;
  flex: none;
  margin-top: 2px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-xs);
  background: var(--surface-2);
  transition: all var(--d-fast) var(--ease-out);
}
.check input[type="radio"] + .check-box { border-radius: 50%; }
.check-box::after {
  content: '';
  position: absolute;
  left: 6px; top: 2px;
  width: 5px; height: 10px;
  border: solid var(--on-brand);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform var(--d-fast) var(--ease-back);
}
.check input:checked + .check-box {
  background: var(--brand);
  border-color: var(--brand);
}
.check input:checked + .check-box::after { transform: rotate(45deg) scale(1); }
.check input:focus-visible + .check-box { box-shadow: 0 0 0 4px var(--brand-soft); }
.check-label { font-size: var(--t-sm); line-height: 1.5; color: var(--ink-2); }
.check-label strong { display: block; color: var(--ink); font-weight: 600; }

/* Chip-style multi-select (services picker) */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: 0 var(--s-4);
  border-radius: var(--r-full);
  border: 1px solid var(--line-2);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: var(--t-sm);
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: all var(--d-base) var(--ease-out);
}
.chip:hover { border-color: var(--line-strong); color: var(--ink); transform: translateY(-1px); }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip:has(input:checked) {
  background: var(--chip-c, var(--brand));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 8px 24px -10px var(--chip-c, var(--brand));
}
.chip:has(input:focus-visible) { outline: 2px solid var(--brand-ring); outline-offset: 3px; }

/* ── Tables ───────────────────────────────────────────────────────────── */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  -webkit-overflow-scrolling: touch;
}
.table { min-width: 560px; font-size: var(--t-sm); }
.table th {
  text-align: left;
  padding: var(--s-3) var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.table td {
  padding: var(--s-4);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
  color: var(--ink-2);
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background var(--d-fast) var(--ease-soft); }
.table tbody tr:hover { background: var(--surface-2); }
.table td strong { color: var(--ink); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Notes / callouts ─────────────────────────────────────────────────── */
.note {
  display: flex;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-md);
  background: var(--surface-2);
  border-left: 2px solid var(--brand);
  font-size: var(--t-sm);
  color: var(--ink-2);
  line-height: var(--lh-body);
}
.note p { max-width: none; }
.note .i { color: var(--brand); margin-top: 2px; }
.note--warn { border-left-color: var(--warn-500); background: var(--warn-bg); }
.note--warn .i { color: var(--warn-500); }
.note--ok   { border-left-color: var(--ok-500); background: var(--ok-bg); }
.note--ok .i { color: var(--ok-500); }
.note--err  { border-left-color: var(--err-500); background: var(--err-bg); }
.note--err .i { color: var(--err-500); }
.note--gold { border-left-color: var(--gold); background: var(--gold-soft); }
.note--gold .i { color: var(--gold); }

/* ── Progress ─────────────────────────────────────────────────────────── */
.meter {
  position: relative;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--surface-3);
  overflow: hidden;
}
.meter-fill {
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--iris-500), var(--iris-300));
  transform-origin: left;
  transition: width 1.1s var(--ease-out);
}
.meter-fill--gold { background: linear-gradient(90deg, var(--aurum-500), var(--aurum-300)); }
.meter-fill--ok   { background: linear-gradient(90deg, var(--ok-500), #5FE3B0); }

/* ── Avatar ───────────────────────────────────────────────────────────── */
.avatar {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  flex: none;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--iris-500), var(--iris-700));
  color: #fff;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-sm);
  letter-spacing: .02em;
  text-transform: uppercase;
  overflow: hidden;
}
.avatar--sm { width: 32px; height: 32px; font-size: var(--t-xs); }
.avatar--lg { width: 64px; height: 64px; font-size: var(--t-md); }
.avatar--gold { background: linear-gradient(135deg, var(--aurum-400), var(--aurum-600)); color: #1A1204; }

/* ─────────────────────────────────────────────── 6. DECOR / TEXTURE ────── */

/* Fine grain — kills banding in the big gradients, reads as print stock.

   Scoped to the two surfaces that actually carry those gradients: the home
   hero and the page header. It used to be a `position: fixed` overlay across
   the whole viewport at z-index 1, which meant the compositor re-blended a
   full screen of translucent noise over every pixel of scrolling content on
   every frame — a measurable slice of the frame budget for a texture at 4.5%
   opacity that is invisible over body copy anyway. */
.grain .hero::after,
.grain .page-head::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--noise-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Engineering grid — the quiet backdrop of a software house */
.grid-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 30%, transparent 78%);
}
.grid-bg--center {
  mask-image: radial-gradient(ellipse 70% 70% at 50% 50%, #000 20%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 70% 70% at 50% 50%, #000 20%, transparent 75%);
}

/* Aurora — one large, slow, out-of-focus light source */
.aurora {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  /* The source is already a soft radial gradient, so a wide blur only
     smooths banding. 90px over a 62vw box was re-rasterised on every
     animated frame; 36px reads the same and costs a fraction. */
  filter: blur(36px);
  opacity: .5;
  will-change: transform;
}
.aurora--iris { background: radial-gradient(circle, var(--iris-500) 0%, transparent 68%); }
.aurora--mint { background: radial-gradient(circle, var(--sig-mobile) 0%, transparent 68%); }
.aurora--gold { background: radial-gradient(circle, var(--aurum-500) 0%, transparent 68%); }
.aurora--coral{ background: radial-gradient(circle, var(--sig-ai) 0%, transparent 68%); }
[data-theme="light"] .aurora { opacity: .22; filter: blur(44px); }

/* Translate only. A scaling keyframe changes the filter's input size, which
   forces the blur to be recomputed every frame; a pure translate lets the
   compositor slide one cached raster around for free. */
@keyframes aurora-drift {
  0%, 100% { transform: translate3d(0, 0, 0); }
  33%      { transform: translate3d(4%, -6%, 0); }
  66%      { transform: translate3d(-5%, 4%, 0); }
}
.aurora--drift { animation: aurora-drift 26s var(--ease-soft) infinite; }

@media (prefers-reduced-motion: reduce) {
  .aurora--drift { animation: none; }
}

/* Hairline rule that fades at both ends */
.rule {
  height: 1px;
  border: 0;
  background: linear-gradient(90deg, transparent, var(--line-2) 18%, var(--line-2) 82%, transparent);
}

/* Gradient border via mask — no double-border artefacts */
.edge {
  position: relative;
}
.edge::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(140deg, var(--line-strong), transparent 40%, transparent 60%, var(--brand-ring));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--d-base) var(--ease-out);
}
.edge:hover::before, .edge.is-active::before { opacity: 1; }

/* Spotlight that follows the pointer across a card */
.spot {
  position: relative;
  overflow: hidden;
}
.spot::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    360px circle at var(--mx, 50%) var(--my, 50%),
    var(--brand-soft), transparent 62%
  );
  opacity: 0;
  transition: opacity var(--d-slow) var(--ease-soft);
}
.spot:hover::after { opacity: 1; }

/* ────────────────────────────────────────────────────────── 7. MOTION ─── */

/* Reveal — set by motion.js. Elements are visible by default when JS is off.
   No blanket `will-change` here: a page can carry ninety of these, and
   promoting ninety elements to their own compositor layers costs far more
   per scrolled frame than it ever saves on the one transition each plays. */

html.js [data-reveal] {
  opacity: 0;
  /* Only opacity and transform — both composite without a repaint. The
     filter/clip-path variants below opt themselves back in. */
  transition:
    opacity var(--d-reveal) var(--ease-out),
    transform var(--d-reveal) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
html.js [data-reveal="up"]    { transform: translate3d(0, 34px, 0); }
html.js [data-reveal="down"]  { transform: translate3d(0, -28px, 0); }
html.js [data-reveal="left"]  { transform: translate3d(38px, 0, 0); }
html.js [data-reveal="right"] { transform: translate3d(-38px, 0, 0); }
html.js [data-reveal="fade"]  { transform: none; }
html.js [data-reveal="scale"] { transform: scale(.94); }
html.js [data-reveal="blur"]  {
  filter: blur(14px); transform: translate3d(0, 20px, 0);
  transition: opacity var(--d-reveal) var(--ease-out),
              transform var(--d-reveal) var(--ease-out),
              filter var(--d-reveal) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
html.js [data-reveal="clip"]  {
  clip-path: inset(0 0 100% 0); transform: translate3d(0, 14px, 0);
  transition: opacity var(--d-reveal) var(--ease-out),
              transform var(--d-reveal) var(--ease-out),
              clip-path var(--d-reveal) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
html.js [data-reveal="rise"]  { transform: translate3d(0, 64px, 0) scale(.97); }

html.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: inset(0 0 0 0);
}

/* Line-mask headline reveal — motion.js wraps each line in .rv-line > .rv-inner */
.rv-line { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.rv-inner {
  display: block;
  transform: translate3d(0, 105%, 0);
  transition: transform 1.05s var(--ease-out);
  transition-delay: var(--line-delay, 0ms);
}
.is-in .rv-inner, .rv-line.is-in .rv-inner { transform: none; }

/* Stagger children — motion.js sets --reveal-delay per child */
[data-stagger] > * { --reveal-delay: 0ms; }

/* Marquee */
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee-track { display: flex; width: max-content; animation: marquee var(--marquee-d, 40s) linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee--rev .marquee-track { animation-direction: reverse; }
@keyframes marquee { to { transform: translate3d(-50%, 0, 0); } }

/* Skeleton shimmer for loading states */
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }

/* Spinner */
.spinner {
  width: 18px; height: 18px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Scroll progress — a hairline of brand at the top of the page */
.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: calc(var(--z-nav) + 5);
  background: linear-gradient(90deg, var(--iris-500), var(--sig-uiux), var(--aurum-400));
  transform: scaleX(0);
  transform-origin: left;
  pointer-events: none;
}

/* ── Reduced motion: everything arrives, nothing moves ───────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html.js [data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; clip-path: none !important; }
  .rv-inner { transform: none !important; }
  .aurora--drift { animation: none; }
  .marquee-track { animation: none; }
  .dot--live::before, .dot--live::after { animation: none; opacity: 0; }
}

/* ───────────────────────────────────────────────────────── 8. UTILITY ─── */

.sr-only {
  position: absolute !important;
  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(--s-3); left: var(--s-3);
  z-index: var(--z-toast);
  padding: var(--s-3) var(--s-5);
  background: var(--brand);
  color: #fff;
  border-radius: var(--r-full);
  font-weight: 600;
  transform: translateY(-160%);
  transition: transform var(--d-base) var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

.hide { display: none !important; }
@media (max-width: 900px)  { .hide-md  { display: none !important; } }
@media (max-width: 640px)  { .hide-sm  { display: none !important; } }
@media (min-width: 901px)  { .only-md  { display: none !important; } }

.full-bleed { width: 100vw; margin-left: 50%; transform: translateX(-50%); }
.relative { position: relative; }
.overflow-clip { overflow: clip; }
.nowrap { white-space: nowrap; }

/* ── Cheap glass for phones ───────────────────────────────────────────────
   backdrop-filter is far more expensive on mobile GPUs than on desktop, and
   the fixed header re-blurs its strip on every scrolled frame. On coarse
   pointers we drop the filter entirely and raise the glass opacity instead,
   so the surfaces stay legible without the per-frame cost. */
@media (pointer: coarse), (max-width: 760px) {
  :root {
    --glass:        rgba(15, 15, 28, .90);
    --glass-strong: rgba(11, 11, 21, .95);
  }
  [data-theme="light"] {
    --glass:        rgba(255, 255, 255, .94);
    --glass-strong: rgba(255, 255, 255, .97);
  }
  .navbar, .btn--glass, .card--glass, .nav-panel, .drawer {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  html.is-past .navbar, .navbar.is-solid {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  /* One aurora is plenty of atmosphere on a small screen. */
  .aurora--b, .aurora--c { display: none; }
  .aurora { filter: blur(28px); }
}

/* Print — legal pages and invoices need to survive a printer */
@media print {
  :root { --canvas: #fff; --surface: #fff; --ink: #000; --ink-2: #333; --line: #ddd; }
  .no-print, .navbar, .site-footer, .scroll-progress, .aurora, .grid-bg { display: none !important; }
  .grain .hero::after, .grain .page-head::after { display: none !important; }
  body { background: #fff; color: #000; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; color: #666; }
  .panel, .card { border: 1px solid #ddd; box-shadow: none; break-inside: avoid; }
}
