/* ═══════════════════════════════════════════════════════════════
   LOCALWORKS V2 - design tokens

   Distilled from the four reference systems (Huly, Dala, Auros,
   Dope Security). All four independently agree on the rules this
   file enforces:

     · near-black neutral canvas, never navy
     · exactly ONE accent colour                (gold #F2A950)
     · ZERO shadows - elevation is hairline borders + surface steps
     · display type 80-113px, weights 200-500, tracking -0.04em
     · hierarchy from SCALE, not weight
     · 4px spacing scale, 96-120px between sections
     · exactly three radii: card / input / pill
     · uppercase mono labels, tracking 0.14-0.2em

   If a style needs something this file doesn't provide, the answer
   is almost always "no it doesn't".
   ═══════════════════════════════════════════════════════════════ */

:root{
  /* ── canvas & ink ── */
  --bg:        #08090B;   /* the page. Near-black, faintly warm, never navy */
  --bg-2:      #0D0F12;   /* raised surface (cards) - a step, not a shadow */
  --bg-3:      #14161A;   /* highest surface (inputs, hover) */
  --ink:       #F2F3F1;   /* primary text */
  --dim:       #A2A7AC;   /* supporting text */
  --faint:     #5C6167;   /* metadata, disabled */

  /* ── THE accent. There is no second one. ──
     Default is Iris violet - the consensus accent family of the
     references (Dala #8052ff, Dope #af50ff). Gold was retired: warm
     amber on black is the classic vice palette and read wrong. */
  --accent:    #8052FF;
  --on-accent: #FFFFFF;
  --accent-dim:rgba(128,82,255,.14);   /* tint wash for marks, never text */

  /* ── the one exception to "there is no second colour" ──
     A form has to be able to say "this field is wrong" in a way that
     cannot be confused with "this field is focused", and focus is the
     accent. Using one colour for both leaves a person staring at a
     form that will not send, unable to see why. So this is FUNCTIONAL,
     not decorative, and it is allowed in exactly two places: error text
     and the underline of the field that error belongs to. It never
     appears in a heading, a button, a border, an icon or a background.
     Muted on purpose so it corrects rather than alarms. */
  --warn:      #D4756A;

  /* ── hairlines do the work shadows used to ── */
  --line:        rgba(242,243,241,.09);
  --line-strong: rgba(242,243,241,.17);

  /* ── spacing - 4px scale ── */
  --s1:4px;  --s2:8px;  --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:64px; --s9:96px; --s10:120px;

  /* ── type ── */
  --font-ui:  'Inter','Segoe UI Variable Display','Segoe UI',-apple-system,system-ui,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,'Cascadia Mono',Consolas,monospace;

  --fs-display: clamp(58px, 8.6vw, 112px);   /* the hero voice */
  --fs-h2:      clamp(34px, 4.6vw, 60px);    /* section openers */
  --fs-h3:      clamp(22px, 2.2vw, 28px);
  --fs-lede:    clamp(16px, 1.4vw, 19px);
  --fs-body:    16px;
  --fs-small:   14px;
  --fs-label:   12px;

  --lh-display: 0.98;
  --lh-tight:   1.08;
  --lh-body:    1.55;

  --track-display: -0.04em;
  --track-tight:   -0.02em;
  --track-label:    0.18em;

  /* ── exactly three radii ── */
  --r-card:  14px;
  --r-input: 6px;
  --r-pill:  999px;

  /* ── motion ── */
  --ease-out: cubic-bezier(.16,1,.3,1);
  --t-fast: 160ms;
  --t-slow: 480ms;

  /* ── glass: a CLEAR plate, not frosted ──
     The references use glass as a pane of window, not a fogged
     panel: you read straight through it. So: tiny blur (2px, just
     enough to settle noisy backdrops), a barely-there white film,
     a hairline edge, and a 1px top highlight where light catches
     the bevel. No shadow, no 26px frost, no inner glow. */
  --glass-film:   rgba(255,255,255,.035);
  --glass-edge:   rgba(255,255,255,.11);
  --glass-bevel:  rgba(255,255,255,.20);
  --glass-blur:   2px;
}

/* ═══ palettes - cool/neutral only.
   Switch with <html data-theme="…">. Every one is drawn from the
   reference systems' own tokens; warm gold is deliberately absent.

   --orb-stops is the swarm's depth ramp, back of the sphere to front.
   Each one now runs FIVE stops instead of four: a deeper shadow end, a
   fully saturated accent through the body, and a true white at the
   front. This is still one hue - it is a wider luminance range of the
   same accent, not a second colour, so the one-accent law holds. The
   old four-stop ramps topped out at a pale tint, which is why the
   marks read washed out no matter how the alpha was tuned. ═══ */

/* Iris - Dala #8052ff / Dope #af50ff family. The default. */
:root[data-theme="iris"]{
  --bg:#08090B; --bg-2:#0D0F12; --bg-3:#14161A;
  --accent:#8052FF; --on-accent:#FFFFFF; --accent-dim:rgba(128,82,255,.14);
  --orb-glow:128,82,255;
  --orb-stops:#200F45,#6B3AF0,#8052FF,#CDB4FF,#FFFFFF;
}
/* Azure - Huly's electric iris on obsidian. Calm, corporate-clean. */
:root[data-theme="azure"]{
  --bg:#090A0C; --bg-2:#111214; --bg-3:#191B1F;
  --accent:#5683DA; --on-accent:#FFFFFF; --accent-dim:rgba(86,131,218,.14);
  --orb-glow:86,131,218;
  --orb-stops:#0D1B33,#3E6ED2,#5683DA,#A8C8F5,#FFFFFF;
}
/* Abyss - Auros: deep teal-green canvas, bioluminescent water. */
:root[data-theme="abyss"]{
  --bg:#011D1C; --bg-2:#012624; --bg-3:#003734;
  --ink:#EDFFFE; --dim:#BBC7C6; --faint:#707777;
  --accent:#00A79E; --on-accent:#00201F; --accent-dim:rgba(0,167,158,.16);
  --line:rgba(237,255,254,.10); --line-strong:rgba(237,255,254,.18);
  --orb-glow:0,130,124;
  --orb-stops:#002E2C,#00857D,#00A79E,#7FE9E0,#FFFFFF;
}
/* Platinum - no colour at all: cool white on near-black, the accent
   is light itself. The most restrained and arguably most expensive. */
:root[data-theme="platinum"]{
  --bg:#090909; --bg-2:#0F0F10; --bg-3:#161617;
  --ink:#F7F9FA; --dim:#A9A9AA; --faint:#6B6B6B;
  --accent:#D6DEE8; --on-accent:#0A0A0B; --accent-dim:rgba(214,222,232,.12);
  --orb-glow:190,205,222;
  --orb-stops:#20262E,#6C7A8B,#A8B4C2,#D6DEE8,#FFFFFF;
}

/* ═══ base ═══ */
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  background:var(--bg); color:var(--ink);
  font-family:var(--font-ui); font-size:var(--fs-body); line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
::selection{background:var(--accent); color:var(--on-accent)}
img,canvas,svg,video{display:block; max-width:100%}
a{color:inherit; text-decoration:none}

/* Shadows are banned. This is load-bearing: every reference system
   states it outright ("shadowless by design"). If something needs
   lift, give it --bg-2 and a --line border. */
*{box-shadow:none !important}

/* ═══ type voices ═══ */
.display{
  font-size:var(--fs-display); line-height:var(--lh-display);
  letter-spacing:var(--track-display); font-weight:300; color:var(--ink);
}
.display b, .display strong{font-weight:500}   /* emphasis via a HALF step, not bold */
h2.h2, .h2{
  font-size:var(--fs-h2); line-height:var(--lh-tight);
  letter-spacing:var(--track-tight); font-weight:350;
}
.lede{
  font-size:var(--fs-lede); line-height:var(--lh-body);
  color:var(--dim); max-width:52ch; font-weight:400;
}
/* Labels are SANS, not monospace. A small tracked monospace caption is
   the single most over-used tell in machine-made layouts, and wrapping
   it in brackets doubles it. Founder call: the numbered index in front
   of each label ("01 How it works") was a second tell of the same kind,
   so labels are now plain words. Nothing on this site is numbered. */
.label{
  font-family:var(--font-ui); font-size:11px;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--faint); font-weight:500;
  display:flex; align-items:baseline; gap:10px;
}
.label .tick{color:var(--accent)}

/* ═══ controls ═══
   Founder rule: a button's label is FULL INK at all times. Text that
   starts grey and brightens on hover reads as disabled until you touch
   it, and a call to action that looks disabled is a bug. So the hover
   signal is a RING drawn around the whole button - `outline` with an
   offset, which sits outside the box and therefore cannot shift layout
   the way a border that appears would. Colour never carries the state. */
.btn{
  display:inline-flex; align-items:center; gap:var(--s2);
  font-size:var(--fs-small); font-weight:500; letter-spacing:.01em;
  padding:14px 26px; border-radius:var(--r-pill);
  outline:1px solid transparent; outline-offset:3px;
  transition:background var(--t-fast) var(--ease-out),
             border-color var(--t-fast) var(--ease-out),
             outline-color var(--t-fast) var(--ease-out),
             outline-offset var(--t-fast) var(--ease-out),
             transform var(--t-fast) var(--ease-out);
}
/* The button lifts toward the cursor as the ring forms, then presses
   back down on the click. Physical, and it makes the ring read as a
   consequence of reaching the button rather than a colour change.

   The lift is MOVEMENT ONLY. No drop shadow under it, ever: every
   reference system we studied bans shadows outright, and a lifted
   button with a soft shadow under it is one of the loudest tells that
   a page came out of a builder. 2px is deliberately small. Enough to
   feel, not enough to notice as an animation. */
.btn:hover, .btn:focus-visible{outline-color:var(--line-strong); outline-offset:5px;
  transform:translateY(-2px)}
/* pressed: it goes back down and the ring tightens onto it. Faster than
   the lift, because a click should feel immediate while a hover can
   afford to glide. */
.btn:active{transform:translateY(0); outline-offset:3px;
  transition-duration:70ms}

.btn-solid{background:var(--accent); color:var(--on-accent)}
.btn-solid:hover, .btn-solid:focus-visible{outline-color:var(--accent)}

.btn-ghost{border:1px solid var(--line-strong); color:var(--ink)}
.btn-ghost:hover, .btn-ghost:focus-visible{border-color:var(--ink); background:var(--bg-2)}

/* Somebody who has asked their machine to stop animating things still
   gets the ring, which is the part that carries the meaning. They just
   do not get the movement. */
@media (prefers-reduced-motion: reduce){
  .btn, .btn:hover, .btn:focus-visible, .btn:active{transform:none}
}

/* ═══ surfaces ═══ */
.card{
  background:var(--bg-2); border:1px solid var(--line);
  border-radius:var(--r-card);
}

/* CLEAR glass - a pane you read through, not a frosted slab.
   The v1 site's glass was 26px blur + travelling glare + pointer
   tilt; that reads as a gimmick. This is one plate of window. */
.glass{
  position:relative;
  background:var(--glass-film);
  backdrop-filter:blur(var(--glass-blur));
  -webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-edge);
  border-radius:var(--r-card);
}
/* the bevel catch: one hairline of light along the top edge */
.glass::before{
  content:''; position:absolute; inset:0 0 auto 0; height:1px;
  border-radius:var(--r-card) var(--r-card) 0 0;
  background:linear-gradient(90deg, transparent, var(--glass-bevel) 22%,
             var(--glass-bevel) 78%, transparent);
  pointer-events:none;
}
/* on glass, content sits above the bevel line */
.glass > *{position:relative}

/* ═══ layout ═══ */
.wrap{width:min(1240px, 100% - clamp(40px, 6vw, 96px)); margin-inline:auto}
.section{padding-block:var(--s10)}
