Repository navigation
feat: taste-tested homepage, tracks ordered by measured demand - #136
Merged
Merged
Conversation
… row, tasted stamp, rhythm Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
…el, dot-grid watermarks Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
Repeat the dot grid and the rose across every band, then polish: - Band edges print in the dot grid over the border, at 18%. - One phrase per heading carries a rose underline. Native text-decoration so it survives a line wrap. - Watermarks fit inside the gutter whole, 3rem, widest screens only. A word cut off by the fade read as a rendering bug. - Door marks are dot-grid tiles that light on hover. - Taste-test numerals are printed in the grid. - Tasted chip on the lead collection, reusing the hero emoji. - Ecosystem logos under the authoring strip, npm lit, the rest dim. - Rose selection colour on the page. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
- Every band heading now uses one clamp scale. The page had four. - The publish band gets the same vertical rhythm as its neighbours. - Community was dropped from the site, so the featured band points at /collections and its copy stops naming a directory we no longer sell. - The hero dot underline was invisible at 35%. It reads now. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
A copy review found claims the page could not support: - Trending is measured from posts. It never counts installs. - "Stars are the only count we show" was false beside three counters. - "every agent" overclaimed under a row naming seven agents. - "stack" and "hot" are banned for collection and trending. - Two bands repeated each other word for word. - The sign-in wall behind "Watch your starred repos" was invisible. - /collections 301s to /community, so three links took a redirect. - Official publishers has its own page. The label now goes there. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
- The page had two left edges. Hero, doors and every band now share max-w-6xl, so nothing steps right when you scroll past the doors. - Each band drew its edge twice, a solid border plus the dotted rule. The dotted rule is the divider now, and the last band drops it. - Doors get symmetric 2.5rem padding, half the band rhythm. - Watermarks anchor to the text column and fade at the far end, so the crisp end is the one beside the heading. - The rail scrollbar and half-faded top row are gone. Vue scoped styles outrank a two-class selector, so the override takes three. - Dimmed chips read as disabled UI. Tiles recede on their border now. - Two h3 steps under the heading scale, not four. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
/api/clusters sorts tracks by how many skills each one holds, which is supply. The grid now takes a demand order instead. Measured 2026-09-04 from production: the 50 named skills trending over a week, the 50 over a month and the top 50 repos by stars. 48% of trending skills have no classifier category, so all 80 named skills were read and placed by hand. Scored with a 1/log2(rank) decay, weighted week 1.0, month 0.8, all-time 0.6. Design leads at 16.5%, then agent workflows and anti-slop writing. SEO scored zero on every board and drops off the twelve-tile grid. Two gaps the order cannot fix: diagrams and codebase maps took 10.8% and the top skill of the week with no track to hold them, and research came back at 6.5% after being retired on 2026-08-13. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
The 2026-09-04 measurement changed the taxonomy, not only its order. `diagrams` is new. Diagrams and codebase maps took 10.8% of weighted trending demand and the top skill of the week, tt-a1i/archify, while their skills scattered across three tracks that promise something else. Nine pins in production, no classifier category to stand on yet. `research` returns 22 days after it was culled for having no demand. It now carries 6.5%, led by browser-use at rank 6 for the week. It takes `scraping` from Agent workflows, since values may not repeat, so it has 37 classified skills under its 8 pins. Its 301 leaves nuxt.config. Nothing retired against them, which breaks the subtraction principle on purpose: a page answers search demand and costs a URL, a tile answers trending demand and costs the scarcest space on the site. The grid caps at twelve, so Performance, Everyday coding and SEO keep their pages and lose their tiles. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
The open item from the demand measurement: /skills/diagrams ran on nine pins with no backfill, because no classifier value described a picture. - `diagramming` joins ABSTRACTNESS_CATEGORIES with two prompt rules: what counts as drawing a structure, and that a chart is not a diagram. - scripts/backfill-diagramming-category.ts asks the same model the same question about a keyword-swept candidate set, instead of bumping the prompt version and putting 23k rows through the cron at 20 an hour. Dry run by default. It writes abstractness_category and nothing else, so a later cron pass can overrule it. - The 8b model calls plotting skills diagramming often enough to matter, so a pure guard holds a verdict back when the text talks about charts and never about structure. Tested. - Ran against production: 281 candidates, 111 now diagramming, 10 held. 53 of them had no category at all before. The track has 52 skills behind its pins where it had none. The track cards now carry the depth they are ranked on: a skill count on every card and a rose mark on a track admitted in the last 45 days. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
The cap set three grid rows and clipped the rest with overflow. In one column that is three tracks visible and nine gone, and the nine stayed in the tab order, so keyboard focus moved to cards nobody could see. The cap is a slice now. The component reads the rendered column count and renders rows x columns cards, leaving a single column uncapped. The server still renders every card, so a crawler sees all twelve. Measured: 1 column 12 cards, 2 columns 6, 3 columns 9, 4 columns 12. Also drops a claim that would rot: the diagrams curator note said the top trending skill of the week sits there, under a curator's name. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
Two more of the defects the track band had. - The first door pointed at #discover, but the trending band hides itself below three repositories, so the link did nothing whenever the band was absent. It now falls back to /skills/trending. - "All publishers" pointed at /skills/official, which 301s to /skills, and the panel beside it already links there. The button is gone and the empty state points straight at /skills. Swept the rest of the page while I was in there: no duplicate ids, no image without alt text, no control without an accessible name, no horizontal overflow at 390, 768 or 1440, and no focusable element clipped out of view. Reduced motion stops the packet and the rail's auto-scroll. The hero copy button and the search typeahead both work. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
InstallCommand renders a code element with no click behaviour, so the tabindex on the authoring command put keyboard focus on something inert, and a phone could only copy it by selecting text. It has a copy button now, with the live region the hero already had, and the tabindex is gone because that command wraps rather than scrolls. Below 30rem the feed heading and its link shared one row, which wrapped "Recently updated" onto two lines beside a button. They stack now. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
A section-by-section audit of the bands the earlier passes had not reached. The theme repeats: copy that outran the data. - recent-publishes joined skills and repos with LEFT JOIN, so an activity row whose skill was deleted survived, and a fallback invented a repo name for it. The feed could link to a page that does not exist. It is an inner join now, like recent-updates always was. - "One digest says what changed and why" ships without the why: DIGEST_AI_SUMMARY_PAUSED is true, so the email carries raw commit messages. Both places now say the digest lists what changed. - The lead collection card could print "Install all 0 skills" beside a live copy button, because the API filters members on trust and render status after counting them. The lead is now the first collection that has skills. - The Tasted chip asserted a review no field records, three lines above a named curator. Removed until something records it. - "Owner verified" is an owner allowlist, not a per-skill check. It says "From official owners". - /community lists curators, not collections, so the two buttons that promised collections now say curators. - A collection with seven authors read as three, and a ten-skill list showed six with nothing saying so. Both carry "+N more" now. - The page description said devs were installing. Nothing measures installs; the feed measures posts. - The authoring strip said skilld drafts the skill, which contradicts the comment four lines above it. The reader's agent drafts it. Production smoke gains the two new track pages, and a check that every featured collection answers 200 at its own URL. A dozen retired collection slugs are 301s, nothing stops one being featured again, and the homepage would link and print an install command for it. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
The hero command is the page's primary call to action and its copies were invisible. It used raw useClipboard, which records nothing and swallows a failure in a browser that blocks writes. Both the hero and the authoring command go through useInstallCopy now. That needed a third install target. The hero installs a whole repository, and filing it as a skill would record a skill name that does not exist, so `repo` joins the kind enum and stores the repository in `name`. Verified end to end: a hero copy writes home-hero / repo / obra / superpowers / install. scripts/seed-trending-local.ts writes the social evidence the trending band needs. Only the discovery cron writes x_posts, so a local database has none and the band hides itself. The site's top call to action was the one surface nobody could see while working on it. Local only, prefixed ids, --clean removes them. Also: an in-page jump landed a heading flush against the sticky header, the lead collection now shows when it was last updated, and GLOSSARY gains `track`, because one concept was called track in the UI, cluster in the code and category in the database. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
The weekly band embeds the real email card as a picture, cropped by overflow. Its own comment says tabbing through an inbox screenshot is a trap, and it set aria-hidden and tabindex="-1" to prevent that. Neither does: a negative tabindex takes the container out of the tab order and leaves every link inside the email markup in it, and aria-hidden over focusable children is its own violation. Five controls were reachable and invisible on the live homepage: a skill link, "Browse trending Skills", "Share this week's board", "Settings" and "Unsubscribe". The frame is `inert` now, which is what the comment was reaching for, with a test that fails on the old attribute. Four buttons to /community carried four labels, two of them naming "the community" as a proper noun, which GLOSSARY bans. They say curators now, matching the page they open. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
Swept the live routes for the defects the homepage had. - The skill page renders the file tree twice, floating and inline, and every folder id was built from the path alone. Six ids appeared twice on one page, and aria-controls resolves to the first match, so the second tree's buttons expanded the first tree's folders. Each tree now carries a useId prefix. - "Browse categories" and two meta strings called a track a category, which GLOSSARY now bans in the interface. They say track. - "Sign Up" on the trending page was the only title-case label on the site, for a button that starts GitHub OAuth. It says sign in with GitHub, which is what happens. Checked and left alone: the trending page's email preview is an iframe, and keyboard focus does not enter it across 120 tabs, so its inert and tabindex pair is doing the job. /skills, /community, a track page and a collection page are clean on traps, names, alt text, ids and overflow. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
/alt becomes /. The prototype has carried the pivot for a while and nothing about it is alternative any more, so the file moves, the `alt-` class prefix becomes `home-`, and the noindex comes off. `/alt` 301s to the page it became. `alt-page` folded into the `home-page` class the root already carried, and the duplicate `home-hero-grid` rule merged into the original. The previous homepage is gone with its weekly email band and its person-authored sections. The new page answers the same two loops in the order the pivot chose: find what devs are sharing, pick a track, watch what changes. Production smoke now asserts the hero's own words on `/`, because the error branch renders an h1 too, and checks the /alt redirect. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
A visitor who clicks off the homepage should not leave the brand behind. Three parts travel, and only three, so inner pages keep their own shape. - Rose selection colour, everywhere. It was homepage-only. - Band edges print in the dot grid site wide. The border keeps its place in the box model and gives up its colour, so nothing reflows. - Ledger numerals are inked rose and printed in the same dot grid as the homepage's taste-test numbers, on track pages and the trending board. The trending board's ranks encode a documented decision: the top three read first, through contrast rather than type scale. That mechanism survives as opacity, so the emphasis is unchanged and the numerals join the brand. Vocabulary followed the GLOSSARY entry this branch added. The curators page called itself Community, which the glossary bans as a proper noun, and counted creators, which it bans for a person. Two eyebrow labels on the brand-kit page were stacked above headings, which DESIGN.md bans and scripts/check-eyebrows.ts catches. That checker is clean now. Claude-Session: https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ
# Conflicts: # layers/registry/server/data/clusters.ts # nuxt.config.ts
The three-row fit moved from the taxonomy to the twelve-tile grid cap, so the count grows to 14 with diagrams and research, and security stays inside backend-data as #134 decided. Claude-Session: https://claude.ai/code/session_017kaxoymhg5taApymPzyx1b
Contributor
🤖 MERGED
GitHub merged this pull request. No further automated Review will run. |
The band moved from tabindex=-1 to inert so the email links leave the tab order too, and the hero search is a new combobox that needs its own axe pass. Claude-Session: https://claude.ai/code/session_017kaxoymhg5taApymPzyx1b
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the homepage with the taste-tested pivot, then follows the change through the registry and the pages around it.
The track order used to come from the API, which sorts by how many skills a track holds. It comes from the page now, and the column count decides how many survive.
The homepage
/altbecomes/. The hero states the category and hands the visitor two ways to move inside one screen: a real search typeahead, and a real install command prefilled with the top trending repo. Under it, the agents that command installs into.Bands, in order: what devs are sharing this week, tracks for your kind of work, the taste test, watch what changes, a whole collection in one command, and a compact strip for maintainers who want to write a skill. Community came out of the top navigation.
The brand system repeats rather than decorating the hero alone: a dot-grid rule on every band edge, a rose underline on one phrase per heading, dot-grid marks on the door tiles and the taste-test numerals, a watermark word in the gutter, and a rose packet riding the trending rail.
Tracks, ordered by measured demand
/api/clusterssorted tracks by how many skills each holds, which is supply. The grid takes demand now, measured on 2026-09-04 from production: the 50 named skills trending over a week, the 50 over a month, and the top 50 repositories by stars, scored with a1/log2(rank)decay.48% of trending skills had no classifier category, so all 80 named skills were read and placed by hand. The measurement changed the taxonomy, not only its order:
diagramsis new. Diagrams and codebase maps took 10.8% of weighted demand and the top skill of the week, and their skills were scattering across three tracks that promise something else.researchreturns 22 days after it was culled for having no demand. It now carries 6.5%, led by browser-use.diagrammingjoined the classifier, and a targeted backfill moved 111 production skills onto it. 53 had no category at all before.Nothing retired against the two additions, which breaks the file's subtraction principle on purpose: a page answers search demand and costs a URL, a tile answers trending demand and costs the scarcest space on the site. The grid caps at twelve, so Performance, Everyday coding and SEO keep their pages and lose their tiles.
Bugs found on the way
aria-hiddenand a negative tabindex, which leaves every link inside the email in the tab order. Five controls were reachable and invisible. It isinertnow.aria-controlspointed the second tree's buttons at the first tree's lists.LEFT JOINlet an activity row outlive its skill, and a fallback invented a repo name for it.Claims the data could not support
The digest promise said "what changed and why", but the AI summary is paused, so the email ships raw commit messages. "Stars are the only count we show" sat beside three other counters. "Owner verified" is an owner allowlist, not a per-skill check. Two buttons promised collections and opened a curators directory. Three links took a 301. All corrected.
Guards added
/, covers both new track pages, and checks that every featured collection answers 200 at its own URL, because a dozen retired collection slugs are permanent redirects and nothing stopped one being featured again.scripts/seed-trending-local.tswrites the social evidence the trending band needs, so the site's top call to action is no longer the one surface nobody can see while working on it.GLOSSARY.mdgainstrack. One concept was called track in the interface, cluster in the code and category in the database.The brand, carried through the site
Three parts of the homepage's system travel to every page, and only three, so inner pages keep their own shape: the rose selection colour, band edges printed in the dot grid, and ledger numerals inked rose and printed in that same grid, on track pages and the trending board.
The trending board's ranks encode a documented decision, that the top three read first through contrast rather than type scale. That mechanism survives as opacity, so the emphasis is unchanged.
Vocabulary followed the new GLOSSARY entry. The curators page called itself Community, which the glossary bans as a proper noun, and counted creators, which it bans for a person. Two eyebrow labels sat above headings on the brand-kit page, which DESIGN.md bans and
scripts/check-eyebrows.tscatches; that checker is clean now.Verification
1587 unit tests, typecheck clean. Checked in the browser at 390, 768, 1024 and 1440, in both themes: no focus traps, no duplicate ids, no missing alt text or accessible names, no horizontal overflow. Reduced motion stops the packet and the rail's auto-scroll. Production counts were queried directly rather than inferred from the local database.
Method and numbers for the demand measurement:
~/scratch/notes/skilld-track-demand-2026-09-04.md.https://claude.ai/code/session_01V83L3sonjzJF9D8aNBRhgJ