bragi-theme-zelda 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. bragi_theme_zelda-0.1.1/LICENSE +21 -0
  2. bragi_theme_zelda-0.1.1/PKG-INFO +140 -0
  3. bragi_theme_zelda-0.1.1/README.md +124 -0
  4. bragi_theme_zelda-0.1.1/pyproject.toml +69 -0
  5. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/__init__.py +10 -0
  6. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/image_frame.py +22 -0
  7. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/plugin.py +359 -0
  8. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/section.py +68 -0
  9. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/.gitkeep +0 -0
  10. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/css/print.css +45 -0
  11. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/css/theme.css +783 -0
  12. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/fonts/Inter-Regular-subset.woff2 +0 -0
  13. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/fonts/Inter-SemiBold-subset.woff2 +0 -0
  14. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/fonts/JetBrainsMono-Regular-subset.woff2 +0 -0
  15. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/fonts/PressStart2P-subset.woff2 +0 -0
  16. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/js/cosplay.js +198 -0
  17. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/heart_container_placeholder.png +0 -0
  18. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/items/kokiri_emerald.png +0 -0
  19. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/items/la_pearl.png +0 -0
  20. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/items/owl_statue.png +0 -0
  21. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/items/triforce_piece.png +0 -0
  22. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/portraits/marin.png +0 -0
  23. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/portraits/owl.png +0 -0
  24. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/portraits/tarin.png +0 -0
  25. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/portraits/ulrira.png +0 -0
  26. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/static/sprites/ui/marin_house_night.png +0 -0
  27. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/_breadcrumbs.html +25 -0
  28. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/_callout_textbox.html +17 -0
  29. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/_gb_frame.html +14 -0
  30. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/_site_nav.html +45 -0
  31. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/base.html +64 -0
  32. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/errors/404.html +17 -0
  33. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/errors/500.html +9 -0
  34. bragi_theme_zelda-0.1.1/src/bragi_theme_zelda/templates/delivery/home/pause_menu.html +19 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eelco Wesemann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.4
2
+ Name: bragi-theme-zelda
3
+ Version: 0.1.1
4
+ Summary: Link's-Awakening-flavoured theme for the bragi CMS, used by zelda.eelcowesemann.nl
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Author: Eelco Wesemann
8
+ Author-email: claude-ai@init1.nl
9
+ Requires-Python: >=3.14,<4.0
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Dist: jinja2 (>=3.1,<4.0)
14
+ Description-Content-Type: text/markdown
15
+
16
+ # bragi-theme-zelda
17
+
18
+ A Link's-Awakening-flavoured theme for the [bragi CMS](https://github.com/sgaduuw/bragi),
19
+ deployed at [zelda.eelcowesemann.nl](https://zelda.eelcowesemann.nl).
20
+
21
+ This is a site-specific theme. The visual choices are opinionated for one Zelda fan site
22
+ (primarily Link's Awakening walkthroughs with secondary Ocarina of Time coverage) and are
23
+ not intended as a general-purpose Zelda theme.
24
+
25
+ ## Theme highlights
26
+
27
+ - **Game Boy LCD palette:** 4-shade GB green light mode, 4-shade GB Pocket greyscale dark
28
+ mode. Two real handheld LCDs under one roof; `prefers-color-scheme` determines which.
29
+ - **Pixel headings over readable body:** Press Start 2P for short strings (headings, labels,
30
+ UI chrome), Inter for body text, JetBrains Mono for code.
31
+ - **MAP-styled sidebar tree:** Current section's siblings and children visible at a glance,
32
+ styled as a pause-menu MAP panel. Walkthrough hierarchy (game, dungeon, room) navigable
33
+ without hunting through a top-level nav.
34
+ - **OoT section chrome flip:** Royal-blue + gold accent shift in the Ocarina of Time section
35
+ via `data-section="oot"`. Body stays GB-green for cohesion; chrome (top bar, image frames,
36
+ links) signals the switch.
37
+ - **GB Pocket greyscale dark mode:** A real GB Pocket palette (light grey on near-black),
38
+ not a colour inversion. Different hardware era, coherent aesthetic family.
39
+ - **Seven cosplay motifs:** text-box callouts (Owl / Marin / Tarin / Ulrira portraits),
40
+ rupee counter, PUSH START splash, item-acquired flourish between sections, pause-menu
41
+ inventory homepage, ZZZZZ 404, heart-container `<hr>`, inventory-row pinned posts.
42
+ - **`prefers-reduced-motion` respected:** Any animation that moves (ZZZZZ float, item-
43
+ acquired scroll, PUSH START blink) switches to a static render.
44
+
45
+ ## Status: v0.1.1
46
+
47
+ v0.1.1 is the first PyPI-published release. It ships the same full visual system as v0.1.0
48
+ (MAP sidebar, chrome, pause-menu home, ZZZZZ 404, all four cosplay JS motifs, and subsetted
49
+ woff2 fonts). **Character portraits, item tiles, the heart-container, and the 404 scene art
50
+ are still placeholder PNGs** (Pillow-generated text-on-coloured-square). The CSS / JS /
51
+ templates reference the correct sprite filenames, so a future release swaps in real art via
52
+ per-file PNG replacement with no code changes.
53
+
54
+ ## Asset provenance
55
+
56
+ Fonts and sprites are documented row-by-row in [ASSETS.md](ASSETS.md). No ROM-ripped
57
+ Nintendo assets; see ASSETS.md for the full sourcing and licence detail.
58
+
59
+ ## Installing
60
+
61
+ The theme is installed into a downstream bragi deployment via a thin `Dockerfile` that
62
+ builds on the published bragi images and `pip install`s this package. From v0.1.1 the
63
+ package is published to PyPI on every GitHub Release; v0.1.0 is git-tag-only.
64
+
65
+ ### Delivery container
66
+
67
+ ```dockerfile
68
+ FROM ghcr.io/sgaduuw/bragi-delivery:v1.26.0
69
+
70
+ # Install from PyPI (pin to a specific version).
71
+ RUN pip install --no-cache-dir bragi-theme-zelda==0.1.1
72
+
73
+ # For development against an unreleased commit, use the git+https form instead:
74
+ # RUN pip install --no-cache-dir \
75
+ # "git+https://github.com/sgaduuw/bragi-theme-zelda.git@v0.1.0"
76
+ ```
77
+
78
+ ### Admin container
79
+
80
+ ```dockerfile
81
+ FROM ghcr.io/sgaduuw/bragi-admin:v1.26.0
82
+
83
+ # Install from PyPI (pin to a specific version).
84
+ RUN pip install --no-cache-dir bragi-theme-zelda==0.1.1
85
+
86
+ # For development against an unreleased commit, use the git+https form instead:
87
+ # RUN pip install --no-cache-dir \
88
+ # "git+https://github.com/sgaduuw/bragi-theme-zelda.git@v0.1.0"
89
+ ```
90
+
91
+ Both containers need the package so template lookups work from the admin preview path and
92
+ from the public delivery path. Restart both after installation to pick up the plugin.
93
+
94
+ Replace the version pin with the version to deploy. v0.1.1 is the first PyPI-published
95
+ release; v0.1.0 is git-tag-only.
96
+
97
+ ## Development
98
+
99
+ ### Prerequisites
100
+
101
+ - Python 3.14+
102
+ - [Poetry](https://python-poetry.org/)
103
+
104
+ ### Install
105
+
106
+ ```sh
107
+ poetry install
108
+ ```
109
+
110
+ ### Run against a bragi dev checkout (editable install)
111
+
112
+ ```sh
113
+ # From this project's directory, install into bragi's venv as an editable package:
114
+ cd ../bragi && poetry run pip install -e ../bragi-theme-zelda
115
+
116
+ # Then in bragi's working tree, point the Zelda site's theme to "zelda"
117
+ # via the admin UI or CLI, and reload the delivery process to pick up template changes.
118
+ ```
119
+
120
+ ### Commands
121
+
122
+ ```sh
123
+ # Run the test suite
124
+ poetry run pytest
125
+
126
+ # Lint
127
+ poetry run ruff check src/ tests/
128
+
129
+ # Format-check
130
+ poetry run ruff format --check src/ tests/
131
+
132
+ # Type-check
133
+ poetry run mypy src/
134
+ ```
135
+
136
+ ## License
137
+
138
+ MIT. See [LICENSE](LICENSE). Theme code and original assets are MIT-licensed. Third-party
139
+ fonts are under their respective open-source licences; see [ASSETS.md](ASSETS.md).
140
+
@@ -0,0 +1,124 @@
1
+ # bragi-theme-zelda
2
+
3
+ A Link's-Awakening-flavoured theme for the [bragi CMS](https://github.com/sgaduuw/bragi),
4
+ deployed at [zelda.eelcowesemann.nl](https://zelda.eelcowesemann.nl).
5
+
6
+ This is a site-specific theme. The visual choices are opinionated for one Zelda fan site
7
+ (primarily Link's Awakening walkthroughs with secondary Ocarina of Time coverage) and are
8
+ not intended as a general-purpose Zelda theme.
9
+
10
+ ## Theme highlights
11
+
12
+ - **Game Boy LCD palette:** 4-shade GB green light mode, 4-shade GB Pocket greyscale dark
13
+ mode. Two real handheld LCDs under one roof; `prefers-color-scheme` determines which.
14
+ - **Pixel headings over readable body:** Press Start 2P for short strings (headings, labels,
15
+ UI chrome), Inter for body text, JetBrains Mono for code.
16
+ - **MAP-styled sidebar tree:** Current section's siblings and children visible at a glance,
17
+ styled as a pause-menu MAP panel. Walkthrough hierarchy (game, dungeon, room) navigable
18
+ without hunting through a top-level nav.
19
+ - **OoT section chrome flip:** Royal-blue + gold accent shift in the Ocarina of Time section
20
+ via `data-section="oot"`. Body stays GB-green for cohesion; chrome (top bar, image frames,
21
+ links) signals the switch.
22
+ - **GB Pocket greyscale dark mode:** A real GB Pocket palette (light grey on near-black),
23
+ not a colour inversion. Different hardware era, coherent aesthetic family.
24
+ - **Seven cosplay motifs:** text-box callouts (Owl / Marin / Tarin / Ulrira portraits),
25
+ rupee counter, PUSH START splash, item-acquired flourish between sections, pause-menu
26
+ inventory homepage, ZZZZZ 404, heart-container `<hr>`, inventory-row pinned posts.
27
+ - **`prefers-reduced-motion` respected:** Any animation that moves (ZZZZZ float, item-
28
+ acquired scroll, PUSH START blink) switches to a static render.
29
+
30
+ ## Status: v0.1.1
31
+
32
+ v0.1.1 is the first PyPI-published release. It ships the same full visual system as v0.1.0
33
+ (MAP sidebar, chrome, pause-menu home, ZZZZZ 404, all four cosplay JS motifs, and subsetted
34
+ woff2 fonts). **Character portraits, item tiles, the heart-container, and the 404 scene art
35
+ are still placeholder PNGs** (Pillow-generated text-on-coloured-square). The CSS / JS /
36
+ templates reference the correct sprite filenames, so a future release swaps in real art via
37
+ per-file PNG replacement with no code changes.
38
+
39
+ ## Asset provenance
40
+
41
+ Fonts and sprites are documented row-by-row in [ASSETS.md](ASSETS.md). No ROM-ripped
42
+ Nintendo assets; see ASSETS.md for the full sourcing and licence detail.
43
+
44
+ ## Installing
45
+
46
+ The theme is installed into a downstream bragi deployment via a thin `Dockerfile` that
47
+ builds on the published bragi images and `pip install`s this package. From v0.1.1 the
48
+ package is published to PyPI on every GitHub Release; v0.1.0 is git-tag-only.
49
+
50
+ ### Delivery container
51
+
52
+ ```dockerfile
53
+ FROM ghcr.io/sgaduuw/bragi-delivery:v1.26.0
54
+
55
+ # Install from PyPI (pin to a specific version).
56
+ RUN pip install --no-cache-dir bragi-theme-zelda==0.1.1
57
+
58
+ # For development against an unreleased commit, use the git+https form instead:
59
+ # RUN pip install --no-cache-dir \
60
+ # "git+https://github.com/sgaduuw/bragi-theme-zelda.git@v0.1.0"
61
+ ```
62
+
63
+ ### Admin container
64
+
65
+ ```dockerfile
66
+ FROM ghcr.io/sgaduuw/bragi-admin:v1.26.0
67
+
68
+ # Install from PyPI (pin to a specific version).
69
+ RUN pip install --no-cache-dir bragi-theme-zelda==0.1.1
70
+
71
+ # For development against an unreleased commit, use the git+https form instead:
72
+ # RUN pip install --no-cache-dir \
73
+ # "git+https://github.com/sgaduuw/bragi-theme-zelda.git@v0.1.0"
74
+ ```
75
+
76
+ Both containers need the package so template lookups work from the admin preview path and
77
+ from the public delivery path. Restart both after installation to pick up the plugin.
78
+
79
+ Replace the version pin with the version to deploy. v0.1.1 is the first PyPI-published
80
+ release; v0.1.0 is git-tag-only.
81
+
82
+ ## Development
83
+
84
+ ### Prerequisites
85
+
86
+ - Python 3.14+
87
+ - [Poetry](https://python-poetry.org/)
88
+
89
+ ### Install
90
+
91
+ ```sh
92
+ poetry install
93
+ ```
94
+
95
+ ### Run against a bragi dev checkout (editable install)
96
+
97
+ ```sh
98
+ # From this project's directory, install into bragi's venv as an editable package:
99
+ cd ../bragi && poetry run pip install -e ../bragi-theme-zelda
100
+
101
+ # Then in bragi's working tree, point the Zelda site's theme to "zelda"
102
+ # via the admin UI or CLI, and reload the delivery process to pick up template changes.
103
+ ```
104
+
105
+ ### Commands
106
+
107
+ ```sh
108
+ # Run the test suite
109
+ poetry run pytest
110
+
111
+ # Lint
112
+ poetry run ruff check src/ tests/
113
+
114
+ # Format-check
115
+ poetry run ruff format --check src/ tests/
116
+
117
+ # Type-check
118
+ poetry run mypy src/
119
+ ```
120
+
121
+ ## License
122
+
123
+ MIT. See [LICENSE](LICENSE). Theme code and original assets are MIT-licensed. Third-party
124
+ fonts are under their respective open-source licences; see [ASSETS.md](ASSETS.md).
@@ -0,0 +1,69 @@
1
+ [tool.poetry]
2
+ name = "bragi-theme-zelda"
3
+ version = "0.1.1"
4
+ description = "Link's-Awakening-flavoured theme for the bragi CMS, used by zelda.eelcowesemann.nl"
5
+ authors = ["Eelco Wesemann <claude-ai@init1.nl>"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ packages = [{ include = "bragi_theme_zelda", from = "src" }]
9
+ include = [
10
+ "src/bragi_theme_zelda/templates/**/*",
11
+ "src/bragi_theme_zelda/static/**/*",
12
+ ]
13
+
14
+ [tool.poetry.dependencies]
15
+ python = "^3.14"
16
+ # jinja2 is imported directly by plugin.py (PackageLoader, Environment type).
17
+ # bragi is the host app and is always present in the deployment environment;
18
+ # it is a dev dep here (git dep) so the published wheel has no direct-URL
19
+ # dependency that PyPI rejects.
20
+ jinja2 = "^3.1"
21
+
22
+ [tool.poetry.group.dev.dependencies]
23
+ # bragi is the host. Git dep because bragi isn't on PyPI (the bragi name there
24
+ # is held by an unrelated project per bragi's CONTEXT.md). Lives in dev so
25
+ # the published wheel carries no direct-URL dep (PyPI rejects those).
26
+ bragi = { git = "https://github.com/sgaduuw/bragi.git", tag = "v1.26.0" }
27
+ ruff = "^0.6"
28
+ mypy = "^1.11"
29
+ pytest = "^8.0"
30
+ fonttools = "^4.63.0"
31
+ brotli = "^1.2.0"
32
+
33
+ [tool.poetry.plugins."bragi.plugins"]
34
+ theme_zelda = "bragi_theme_zelda.plugin"
35
+
36
+ [tool.ruff]
37
+ line-length = 88
38
+ # ruff 0.6.x tops out at py313; bump when upgrading ruff past 0.7.
39
+ target-version = "py313"
40
+ src = ["src", "tests"]
41
+
42
+ [tool.ruff.lint]
43
+ select = ["E", "F", "I", "B", "UP", "N", "RUF"]
44
+
45
+ [tool.mypy]
46
+ python_version = "3.14"
47
+ strict = true
48
+ files = ["src"]
49
+
50
+ # bragi does not ship py.typed (it's deploy-as-container, not a PyPI lib).
51
+ # Silence mypy's import-untyped error for the bragi imports in this package.
52
+ [[tool.mypy.overrides]]
53
+ module = "bragi.*"
54
+ ignore_missing_imports = true
55
+
56
+ # pluggy's @hookimpl decorator doesn't preserve the decorated function's
57
+ # type signature, so mypy fires "untyped-decorator" in strict mode.
58
+ # The hook contract is tested behaviourally; suppressing here is intentional.
59
+ [[tool.mypy.overrides]]
60
+ module = "bragi_theme_zelda.plugin"
61
+ disable_error_code = ["untyped-decorator"]
62
+
63
+ [tool.pytest.ini_options]
64
+ testpaths = ["tests"]
65
+ addopts = "-v"
66
+
67
+ [build-system]
68
+ requires = ["poetry-core"]
69
+ build-backend = "poetry.core.masonry.api"
@@ -0,0 +1,10 @@
1
+ """bragi-theme-zelda: a Link's-Awakening-flavoured bragi theme."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ try:
6
+ __version__ = version("bragi-theme-zelda")
7
+ except PackageNotFoundError:
8
+ __version__ = "0.0.0+unknown"
9
+
10
+ __all__ = ["__version__"]
@@ -0,0 +1,22 @@
1
+ """GB-frame wrapper for body images.
2
+
3
+ Takes the HTML for an already-pictureified <picture> block and wraps it
4
+ in <figure class="gb-frame"> with a pixel-font caption bar. The caption
5
+ comes from the markdown directive or, if absent, from the inner img alt.
6
+
7
+ Caption is uppercased to match the in-game text-box label convention.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+
13
+ def wrap_picture(picture_html: str, caption: str = "") -> str:
14
+ label_html = ""
15
+ if caption:
16
+ label_html = f'<span class="gb-frame__label">{caption.upper()}</span>'
17
+ return (
18
+ f'<figure class="gb-frame">'
19
+ f"{label_html}"
20
+ f'<div class="gb-frame__inner">{picture_html}</div>'
21
+ f"</figure>"
22
+ )