# Changelog

All notable changes to this project are documented here. Newest entries on top.

## [2026.10.31-258] - 2026-10-31 - 02:58

### Added

- Published on GitLab Pages at <https://volleyball-digital-scoresheet.niftylittletools.dev/>: a `.gitlab-ci.yml` runs the 27 engine tests, builds the site and publishes it; `site` set; the README's Live line.

## [2026.10.30-1916] - 2026-10-30 - 19:16

### Changed

- Repository link: GitLab group `web-static` is now `browser-tools`.

## [2026.10.30-1844] - 2026-10-30 - 18:44

### Changed

- Repository: `gitlab.com/nifty-little-tools/web-static/volleyball-digital-scoresheet`, in the README.

## [2026.10.29-1959] - 2026-10-29 - 19:59

### Documentation

- README rewritten to the workspace structure (`_templates/README.md`): the key line, Usage steps, Parameters/Flags (match type, every shortcut, the single-key switch) and a Development section with the check, test and build commands.

## [2026.10.27-2251] - 2026-10-27 - 22:51

### Changed

- `fivb_rules.md` is excluded from markdownlint, with the reason in the file: it is a machine extraction of the FIVB rules PDF, whose headings and lists follow the PDF's layout, not prose this project authors.

## [2026.10.27-2248] - 2026-10-27 - 22:48

### Added

- **Guided tour**, the education template's tour mechanic (`src/lib/tour.js`, copied; `src/lib/tutorial.js`, a plain-JS port of its `Tutorial.svelte`): ten steps through one real match, from filling the teams through the lineups, a rally, the side-out, a time-out and the action log to the report. A step that asks for an action waits for it and moves on by itself. The tour starts on a first visit once the privacy notice is answered, and again from the header's **Take the guided tour** button. Esc or Skip ends it, and the choice is stored under `vds-tourDone`. It steps aside while a dialog or the privacy notice is open, and the footer's Privacy settings button stays clickable above its shade.
- **Keyboard shortcut legend** under the match controls, with a **Single-key shortcuts** switch stored under `vds-keys` (WCAG 2.1.4, Character Key Shortcuts). The legend, the Help table and the key handler all read one table (`src/lib/shortcuts.js`), and each button carries `aria-keyshortcuts`.
- Tests for the shortcuts in both directions, the tour's card placement and its step text (`tests/shortcuts.test.js`).

### Changed

- **Keyboard shortcuts are single keys**: A or B point, D details, S substitution, L libero, T time-out, X sanction, V video challenge, G statistics, ? help, and Ctrl + Z undo, which works even with single keys off. The old Ctrl+A / B / S / L / T set clashed with the browser: Ctrl+T and Ctrl+L can't be overridden, and Ctrl+A and Ctrl+S select all and save. A shortcut presses its button, so it does nothing while that button is disabled or hidden.

### Fixed

- `fivb_rules.md`: eleven control characters left by the PDF extraction are restored to the glyphs they stood for (two label separators, six hyphens, one "fi" ligature, and two stray bells removed).

## [2026.10.27-1913] - 2026-10-27 - 19:13

### Fixed

- Dialogs open in the centre of the screen: Tailwind’s reset set their margin to 0, and a native dialog centres itself with margin: auto, so every dialog opened in the top-left corner (owner review).

## [2026.10.27-1509] - 2026-10-27 - 15:09

### Added

- **The match engine** (`src/lib/engine.js`), the FIVB Official Volleyball Rules 2025-2028 as pure functions: starting lineups (7.3); rally scoring, the serve and clockwise rotation on a side-out (6.1, 7.6); sets to 25 by two and the deciding set to 15, best of five or three (6.2, 6.3); the court change at 8 in the deciding set (18.2.2); two time-outs (15.4) and six substitutions per set with the starter / substitute re-entry rule (15.6); libero replacements, with the libero leaving on rotating into the front row (19.3); sanctions, a penalty being a point and the serve to the opponent (21.3); video challenges; undo; statistics. The page could record nothing before: `handleAction`, `checkSetEnd`, `updateScores` and `updateScoresheet` were called but not defined (the rework committed on 2026-10-26 had removed them).
- **The PDF match report** (`src/lib/report.js`, jsPDF, bundled): result, sets with durations, time-outs and substitutions, statistics, sanctions and the point-by-point score. The Export Report button called `generatePDFReport()`, which never existed.
- Vitest tests for the engine and the report (18), each expected value traced step by step; they replace the Jest test, which no longer matched the page.
- A toggleable, remembered intro saying what the tool is (global §11).

### Changed

- **Rebuilt on Astro + Tailwind CSS** (the workspace's target stack) in the house **Cyanotype** style, replacing the vanilla page on Bootstrap. Every dialog is a native `<dialog>`; the statistics tabs follow the WAI-ARIA tab pattern.
- **Nothing is loaded from a CDN any more** (global §20): Font Awesome, IBM Plex and jsPDF are npm packages, bundled; Bootstrap and Chart.js (which nothing used) are gone. The Content-Security-Policy is `'self'` throughout, and the privacy notice lists no third party.
- Every string moved to `src/i18n/en.js` (global §3).
- The theme key is `vds-theme` (the old `theme` is read once, so a returning visitor keeps their choice).
- README rewritten for the engine, the report, the stack and the commands.

### Removed

- The technical time-out indicator (the 2025 rules in `fivb_rules.md` have none), the Australian rule-set option (it changed nothing), and the per-team charts (Chart.js was loaded but never used).

### Fixed

- Duplicate element IDs (`teamAName` and `teamAPlayers` each named two elements).

## [2026.10.27-926] - 2026-10-27 - 09:26

### Changed

- Tooling: pnpm 12.15.0, the newest 12.x, pinned in `mise.toml` and in `packageManager` with its sha512; the lockfile's own pnpm entry follows, so `pnpm install --frozen-lockfile` passes on the new pin.

## [2026.10.27-911] - 2026-10-27 - 09:11

### Fixed

- The privacy notice sits above every overlay and closing it returns focus to what opened it.

### Known issue

- jsdom 30 was tried and reverted to 26: its dependencies are ES-module only, which Jest's CommonJS loader cannot `require`, so no test could load. jsdom 26 audits clean; the test rewrite (Phase 5) can move to Vitest.

## [2026.10.26-1926] - 2026-10-26 - 19:26

### Added

- **Privacy & security notice** (`_notice/`, English only until this page gains i18n): first-visit notice, equal Reject / Accept, "Exactly what we store" (`theme`, jsDelivr and cdnjs), choice under `privacy-consent:volleyball-digital-scoresheet`.
- A footer: version linked to `CHANGELOG.md`, attribution, **Privacy settings**.
- Content-Security-Policy (jsDelivr and cdnjs allowed) and referrer-policy `<meta>` tags; README `## Privacy & security`.

### Fixed

- **Theme flash on load** (global §9): an inline pre-paint script now applies the saved `theme` before the page draws; the toggle carries `data-theme-toggle`.

### Verified

- `verify.mjs` in Edge: 16 of 17. The one fail is the repository link: this tool has no remote yet, and no URL is invented.

### Known issue

- Chart.js is loaded unpinned (`cdn.jsdelivr.net/npm/chart.js`), so a new release can change the page without a commit; pin it in this tool's conversion.
- The footer version is typed by hand (a plain page cannot import `package.json`).

## [2026.10.26-1833] - 2026-10-26 - 18:33

### Security

- Dependency CVE sweep (global §8): `pnpm update` within the declared ranges. `pnpm audit` went from 1 critical, 3 high, 2 moderate to **none** (all in the test toolchain).

## [2026.10.26-1813] - 2026-10-26 - 18:13

### Changed

- npm lockfile replaced by `pnpm-lock.yaml` (`pnpm import`, same resolved versions).
- `package.json` is now a real manifest: name, `version` synced to this changelog, AGPL-3.0
  licence, a `test` script, and the test packages as `devDependencies` — `jest` itself was
  missing, so the tests could never run. Jest moves to 30.5.2 with `jest-environment-jsdom`.
- `jest.config.js`: `testEnvironment: 'node'`, because each test builds its own JSDOM and jsdom
  cannot be constructed inside Jest's jsdom environment.
- `pnpm-workspace.yaml`: `allowBuilds` decided for `@parcel/watcher` and `unrs-resolver` (both
  `false`: they ship prebuilt binaries), which pnpm 12 otherwise refuses to install past.

### Known issue

- `pnpm test` now runs and **fails 2 of 2**: the tests `require('../app')` into Jest's globals
  rather than loading the page into their JSDOM, so `document` is undefined. Rewriting them is
  part of this tool's conversion (plan Phase 5).
- `.gitattributes` normalising line endings to LF (`* text=auto eol=lf`) and marking binaries.
- `README.md` (what it is, features, installation, usage, licence) and the house
  `.markdownlint.jsonc`.
- `mise.toml` pinning Node 24 and pnpm 12.12.1 (global §9; replaces any hand-installed toolchain).
- `packageManager` pinned to `pnpm@12.12.1` with its sha512, so corepack in CI uses the same pnpm.

## [2026.6.29-2006] - 2026-06-29 - 20:06

### Added

- **Navbar logo:** the tool's `logo.svg` now appears as the brand mark in the
  header/navbar, matching the in-app favicon and the catalogue listing.

## [2026.6.29-0412] - 2026-06-29 - 04:12

### Added

- **Logo / favicon:** added a tool-specific `logo.svg` (Lightline house recipe —
  accent-coloured Font Awesome `volleyball` glyph on a dark rounded tile) and wired it
  as the favicon. was none; added a CHANGELOG and a timestamp version. The single SVG doubles as the reusable tool logo.
