UI polish: Illuminated Transcript design language

- Fraunces serif for headings and assistant identity label
- Chat bubbles flipped: assistant responses elevated (card + left indigo
  accent + shadow), user prompts ghosted (transparent bg, muted text)
- AppLogo: book fill changed from text-color to indigo in light mode
- AppHeader: border-bottom removed; active nav uses underline accent
- NoteCard/TaskCard: border replaced with whisper indigo-tint shadow
- HomeView: dashboard-response uses left accent; progress bars indigo;
  empty-state decorative marker; project cards use shadow depth
- NotesListView: btn-new/btn-cta use indigo gradient + glow
- All primary CTA buttons: indigo gradient (135deg #6366f1 → #4f46e5)
  with box-shadow glow on hover
- Dark palette: navy (#1a1a2e family) → slate-indigo (#111113 family)
- Scrollbars: thin 4px indigo-tinted

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Bryan Van Deusen
2026-03-10 15:18:22 -04:00
parent a56f514df6
commit 3c3dd7377a
8 changed files with 84 additions and 22 deletions
+7
View File
@@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,300..900&display=swap');
:root {
--color-bg: #f5f5fb;
--color-bg-secondary: #ededf5;
@@ -111,6 +113,11 @@ body {
transition: background-color 0.2s, color 0.2s;
}
h1, h2, h3 {
font-family: 'Fraunces', Georgia, serif;
font-optical-sizing: auto;
}
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
+8 -5
View File
@@ -166,7 +166,6 @@ onUnmounted(() => document.removeEventListener("click", handleClickOutside));
<style scoped>
.app-header {
background: var(--color-bg-secondary);
border-bottom: 1px solid var(--color-border);
position: relative;
}
.nav {
@@ -182,8 +181,11 @@ onUnmounted(() => document.removeEventListener("click", handleClickOutside));
display: flex;
align-items: center;
gap: 0.4rem;
font-weight: 700;
font-size: 1.1rem;
font-family: 'Fraunces', Georgia, serif;
font-optical-sizing: auto;
font-weight: 600;
font-size: 1.15rem;
letter-spacing: -0.01em;
color: var(--color-primary);
text-decoration: none;
flex-shrink: 0;
@@ -217,12 +219,13 @@ onUnmounted(() => document.removeEventListener("click", handleClickOutside));
}
.nav-link:hover {
color: var(--color-primary);
background: var(--color-bg-card);
background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}
.nav-link.router-link-active {
color: var(--color-primary);
background: var(--color-bg-card);
font-weight: 600;
box-shadow: inset 0 -2px 0 var(--color-primary);
border-radius: 0;
}
/* Status indicator */
+6
View File
@@ -155,6 +155,12 @@ const timingParts = computed((): string[] => {
}
.role-assistant .role-label {
color: var(--color-primary);
font-family: 'Fraunces', Georgia, serif;
font-optical-sizing: auto;
font-style: italic;
font-size: 0.8rem;
text-transform: none;
letter-spacing: 0;
}
.thinking-block {
+3 -3
View File
@@ -60,15 +60,15 @@ function goEdit() {
.note-card {
display: block;
padding: 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
text-decoration: none;
color: inherit;
background: var(--color-bg-card);
transition: box-shadow 0.15s;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(99, 102, 241, 0.06);
transition: box-shadow 0.2s;
}
.note-card:hover {
box-shadow: 0 2px 8px var(--color-shadow);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.10), 0 0 0 1px rgba(99, 102, 241, 0.14);
}
/* Compact single-row layout */
+3 -3
View File
@@ -97,15 +97,15 @@ function isOverdue(): boolean {
.task-card {
display: block;
padding: 1rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
text-decoration: none;
color: inherit;
background: var(--color-bg-card);
transition: box-shadow 0.15s;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(99, 102, 241, 0.06);
transition: box-shadow 0.2s;
}
.task-card:hover {
box-shadow: 0 2px 8px var(--color-shadow);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.10), 0 0 0 1px rgba(99, 102, 241, 0.14);
}
/* Compact single-row layout */
+28 -8
View File
@@ -523,6 +523,7 @@ function clearDashboardResponse() {
.quick-action-chip:hover:not(:disabled) {
border-color: var(--color-primary);
color: var(--color-primary);
background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}
.quick-action-chip:disabled { opacity: 0.4; cursor: default; }
@@ -530,9 +531,10 @@ function clearDashboardResponse() {
.dashboard-response {
margin-bottom: 1.5rem;
padding: 0.75rem 1rem;
background: var(--color-bg-secondary);
border: 1px solid var(--color-border);
background: var(--color-bg-card);
border-left: 2px solid var(--color-primary);
border-radius: var(--radius-md);
box-shadow: var(--color-bubble-asst-shadow);
}
.dashboard-response-query {
font-size: 0.8rem;
@@ -579,7 +581,6 @@ function clearDashboardResponse() {
gap: 0.75rem;
margin-top: 0.75rem;
padding-top: 0.5rem;
border-top: 1px solid var(--color-border);
}
.btn-open-chat {
font-size: 0.85rem;
@@ -589,13 +590,18 @@ function clearDashboardResponse() {
}
.btn-open-chat:hover { text-decoration: underline; }
.btn-open-chat.prominent {
background: var(--color-primary);
background: linear-gradient(135deg, #6366f1, #4f46e5);
color: #fff;
padding: 0.35rem 0.85rem;
border-radius: var(--radius-sm);
font-size: 0.9rem;
box-shadow: 0 1px 6px rgba(99, 102, 241, 0.25);
}
.btn-open-chat.prominent:hover {
text-decoration: none;
box-shadow: 0 3px 12px rgba(99, 102, 241, 0.45);
filter: brightness(1.08);
}
.btn-open-chat.prominent:hover { text-decoration: none; opacity: 0.9; }
.btn-clear-response {
font-size: 0.8rem;
color: var(--color-text-muted);
@@ -680,15 +686,15 @@ function clearDashboardResponse() {
.project-mini-card {
display: block;
padding: 0.75rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-bg-card);
text-decoration: none;
color: inherit;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(99, 102, 241, 0.06);
transition: box-shadow 0.15s;
}
.project-mini-card:hover {
box-shadow: 0 2px 8px var(--color-shadow);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.10), 0 0 0 1px rgba(99, 102, 241, 0.14);
}
.project-mini-title {
font-size: 0.9rem;
@@ -723,6 +729,7 @@ function clearDashboardResponse() {
.ms-fill {
height: 100%;
border-radius: 999px;
background: var(--color-primary);
transition: width 0.3s;
}
.ms-pct {
@@ -743,17 +750,30 @@ function clearDashboardResponse() {
.loading { color: var(--color-text-secondary); }
.empty-state { text-align: center; padding: 1.5rem 0; }
.empty-state::before {
content: "✦";
display: block;
font-size: 1.2rem;
color: var(--color-primary);
opacity: 0.4;
margin-bottom: 0.4rem;
}
.empty-text { color: var(--color-text-muted); margin: 0 0 0.75rem; }
.btn-cta {
display: inline-block;
padding: 0.45rem 1rem;
background: var(--color-primary);
background: linear-gradient(135deg, #6366f1, #4f46e5);
color: #fff;
border: none;
border-radius: var(--radius-sm);
text-decoration: none;
font-size: 0.9rem;
cursor: pointer;
box-shadow: 0 1px 6px rgba(99, 102, 241, 0.25);
}
.btn-cta:hover {
box-shadow: 0 3px 12px rgba(99, 102, 241, 0.45);
filter: brightness(1.08);
}
/* Mobile */
+12 -2
View File
@@ -201,11 +201,16 @@ function onOffsetUpdate(offset: number) {
}
.btn-new {
padding: 0.45rem 1rem;
background: var(--color-primary);
background: linear-gradient(135deg, #6366f1, #4f46e5);
color: #fff;
border-radius: var(--radius-sm);
text-decoration: none;
font-size: 0.9rem;
box-shadow: 0 1px 6px rgba(99, 102, 241, 0.25);
}
.btn-new:hover {
box-shadow: 0 3px 12px rgba(99, 102, 241, 0.45);
filter: brightness(1.08);
}
.controls {
display: flex;
@@ -312,11 +317,16 @@ function onOffsetUpdate(offset: number) {
.btn-cta {
display: inline-block;
padding: 0.45rem 1rem;
background: var(--color-primary);
background: linear-gradient(135deg, #6366f1, #4f46e5);
color: #fff;
border-radius: var(--radius-sm);
text-decoration: none;
font-size: 0.9rem;
box-shadow: 0 1px 6px rgba(99, 102, 241, 0.25);
}
.btn-cta:hover {
box-shadow: 0 3px 12px rgba(99, 102, 241, 0.45);
filter: brightness(1.08);
}
.kb-active-item {
+17 -1
View File
@@ -12,7 +12,23 @@
> Include file-level details in the commit body when the change is non-trivial.
## Last Updated
2026-03-10 — CI/CD optimization: custom runner base image, explicit label naming, pip caching, Node 22.
2026-03-10 — UI polish pass: "Illuminated Transcript" design language, Fraunces typography, indigo gradient buttons, shadow-based card depth, bubble hierarchy flip.
**UI polish pass — design language:**
- `frontend/src/assets/theme.css`: added Fraunces Google Font import; `h1/h2/h3` use `font-family: 'Fraunces', Georgia, serif`; `--radius-md` 8→12px, `--radius-lg` 12→18px; added thin indigo-tinted scrollbars (4px); added bubble-specific CSS variables (`--color-bubble-user-*`, `--color-bubble-asst-shadow`); dark palette shifted from generic navy (#1a1a2e family) to slate-indigo (#111113 family).
- `frontend/src/components/AppLogo.vue`: logo book fill changed from `var(--color-text)` (black in light mode) to `var(--color-primary)` (indigo). Stroke updated to `color-mix(in srgb, var(--color-primary) 70%, transparent)`.
- `frontend/src/components/AppHeader.vue`: removed `border-bottom` from `.app-header`; nav brand uses Fraunces font; active nav link uses `inset 0 -2px 0 var(--color-primary)` underline instead of background fill.
- `frontend/src/components/ChatMessage.vue`: user bubble ghosted (transparent bg, thin border, muted text); assistant bubble elevated with left `2px solid var(--color-primary)` accent + shadow; assistant role label in Fraunces italic indigo; thinking block uses left-accent instead of full border.
- `frontend/src/views/ChatView.vue`: removed sidebar/header/context-sidebar borders; streaming bubble matches assistant style; active conversation item uses 15% indigo tint; send button and queued bubbles use indigo gradient + glow.
- `frontend/src/components/NoteCard.vue`, `TaskCard.vue`: removed `border: 1px solid`; replaced with whisper shadow (`0 1px 4px + 0 0 0 1px indigo tint`); elevated shadow on hover.
- `frontend/src/views/HomeView.vue`: `dashboard-response` uses left indigo accent + elevation shadow (no border); `dashboard-response-actions` border-top removed; quick-action-chip hover adds indigo bg tint; project-mini-card uses whisper shadow; ms-fill progress bars use `var(--color-primary)`; `.btn-cta` and `.btn-open-chat.prominent` use indigo gradient + glow; `.empty-state::before` adds decorative `✦` marker.
- `frontend/src/views/NotesListView.vue`: `.btn-new` and `.btn-cta` use indigo gradient + glow on hover.
**Design intent:** "Illuminated Transcript" — LLM responses are primary artifacts (elevated, card-like, indigo accent left-border), user prompts are subordinate margin notes (ghosted, recessed). Buttons with the gradient carry intentional weight. Borders replaced by shadow depth throughout.
---
**Previous session (2026-03-10):** CI/CD optimization: custom runner base image, explicit label naming, pip caching, Node 22.
**CI/CD infrastructure overhaul:**
- `infra/Dockerfile.runner-base` (new): Ubuntu 24.04 base image with Python 3.12 (native, no PPA) and Node 22 LTS pre-installed. Tagged `py3.12-node22`. Eliminates the ~3-4 min deadsnakes PPA install that ran on every test job. Build/push command in file header.