feat: Digital Jass Scoreboard (Schiefertafel Z/Z)#7
Conversation
Co-authored-by: LFDave <36726874+LFDave@users.noreply.github.com>
|
@copilot check the above comment |
Co-authored-by: LFDave <36726874+LFDave@users.noreply.github.com>
|
Done in commit f597677. The board now has two full Z shapes — one per player — stacked vertically. The top panel shows Team A's Z (team name → two horizontal red chalk lines with diagonal → total). The bottom panel shows Team B's Z rotated 180° so it's readable from the opposite side of the table. |
|
@copilot try svg and ensure top bar dashes count as 100, diagonal bar dashes as 50, bottom bar as 20 SVG Coordinate Geometry (The "Z" Blueprint) |
Co-authored-by: LFDave <36726874+LFDave@users.noreply.github.com>
Done in commit 5c01474. Each Z panel is now a proper inline SVG with three structural lines:
Tick marks are rendered as chalk-white vertical lines crossing through their respective bar line. The input system is redesigned to match: team toggle buttons (A/B) + three mark buttons (+100 Oben / +50 Diagonal / +20 Unten) — one tap to record a mark directly on the correct line. |



Adds a browser-based Swiss Jass slate scoreboard as a new static app under
jass-scoreboard/. Pure HTML/CSS/Vanilla JS (ES6 modules) — no frameworks.Architecture
Responsibility-separated module structure:
state.jsstorage.jslocalStoragepersistence (jassScoreboardState)scoring.jsrenderer.jsui.jsapp.jsKey behaviours
SVG Z marks on lines — each team's score panel is a full inline SVG Z shape. Chalk-white tick marks are rendered directly ON the structural lines of the Z, with fixed denominations matching the physical Jasstafel convention:
Mark-based input — score entry uses team toggle buttons (A / B) and three mark buttons (+100 Oben / +50 Diagonal / +20 Unten); one tap records a mark on the correct line. The entry model stores
{teamId, barType, value, timestamp}.Win condition —
total > targetScore(must exceed, not merely reach); disables score entry, undo/reset remain activeBoard layout — two full Z shapes stacked vertically, one per player; the bottom panel is rotated 180° so the opposing player can read their score from across the table. The ↕ swap button exchanges which team's data appears in the top vs. bottom Z without altering the data model.
Persistence — full state (entries, teams, target, flip, winner) saved on every mutation, restored on load. Legacy entries (old
pointsfield) are handled gracefully on restore.Screenshots
Scoreboard — SVG Z marks on lines, one Z per player:

Win overlay with chalk particle animation:

Original prompt
This section details on the original issue you should resolve
<issue_title>jasstafel application</issue_title>
<issue_description>Product Requirements Document
Digital Jass Scoreboard (Schiefertafel Z/Z)
Version: 1.0
Target: Agentic Implementation
Technology: HTML, CSS, Vanilla JavaScript
1.1 Product Name
Digital Jass Scoreboard (Schiefertafel Z/Z)
1.2 Product Description
A browser-based web application that replicates a traditional Swiss Jass slate scoreboard with Z/Z representation.
The application allows two teams to record points during a Jass game while preserving the visual appearance of a chalk slate board.
The application is designed to be:
extremely fast to use during gameplay
visually similar to physical Jasstafeln
deployable as a static web app
2.1 Allowed Technologies
The application must use only:
HTML5
CSS3
Vanilla JavaScript (ES6+)
2.2 Forbidden Technologies
The following are not allowed:
React
Angular
Vue
jQuery
TypeScript
external JS frameworks
External CSS libraries should be avoided.
The application must create a dedicated project folder containing all files.
Example root folder name:
jass-scoreboard
3.1 Folder Structure
The implementation must use the following folder structure.
jass-scoreboard/
│
├── index.html
│
├── css/
│ └── styles.css
│
├── js/
│ ├── app.js
│ ├── state.js
│ ├── storage.js
│ ├── scoring.js
│ ├── renderer.js
│ └── ui.js
│
├── assets/
│ ├── textures/
│ │ └── slate-bg.png
│ └── fonts/
│
└── README.md
3.2 File Responsibilities
index.html
Responsibilities:
root HTML structure
load CSS
load JavaScript modules
define DOM containers
styles.css
Responsibilities:
layout
chalkboard styling
Z/Z board grid
responsive layout
animations
win animation
app.js
Responsibilities:
application bootstrap
initialize state
attach UI events
start render cycle
state.js
Responsibilities:
global state definition
state mutations
state validation
storage.js
Responsibilities:
localStorage persistence
state serialization
state restoration
scoring.js
Responsibilities:
add score
calculate totals
check winner
renderer.js
Responsibilities:
render board
render tallies
render totals
render win state
ui.js
Responsibilities:
handle user input
bind event listeners
validate inputs
The application uses a single global state object.
4.1 Global State
state = {
teams: [
{ id: "A", name: "Team A" },
{ id: "B", name: "Team B" }
],
entries: [],
totals: {
A: 0,
B: 0
},
targetScore: 2500,
flipped: false,
winner: null,
gameFinished: false
}
4.2 Entry Model
Each score entry must be stored as:
{
teamId: "A",
points: 120,
timestamp: 1710000000000
}
5.1 Teams
Exactly two teams.
Team names are editable.
Constraints:
min length: 1
max length: 30
5.2 Target Score
Default value:
2500
Editable by user.
Valid range recommended:
100 – 10000
5.3 Win Condition
A team wins when:
team_total > targetScore
Important:
The score must exceed the target.
5.4 Game End State
When a team wins:
state.gameFinished = true
state.winner = teamId
Score entry must then be disabled.
Undo remains allowed.
6.1 Input Workflow
User steps:
Select team
Enter points
Click "Add"
6.2 Validation
Points must satisfy:
integer
points > 0
points ≤ 500 (recommended)
6.3 Score Calculation
Totals are computed as:
team_total = sum(points for team)
Totals must never be manually edited.
7.1 Slate Board Style
Visual design must resemble:
traditional chalk slate board
Required elements:
dark background
chalk text
red guide lines
diagonal Z/Z layout
8.1 Rule
Round entries must not display numeric values.
Instead they use tally marks.
Example:
5 points
||||\
8.2 Rendering Algorithm
Pseudo logic:
function renderTallies(points):
The board must visually divide into two mirrored areas.
Simplified layout:
Team A board | Team B board
With diagonal guideline elements to mimic Z/Z chalk layout.
CSS grid recommended.
10.1 Purpose
Players sitting on opposite sides of the table must read the board.
10.2 Behavior
Flip button toggles:
state.flipped = !state.flipped
Rendering must swap team panel positions.
Important:
Data model remains unchanged.
Undo removes the last entry.
entries.pop()
Then:
recalculate totals
check winner
re-render board
Reset must...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.