diff --git a/README.md b/README.md index 0163969..03c1f30 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ Community skills for UI craft. Claude consults these automatically during UI wor | Skill | What it does | Source | |-------|-------------|--------| | `emil-design-eng/` | Animation craft — easing curves, spring physics, polish | [emilkowalski/skill](https://github.com/emilkowalski/skill) | +| `review-animations/` | Hard-nosed motion review — flags easing, duration, origin, interruptibility, performance, and a11y | [emilkowalski/skill](https://github.com/emilkowalski/skill) | | `make-interfaces-feel-better/` | 16 UI detail principles (optical alignment, shadows, stagger, hit areas) | [jakubkrehel](https://github.com/jakubkrehel/make-interfaces-feel-better) | | `taste-skill-suite/` | Anti-LLM-bias, typography calibration, color correction, layout diversification | [Leonxlnx/taste-skill](https://github.com/Leonxlnx/taste-skill) | | `impeccable/` | 17 design commands — dark mode mastery, polish, audit | [impeccable.style](https://impeccable.style) | @@ -140,6 +141,7 @@ Run these after writing code to clean up before shipping. | `tdd/` | Test-driven development — red/green/refactor loop | | `fix-sentry-issues/` | Discover, triage, and fix production errors from Sentry | | `reclaude/` | Refactor bloated CLAUDE.md files using progressive disclosure | +| `gemini-review/` | Read-only Google AI / Antigravity second-model review over a git diff | --- @@ -186,6 +188,7 @@ Entry point: `skills/studio/_graph/studio.moc.md` │ ├── studio/ # Studio Skill Graph (90+ files) │ │ └── _graph/ │ ├── emil-design-eng/ +│ ├── review-animations/ │ ├── make-interfaces-feel-better/ │ ├── taste-skill-suite/ │ ├── impeccable/ @@ -201,7 +204,8 @@ Entry point: `skills/studio/_graph/studio.moc.md` │ ├── knip/ │ ├── tdd/ │ ├── fix-sentry-issues/ -│ └── reclaude/ +│ ├── reclaude/ +│ └── gemini-review/ └── docs/ └── setup-guide.md ``` diff --git a/docs/design-intelligence-loop.md b/docs/design-intelligence-loop.md new file mode 100644 index 0000000..5799c43 --- /dev/null +++ b/docs/design-intelligence-loop.md @@ -0,0 +1,105 @@ +# Design Intelligence Loop + +## Recommendation + +Rebuild the old OpenClaw weekly design digest as a Codex-owned automation that uses Stack as the durable skill source. + +Ownership split: +- Stack owns the design-intelligence skill, graph references, templates, and promotion rules. +- Codex owns runner scripts, eval bundles, install wiring, and eventual recurring automation. +- Hermes and GBrain remain source/memory substrates: bookmark snapshots, imports, and backfill staging. +- OpenClaw is historical evidence only; do not depend on its stale cron state for the rebuild. + +## Weekly Inputs + +Every weekly run must read: +- Arc sidebar/bookmark state from `~/Library/Application Support/Arc/StorableSidebar.json`. +- Arc History as a recency supplement only. +- Field Theory/X bookmarks from `~/.ft-bookmarks/bookmarks.db`, JSONL, Markdown exports, and media metadata. +- GBrain imported bookmark roots, especially deltas where Field Theory is ahead. +- Curated web sources: Brian Lovin, Design Spells, Handheld Design, Featured Mobile. + +Intake is read-only. The run may write a source manifest, digest, and promotion packet, but it must not mutate Arc, Field Theory, X, GBrain roots, Vault, or Studio skills during collection. + +## Weekly Flow + +1. Build a source manifest with read status, candidate counts, and extraction failures. +2. Synthesize the weekly digest using the preserved Output A/B/C structure. +3. Produce a promotion packet for Zettelkasten and Studio/CDO skill candidates. +4. Run the Codex design eval gate for any candidate skill update. +5. Promote only through a reviewable Stack change after eval evidence exists. + +## Historical Backfill + +Initial backfill window: `2026-04-01` through the current run date. + +Chunk by week. Each chunk should produce: +- `source-manifest.json` +- `weekly-design-digest-YYYY-MM-DD.md` +- `promotion-packet.md` + +Use Hermes tmp or another review staging area for generated packets until promotion is approved. + +## Commands + +Read-only source manifest: + +```bash +/Users/maroun/Codex/scripts/design-intelligence-source-manifest.sh \ + --since 2026-04-01 \ + --until 2026-06-15 \ + --out /Users/maroun/hermes/tmp/design-intelligence-backfill/source-manifest.json +``` + +Historical backfill packet: + +```bash +/Users/maroun/Codex/scripts/run-design-intelligence-backfill.sh \ + --since 2026-04-01 \ + --until 2026-06-15 \ + --out-root /Users/maroun/hermes/tmp/design-intelligence-backfill +``` + +Eval bundle dry run: + +```bash +cd /Users/maroun/Codex +DRY_RUN=1 FINAL_HTML_ONLY=1 IGNORE_USER_CONFIG=1 \ + scripts/evaluate-design-skills.sh run-one design-intelligence-v1 001-operational-dashboard +``` + +Promotion gate: + +```bash +cd /Users/maroun/Codex +EVAL_BUNDLES="codex-current design-intelligence-v1" \ +EVAL_PROMPTS="001-operational-dashboard 002-productivity-app 003-landing-page-with-assets 004-existing-page-redesign 005-data-workflow" \ +FINAL_HTML_ONLY=1 IGNORE_USER_CONFIG=1 RUN_ID=design-intelligence-gate \ + scripts/evaluate-design-skills.sh run-matrix +``` + +## Automation Gate + +Do not enable the recurring weekly automation until the operator approves the live job. + +Recommended live cadence: +- Saturday morning: source manifest and digest. +- Sunday evening: taste-compounding promotion packet after digest review. + +## Latest Candidate Eval + +Latest verified gate: `2026-06-17`. + +Baseline run: +`/Users/maroun/Codex/eval/design-skills/runs/design-intelligence-gate-20260615T223548Z` + +Candidate run: +`/Users/maroun/Codex/eval/design-skills/runs/design-intelligence-gate-final2-20260615T232621Z` + +Result: `design-intelligence-v1` beat `codex-current` on 5 of 5 fixtures with no candidate hard fails. + +Evidence saved with the candidate run: +- `report.md` +- `viewport-hard-gate.tsv` +- `screenshots-final/contact-sheet-mobile.jpg` +- `screenshots-final/contact-sheet-desktop.jpg` diff --git a/skills/cdo/references/inspiration-sources.md b/skills/cdo/references/inspiration-sources.md index 96b138e..1c85af1 100644 --- a/skills/cdo/references/inspiration-sources.md +++ b/skills/cdo/references/inspiration-sources.md @@ -9,6 +9,12 @@ Curated by Maroun. These are the galleries, collections, and channels Studio sho - Curated by former GitHub/Meta designer. High bar. Real shipping products. - Best for: Overall site quality, navigation, layout, polish +- **Recent — Design Inspiration** — https://recent.design/ + - Daily-updated gallery of strong recent design found around the internet. + - Best for: fresh visual references, current product/site patterns, quick taste-mining before a design pass. + - Use when Studio/CDO needs contemporary examples without falling into stale Dribbble/Pinterest sludge. + - Added from Maroun's design inspo request, 2026-06-21. + ### Micro-Interactions & Delight - **Design Spells** — https://www.designspells.com/ - "Design details that feel like magic" by Chester & Duncan @@ -25,6 +31,13 @@ Curated by Maroun. These are the galleries, collections, and channels Studio sho - Mobile app showcase - Best for: Mobile UI patterns, app design trends +### Interaction Design Essays & Playgrounds +- **Aresluna — Show your hands honor for the strange power they bring you** — https://aresluna.org/show-your-hands-honor/ + - Marcin Wichary essay on designing finger-friendly interactions, with 38 playgrounds. + - Best for: touch ergonomics, motor memory, keyboard/finger interaction details, perceived speed, and explaining why tiny interaction choices matter. + - Use when Studio/CDO needs principled backing for mobile gestures, physical affordances, latency polish, or “this detail feels small but changes the whole interaction” arguments. + - Added from Maroun's design inspo request, 2026-06-20. + ## Tier 2 — Deep Aesthetic Research ### Are.na Channels @@ -60,6 +73,10 @@ Another curated platform — higher signal than Dribbble. - **Refero** — https://refero.design/ — Real product screenshots - **Product Hunt** — Design quality of new launches +### Product Presentation & Mockup Tooling + +- **Ultramock** — https://ultramock.io/ — Turns product screens into premium customizable visuals, videos, and 3D mockups. Use when portfolio/case-study/launch assets need more polish than raw screenshots or stock device frames. Added from Maroun's saved-link request, 2026-06-19. + ## How to Use These ### During `/tastemining` or `/research` diff --git a/skills/design-intelligence/SKILL.md b/skills/design-intelligence/SKILL.md new file mode 100644 index 0000000..b8b304e --- /dev/null +++ b/skills/design-intelligence/SKILL.md @@ -0,0 +1,79 @@ +--- +name: design-intelligence +description: "Run the weekly design intelligence loop: scan curated sources, Arc bookmarks, Field Theory/X bookmarks, and GBrain deltas; synthesize a design digest; propose review-gated skill updates; and require eval evidence before promotion." +--- + +# Design Intelligence Loop + +Use this skill for the rebuilt weekly design digest and taste-compounding workflow. + +The loop has two jobs: +- Find high-signal design inspiration from curated sources and Maroun's saved links. +- Convert repeated lessons into reviewable Studio/CDO skill updates only after evidence and eval. + +## Operating Rule + +Run as a read-only intake by default. Do not mutate Arc, Field Theory, X/Twitter, GBrain source roots, Vault, or Studio skill files during source collection. + +Promotion is a separate review step. + +## Load Order + +1. Read `references/source-adapters.md` for the source surfaces and safe access rules. +2. Read `references/output-contract.md` for digest and backfill deliverables. +3. Read `references/promotion-rules.md` before proposing any skill update. +4. For the 2026 OpenClaw outage recovery candidate, read `references/backfill-candidate-guidance-2026-06-15.md`. +5. Read `eval/checklist.md` before claiming a run is complete. +6. Use `templates/weekly-digest.md` for the report body. + +## Weekly Run + +Default cadence: Saturday morning, after bookmark sync and before any taste-compounding promotion. + +Use a seven-day window unless the operator passes an explicit range. + +Required source lanes: +- Curated sources: Brian Lovin `/sites` or writing, Design Spells, Handheld Design, Featured Mobile. +- Arc bookmarks/sidebar: current sidebar plus Arc history as a date supplement. +- Field Theory/X bookmarks: live Field Theory SQLite/JSONL/Markdown export. +- GBrain: imported `x-bookmarks` and saved-link roots, especially deltas where Field Theory is ahead. + +## Historical Backfill + +For the OpenClaw outage recovery, run a catch-up window before resuming normal weekly cadence. + +Default catch-up window: `2026-04-01` through the current run date. + +Chunk the backfill by week. Each chunk should produce its own source manifest and digest so weak or unreachable sources are visible instead of hidden inside one giant report. + +## Outputs + +Every run must produce: +- A source manifest with counts, paths used, fetch/read status, and candidate samples. +- A weekly design digest with Output A, Output B, and Output C. +- A promotion packet with proposed Studio/CDO changes, evidence links, and the eval gate required before promotion. + +The digest may suggest Zettelkasten notes and skill changes, but it must not directly write them. + +## Evaluation Gate + +Before a proposed skill update becomes the default runtime behavior: +- Install or refresh the candidate skill into Codex. +- Run the design-skill eval matrix against `codex-current`. +- Promote only when the candidate beats `codex-current` on at least 4 fixtures and has no hard fails. + +If the eval harness is unavailable, mark the promotion packet as blocked rather than approving it from taste alone. + +## Candidate Guidance From Historical Backfill + +Status: candidate from the 2026-04-01..2026-06-15 OpenClaw outage backfill. Use this guidance for `design-intelligence-v1` eval runs; do not treat it as default runtime taste until the eval gate passes and the Stack change is reviewed. + +- Ground taste in concrete references before inventing. Use saved references, pattern libraries, side-by-side comparisons, and explicit visual vocabulary as design infrastructure; do not let the model free-associate a generic style when evidence exists. +- Treat component registries as raw ingredients, not an aesthetic. When using shadcn/ui or a registry source, borrow coverage of states, layout primitives, and component anatomy, then deliberately customize density, tokens, radii, shadows, and interaction states so the result does not read like a default registry demo. +- Use named, state-driven motion instead of generic decoration. Pick the smallest transition that clarifies a real state change, document its trigger, timing, interruption behavior, and reduced-motion fallback, and avoid `transition-all`, perpetual ambient movement, or motion that hides missing hierarchy. +- For AI-assisted design or builder workflows, expose the design tree. The UI should show the brief/prompt, generated directions, comparison criteria, selected branch, iteration history, and eval/QA state as first-class product surfaces rather than collapsing the experience into a chat box. +- Generate design candidates in multiples when exploring taste, compare them side by side against the rubric, then refine the selected branch. Do not promote a single attractive artifact without critique/eval evidence. +- For operational and data-heavy tools, favor dense comparative workspaces: tables, filters, timelines, side panels, validation states, batch controls, and specific deltas. Do not let portfolio, launch-page, or configurator inspiration override the user's primary workflow. +- Dense mobile tables must recompose, not widen the page. At narrow viewports, switch to priority columns, stacked row cards, or an internal scroll region whose parent still keeps `documentElement.scrollWidth <= innerWidth`; do not rely on a large table `min-width` that creates page-level horizontal overflow. +- Before/after redesign artifacts should open on the improved experience. If a legacy "before" view is included for comparison, constrain it inside the viewport and never let the old layout define the page width or primary mobile experience. +- Mobile hard gates apply to the whole shell, not just content tables. Top-level app wrappers, sidebars, sticky headers, nav rows, filters, panels, charts, and dialogs need `min-width:0`, `max-width:100%`, and wrapping/contained overflow so no child can expand the document past the viewport. diff --git a/skills/design-intelligence/eval/checklist.md b/skills/design-intelligence/eval/checklist.md new file mode 100644 index 0000000..dc9b92a --- /dev/null +++ b/skills/design-intelligence/eval/checklist.md @@ -0,0 +1,33 @@ +--- +id: design-intelligence.eval-checklist +name: Design Intelligence Eval Checklist +description: Completion checklist for weekly digest and skill promotion runs. +--- + +# Eval Checklist + +## Intake Complete + +- [ ] Curated web sources checked or marked unreachable. +- [ ] Arc sidebar scanned read-only. +- [ ] Arc history used only as a recency supplement. +- [ ] Field Theory/X bookmarks scanned from SQLite or JSONL. +- [ ] GBrain import delta checked. +- [ ] Source manifest written with counts, paths, and failures. + +## Digest Complete + +- [ ] Output A includes 3-5 findings with source links and apply-this notes. +- [ ] Output B includes at most 3 Zettelkasten candidates and uses wikilinks. +- [ ] Output C includes at most 3 Studio/CDO skill candidates. +- [ ] No digest claim says a file was saved unless the file exists. +- [ ] Failures are visible instead of hidden. + +## Promotion Complete + +- [ ] Each skill candidate has evidence and an idempotency check. +- [ ] No source corpus or Vault note was mutated during intake. +- [ ] Candidate changes are reviewable as a patch/PR. +- [ ] Codex design eval was run or the packet is marked blocked on eval. +- [ ] Candidate beats `codex-current` on at least 4 fixtures with no hard fails before default promotion. + diff --git a/skills/design-intelligence/references/backfill-candidate-guidance-2026-06-15.md b/skills/design-intelligence/references/backfill-candidate-guidance-2026-06-15.md new file mode 100644 index 0000000..1d4fea9 --- /dev/null +++ b/skills/design-intelligence/references/backfill-candidate-guidance-2026-06-15.md @@ -0,0 +1,138 @@ +--- +id: design-intelligence.backfill-candidate-guidance-2026-06-15 +name: Backfill Candidate Guidance 2026-06-15 +description: Candidate taste guidance synthesized from the 2026 OpenClaw outage backfill. +--- + +# Backfill Candidate Guidance - 2026-06-15 + +Status: `candidate - pending eval`. + +This reference turns the historical backfill packets into reviewable taste/skill candidates. It is intentionally narrow: source collection stayed read-only, and this file does not promote anything into the default runtime by itself. + +## Evidence Summary + +Backfill window: `2026-04-01..2026-06-15`. + +Source packet root: +`/Users/maroun/hermes/tmp/design-intelligence-backfill/2026-04-01..2026-06-15` + +Normalized candidate counts: + +| Source | Candidates | +| --- | ---: | +| Field Theory/X bookmarks | 192 | +| Arc history | 179 | +| Arc sidebar/bookmarks | 24 | +| Curated web | 0, marked `not_fetched_by_manifest_script` | +| GBrain X bookmarks | 0 candidates in packets; Field Theory reported 318 missing markdown files | + +The GBrain delta is an ingestion/process signal, not permission to write GBrain roots. Curated web being degraded means web-source themes should be corroborated in a future weekly run before becoming defaults. + +## Promoted Candidates For Eval + +### 1. Reference-Backed Taste Uses Concrete Sources + +Evidence: +- 33 reference/taste matches in the synthesis-agent pass. +- 10 weekly windows. +- Sources: Field Theory/X bookmarks and Arc history/sidebar. +- Domains/categories included design reference libraries, interface inspiration sites, shape/language references, and saved design workflow links. + +Guidance: +- Pull from concrete reference sets before inventing: saved links, pattern libraries, visual vocabulary, reference boards, and side-by-side comparisons. +- Treat references as design infrastructure. They should shape the vocabulary, hierarchy, interaction model, and component choices, not sit in a generic inspiration appendix. +- If a reference source is degraded or unreachable, mark the limitation and do not promote a claim as default taste. +- Translate dense references responsively. If a source pattern uses a wide grid or table, preserve its comparison logic on mobile with priority columns, stacked row cards, or contained scrolling that does not widen the page. + +Idempotency: +- Existing CDO guidance already asks for inspiration. This candidate makes references operational: inspect, compare, and translate them into specific decisions before producing a UI. + +Rollback: +- Remove this section and the matching bullets in `SKILL.md`; leave source packets untouched. + +### 2. Component Registry Patterns Are Ingredients + +Evidence: +- 12 registry/component matches. +- 5 weekly windows. +- Sources: Field Theory/X bookmarks and Arc history. +- Domains/categories included X design bookmarks, `ui.shadcn.com`, and `registry.directory`. + +Guidance: +- Use registries to identify component anatomy, state coverage, and useful primitives. +- Do not copy registry defaults as the finished aesthetic. +- If using shadcn/ui or registry blocks, customize tokens, radii, density, shadows, empty/error/loading states, and product-specific data before considering the result complete. + +Idempotency: +- Existing taste guidance already says not to ship generic shadcn defaults. This candidate sharpens that rule by treating registries as pattern libraries for coverage and states, not just as code sources. + +Rollback: +- Remove this section and the matching bullets in `SKILL.md`; leave source packets untouched. + +### 3. Named Motion Must Explain State + +Evidence: +- 23 motion/microinteraction matches. +- 9 weekly windows. +- Sources: Field Theory/X bookmarks, Arc history, and Arc sidebar. +- Domains/categories included X design bookmarks, `60fps.design`, `framer.com`, and transition libraries. + +Guidance: +- Choose motion only when it clarifies a state change: selection, reveal, sorting, loading, dismissal, validation, or navigation. +- Name the transition pattern in the design/code reasoning, then specify trigger, duration/easing, interruption behavior, and reduced-motion fallback. +- Avoid `transition-all`, decorative perpetual motion, or animation that compensates for weak hierarchy. + +Idempotency: +- Existing motion guidance covers craft and reduced motion. This candidate adds a sharper intake-derived rule: motion must be selected from a named state-change pattern, not sprinkled on as polish. + +Rollback: +- Remove this section and the matching bullets in `SKILL.md`; leave source packets untouched. + +### 4. AI Design Workflows Need A Visible Design Tree + +Evidence: +- 190 AI design workflow/prompting matches. +- All 11 weekly windows. +- Sources: Field Theory/X bookmarks, Arc history, and Arc sidebar. +- Domains/categories included X design workflow bookmarks, `claude.ai`, Figma, builder/prototype tools, and local preview surfaces. + +Guidance: +- For AI-assisted design tools, expose the design tree as the product surface: brief, generated directions, comparison criteria, chosen branch, iterations, and eval/QA state. +- Prefer inspectable artifacts and branch comparisons over a chat-only shell. +- When making an agentic design interface, show where the model is deciding, where the user can steer, and what evidence supports promotion. + +Idempotency: +- Existing product guidance asks for real workflows. This candidate is specific to AI design products and the self-improving design loop Maroun is rebuilding. + +Rollback: +- Remove this section and the matching bullets in `SKILL.md`; leave source packets untouched. + +### 5. Variation And Critique Are Part Of Taste + +Evidence: +- 21 variation/critique-loop matches in the synthesis-agent pass. +- 7 weekly windows, plus every weekly promotion packet repeated the eval requirement. +- Sources: Field Theory/X bookmarks, Arc history, and the generated promotion packets. + +Guidance: +- When exploring a taste direction, generate multiple candidates, compare side by side, score against the rubric, then refine the selected branch. +- Treat critique artifacts, eval traces, and comparison criteria as part of the design workflow, not as optional reporting. +- Promote only the candidate that survives review and beats the baseline gate. +- A candidate with page-level horizontal overflow at 390px is a hard fail even if the desktop composition is stronger. +- For before/after redesign outputs, make the redesigned experience the default active view. Keep the legacy "before" state contained, scrollable within its own panel if necessary, and subordinate to the improved workflow. +- Check top-level shells as well as tables. Sidebars, sticky mobile headers, nav strips, metrics, charts, dialogs, and filter bars must use `min-width:0`, `max-width:100%`, wrapping, or contained overflow so `document.documentElement.scrollWidth` never exceeds `window.innerWidth`. + +Idempotency: +- Existing promotion rules define the gate. This candidate brings the same loop into design generation so the artifact being evaluated is not a one-shot. + +Rollback: +- Remove this section and the matching bullets in `SKILL.md`; leave source packets untouched. + +## Watchlist, Not Promoted + +Visual-finish tokens appeared repeatedly, including gradients, overlays, depth, typography, and surface polish. Keep this as a narrow future patch for `make-interfaces-feel-better` or CDO finish references because it overlaps existing polish rules. + +Portfolio and visual-craft references appeared often, but the matches mix portfolios, brand sites, product pages, and working sessions. Use them as landing/portfolio inspiration, not operational-tool defaults. + +Configurator and checkout references appeared in only 2 weekly windows and only from Arc history. Hold as a future source theme until more corroboration appears. diff --git a/skills/design-intelligence/references/output-contract.md b/skills/design-intelligence/references/output-contract.md new file mode 100644 index 0000000..25d8e55 --- /dev/null +++ b/skills/design-intelligence/references/output-contract.md @@ -0,0 +1,93 @@ +--- +id: design-intelligence.output-contract +name: Design Intelligence Output Contract +description: Required digest, backfill, and promotion packet structure. +--- + +# Output Contract + +Every run creates a reviewable packet. A good packet proves what was read, what failed, what was learned, and what should happen next. + +## Files + +Recommended run folder: + +```text +/Users/maroun/Codex/tmp/design-intelligence/runs/YYYY-MM-DD/ +``` + +Required files: + +```text +source-manifest.json +weekly-design-digest-YYYY-MM-DD.md +promotion-packet.md +``` + +Historical backfills should use one folder per weekly chunk: + +```text +/Users/maroun/hermes/tmp/design-intelligence-backfill/YYYY-MM-DD..YYYY-MM-DD/YYYY-MM-DD..YYYY-MM-DD/ +``` + +## Weekly Digest + +Use `templates/weekly-digest.md`. + +Preserve the old OpenClaw output contract: +- Output A - Design Digest. +- Output B - Zettelkasten Candidates. +- Output C - Studio Skill Update Candidates. +- Telegram or short summary text. + +Improve it with: +- source status per source lane. +- Arc bookmark section. +- Field Theory/X bookmark section. +- GBrain delta section. +- no claimed save unless the file exists. +- wikilinks for proposed Zettelkasten notes, not hashtags. + +## Output A - Design Digest + +Include 3-5 strongest findings. + +For each finding: +- what it is. +- why it matters. +- source links. +- evidence type: direct page, Arc bookmark, X bookmark, GBrain imported note, or cross-source pattern. +- apply-this instruction for future product/design work. + +## Output B - Zettelkasten Candidates + +Suggest up to 3 notes. Do not write them by default. + +For each note: +- title. +- proposed location. +- source links. +- outline. +- likely wikilinks. +- why this is durable knowledge instead of a weekly mention. + +## Output C - Studio Skill Update Candidates + +Suggest up to 3 skill updates. Do not apply them by default. + +For each update: +- target file. +- proposed rule or snippet. +- evidence links. +- duplicate/idempotency check. +- eval required before promotion. + +## Backfill Packet + +For the outage catch-up, chunk by week and include: +- window start and end. +- source manifest for that chunk. +- top missed Arc candidates. +- top missed Field Theory/X candidates. +- GBrain delta summary. +- whether each chunk should produce a new permanent note, a skill candidate, both, or neither. diff --git a/skills/design-intelligence/references/promotion-rules.md b/skills/design-intelligence/references/promotion-rules.md new file mode 100644 index 0000000..f1505fc --- /dev/null +++ b/skills/design-intelligence/references/promotion-rules.md @@ -0,0 +1,71 @@ +--- +id: design-intelligence.promotion-rules +name: Design Intelligence Promotion Rules +description: Review and eval gates for turning digest findings into skill updates. +--- + +# Promotion Rules + +The loop compounds taste only when a finding repeats, survives review, and improves eval outcomes. + +## Default Safety + +Do not directly mutate: +- Arc browser state. +- Field Theory bookmark corpus. +- X/Twitter account state. +- GBrain source roots. +- Vault notes. +- Studio/CDO skills. +- critique logs. + +Source collection is read-only. Promotion is review-gated. + +## Candidate Thresholds + +A finding can become a skill candidate when at least one is true: +- the same pattern appears in 2 or more independent sources. +- a bookmark explicitly names a reusable design technique. +- a prior critique log issue recurs at least twice. +- the pattern fixes a hard eval failure such as mobile overflow, card nesting, unreadable density, fake data, or decorative slop. + +## Proposal Requirements + +Every candidate must include: +- evidence links or local source references. +- the exact target skill/reference file. +- the smallest proposed text change. +- an idempotency note explaining why this is not already covered. +- a rollback path: leave the current skill untouched until PR/review approval. + +## Eval Gate + +Use the Codex design skill eval harness when available. + +Scope the gate to the actual candidate bundle and `codex-current`; do not run unrelated historical bundles when evaluating one candidate change. + +Recommended scoped command: + +```bash +cd /Users/maroun/Codex +EVAL_BUNDLES="codex-current design-intelligence-v1" \ +EVAL_PROMPTS="001-operational-dashboard 002-productivity-app 003-landing-page-with-assets 004-existing-page-redesign 005-data-workflow" \ +FINAL_HTML_ONLY=1 IGNORE_USER_CONFIG=1 RUN_ID=design-intelligence-gate \ + scripts/evaluate-design-skills.sh run-matrix +``` + +Promotion rule: +- candidate beats `codex-current` on at least 4 fixtures. +- no hard fails on mobile width, content overflow, missing primary workflow, fake critical data, or broken HTML. +- screenshot/rubric evidence is saved with the run. + +If the candidate is useful but the eval is not run, label it `candidate - blocked on eval`, not `promoted`. + +## Runtime Promotion + +The skill may generate: +- a PR or review packet for Stack. +- an eval bundle candidate for Codex. +- a short summary for chat/Telegram. + +It must not silently update the default runtime bundle, install skills globally, or enable a recurring automation without operator approval. diff --git a/skills/design-intelligence/references/source-adapters.md b/skills/design-intelligence/references/source-adapters.md new file mode 100644 index 0000000..9d6fd28 --- /dev/null +++ b/skills/design-intelligence/references/source-adapters.md @@ -0,0 +1,105 @@ +--- +id: design-intelligence.source-adapters +name: Design Intelligence Source Adapters +description: Read-only source map for weekly design intelligence intake. +--- + +# Source Adapters + +All adapters are read-only during intake. They may create a run-local manifest, but they must not mark source rows processed, edit browser state, sync accounts, or write permanent notes. + +## Curated Web Sources + +| Source | Focus | Notes | +|--------|-------|-------| +| Brian Lovin `/sites` and writing | Product taste, systems, design engineering | High signal; prefer current `/sites` entries plus new essays. | +| Design Spells | Micro-interactions and delightful details | JS-heavy; use a browser-capable scrape if plain fetch is thin. | +| Handheld Design | Mobile product decisions and rationale | Substack; capture article title, date, and pattern. | +| Featured Mobile | Curated mobile UI examples | JS-heavy; if extraction fails, record failure in the manifest. | + +## Arc Bookmarks + +Default local source: + +```text +~/Library/Application Support/Arc/StorableSidebar.json +``` + +Supplemental date source: + +```text +~/Library/Application Support/Arc/User Data/Default/History +``` + +Use the sidebar as the canonical bookmark-like source. Use History only to enrich recency because Arc sidebar records can lack a useful saved date. + +Safe read-only scan: + +```bash +python3 /Users/maroun/hermes/scripts/mookie_link_inbox.py arc scan \ + --path "$HOME/Library/Application Support/Arc/StorableSidebar.json" \ + --dry-run +``` + +Design relevance signals: +- title or URL contains design, interface, UI, UX, typography, motion, brand, landing, dashboard, component, product, portfolio, layout, mobile, animation, Figma, Framer, Mobbin, Awwwards, Godly, Land-book, Refero, SiteInspire, Screenlane, Lapa, SaaSFrame, or Landingfolio. +- recent `timeLastActiveAt` activity after the run window start. +- matching Arc history visit in the run window. + +Do not run `mookie_link_inbox.py process --apply` from this loop; that mutates saved-link processing state. + +## Field Theory / X Bookmarks + +Default local source root: + +```text +~/.ft-bookmarks +``` + +Expected surfaces: + +```text +~/.ft-bookmarks/bookmarks.db +~/.ft-bookmarks/bookmarks.jsonl +~/.ft-bookmarks/md/bookmarks/ +~/.ft-bookmarks/media/ +``` + +Use SQLite first because it has `tweet_id`, `url`, `text`, `posted_at`, `synced_at`, `primary_domain`, `categories`, `domains`, `links_json`, and `media_count`. + +Important date rule: current Field Theory rows may not have `bookmarked_at`. Use `synced_at` for local capture/import recency and `posted_at` for content recency. + +Design relevance signals: +- `primary_domain = 'design'`. +- `categories`, `domains`, `article_title`, `article_text`, or tweet text contains the design terms listed in the Arc section. +- attached media count or link count is nonzero. + +Syncing through Arc cookies is a separate guarded operation. Do not run it from the digest unless the operator explicitly approves account sync: + +```bash +/Users/maroun/hermes/scripts/field-theory-sync-from-arc.py --max-minutes 30 +``` + +## GBrain + +Default source roots: + +```text +~/.gbrain/source-roots/x-bookmarks-native +~/.gbrain/source-roots/saved-links +``` + +Use GBrain to detect what has already been imported and where Field Theory is ahead. The weekly digest should prefer the live Field Theory corpus for newest X bookmarks, then report GBrain deltas as an ingestion/backfill lane. + +The loop may stage review manifests under Hermes tmp or a new GBrain-owned source root only after approval. It must not edit `.ft-bookmarks`, Arc, Vault, or mark any row processed. + +## Source Manifest + +Each run should record: +- exact path or URL for each source. +- whether the source was reachable/readable. +- candidate counts per source. +- design-relevant candidate counts in the run window. +- GBrain delta counts, especially Field Theory bookmark markdown files missing from `x-bookmarks-native`. +- failures and extraction limits. + diff --git a/skills/design-intelligence/templates/weekly-digest.md b/skills/design-intelligence/templates/weekly-digest.md new file mode 100644 index 0000000..5c9ea74 --- /dev/null +++ b/skills/design-intelligence/templates/weekly-digest.md @@ -0,0 +1,60 @@ +# Weekly Design Digest - YYYY-MM-DD + +## Execution Log + +- Window: +- Runner: +- Source manifest: +- Status: + +## Source Status + +| Source lane | Status | Candidates | Notes | +|-------------|--------|------------|-------| +| Curated web | | | | +| Arc bookmarks | | | | +| Field Theory/X bookmarks | | | | +| GBrain deltas | | | | + +## Output A - Design Digest + +### 1. Finding title + +- What: +- Why it matters: +- Links: +- Evidence type: +- Apply this: + +## Output B - Zettelkasten Candidates + +### 1. [[Candidate Note Title]] + +- Proposed location: +- Source links: +- Outline: +- Wikilinks: +- Why durable: + +## Output C - Studio Skill Update Candidates + +### 1. Candidate rule + +- Target file: +- Proposed snippet: +- Evidence: +- Idempotency check: +- Eval required: + +## Promotion Packet Summary + +- Promote now: +- Needs review: +- Blocked: + +## Short Summary + +- Highlight 1 +- Highlight 2 +- Highlight 3 + diff --git a/skills/emil-design-eng/SKILL.md b/skills/emil-design-eng/SKILL.md index 6d76dc9..8a578e1 100644 --- a/skills/emil-design-eng/SKILL.md +++ b/skills/emil-design-eng/SKILL.md @@ -1,10 +1,35 @@ --- name: emil-design-eng description: This skill encodes Emil Kowalski's philosophy on UI polish, component design, animation decisions, and the invisible details that make software feel great. +license: Source wrapper for https://github.com/emilkowalski/skill; upstream GitHub repo currently has no explicit license. +metadata: + source: https://github.com/emilkowalski/skill + source_site: https://emilkowal.ski/skill + upstream_skill: skills/emil-design-eng + upstream_commit: ea2cd0ddb235abbe85cdbc03f26686cd465df897 --- # Design Engineering +## Source Boundary + +- Upstream repo: https://github.com/emilkowalski/skill +- Upstream site: https://emilkowal.ski/skill +- Upstream skill path: `skills/emil-design-eng` +- Upstream commit: `ea2cd0ddb235abbe85cdbc03f26686cd465df897` +- Upstream GitHub license: none reported as of 2026-06-24. +- Stack source metadata: [references/source.json](references/source.json). + +Because the upstream repo has no explicit license, keep this as an attributed Stack reference and review licensing before publishing or relicensing the source text outside this repo. + +## Initial Response + +When this skill is first invoked without a specific question, respond only with: + +> I'm ready to help you build interfaces that feel right, my knowledge comes from Emil Kowalski's design engineering philosophy. If you want to dive even deeper, check out Emil’s course: [animations.dev](https://animations.dev/). + +Do not provide any other information until the user asks a question. + You are a design engineer with the craft sensibility. You build interfaces where every detail compounds into something that feels right. You understand that in a world where everyone's software is good enough, taste is the differentiator. ## Core Philosophy diff --git a/skills/emil-design-eng/references/source.json b/skills/emil-design-eng/references/source.json new file mode 100644 index 0000000..26a0153 --- /dev/null +++ b/skills/emil-design-eng/references/source.json @@ -0,0 +1,19 @@ +{ + "source_site": "https://emilkowal.ski/skill", + "source_repo": "https://github.com/emilkowalski/skill", + "upstream_skill_path": "skills/emil-design-eng", + "checked_at": "2026-06-24T16:00:36Z", + "license": { + "github_reported_spdx_id": null, + "note": "GitHub reports no explicit upstream license; keep attribution and review before publishing or relicensing the source text outside this repo." + }, + "latest_commit": { + "sha": "ea2cd0ddb235abbe85cdbc03f26686cd465df897", + "date": "2026-06-22T00:24:43+02:00", + "message": "Update README.md", + "author": "Emil Kowalski" + }, + "files": [ + "skills/emil-design-eng/SKILL.md" + ] +} diff --git a/skills/gemini-review/SKILL.md b/skills/gemini-review/SKILL.md new file mode 100644 index 0000000..ed68f4e --- /dev/null +++ b/skills/gemini-review/SKILL.md @@ -0,0 +1,102 @@ +--- +name: gemini-review +description: "Run a read-only Google AI / Antigravity second-model review over a git diff. Use when Maroun asks for Gemini review, Antigravity review, Google AI review, second-model review, or model-diverse review of a repo/PR/diff." +metadata: + local_wrapper: /Users/maroun/bin/mookie-gemini-review + report_dir: /Users/maroun/hermes/reports/google-ai-pro + working_surface: antigravity-cli +--- + +# Gemini Review + +Use this skill to run Google AI as an advisory second reviewer without replacing Codex as the executor. + +Despite the historical name, the current working model-call surface is **Antigravity CLI** through `/Users/maroun/bin/mookie-gemini-review`. Legacy `gemini-cli` is installed but is not supported for individual Code Assist model calls. + +## Boundary + +This is read-only and advisory. + +Do not: + +- edit files; +- push, commit, merge, or open PRs; +- run the review from inside `/Users/maroun/Vault`, private source corpora, browser profiles, Gmail/Calendar exports, finance, health, or credential directories; +- send `.env`, credentials, auth JSON, secret-looking files, raw finance/health/email bodies, or full repos; +- use `GEMINI_API_KEY` or `GOOGLE_API_KEY`; +- treat Gemini/Antigravity findings as authoritative without Codex/user review. + +The wrapper unsets Gemini API key environment variables before invoking Antigravity. It also refuses sensitive-looking changed paths and sends only a redacted git diff/stat from a scratch directory. + +## Source Of Truth + +- Wrapper: `/Users/maroun/bin/mookie-gemini-review` +- Reports: `/Users/maroun/hermes/reports/google-ai-pro/` +- Scratch cwd for Antigravity calls: `/Users/maroun/hermes/tmp/google-ai-pro/login-smoke` + +## Required Preflight + +From any directory, confirm the wrapper and quota surface: + +```bash +/Users/maroun/bin/mookie-google-ai-usage +/Users/maroun/bin/mookie-gemini-smoke --no-model-call +``` + +Both commands should return JSON with `ok: true` or a report path whose JSON says `ok: true`. + +If either fails because Antigravity is not logged in, stop and report the login/auth blocker. + +## Review Command + +Run this against the target git repo: + +```bash +/Users/maroun/bin/mookie-gemini-review --repo /absolute/path/to/repo --base HEAD +``` + +Optional knobs: + +```bash +/Users/maroun/bin/mookie-gemini-review --repo /absolute/path/to/repo --base main --max-chars 80000 +/Users/maroun/bin/mookie-gemini-review --repo /absolute/path/to/repo --out /Users/maroun/hermes/reports/google-ai-pro/review-custom.md +``` + +## Output Contract + +The wrapper prints the markdown report path. Read the report and summarize: + +- blocker / should-fix findings; +- open questions; +- test gaps; +- whether the report is useful enough to act on; +- any false positives or stale-context issues. + +Do not paste raw long output unless Maroun asks for it. + +## Verification + +A successful run has: + +- exit code `0`; +- a report under `/Users/maroun/hermes/reports/google-ai-pro/`; +- no secret-looking strings in the report; +- no file changes in the reviewed repo caused by this skill. + +Recommended secret scan for the new report: + +```bash +rg -n 'AIza[0-9A-Za-z_-]{20,}|GEMINI_API_KEY=[0-9A-Za-z_./:+-]{8,}|GOOGLE_API_KEY=[0-9A-Za-z_./:+-]{8,}|x-goog-api-key: [0-9A-Za-z_./:+-]{8,}' /Users/maroun/hermes/reports/google-ai-pro/review-*.md +``` + +An exit code of `1` from `rg` means no matches, which is good. + +## Closeout + +Close with: + +- report path; +- verification commands run; +- top findings; +- whether Codex agrees, disagrees, or needs more context; +- next action, if any. diff --git a/skills/goal-validation-threads/SKILL.md b/skills/goal-validation-threads/SKILL.md new file mode 100644 index 0000000..dec67bb --- /dev/null +++ b/skills/goal-validation-threads/SKILL.md @@ -0,0 +1,77 @@ +--- +name: goal-validation-threads +description: "Create and inspect focused Codex validation threads for candidate skills, workflows, automation changes, or multi-agent plans. Use when a draft skill or workflow needs independent forward-testing with /goal prompts, project resolution, isolated worktrees for mutating tests, concrete pass/fail gates, and promotion/revision recommendations." +--- + +# Goal Validation Threads + +Use this skill to validate whether a candidate skill or workflow actually helps in a fresh Codex thread. The validation must exercise the candidate on a realistic target and produce inspectable evidence. + +## Candidate Intake + +For each candidate, record: +- skill name and draft path; +- motivating evidence from real threads, commands, artifacts, blockers, or automation results; +- target project/repo/path; +- whether validation can be read-only or might modify repo state; +- expected output artifact and pass/fail gate. + +Validate at most three candidates in one run unless Maroun explicitly raises the cap. + +## Thread Prompt Contract + +Each validation thread prompt must include: + +```text +/goal +Objective: +Target path/repo: +Skill under test: +Allowed actions: +Hard stops: +Expected output artifact: +Pass/fail gate: +High-quality output means: +Report back with: +``` + +Use the draft skill as an input, not a hidden answer key. Do not tell the validator the conclusion you want. + +## Isolation Rules + +- Use project resolution before creating threads when the platform exposes `list_projects`. +- Use a worktree when validation may change repo state. +- Use local/no-worktree only for strictly read-only validation. +- Do not validate against source corpora, Vault, credentials, browser profiles, external accounts, email/calendar, LaunchAgents, production systems, or unrelated repos. +- Do not merge, push to main, install global/runtime changes, or promote a skill automatically. + +## Inspect Results + +After a validation thread finishes or clearly blocks, inspect: +- thread id or pending worktree id; +- output artifact path; +- commands/checks used; +- whether the candidate skill was actually used; +- pass/fail evidence; +- isolation choice, such as local read-only, local mutating, or worktree; +- quality notes; +- smallest next fix if failed. + +Recommend promotion only with concrete pass evidence and a useful output. If the thread is queued, unavailable, or blocked before validation, mark the candidate blocked rather than passed. + +## Closeout + +For each candidate, report: + +```text +Skill: +Evidence: +Draft path: +Validation thread: +Validation gate: +Verdict: +Recommendation: +Isolation: +``` + +Keep sensitive evidence paraphrased and label private/sensitive lanes when needed. diff --git a/skills/goal-validation-threads/agents/openai.yaml b/skills/goal-validation-threads/agents/openai.yaml new file mode 100644 index 0000000..c37c365 --- /dev/null +++ b/skills/goal-validation-threads/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Goal Validation Threads" + short_description: "Validate skills in fresh goal threads" + default_prompt: "Use $goal-validation-threads to create focused validation goals for candidate skills." diff --git a/skills/muller-brockmann-grid-systems/SKILL.md b/skills/muller-brockmann-grid-systems/SKILL.md new file mode 100644 index 0000000..9014c37 --- /dev/null +++ b/skills/muller-brockmann-grid-systems/SKILL.md @@ -0,0 +1,125 @@ +--- +name: muller-brockmann-grid-systems +description: Build editorial, magazine, report, and longform webpages on a genuine Muller-Brockmann modular grid with CSS grid tokens, same-box overlay guides, subgrid bands, baseline rhythm, optical headline alignment, and Puppeteer verification. +--- + + + +## Codex Packaging Notes + +Use this skill when a page should be visibly, rigorously organized by a Swiss/International Typographic Style grid. The upstream helper scripts are bundled here: + +- `scripts/grid_tokens.py` generates the CSS and JavaScript scaffold for the modular grid, overlay toggle, baseline grid, and optical headline alignment. +- `scripts/verify_grid.js` runs the Puppeteer verification harness for column and baseline adherence. + +## When To Use + +Load when building any editorial/magazine/report/longform webpage that must read as rigorously grid-aligned, Swiss/International-Typographic-Style, or "Müller-Brockmann." Triggers: "magazine spread", "grid system", "Swiss design", "editorial layout", "show the grid / grid overlay toggle", "align everything to the grid". Also the reference for the corpus→skill→artifact "Tufte pattern" sizzle move on grid design, and for the recurring failure modes: a grid overlay that's "slapped on top / misaligned" (overlay not sharing the content box), and large display type that looks "off the grid" even when its box is on it (glyph side-bearing → needs optical alignment). Sibling to the Vignelli Canon skill (Vignelli = six-typeface canon + transit wayfinding); use THIS one for Müller-Brockmann modular magazine grids and the verifiable web-grid engineering. + +# Müller-Brockmann Grid Systems — built real, visible, and verified + +Josef Müller-Brockmann (1914–1996), Zurich; *Grid Systems in Graphic Design* (1981) is the corpus. The grid is treated as an ethic, not decoration: **"The grid system is an aid, not a guarantee. It permits a number of possible uses and each designer can look for a solution appropriate to his personal style. But one must learn how to use the grid; it is an art that requires practice."** This skill encodes that discipline AND — the part most attempts get wrong — the front-end engineering to make the grid genuinely load-bearing on the web, plus a harness that PROVES it. + +> Two real review notes this skill exists to prevent: +> 1. *"the grid is just slapped on top and misaligned"* → the overlay wasn't in the same content box as the content (see §2.2). +> 2. *"the H in the headline is off the grid"* → the headline's BOX was on the grid but its INK wasn't; large glyphs carry a side-bearing (see §2.6). **Box-on-grid ≠ ink-on-grid.** + +--- + +## PART 1 — THE DISCIPLINE (decide before drawing) +- **Objective order.** The grid brings "constructive thought," legibility, and "objective and functional" design. Restraint is the point; the system, not the ego, organizes the page. +- **Modular grid.** Divide the type area into a field of **modules** — columns AND rows — separated by consistent **gutters**, inside defined **margins**. Text and images occupy whole modules. Müller-Brockmann specimens common field counts (8 / 20 / 32 fields). For the web, a **12-column grid + 8px baseline** is a robust general default; a **6×6 or 4×8 modular field grid** when you want visible rows too. +- **Baseline grid.** Vertical rhythm is sacred: **leading = a whole multiple of the baseline unit**, and every element snaps to it. This is what makes facing columns and images line up across the page. +- **Typography.** A **grotesque sans** (Akzidenz-Grotesk / Helvetica; on the web Inter, Helvetica Now, Archivo). **Flush-left, ragged-right.** Few sizes, large jumps in **scale** for hierarchy; objective, not expressive. Big **numerals/data set large** is a signature move. +- **Palette.** Pure white paper, near-black ink, **one accent — red is canonical**. Avoid the warm-cream "Claude look"; **never blue/purple gradients** (hard house rule). +- **White space + asymmetry.** Generous margins; asymmetric compositions held in tension by the grid. + +--- + +## PART 2 — MAKE THE GRID REAL ON THE WEB (the load-bearing engineering) +`grid_tokens.py` emits this whole scaffold correctly; the rules below are why it's built the way it is. + +### 2.1 One source of truth +Put every grid parameter in `:root` CSS variables — `--cols, --gutter, --margin, --bl (baseline), --lh (leading=3×bl), --maxw`. **Content and the overlay both read these same variables.** Never hand-author the overlay separately or it will drift. + +### 2.2 The overlay MUST live in the SAME content box as the content ← #1 bug +Failure mode: content sits in a centered `max-width` container while the overlay is a **full-width sibling** of the section. On any viewport wider than `--maxw`, the centered content and the full-width overlay no longer share column positions → "slapped on top / misaligned." +**Fix:** put `.guides` *inside* the same `.wrap`, and draw the column guides with `left/right = var(--margin)` and the **same** `repeat(var(--cols),1fr)` + `column-gap:var(--gutter)`. Then the overlay columns **are** the content columns at every width. Add left/right margin lines at `var(--margin)`. + +### 2.3 Place every element by column LINE via subgrid bands +Don't eyeball spans. Each horizontal **band** spans all columns and re-exposes them: +```css +.band{grid-column:1 / -1; display:grid; grid-template-columns:subgrid; column-gap:var(--gutter); align-items:start;} +@supports not (grid-template-columns:subgrid){ .band{grid-template-columns:repeat(var(--cols),1fr);} } +``` +Children place with `grid-column: / ` (e.g. `1 / 6`, `6 / 13`). Every headline, paragraph, photo, caption now snaps to identical lines. + +### 2.4 Lock vertical rhythm to the baseline +- Leading = `--lh` (e.g. 24px = 3×8). **Every line-height a multiple of the baseline, in px (not unitless) for display type** — unitless line-heights on large type push the box off the grid. +- Every margin/padding a multiple of the baseline. Spread top/bottom padding a multiple too, so content starts on a line. +- **Media heights = multiples of the leading** (e.g. 240/360/432/480px) so a photo's top AND bottom both land on lines. +- Hairline rules sit inside a baseline-height band, not free-floating. + +### 2.5 The toggle (sizzle within the sizzle) +A control (button **+ `G` key**) toggles `body.grid-on`; overlay fades 0→1. Overlay draws: translucent **numbered column fields**, the **baseline** (major line every `--lh`, faint minor every `--bl`), and **margin lines**. Showing the real grid the page is built on IS the demo. + +### 2.6 OPTICAL ALIGNMENT — display ink, not its box ← the subtle bug +A 180px headline whose layout box is exactly on line 1 still looks misaligned against body text, because the letterform's **ink** is inset by its **left side-bearing**. Cure at runtime: +```js +// after document.fonts.ready and on resize: +var cvs=document.createElement('canvas'),ctx=cvs.getContext('2d'); +document.querySelectorAll('.masthead,.numeral,.shead h2,.h2b').forEach(function(el){ + el.style.marginLeft='0px'; + var cs=getComputedStyle(el),ch=(el.textContent||'').trim()[0]; if(!ch) return; + if(cs.textTransform==='uppercase') ch=ch.toUpperCase(); + ctx.font=cs.fontStyle+' '+cs.fontWeight+' '+cs.fontSize+' '+cs.fontFamily; ctx.textAlign='left'; + var abl=ctx.measureText(ch).actualBoundingBoxLeft; // +ve = ink overhangs left of box + if(isFinite(abl)) el.style.marginLeft=abl.toFixed(2)+'px'; // shift box so INK lands on the line +}); +``` +Apply to the masthead, big numerals, and section headlines. It scales with fluid type (re-runs on resize) and uses the **actually-loaded** font, so it's correct in the user's browser. +**CRITICAL measurement caveat:** side-bearing is **font-specific**. If you measure with the wrong font you get the wrong nudge. Headless/sandbox Chrome usually lacks the webfont, so canvas falls back to a different grotesque (measured **−16px on the fallback vs −7px on real Inter** for the same `H`). To verify optics offline you must **embed the real webfont** via `@font-face` (local TTF). In production the runtime JS measures the loaded font and is correct. + +--- + +## PART 3 — VERIFY (don't trust, measure) → `verify_grid.js` +Render with headless Chrome (Puppeteer) and assert, at **several widths including > and < `--maxw`** (to catch centered-container drift, e.g. 1440 / 1180 / 900): +1. **Column adherence** — every placed `.band > *` left snaps to a column START and right to a column END (~0px). **Exclude the optically-aligned display elements** from this box check (their box is intentionally side-bearing-offset; they're validated in step 4). **Gotcha:** build BOTH the column-start set and the column-end set — a grid item spanning "to line N" ends at the *far* side of the gutter, so single-edge math falsely reports a one-gutter error. +2. **Overlay match** — each `.guides .col` rect equals the computed column rect (~0px). +3. **Baseline** — text tops modulo the baseline ≈ 0 (tolerance ≈ half a baseline; the box-top is a proxy — the leading does the real work). +4. **Optical ink** — each display element's ink-left (box − `actualBoundingBoxLeft`, real font) equals **its own** column line (nearest column-start to its box), not always line 1. + +Sandbox Chrome flags that work: `--headless=new --no-sandbox --disable-gpu --disable-dbus --use-gl=angle --use-angle=swiftshader`. `file://` works for non-ES-module pages; the CLI `--screenshot` can hang on tall pages — drive via Puppeteer and screenshot per viewport. Read PNGs back with the image-capable Read tool to eyeball a **zoom crop of the top-left corner** (masthead vs body vs column line) — the fastest human check. + +A clean run looks like: `col=0px overlay=0px baseline≤4px ink=0px` → `GRID VERIFY: PASS`. + +--- + +## PART 4 — CRAFT DEFAULTS (so it looks excellent, not just aligned) +- **Palette:** white `#fff`, ink `#111`, one accent (Swiss red `#e4002b`). No warm-cream Claude look; no blue/purple gradients. +- **Type:** a real grotesque webfont (Inter / Helvetica Now / Archivo) for display + body; a **mono** (Space Mono / IBM Plex Mono) for folios, captions, grid annotations — reinforces the technical register. Non-Latin via Noto Sans JP etc. +- **Hierarchy** through scale + weight + white space, not color. Treat key data as **large numerals**. Kicker labels in mono caps. Per-spread folios. +- **Real photography.** Ground real subjects in real photos (`SearchImages`). **Host each image via `PublishFilePublicly` and embed the `pub.hyperagent.com` URL** — a `PublishWebpage` artifact runs in a sandboxed iframe that can't authenticate thread-scoped `/api/files/...` URLs (broken-image trap). +- **Type fidelity if you ever rasterize art** (cairosvg / headless screenshots / image-gen reference): a `Helvetica`/`Arial` CSS stack silently falls back to **Noto Sans** (reads like Calibri). Render in **Liberation Sans** or an embedded Helvetica/Arimo TTF before trusting it. (Same trap as the optical-measurement caveat: wrong font in → wrong result out.) +- **Spread model:** full-width sections, each its own per-spread `.grid` + `.guides`, consistent margins/folios. + +--- + +## PART 5 — WORKFLOW +1. Pick the subject; gather real photos; host them publicly. +2. Generate the scaffold: `python3 grid_tokens.py` (or `--scaffold` for a full page; `--cols/--baseline/--gutter/--margin/--maxw/--accent` to taste; it warns if gutter/margin aren't baseline multiples). +3. Build spreads as **subgrid bands**; place everything by **column line**; lock spacing/line-heights/media heights to the **baseline**. +4. Add the overlay (same content box) + toggle + optical-alignment JS (already in the scaffold; point its selector list at your display elements). +5. Publish, then **verify**: `CHROME=… PUP=… node verify_grid.js --widths=1440,1180,900`. Eyeball a top-left zoom crop. Fix, republish. + +## SCRIPTS +- **`grid_tokens.py`** — deterministic scaffold generator. Emits the `:root` tokens, `.grid`/`.band` (subgrid) scaffold, `.guides` overlay CSS, toggle JS, and the optical-alignment JS — all wired to one source of truth. `--scaffold` emits a full minimal HTML page. No network/credentials. +- **`verify_grid.js`** — Puppeteer harness implementing all four checks above with the corrected both-edges column math, the optical-exclusion, per-element column-line ink targeting, and PASS/FAIL output at multiple widths. Env: `CHROME` (chrome binary), `PUP` (puppeteer-core module path). + +## CREED +A grid you can't toggle on and measure is a mood board, not a system. Build it from one source of truth, prove it at 0px, and align the **ink**. diff --git a/skills/muller-brockmann-grid-systems/scripts/grid_tokens.py b/skills/muller-brockmann-grid-systems/scripts/grid_tokens.py new file mode 100755 index 0000000..c3c581d --- /dev/null +++ b/skills/muller-brockmann-grid-systems/scripts/grid_tokens.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python3 +""" +grid_tokens.py — Müller-Brockmann editorial grid scaffold generator. + +Emits a battle-tested, self-contained CSS + JS scaffold for building an +editorial/magazine webpage on a REAL, VISIBLE, VERIFIED modular grid: + + • ONE source of truth: all grid params live in :root CSS variables. + • The grid-toggle OVERLAY reads the SAME variables and lives in the SAME + content box as the content, so its columns ARE the content columns + (this is the fix for the "grid is just slapped on top / misaligned" bug + that happens when the overlay is a full-width sibling of a centered + max-width container). + • Subgrid "bands" so every element is placed by column LINE, not eyeballed. + • Vertical rhythm locked to an 8px baseline (24px leading). + • Runtime OPTICAL ALIGNMENT: display type is nudged so its INK (not its box) + lands on the column line — large letterforms carry a left side-bearing, so + a headline whose box is on the grid still looks misaligned vs body text. + +No network, no credentials. Deterministic. + +Usage: + python3 grid_tokens.py # print CSS + JS block + python3 grid_tokens.py --scaffold # print a full minimal HTML page + python3 grid_tokens.py --cols 12 --baseline 8 --gutter 24 --margin 72 \ + --maxw 1296 --accent "#e4002b" +""" +import argparse, sys + +def build(cfg): + c = cfg + lh = c.baseline * 3 # leading = 3 baselines + css = f""":root{{ + --cols:{c.cols}; + --bl:{c.baseline}px; /* baseline unit */ + --lh:{lh}px; /* leading = 3 x baseline */ + --gutter:{c.gutter}px; + --margin:{c.margin}px; + --pad:{c.baseline*12}px; /* spread top/bottom pad (x baseline) */ + --maxw:{c.maxw}px; + + --paper:#ffffff; + --ink:#111315; + --ink-soft:#5b6066; + --accent:{c.accent}; + + --g-col:rgba(228,0,43,.075); /* column field fill (re-tint to taste) */ + --g-edge:rgba(228,0,43,.40); /* column edge / margin line */ + --g-base:rgba(0,150,140,.34); /* major baseline line ({lh}px) */ + --g-base-min:rgba(0,150,140,.12);/* minor baseline line ({c.baseline}px) */ +}} +*{{box-sizing:border-box;}} +body{{margin:0;background:var(--paper);color:var(--ink); + font-family:"Inter",system-ui,sans-serif;font-size:16px;line-height:var(--lh); + -webkit-font-smoothing:antialiased;}} +img{{display:block;width:100%;height:100%;object-fit:cover;}} + +/* ---- spread + grid scaffold (ONE source of truth) ---- */ +.spread{{position:relative;width:100%;}} +.wrap{{position:relative;max-width:var(--maxw);margin:0 auto;padding:var(--pad) var(--margin);}} +.grid{{display:grid;grid-template-columns:repeat(var(--cols),1fr); + column-gap:var(--gutter);row-gap:var(--lh);}} +/* a band spans all columns and re-exposes them as a subgrid so children + align to the SAME lines as everything else on the page */ +.band{{grid-column:1 / -1;display:grid;grid-template-columns:subgrid; + column-gap:var(--gutter);row-gap:var(--lh);align-items:start;}} +@supports not (grid-template-columns:subgrid){{ + .band{{grid-template-columns:repeat(var(--cols),1fr);}} +}} +/* place children with: style="grid-column: / " */ + +/* ---- the grid OVERLAY (same content box -> columns match exactly) ---- */ +.guides{{position:absolute;inset:0;pointer-events:none;z-index:60;opacity:0; + transition:opacity .26s ease;}} +body.grid-on .guides{{opacity:1;}} +.guides .cols{{position:absolute;top:0;bottom:0;left:var(--margin);right:var(--margin); + display:grid;grid-template-columns:repeat(var(--cols),1fr);column-gap:var(--gutter);}} +.guides .col{{background:var(--g-col); + box-shadow:inset 1px 0 0 var(--g-edge),inset -1px 0 0 var(--g-edge);position:relative;}} +.guides .col span{{position:absolute;top:{c.baseline*4}px;left:0;right:0;text-align:center; + font-family:"Space Mono",monospace;font-size:10px;line-height:1;color:var(--accent);}} +.guides .rows{{position:absolute;left:var(--margin);right:var(--margin);top:var(--pad);bottom:0; + background-image: + repeating-linear-gradient(to bottom,var(--g-base) 0 1px,transparent 1px var(--lh)), + repeating-linear-gradient(to bottom,var(--g-base-min) 0 1px,transparent 1px var(--bl));}} +.guides .mline{{position:absolute;top:0;bottom:0;width:1px;background:var(--g-edge);}} +.guides .mline.l{{left:var(--margin);}} .guides .mline.r{{right:var(--margin);}} + +/* ---- vertical rhythm helpers (keep ALL spacing a multiple of --bl) ---- + line-heights for display type MUST be px multiples of --bl, never unitless, + or the box height drifts off the baseline. Media heights = multiples of --lh + so photo top AND bottom land on lines. */ +.toggle{{position:fixed;top:18px;right:18px;z-index:200;display:flex;align-items:center;gap:10px; + background:var(--ink);color:#fff;border:none;cursor:pointer;font-family:"Space Mono",monospace; + font-size:12px;letter-spacing:.14em;text-transform:uppercase;padding:11px 14px;}} +.toggle .dot{{width:9px;height:9px;border-radius:50%;background:#555;}} +body.grid-on .toggle{{background:var(--accent);}} body.grid-on .toggle .dot{{background:#fff;}}""" + + js = """/* toggle: button + 'G' key */ +var btn=document.getElementById('gridToggle'); +function setGrid(on){document.body.classList.toggle('grid-on',on); + if(btn){btn.setAttribute('aria-pressed',on?'true':'false'); + var l=btn.querySelector('.lbl'); if(l) l.textContent=on?'Hide grid':'Show grid';}} +if(btn) btn.addEventListener('click',function(){setGrid(!document.body.classList.contains('grid-on'));}); +document.addEventListener('keydown',function(e){ + if((e.key==='g'||e.key==='G')&&!e.metaKey&&!e.ctrlKey&&!e.altKey){ + setGrid(!document.body.classList.contains('grid-on'));}}); + +/* populate every overlay's column guides (numbered) */ +document.querySelectorAll('.guides .cols').forEach(function(h){ + var n=getComputedStyle(document.documentElement).getPropertyValue('--cols').trim()||'12'; + for(var i=1;i<=parseInt(n,10);i++){var c=document.createElement('div');c.className='col'; + var s=document.createElement('span');s.textContent=i;c.appendChild(s);h.appendChild(c);}}); + +/* ---- OPTICAL ALIGNMENT -------------------------------------------------- + Large display glyphs carry a left side-bearing: the ink sits inside the + layout box, so a headline whose BOX is on the column line still LOOKS + indented (or overhangs) vs body text. Measure each display glyph's actual + ink offset and nudge the element so its visible ink lands on the line. + Scales with fluid type; re-runs after the webfont loads and on resize. + Add the selector list to match your display elements. */ +(function(){ + var cvs=document.createElement('canvas'),ctx=cvs.getContext('2d'); + var sel='.masthead, .numeral, .shead h2, .h2b'; /* <-- your display selectors */ + function align(){ + document.querySelectorAll(sel).forEach(function(el){ + el.style.marginLeft='0px'; + var cs=getComputedStyle(el),ch=(el.textContent||'').trim().charAt(0); if(!ch) return; + if(cs.textTransform==='uppercase') ch=ch.toUpperCase(); + ctx.font=cs.fontStyle+' '+cs.fontWeight+' '+cs.fontSize+' '+cs.fontFamily; + ctx.textAlign='left'; + var abl=ctx.measureText(ch).actualBoundingBoxLeft; /* +ve = ink overhangs left */ + if(isFinite(abl)) el.style.marginLeft=abl.toFixed(2)+'px'; /* ink -> on the line */ + }); + } + if(document.fonts&&document.fonts.ready){document.fonts.ready.then(align);} + align(); + var t;window.addEventListener('resize',function(){clearTimeout(t);t=setTimeout(align,120);}); +})();""" + + band = """ +
+
+
+
""" + + overlay = """ """ + + if cfg.scaffold: + return f""" + + +Editorial — modular grid + + + + + + +
+
+
+{band} +
+{overlay} +
+
+ + +""" + else: + return ("/* ===== CSS (paste in \\n\\n\\n\\n
\\n
\\n
\\n{band}\\n
\\n{overlay}\\n
\\n
\\n\\n\\n\\\"\\\"\\\"\\n else:\\n return (\\\"/* ===== CSS (paste in