From eeaeacbe3f93a3735ec600182da049dc7b97c2f4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 22 Oct 2026 15:54:02 +0200 Subject: [PATCH] style(ui): refine canvas layouts and rollback settings --- DESIGN.md | 70 +++++++++++++++++-- resources/css/app.css | 40 ++++++++++- .../configuration-sidebar.blade.php | 8 --- resources/views/layouts/app.blade.php | 2 +- .../project/application/rollback.blade.php | 40 +++++------ .../project/service/domains.blade.php | 4 +- 6 files changed, 124 insertions(+), 40 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 4a8f187df2..708a3db1ce 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -195,8 +195,10 @@ Class names below are examples. Keep the values and structure. table rows are the darker content layer below them. - 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 `#120e1a` with a brand-purple wash at the top (about 9%, - fading out) and a faint lavender right edge (`rgb(163 145 255 / 0.10)`). + 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. - The top bar matches the canvas. It has no bottom border at rest. After the page scrolls under it, dark mode draws a lavender hairline (`rgb(163 145 255 / 0.12)`), a translucent bar, blur, and a soft shadow. @@ -204,6 +206,38 @@ Class names below are examples. Keep the values and structure. - Keep the chrome borders faint. A strong border on near-black looks like a line drawn on the page. +### App header (logo cell) + +- The logo cell is the top of the sidebar column, in the 48px top bar. It is + as wide as the sidebar: 224px expanded, 64px collapsed. +- Expanded: the wordmark (15px semibold, tight tracking, `--ui-fg`), then the + version on the same baseline (10.5px medium, `--ui-fg-faint`), with 6px + between them and 16px side padding. An update badge sits at the right end. +- Collapsed: only the 20px logo mark, centered. The cell gets a bottom border + so that it lines up with the top bar edge. +- The update badge is a small pill: 18px high, 6px side padding, 9.5px + semibold text, fully rounded, a 10% fill, and a 25% inset ring of the same + color. It is purple in light mode and warning yellow in dark mode. While an + update runs, the same pill says "Updating". It hides when the sidebar is + collapsed. +- The mobile drawer starts with the same wordmark and version in a 48px row + with a bottom border, and a 32px close button on the right. It has no update + badge. + +### Mobile header + +- Below the desktop breakpoint (1024px) a sticky top bar replaces the desktop + top bar and sidebar. It is about 56px high (12px vertical padding, 16px side + padding, 24px from 640px), translucent (95% of `--ui-panel`) with a small + blur, and has a faint bottom border. +- Left: the logo mark (18px) in a 32px tile with an 8px radius and a neutral + fill (`rgb(255 255 255 / 6%)` in dark mode), then the team switcher. The + team name truncates. +- Right, with 4px gaps: status indicators (configuration warnings, active + deployments), the update badge, the user menu, and a 36px sidebar button + (the same sidebar glyph as the desktop collapse toggle). The sidebar button + opens the drawer from the right. + ### Sidebar navigation ```css @@ -622,8 +656,9 @@ lift off the content: 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` - (`#120e1a`): a vertical brand wash on the nav, a radial wash on the logo - cell, and a lavender right edge. Section labels are 10.5px uppercase mono in + (`#120e1a`): a vertical brand wash on the nav, a flat 9% wash on the logo + cell (the same color as the top of the nav wash), and a lavender right + edge. Section labels are 10.5px uppercase mono in muted lavender. Chevrons are hidden until the row is hovered, focused, or current. The Admin icon stays neutral. The footer is transparent so the wash continues. Do not use `dark:border-white/[0.06]` on these chrome edges; @@ -690,8 +725,31 @@ color. Row-hover states keep the lighter `dark:hover:bg-white/[0.025]`. rows; yellow washes look muddy on dark UI. - Nested items sit behind a thin 1px guide line (`.nav-children`) and use the same selected pill, not a thick box border. -- The update badge sits on the version row and uses a tiny fully rounded - primary-action pill. +- The logo cell (`.app-topbar-brand` in `layouts/app.blade.php`) is `w-56` + expanded and `w-16` collapsed. Expanded, it shows the `Coolify` wordmark + (`text-[15px] font-semibold tracking-tight`), `` + (`text-[10.5px]`, `text-fg-faint` in dark), and the update badge + (`livewire:upgrade`, instance admins on self-hosted only) at `ml-auto`. + Collapsed, it shows only `/coolify-logo.svg` at `size-5` and adds + `border-b`. +- The update badge sits on the version row: an 18px fully rounded pill with + 9.5px semibold text. It is `bg-coollabs/10 text-coollabs ring-coollabs/25` in + light mode and the warning pill (`dark:bg-warning/15 dark:text-warning + dark:ring-warning/25`) in dark mode, because an update is a real warning. + While an upgrade runs it says "Updating". Both open the upgrade modal. +- The mobile drawer header (`data-mobile-sidebar-brand`) repeats the wordmark + and version in an `h-12` row with a bottom border and a close button. It + does not show the update badge. +- The mobile top bar (`MOBILE TOP BAR` in `layouts/app.blade.php`, `lg:hidden`) + is `sticky top-0 z-40`, `px-4 py-3 sm:px-6`, `bg-white/95 dark:bg-panel/95 + backdrop-blur-sm` with `border-neutral-200/60 dark:border-white/[0.06]`. + Left: `/coolify-logo.svg` (18px) in a `size-8 rounded-lg bg-neutral-100 + dark:bg-white/[0.06]` tile, then `livewire:switch-team`. Right (`gap-1`): + `#configuration-warning-hud-slot-mobile`, `deployments-indicator + variant="mobile"`, the update badge (`livewire:upgrade key="mobile-upgrade"`, + instance admins on self-hosted only), `x-top-user-menu`, and a `size-9` + button that toggles the drawer. Keep these in the same order as the desktop + top bar. - Submenu chevrons (the right chevron on rows that open a submenu and the back chevron) are `text-coollabs` in light mode and grey in dark mode (`dark:text-fg-faint` right, `dark:text-fg-dim` back). diff --git a/resources/css/app.css b/resources/css/app.css index f605a36497..3694f7ff41 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -6023,9 +6023,10 @@ html.dark .mobile-sidebar-sheet [role="dialog"] { --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 .app-topbar-brand { background-color: var(--color-sidebar); - background-image: radial-gradient(140% 260% at 0% 0%, rgb(107 22 237 / 0.12), transparent 70%); + 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); } @@ -6102,6 +6103,43 @@ html.dark.is-scrolled:not([data-nav-style="floating"]) .app-topbar > div:not(.ap box-shadow: 0 10px 30px -14px rgb(0 0 0 / 0.95), 0 1px 0 rgb(107 22 237 / 0.06); } +/* Canvases (default navigation): the canvas runs under a clear top bar, and the + canvas root paints the dots (set by the canvas JS) behind it, like the + floating navigation does. */ +@media (min-width: 1024px) { + html:not([data-nav-style="floating"]) .app-main.app-main-full:has(:is([data-ec-root], .cv-root)) { + padding-top: 0; + } + + html:not([data-nav-style="floating"]) .app-main-full :is([data-ec-root], .cv-root) { + padding-top: calc(3rem + 0.5rem); + } + + /* The deploy canvas (.cv-root) paints its own dots. */ + html:not([data-nav-style="floating"]) .app-main-full [data-ec-root] { + background-image: var(--canvas-dots-image, radial-gradient(circle, rgb(0 0 0 / 0.13) 1px, transparent 1px)); + background-size: var(--canvas-dots-size, 20px 20px); + background-position: var(--canvas-dots-position, 0 0); + } + + html.dark:not([data-nav-style="floating"]) .app-main-full [data-ec-root] { + background-image: var(--canvas-dots-image, radial-gradient(circle, rgb(255 255 255 / 0.09) 1px, transparent 1px)); + } + + html:not([data-nav-style="floating"]) .app-main-full [data-ec-viewport] { + background-image: none; + } + + html:not([data-nav-style="floating"]):has(.app-main-full :is([data-ec-root], .cv-root)) .app-topbar { + background-color: transparent; + backdrop-filter: none; + } + + html:not([data-nav-style="floating"]):has(.app-main-full :is([data-ec-root], .cv-root)) .app-topbar > div:not(.app-topbar-brand) { + border-bottom-color: transparent; + } +} + html.dark .view-toggle { gap: 2px; padding: 2px; diff --git a/resources/views/components/application/configuration-sidebar.blade.php b/resources/views/components/application/configuration-sidebar.blade.php index 2b4c27bd05..8f86e0d217 100644 --- a/resources/views/components/application/configuration-sidebar.blade.php +++ b/resources/views/components/application/configuration-sidebar.blade.php @@ -233,14 +233,6 @@ ], ['id' => 'healthcheck-timing-section', 'label' => 'Timing and retries'], ], - 'project.application.rollback' => [ - ['id' => 'rollback-retention-section', 'label' => 'Image retention'], - ['id' => 'rollback-images-section', 'label' => 'Available images'], - ], - 'project.application.resource-limits' => [ - ['id' => 'cpu-limits-section', 'label' => 'CPU'], - ['id' => 'memory-limits-section', 'label' => 'Memory'], - ], 'project.application.resource-operations' => [ ['id' => 'clone-destination-section', 'label' => 'Clone destination'], ['id' => 'clone-environment-section', 'label' => 'Clone environment'], diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index a6807574eb..6c9fffcaff 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -103,7 +103,7 @@ x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" class="relative flex h-full w-72 max-w-[85vw] min-w-0 flex-col overflow-hidden rounded-l-2xl border-l border-neutral-200 bg-white shadow-[-8px_0_30px_-6px_rgba(0,0,0,0.18)] dark:border-white/[0.12] dark:bg-panel dark:shadow-[-8px_0_30px_-4px_rgba(0,0,0,0.5)]">
+ class="flex h-12 shrink-0 items-center justify-between gap-1.5 border-b border-neutral-200 px-4 dark:border-white/[0.06] dark:bg-panel">