Files
Termix/src/ui/index.css
T

787 lines
19 KiB
CSS

/* Plugin utilities (termix-plugin build) rank above base, below core's own. */
@layer properties, termix-plugin-properties, theme, base, components,
termix-plugin-utilities, utilities;
@import "tailwindcss";
@import "tw-animate-css";
@import "./theme.css";
@import "@fontsource-variable/jetbrains-mono";
@import "@fontsource/jetbrains-mono/400.css";
@import "@fontsource/jetbrains-mono/400-italic.css";
@import "@fontsource/jetbrains-mono/700.css";
@import "@fontsource/jetbrains-mono/700-italic.css";
@import "@fontsource/fira-code/400.css";
@import "@fontsource/fira-code/700.css";
@import "@fontsource/source-code-pro/400.css";
@import "@fontsource/source-code-pro/400-italic.css";
@import "@fontsource/source-code-pro/700.css";
@import "@fontsource/source-code-pro/700-italic.css";
@font-face {
font-family: "Caskaydia Cove Nerd Font Mono";
src: url("/fonts/CaskaydiaCoveNerdFontMono-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Caskaydia Cove Nerd Font Mono";
src: url("/fonts/CaskaydiaCoveNerdFontMono-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Caskaydia Cove Nerd Font Mono";
src: url("/fonts/CaskaydiaCoveNerdFontMono-Italic.ttf") format("truetype");
font-weight: 400;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "Caskaydia Cove Nerd Font Mono";
src: url("/fonts/CaskaydiaCoveNerdFontMono-BoldItalic.ttf") format("truetype");
font-weight: 700;
font-style: italic;
font-display: swap;
}
:root {
--accent-brand: #f59145;
--motion-duration-micro: 110ms;
--motion-duration-panel: 220ms;
--motion-duration-context: 340ms;
--motion-ease-enter: cubic-bezier(0.16, 1, 0.3, 1);
--motion-ease-exit: cubic-bezier(0.4, 0, 1, 1);
--background: oklch(1 0 0);
--foreground: oklch(0.1802 0.0043 128.73);
--card: oklch(1 0 0);
--card-foreground: oklch(0.1802 0.0043 128.73);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.1802 0.0043 128.73);
--primary: oklch(0.2115 0.0042 128.68);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.2115 0.0042 128.68);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.44 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.2115 0.0042 128.68);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--radius: 0.625rem;
--surface: oklch(0.97 0 0);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.1802 0.0043 128.73);
--sidebar-primary: oklch(0.2115 0.0042 128.68);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.2115 0.0042 128.68);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.155 0.004 128.73);
--foreground: oklch(0.985 0 0);
--card: oklch(0.21 0.004 128.68);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.21 0.004 128.68);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.2115 0.0042 128.68);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--surface: oklch(0.185 0.004 128.73);
--surface-dim: oklch(0.165 0.003 128.73);
--muted: oklch(0.255 0 0);
--muted-foreground: oklch(0.72 0 0);
--accent: oklch(0.255 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 12%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.195 0.004 128.68);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.255 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 12%);
--sidebar-ring: oklch(0.556 0 0);
}
/* ── Dracula ────────────────────────────────────────────────── */
.dracula {
--background: #282a36;
--foreground: #f8f8f2;
--card: #2d303d;
--card-foreground: #f8f8f2;
--popover: #2d303d;
--popover-foreground: #f8f8f2;
--primary: #8be9fd;
--primary-foreground: #282a36;
--secondary: #50536b;
--secondary-foreground: #f8f8f2;
--surface: #2d303d;
--surface-dim: #21222c;
--muted: #50536b;
--muted-foreground: #a8b3d9;
--accent: #5a5e7a;
--accent-foreground: #f8f8f2;
--destructive: #ff5555;
--border: rgba(168, 179, 217, 0.18);
--input: rgba(168, 179, 217, 0.14);
--ring: #8be9fd;
--chart-1: #ff79c6;
--chart-2: #8be9fd;
--chart-3: #50fa7b;
--chart-4: #ffb86c;
--chart-5: #bd93f9;
--radius: 0.625rem;
--sidebar: #21222c;
--sidebar-foreground: #f8f8f2;
--sidebar-primary: #8be9fd;
--sidebar-primary-foreground: #282a36;
--sidebar-accent: #5a5e7a;
--sidebar-accent-foreground: #f8f8f2;
--sidebar-border: rgba(168, 179, 217, 0.18);
--sidebar-ring: #8be9fd;
}
/* ── Catppuccin Mocha ───────────────────────────────────────── */
.catppuccin {
--background: #1e1e2e;
--foreground: #cdd6f4;
--card: #202235;
--card-foreground: #cdd6f4;
--popover: #202235;
--popover-foreground: #cdd6f4;
--primary: #89b4fa;
--primary-foreground: #1e1e2e;
--secondary: #3b3d52;
--secondary-foreground: #cdd6f4;
--surface: #202235;
--surface-dim: #181825;
--muted: #3b3d52;
--muted-foreground: #b8c0e0;
--accent: #45475a;
--accent-foreground: #cdd6f4;
--destructive: #f38ba8;
--border: rgba(186, 194, 222, 0.18);
--input: rgba(186, 194, 222, 0.14);
--ring: #89b4fa;
--chart-1: #f38ba8;
--chart-2: #89dceb;
--chart-3: #a6e3a1;
--chart-4: #fab387;
--chart-5: #cba6f7;
--radius: 0.625rem;
--sidebar: #181825;
--sidebar-foreground: #cdd6f4;
--sidebar-primary: #89b4fa;
--sidebar-primary-foreground: #1e1e2e;
--sidebar-accent: #45475a;
--sidebar-accent-foreground: #cdd6f4;
--sidebar-border: rgba(186, 194, 222, 0.18);
--sidebar-ring: #89b4fa;
}
/* ── Nord ───────────────────────────────────────────────────── */
.nord {
--background: #2e3440;
--foreground: #eceff4;
--card: #353c4a;
--card-foreground: #eceff4;
--popover: #353c4a;
--popover-foreground: #eceff4;
--primary: #88c0d0;
--primary-foreground: #2e3440;
--secondary: #434c5e;
--secondary-foreground: #eceff4;
--surface: #353c4a;
--surface-dim: #2a303b;
--muted: #434c5e;
--muted-foreground: #b4c0d4;
--accent: #4c566a;
--accent-foreground: #eceff4;
--destructive: #bf616a;
--border: rgba(180, 192, 212, 0.18);
--input: rgba(180, 192, 212, 0.14);
--ring: #88c0d0;
--chart-1: #bf616a;
--chart-2: #88c0d0;
--chart-3: #a3be8c;
--chart-4: #ebcb8b;
--chart-5: #b48ead;
--radius: 0.625rem;
--sidebar: #2a303b;
--sidebar-foreground: #eceff4;
--sidebar-primary: #88c0d0;
--sidebar-primary-foreground: #2e3440;
--sidebar-accent: #4c566a;
--sidebar-accent-foreground: #eceff4;
--sidebar-border: rgba(180, 192, 212, 0.18);
--sidebar-ring: #88c0d0;
}
/* ── Solarized Dark ─────────────────────────────────────────── */
.solarized {
--background: #002b36;
--foreground: #b7c4c4;
--card: #073642;
--card-foreground: #b7c4c4;
--popover: #073642;
--popover-foreground: #b7c4c4;
--primary: #268bd2;
--primary-foreground: #002b36;
--secondary: #0b4654;
--secondary-foreground: #b7c4c4;
--surface: #073642;
--surface-dim: #00212b;
--muted: #0b4654;
--muted-foreground: #9fb3b3;
--accent: #105667;
--accent-foreground: #d5dddd;
--destructive: #dc322f;
--border: rgba(159, 179, 179, 0.2);
--input: rgba(159, 179, 179, 0.16);
--ring: #268bd2;
--chart-1: #dc322f;
--chart-2: #2aa198;
--chart-3: #859900;
--chart-4: #b58900;
--chart-5: #6c71c4;
--radius: 0.625rem;
--sidebar: #073642;
--sidebar-foreground: #b7c4c4;
--sidebar-primary: #268bd2;
--sidebar-primary-foreground: #002b36;
--sidebar-accent: #105667;
--sidebar-accent-foreground: #d5dddd;
--sidebar-border: rgba(159, 179, 179, 0.2);
--sidebar-ring: #268bd2;
}
/* ── Tokyo Night ────────────────────────────────────────────── */
.tokyo-night {
--background: #1a1b26;
--foreground: #c0caf5;
--card: #1f2335;
--card-foreground: #c0caf5;
--popover: #1f2335;
--popover-foreground: #c0caf5;
--primary: #7aa2f7;
--primary-foreground: #1a1b26;
--secondary: #2a2f47;
--secondary-foreground: #c0caf5;
--surface: #1f2335;
--surface-dim: #16161e;
--muted: #2a2f47;
--muted-foreground: #8b93bd;
--accent: #2f3654;
--accent-foreground: #c0caf5;
--destructive: #f7768e;
--border: rgba(139, 147, 189, 0.2);
--input: rgba(139, 147, 189, 0.16);
--ring: #7aa2f7;
--chart-1: #f7768e;
--chart-2: #7dcfff;
--chart-3: #9ece6a;
--chart-4: #e0af68;
--chart-5: #bb9af7;
--radius: 0.625rem;
--sidebar: #16161e;
--sidebar-foreground: #c0caf5;
--sidebar-primary: #7aa2f7;
--sidebar-primary-foreground: #1a1b26;
--sidebar-accent: #2f3654;
--sidebar-accent-foreground: #c0caf5;
--sidebar-border: rgba(139, 147, 189, 0.2);
--sidebar-ring: #7aa2f7;
}
/* ── One Dark ───────────────────────────────────────────────── */
.one-dark {
--background: #282c34;
--foreground: #abb2bf;
--card: #2f343d;
--card-foreground: #abb2bf;
--popover: #2f343d;
--popover-foreground: #abb2bf;
--primary: #61afef;
--primary-foreground: #282c34;
--secondary: #3a404b;
--secondary-foreground: #abb2bf;
--surface: #2f343d;
--surface-dim: #21252b;
--muted: #3a404b;
--muted-foreground: #9aa3b2;
--accent: #424957;
--accent-foreground: #abb2bf;
--destructive: #e06c75;
--border: rgba(154, 163, 178, 0.18);
--input: rgba(154, 163, 178, 0.14);
--ring: #61afef;
--chart-1: #e06c75;
--chart-2: #56b6c2;
--chart-3: #98c379;
--chart-4: #e5c07b;
--chart-5: #c678dd;
--radius: 0.625rem;
--sidebar: #21252b;
--sidebar-foreground: #abb2bf;
--sidebar-primary: #61afef;
--sidebar-primary-foreground: #282c34;
--sidebar-accent: #424957;
--sidebar-accent-foreground: #abb2bf;
--sidebar-border: rgba(154, 163, 178, 0.18);
--sidebar-ring: #61afef;
}
/* ── Gruvbox Dark ───────────────────────────────────────────── */
.gruvbox {
--background: #282828;
--foreground: #ebdbb2;
--card: #32302f;
--card-foreground: #ebdbb2;
--popover: #32302f;
--popover-foreground: #ebdbb2;
--primary: #fabd2f;
--primary-foreground: #282828;
--secondary: #45403d;
--secondary-foreground: #ebdbb2;
--surface: #32302f;
--surface-dim: #1d2021;
--muted: #45403d;
--muted-foreground: #c4b59d;
--accent: #504945;
--accent-foreground: #ebdbb2;
--destructive: #fb4934;
--border: rgba(196, 181, 157, 0.18);
--input: rgba(196, 181, 157, 0.14);
--ring: #fabd2f;
--chart-1: #fb4934;
--chart-2: #8ec07c;
--chart-3: #b8bb26;
--chart-4: #fabd2f;
--chart-5: #d3869b;
--radius: 0.625rem;
--sidebar: #1d2021;
--sidebar-foreground: #ebdbb2;
--sidebar-primary: #fabd2f;
--sidebar-primary-foreground: #282828;
--sidebar-accent: #504945;
--sidebar-accent-foreground: #ebdbb2;
--sidebar-border: rgba(196, 181, 157, 0.18);
--sidebar-ring: #fabd2f;
}
@layer base {
* {
/* Tailwind v4 defaults border-color to currentColor, so any bare "border"
utility picked up the text color and rendered near-white. */
@apply border-border outline-none;
scrollbar-width: thin;
scrollbar-color: oklch(1 0 0 / 20%) transparent;
}
*::-webkit-scrollbar {
width: 6px;
height: 6px;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: oklch(1 0 0 / 20%);
border-radius: 3px;
}
*::-webkit-scrollbar-thumb:hover {
background: oklch(1 0 0 / 35%);
}
*::-webkit-scrollbar-corner {
background: transparent;
}
html,
body,
#root {
height: 100dvh;
@apply overflow-hidden;
}
body {
@apply bg-background text-foreground font-mono;
}
html {
@apply font-mono;
}
}
/* Icons sized with the size prop carry width/height attributes in px, which
the interface size setting cannot reach. These restate them in CSS, where
they become rem like every other length. A size class on the icon wins. */
@layer base {
svg.lucide[width="8"] {
width: 8px;
height: 8px;
}
svg.lucide[width="9"] {
width: 9px;
height: 9px;
}
svg.lucide[width="10"] {
width: 10px;
height: 10px;
}
svg.lucide[width="11"] {
width: 11px;
height: 11px;
}
svg.lucide[width="12"] {
width: 12px;
height: 12px;
}
svg.lucide[width="13"] {
width: 13px;
height: 13px;
}
svg.lucide[width="14"] {
width: 14px;
height: 14px;
}
svg.lucide[width="15"] {
width: 15px;
height: 15px;
}
svg.lucide[width="16"] {
width: 16px;
height: 16px;
}
svg.lucide[width="17"] {
width: 17px;
height: 17px;
}
svg.lucide[width="18"] {
width: 18px;
height: 18px;
}
svg.lucide[width="19"] {
width: 19px;
height: 19px;
}
svg.lucide[width="20"] {
width: 20px;
height: 20px;
}
svg.lucide[width="21"] {
width: 21px;
height: 21px;
}
svg.lucide[width="22"] {
width: 22px;
height: 22px;
}
svg.lucide[width="23"] {
width: 23px;
height: 23px;
}
svg.lucide[width="24"] {
width: 24px;
height: 24px;
}
svg.lucide[width="25"] {
width: 25px;
height: 25px;
}
svg.lucide[width="26"] {
width: 26px;
height: 26px;
}
svg.lucide[width="27"] {
width: 27px;
height: 27px;
}
svg.lucide[width="28"] {
width: 28px;
height: 28px;
}
svg.lucide[width="29"] {
width: 29px;
height: 29px;
}
svg.lucide[width="30"] {
width: 30px;
height: 30px;
}
svg.lucide[width="31"] {
width: 31px;
height: 31px;
}
svg.lucide[width="32"] {
width: 32px;
height: 32px;
}
svg.lucide[width="36"] {
width: 36px;
height: 36px;
}
svg.lucide[width="40"] {
width: 40px;
height: 40px;
}
svg.lucide[width="48"] {
width: 48px;
height: 48px;
}
svg.lucide[width="64"] {
width: 64px;
height: 64px;
}
svg.lucide[width="96"] {
width: 96px;
height: 96px;
}
}
/* Font size scale applied to html element */
html.fs-xs {
font-size: 12px;
}
html.fs-sm {
font-size: 13px;
}
html.fs-md {
font-size: 14px;
}
html.fs-lg {
font-size: 17px;
}
html.fs-xl {
font-size: 20px;
}
@supports (padding-bottom: env(safe-area-inset-bottom)) {
.safe-bottom {
padding-bottom: env(safe-area-inset-bottom);
}
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
/* Motion communicates state and hierarchy. Keep it off the terminal glyph layer. */
.motion-interactive {
transition-duration: var(--motion-duration-micro);
transition-timing-function: var(--motion-ease-enter);
}
.motion-meter {
transition: width var(--motion-duration-panel) var(--motion-ease-enter);
}
.motion-panel-enter {
animation: motion-panel-enter var(--motion-duration-panel)
var(--motion-ease-enter) both;
}
.motion-context-enter {
animation: motion-context-enter var(--motion-duration-context)
var(--motion-ease-enter) both;
}
.motion-workspace-enter {
animation: motion-workspace-enter var(--motion-duration-panel)
var(--motion-ease-enter) both;
}
.motion-workspace-layout {
animation: motion-workspace-layout var(--motion-duration-context)
var(--motion-ease-enter) both;
}
.motion-transfer-phase {
animation: motion-transfer-phase var(--motion-duration-micro)
var(--motion-ease-enter) both;
}
.transfer-progress-track {
position: relative;
height: 5px;
overflow: hidden;
background: color-mix(in oklab, var(--primary) 16%, transparent);
}
.transfer-progress-fill {
width: 100%;
height: 100%;
background: var(--accent-brand);
transform: scaleX(var(--transfer-progress, 0));
transform-origin: left center;
transition: transform var(--motion-duration-panel) var(--motion-ease-enter);
}
.transfer-progress-indeterminate {
width: 32%;
transform: translateX(-110%);
animation: transfer-progress-flow 1.1s var(--motion-ease-enter) infinite;
}
.transfer-progress-stalled {
background: var(--destructive);
animation: none;
}
.transfer-progress-indeterminate.transfer-progress-stalled {
transform: translateX(105%);
}
.host-status-stripe {
position: relative;
isolation: isolate;
}
.host-status-stripe[data-locking="true"]::after {
content: "";
position: absolute;
inset: 0 -3px;
z-index: -1;
background: inherit;
opacity: 0;
transform: scaleX(1);
animation: host-signal-lock var(--motion-duration-context)
var(--motion-ease-enter) both;
}
@keyframes motion-panel-enter {
from {
opacity: 0;
transform: translateY(6px) scale(0.99);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes motion-context-enter {
from {
opacity: 0;
transform: scale(0.995);
filter: saturate(0.65);
}
to {
opacity: 1;
transform: scale(1);
filter: saturate(1);
}
}
@keyframes motion-workspace-enter {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes motion-workspace-layout {
from {
opacity: 0.72;
transform: scale(0.996);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes motion-transfer-phase {
from {
opacity: 0.45;
transform: translateX(-3px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes transfer-progress-flow {
to {
transform: translateX(420%);
}
}
@keyframes host-signal-lock {
0% {
opacity: 0;
transform: scaleX(3.2);
}
38% {
opacity: 0.48;
}
100% {
opacity: 0;
transform: scaleX(1);
}
}
@media (prefers-reduced-motion: reduce) {
:root {
--motion-duration-micro: 1ms;
--motion-duration-panel: 1ms;
--motion-duration-context: 1ms;
}
.motion-panel-enter,
.motion-context-enter,
.motion-workspace-enter,
.motion-workspace-layout,
.motion-transfer-phase,
.transfer-progress-indeterminate,
.host-status-stripe[data-locking="true"]::after {
animation: none;
}
.motion-meter {
transition: none;
}
.transfer-progress-indeterminate {
transform: translateX(105%);
}
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
transition-duration: 1ms !important;
}
}