/*
 * tokens.css — capture-kit design tokens (UX proposal §1).
 * Single dark theme. This file mirrors packages/capture-kit/src/*.ts 1:1;
 * a test in tests/css-parity.test.ts fails if the two drift apart.
 */

:root {
  /* Colors — §1.1 */
  --abysse: #05131F;
  --fond: #0B2433;
  --fond-2: #0E2C3E;
  --ecume: #EAF6F1;
  --brume: rgba(234, 246, 241, .60);
  --maree: #6FC7BC;
  --lumen: #7DF5D4;
  --corail: #F49E77;
  --ambre: #F0B454;
  --ion: #6EA8FF;
  --rose: #E87A96;
  --hairline: rgba(125, 245, 212, .14);

  /* Typography — §1.2 */
  --font-parle: 'Fraunces', ui-serif, Georgia, serif;
  --font-explique: 'Inter', ui-sans-serif, system-ui, sans-serif, 'Twemoji Mozilla';
  --font-mesure: 'IBM Plex Mono', ui-monospace, monospace, 'Twemoji Mozilla';
  --micro-label-size: 10px;
  --micro-label-tracking: .16em;

  /* Spacing — §1.3, 4pt grid, 20pt screen margins */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --screen-margin: 20px;

  /* Radius — §1.3, mode signal: capture = soft (rivage), analysis = tight (cockpit) */
  --radius-capture-min: 20px;
  --radius-capture-max: 24px;
  --radius-analysis-min: 6px;
  --radius-analysis-max: 8px;

  /* Motion — §1.4, tidal: slow, periodic, never soliciting */
  --breath: 7s ease-in-out infinite;
  --ripple: 3.2s ease-out infinite;
  --ripple-stagger: 800ms;
  --drift-1: 13s linear infinite;
  --drift-2: 21s linear infinite;
  --drift-3: 34s linear infinite;
  --glow-save: 400ms ease-out 1;
}

/* Self-hosted webfonts — §1.2. Fraunces (display, italic), Inter (UI), IBM
 * Plex Mono (measure). Variable-font files for Fraunces/Inter; four static
 * weights for IBM Plex Mono (no variable release upstream). font-display:
 * swap avoids an invisible-text flash; files are vendored under
 * ui/hub/public/fonts/ (SIL OFL 1.1, see LICENSE.txt there) and precached
 * by the service worker (ui/hub/src/sw.ts) for offline-first boot.
 */
@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/Fraunces.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/Fraunces-Italic.woff2') format('woff2');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

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

@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Italic.woff2') format('woff2');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/IBMPlexMono-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/IBMPlexMono-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/IBMPlexMono-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/IBMPlexMono-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* Self-hosted color emoji fallback (Twemoji Mozilla, COLR/CPAL) — emotion
 * chips (emotions.ts's `emotionPalette`) render real Unicode emoji glyphs;
 * without a bundled font, any client whose OS/browser has no system emoji
 * font renders them as tofu boxes. Declared as its own family (not merged
 * into --font-explique) and appended to every font-stack that can carry an
 * emoji character, so it only ever engages as a per-glyph fallback for
 * codepoints Inter/Fraunces/IBM Plex Mono don't cover — normal Latin text
 * in those fonts is completely unaffected.
 */
@font-face {
  font-family: 'Twemoji Mozilla';
  src: url('/fonts/Twemoji.woff2') format('woff2');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* Capture-vs-analysis radius rule (§1.3): one app, two textures. */
.capture-surface {
  border-radius: var(--radius-capture-min);
}

.analysis-surface {
  border-radius: var(--radius-analysis-min);
}

/* Motion keyframes — §1.4 */
@keyframes tk-breath {
  0%, 100% { opacity: .82; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.015); }
}

@keyframes tk-ripple {
  0% { opacity: .45; transform: scale(.92); }
  100% { opacity: 0; transform: scale(1.6); }
}

@keyframes tk-drift {
  0% { transform: translateX(0); }
  100% { transform: translateX(-33.333%); }
}

@keyframes tk-glow-save {
  0% { box-shadow: 0 0 0 0 rgba(111, 199, 188, 0); }
  30% { box-shadow: 0 0 24px 4px rgba(111, 199, 188, .55); }
  100% { box-shadow: 0 0 0 0 rgba(111, 199, 188, 0); }
}

.tk-breathe {
  animation: tk-breath var(--breath);
}

.tk-ripple {
  animation: tk-ripple var(--ripple);
}

.tk-ripple[data-layer='2'] {
  animation-delay: var(--ripple-stagger);
}

.tk-drift-1 { animation: tk-drift var(--drift-1); }
.tk-drift-2 { animation: tk-drift var(--drift-2); }
.tk-drift-3 { animation: tk-drift var(--drift-3); }

.tk-glow-save {
  animation: tk-glow-save var(--glow-save);
}

/* prefers-reduced-motion kill-switch — §1.4: "coupe tout." */
@media (prefers-reduced-motion: reduce) {
  .tk-breathe,
  .tk-ripple,
  .tk-drift-1,
  .tk-drift-2,
  .tk-drift-3,
  .tk-glow-save {
    animation: none !important;
  }
}
