Design System Governance

A consolidation audit and governance framework for the Samtrygg design system. Not a redesign proposal — a steering document.

Samtrygg AB · Org.nr 556876-2529 Design System v1.3 April 2026 38 pages audited

1. Executive Summary

The Samtrygg design system has a strong foundation: a coherent brand palette built around #FF6D59, a distinctive proprietary typeface (Nuckle), a well-structured 8px spacing scale, and a component language that is largely consistent in intent if not in implementation. The Design System document is intended to be the single source of truth and is mostly correct, but the current page implementations do not yet reflect it consistently.

However, an audit of 38 pages reveals three structural problems that will compound as the product grows:

Problem 1 — Token Gap

The :root defines 10 primitive colour tokens. Pages use 40–60 raw hex values that are not mapped to any token. Feedback colours (#1a7a3c, #8b5a00, #e7f5ed, #fdecea) appear on nearly every page with no token name. When these colours need to change, every usage must be hunted manually across all files.

Problem 2 — Button Fragmentation

The Design System defines btn--primary (BEM). Pages use btn-primary (single dash). These are two parallel, incompatible systems operating simultaneously. The DS wins on paper; the pages win in practice. Neither is authoritative.

Problem 3 — Missing Semantic Layer

--sam-red is used for CTAs, error borders, and decorative brand accents simultaneously. There is no semantic mapping between primitive values and their intended function. When the brand evolves, the intent is invisible to anyone reading the code.

These are fixable without a rebuild. The system is not broken — it is incomplete. The recommendations in this document are conservative, prioritised, and practical.

2. Design Principles

These six principles should guide every future design system decision. They are not aesthetic preferences — they are decision filters. When a proposed change conflicts with one of these principles, the principle wins unless there is a strong, documented reason to override it.

01

Warm, not soft

Samtrygg handles one of the most significant financial relationships a person has. The design should feel warm and human, but never vague or imprecise. Clarity is a form of care. Do not sacrifice legibility or structure in pursuit of warmth.

02

Trust through consistency

Inconsistency erodes trust faster than any single bad design decision. Every component should behave the same way in every context. A button that looks different on page 12 than it does on page 3 signals unreliability — even to users who cannot name what they noticed.

03

One source of truth

If a value, colour, or pattern is defined in the design system, it must not be redefined locally. Local exceptions are technical debt dressed as pragmatism. The system is only as useful as it is complete and enforced.

04

Functional before decorative

Every visual element should serve a communicative function. Decorative colour, unnecessary shadows, and gratuitous animation dilute the signal-to-noise ratio. If removing an element does not change what the user understands, remove it.

05

Brand has a context

Brand expressiveness belongs on public-facing surfaces. Product surfaces — account pages, forms, dashboards — should recede and let the task take precedence. The same brand DNA applies to both, but the emphasis is different. Do not bring marketing energy into a lease agreement form.

06

Design for implementation

A design decision that cannot be implemented consistently across the codebase is not a design decision — it is a wish. Every pattern added to the system must come with a clear token, class, or component name. Ambiguous naming is a bug.

On exceptions

Exceptions are allowed only when they are documented and intentionally reusable. A local exception that solves only one page is usually a missing token, variant, or component — not a legitimate exception. Treat it as a signal to extend the system, not to bypass it.

3. What to Keep

ElementReason
Core palette
--sam-red: #FF6D59, --sam-dark: #313131, --sam-brown-* family
Distinctive, warm, proprietary. The warm-brown neutrals in particular are a genuine differentiator from the grey-dominant rental market. Do not swap or extend the palette without strong reason.
8px spacing scale
--s-1 through --s-9
Correct base, well-distributed steps. Covers all practical layout needs without gaps or redundancy.
Radius system
--radius-sm through --radius-pill
Consistent and already used correctly across pages. The pill radius on buttons is a recognisable brand mark.
Three-level shadow systemWell-calibrated. Shadow-1 for resting state, shadow-2 for hover lift, shadow-3 for modals and overlays. Not overdone.
Nuckle as primary typefaceStrong brand differentiator. Works at both display and body sizes. Manrope as fallback is the right choice — compatible rhythm, similar proportions.
Button base with CSS custom property injection
--btn-bg, --btn-fg, --btn-border
Excellent pattern. Variants are created by overriding local properties, not by repeating the full rule set. Keep and extend.
Handoff bar conventionThe dark bar on every mockup page encoding route, controller, and field names is a practical developer communication tool. Preserve this pattern as mockups evolve.

4. What to Change

4a. Add a semantic colour layer

The current system is primitive only. Every colour decision requires knowing the brand palette by heart. A thin semantic layer adds intent without changing any visual output:

/* Interactive */
--color-action:       var(--sam-red);
--color-action-hover: color-mix(in oklab, var(--sam-red) 88%, black);
--color-action-fg:    var(--sam-white);

/* Feedback */
--color-success:      #1a7a3c;    /* currently raw hex on 30+ pages */
--color-success-bg:   #e7f5ed;
--color-warning:      #8b5a00;
--color-warning-bg:   #fff4e0;
--color-danger:       var(--sam-error);
--color-danger-bg:    #fdecea;
--color-info:         #1a4a8a;
--color-info-bg:      #e8f0fe;

/* Surface */
--surface-base:       var(--sam-brown-light);   /* page background */
--surface-raised:     var(--sam-white);         /* cards */
--surface-sunken:     #f7f8fc;                 /* inputs, OTP, code blocks */
--surface-overlay:    rgba(49,49,49,.50);       /* modal backdrops */
--surface-inverse:    var(--sam-dark);          /* dark sections, topband, footer */

/* Text */
--text-primary:       var(--sam-dark);
--text-secondary:     var(--sam-medium);
--text-disabled:      var(--sam-light);
--text-inverse:       var(--sam-white);
--text-link:          var(--sam-red);

/* Border */
--border-default:     var(--sam-light);
--border-strong:      var(--sam-dark);
--border-focus:       var(--sam-dark);
--border-error:       var(--sam-error);

4b. Unify the button class system

Two incompatible button systems currently co-exist:

Design System (BEM)Pages (single dash)Resolution
btn--primarybtn-primaryAdopt BEM throughout
btn--secondarybtn-secondaryAdopt BEM throughout
btn--ghostbtn-ghostAdopt BEM throughout
btn--lgbtn-lgAdopt BEM throughout
missingbtn-successMap to btn--primary + --btn-bg: var(--color-success)
missingbtn-outline-whiteAdd btn--ghost-inverse to DS
missingbtn-neutralAdd btn--subtle to DS
missingbtn-link, link-btnConsolidate to one btn--link

4c. Define a type scale

Pages use 15+ arbitrary font sizes (including half-steps like 11.5px, 13.5px, 14.5px) because the system defines font families but not a scale. Add:

--text-xs:   11px;   /* legal, captions, metadata */
--text-sm:   13px;   /* labels, helper text, badges */
--text-base: 15px;   /* body default */
--text-md:   17px;   /* body large, lead text */
--text-lg:   20px;   /* card titles, section subheads */
--text-xl:   26px;   /* page headings (product surfaces) */
--text-2xl:  34px;   /* section headings, hero sub */
--text-3xl:  48px;   /* display (brand surfaces only) */

4d. Tokenise placeholder image gradients

Five gradient pairs are used as listing card placeholders across 15+ pages as raw hex. Tokenise them:

--ph-warm-start:   #e8d5c4; --ph-warm-end:   #c9a382;
--ph-green-start:  #c5d9c2; --ph-green-end:  #8aaa85;
--ph-blue-start:   #c5d2e0; --ph-blue-end:   #8aa2bc;
--ph-rose-start:   #f4d3d7; --ph-rose-end:   #e9aab0;
--ph-purple-start: #d4c5e2; --ph-purple-end: #a89fc0;

5. What to Remove

ItemReason
Remove Login v1.htmlUses #E11D2E (wrong brand red), #121212, and 60+ unregistered hex values from a prior system. Dead file that contradicts the current system.
Review --font-displayIf it remains identical to --font-body and no intentional divergence is planned, merge the two. If it is intended as future semantic separation, keep it deliberately and document that intent. The token name carries implicit promise — do not leave it undefined.
Remove --density: 1Defined in :root but never used anywhere. Remove or implement. Dead variables in a source of truth undermine confidence in the file.
Remove Half-step font sizes (11.5px, 13.5px, 14.5px)Signal an undefined scale. They appear where a designer reached for something between two steps. Fix the scale, not the exception.
Remove Inline style="" colour overridesBypass the token system entirely. Invisible to global search. Not auditable. Should be replaced with utility classes or documented component variants.
Remove sitemap.html reference to #E11D2EWrong brand red. Update to --sam-red: #FF6D59.

6. What to Standardise First

In strict priority order — not time-boxed, because estimates at this stage would be false precision:

  1. Semantic colour tokens — add to :root in the Design System. Zero visual change. Highest leverage because every future page inherits the benefit immediately.
  2. Button class unification — find-replace across 38 files. Mechanical work, no design judgment required. Eliminates the largest single source of implementation confusion.
  3. Type scale tokens — add 8 variables to :root, then make a pass replacing arbitrary sizes across pages.
  4. Placeholder gradient tokens — add 10 variables, update page CSS. Straightforward.
  5. Brand vs product surface rules — document and enforce two clear layout templates (see Section 7). This is the highest-judgment item and should be done after the mechanical fixes above.
  6. Focus states — add --border-focus token and apply consistently to all :focus-visible selectors on form elements. Accessibility baseline.
Working principle

Items 1–4 are infrastructure: low judgment, high mechanical effort, immediate payoff. Item 5 requires design leadership. Item 6 requires QA and testing. Do not skip ahead to item 5 before items 1–4 are complete — surface rules applied on top of an inconsistent token system produce inconsistent results.

7. Brand vs Product Surface Rules

Samtrygg operates across two distinct surface contexts. They share the same brand DNA — same typeface, same palette, same component shapes — but they differ fundamentally in intent, density, and visual emphasis. Treating them identically produces pages that are simultaneously over-designed for task completion and under-expressive for brand communication.

Brand Surface
Pages
Homepage, LandlordLanding, SearchLanding, SafetyPackage, guides, error pages
Typography
Nuckle at display sizes (--text-2xl to --text-3xl for heroes). Generous line-height (1.1–1.15 for headings). Body at --text-md (17px).
Spacing
Generous vertical rhythm. Section padding --s-8 to --s-9 (96–128px). Let content breathe.
Surface treatment
Dark hero sections (--surface-inverse) contrast against warm neutral body (--surface-base). Avoid white-on-white monotony.
Component density
Loose. Cards have more internal padding. CTAs are large (btn--lg). Navigation is spacious.
Visual tone
Warm, expressive, confident. Colour used actively — not just for feedback. Nuckle at large sizes carries the brand personality.
Interaction emphasis
One clear primary CTA per section. Hover states with --shadow-2 lift. Subtle but present animation on key transitions.
Product Surface
Pages
All account pages, forms, dashboards, agreements, booking flows, settings
Typography
Nuckle at task sizes (--text-xl max for page titles, --text-lg for section heads). Body at --text-base (15px). Tighter line-height (1.5).
Spacing
Deliberate. Section padding --s-5 to --s-6 (32–48px). Form groups --s-3 (16px). Density serves scanning, not breathing room.
Surface treatment
White cards on --surface-base. Dark topband and footer. Minimal decorative colour — reserve for status communication only.
Component density
Standard. Cards use default padding. Buttons are default height unless the action is primary and isolated. Form fields fill available width.
Visual tone
Calm, structured, reliable. Colour used almost exclusively for feedback (success/warning/error/info). Brand warmth expressed through the palette neutrals, not bold colour.
Interaction emphasis
One primary CTA per form or step. Status clearly communicated at a glance. Focus states always visible. Loading states explicit, not ambiguous.
Common failure mode

Applying brand-surface visual density (large type, bold colour, generous spacing) to product surfaces makes forms feel like marketing. Applying product-surface restraint to brand surfaces makes them feel like SaaS. The distinction should be enforced at the layout level, not patched per-component.

CTA hierarchy across surfaces

The current system allows multiple primary buttons per view, which dilutes the signal. The rule should be:

SurfacePrimary CTAs per viewSecondaryGhost/Link
Brand / marketingOne per section (not per page)One, at most — paired with primaryNavigation only
Product / taskOne per form, step, or modal by defaultOne destructive/cancel actionUtility actions (save draft, view details)
Error / empty stateOne recovery actionOne soft fallback (go back, browse)None

8. Component Intent

For each core component: what it is for, and what it is not for. These definitions should govern every future usage decision.

Component Purpose Usage rules
Button
Triggers an action. The hierarchy of button variants communicates the hierarchy of available actions. btn--primary is a commitment. btn--secondary is an alternative. btn--ghost is a utility. btn--link is navigation dressed as action.
  • One btn--primary per form or card by default. Duplicate primary actions are only acceptable when they represent the same action in different scroll or viewport contexts.
  • Destructive actions (delete, cancel) use btn--danger, always paired with a confirmation step
  • Never use colour to communicate loading state — use a spinner inside the button
  • btn--ghost on dark backgrounds requires btn--ghost-inverse — do not rely on contrast alone
  • Disabled state must be visually distinct — use opacity: 0.45 + cursor: not-allowed, never just greyed text
Card
A contained unit of related content. Cards establish a boundary — everything inside belongs together. There are three behavioural variants: static (information only), interactive (the whole card is clickable), and actioned (card has internal actions like save or apply).
  • Static cards have no hover state — adding one implies interactivity
  • Interactive cards use translateY(-2px) + --shadow-2 on hover — not border colour change
  • Never nest interactive elements inside a fully-clickable card — choose one pattern
  • Card padding: --s-4 (24px) default on product surfaces, --s-5 (32px) on brand surfaces
  • Card radius should default to --radius-xl (24px). Smaller radii should only be used if there is a documented system-level reason.
Input
Captures user-entered data. The input component communicates three states at minimum: default, focused (user is here), and error (validation failed). A fourth state — success (value accepted) — is used only in multi-step flows where confirmation is meaningful.
  • Default: --border-default border
  • Focus: --border-focus border + 3px shadow ring at 8% opacity — never colour-only focus
  • Error: --border-error border + error message directly below, never above
  • Labels always above the field — never floating labels (they fail on autofill and screen readers)
  • Required fields: mark with * in label — do not rely on placeholder text alone
  • Disabled: --surface-sunken background + --text-disabled text
Badge / Chip
Communicates status, category, or count. Badges are read-only labels. Chips are interactive (filterable, toggleable). These are not the same component — distinguish them in implementation.
  • Status badges use semantic colours: --color-success-bg, --color-warning-bg, --color-danger-bg, --color-info-bg
  • Never use --sam-red for a status badge unless it is genuinely an error — the brand red is an action colour, not an alert colour
  • Badge text should default to uppercase, --text-xs, font-weight 700, unless a specific readability or localisation case requires otherwise.
  • Interactive chips: add border, hover state, and aria-pressed
  • Limit to 2–3 badges per card — more creates visual noise, not information density
Alert
Communicates a system-level message that requires user attention. Alerts are contextual (inline, near the relevant content) or page-level (at the top of the view). They are not decorative — every alert must communicate something the user needs to act on or be aware of.
  • Four semantic variants only: success, warning, error, info — mapped to --color-* tokens
  • Always include an icon alongside colour — colour alone fails for colour-blind users
  • Dismissible alerts: always include a visible close affordance (× or "Dismiss")
  • Inline errors on form fields are not alerts — they are a component of the input, not a separate component
  • Page-level alerts appear below the topband/nav, never inside it
  • Do not use alerts for empty states — empty states are their own component
Tabs
Switches between related views of the same content or context. Tabs imply that all options are always available — the user chooses what to show, not what to do next. They are not a step indicator, a wizard, or a navigation system.
  • Maximum 5–6 tabs before content should be restructured into separate pages
  • Active tab: --border-strong underline (2px), text at full opacity
  • Inactive tab: --text-secondary, no underline
  • Tabs should default to text with underline state, not boxed controls, unless a clearly different navigation pattern is intentionally introduced at system level.
  • On mobile: scrollable tab row, not collapsed to select
  • Do not use tabs inside modals or drawers — the nesting creates spatial confusion
Empty State
Shown when a list, dashboard, or content area has no items to display. The empty state is a teaching moment — it should explain why the space is empty and offer a clear path forward. It is not a loading state or an error state.
  • Always include: a single icon or illustration, a heading (what's missing), one sentence of explanation (why), one primary CTA (what to do)
  • Icon: monochrome, 48–56px, uses --text-secondary colour
  • Heading: --text-lg, font-weight 700
  • Never show an empty state while data is still loading — show a skeleton instead
  • Never use the empty state as a loading placeholder — they communicate different things
  • On product surfaces: centred, contained within the list area. On brand surfaces: full-section treatment with more generous spacing.

9. Visual Hierarchy, CTA Hierarchy, and Form Communication

Visual hierarchy

The current pages have consistent component styling but inconsistent visual hierarchy within pages. The heading scale is applied locally rather than systematically, which means a --text-xl heading on one page competes with a --text-2xl heading on an adjacent page at the same level of the information architecture.

Status and form communication

The current system communicates form state primarily through border colour. This is insufficient. Validation, loading, and success states need a fuller communication pattern:

StateBorderAdditional signalText
Default--border-defaultLabel at --text-sm
Focus--border-focus (2px)3px ring at 8% opacityLabel unchanged
Error--border-errorError icon in field trailing positionError text in --color-danger below field
Success (confirmed)--border-defaultCheckmark icon in trailing positionHelper text in --color-success
Disabled--border-default--surface-sunken background--text-disabled colour
Loading--border-defaultSpinner in trailing positionLabel unchanged
Principle

Never rely on colour alone to communicate state. Every colour-based signal must be paired with a shape signal (icon, border weight, or position change). This is both an accessibility requirement and a clarity improvement.

10. Priority Fixes

#IssueWhy it mattersSeverityRecommendation
1 #1a7a3c, #e7f5ed, #8b5a00 etc. used as raw hex on 30+ pages Success/warning/danger states have no token. Impossible to update globally. Any brand refresh requires a full codebase hunt. Critical Add semantic feedback tokens to :root: --color-success, --color-success-bg, --color-warning, --color-warning-bg, --color-danger-bg, --color-info, --color-info-bg
2 Two incompatible button class systems (btn--primary vs btn-primary) Developers implement both in the same codebase. The DS is not authoritative. Every new page adds to the inconsistency. Critical Adopt BEM form (btn--primary) throughout. Mechanical find-replace across all pages. Update Design System to document all variants including new additions.
3 No type scale tokens — 15+ arbitrary font sizes found Arbitrary sizes proliferate with each new page. Visual hierarchy is inconsistent because the same information level uses different sizes in different pages. High Add --text-xs through --text-3xl to :root. Enforce through DS documentation. Phase out half-step sizes (11.5px, 13.5px, 14.5px).
4 Placeholder gradient pairs as raw hex in 15 files Changing the placeholder visual style requires editing 15 files individually. High change cost for low-stakes visual decision. High Add --ph-* gradient start/end tokens to :root. Update all usage in one pass.
5 Brand/product surface distinction not formally defined or enforced Product pages feel over-designed; brand pages feel under-differentiated. The same spacing and component sizing is applied to both, making neither work optimally. High Document brand and product surface rules (see Section 7). Apply to 2–3 representative pages as proof of concept before rolling out.
6 Multiple primary CTAs per view on several pages Dilutes the primary action signal. Users hesitate when everything looks equally important. Increases cognitive load at exactly the moment the user should be deciding. High Enforce CTA hierarchy rules from Section 7. Audit all pages: one btn--primary per form or step, one secondary, remaining actions as ghost or link.
7 Focus states not consistently defined across form inputs Keyboard and assistive technology users cannot reliably track focus position. WCAG 2.1 AA failure. Also a usability issue for all users on forms with many fields. High Add --border-focus token. Apply consistent :focus-visible rule to all interactive elements: 2px --border-focus + 3px shadow ring at 8% opacity.
8 Form validation communicates only via border colour Fails for colour-blind users. Also insufficient for complex forms where errors may be far from the current scroll position. Medium Add icon signal (trailing position) to all error, success, and loading states. Add scroll-to-first-error behaviour on form submit failure. See Section 9 state table.
9 Inline style="" colour overrides used throughout Bypass the token system. Not auditable. Not searchable. Accumulate silently as each page adds local exceptions. Medium Extract to utility classes or component variant classes. Establish a rule: no inline colour styles. Exceptions require documentation.
10 Login v1.html uses #E11D2E (wrong brand red) Wrong brand colour in the project. Could be referenced accidentally by a developer unfamiliar with the file history. Medium Delete the file. If a reference version is needed, archive it outside the active pages directory.
11 btn-outline-white (dark bg ghost button) has no DS definition Used on dark hero sections but not documented. Each implementation reinvents it slightly differently. Inconsistent appearance on brand surfaces. Medium Add btn--ghost-inverse to DS: white border, white text, transparent background. Document usage context (dark surfaces only).
12 --density: 1 defined but never used Dead variable in source of truth. Erodes confidence in the design system file. If it exists, it should do something. Low Remove if not planned. Implement if compact/touch modes are on the roadmap — would be high value for mobile product surfaces.
13 Shadow tokens use rgba(49,49,49,...) not var(--sam-dark) Minor inconsistency — the raw colour in shadows is not connected to the colour token. Low practical impact today, but signals a pattern to avoid. Low Update shadow tokens to use color-mix(in oklab, var(--sam-dark) 5%, transparent) etc. Address after higher-priority items.

10a. Change Control

This document is titled a governance document. It requires a lightweight rule set for how the system itself evolves — not just what it currently contains.

All future design system changes should follow these rules:

On exceptions

Exceptions are allowed only when they are documented and intentionally reusable. A local exception that solves only one page is usually a missing token, variant, or component — not a legitimate exception. Treat it as a signal to extend the system, not to bypass it.

11. Final Recommendation

Primary directive

Do not redesign pages. The visual direction is correct. The problem is infrastructure, not aesthetics. Time spent on token consolidation now will reduce effort and inconsistency on every future page.

The Samtrygg design system is at a decision point. It has enough surface area to work — the brand is recognisable, the palette is distinctive, the component shapes are appropriate. But it is missing the governance layer that would make it scale reliably.

The recommended sequence is not a fixed timeline but a dependency graph. Steps 1–4 create the conditions for Step 5 to succeed consistently. Step 5 creates the conditions for new page production to scale. Do not skip ahead.

PhaseWorkRelative effortDependency
Phase 1
Token foundation
Add semantic colour layer, type scale tokens, placeholder tokens. Remove dead variables. Update Design System document.Low — mechanical, no design judgmentNone — do this first
Phase 2
Component unification
Unify button classes (BEM). Add missing variants. Define focus states. Update all 38 pages.Medium — mechanical + light reviewPhase 1 complete
Phase 3
Surface templates
Write brand surface and product surface rules. Apply to 3 pages each as proof of concept. Document and get sign-off before rolling out.Medium-high — requires design judgment and stakeholder alignmentPhase 2 complete
Phase 4
Form and status
Implement full validation state pattern (icon + colour + text). Add scroll-to-error. Audit CTA hierarchy across all pages.Medium — requires dev collaborationPhase 1–2 complete
Ongoing
Governance
Enforce: no inline colour styles. No new hex values without a token. Every new component documented before shipping. Design System reviewed quarterly.Low per page — high upfront as habitPhase 1 complete

The goal of this document is not to produce a perfect design system immediately. It is to make the next decision easier than the last one — and the one after that easier still. That only happens when the system is trusted, which only happens when it is complete, consistent, and enforced.

12. v1.3 Addendum — April 22, 2026

This addendum captures decisions made during the April 22 polish rundor. None contradict the governance directives above — each extends the system.

DecisionRationaleStatus
New component: _public-nav drawer (hamburger + slide-in)Homepage + LandlordLanding hid nav at narrow widths with no replacement. Shared drawer unblocks ≤976px users.Shipped. Documented in DS § 24.
New component: _rating (5-star input)RateExperience.html inlined its own stars. Extracted with Samtrygg.rating API for reuse on future landlord/tenant review flows.Shipped. Documented.
New component: _media-upload (drag-drop + reorder)CreateListing inlined its own uploader. Extracted for reuse on ID verification uploads, listing edits, profile photo changes.Shipped. CreateListing not yet refactored (avoid publishing-flow regression).
New component: _bankid (QR auth modal)BankID pattern lived only as inline panel in Login. Promoted to Samtrygg.bankid.open() helper so other flows (signing, verification) can invoke the same visual.Shipped. Login not yet refactored.
Sidebar badges → runtime-drivenPrevious hardcoded "4", "12" etc. blocked server-side integration. Now reads window.SAM_BADGES or localStorage.sam_badges.Shipped. Razor integrates via <script>window.SAM_BADGES = …</script> in layout.
LandlordProfile split from PublicProfileReusing tenant-as-seen-by-landlord view as landlord's own-profile edit page was semantically wrong. Separate page added.Shipped.
Desktop filter drawer (Search)Mobile bottom-sheet was already comprehensive; desktop lacked any deep filter entry. Added right-drawer variant reusing the same .sheet markup.Shipped.
Token migration: #faf9f8var(--sam-brown-light); #d97706var(--color-warning-accent); timeline/agr-card hex removedComplies with governance § "No hex values without a token".Shipped in _agreement.css.
Spacing normalisation — shared asset filesCore files now stick to 4/8/12/16/20/24/28 scale. Page-specific inline off-grid values remain (~105) — to be addressed per page during integration.Partial. Core files clean.
Enforcement note

Any new hex literal, off-grid padding, or inline component markup introduced after v1.3 must either reference an existing token/component or file a governance exception. Six components remain un-integrated from their original locations (see Known remainders in DEV_HANDOFF.md) — integrate, don't duplicate.

Brand color contrast — documented WCAG AA exceptions

Lighthouse audit 2026-04-22 flagged the following contrast ratios below WCAG AA 4.5:1. After deliberation, these are accepted brand exceptions, not defects:

CombinationRatioWhere usedDecision
White text on --sam-red (#FF6D59)2.76:1Every .btn--primary + .badge--brand across the siteAccepted. Brand-red is core identity; alternative would require either (a) darkening brand red (rejected — brand integrity) or (b) forcing all primary-button text to 18pt+ bold (rejected — visually heavy).
--sam-red text on --sam-brown-light2.36:1Hero em accents (hem., Vi tar hand om resten.)Accepted. Single-word brand emphasis at ≥28px bold. Decorative rather than informational — the meaning is carried by the surrounding black text.
--sam-red text on #3D3D3D (dark hero)3.92:1Process-step labels on dark bandsAccepted. ≥14pt bold passes the AA large-text threshold (3:1).
Muted gray #848484 on white3.74:1Was: --sam-medium labels, lang-switch inactive, footer org-lineFixed. --sam-medium darkened to #707070 (4.8:1). Footer secondary gray #6a6a6a#9e9e9e (4.6:1 on #313131).

Brand-red exceptions apply only to decorative text and CTA button labels. Any new use of red on white/brown-light outside those contexts must pass 4.5:1 or be restyled.


Samtrygg Design System Governance v1.3 · April 2026 · Design Systems Lead · Samtrygg (Remix)