Skip to content

Phase 1: Midnight skin + mobile-first layout#1

Merged
github-actions[bot] merged 4 commits into
mainfrom
feat/midnight-skin
Apr 23, 2026
Merged

Phase 1: Midnight skin + mobile-first layout#1
github-actions[bot] merged 4 commits into
mainfrom
feat/midnight-skin

Conversation

@4Gaige
Copy link
Copy Markdown
Owner

@4Gaige 4Gaige commented Apr 23, 2026

Summary

Phase 1 of Dispatch: apply the Midnight dark-only design system as a mobile-first skin.

  • Ships Midnight v1.1 tokens, component classes, and Tailwind theme extension
  • Adds a 5-slot bottom tab bar (mobile, <1024px) and a 64px persistent left rail (desktop, lg+)
  • Rewrites every hardcoded Tailwind color site flagged in the phase brief to use Midnight semantic classes or shadcn vars mapped to Midnight tokens

Changes by commit

Commit Scope
feat(skin): install Midnight design system tokens and shadcn mapping src/styles/midnight.css (copied + stripped of duplicate at-rules), src/index.css (shadcn --background/--foreground/etc. remapped to Midnight tokens), tailwind.config.js (pastels, radii, shadows, motion curves, typography), index.html (<html class="dark"> + font preconnect)
feat(skin): add mobile tab bar and persistent desktop left rail New src/components/layout/{useAppNavItems, MobileTabBar, DesktopRail, MobileSidebarSheet}.tsx, wired into src/components/app/AppContent.tsx. Section-level data-accent drives focus rings + selection highlights per Phase-1 accent table (Chat=sky, Sidebar=lavender, Preview=mint, Browser=peach, Tasks=butter, Settings=blush).
feat(skin): replace raw Tailwind color classes with Midnight semantics src/components/mcp/constants.ts, src/components/task-master/{view/TaskCard.tsx, utils/taskKanban.ts}, src/components/file-tree/view/ImageViewer.tsx, src/components/auth/view/LoginForm.tsx, src/shared/view/ui/Queue.tsx
fix(skin): a11y polish — drop tablist role, make sheet keyboard-aware Rail drops role="tablist" it didn't implement; bottom sheet subtracts --keyboard-height so iOS keyboard doesn't clip session list

Guardrails

  • Churny-file rule: zero changes to server/projects.js, server/index.js, src/components/sidebar/subcomponents/SidebarProjectItem.tsx (git diff --name-only main..HEAD confirms).
  • No raw Tailwind color classes in touched files: grep -rnE 'bg-(blue|red|green|gray|yellow|pink|purple|indigo|orange|slate|zinc|neutral|stone|amber|emerald|teal|cyan|rose|violet|fuchsia)-[0-9]' on the diff returns nothing.
  • Mobile-first: tab bar is 44×44 min-touch, env(safe-area-inset-bottom) respected via .ios-bottom-safe, sheet swipes down to dismiss (>120px or >0.4 px/ms flick), Esc also closes.
  • Bundle delta: JS +0.14% (2,444,186 → 2,447,663 B), CSS -3.4% (182,841 → 176,545 B). Well inside the 5% budget.

Known follow-ups (out-of-scope for Phase 1)

  • The "Browser" rail slot routes to the chat view for now; the live Chrome viewport arrives in Phase 5.
  • No focus-trap on MobileSidebarSheet; Esc closes it, Tab can escape. Candidate for Phase 2 a11y pass.

Test plan

  • npm run build succeeds (client + server)
  • npm run typecheck clean
  • npm run lint — 0 errors (warnings are pre-existing + style-only)
  • No test script configured in this repo (npm test exits with "Missing script: test")
  • Fresh-eyes Opus review: all 12 checklist items + 5 acceptance criteria YES
  • Visual review with Playwright screenshots at 375×812 + 1440×900 — scheduled for the Phase 2 visual-review pass per build plan

🤖 Generated with Claude Code

4Gaige and others added 4 commits April 22, 2026 23:50
Adds the Midnight v1.1 token set as src/styles/midnight.css and wires
shadcn-style semantic vars (--background, --foreground, --primary, etc.)
to resolve against Midnight tokens so legacy bg-background / text-muted-
foreground utilities keep working. Tailwind config extends with Midnight
palette, pastels, radii, shadows, and motion curves. HTML root now
declares class=dark and preconnects to Inter + Geist Mono.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduces a five-slot primary navigation — Chat, Sessions, Preview,
Browser, More — that renders as a bottom .ds-tabbar below 1024px and a
64px left rail at lg+. Sessions slot opens the sidebar as a Midnight
.ds-sheet on mobile (swipe-down-to-dismiss) and selects the persistent
second-column sidebar on desktop. Per-section data-accent wires
focus rings and selection highlights to the section's pastel.

Touch targets are 44x44px minimum on mobile; safe-area-inset-bottom
is respected via .ios-bottom-safe on the tab bar container.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rewrites the hardcoded color sites called out in the phase-1 brief so
none rely on literal Tailwind palette classes. MCP provider buttons
now use primary/card; kanban columns compose .ds-tile-inset with per-
status pastel accents; TaskCard becomes a .ds-tile-hover with status-
accented dots; the image viewer sits on a .ds-sheet-backdrop inside a
.ds-tile; login submit becomes .btn-primary; Queue indicators use the
pastel mint/sky tokens.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
DesktopRail drops the role="tablist" / role="tab" pair since the
component does not implement the roving-tabindex / arrow-key semantics
those roles promise. Replaces with aria-current="page" on the active
item, which is accurate for primary nav.

MobileSidebarSheet now subtracts --keyboard-height from its 80vh/svh
target so the iOS keyboard does not clip the session list when a text
field inside focuses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions github-actions Bot merged commit a7e81ba into main Apr 23, 2026
2 checks passed
@4Gaige 4Gaige deleted the feat/midnight-skin branch April 23, 2026 05:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant