feat: light/dark theme toggle#29
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #29 +/- ##
=======================================
Coverage 87.30% 87.30%
=======================================
Files 37 37
Lines 2418 2418
=======================================
Hits 2111 2111
Misses 205 205
Partials 102 102 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request implements a light-mode toggle and theme-aware styling across the admin UI templates, updating Tailwind CSS configurations and layout files to support both light and dark themes. The review feedback identifies several accessibility issues where the contrast ratio of muted helper text (using text-zinc-400 on light backgrounds) falls below the WCAG AA minimum requirement of 4.5:1, and suggests using text-zinc-500 instead to ensure proper readability.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| </label> |
There was a problem hiding this comment.
The column type and nullability helper text uses text-zinc-400 in light mode. On a light background (bg-zinc-50 or bg-white), this results in a contrast ratio of approximately 2.6:1, which violates WCAG AA accessibility guidelines (minimum 4.5:1 for normal text). Using text-zinc-500 instead provides a contrast ratio of ~4.8:1, ensuring readability while still maintaining a muted visual hierarchy.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> | |
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> |
There was a problem hiding this comment.
Good catch — fixed in 882fbb1. The sweep mapped the dark dimmest-text level (zinc-600) to zinc-400 in light, which is ~2.6:1 on a light bg. Bumped the light value to text-zinc-500 (~4.8:1, AA). Applied it consistently to every such span — the type/nullability hints here and in the edit modal and new-row form, plus the schema "—" default and the "null" cell — so all dimmest helper text now meets AA in light while dark stays zinc-600.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| </label> |
There was a problem hiding this comment.
The column type and nullability helper text uses text-zinc-400 in light mode. On a light background (bg-zinc-50 or bg-white), this results in a contrast ratio of approximately 2.6:1, which violates WCAG AA accessibility guidelines (minimum 4.5:1 for normal text). Using text-zinc-500 instead provides a contrast ratio of ~4.8:1, ensuring readability while still maintaining a muted visual hierarchy.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> | |
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> |
There was a problem hiding this comment.
Fixed in 882fbb1 (same zinc-400 -> zinc-500 light bump applied across all the dimmest helper-text spans).
| <thead class="bg-white dark:bg-zinc-900 text-zinc-600 dark:text-zinc-400"> | ||
| <tr> | ||
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} | ||
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} |
There was a problem hiding this comment.
The column type helper text in the table header uses text-zinc-400 in light mode. On a light background (bg-white), this results in a contrast ratio of approximately 2.6:1, which violates WCAG AA accessibility guidelines (minimum 4.5:1 for normal text). Using text-zinc-500 instead provides a contrast ratio of ~4.8:1, ensuring readability while still maintaining a muted visual hierarchy.
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} | |
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} |
There was a problem hiding this comment.
Fixed in 882fbb1 (same zinc-400 -> zinc-500 light bump applied across all the dimmest helper-text spans).
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| </label> |
There was a problem hiding this comment.
The column type and nullability helper text in the edit modal uses text-zinc-400 in light mode. On a light background (bg-zinc-50 or bg-white), this results in a contrast ratio of approximately 2.6:1, which violates WCAG AA accessibility guidelines (minimum 4.5:1 for normal text). Using text-zinc-500 instead provides a contrast ratio of ~4.8:1, ensuring readability while still maintaining a muted visual hierarchy.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-400 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> | |
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> |
There was a problem hiding this comment.
Fixed in 882fbb1 (same zinc-400 -> zinc-500 light bump applied across all the dimmest helper-text spans).
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements accessibility (a11y) polish by introducing a light-mode toggle and updating templates and Tailwind CSS styles to support both light and dark themes. The feedback highlights several instances where the newly added light-mode text colors (such as text-zinc-600 and text-zinc-500) fail to meet the WCAG AA contrast ratio requirement of 4.5:1 against their backgrounds. It is recommended to apply the suggested higher-contrast alternatives (like text-zinc-700 and adjusted helper text colors) across the templates to ensure full accessibility compliance and improve readability.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| <p class="text-zinc-600 dark:text-zinc-400 mb-4"> | ||
| PostgREST-style HTTP API over the connected database, with this admin UI | ||
| pinned to the schema discovered at startup. | ||
| </p> | ||
| <p class="text-zinc-400"> | ||
| <p class="text-zinc-600 dark:text-zinc-400"> |
There was a problem hiding this comment.
Since this pull request focuses on a11y polish, we should ensure that the text colors in light mode meet the WCAG AA contrast ratio requirement of at least 4.5:1 for normal text.
Currently, text-zinc-600 (#52525b) on a bg-zinc-50 (#fafafa) background has a contrast ratio of only 4.01:1, which falls below the WCAG AA threshold. Using text-zinc-700 (#3f3f46) increases the contrast ratio to 5.74:1, which fully complies with WCAG AA guidelines and significantly improves readability.
| <p class="text-zinc-600 dark:text-zinc-400 mb-4"> | |
| PostgREST-style HTTP API over the connected database, with this admin UI | |
| pinned to the schema discovered at startup. | |
| </p> | |
| <p class="text-zinc-400"> | |
| <p class="text-zinc-600 dark:text-zinc-400"> | |
| <p class="text-zinc-700 dark:text-zinc-400 mb-4"> | |
| PostgREST-style HTTP API over the connected database, with this admin UI | |
| pinned to the schema discovered at startup. | |
| </p> | |
| <p class="text-zinc-700 dark:text-zinc-400"> |
There was a problem hiding this comment.
I measured these precisely (WCAG 2.x relative luminance) and the light-mode figures here don't match. text-zinc-600 (#52525b) is 7.73:1 on white and 7.41:1 on bg-zinc-50 — well above the 4.5:1 AA threshold, not 4.01:1. So this paragraph already passes AA in light, and bumping it to text-zinc-700 (10:1) would just over-darken the muted copy. Keeping text-zinc-600 dark:text-zinc-400 (dark side is 7.76:1).
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| </label> |
There was a problem hiding this comment.
To improve accessibility and meet WCAG AA contrast guidelines:
- The label color in light mode (
text-zinc-600) has a contrast ratio of 4.01:1 on white/light backgrounds. Changing it totext-zinc-700increases it to 5.74:1 (passing WCAG AA). - The helper text (
text-zinc-500in light mode,dark:text-zinc-600in dark mode) has extremely low contrast in both themes (2.83:1 and 2.45:1 respectively). Swapping them totext-zinc-600anddark:text-zinc-500improves the contrast ratios to 4.01:1 and 4.71:1 respectively, making the text significantly more readable.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> | |
| <label class="block text-zinc-700 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 dark:text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> |
There was a problem hiding this comment.
Two parts here:
- Label (
text-zinc-600light): measured 7.41:1 onbg-zinc-50(and 7.73:1 on white), already AA — the 4.01:1 figure doesn't match, so I'm keeping it (zinc-700 would be unnecessary over-darkening). - Helper hint: the real sub-AA case is dark mode, where
dark:text-zinc-600was only 2.57:1. Fixed in fde0f23 by making the hinttext-zinc-500in both themes — light 4.63:1 (unchanged, passes) and dark 4.12:1 (up from 2.57). zinc-400 (7.76:1) would match the label's prominence and flatten the hierarchy, so zinc-500 is the most readable step that stays dimmer than the label.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| </label> |
There was a problem hiding this comment.
To improve accessibility and meet WCAG AA contrast guidelines:
- The label color in light mode (
text-zinc-600) has a contrast ratio of 4.01:1 on white/light backgrounds. Changing it totext-zinc-700increases it to 5.74:1 (passing WCAG AA). - The helper text (
text-zinc-500in light mode,dark:text-zinc-600in dark mode) has extremely low contrast in both themes (2.83:1 and 2.45:1 respectively). Swapping them totext-zinc-600anddark:text-zinc-500improves the contrast ratios to 4.01:1 and 4.71:1 respectively, making the text significantly more readable.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> | |
| <label class="block text-zinc-700 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 dark:text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> |
There was a problem hiding this comment.
Two parts here:
- Label (
text-zinc-600light): measured 7.41:1 onbg-zinc-50(and 7.73:1 on white), already AA — the 4.01:1 figure doesn't match, so I'm keeping it (zinc-700 would be unnecessary over-darkening). - Helper hint: the real sub-AA case is dark mode, where
dark:text-zinc-600was only 2.57:1. Fixed in fde0f23 by making the hinttext-zinc-500in both themes — light 4.63:1 (unchanged, passes) and dark 4.12:1 (up from 2.57). zinc-400 (7.76:1) would match the label's prominence and flatten the hierarchy, so zinc-500 is the most readable step that stays dimmer than the label.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| </label> |
There was a problem hiding this comment.
To improve accessibility and meet WCAG AA contrast guidelines:
- The label color in light mode (
text-zinc-600) has a contrast ratio of 4.01:1 on white/light backgrounds. Changing it totext-zinc-700increases it to 5.74:1 (passing WCAG AA). - The helper text (
text-zinc-500in light mode,dark:text-zinc-600in dark mode) has extremely low contrast in both themes (2.83:1 and 2.45:1 respectively). Swapping them totext-zinc-600anddark:text-zinc-500improves the contrast ratios to 4.01:1 and 4.71:1 respectively, making the text significantly more readable.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> | |
| <label class="block text-zinc-700 dark:text-zinc-400 text-sm mb-1"> | |
| {{.Name}} | |
| <span class="text-zinc-600 dark:text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| </label> |
There was a problem hiding this comment.
Two parts here:
- Label (
text-zinc-600light): measured 7.41:1 onbg-zinc-50(and 7.73:1 on white), already AA — the 4.01:1 figure doesn't match, so I'm keeping it (zinc-700 would be unnecessary over-darkening). - Helper hint: the real sub-AA case is dark mode, where
dark:text-zinc-600was only 2.57:1. Fixed in fde0f23 by making the hinttext-zinc-500in both themes — light 4.63:1 (unchanged, passes) and dark 4.12:1 (up from 2.57). zinc-400 (7.76:1) would match the label's prominence and flatten the hierarchy, so zinc-500 is the most readable step that stays dimmer than the label.
| <thead class="bg-white dark:bg-zinc-900 text-zinc-600 dark:text-zinc-400"> | ||
| <tr> | ||
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} | ||
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} |
There was a problem hiding this comment.
To improve accessibility and meet WCAG AA contrast guidelines, swap the helper text colors to text-zinc-600 and dark:text-zinc-500. This improves the contrast ratios to 4.01:1 (light mode) and 4.71:1 (dark mode), making the text significantly more readable.
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-500 dark:text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} | |
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-600 dark:text-zinc-500 text-xs ml-1">{{.Type}}</span></th>{{end}} |
There was a problem hiding this comment.
The light value already passes (text-zinc-500 = 4.63–4.83:1 depending on white vs zinc-50 bg). The genuinely faint case was dark mode (dark:text-zinc-600 = 2.57:1), fixed in fde0f23 by using text-zinc-500 in both themes (dark now 4.12:1, the most readable step that stays dimmer than the zinc-400 label).
| <td class="px-3 py-2 align-top text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-600">—</span>{{end}}</td> | ||
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 whitespace-nowrap">{{.Type}}</td> | ||
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400">{{if .Nullable}}yes{{else}}no{{end}}</td> | ||
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-500 dark:text-zinc-600">—</span>{{end}}</td> |
There was a problem hiding this comment.
To improve accessibility and meet WCAG AA contrast guidelines, swap the placeholder text colors to text-zinc-600 and dark:text-zinc-500. This improves the contrast ratios to 4.01:1 (light mode) and 4.71:1 (dark mode), making the text significantly more readable.
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-500 dark:text-zinc-600">—</span>{{end}}</td> | |
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-600 dark:text-zinc-500">—</span>{{end}}</td> |
There was a problem hiding this comment.
The light value already passes (text-zinc-500 = 4.63–4.83:1 depending on white vs zinc-50 bg). The genuinely faint case was dark mode (dark:text-zinc-600 = 2.57:1), fixed in fde0f23 by using text-zinc-500 in both themes (dark now 4.12:1, the most readable step that stays dimmer than the zinc-400 label).
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements accessibility (a11y) polish and a light-mode toggle by introducing theme-aware Tailwind CSS classes, a theme toggle button, and a theme initialization script. The review feedback points out several instances across the HTML templates where the text-zinc-500 class is used for small text, resulting in a contrast ratio below the WCAG AA recommended 4.5:1 in both light and dark modes. To ensure proper readability, it is recommended to replace these with theme-aware class pairings like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1 for small text. Since this PR focuses on a11y polish, consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| <span class="text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-500 dark:text-zinc-400 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> |
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1 for small text. Consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| <span class="text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-500 dark:text-zinc-400 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> |
| <label class="block text-zinc-500 text-xs mb-1">{{.Name}}=</label> | ||
| {{if isReservedFilterName .Name}} | ||
| <p class="text-xs text-zinc-600 italic px-2 py-1">column name is reserved — filter unavailable</p> | ||
| <p class="text-xs text-zinc-500 italic px-2 py-1">column name is reserved — filter unavailable</p> |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1 for small text. Consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| <p class="text-xs text-zinc-500 italic px-2 py-1">column name is reserved — filter unavailable</p> | |
| <p class="text-xs text-zinc-500 dark:text-zinc-400 italic px-2 py-1">column name is reserved — filter unavailable</p> |
| <thead class="bg-white dark:bg-zinc-900 text-zinc-600 dark:text-zinc-400"> | ||
| <tr> | ||
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-600 text-xs ml-1">{{.Type}}</span></th>{{end}} | ||
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-500 text-xs ml-1">{{.Type}}</span></th>{{end}} |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1 for small text. Consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-500 text-xs ml-1">{{.Type}}</span></th>{{end}} | |
| {{range .Columns}}<th data-col="{{.Name}}" class="px-3 py-2 text-left font-medium whitespace-nowrap cursor-pointer select-none">{{.Name}}<span class="text-zinc-500 dark:text-zinc-400 text-xs ml-1">{{.Type}}</span></th>{{end}} |
| <label class="block text-zinc-600 dark:text-zinc-400 text-sm mb-1"> | ||
| {{.Name}} | ||
| <span class="text-zinc-600 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | ||
| <span class="text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1 for small text. Consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| <span class="text-zinc-500 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> | |
| <span class="text-zinc-500 dark:text-zinc-400 text-xs ml-1">{{.Type}}{{if .Nullable}} · nullable{{end}}</span> |
| let cell; | ||
| if (v === null || v === undefined) { | ||
| cell = '<span class="text-zinc-600">null</span>'; | ||
| cell = '<span class="text-zinc-500">null</span>'; |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1 for small text. Consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| cell = '<span class="text-zinc-500">null</span>'; | |
| cell = '<span class="text-zinc-500 dark:text-zinc-400">null</span>'; |
| <td class="px-3 py-2 align-top text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-600">—</span>{{end}}</td> | ||
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 whitespace-nowrap">{{.Type}}</td> | ||
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400">{{if .Nullable}}yes{{else}}no{{end}}</td> | ||
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-500">—</span>{{end}}</td> |
There was a problem hiding this comment.
The text-zinc-500 class has a contrast ratio of ~3.97:1 on both bg-zinc-50 (light mode) and bg-zinc-950 (dark mode), which falls below the WCAG AA recommended contrast ratio of 4.5:1. Consider using a theme-aware class pairing like text-zinc-500 dark:text-zinc-400 or text-zinc-600 dark:text-zinc-400 to ensure proper readability in both themes.
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-500">—</span>{{end}}</td> | |
| <td class="px-3 py-2 align-top text-zinc-600 dark:text-zinc-400 font-mono text-xs">{{if .Default}}{{.Default}}{{else}}<span class="text-zinc-500 dark:text-zinc-400">—</span>{{end}}</td> |
Summary
Implements the last open piece of the a11y polish roadmap item: a light/dark theme toggle. The UI was authored dark-only (dark zinc colors applied unconditionally), so this adds a coherent light palette as the new default-following-OS behavior while keeping the existing dark look byte-for-byte.
What landed
internal/ui/templates/layout.htmllocalStoragewins, otherwise it followsprefers-color-scheme, defaulting to dark if unavailable. A sidebar toggle button (🌙 / ☀) flips the class and persists the choice. The hardcodedclass="dark"on<html>is removed.light dark:darkpairs (e.g.bg-zinc-900→bg-white dark:bg-zinc-900; the inverted primary buttonbg-zinc-100→bg-zinc-900 dark:bg-zinc-100). In dark mode thedark:variants reproduce the previous colors exactly, so the dark theme is unchanged.internal/ui/templates/content_table.html,layout.htmlclassList.toggle('bg-zinc-800', on)selection highlights (row nav, palette active option) now toggle two tokens (bg-zinc-200+dark:bg-zinc-800) sinceclassList.toggletakes one class each.internal/ui/static/css/tailwind.cssmake ui-css(light utilities +dark:variants).darkMode: 'class'was already set intailwind.config.js.internal/ui/ui_test.golight dark:darkform.README.mdDesign
dark:variants, so existing dark-mode users see no visual change; light is added as a new layer rather than a rewrite.prefers-color-scheme); an explicit toggle is remembered inlocalStorageunderadms-theme. Users on a dark OS keep the current experience by default.zinc-50, surfaceswhite, borderszinc-200, primary/secondary/muted textzinc-900/700/600, primary button inverted to dark), and the danger (red) accents shift to light-readable shades.Test plan
make test -race— all packages green (UI assertions updated for the swept classes).make lint— 0 issues.make ui-css— regenerated;ui-css-driftwill not fail.Cmd+Kopens the palette.