/* Codify AI theme for the console.
 *
 * Overrides LibreChat's design tokens rather than fighting its utility classes,
 * so this survives upstream updates and needs no fork. Tokens are
 * space-separated RGB triplets consumed as rgb(var(--token)), so every override
 * must use that same form — a hex value here silently breaks the alpha variants
 * (rgb(var(--x) / 0.5)) that LibreChat uses throughout.
 *
 * The token names below were read off the running app, not guessed. An earlier
 * pass overrode only --accent-primary, which left the primary submit button
 * green: it resolves --surface-submit, a separate semantic token pointing at
 * --green-700. Recolouring a design system means recolouring the whole ramp;
 * a half-mapped palette reads as broken rather than restrained.
 *
 * Layout is deliberately untouched. Colour, type, radius and elevation are safe
 * to restyle across releases. Moving boxes is not.
 */

/* ---------------------------------------------------------------- palette --
 * One cool, slightly violet-tinted neutral ramp. LibreChat ships pure neutral
 * greys; mixing those with a violet-tinted background is what made the first
 * attempt look off. Steps are spaced so adjacent surfaces stay distinguishable
 * without hard edges.
 */
:root {
  --codify-violet-400: 160 140 255;
  --codify-violet-500: 141 118 255;
  --codify-violet-600: 111 88 250;
  --codify-violet-700: 96 64 240; /* the mark */
  --codify-violet-800: 82 52 214;
  --codify-violet-900: 60 36 180;

  --font-family-sans: 'Inter var', 'Inter', -apple-system, BlinkMacSystemFont,
    'SF Pro Text', 'Segoe UI', system-ui, sans-serif;
}

/* ----------------------------------------------------------- light theme --
 * Kept coherent with dark so switching themes is not a different product.
 *
 * Light must be declared BEFORE dark. `:root` and `.dark` carry identical
 * specificity, so whichever block is written last wins on an element matching
 * both — and <html> in dark mode matches both. With dark first, every surface
 * resolved to its light value while the app was in dark mode. The dark block
 * additionally qualifies as `:root.dark` so it outranks `:root` on specificity
 * too, and this cannot silently regress if the blocks are ever reordered.
 */
:root,
:root[data-theme='light'] {
  --surface-primary: 255 255 255;
  --surface-primary-alt: 250 250 253;
  --surface-primary-contrast: 244 244 249;
  --surface-secondary: 248 248 251;
  --surface-secondary-alt: 242 242 247;
  --surface-tertiary: 242 242 247;
  --surface-tertiary-alt: 234 234 241;

  --surface-chat: 248 248 251;
  --surface-dialog: 255 255 255;
  --surface-code: 245 245 250;
  --presentation: 255 255 255;

  --surface-hover: 238 238 245;
  --surface-hover-alt: 230 230 239;
  --surface-active: 222 222 233;
  --surface-active-alt: 238 238 245;
  --surface-composer-hover: 238 238 245;

  --surface-submit: var(--codify-violet-700);
  --surface-submit-hover: var(--codify-violet-800);
  --text-on-status: 255 255 255;

  --border-light: 232 232 239;
  --border-medium: 218 218 228;
  --border-medium-alt: 218 218 228;
  --border-heavy: 168 168 183;
  --border-xheavy: 120 120 138;

  --text-primary: 24 24 32;
  --text-secondary: 76 76 92;
  --text-secondary-alt: 116 116 134;
  --text-tertiary: 116 116 134;
  --text-muted: 116 116 134;

  --header-primary: 255 255 255;
  --header-hover: 238 238 245;
  --header-button-hover: 238 238 245;

  --accent-primary: var(--codify-violet-700);
  --accent-primary-hover: var(--codify-violet-800);
  --brand-purple: var(--codify-violet-700);
  --ring-primary: var(--codify-violet-700);

  --link: var(--codify-violet-800);
  --link-hover: var(--codify-violet-900);
  --link-visited: var(--codify-violet-800);
}

/* ------------------------------------------------------------ dark theme --
 * The default for this console.
 */
:root.dark,
:root[data-theme='dark'] {
  /* Surfaces, darkest to lightest. */
  --surface-primary: 12 12 16;
  --surface-primary-alt: 17 17 23;
  --surface-primary-contrast: 22 22 29;
  --surface-secondary: 17 17 23;
  --surface-secondary-alt: 28 28 37;
  --surface-tertiary: 22 22 29;
  --surface-tertiary-alt: 36 36 47;

  --surface-chat: 17 17 23;
  --surface-dialog: 22 22 29;
  --surface-code: 24 24 32;
  --presentation: 17 17 23;

  --surface-hover: 36 36 47;
  --surface-hover-alt: 45 45 58;
  --surface-active: 55 55 71;
  --surface-active-alt: 36 36 47;
  --surface-composer-hover: 45 45 58;

  /* The primary call to action. Stock LibreChat ships this green. */
  --surface-submit: 111 88 250;
  --surface-submit-hover: 132 112 255;
  --text-on-status: 255 255 255;

  --surface-inverted: 240 240 246;
  --surface-inverted-hover: 222 222 232;

  /* Borders: low contrast, cool. Visible enough to separate, quiet enough
     not to draw the eye before the content does. */
  --border-light: 32 32 42;
  --border-medium: 45 45 58;
  --border-medium-alt: 45 45 58;
  --border-heavy: 72 72 90;
  --border-xheavy: 110 110 132;

  --text-primary: 238 238 244;
  --text-secondary: 190 190 202;
  --text-secondary-alt: 140 140 156;
  --text-tertiary: 140 140 156;
  --text-muted: 140 140 156;
  --text-inverted: 22 22 29;

  --header-primary: 17 17 23;
  --header-hover: 36 36 47;
  --header-button-hover: 36 36 47;

  --accent-primary: var(--codify-violet-500);
  --accent-primary-hover: var(--codify-violet-400);
  --brand-purple: var(--codify-violet-500);
  --ring-primary: var(--codify-violet-600);

  --link: var(--codify-violet-400);
  --link-hover: 180 165 255;
  --link-visited: var(--codify-violet-400);
}

/* ------------------------------------------------------------ typography -- */
body,
button,
input,
textarea,
select {
  font-family: var(--font-family-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Optical correction: tighten only the large sizes. Applying negative tracking
   to body text hurts legibility at 14px. */
h1, h2, h3, h4,
.text-xl, .text-2xl, .text-3xl {
  letter-spacing: -0.018em;
}

/* ---------------------------------------------------------------- shape --
 * Rounder than stock, which is most of the difference between "utilitarian"
 * and "modern". Scoped to the utility classes LibreChat actually uses so
 * component geometry stays predictable.
 */
.rounded-md { border-radius: 0.5rem; }
.rounded-lg { border-radius: 0.7rem; }
.rounded-xl { border-radius: 0.9rem; }
.rounded-2xl { border-radius: 1.1rem; }
.rounded-3xl { border-radius: 1.4rem; }

/* ------------------------------------------------------------ elevation --
 * Floating surfaces get depth from shadow rather than from a brighter fill,
 * so the palette stays flat and calm while menus still read as "above".
 */
[role='dialog'],
[role='menu'],
[role='listbox'],
[data-radix-popper-content-wrapper] > * {
  box-shadow:
    0 0 0 1px rgb(var(--border-light) / 0.9),
    0 12px 32px -8px rgb(0 0 0 / 0.45),
    0 4px 12px -4px rgb(0 0 0 / 0.3);
}

/* --------------------------------------------------------------- motion --
 * Short and eased, on cheap properties only so nothing janks mid-stream.
 */
button,
a,
[role='button'],
[role='menuitem'] {
  transition:
    background-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    border-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    opacity 140ms cubic-bezier(0.4, 0, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {
  button,
  a,
  [role='button'],
  [role='menuitem'] {
    transition: none;
  }
}

/* Focus ring in the brand colour, and never removed — it is the only cursor a
   keyboard user has. */
:focus-visible {
  outline: 2px solid rgb(var(--accent-primary));
  outline-offset: 2px;
}

/* ----------------------------------------------------------- scrollbars -- */
* {
  scrollbar-width: thin;
  scrollbar-color: rgb(var(--border-heavy) / 0.6) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background-color: rgb(var(--border-heavy) / 0.55);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover {
  background-color: rgb(var(--border-heavy) / 0.85);
}
