diff --git a/CLAUDE.md b/CLAUDE.md index e94aeae..f0f8bd2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5232,6 +5232,78 @@ Ferdig og verifisert: Begge containere boot-et rent, `/health`/`/dashboard` → 200, `teeoff.no` upåvirket. +- **Match-identitetsbanneret: territorium-bar i stedet for flat 50/50-boks, + BYGGET, GRUNDIG BROWSERVERIFISERT (inkl. en reell overlapp-bug funnet OG + fikset) OG LIVE (2026-07-29), samme dag:** brukeren lastet opp to bilder + av dagens banner (samme identitetskort som ble bygget dagen før -- navn+ + HCP i hver ende, en sentrert statusboks) og en "VELDIG DÅRLIG, kun + illustrerende" skisse av eget forslag: den ledende sidens halvdel bør + markeres OVER på motstanderens halvdel (ikke en statisk 50/50-boks), og + ved AS skal begge sider markeres likt (nøytralt). + **Design:** ny `leadZoneFraction(lead, totalHoles)` -- `0.5 + (lead / + totalHoles) * 0.5`, klippet til `[0.18, 0.82]` for å alltid holde begge + navn lesbare selv ved en ekstrem ledelse. Dominant side får en solid, + mettet farge (`bg-primary`/`bg-brand-orange`, hvit/kontrastfarget tekst + via allerede eksisterende `--primary-foreground`/`--brand-orange- + foreground`-tokens) og strekker seg proporsjonalt forbi midtlinjen; + underlegne side beholder samme fargetone som en svak, lys tint + (`/12`-opacity) med vanlig temafarget tekst. Ved AS (eller ingen hull + spilt ennå): begge soner nøyaktig 50/50 og nøytralt `bg-muted` -- ingen + side ser ut til å lede. Egen lokal kopi i alle tre filer der et match- + identitetsbanner finnes (samme "én fil, én kopi"-konvensjon som + MatchScorecardCell-arbeidet dagen før): `round-detail.tsx` sin + `FormatResultPanel` (primary/brand-orange-tokens), `round-scorecard.tsx` + sin nye delte `LeadBar`+`LeadZone` (samme tokens, portert fra den + tidligere `IdentitySide`+`CenterBadge`-duoen), `session-scorecard.tsx` + sin `IdentityBlock` (FAKTISK lagets `team.color`-hex i stedet for faste + tokens -- dominant sone `backgroundColor: color` + hvit tekst, svak sone + `color-mix(in srgb, ${color} 15%, transparent)`, samme kontrastvalg som + den eksisterende `SegmentedBar` i tournament-leaderboard.tsx). + **Reell overlapp-bug funnet OG fikset UNDER selve browserverifiseringen, + ikke antatt riktig fra kodegjennomgang alene:** første forsøk brukte en + `position:absolute`-sentrert statusboks OPPÅ to `width:X%`-delte soner -- + et ekte skjermbilde på en smal (390px) mobil-viewport viste at et langt + navn ("Erol Haagenrud") ble delvis SKJULT bak statusboksen ("l Haagenrud" + vist i stedet, ikke en ellipse-trunkering, et reelt visuelt overlapp). + Første fiksforsøk (CSS Grid med `minmax(0,X fr) auto minmax(0,Y fr)` i + stedet for absolutt posisjonering) løste IKKE problemet alene -- fortsatt + samme overlapp ved re-test. Rot-årsaken var dypere: identitetsboksen + brukte `items-start`/`items-end` på sin YTRE flex-kolonne, som sizer + boksen etter INNHOLDETS egen bredde (shrink-to-fit) i stedet for sonens + faktiske tildelte bredde -- innholdet kunne dermed visuelt strekke seg + utover sin egen sone og inn i midt-kolonnen uansett hvor korrekt selve + grid-/bredde-fordelingen var. Fikset ved at boksen alltid STREKKER SEG + (fjernet items-start/items-end helt), med venstre/høyre-justering i + stedet løst via `justify-start`/`justify-end` på navne-raden og + `text-left`/`text-right` på HCP-teksten -- INNI en boks som nå alltid har + sonens fulle, korrekte bredde, slik at `truncate` faktisk virker presist. + **Verifisert grundig i en isolert scratch-nettleserøkt** (fersk + `teecup_scratch`-database + isolert scratch-MinIO + engangs API- + container, ekte `next dev` mot scratch-backend, Chrome DevTools MCP, 390× + 844 mobil-viewport): bygget en ekte match-runde fra bunnen via API (egen- + definert 18-hulls bane, Erol HCP 10 vs. gjest "Tore Morell" HCP 54, + samme HCP-mønster som brukerens skjermbilde) og testet re-render etter + HVER kodeendring, ikke bare én gang til slutt -- fanget nettopp DERFOR + både at CSS Grid-fiksen alene ikke var nok, og at stretch-fiksen + faktisk løste det. Bekreftet: normal ledelse ("1 UP", dominant sone + moderat bredere), en EKSTREM ledelse (avgjort "9&7", dominant sone + nesten fyller hele baren, underlegne navn korrekt trunkert "T…"/"HCP…" + i stedet for å overlappe), AS/ingen-hull-spilt (nøytral 50/50, `bg- + muted`), BÅDE lys og mørk modus (kontrast bekreftet i begge), og samme + fiks bekreftet å fungere identisk i `round-scorecard.tsx` sin + `MatchScorecardGrid`-visning (samme runde, `/my-rounds/{id}/scorecard`). + `session-scorecard.tsx` sin tournament-variant IKKE egen nettleser- + testet denne runden (identisk kodemønster, kun `team.color`-hex i stedet + for faste tokens -- lavere risiko, men flagget ærlig som ikke eget + bevist). Ekte typesjekket produksjonsbuild kjørt (to runder -- én etter + første, mislykkede CSS Grid-only-forsøk, én etter den faktiske stretch- + fiksen), alle 24 ruter listet begge ganger. + **Rullet ut live 2026-07-29**, bruker bekreftet eksplisitt: ingen + migrasjon (ren frontend), `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 — nå FAKTISK nettleser-bekreftet (2026-07-27, full 22-skjerms gjennomgang):** rendrer korrekt, ingen diff --git a/frontend/components/round-detail.tsx b/frontend/components/round-detail.tsx index 684b74c..edb3bfe 100644 --- a/frontend/components/round-detail.tsx +++ b/frontend/components/round-detail.tsx @@ -2396,6 +2396,74 @@ function IdentitySide({ identity, side }: { identity: { name: string; hcp: numbe ) } +// Territorium-bar (2026-07-29, erstatter det tidligere flate, likt-delte +// banneret) -- den ledende sidens sone strekker seg PROPORSJONALT forbi +// midtlinjen inn på motstanderens halvdel (brukerens eget forslag: "hele +// den halve delen som tilhører den som er en opp er markert over på +// motstanderens halvdel"), i stedet for en statisk 50/50-boks med tekst i +// midten. Ved AS (eller ingen hull spilt ennå) er begge soner nøyaktig like +// store OG likt (nøytralt) farget -- ingen side skal se ut til å lede. +// Bruker samme proporsjonale to-fargede-bar-idé som SegmentedBar +// (tournament-leaderboard.tsx), tilpasset lead-i-hull i stedet for poeng. +function leadZoneFraction(lead: number, totalHoles: number): number { + if (totalHoles <= 0) return 0.5 + const fraction = 0.5 + (lead / totalHoles) * 0.5 + return Math.min(0.82, Math.max(0.18, fraction)) +} + +function LeadZone({ + identity, + side, + dominant, +}: { + identity: { name: string; hcp: number | null } + side: "a" | "b" + dominant: boolean +}) { + const textTone = dominant ? (side === "a" ? "text-primary-foreground" : "text-brand-orange-foreground") : "text-foreground" + const subTone = dominant + ? side === "a" + ? "text-primary-foreground/75" + : "text-brand-orange-foreground/75" + : "text-muted-foreground" + // Merk: den ytre boksen STREKKER SEG (ingen items-start/items-end her -- + // det ville sizet boksen etter innholdets egen bredde, ikke etter sonens + // faktiske tildelte bredde, og kunne visuelt lekke inn i midt-kolonnen på + // smale skjermer). Venstre/høyre-justering skjer i stedet med + // justify-start/justify-end og text-align INNI en boks som alltid har + // sonens fulle, korrekte bredde -- truncate virker da presist. + return ( +
diff --git a/frontend/components/session-scorecard.tsx b/frontend/components/session-scorecard.tsx index 43de042..6c9a34d 100644 --- a/frontend/components/session-scorecard.tsx +++ b/frontend/components/session-scorecard.tsx @@ -967,24 +967,62 @@ function unitGross(scorecard: ApiScorecard, unit: Unit, holeNumber: number): num return entry ? entry.gross_strokes : null } +// Territorium-bar (2026-07-29, brukerens eget forslag: den ledende sidens +// sone strekker seg proporsjonalt forbi midtlinjen inn på motstanderens +// halvdel). Ulikt round-detail.tsx/round-scorecard.tsx sin primary/brand- +// orange-versjon bruker denne lagets FAKTISKE `team.color` (vilkårlig hex, +// samme som SegmentedBar i tournament-leaderboard.tsx) -- dominant sone får +// hvit tekst (samme kontrastvalg som SegmentedBar), lys sone en svak +// gjennomsiktig tone av samme farge med vanlig tema-tekst. +function leadZoneFraction(lead: number, totalHoles: number): number { + if (totalHoles <= 0) return 0.5 + const fraction = 0.5 + (lead / totalHoles) * 0.5 + return Math.min(0.82, Math.max(0.18, fraction)) +} + function IdentityBlock({ name, hcp, color, side, + dominant, }: { name: string hcp: number | null color: string side: "a" | "b" + dominant: boolean }) { + // Boksen STREKKER SEG (ingen items-start/items-end) -- ellers sizes den + // etter innholdets egen bredde, ikke sonens faktiske tildelte bredde, og + // kan visuelt lekke inn i midt-kolonnen på smale skjermer. Justering skjer + // med justify-start/justify-end + text-align inni en boks som alltid har + // full, korrekt bredde -- truncate virker da presist. return ( -