ui: brand-consistent button and card styling

Replace traffic light colors (green/yellow/red) with brand palette:
- Primary actions: blue gradient
- Secondary actions: ghost/outline
- Destructive actions: ghost with red hover (modals keep filled red)
- Running cards: blue glow instead of green border
- Bottom-aligned buttons via flexbox column layout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 21:32:44 +01:00
parent d7e5332a11
commit f6b09ca99e
2 changed files with 64 additions and 27 deletions
+9
View File
@@ -1,5 +1,14 @@
## Changelog
### v0.31.6 — UI: Brand-consistent button & card styling (2026-02-25)
#### Changed
- **Buttons**: Replaced traffic light colors (green/yellow/red) with brand-consistent palette — primary actions use blue gradient, secondary actions use ghost/outline, destructive actions show red tint on hover only (modal confirmations keep filled red)
- **Card borders**: Running apps now show a subtle blue glow instead of green top border; all other states have neutral borders
- **Status badges**: Running state badge uses brand blue instead of green
- **Button alignment**: Cards use flexbox column layout with `margin-top: auto` on actions — buttons always align to the bottom regardless of card content height
- **Dashboard cards**: Left border indicator changed from green to blue for running apps
### v0.31.5 — Fix Nextcloud-OnlyOffice callback URL + trusted_domains (2026-02-25)
#### Fixed
+55 -27
View File
@@ -280,20 +280,19 @@ h3 {
border-radius: var(--radius);
padding: 1rem 1.25rem;
border: 1px solid var(--border-color);
border-left: 4px solid var(--gray);
border-left: 4px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
transition: border-color 0.3s ease, transform 0.2s ease;
transition: border-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
}
.stack-card:hover {
border-color: var(--accent-blue);
}
.stack-state-green { border-left-color: var(--green); }
.stack-state-red { border-left-color: var(--red); }
.stack-state-yellow { border-left-color: var(--yellow); }
.stack-state-orange { border-left-color: var(--orange); }
.stack-state-gray { border-left-color: var(--gray); }
.stack-card.stack-state-green {
border-left-color: var(--accent-blue);
box-shadow: 0 0 12px rgba(0, 136, 204, 0.1);
}
.stack-info {
display: flex;
align-items: center;
@@ -339,17 +338,22 @@ h3 {
border-radius: var(--radius);
padding: 1.25rem;
border: 1px solid var(--border-color);
border-top: 4px solid var(--gray);
transition: border-color 0.3s ease, transform 0.3s ease;
transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
display: flex;
flex-direction: column;
}
.stack-detail-card:hover {
border-color: var(--accent-blue);
transform: translateY(-2px);
}
.stack-detail-card.stack-state-green { border-top-color: var(--green); }
.stack-detail-card.stack-state-red { border-top-color: var(--red); }
.stack-detail-card.stack-state-orange { border-top-color: var(--orange); }
.stack-detail-card.stack-state-yellow { border-top-color: var(--yellow); }
.stack-detail-card.stack-state-green {
border-color: rgba(0, 136, 204, 0.25);
box-shadow: 0 0 16px rgba(0, 136, 204, 0.12), 0 0 4px rgba(0, 136, 204, 0.08);
}
.stack-detail-card.stack-state-green:hover {
border-color: var(--accent-blue);
box-shadow: 0 0 20px rgba(0, 136, 204, 0.2), 0 0 6px rgba(0, 136, 204, 0.12);
}
.stack-detail-header {
display: flex;
justify-content: space-between;
@@ -375,12 +379,12 @@ h3 {
font-weight: 600;
white-space: nowrap;
}
.state-green { background: var(--green-bg); color: var(--green); }
.state-green { background: rgba(0, 136, 204, 0.12); color: var(--accent-light); }
.state-red { background: var(--red-bg); color: var(--red); }
.state-yellow { background: var(--yellow-bg); color: var(--yellow); }
.state-orange { background: var(--orange-bg); color: var(--orange); }
.state-gray { background: var(--gray-bg); color: var(--gray); }
.state-text-green { color: var(--green); }
.state-text-green { color: var(--accent-light); }
.state-text-red { color: var(--red); }
.state-text-orange { color: var(--orange); }
.state-text-yellow { color: var(--yellow); }
@@ -421,7 +425,8 @@ h3 {
.stack-detail-actions {
display: flex;
gap: .5rem;
margin-top: 1rem;
margin-top: auto;
padding-top: 1rem;
flex-wrap: wrap;
}
@@ -454,11 +459,31 @@ h3 {
box-shadow: 0 4px 12px var(--accent-glow);
}
.btn-primary:hover { box-shadow: 0 6px 20px var(--accent-glow); }
.btn-success { background: var(--green); }
.btn-success:hover { box-shadow: 0 4px 12px rgba(35, 134, 54, 0.3); }
.btn-warning { background: var(--yellow); color: #0d1117; }
.btn-danger { background: var(--red); }
.btn-danger:hover { box-shadow: 0 4px 12px rgba(218, 54, 51, 0.3); }
.btn-success {
background: linear-gradient(135deg, var(--accent-blue), var(--accent-light));
box-shadow: 0 4px 12px var(--accent-glow);
}
.btn-success:hover { box-shadow: 0 6px 20px var(--accent-glow); }
.btn-warning {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-secondary);
}
.btn-warning:hover {
border-color: var(--accent-blue);
color: var(--accent-light);
background: rgba(0, 136, 204, 0.08);
}
.btn-danger {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-secondary);
}
.btn-danger:hover {
border-color: var(--red);
color: var(--red);
background: var(--red-bg);
}
.btn-outline {
background: transparent;
border: 1px solid var(--border-color);
@@ -2483,14 +2508,16 @@ a.stat-card:hover {
margin-bottom: 0;
}
.btn-danger {
/* Red-filled danger buttons inside modal confirmation dialogs */
.modal-actions .btn-danger {
background: var(--red);
color: white;
border-color: var(--red);
}
.btn-danger:hover {
.modal-actions .btn-danger:hover {
opacity: 0.85;
background: var(--red);
color: white;
}
/* Cross-drive backup card on deploy page */
@@ -2985,7 +3012,8 @@ a.stat-card:hover {
box-shadow: 0 0 0 2px rgba(218, 54, 51, 0.2);
}
.btn-danger {
/* Debug page: red-filled danger buttons for destructive debug actions */
.debug-section .btn-danger {
background: var(--red);
color: #fff;
border: none;
@@ -2996,8 +3024,8 @@ a.stat-card:hover {
font-weight: 600;
transition: background .15s, opacity .15s;
}
.btn-danger:hover { background: #e5534b; }
.btn-danger:disabled { opacity: 0.5; cursor: not-allowed; }
.debug-section .btn-danger:hover { background: #e5534b; }
.debug-section .btn-danger:disabled { opacity: 0.5; cursor: not-allowed; }
.debug-spinner {
display: inline-block;