From 48018d61516994a97996e19958f09eddd5b5ecc3 Mon Sep 17 00:00:00 2001 From: fOuttaMyPaint Date: Sat, 20 Jun 2026 16:03:49 -0400 Subject: [PATCH] docs: facelift the examples gallery + enrich landing meta Gallery page (this-repo-owned, generated from gallery.json): - Add light/dark/auto theme with a toggle synced to the landing page's localStorage 'theme' key, so a visitor's choice carries across pages (was hardcoded dark, inconsistent with the landing). - Full meta/SEO/social: canonical, og:*, twitter card, theme-color, favicon. - Visual polish: sticky top bar, fluid type scale, refined cards with hover lift, :focus-visible states, skip link, prefers-reduced-motion guard. - Responsive 1->2 columns at 720px; heroes kept uncropped (align-items:start). Landing (via existing site.json template hooks -- no template edit, no fleet blast radius): favicon, canonical, and a this-repo og:image (was the meta-repo default logo), plus Claude Code + cross-platform compatibility badges. Add assets/favicon.svg (shared by both pages; build_site copies assets/ -> docs/assets/). Capture the design direction in docs/gallery/DESIGN_NOTES.md as the prototype for the Option-2 fleet facelift. Co-Authored-By: Claude Opus 4.8 Signed-off-by: fOuttaMyPaint --- assets/favicon.svg | 10 ++ docs/gallery/DESIGN_NOTES.md | 44 +++++++ docs/gallery/index.html | 157 ++++++++++++++++++------- examples/gallery.json | 3 + scripts/build_gallery.py | 215 +++++++++++++++++++++++++---------- site.json | 7 ++ 6 files changed, 336 insertions(+), 100 deletions(-) create mode 100644 assets/favicon.svg create mode 100644 docs/gallery/DESIGN_NOTES.md diff --git a/assets/favicon.svg b/assets/favicon.svg new file mode 100644 index 0000000..cc4c49a --- /dev/null +++ b/assets/favicon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/gallery/DESIGN_NOTES.md b/docs/gallery/DESIGN_NOTES.md new file mode 100644 index 0000000..d15fa05 --- /dev/null +++ b/docs/gallery/DESIGN_NOTES.md @@ -0,0 +1,44 @@ +# Gallery design direction — prototype for the Option-2 fleet facelift + +This local gallery (`docs/gallery/`, generated by `scripts/build_gallery.py` from +`examples/gallery.json`) is the **deliberate prototype** for the eventual shared-template +facelift tracked in [Developer-Tools-Directory#86](https://github.com/TMHSDigital/Developer-Tools-Directory/issues/86) +and the ROADMAP "Fleet Pages examples support" candidate. The markup here is throwaway on +migration; the **data** (`gallery.json`) and the **visual direction** below are what carry over. + +## Tokens (aligned to the fleet landing page so the two never clash) + +| Token | Dark | Light | Notes | +| --- | --- | --- | --- | +| `--bg` | `#0d1117` | `#f6f8fa` | matches landing's GitHub-dark base | +| `--surface` | `#161b22` | `#ffffff` | card background | +| `--surface-2` | `#1c2128` | `#f0f2f5` | toggle / inline code | +| `--border` | `#30363d` | `#d0d7de` | | +| `--text` | `#e6edf3` | `#1f2328` | | +| `--text-dim` | `#8b949e` | `#656d76` | secondary text | +| `--accent` / `--accent-light` | `#7c3aed` / `#a78bfa` | same | from `site.json`; shared with landing | +| `--radius` / `--radius-lg` | `8px` / `12px` | — | cards use `-lg` | +| font | `'Inter', system-ui…` | — | landing ships the Inter webfont; the prototype uses the same stack and falls back to system sans (no coupling to the fleet font files) | + +## Type scale +- Page title `h1`: `clamp(1.9rem, 4vw, 2.6rem)`, `letter-spacing: -0.02em` — fluid hero. +- Card title `h2`: `1.22rem`. +- Body: `1rem` / `line-height: 1.6`; secondary `0.9rem`; tag `0.68rem` uppercase. + +## Layout +- Container `max-width: 1080px`, centered, `1.25rem` side padding. +- Grid: **1 column** mobile → **2 columns at ≥720px**, `align-items: start` (cards don't stretch to a shared row height — heroes have mixed aspect ratios, e.g. the 8:3 swatch panorama vs 16:9 stills, and must not be cropped). +- Card: hero image (full-bleed, natural aspect, never cropped) above a body block; hover lifts `-3px` with an accent-tinted border and soft shadow. + +## Theme +- Tri-state **auto / light / dark** mirroring the landing: `data-theme` on ``, persisted in `localStorage['theme']` — **the same key the landing uses**, so a visitor's choice carries across both pages. +- FOUC guard runs before first paint. `theme-color` meta per scheme. Toggle cycles auto→light→dark with a sun/moon glyph and an accurate `aria-label`. + +## Accessibility +- Skip-to-content link; `:focus-visible` outlines (accent, 2px); `prefers-reduced-motion` disables hover transform + smooth scroll; descriptive `alt` per hero ("``"); single `h1`, card titles as `h2`. + +## What the fleet template should adopt (not the markup, the direction) +1. The token set above as CSS variables, light/dark parity with the existing landing palette. +2. An **Examples grid** section reading `gallery.json` (per-entry `name/dir/teaches/witnessesFix/hero/preview`), cards styled as here. +3. A **nav link to the gallery** (closes the landing→gallery cross-link gap — impossible today without a template edit). +4. Keep heroes uncropped (`align-items: start`, natural aspect) — cropping loses content like the swatch panorama's outer spheres. diff --git a/docs/gallery/index.html b/docs/gallery/index.html index 4886f73..b65dbcf 100644 --- a/docs/gallery/index.html +++ b/docs/gallery/index.html @@ -5,83 +5,142 @@ Examples Gallery — Blender Developer Tools + + + + + + + + + + + + + + + -
- ← Blender Developer Tools + + +

Examples Gallery

-

Runnable, smoke-gated demos. Each is executed headless on Blender 4.5 LTS and 5.1 by the - blender-smoke workflow, so every render reflects code that actually runs.

+

Runnable, smoke-gated Blender Python examples — each executed headless on Blender 4.5 LTS and 5.1, so every render reflects code that actually runs.

-
+
- - swatch-grid — Procedural Principled materials — metal and dielectric, the emission pattern, and the cross-version set_specular shim + + swatch-grid — Procedural Principled materials — metal and dielectric, the emission pattern, and the cross-version set_specular shim

swatch-grid

Procedural Principled materials — metal and dielectric, the emission pattern, and the cross-version set_specular shim.

witnesses EEVEE engine-id mapping: BLENDER_EEVEE on 5.x, BLENDER_EEVEE_NEXT on 4.2–4.5.

- View example → + View example
- - turntable — A slotted-actions Z-rotation turntable keyed through the cross-version channelbag path (get_channelbag_for_slot) + + turntable — A slotted-actions Z-rotation turntable keyed through the cross-version channelbag path (get_channelbag_for_slot)

turntable

A slotted-actions Z-rotation turntable keyed through the cross-version channelbag path (get_channelbag_for_slot).

witnesses Slotted-actions boundary: ensure-helper channelbag on 5.x, strip.channelbag on 4.4/4.5.

- View example → + View example
- - gn-sdf-remesh — A Geometry Nodes SDF remesh (MeshToSDFGrid → GridToMesh at the SDF zero-level), with a Set Material node carrying the material through the remesh + + gn-sdf-remesh — A Geometry Nodes SDF remesh (MeshToSDFGrid → GridToMesh at the SDF zero-level), with a Set Material node carrying the material through the remesh

gn-sdf-remesh

A Geometry Nodes SDF remesh (MeshToSDFGrid → GridToMesh at the SDF zero-level), with a Set Material node carrying the material through the remesh.

witnesses An SDF grid is meshed with Grid to Mesh, not Volume to Mesh; GN geometry needs Set Material or it renders untextured.

- View example → + View example
@@ -89,5 +148,25 @@

- - {name} — {teaches_plain} + + __ALT__
-

{name}

-

{teaches}

-

witnesses {witnesses}

- View example → +

__NAME__

+

__TEACHES__

+

witnesses __WITNESSES__

+ View example
""" @@ -40,66 +42,145 @@ - Examples Gallery — Blender Developer Tools - + __TITLE__ — Blender Developer Tools + + + + + + + + + + + + + + + + -
- ← Blender Developer Tools -

Examples Gallery

-

Runnable, smoke-gated demos. Each is executed headless on Blender 4.5 LTS and 5.1 by the - blender-smoke workflow, so every render reflects code that actually runs.

+ + +
+

__TITLE__

+

__DESC__

-
-{cards} +
+__CARDS__
Generated from examples/gallery.json by scripts/build_gallery.py.  •  CC-BY-NC-ND-4.0
+ """ -def strip_to_page_relative(repo_rel: str) -> str: +def page_relative(repo_rel: str) -> str: """docs/gallery/assets/x.webp -> assets/x.webp (relative to the gallery page).""" prefix = "docs/gallery/" return repo_rel[len(prefix):] if repo_rel.startswith(prefix) else repo_rel @@ -108,6 +189,9 @@ def strip_to_page_relative(repo_rel: str) -> str: def main() -> int: data = json.loads(DATA.read_text(encoding="utf-8")) base = data["repoBaseUrl"].rstrip("/") + site = data.get("siteBaseUrl", "").rstrip("/") + title = data.get("title", "Examples Gallery") + desc = data.get("description", "") examples = data["examples"] if not examples: print("ERROR: no examples in gallery.json", file=sys.stderr) @@ -115,21 +199,30 @@ def main() -> int: cards = [] for ex in examples: - hero_rel = strip_to_page_relative(ex["hero"]) if not (REPO / ex["hero"]).is_file(): print(f"ERROR: hero image missing: {ex['hero']}", file=sys.stderr) return 3 - cards.append(CARD.format( - href=html.escape(f"{base}/{ex['dir']}"), - hero=html.escape(hero_rel), - name=html.escape(ex["name"]), - teaches=html.escape(ex["teaches"]), - teaches_plain=html.escape(ex["teaches"].split(".")[0]), - witnesses=html.escape(ex["witnessesFix"]), - )) + alt = f'{ex["name"]} — {ex["teaches"].split(".")[0]}' + card = (CARD + .replace("__HREF__", html.escape(f"{base}/{ex['dir']}")) + .replace("__HERO__", html.escape(page_relative(ex["hero"]))) + .replace("__ALT__", html.escape(alt)) + .replace("__NAME__", html.escape(ex["name"])) + .replace("__TEACHES__", html.escape(ex["teaches"])) + .replace("__WITNESSES__", html.escape(ex["witnessesFix"]))) + cards.append(card) + + og_image = f"{site}/gallery/assets/{page_relative(examples[0]['hero']).split('/')[-1]}" if site else "" + canonical = f"{site}/gallery/" if site else "" + out_html = (PAGE + .replace("__CARDS__", "\n".join(cards)) + .replace("__TITLE__", html.escape(title)) + .replace("__DESC__", html.escape(desc)) + .replace("__CANONICAL__", html.escape(canonical)) + .replace("__OGIMAGE__", html.escape(og_image))) OUT.parent.mkdir(parents=True, exist_ok=True) - OUT.write_text(PAGE.format(cards="\n".join(cards)), encoding="utf-8") + OUT.write_text(out_html, encoding="utf-8") print(f"Wrote {OUT} ({len(examples)} examples)") return 0 diff --git a/site.json b/site.json index c658b37..13b349e 100644 --- a/site.json +++ b/site.json @@ -3,6 +3,13 @@ "accentLight": "#a78bfa", "heroGradientFrom": "#0d1117", "heroGradientTo": "#161b22", + "canonical": "https://tmhsdigital.github.io/Blender-Developer-Tools/", + "favicon": "assets/favicon.svg", + "ogImage": "https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/swatch-grid-hero.webp", + "compatibility": { + "claude": "Claude Code", + "os": ["Windows", "macOS", "Linux"] + }, "links": { "github": "https://github.com/TMHSDigital/Blender-Developer-Tools" },