/* Libra design tokens — the single source of truth for both the entry page and the workbench.
 *
 * Every page loads this file FIRST and then exactly one page stylesheet. Nothing here is
 * page-specific, and no page stylesheet may redefine a token: a second definition is how the
 * workbench ended up with eleven sheets overriding each other across six layers.
 *
 * Self-hosted assets only — no external fonts, icon packs or script CDNs, so a page load never
 * discloses a visitor to a third party and the strict CSP stays intact.
 */
@font-face {
  font-family: 'Space Grotesk';
  src: url('/fonts/space-grotesk-latin.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  src: url('/fonts/plus-jakarta-sans-latin.woff2') format('woff2');
  font-weight: 300 800; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('/fonts/source-serif-4-latin.woff2') format('woff2');
  font-weight: 200 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}

:root {
  /* ---- typography: one display face for headings and labels, one body face for prose ----
   * The CJK fallback is deliberate: the self-hosted subsets are latin-only, so Chinese text in
   * the workbench falls through to the system CJK face instead of shipping a 10 MB font. */
  --display: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
  --body: 'Plus Jakarta Sans', 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', system-ui, sans-serif;
  --mono: ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', monospace;
  /* Reading text on the entry and notice pages: a book face, the way a lab writes up a method. */
  --serif: 'Source Serif 4', Georgia, 'Times New Roman', serif;

  /* ---- type scale: the entry page sells, the workbench works. Dense UI uses --fs-xs..--fs-md;
   * only the entry page reaches for --fs-xl and above. */
  --fs-xs: 11px; --fs-sm: 12.5px; --fs-base: 14px; --fs-md: 16px; --fs-lg: 19px; --fs-xl: 28px;

  /* ---- spacing: a 4px grid. Use these, never raw pixels, so panels line up across pages. ---- */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 22px; --sp-6: 30px;
  --page-top: 12px;

  /* ---- radii: cards are soft, controls are tighter, chips are pills ---- */
  --radius: 16px; --radius-sm: 10px; --radius-xs: 6px; --radius-pill: 999px;

  /* ---- brand colour, identical in every theme: this is what makes the two pages one product ---- */
  --accent: #22d3ee;
  --accent-soft: #67e8f9;
  --accent-deep: #06b6d4;
  --blue: #2563eb;
  /* Flat on purpose. A gradient wash with a glow behind it is the look of a template, not a tool. */
  --brand-wash: var(--accent);

  /* ---- semantic status colours. Never hard-code a status colour in a page stylesheet: a
   * warning must look the same on the entry page and in the workbench. ---- */
  --danger: #fb7185;
  --warn: #fbbf24;
  --ok: #4ade80;
  /* A peak that no reference explains. The workbench marks those in this orange, so every page does. */
  --unexplained: #fb923c;

  --shadow-card: 0 18px 40px -24px rgba(0, 0, 0, .8);
  --shadow-glow: none;
}

/* ---- dark: the default, worn by the entry page ---- */
:root, [data-theme='dark'] {
  /* The browser paints the parts of a control we cannot reach — the <select> popup list, the
     scrollbars, the focus ring inside a native widget. Without this declaration those stay in the
     light palette, which is why an otherwise dark page opened a white option list. */
  color-scheme: dark;
  --bg: #000000;
  --bg-deep: #000000;
  --panel: rgba(10, 14, 24, .7);
  --panel-solid: #06080f;
  --sunken: rgba(255, 255, 255, .03);
  /* Separation is carried by hairlines, not by boxes: on pure black a filled panel reads as a
     second background. Both lines are sub-pixel-thin at any zoom because they are 1px borders. */
  --line: rgba(148, 163, 184, .22);
  --line-soft: rgba(148, 163, 184, .12);
  /* Only the plot sits on its own surface — a deep blue that separates data from chrome. */
  --plot-canvas: #071023;
  --text: #e2e8f0;
  --text-strong: #f8fafc;
  --text-soft: #cbd5e1;
  --muted: #94a3b8;
  --faint: #64748b;
}

/* ---- light: available for any surface where reading dense data beats atmosphere.
 * Set data-theme="light" on <html>; every token below keeps its meaning, so components
 * written against the tokens need no per-theme rules. ---- */
[data-theme='light'] {
  color-scheme: light;
  --bg: #f6f8fa;
  --bg-deep: #eef2f6;
  --panel: #ffffff;
  --panel-solid: #ffffff;
  --sunken: #f1f5f9;
  --line: #d7dfe8;
  --line-soft: #e6ecf2;
  --text: #24333f;
  --text-strong: #0f1b26;
  --text-soft: #3d4f5c;
  --muted: #5d7183;
  --faint: #83939f;
  --accent: #0e7490;
  --accent-soft: #0891b2;
  --shadow-card: 0 10px 28px -22px rgba(15, 27, 38, .55);
}

/* ---- reset and shared primitives ---- */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; }
/* The root carries the page colour too, so a hidden body or a repaint never shows the browser's white. */
html { background: var(--bg); }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--body); font-size: var(--fs-base); line-height: 1.6;
  -webkit-tap-highlight-color: transparent;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
button:disabled { cursor: not-allowed; opacity: .5; }
a { color: var(--accent); text-decoration: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.hidden { display: none !important; }
.icon { width: 1em; height: 1em; flex: 0 0 auto; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
/* Two historical names for the same thing; both stay until every page uses one. */
.visually-hidden, .sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.eyebrow {
  font-family: var(--display); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .3em; text-transform: uppercase; color: var(--accent); margin: 0;
}
.subtle { color: var(--faint); font-size: var(--fs-xs); }

/* ---- buttons: three ranks, used identically on both pages ---- */
.primary-button, .button.primary {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: 10px 18px; border: 1px solid var(--accent); border-radius: var(--radius-xs);
  background: var(--accent); color: #031219;
  font-family: var(--body); font-size: var(--fs-base); font-weight: 650; letter-spacing: 0;
  transition: background-color .12s ease, border-color .12s ease;
}
.primary-button:hover:not(:disabled), .button.primary:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent-soft); }
.primary-button:disabled, .button.primary:disabled { opacity: .5; }
.primary-button.wide { width: 100%; margin-top: var(--sp-4); padding: 11px 18px; }

.ghost-button, .button.secondary {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  border: 1px solid var(--line); background: transparent; color: var(--text);
  font-size: var(--fs-sm); font-weight: 550; padding: 7px 14px; border-radius: var(--radius-xs);
  transition: border-color .12s ease, color .12s ease;
}
.ghost-button:hover, .button.secondary:hover { color: var(--text-strong); border-color: var(--text-soft); }

.text-button {
  border: 0; background: transparent; color: var(--muted);
  font-size: var(--fs-xs); padding: var(--sp-1) var(--sp-2); border-radius: var(--radius-xs);
}
.text-button:hover:not(:disabled) { color: var(--accent); }
.button.small { font-size: var(--fs-xs); padding: 7px 13px; }
.button.danger { border-color: rgba(251, 113, 133, .45); color: var(--danger); }

/* ---- word mark: "LIBRA | AI4Gem", one definition for every page. Position is the page's
   business (the entry page's top bar and the workbench rail share --page-top);
   what it looks like is not, so that nothing about it changes when you move between pages. ---- */
.wordmark {
  display: inline-flex; align-items: baseline; gap: 10px; line-height: 28px;
  color: var(--text-strong); text-decoration: none; white-space: nowrap;
}
.wordmark .brand-text { font-family: var(--display); font-size: 20px; font-weight: 700; letter-spacing: .08em; }
/* A hair more room after the rule than before it, so "AI4Gem" reads as the second half of the
   mark rather than as something stuck to the line. */
.wordmark .brand-sep { color: var(--line); font-weight: 300; margin-right: 4px; }
.wordmark .brand-partner { font-family: var(--display); font-size: var(--fs-sm); font-weight: 600; letter-spacing: .06em; color: var(--muted); }

/* ---- surfaces ---- */
.card, .panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}

/* ---- form fields ---- */
.field { display: block; font-size: var(--fs-sm); color: var(--muted); margin-bottom: var(--sp-3); }
.field input, .field select, .field textarea {
  display: block; width: 100%; margin-top: var(--sp-1); padding: 10px 12px;
  font-size: var(--fs-base); color: var(--text-strong);
  background: var(--sunken); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.field input::placeholder { color: var(--faint); }
/* Chromium paints <option> rows from the element's own colours on Linux; `color-scheme` alone
   leaves them on the widget default. Declared once here so every select on both pages matches. */
select { background-color: var(--sunken); color: var(--text-strong); }
option, optgroup { background-color: var(--panel-solid); color: var(--text); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--accent); }
.field small, .field-note { display: block; font-size: var(--fs-xs); color: var(--faint); line-height: 1.7; margin-top: var(--sp-1); }
.checkbox { display: flex; align-items: flex-start; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--muted); }
.checkbox input { accent-color: var(--accent); margin: 3px 0 0; }
.form-error, .auth-error { min-height: 1.1em; margin: 2px 0 0; font-size: var(--fs-sm); color: var(--danger); }

/* ---- status chips ---- */
.status-pill {
  font-size: var(--fs-sm); color: var(--muted); border: 1px solid var(--line-soft);
  border-radius: var(--radius-pill); padding: 5px 12px; white-space: nowrap;
}
.status-pill.ready { color: var(--accent-soft); border-color: rgba(34, 211, 238, .35); background: rgba(34, 211, 238, .08); }
.status-pill.down { color: var(--danger); border-color: rgba(251, 113, 133, .4); background: rgba(251, 113, 133, .08); }
.status-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ok); }
.status-dot.offline { background: var(--warn); }

/* ---- toast: one implementation, both pages ---- */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 50;
  max-width: min(92vw, 560px); margin: 0; padding: 12px 18px;
  background: var(--panel-solid); border: 1px solid var(--line); border-radius: var(--radius-sm);
  color: var(--text); font-size: var(--fs-sm); box-shadow: var(--shadow-card);
}
.toast.error { border-color: rgba(251, 113, 133, .5); color: #fecdd3; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
