refactor(design): no amber boxes, attention is one ochre sentence (#1562)

The founder wants the yellow boxes gone everywhere. The design system
already agreed: status colors are data, not chrome (convention 12) and
attention is a single ochre sentence, never a banner (convention 6).
This enforces it:

- ConfirmationDialog: the amber warning panel is now an AttnLine, and
  the hardcoded Swedish default warningText is gone: it injected an
  immutability warning into dialogs whose authors never asked for one
  (every current caller passes the prop explicitly, so no behavior
  change at any call site).
- Badge warning variant: amber fill replaced with a hairline chip and
  ochre text.
- DestructiveConfirmDialog warning variant: neutral icon disc, default
  primary confirm button (only --destructive survives as chrome).
- BankSyncStatusChip stale state: same neutral shape as the healthy
  chip, ochre text carries the signal.
- SandboxBanner: solid amber bar becomes secondary-on-border chrome.
- BankIdAuth, BankIdCompanyPicker, SessionTimeoutModal: the last three
  raw-amber (bg-amber-*) holdouts moved onto tokens, the company-picker
  banner becoming a plain AttnLine.
- Mechanical sweep of the ~58 hand-rolled bg-warning/border-warning
  boxes across 45 files: fills to bg-muted/30 (icon discs bg-muted),
  borders to border-border, text-warning-foreground to text-attn. The
  account-class dots in account-number.tsx keep bg-warning: they are
  data indicators, not chrome.

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:
Jakob Wennberg
2026-08-13 11:20:16 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Fable 5
parent abff8d90f6
commit e51a2c8102
50 changed files with 157 additions and 156 deletions
@@ -130,10 +130,10 @@ export function ActivateAccountsDialog({
)}
{!loading && unknownRows.length > 0 && (
<div className="rounded-md border border-warning/40 bg-warning/5 px-3 py-2 text-xs text-warning-foreground">
<div className="rounded-md border border-border bg-muted/30 px-3 py-2 text-xs text-attn">
<p className="font-medium">Finns inte i BAS-katalogen:</p>
<p className="mt-1 font-mono">{unknownRows.map((r) => r.account_number).join(', ')}</p>
<p className="mt-1 text-warning-foreground/80">
<p className="mt-1 text-attn/80">
Skapa dem som egna konton, eller kontrollera inmatningen.
</p>
{onCreateUnknown && (
+3 -3
View File
@@ -184,9 +184,9 @@ export function AddAccountDialog({
<div className="space-y-4 py-2">
{isBASMatch && (
<div className="flex items-start gap-2 rounded-lg bg-warning/10 border border-warning/30 p-3">
<AlertTriangle className="h-4 w-4 text-warning-foreground mt-0.5 shrink-0" />
<p className="text-sm text-warning-foreground">
<div className="flex items-start gap-2 rounded-lg bg-muted/30 border border-border p-3">
<AlertTriangle className="h-4 w-4 text-attn mt-0.5 shrink-0" />
<p className="text-sm text-attn">
Kontonummer {accountNumber} finns i BAS-standarden. Använd &quot;BAS-katalog&quot;-fliken för att aktivera standardkonton istället.
</p>
</div>
@@ -321,8 +321,8 @@ export default function AttachmentPreviewSheet({
{isPdfType(doc.mime_type, doc.file_name) && integrity[doc.id] === 'invalid' && (
<div className="flex h-[70vh] w-full flex-col items-center justify-center gap-4 rounded-lg border border-border bg-muted/30 p-6 text-center">
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-warning/15">
<AlertTriangle className="h-5 w-5 text-warning-foreground" />
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-muted">
<AlertTriangle className="h-5 w-5 text-attn" />
</div>
<div className="max-w-md space-y-2">
<p className="text-sm font-medium">{t('corrupt_title')}</p>
@@ -420,8 +420,8 @@ export default function AttachmentPreviewSheet({
<DialogContent>
<DialogHeader>
<div className="flex items-center gap-3">
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-warning/15 shrink-0">
<Lock className="h-5 w-5 text-warning-foreground" />
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-muted shrink-0">
<Lock className="h-5 w-5 text-attn" />
</div>
<DialogTitle>{tj('remove_blocked_title')}</DialogTitle>
</div>
@@ -135,7 +135,7 @@ export default function CorrectOpeningBalanceDialog({
</DialogHeader>
{/* Storno explanation: a booked verifikat can't be edited in place */}
<div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/5 px-4 py-3">
<div className="flex items-start gap-3 rounded-lg border border-border bg-muted/30 px-4 py-3">
<AlertTriangle className="h-4 w-4 text-warning mt-0.5 shrink-0" />
<p className="text-sm text-warning">
En bokförd verifikation kan inte ändras direkt (Bokföringslagen). När du sparar stornas
@@ -432,8 +432,8 @@ export default function JournalEntryAttachments({
<DialogContent>
<DialogHeader>
<div className="flex items-center gap-3">
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-warning/15 shrink-0">
<Lock className="h-5 w-5 text-warning-foreground" />
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-muted shrink-0">
<Lock className="h-5 w-5 text-attn" />
</div>
<DialogTitle>{t('remove_blocked_title')}</DialogTitle>
</div>
+10 -10
View File
@@ -1277,9 +1277,9 @@ export default function JournalEntryForm({
</div>
{(monthChanged || selectedPeriodLocked) && (
<div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/10 p-3">
<AlertTriangle className="h-5 w-5 text-warning-foreground mt-0.5 shrink-0" />
<div className="flex-1 text-sm text-warning-foreground space-y-0.5">
<div className="flex items-start gap-3 rounded-lg border border-border bg-muted/30 p-3">
<AlertTriangle className="h-5 w-5 text-attn mt-0.5 shrink-0" />
<div className="flex-1 text-sm text-attn space-y-0.5">
{monthChanged && (
<p className="font-medium">
{t('review_month_changed', { prev: monthLabel(lastPostedMonth as string), current: monthLabel(entryMonth) })}
@@ -1291,7 +1291,7 @@ export default function JournalEntryForm({
)}
{uploadedFiles.filter((f) => f.status === 'uploaded').length === 0 && (
<div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/10 p-3 text-sm text-warning-foreground">
<div className="flex items-start gap-3 rounded-lg border border-border bg-muted/30 p-3 text-sm text-attn">
<AlertTriangle className="h-5 w-5 mt-0.5 shrink-0" />
<p>{t('no_doc_body')}</p>
</div>
@@ -1510,9 +1510,9 @@ export default function JournalEntryForm({
)}
{periodMismatch === 'no_period' && (
<div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/10 p-3">
<AlertTriangle className="h-5 w-5 text-warning-foreground mt-0.5 shrink-0" />
<div className="flex-1 text-sm text-warning-foreground">
<div className="flex items-start gap-3 rounded-lg border border-border bg-muted/30 p-3">
<AlertTriangle className="h-5 w-5 text-attn mt-0.5 shrink-0" />
<div className="flex-1 text-sm text-attn">
<p className="font-medium">{t('no_period_warning', { date: entryDate })}</p>
<p className="mt-0.5">{t('no_period_help')}</p>
</div>
@@ -2043,9 +2043,9 @@ export default function JournalEntryForm({
warningText={embedded ? '' : t('review_warning')}
>
{(monthChanged || selectedPeriodLocked) && (
<div className="mb-4 flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/10 p-3">
<AlertTriangle className="h-5 w-5 text-warning-foreground mt-0.5 shrink-0" />
<div className="flex-1 text-sm text-warning-foreground space-y-0.5">
<div className="mb-4 flex items-start gap-3 rounded-lg border border-border bg-muted/30 p-3">
<AlertTriangle className="h-5 w-5 text-attn mt-0.5 shrink-0" />
<div className="flex-1 text-sm text-attn space-y-0.5">
{monthChanged && (
<p className="font-medium">
{t('review_month_changed', {
@@ -237,7 +237,7 @@ export function DispositionsStep({
fiscalYear={fiscalYear}
/>
{taxDepreciationDirty && (
<p className="text-sm text-warning-foreground" role="status">
<p className="text-sm text-attn" role="status">
Spara eller återställ ändringarna i skattemässig avskrivning innan du lämnar steget.
</p>
)}
@@ -302,7 +302,7 @@ export function DispositionsStep({
{proposal.warnings?.map((warning) => (
<Card key={warning}>
<CardContent className="p-4 text-sm text-warning-foreground flex items-start gap-2">
<CardContent className="p-4 text-sm text-attn flex items-start gap-2">
<AlertTriangle className="h-4 w-4 shrink-0 mt-0.5" />
<span>{warning}</span>
</CardContent>
@@ -335,7 +335,7 @@ export function DispositionsStep({
{completed.warnings.length > 0 && (
<CardContent className="space-y-2">
{completed.warnings.map((warning) => (
<p key={warning} className="text-sm text-warning-foreground">{warning}</p>
<p key={warning} className="text-sm text-attn">{warning}</p>
))}
</CardContent>
)}
@@ -378,7 +378,7 @@ export function DispositionsStep({
)}
{taxDepreciationDirty && (
<p className="text-sm text-warning-foreground" role="status">
<p className="text-sm text-attn" role="status">
Spara eller återställ ändringarna i skattemässig avskrivning innan du lämnar steget.
</p>
)}
@@ -582,7 +582,7 @@ function ProposalCard({
</CardHeader>
<CardContent className="space-y-3">
{proposal.warnings.map((w, i) => (
<p key={i} className="text-sm text-warning-foreground">
<p key={i} className="text-sm text-attn">
{w}
</p>
))}
@@ -186,7 +186,7 @@ export function EfDeclarationSection({
{noPostedEntries && (
<Card className="border-border">
<CardContent className="p-4 flex items-start gap-3">
<AlertTriangle className="h-4 w-4 mt-0.5 text-warning-foreground shrink-0" />
<AlertTriangle className="h-4 w-4 mt-0.5 text-attn shrink-0" />
<p className="text-sm">
<span className="font-medium">Inga verifikat bokförda i perioden.</span>{' '}
Värdena nedan baseras enbart på NE-bilagans räkenskapsschema (intäkter och
@@ -298,7 +298,7 @@ export function EfDeclarationSection({
{inputWarnings.map((w, i) => (
<Card key={i} className="border-border">
<CardContent className="p-4 flex items-start gap-3">
<AlertTriangle className="h-4 w-4 mt-0.5 text-warning-foreground shrink-0" />
<AlertTriangle className="h-4 w-4 mt-0.5 text-attn shrink-0" />
<p className="text-sm">{w}</p>
</CardContent>
</Card>
@@ -335,7 +335,7 @@ export function EfDeclarationSection({
</div>
</CardHeader>
{item.warnings.length > 0 && (
<CardContent className="text-sm text-warning-foreground space-y-1">
<CardContent className="text-sm text-attn space-y-1">
{item.warnings.map((w, i) => (
<p key={i}>{w}</p>
))}