refactor(design): lock the border-radius ladder, one radius per role (#1607)
Seven radii were in circulation (4/5/6/8/12/16px + pill) with no rule for which went where; one toolbar row on /transactions mixed four shape languages. This locks a 4-tier ladder (design.md convention 16): - pill: interactive toolbar controls (buttons, chips, pickers, segmented controls, toolbar search, count nubs) - rounded-xl (12px): overlay tier: page panel, dialogs, slide-overs - rounded-lg (8px): cards, form fields, popover/menu content, boxes - rounded-sm (4px): nested leaves (menu items, checkboxes, kbd/code nubs) Changes: - New SegmentedControl primitive (pill-in-pill tablist, h-8) replaces the hand-rolled bg-muted/70 tablist copied across 11 files - New ToolbarSearch primitive (pill, h-8) adopted on 9 page toolbars; dialog/picker searches keep the rounded-lg Input - dialog.tsx 8px -> 12px, matching SettingsModal/slide-over/CommandPalette - ContextPicker chips at the shared h-8 toolbar height - ~300 rounded-md / bare rounded call sites remapped by role; auth icon tiles and the mobile nav sheet come down from 16px to 12px - rounded-md, bare rounded, rounded-2xl and rounded-[Npx] are dead vocabulary, enforced by a new off-ladder-radius check in check:guards Verified: lint 0 errors, 14422 unit tests pass, check:guards green, tsc clean on all changed files, sandbox screenshots of transactions/ bookkeeping/granskning toolbars and the Ny verifikation dialog. Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Jakob Wennberg
Claude Fable 5
parent
18c20e68e6
commit
9686b54b41
@@ -275,7 +275,7 @@ export default function AttGoraSection({
|
||||
)}
|
||||
>
|
||||
<div className="overflow-hidden pb-1">
|
||||
<div className="flex items-center gap-3 rounded bg-secondary/40 px-3 py-2">
|
||||
<div className="flex items-center gap-3 rounded-sm bg-secondary/40 px-3 py-2">
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm truncate">
|
||||
{match.transaction_description}
|
||||
@@ -302,7 +302,7 @@ export default function AttGoraSection({
|
||||
href={`/transactions?highlight=${match.transaction_id}`}
|
||||
aria-label={t('suggested_view')}
|
||||
title={t('suggested_view')}
|
||||
className="shrink-0 h-10 w-10 inline-flex items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-secondary/60 transition-colors"
|
||||
className="shrink-0 h-10 w-10 inline-flex items-center justify-center rounded-sm text-muted-foreground hover:text-foreground hover:bg-secondary/60 transition-colors"
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
</Link>
|
||||
|
||||
@@ -152,7 +152,7 @@ export default function CompanySwitcher() {
|
||||
onClick={() => handleSwitch(c.id)}
|
||||
disabled={isPending}
|
||||
className={cn(
|
||||
'flex items-center gap-2 w-full px-2.5 py-2 text-left text-[13px] leading-snug transition-colors rounded-md md:whitespace-nowrap',
|
||||
'flex items-center gap-2 w-full px-2.5 py-2 text-left text-[13px] leading-snug transition-colors rounded-sm md:whitespace-nowrap',
|
||||
c.id === company?.id
|
||||
? 'text-foreground bg-muted/40'
|
||||
: 'text-muted-foreground hover:text-foreground hover:bg-muted/40',
|
||||
@@ -184,7 +184,7 @@ export default function CompanySwitcher() {
|
||||
<Link
|
||||
href="/select-company?choose=1"
|
||||
onClick={() => setOpen(false)}
|
||||
className="flex items-center gap-2 px-2.5 py-2 text-[13px] text-muted-foreground hover:text-foreground hover:bg-muted/40 rounded-md transition-colors md:whitespace-nowrap"
|
||||
className="flex items-center gap-2 px-2.5 py-2 text-[13px] text-muted-foreground hover:text-foreground hover:bg-muted/40 rounded-sm transition-colors md:whitespace-nowrap"
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
{t('add_company')}
|
||||
|
||||
@@ -738,7 +738,7 @@ export default function DashboardNav({ companyName: _companyName, entityType, pa
|
||||
alt=""
|
||||
width={26}
|
||||
height={26}
|
||||
className="h-[26px] w-[26px] rounded-md"
|
||||
className="h-[26px] w-[26px] rounded-lg"
|
||||
/>
|
||||
</Link>
|
||||
<button
|
||||
@@ -1010,7 +1010,7 @@ export default function DashboardNav({ companyName: _companyName, entityType, pa
|
||||
{/* Bottom sheet */}
|
||||
<div
|
||||
className={cn(
|
||||
"md:hidden fixed inset-x-0 bottom-0 z-50 bg-card rounded-t-2xl border-t border-border/40 overflow-y-auto overscroll-contain",
|
||||
"md:hidden fixed inset-x-0 bottom-0 z-50 bg-card rounded-t-xl border-t border-border/40 overflow-y-auto overscroll-contain",
|
||||
isClosing
|
||||
? "animate-out slide-out-to-bottom duration-200"
|
||||
: "animate-in slide-in-from-bottom duration-300"
|
||||
@@ -1020,7 +1020,7 @@ export default function DashboardNav({ companyName: _companyName, entityType, pa
|
||||
aria-label={tNav('navigation_menu')}
|
||||
>
|
||||
{/* Drag handle */}
|
||||
<div className="flex justify-center pt-3 pb-1 sticky top-0 bg-card rounded-t-2xl">
|
||||
<div className="flex justify-center pt-3 pb-1 sticky top-0 bg-card rounded-t-xl">
|
||||
<div className="w-8 h-1 rounded-full bg-muted-foreground/25" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ export function SandboxBanner() {
|
||||
</span>
|
||||
<button
|
||||
onClick={handleCreateAccount}
|
||||
className="shrink-0 rounded-md bg-foreground/10 px-3 py-0.5 text-xs font-semibold hover:bg-foreground/15 transition-colors"
|
||||
className="shrink-0 rounded-full bg-foreground/10 px-3 py-0.5 text-xs font-semibold hover:bg-foreground/15 transition-colors"
|
||||
>
|
||||
Skapa konto
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setDismissed(true)}
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 rounded p-1 hover:bg-foreground/10 transition-colors"
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 rounded-sm p-1 hover:bg-foreground/10 transition-colors"
|
||||
aria-label="Stäng"
|
||||
>
|
||||
<X className="h-3.5 w-3.5" />
|
||||
|
||||
@@ -63,7 +63,7 @@ function CompanyMark({ name }: { name: string }) {
|
||||
return (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-[4px] bg-secondary text-[9px] font-semibold uppercase leading-none text-foreground"
|
||||
className="flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-sm bg-secondary text-[9px] font-semibold uppercase leading-none text-foreground"
|
||||
>
|
||||
{name.trim().charAt(0) || '?'}
|
||||
</span>
|
||||
@@ -193,7 +193,7 @@ export default function UserMenu({
|
||||
)
|
||||
|
||||
const menuRow =
|
||||
'flex w-full items-center gap-2.5 rounded-md px-2.5 py-2 text-left text-[13px] ' +
|
||||
'flex w-full items-center gap-2.5 rounded-sm px-2.5 py-2 text-left text-[13px] ' +
|
||||
'text-muted-foreground hover:text-foreground hover:bg-secondary/60 ' +
|
||||
'transition-colors duration-150 cursor-pointer'
|
||||
|
||||
@@ -293,7 +293,7 @@ export default function UserMenu({
|
||||
role="option"
|
||||
aria-selected={c.id === company?.id}
|
||||
className={cn(
|
||||
'flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-[13px] leading-snug transition-colors',
|
||||
'flex w-full items-center gap-2 rounded-sm px-2.5 py-2 text-left text-[13px] leading-snug transition-colors',
|
||||
c.id === company?.id
|
||||
? 'bg-secondary/60 text-foreground'
|
||||
: 'text-muted-foreground hover:bg-secondary/60 hover:text-foreground',
|
||||
|
||||
Reference in New Issue
Block a user