mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(ui): restore the purple dark sidebar from v4.5.0
- Bring back the #120e1a sidebar with its brand wash, lavender tiles, edges, Search, section labels, and account menu in the default dark theme. - Keep the neutral sidebar rules for custom themes. - Set the Coolify preset sidebar to #1a0f2d, the color the dark sidebar shows. - Update DESIGN.md to match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
029827db9e
commit
73b1ad1587
@@ -36,10 +36,10 @@ change.
|
||||
pure neutral gray.
|
||||
- **One accent.** Coolify purple in both themes (`#6b16ed`, hover `#7317ff`,
|
||||
pressed `#5a12c7`, depth `#4a0fa3`, light text and icons `#a391ff`). Yellow
|
||||
is only for real warnings. The dark sidebar, including the logo cell, is
|
||||
quiet neutral near-black (`#0d0d0d`), so the content keeps the focus; only
|
||||
the current item's tile is purple. The dark command palette has a
|
||||
light purple tint. The page canvas stays neutral.
|
||||
is only for real warnings. In the default dark theme the sidebar, including
|
||||
the logo cell, is purple-black (`#120e1a`) with a faint brand wash. Users
|
||||
who want a neutral sidebar can pick a custom theme. The dark command palette
|
||||
has a light purple tint. The page canvas stays neutral.
|
||||
- **Quiet text.** Sentence case. A clear text ladder: primary, dim, faint.
|
||||
No em dashes in UI copy.
|
||||
|
||||
@@ -127,7 +127,7 @@ follow the theme.
|
||||
--ui-accent-edge: #4a0fa3;
|
||||
--ui-accent-fg: #ffffff;
|
||||
--ui-accent-light: #a391ff;
|
||||
--ui-sidebar: #0d0d0d;
|
||||
--ui-sidebar: #120e1a;
|
||||
--ui-card: #121212;
|
||||
--ui-success: oklch(72.27% 0.192 149.58);
|
||||
--ui-warning: oklch(88.13% 0.1507 91.7);
|
||||
@@ -144,8 +144,9 @@ Rules for the tokens:
|
||||
- Floating surfaces (menus, popovers, tooltips, modals) must be opaque. Use
|
||||
`--ui-menu-bg`, never a translucent value, or the content behind shows
|
||||
through.
|
||||
- Keep the page canvas, cards, menus, logs, and the sidebar pure neutral
|
||||
(chroma 0). The dark command palette is the only tinted surface.
|
||||
- Keep the page canvas, cards, menus, and logs pure neutral (chroma 0). The
|
||||
default dark sidebar, the logo cell above it, and the dark command palette
|
||||
are the tinted surfaces.
|
||||
- **Dark lightness level.** The canvas is at 14.48% and the header panel at
|
||||
19.13%. To
|
||||
change the level, move every dark surface and border token by the same
|
||||
@@ -220,11 +221,12 @@ Class names below are examples. Keep the values and structure.
|
||||
well is `--ui-panel` (`#121212`). Tables use the same pair: the darker mix
|
||||
for the header row and `--ui-panel` for the rows.
|
||||
- In light mode the sidebar is the canvas color and has a 1px
|
||||
`--ui-chrome-border` right edge. In dark mode the sidebar column, including
|
||||
the logo cell, is a flat neutral `#0d0d0d` (one step above the `#0a0a0a`
|
||||
canvas) with a faint `rgb(255 255 255 / 0.06)` right edge. Do not add a
|
||||
brand tint or wash to the sidebar: a colored sidebar competes with the
|
||||
content for attention.
|
||||
`--ui-chrome-border` right edge. In the default dark theme the sidebar
|
||||
column, including the logo cell, is `#120e1a` with a faint lavender right
|
||||
edge (`rgb(163 145 255 / 0.10)`). The nav has a brand-purple wash that
|
||||
starts at 9% and fades out; the logo cell has a flat 9% wash, so the two
|
||||
read as one surface. A custom theme gets the neutral sidebar rules and its
|
||||
own sidebar color.
|
||||
- The top bar matches the canvas. It has no bottom border at rest. After the
|
||||
page scrolls under it, dark mode draws a neutral hairline
|
||||
(`rgb(255 255 255 / 0.06)`), a translucent bar, blur, and a soft shadow.
|
||||
@@ -679,12 +681,13 @@ lift off the content:
|
||||
mode, top-level card wells and table rows use `--color-card` (`#121212`),
|
||||
not the top bar.
|
||||
- **Desktop sidebar and the topbar brand block** (Coolify name and version)
|
||||
use the canvas color in light mode. In dark mode they use `--color-sidebar`
|
||||
(`#0d0d0d`), flat and neutral, with a `rgb(255 255 255 / 0.06)` right edge.
|
||||
Inactive icon tiles, Search, the account button in the footer, and section
|
||||
labels (10.5px uppercase mono, `--color-nav-muted`) are neutral gray. Only
|
||||
the current item's tile uses the brand purple, so the sidebar does not
|
||||
compete with the content. Chevrons are hidden until the row is hovered,
|
||||
use the canvas color in light mode. In the default dark theme they use
|
||||
`--color-sidebar` (`#120e1a`): a vertical brand wash on the nav, a flat 9%
|
||||
wash on the logo cell, and a lavender right edge. Inactive icon tiles,
|
||||
Search, the account button, and section labels (10.5px uppercase mono) are
|
||||
lavender. The Admin icon stays neutral. These purple rules use
|
||||
`html.dark:not([data-theme="custom"])`; a custom theme keeps neutral tiles,
|
||||
Search, and account button. Chevrons are hidden until the row is hovered,
|
||||
focused, or current. Do not use `dark:border-white/[0.06]` on these chrome
|
||||
edges; a global rule forces that utility to the solid hairline grey.
|
||||
|
||||
@@ -695,9 +698,9 @@ value. The dark ladder is `--color-app` 10, `--color-panel` 20,
|
||||
`--coollabs-recessed` 34 (sRGB, r=g=b), which reads as distinct surfaces.
|
||||
|
||||
Temperature: the page canvas, cards, menus, listboxes, modals, and logs stay
|
||||
**pure neutral gray** (r=g=b). Do not tint those. The dark sidebar
|
||||
(`--color-sidebar`, `#0d0d0d`) is neutral too. The dark command palette is the
|
||||
only exception: it carries a faint brand-purple wash. A custom theme derives all
|
||||
**pure neutral gray** (r=g=b). Do not tint those. The exceptions are the
|
||||
default dark sidebar (`--color-sidebar`, `#120e1a`, with a brand-purple wash)
|
||||
and the dark command palette (a faint brand-purple wash). A custom theme derives all
|
||||
of these surfaces from its background and sidebar colors (see the token rules in P2). The light page canvas uses `bg-neutral-50` (not
|
||||
`bg-gray-50`, which is faintly cool) so it matches the neutral cards and chrome.
|
||||
The only intentional color is the purple brand accent. Yellow is for warnings.
|
||||
|
||||
+64
-8
@@ -1319,7 +1319,7 @@ html:not(.dark) .application-console-shell[data-console-theme="system"] .termina
|
||||
/* Cards sit one step above the #0a0a0a canvas. The top bar uses the canvas,
|
||||
not this color. The sidebar uses --color-sidebar. */
|
||||
--color-card: #121212;
|
||||
--color-sidebar: #0d0d0d;
|
||||
--color-sidebar: #120e1a;
|
||||
/* Dark surface ladder in hex (sRGB), not oklch: oklch lightness compresses
|
||||
to near-black below ~15%, so oklch(15%) rendered as sRGB 11 and cards
|
||||
could not lift off the content canvas (sRGB 10). These give clear,
|
||||
@@ -6250,9 +6250,9 @@ html.dark .canvas-zoom-max {
|
||||
}
|
||||
}
|
||||
|
||||
/* Brand shell (dark): black canvas and top bar, quiet neutral sidebar, scroll hairline.
|
||||
The sidebar stays neutral so the content keeps the focus; only the current item
|
||||
uses the brand purple. Light mode keeps the neutral shell. Floating navigation
|
||||
/* Brand shell (dark): black canvas and top bar, sidebar, scroll hairline.
|
||||
The default dark theme tints the sidebar purple (below); a custom theme gets
|
||||
these neutral rules. Light mode keeps the neutral shell. Floating navigation
|
||||
keeps its own frame. */
|
||||
html.dark .app-sidebar nav.sidebar-nav,
|
||||
html.dark .mobile-sidebar-sheet [role="dialog"] {
|
||||
@@ -6279,20 +6279,20 @@ html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search {
|
||||
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06) !important;
|
||||
}
|
||||
|
||||
/* The account button is a .button, which is purple in dark mode; keep it neutral in the sidebar. */
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) {
|
||||
/* The account button is a .button, which is purple in dark mode; keep it neutral in a custom theme sidebar. */
|
||||
html.dark[data-theme="custom"] :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) {
|
||||
--button-depth-color: rgb(255 255 255 / 0.05);
|
||||
background-color: rgb(255 255 255 / 0.04);
|
||||
border-color: rgb(255 255 255 / 0.08);
|
||||
color: var(--color-nav-text);
|
||||
}
|
||||
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):hover {
|
||||
html.dark[data-theme="custom"] :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):hover {
|
||||
background-color: rgb(255 255 255 / 0.07);
|
||||
border-color: rgb(255 255 255 / 0.12);
|
||||
}
|
||||
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) svg {
|
||||
html.dark[data-theme="custom"] :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) svg {
|
||||
color: var(--color-nav-muted);
|
||||
}
|
||||
|
||||
@@ -6327,6 +6327,62 @@ html.dark .app-sidebar .menu-item:not(:hover):not(:focus-visible):not(.menu-item
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Default dark theme sidebar: purple-black with a faint brand wash and lavender
|
||||
tiles, text, and edges. A custom theme keeps the neutral rules above. */
|
||||
html.dark:not([data-theme="custom"]) .app-sidebar nav.sidebar-nav,
|
||||
html.dark:not([data-theme="custom"]) .mobile-sidebar-sheet [role="dialog"] {
|
||||
background-image: linear-gradient(180deg, rgb(107 22 237 / 0.09), transparent 520px);
|
||||
border-right-color: rgb(163 145 255 / 0.10);
|
||||
--color-nav-text: oklch(80% 0.02 300);
|
||||
--color-nav-muted: oklch(58% 0.04 300);
|
||||
}
|
||||
|
||||
/* Same color as the top of the sidebar gradient, so the brand and sidebar read as one surface. */
|
||||
html.dark:not([data-theme="custom"]) .app-topbar-brand {
|
||||
background-image: linear-gradient(rgb(107 22 237 / 0.09), rgb(107 22 237 / 0.09));
|
||||
border-right-color: rgb(163 145 255 / 0.10);
|
||||
}
|
||||
|
||||
html.dark:not([data-theme="custom"]) :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search {
|
||||
background-color: rgb(163 145 255 / 0.06) !important;
|
||||
box-shadow: inset 0 0 0 1px rgb(163 145 255 / 0.10) !important;
|
||||
}
|
||||
|
||||
html.dark:not([data-theme="custom"]) :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search:hover {
|
||||
background-color: rgb(163 145 255 / 0.10) !important;
|
||||
}
|
||||
|
||||
html.dark:not([data-theme="custom"]) :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search kbd {
|
||||
border-color: rgb(163 145 255 / 0.18) !important;
|
||||
}
|
||||
|
||||
/* Group dividers use the lavender sidebar edge: the neutral hairline looks olive on the purple-black sidebar. */
|
||||
html.dark:not([data-theme="custom"]) :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-nav :is([class~="dark:border-white/[0.06]"], [class~="dark:border-white/[0.07]"], [class~="dark:border-white/[0.08]"]) {
|
||||
border-color: rgb(163 145 255 / 0.10) !important;
|
||||
}
|
||||
|
||||
/* Admin keeps the neutral tile unless it is the current page. */
|
||||
html.dark:not([data-theme="custom"]):where(:not([data-nav-items="flat"])) :is(.app-sidebar, .mobile-sidebar-sheet) :is(.menu-item, .menu-subitem):not(.sidebar-toggle):not(.menu-search):not(.nav-admin):not(.menu-item-active):not(.menu-subitem-active) .menu-item-icon,
|
||||
html.dark:not([data-theme="custom"]):where(:not([data-nav-items="flat"])) .app-sidebar nav.sidebar-collapsed .menu-search.menu-item .menu-item-icon {
|
||||
border-color: rgb(163 145 255 / 0.13);
|
||||
background: rgb(107 22 237 / 0.07);
|
||||
color: #b9adff;
|
||||
}
|
||||
|
||||
html.dark:not([data-theme="custom"]) :is(.app-sidebar, .mobile-sidebar-sheet) nav:not(.sidebar-collapsed) .nav-section {
|
||||
color: rgb(163 145 255 / 0.55);
|
||||
}
|
||||
|
||||
/* Sidebar account menu: the purple tint of the sidebar it opens from. */
|
||||
html.dark:not([data-theme="custom"]) .listbox-panel.top-user-menu-panel-sidebar {
|
||||
background: color-mix(in oklab, #6b16ed 10%, var(--coollabs-elevated));
|
||||
border-color: rgb(163 145 255 / 0.22);
|
||||
}
|
||||
|
||||
html.dark:not([data-theme="custom"]) .top-user-menu-panel-sidebar .listbox-option:hover {
|
||||
background: rgb(163 145 255 / 0.10);
|
||||
}
|
||||
|
||||
/* Custom theme sidebar. These rules come after the dark sidebar rules above, so they win. */
|
||||
/* !important: the light custom theme maps bg-neutral-50 to the canvas with !important. */
|
||||
html[data-theme="custom"] :is(.app-sidebar nav.sidebar-nav, .app-topbar-brand, .mobile-sidebar-sheet [role="dialog"]) {
|
||||
|
||||
@@ -76,8 +76,9 @@
|
||||
: { sidebar: mixHex('#0c0c0e', accent, 0.1), selected: mixHex('#1c1c1f', accent, 0.3), accent, background: mixHex('#0f0f11', accent, 0.12) };
|
||||
};
|
||||
window.customThemePresets = [
|
||||
// The built-in Dark theme, not a custom theme. Its colors start the fields when the user edits it.
|
||||
{ name: 'Coolify', theme: null, swatch: { sidebar: '#0d0d0d', selected: '#1c1c1c', accent: '#6b16ed', background: '#0a0a0a' } },
|
||||
// The built-in Dark theme, not a custom theme. Its colors start the fields when the user edits it. The sidebar is
|
||||
// the color that the Dark sidebar shows: #120e1a with its 9% purple wash.
|
||||
{ name: 'Coolify', theme: null, swatch: { sidebar: '#1a0f2d', selected: '#1c1c1c', accent: '#6b16ed', background: '#0a0a0a' } },
|
||||
{ name: 'Midnight', theme: { sidebar: '#0f172a', selected: '#2e4a7d', accent: '#f2458f', background: '#1a2338' } },
|
||||
{ name: 'Forest', theme: { sidebar: '#12342b', selected: '#2c6e57', accent: '#f4b860', background: '#1b2a25' } },
|
||||
{ name: 'Ember', theme: { sidebar: '#3b1410', selected: '#8f2d1f', accent: '#ffb86b', background: '#241816' } },
|
||||
|
||||
Reference in New Issue
Block a user