1107 lines · 27.4 KB · CSS
RawDownload
/* ==========================================================   Synthetic Sciences — Thesis-style design system    Adapted from Thesis "Obsidian Glass" tokens. Frosted-glass   panels over a quiet background mesh. Mono-first typography   for instrument-readout density. 4px controls, 8px surfaces.   ========================================================== */ /* Computer Modern (SIL OFL, see /fonts/cmc/OFL.md). Self-hosted, regular + bold. */@font-face {  font-family: "Computer Modern";  font-style: normal;  font-weight: 400;  font-display: swap;  src: url("/fonts/cmc/cmunorm.woff2") format("woff2");}@font-face {  font-family: "Computer Modern";  font-style: normal;  font-weight: 700;  font-display: swap;  src: url("/fonts/cmc/cmunobx.woff2") format("woff2");} :root {  /* The app's --color-* namespace is a thin ALIAS layer over the @synsci/ui     semantic tokens (theme.css statics + the runtime-injected theme, default     frontend/ui/src/theme/themes/openscience.json). One palette, one source of     truth — the shell, the transcript, and Settings all move together, and     picking a different theme restyles the whole app coherently. */  --color-bg: var(--background-base);  --color-bg-subtle: var(--background-weak);  --color-bg-elevated: var(--input-disabled);  --color-surface: var(--surface-raised-strong);  --color-surface-solid: var(--surface-raised-stronger-non-alpha);  --color-border: var(--border-base);  --color-border-strong: var(--border-strong-base);  --color-text: var(--text-strong);  --color-text-muted: var(--text-weak);  --color-text-faint: var(--text-weaker);  --color-accent: var(--text-strong);  --color-accent-hover: var(--text-base);  --color-accent-subtle: var(--surface-base-hover);  --color-focus: var(--border-selected);  --color-on-accent: var(--background-base);  --glass-bg: rgba(255, 255, 255, 0.85);  --glass-border: rgba(0, 0, 0, 0.1);  --glass-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 4px 12px rgba(0, 0, 0, 0.03);  --glass-blur: 20px;   /* Radius — one crisp system: 4px controls, 8px overlays (modals, dialogs,     drawers); circular only for toggles/dots/avatars. Sharp + consistent is the     product's identity — refined, not rounded into a generic look. */  --radius: 4px;  --radius-sm: 4px;  --radius-xs: 4px;  --radius-lg: 8px;   --color-success: var(--surface-success-strong);  --color-success-muted: var(--surface-success-weak);  --color-error: var(--surface-critical-strong);  --color-error-muted: var(--surface-critical-weak);  --color-warning: var(--surface-warning-strong);  --color-warning-muted: var(--surface-warning-weak);   --kind-insight: #7e6b8f;  --kind-insight-bg: rgba(126, 107, 143, 0.08);  --kind-empirical: #f97316;  --kind-empirical-bg: rgba(249, 115, 22, 0.08);  --kind-untyped: #71717a;  --kind-untyped-bg: rgba(113, 113, 122, 0.08);   --space-1: 4px;  --space-2: 8px;  --space-3: 12px;  --space-4: 16px;  --space-5: 24px;  --space-6: 32px;  --space-7: 48px;  --space-8: 64px;   --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.06);   --text-2xs: 9px;  --text-xs: 10px;  --text-sm: 11px;  --text-base: 12px;  --text-md: 13px;  --text-lg: 14px;  --text-xl: 16px;  --text-2xl: 20px;   --font-sans: "Computer Modern", "Latin Modern Roman", Georgia, "Times New Roman", serif;  --font-serif: "Computer Modern", "Latin Modern Roman", Georgia, "Times New Roman", serif;  /* Code font: single source. --font-family-mono is owned by @synsci/ui theme.css     and written at runtime by the Settings mono-font picker (self-hosted Nerd     Font families) — everything code-shaped routes through it. */  --font-code: var(--font-family-mono);  --font-ui-sans: "Computer Modern", "Latin Modern Roman", Georgia, "Times New Roman", serif;  /* Bridge @synsci/ui (SessionTurn chat transcript) typography to Computer Modern */  --font-family-sans: "Computer Modern", "Latin Modern Roman", Georgia, serif;   --z-header: 20;  --z-sticky: 50;  --z-fab: 100;  --z-overlay: 200;  --z-modal: 300;  --z-toast: 400;   --agent-bubble-radius: 4px;  --agent-bubble-pad-x: 14px;  --agent-bubble-pad-y: 11px;  --agent-gap: 14px;  --agent-trace-w: 1px;  --agent-ease: cubic-bezier(0.16, 1, 0.3, 1);   --agent-signal: var(--color-text-muted);  --agent-signal-soft: var(--color-accent-subtle);  --agent-record: var(--color-text-muted);   --agent-code-bg: #0c0c0d;  --agent-code-bg-soft: #15151a;  --agent-code-fg: #e6e6e6;  --agent-code-fg-faint: #6e6e76;  --agent-code-border: rgba(255, 255, 255, 0.06);   --logo-filter: none;} /* The one keyboard focus ring. !important so it survives inline style resets   (`all: unset` on hand-rolled buttons) and component-level outline:none —   keyboard users always get the same accent ring. */:where(button, [role="button"], a, input, textarea, select, [tabindex]):focus-visible {  outline: 2px solid var(--color-focus) !important;  outline-offset: 2px;} /* The old light-mode "cream neutralisation" remap block is gone: the default   openscience theme now ships the product's neutral greys directly, so the ui   semantic layer needs no app-side patching (and non-default themes render   exactly as authored). */ /* Settings reads as a full surface, not a small floating card. */[data-component="dialog"]:has(.settings-dialog) [data-slot="dialog-container"] {  width: min(calc(100vw - 48px), 1060px);  height: min(calc(100vh - 48px), 800px);} :root.dark,.dark,html[data-color-scheme="dark"] {  /* --color-* aliases resolve through the mode-aware semantic tokens, so only     the values with no semantic source live here. */  --glass-bg: rgba(23, 23, 23, 0.9);  --glass-border: rgba(255, 255, 255, 0.12);  --glass-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);   --kind-insight: #a596b8;  --kind-insight-bg: rgba(165, 150, 184, 0.12);  --kind-empirical: #fb923c;  --kind-empirical-bg: rgba(251, 146, 60, 0.1);  --kind-untyped: #a1a1aa;  --kind-untyped-bg: rgba(161, 161, 170, 0.1);   --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);   --agent-code-bg: #060608;  --agent-code-bg-soft: #0d0d11;  --agent-code-border: rgba(255, 255, 255, 0.05);   --logo-filter: invert(1);} /* ==========================================================   Base — flat, quiet canvas. (The colored ambient mesh that used   to sit here read as a random gradient bleeding around the chat   and message boxes, so it's gone.)   ========================================================== */.thesis-root {  position: relative;  background: var(--color-bg);  color: var(--color-text);  font-family: var(--font-sans);  letter-spacing: -0.011em;  -webkit-font-smoothing: antialiased;  -moz-osx-font-smoothing: grayscale;  font-feature-settings: "ss01", "ss02";} /* The 40px ruled grid overlay that used to live in .thesis-root::before was   removed — it read as distracting horizontal lines in empty areas (e.g. the   chat), and its full-viewport masked repaint was costly during layout changes   like opening the right pane. */ .thesis-root > * {  position: relative;  z-index: 1;} .thesis-root code,.thesis-root pre,.thesis-root [data-mono],.thesis-root .font-mono {  font-family: var(--font-code);  font-feature-settings: "liga" 0;} /* ==========================================================   Glass panels — the core design primitive   ========================================================== */.g-card {  background: var(--color-surface-solid);  border: 1px solid var(--color-border);  border-radius: var(--radius);  box-shadow: var(--shadow-xs);} .g-card-muted {  background: var(--color-bg-subtle);  border: 1px solid var(--color-border);  border-radius: var(--radius);} .g-assistant {  background: var(--color-surface-solid);  border: 1px solid var(--color-border);  border-left: 2px solid var(--color-text-faint);  border-radius: var(--radius);} .g-strip {  background: rgba(255, 255, 255, 0.55);  backdrop-filter: blur(14px) saturate(1.2);  -webkit-backdrop-filter: blur(14px) saturate(1.2);  border-bottom: 1px solid var(--color-border);} .dark .g-strip,html[data-color-scheme="dark"] .g-strip {  background: rgba(23, 23, 23, 0.7);} .g-composer {  background: var(--color-surface-solid);  border: 1px solid var(--color-border);  border-radius: 4px;  transition:    border-color 120ms ease,    box-shadow 160ms ease;  box-shadow: var(--shadow-xs);}.g-composer:focus-within {  border-color: var(--color-focus);  box-shadow:    0 0 0 3px color-mix(in srgb, var(--color-focus) 15%, transparent),    var(--shadow-xs);} .g-divider {  height: 1px;  background: var(--color-border);} .glass {  background: var(--glass-bg);  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);  border: 1px solid var(--glass-border);  box-shadow: var(--glass-shadow);  border-radius: var(--radius);} .glass-flat {  background: var(--glass-bg);  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);  border-right: 1px solid var(--glass-border);} /* ==========================================================   Tabular figures   ========================================================== */.tab-fig {  font-variant-numeric: tabular-nums;  font-feature-settings:    "tnum" 1,    "ss01" 1,    "ss02" 1;} /* ==========================================================   Animations   ========================================================== */@keyframes thesis-spin {  to {    transform: rotate(360deg);  }}@keyframes thesis-pulse {  0%,  100% {    opacity: 1;  }  50% {    opacity: 0.5;  }}@keyframes thesis-stagger-fade-in {  from {    opacity: 0;    transform: translateY(6px);  }  to {    opacity: 1;    transform: translateY(0);  }}@keyframes thesis-slide-up {  from {    opacity: 0;    transform: translateY(8px);  }  to {    opacity: 1;    transform: translateY(0);  }}@keyframes thesis-fade-in {  from {    opacity: 0;  }  to {    opacity: 1;  }}@keyframes thesis-blink-cursor {  0%,  49% {    opacity: 1;  }  50%,  100% {    opacity: 0;  }}@keyframes thesis-scale-in {  from {    opacity: 0;    transform: scale(0.96);  }  to {    opacity: 1;    transform: scale(1);  }}@keyframes thesis-loading-slide {  0% {    transform: translateX(-100%);  }  100% {    transform: translateX(433%);  }} .thesis-spin {  animation: thesis-spin 0.9s linear infinite;}.thesis-pulse {  animation: thesis-pulse 1.6s ease-in-out infinite;}.thesis-fade-in {  animation: thesis-fade-in 200ms var(--agent-ease);}.thesis-slide-up {  animation: thesis-slide-up 240ms var(--agent-ease);}.thesis-stagger {  animation: thesis-stagger-fade-in 240ms var(--agent-ease);  animation-fill-mode: backwards;}.thesis-blink {  animation: thesis-blink-cursor 1.1s steps(1) infinite;} @keyframes thesis-pop-up {  from {    opacity: 0;    transform: translateY(6px) scale(0.985);  }  to {    opacity: 1;    transform: translateY(0) scale(1);  }}/* Smooth pop for upward-opening menus (model/agent/effort/graph pickers). */.thesis-pop-up {  animation: thesis-pop-up 150ms var(--agent-ease);  transform-origin: bottom left;  will-change: transform, opacity;} /* Reduced-motion: mount/enter animations replay every time a component mounts   or a keep-alive surface is first revealed, which reads as a jarring flash   when switching tabs / files / folders / terminal / atlas. Honor the OS   preference by making them instant (final state, no transform/opacity ramp)   while keeping functional loaders (spin/blink) intact. */@media (prefers-reduced-motion: reduce) {  .thesis-fade-in,  .thesis-slide-up,  .thesis-stagger,  .thesis-pop-up,  .thesis-modal,  .thesis-overlay,  .thesis-drawer-right {    animation: none !important;  }  .thesis-skeleton,  .thesis-glow,  .thesis-pulse,  .thesis-orbit-ring-1,  .thesis-orbit-ring-2 {    animation: none !important;  }} /* ==========================================================   Soft glow on the orbit ring + frame brackets on transcript   ========================================================== */.thesis-agent-orbit {  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--color-focus) 25%, transparent));}.dark .thesis-agent-orbit,html[data-color-scheme="dark"] .thesis-agent-orbit {  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--color-focus) 35%, transparent));} @keyframes thesis-glow {  0%,  100% {    opacity: 0.6;  }  50% {    opacity: 0.95;  }}.thesis-glow {  animation: thesis-glow 2.6s ease-in-out infinite;} /* ==========================================================   Buttons & chips   ========================================================== */.thesis-btn {  font-family: var(--font-sans);  font-size: 11px;  font-weight: 500;  padding: 5px 10px;  border-radius: var(--radius);  border: 1px solid var(--color-border);  background: var(--color-surface-solid);  color: var(--color-text);  cursor: pointer;  transition: all 120ms ease;  display: inline-flex;  align-items: center;  gap: 6px;}.thesis-btn:hover {  border-color: var(--color-border-strong);  background: var(--color-bg-elevated);}.thesis-btn:disabled {  opacity: 0.5;  cursor: not-allowed;} .thesis-btn-primary {  background: var(--color-accent);  color: var(--color-bg);  border-color: var(--color-accent);}.thesis-btn-primary:hover {  background: var(--color-accent-hover);  border-color: var(--color-accent-hover);} .thesis-btn-ghost {  background: transparent;  border: 1px solid transparent;  color: var(--color-text-muted);}.thesis-btn-ghost:hover {  background: var(--color-accent-subtle);  color: var(--color-text);} 

Lines 1–500 of 1107.