Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
name: Website checks

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
static-site:
name: Static site and design contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Verify Apple Design contract
run: python -m unittest discover -s tests -p 'test_*.py'
- name: Serve and smoke-test the published document
run: |
python -m http.server 8765 --directory . >/tmp/mhtoolkit-site.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
curl --fail --retry 5 --retry-connrefused http://127.0.0.1:8765/
- name: Reject whitespace errors
run: git diff --check
67 changes: 67 additions & 0 deletions assets/design-tokens.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
:root {
color-scheme: dark;
--surface-window: #071019;
--surface-sidebar: rgba(12, 26, 40, 0.78);
--surface-content: rgba(18, 39, 58, 0.94);
--separator: rgba(150, 210, 255, 0.22);
--label-primary: #ecf7ff;
--label-secondary: #a9bdcd;
--accent: #4dd2ff;
--state-success: #89ffcb;
--state-warning: #ffd166;
--state-error: #ff7b86;
--motion-response: 380ms;
--motion-easing: cubic-bezier(.2, .8, .2, 1);
--target-minimum: 44px;
--focus-ring: 0 0 0 3px rgba(77, 210, 255, 0.55);
}

a, button {
transition: color var(--motion-response) var(--motion-easing),
background-color var(--motion-response) var(--motion-easing),
transform var(--motion-response) var(--motion-easing);
}

a:focus-visible, button:focus-visible {
outline: none;
box-shadow: var(--focus-ring);
}

.button, .links a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link h2 a {
min-block-size: var(--target-minimum);
display: inline-flex;
align-items: center;
}

.project-link:hover { transform: translateY(-2px); }
.status[data-state="planning"] { border-inline-start: 4px solid var(--state-warning); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}

@media (prefers-reduced-transparency: reduce) {
:root {
--surface-sidebar: #0c1a28;
--surface-content: #12273a;
}
.logo-card { backdrop-filter: none !important; }
}

@media (prefers-contrast: more) {
:root {
--separator: rgba(236, 247, 255, 0.68);
--label-secondary: #d6e4ef;
}
}
54 changes: 54 additions & 0 deletions docs/design/accessibility-tree-2026-07-19.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- navigation [ref=e3]:
- link "MH Toolkit home" [ref=e4] [cursor=pointer]:
- /url: /
- img "MH Toolkit Nemessix shield logo" [ref=e5]
- generic [ref=e6]: MH Toolkit
- navigation "Project navigation" [ref=e7]:
- link "Projects" [ref=e8] [cursor=pointer]:
- /url: "#projects"
- link "Releases" [ref=e9] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub" [ref=e10] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- main [ref=e11]:
- generic [ref=e13]:
- generic [ref=e14]: macOS · Android · classic hunting tools
- heading "MH Toolkit" [level=1] [ref=e15]
- paragraph [ref=e16]: "An organization-level toolkit ecosystem for classic Monster Hunter emulation: focused repositories for overlays, emulator integration, saves, multiplayer, content tooling, and coordinated releases for macOS and Android."
- generic [ref=e17]:
- link "View the hub" [ref=e18] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- link "GitHub organization" [ref=e19] [cursor=pointer]:
- /url: https://github.com/MHToolkit
- region "Project areas" [ref=e21]:
- article [ref=e22]:
- heading [level=2] [ref=e23]:
- link "Nemessix" [ref=e24] [cursor=pointer]:
- /url: https://github.com/MHToolkit/nemessix
- paragraph [ref=e25]: A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.
- article [ref=e26]:
- heading [level=2] [ref=e27]:
- link "MH Overlay" [ref=e28] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-overlay
- paragraph [ref=e29]: Fail-closed, version-aware battle information with native macOS and Android presentation.
- article [ref=e30]:
- heading [level=2] [ref=e31]:
- link "MH Save Sync" [ref=e32] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-save-sync
- paragraph [ref=e33]: Encrypted, conflict-preserving save history with explicit queue and recovery states.
- article [ref=e34]:
- heading [level=2] [ref=e35]:
- link "MH Field Map" [ref=e36] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-field-map
- paragraph [ref=e37]: Accessible field reference and map states designed for online and offline use.
- article [ref=e38]:
- heading [level=2] [ref=e39]:
- link "Coordinated releases" [ref=e40] [cursor=pointer]:
- /url: https://github.com/MHToolkit/mh-toolkit
- paragraph [ref=e41]: Exact repository identities, platform support evidence, artifact hashes, and setup paths.
- status [ref=e42]:
- strong [ref=e43]: "Status:"
- text: active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.
- contentinfo [ref=e44]: © 2026 MH Toolkit · Built on GitHub Pages
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions docs/design/apple-design-inventory.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
# MHToolkit website Apple Design inventory

## Real UI entry points

- `index.html`: global navigation, hero, project/release navigation, status surface, responsive layout.
- `assets/design-tokens.css`: semantic surface/label/state/motion/accessibility mapping.

## State and accessibility inventory

- The release status is a persistent `role=status` surface with an explicit `data-state`.
- Project navigation needs visible focus, 44px targets, reduced-motion behavior, reduced-transparency fallback, increased-contrast tokens, and mobile reflow.
- The site must not infer compatibility from a repository link; copy remains fail-closed.

## Verification

- Contract: `rtk test python -m unittest tests/test_apple_design.py`
- Runtime: serve the repository root and capture desktop/mobile screenshots with Playwright.
- Static gate: `rtk git diff --check`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file addeddocs/design/apple-design-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/design/evidence-2026-07-18.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
# MHToolkit website Apple Design evidence — 2026-07-18

## Runtime capture

The site was served locally with `python -m http.server 8765` and captured with installed Google
Chrome through Playwright. No emulator, game, account, or restricted asset was launched.

```text
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='1440,1000' http://127.0.0.1:8765 \
docs/design/apple-design-desktop.png
rtk proxy npx playwright screenshot --channel=chrome --full-page \
--viewport-size='390,844' http://127.0.0.1:8765 \
docs/design/apple-design-mobile.png
```

| Artifact | SHA-256 |
| --- | --- |
| `apple-design-desktop.png` | `f1602218cc9464a1f60f9fd64cd60cbda4ff5bba35e769a488aef59a367a8263` |
| `apple-design-mobile.png` | `3e4d655d1d6e0a9716ee59734b9211ec70e29a48a87dea3ad2dddf9f81174522` |

## Automated evidence

`rtk test python -m unittest tests/test_apple_design.py` passed 2 tests. The contract covers semantic
tokens, focus visibility, reduced motion/transparency, increased contrast, all four product links,
project navigation semantics, and explicit planning state. `rtk git diff --check` passed.

PR [MHToolkit.github.io#1](https://github.com/MHToolkit/MHToolkit.github.io/pull/1) now has a
real `Website checks / Static site and design contract` workflow. Run `29656576581` passed the
three-test unittest discovery, served `index.html` over a local HTTP server, fetched it with
fail-closed `curl --fail`, and checked whitespace on commit `adb31fc601521f6006c3218e839770fa910ff71d`.
46 changes: 46 additions & 0 deletions docs/design/runtime-accessibility-2026-07-19.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
# MHToolkit website runtime and accessibility evidence — 2026-07-19

## Runtime

The worktree was served without any game, emulator, account, or restricted asset:

```text
rtk proxy python3 -m http.server 8765 --bind 127.0.0.1
rtk proxy curl --fail --silent --show-error http://127.0.0.1:8765/ -o /tmp/mhtoolkit-web-index.html
```

The HTTP smoke request exited `0`; the fetched document SHA-256 was
`716c77de84c4f880f7c61920056430ae237d92dbf3deb3fda0ee77afdc32af4b`.

Playwright CLI opened `http://127.0.0.1:8765/` in Chrome, reloaded after the semantic
contract change, and captured the full scrollable page at both target viewports.

| Artifact | Viewport | SHA-256 |
| --- | --- | --- |
| `apple-design-desktop-runtime-full.png` | 1440x1000 | `10952f588c0ac7e68c2e65559257080ed60d4904b0fc1d0646657b8629b233e8` |
| `apple-design-mobile-runtime-full.png` | 390x844 | `4faf143970c69fcc0708e5dca01d9983b184730fb9542ee23aa03d51612929e5` |

## Semantic/accessibility tree

The captured Playwright accessibility snapshot is checked in at
`docs/design/accessibility-tree-2026-07-19.yml` (SHA-256
`00b9b913eb69cd293f66f40f80108db9967ba0df3c8d600a43b0816cb9286dc5`). It confirms:

- document title `MH Toolkit`, language `en`, and banner/main/contentinfo landmarks;
- explicit `Project navigation` navigation landmark;
- labelled `Project areas` region with five article entries and links for Nemessix, MH Overlay,
MH Save Sync, MH Field Map, and Coordinated releases;
- a `status` live region containing the fail-closed compatibility state;
- all 11 links exposed as keyboard focusable controls.

The browser-side computed-style probe confirmed each project link uses
`display: inline-flex` and `min-block-size: 44px`. The static contract also covers focus-visible,
reduced-motion, reduced-transparency, and increased-contrast states.

## Verification

```text
rtk test python -m unittest discover -s tests -p 'test_*.py' # 3 passed
rtk git diff --check # exit 0
```

54 changes: 31 additions & 23 deletions index.html
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,17 +10,17 @@
<meta property="og:url" content="https://mhtoolkit.github.io" />
<title>MH Toolkit</title>
<link rel="icon" href="assets/logo.png" />
<link rel="stylesheet" href="assets/design-tokens.css" />
<style>
:root {
color-scheme: dark;
--bg: #071019;
--panel: rgba(12, 26, 40, 0.78);
--panel-strong: rgba(18, 39, 58, 0.94);
--text: #ecf7ff;
--muted: #9fb4c6;
--line: rgba(150, 210, 255, 0.18);
--accent: #4dd2ff;
--accent-2: #89ffcb;
--bg: var(--surface-window);
--panel: var(--surface-sidebar);
--panel-strong: var(--surface-content);
--text: var(--label-primary);
--muted: var(--label-secondary);
--line: var(--separator);
--accent-2: var(--state-success);
--shadow: rgba(0, 0, 0, 0.35);
}

Expand DownExpand Up@@ -79,10 +79,10 @@
<img src="assets/logo.png" alt="MH Toolkit Nemessix shield logo" />
<span>MH Toolkit</span>
</a>
<div class="links">
<a href="https://github.com/MHToolkit/mh-toolkit">Toolkit</a>
<a href="https://github.com/MHToolkit/mh-overlay">Overlay</a>
<a href="https://github.com/MHToolkit/nemessix">Nemessix</a>
<div class="links" role="navigation" aria-label="Project navigation">
<a href="#projects">Projects</a>
<a href="https://github.com/MHToolkit/mh-toolkit">Releases</a>
<a href="https://github.com/MHToolkit">GitHub</a>
</div>
</nav>
</header>
Expand All@@ -103,22 +103,30 @@ <h1>MH Toolkit</h1>
</div>
</section>

<section class="grid" aria-label="Project areas">
<article class="card">
<h2>Focused tool repositories</h2>
<p>Overlay, emulator integration, save sync, multiplayer and content tooling evolve in separate owner-led repositories instead of one overloaded implementation repo.</p>
<section class="grid" id="projects" aria-label="Project areas">
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/nemessix">Nemessix</a></h2>
<p>A capability-driven Nintendo engine platform with a unified library and platform-native multiplayer coordination.</p>
</article>
<article class="card">
<h2>Hub-level releases</h2>
<p>The hub tracks repository responsibilities, integration gates, coordinated tags, release notes, and user-facing setup paths.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-overlay">MH Overlay</a></h2>
<p>Fail-closed, version-aware battle information with native macOS and Android presentation.</p>
</article>
<article class="card">
<h2>Nemessix first</h2>
<p>Phase one validates runtime behavior through Nemessix while the architecture stays ready for additional emulator adapters later.</p>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-save-sync">MH Save Sync</a></h2>
<p>Encrypted, conflict-preserving save history with explicit queue and recovery states.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-field-map">MH Field Map</a></h2>
<p>Accessible field reference and map states designed for online and offline use.</p>
</article>
<article class="card project-link">
<h2><a href="https://github.com/MHToolkit/mh-toolkit">Coordinated releases</a></h2>
<p>Exact repository identities, platform support evidence, artifact hashes, and setup paths.</p>
</article>
</section>

<p class="status"><strong>Status:</strong> planning and infrastructure bootstrap. Repositories are private while architecture, governance, and implementation boundaries are being prepared.</p>
<p class="status" data-state="planning" role="status"><strong>Status:</strong> active platform development. Compatibility remains fail-closed until each product and artifact has reproducible evidence.</p>
</main>

<footer class="shell">
Expand Down
34 changes: 34 additions & 0 deletions tests/test_apple_design.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class AppleDesignWebTests(unittest.TestCase):
def test_shared_semantic_tokens_and_accessibility_states_are_wired(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()

self.assertIn('href="assets/design-tokens.css"', html)
self.assertIn("--surface-window", tokens)
self.assertIn("--state-warning", tokens)
self.assertIn("prefers-reduced-motion", tokens)
self.assertIn("prefers-reduced-transparency", tokens)
self.assertIn("prefers-contrast", tokens)
self.assertIn(":focus-visible", tokens)

def test_project_navigation_exposes_all_user_products(self):
html = (ROOT / "index.html").read_text()
tokens = (ROOT / "assets/design-tokens.css").read_text()
for product in ("Nemessix", "MH Overlay", "MH Save Sync", "MH Field Map"):
self.assertIn(product, html)
self.assertIn('aria-label="Project navigation"', html)
self.assertIn('role="navigation"', html)
self.assertIn(".project-link h2 a", tokens)
self.assertIn("min-block-size: var(--target-minimum)", tokens)
self.assertIn('data-state="planning"', html)


if __name__ == "__main__":
unittest.main()
18 changes: 18 additions & 0 deletions tests/test_ci_contract.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
import unittest
from pathlib import Path


ROOT = Path(__file__).parents[1]


class CiContractTests(unittest.TestCase):
def test_ci_workflow_runs_contract_and_static_site_tests(self):
workflow = (ROOT / ".github" / "workflows" / "ci.yml").read_text()

self.assertIn("python -m unittest discover -s tests -p 'test_*.py'", workflow)
self.assertIn("python -m http.server", workflow)
self.assertIn("curl --fail", workflow)


if __name__ == "__main__":
unittest.main()
Loading