Commit Graph
116 Commits
Author SHA1 Message Date
Youssef 3ec0173896 Install · scope the skill to skills/hallmark/ (fixes #9)
The skills CLI copies everything under the directory containing SKILL.md.
With SKILL.md at the repo root, installs were pulling in docs/, site/,
package.json, README, ROADMAP, vercel.json, LICENSE. Moving the skill
into skills/hallmark/ scopes the install to just SKILL.md + references/.

The CLI's priority search hits skills/ first, so `npx skills add
nutlope/hallmark` is unchanged. Updated README install paths,
package.json (entry/references/files), and the internal links that
crossed the new boundary.
2026-05-26 12:07:51 +01:00
Riccardo Giorato 9aba10e518 feat: enhance remote URL safety checks and documentation 2026-05-20 21:58:53 +02:00
Hassan El MghariandGitHub 2fec50f4dd Merge pull request #7 from Nutlope/trim-readme-roadmap
Docs · shorten README and ROADMAP
2026-05-20 11:45:15 -04:00
Youssef 9fc2369e09 OG · swap to new readme/social card art
New 2400×1356 artwork replaces the previous 4800×2520 image.
Meta width/height tags updated to match.
2026-05-20 16:26:02 +01:00
Youssef a0a02cae7f Study · drop the refuse-competitor-pages clause
Remove the "refuses competitor pages" policy from the study verb.
Touches the verb summary in README and SKILL.md, both refusal tables
in study.md, the URL refuse list, the schema's refusal enum, the
emission-attestation parenthetical, and the worked examples plus the
test fixtures.

Paid-template refusal and the signature-work soft-refusal stay —
those carry real copyright weight.
2026-05-20 14:40:52 +01:00
Youssef a569532759 Roadmap · refine Next items
Add a brand-first flow as the lead Next item — from a short product
description, Hallmark generates a complete brand (palette, type, voice,
Nanobanana imagery) into a design.md, then builds the whole site
against it.

Rewrite the data-viz item as "Charts reference for analytics pages" —
names the actual AI tells (rainbow palettes, 3D donuts, dual-axis
spaghetti) and what the new reference file would do.

Fold the proposed hallmark extract verb into study as a third input
mode (codebase path, alongside screenshot and URL). Same verb, same
design.md output, no new surface area.

Drop the Won't-do section.
2026-05-20 13:56:29 +01:00
Youssef bb2411fae3 Docs · shorten README and ROADMAP
README: 147 → 81 lines. Drop the comparison table, the long
"What's distinct" bullet list, the references/ inventory, the
v1.0.0 release-note blockquote, and the duplicate Update section.
Keep the verb table, the example grid, and install paths.

ROADMAP: 201 → 50 lines. Fold the Status/Build/Why-it-matters
tri-headers into one or two sentences per item. Drop the stale
"What's already shipped" list, the "Measurement" section, and
the duplicate Deferred entry. Keep the Won't-do list — that's
where the discipline lives.
2026-05-20 13:43:04 +01:00
Hassan El MghariandGitHub dcd6ac64b4 Merge pull request #6 from Nutlope/fix-aggresive-redesign
Fix redesign that was too aggressive & build some guardrails in there
2026-05-19 18:13:45 -04:00
Hassan El Mghari 8eed815bd9 wip 2026-05-19 18:12:33 -04:00
YoussefandGitHub c494f3998e Merge pull request #5 from Nutlope/update-skill-description
Refine and condense SKILL.md description
2026-05-19 23:09:28 +01:00
Youssef 3c343632b5 Refine and condense SKILL.md description 2026-05-19 23:08:34 +01:00
Hassan El MghariandGitHub 6d42491c6a Merge pull request #2 from JaySmith502/fix/skill-md-yaml-frontmatter
Fix: quote SKILL.md description so YAML frontmatter parses (npx skills add fails)
2026-05-19 17:42:27 -04:00
JaySmith502andWOZCODE 75b5bfa752 Fix · quote SKILL.md description so YAML frontmatter parses
The description was an unquoted YAML plain scalar containing multiple
colon-space sequences ("Four verbs: ", "Fires when ANY: ", "Does NOT
fire on: ", "Decisive signal: "). YAML reads ': ' inside a plain
scalar as a nested mapping, so strict parsers abort with 'mapping
values are not allowed here'. The skills CLI parses this frontmatter
during 'npx skills add', so install failed.

Wrapped the value in double quotes (no internal " or backslash, so
this is lossless and stays one line). Frontmatter now parses; name,
description, and version keys intact.

Co-Authored-By: WOZCODE <contact@withwoz.com>
2026-05-19 15:23:26 -04:00
Youssef fc38eb7a80 Site · add Plausible analytics snippet to head 2026-05-19 19:49:36 +01:00
Youssef 4051c22776 Codex · trim SKILL.md description under 1024-char limit + document install path
Codex enforces a 1024-char cap on the frontmatter description; ours was 1813,
causing "invalid description: exceeds maximum length of 1024 characters" on
load. Rewrote to 927 chars, lossless on routing signals — all five fire
triggers, all three don't-fire conditions, and the decisive heuristic are
preserved. Stripped duplicate verb listings, parenthetical examples on each
trigger, and padding prose.

README + site install panes now document `~/.codex/skills/hallmark/` (personal)
and `.codex/skills/hallmark/` (project-scoped) for Codex, replacing the prior
"manual / git clone" placeholder.
2026-05-19 19:43:21 +01:00
Youssef 38f1885c97 Site · tighten banner picker↔shuffle gap to match Install↔Star + link "Together AI" in footer 2026-05-19 19:08:44 +01:00
Youssef 0757b51936 Fix · star counter shows live count + stale-while-revalidate 2026-05-19 18:51:58 +01:00
Youssef b54381fa02 Docs · add Updating section to README 2026-05-19 17:07:03 +01:00
Youssef 9f9cf0dbd5 Site · point at www.usehallmark.com + fade page in once web fonts resolve 2026-05-19 16:07:34 +01:00
Hassan El MghariandGitHub 7870c1a959 Update README.md 2026-05-19 08:05:33 -07:00
YoussefandGitHub d58600dd63 Update README.md 2026-05-19 14:46:21 +01:00
Youssef f39d30740e Fix · gate 66 + eyebrow rule bind on content shape, not class name; not bypassable by parity instructions
A subagent generating a Hallmark page with explicit "preserve structural parity with this reference build" instructions inherited the banned tag-left / header-right pattern (`.workbench__head` with `grid-template-columns: minmax(0, 0.4fr) minmax(0, 1fr)` and three `01 · The tour`-style eyebrows) from a launch-day reference that pre-dated gates 66/67/68/69. Gate 66 didn't catch it because the wrapper used `.workbench__head` rather than the canonical `.section__head` named in the original wording.

Two fixes:

1. **gate 66 (slop-test.md) — bind on content shape, not class.** The rule now reads "any <header>, <div>, or <section> wrapper — regardless of class name (.section__head, .workbench__head, .pricing__head, .catches__head, .foo__intro, anything macrostructure- or section-specific) — that contains both an eyebrow/label/number/kicker element AND a heading element MUST resolve to single-column layout." Class-name allowlists are out; the rule binds wherever the *shape* appears.

2. **Both rules (gate 66 + anti-patterns.md "Eyebrow on every section") — explicitly non-bypassable by parity instructions.** New clause in both: instructions to "preserve structural parity", "mirror this reference build", or "match the prior build" do NOT exempt the new build from the rule. If the reference ships the banned pattern, silently flatten it in the new build — the rules win over parity. Reference builds often pre-date these gates; the gates are authoritative.

No content/scope change beyond hardening the wording. Local Hallmark mirror updated.
2026-05-19 14:00:22 +01:00
Youssef 42e5db6441 Chore · gitignore skills-lock.json and .agents/ — 'skills add' artifacts, not skill source 2026-05-19 12:19:49 +01:00
Youssef 899d846196 Fix · escape YAML-breaking colon in SKILL.md frontmatter + gitignore ephemera
The skills CLI's frontmatter parser rejected SKILL.md with "Nested mappings are not allowed in compact mappings" because the description contained " ANY of: (1) " — the colon-space sequence inside an unquoted YAML scalar made the parser think it had hit a nested key/value pair. End result: 'npx skills add nutlope/hallmark' cloned successfully but then bailed with "No skills found. Skills require a SKILL.md with name and description."

Fix: rephrase "Fires when ANY of:" → "Fires when ANY of these match —". Single character semantic — colon→em-dash. Frontmatter now parses cleanly under js-yaml. No content semantics change.

Also tightened the repo to what actually helps the skill or a future user — per the new instruction. Added to .gitignore + git rm --cached:
- .hallmark/                — runtime state from my dogfooding runs, has no business being committed
- site/_launch-comparison/  — one-off launch-day comparison artifact (Hallmark / Impeccable / no-skills); not linked from the marketing site, README, or anywhere else

Working-directory copies preserved (rm --cached, not rm). docs/talk-slides.md left in place — it's user-authored content, not mine to remove.
2026-05-19 12:18:24 +01:00
Youssef aedca8cb03 Refactor · move SKILL.md + references/ to repo root so 'npx skills add nutlope/hallmark' works
The published install command in the README — npx skills add nutlope/hallmark — was failing for users because the skills CLI looks for SKILL.md at the repo root, not at skill/SKILL.md where Hallmark kept it. The clone succeeded but the CLI reported "No skills found." Manual cp was the only working install path.

Flattened the layout:
- skill/SKILL.md            → SKILL.md
- skill/references/         → references/
- (skill/ directory removed; was empty after moves)

git mv preserved rename history for all 76+ files (SKILL.md + 28 reference files + 21 macrostructures + 46 components + 7 verb/genre subfolders).

Updated every cross-reference (36 occurrences across 9 files):
- README.md — 4 links (SKILL.md + references/ + the install snippet still reads the same)
- ROADMAP.md — 4 links to reference files
- package.json — "files" field + "skill" entry/references paths
- site/js/main.js — 3 source comments
- references/design-md.md — one broken link (was pointing skill/references/export-formats.md from inside references/ — now just export-formats.md as a sibling)
- site/_tests/verbs/study/notes.md, diagnosis.md and verbs/audit/audit-report.md, custom/README.md — test-artifact relative paths shortened by one segment (e.g. ../../../skill/SKILL.md → ../../../SKILL.md)

No skill content changes. After this lands, 'npx skills add nutlope/hallmark' should clone + install correctly without any manual cp fallback.
2026-05-19 12:12:45 +01:00
Youssef db1072fe32 Docs · fresh hero screenshots in README, study URL example on landing page, roadmap priorities
- docs/screenshots/hero-*.jpg: 8 fresh hero-only captures of each worked example (1440×900 via Chrome headless on the local dev server). Replaces the mid-video stills in _tests/_thumbs/*-still.jpg which had video-player overlay and cropped headlines. Each is unique — no duplicates. README "Different briefs, different shapes" section now uses these and each thumbnail is a clickable link to the live deployed example.
- site/index.html: the Study verb's brief-pill swapped from "/hallmark study this landing page" to "/hallmark study together.ai · or paste a screenshot" so URL mode is visually concrete next to the lede that already names both modes. One-line change.
- ROADMAP.md: new "Now — actively working on" section at the top. N.1 covers tightening the existing 22 themes + adding 4–6 new distinct ones + lowering the bar to route to custom. N.2 covers first-class Nanobanana image generation + a new image-led theme (working title: Plate) + token discipline for generated stills.
2026-05-18 16:54:59 +01:00
Youssef 1552cd2b21 Fix · /hallmark slash-picker description leads with what the skill does
The frontmatter description opened with "Use this skill when ANY of these fire" — agent-facing trigger logic. Users typing /hall in the slash picker saw the truncated preview as "Use this skill when ANY of these fire — (1) the user names one of Hallmark's explicit verbs..." which says nothing about what Hallmark actually does.

Prepended a one-line user-facing summary so the picker preview reads as: "Anti-AI-slop design skill — generate distinctive landing pages, audit existing UIs, redesign templated pages, or study an admired URL / screenshot to extract its DNA." plus a usage hint with the four verbs. The full 5-condition trigger logic stays underneath unchanged so Claude's auto-fire behaviour is preserved.
2026-05-18 16:43:14 +01:00
Youssef 9f907ad38e Marketing · make Worked-examples cards clickable, open in new tab
Each .ex-card div is now an <a target="_blank" rel="noopener"> wrapping the same content. The hover-play video, prompt line, and .ex-card styles all work unchanged (the class already had color: inherit + focus-visible). Added one CSS line — text-decoration: none on .ex-card — so the <a> doesn't underline the card.

Linked destinations:
- examples/tally/        — SaaS, modern-minimal (from /Users/youssef/test-hallmark-9)
- examples/wayfare/      — travel booking, atmospheric (from test-hallmark-12)
- _tests/09-slow-pour/   — small-batch coffee subscription (already in site)
- examples/bananastudio/ — creative studio with playful motion (from test-hallmark-6)
- _tests/06-anya-portfolio/ — software architect personal site (already in site)
- examples/najm/         — Moroccan fashion (from test-hallmark-7)
- _tests/11-soroe-ceramics/ — small ceramics studio (already in site)
- examples/hyperlane/    — developer infrastructure (from test-hallmark-15)

site/examples/ adds ~308 KB total across the 5 copied projects. The other 3 already live under site/_tests/ so no copying needed for them.
2026-05-18 16:23:29 +01:00
Youssef ab5f84ee9d Fix · study handoff uses extracted DNA as the system, not a catalog theme
When the user ran `study <URL>` and then said "build it", Hallmark fell back to a catalog theme (the "closest cousin" hint in the diagnosis) instead of using the studied DNA — paper/accent/fonts/macrostructure from the source were discarded.

- study.md: rewrote both diagnosis templates and the worked example. The "closest catalog theme" line is now framed as an explicit pivot option ("just say 'use X instead'"), not a recommendation. The "build it" handoff explicitly uses the studied DNA as the system.
- SKILL.md § 2.6: new Condition 0 (highest priority) — when a study diagnosis was emitted earlier in the conversation and the user asks to build from it ("build it" / "make it" / "use this DNA"), skip catalog/custom dispatch entirely. The DNA's tokens, macrostructure, and archetypes become the locked system. Diversification suspended for the build. Pivot phrases ("use Linen instead" / "ignore the DNA") route back to normal dispatch.
- SKILL.md Step 6: stamp's `theme:` field is `studied-DNA (source: <URL or image>)` with inline OKLCH/font values for studied builds.
- slop-test.md: new gate 69 auto-fails any build that names a catalog theme in its stamp when a recent study exists and the user didn't explicitly pivot.
- Gate count bumped 68 → 69 in SKILL.md + preview-examples.md.
2026-05-18 15:37:09 +01:00
Youssef f5d5c075a2 Fix · Bloom section heads left-align (hero stays centered) + drop Newsprint double-rule
- Bloom: .section__head was text-align: center with .section-label justify-content: center and .section__title margin-inline: auto — every section read as centered-everything (the AI fingerprint). Flipped to text-align: left, justify-content: flex-start, margin-inline: 0. Hero (.hero--marquee) stays centered via its own rules; the atmospheric glow does the centering work without needing every section head to repeat it. Tag stays above the title in the same column (still passes gate 66).
- Newsprint: removed border-top: 3px double var(--color-ink) from .section__head — the double rule above each section tag was reading as decorative noise on a layout that already has a strong 1 px bottom border. Single bottom border kept.
2026-05-18 15:10:02 +01:00
Youssef b41a3e60e2 Fix · Almanac sticky section heads bleeding over the top nav
Two sticky-at-top:0 elements in the same stacking context (.banner and Almanac's .section__head) overlapped during scroll because they shared --z-sticky (200) and the section head paints last in DOM order. Visible on the marketing site as the section header drawing on top of the nav as you scroll.

site/ — actual fix for the live page:
- tokens.css: split --z-sticky into --z-sticky (200, in-page) + --z-sticky-nav (300, top nav); add --banner-height: 44px so secondary stickies can offset by a single token
- components.css: .banner now uses --z-sticky-nav and reads --banner-height for its height (kept at 44 px)
- sections.css: Almanac .section__head docks at top: var(--banner-height) instead of top: 0; z-index stays at --z-sticky so the banner always out-paints when their boxes momentarily overlap

skill/ — prevent the pattern in future generated pages (without forcing sticky on every output):
- slop-test.md: new gate 68 auto-fails any second sticky-at-top:0 element when a sticky page-level nav exists; fires only when the page actually has sticky elements (S3, F2, sticky TOCs), trivial pass otherwise
- components/s3-sticky-pinned.md: recipe rewritten to use top: var(--banner-height) + --z-sticky; pairing rule explained
- components/f2-sticky-scroll-stack.md: top now calc(var(--banner-height) + var(--space-xl)) so the sticky pane docks below the nav with breathing room
- SKILL.md + preview-examples.md: gate count bumped 67 → 68

Only Almanac uses sticky section heads in the live site — no other themes affected.
2026-05-18 14:54:11 +01:00
Youssef a2cd497977 Fix · Manifesto + Sport line-height collision on wrapped uppercase headings
Manifesto and Sport themes set --lh-tight: 0.94 paired with text-transform: uppercase and condensed display faces (Anton / Inter Tight 900). On a two-line .section__title the cap-tops of line N+1 collide with the baseline of line N — most visible on the marketing site's "SAME PROMPT, TWO / DIFFERENT OUTPUTS." headline where the comma and the D fuse into one glyph.

- tokens.css: bump --lh-tight to 1.02 for both themes (safe floor for all-caps condensed display)
- slop-test.md: new gate 67 auto-fails any display-size element that pairs text-transform: uppercase with line-height < 1.0
- typography.md: explicit "Floor for all-caps display heads is 1.0 — recommended 1.02–1.08" line added to body-text rules
- SKILL.md + preview-examples.md: gate count bumped 66 → 67
2026-05-18 14:45:40 +01:00
Youssef 546ddfac86 Perf · split macros + components per-item, lazy-load slop-test, extract preview examples
- macrostructures.md (37 KB monolith) split into 21 per-macro files in references/macrostructures/; slim index lists names + summaries; SKILL.md Step 2 instructs to pick from index, then load ONLY the matching per-item file
- component-cookbook.md (55 KB monolith) split into 46 per-archetype files in references/components/; slim index lists names + summaries; SKILL.md Step 2 instructs to pick archetype codes, then load ONLY the matching files (typical build: 5–7 archetype files vs the whole cookbook)
- SKILL.md § 3 load-list rewritten: macros + components moved from eager-load to index-then-pick; slop-test.md gated to Step 7 only with explicit "do not pre-load" language; hero-enrichment.md no longer auto-loaded at Step 4
- 4 worked Step 5 preview blocks extracted from SKILL.md to references/preview-examples.md (lazy-loaded)
- gate count bumped 65 → 66 across SKILL.md (gate 66 was added in prior commit)

Expected token reduction per build: ~30–40 K (~30–40 % of the previous ~100 K-per-build cost), driven primarily by no longer loading 21 macros or 46 archetypes when only one of each is picked.
2026-05-18 14:37:09 +01:00
YoussefandClaude Opus 4.7 7088415045 Launch · hero sizing, greenfield auto-trigger, section-tag default off
- Hero headline size brackets in typography.md; SKILL.md Step 6 enforces ≤7 words / ≤50 chars when AI-written, aggressive-display themes auto-step down past 50 chars
- SKILL.md frontmatter now auto-fires on greenfield full-page / full-site builds, stays silent on component-scope and iteration on existing styled UI
- Eyebrows / section tags default OFF (anti-patterns.md strengthened); tag-left / header-right two-column section heads banned outright by new slop-test gate 66; structure.md Left-margin + Numbered display and layout-and-space.md Hanging headers marked opt-in only

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 14:04:45 +01:00
YoussefandClaude Opus 4.7 b4e454fea2 Study · emit portable design.md from diagnosis (opt-in)
After a study diagnosis, the user can now say "lock the DNA" to write
a portable design.md from the extracted DNA — same format as the
default verb's lock-the-system flow, seeded from the studied source.

URL mode populates exact tokens + fonts; image mode populates
estimated bands + candidate fonts. URL-mode emission asks the user
to attest the source is theirs or a public reference for their own
brand — third-party URLs are refused at the emission step even when
the diagnosis itself was allowed. Image mode emits without asking.

Updates skill protocol, design-md trigger list, public verb table,
README comparison, and the site's Study row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 14:10:35 +01:00
YoussefandClaude Opus 4.7 1cfcc89a06 Study · accept URL input alongside screenshots
URL mode reads HTML/CSS via WebFetch — names exact fonts and exact
colour values; trades the rhythm pass for everything else getting
more accurate. Auto-refuses template-marketplace URLs; falls back
to asking for a screenshot if the URL is auth-walled or an SPA shell.

Also drops a stale external reference from ROADMAP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:36:12 +01:00
YoussefandClaude Opus 4.7 422065f77a Fix · install hover-stick + Atelier hero header + With/Without rename
Banner Install hover-stick:
- Smooth-scroll on a sticky banner can leave the cursor over the
  pill after click; Safari/Chrome occasionally keep :hover stuck
  even after the pointer moves away.
- Scope the hover rule to (hover: hover) and (pointer: fine) so a
  touch tap never sticks the inverted state.
- Add :focus:not(:focus-visible) reset so synthesised mouse-focus
  doesn't keep the inverted look either.
- Add a JS click handler that blur()s the pill and toggles
  pointer-events for one frame, forcing the browser to release any
  sticky :hover/:focus state.

Atelier hero header:
- Quote copy: "Restraint, repeated, becomes a signature." → "A
  workshop, not a template." Shorter, declarative, fits Atelier's
  workshop voice.
- Override the hero quote to use the upright display face
  (var(--font-display), normal style, --display-weight 900),
  matching the "Atelier" wordmark in the banner and every section
  title. Italic var(--font-serif) was making the header read as a
  pull-quote rather than the page's primary statement; Atelier's
  voice is declarative, not quoted.

With / Without rename:
- Section 06 label "Before / After" → "With / Without". Both panels
  exist now (Sonnet 4.6 alone vs Sonnet 4.6 + Hallmark) — there is
  no temporal before/after, only a presence/absence comparison.
- HTML comment updated to match.

Diptych screenshot centring:
- .ba__frame img object-position: top left → center. The full hero
  composition reads inside the 16:10 frame instead of clipping to
  the top-left corner. Other diptychs (.diptych__half, .brief-output)
  intentionally stay top-aligned — they're page screenshots where
  the masthead matters; the .ba__frame is hero-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 19:10:58 +01:00
YoussefandClaude Opus 4.7 ad3d07e507 Fix · mobile copy button regression — hide button, make pre tap-to-copy
The previous mobile fix (display: block + width: 100% on the button)
overflowed the frame because .code has white-space: nowrap and the
button rendered inline-flex on the same nowrap line as the command,
spilling past the right edge.

Cleaner pattern, matching what gh repo clone / npmjs / Vercel
install panes do on touch devices:

- Hide .code__copy entirely below 45rem.
- Bind a click handler on the whole [data-copy-source] pre so the
  command area itself is tap-to-copy. cursor: pointer signals it.
- Add a transient "Copied ✓" badge inside the pre on success
  (anchored top/right/centred-vertically) — replaces the button's
  label-swap on mobile. Animates in and clears after 2.2 s.
- Restore the original .code flex + align-items: center so the
  command sits vertically centred in the frame regardless of height.

JS:
- Refactor attachCopyButtons to share a copyFromSource helper.
- Source binding uses data-copy-bound; button binding uses
  data-copy-btn-bound (separate flags so re-attached cloned heroes
  don't double-bind).
- Button click stops propagation so a single tap on the visible
  button (desktop) doesn't fire both the button and source handlers.
- Both surfaces flash data-state="copied" together so CSS feedback
  works on whichever surface is visible at the active breakpoint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 19:07:01 +01:00
YoussefandClaude Opus 4.7 e27a02f981 Section 06 prompt · update to dev event launch brief
The shared prompt in the Before/After Hallmark gallery used the old
Quiet Hour natural-wine brief — stale now that the before/after
thumbs were swapped to the DevForge dev-conference landing pages.
Updated the prompt to match the new content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:58:08 +01:00
YoussefandClaude Opus 4.7 6358ab559e Fix · before/after Quiet Hour thumbs — restore PNG + correct filenames
The before/after demo in the comparison gallery (Section 06) was
broken because the on-disk files had drifted from the HTML refs:

- HTML: <img src="_tests/_thumbs/before-quiet-hour.png" />
- Disk: before-quite-hours.jpeg (JPEG, typo "quite", plural "hours")

- HTML: <img src="_tests/_thumbs/after-quiet-hour.png" />
- Disk: after-quite-hour.png (typo "quite")

Re-encoded the before file from JPEG to PNG via sips and renamed
both to the correct singular "quiet-hour" spelling that the HTML
references. The Quiet Hour DevForge before/after now renders.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:57:33 +01:00
YoussefandClaude Opus 4.7 3375a99da4 Fix · mobile copy/star + footer bottom space + drop "Powered by Together AI"
Hero install copy button:
- On coarse-pointer (touch) devices the copy button sits visible at
  all times. With its absolute right-aligned position it overlapped
  the npx command text on narrow viewports — most visible on
  Specimen but applied to every theme using .code.
- Below 45rem, drop the absolute positioning and let the button flow
  as a full-width row beneath the command (GitHub / Vercel / npmjs
  pattern). The command keeps its horizontal scroll for long URLs.

Banner GitHub star spacing on mobile:
- The star uses a negative inline-start margin (-0.75rem) tuned for
  the install/star pair on desktop. On mobile the install link is
  hidden, so that same margin pulls the star too close to the
  wordmark.
- Below 50rem, loosen the start margin to -0.25rem (+8 px breathing
  room from the wordmark, matching the requested gap).

Specimen eyebrow:
- Drop " · Powered by Together AI" from the Specimen hero eyebrow
  copy. The Together AI credit lives in the footer; repeating it in
  the hero made the lede read like a sponsorship banner.

Footer bottom spacing:
- .page added padding-block-end: var(--space-4xl) (10 rem ≈ 160 px),
  and .foot--colophon added another --space-2xl (4 rem ≈ 64 px) of
  internal bottom padding. Combined ≈ 224 px of empty space below
  "Made by Together AI" on every theme.
- Drop the page-wrapper bottom padding to 0 — the colophon owns its
  own end-spacing.
- Cap the colophon's own bottom padding at --space-md (16 px) on
  desktop and mobile. The credit line now hugs ≤ 20 px from the
  viewport bottom.

Stale stats in footer (caught while in there):
- 23 themes → 22 (Pastel removed earlier).
- 60 slop-test gates → 65 (caught up to slop-test.md's actual count).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:46:31 +01:00
YoussefandClaude Opus 4.7 9c4827687e Fix · interlude + diptych: contrast bug from --color-accent-ink misuse
The "The page is the demo" interlude rendered with white-on-light text
on Coral, Violet, Plume, Editorial — and dark-on-dark on Aurora, Halo
— because .interlude__phrase em was reaching for --color-accent-ink.
That token is "text laid over the accent fill" (paper-coloured on
most themes), so it disappears on the paper-2 band.

Use --color-accent directly. The accent itself is mid-L on every
theme (40-78% L), so it has the right contrast against either light
or dark paper.

Same root cause caught in two more places:
- .diptych__half[data-state="after"] .diptych__cap (the small label
  under the "after" diptych panel — same paper background)
- [data-theme="midnight"] .opening__title em (works visually on
  Midnight because its accent and accent-ink are equal, but the token
  usage was semantically wrong; aligning for consistency)

Six themes specifically affected by the visible bug: Coral, Violet,
Plume, Editorial (light, near-white em on light paper) and Aurora,
Halo (dark, near-black em on dark paper). All six now read clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:58:10 +01:00
YoussefandClaude Opus 4.7 32c02f1775 Catalog · drop Pastel theme (23 → 22) · centre Plume hero
Pastel removal:
- skill/SKILL.md — theme list, five count refs, four example refs
  (rotation log, preview block, diversification text, display-style
  cluster).
- skill/references/ — structure.md (table row), component-cookbook.md
  (modern-minimal nav routing), custom-theme.md (theme list + count;
  also fixes 55 → 65 gate-count drift), study.md (DNA-match row),
  copy.md (×2 sample copy → Plume), macrostructures.md (Letter
  sample), hero-enrichment.md (stamp example → Linen), playful.md
  (Plume becomes the canonical playful theme).
- site/js/main.js — THEME_NAMES, ARCHETYPES, THEME_GENRES, COPY
  block; "twenty-three" → "twenty-two"; almanac letterBody updated
  ("23 themes, 55 slop-test gates" → "22 themes, 65 slop-test
  gates" — also catches the gate-count drift).
- site/index.html — delete Pastel button; renumber Riso through
  Editorial (15 → 14 ... 23 → 22).
- site/css/tokens.css — delete Pastel theme block + its per-theme
  radius override; update "soft themes" + Plume neighbour comments.
- site/css/components.css — delete two Pastel blocks (banner pill +
  big component overrides); update stale "Pastel post-Linear-soft"
  comment; "23 themes" → "22 themes".
- site/css/sections.css — delete Pastel skill-row + brief-output.
- README — "twenty-three" → "twenty-two"; theme list drops Pastel.

Plume hero centring:
- Delete the [data-theme="plume"] .hero__bloom-stage::after feather
  glyph.
- Add a Plume-only override that hides .hero__bloom-stage entirely
  and recasts .hero--bloom as a single centred column with text +
  CTA + eyebrow + proof centred. Hero only — the rest of the Plume
  page keeps its asymmetric rhythm.

Verified the demo site loads on a static server (HTTP 200 on
index.html + all CSS + JS), main.js parses with node --check, and
the theme dropdown now has 22 buttons.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:51:25 +01:00
YoussefandClaude Opus 4.7 a6a157e520 Rebrand · GitHub URLs and install command to nutlope/hallmark
Repo handover prep. Replaces:
- github.com/Luffixos/hallmark → github.com/nutlope/hallmark
  (banner star link, footer link, JS REPO constant for star count)
- npx skills add hallmark → npx skills add nutlope/hallmark
  (README install section, four install panes in site/index.html)

No skill internals touched — SKILL.md and references/ unchanged.
The local installed skill at ~/.claude/skills/hallmark/ continues
to work; the URL change is content-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:39:18 +01:00
YoussefandClaude Opus 4.7 6020d445ed Skill · opt-in design.md lock-the-system flow
Phrase-triggered design-system extraction. The user iterates freely on
the first builds; when the system is settled, they say "lock the system"
(or "give me a design.md", "make this portable") and Hallmark writes a
portable ~45-line design.md at the project root.

Why opt-in:
- Zero churn — no design.md flickering as the user swaps themes between
  iterations.
- The locked system reflects a settled choice, not build #1's hot take.
- Mirrors how design teams actually work: formalise after patterns hold.

Mechanics:
- skill/references/design-md.md (new) — trigger phrases, scope rules,
  the tight format template, no-overwrite policy.
- SKILL.md Step 3 — design-md.md added to load-conditionally.
- SKILL.md Step 5 — preview block carries one quiet CTA line. Skipped
  on component-scope or when design.md already exists.
- SKILL.md Step 6 — opt-in design.md bullet alongside tokens.css and
  multi-format-export rules. Default verb does NOT auto-emit. Multi-
  page redesign keeps producing the heavyweight design.md (unchanged).
- README — one bullet under What's distinct.

Page-scope only; component-scope skips. Once design.md exists every
Hallmark run defers to it (existing pre-flight rule, unchanged) and
the diversification rule inverts to consistency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:33:52 +01:00
YoussefandClaude Opus 4.7 d4b9ce1463 Favicons · refined Hn glyph paths
Both favicon SVGs (dark + light) updated with hand-tuned path
coordinates for the Hn wordmark glyphs. No structural change to
the SVG; just nudged stroke positions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:04:31 +01:00
YoussefandClaude Opus 4.7 89f2139497 Docs sync · 4 verbs · 65 gates · stills replace videos
The README and SKILL.md had drifted out of sync with the current
slop-test.md (now 65 gates) and the verb state (refine was removed;
audit · redesign · study + default = four verbs total).

- README: revert lingering "refine" references; verb count 5 → 4
- README: gate count 55/60 → 65 across body + side notes
- README: section title "Eight pages, eight different shapes" →
  "Different briefs, different shapes" — the old phrasing implied
  the skill could only produce these eight specific sites
- README: replace eight <video src=...mp4> tags with <img> stills
  (first-frame extracts via ffmpeg from the existing .mp4 files;
  no autoplay overhead, faster page render on the readme view)
- SKILL.md: drop "refine" from the frontmatter trigger description;
  sync "55-gate" → "65-gate" across routing file + stamp examples

No version bump — pure documentation drift catching up to the
current rule-set state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:04:11 +01:00
YoussefandClaude Opus 4.7 c38c84a887 Skill trigger · narrow to explicit verbs only
Description was firing on broad catch-alls — "design a", "build a
landing page", "make a dashboard", and the universal trap "any
request that will produce HTML / CSS / JSX / Tailwind output". Net
effect: Hallmark hijacked generic UI prompts that should have gone
to frontend-design or whatever else is loaded.

Tightened to four conditions:

  1. User explicitly names a verb — audit · refine · redesign · study
  2. User says a UI "feels AI-generated" / "looks templated" / "looks
     like every other AI page", or asks to "make it less AI-generated"
  3. User attaches a screenshot of a design they admire (study verb)
  4. User invokes by name — "use Hallmark" or /hallmark

Added an explicit DO-NOT list — "design a button", "build me a form",
"add a navbar" — pointing those at frontend-design or other UI skills.

Hallmark stays proactive (matches the peer-skill convention) but the
phrase list is on-purpose, not catch-all. Skill discoverability
preserved; default-builder behaviour removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:57:43 +01:00
YoussefandClaude Opus 4.7 22fb6626c1 Design-context gate · tighten the "always ask" rule
The previous wording said "almost always asks" with two carve-outs,
and the "user already named all three" exception let the model skip
the gate on five-word briefs by wishfully reading "podcast site" as
audience+use+tone. Removed that exception. The only silent verbs
are now audit / study / redesign --mood. Updated the prompt format
to match the canonical 1-2-3 layout (Audience · Use case · Tone)
with bolded labels. Added an explicit no-length-threshold clause:
short briefs get the same gate, the user waves through with "go ahead".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:28:43 +01:00
YoussefandClaude Opus 4.7 a80cf00f28 Anti-pattern · eyebrow on every section
Default to no section eyebrow. Use one only when the section is
genuinely ordinal (numbered manifesto, multi-step process, long
document chapters) or when the section name is too short to read
as a heading on its own. At most 1–2 per page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:02:44 +01:00