diff --git a/CLAUDE.md b/CLAUDE.md
index 0a445cd..36844d8 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -19,6 +19,16 @@ Les dette først i hver økt. Det koder hva vi har bestemt og hvordan vi jobber.
turneringsformatene som ennå ikke er designet (Københavner/High-low-high/
Robbins/Try all, se FEATURE_BACKLOG.md), siden disse dokumentene trolig
dekker akkurat de reglene som trengs der.
+- **Design-dokumentasjon, to filer med bevisst motsatt retning (2026-07-27):**
+ `DESIGN_SYSTEM.md` (innsjekket i git) er DESKRIPTIV — hva som faktisk ER i
+ koden i dag (farger/typografi/komponentmønstre/golfscore-språket), avledet
+ direkte fra `globals.css`/`components/ui/*`. `teecup-scorekort-og-entry-
+ spec.md` (lastet opp av brukeren til prosjektroten, IKKE innsjekket i git)
+ er PRESKRIPTIV — hva scorekort-/score-entry-skjermene BØR bli, basert på en
+ sammenligning mot fem etablerte golf-apper. Der de to avviker vinner
+ kildekoden (DESIGN_SYSTEM.md beskriver den), men spec-dokumentets §3
+ "Compliance-pass" er en konkret sjekkliste over kjente avvik — les den FØR
+ videre visuelt arbeid på scorekort-/score-entry-skjermene.
## Sikkerhetsregler (ufravikelige)
- Rør ALDRI `teeoff`-databasen eller den ekte `teecup_db` uten at brukeren
@@ -3495,6 +3505,77 @@ Ferdig og verifisert:
ingen migrasjon, `docker compose up -d --build teecup_frontend`
(gjenskapte også `teecup_api` som vanlig bivirkning). Begge containere
boot-et rent, `/health`/`/dashboard` → 200, `teeoff.no` upåvirket.
+- **`DESIGN_SYSTEM.md` opprettet (2026-07-27):** brukeren ba om en ny fil
+ som viser designsystemet arbeidet tar utgangspunkt i. Skrevet fra bunnen,
+ DESKRIPTIVT (hva som ER i koden, ikke et mål) — grunnet direkte i
+ `globals.css`/`components/ui/*.tsx` og etablerte tvers-fil-mønstre:
+ fargetoken (inkl. OKLCH-opprinnelsen til `primary`/`brand-orange` fra
+ ADR-009/016), typografi, avstand/hjørner/lag (inkl. "én sammenhengende
+ liste med `divide-y`, ikke separate kort"-regelen fra 2026-07-26s
+ leaderboard-fiks), lokale komponentmønstre (NumberPicker/Stepper/
+ ChoiceRow/DirectionCross — bevisst per-fil, ikke delte importer),
+ golfscore-språket (`ScoreMark`/`ToParMark`/`PointsMark`/`HoleMark`),
+ ikonografi, tilbakemelding/tilstander, og navneformat (pekt til CLAUDE.md).
+- **`teecup-scorekort-og-entry-spec.md` lest og evaluert, delvis BYGGET SOM
+ COMPLIANCE-PASS SAMME DAG (2026-07-27):** brukeren lastet opp et
+ PRESKRIPTIVT motstykke til DESIGN_SYSTEM.md (5-app-sammenligning: Golf
+ GameBook/Golf Pad/Golfshot/Hole 19/18Birdies) og spurte om det ga mening
+ og kunne forbedre TeeCup. Vurdert som reelt verdifullt — sylskarpeste nye
+ innsikt: "grønt-på-grønt"-diagnosen (§0.2) forklarer noe av "fortsatt
+ rotete"-følelsen fra v1-v3-rundene bedre enn tetthet alene: `primary`
+ (grønn) var brukt om hverandre for BÅDE "aktiv tilstand" og "generisk
+ fylt/positiv", uten at begge betydde det samme sted. Foreslo (og
+ brukeren bekreftet) å fikse spec-dokumentets §3 "Compliance-pass" FØR den
+ større strukturelle §1-omleggingen (scorekort som grid) vurderes som egen,
+ senere runde.
+ **To av sjekklistens fem punkter var KONKRETE, VERIFISERBARE bugs, bekreftet
+ direkte i koden (ikke antatt fra spec-teksten alene) FØR de ble fikset:**
+ 1. **"Deg Deg"-duplikat:** `playerLabel()` (`round-detail.tsx`) erstattet
+ tidligere selve navnet med "Deg" for viewer-relativ egen rad, OG en
+ separat `Deg` sto ved siden av samme sted (spillerkort,
+ scoringslisten) — bekreftet duplikat, matchet et tidligere skjermbilde
+ brukeren delte. **Fikset:** `playerLabel()` returnerer nå alltid det
+ faktiske `display_name` (aldri "Deg") — Badge-en er nå ENESTE
+ selv-indikator. Dette retter samtidig et videre, ikke tidligere flagget
+ avvik: spec-dokumentet krever eksplisitt "roster-kontekst → fullt navn"
+ for BÅDE scorekort-gridet og score-entry-headeren — veiviserens header/
+ kontekst-rad/"Neste: {navn}"/fullført-banneret viste tidligere "Deg" i
+ stedet for et fullt navn der også, uten noen badge til å disambiguere
+ (reelt forvirrende på en delt telefon som sendes rundt en flight).
+ Det nå overflødige `rawName`-feltet (var identisk med `name` etter
+ fiksen) fjernet, tre kallsteder oppdatert.
+ 2. **Score-knappen fulgte ikke `§Golfscore-språket`:** den store runde
+ knappen i den kompakte scoringslisten (`round-detail.tsx`, bygget i
+ v2-runden) var `rounded-full`+grønn UANSETT om resultatet var under,
+ over eller på par — bogey og eagle så identiske ut. **Fikset:** ny
+ `scoreMarkClasses(diff)`-hjelpefunksjon som gjenbruker EKSAKT samme
+ `primary`/`brand-orange`-fargespråk og fylt-vs-border+10%-tint-omfangs-
+ regel som `ScoreMark` i `round-scorecard.tsx` (bekreftet ved å lese
+ `ScoreMark` sin kildekode direkte, ikke gjettet) — sirkel under par,
+ nøytral sirkel på par, `rounded-2xl` (bevisst mildere enn scorekortets
+ `rounded-[4px]`, for å matche denne skjermens øvrige 56px-trykkflate-
+ avrunding) over par, fylt ved 2+ slag fra par.
+ **Resten av sjekklisten (44px-trykkgulv, `tabular-nums`) auditert
+ systematisk mot AKKURAT denne filen** (samme fil brukerens skjermbilder
+ viste) — 2 manglende `tabular-nums` (HCP/tildelte slag i spillerkortet)
+ og 11 knapper/lenker under 44px (fane-bryteren `min-h-10`→`min-h-11`,
+ `EditRoundPanel`s lukk-ikon `size-8`→`size-11`, feilside-tilbakelenken,
+ og åtte knapper i bane-bytte-/legg-til-medspiller-skjemaene) rettet.
+ **Bevisst UTENFOR omfang denne runden:** spec-dokumentets §1 (scorekort
+ som fullt grid, celle åpner veiviseren) — en STØRRE strukturell endring
+ som fortjener et eget, bevisst ja fra brukeren, ikke bygget stille inn i
+ en "fiks kjente bugs"-runde.
+ **Verifisert:** ekte typesjekket produksjonsbuild (samme `Dockerfile` som
+ deployes) kompilerte rent, alle 24 ruter listet. **Samme ærlige
+ begrensning som ALLE håndkodede runder denne uken:** ingen ekte
+ nettleser-interaksjonstest av det faktiske visuelle resultatet (kun kode-
+ lesing + build-verifisering + bevisst gjenbruk av en allerede lest,
+ eksisterende komponents fargespråk for å holde risikoen lav).
+ **Rullet ut live 2026-07-27**, bruker bekreftet eksplisitt: ingen
+ migrasjon, `docker compose up -d --build teecup_frontend` (gjenskapte
+ også `teecup_api` som vanlig bivirkning, ingen backend-kode rørt). Begge
+ containere boot-et rent, `/health`/`/dashboard` → 200, `teeoff.no`
+ upåvirket.
Neste steg:
0a. **Spillerliste-redesign — LIVE, men ikke nettleser-testet
diff --git a/FEATURE_BACKLOG.md b/FEATURE_BACKLOG.md
index f37a8ca..89b71ec 100644
--- a/FEATURE_BACKLOG.md
+++ b/FEATURE_BACKLOG.md
@@ -1326,6 +1326,18 @@ ARCHITECTURE_DECISIONS.md (ADR-033-oppdatering 2026-07-26), full
verifiserings-/utrullingsdetalj i CLAUDE.md sin statuslogg — ikke
duplisert her.
+**Oppfølging 2026-07-27 — `teecup-scorekort-og-entry-spec.md` (nytt,
+brukeropplastet PRESKRIPTIVT motstykke til `DESIGN_SYSTEM.md`, basert på
+en 5-app-sammenligning) evaluert, §3 "Compliance-pass" delvis BYGGET SAMME
+DAG — ✅ LIVE:** "Deg Deg"-badge-duplikat fjernet (`playerLabel()` viser nå
+alltid ekte navn), scoringslistens score-knapp gjort om til å følge
+`§Golfscore-språket` (gjenbruker `ScoreMark`s fargespråk fra
+`round-scorecard.tsx`), pluss et systematisk `tabular-nums`/44px-
+trykkgulv-avvik-audit fikset (13 steder). Spec-dokumentets §1 (scorekort
+som fullt grid, egen skjerm) bevisst IKKE bygget — større strukturell
+endring, egen fremtidig runde. Full detalj i CLAUDE.md sin statuslogg
+(2026-07-27) — ikke duplisert her.
+
---
## En tredje (informasjons-)farge til designet — 🧠 DRØFTET 2026-07-25, IKKE besluttet
diff --git a/frontend/components/round-detail.tsx b/frontend/components/round-detail.tsx
index 9b70567..dc54e1d 100644
--- a/frontend/components/round-detail.tsx
+++ b/frontend/components/round-detail.tsx
@@ -52,12 +52,10 @@ type PuttBucket = "<1m" | "<2m" | "<3m" | "<5m" | "<8m" | "8m+"
type Player = {
id: string
- // Visningsnavn -- "Deg" for spilleren SOM SER PÅ (viewer-relativt, se
- // playerLabel()), IKKE nødvendigvis den faktiske display_name.
+ // Alltid den faktiske display_name (2026-07-27: fjernet "Deg"-erstatning
+ // her -- se playerLabel() -- brøt "roster-kontekst → fullt navn" og ga en
+ // "Deg Deg"-duplikat der en egen Badge også viste "Deg" ved siden av).
name: string
- // Den faktiske, urørte display_name -- ALDRI "Deg". Brukt til å
- // forhåndsutfylle "Rediger"-flytens navnefelt for en gjest (2026-07-26).
- rawName: string
userId: string | null
guestEmail: string | null
isOwner: boolean
@@ -264,11 +262,17 @@ function statToPatchBody(s: HoleStat) {
}
}
-// Viewer-relativt (ADR-036 fase 3-utvidelsen, 2026-07-26): "Deg" skal vises
-// for DEN SOM SER PÅ, ikke alltid runde-eieren -- en lenket medspiller som
-// åpner runden skal se seg selv som "Deg" og eieren under sitt eget navn.
-function playerLabel(p: ApiParticipant, viewerId: string | null): string {
- return viewerId !== null && p.user_id === viewerId ? "Deg" : p.display_name
+// Alltid det faktiske visningsnavnet -- ALDRI "Deg" (2026-07-27, compliance-
+// pass mot teecup-scorekort-og-entry-spec.md). "Deg" var tidligere en
+// viewer-relativ erstatning for selve navnet, men det produserte en ekte
+// "Deg Deg"-duplikat der navnet OGSÅ sto ved siden av en egen "Deg"-badge
+// (spillerkort, scoringslisten) -- og brøt spesifikasjonens eksplisitte
+// "roster-kontekst → fullt navn"-regel i skjermer uten noen badge i det
+// hele tatt (veiviserens header/kontekst-rad, "Neste: {navn}", fullført-
+// banneret). `isSelf` (se players-konstruksjonen under) er fortsatt
+// viewer-relativ og brukes alene til å vise "Deg"-badgen der det trengs.
+function playerLabel(p: ApiParticipant): string {
+ return p.display_name
}
// --- Component -------------------------------------------------------------
@@ -414,8 +418,7 @@ export function RoundDetail({ roundId }: { roundId: string }) {
const players: Player[] =
round?.participants.map((p) => ({
id: p.id,
- name: playerLabel(p, viewerId),
- rawName: p.display_name,
+ name: playerLabel(p),
userId: p.user_id,
guestEmail: p.guest_email,
isOwner: p.is_owner,
@@ -651,7 +654,10 @@ export function RoundDetail({ roundId }: { roundId: string }) {
return (
@@ -2684,6 +2697,26 @@ function golfTermForScore(n: number, par: number): string | null {
return null
}
+// Golfscore-språket (§Golfscore-språket i DESIGN_SYSTEM.md, håndhevet
+// eksplisitt av teecup-scorekort-og-entry-spec.md §0.3/§3): form encoder
+// retning (sirkel = under par, "firkant" = over par) slik at betydningen
+// overlever selv uten farge; fylt vs. border+10%-tint encoder omfang (fylt =
+// 2 slag eller mer fra par). Samme klassifisering som `ScoreMark` i
+// round-scorecard.tsx -- egen kopi her siden denne knappen (size-14,
+// trykkbar) trenger andre grunnklasser enn scorekortets små tabell-merker,
+// men SAMME fargespråk (2026-07-27, compliance-pass). Bevisst `rounded-2xl`
+// for "over par" i stedet for scorekortets `rounded-[4px]` -- fortsatt
+// tydelig IKKE en sirkel, men matcher denne skjermens øvrige store
+// trykkflate-avrunding (NumberPicker/hull-panel bruker samme radius).
+function scoreMarkClasses(diff: number | null): string {
+ if (diff === null) return "rounded-full border-dashed border-border text-muted-foreground hover:border-primary/60 hover:text-primary"
+ if (diff <= -2) return "rounded-full border-primary bg-primary text-primary-foreground"
+ if (diff === -1) return "rounded-full border-primary bg-primary/10 text-primary"
+ if (diff === 0) return "rounded-full border-border bg-card text-foreground"
+ if (diff === 1) return "rounded-2xl border-brand-orange bg-brand-orange/10 text-brand-orange"
+ return "rounded-2xl border-brand-orange bg-brand-orange text-brand-orange-foreground"
+}
+
function NumberPicker({
label,
value,