# TeeCup — designsystem (referanse)
> Dette dokumentet beskriver det VISUELLE grunnlaget for alt frontend-
> arbeid i TeeCup — fargetoken, typografi, avstand, komponentmønstre og
> tilgjengelighetsregler. Det er en beskrivelse av hva som ER etablert i
> koden (`frontend/app/globals.css`, `frontend/components/ui/*`, og
> mønstrene brukt på tvers av `components/*.tsx`), ikke et nytt forslag —
> hensikten er at både V0-prompter og håndkodet arbeid skal kunne
> forankres i akkurat dette, i stedet for å gjettes på nytt hver gang.
>
> Ufravikelig grunnregel (fra CLAUDE.md, gjelder ALT, eksisterende og
> fremtidig): appen skal være lesbar, forståelig og betjenbar for noen med
> noe redusert syn UTEN briller. God kontrast, stor nok skrift, store nok
> trykkflater, ikke ikon-only uten tekstlabel for viktige handlinger, ikke
> avhengig av finmotorikk/skarpt syn. Enhver visuell beslutning under
> veies mot dette først.
>
> **2026-07-29:** dette dokumentet ble revidert og formalisert basert på
> "alternativ designinstruks.md" (brukerens eget forslag, forsøkt først på
> dashbordet, deretter godkjent som ny fasit). Innholdet under ER derfor nå
> den gjeldende regelen — men er ikke nødvendigvis rullet ut på ALLE
> skjermer ennå (se `CLAUDE.md`-status for hvor langt konsistens-sjekken har
> kommet). Rett opportunistisk opp eldre skjermer mot dette dokumentet når
> de likevel røres, samme mønster som tilgjengelighetsregelen over.
## Merkevare-opprinnelse
Fargeformen/-tonen er hentet fra Teeoff-logoen (samme merkevarefamilie,
egne farger — se ADR-009/ADR-016), IKKE navn eller logo. Basisfargene ble
regnet ut som presise OKLCH-verdier fra de opprinnelige hex-fargene:
- Grønn (primær): `#8bc24a`
- Oransje (sekundær/"brand-orange"): `#ff5722`
Disse to er de ENESTE to kjernefargene i merkevaren. Et forslag om en
tredje ("informasjons"-)farge ble vurdert 2026-07-25 og IKKE besluttet —
se FEATURE_BACKLOG.md. Anbefalingen der var å gjenbruke `--chart-3`
(allerede en blåtone i statistikk-skalaen) fremfor å finne på noe nytt.
## Fargetoken (`frontend/app/globals.css`)
Alle farger er definert som OKLCH-variabler, med egne verdier for lys og
mørk modus (`:root` / `.dark` / `@media (prefers-color-scheme: dark)`,
alle tre holdt i synk). Bruk ALLTID token-navnene under (Tailwind-klasser
som `bg-primary`, `text-muted-foreground` osv.) — aldri rå hex/oklch, og
ALDRI hardkodede Tailwind-fargeklasser som `slate-500`/`gray-100` i ny
kode. Dette er ikke bare en stilregel: hardkodede farger bryter den
automatiske mørk/lys-tema-logikken (se "Lyst og mørkt tema" under), som
ellers virker helt av seg selv så lenge token-klassene brukes.
| Token | Lys modus | Rolle |
|---|---|---|
| `background` / `foreground` | nesten hvit / mørk grå | sideflate / brødtekst |
| `card` / `card-foreground` | hvit / mørk grå | kort, paneler, seksjoner |
| `primary` / `primary-foreground` | `oklch(0.7512 0.1613 130.33)` (grønn) / mørk | hovedhandling, valgt tilstand, "under par"/positiv |
| `secondary` / `secondary-foreground` | lys grå | sekundær vekt, sjeldent brukt alene |
| `muted` / `muted-foreground` | lys grå / dempet | bakgrunnstoner, sekundær tekst/bildetekst |
| `accent` / `accent-foreground` | lys grå | hover-tilstand på nøytrale flater |
| `destructive` | rød-oransje | slett/fare-handlinger |
| `border` / `input` | lys grå | kant på kort, felt, delelinjer |
| `ring` | samme som `primary` | fokus-ring (tastatur-tilgjengelighet) |
| `brand-orange` / `brand-orange-foreground` | `oklch(0.6792 0.2128 36.53)` | sekundærfarge — "over par"/advarsel, IKKE feil (det er `destructive`) |
| `chart-1` … `chart-6` | grønn→blå→gul→oransje→rød-skala | statistikk-/fordelingsvisualiseringer (ADR-033), ALDRI brukt for kategoriske UI-tilstander |
**2026-08-02:** alle nøytrale tokens (`background`/`muted`/`accent`/
`border`/`secondary` m.fl.) hadde tidligere en svak grønn hue (130-145)
iblandet selv når de skulle være "nøytral grå" — dette ga et vedvarende,
utilsiktet grønt skjær på nesten hver bakgrunn, hover-tilstand og kant i
hele appen (brukeren opplevde appen som "stuck i det lysegrønne
utseendet"). Rettet til ekte nøytral grå (`chroma 0`) på tvers av lys/
mørk/media-query-blokkene. `primary` er UENDRET og fortsatt den eneste
tokenen som skal lese som grønn — reservert til valgt/aktiv tilstand og
primærhandling, se semantikk-listen under.
**Farge-semantikk, konsekvent på tvers av hele appen:**
- `primary` (grønn) = valgt/aktiv, positivt resultat (under par, ledende,
bekreftet), primærhandling.
- `brand-orange` = nest viktigst/kontrast-pol i et par (over par, "Poeng"
i noen sammenhenger), IKKE en feilfarge.
- `destructive` = KUN faktiske slette-/fare-handlinger (Slett runde,
fjern spiller), aldri "over par" eller lignende domenetilstand.
- `muted-foreground` = all sekundær/bildetekst-tekst, aldri brødtekstens
hovedfarge.
**Aldri farge alene.** Hver gang farge bærer betydning (over/under par,
leder, valgt/uvalgt), følges den av FORM (sirkel vs. firkant, fylt vs.
bordered), tekst (+N/−N/E, "Deg"/"Eier"), eller et ikon — se
"Golfscore-språket" under. Dette er ikke en stilistisk preferanse, det
er et direkte utslag av tilgjengelighetsregelen øverst.
## Typografi
- **Skrifttype:** Nunito (`next/font/google`, lastet i `app/layout.tsx`,
eksponert som `--font-sans`) — rund, vennlig, god lesbarhet på små
trykkflater. Ingen sekundær/monospace-font i UI-et (tabular-nums
brukes for tallinnretting i stedet for en egen tallfont — se under).
- **Skala** (Tailwind-klasser, brukt konsekvent):
- `text-sm` — bildetekst, sekundær informasjon, knapp-tekst i tette
kontekster
- `text-base` — brødtekst, standard knapp-/felt-tekst, listeelementer
- `text-lg` / `text-xl` — kortoverskrifter, seksjonstitler
- `text-2xl` / `text-3xl` — sideoverskrifter, hull-header, store
resultat-tall
- **Vekt (revidert 2026-07-29):** ved `text-base` (16px) og god kontrast
(`text-foreground`) er `font-normal` helt akseptabelt og FORETRUKKET for
brødtekst — unngår visuell støy av at alt roper likt. Hierarki skapes
primært med STØRRELSE og FARGE (kontrast), ikke bare vekt. `text-sm`
eller mindre (bildetekst/metadata) bør derimot ofte gis `font-medium`
for å kompensere for den mindre størrelsen — aldri `font-normal` under
`text-base`. Overskrifter/tall/primærhandlinger beholder
`font-bold`/`font-extrabold` som før.
- **`tabular-nums` på ALL numerisk visning** (skår, HCP, datoer,
rangeringer) — hindrer tall fra å "hoppe" i bredde når de endres.
- **Golfvis fortegn:** til-par-tall formateres ALLTID som "E" (jevnt med
par), "+N" (over), "−N" — ekte minustegn (U+2212), ALDRI en vanlig
bindestrek eller et bart negativt tall. Samme regel for HCP/
differensial-tall der fortegn er meningsbærende.
## Avstand, hjørner og lag
- **8-punkts rutenett (2026-07-29):** marger, padding og `gap` følger
8-gangen (`p-2`=8px, `p-4`=16px, `p-6`=24px, `p-8`=32px) for
forutsigbar rytme. Halv-steg (`gap-1.5`, `py-2.5` osv.) unngås i nytt
arbeid — brukes kun der et etablert mønster (f.eks. shadcn sine egne
primitiver) allerede definerer det.
- **Kort får tydeligere løft (2026-07-29):** `shadow-md shadow-black/8`
(opp fra `shadow-sm shadow-black/5`) på kort/paneler i lyst tema — mer
synlig separasjon fra bakgrunnen. Se `round-card.tsx`/
`tournament-card.tsx`/`install-prompt.tsx`/`dashboard.tsx` for det
gjeldende mønsteret; eldre skjermer som fortsatt har `shadow-sm
shadow-black/5` bør rettes opp neste gang de røres.
- **Hjørneradius** (fra `--radius: 0.625rem`, skalert opp via
`--radius-sm/md/lg/xl/2xl/3xl/4xl`): `rounded-xl` for felt/knapper i
tette rader, `rounded-2xl` for kort/paneler/knapper med normal vekt,
`rounded-3xl` for store side-nivå-containere (hull-panel, rundekort).
`rounded-full` reservert for sirkulære tilstander (se golfscore-språket)
og pille-formede brytere/merker.
- **Kort/panel-basismønster:** `rounded-2xl` eller `rounded-3xl`, `border
border-border`, `bg-card`, `p-4` (tett) til `p-5 sm:p-6` (romslig), ofte
`shadow-sm shadow-black/5` for lett løft fra bakgrunnen.
- **Sammenhengende lister** (leaderboard, spillerliste): ÉN container
(`rounded-2xl border border-border overflow-hidden`) med
`divide-y divide-border` mellom radene — IKKE separate kort med
mellomrom, det gir en "kort-følelse" som virker mer oppstykket enn
nødvendig når radene i praksis hører sammen (bevisst rettet opp
2026-07-26 på leaderboardet, se CLAUDE.md).
- **Stiplet kant** (`border border-dashed border-border`) markerer en
"legg til"/tom-tilstand-affordance (f.eks. "+ Medspiller"), ALDRI
brukt på innhold som allerede finnes.
## Trykkflater og avstand mellom elementer
- **44px er det ufravikelige gulvet** for enhver trykkbar flate
(`min-h-11` i Tailwind-tall siden 1 enhet = 4px). Primærhandlinger er
ofte enda større: `h-12`–`h-16` for tallvelgere/hovedknapper.
- Runde ikon-only-knapper (lukk, fjern) er minimum `size-11`.
- Gap mellom relaterte kontroller: `gap-2`/`gap-2.5`/`gap-3` normalt,
`gap-4`/`gap-6` mellom distinkte seksjoner.
## Interaksjon (2026-07-29)
- Alle interaktive elementer skal ha en definert `:hover`- OG
`:active`-tilstand — `:active` (f.eks. `active:scale-[0.98]` på kort/
knapper, `active:opacity-70` på lenker/ikon-knapper) gir umiddelbar,
taktil bekreftelse på at trykket faktisk ble registrert. shadcn sin
`Button`-primitiv har allerede `active:translate-y-px` innebygd; egne
håndbygde trykkflater (kort, ``-baserte rader) må legge det til
eksplisitt siden de ikke arver primitivens klasser.
- `disabled` bruker `disabled:opacity-50 disabled:pointer-events-none`
(allerede standard i `Input`/`Button`).
- Bevegelse: `transition-all duration-200 ease-in-out` for state-
endringer på knapper/kort — kjapt og "snappy", ikke en treg nettside-
følelse. Ingen animasjon/fade lenger enn 300ms.
## Skjemaer og inndata (mobil-først)
- Tekst i ``/`