/* ========================================================== 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. Load more
/* ========================================================== 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); }