@import "tailwindcss";
@plugin "@tailwindcss/typography";

/*
 * Tailwind v4 defaults the `dark:` variant to `prefers-color-scheme: dark`.
 * Our theme switcher writes `data-theme="dark"` on <html> instead (so user
 * choice via the toggle wins over OS preference). Re-bind `dark:` to that
 * attribute so component classes like `dark:bg-zinc-800` track the same
 * source of truth as the `[data-theme="dark"]` token overrides below.
 */
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));

/*
 * Load order:
 *   1. Tailwind core (v4) — provides preflight + utility generation.
 *   2. xterm — overrides preflight on its own .xterm-* class names; must
 *      load AFTER tailwind so its specificity wins.
 *   3. theme-tokens.css — canvas-only motion + deploy animation vars
 *      (--mol-duration-*, --mol-easing-*, --mol-deploy-*). NOT colour
 *      tokens; the warm-paper @theme block below owns those.
 *   4. settings-panel.css / org-deploy.css — feature stylesheets that
 *      reference the variables above.
 */
@import "xterm/css/xterm.css";
@import "../styles/theme-tokens.css";
@import "../styles/settings-panel.css";
@import "../styles/org-deploy.css";

/*
 * Warm-paper semantic tokens — light defaults via @theme, dark
 * overrides via [data-theme="dark"]. Names are role-based
 * (`bg-surface`, `text-ink`, `border-line`) not colour-based, so the
 * same component classes work in either mode.
 *
 * Source of truth: molecule-app/app/globals.css. Keep aligned across
 * surfaces (landing, market, app, canvas) so a token tweak ripples
 * everywhere via a single PR per repo.
 *
 * Theme preference is persisted in the `mol_theme` cookie scoped to
 * Domain=.moleculesai.app so the choice follows the user across
 * subdomains. The inline boot script in app/layout.tsx applies it
 * before paint to eliminate flash.
 */
@theme {
  /* Surface — page / elevated card / sunken input / deep card */
  --color-surface: #fafaf7;
  --color-surface-elevated: #ffffff;
  --color-surface-sunken: #f3f1ec;
  --color-surface-card: #efece4;

  /* Borders */
  --color-line: #e6e2d8;
  --color-line-soft: #efece4;

  /* Text */
  --color-ink: #15181c;
  --color-ink-mid: #5a5e66;
  --color-ink-soft: #8b8e95;

  /* Brand + state */
  --color-accent: #3b5bdb;
  --color-accent-strong: #1a2f99;
  --color-warm: #c0532b;
  --color-good: #2f7a4d;
  --color-bad: #b94e4a;
}

[data-theme="dark"] {
  --color-surface: #0e1014;
  --color-surface-elevated: #15181c;
  --color-surface-sunken: #0a0b0e;
  --color-surface-card: #1a1d23;

  --color-line: #2a2f3a;
  --color-line-soft: #1f2329;

  --color-ink: #f4f1e9;
  --color-ink-mid: #c8c2b4;
  --color-ink-soft: #8d92a0;

  /* Accents brighten slightly for AA contrast on dark backgrounds. */
  --color-accent: #6883e8;
  --color-accent-strong: #8aa1ee;
  --color-warm: #d96f48;
  --color-good: #4ca06e;
  --color-bad: #d27773;
}

:root {
  color-scheme: light;
}
[data-theme="dark"] {
  color-scheme: dark;
}

/*
 * Always-dark surface tokens. Terminals (xterm), the console modal,
 * and log streams stay dark in both modes — readable green-on-black
 * code surfaces don't translate cleanly to a light theme. Components
 * that should not light-flip use `bg-bg`, `bg-bg-elev`, `bg-bg-card`,
 * `text-ink-mute`, `text-ink-dim`, `border-line-strong` instead of
 * the warm-paper utilities above.
 *
 * Distinct names (bg-* / ink-mute / ink-dim / line-strong) so they
 * don't collide with the warm-paper namespace (surface / ink /
 * line). Both palettes coexist; the choice between them is per
 * component, not per theme.
 */
@theme {
  --color-bg: rgb(9 9 11);            /* zinc-950 */
  --color-bg-elev: rgb(24 24 27);     /* zinc-900 */
  --color-bg-card: rgb(39 39 42);     /* zinc-800 */
  --color-line-strong: rgb(63 63 70); /* zinc-700 */
  --color-ink-mute: rgb(161 161 170); /* zinc-400 */
  --color-ink-dim: rgb(113 113 122);  /* zinc-500 */
  --color-accent-dim: rgb(96 165 250);/* blue-400 */
  --color-plasma: rgb(59 130 246);    /* blue-500 */
  --color-warn: rgb(251 191 36);      /* amber-400 */
}

body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: var(--color-surface);
  color: var(--color-ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* React Flow overrides for both themes. Edge stroke pulls from the
   semantic line token so dark mode keeps its existing zinc-700 look
   and light mode picks up the warm-paper line colour. */
.react-flow__edge-path {
  stroke: var(--color-line) !important;
  stroke-width: 1.5 !important;
}

.react-flow__edge.animated .react-flow__edge-path {
  stroke-dasharray: 5;
  animation: dashdraw 0.5s linear infinite;
}

@keyframes dashdraw {
  to {
    stroke-dashoffset: -10;
  }
}

.react-flow__handle {
  transition: all 0.15s ease;
}

.react-flow__node {
  /* Transform transition drives the "spawn from parent" motion —
     org-deploy sets the node's initial position to the parent's
     absolute coords, then repositions to the real slot, and this
     transition interpolates the translate() in between.
     Non-deploy workspace moves (drag, nest) get the same smoothing
     for free. */
  transition:
    box-shadow var(--mol-duration-fast) ease,
    transform var(--mol-duration-spawn) var(--mol-easing-bounce-out);
}
/* Drag events must feel instant — React Flow adds this class
   for the lifetime of the gesture. */
.react-flow__node.dragging {
  transition: box-shadow var(--mol-duration-fast) ease;
}

/* Scrollbar styling. Track + thumb pull from the surface tokens so
   they feel native to either theme. */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--color-line);
  border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--color-line-strong, var(--color-ink-soft));
}

/* Selection */
::selection {
  background: color-mix(in srgb, var(--color-accent) 30%, transparent);
}

/* Panel slide animation */
@keyframes slide-in-from-right {
  from { transform: translateX(100%); }
  to { transform: translateX(0); }
}

@keyframes slide-in-from-bottom {
  from { transform: translateY(10px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.slide-in-from-bottom {
  animation-name: slide-in-from-bottom;
}

@keyframes slide-in-from-top {
  from { transform: translateY(-10px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.slide-in-from-top {
  animation-name: slide-in-from-top;
}

.animate-in {
  animation-fill-mode: both;
}

.slide-in-from-right {
  animation-name: slide-in-from-right;
}

.duration-200 {
  animation-duration: 200ms;
}

/* Subtle node entrance */
@keyframes node-appear {
  from { opacity: 0; transform: scale(0.9); }
  to { opacity: 1; transform: scale(1); }
}

.react-flow__node {
  animation: node-appear 0.3s ease-out;
}

/* ============================================================
   REDUCED MOTION — WCAG 2.3.3
   Disable all animations/transitions for users who prefer it.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Custom slide-in / animate-in classes used by Toaster & ApprovalBanner */
  .animate-in,
  .slide-in-from-bottom,
  .slide-in-from-top,
  .slide-in-from-right {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
  }

  /* React Flow animated edges */
  .react-flow__edge.animated .react-flow__edge-path {
    animation: none !important;
    stroke-dasharray: none !important;
  }

  /* React Flow node appear animation */
  .react-flow__node {
    animation: none !important;
  }

  /* React Flow Controls toolbar buttons — WCAG 2.4.7 focus-visible */
  .react-flow__controls button:focus-visible {
    outline: 2px solid var(--accent, #3b5bdb);
    outline-offset: 2px;
  }

  /* React Flow Minimap nodes — WCAG 2.4.7 focus-visible */
  .react-flow__minimap:focus-visible,
  .react-flow__minimap svg:focus-visible {
    outline: 2px solid var(--accent, #3b5bdb);
    outline-offset: 2px;
  }
}
