267 lines
8.5 KiB
CSS
267 lines
8.5 KiB
CSS
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
/* ============================================================
|
|
Theme palettes — switch via data-theme on <html>.
|
|
Values are RGB channels so Tailwind opacity modifiers work
|
|
(e.g. bg-accent-green/5 -> rgb(var(--accent-green) / 0.05)).
|
|
============================================================ */
|
|
:root,
|
|
:root[data-theme="dark"] {
|
|
--bg-base: 10 10 15;
|
|
--bg-surface: 17 17 24;
|
|
--bg-raised: 24 24 31;
|
|
--bg-border: 37 37 48;
|
|
--accent-green: 0 255 136;
|
|
--accent-dim: 0 204 106;
|
|
--accent-muted: 0 51 34;
|
|
--text-primary: 232 232 240;
|
|
--text-secondary: 136 136 170;
|
|
--text-muted: 68 68 90;
|
|
--danger: 255 68 68;
|
|
--warn: 255 170 0;
|
|
--scrollbar-hover: 51 51 68;
|
|
}
|
|
|
|
/* Catppuccin Frappé — soft pastels on a dark blue-grey base */
|
|
:root[data-theme="frappe"] {
|
|
--bg-base: 48 52 70; /* base #303446 */
|
|
--bg-surface: 41 44 60; /* mantle #292c3c */
|
|
--bg-raised: 65 69 89; /* surface0 #414559 */
|
|
--bg-border: 81 87 109; /* surface1 #51576d */
|
|
--accent-green: 166 209 137; /* green #a6d189 */
|
|
--accent-dim: 140 180 115; /* darker green for hovers */
|
|
--accent-muted: 65 69 89; /* surface0 */
|
|
--text-primary: 198 208 245; /* text #c6d0f5 */
|
|
--text-secondary: 165 173 206; /* subtext0 #a5adce */
|
|
--text-muted: 115 121 148; /* overlay0 #737994 */
|
|
--danger: 231 130 132; /* red #e78284 */
|
|
--warn: 229 200 144; /* yellow #e5c890 */
|
|
--scrollbar-hover: 98 104 128; /* surface2 #626880 */
|
|
}
|
|
|
|
/* Catppuccin Latte — soft pastels, true light mode */
|
|
:root[data-theme="latte"] {
|
|
--bg-base: 239 241 245; /* base #eff1f5 */
|
|
--bg-surface: 230 233 239; /* mantle #e6e9ef */
|
|
--bg-raised: 220 224 232; /* crust #dce0e8 */
|
|
--bg-border: 204 208 218; /* surface0 #ccd0da */
|
|
--accent-green: 64 160 43; /* green #40a02b */
|
|
--accent-dim: 50 130 35; /* darker green for hovers */
|
|
--accent-muted: 204 227 192; /* light green tint */
|
|
--text-primary: 76 79 105; /* text #4c4f69 */
|
|
--text-secondary: 108 111 133; /* subtext0 #6c6f85 */
|
|
--text-muted: 140 143 161; /* overlay1 #8c8fa1 */
|
|
--danger: 210 15 57; /* red #d20f39 */
|
|
--warn: 223 142 29; /* yellow #df8e1d */
|
|
--scrollbar-hover: 188 192 204;/* surface1 #bcc0cc */
|
|
}
|
|
|
|
/* Latte is the only light theme — theme its native form controls light. Set on
|
|
body (not :root) so it never tints the transparent document canvas. */
|
|
:root[data-theme="latte"] body { color-scheme: light; }
|
|
|
|
@layer base {
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
html, body, #root {
|
|
height: 100%;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
/* Keep the WebKit canvas transparent so the rounded app-root corners show
|
|
through to the desktop. Without this the browser paints an OPAQUE canvas
|
|
backdrop dictated by `color-scheme`, which fills the four corners with a
|
|
square — the theme-switch "square corners" bug. color-scheme is therefore
|
|
set on <body>/controls below, NOT on :root, so it can't tint the canvas. */
|
|
background-color: transparent;
|
|
}
|
|
|
|
/* The rounded window surface lives HERE — on #root, which is always present —
|
|
not on a per-screen container. Previously only the main app root was
|
|
rounded, so the loading screen and the lock gate showed a SQUARE window
|
|
until the main view mounted (the "square at login, rounds a few seconds
|
|
after the password" bug). Rounding #root makes every screen rounded from the
|
|
first paint. overflow:hidden clips children to the radius; bg-base fills it;
|
|
outside the radius stays transparent so the corners show the desktop. */
|
|
#root {
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
background: rgb(var(--bg-base));
|
|
}
|
|
|
|
body {
|
|
/* The rounded app root (App.tsx) carries the real bg so the window corners
|
|
clip to transparency. Needs the translucent window surface set in main.go.
|
|
color-scheme lives here (not :root) to theme native controls without
|
|
forcing an opaque document canvas. */
|
|
background: transparent;
|
|
color-scheme: dark;
|
|
color: rgb(var(--text-primary));
|
|
font-family: 'IBM Plex Sans', sans-serif;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
-webkit-font-smoothing: antialiased;
|
|
/* Content is selectable/copyable; interactive chrome opts out below. */
|
|
user-select: text;
|
|
-webkit-user-select: text;
|
|
}
|
|
|
|
/* Buttons, navigation and the title bar shouldn't be text-selectable —
|
|
keeps the native app feel and avoids accidental drag-selection of UI. */
|
|
button, [role="button"], nav, aside, .titlebar {
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
}
|
|
|
|
::selection {
|
|
background: rgb(var(--accent-green) / 0.25);
|
|
color: rgb(var(--text-primary));
|
|
}
|
|
|
|
/* Themed form elements — color-scheme is set per theme on :root */
|
|
input, textarea, select {
|
|
background-color: rgb(var(--bg-raised));
|
|
color: rgb(var(--text-primary));
|
|
border-color: rgb(var(--bg-border));
|
|
}
|
|
|
|
select {
|
|
background-color: rgb(var(--bg-raised));
|
|
color: rgb(var(--text-primary));
|
|
appearance: none;
|
|
-webkit-appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2388889a' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 8px center;
|
|
padding-right: 28px;
|
|
}
|
|
|
|
select option {
|
|
background-color: rgb(var(--bg-raised));
|
|
color: rgb(var(--text-primary));
|
|
}
|
|
|
|
input[type="checkbox"] {
|
|
accent-color: rgb(var(--accent-green));
|
|
background-color: rgb(var(--bg-raised));
|
|
}
|
|
|
|
input::placeholder {
|
|
color: rgb(var(--text-muted));
|
|
}
|
|
|
|
::-webkit-scrollbar {
|
|
width: 6px;
|
|
height: 6px;
|
|
}
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
::-webkit-scrollbar-thumb {
|
|
background: rgb(var(--bg-border));
|
|
border-radius: 3px;
|
|
}
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: rgb(var(--scrollbar-hover));
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
.card {
|
|
@apply bg-bg-surface border border-bg-border rounded-lg;
|
|
}
|
|
|
|
.btn {
|
|
@apply inline-flex items-center gap-2 px-3 py-1.5 rounded text-sm font-medium
|
|
transition-all duration-150 cursor-pointer select-none
|
|
disabled:opacity-40 disabled:cursor-not-allowed;
|
|
}
|
|
|
|
.btn-primary {
|
|
@apply btn bg-accent-green text-bg-base hover:bg-accent-dim active:scale-95;
|
|
}
|
|
|
|
.btn-ghost {
|
|
@apply btn bg-transparent text-text-secondary border border-bg-border
|
|
hover:bg-bg-raised hover:text-text-primary active:scale-95;
|
|
}
|
|
|
|
.btn-danger {
|
|
@apply btn bg-danger/10 text-danger border border-danger/20
|
|
hover:bg-danger/20 active:scale-95;
|
|
}
|
|
|
|
.btn-warn {
|
|
@apply btn bg-warn/10 text-warn border border-warn/20
|
|
hover:bg-warn/20 active:scale-95;
|
|
}
|
|
|
|
.input {
|
|
@apply bg-bg-raised border border-bg-border rounded px-3 py-1.5
|
|
text-sm text-text-primary placeholder:text-text-muted
|
|
focus:outline-none focus:border-accent-green/50
|
|
transition-colors duration-150 w-full;
|
|
}
|
|
|
|
.badge {
|
|
@apply inline-flex items-center px-2 py-0.5 rounded text-xs font-medium;
|
|
}
|
|
|
|
.badge-green {
|
|
@apply badge bg-accent-green/10 text-accent-green;
|
|
}
|
|
|
|
.badge-red {
|
|
@apply badge bg-danger/10 text-danger;
|
|
}
|
|
|
|
.badge-yellow {
|
|
@apply badge bg-warn/10 text-warn;
|
|
}
|
|
|
|
.badge-gray {
|
|
@apply badge bg-bg-border text-text-secondary;
|
|
}
|
|
|
|
.section-title {
|
|
@apply text-xs font-medium uppercase tracking-widest text-text-muted;
|
|
}
|
|
|
|
/* compact icon button for the Logcat visual map overlays */
|
|
.map-btn {
|
|
@apply inline-flex items-center justify-center h-7 w-7 rounded bg-black/40
|
|
text-text-secondary border border-bg-border hover:bg-bg-raised
|
|
hover:text-text-primary transition-colors cursor-pointer;
|
|
}
|
|
|
|
.mono {
|
|
@apply font-mono text-sm;
|
|
}
|
|
}
|
|
|
|
/* Glow effect on accent elements */
|
|
.glow {
|
|
box-shadow: 0 0 12px rgb(var(--accent-green) / 0.15);
|
|
}
|
|
|
|
@keyframes pulse-dot {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.3; }
|
|
}
|
|
|
|
.status-dot {
|
|
display: inline-block;
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
animation: pulse-dot 2s ease-in-out infinite;
|
|
}
|
|
|
|
.status-dot-green { background: rgb(var(--accent-green)); box-shadow: 0 0 6px rgb(var(--accent-green) / 0.53); }
|
|
.status-dot-red { background: rgb(var(--danger)); box-shadow: 0 0 6px rgb(var(--danger) / 0.53); }
|
|
.status-dot-gray { background: rgb(var(--text-muted)); animation: none; }
|