Hele kortet kan klikkes, men lenken heter det tittelen sier, og resten leses som tekst.
Levende merkevarebok
Designsystemet, i live
Dette er ikke en PDF. Hver farge, avstand og bevegelse på denne siden leses fra @hjconsult/tokens, de samme tokenene nettstedet er bygget av. Bytter du tema, bytter boka.
Prinsipper
Tre regler vi designer etter
Stemme, bevegelse og tilgjengelighet er ikke pynt lagt på til slutt. De ligger i tokenene, i komponentene og i måten vi skriver på.
Stemme og tone
Trygg, varm og rett på sak, med et glimt i øyet. Vi skriver «vi bygger», ikke «det leveres». Korte setninger og ingen buzzord. Tankestrek bare når pausen er selve poenget, og aldri punktum i en overskrift. Humor bare når setningen fortsatt gir mening uten den.
Written natively, never translated word for word. Confident, warm and plain-spoken. Contractions are fine, jargon is not. No dash as a pause and no full stop on a heading: a comma, a colon or a new sentence does the job better. The joke is allowed only if the sentence still works without it.
- «Vi setter opp overvåking i fase én.»
- «Dataene dine blir i EU.»
- «Dette vet vi ikke ennå. Vi finner det ut i briefen.»
- «Vi bygger det, og du eier koden.»
- «Vi leverer innovative, skalerbare synergier.»
- «Kontakt oss for et uforpliktende tilbud!!!»
- «Enterprise-grade KI-transformasjon.»
- «Vi skriver ikke bare kode – vi skaper verdi.»
Bevegelse
- 01
Innholdet først
Alt finnes i HTML-en før JavaScript kjører. Bevegelse legger til, og avslører aldri noe som ellers er skjult.
- 02
Tokens, ikke tall
Varigheter fra motion.duration.*, kurver fra motion.ease.*, fjærer fra motion.spring.*. Ingen magiske millisekunder i komponentene.
- 03
Respekt for redusert bevegelse
prefers-reduced-motion nuller alle varigheter og dropper parallakse og shader-animasjon. Alt har en statisk versjon.
- 04
Inn med expo, flytt med standard
Elementer kommer inn raskt og lander mykt (out-expo). Flytting bruker standard-kurven. Loops bruker in-out.
Tilgjengelighet
- 01
Minst WCAG 2.2 AA
Tekst på canvas ≥ 7:1 og dempet tekst ≥ 4,5:1, testet for hvert tema og fargeskjema i byggetrinnet.
- 02
Synlig fokus
color.focus med tykk ring og 2 px avstand. Vi fjerner aldri outline.
- 03
Semantikk før ARIA
Landemerker, én h1 per side, ekte knapper og lenker. ARIA fyller hull og er aldri en lapp.
- 04
Tastatur og skjermleser
Alt kan nås med Tab. Dekorative effekter er aria-hidden, og animert tekst beholder den ekte strengen i DOM-en.
Logo
Merket og ordmerket
Logoen finnes som et horisontalt oppsett (merke + ordmerke) og som frittstående merke. Begge er vektor og arver tekstfargen, så de fungerer på alle flater i systemet.
- På canvasHJ ConsultHorisontalt oppsett
- På hevet flateHJ ConsultHorisontalt oppsett
- På aksentHJ ConsultHorisontalt oppsett
Luft rundt
Hold minst høyden av merket fritt på alle sider. Ingenting skal inn i den sonen, verken tekst, ikoner eller kanter.
Minste størrelse
Horisontalt oppsett: aldri under 24 px høyt på skjerm. Merket alene: aldri under 16 px.
Ikke gjør dette
- Ikke strekk, roter eller skråstill logoen.
- Ikke legg til skygge, glød eller kontur.
- Ikke bruk andre farger enn color.fg, color.fg-on-accent og color.accent.
- Ikke plasser logoen på bilder uten en rolig, ensfarget sone bak.
- Ikke lag egne oppsett. Bruk de to som finnes.
SVG, PNG og favicon i begge oppsett, til trykk, presentasjoner og partnere.
Pakken legges ut her når de endelige filene er klare. Trenger du logoen nå, send oss en e-post.
Be om logopakken på e-post/brand/hjconsult-logo-pack.zipFarger
Semantiske farger som følger temaet
Komponenter bruker bare semantiske tokens (color.*). Palettene bak er OKLCH-ramper, og hvert tema peker tokenene til sine egne stopp. Kontrasten under er regnet ut i byggetrinnet, mot color.canvas i hvert temas native fargeskjema.
Flater
| Token | Bruk | Nordlys | Systems |
|---|---|---|---|
color.canvas--hj-color-canvas | Page background: the lowest layer everything sits on. | – | – |
color.surface--hj-color-surface | Default panel and card background, one step above canvas. | 1.1:1Kun dekor | 1.0:1Kun dekor |
color.surface-raised--hj-color-surface-raised | Elevated surface: popovers, sticky bars, hovered cards. | 1.1:1Kun dekor | 1.1:1Kun dekor |
Tekst
| Token | Bruk | Nordlys | Systems |
|---|---|---|---|
color.fg--hj-color-fg | Primary text and icons. ≥ 7:1 on canvas in every theme and scheme. | 17.4:1AAA | 18.1:1AAA |
color.fg-muted--hj-color-fg-muted | Secondary text: metadata, descriptions. ≥ 4.5:1 on canvas. | 7.9:1AAA | 8.1:1AAA |
color.fg-subtle--hj-color-fg-subtle | Tertiary text for placeholders, disabled and decorative content. It only clears 3:1, so keep it to large or non-essential text. | 5.3:1AA | 5.2:1AA |
color.fg-on-accent--hj-color-fg-on-accent | Text and icons placed on accent fills. ≥ 4.5:1 on accent.vs color.accent | 14.4:1AAA | 13.2:1AAA |
color.accent-alt-fg--hj-color-accent-alt-fg | Text and icons placed on accent-alt fills.vs color.accent-alt | 7.0:1AAA | 14.8:1AAA |
Aksent
| Token | Bruk | Nordlys | Systems |
|---|---|---|---|
color.accent--hj-color-accent | Primary brand accent: links, primary buttons, highlights. | 14.4:1AAA | 13.2:1AAA |
color.accent-strong--hj-color-accent-strong | Deeper accent for hover/active states and thin strokes that need ≥ 3:1 against canvas. | 10.5:1AAA | 10.1:1AAA |
color.accent-soft--hj-color-accent-soft | Accent at ~15 % alpha: selected rows, soft badges, tints. | 1.4:1Kun dekor | 1.3:1Kun dekor |
color.accent-alt--hj-color-accent-alt | Secondary accent: data visualisation, tags, the second hero colour. | 7.0:1AAA | 14.8:1AAA |
color.focus--hj-color-focus | Focus ring colour. Pair with border.width.thick and a 2px offset. | 14.4:1AAA | 13.2:1AAA |
Linjer og glass
| Token | Bruk | Nordlys | Systems |
|---|---|---|---|
color.line--hj-color-line | Hairline dividers and default borders (alpha, works over any surface). | 1.2:1Kun dekor | 1.2:1Kun dekor |
color.line-strong--hj-color-line-strong | Emphasised borders: inputs, table headers, hard rules. | 1.5:1Kun dekor | 1.8:1Kun dekor |
color.glass--hj-color-glass | Translucent fill for glass panels. Pair it with backdrop-filter. | 1.1:1Kun dekor | 1.1:1Kun dekor |
color.glass-line--hj-color-glass-line | Border for glass panels. | 1.4:1Kun dekor | 1.5:1Kun dekor |
Status
| Token | Bruk | Nordlys | Systems |
|---|---|---|---|
color.positive--hj-color-positive | Success and confirmation: text-safe on canvas. | 9.1:1AAA | 9.3:1AAA |
color.warning--hj-color-warning | Caution and pending: text-safe on canvas. | 10.3:1AAA | 10.6:1AAA |
color.danger--hj-color-danger | Errors and destructive actions: text-safe on canvas. | 6.7:1AA | 6.9:1AA |
Hero-palett
| Token | Bruk | Nordlys | Systems |
|---|---|---|---|
color.hero.a--hj-color-hero-a | Shader / illustration palette stop A: the base (darkest or lightest field). | 1.0:1Kun dekor | 1.2:1Kun dekor |
color.hero.b--hj-color-hero-b | Shader / illustration palette stop B: the mid-tone wash. | 4.0:1Stor tekst | 7.3:1AAA |
color.hero.c--hj-color-hero-c | Shader / illustration palette stop C: the accent glow. | 14.4:1AAA | 14.9:1AAA |
color.hero.d--hj-color-hero-d | Shader / illustration palette stop D: the contrasting flare. | 4.7:1AA | 14.8:1AAA |
Kontrast regnes på sRGB-fallback med alfa komponert over canvas, slik nettleseren gjør det. Selve fargeprøvene bruker var(--hj-…) og følger temaet du ser på.
Typografi
Én grotesk, én mono, én flytende skala
Display og brødtekst settes i Schibsted Grotesk, kode og etiketter i Geist Mono. Skalaen er flytende: hvert trinn har min og maks mellom breakpoint.sm og breakpoint.xl, med linjehøyde og sperring bakt inn i Tailwind-klassen.
var(--font-schibsted), "Schibsted Grotesk", ui-sans-serif, system-ui, sans-serifBlåbærsyltetøy, ærlig øl og sære måker på en rå fjordbrygge.
Æ Ø Å æ ø å 0123456789 «sitat» → ← ↑ ↓ 12 °C
var(--font-schibsted), "Schibsted Grotesk", ui-sans-serif, system-ui, sans-serifSphinx of black quartz, judge my vow.
Blåbærsyltetøy, ærlig øl og sære måker på en rå fjordbrygge. Æ Ø Å æ ø å 0123456789 «sitat» → ← ↑ ↓ 12 °C
Æ Ø Å æ ø å 0123456789 «sitat» → ← ↑ ↓ 12 °C
var(--font-geist-mono), "Geist Mono", ui-monospace, "SFMono-Regular", monospaceÆ Ø Å æ ø å 0123456789 «sitat» → ← ↑ ↓ 12 °C
:root {
--hj-color-accent: oklch(0.877 0.15 167);
--hj-motion-ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}Flytende skala
| Rolle | Prøve | Min | Maks | Linjehøyde | Sperring | Tailwind |
|---|---|---|---|---|---|---|
display-1 | Aa Ææ Øø Åå | 3rem | 8rem | 1.05 | -0.03em | text-display-1 |
display-2 | Aa Ææ Øø Åå | 2.5rem | 5.5rem | 1.05 | -0.03em | text-display-2 |
h1 | Aa Ææ Øø Åå | 2.25rem | 4rem | 1.05 | -0.015em | text-h1 |
h2 | Aa Ææ Øø Åå | 1.75rem | 2.75rem | 1.15 | -0.015em | text-h2 |
h3 | Aa Ææ Øø Åå | 1.375rem | 1.875rem | 1.15 | -0.015em | text-h3 |
h4 | Aa Ææ Øø Åå | 1.125rem | 1.375rem | 1.3 | 0 | text-h4 |
h5 | Aa Ææ Øø Åå | 1rem | 1.125rem | 1.3 | 0 | text-h5 |
h6 | Aa Ææ Øø Åå | 0.875rem | 1rem | 1.3 | 0.08em | text-h6 |
lead | Aa Ææ Øø Åå | 1.125rem | 1.375rem | 1.65 | 0 | text-lead |
body | Aa Ææ Øø Åå | 1rem | 1.125rem | 1.5 | 0 | text-body |
small | Aa Ææ Øø Åå | 0.875rem | 0.9375rem | 1.5 | 0 | text-small |
caption | Aa Ææ Øø Åå | 0.75rem | 0.8125rem | 1.5 | 0 | text-caption |
Tokens
Avstand, radius, skygge og bevegelse
Alt under er hentet fra tokenpakken i byggetrinnet. Verdiene er de faktiske; visualiseringene bruker var(--hj-…) og følger derfor temaet.
Avstand
4 px-rutenett. Tailwind-klassene speiler multiplikatoren: p-4 = space.4 = 1 rem. De flytende trinnene (gutter, section-*) er clamp() mellom sm og xl.
| Token | Verdi | Avstand | Tailwind |
|---|---|---|---|
space.px--hj-space-px | 1px | p-px | |
space.0-5--hj-space-0-5 | 0.125rem | p-0.5 | |
space.1--hj-space-1 | 0.25rem | p-1 | |
space.2--hj-space-2 | 0.5rem | p-2 | |
space.3--hj-space-3 | 0.75rem | p-3 | |
space.4--hj-space-4 | 1rem | p-4 | |
space.5--hj-space-5 | 1.25rem | p-5 | |
space.6--hj-space-6 | 1.5rem | p-6 | |
space.8--hj-space-8 | 2rem | p-8 | |
space.10--hj-space-10 | 2.5rem | p-10 | |
space.12--hj-space-12 | 3rem | p-12 | |
space.16--hj-space-16 | 4rem | p-16 | |
space.20--hj-space-20 | 5rem | p-20 | |
space.24--hj-space-24 | 6rem | p-24 | |
space.32--hj-space-32 | 8rem | p-32 | |
space.40--hj-space-40 | 10rem | p-40 | |
space.48--hj-space-48 | 12rem | p-48 | |
space.64--hj-space-64 | 16rem | p-64 | |
space.fluid.gutter.*--hj-space-gutter | 1rem → 2.5rem | Page gutter at the sm breakpoint (16px). | px-gutter |
space.fluid.section.sm.*--hj-space-section-sm | 2.25rem → 5rem | Compact section padding on a phone (36px). | py-section-sm |
space.fluid.section.md.*--hj-space-section-md | 3.25rem → 8rem | Default section padding on a phone (52px). | py-section-md |
space.fluid.section.lg.*--hj-space-section-lg | 4.5rem → 12rem | Hero/feature section padding on a phone (72px). | py-section-lg |
Radius
Fra xs for chips til 3xl for store paneler. full gir pillform og sirkler.
radius.xs2pxrounded-xsradius.sm4pxrounded-smradius.md6pxrounded-mdradius.lg8pxrounded-lgradius.xl12pxrounded-xlradius.2xl16pxrounded-2xlradius.3xl24pxrounded-3xlradius.full9999pxrounded-full
Skygge
Tre nivåer pluss glow. Fargen på glow følger temaets aksent.
shadow.1shadow-1shadow.2shadow-2shadow.3shadow-3shadow.glowshadow-glow
Bevegelse
Varigheter, kurver, forsinkelser og fjærer. Under redusert bevegelse ganges alt med motion.reduced.multiplier (0).
Varigheter
| Token | Verdi | Bruk |
|---|---|---|
motion.duration.instant | 0ms | No animation, for reduced motion and instant state swaps. |
motion.duration.fast | 120ms | Hover, focus, toggles. |
motion.duration.base | 240ms | Default UI transition for reveals, menus and accordions. |
motion.duration.slow | 480ms | Page-level transitions, large panels. |
motion.duration.hero | 1200ms | Cinematic hero reveals and shader fades. |
motion.stagger.base | 40ms | Stagger between list/grid children. |
motion.stagger.slow | 80ms | Stagger for hero lines and large cards. |
motion.reduced.multiplier | 0 | Multiply durations by this when prefers-reduced-motion is set (0 = instant). |
Kurver
| Token | Verdi | Tailwind |
|---|---|---|
motion.ease.standardDefault easing for UI state changes. | cubic-bezier(0.2, 0, 0, 1) | ease-standard |
motion.ease.out-quartFast start and soft landing, for reveals and enters. | cubic-bezier(0.25, 1, 0.5, 1) | ease-out-quart |
motion.ease.out-expoVery fast start and long settle, for the hero and scroll-linked reveals. | cubic-bezier(0.16, 1, 0.3, 1) | ease-out-expo |
motion.ease.in-outSymmetric, for page transitions and looping motion. | cubic-bezier(0.83, 0, 0.17, 1) | ease-in-out |
motion.ease.anticipatePulls back before overshooting, for playful kinetic accents. | cubic-bezier(0.68, -0.4, 0.32, 1.4) | ease-anticipate |
Fjærer
| Token | stiffness | damping | mass | Bruk |
|---|---|---|---|---|
motion.spring.snappy | 400 | 30 | 1 | Stiffness of the snappy spring, for UI feedback. |
motion.spring.gentle | 170 | 26 | 1 | Stiffness of the gentle spring, for drifts and layout shifts. |
motion.spring.bouncy | 300 | 12 | 1 | Stiffness of the bouncy spring, for motion that should catch the eye. |
Se kurvene
Spill av hver kurve med sin typiske varighet. Under redusert bevegelse vises sluttbildet med én gang, slik nettstedet også oppfører seg.
- Kurve
motion.ease.standardVarighet: 240ms (motion.duration.base) - Kurve
motion.ease.out-quartVarighet: 480ms (motion.duration.slow) - Kurve
motion.ease.out-expoVarighet: 480ms (motion.duration.slow) - Kurve
motion.ease.in-outVarighet: 480ms (motion.duration.slow) - Kurve
motion.ease.anticipateVarighet: 1200ms (motion.duration.hero)
Komponenter
Hele @hjconsult/ui, i sine viktigste varianter
Hver komponent leser tokens gjennom Tailwind-utilities, så alt her bytter tema sammen med resten av siden. Navnet i hjørnet er registry-elementet.
Grunnelementer
- Button
Installer r/button.json - IconButton
Installer r/icon-button.json - Link
Installer r/link.json - Heading
Installer r/heading.jsondisplay-2Vi bygger det andre sier er vanskelig.
h1Vi bygger det andre sier er vanskelig.
h2Vi bygger det andre sier er vanskelig.
h3Vi bygger det andre sier er vanskelig.
h4Vi bygger det andre sier er vanskelig.
h5Vi bygger det andre sier er vanskelig.
h6Vi bygger det andre sier er vanskelig.
- Text
Installer r/text.jsonIngress: den første setningen leseren møter.
Brødtekst: rolig, lesbar og aldri lengre enn 65 tegn per linje når measure er på.
Liten tekst til bildetekster og metadata.
Caption i mono til etiketter.
- Eyebrow
Installer r/eyebrow.jsonEtikettMed prikk07Med indeksAksent - Badge
Installer r/badge.jsonNøytralAksentAlternativI driftForsinketNede - LogoMark
Installer r/logo-mark.json - Avatar
Installer r/avatar.json
Layout
- Container
Installer r/container.jsonContainer sentrerer innholdet og gir det den flytende margen. Fire bredder: prose, narrow, default, wide.
size="prose"size="narrow"size="default"size="wide" - Section
Installer r/section.jsonSection gir vertikal rytme fra space.fluid.section.* og en innebygd container.
space="sm"space="md"space="lg" - Grid
Installer r/grid.jsonCelle 1Celle 2Celle 3Celle 4Celle 5Celle 6 - Bento
Installer r/grid.jsonSpenner 8 av 12Spenner 4Spenner 4Spenner 8 - Separator
Installer r/separator.jsonSeparator: dekorativ som standard, semantisk hr når decorative er false.
Flater
- Card (surface)
Installer r/card.jsonKorttittel
Beskrivelse under tittelen.
Kortets innhold. Fire varianter med de samme slotene: surface, raised, glass og outline.
surfaceBunntekst - Card (raised)
Installer r/card.jsonKorttittel
Beskrivelse under tittelen.
Kortets innhold. Fire varianter med de samme slotene: surface, raised, glass og outline.
raisedBunntekst - Card (glass)
Installer r/card.jsonKorttittel
Beskrivelse under tittelen.
Kortets innhold. Fire varianter med de samme slotene: surface, raised, glass og outline.
glassBunntekst - Card (outline)
Installer r/card.jsonKorttittel
Beskrivelse under tittelen.
Kortets innhold. Fire varianter med de samme slotene: surface, raised, glass og outline.
outlineBunntekst - Card (interactive)
Installer r/card.json - Card (link)
Installer r/card.json
Skjema
- Field + Input
Installer r/input.jsonValgfrittVi bruker den bare til å svare deg.
- Field (error)
Installer r/field.jsonOrg.nr har ni siffer.
- Field + Textarea
Installer r/textarea.json
Tilbakemelding
- Stat
Installer r/stat.json2Eksempelverdi16Eksempelverdieksempel0Eksempelverdistabilt - Skeleton
Installer r/skeleton.jsonSkeleton skimrer i motion-safe og står stille under redusert bevegelse.
- Marquee
Installer r/marquee.json
Bevegelse
- Reveal
Installer r/motion.json010203Reveal: innholdet finnes i HTML-en, og GSAP animerer det inn når det rulles inn i bildet.
- SplitHeading
Installer r/motion.jsonOverskrift som stiger linje for linje.
- Magnetic
Installer r/motion.json - Parallax
Installer r/motion.jsonParallax: rull forbi meg. - Counter
Installer r/motion.json329Counter teller opp til verdien, som står i HTML-en fra start
Tilgjengelighet
- SkipLink
Installer r/a11y.jsonSkipLink er første tab-stopp på hver side. Trykk Tab her for å se den.
Hopp til innholdet - VisuallyHidden
Installer r/a11y.jsonSynlig tekst – og en usynlig del for skjermlesere.
– og en usynlig del for skjermlesere. - LiveRegion with announce()
Installer r/a11y.jsonLiveRegion og announce() gir skjermlesere beskjed uten å flytte fokus.
Bruk det
Tokens som pakke, komponenter som registry
Designsystemet er laget for å tas i bruk av oss, av kunder og av agenter som skriver kode.
DTCG 2025.10-tokens kompilert til CSS-variabler, Tailwind v4-tema, JSON og TypeScript. Importer stilarkene, sett data-theme, ferdig.
- 1. Pek @hjconsult mot GitHub Packages og installer (tilgang på forespørsel)
npm config set @hjconsult:registry https://npm.pkg.github.com pnpm add @hjconsult/tokens - 2. Importer stilarkene etter Tailwind
@import "tailwindcss"; @import "@hjconsult/tokens/css"; @import "@hjconsult/tokens/theme.css"; @import "@hjconsult/tokens/fluid.css"; - 3. Velg tema og fargeskjema på html-elementet
<html data-theme="nordlys" data-scheme="dark">
Hver komponent kan installeres rett inn i et prosjekt med shadcn CLI. Kilden kopieres til hj/components/…, så du eier koden.
npx shadcn add https://hjconsult.no/r/button.jsonFor agenter
DESIGN.md i tokenpakken beskriver hver token, hver permutasjon og do/don't-lista. /r/registry.json lister alle elementer. Begge er skrevet for å leses av maskiner like mye som av folk.
@hjconsult/tokens/design.md@hjconsult/tokens/json/r/registry.json