* feat(ui): shared migration primitives (UI migration PR 3)
The component kit every page migration (PR 4-8) builds on:
- ContextPicker: the one-per-page chip-dropdown context scope (convention
8), right-aligned popover with checks and muted annotations
- FyPicker: fiscal-year picker on ContextPicker with the same controlled
API and per-company localStorage key as FiscalYearSelector, which it
replaces page by page from PR 4
- SplitButton: primary + caret menu, last-used mode persisted per user
via ui_state.create_mode (lib/ui-state/client, unit-tested); nav
persistence refactored onto the same helper
- ConfirmDialog: centered min-460px confirm-up-front dialog (convention
10) with pending state on an awaitable onConfirm
- HelpPopover: 17px "?" after the H1 opening an anchored popover
(convention 7); PageHeader gets a `help` slot
- AttnLine: the one-ochre-sentence attention pattern (convention 6) with
optional inline action; new AA-safe --attn token pair
- RowStatus: chips-mark-exceptions helper (convention 5)
- SlideOver: right review panel, 480px, 18px inset, rounded, veil + Esc
(convention 13), with header kicker / body / footer slots
- Stagger: .stagger-enter applied to the five target pages' list
containers (bookkeeping, transactions, pending, invoices,
supplier-invoices); structural loading.tsx added for supplier-invoices,
customers, kpi, pending, deadlines
No page adopts the new pickers/dialogs yet: that is PR 4-8, one page per
PR against this kit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(ui): FyPicker chip must not double the Rakenskapsar label
Real fiscal periods are often named "Rakenskapsar 2026" already; only
prefix the label when the period name lacks it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(ui): frame-layout shell, pill buttons, 24px page titles (UI migration PR 1)
The visual shell from the concept, zero behavior change:
- New --frame token pair (40 18% 96% light / 0 0% 5% dark); the dashboard
wrapper is bg-frame and <main> becomes a rounded 12px panel with its own
inner scroll (md-gated; mobile keeps document flow + bottom nav)
- Sidebar goes borderless/transparent on the frame
- Buttons are pills app-wide (radius 99px, default 7px/16px padding, 13px
text, icon buttons become circles), set once in components/ui/button.tsx
- PageHeader locked at exactly 24px/32px Hedvig serif
- MainContainer resets panel scroll on route change (Next's window
scroll-to-top never fires for an inner scroll container)
- chat layout + extension workspaces switch viewport-height formulas to
h-full so they fill the panel instead of overflowing it by 20px
- .claude/rules/design.md rewritten with the 14 locked UI-migration
conventions from dev_docs/ui_migration_plan.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(ui): clamp hand-rolled page titles to the locked 24px/32px
Transaktioner (TransactionStatusBar) and 13 other pages hand-roll their
h1 instead of using PageHeader, so they kept text-3xl/4xl after the
shell change. Clamp them all to font-display text-2xl leading-8.
Onboarding heroes and headline numbers are intentionally untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(ui): keep the frame strip above the panel on banner-less accounts
<main>'s 10px top margin was the first in-flow margin inside the shell
wrapper, so it collapsed through the wrapper and pushed the whole shell
down, showing white body background above the panel instead of the warm
frame strip (only visible on real accounts: the sandbox banner blocked
the collapse). Flex containers never collapse child margins, so the
shell wrappers become md:flex md:flex-col.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: mobile UX improvements across dashboard pages
- Responsive layouts with stacked mobile forms and grid desktop views
- Safe area handling (viewportFit cover, bottom nav insets, main padding)
- Touch-friendly dialogs, tabs, and page headers
- Mobile nav drawer open/close animation
- Dashboard layout parallel Supabase queries
- SIE parser: handle quoted VER/TRANS fields
- Skip account override for template-based transaction booking
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review feedback from Greptile
- Fix nav drawer close timer race condition with useRef + clearTimeout
- Show locked VAT rate as read-only label on mobile instead of hiding it
- Remove dead bottom-16 class overridden by inline style
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>