Skip to content

Commit 3c4d2e0

Browse files
committed
fix(frontend): port v4 DaisyUI CSS vars to v5 + full-width sidebar menu
Related #498 DaisyUI v5 renamed all theme CSS variables (--su->--color-success, --p->--color-primary, --b1/2/3->--color-base-100/200/300, --bc->--color-base-content) and the variable now holds the complete color (so the hsl()/oklch() wrapper must be dropped). The undefined v4 short vars resolved to black/none, which turned the dashboard connection dots/lines black and dropped the MCP logo glow. Converted ~50 references across Dashboard, TokenPieChart, HintsPanel and CollapsibleHintsPanel; opacity uses become color-mix(in oklch, <color> N%, transparent). Also: v5 .menu defaults to width:max-content, so the left sidebar nav items (and their active highlight) only spanned content width. Added w-full to the sidebar .menu lists (ul width 117px -> 231px, fills the rail). Verified: dots fill oklch(0.62 0.194 149.214) (green); logo glow restored; make build green.
1 parent e3136f3 commit 3c4d2e0

11 files changed

Lines changed: 71 additions & 61 deletions

File tree

frontend/src/components/CollapsibleHintsPanel.vue

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,17 @@ const copyToClipboard = async (text: string) => {
154154
align-items: center;
155155
gap: 0.75rem;
156156
padding: 0.75rem 1.25rem;
157-
background: hsl(var(--b2));
158-
border: 1px solid hsl(var(--bc) / 0.15);
157+
background: var(--color-base-200);
158+
border: 1px solid color-mix(in oklch, var(--color-base-content) 15%, transparent);
159159
border-radius: 0.5rem;
160160
cursor: pointer;
161161
transition: all 0.2s ease;
162162
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
163163
}
164164
165165
.hints-collapsed:hover {
166-
background: hsl(var(--b3));
167-
border-color: hsl(var(--bc) / 0.25);
166+
background: var(--color-base-300);
167+
border-color: color-mix(in oklch, var(--color-base-content) 25%, transparent);
168168
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
169169
}
170170
@@ -177,22 +177,22 @@ const copyToClipboard = async (text: string) => {
177177
font-weight: 600;
178178
font-size: 0.95rem;
179179
flex: 1;
180-
color: hsl(var(--bc) / 0.85);
180+
color: color-mix(in oklch, var(--color-base-content) 85%, transparent);
181181
}
182182
183183
.expand-icon,
184184
.collapse-icon {
185185
width: 1.25rem;
186186
height: 1.25rem;
187187
flex-shrink: 0;
188-
color: hsl(var(--bc) / 0.6);
188+
color: color-mix(in oklch, var(--color-base-content) 60%, transparent);
189189
transition: transform 0.2s ease;
190190
}
191191
192192
/* Expanded State */
193193
.hints-expanded {
194-
background: hsl(var(--b2));
195-
border: 1px solid hsl(var(--bc) / 0.15);
194+
background: var(--color-base-200);
195+
border: 1px solid color-mix(in oklch, var(--color-base-content) 15%, transparent);
196196
border-radius: 0.5rem;
197197
overflow: hidden;
198198
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
@@ -216,12 +216,12 @@ const copyToClipboard = async (text: string) => {
216216
justify-content: space-between;
217217
padding: 0.75rem 1.25rem;
218218
cursor: pointer;
219-
border-bottom: 1px solid hsl(var(--bc) / 0.1);
220-
background: hsl(var(--b3));
219+
border-bottom: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
220+
background: var(--color-base-300);
221221
}
222222
223223
.hints-header:hover {
224-
background: hsl(var(--b2));
224+
background: var(--color-base-200);
225225
}
226226
227227
.hints-header-left {
@@ -240,7 +240,7 @@ const copyToClipboard = async (text: string) => {
240240
.hint-section {
241241
margin-bottom: 2rem;
242242
padding-bottom: 2rem;
243-
border-bottom: 1px solid hsl(var(--bc) / 0.1);
243+
border-bottom: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
244244
}
245245
246246
.hint-section:last-child {
@@ -264,13 +264,13 @@ const copyToClipboard = async (text: string) => {
264264
.hint-section-title {
265265
font-size: 1.1rem;
266266
font-weight: 600;
267-
color: hsl(var(--bc));
267+
color: var(--color-base-content);
268268
margin: 0;
269269
}
270270
271271
.hint-description {
272272
margin: 0 0 1rem 0;
273-
color: hsl(var(--bc) / 0.7);
273+
color: color-mix(in oklch, var(--color-base-content) 70%, transparent);
274274
font-size: 0.9rem;
275275
line-height: 1.5;
276276
}
@@ -287,21 +287,21 @@ const copyToClipboard = async (text: string) => {
287287
.subsection-title {
288288
font-size: 0.95rem;
289289
font-weight: 600;
290-
color: hsl(var(--bc) / 0.9);
290+
color: color-mix(in oklch, var(--color-base-content) 90%, transparent);
291291
margin: 0 0 0.5rem 0;
292292
}
293293
294294
.subsection-text {
295295
margin: 0 0 0.75rem 0;
296-
color: hsl(var(--bc) / 0.7);
296+
color: color-mix(in oklch, var(--color-base-content) 70%, transparent);
297297
font-size: 0.875rem;
298298
line-height: 1.5;
299299
}
300300
301301
/* Code Blocks */
302302
.code-block-wrapper {
303-
background: hsl(var(--b3));
304-
border: 1px solid hsl(var(--bc) / 0.1);
303+
background: var(--color-base-300);
304+
border: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
305305
border-radius: 0.5rem;
306306
overflow: hidden;
307307
margin: 0.5rem 0;
@@ -312,32 +312,32 @@ const copyToClipboard = async (text: string) => {
312312
align-items: center;
313313
justify-content: space-between;
314314
padding: 0.5rem 0.75rem;
315-
background: hsl(var(--b2));
316-
border-bottom: 1px solid hsl(var(--bc) / 0.1);
315+
background: var(--color-base-200);
316+
border-bottom: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
317317
}
318318
319319
.code-language {
320320
font-size: 0.75rem;
321321
font-family: 'Courier New', Courier, monospace;
322-
color: hsl(var(--bc) / 0.6);
322+
color: color-mix(in oklch, var(--color-base-content) 60%, transparent);
323323
text-transform: uppercase;
324324
}
325325
326326
.copy-button {
327327
padding: 0.25rem 0.5rem;
328328
font-size: 0.75rem;
329329
background: transparent;
330-
border: 1px solid hsl(var(--bc) / 0.2);
330+
border: 1px solid color-mix(in oklch, var(--color-base-content) 20%, transparent);
331331
border-radius: 0.25rem;
332332
cursor: pointer;
333-
color: hsl(var(--bc) / 0.7);
333+
color: color-mix(in oklch, var(--color-base-content) 70%, transparent);
334334
transition: all 0.2s ease;
335335
}
336336
337337
.copy-button:hover {
338-
background: hsl(var(--bc) / 0.1);
339-
border-color: hsl(var(--bc) / 0.3);
340-
color: hsl(var(--bc));
338+
background: color-mix(in oklch, var(--color-base-content) 10%, transparent);
339+
border-color: color-mix(in oklch, var(--color-base-content) 30%, transparent);
340+
color: var(--color-base-content);
341341
}
342342
343343
.code-block {
@@ -347,8 +347,8 @@ const copyToClipboard = async (text: string) => {
347347
font-family: 'Courier New', Courier, monospace;
348348
font-size: 0.8rem;
349349
line-height: 1.5;
350-
color: hsl(var(--bc));
351-
background: hsl(var(--b3));
350+
color: var(--color-base-content);
351+
background: var(--color-base-300);
352352
}
353353
354354
.code-block code {
@@ -358,8 +358,8 @@ const copyToClipboard = async (text: string) => {
358358
359359
/* Simple Code (backward compatibility) */
360360
.simple-code {
361-
background: hsl(var(--b3));
362-
border: 1px solid hsl(var(--bc) / 0.1);
361+
background: var(--color-base-300);
362+
border: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
363363
border-radius: 0.5rem;
364364
padding: 0.75rem;
365365
margin: 0.5rem 0;
@@ -376,7 +376,7 @@ const copyToClipboard = async (text: string) => {
376376
.hint-list {
377377
margin: 0.5rem 0;
378378
padding-left: 1.5rem;
379-
color: hsl(var(--bc) / 0.8);
379+
color: color-mix(in oklch, var(--color-base-content) 80%, transparent);
380380
font-size: 0.875rem;
381381
line-height: 1.6;
382382
}
@@ -395,16 +395,16 @@ const copyToClipboard = async (text: string) => {
395395
}
396396
397397
.hints-content::-webkit-scrollbar-track {
398-
background: hsl(var(--b3));
398+
background: var(--color-base-300);
399399
border-radius: 0.25rem;
400400
}
401401
402402
.hints-content::-webkit-scrollbar-thumb {
403-
background: hsl(var(--bc) / 0.3);
403+
background: color-mix(in oklch, var(--color-base-content) 30%, transparent);
404404
border-radius: 0.25rem;
405405
}
406406
407407
.hints-content::-webkit-scrollbar-thumb:hover {
408-
background: hsl(var(--bc) / 0.5);
408+
background: color-mix(in oklch, var(--color-base-content) 50%, transparent);
409409
}
410410
</style>

frontend/src/components/HintsPanel.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const copyToClipboard = async (text: string) => {
103103
}
104104
105105
.collapse {
106-
border: 1px solid hsl(var(--bc) / 0.1);
106+
border: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
107107
}
108108
109109
.collapse-title {
@@ -129,20 +129,20 @@ code {
129129
130130
.mockup-code {
131131
padding: 1rem;
132-
background: hsl(var(--b3));
132+
background: var(--color-base-300);
133133
border-radius: 0.5rem;
134134
}
135135
136136
.prose {
137-
color: hsl(var(--bc));
137+
color: var(--color-base-content);
138138
}
139139
140140
.prose h4 {
141141
margin: 0.5rem 0;
142-
color: hsl(var(--bc));
142+
color: var(--color-base-content);
143143
}
144144
145145
.prose p {
146146
margin: 0.5rem 0;
147147
}
148-
</style>
148+
</style>

frontend/src/components/SidebarNav.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
>
9494
<!-- Server Edition: User Menu -->
9595
<template v-if="authStore.isTeamsEdition">
96-
<ul class="menu menu-sm gap-0.5 p-0">
96+
<ul class="menu menu-sm w-full gap-0.5 p-0">
9797
<li v-if="authStore.isAdmin && !collapsed" class="menu-title px-3 !py-1">
9898
<span class="text-[10px] font-semibold uppercase tracking-[0.12em] text-base-content/40">My Workspace</span>
9999
</li>
@@ -111,7 +111,7 @@
111111

112112
<template v-if="authStore.isAdmin">
113113
<div class="divider my-2 px-2"></div>
114-
<ul class="menu menu-sm gap-0.5 p-0">
114+
<ul class="menu menu-sm w-full gap-0.5 p-0">
115115
<li v-if="!collapsed" class="menu-title px-3 !py-1">
116116
<span class="text-[10px] font-semibold uppercase tracking-[0.12em] text-base-content/40">Administration</span>
117117
</li>
@@ -136,7 +136,7 @@
136136
to a quiet checkmark when all three tabs (clients/servers/verify)
137137
are satisfied. Click reopens the wizard at the first
138138
incomplete tab. -->
139-
<ul class="menu menu-sm gap-0.5 p-0 mb-1">
139+
<ul class="menu menu-sm w-full gap-0.5 p-0 mb-1">
140140
<li>
141141
<a
142142
href="#"
@@ -178,7 +178,7 @@
178178
</ul>
179179

180180
<!-- Dashboard (solo top row, no section label) -->
181-
<ul class="menu menu-sm gap-0.5 p-0">
181+
<ul class="menu menu-sm w-full gap-0.5 p-0">
182182
<li>
183183
<router-link
184184
to="/"
@@ -201,7 +201,7 @@
201201
</div>
202202
<div v-else class="mt-3 mb-1 mx-auto w-6 h-px bg-base-300"></div>
203203

204-
<ul class="menu menu-sm gap-0.5 p-0">
204+
<ul class="menu menu-sm w-full gap-0.5 p-0">
205205
<li>
206206
<router-link
207207
to="/servers"
@@ -296,7 +296,7 @@
296296
</div>
297297
<div v-else class="mt-3 mb-1 mx-auto w-6 h-px bg-base-300"></div>
298298

299-
<ul class="menu menu-sm gap-0.5 p-0">
299+
<ul class="menu menu-sm w-full gap-0.5 p-0">
300300
<li>
301301
<router-link
302302
to="/repositories"

frontend/src/components/TokenPieChart.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const chartData = computed(() => ({
3535
data: props.data.map(d => d.value),
3636
backgroundColor: props.data.map(d => d.color),
3737
borderWidth: 2,
38-
borderColor: 'hsl(var(--b1))'
38+
borderColor: 'var(--color-base-100)'
3939
}
4040
]
4141
}))

frontend/src/views/Dashboard.vue

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,40 +142,40 @@
142142
<!-- Connection lines: one fat horizontal line each side, big green running dot -->
143143
<svg class="absolute inset-0 w-full h-full pointer-events-none hidden lg:block overflow-visible" preserveAspectRatio="none">
144144
<!-- Left fat line (clients → hub) -->
145-
<line x1="0" y1="50%" x2="42%" y2="50%" stroke="oklch(var(--su))" stroke-width="4" stroke-opacity="0.25" />
145+
<line x1="0" y1="50%" x2="42%" y2="50%" stroke="var(--color-success)" stroke-width="4" stroke-opacity="0.25" />
146146
<!-- Right fat line (hub → servers) -->
147-
<line x1="58%" y1="50%" x2="100%" y2="50%" stroke="oklch(var(--su))" stroke-width="4" stroke-opacity="0.25" />
147+
<line x1="58%" y1="50%" x2="100%" y2="50%" stroke="var(--color-success)" stroke-width="4" stroke-opacity="0.25" />
148148

149149
<!-- Green dots travel once every 20s cycle, 4 dots total -->
150150
<!-- Left dot 1: clients → hub -->
151-
<circle r="7" fill="oklch(var(--su))" opacity="0">
151+
<circle r="7" fill="var(--color-success)" opacity="0">
152152
<animate attributeName="cx" values="0%;0%;42%;42%" keyTimes="0;0.05;0.15;1" dur="20s" repeatCount="indefinite" />
153153
<animate attributeName="cy" values="50%;50%;50%;50%" dur="20s" repeatCount="indefinite" />
154154
<animate attributeName="opacity" values="0;0.9;0.9;0;0" keyTimes="0;0.05;0.13;0.15;1" dur="20s" repeatCount="indefinite" />
155155
</circle>
156156
<!-- Left dot 2: clients → hub, staggered -->
157-
<circle r="6" fill="oklch(var(--su))" opacity="0">
157+
<circle r="6" fill="var(--color-success)" opacity="0">
158158
<animate attributeName="cx" values="0%;0%;42%;42%" keyTimes="0;0.1;0.2;1" dur="20s" repeatCount="indefinite" />
159159
<animate attributeName="cy" values="50%;50%;50%;50%" dur="20s" repeatCount="indefinite" />
160160
<animate attributeName="opacity" values="0;0.7;0.7;0;0" keyTimes="0;0.1;0.18;0.2;1" dur="20s" repeatCount="indefinite" />
161161
</circle>
162162

163163
<!-- Right dot 1: servers → hub -->
164-
<circle r="7" fill="oklch(var(--su))" opacity="0">
164+
<circle r="7" fill="var(--color-success)" opacity="0">
165165
<animate attributeName="cx" values="100%;100%;58%;58%" keyTimes="0;0.07;0.17;1" dur="20s" repeatCount="indefinite" />
166166
<animate attributeName="cy" values="50%;50%;50%;50%" dur="20s" repeatCount="indefinite" />
167167
<animate attributeName="opacity" values="0;0.9;0.9;0;0" keyTimes="0;0.07;0.15;0.17;1" dur="20s" repeatCount="indefinite" />
168168
</circle>
169169
<!-- Right dot 2: servers → hub, staggered -->
170-
<circle r="6" fill="oklch(var(--su))" opacity="0">
170+
<circle r="6" fill="var(--color-success)" opacity="0">
171171
<animate attributeName="cx" values="100%;100%;58%;58%" keyTimes="0;0.12;0.22;1" dur="20s" repeatCount="indefinite" />
172172
<animate attributeName="cy" values="50%;50%;50%;50%" dur="20s" repeatCount="indefinite" />
173173
<animate attributeName="opacity" values="0;0.7;0.7;0;0" keyTimes="0;0.12;0.2;0.22;1" dur="20s" repeatCount="indefinite" />
174174
</circle>
175175

176176
<!-- Static green dots at hub connection points -->
177-
<circle cx="42%" cy="50%" r="5" fill="oklch(var(--su))" opacity="0.7" />
178-
<circle cx="58%" cy="50%" r="5" fill="oklch(var(--su))" opacity="0.7" />
177+
<circle cx="42%" cy="50%" r="5" fill="var(--color-success)" opacity="0.7" />
178+
<circle cx="58%" cy="50%" r="5" fill="var(--color-success)" opacity="0.7" />
179179
</svg>
180180

181181
<!-- Token savings badge (above hub) -->
@@ -824,10 +824,10 @@ onUnmounted(() => {
824824
/* Hub glow animation when MCPProxy is active — uses drop-shadow to follow the logo shape */
825825
@keyframes hubGlow {
826826
0%, 100% {
827-
filter: drop-shadow(0 4px 8px oklch(var(--p) / 0.15)) drop-shadow(0 2px 4px oklch(var(--p) / 0.1));
827+
filter: drop-shadow(0 4px 8px color-mix(in oklch, var(--color-primary) 15%, transparent)) drop-shadow(0 2px 4px color-mix(in oklch, var(--color-primary) 10%, transparent));
828828
}
829829
50% {
830-
filter: drop-shadow(0 6px 16px oklch(var(--p) / 0.3)) drop-shadow(0 3px 8px oklch(var(--p) / 0.15));
830+
filter: drop-shadow(0 6px 16px color-mix(in oklch, var(--color-primary) 30%, transparent)) drop-shadow(0 3px 8px color-mix(in oklch, var(--color-primary) 15%, transparent));
831831
}
832832
}
833833
124 KB
Loading
27.3 KB
Loading
13.3 KB
Loading
1.79 KB
Loading

specs/055-frontend-major-upgrades/verification/build-report.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,15 @@ def img(path, cls="shot"):
6363
<table>
6464
<tr><th>Regression</th><th>Cause (v5 breaking change)</th><th>Fix</th></tr>
6565
<tr><td>Form labels/inputs misaligned across ~16 views</td><td>v5 removed <code>.form-control</code> and repurposed <code>.label</code>/<code>.label-text</code></td><td>Unlayered compat shim in <code>main.css</code> restoring v4 stack semantics (overrides DaisyUI's cascade layer)</td></tr>
66+
<tr><td>Form inputs only ~half width</td><td>v5 gives <code>.input</code>/<code>.select</code>/<code>.textarea</code> an intrinsic width, so <code>form-control</code>'s flex stretch no longer fills the row</td><td><code>.form-control :where(.input,.select,.textarea){{width:100%}}</code> in the shim</td></tr>
6667
<tr><td>Manual/Import &amp; server-detail tabs looked like plain text</td><td><code>tabs-boxed</code>→<code>tabs-box</code>, <code>tabs-bordered</code>→<code>tabs-border</code> renamed in v5</td><td>Renamed tab containers in AddServerModal, OnboardingWizard, ServerDetail</td></tr>
6768
<tr><td>Theme dropdown clipped (labels + title cut off-screen)</td><td>Menu too narrow (<code>w-64</code>) and <code>dropdown-end</code> pushed a wider menu off the left of the viewport from the left sidebar</td><td>Widened to <code>w-72</code> + <code>flex-nowrap</code>; dropped <code>dropdown-end</code> so it opens rightward (left edge x: −85px → +12px, on-screen)</td></tr>
69+
<tr><td>Sidebar nav items + active highlight only content-width</td><td>v5 <code>.menu</code> defaults to <code>width: max-content</code> (v4 filled the rail)</td><td>Added <code>w-full</code> to the sidebar <code>.menu</code> lists (ul width 117px → 231px)</td></tr>
70+
<tr><td>Dashboard connection dots/lines black; MCP logo glow gone</td><td>v5 renamed all theme CSS vars (<code>--su</code>→<code>--color-success</code>, <code>--p</code>→<code>--color-primary</code>, <code>--b1/2/3</code>, <code>--bc</code>) and the var now holds the full color (no <code>hsl()</code>/<code>oklch()</code> wrapper); undefined short vars resolved to black/none</td><td>Converted ~50 refs across Dashboard, TokenPieChart, Hints panels to v5 vars; opacity uses → <code>color-mix(in oklch, …, transparent)</code></td></tr>
6871
</table>
69-
<div class="pair">
72+
<div class="qa-grid">
73+
<figure><figcaption>Dashboard — fixed (green connection dots/lines + MCP logo glow restored)</figcaption>{img(os.path.join(EXTRAS, "dashboard-fixed.png"))}</figure>
74+
<figure><figcaption>Sidebar nav — fixed (items + active highlight fill the rail)</figcaption>{img(os.path.join(EXTRAS, "sidebar-servers.png"))}</figure>
7075
<figure><figcaption>Add-server form — fixed (labels stack, full-width inputs, boxed tabs)</figcaption>{img(form)}</figure>
7176
<figure><figcaption>Theme dropdown — fixed (on-screen, all 32 themes + swatches fit)</figcaption>{img(theme)}</figure>
7277
</div>"""

0 commit comments

Comments
 (0)