/* aesyna.css — the Aesyna brand material, light and motion layer.  AESYNA_LAYER_VERSION 1.0.1
 *
 * SSOT: syna-theme-kit/css/aesyna.css. Hosts take a BYTE COPY (npm run sync-aesyna) — never @import across repos.
 * Contract + reasoning: docs/AESYNA-BRAND.md. Every number below is lifted from the real Aesyna source
 * (www/aesyna styles.css · app.js · field.js) or is a documented extension; change it here, never in a host.
 *
 * What this file is: brand TOKENS and RECIPES (whole box-shadow / gradient / transition values held in custom
 * properties) plus a few opt-in primitives. Hosts bind recipes to their own selectors in their own chrome sheet.
 * What it is not: the standard kit tokens (--bg-*, --accent-*, --glass-*) — those come from the aesyna skin JSON
 * through the host theme loader, which writes them inline on :root and therefore always wins over a stylesheet.
 *
 * Scope: everything is gated on :root[data-skin-family="aesyna"], so every other skin is untouched.
 */

/* ── 1. Motion signature — global on purpose: curves are brand, not skin ─────────────────────────────── */
:root {
  --ae-ease: cubic-bezier(.4, 0, .2, 1);          /* LIGHT: opacity, colour, fill, shadow */
  --ae-glide: cubic-bezier(.16, 1, .3, 1);        /* MASS: every translate / scale / height. Long silk tail. */
  --ae-spring: cubic-bezier(.34, 1.56, .64, 1);   /* ARRIVAL: selection + confirmation only. One overshoot. */

  /* Instrument tempo (work chrome). Site tempo is 2–2.6× slower and is for hero/marketing surfaces only. */
  --ae-t-press: 150ms;      /* :active, toggles              (Aesyna --fast)   */
  --ae-t-state: 300ms;      /* hover, colour, selection fill  (Aesyna --normal) */
  --ae-t-fade: 300ms;       /* a surface's light arriving                      */
  --ae-t-travel: 420ms;     /* a surface's mass arriving      (Aesyna FAQ height: 420ms on glide) */
  --ae-t-settle: 700ms;     /* spring settle on selection     (Aesyna loop node: 700ms on spring) */
  --ae-t-exit-fade: 200ms;  /* exits run ≈ .66× of entrances  (Aesyna rotor 380/520, 480/720)    */
  --ae-t-exit-travel: 280ms;
  --ae-stagger: 45ms;       /* siblings never arrive together (Aesyna cards 45ms · reveals 70ms) */
  --ae-stagger-cap: 6;
  --ae-rise: 14px;          /* entrance offset                (Aesyna caption 14px · reveal 28px) */

  /* Pointer-driven smoothing: k = 1 − rate^dt  (frame-rate independent). Read by effects/pointerLight.ts. */
  --ae-light-rate: .002;        /* glow in/out, half-life ≈ 110ms   (Aesyna tilt()) */
  --ae-light-track-rate: 1e-7;  /* light position, half-life ≈ 43ms (Aesyna cursor dot) */
  --ae-press-rate: .02;         /* press bloom decay, half-life ≈ 177ms */

  /* Recipes every skin may use */
  --ae-tr-state: background-color var(--ae-t-state) var(--ae-ease), color var(--ae-t-state) var(--ae-ease),
    border-color var(--ae-t-state) var(--ae-ease), box-shadow var(--ae-t-state) var(--ae-ease),
    opacity var(--ae-t-state) var(--ae-ease);
  --ae-tr-mass: transform var(--ae-t-travel) var(--ae-glide);
  --ae-tr-arrive: transform var(--ae-t-settle) var(--ae-spring);
}

/* ── 2. Hue logic + surfaces (dark is the hero mode; Aesyna itself has no light mode) ─────────────────── */
:root[data-skin-family="aesyna"] {
  /* Hues follow the active accent palette so a palette swap re-lights the glass instead of fighting it.
     With the `aesyna` palette these resolve to the site's exact values. */
  --ae-violet: var(--accent-purple, #a855f7);   /* KEY light — enters upper-left */
  --ae-indigo: var(--accent-indigo, #6366f1);   /* selection body */
  --ae-blue:   var(--accent-blue, #4f7bff);
  --ae-ice:    var(--accent-cyan, #4de8ff);     /* SIGNAL: focus, selection ring, kickers, links */
  --ae-rose:   var(--accent-pink, #e879f9);     /* rare warmth; never structural */
  --ae-mint:   var(--accent-teal, #5dffc1);     /* live / healthy */
  --ae-sky: #12b0ff;                            /* FILL light — lower-right; gradient tail only */

  --ae-grad: linear-gradient(100deg, #b26bff 0%, #6f7dff 48%, #1fb6ff 100%);          /* text + hairline accents */
  --ae-grad-action: linear-gradient(100deg, #8b3dff, #4f6dff 55%, #0fa2f5);          /* THE primary action */

  --ae-ink: #e8ecf8; --ae-ink-2: #a3acc6; --ae-ink-3: #7d86a6;   /* ink-3 lifted from site #6b7493 → AA-large on panels */
  --ae-ink-hot: #ffffff;

  --ae-void: #05050c;        /* app floor: what shows in the gutters between capsules */
  --ae-surface: #0e0c16;     /* glass tint source (kit --bg-primary) */
  --ae-solid: #100e1c;       /* opaque fallback for any glass */
  --ae-raised: #14112a;
  --ae-well: #0a0918;        /* recessed: inputs, tracks, code wells */

  /* Static glass — the default panel. No backdrop-filter: costs nothing per frame. Lit from upper-left. */
  --ae-panel-fill: linear-gradient(160deg, #17143a 0%, #100e24 38%, #0c0a1c 100%);
  --ae-panel-fill-raised: linear-gradient(160deg, #1d1947 0%, #14112c 42%, #0e0c20 100%);
  --ae-header-fill: linear-gradient(180deg, rgb(255 255 255 / .045), rgb(255 255 255 / 0) 100%);

  /* Live glass — hero layers only (menus, popovers, dialogs, toasts, floating bars). Budget: ≤ 3 in view. */
  --ae-live-fill: color-mix(in oklab, var(--ae-surface) 72%, transparent);   /* thick tier: dense text */
  --ae-live-fill-regular: color-mix(in oklab, var(--ae-surface) 64%, transparent);
  --ae-live-filter: blur(22px) saturate(140%);

  /* Rim: top light · hairline edge · bottom bounce. Two strengths, both straight from the site. */
  --ae-rim-hero: inset 0 1px 0 rgb(255 255 255 / .26), inset 0 0 0 1px rgb(255 255 255 / .13), inset 0 -1px 0 rgb(255 255 255 / .05);
  --ae-rim-panel: inset 0 1px 0 rgb(255 255 255 / .16), inset 0 0 0 1px rgb(255 255 255 / .08);
  --ae-rim-control: inset 0 0 0 1px rgb(255 255 255 / .16);
  --ae-rim-control-hot: inset 0 0 0 1px rgb(255 255 255 / .40);
  /* Gradient stroke: violet where the key light lands, clear through the middle, sky where the fill catches. */
  --ae-stroke: linear-gradient(135deg, color-mix(in oklab, var(--ae-violet) 70%, transparent), transparent 35%, transparent 65%, color-mix(in oklab, var(--ae-sky) 70%, transparent));
  --ae-stroke-opacity: .7;

  /* Pointer light: a 340px pool that follows the hand; --glow/--press are LERPed by pointerLight.ts.
     TRAP: the gradient must be written inline in the rule that paints it (see .ae-lit below and
     AESYNA-BRAND.md § 3) — a custom property holding var(--mx) would bake :root's fallback. */
  --ae-light-size: 340px;
  --ae-light-h: 250;
  --ae-light-l: 78%;
  --ae-light-a: .26;   /* hover alpha at full glow */
  --ae-press-a: .30;   /* extra alpha at full press */

  /* State light */
  --ae-hover-fill: rgb(255 255 255 / .04);        /* rows */
  --ae-hover-fill-strong: rgb(255 255 255 / .08); /* pills, tabs */
  --ae-ghost-fill: rgb(255 255 255 / .05);
  --ae-ghost-fill-hot: rgb(255 255 255 / .10);
  --ae-hairline: rgb(255 255 255 / .08);
  --ae-selected-fill: color-mix(in oklab, var(--ae-indigo) 34%, transparent);
  --ae-selected-ring: inset 0 0 0 1px color-mix(in oklab, var(--ae-ice) 60%, transparent);
  --ae-selected-glow: 0 0 26px color-mix(in oklab, var(--ae-indigo) 34%, transparent);
  --ae-open-ring: inset 0 0 0 1px color-mix(in oklab, var(--ae-ice) 34%, transparent);
  --ae-focus-ring: 2px solid var(--ae-ice);
  --ae-focus-offset: 2px;

  /* Lift is LIGHT BLEED, not black shadow: coloured, wide, negative spread. */
  --ae-lift-float: 0 24px 80px -24px #2b2bff66, 0 8px 24px -12px rgb(0 0 0 / .6);
  --ae-lift-action: 0 10px 40px -10px #5b5bffaa;
  --ae-lift-action-hot: 0 14px 60px -8px #6f6fffee, 0 0 30px #12b0ff55;
  --ae-scrim: rgb(3 3 10 / .62);

  /* Floor: the aurora the glass is glass *to* (site body::before). Painted once, never animated. */
  --ae-floor:
    radial-gradient(60vmax 50vmax at 18% 12%, #4c1d95aa, transparent 60%),
    radial-gradient(55vmax 55vmax at 85% 30%, #1d4ed877, transparent 62%),
    radial-gradient(60vmax 40vmax at 50% 100%, #0e7490aa, transparent 60%),
    var(--ae-void);
  --ae-grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  --ae-grain-opacity: .07;

  /* Radii + rhythm. Site: 28 / 20 / 14 / pill. Instrument chrome steps each role down one notch. */
  --ae-r-surface: 20px; --ae-r-component: 14px; --ae-r-control: 10px; --ae-r-chip: 6px; --ae-r-pill: 999px;
  --ae-gap: 6px;           /* capsule gutter (UI-PROTOCOL capsule-panels) */
  --ae-row: 28px;          /* list / tree / inspector row: one height everywhere */
  --ae-pad: 12px;

  /* Type voice */
  --ae-display: 'Quicksand', 'Outfit', 'Manrope', system-ui, sans-serif;
  --ae-body: 'Manrope', 'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ae-track-label: .2em;    /* 10.5–11.5px uppercase labels */
  --ae-track-kicker: .34em;  /* section kickers, panel titles */
  --ae-track-body: .005em;
}

:root[data-skin-family="aesyna"][data-theme="light"] {
  /* Extension — the site has no light mode. Cool lavender paper (kit no-brown rule), violet ink, same light model. */
  --ae-ink: #1a1430; --ae-ink-2: #4a4668; --ae-ink-3: #6c6890; --ae-ink-hot: #0d0a1f;
  --ae-void: #dcd9f0; --ae-surface: #f4f2fc; --ae-solid: #f7f5fd; --ae-raised: #ffffff; --ae-well: #ebe8f7;
  --ae-sky: #0284d8;
  --ae-panel-fill: linear-gradient(160deg, #ffffff 0%, #f6f3fe 40%, #efecfa 100%);
  --ae-panel-fill-raised: linear-gradient(160deg, #ffffff 0%, #fbfaff 45%, #f4f1fd 100%);
  --ae-header-fill: linear-gradient(180deg, rgb(255 255 255 / .7), rgb(255 255 255 / 0) 100%);
  --ae-live-fill: color-mix(in oklab, #f7f5fd 78%, transparent);
  --ae-live-fill-regular: color-mix(in oklab, #f7f5fd 66%, transparent);
  --ae-rim-hero: inset 0 1px 0 rgb(255 255 255 / .95), inset 0 0 0 1px rgb(60 40 140 / .12), inset 0 -1px 0 rgb(60 40 140 / .06);
  --ae-rim-panel: inset 0 1px 0 rgb(255 255 255 / .9), inset 0 0 0 1px rgb(60 40 140 / .09);
  --ae-rim-control: inset 0 0 0 1px rgb(60 40 140 / .18);
  --ae-rim-control-hot: inset 0 0 0 1px rgb(60 40 140 / .42);
  --ae-stroke-opacity: .55;
  --ae-light-l: 66%; --ae-light-a: .14; --ae-press-a: .18;
  --ae-hover-fill: rgb(60 40 140 / .05); --ae-hover-fill-strong: rgb(60 40 140 / .09);
  --ae-ghost-fill: rgb(60 40 140 / .05); --ae-ghost-fill-hot: rgb(60 40 140 / .10);
  --ae-hairline: rgb(60 40 140 / .10);
  --ae-selected-fill: color-mix(in oklab, var(--ae-indigo) 16%, transparent);
  --ae-selected-glow: 0 0 22px color-mix(in oklab, var(--ae-indigo) 20%, transparent);
  --ae-lift-float: 0 24px 80px -28px #4b3bd655, 0 8px 24px -14px rgb(40 30 90 / .25);
  --ae-scrim: rgb(30 24 60 / .38);
  --ae-floor:
    radial-gradient(60vmax 50vmax at 18% 12%, #c4b5fd66, transparent 60%),
    radial-gradient(55vmax 55vmax at 85% 30%, #93c5fd59, transparent 62%),
    radial-gradient(60vmax 40vmax at 50% 100%, #a5f3fc66, transparent 60%),
    var(--ae-void);
  --ae-grain-opacity: .04;
}

/* ── 3. Opt-in primitives (hosts may also bind the recipes to their own selectors) ───────────────────── */

/* The floor: put on the app root. One paint; the grain is a fixed, non-interactive pseudo-element. */
:root[data-skin-family="aesyna"] .ae-floor { background: var(--ae-floor); }
:root[data-skin-family="aesyna"] .ae-floor::after {
  content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: var(--ae-grain-opacity); background-image: var(--ae-grain);
}

/* Static glass panel + its two light layers. ::before = pointer light, ::after = gradient stroke.
   The mask lives on the stroke, never on a backdrop-filtered pane (exp-glass-ui §6). */
:root[data-skin-family="aesyna"] .ae-glass {
  position: relative; isolation: isolate; border: 0; border-radius: var(--ae-r-component);
  background: var(--ae-panel-fill); box-shadow: var(--ae-rim-panel);
}
:root[data-skin-family="aesyna"] .ae-glass::before,
:root[data-skin-family="aesyna"] .ae-lit::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: -1;
  background: radial-gradient(var(--ae-light-size) circle at var(--mx, 50%) var(--my, 0%),
    hsl(var(--ae-light-h) 100% var(--ae-light-l) / calc(var(--glow, 0) * var(--ae-light-a) + var(--press, 0) * var(--ae-press-a))), transparent 62%);
}
/* Paste this layer as the FIRST background image of any rule that should catch the light:
   background: radial-gradient(var(--ae-light-size) circle at var(--mx, 50%) var(--my, 0%), hsl(var(--ae-light-h) 100% var(--ae-light-l) / calc(var(--glow, 0) * var(--ae-light-a) + var(--press, 0) * var(--ae-press-a))), transparent 62%), <fill>; */
:root[data-skin-family="aesyna"] .ae-glass::after,
:root[data-skin-family="aesyna"] .ae-stroked::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; z-index: -1;
  background: var(--ae-stroke); opacity: var(--ae-stroke-opacity);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
:root[data-skin-family="aesyna"] .ae-lit, :root[data-skin-family="aesyna"] .ae-stroked { position: relative; isolation: isolate; }

/* Live glass: solid first, blur only where the engine supports it, never for users who asked for less. */
:root[data-skin-family="aesyna"] .ae-glass--live { background: var(--ae-solid); box-shadow: var(--ae-rim-hero), var(--ae-lift-float); border-radius: var(--ae-r-surface); }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root[data-skin-family="aesyna"] .ae-glass--live {
    background: var(--ae-live-fill); -webkit-backdrop-filter: var(--ae-live-filter); backdrop-filter: var(--ae-live-filter);
  }
}

/* ── 4. Motion primitives. Light leads, mass follows, nothing snaps. ─────────────────────────────────── */
@keyframes ae-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ae-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes ae-rise-in { from { transform: translate3d(0, var(--ae-rise), 0); } to { transform: none; } }
@keyframes ae-drop-in { from { transform: translate3d(0, calc(var(--ae-rise) * -1), 0); } to { transform: none; } }
@keyframes ae-grow-in { from { transform: scale(.94); } to { transform: none; } }     /* grows from its opener: set transform-origin */
@keyframes ae-grow-out { from { transform: none; } to { transform: scale(.96); } }
@keyframes ae-arrive { from { transform: scale(.9); } to { transform: none; } }       /* use with --ae-spring */
@keyframes ae-breathe { 50% { opacity: .35; } }                                       /* live dot, 2.4s */
@keyframes ae-sweep { from { transform: translate3d(-100%, 0, 0); } to { transform: translate3d(100%, 0, 0); } }

:root[data-skin-family="aesyna"] .ae-enter {            /* surfaces: menus, popovers, toasts, dialogs */
  animation: ae-fade-in var(--ae-t-fade) var(--ae-ease) both, ae-grow-in var(--ae-t-travel) var(--ae-glide) both;
}
:root[data-skin-family="aesyna"] .ae-enter-rise {       /* content arriving inside a surface */
  animation: ae-fade-in var(--ae-t-fade) var(--ae-ease) both, ae-rise-in var(--ae-t-travel) var(--ae-glide) both;
  animation-delay: calc(min(var(--i, 0), var(--ae-stagger-cap)) * var(--ae-stagger));
}
:root[data-skin-family="aesyna"] .ae-exit {
  animation: ae-fade-out var(--ae-t-exit-fade) var(--ae-ease) both, ae-grow-out var(--ae-t-exit-travel) var(--ae-ease) both;
}

/* ── 5. Accessibility fallbacks ──────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  /* Keep every state change; drop the travel. Light still fades — it is feedback, not motion. */
  :root { --ae-t-travel: 1ms; --ae-t-settle: 1ms; --ae-t-exit-travel: 1ms; --ae-rise: 0px; --ae-stagger: 0ms; }
  :root[data-skin-family="aesyna"] .ae-enter, :root[data-skin-family="aesyna"] .ae-enter-rise { animation: ae-fade-in var(--ae-t-fade) linear both; }
  :root[data-skin-family="aesyna"] .ae-exit { animation: ae-fade-out var(--ae-t-exit-fade) linear both; }
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  :root[data-skin-family="aesyna"] .ae-glass--live { background: var(--ae-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
  :root[data-skin-family="aesyna"] { --ae-live-fill: var(--ae-solid); --ae-live-fill-regular: var(--ae-solid); --ae-live-filter: none; --ae-grain-opacity: 0; }
}
@media (forced-colors: active) {
  :root[data-skin-family="aesyna"] .ae-glass, :root[data-skin-family="aesyna"] .ae-glass--live { background: Canvas; border: 1px solid CanvasText; -webkit-backdrop-filter: none; backdrop-filter: none; }
  :root[data-skin-family="aesyna"] .ae-glass::before, :root[data-skin-family="aesyna"] .ae-glass::after { display: none; }
}
