# Changelog

All notable changes to this project are written here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
[Semantic Versioning](https://semver.org/).


## [Unreleased]

## [0.10.2] - 2026-10-14

### Fixed

- **A team's round mark and its name are painted over the surface's lines.** A hockey rink's face-off circles, red and blue lines and creases, and the lines of the football fields, the ballpark, the lacrosse, rugby, Australian football, Gaelic games, field hockey, handball and netball surfaces and the pools (swimming, water polo, diving, artistic swimming), were written after the team marks and names, so they ran across a logo and a name. The marks and the names now come after every line, and so do the data layers, the lineup, the annotations, the pageant's names and the score's panel, for every sport, look and size. The courts, the pitch, the athletics track, the skating rinks and the budō surfaces already did. The drawing is the same string as before apart from that order, and the internal `bannersOver` flag that chose it is gone.

### Added

- **A test holds the order for every sport:** `src/overlay.order.test.ts` reads the drawing's leaves in paint order and fails when a marking of the surface comes after the first mark, name, layer, lineup, situation widget, annotation, pageant word or score panel, for every sport and every look, wide, tall, with the panel and without it, with layers, landmarks, a situation, a crowd, a special game and every pageant.

## [0.10.1] - 2026-10-14

The docs are one language to a page. No change to the package or its pictures.

### Changed

- **The docs are single-language.** `CONTRIBUTING.md` says so (one page per language, no mixed tables, the Japanese twin named `<name>.ja.md`), and a new test, `src/docs-language.test.js`, fails when an English page holds Japanese outside code or a Japanese page holds English prose. Four pages that mixed the two were split, and the build writes both: [docs/grounds.md](docs/grounds.md) and [docs/grounds.ja.md](docs/grounds.ja.md) (`pnpm grounds`), [docs/variants.md](docs/variants.md) and [docs/variants.ja.md](docs/variants.ja.md) (`pnpm docs:make`), the table of park names in [docs/ballparks.md](docs/ballparks.md) and its Japanese twin [docs/ballparks.ja.md](docs/ballparks.ja.md), and the Japanese Wikipedia articles of [NOTICE.md](NOTICE.md), now in [NOTICE.ja.md](NOTICE.ja.md). The Japanese rule-book words of the pools, the athletics stadium, the skating rinks and the budō are in a new page, [docs/terminology.md](docs/terminology.md), which, like `docs/strings-ja.md`, shows both languages side by side on purpose. Japanese glosses were taken out of the English prose of the other pages, and the README's list of the family and the titles of Japanese rule books cited in the sources are named in the test as exceptions, each with its reason. No change to the package or its pictures.

## [0.10.0] - 2026-10-14

### Added

- **The demo has an optional Background menu.** None by default, then the family's twenty-five backgrounds (`scripts/family-backgrounds.ts`, version 1.0.0, copied byte for byte from taisen-brackets and pinned by version and sha256), also by `?background=<name>`. It draws one behind the stage in the dark or the light variant of the page's look, takes the stage's text colour from the ink the background returns, and loads the module only when one is chosen. It is presentation only: the drawing's SVG is the same string with and without it, and an e2e test holds that. The package ships none of it and still has no dependency.

### Changed

- **Every README picture stands on one of the family's backgrounds,** in a light and a dark twin (ice behind the rinks, floodlights behind the football field, a royal purple behind the ballpark, a glow or a spotlight behind the courts), and `pnpm screenshots:readme` remakes all twenty in one run.
- **The docs' and the README's samples use real countries,** Canada, the USA and Japan first, with their names and colours and no flag (a snippet cannot await Hata); where a sample shows marks it draws a maple leaf and a sun disc of its own. The gallery's teams and the pool races' swimmers' countries are real too.

## [0.9.0] - 2026-10-14

### Added

- **Country flags from a plug-in: `useFlags(render)` and the `flags` option.** A team takes a country's code, `flag: "CA"`, and the flag is drawn by a function you plug in, as the emblems are by `useEmblems`. The renderer is `(code, { shape, size, theme }) => string` (an SVG document, or nothing for a code it has no flag for), synchronous because a drawing is a pure function of its options: it is the shape [Taisen Brackets](https://www.npmjs.com/package/@johnmorrisdotca/taisen-brackets) takes, so one adapter over [Hata](https://github.com/johnmorrisdotca/hata) serves both. `shape` is `round` (a round mark, a pageant's stage), `rect` (a plain mark, a banner, a badge, a pageant's carpet, in its own proportions) or `square`; `size` is a nominal width in pixels; `theme` is `light`, `dark` or `inherit`. `useFlags` is in the main entry and in `/element`; `flags: render` in the options of a drawing (or the `surface` of a chart) wins over it for that drawing. The same code works for `Swimmer.country` and `LineupPlayer.country` (where `flag` is missing), for the `country` of an athlete or a skater of a lane draw or a start list, a layer's mark of the shape `logo` for a team, and the element's `home-flag` and `away-flag` attributes. A team's `flag` wins over its `logo` where the renderer has a flag for the code; with no renderer, or none for the code, a drawing is the text it was (and a code that is not a code is never asked about). A round flag turns with its team's name as a round logo does. Kyogijo imports no flag and keeps no dependencies; `@johnmorrisdotca/hata` 1.5.0 is a development dependency (for the demo and the tests) and an optional peer one. [Flags](./docs/flags.md).

### Changed

- **The demo's teams are real countries, drawn with Hata's flags.** The made-up teams (Harbour City Gulls and the rest) and the sixteen made-up nations of `demo/nations.js` are replaced by Canada, USA, Japan, Mexico, Australia, Brazil, England, Korea, Germany, France and Italy, each with its national flag through the plug-in (the build loads the flags it draws from Hata into the page), and the pool's swimmers, who still do not exist, swim for real countries. The demo's teams have a new "Flag" logo choice, the default; "Own logo" shows a logo of your own beside it: a maple leaf with the word CANADA, a red sun disc with the word JAPAN and, for the others, a roundel of their letters, all drawn in the demo's code. No federation's crest or logo, and no Olympic rings, is used. The embedded frame takes `aflag` and `hflag`. The made-up nations stay, for the tests only, in `src/nations.fixture.ts`, so that no drawing in a test changed.

## [0.8.0] - 2026-10-14

### Added

- **The venue in the 3D view** ([docs/turn.md](./docs/turn.md#the-venue)): the stands, roofs and rooms round a surface are raised from the data the package already has, so that a whole stadium, ballpark, arena or dojo turns by mouse drag, finger, keys and buttons. Every tier of `crowdStands()` is a strip of raked planes (a quad to each straight side, three to each corner, a ballpark's points, 28 round an oval) from the height of its first row to its last, with the crowd's own pattern as texture (people, empty seats, row lines, aisles, the visitors' block, the tifo), the walks between the tiers, a low wall under the first row, and the places the stands are left open left open. A ballpark gets its grandstands and bleachers and, where the park has them, the seats on top of the wall (Fenway Park's Green Monster at 37 ft 2 in). A dojo gets its cream walls over a wood wainscot, painted in the floor's own look, with the doors and windows of `dojoRoom()`, the dais, the banner, the shrine, the balconies as steps of seats behind a rail with the crowd in them, overlooking the floor, and the thickness of the mats at their edge. `venue: true | false | { roof, detail }` is the switch: on when the drawing has a `crowd` or is a dojo, off with `uprights: false`; `roof: true` adds a canopy over the top tier or a lid over a hall. The stands and walls fade on the side nearest the eye as the boards do, so the surface is never hidden. A full soccer bowl is about 110 planes and 500 elements and the biggest venues under 1,000, whatever the seats taken; `detail` cuts the curves coarser or finer. The element reads `turn-venue="false"` and `turn-roof`; the demo has a Roof toggle in 3D.
- **An auto-turn for the 3D view**, a trophy case's slow turn: an Auto-turn toggle button (`aria-pressed`, 44 pixels or more, in English and Japanese) and Space start and stop it; `autoPlay` (`true`, or `"force"`) is the opt-in start, `speed` its degrees a second, `onPlayChange` its callback, and the handle has `playing`, `play()`, `pause()` and `togglePlay()`. It holds while the pointer holds the view, does nothing on a hidden page or off the screen, is stopped by the arrow keys, a viewpoint, the reset or `set`, starts paused for a reader who prefers reduced motion, and moves nothing until Play is pressed unless `autoPlay` asks. The element reads `turn-autoplay` and `turn-speed`.

### Changed

- **The Kodokan's gallery is as its owner counts it, in 2D and 3D.** `dojo.balcony` takes `rows` and `sections` (the seats in each block of a row, with an aisle between blocks, the same on every side): the main dojo has `{ rows: 3, sections: [5, 8, 8, 8, 5] }`, 34 seats to a row and 102 to a side, per the owner and his photographs. `dojoRoom()`'s balconies carry `sections`, `seatWidth`, `aisle`, `aisles` (the shares of a side the aisles lie at) and `sectionsBasis`, and `dojoGallery()` returns `sections` and `aisles`; a side with no `sections` is cut into blocks of about 9 m (ours). The gallery is 3 rows deep by default and its seats are empty: a dojo's crowd density defaults to 0 and people are drawn only when `density` or `attendance` asks. In 2D the aisles lie across the band and each row is dashed cushions with a darker line of backs; in 3D the seats are dark brown cushions and backs in blocks on dark treads, the aisles lighter wood with their stairs, a white rail, honey wood panelling on the walls under the gallery, plain off-white above it with a clock, two doors and three windows, the kamiza's alcove with a framed shrine, a scroll and a plain purple banner, and, with `roof: true`, a pale ceiling band with box lights. The surround of a dojo (when it has one) is polished hardwood: the basketball floor's boards and seams, at half strength, under a warm satin sheen.

- **A dojo's gallery is a proper balcony in 3D and neat seat rows in 2D.** In 3D each balcony has a floor slab that projects over the room (with its thickness showing), a white rail with two bars and posts on its edge, and four tiers of seats drawn as cushions and backs, a seat every 0.6 m, on light treads. In 2D, from above, the gallery is rows of seats along its band (a dashed line to a row, in the gallery's brown) and not a ring of round heads; `crowd` still gives the people in the 3D balcony. The Kodokan's four areas are the IJF's block (8 m areas, 4 m shared safety between them, 3.2 m round in the 26.4 m square of 420 jō): the pale areas are 256 m² of 697.

- **The mats look like mats, in 2D and 3D.** The seams between tatami are drawn a few per cent darker than the mat (ink at 12%, they were 26%), the weave is dark ridges 3% deep at most (it had white ridges 14% deep), the faint light line on the mat edges is a 4% dark one, and the heri, which drew heavy dark bands between the mats, is as faint as a seam unless `colours.heri` names a colour (`--ky-bud-hop` then restores its 0.82). A contest area is just another colour of mat. The walls of every look are a light cream, not a dark grey. This is the drawing of the dojo, judo, karate and kendo themselves, so every drawing of them changes (their fingerprints in the identity test are made again).
- **The dojo's room is a storey high and its gallery is on the upper level.** A dojo with a gallery has walls 4.5 m high, the gallery's floor level with their tops (it was 3 m walls under a gallery at 4 m), the gallery as steps of seats behind a white rail, three large windows high in the wall behind it on the east side, and, with `roof: true`, a pale ceiling over it; `dojoRoom()` gives `upperWindows` and `ceiling` (all ours). The Kodokan's main dojo has a polished wood floor 4 m wide all round the mats (it was 1 m), so its walls stand far out.

- A 3D view with a crowd no longer lays the flat crowd on its floor: the stands are planes, and the floor is the surface with the ground they stand on. `venue: false` gives the flat crowd back. The crowd's `patterns()` take an optional row-lines argument (the 2D drawing is byte for byte as it was).

## [0.7.0] - 2026-10-14

### Removed

- **`roadToFinal` and the road-to-the-final chart moved to [`@johnmorrisdotca/taisen-brackets`](https://www.npmjs.com/package/@johnmorrisdotca/taisen-brackets)** (0.4.0 and later; its `/road` entry), where it is built on the bracket package and shares its look. There is no shim here: import it from taisen. Gone from `@johnmorrisdotca/kyogijo-stadiums/charts`: `roadToFinal`, `ROAD_SIZES`, `KYOGIJO_ROAD_STYLE` (and from `KYOGIJO_STYLE`) and the types `RoadChart`, `RoadDecided`, `RoadFinal`, `RoadFinalist`, `RoadGroupMatch`, `RoadMatch`, `RoadOptions`, `RoadRecord`, `RoadScore`, `RoadSize`, `RoadSizeInfo` and `RoadTotals`. The `road` words are gone from `KYOGIJO_STRINGS` (a custom set of words no longer has to give them), and the docs' section, the demo's "Road to the final" section, its gallery items and its tests went with it.
- **The round mark stays.** `Team.mark`, `markShape` and `KYOGIJO_MARK_STYLE` are for surfaces and are unchanged. The demo's section for them is now "Round marks" (a pitch wide and tall, and a badge), with its own sixteen made-up nations in `demo/nations.js`, the same flags as before.

## [0.6.2] - 2026-10-14

### Fixed

- **A round mark turns with its team's name.** Where a zone's words are turned (along the ends of a wide pitch, and in a tall drawing, where the surface is turned a quarter and the words are turned back) the flag in its circle was turned back to stay upright, so on a wide pitch the flag stood upright beside a name written sideways, and in a tall drawing the flag lay a quarter turn over while the name read upright. The mark's group now lies in the banner's group and takes its turn: the same angle, the same way, as the name, so a flag and its name read as one unit (sideways along the ends of a wide pitch, the right way up in a tall drawing). The clip, the ring, the hairline and the initials of a team with no picture turn with the group, and the clip path's id (`<id>-mk-home-c`, `<id>-mk-away-c`) is unchanged. A flag in a zone that is not turned is as before, and so are the badge and the strip of a compact card, which are not turned. `RoundMark.upright` stays in `mark.ts`, but the score no longer passes it. A test reads the turn of the mark and of the name in every orientation, with logos and with initials, and holds the two equal.

## [0.6.1] - 2026-10-14

### Fixed

- **The 3D view zoomed in and out as it turned.** The camera fitted the scene to its box for each angle on its own, so every angle fitted but the scale changed with the yaw: a long floor was drawn up to 1.8 times as large (overhead; 1.5 times at a tip of 30 degrees and 1.15 to 1.65 times from 60 to 80) at the angle where it is seen end-on as side-on, and the field grew and shrank under a drag or the auto-turn. `fit` now fits the scene at every angle of the circle at the view's pitch (so it takes the pitch and not the yaw) and takes the one scale and centre that hold them all: turning never changes the zoom or sways the scene, and no angle is cut off. The floor is the size it had at its tightest angle (down to 0.55 of its old size where it had room). Tipping the view still rescales it, since the pitch changes the extent; zoom is laid on top of the fit as before. `src/turn.camera.test.ts` holds the scale constant over every yaw, pitch and container, for every sport's scene, and measures every degree of the turn against the box.

## [0.6.0] - 2026-10-14

Six budō sports and a dojo builder (39 sports in all), the situation of a game, lineups, zones, a pointer and goal mouths, the arenas of the NHL, the NBA, the WNBA and the PWHL (330 places on the atlas), and Dougu Sports 0.2.0 for an icon on every sport. The 3D view's keys, buttons and drag now turn the surface the same way.

### Fixed

- **The 3D view turned the wrong way across.** A drag to the right (mouse, or a finger with `touch: "turn"` or a sideways swipe) carried the side of the surface nearest the eye to the left. The drag now takes hold of the surface, as the cube of kyuubu and most 3D viewers do: right carries the near side to the right and left to the left, and the Right and Left arrow keys turn the same way as a drag to that side. Dragging up and down was already right (down tips the top toward the eye) and is unchanged, as are the viewpoints, `set` and the buttons. `drag()` in `/turn` has the opposite sign for `dx`. A browser test drags a marker on the near boards and a unit test holds the signs.
- **The 3D view's buttons and the Up and Down keys turned the wrong way.** After the drag was corrected, the turn-left button turned the way a drag to the right does, and ArrowUp tipped the surface the way a drag down does. A drag, an arrow key and a button toward one side now all move the surface the same way: Left and Right carry the near side that way, Up tips it as a drag up does and Down as a drag down (the up and down buttons follow the keys; the drag's own pitch is unchanged). `nudge(view, "left" | "right" | "up" | "down", degrees)` in `/turn` is the step the keys and buttons share, and a unit test and a browser test hold the three together. The up and down buttons are now named for what they do, "Tip the surface away" and "Tip the surface toward you" (they were "Raise the view" and "Lower the view"), and the announcement says "Turned to 40 degrees, seen from 34 degrees above the floor" where it said "raised 34 degrees".
- **The demo had no icon on the deployed site.** The page's icon was an inline `data:` address, which a sanitizer in front of the deployed page turned into `about:invalid#zCSafez`. The site now ships a static `favicon.svg` and `apple-touch-icon.png` and every page (the demo, the API reference, the docs pages and the gallery) links them.
- **A football lineup's two teams are one size**, so the offence is not shrunk to fit its line.

### Changed

- **The pools follow the World Aquatics Competition Regulations in force from February 2026.** Every citation of a pool figure, a goal and a diving distance is to that edition's numbering (Part Two Article 15 for the swimming pool, Part Four Article 15 and Appendix 2 for diving, Part Six Articles 20 and 21 for water polo, Part Seven Article 12 for artistic swimming), with the June 2025 number beside it. Three figures changed with it: the water polo field is at least 2.00 m deep everywhere (`WATER_POLO.depth`, was 1.80 m, 2.00 m at the Olympic Games and the World Championships); the diving depth at the plummet, `DIVING.H`, has the minima 3.40 m (1 m springboard), 3.70 (3 m), 3.20 (1 m platform), 3.50 (3 m), 3.70 (5 m), 4.10 (7.5 m) and 4.50 m (10 m), and 5.00 m preferred as before (they were 3.50, 3.80, 3.30, 3.60, 3.80, 4.30 and 5.00 m); and a starting block is at least 0.5 by 0.5 m (`SWIMMING.block.length` 0.5, was 0.6, which shows in the 3D view). The drawings of the pools do not change. Not found in the February 2026 text, and marked unverified where they are cited: the false start rope, a pool shared with artistic swimming at 3 m, the 5 m under the boards at the Olympic Games and the World Championships, the lane rope float's 0.15 m. The water polo goal is Part Six Article 21.6 (the old "Appendix 4" is now the video referee protocol) and the field hockey goal is "Field and Equipment Specifications 1.5 (Goals)" of the FIH Rules of Hockey 2026.
- **The Japanese words of the pools** keep the federation's own article numbers (`水球競技ハンドブック` 18.3.2 for `審判台`; `アーティスティックスイミング競技規則` 27.2.8 and 27.2.7 for `ジャッジ台` and `スタート台`), read again in the books of 2023-04-01 and 2026-04-23; the number given for the 5 m mark was the definition of a goal, and is now 18.3.1.

### Added

- **A lineup takes the score to the strip.** A score drawn with a `lineup` layer puts its panel in the compact strip under the surface, as a pageant's `score: "auto"` does, and the situation's pill, scorebug or tag goes to the strip with it, so that nothing hides a player; what the situation lights (a runner's base, a drive's arrows) is drawn under the players. The new option `score: "centre" | "strip" | "auto"` says it, and `score: "centre"` keeps the panel over the surface ([score and layout](./docs/score.md)).
- **Dougu Sports 0.2.0** (the development dependency of the demo and the tests): 167 emblems, an icon for each of the 38 sports including judo, karate, kendo, sumo and kyudo; the dojo takes the judo one.
- **The situation of a game: `situation`** ([docs/situation.md](./docs/situation.md)). Hockey's skaters (a power play or an empty net as a pill, `5v4 PP 1:42`, with the attacking zone tinted in the attacking team's colour and the empty net ringed), a delayed penalty, and a shootout as a strip of dots across centre ice (a goal filled, a miss hollow, the rounds after the third as sudden death); baseball's (softball's and the NPB's) runners lit on the diamond and a scorebug with the outs, the inning and the count; football's line of scrimmage (blue), first-down line (yellow), red zone and down-and-distance tag, and `drive` for a drive chart of arrows by result. The CFL's field of 110 yards with end zones of 20 and its three downs are respected. The badge and the compact card show the pill, the scorebug or the tag in place of the surface's picture, and the description says it in English and Japanese. The Japanese is for review.
- **`situationText`, `readSituation`, `DRIVE_CODES` and `KYOGIJO_SITUATION_STYLE`**, and the types `Situation`, `HockeySituation`, `BaseballSituation`, `FootballSituation`, `DriveLeg`, `DriveResult`, `ShootoutRound`, `SituationRead`.
- **Two rinks:** `league: "olympic"`, the IIHF rink at 60 by 26 m (the IIHF's statement of 9 December 2025 gives it for Milano Cortina 2026, as Beijing 2022 and the NHL's Global Series arenas), and `league: "boston-garden"`, 58.2 by 25.3 m, with the NHL's figures for the rest.
- **`rulesFor("nhl", year).rules.twoLinePass`:** the centre line judged the offside pass from 1943-44 to 2004-05 (data only: no mark on the ice changes).
- The demo has a Situation group of controls, each a finger wide.
- Not found, so not drawn, and set down in [docs/references.md](./docs/references.md): Buffalo Memorial Auditorium's and Maple Leaf Gardens' ice, the NHL goal crease before today's, the NHL's blue lines before 1998-99.
- **Lineups** ([docs/team-shape.md](./docs/team-shape.md#lineups)). A new kind of data layer, `lineup`: a team's players placed by position code, with no coordinates. `{ kind: "lineup", side, formation?, players: [{ pos, name, number, flag?, captain?, line? }] }` reads where each position stands from a formation, draws each player as a disc or a jersey (`shape`) with the shirt number in it and the name under it (a long name shrinks to fit, then is cut with an ellipsis), a small "C" for the captain and a flag badge, and puts the visitors at the other end (`side: "away"`); two teams are two layers. Without a `formation` the one of the sport that places the most of the players is chosen. Short codes (`CB` for either centre-back, `D` for a defenceman, `OF`, the scorer's numbers 1 to 9, `HK`, `SH`...) are listed in `LINEUP_CODES`; hockey's second line is `line: 2`; a volleyball team turns by `rotation`; baseball's designated hitter is listed beside home plate. A lineup is not cut to the surface's outline unless `clip: "surface"`. Types `LineupLayer` and `LineupPlayer`; the table (`layerTable`) lists each place, its player and the captain, and each player with no place.
- **Formations for more sports** (`FORMATIONS` now holds 36): rugby union's fifteen, Australian football's eighteen, three cricket fielding presets (an attacking field with three slips, the one-day powerplay, defending the boundary), volleyball's six places of the rotation, handball's attack and 6-0 defence, a water polo attack, field hockey's 4-3-3 and 3-4-3, netball's seven positions, softball's defence, hockey's two lines, and a traditional basketball set; each with its position names in English and Japanese. `Formation.extra` lists places that a lineup draws and a `formation` layer does not (the designated hitter), `FormationPosition.size` scales a place's mark in a lineup, and `FormationSport` has thirteen sports.
- **The demo's address holds every control.** Sport, league, park, ground, season, size, layout, theme, 3D view and viewpoint, the looks (court, stripes, goals, half, flags, hardwood, crowd and its density, pageant and emblem, pool and track settings), the lineup, the placed points, the code tab and the game itself (names, abbreviations, scores, colours, penalties, logos, status, winner, competition, date, label) are in the address and restored from it, so a shared link reproduces the exact view; a field is written only when it differs from the sport's made-up game. The keys the page already had are unchanged. A "Copy link" button sits beside the code's Copy.
- **Click to place in the demo.** A toggle drops a point where the drawing is clicked and shows its coordinates (feet from the surface's top left, and metres) as the pointer moves; the toggle and the points are in the address (`drop` and `shots`) and in the code, and "Clear points" removes them. A Lineup choice draws made-up teams on sports that have formations.
- **Arenas: the homes of the NHL's, the NBA's, the WNBA's and the PWHL's clubs** ([docs/arenas.md](./docs/arenas.md)). `ARENAS` (from `/arenas` and the main entry; `ARENA_IDS`, `arenaById`, `arenaByName`, `arenasByName`, `arenaByWikidata`, `arenaNameIn`, `arenaOfficialName`, `arenaSourceUrl`, `arenaRinkIn`, `arenaCourtIn`) lists 167 arenas, 57 that a club of those leagues plays in today (every one of the 32 NHL and the 30 NBA arenas) and 110 of the past, back to the Montreal Arena of 1898: the Boston Arena, the Montreal Forum, Maple Leaf Gardens, Boston Garden, the Chicago Stadium, the old Madison Square Garden of 1925, the Spectrum and the halls of the BAA's first season among them. Each has its Wikidata item and coordinates, the names it had with their years (`Staples Center` until 2019), its name in Japanese with the reading, the years it opened and closed or was pulled down, the seats the article gives for hockey and for basketball, and the English article and revision every fact was read from. An arena is listed when a club of those leagues played its home games there; practice rinks, one-off sites and college gyms with no such club are not, nor are the domes whose home was a football or baseball club (the Superdome, the Kingdome, the Silverdome, the Georgia Dome and the Alamodome).
- **The size of a rink, where an article gives one.** Five arenas have a rink other than the NHL's 200 by 85 feet, each with the article, revision and a few words of what it says: Boston Garden (58.2 by 25.3 metres, 190.9 by 83 feet), the Boston Arena (220 by 90 feet until 1972, 200 by 80 from 1972, 200 by 90 from 1995), the Philadelphia Arena (220 by 101), the Barton Street Arena (200 by 80) and the Windsor Arena (195 by 80). The Chicago Stadium, Buffalo's Memorial Auditorium and the Cow Palace are said to have had a short rink that no article measures: `rinkUnknown`, drawn at the NHL's size and said so in the description. No article gives the size of a court.
- **`drawKyogijo({ sport: "nhl", arena })` and `{ sport: "nba", arena }`** (and the `arena` attribute of `<kyogijo-field>`, and `outlineOf`) draw an arena's rink or court at its own size where there is one, with the markings of the `year` (the Boston Arena's ice is 220 by 90 feet in 1926 and 200 by 80 in 1972), titled with the arena's name of that year (`Staples Center, basketball court`) and a description that says the size is the one published for it. An arena that is not one, a hostile value and a sport other than the NHL and the NBA change nothing; a `league` of your own wins over the arena's size.
- **The atlas has the arenas.** `PLACES` is 330 places (158 parks and grounds, the five halls of the budō and the 167 arenas): `Place.kind` is `arena` for the 167, `Place.sport` is `hockey` or `basketball` (the sport of the first club) and the new `Place.sports` has both for the 48 arenas of both; `placesBy({ sport })` matches any of a place's sports, `atlasFacets().sports` is `baseball, basketball, budo, hockey, soccer`, `surfacesOf(arena)` offers the rink and the court (`{ sport: "nhl", arena }`, `{ sport: "nba", arena }`) and `surfaceOf(place, "nhl" | "nba")` the one asked for. `PlaceSurface` and `surfaceOf` have the new arena member. The search finds an arena by its names and by the clubs that played there in English and in Japanese.
- **Tenants: 798 tenants (519 clubs) at 322 of the 330 places** (355 more, all at arenas; the parks' and grounds' are as they were). The WNBA, the PWHL and the Basketball Association of America (the NBA's own first years) are leagues of the table; `pnpm tenants:fetch --arenas` reads the arenas only and adds them to the evidence, and five rows of `scripts/tenants.curated.json` hold a club that an article says starts in the future. Five clubs have an everyday name in Japanese where Wikidata's label carries a disambiguator.
- **The demo's Atlas has hockey and basketball.** The sport filter has Hockey and Basketball, the map a bar across a hockey arena and an upright bar on a basketball arena, the facts of an arena say its rink and court (the NHL's, or the published size), its seats for each sport and its names; the button of the other sport opens the playground on the court beside the rink, and the playground draws the arena. The gallery has eight arenas, including Boston Garden and the Boston Arena in two years.
- **Tooling:** `pnpm arenas` (writes `src/arenas.data.ts` and `docs/arenas.md` from `scripts/arenas.data.json`), `pnpm arenas:fetch` (the evidence from Wikidata and the English Wikipedia, one request at a time, into `scripts/arenas.wikidata.json`) and `pnpm arenas:check` (reads Wikidata again and compares the item, the article, a name, the coordinates and the country).
- **Trophies, medals, balls and crests by id, from Dougu Sports** ([docs/emblems.md](./docs/emblems.md)). `useEmblems(render)` (from the main entry and from `/element`) plugs a renderer of ready-made emblems into the package, which keeps zero dependencies and bundles no art: `import { renderEmblem } from "@johnmorrisdotca/dougu-sports/emblems"; useEmblems(renderEmblem);`. After that an emblem's id is accepted wherever a logo, a flag or a mark was: a team's `logo` in a score, a compact card, a badge and a pageant, the pageant's `emblem`, the road to the final, a layer's `logo`, a swimmer's flag, a court's `centreLogo`, and the element's `home-logo` and `away-logo`. `logo: "crest:shield"` takes the team's `color`, `textColor` and the first letters of its `abbr`; `"cup"` is `"trophy:cup"`, and `/line` after an id gives the outline style.
- **`emblems: render` in the options of one drawing** (and of a road chart): a renderer for that drawing alone, over the page's own.
- **Types:** `EmblemRenderer`, `EmblemDrawOptions`, `EmblemRef` and `EmblemId`, which is the union of Dougu Sports' ids where `@johnmorrisdotca/dougu-sports` is installed beside the package and `string` where it is not. `safePicture` is exported: the check of an address, an image `data:` address or an SVG document, without the emblems. `safeLogo(value, context?)` is that check after looking for an emblem's id, and takes the team's colours for a crest.
- Without a renderer plugged in an id is an address like any other and is refused as before; in development the first refused id with a group (`"crest:shield"`) prints one hint to the console saying how to plug Dougu Sports in (nothing is printed where `process.env.NODE_ENV` is `"production"`).
- The demo's playground has a Ready-made choice for a team's logo and a picker for the pageant's centre (a tile for each of Dougu Sports' 148 emblems, a finger wide, named in English and Japanese), an Outline style chip, and the code tabs add the two lines that plug Dougu Sports in when an id is used. Dougu Sports is a development dependency, used by the docs, the demo and the tests only.
- **`zoneAt`: where a point lies by a sport's own rules** (`@johnmorrisdotca/kyogijo-stadiums/zones`, [docs/zones.md](./docs/zones.md)). `zoneAt(sport, point, { frame, attacking, league, year, park, pitch })` names the zone, the finer area in it and every other area that holds, by id and in English or Japanese, from the package's own figures: hockey's zones, crease, trapezoid, slot and face-off circles; basketball's frontcourt, restricted area, paint, mid-range, corner threes and arc by the league's court and the season's three-point line; soccer's thirds, six-yard box, penalty area, D and half-spaces; baseball's infield, outfield, foul territory, warning track and over the wall by the park's own fence; football's end zones, red zone and hashes. Every other sport answers in its zone sets. Questions: `isThreePointer`, `inPaint`, `inRestrictedArea`, `inSlot`, `inCrease`, `inPenaltyArea`, `inSixYardBox`, `inRedZone`, `betweenHashes`, `isFair`, `overWall`, `onWarningTrack`. Tests hold the hockey slot and the basketball shot zones to the package's own zone sets on a grid.
- **`isHomeRun(park, point, { height })`**, from the park's fence distance and wall height; `homeRun` says why. Where the park's article gives no wall height the answer is `undefined`, and `PARKS_WITHOUT_WALL_HEIGHTS` lists the 59 of the 94 parks that hold none.
- **`clientPointToField(svg, x, y, { provider })` and `fieldPointToClient`** (`.../pointer`, [docs/pointer.md](./docs/pointer.md)): a pointer's place on a drawing in any of the 42 frames (and the surface's own, in any unit), with the zone, through the browser's own matrix, so it holds for wide and tall drawings, any size, padding and viewBox, ranges and the end a team attacks; `clientPointToFrames` gives every frame of the sport at once. A drawing must be made with the new option `pointer: true` (off by default, so that no existing drawing changes); the 3D view answers `null`. Tested by round trip through every frame of every sport and by clicking real drawings in a browser.
- **`marks: true`: `data-mark-id`, `data-index` and `data-zone` on every mark**, with an optional `<title>`, so that one listener can link a mark to a table: the points, lines (and `data-zone-end`), arrows, text, heat cells, hexagons, zone cells, contour bands, players, formation spots, Voronoi cells and network links of the layers. Off by default, so that a drawing stays as compact as ever; on for every layer with `marks: true` in the drawing's options, for one layer with `marks: true` on it, by itself for a layer whose data has an `id` (a new field of every datum; the charts pass a shot's `id` through) and with `pointer: true`. A React and a vanilla delegated listener are in [docs/layers.md](./docs/layers.md#linking-marks-to-a-table). A marked heat map has a path for each cell, about 50 to 90 bytes more each.
- **Goal mouths, the strike zone and the stumps** (`.../target`, [docs/targets.md](./docs/targets.md)). `drawGoalMouth` for hockey (6 by 4 feet), soccer, handball, water polo, lacrosse (6 by 6 feet; the box floor's 4 ft 9 in by 4 with `league: "nll"`) and field hockey, each from its rulebook, with the shots as marks (goal, saved, post, crossbar, wide, high), nine zones (the top shelf and the five-hole in hockey), light and dark, English and Japanese, and as data in every renderer. `drawStrikeZone`: the catcher's view of the 17-inch plate with the rules' zone (`top` and `bottom` as options), the nine cells and the 13-zone chase grid, the batter's side, and the pitches numbered, coloured by result or type and shaped by what became of them. `drawStumps`: Law 8's 28 by 9 inches with the bails, the line zones and the length zones of a delivery.
- **The demo's "Point at the field"**, under "Move a point between providers": click, drag or use the arrow keys on a rink, pitch, court, ballpark or field and read the place in every provider's numbers with the zone's name.
- **Six budo sports and the dojo** (`budo`, [docs/budo.md](./docs/budo.md)): judo (the IJF contest area of 8 to 10 m, its safety area, the common safe zone, the free zone, the platform, the start marks and the 2 by 1 m tatami, in the IJF's yellow and blue, red and blue, and green and beige looks; the AJJF's smaller mat and red danger band; kata), karate (WKF kumite and kata areas), kendo (the FIK's shiai-jo), sumo (the dohyo with its tawara, shikiri-sen and optional tassels) and kyudo (the 28 m kinteki and 60 m enteki ranges with the shajo, azuchi and yatori-michi). Every figure carries its rule number or address in [docs/sources.md](./docs/sources.md).
- **`dojo({ mats, pattern, colours, kamiza, entrances, walls, windows, shinzen, label })`**: a dojo built from real tatami units, in jo or metres (generic 8, 12, 20, 50, 100 and 200 jo), laid so that no four corners meet, in the traditional green and beige or the competitive colours, with several contest areas.
- **Halls in the atlas** (`Place.kind: "hall"`, `HALLS`, `hallSurfaces`): the Kodokan, the Nippon Budokan, the Ryogoku Kokugikan, the Kyoto Butokuden and the Budokwai, each with only facts that can be cited and a generic layout where the real one is not published (said so in the place's notes).
- **The dojo builder grows a room and a history:** `areas: { across, down }` and `areaSize` for a block of contest areas, `outline` (border mats round each area), `surround` (wood round the mats), `dais`, `banner`, `balcony`, `eras` with `era` and `year` (a floor's looks over time, the years `null` where no source gives them), `colours` that really paint, and `texture: "weave"` (the rice-straw weave as one repeating gradient, turned a quarter on a mat that lies across; judo too). The dojo looks `yellow-green` and `green-orange` are new.
- **A dojo's crowd is its gallery** (`crowdStands()` reports `gallery: true`; `dojoGallery()`): a thin band of plain brown seats behind a rail close to the walls, a few neutral people and no team colours, from the same balcony data as `dojoRoom()`; the Budokan and the Kokugikan keep their bowls.
- **`dojoRoom(options)`** (`/budo`): the room round any budo surface as plain data for a 3D view to raise (walls, surround, dais, banners, balconies, doors, windows, shrine, mat thickness, the Budokan's octagon), with the figures that are ours listed in `notes`.
- **The Kodokan as a building:** the main dojo (420 jō, four contest areas, the dais, banner and gallery, in its earlier and its current colours), the Judo School, international, women's and boys' dojos, each drawable on its own.
- Judo scores (ippon, waza-ari, shido), karate points, kendo ippon and the sumo kimarite (82), boards for them, crowd profiles for the Budokan (an octagonal hall) and the Kokugikan, a 3D view with the dohyo's mound and the azuchi, and Japanese names throughout.


## [0.5.0] - 2026-10-14

Thirteen new sports (padel, squash, racquetball, sepak takraw, teqball, roundnet and netball, with sitting volleyball; swimming, water polo, diving and artistic swimming; athletics and skating), which makes 33. A 3D view that stands what a rulebook puts on a surface (nets, posts, goals, walls, blocks, boards, bars, hurdles, boards and platforms) on a floor that turns. A crowd in the stands, and a pageant of flags and crests over the halves. A folded curling sheet, with a heat chart and statistics. A realistic basketball floor. The clubs that played in each ballpark and ground, with their Japanese names as Japanese media say them.

### Added

- **Athletics and skating in the 3D view** ([docs/turn.md](./docs/turn.md#what-stands-on-each-surface)). An athletics stadium has the high jump's uprights 4.02 m apart with a bar, the pole vault's 5.20 m apart with a bar, the discus and hammer cage with its netting 4 m high and 6 m at the front of each side (Facilities Manual 2.4.1.3), the hurdles of the races a drawing marks at their heights (1.067, 0.838 and 0.914 m) in every lane, and the steeplechase's five barriers with the water jump's pit; a skating rink has the padding round a long or short track, 0.80 m high (ISU Rule 228.2), or a figure skating rink's boards, which are cut away on the eye's side like a hockey rink's. New upright kinds `hurdles`, `steeplechase`, `high-jump`, `pole-vault`, `cage`, `padding` and `rink-boards`, in English and Japanese. The javelin, the finish posts and the skating blocks have no height among the figures and are not drawn. Athletics gets a crowd profile (an oval bowl) and skating one (an arena's two tiers); both are in the e2e list.
- **The pools in the 3D view, at the heights of World Aquatics' rules** ([docs/turn.md](./docs/turn.md#what-stands-on-each-surface), [docs/sources.md](./docs/sources.md#heights-in-the-3d-view)). A swimming pool has a numbered starting block 0.7 m high in each lane at each end, a flagged rope 1.8 m above the water 5 m from each wall and the false start rope 1.2 m above it at 15 m; a diving well its springboards (1 m and 3 m) and platforms (5, 7.5 and 10 m, or the ones asked for) on stands and towers; a water polo field a floating goal on each goal line, 3 m wide with the bar's underside 0.9 m over the water; an artistic swimming area the judges' platform (0.6 m) and the starting platform (0.7 m). New upright kinds `starting-blocks`, `backstroke-flags`, `false-start-rope`, `springboards`, `platforms` and `judges-stand`, in English and Japanese (`スタート台`, `背泳ぎ用フラッグ`, `フォルススタートロープ`, `飛板`, `固定台`, `ジャッジ台`). The pools are in the e2e list of surfaces that stand up.
- **Walls give way to the eye in the 3D view.** The glass and walls of a padel court, the walls of squash and racquetball courts and the boards and glass of a rink are cut away on the side nearest the eye, more the lower the eye is, and are whole again from above or from the far side: `Plane.shy`, `fadeOf` and `Layout.fade` (`/turn`).
- **A folded curling sheet has no crowd.** Its enlarged houses cover where the stands would be, so `crowd` on a folded sheet draws nothing; the same sheet with a score shows the whole sheet and keeps its stands, with a pageant as well.
- **A folded curling sheet: `sheet.show: "folded"`** ([docs/curling.md](./docs/curling.md#the-top-end-the-bottom-end-or-both-folded)). The whole sheet as a strip, with its two houses enlarged beside it, so that a sheet 150 feet long and 15 wide fills a roughly square frame. A tall drawing has the top house on the left of the strip and the bottom house on the right; a wide one has the left house above and the right house below (the same drawing turned a quarter). The strip keeps its scale and its numbers, so a data layer lies on it as on a sheet drawn whole; each panel is the same sheet from the hog line to the back line (`sheet.panels: "half"`, the default) or just the house (`"house"`), enlarged until the whole has the shape `sheet.fit` asks (width over height, 0.5 to 2, a square by default; a panel is never longer than the strip), labelled ("Top house", "Bottom house", "Left house", "Right house"; in Japanese too) and joined to the part of the strip it enlarges by a faint fan and a frame. Stones, heat and every other layer are drawn in the strip and again in each panel, at the panel's scale, with the copies hidden from a screen reader and ids of their own. `range: "folded"` says the same (a new name in `RANGES.curling`), the description says what is enlarged and where, a score still shows the whole sheet, and the annotations (`landmarks`, `axes`, `direction`) are not drawn on it. The scene, the canvas, d3, Plot, GeoJSON and PNG read it like any drawing. New: `SheetShow` has `"folded"`, `SheetStyle.panels` and `SheetStyle.fit`, `RangeName` has `"folded"`, and `KYOGIJO_FOLD_STYLE` (written in only by a folded sheet; every other curling drawing is the same text as before).
- **`top` and `bottom` as names for a tall sheet's ends.** `sheet.end` and `range: { name, end }` take `top` (the left end, the far house of a tall drawing, the default) and `bottom` (the right end) as well as `left` and `right`; the new type is `SheetEnd`. The top end alone and the bottom end alone are `show: "half"` or `"house"` with either, and are documented as the three ways to look closer at a tall sheet.
- **`curlingHeat`: where the stones of many ends came to rest** (`@johnmorrisdotca/kyogijo-stadiums/charts`, [docs/curling.md](./docs/curling.md#where-the-stones-of-many-ends-came-to-rest)). A chart on the heat layers: stones counted into square cells (a foot by default), hexagons, a density or the zones of the house (the button, the three rings and the free guard zone), or drawn as translucent discs in each team's colour so that stones that fall on each other build up colour. It judges the stones by `curlingScore`'s rules, and keeps one team's stones (`team`), only the free guards or only the stones in the house (`only`); on the half, the house, the whole sheet or the folded sheet (`show`). The totals say how many stones were in play and drawn, the free guards and the stones in the house for each team, and the share in each zone. New: `CurlingHeatOptions`, `CurlingHeatTotals`, the `titleCurlingHeat`, `curlingHeatStat`, `sumCurlingHeat`, `curlingHeatTeam`, `curlingHeatGuards` and `curlingHeatHouse` words of `KYOGIJO_STRINGS[...].charts` (`en` and `ja`; a custom set of words must give them) and `CurlingOptions.show`, so that `curlingStones` can be folded too.
- **Curling statistics, beside `curlingScore`:** `curlingFreeGuards` (the free guards of a layout: a stone in play between the tee line and the hog line and not touching the house), `curlingInPlay` (the stones in play after each throw, and the most), `curlingHammers` and `curlingEndStats` (each end's record, and for each team its points, hammer efficiency, how often it scored, blanked, was held to one or was stolen from with the hammer, and its steal rate without it), `curlingGuardScores` (the free guard analysis: points against guards, by band, for the team with the hammer and the team without it) and `curlingShotStats` with `curlingIsHit` and `CURLING_HIT_TYPES` (shot percentage, hit rate and the types played). Pure functions of plain data. Written from the rules and from what curlovision and Jordan Myslik's curling analytics describe; nothing of either was copied (see [references](./docs/references.md#curling)), and [Curling](./docs/curling.md#what-other-curling-analyses-offer-and-what-is-here) compares what each offers with what is here.
- **`HeatLegend.region`** (and the same on a `legend` layer): a heat layer's colour bar is sized and placed against a part of the surface in feet instead of the whole of what is shown, so that it can be read on the half of a sheet or in an enlarged house.
- The docs' curling gallery has the folded sheet, the top end and the bottom end, the heat chart in each of its views and a game's ends in one picture; the demo has a Show choice for a curling sheet (whole sheet, top end, bottom end, folded) with finger-wide buttons, in English and Japanese, in the address and in the code it writes.
- **A realistic basketball floor** (`court: { hardwood: true }`, [docs/hardwood.md](./docs/hardwood.md)). The court seen from above as a maple strip floor: boards of one width (2.25 inches by default) running the length of the court, each row ending in different places from the rows next to it, each board with a tone of its own and fine grain along it, all laid from a seed (`seed`, 1 by default) with a generator of our own, so the same options give the same floor in every renderer; the keys, the centre circle and the border are stain, with the wood and the seams showing through (`stain`, 0.82 by default); the strip behind each baseline takes the colour of the team that defends it (`leftColor` and `rightColor`, a team's `color` in a score, or the new `baselineColor`); the baseline words are set in that strip and new `sidelineText` along the sides; `centreLogo` (an image or an SVG document) fills the centre circle; each basket is drawn from above with its backboard, rim, net and padded stanchion and a soft shadow; the coaching box's lines, the scorers' table and the two benches stand along the bottom sideline; and a satin sheen and the shade at the floor's edge are gradients over the paint (`sheen`). Every league of the sport takes it (NBA, WNBA, FIBA, NCAA men's and women's, NFHS, G League), wide and tall, in light and dark, with a score, a `range`, a `host`, and the data layers and charts over it. The detail drops at small sizes: `detail: "auto"` draws the plain floor (broad boards, the stain and the sheen, one shadow, no seams, grain, table or benches) for `detail: "simple"` or a `width` under 480 pixels, and `fine` or `plain` can be asked for. It is made only of patterns, gradients and rectangles, so the scene, the canvas, d3, Plot, GeoJSON and PNG renderers all draw it: the SVG is about 30 kB in the fine detail (the clean court's is about 11 kB) and about 15 kB in the plain, from two tiles of pattern and about 90 more shapes. Off by default, and a drawing without it is the same text as before. New: the options `HardwoodOptions` and `CourtStyle.hardwood`, `CourtStyle.baselineColor` and `CourtStyle.sidelineText`, `KYOGIJO_HARDWOOD_STYLE` (also in `KYOGIJO_STYLE`) and `HARDWOOD_SMALL`.
- The demo's court controls have a "Real hardwood" chip (a finger wide on a phone, in English and Japanese), and the court cards show the real floor in a club's colours and its plain version for small sizes; the docs gallery has the floor in nine drawings, each made from the code beside it.
- **Multi-sport places: the clubs that played in each ballpark and ground** ([docs/atlas.md](./docs/atlas.md#tenants)). `Place.tenants` lists the clubs that played their home matches in a place, each with its `club` (and `clubJa`), `league`, `sport`, first and last year (`from`, `to`), Wikidata item and `source` (the Wikidata statement, the article and revision, and which of the two the years were read from): 443 tenants (333 clubs) at 155 of the 158 places, 117 of them still there, among them the BC Lions and the Whitecaps at BC Place, the Expos and the Alouettes at the Olympic Stadium in Montreal, the Blue Jays, the Argonauts and the Raptors (1995 to 1999) at the Rogers Centre, the Giants and the Jets at MetLife Stadium, the Patriots and the Revolution at Gillette Stadium and the Seahawks, the Sounders and the Reign at Lumen Field. The clubs and their leagues are Wikidata's (CC0, the places' occupants P466 and the clubs' home venues P115) and the `tenants` lines of the infoboxes of the places' English Wikipedia articles (CC BY-SA 4.0, at the revision named); the years are Wikidata's where it has them and the article's otherwise, never guessed. `pnpm tenants:fetch` reads them and `pnpm tenants` builds `src/tenants.data.ts`.
- `tenantsOf(place, { year, league, sport, current })` (`/atlas`): a place's clubs, the current ones first; `placesByClub(name)`: the places a club played in, by its name in English or in Japanese, in full or by a word of it (`Whitecaps`, `ライオンズ`); `surfacesOf(place)`: every surface a place offers, its own first and then one for each sport a tenant plays that the package draws (the CFL's field for BC Place, the NFL's for MetLife Stadium, the NRL's for Stadium Australia); and `surfaceOf(place, sport)`: the surface a place offers for a sport (`surfaceOf(bcPlace, "cfl")` is `{ sport: "cfl" }`, `surfaceOf(fenwayPark, "cfl")` is `undefined`). New: `TENANTS`, the types `Tenant`, `TenantArticle`, `TenantSource`, `TenantSport`, `TenantFilter`, `PlaceSurface` and `SurfaceSport`.
- The demo's Atlas panel lists the clubs that played in a place with their league and years, offers a button for each other surface a place has (BC Place: the CFL field; the Olympic Stadium: the CFL field, the NFL field and the soccer pitch) that opens the playground on that sport, groups the league filter into the main leagues and tournaments and the rest, and finds a place by a club's name in English or Japanese; English and Japanese words for the new controls and for the leagues that have a Japanese name.
- **The 3D view hangs the score up as a scoreboard** (`score: "board" | "floor"` in the settings, `board` by default; [docs/turn.md](./docs/turn.md#the-score)). The badge of the score is put on a dark board that turns to face the eye: hung on cables over the middle of a court or a rink, standing on legs behind an end of a field, a pitch, a table or a curling sheet, behind centre field in a ballpark. The floor loses its panel and keeps the teams' names. This needs a new option for every drawing, `plate: false` (`ScoreOptions.plate`), which draws a score with the teams' places and no panel; on by default, and a drawing without it is the same text as before. New: `Plane.billboard`, `facing`, `scoreboard`, `UprightKind` `"scoreboard"`, `UprightOptions.score`, and the `scoreboard` word of `turn.parts`.
- **A 3D view: `@johnmorrisdotca/kyogijo-stadiums/turn`** ([docs/turn.md](./docs/turn.md)). Any surface as a floor that turns: the flat drawing itself (with its score, data layers and labels) tipped and turned by the mouse, a finger, Ctrl and the wheel or the keys, with four viewpoints (`overhead`, `broadcast`, `end`, `corner`; the broadcast view is turned a little to show the boards, nets and goals their faces, the net sports' is from behind an end line, where a net can be seen, and a curling sheet's is square on) and a reset, in plain DOM and CSS with no dependency. `mountKyogijoTurn(container, options, settings)` mounts it and gives back `view()`, `set()`, `preset()`, `reset()`, `update()`, `svg()` and `destroy()`; `<kyogijo-field turn turn-view="end">` is the element's way (`turn-controls`, `turn-uprights`, `turn-touch`, and `turn` and `turnSettings` properties); `turnMarkup(options, settings)` is the same view as a string, pure, for a server. Every part that stands up is a flat rectangle with a little SVG on it, and every element carries its whole place on the screen in one `matrix3d`, stacked far to near by `z-index`: nothing is nested in 3D (no `preserve-3d`), so Safari on a phone cannot flatten it, and the flat drawing stays where 3D is not available (`turnSupported`), with a sentence that says so. What stands on each surface, at the height the current rulebook gives (each read on 2026-10-13 and cited by rule number in [docs/sources.md](./docs/sources.md#heights-in-the-3d-view), with what is ours said to be): the NHL's glass is 8 ft over the boards at the ends and 6 ft along the sides, the NFL's uprights 45 ft, the CFL's 40 ft and the NCAA's at least 30 ft, rugby league's 16 m, a basket's board lower edge 150 mm under the ring (FIBA 1.1.5) and its stanchion 2 m behind the end line (FIBA 1.4.3).  the volleyball net at 2.43 m or 2.24 m (`netHeight: "women"`) with its posts and antennae, the nets and posts of tennis (and singles sticks), badminton, pickleball and table tennis (the table lifted 76 cm on legs), each basket's backboard, rim, net and stanchion, a rink's boards, glass and goals, the goals of soccer (with corner flags), handball, field hockey and lacrosse, the posts and pylons of football, the posts of rugby, Gaelic football and Australian football, a cricket pitch's stumps, and a ballpark's fence (as high as its walls), foul poles and backstop. `uprightsFor` and `describeUprights` give them as planes and as a sentence; the view's description says what stands in it, with its heights in the rulebook's own unit, in English and Japanese. A finger drags sideways to turn the view and leaves a vertical swipe to the page (`touch: "turn"` keeps every touch); the wheel is the page's unless Ctrl is held or the view is focused; the keys are the arrows, plus and minus, 1 to 4 and 0; the buttons are 44 pixels or more; a viewpoint, a reset and the end of a drag are said in a polite live region; with `prefers-reduced-motion` the view jumps instead of gliding. New: `mountKyogijoTurn`, `turnMarkup`, `turnMarkupOf`, `buildTurn`, `layoutOf`, `turnSupported`, `uprightsFor`, `describeUprights`, `planesOf`, `heightUnit`, `TURN_PRESETS`, `NET_PRESETS`, `TURN_PRESET_NAMES`, `KYOGIJO_TURN_STYLE`, the camera's `fit`, `project`, `cameraMatrix`, `clampView`, `drag` and `step`, the types `KyogijoTurn`, `TurnSettings`, `TurnView`, `TurnPreset`, `TurnModel`, `Uprights`, `UprightOptions`, `Plane` and the rest, the `turn` words of `KYOGIJO_STRINGS` (`en` and `ja`; a custom set of words must give them), and `pitchOf` is exported from the drawing's own module for it.
- The demo's playground has a View switch (Flat, 3D): the surface in 3D with the viewpoint buttons under it, the viewpoint in the address (`view=3d&viewpoint=end`), the 3D code in the code tabs; and `e2e/turn.demo.mjs` plays it in Chromium, on a phone and in WebKit.
- **Seven more court sports, and sitting volleyball** ([docs/courts.md](./docs/courts.md)), each drawn to scale from its governing body's own current rules, with its named looks (light and dark), a free zone where the rulebook gives one, simple and full detail, wide and tall, an outline, a description and labelled parts in English and Japanese, a frame, ranges, a score and a badge (`SPORTS` is now 27):
  - **`padel`** (the FIP's Rules of Padel, review of 1 January 2026): 20 by 10 m inside its walls, the service lines at 6.95 m, the central service line, the net, and the walls and metal fence of the enclosure.
  - **`squash`** (World Squash's Specifications for Squash Courts, 28 November 2017): the short line, half court line and service boxes of the floor, with the front wall laid flat beside it to show its tin, service line and front wall line; `league: "wsf-doubles"` and `"wsf-doubles-wide"` for the doubles courts.
  - **`racquetball`** (the IRF's Official Rules 2026-2028 and Court Specifications): 40 by 20 feet, the short line, service line, service boxes, drive serve lines and the broken receiving line.
  - **`sepaktakraw`** (the ISTAF's Law of the Game, 2013 edition, the one that could be read): 13.4 by 6.1 m, the centre line, four quarter circles, two service circles, the net.
  - **`teqball`** (the FITEQ's rules, 2026): the 3 by 1.5 m table and its net in the middle of a court of 16 by 12 m, the halfway line, the service lines, the surrounds.
  - **`roundnet`** (the International Roundnet Federation's rules, 2022): the set, the no hit zone line, the serving line and the four service positions, on a square with no out of bounds.
  - **`netball`** (World Netball's Rules of Netball, 2024): 30.5 by 15.25 m, the transverse lines, centre circle, goal circles and goalposts with their rings; scored as a goals sport, with the usual score and the home team on the left.
  - **`league: "wpv-sitting"`** of `volleyball` (World ParaVolley's Official Sitting Volleyball Rules 2025-2028): 10 by 6 m, the attack line at 2 m, a 7 m net 1.15 m high.
  - New zone sets `wall-court` (squash, racquetball) and `roundnet-rings`; `net-court` now covers padel, sepak takraw and teqball, and `field-thirds` netball. 36 coordinate frames (7 more), 7 more `half-court` ranges, and 7 more sports in the demo's picker, its gallery and the docs gallery, with the sources and licence notes in [docs/sources.md](./docs/sources.md) and [docs/references.md](./docs/references.md).
  - The colours follow the rulebooks where they give one: squash's lines are red (a dark red on the light floor, a pale red on the dark one; World Squash's specification asks only that markings contrast, clauses 5.01.01 and 10.13, so the red is ours) on the floor and the front wall, with the wall's lines drawn separately as the specification allows; racquetball's lines are the IRF's recommended bright red (blue on the convertible look) on a floor light enough to read them; padel's, netball's and sitting volleyball's lines are white as their rules prefer or require, and sitting volleyball has the wooden floor only (a light indoor floor, Rule 1.2.2).
  - Footvolley is not drawn: the only rulebook found that gives its dimensions is a European league's, not an international governing body's. Futsal is `pitch: "futsal"` of `soccer`, as before.
- **The stands and the crowd** (`crowd: true`, [docs/crowd.md](./docs/crowd.md)) on every surface that has spectators. Seating bowls drawn round the surface at the distance a venue of its kind keeps: a bowl, two sides (`sides`), a horseshoe open at an end (`horseshoe`, `open`), an oval round the oval grounds of Australian football and cricket, an arena's courtside rows with a lower and an upper bowl for the rinks and courts, and for a ballpark grandstands along the foul lines and behind home plate with bleachers behind the park's own fence (laid from `fenceOutline`, with a gap at the batter's eye), each stand on a plaza of its own. A soccer pitch in the stadium of an NFL or CFL club (`GRIDIRON_GROUNDS`, or `stadium: "nfl"` or `"cfl"`) keeps the football field's footprint: the stands stand where a football field's stands are and the 360 by 160 foot field is drawn faintly over the pitch (end zones, five-yard lines, dashed outline), so that the gap is seen to scale: the touchlines are 8.5 feet from the front rows, not the 28 to 36 of a ground built for soccer. The people are a seeded tile of 36 seats repeated as an SVG pattern, each seat empty with the probability the density leaves or a dot of shirt (the team's colour in two shades, or a neutral) with a dot of hair over it, so that the stands are a few shapes and a few kB (about 9 kB added to a soccer drawing, 4.5 kB as blocks) however many seats there are: `density` (0 to 1, 0.85 by default), or `attendance` over `capacity` (a ground's own capacity by default for soccer), `seed`, `home` and `away` colours (the teams' colours of a score, else the sides'), the visitors' block at an end or in a corner (`awayEnd`), a card display in stripes or checks behind a goal (`tifo`, `tifoDesign`), and a tunnel, a camera platform, benches and a media row on the bench side (`gaps`). Aisles and the shade of each tier's front wall and roof edge are drawn in the `fine` detail; for `detail: "simple"` or a `width` under 480 pixels (`detail: "auto"`) the stands are blocks of colour with no pattern. The drawing's ground is made as wide as the stands need (a `margin` of your own is kept). It works wide and tall, light and dark (the crowd is dimmer in the dark), as a score with its round marks, with `range` (a crop shows the stands it covers) and with the data layers over it; a special game (`host`) has none. The scene, the canvas, d3, Plot and PNG renderers draw it. `crowdStands(options)` gives the stands as data in feet in the surface's wide frame (rings with their outlines, `from` and `to`, the height of the first and last row, the rake in degrees, the seats; the visitors' and the card display's sectors; the gaps; the footprint; the reach), with `outlinePath` and `outlinePoints`, so that a view that raises the stands (the 3D view of `work/turn`) can use it: a follow-up. Off by default, and a drawing without it is the same text as before. New: `CrowdOptions`, `CrowdShape`, `CrowdStands`, `StandRing`, `StandSector`, `StandGap`, `StandOutline`, `GRIDIRON_GROUNDS` and `KYOGIJO_CROWD_STYLE` (also in `KYOGIJO_STYLE`; `--ky-cr-home` and `--ky-cr-away` are the crowd's colours).
- **The stands read as seats from above** (polish of the crowd). Row lines every second row follow each tier's curves, with aisles across every tier (square to the front on the sides, fanning round the corners) and every fourth a wider dark vomitory; the visitors' block and a card display are whole sections cut on aisle lines, not wedges (a wedge only round an oval ground); the walk between the tiers is a thin darker band (`concourses`) instead of a wide pale ring, and the roof's edge throws a shade on the upper tier (`roof`, on by default). A soccer pitch's run-off is the 6 metres along the touchlines and 8.5 behind the goal lines that stadium guidance recommends (19.7 and 27.9 feet, 27.7 on the bench side), so that a pitch in a gridiron stadium has the narrower apron at the touchlines (8.5 feet) and a wider one behind the goals (33.8). A ballpark's grandstand edge is a smooth curve with no notches, its bleachers stand 12 feet behind the fence, and where the park has seats on top of a wall (Fenway Park's Green Monster) a band of them runs along the wall at its height (`wallSeats`, `WALL_SEATS`). The stands data gains `aisles` on every ring and `concourses`, a wall's seats are a ring with the tier `wall`, and the tiers of an arena are 7 feet apart.
- The demo has a "Crowd" chip with a "Card display" chip and a "Seats taken" slider (finger-wide on a phone, in English and Japanese), for every sport, and the docs gallery has the stands in ten drawings (soccer in a bowl, soccer in an NFL stadium, a ballpark, an NHL arena, an NBA arena, curling and more), each made from the code beside it.
- **The pageant: each team's flag or crest laid large over its half of the surface, and an emblem in the centre** ([docs/pageant.md](./docs/pageant.md)). `pageant: "carpet"`, `"stage"`, `true` (a carpet) or `PageantOptions` on a score drawing, off by default, so a drawing without it is the same text as before. A **carpet** is the flag or logo laid flat over its half, filling the room the half gives it with a margin of about 5% (`fit: "fill"`, the default: its shape may differ from the flag's ratio by up to 1.75 to 1, the art stretched a little and cropped a little; `fit: "ratio"` keeps the flag's own ratio, `Team.logoRatio`, else the `viewBox` of an SVG logo, else 3 to 2), with a border band (`border`: `dark`, `team` or a colour; `borderWidth`), a soft shadow and a gentle fixed wave of light and shade (`fabric`); a **stage** is the crest on a large round disc with a ring (`ring`: `gold`, `team` or a colour), the crest a round mark inside it. A team with no flag or logo is its colours as a carpet of two with its name across a band, or its initials on its colour on a stage. `emblem` (an address, an image `data:` address or an SVG document as text: yours, none is supplied; `emblemShape` `round` or `plain`, `emblemFit`, `emblemName`) goes in the centre circle, centre ice, centre court, the middle of a field or sheet, or on the mound. Every surface has a place for the pictures: the halves, each side of a cricket pitch, a diamond's infield (home) and outfield (visitors), a curling sheet's two houses; each lies wholly inside the surface's outline (a rink's rounded corners, a fence, an oval). Tall and wide drawings lay the halves where the reader sees them and keep every picture upright. The score stays readable by `score`: `centre` (the plate stays, 15% smaller, and the pictures keep clear of it), `strip` (the compact strip under the drawing, carrying each team's round mark) or `auto` (the default: the strip with an emblem or a large board, else whichever leaves the pictures at least 70% of their width). `lines` is `over` (the default), `under` or `through` the pictures; `scale` and `names` size and name them; under 320 pixels wide or with `detail: "simple"` the fabric, hairlines and name pills are left out; dark theme has its own colours (`--ky-pg-border`, `--ky-pg-edge`, `--ky-pg-seam`, `--ky-pg-shadow`, `--ky-pg-disc`, `--ky-pg-groove`, `--ky-pg-light`); a `range` shows the carpet where the range shows it. `animate: "unfurl"` or `"fade"` is an entrance in CSS only, off by default, inside `@media (prefers-reduced-motion: no-preference)`. Every renderer draws it (the scene, canvas, d3, Plot, PNG); `sceneToGeoJSON` leaves it out, since the GeoJSON is of the surface. New: `Surface.pageant` and `centreRadius` (where a builder puts the pictures and its centre circle), `Team.logoRatio`, the `pageant` words of `KYOGIJO_STRINGS` (`en` and `ja`; a custom set of words must give them), `KYOGIJO_PAGEANT_STYLE`, `KYOGIJO_PAGEANT_MOTION`, the types `PageantOptions` and `PageantStyle`, the `pageant` attribute of `<kyogijo-field>`, and the root's `data-pageant`.
- The demo has "Flags on the halves" under Look: off, carpets or stages, the lines over, under or through, a made-up cup in the centre and the entrance, in English and Japanese, each a finger wide, in the address (`pageant`, `pageantlines`, `emblem`) and in the code it shows; the docs have a page and a gallery of a carpet and a stage on each of the twenty surfaces, the emblem, tall and small, the borders, the lines, a team with no flag, dark and a crop, with made-up nations and flags drawn in code.

### Added

- **Swimming, water polo, diving and artistic swimming** (`sport: "swimming"`, `"waterpolo"`, `"diving"`, `"artisticswimming"`; [docs/pools.md](./docs/pools.md)). Four pools, to scale, from World Aquatics' *Competition Regulations* in force as from 25 June 2025 (Part Two Article 16, Part Four Article 13 and Appendix 2, Part Six Article 18 and Appendix 4, Part Seven Article 27; the 2017 and 2021 Facilities Rules' numbers where they differ), each figure cited in [docs/sources.md](./docs/sources.md#the-pools): the swimming pool of 50 or 25 m and one to ten lanes (25 m wide for eight lanes of 2.5 m, ten lanes 0 to 9 with the end lanes 2.4 m, or the 26 m temporary pool) with its ropes (green, blue and yellow, red floats within 5 m of the walls, a distinct run at 15 and 25 m), the lane markings with their cross lines and the cross lines at 15 m, the touch panels and their target lines, the starting blocks with their lane numbers, the backstroke flags at 5 m and the false start rope at 15 m, and a warm-up pool without the competition fixtures; the water polo field of 25 by 20 m with its ropes and referees' platforms in red, yellow and green, the 2, 5 and 6 m lines, the goals, the goal areas, the re-entry areas, the table and the substitution areas; the diving well with the 1 and 3 m springboards and the 5, 7.5 and 10 m platforms (and the 1 and 3 m platforms) at the preferred distances of Appendix 2 from the walls and from each other, and the three lines across the well; the artistic swimming area (30 by 20 m, or 25 by 15 m with its 12 by 12 m deep part) with its floor lines and platforms. A score on any of them; the home team on the left in water polo.
- **The looks of the water and the deck** (`pool.look`: `flat`, `water`, `tiled`; `pool.deck`: `plain`, `tiled`; `pool.seed`). A flat, clean water by default; a faint net of light on the floor made from a seed (a few soft closed curves in one small repeating tile, the same seed the same light), a gradient across the lanes and, for `tiled`, the floor's tiles, all patterns defined once. Every named look has a palette for the pools, and the stylesheet carries only the rules a drawing uses.
- **A side section** (`pool.section`): the water and its depth (2.5 m for a 50 m pool, 2 m for a 25 m one, or your own), the blocks and panels, the flags 5 m from each end, the false start rope at 15 m, a lane rope at the surface and the least depth the rules ask near a wall with blocks, the height exaggerated and said so.
- **The lanes of a race** (`pool.race`): each swimmer in a lane with a name, three letters and a flag (an address, an image or SVG text you pass; the package bundles no flags), and, once the race is swum, places (a gold, silver or bronze disc for the first three, taken from the times when none is given), times, reaction times, splits, records and `dq`, `dns` and `dnf`. Plates at the starting and the turning end, an event title, and a description that says each lane in words, in English and Japanese. `pace` draws **split pace bars**: each lane the whole race laid flat, each split a bar as long as its share, in a colour from the field's slowest pace to its fastest, under a ruler of distances. A tall drawing lays the names and times along the lanes.
- **`raceTimeline`** (`@johnmorrisdotca/kyogijo-stadiums/replay`): a race replay by lane. The splits of a race become a timeline of the package's replay: each swimmer goes down the first length and back the next at the speed of each split, on the block until the reaction time, with the start, the turns and the finishes as events, in the new `swimming` frame (metres from the middle of the water). `drawFrame`, `mountKyogijo(...).replay` and `<kyogijo-field>` play it. `formatTime` and `parseTime` write and read times as swimming does.
- **`splitsChart`** (`@johnmorrisdotca/kyogijo-stadiums/charts`, [docs/charts.md](./docs/charts.md#the-splits-of-a-race)): the pace bars with a title, a summary, the numbers (`totals`, with the fastest split of the field) and a table of every split.
- **A natatorium** (`pool.venue: "natatorium"`, or `{ pools, apart, labels, seating }`): several pools in one hall, to scale, at least 8 m apart (10 m by default, as the rules keep a swimming pool and a diving well, CR 16.2.17), each drawn by its own sport's builder with the deck, the paint and the names once, and seating along the top. `venueLayout` gives the places.
- Ranges (`pool-end`, `springboards`, `platforms`, `centre-stage`, with `half` and `goal-area`), the zone sets `pool-lanes`, `water-polo-areas` and `pool-thirds`, the four frames, `landmarks` for every pool, features to colour (`water`, `lane-ropes`, `rope-red`, `touch-pads`, `starting-blocks`, `backstroke-flags`, `platforms`, `springboards` and more), `SWIMMING`, `WATER_POLO`, `DIVING` and `ARTISTIC` in `/geometry` (metres, any unit by `dimensionsOf`), and their words in English and Japanese. `Sport` and `SPORTS` grow from 20 to 24; the other twenty draw byte for byte as before.
- The demo has the four pools in its sport picker with the pool's own controls, a Pools section with a made-up race (nations that do not exist, flags drawn in code in `demo/pool-data.js`), the pace bars, a race replay and the natatorium; the docs have a [Pools](./docs/pools.md) page and a gallery page of them, each picture made from the code beside it.

### Added

- **`sport: "athletics"`: the athletics stadium** ([docs/athletics.md](./docs/athletics.md), `@johnmorrisdotca/kyogijo-stadiums/athletics`). The 400 m standard track of World Athletics' Track and Field Facilities Manual (2019) and Technical Rules (in force 1 July 2026): eight lanes of 1.22 m (4 to 9) with the running lines at Rule 14, the finish straight (6 to 10 lanes), the lane numbers, and the start lines of 20 races: the sprints and the hurdles on the straight, the staggers of the 200 m, 400 m, 400 m hurdles, 800 m and the relays, the 800 m's and the 4 x 400 m's breakline, the curved starts of the 1000 m to the 10,000 m and the mile with the group starts, the exchange zones of the 4 x 100 m and 4 x 400 m, and the steeplechase's lap with the water jump inside or outside the second bend. The staggers are worked out from the running lines' radii and the breakline's involute (not copied from the table) and a test holds them to Table 2.2.1.6a (200 m and 400 m within 0.6 mm, 800 m and 4 x 400 m within 2.5 mm). Every field event is in its place in the standard arena (high jump, pole vault, long and triple jump with their boards and pits, shot put, discus and hammer with the cage and the sector of 34.92 degrees, javelin with the 8 m arc and the sector of 28.96 degrees), each switchable with `events`, or alone at a large scale with `layout`. The infield is the soccer pitch (a preset or a size, or a ground's own) or plain grass; the track is red, blue, terracotta or green. `league: "world-athletics-short"` is the covered 200 m banked track of six lanes with a 60 m straight and its own stagger table; a `ground` that has a track draws the stadium with that ground's pitch (six grounds). New: `range: "start"` (a close-up of the start of `athletics.start`, turned so that the athletes run to the right, or up the page in portrait, with stencil lane numbers drawn as paths and lane-sized tags on a bend), `finish`, `bend`, `home-straight`, `back-straight`, `infield`, one range for each field event and `water-jump`; the look `line-drawing` (ink only: black on white with outlines for the track, pits and mats, white on black in dark mode); the frame `athletics` (metres from the middle of the track); the zone set `athletics-track`; the `athletics` words in English and Japanese; `KYOGIJO_ATHLETICS_STYLE` and `KYOGIJO_TRACK_STYLE`.
- **Athletics data charts** (`@johnmorrisdotca/kyogijo-stadiums/athletics`): `laneDraw` (the names and flags on the lanes of a start, at each lane's stagger, with the flags passed as SVG), `raceResults` (places as medal discs, times, reaction times and splits), `raceReplay` (a timeline for the replay: each runner on the curve of his lane from his lane's start line by his reaction time, splits and finish time) and `fieldMarks` (a throw or jump as a mark where it landed, a foul at the line and the best valid mark picked out). The entry also exports the plan, the track's geometry (`stagger`, `breaklineStagger`, `lap`, `pose`), the races and field events (names in English, Japanese and French) and the figures.
- **`sport: "skating"`: the skating rinks** ([docs/skating.md](./docs/skating.md), `@johnmorrisdotca/kyogijo-stadiums/skating`). The ISU's standard 400 m speed skating track (`league: "isu-long-track"`, the default): two lanes (the inner 4 m, the outer 4 m or more), the inner curve of 25 m to 26 m and the straight that makes a lap 400 m (113.57 m, 112.00 m, 110.43 m for 25 m, 25.5 m, 26 m, as the ISU's table has them), the warm-up lane, the lanes' fully painted lines, the blocks of the curves (50 cm apart for the first 15 m, 2 m after, a cone at the entrance), the coaches' area on the crossing straight, the padding, the finishing line with its metres and the starting lines of the 500 m to the 10,000 m, the mass start and the team races: each lane's line worked out from the race's distance back from its finish along the skater's own way (the lane changed once a lap, not on the first straight of the 1000 m and the 1500 m) and held to the layout plan's own dimensions (6.32 m, 6.25 m, 7.32 m, 12.57 m). `league: "isu-short-track"` is the oval of 111.12 m on a rink of 60 by 30 m or more with seven blocks in each curve, five or seven tracks with their starting lines, the finishing line and the five starting positions of the 500 m and the 1000 m; `league: "isu-figure"` the rink of 60 by 30 m (56 by 26 m at the least) with the judges' and the referee's seats at the rinkboard, the technical panel and the kiss and cry. `skating` options: `innerRadius`, `laneWidth`, `warmUp`, `infield`, `blocks`, `coaches`, `padding`, `races`, `start`, `tracks`, `rink`, `furniture`. New: the ranges `crossing-straight`, `first-bend`, `second-bend`, `judges` and `kiss-and-cry` (and `home-straight`, `bend`, `finish`, `start`, `infield` and `half` for the rinks that have them), the frame `skating`, the zone set `skating-track`, the `skating` words in English and Japanese, `KYOGIJO_SKATING_STYLE`. The rinks take the hockey rink's colours in every look.
- **Skating data charts** (`@johnmorrisdotca/kyogijo-stadiums/skating`): `skatingPairs` (a pair's names and flags on the lines of their lanes, the armbands white and red), `skatingGrid` (the starters of a short track race on the five positions), `skatingResults` (medals, times, splits along the lane, lap times in the table), `skatingReplay` (a timeline: each skater on his own way, the lane changed on every crossing) and `figureElements` (a jump, a spin, a step sequence and the other elements of a programme as marks on the ice, the track of a sequence as a line).
- The docs have a page for the stadium, a gallery of it (52 pictures, each made from the code beside it) and the athletics rows of the sources, references, notice, limits, ranges and frames pages.

### Fixed

- **`toPNG` no longer stops the process on a drawing cropped to a range.** resvg (the PNG renderer) panics on a shape with an opacity below 1 that lies wholly outside the viewBox, as the net of a soccer goal does in the `penalty-area` and `defensive-third` ranges: `toPNG` now leaves out the shapes wholly outside the frame (they paint nothing). A test renders every named range of every sport and league, wide and tall, to a PNG.

### Changed

- **A club's name in Japanese is the one Japanese media say.** Wikidata's label is a Japanese Wikipedia page title, and for 33 clubs it is a long transliteration of initials or of a formal name (`ブリティッシュ・コロンビア・ライオンズ`, now `BCライオンズ`; `インテルナツィオナーレ・ミラノ`, now `インテル・ミラノ`), a title with a disambiguator or "history of" (`ボルチモア・コルツの歴史`) or the club's name in another period (`OLレイン`). `scripts/tenants.names-ja.json` holds the everyday form of each, with its kind and a source note, and `Tenant.clubJa` is that form; Wikidata's label is kept in the new `Tenant.aliasesJa`, so a search by it still finds the club. `TENANT_JAPANESE_NAMES` and `nameJaOf` (`/atlas`) give the table and the note on a tenant's name.
- The named looks (`look: "night"` and the others) write one more selector for each sport of the court group into the drawing's style, so a drawing with a look has a longer style text than before; the drawing itself is unchanged.
- The name a reader sees is Kyogijo Stadiums (`競技場` in Japanese): the demo's title, the docs site, the API page, the README and the package description. Code names (`drawKyogijo`, `<kyogijo-field>`) are unchanged.
- The indoor volleyball court shows its centre line: it runs under the net (FIVB Rule 1.3.3) and the net was drawn over it, so only a dark bar showed. The line now shows between the net's edges. The court's other lines were already all there (the boundary, both attack lines, the attack lines' extensions and the service zone's marks in the full detail); the beach court has only its four boundary lines, as the beach rules say.
- The demo's year switch in the atlas is a finger wide before its words arrive, in WebKit too.
- The badminton court's labelled parts use the BWF's words: the line inside the back boundary is the "Doubles long service line" (it was "Long service line", which in singles is the back boundary line itself), and the back boundary line says it is the singles long service line (Diagram A). The short service line's label no longer runs into the net's. An audit of every net sport's figures against the current rulebooks (ITF 2026, FIVB 2025-2028, BWF as amended 26 April 2025, USA Pickleball 2026, ITTF 2026) found no figure to change.

### Fixed

- **The badge's code and score no longer touch.** A 3-digit score (`101`) in the badge and in the strip of a compact card sat 8 units from the team's code (`101CAL`, `AUR99`). The score is measured with the package's text width, the code and the score keep a gap of 10 (the estimate is widened by a tenth for digits and a fifth for capitals, which is what a bold face draws), the code shrinks first (to 12 at the least), then the score, and the flag is left out when the room still runs out, at any width since the strip scales as one drawing. A short score is laid out as before, and no existing drawing changed.
- **BC Place read "FIFA World Cup, FIFA Women's World Cup" only, though it is the BC Lions' home (the CFL, since 1983) and the Whitecaps' (MLS, since 2011).** A place was known through one list, with only the tournaments it staged or the club of its park, so a stadium of two sports showed one. `Place.leagues` now has the league of every club that played there, then the tournaments; `placesBy({ league: "CFL" })` finds BC Place and the Rogers Centre, and `placesBy({ text })` finds a place by a club. A drawing of a place that has no other surface, or of a place's own surface, is the same text as before.

## [0.4.0] - 2026-10-14

Previously `@johnmorrisdotca/kyogijo`; renamed in 0.4.0 to `@johnmorrisdotca/kyogijo-stadiums`.

### Added

- **`roadToFinal`: the road to a tournament's final** (`@johnmorrisdotca/kyogijo-stadiums/charts`, [docs/charts.md](./docs/charts.md#the-road-to-the-final)). The two finalists as large round marks with their names; down the middle the rounds, the last at the top, on a dotted road; on each finalist's side its matches, each as the round mark of both teams with the score between them in large type and FT, AET or the shoot-out under it; and the group stage as a row of small marks, three-letter codes and scores at the foot. A finalist is a `Team` with a `path` of `{ round, opponent, score, decidedBy, pens, homeFirst, note }` and an optional `group`; a round is a key with words in English and Japanese (`round-of-32` to `semi-final`) or any key named in `labels`, so a play-off series (`4-2`) draws as well as a knockout. `final` writes the final's score between the large marks and quiets the loser; `winner` makes the side that won each match brighter; `codes`, `endnote`, `groupLabel`, `theme`, `language` and `style: "none"` as in the other drawings. Four sizes: `card` (1080 by 1350), `square` (1080 by 1080), `wide` (1200 by 675, the finalists at the two ends) and `phone` (390 wide, as tall as the rounds need), listed in `ROAD_SIZES`. It gives back a chart's shape without layers: `options`, `title`, `summary`, `totals` (each finalist's record, the rounds, the champion), `draw(extra)` and `table()`, a row for every match. The SVG is `role="img"` with a title and a description, reads in the scene and every renderer, goes in a `drawGrid`, and has ids of its own; a team with no flag or logo is drawn as its initials on its colour. New: `KYOGIJO_ROAD_STYLE`, the types `RoadChart`, `RoadFinalist`, `RoadMatch`, `RoadGroupMatch`, `RoadFinal`, `RoadOptions`, `RoadScore`, `RoadDecided`, `RoadSize`, `RoadSizeInfo`, `RoadRecord` and `RoadTotals`, and the `road` words of `KYOGIJO_STRINGS` (`en` and `ja`; a custom set of words must give them).
- **A round team mark in a score** ([docs/score.md](./docs/score.md#round-marks)). `mark: "round"` on a team, or `markShape: "round"` on the score, draws its flag or logo clipped to a circle with a thin ring, on each side of the surface (the end zones of a pitch, the halves of a court), in the badge and in the strip of a compact card; where the words are turned (along the ends of a wide pitch, in a tall drawing) the mark turns with them (0.6.1 and before turned it back to stay upright, which left a flag standing beside a name that lay sideways, and sideways in a tall drawing). A round mark with no logo is the team's initials on its colour; `markFit: "contain"` shows a crest whole on a plain disc. Off by default, and a drawing without it is the same text as before. New: `Team.mark`, `Team.markFit`, `ScoreOptions.markShape`, the type `TeamMark` and `KYOGIJO_MARK_STYLE` (`--ky-mark-ring`, `--ky-mark-edge`, `--ky-mark-plain`); a drawing writes the rules in only when it has a round mark.
- The demo has a "Road to the final" section with made-up nations (sixteen that do not exist, each with a simple flag drawn in code in `demo/road-data.js`), a play-off series, and the round mark on a pitch, in English and Japanese; the docs gallery has the same drawings, each made from the code beside it.

### Changed

- **Breaking: the package is now `@johnmorrisdotca/kyogijo-stadiums`** (it was `@johnmorrisdotca/kyogijo`, whose last version is 0.3.0). The code is the same, and so are the names in it: `drawKyogijo`, `mountKyogijo`, `<kyogijo-field>` and the `kyogijo` class are unchanged, and the product is still Kyogijo (`競技場`). What changes is where it is installed and imported from: `npm install @johnmorrisdotca/kyogijo-stadiums`, `import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums"`, and the same for every entry (`/charts`, `/replay`, `/layouts` and the rest) and for the CDNs (`https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kyogijo-stadiums@0/+esm`). The repository is now `github.com/johnmorrisdotca/kyogijo-stadiums` and the demo `johnmorrisdotca.github.io/kyogijo-stadiums/` (the old repository address redirects; the old demo address does not). The demo keeps its choices of language and theme on the device under `kyogijo-stadiums.page.lang` and `kyogijo-stadiums.theme` (they were `kyogijo.`), so each visitor is asked once more. The family's template (`scripts/family-template.mjs`, version 2026-10-14) names the package `kyogijo-stadiums` in the footer and in every package's list of the family.
- **The demo's Ballparks section is short, with filters, and there is a Soccer grounds section like it.** All 94 park cards in one grid made a section 2,200 px tall on a desk and 6,000 px on a phone. It now opens on the MLB parks in use today (30), as two rows of eight on a desk and one row that scrolls sideways on a phone (a row keeps the section to one screen, and the next card shows at the edge to say it scrolls), with "Show all 30 parks" under them: 640 px on a desk and 580 px on a phone. Above the cards are the league (All, MLB, NPB), whether a park is in use (All, Today, Past), the era (a decade, for the past parks), a search that reads every name a park has had, in English and in Japanese (`placesBy`: `Camden Yards`, `甲子園`, `ヤンキースタジアム`; the filters are off while it is typed, so it reaches every park), a count line in a polite live region (`30 of 94 parks`) and a reset. The grounds have the same: the grounds of the World Cup finals open (28 of 64), with group (finals, 2026, clubs), country and search, and the section is no taller. The filters are in the address under their own names (`parkleague`, `parkstatus`, `parkera`, `parkq`, `parkall`; `groundgroup`, `groundcountry`, `groundq`, `groundall`), written only when they are not the default. The build draws the default view of both sections into the HTML, so they are whole with scripts off and move nothing when the script takes over; the e2e tests hold that (a layout shift of 0 with the sections in view) and cover the filters, both searches, show all, the address, the phone and the desk. The package is unchanged.
- **The demo's Every sport and The soccer pitch sections are short too, with chips.** The sport gallery was 4,451 px tall on a desk and 11,941 px on a phone, and the pitches section 3,236 px and 8,455 px, because every card drew tall. They now open on the first cards, wide, in boxes of one shape: two rows of three on a desk and one row that scrolls sideways on a phone with the next card peeking (738 and 458 px for the sports, 755 and 509 px for the pitches), with chips for the family of sport (Football codes, Hockey, Basketball, Baseball, Soccer, Curling, Net sports, Field sports) or the kind of pitch (Presets, Small-sided, Futsal, Famous grounds, Layouts, Mowing and goals; the mowing cards joined the pitches, with 5- and 9-a-side), a count that a screen reader hears, "Show all", and the chips in the address (`galleryfamily`, `galleryall`, `pitchesgroup`, `pitchesall`), English and Japanese. The first view is drawn into the page, and the cards a desk does not show first are boxes that the script draws when the grid comes near the screen, so the page does not carry a drawing of every card and nothing moves when one arrives (the same for the Ballparks and Soccer grounds).
- **Breaking: soccer, rugby (union and league), Australian football, Gaelic games, field hockey, handball and cricket now put the home team first (left) by default; pass `homeSide: "right"` for the old layout** ([docs/score.md](./docs/score.md#which-side-the-home-team-is-on)). The default was the North American "away at home" for every sport, which reversed a soccer score against "Home 2-1 Away". NFL, CFL, IFAF, NHL, NBA, MLB, curling, the net sports and lacrosse (except the `world-men`, `world-women` and `world-box` leagues, which are home first) keep the home team on the right. An explicit `homeSide` always wins. The badge, the compact strip, the order of the teams in the title and the description (`Calvara 1, Aurelia 2`, in Japanese too) and of a shoot-out in the status (`Final · 2-4 pens`) follow the side. New: `homeSideFor(sport, league?)`, and the `HOME_FIRST` and `HOME_FIRST_LEAGUES` tables behind it. `abbreviate()` now says that its guess is not a country code (Spain gives `SPA`, FIFA's is `ESP`): pass each national team's `abbr`.

### Fixed

- **The demo's first paint is whole.** The stage was a thin bar and every panel an empty box until the script ran, then the page jumped (a layout shift of 0.5). The build now draws the playground's first view into the HTML: the default rink, every English word, and the controls in their first state, so the page reads and shows its drawing with scripts off, and the script takes over the nodes that are there. The stage keeps its box from the first byte (its shape, by the drawing's width over its height), and an address that asks for another sport, size or way round has its box, rows and pressed choices set by a small inline script before anything is drawn, so the drawing swaps in place; a page opened in Japanese (the address, a kept choice or the browser) is held back, invisible but laid out, and shown in Japanese rather than English first. The docs, the gallery and the API reference have their header, footer and search words in the HTML too, and set `lang` before paint. The layout shift on load is 0 at every address and width tried (0.003 at most, for a past season whose notes are drawn by the script), and the e2e tests hold it under 0.05. The package is unchanged.

## [0.3.0] - 2026-10-14

### Added

- **Names for every park and ground** ([docs/ballparks.md](./docs/ballparks.md#names), [docs/grounds.md](./docs/grounds.md#names), [docs/references.md](./docs/references.md#names)). Each of the 94 ballparks and 64 grounds has `name`, the everyday name in English (the one English sports media use, with the current sponsor's where that is what people say); `nameJa`, the everyday name in Japanese (every place has one: the 74 ballparks of the United States and Canada, which a Japanese drawing used to name in English, now have the title of their Japanese article); `readingJa`, its reading in kana wherever it has kanji; `localName` and `localLanguage`, the everyday name in the language of the place; and `aliases`, `{ name, lang, kind, from?, to?, source?, revision?, reading? }`: 720 names, each with where it was read, of the kinds `wikipedia` (every article that was cited, English and Japanese, with its revision, so that no citation is lost), `official`, `sponsor`, `former` (with the years a source gives) and `nickname`. The evidence is Wikidata's labels, aliases and properties official name, nickname and name (CC0), read politely by `pnpm names:fetch` into `scripts/names.wikidata.json`, and the infobox and first paragraph of the articles each place cites; a name with no source stops the build. A ground's `names` (the names it had in some years) are as before.
- **Lookups by name**: `parkByName` and `parksByName` (`/parks`), `groundByName` and `groundsByName` (`/grounds`), and `placeByName` and `placesByName` (`/atlas`) find a place by any of its names, in English, in Japanese or in the language of the place, best match first (the everyday names, then the official, cited and sponsors' names, then the former names and the nicknames). The comparison, `plainName`, ignores case, accents, spaces and punctuation, full-width and half-width, hiragana and katakana, the long vowel mark (`ヤンキー・スタジアム` is `ヤンキースタジアム`), the old and new forms of `ヂ`, `ヅ` and `ヴ`, and a leading `The`. The atlas search (`placesBy({ text })`) reads the aliases and the readings too. `officialName`, `parkOfficialName` and `groundOfficialName` give the name a place officially has when it is not the everyday one.
- A drawing says the official name in its description when it is not the name it uses: `Its official name is Hanshin Koshien Stadium.`, `正式名称は阪神甲子園球場です。` (`said.officially` in `KYOGIJO_STRINGS`), in the year of the drawing where the official name is dated.
- The demo's Atlas detail panel lists the official name and the other names (`atlasOfficial`, `atlasAlso`), and its search finds them.

### Changed

- **Breaking: `name` is the everyday name, no longer the title of the article that was cited** (that title is an alias with kind `wikipedia`). Seven English names changed: `hanshin-koshien-stadium` is `Koshien Stadium` (was `Hanshin Koshien Stadium`), `mazda-stadium-hiroshima` `Mazda Stadium` (was `Mazda Zoom-Zoom Stadium Hiroshima`), `rakuten-mobile-park-miyagi` `Rakuten Mobile Saikyo Park Miyagi` (was `Rakuten Mobile Park Miyagi`, the name until 2025), `globe-life-park-in-arlington` `Choctaw Stadium` (as its article is titled now), `olympiastadion-munich` `Munich Olympic Stadium`, `olympiastadion-berlin` `Berlin Olympic Stadium`, and `groupama-stadium` `Groupama Stadium` (was `Parc Olympique Lyonnais`). `nrg-stadium` stays `Reliant Stadium`: its article says it was renamed back from `NRG Stadium` on 1 August 2026, and `NRG Stadium` (2014 to 2026) is a dated name and a `sponsor` alias.
- **Breaking: `nameJa` is the everyday name in Japanese**, as Japanese media say it where the Japanese article says which. Thirteen changed: `甲子園球場` (was `阪神甲子園球場`), `神宮球場` (was `明治神宮野球場`), `マツダスタジアム`, `エスコンフィールド北海道`, `楽天モバイル 最強パーク宮城`, `日産スタジアム` (was `横浜国際総合競技場`), `マラカナン`, `エスタディオ・モヌメンタル`, `ドイチェ・バンク・パルク`, `グルパマ・スタジアム`, `サン・シーロ`, `エティハド・スタジアム` and `カシマサッカースタジアム`; the old names are aliases (`official` or `wikipedia`). `ParkData.nameJa` and `Place.nameJa` are no longer optional: code that builds a `ParkData` or a `Place` of its own must give one.
- **Breaking: `Ground.nameLocal` is now `localName`**, and it is the everyday name in the language of the place (`San Siro` for the Meazza, `Maracanã`, `La Bombonera`, `Лужники`, `日産スタジアム`), not the name of the local article (the official ones are aliases). The parks of Japan, Montreal's two, and every ground outside the English-speaking world have `localName` and `localLanguage` too.
- **Breaking: the SVG written by `drawKyogijo` changes.** The English drawing of 15 grounds and 13 ballparks differs from 0.2.0's (the name, or the sentence that says the official name), and so does the Japanese drawing of every sport wherever it uses a word the native read of the Japanese settled (see below); every drawing's `data-version` reads `0.3.0`, which also changes the ids that are made from it. A stored copy of an old drawing, or a snapshot test of one, needs to be made again.
- **A native read of every Japanese string**, one terminology for the whole package: `ペナルティー` with the long vowel, as the JFA writes it (`ペナルティーエリア`, `ペナルティーアーク`, `ペナルティーマーク`, `ペナルティースポット`), `ウイング`, `本塁` for home plate (was `ホームベース`), `ゴーリー` for the goaltender, `国際標準` for the FIFA pitch, `BCプレイス`, `ゲーリック・ゲームズ`, `中堅正面` for dead centre, `ゴール裏` for behind the goal line, `フェアゾーン` and `ファウルゾーン`, `ゲームごとのスコア`; ranges are written with `〜` (was the full-width tilde `～`), and a size gives its unit once, `105×68m` (was `105m×68m`). English output is unchanged.
- The drawings that changed on purpose: the English drawing of 15 grounds and 13 ballparks (the name, or the sentence that says the official name) and the Japanese drawing of 8 grounds and 84 ballparks (the 74 of the United States and Canada, named in katakana now instead of in English, and 10 of Japan); a test holds every other drawing, in English and in Japanese, to the bytes it had.
- The demo's help text for the sport selector names all 20 sports, in English and in Japanese (it listed 14).
- The demo's Japanese status choices read as the status the drawing prints (`試合終了（延長）`, `試合終了（SO）`, `試合終了（延長戦）`, `試合終了（PK戦）`), and its Japanese page titles and labels follow the same terminology.

### Fixed

- **Spoken times in Japanese read as the time of day.** A replay's length and an event's time were said as `0:12` and `1:12`, which a Japanese reader takes for a clock; they are `12秒` and `1分12秒` now (`replaySpoken`, and the new strings `replay.spokenSeconds`, `replay.spokenMinutes` and `replay.spokenHours`, which a custom set of words must give). English still says `0:12`.
- **A convex hull's area unit was `平方m` in Japanese.** The unit is a word of the language now, `平方メートル`, `平方フィート` and `平方ヤード` (`team.squareUnits`, `team.squareOther`; `team.hullItem` takes the whole unit, `{unit}`, not `square {unit}`). English reads as it did.

## [0.2.0] - 2026-10-14

### Added

- **Layouts: small multiples** (`@johnmorrisdotca/kyogijo/layouts`, [docs/layouts.md](./docs/layouts.md)). `drawGrid(cells, { columns, gap, title, subtitle, endnote, legend, width, height, preset, background, language, theme })` puts many drawings in one SVG, as mplsoccer's `grid` does for pitches: one per park, per period or per player, under a shared title and subtitle, over a credit line, with a key they share. A cell is the options of `drawKyogijo`, a drawing's SVG, a chart, or `{ drawing, label }`. Every drawing keeps its own title and description and gets ids of its own (the same drawing may appear twice, and each rule scoped to an id follows it); the group has a title and a description made from them; the base stylesheet is written once. `preset` fits a social card (`card`, 1200 by 675), a square post (`square`, 1080 by 1080) or a phone (`phone`, 390 wide, one column, as tall as the drawings need); the columns are the number that makes the drawings largest. The scene and every renderer read a grid like any drawing. English and Japanese words for the group's title and description, and a test of every sport, every preset, ids, bounds and renderers.
- **Backgrounds** (`background` in the options of a drawing, and of a grid). A pattern drawn in SVG, with no image and no random number (`felt`, `grass`, `wood`, `ice`, `paper`, `grid`, `dots`), in the drawing's own ink at a low opacity so that it follows light and dark, laid on the apron under the surface; a colour under it; and a photograph (`image`, held to the rules of a team's `logo`, `imageOpacity`, `imageFit`) as an `<image>` between the two. Without a background a drawing is byte for byte as before. The canvas renderer cuts a photograph that fills the ground (`slice`) at its edges.
- **Runnable gallery examples.** Every picture of the gallery has a link to download the drawing as an SVG file and an "Open in a page" link to one HTML file, made when the site is built, that shows the picture, runs the snippet against the package on jsDelivr (`@johnmorrisdotca/kyogijo@<major>/+esm`, with the entries imported as `<major>/charts/+esm` and so on) and keeps the build's picture when the published package has no such feature. No third-party sandbox is used, and the page says that jsDelivr serves only published versions. A test runs every page's script against the source. A gallery page of layouts and backgrounds.
- **Lacrosse, rugby, Australian football, Gaelic games, cricket, field hockey and handball** (`sport: "lacrosse"`, `"rugby"`, `"afl"`, `"gaelic"`, `"cricket"`, `"fieldhockey"`, `"handball"`, [docs/field-sports.md](./docs/field-sports.md)). Each surface to scale from its own current rulebook, every figure cited, rule by rule, in docs/sources.md: World Lacrosse's men's and women's fields and box floor (2025 to 2028), the NCAA's men's and women's fields, the PLL's field (its 2024 book, the newest found) and the NLL's floor; World Rugby's Law 1 (2026), the NRL's (2023) and the IRL's (2024) playing fields; the AFL's Law 3 (2026), as an oval cut at its ends, with six named grounds at the length and width the AFL's venue pages print; the GAA's Rule 1 for football and hurling (2026); the pitch, creases and wickets of the Laws of Cricket (4th Edition 2026) in a ground with a boundary of your own and the ICC's 30-yard circle (October 2026); the FIH's pitch (March 2026) and the IHF's court (1 July 2025). 7 sports, 7 lacrosse leagues, 3 rugby, 2 Gaelic, 3 cricket (`LEAGUES`), the option `field` (`length`, `width`, `inGoal`, `ground`, `boundary`, `circle`: a size within the range each rulebook allows, an error that says the range when it is outside), `FIELD_SPORTS`, `fieldPlan` and `AFL_GROUNDS`.
- **The field sports' scores**: Australian football's `goals` and `behinds` written `10.12 (72)` and Gaelic games' `goals` and `points` written `2-14 (20)`, the total worked out; a cricket board of runs for wickets, overs and each innings (`wickets`, `overs`, `innings`, the status `innings-2`), with the sentences for each in the description.
- Ranges for the field sports (`in-goal`, `twenty-two`, `twenty`, `crease`, `forward-fifty`, `centre-square`, `large-rectangle`, `pitch`, `circle`, `twenty-three`, `goal-area`, with `RangeInfo.leagues` for a range that only some leagues mark), the zone sets `field-thirds` and `cricket-ground`, the frames `lacrosse`, `rugby`, `afl`, `gaelic`, `cricket`, `fieldhockey` and `handball` (the centre of the surface as the origin), landmarks, features (`FEATURES.rugby` and the others), the goal styles for lacrosse, field hockey and handball, `KYOGIJO_FIELDS_STYLE` (the colours of a handball floor and a hockey pitch), a gallery page and English and Japanese words for all of it. The other 13 surfaces' drawings are the same text as before.
- **Walls and quirks of a ballpark** (`walls`, `quirks`, `parkWallsIn`, `parkQuirksIn`, `Park.walls`, `Park.quirks`, [docs/ballparks.md](./docs/ballparks.md)). `walls: true` draws a band outside each stretch of a park's fence whose width and shade (four, light and dark, `KYOGIJO_WALLS_STYLE`) say how high it stands, from the height its article gives (35 parks, 24 of MLB and 11 of Japan: the Green Monster 37 feet 2 inches, the Little Green Monster, the Crawford Boxes, Oracle Park's 24 foot right field wall, the Baggie, Wrigley Field's ivy walls), for the season `year` names; `walls: { legend: true, labels: true }` adds a key and each wall's name and height, in feet or metres, in English or Japanese, and the description lists them. `quirks: true` draws Tal's Hill (2000 to 2016), the Polo Grounds' and Tiger Stadium's overhangs, Pesky's Pole, the Tiger Stadium flagpole, the Polo Grounds' bullpens, Wrigley Field's ivy and basket, the distance to the backstop (43 parks) and the sides of four parks' dugouts; `quirks: { only, labels }` chooses and names them. The element reads `walls` and `quirks`. The data is `walls`, `quirks`, `labels`, `track_ft`, `backstop_ft` and `dugouts` in `scripts/parks.data.json`, each at the revision the park already cites; the angles each stretch covers are our reading of the article's words (docs/references.md), a park whose article gives no figure keeps its drawing, and without the options every park's drawing is byte for byte what it was (a test holds the hash of 90).
- **More points of a fence, and a warning track.** Wrigley Field's two wells (9 points, not 5), Sportsman's Park's twelve markers (not 6) and Milwaukee County Stadium's nine (not 7) are read from their articles' text, each with its label in `Park.labels`; PNC Park's warning track is its published 18 feet and not the rule of thumb of 15. These four parks' drawings change; the other 90 do not.
- **Display ranges and zoom** (`range`, `RANGES`, [docs/ranges.md](./docs/ranges.md)). A drawing cropped to a named part of any of the thirteen surfaces, as sportypy's `display_range` and hockey_rink's partial rinks do, in one option: a rink's `offensive-zone`, `defensive-zone`, `neutral-zone` and `half`; a court's `half-court` and `paint`; a football field's `red-zone`, `between-the-20s`, `end-zone`, `field-of-play`, `own-half` and `opponent-half`; a pitch's `half`, `final-third`, `defensive-third`, `middle-third` and `penalty-area`; a ballpark's `infield` and `outfield`; a net sport's `half-court`; a curling sheet's `sheet`, `half` and `house` (which `sheet.show` and `sheet.end` keep saying); at the end `{ name, end }` asks for, or a box `{ x0, x1, y0, y1 }` in the drawing's frame, in `units` or in any registered frame. The view is cut with a small margin and the orientation is kept; data and heat layers are cut to the range and sized, laid out and binned against it, with the legend inside; `axes`, `landmarks` and `direction` stand against what is shown, on the apron beyond the cut; a score's panel is moved inside the range or, for one too small to hold it, becomes the strip under the drawing, and a team's name is written only where its place is shown. The description says what is shown, in English and Japanese, and the root carries `data-range`. `<kyogijo-field>` reads `range` and `range-end`. Without `range` the drawing is byte for byte what it was, and a test holds every named range of every sport, wide and tall, with data, annotations and a score.
- **Special games** (`host`, `placement` and `event` in the options, `@johnmorrisdotca/kyogijo/events`, [docs/special-games.md](./docs/special-games.md)). One surface set inside another, to scale: the host (a ballpark of `PARKS`, a soccer ground or pitch, a football field, or a plain deck) drawn as it is alone, and the drawing's own surface set inside it through one transform, so that its lines, its team banners, its score and its data `layers` are the inner surface's, in its own frame. `EVENTS` holds 18 games in the order they were played, each with its day, its venue, its host, where the surface stood and its sources: the NHL's Winter Classics of 2009, 2010, 2017, 2018, 2019, 2022 and 2023, the Stadium Series of 2014 at Dodger Stadium and Yankee Stadium, the Heritage Classics of 2003, 2011, 2014, 2016, 2019 and 2023, the 2011 Carrier Classic on USS Carl Vinson, and MLB's London Series of 2019 and 2023 with their published fences. Where a source gives the rink's place (Wrigley Field 2009, Fenway Park 2023) it is used and cited; where none does the place is a convention (`midfield`, `infield`, `diamond`, `deck`, worked out by `conventionPlacement`) and each game says so. `eventOptions(id)` draws a game, `eventFit(id)` says whether its surface lies inside the host or how much of it lies beyond, and a drawing of a game says so in its description, in English and Japanese. A drawing with no host is the same string as before.
- **Renderers** ([docs/renderers.md](./docs/renderers.md)). The drawing as plain data and on other targets, from the code that writes the SVG, with no second drawing and no dependency added: `sceneOf` (`@johnmorrisdotca/kyogijo/scene`) lists every shape in paint order with its colours worked out for light or dark, its matrix, clips, gradients and patterns, and `sceneToSvg` writes it as an SVG that needs no stylesheet; `drawToCanvas(ctx, drawing, { width, theme })` (`/canvas`) paints it on a browser's, an `OffscreenCanvas`'s or a Node canvas's context with the context typed by what is called; `appendSurface(selection, drawing, x, y)` and `surfaceDomain` (`/d3`) put it in a d3 selection by the caller's linear scales; `surfaceMark` and `surfaceScales` (`/plot`) make an Observable Plot mark and its scales; `sceneToGeoJSON(drawing, { frame })` (`/geojson`) writes each shape as an RFC 7946 feature in feet or a provider's frame; `toPNG(drawing, { width })` (`/png`) draws a PNG in Node through the optional peer `@resvg/resvg-js`, loaded when called, with an error that says what to install. The SVG tree gives every drawing back byte for byte (`parseSvg`, `writeSvg`), the style was compared with Chromium's `getComputedStyle` and the canvas with the browser's own drawing of the SVG (`e2e/renderers.demo.mjs`), and the sizes of the code are held to budgets.
- **Tennis, volleyball, badminton, pickleball and table tennis** (`sport: "tennis"`, `"volleyball"`, `"badminton"`, `"pickleball"`, `"tabletennis"`, [docs/courts.md](./docs/courts.md)). Each court to scale from its own rulebook, every figure cited in docs/sources.md: the ITF's Rules of Tennis (2026; the court, the service lines 21 feet from the net, the centre mark, the net posts 3 feet outside the doubles court, the singles sticks on request), the FIVB's Official Volleyball Rules and Official Beach Volleyball Rules (2025-2028; the centre line, the attack line 3 m from its axis, the front zones, the antennae, the free zone, the attack line's extension and the posts 1 m out for the FIVB's competitions; beach volleyball is `league: "fivb-beach"`), the BWF's Laws of Badminton (as amended 26 April 2025, with Diagram A), USA Pickleball's rulebook (2026; the non-volley zones and centerlines) and the ITTF's Laws of Table Tennis (the 2026 statutes; the table and the net). They lie wide; `orientation: "portrait"` lays them tall. `net.look` picks a named look (tennis `hard-blue`, `hard-green`, `clay`, `grass`; volleyball `wood`, `blue`, `sand`; badminton, pickleball and table tennis their own), `net.free` the free zone (`official`, `least`, `none`) and `net.sticks` the tennis singles sticks.
- **A score for the net sports**: each team's `sets` (tennis: its games; pickleball and table tennis: each game's points), `tiebreaks` and `points` in tennis, `serving`; a board of sets and games over the net and a badge with the server's ball; the statuses `set-3`, `game-2`, `tiebreak`, `match-tiebreak`, `retired` and `walkover`; and the server, each set and the game in the description. The board's heads follow each rulebook's word: sets for tennis and volleyball, games for badminton, pickleball and table tennis.
- The leagues `itf`, `fivb`, `fivb-beach`, `bwf`, `usap` and `ittf`, the sources for each, the frames `tennis`, `volleyball`, `badminton`, `pickleball` and `tabletennis` (the centre of the net as the origin), the zone set `net-court` (the front court and the back court on each side of the net), `TENNIS`, `VOLLEYBALL`, `BEACH_VOLLEYBALL`, `BADMINTON`, `PICKLEBALL` and `TABLE_TENNIS` in `/geometry`, `netOf` in `/leagues`, English and Japanese words for all of it, and a gallery page.
- **Styling** ([docs/theming.md](./docs/theming.md)). `look` (the root says `data-palette`, as `data-look` is a net court's) paints a whole drawing in one of seven named palettes (`grass`, `night`, `chalkboard`, `blueprint`, `print`, `broadcast`, `high-contrast`, in `LOOKS`), light and dark, for every sport, as custom properties at no weight; a test holds every painted line of every look, mode and sport to 3:1 against what it is painted on, and the words to 4.5:1 against the apron. `featureColors` colours a part by name (`FEATURES[sport]` lists them: 12 for football, 17 for the rink, 18 for the court, 13 for the ballpark, 14 for the pitch, 15 for the sheet, 8 for each net sport). `lineWidth` (a scale or an absolute width), `lineDash` and `lineOpacity` for the painted lines. `goals` now styles a hockey net, a basketball basket and a football field's posts as it did a soccer goal, and `goalMarkup` takes a function of your own that draws the goals. `stripePattern` mows football fields and ballparks (and adds `circles` for every grass surface, and `rings` and `fan` for a ballpark). Nothing changes in a drawing that uses none of them: a snapshot of 122 drawings proves it. Ideas from sportypy (colours by named feature), ggsoccer (line widths, types and alpha, goal styles and a goal function) and mplsoccer (stripes), credited in docs/references.md; no code is used.
- **Annotations** ([docs/annotations.md](./docs/annotations.md)). `direction` draws an arrow for the end each team attacks (by the sport's rule for the period, with `changedAfter` for a case no rule settles); `axes` draws ticks and numbers along the edges, in the drawing's own numbers or in any registered frame of the sport; `landmarks` names the parts of every surface, in English and Japanese, with a leader to each. They follow a surface turned a quarter with every word upright, make the margin as wide as they need, and are said in the description. A test holds the arrows, the words and the anchors, for every surface wide and tall and with either end attacked, and the soccer penalty arc outside its box in every provider's numbers. The `look`, `line-width`, `line-dash`, `line-opacity` and `landmarks` attributes of `<kyogijo-field>`.
- **Curling** (`sport: "curling"`, [docs/curling.md](./docs/curling.md)). A sheet to scale from R1 of World Curling's Rules of Curling (1 September 2026) and Rule 3 of Curling Canada's Rules of Curling for General Play (2022 to 2026): a house at each end, the tee, back, hog and centre lines, the hacks and, in World Curling's, the hack and courtesy lines; tall by default, with the far house at the top. `league` is `wcf` (the default, in metres) or `curling-canada` (feet); `sheet` sets the length and the width within the rules' range, the colours of the rings, the ice's pebble, the shaded free guard zone and a part of the sheet (`half`, `house`).
- **A curling score**: each team's `ends` and `hammer`, a board on the ice (the ends down a tall sheet, across a wide one) and a badge with the hammer, the statuses `end-6` and `extra-end`, and the ends and the hammer in the description.
- **`curlingStones` and `curlingScore`** (`@johnmorrisdotca/kyogijo/charts`): the stones of an end on the house, judged by the rules (out of play, in the house, counting, the shot rock, a blank end), with the zone set `curling-house`, the frame `curling` (feet from the button) and the stone's size (`STONE_DIAMETER`, from 36 inches round).
- The league `curling-canada`, the sources `wcf-rules` and `curling-canada-rules`, English and Japanese words for all of it, and a gallery page.
- **Team shape** ([docs/team-shape.md](./docs/team-shape.md)). Seven new kinds of data layer for team analysis, each drawn on any surface in its feet or a provider's frame, cut to the surface's outline, in the layer colours of the page (light and dark), with a title, a description, a tooltip for each mark and, with `layerTable(layers, { surface })`, a table of its numbers: `network` (a pass network: a node for each player at the average place of the passes he made and received, sized by touches, a link for each pair sized and shaded by passes, `minPasses`, `directed`, labels), `formation` (a labelled mark for each position of a named formation, with a lineup's numbers and names on them), `voronoi` (space control: each player's cell in his team's colour, each team's share of the surface counted on a grid kept to the surface), `delaunay` (the triangulation of each team's players or of all), `hull` (the convex hull of each team, with its area), `flow` (the mean direction of the movements that start in each cell of a grid, as arrows of the mean length or of one length shaded by steadiness) and `sonar` (direction roses of counts or mean lengths, for all, each player, each cell of a grid or each zone of a zone set). `passNetwork(passes, options)` in the charts entry makes the network with a key, totals and two tables. `FORMATIONS` holds 21 formations in the frames of their sports (soccer 4-4-2, 4-3-3, 4-2-3-1, 4-1-4-1, 3-5-2, 3-4-3, 5-3-2, 5-4-1, 4-3-2-1 and the diamond; hockey five on five and a 1-3-1 power play; basketball five out, four out and one in, and 1-4 high; football's I formation, shotgun, 4-3 and 3-4; baseball's standard defence and an infield shift), with the names of the positions in English and Japanese (conventional: the Laws of the Game name only the goalkeeper) and `los`, `attacking`, `names` and `labels` options; a formation of your own is plain data. The geometry is written for this package with no dependency and exported from the layers entry: `convexHull` (monotone chain), `delaunay` (Bowyer and Watson with ghost triangles for the hull) and `voronoiCells`, held by tests on random points, lattices, points on one circle, collinear, repeated, one, two and no points, and points of huge, tiny and far-off scale. Budgets held by tests: a Voronoi diagram of 22 players under 12 kB, a pass network of 600 passes under 16 kB in under 100 ms, a triangulation of 1,000 points in under 600 ms, a flow field of 5,000 movements under 20 kB in under 150 ms. Ideas from mplsoccer (MIT), credited in docs/references.md; no code of it is used. The gallery has an entry for each, the comparison table a row for them, and docs/sources.md says what its formations rest on.
- **Replay** (`@johnmorrisdotca/kyogijo/replay`, [docs/replay.md](./docs/replay.md)). Tracking data played on any surface: a timeline of frames (`{ t, objects: [{ id, team, x, y, label?, number? }] }`, in any registered frame) and events at times (pass, shot, goal, whistle). Pure functions: `interpolate` (straight, or a Catmull-Rom curve through the frames with `smooth`), `trails`, `possession` (when the data says), `activeEvents` and `drawFrame(options, timeline, t)`, a deterministic SVG string built on the data layers (the home team as circles, the away team as squares, shirt numbers, the ball with its trail, passes and shots as arrows, a goal as a star), with a description that does not change with the time. `createReplay` is the clock as a state machine with no page in it (play, pause, seek, step, speed 0.25 to 4, loop, the events that went by). `mountKyogijo(...).replay(timeline)` and `<kyogijo-field>.timeline` play it with controls under the drawing (play and pause, step back and on, speed, loop, a position slider and the time), the keyboard (space, the arrow keys, shift and the arrows, Home and End), and only the marks that move moved on `requestAnimationFrame`, never the surface. `prefers-reduced-motion` is followed: nothing plays by itself and play steps instead; a hidden page pauses; a live region says each goal, shot, pass and whistle as it passes; every control is named in English and Japanese. `update()` keeps the replay. A score that changes through `update()` now swells and settles once (a fade only, with reduced motion). The demo has a Replay section with a made-up, seeded play on the rink and on the pitch, the gallery has a frame of each, and 22 players and a ball for 60 seconds at 25 frames a second are held to a time and size budget.
- **A docs site** at `/docs/` of the demo site, made by `pnpm site` from `docs/*.md`: 31 pages in groups, a search box over every title and heading, the pages before and after, a copy button on every block of code, light and dark, phone width, and the contents in Japanese. The README keeps the pitch, the first minute, one example per area and the family block, and is about 37,000 characters instead of 64,000; its reference sections moved to [docs/](./docs/README.md) (getting started, surfaces, score and layout, soccer, ballparks, units, coordinate frames, accessibility, limits, entry points, architecture).
- **A gallery** in the docs site: every surface, league variant, season, park and ground sample, layer kind, heat layer and chart, each drawn by the build from the code shown beside it, with a copy button. A test runs every snippet.
- **How it compares** ([docs/compare.md](./docs/compare.md)): a table against sportypy, sportyR, `@sportsdataverse/sporty`, hockey_rink, mplsoccer, ggsoccer, GeomMLBStadiums, gavinr's spring-training parks and thestadi.com, from each README.
- **Coordinate frames and surface units as tables made from the code** (`pnpm docs:make`), with the same spot drawn in each of the 16 frames side by side.
- Every `ts` example of the README and of every docs page is run, and what it prints is held to its comment lines.
- **Ready-made charts** (`@johnmorrisdotca/kyogijo/charts`, [docs/charts.md](./docs/charts.md)). One call each makes the layers and the drawing options for a chart, so a good chart takes one line and every layer can still be changed: `nbaShotChart` (made and missed shots and the six shot zones coloured by field-goal percentage, diverging from the league's), `nhlShotMap` (goals and shots sized by expected goals, `fold` to put both ends on one, slot zones or hexagons), `mlbSprayChart` (balls in play on the park of their season, past parks included, a mark for each hit type, balls beyond the fence drawn beyond it, spray zones by the side the batter bats from, Retrosheet codes as well as Statcast's `hc_x` and `hc_y`), `nflPassChart` (destinations by outcome and air yards, the line of scrimmage, the pass grid's completion percentages) and `soccerShotMap` with `goalMouth()` / `soccerGoalMouth` (shots sized by expected goals on the pitch or its half, a view of the goal frame with where each shot crossed the goal line, xG totals). Each chart has a key, a legend, a title and description for every layer and a table; the drawings are deterministic, held by fingerprints and size budgets; its words are in English and Japanese; every example on the page is run by a test. The tables of layers and heat layers now name the unit of a frame's own numbers (tenths of a foot for the NBA's) and not the drawing's. The demo has a Charts section.
- **Heat layers.** Five new kinds of data layer: `heatmap` (a binned statistic on a grid over the surface), `hexbin`, `zones` (named zones with aggregated values and labels), `contour` (a Gaussian kernel density, Scott's rule by default, drawn as filled bands or lines) and `legend`. Statistics are `count`, `sum`, `mean`, `median`, `max`, `min`, `percent`, `rate` (a field-goal percentage from made and missed) or a function, with `normalize`, `minCount`, a `domain`, a diverging `center` and cell or zone labels. Cells, hexagons and bands are cut to the surface's outline. Ten zone sets, each cited in docs/sources.md: soccer positional zones (juego de posición), thirds, channels and the 18 zones; the NBA's shot zones; the NHL's slot and home plate; baseball's spray zones and Retrosheet's sectors; football's pass grid. Five built-in colour ramps (`ember`, `ocean`, `mono`, `balance`, `tide`) with a light and a dark set, checked against every surface's colour; custom stops. Each layer has a title, a description that names its hottest cells or zones and, with `layerTable(layers, { surface })`, a table of its numbers. A 50 by 30 grid is held under 30 kB on every sport and 10,000 marks make a density in under 500 ms. The `/layers` entry exports the numbers (`binGrid`, `hexBins`, `densityGrid`, `contourRings` and more), `ZONE_SETS` and `buildZoneSet`. The demo's Data section shows a rink heat map, an NBA shot-zone chart with field-goal percentages, a soccer positional heat map and a density contour.
- **Past ballparks.** `PARKS` grows by 44 past parks, and every park carries its Wikidata item (`wikidata`, `parkByWikidata`). A past park has the seasons it was used (`from`, `to`) and, where an article dates earlier fences, `periods`, chosen by the new `year` option (`parkPointsIn`).
- **Units.** `SURFACE_UNITS` names the unit each rulebook states its figures in; `convertLength`, `lengthsIn`, `dimensionsOf`, `surfaceSize` and `fenceIn` give every dimension in feet, inches, yards, metres, centimetres or millimetres; the `units` option says what the lengths of a drawing's options (`margin`, `fence`) are in.
- **Coordinate frames** (`@johnmorrisdotca/kyogijo/frames`). `toSurface`, `fromSurface` and `convert` put a provider's points on a surface and move them between providers, with `units`, `anchors`, `limits` and `attacking`; the frames of the NHL API, HockeyTech, NBA stats, NFL tracking data, MLBAM and Retrosheet's hit locations; `registerFrame` and `piecewise` for the frames of other sports.
- **Soccer.** `sport: "soccer"` draws a pitch from Law 1 of the IFAB Laws of the Game at any size (`pitch`), with presets (international, UEFA, MLS, NCAA, the Laws' least and most, the FA's 9-, 7- and 5-a-side, FIFA's futsal), half pitches, six mowing patterns, four goal styles, corner flags, teams in their penalty areas and a score with extra time and penalties (`Team.penalties`, `final-aet`, `final-pens`). Ten data providers (`SOCCER_PROVIDERS`) as frames, a pitch drawn in a provider's own coordinates (`pitchType`) with an empty `ky-data` group for raw data, and `rescale` between any two, landmark to landmark.
- **Data layers** (`layers` in the options; `drawLayers`, `layerTable` and the `@johnmorrisdotca/kyogijo/layers` entry). Points (seven shapes and team logos), lines, arrows (curved, wavy, open or filled heads, comet lines that fade along their length) and text over any surface, in the surface's feet, any unit or a provider's frame, cut to the boards, the fence or the court's lines with a clip path for each drawing, upright when the surface lies tall. Size by value, colour by value, team or outcome, filled and hollow outcomes (`OUTCOMES`), new colour properties (`--ky-layer`, `--ky-layer-home`, `--ky-layer-away`, `--ky-layer-edge`, `--ky-layer-hollow`, `--ky-layer-ink`, `--ky-layer-halo`) that follow a score drawing's teams. A title and a description for each layer, a tooltip for each mark and an HTML table of the data. 1,000 points add about 60 kB; 10,000 are drawn in about 20 ms. The demo has a Data section with a shot map, a pass map and a spray chart made from seeded, made-up data.
- **Surfaces through the years** (`@johnmorrisdotca/kyogijo/eras`). `year` draws a surface as its league's rules marked it in a season, for the NHL, the NBA, the NFL, the CFL and baseball: the NHL's centre red line, goal lines, blue lines and trapezoid, the NBA's lane, three-point line and restricted area, the NFL's hash marks and goal posts, the CFL's end zones, hash marks and goal posts (and the field planned for 2027), the baseball pitcher's box and plate, batter's boxes and home plate. `rulesFor`, `eraChanges`, `eraStates`, `eraRange`, `seasonLabel` and `footballIn`; each change has the season it began in, a sentence in English and Japanese and its sources, and a marking no source covers is listed in `gaps` rather than guessed. The demo has a season slider.
- **Famous soccer grounds.** `GROUNDS` (`@johnmorrisdotca/kyogijo/grounds`) has 64 grounds: the venue of every men's World Cup final from 1930 to 2022 and the 2026 final, all 16 venues of 2026, the venue of every Women's World Cup final, and well-known club grounds (both Wembleys, the Maracanã, Camp Nou, the Bernabéu, San Siro, Old Trafford, Anfield, Signal Iduna Park, the Allianz Arena, La Bombonera, Hampden Park, Celtic Park, the Estádio da Luz, the Parc des Princes, Saitama Stadium 2002, Nissan Stadium, the Seoul World Cup Stadium and more). Each has its city, country, Wikidata item and coordinates, the names it had with their years, its name in the place's language and in Japanese, its opening and closing years, capacity, the World Cups it staged, the pitch's length and width where its English Wikipedia article publishes them (42 of 64; the others are drawn at 105 by 68 m and marked `pitchSize: "default"`), and the article and revision each was read from. `drawKyogijo({ sport: "soccer", ground: "maracana", year })` draws the pitch at the ground's size under its name for the year; `groundById`, `groundByWikidata`, `groundNameIn`, `groundsHosting`, `groundSourceUrl`. `pnpm grounds` builds the data and docs/grounds.md; `pnpm grounds:check` asks Wikidata again. The demo has a ground picker.
- **A stadium atlas** (`@johnmorrisdotca/kyogijo/atlas`). `PLACES` joins the 94 ballparks and 64 soccer grounds into one list with where each stands (`lat`, `lon`, Wikidata's P625), its country and city, its sport, leagues, whether it is in use today or of the past, and the years it was in use; `placesBy({ sport, kind, league, country, status, year, text })`, `placeById`, `atlasFacets` and `surfaceOf`. Every park now has its coordinates and the years it opened and closed (`pnpm parks:coordinates` fetches them, `pnpm parks:check` compares them with Wikidata). The demo has an Atlas: a chizu world map with a marker on every place (a circle for today, a diamond for the past), filters, a year slider, a list and the chosen place's surface beside the map; docs/atlas.md has a picture of the map, made by `pnpm site`.
- **League variants** (`@johnmorrisdotca/kyogijo/leagues`). `league` draws a surface as one league's rulebook marks it, with `sport` naming the family: basketball (the WNBA, FIBA, NCAA men and women, NFHS, the G League), hockey (the IIHF, NCAA men and women, AHL, ECHL, OHL, WHL, QMJHL, USHL, PWHL), football (the NCAA, NFHS 11, 9, 8 and 6 players, Texas six-man, the Indoor Football League) and baseball and softball (MiLB, NCAA, NFHS, Little League and its Intermediate division, three PONY divisions, NCAA and NFHS softball, USA Softball fast and slow pitch, WBSC slow pitch). Each league has its figures in its own unit, its name in English and Japanese, its sources with edition and address (`LEAGUES`, `VARIANTS`, `LEAGUE_SOURCES`, `leagueFigures`), and the changes a source dates (`leagueChanges`, `leagueAt`): the WNBA lane (2004), the NCAA restricted-area arc, the IIHF blue line and goalkeepers' trapezoid, the AHL blue lines (2005-06) and the NCAA men's trapezoid (2026-27). Score mode, themes, orientation, badges, `year` and data layers work on every league. The demo has a league picker; docs/variants.md lists every figure and docs/references.md what could not be cited.

### Changed

- **Breaking: the park status `"historic"` is now `"past"`.** `Park["status"]` is `"current" | "secondary" | "past"`, as for the grounds and the atlas; the six NPB parks that read `"historic"` read `"past"` (the type and the value in `PARKS`). Code that compares `park.status === "historic"` must compare with `"past"`.
- **Breaking: `Sport` and `SPORTS` grow from 6 to 20 sports.** The type was `"nfl" | "cfl" | "ifaf" | "nhl" | "nba" | "mlb"`; it now also has `"soccer"`, `"curling"`, the net sports (`"tennis"`, `"volleyball"`, `"badminton"`, `"pickleball"`, `"tabletennis"`) and the field sports (`"lacrosse"`, `"rugby"`, `"afl"`, `"gaelic"`, `"cricket"`, `"fieldhockey"`, `"handball"`). A TypeScript `switch` over `Sport` that is checked to be exhaustive must add a case for each, and code that loops over `SPORTS` now meets all twenty.
- **Breaking: the NHL trapezoid is 22 feet wide at the goal line, not 18.** `NHL.trapezoid.atGoalLine` was 18 feet; Rule 1.8 has 22 feet, the figure since 2014-15, when the trapezoid was widened by 2 feet each side (18 feet from 2005-06 to 2013-14, which `rulesFor("nhl", year)` and a drawing with `year` still give). The rink is drawn with the wider trapezoid by default.
- **Breaking: the NHL's hash marks are 5 feet 7 inches apart, not 5 feet 11 inches.** The marks beside an end-zone circle were drawn 5 feet 11 inches apart, which added the lines' width to a gap it does not enter; Rule 1.9 says 5 feet 7 inches (`NHL.hashApart`). The AHL, ECHL, OHL, WHL and PWHL, which share the NHL's Rule 1, change with it. docs/sources.md also records where the NHL's Rule 1.8 (a 22-foot trapezoid at the goal line, drawn) and Rule 27.8 (18 feet) disagree.
- **Breaking: MLB bases are 18 inches square, not 15.** `MLB.baseSize` was 15 inches; Rule 2.03 of the Official Baseball Rules has 18 inches from the 2023 season. The size is now a marking in `rulesFor("mlb", year)` (`baseSize`, 15 inches before 2023, 18 from 2023, with `eraChanges("mlb")` listing it), so the field is drawn with 18-inch bases by default and 15-inch ones for a season before 2023.
- **Breaking: the SVG written by `drawKyogijo` changes.** Every NHL drawing (the trapezoid and the hash marks) and every MLB drawing (the bases) differs from 0.1.0's, so a stored copy of an old drawing, or a snapshot test of one, needs to be made again. Every drawing's stylesheet is also about 2 kB larger.

### Fixed

- **NHL hash marks were 3 feet apart before 2014-15.** The rulebook of 2012-13 (Rule 1.9) says "three feet (3') apart", and the NHL and NHLPA release of 6 October 2014 moves them to 5 feet 7 inches for 2014-15. `rulesFor("nhl", year).rules.hashApart` is 3 feet through 2013-14 and 5 feet 7 inches after, `eraChanges("nhl")` lists both (`nhl.hashApart.2012`, `nhl.hashApart.2014`) and a rink drawn for an earlier season has the marks 3 feet apart. Seasons before 2012-13 are cited by no rulebook read, so they keep 3 feet and `gaps` names `hashApart`. The AHL, ECHL, OHL, WHL and PWHL are unchanged: no page read dates a change of their marks.
- **docs/sources.md cited the wrong baseball rule for home plate.** Home plate is Official Baseball Rules 2.02 (Home Base) in the 2024 edition; 2.03 is The Bases. The 90-foot square is 2.01, not 2.01 and 2.02.

## [0.1.0] - 2026-10-13

### Added

- **Six surfaces drawn to scale as SVG**: the NFL, CFL and IFAF football fields, the NHL rink, the NBA court and the baseball field, each from its rulebook or federation diagram, with every figure cited in docs/sources.md.
- **Score mode.** `drawKyogijo`, `drawScore` and `drawBadge` put each team's name and logo on its side (the end zones, the ends of the ice, the halves of the court, the dugouts) and the score in the middle, with the competition, the status, the date and an emphasis on the winner. Sizes `full`, `compact` and `badge`.
- **Wide, tall or fit the box.** `orientation: "landscape" | "portrait" | "auto"`: portrait turns the surface a quarter with every word upright and the teams top and bottom; `auto` follows `aspect`, and `mountKyogijo` watches the container and draws again when its shape changes.
- **Every ballpark.** `PARKS` has the 30 MLB parks, the 12 NPB home parks and eight other NPB grounds, each fence drawn from the distances published for it, with the article and revision each was read from. `park` and `fence` options; names in English and Japanese.
- **Theming.** Every colour is a custom property in a light and a dark set, `colors` sets them from code, and a court has its own look (`court`) with five to start from in `COURT_THEMES`.
- **Four ways in.** The function, `mountKyogijo` for a container, the `<kyogijo-field>` custom element with parts, and a frame (`embed.html`) for a page that runs no script; `@johnmorrisdotca/kyogijo/react` for React, which does not import it.
- **Accessible.** Each drawing is an `img` with a title and a description in English or Japanese.
- **The demo** with every sport and every park, wide and tall, light and dark, badges, compact cards, court looks, a live score, snippets for the four ways in, and the API reference.
