npm package: @skagerakenergi/skagerak-design-components
Description: Statkraft design tokens + BeerCSS theme bridge with Designsystemet coexistence via CSS layers
Latest version: 0.1.3

# `@skagerakenergi/skagerak-design-components`

> Delt temapakke som kobler **Designsystemet** og **BeerCSS** til én samlet, Skagerak-brandet visuell profil.

---

## Innholdsfortegnelse

1. [Konsept og arkitektur](#1-konsept-og-arkitektur)
2. [Tilgjengelige temaer](#2-tilgjengelige-temaer)
3. [Hurtigstart](#3-hurtigstart)
4. [Detaljert oppsett — steg for steg](#4-detaljert-oppsett--steg-for-steg)
   - [4.1 Installer pakken](#41-installer-pakken)
   - [4.2 `index.html` — BeerCSS via CDN med lag-isolasjon](#42-indexhtml--beercss-via-cdn-med-lag-isolasjon)
   - [4.3 `main.ts` — importer stiler og web-komponenter](#43-maints--importer-stiler-og-web-komponenter)
   - [4.4 TypeScript-typer](#44-typescript-typer)
   - [4.5 `App.vue` / rotkomponent — tema-initialisering](#45-appvue--rotkomponent--tema-initialisering)
5. [Mørk modus og temabytte under kjøring](#5-mørk-modus-og-temabytte-under-kjøring)
6. [Enkel modus — ett tema, ingen bytte](#6-enkel-modus--ett-tema-ingen-bytte)
7. [Eksponerte API-er](#7-eksponerte-api-er)
8. [Pakkestruktur](#8-pakkestruktur)
9. [CSS-lag og prioritetsrekkefølge](#9-css-lag-og-prioritetsrekkefølge)
10. [Hvordan fargemapping fungerer](#10-hvordan-fargemapping-fungerer)
11. [Legge til et nytt tema](#11-legge-til-et-nytt-tema)
12. [Feilsøking](#12-feilsøking)
13. [Ekstern dokumentasjon](#13-ekstern-dokumentasjon)

---

## 1. Konsept og arkitektur

Pakken løser ett konkret problem: **BeerCSS og Designsystemet bruker begge globale CSS-variabler og stilregler som ellers ville overskrevet hverandre.**

Løsningen er tredelt:

```
┌─────────────────────────────────────────────────┐
│  @layer beercss          (lavest prioritet)      │
│  BeerCSS – layout, spacing, Material Design 3   │
├─────────────────────────────────────────────────┤
│  @layer ds.*             (mellomprioritet)       │
│  Designsystemet – tokens, komponentstiler        │
├─────────────────────────────────────────────────┤
│  (ikke-lagdelte regler)  (høyest prioritet)      │
│  App-spesifikke overstyringer                    │
└─────────────────────────────────────────────────┘
```

**Temabrobygging:** Token-CSS-filene fra Designsystemet (f.eks. `statkraft-blue.css`) tolkes ved byggetid. Fargene leses ut og oversettes til BeerCSS sine egne CSS-variabler via `ui('theme', …)`. Dermed styres **begge** rammeverk fra én enkelt kilde til sannhet.

**Kjøretidsbytte:** `swapDsTokens()` bytter ut `<link>`-elementet i `<head>` med en ny tokenfil. `syncDsColorScheme()` setter `data-color-scheme`-attributtet på `<body>`. BeerCSS sin `ui('mode', …)` og `ui('theme', …)` håndterer resten.

---

## 2. Tilgjengelige temaer

| ID                  | Label             | Primærfarge |
| ------------------- | ----------------- | ----------- |
| `statkraft-blue`    | Statkraft Blue    | `#00B0DC`   |
| `statkraft-blue-15` | Statkraft Blue 15 | `#DAF4FC`   |
| `statkraft-blue-50` | Statkraft Blue 50 | `#80DAF3`   |

---

## 3. Hurtigstart

> Forutsetter Vite + Vue 3 + pnpm. Tilpass etter behov for andre rammeverk.

**1. Installer:**

```bash
pnpm add @skagerakenergi/skagerak-design-components
```

**2. `index.html`:**

```html
<head>
  <!-- Lag-deklarasjon — MÅ komme først -->
  <style>
    @layer beercss;
  </style>

  <!-- BeerCSS CSS via CDN, låst til laget -->
  <style>
    @import url('https://cdn.jsdelivr.net/npm/beercss@4.0.16/dist/cdn/beer.min.css') layer(beercss);
  </style>

  <!-- BeerCSS JS + Material Dynamic Colors (kreves av ui('theme')) -->
  <script
    type="module"
    src="https://cdn.jsdelivr.net/npm/beercss@4.0.16/dist/cdn/beer.min.js"
  ></script>
  <script
    type="module"
    src="https://cdn.jsdelivr.net/npm/material-dynamic-colors@1.1.4/dist/cdn/material-dynamic-colors.min.js"
  ></script>
</head>
```

**3. `main.ts`:**

```ts
import '@skagerakenergi/skagerak-design-components/styles'
import '@skagerakenergi/skagerak-design-components/web-components'
```

**4. `App.vue` (rotkomponent):**

```ts
import {
  defaultThemeVariant,
  themeById,
  themeVariants,
  swapDsTokens,
  syncDsColorScheme,
  type ThemeVariantId
} from '@skagerakenergi/skagerak-design-components'

onMounted(async () => {
  syncDsColorScheme('light')
  swapDsTokens('statkraft-blue')
  await ui('mode', 'light')
  await ui('theme', themeById['statkraft-blue'])
})
```

---

## 4. Detaljert oppsett — steg for steg

### 4.1 Installer pakken

```bash
# I roten av monorepoet (eller i app-mappen)
pnpm add @skagerakenergi/skagerak-design-components
```

Pakken er `private: true` og leveres kildekode-first (ingen separat byggsteg). Vite i konsumerende app kompilerer TypeScript direkte fra `src/`.

---

### 4.2 `index.html` — BeerCSS via CDN med lag-isolasjon

BeerCSS lastes **ikke** via npm-import — den lastes fra CDN direkte i HTML. Dette er nødvendig for at `@layer`-deklarasjonen skal fungere korrekt.

```html
<!doctype html>
<html lang="no">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Min app</title>

    <!--
      Trinn 1: Deklarer lag-rekkefølgen.
      Denne <style>-blokken MÅ stå FØR alle andre stilark.
      Nettlesere bruker rekkefølgen her til å avgjøre prioritet
      når det oppstår konflikter mellom lag.
    -->
    <style>
      @layer beercss;
    </style>

    <!--
      Trinn 2: Last inn BeerCSS CSS og plasser den i laget.
      Nettlesere som ikke støtter @import layer() vil falle tilbake
      til standard oppførsel (lite sannsynlig i 2026).
    -->
    <style>
      @import url('https://cdn.jsdelivr.net/npm/beercss@4.0.16/dist/cdn/beer.min.css')
      layer(beercss);
    </style>

    <!--
      Trinn 3: BeerCSS JavaScript — nødvendig for ui()-funksjonen.
      Material Dynamic Colors — nødvendig for dynamisk tema-generering.
      Begge lastes som ES-moduler for ikke å blokkere parsing.
    -->
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/beercss@4.0.16/dist/cdn/beer.min.js"
    ></script>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/material-dynamic-colors@1.1.4/dist/cdn/material-dynamic-colors.min.js"
    ></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
```

> **Viktig:** Ikke importer `beercss` via `import 'beercss'` i TypeScript/JavaScript — da mister du lag-isolasjonen og Designsystemet vil bli overstyrt.

---

### 4.3 `main.ts` — importer stiler og web-komponenter

```ts
// Designsystemet CSS (bruker @layer ds.* internt — vinner over @layer beercss)
import '@skagerakenergi/skagerak-design-components/styles'

// Registrerer alle Designsystemet web-komponenter (<ds-button>, <ds-field>, osv.)
import '@skagerakenergi/skagerak-design-components/web-components'

// Din app-kode som vanlig...
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
// ...
app.mount('#app')
```

**Rekkefølge er viktig:** Stilimporter må komme før app-montering for at CSS-lagene skal være registrert i korrekt rekkefølge.

---

### 4.4 TypeScript-typer

For at TypeScript skal kjenne til Designsystemet sine web-komponent-typer (f.eks. `<ds-button>` i Vue-templates), legg til i `tsconfig.json` eller `tsconfig.app.json`:

```jsonc
{
  "compilerOptions": {
    "types": ["@skagerakenergi/skagerak-design-components/globals"]
  }
}
```

Dette tilsvarer å referere til `@digdir/designsystemet-web`, `@digdir/designsystemet-types` og `@digdir/designsystemet-css/theme` direkte — pakket i ett sted.

---

### 4.5 `App.vue` / rotkomponent — tema-initialisering

Dette er det fullstendige mønsteret brukt i `customerportal_beerless`. Kopier og tilpass:

```vue
<script setup lang="ts">
  import { ref, onMounted, watch, provide } from 'vue'
  import {
    defaultThemeVariant,
    themeById,
    themeVariants,
    swapDsTokens,
    syncDsColorScheme,
    type ThemeVariantId
  } from '@skagerakenergi/skagerak-design-components'

  // BeerCSS sin ui()-funksjon er global (lastet via CDN-script i index.html)
  declare global {
    function ui(type: 'mode', value?: 'light' | 'dark' | 'auto'): Promise<string>
    function ui(
      type: 'theme',
      value?: { light: string; dark: string }
    ): Promise<{ light: string; dark: string }>
  }

  const themeMode = ref<'light' | 'dark'>('light')
  const themeVariant = ref<ThemeVariantId>(defaultThemeVariant)

  // Gjør tilgjengelig for underkomponenter via provide/inject
  provide('themeVariants', themeVariants)
  provide('themeVariant', themeVariant)
  provide('themeMode', themeMode)

  onMounted(async () => {
    // Les lagrede preferanser fra localStorage
    const savedMode = localStorage.getItem('themeMode')
    const savedVariant = localStorage.getItem('themeVariant') as ThemeVariantId | null

    // Sett modus: lagret verdi → system-preferanse → 'light'
    themeMode.value =
      savedMode === 'light' || savedMode === 'dark'
        ? savedMode
        : globalThis.matchMedia('(prefers-color-scheme: dark)').matches
          ? 'dark'
          : 'light'

    // Sett variant: lagret verdi → standard
    if (savedVariant && savedVariant in themeById) {
      themeVariant.value = savedVariant
    }

    // Synkroniser begge rammeverk i parallell
    syncDsColorScheme(themeMode.value) // setter data-color-scheme på <body>
    swapDsTokens(themeVariant.value) // setter inn riktig token-CSS i <head>

    await Promise.allSettled([
      ui('mode', themeMode.value), // BeerCSS lys/mørk modus
      ui('theme', themeById[themeVariant.value]) // BeerCSS fargepalett
    ])
  })

  // Reagér på modus-bytte (f.eks. fra en toggle-knapp)
  watch(themeMode, (newMode) => {
    syncDsColorScheme(newMode)
    ui('mode', newMode)
    localStorage.setItem('themeMode', newMode)
  })

  // Reagér på tema-bytte (f.eks. fra en tema-velger)
  watch(themeVariant, (newVariant) => {
    swapDsTokens(newVariant)
    ui('theme', themeById[newVariant])
    localStorage.setItem('themeVariant', newVariant)
  })
</script>

<template>
  <!-- body-elementet: BeerCSS bruker data-bs-theme, vi setter data-color-scheme via syncDsColorScheme -->
  <RouterView />
</template>
```

---

## 5. Mørk modus og temabytte under kjøring

Tre ting må skje **synkront** ved et modus- eller temabytte:

| Hva                        | Funksjon / metode                          | Påvirker                                  |
| -------------------------- | ------------------------------------------ | ----------------------------------------- |
| Designsystemet fargetokens | `syncDsColorScheme('dark' \| 'light')`     | `data-color-scheme`-attributt på `<body>` |
| Designsystemet tokenfil    | `swapDsTokens('statkraft-blue')`           | `<link data-ds-tokens>` i `<head>`        |
| BeerCSS modus              | `ui('mode', 'dark')`                       | BeerCSS CSS-variabler                     |
| BeerCSS fargepalett        | `ui('theme', themeById['statkraft-blue'])` | BeerCSS farge-tokens                      |

Eksempel på en tema-toggle-knapp:

```vue
<script setup lang="ts">
  import { inject, type Ref } from 'vue'
  import {
    themeById,
    swapDsTokens,
    syncDsColorScheme,
    type ThemeVariantId
  } from '@skagerakenergi/skagerak-design-components'

  const themeMode = inject<Ref<'light' | 'dark'>>('themeMode')!
  const themeVariant = inject<Ref<ThemeVariantId>>('themeVariant')!

  function toggleMode() {
    themeMode.value = themeMode.value === 'light' ? 'dark' : 'light'
    // watch i App.vue tar seg av resten
  }
</script>

<template>
  <button @click="toggleMode">
    {{ themeMode === 'dark' ? '☀️ Lys' : '🌙 Mørk' }}
  </button>
</template>
```

---

## 6. Bruksmønstre — hva trenger du?

### Hva gjør `ui()` egentlig?

Det er viktig å skille mellom de to BeerCSS-kallene:

| Kall                           | Hva det gjør                                                         | Nødvendig for Statkraft-farger?                                       |
| ------------------------------ | -------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `ui('mode', 'dark')`           | Setter `class="dark"` på `<body>` — BeerCSS sin egen lys/mørk-toggle | Nei — bare for BeerCSS sin mørk modus                                 |
| `ui('theme', { light, dark })` | Overskriver BeerCSS sine CSS-fargevariabler med Skagerak-tokens      | **Ja** — uten dette bruker BeerCSS standard lilla Material You-palett |

`ui('mode')` og `ui('theme')` er **helt uavhengige** av hverandre. Du kan bruke én uten den andre.

---

### Mønster A — Bare lys/mørk-bytte, ingen Skagerak-merkevare på BeerCSS

Bruk dette hvis du kun bruker BeerCSS til layout og ikke bryr deg om at BeerCSS-elementer får standard lilla farger.

```ts
// main.ts
import '@skagerakenergi/skagerak-design-components/styles'
import '@skagerakenergi/skagerak-design-components/tokens/statkraft-blue' // Designsystemet-tokens
import '@skagerakenergi/skagerak-design-components/web-components'
```

```vue
<!-- App.vue -->
<script setup lang="ts">
  import { ref, onMounted, watch } from 'vue'
  import { syncDsColorScheme } from '@skagerakenergi/skagerak-design-components'

  const isDark = ref(false)

  onMounted(() => {
    isDark.value = matchMedia('(prefers-color-scheme: dark)').matches
    syncDsColorScheme(isDark.value ? 'dark' : 'light')
    // BeerCSS: ui('mode') setter bare class="dark" på <body> — det gjør vi manuelt:
    document.body.classList.toggle('dark', isDark.value)
  })

  watch(isDark, (dark) => {
    syncDsColorScheme(dark ? 'dark' : 'light')
    document.body.classList.toggle('dark', dark)
    localStorage.setItem('themeMode', dark ? 'dark' : 'light')
  })
</script>
```

> **Merk:** `ui('mode', 'dark')` er bare en snarvei for `document.body.classList.add('dark')`. Du kan kalle `ui('mode', …)` i stedet om du foretrekker det — resultatet er identisk.

---

### Mønster B — Fast Skagerak-tema + lys/mørk-bytte (anbefalt)

Ett fast tema, ingen variant-switching. BeerCSS får Skagerak-farger. Mørk modus fungerer for begge rammeverk.

```ts
// main.ts
import '@skagerakenergi/skagerak-design-components/styles'
import '@skagerakenergi/skagerak-design-components/web-components'
// Ikke importer tokenfil statisk her — swapDsTokens() setter den inn dynamisk
```

```vue
<!-- App.vue -->
<script setup lang="ts">
  import { ref, onMounted, watch } from 'vue'
  import { themeById, swapDsTokens, syncDsColorScheme } from '@skagerakenergi/skagerak-design-components'

  const themeMode = ref<'light' | 'dark'>('light')

  onMounted(async () => {
    const saved = localStorage.getItem('themeMode')
    themeMode.value =
      saved === 'dark'
        ? 'dark'
        : saved === 'light'
          ? 'light'
          : matchMedia('(prefers-color-scheme: dark)').matches
            ? 'dark'
            : 'light'

    syncDsColorScheme(themeMode.value)
    swapDsTokens('statkraft-blue')

    await Promise.allSettled([
      ui('mode', themeMode.value),
      ui('theme', themeById['statkraft-blue']) // én gang — ikke byttet ut senere
    ])
  })

  watch(themeMode, (mode) => {
    syncDsColorScheme(mode)
    ui('mode', mode) // BeerCSS: kun class-toggle på <body>
    localStorage.setItem('themeMode', mode)
    // ui('theme') kalles IKKE her — fargepaletten er allerede satt og endres ikke
  })
</script>
```

---

### Mønster C — Fullt tema- og mørk-modus-bytte

Se [seksjon 4.5](#45-appvue--rotkomponent--tema-initialisering) for komplett eksempel med variant-switching og `provide/inject`.

---

## 7. Eksponerte API-er

### Typer

```ts
type ThemeVariantId = 'statkraft-blue' | 'statkraft-blue-15' | 'statkraft-blue-50'

interface BeerTheme {
  light: string // BeerCSS-temastreng for lys modus
  dark: string // BeerCSS-temastreng for mørk modus
}

interface ThemeVariant {
  id: ThemeVariantId
  label: string // Visningsnavn, f.eks. "Statkraft Blue"
  previewColor: string // Hex-farge for forhåndsvisning
  theme: BeerTheme
}
```

### Konstanter

```ts
import {
  themeVariants, // ThemeVariant[]  — alle varianter, f.eks. for en dropdown
  themeById, // Record<ThemeVariantId, BeerTheme> — rask oppslag
  defaultThemeVariant // ThemeVariantId  — 'statkraft-blue'
} from '@skagerakenergi/skagerak-design-components'
```

### Funksjoner

```ts
import { swapDsTokens, syncDsColorScheme } from '@skagerakenergi/skagerak-design-components'

// Bytter Designsystemet token-stilark i <head>
// Kall denne når brukeren velger et annet tema
swapDsTokens('statkraft-blue-50')

// Setter data-color-scheme="dark|light" på <body>
// Kall denne når brukeren bytter mellom lys og mørk modus
syncDsColorScheme('dark')
```

### CSS-eksporter (statisk import)

```ts
'@skagerakenergi/skagerak-design-components/styles' // Designsystemet CSS
'@skagerakenergi/skagerak-design-components/tokens/statkraft-blue' // Token-CSS: blå
'@skagerakenergi/skagerak-design-components/tokens/statkraft-blue-15' // Token-CSS: blå 15 %
'@skagerakenergi/skagerak-design-components/tokens/statkraft-blue-50' // Token-CSS: blå 50 %
'@skagerakenergi/skagerak-design-components/web-components' // Designsystemet web-komponenter
```

---

## 8. Pakkestruktur

```
packages/skagerak-design-components/
├── package.json
├── tsconfig.json
└── src/
    ├── index.ts                    ← Hoved-API: typer, konstanter, funksjoner
    ├── styles.css                  ← Re-eksporterer @digdir/designsystemet-css
    ├── web-components.ts           ← Registrerer alle ds-* web-komponenter
    ├── globals.d.ts                ← TypeScript-referanser for ds-typer
    ├── env.d.ts                    ← Vite ?raw / ?url -støtte
    ├── head.html                   ← Kopi-paste-mal for index.html <head>
    ├── designsystemet.config.json  ← Token-generatorkonfig (@digdir/designsystemet CLI)
    ├── design-tokens/              ← Kilde-tokens generert av Designsystemet CLI
    └── design-tokens-build/        ← Bygde token-CSS-filer (script-generert, ikke rediger)
        ├── statkraft-blue.css      ← Statkraft Blue (fullt tema)
        ├── statkraft-blue-15.css   ← Statkraft Blue 15 %
        ├── statkraft-blue-50.css   ← Statkraft Blue 50 %
        ├── colors.d.ts             ← Fargetoken TypeScript-typer (deprecated, bruk types.d.ts)
        └── types.d.ts              ← CSS-modul TypeScript-typer
```

---

## 9. CSS-lag og prioritetsrekkefølge

CSS Cascade Layers (`@layer`) er kjernen i isolasjonsstrategien. Nettleseren behandler lag i **deklarert rekkefølge** — lag deklarert **sist** vinner.

```
@layer beercss;    ← deklarert i <style> i index.html (lavest)
@layer ds.theme.*; ← kommer fra statkraft-blue.css (vinner over beercss)
@layer ds.*;       ← kommer fra @digdir/designsystemet-css (vinner over ds.theme.*)
(ingen lag)        ← app-egne stiler vinner alltid
```

Fordi `@layer beercss` er deklarert **uten innhold** som den første `@layer`-setningen, vil alle andre lag (inkludert Designsystemets `ds.*`) automatisk ha høyere prioritet — uavhengig av rekkefølgen stilarkene lastes inn.

---

## 10. Hvordan fargemapping fungerer

Ved byggetid leser `index.ts` de bygde token-CSS-filene som rå tekst (`?raw`). CSS-parseren trekker ut alle `--ds-*`-variabler fra `:root`-blokken (lys modus) og `[data-color-scheme="dark"]`-blokken (mørk modus), og oversetter dem til BeerCSS-variabler via denne tabellen:

| BeerCSS-variabel      | Designsystemet-kilde                      |
| --------------------- | ----------------------------------------- |
| `--primary`           | `--ds-color-accent-base-default`          |
| `--on-primary`        | `--ds-color-accent-base-contrast-default` |
| `--primary-container` | `--ds-color-accent-surface-tinted`        |
| `--secondary`         | `--ds-color-dark-blue-base-default`       |
| `--background`        | `--ds-color-neutral-background-default`   |
| `--surface`           | `--ds-color-neutral-surface-default`      |
| `--outline`           | `--ds-color-neutral-border-default`       |
| `--error`             | `--ds-color-orange-red-base-default`      |
| ... (se `index.ts`)   | ...                                       |

Resultatet er to strenger — én for lys og én for mørk modus — som sendes direkte til `ui('theme', { light, dark })`.

---

## 11. Legge til et nytt tema

1. **Legg til tema i `src/designsystemet.config.json`** og kjør Designsystemets CLI for å generere tokenfiler i `src/design-tokens/`. Deretter kjør build-skriptet som kompilerer til `src/design-tokens-build/mitt-nye-tema.css`.

2. **Legg til import** i `src/index.ts`:

   ```ts
   import mittNyeTema from './design-tokens-build/mitt-nye-tema.css?raw'
   ```

3. **Utvid `ThemeVariantId`**:

   ```ts
   export type ThemeVariantId =
     | 'statkraft-blue'
     | 'statkraft-blue-15'
     | 'statkraft-blue-50'
     | 'mitt-nye-tema'
   ```

4. **Bygg tema og legg til i arrays**:

   ```ts
   const mittNyeTemaTheme = buildTheme(mittNyeTema)

   export const themeVariants: ThemeVariant[] = [
     // ...eksisterende
     {
       id: 'mitt-nye-tema',
       label: 'Mitt Nye Tema',
       previewColor: '#AABBCC',
       theme: mittNyeTemaTheme
     }
   ]

   export const themeById: Record<ThemeVariantId, BeerTheme> = {
     // ...eksisterende
     'mitt-nye-tema': mittNyeTemaTheme
   }
   ```

5. **Eksporter CSS-fil** i `package.json`:
   ```json
   "./tokens/mitt-nye-tema": "./src/design-tokens-build/mitt-nye-tema.css"
   ```

---

## 12. Feilsøking

### `The stylesheet .../undefined was not loaded because its MIME type is "text/html"`

`swapDsTokens()` fant ikke URL-en for varianten. Årsak: `import.meta.glob`-banen i `index.ts` samsvarer ikke med filplasseringen.

**Sjekk:** At alle `.css`-filer faktisk ligger i `src/design-tokens-build/` og at glob-mønsteret er `'./design-tokens-build/statkraft-*.css'`.

---

### `[postcss] ENOENT: no such file or directory, open 'beercss'`

Du har en `@import 'beercss'` i en `.css`-fil. Fjern den — BeerCSS skal kun lastes via CDN `<link>` i `index.html`.

---

### BeerCSS viser fremdeles standard lilla/blå farger

`ui('theme', …)` er ikke kalt, eller ble kalt **før** BeerCSS-scriptet var ferdig lastet fra CDN.

- `ui('theme', …)` **må** kalles for at BeerCSS skal bruke Skagerak-farger. Uten det bruker BeerCSS sin innebygde lilla Material You-palett.
- Kall `ui('theme', …)` i `onMounted()` (ikke øverst i `<script setup>`).
- Bruk `await Promise.allSettled([ui('mode', …), ui('theme', …)])` for å vente på begge.

---

### Designsystemet bytter ikke farge ved mørk/lys-toggle

To ting må skje:

1. `syncDsColorScheme('dark')` — setter `data-color-scheme`-attributtet på `<body>`.
2. Den riktige tokenfilen må være lastet (gjøres av `swapDsTokens()`).

Sjekk i devtools at `<body data-color-scheme="dark">` er satt, og at `<link data-ds-tokens="...">` finnes i `<head>`.

---

### TypeScript klager på `<ds-button>` og andre web-komponenter

Legg til i `tsconfig.json`:

```jsonc
{
  "compilerOptions": {
    "types": ["@skagerakenergi/skagerak-design-components/globals"]
  }
}
```

---

### `ui is not defined`

BeerCSS JavaScript-scriptet er ikke lastet. Kontroller at disse to linjene finnes i `index.html` **før** `<script type="module" src="/src/main.ts">`:

```html
<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/beercss@4.0.16/dist/cdn/beer.min.js"
></script>
<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/material-dynamic-colors@1.1.4/dist/cdn/material-dynamic-colors.min.js"
></script>
```

---

## 13. Ekstern dokumentasjon

| Ressurs                                            | URL                                                                                               |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Designsystemet** — oppsett og komponenter        | https://designsystemet.no/no/fundamentals/code/setup                                              |
| **Designsystemet** — fargesystem og tokens         | https://designsystemet.no/no/fundamentals/design/colors                                           |
| **Designsystemet** — GitHub                        | https://github.com/digdir/designsystemet                                                          |
| **BeerCSS** — hjemmeside og komponent-eksempler    | https://www.beercss.com                                                                           |
| **BeerCSS** — innstillinger / `ui()`-dokumentasjon | https://github.com/beercss/beercss/blob/main/docs/SETTINGS.md                                     |
| **BeerCSS** — elementer                            | https://github.com/beercss/beercss/blob/main/docs/ELEMENTS.md                                     |
| **BeerCSS** — hjelpere                             | https://github.com/beercss/beercss/blob/main/docs/HELPERS.md                                      |
| **BeerCSS** — CDN (jsDelivr)                       | https://cdn.jsdelivr.net/npm/beercss@4.0.16/dist/cdn/                                             |
| **CSS Cascade Layers** — MDN                       | https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Cascade_layers |