detached da30642

style(webui): refactor tailwind theme colors to css variables + add tw-animate

commit
da30642950c3d4629b16f4056c80016e21e2aa62
author
bnema · · 2025-12-21 13:53 UTC
parent
99d9c6c
signature
unsigned
2 files · +21 -165
M webui/src/styles/app.css +2 -165
@@ -1,4 +1,5 @@
11 @import "tailwindcss";
2+@import "tw-animate-css";
23
34 /*
45 * Dumber Browser - Unified Theme CSS
@@ -182,173 +183,9 @@
182183 * ═══════════════════════════════════════════════════════════════ */
183184 @layer base {
184185 * {
185- @apply border-border;
186+ @apply border-border outline-ring/50;
186187 }
187188 body {
188189 @apply bg-background text-foreground;
189190 }
190191 }
191-
192-/* ═══════════════════════════════════════════════════════════════
193- * BROWSER UI COMPONENTS
194- * Custom styles for browser-specific UI elements
195- * ═══════════════════════════════════════════════════════════════ */
196-
197-/* Toast notifications */
198-.toast-base {
199- border-radius: 0;
200- box-shadow:
201- 0 10px 15px -3px rgb(0 0 0 / 0.1),
202- 0 4px 6px -4px rgb(0 0 0 / 0.1);
203- padding: 0.25rem 0.5rem;
204- max-width: 24rem;
205- pointer-events: auto;
206- background-color: var(--card);
207- color: var(--foreground);
208- border-width: 1px;
209- border-style: solid;
210- border-color: var(--border);
211-}
212-
213-/* Omnibox/Find bar */
214-.omnibox-base {
215- background-color: var(--background);
216- color: var(--foreground);
217- border-width: 1px;
218- border-style: solid;
219- border-color: var(--border);
220- box-shadow:
221- 0 4px 6px -1px rgb(0 0 0 / 0.1),
222- 0 2px 4px -2px rgb(0 0 0 / 0.1);
223- transition: all 150ms;
224-}
225-
226-.omnibox-base:focus-within {
227- border-color: var(--primary);
228-}
229-
230-.omnibox-input {
231- width: 100%;
232- padding: 0.5rem 0.75rem;
233- background-color: transparent;
234- color: var(--foreground);
235- outline: none;
236- font-size: 0.875rem;
237-}
238-
239-.omnibox-input::placeholder {
240- color: var(--muted-foreground);
241-}
242-
243-/* Find bar */
244-.findbar {
245- display: flex;
246- align-items: center;
247- gap: 0.5rem;
248- padding: 0.5rem 0.75rem;
249-}
250-
251-.findbar-input {
252- flex: 1;
253- background-color: transparent;
254- color: var(--foreground);
255- outline: none;
256- font-size: 0.875rem;
257-}
258-
259-.findbar-input::placeholder {
260- color: var(--muted-foreground);
261-}
262-
263-.findbar-button {
264- padding: 0.25rem 0.5rem;
265- border-radius: 0;
266- color: var(--muted-foreground);
267- transition: color 150ms;
268- font-size: 0.875rem;
269-}
270-
271-.findbar-button:hover {
272- color: var(--foreground);
273-}
274-
275-.findbar-count {
276- font-size: 0.75rem;
277- color: var(--muted-foreground);
278- font-variant-numeric: tabular-nums;
279-}
280-
281-/* Find highlighting */
282-.find-highlight {
283- background-color: rgb(255 235 59);
284- color: rgb(0 0 0);
285- padding: 0 0.125rem;
286- border-radius: 0.125rem;
287- box-shadow: 0 0 0 1px rgb(200 185 0) inset;
288-}
289-
290-.find-active {
291- background-color: rgb(255 152 0) !important;
292- color: rgb(0 0 0);
293- box-shadow: 0 0 0 1px rgb(179 107 0) inset !important;
294-}
295-
296-/* Animation utilities */
297-.slide-in-top {
298- animation: slide-in-top 0.25s ease-out;
299-}
300-
301-.slide-out-top {
302- animation: slide-out-top 0.25s ease-in;
303-}
304-
305-.fade-in {
306- animation: fade-in 0.15s ease-out;
307-}
308-
309-.fade-out {
310- animation: fade-out 0.15s ease-in;
311-}
312-
313-@keyframes slide-in-top {
314- from {
315- transform: translateY(-100%);
316- opacity: 0;
317- }
318- to {
319- transform: translateY(0);
320- opacity: 1;
321- }
322-}
323-
324-@keyframes slide-out-top {
325- from {
326- transform: translateY(0);
327- opacity: 1;
328- }
329- to {
330- transform: translateY(-100%);
331- opacity: 0;
332- }
333-}
334-
335-@keyframes fade-in {
336- from { opacity: 0; }
337- to { opacity: 1; }
338-}
339-
340-@keyframes fade-out {
341- from { opacity: 1; }
342- to { opacity: 0; }
343-}
344-
345-/* Component isolation utility */
346-.browser-component-root {
347- all: initial;
348- font-family: Fira Sans, system-ui, -apple-system, sans-serif;
349- box-sizing: border-box;
350-}
351-
352-.browser-component-root * {
353- box-sizing: border-box;
354-}
@@ -1,4 +1,5 @@
1 @import "tailwindcss";1 @import "tailwindcss";
2+@import "tw-animate-css";
2 3
3 /*4 /*
4 * Dumber Browser - Unified Theme CSS5 * Dumber Browser - Unified Theme CSS
@@ -182,173 +183,9 @@
182 * ═══════════════════════════════════════════════════════════════ */183 * ═══════════════════════════════════════════════════════════════ */
183 @layer base {184 @layer base {
184 * {185 * {
185- @apply border-border;186+ @apply border-border outline-ring/50;
186 }187 }
187 body {188 body {
188 @apply bg-background text-foreground;189 @apply bg-background text-foreground;
189 }190 }
190 }191 }
191-
192-/* ═══════════════════════════════════════════════════════════════
193- * BROWSER UI COMPONENTS
194- * Custom styles for browser-specific UI elements
195- * ═══════════════════════════════════════════════════════════════ */
196-
197-/* Toast notifications */
198-.toast-base {
199- border-radius: 0;
200- box-shadow:
201- 0 10px 15px -3px rgb(0 0 0 / 0.1),
202- 0 4px 6px -4px rgb(0 0 0 / 0.1);
203- padding: 0.25rem 0.5rem;
204- max-width: 24rem;
205- pointer-events: auto;
206- background-color: var(--card);
207- color: var(--foreground);
208- border-width: 1px;
209- border-style: solid;
210- border-color: var(--border);
211-}
212-
213-/* Omnibox/Find bar */
214-.omnibox-base {
215- background-color: var(--background);
216- color: var(--foreground);
217- border-width: 1px;
218- border-style: solid;
219- border-color: var(--border);
220- box-shadow:
221- 0 4px 6px -1px rgb(0 0 0 / 0.1),
222- 0 2px 4px -2px rgb(0 0 0 / 0.1);
223- transition: all 150ms;
224-}
225-
226-.omnibox-base:focus-within {
227- border-color: var(--primary);
228-}
229-
230-.omnibox-input {
231- width: 100%;
232- padding: 0.5rem 0.75rem;
233- background-color: transparent;
234- color: var(--foreground);
235- outline: none;
236- font-size: 0.875rem;
237-}
238-
239-.omnibox-input::placeholder {
240- color: var(--muted-foreground);
241-}
242-
243-/* Find bar */
244-.findbar {
245- display: flex;
246- align-items: center;
247- gap: 0.5rem;
248- padding: 0.5rem 0.75rem;
249-}
250-
251-.findbar-input {
252- flex: 1;
253- background-color: transparent;
254- color: var(--foreground);
255- outline: none;
256- font-size: 0.875rem;
257-}
258-
259-.findbar-input::placeholder {
260- color: var(--muted-foreground);
261-}
262-
263-.findbar-button {
264- padding: 0.25rem 0.5rem;
265- border-radius: 0;
266- color: var(--muted-foreground);
267- transition: color 150ms;
268- font-size: 0.875rem;
269-}
270-
271-.findbar-button:hover {
272- color: var(--foreground);
273-}
274-
275-.findbar-count {
276- font-size: 0.75rem;
277- color: var(--muted-foreground);
278- font-variant-numeric: tabular-nums;
279-}
280-
281-/* Find highlighting */
282-.find-highlight {
283- background-color: rgb(255 235 59);
284- color: rgb(0 0 0);
285- padding: 0 0.125rem;
286- border-radius: 0.125rem;
287- box-shadow: 0 0 0 1px rgb(200 185 0) inset;
288-}
289-
290-.find-active {
291- background-color: rgb(255 152 0) !important;
292- color: rgb(0 0 0);
293- box-shadow: 0 0 0 1px rgb(179 107 0) inset !important;
294-}
295-
296-/* Animation utilities */
297-.slide-in-top {
298- animation: slide-in-top 0.25s ease-out;
299-}
300-
301-.slide-out-top {
302- animation: slide-out-top 0.25s ease-in;
303-}
304-
305-.fade-in {
306- animation: fade-in 0.15s ease-out;
307-}
308-
309-.fade-out {
310- animation: fade-out 0.15s ease-in;
311-}
312-
313-@keyframes slide-in-top {
314- from {
315- transform: translateY(-100%);
316- opacity: 0;
317- }
318- to {
319- transform: translateY(0);
320- opacity: 1;
321- }
322-}
323-
324-@keyframes slide-out-top {
325- from {
326- transform: translateY(0);
327- opacity: 1;
328- }
329- to {
330- transform: translateY(-100%);
331- opacity: 0;
332- }
333-}
334-
335-@keyframes fade-in {
336- from { opacity: 0; }
337- to { opacity: 1; }
338-}
339-
340-@keyframes fade-out {
341- from { opacity: 1; }
342- to { opacity: 0; }
343-}
344-
345-/* Component isolation utility */
346-.browser-component-root {
347- all: initial;
348- font-family: Fira Sans, system-ui, -apple-system, sans-serif;
349- box-sizing: border-box;
350-}
351-
352-.browser-component-root * {
353- box-sizing: border-box;
354-}
M webui/tailwind.config.js +19 -0
@@ -10,6 +10,25 @@ export default {
1010 },
1111 // Custom design system colors
1212 colors: {
13+ border: "var(--border)",
14+ input: "var(--input)",
15+ ring: "var(--ring)",
16+ background: "var(--background)",
17+ foreground: "var(--foreground)",
18+ primary: "var(--primary)",
19+ "primary-foreground": "var(--primary-foreground)",
20+ secondary: "var(--secondary)",
21+ "secondary-foreground": "var(--secondary-foreground)",
22+ destructive: "var(--destructive)",
23+ "destructive-foreground": "var(--destructive-foreground)",
24+ muted: "var(--muted)",
25+ "muted-foreground": "var(--muted-foreground)",
26+ accent: "var(--accent)",
27+ "accent-foreground": "var(--accent-foreground)",
28+ popover: "var(--popover)",
29+ "popover-foreground": "var(--popover-foreground)",
30+ card: "var(--card)",
31+ "card-foreground": "var(--card-foreground)",
1332 // Browser-specific colors that work well in both themes
1433 browser: {
1534 bg: "rgb(var(--browser-bg) / <alpha-value>)",
@@ -10,6 +10,25 @@ export default {
10 },10 },
11 // Custom design system colors11 // Custom design system colors
12 colors: {12 colors: {
13+ border: "var(--border)",
14+ input: "var(--input)",
15+ ring: "var(--ring)",
16+ background: "var(--background)",
17+ foreground: "var(--foreground)",
18+ primary: "var(--primary)",
19+ "primary-foreground": "var(--primary-foreground)",
20+ secondary: "var(--secondary)",
21+ "secondary-foreground": "var(--secondary-foreground)",
22+ destructive: "var(--destructive)",
23+ "destructive-foreground": "var(--destructive-foreground)",
24+ muted: "var(--muted)",
25+ "muted-foreground": "var(--muted-foreground)",
26+ accent: "var(--accent)",
27+ "accent-foreground": "var(--accent-foreground)",
28+ popover: "var(--popover)",
29+ "popover-foreground": "var(--popover-foreground)",
30+ card: "var(--card)",
31+ "card-foreground": "var(--card-foreground)",
13 // Browser-specific colors that work well in both themes32 // Browser-specific colors that work well in both themes
14 browser: {33 browser: {
15 bg: "rgb(var(--browser-bg) / <alpha-value>)",34 bg: "rgb(var(--browser-bg) / <alpha-value>)",

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close