From f533d53c749d3ff920c7241a3e0e8f5f9415b87a Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sat, 16 May 2026 21:41:58 +0200 Subject: [PATCH] feat(15-02): port sidebar + project-card CSS into app.css and register in tailwind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create backend/internal/web/ui/app.css with dashboard shell, sidebar, and project-card CSS ported verbatim from go-backend - All color values use var(--...) design tokens — no hex colors - Add @import "./internal/web/ui/app.css" to backend/tailwind.input.css --- backend/internal/web/ui/app.css | 450 ++++++++++++++++++++++++++++++++ backend/tailwind.input.css | 1 + 2 files changed, 451 insertions(+) create mode 100644 backend/internal/web/ui/app.css diff --git a/backend/internal/web/ui/app.css b/backend/internal/web/ui/app.css new file mode 100644 index 0000000..e326167 --- /dev/null +++ b/backend/internal/web/ui/app.css @@ -0,0 +1,450 @@ +/* app.css — dashboard shell, sidebar, and project-card CSS */ +/* Ported verbatim from go-backend/internal/web/ui/app.css */ +/* All color values use var(--...) design tokens — no hard-coded hex values */ + +/* ============================================================ + Section 1 — Dashboard shell and sidebar grid + ============================================================ */ + +.dashboard-shell { + background: var(--gradient-shell); + color: var(--foreground); + display: grid; + grid-template-columns: minmax(16rem, 18rem) 1fr; + min-height: 100vh; +} + +.dashboard-sidebar { + padding-left: env(safe-area-inset-left, 0px); +} + +/* ============================================================ + Section 2 — Sidebar nav shell + ============================================================ */ + +.sidebar-nav-shell { + background: var(--color-surface-elevated); + border-right: 1px solid var(--color-border-panel); + box-shadow: var(--shadow-sidebar); + display: flex; + flex-direction: column; + height: 100vh; + overflow-x: hidden; + overflow-y: auto; + padding: env(safe-area-inset-top, 0px) 0.75rem env(safe-area-inset-bottom, 0px) 0; + position: sticky; + top: 0; +} + +/* ============================================================ + Section 3 — Sidebar brand + ============================================================ */ + +.sidebar-brand { + align-items: center; + display: flex; + justify-content: center; + padding: 0.75rem 0.5rem; + position: relative; +} + +.sidebar-brand-link { + align-items: center; + display: flex; + flex-direction: column; + gap: 0.5rem; + width: 100%; +} + +.sidebar-brand-logo { + border-radius: 0.75rem; + height: 4rem; + object-fit: cover; + width: 4rem; +} + +.sidebar-brand-title { + color: var(--color-text-heading-alt); + font-size: 1.125rem; + font-weight: 700; + margin: 0; +} + +/* ============================================================ + Section 4 — Sidebar collapse button + ============================================================ */ + +.sidebar-collapse-button { + align-items: center; + background: var(--color-surface-elevated-strong); + border: 0; + border-radius: 999px; + box-shadow: var(--shadow-floating-control); + color: var(--color-text-muted); + cursor: pointer; + display: inline-flex; + height: 1.5rem; + justify-content: center; + padding: 0.25rem; + position: absolute; + right: 0.75rem; + top: 0.5rem; + width: 1.5rem; +} + +.sidebar-collapse-button svg { + height: 1rem; + width: 1rem; +} + +/* ============================================================ + Section 5 — Sidebar primary, list, divider + ============================================================ */ + +.sidebar-primary { + display: flex; + flex: 1; + flex-direction: column; +} + +.sidebar-list { + display: grid; + gap: 0; + list-style: none; + margin: 0; + padding: 0.75rem 0 0; +} + +.sidebar-divider { + margin: 0.5rem 0; + padding: 0 0.875rem; +} + +.sidebar-divider hr, +.sidebar-projects hr { + border: 0; + border-top: 1px solid var(--color-border-panel-muted); + margin: 0; +} + +/* ============================================================ + Section 6 — Sidebar nav items + ============================================================ */ + +.sidebar-nav-item { + border-radius: 0.9rem; + color: var(--color-text-muted); + font-weight: 500; + margin: 0 0.5rem; + padding: 0.15rem 0; + transition: background-color 0.2s ease, color 0.2s ease; +} + +.sidebar-nav-item:hover { + background: var(--overlay-dark-soft); + color: var(--color-surface-muted-inverse); +} + +.sidebar-nav-item.is-active { + background: var(--overlay-brand-soft-strong); + color: var(--color-text-brand); + font-weight: 600; +} + +/* ============================================================ + Section 7 — Sidebar nav link and inner elements + ============================================================ */ + +.sidebar-nav-link { + display: block; + width: 100%; +} + +.sidebar-nav-link-inner { + align-items: center; + display: flex; + gap: 0.75rem; + padding: 0.6rem 0.95rem; +} + +.sidebar-nav-icon { + align-items: center; + display: inline-flex; + justify-content: center; +} + +.sidebar-nav-icon svg { + height: 1.35rem; + width: 1.35rem; +} + +.sidebar-nav-label { + font-size: 1rem; +} + +/* ============================================================ + Section 8 — Sidebar projects section + ============================================================ */ + +.sidebar-projects { + margin-top: 0.4rem; + padding: 0 0.75rem 0.75rem; +} + +.sidebar-section-label { + color: var(--color-text-muted); + font-size: 0.625rem; + font-weight: 700; + letter-spacing: 0.14em; + margin: 0.9rem 0 0.65rem; + padding: 0 0.5rem; + text-transform: uppercase; +} + +.sidebar-project-list { + display: grid; + gap: 0.1rem; + list-style: none; + margin: 0; + padding: 0; +} + +/* ============================================================ + Section 9 — Sidebar project links + ============================================================ */ + +.sidebar-project-link { + align-items: center; + border-radius: 0.85rem; + color: var(--color-text-muted); + display: flex; + gap: 0.65rem; + padding: 0.48rem 0.5rem; + transition: background-color 0.2s ease, color 0.2s ease; +} + +.sidebar-project-link:hover { + background: var(--overlay-dark-soft); + color: var(--color-surface-muted-inverse); +} + +.sidebar-project-icon { + align-items: center; + border: 1px solid var(--color-border-panel-strong); + border-radius: 999px; + display: inline-flex; + flex-shrink: 0; + height: 1.55rem; + justify-content: center; + width: 1.55rem; +} + +.sidebar-project-icon svg { + height: 0.9rem; + width: 0.9rem; +} + +.sidebar-project-label { + flex: 1; + font-size: 0.9rem; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +/* ============================================================ + Section 10 — Sidebar footer links + ============================================================ */ + +.sidebar-footer-links { + margin-top: auto; + padding-bottom: 0.25rem; +} + +/* ============================================================ + Section 11 — Sidebar organization footer + ============================================================ */ + +.sidebar-organization { + background: var(--color-surface-elevated); + padding: 0 0.5rem 0.9rem; +} + +.organization-button { + align-items: center; + background: transparent; + border: 0; + border-radius: 0.95rem; + cursor: pointer; + display: flex; + gap: 0.65rem; + padding: 0.55rem 0.65rem; + text-align: left; + transition: background-color 0.2s ease; + width: 100%; +} + +.organization-button:hover { + background: var(--overlay-dark-soft); +} + +.organization-avatar { + border-radius: 999px; + display: inline-flex; + flex-shrink: 0; + height: 1.75rem; + overflow: hidden; + width: 1.75rem; +} + +.organization-avatar img { + aspect-ratio: 1; + height: 100%; + object-fit: cover; + width: 100%; +} + +.organization-copy { + display: flex; + flex-direction: column; + min-width: 0; +} + +.organization-name { + color: var(--color-text-body-subtle); + font-size: 0.95rem; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.organization-meta { + color: var(--color-text-muted); + font-size: 0.75rem; +} + +/* ============================================================ + Section 12 — Dashboard main content area + ============================================================ */ + +.dashboard-main { + display: flex; + flex-direction: column; + gap: 1.5rem; + min-width: 0; + padding: 2rem; +} + +/* ============================================================ + Section 13 — Overview section heading + ============================================================ */ + +.overview-section { + padding: 0.25rem 0 0; +} + +.overview-section-heading { + align-items: center; + display: flex; + justify-content: space-between; + margin-bottom: 1.5rem; +} + +.overview-section-heading h3, +.tasks-section-header h3 { + color: var(--color-surface-muted-inverse); + font-size: 1.6rem; + font-weight: 600; + margin: 0; +} + +/* ============================================================ + Section 14 — Project grid + ============================================================ */ + +.project-grid { + display: grid; + gap: 1.25rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +/* ============================================================ + Section 15 — Project card and top + ============================================================ */ + +.project-card { + background: var(--color-surface-default); + border: 1px solid var(--color-border-subtle); + border-radius: 1rem; + cursor: pointer; + padding: 1rem; + transition: box-shadow 0.2s ease; +} + +.project-card-top { + align-items: center; + display: flex; + justify-content: space-between; + margin-bottom: 1rem; +} + +/* ============================================================ + Section 16 — Project card icon button overrides + ============================================================ */ + +.project-card-top .borderless-icon-button { + padding: 0; +} + +.project-card-top .ui-icon-button-ghost.ui-icon-button-neutral:hover { + color: var(--color-text-primary); +} + +.project-card-top .ui-icon-button-ghost.ui-icon-button-danger:hover { + color: var(--color-status-danger-icon-hover); +} + +/* ============================================================ + Section 17 — Project card title row and avatar + ============================================================ */ + +.project-card-title-row { + align-items: center; + display: flex; + gap: 0.75rem; + margin-bottom: 1rem; +} + +.project-avatar { + align-items: center; + background: var(--project-color, var(--color-project-fallback)); + border-radius: 0.85rem; + color: var(--color-text-inverse); + display: inline-flex; + flex-shrink: 0; + font-size: 1.1rem; + font-weight: 700; + height: 3rem; + justify-content: center; + width: 3rem; +} + +.project-avatar > svg { + height: 1.25rem; + width: 1.25rem; +} + +/* ============================================================ + Section 18 — Project date row + ============================================================ */ + +.project-date-row { + align-items: center; + color: var(--color-text-muted); + display: flex; + font-size: 0.875rem; + gap: 0.5rem; + margin-bottom: 1rem; +} diff --git a/backend/tailwind.input.css b/backend/tailwind.input.css index 2e10b45..1b0d1ca 100644 --- a/backend/tailwind.input.css +++ b/backend/tailwind.input.css @@ -18,3 +18,4 @@ @import "./internal/web/ui/icon-button.css"; @import "./internal/web/ui/form-field.css"; @import "./internal/web/ui/spacing.css"; +@import "./internal/web/ui/app.css";