{"slug":"guideword","name":"Guideword","version":"1.0.0","category":"directory","priceCents":3400,"ui_library":{"version":"1.5.2","files":["html/src/js/_tt/anchor.js","html/src/js/_tt/field-ids.js","html/src/js/_tt/field.js","html/src/js/_tt/filter-chip.js","html/src/js/_tt/focusables.js","html/src/js/_tt/form-error-summary.js","html/src/js/_tt/form.js","html/src/js/_tt/layer.js","html/src/js/_tt/mode.js","html/src/js/_tt/pagination.js","html/src/js/_tt/pending.js","html/src/js/_tt/popover.js","html/src/js/_tt/presence.js","html/src/js/_tt/reduced-motion.js","html/src/js/_tt/roving.js","html/src/js/_tt/search-input.js","html/src/js/_tt/toggle-group.js","html/src/js/_tt/variant-selector.js","src/components/ui/_tt/anchor.ts","src/components/ui/_tt/capture.ts","src/components/ui/_tt/field-ids.ts","src/components/ui/_tt/field.axes.ts","src/components/ui/_tt/field.capture.ts","src/components/ui/_tt/field.fixtures.ts","src/components/ui/_tt/field.tsx","src/components/ui/_tt/filter-chip.axes.ts","src/components/ui/_tt/filter-chip.fixtures.ts","src/components/ui/_tt/filter-chip.tsx","src/components/ui/_tt/focusables.ts","src/components/ui/_tt/form-error-summary.axes.ts","src/components/ui/_tt/form-error-summary.fixtures.ts","src/components/ui/_tt/form-error-summary.tsx","src/components/ui/_tt/form.axes.ts","src/components/ui/_tt/form.fixtures.ts","src/components/ui/_tt/form.part.tsx","src/components/ui/_tt/form.ts","src/components/ui/_tt/hint.axes.ts","src/components/ui/_tt/hint.fixtures.ts","src/components/ui/_tt/hint.tsx","src/components/ui/_tt/host.ts","src/components/ui/_tt/ids.ts","src/components/ui/_tt/layer.ts","src/components/ui/_tt/layout-effect.ts","src/components/ui/_tt/pagination.axes.ts","src/components/ui/_tt/pagination.fixtures.ts","src/components/ui/_tt/pagination.tsx","src/components/ui/_tt/popover.axes.ts","src/components/ui/_tt/popover.fixtures.ts","src/components/ui/_tt/popover.tsx","src/components/ui/_tt/presence.ts","src/components/ui/_tt/recipe.ts","src/components/ui/_tt/reduced-motion.ts","src/components/ui/_tt/roving.ts","src/components/ui/_tt/search-input.axes.ts","src/components/ui/_tt/search-input.capture.ts","src/components/ui/_tt/search-input.fixtures.ts","src/components/ui/_tt/search-input.tsx","src/components/ui/_tt/toggle-group.axes.ts","src/components/ui/_tt/toggle-group.fixtures.ts","src/components/ui/_tt/toggle-group.tsx","src/components/ui/_tt/variant-selector.axes.ts","src/components/ui/_tt/variant-selector.capture.ts","src/components/ui/_tt/variant-selector.fixtures.ts","src/components/ui/_tt/variant-selector.tsx"]},"license":"standard","description":"For the developer who already has the data and a checkout and wants the directory's UI rather than another boilerplate: Guideword is a Next.js and Tailwind CSS directory template set as a printed trade directory, with no auth, payments or database and two functions to wire your own. Nine routes: the home spread, the classified index, a heading page with district and Saturday filters, the A–Z name index, a listing with LocalBusiness JSON-LD, search with a cross-reference for the word you used, the amendments slip, the list-your-business form with its live proof, and the styleguide. Every listing surface is a numbered page with guide words at its head, two ruled columns and an A–Z thumb index cut into the edge; an entry prints in three weights, line, bold and box, and those weights are the paid tiers, labelled as paid in words. Seventeen sections and twenty-two primitives around a 186-entry fixture, the Glasgow Repair Register, in light and dark and in React and HTML. Every count, folio and guide word is derived from the fixture, which refuses a record it cannot print; every pair passes AA in both modes; the zip runs as it is; AGENTS.md and four skills say how to rebrand it and add to it.","summary":"A nextjs directory template set as a printed trade directory: paid tiers as print weights, no auth or database, two functions wire your own data and checkout.","tags":["nextjs directory template","directory website template tailwind","business directory template react","listing directory ui template","local directory website template"],"accent_mode":"second-hue","palette":{"bg":"#f4f2eb","surface":"#fdfcf9","accent":"#0000ee","text":"#1a1711","line":"#1a1711"},"darkMode":true,"pages":[{"path":"/","title":"Find someone who fixes it.","sections":["site-header","home-verso","classified-index","home-recto","site-footer"]},{"path":"/trades","title":"By trade","sections":["site-header","classified-table","site-footer"]},{"path":"/trades/clock-and-watch-repairs/3","title":"Clock & watch repairs","route":"/trades/[slug]/[page]","sections":["site-header","heading-band","trade-page","site-footer"]},{"path":"/a-z/s/1","title":"A–Z: S","route":"/a-z/[letter]/[page]","sections":["site-header","az-spread","site-footer"]},{"path":"/listing/spoke-and-spanner","title":"Spoke & Spanner","route":"/listing/[slug]","sections":["site-header","listing-opener","listing-record","listing-as-printed","site-footer"]},{"path":"/search","title":"Search the register","sections":["site-header","search-spread","classified-index","site-footer"]},{"path":"/amendments","title":"Amendments","sections":["site-header","amendments-slip","site-footer"]},{"path":"/list-your-business","title":"List your business","sections":["site-header","listing-head","listing-form","site-footer"]},{"path":"/components","title":"Guideword's parts","sections":["site-header","site-footer"]}],"components":[{"name":"site-header","file":"src/components/site-header.tsx","renders":"The register's type-set name and edition, four routes in the link ink with the page's section underlined as current, the lamp switch and a quiet \"List your business\"; below lg the routes take their own row."},{"name":"home-verso","file":"src/components/home-verso.tsx","renders":"The spread's left page: the running head with the latest correction, \"Find someone who fixes it.\" at d6, the derived counts, the search and the classified index."},{"name":"classified-index","file":"src/components/classified-index.tsx","renders":"Every heading with a dot leader to the page it opens on, under a \"Page\" column head, in two columns from sm; no counts."},{"name":"home-recto","file":"src/components/home-recto.tsx","renders":"The spread's right page: page 2 of the typeset register, turning in place with ‹ › and the thumb letters, the end repeat \"A line entry is free\" at its foot."},{"name":"site-footer","file":"src/components/site-footer.tsx","renders":"The colophon: the editors by name, the check window and the edition the checks hold to, and every route including /components."},{"name":"classified-table","file":"src/components/classified-table.tsx","renders":"The classified index as a table, Trade · Entries · Pages · See also, 24 rows with every figure derived, a heading that runs over giving both pages, beside the route's band with the H1, the counts and the one filled action."},{"name":"heading-band","file":"src/components/heading-band.tsx","renders":"A trades page's left half: the running head with the book's folio, the heading as H1, its entries and pages, what it follows on the page, see also, the district select and the Any day · Open Saturdays group, the active filters as chips, the result line and the filled \"List your business\"."},{"name":"trade-page","file":"src/components/trade-page.tsx","renders":"The spread: the band, then the book's folio with the thumb index on its fore-edge, ‹ › turning only the heading's folios; a filter re-typesets the heading's matching entries into their own run in place, and nothing matching is a sentence with each filter offered relaxed."},{"name":"az-spread","file":"src/components/az-spread.tsx","renders":"The name index's spread: the thumb index as a head row of twenty-six, the letter band and one page of the letter's run; ‹ › route to the next address standalone and turn the page in place when embedded."},{"name":"az-band","file":"src/components/az-band.tsx","renders":"The letter band in two pieces: the running head, the letter at d5 and the derived lede; then the letter's pages with their guide words, the trades filed under it with the page each opens on, and the cross-reference to the classified index."},{"name":"listing-opener","file":"src/components/listing-opener.tsx","renders":"The entry set large: the heading as kicker, the name at d4 in its tier's weight, the number at d3 as a tel: link in the acting ink, the address, the tier in words, and the plate beside it for a box; a delisted entry prints its date and reason first and is struck."},{"name":"listing-record","file":"src/components/listing-record.tsx","renders":"The record as ruled rows: services, what it does not do, hours row by row or \"Hours not given\", the check and how long it holds or when it lapsed, listed since, and every amendment as before → after with how it came in."},{"name":"listing-as-printed","file":"src/components/listing-as-printed.tsx","renders":"The entry between its real neighbours at the register's 280px column measure, headed \"As printed · p. n\" with a link to the page; a delisted entry says when it left the pages and points at the slip."},{"name":"search-spread","file":"src/components/search-spread.tsx","renders":"The search spread: the field opened on ?q= with one sentence saying how many entries matched and under which heading, the results typeset as a page with the alphabetical first and last match as guide words, and the classified index to start from when nothing does."},{"name":"amendments-slip","file":"src/components/amendments-slip.tsx","renders":"The corrigenda slip: the running head and \"Amendments\" at d5 beside the derived counts and a one-clause helper with its hint, then every correction and delisting newest first on one measure."},{"name":"listing-head","file":"src/components/listing-head.tsx","renders":"The head of the listing page: the running head saying a line entry is free, \"List your business\" at d4 and one line on what the page does."},{"name":"listing-form","file":"src/components/listing-form.tsx","renders":"Seven fields validated on blur and on submit from one message table, the weight picker priced beside each weight, the one filled \"Send your entry\", and a receipt that says Not sent while no desk is connected."},{"name":"ui/directory-page","file":"src/components/ui/directory-page.tsx","renders":"One printed page: guide words and folio in the live page head, the legend with its hint, two columns under a full-ink rule, and the foot with \"continues on page n\"; or, as a roll, every page of a run in one flow under a running head that follows the entries in view."},{"name":"ui/entry","file":"src/components/ui/entry.tsx","renders":"One entry in its printed weight: line (name, dot leader, number, address), bold (\"Paid listing ·\" and a line of services) or box (directory yellow, plate, copy, hours, the number set large)."},{"name":"ui/thumb-index","file":"src/components/ui/thumb-index.tsx","renders":"A to Z cut into the fore-edge, the open page's letters reversed in a half-round ink tab, unfiled letters printed but not linked; a head row of two by thirteen below lg."},{"name":"ui/register-search","file":"src/components/ui/register-search.tsx","renders":"The GET search to /search with the filled \"Search\" and the live near-miss line that names the heading a reader's word is filed under."},{"name":"ui/action","file":"src/components/ui/action.tsx","renders":"The action shape in two weights: filled #0000ee under a white label, or quiet with an ink-grey edge."},{"name":"ui/text-link","file":"src/components/ui/text-link.tsx","renders":"The three link inks as class strings: the underlined ink link, the turn link in the one blue for what moves the page, and the box link that stays ink on the yellow island."},{"name":"ui/mode-toggle","file":"src/components/ui/mode-toggle.tsx","renders":"One button between newsprint and the desk lamp, named for what pressing it does, aria-pressed."},{"name":"ui/wordmark","file":"src/components/ui/wordmark.tsx","renders":"The register's name in Big Shoulders caps with the edition beneath, in data-brand-name."},{"name":"ui/item-list","file":"src/components/ui/item-list.tsx","renders":"One ItemList in JSON-LD per trades page, derived from the same fixture the page prints, with every character a parser acts on escaped."},{"name":"ui/local-business","file":"src/components/ui/local-business.tsx","renders":"One LocalBusiness JSON-LD node per listing: the name, the E.164 telephone, the address, the box copy as description and openingHoursSpecification where hours exist; nothing for a delisted entry."},{"name":"ui/amendment","file":"src/components/ui/amendment.tsx","renders":"One row of the slip at full ink: the date, the entry linking to its listing, the field with before → after or \"Delisted: closed\", and \"By reader report\", \"By phone check\" or \"Left the pages\"."},{"name":"ui/proof-slip","file":"src/components/ui/proof-slip.tsx","renders":"The submitter's entry set one column wide in the weight picked, under the heading it files beneath and a ruled head saying from which page, with its cost in lines of the column from measure()."},{"name":"ui/pagination","file":"src/components/ui/pagination.tsx","renders":"The page head: guide words and folio in a polite live line over the full-ink rule, with the book's ends, ‹ and ›, that disable on the first and last page instead of wrapping."},{"name":"ui/search-input","file":"src/components/ui/search-input.tsx","renders":"The register's search field: a native search input under a persistent label, a clear control that returns focus, and the near-miss cross-reference announced as you type."},{"name":"ui/field","file":"src/components/ui/field.tsx","renders":"A labelled native control on the card, found by its edge; invalid keeps a critical edge, a glyph and a sentence while the ink ring is drawn round it."},{"name":"ui/form","file":"src/components/ui/form.tsx","renders":"The submit form: a two-column fieldset from lg that keeps every value on a rejected submit; its receipt is a ruled, padded slip focused on success."},{"name":"ui/form-error-summary","file":"src/components/ui/form-error-summary.tsx","renders":"The panel a failed submit moves focus to: the critical soft ground under a full critical edge, the count in words and one link per field."},{"name":"ui/filter-chip","file":"src/components/ui/filter-chip.tsx","renders":"An active filter printed as a ruled tag with a 40px remove control; the chips stay on the page when nothing matches."},{"name":"ui/variant-selector","file":"src/components/ui/variant-selector.tsx","renders":"The proof slip's weight picker: line, bold or box as native radios with the price beside each, the chosen row told by dot, ink edge and ground together."},{"name":"ui/popover","file":"src/components/ui/popover.tsx","renders":"The one slip of card stock over the page, hairline all round and no shadow; vendored because the hint composes it."},{"name":"ui/hint","file":"src/components/ui/hint.tsx","renders":"A one-clause line with its reasoning one press away, behind a 24px trigger named for what it opens."},{"name":"ui/toggle-group","file":"src/components/ui/toggle-group.tsx","renders":"A row of ruled segments sharing one ink edge, the chosen one reversed in ink like the thumb tab: the heading band's day filter, and the styleguide's pages-or-roll switch."}],"tokens":{"--background":"#f4f2eb","--foreground":"#1a1711","--card":"#fdfcf9","--card-foreground":"#1a1711","--secondary":"#e5e3dc","--secondary-foreground":"#1a1711","--muted":"#ebe9e2","--muted-foreground":"#5e5a53","--border":"#d2cfc7","--surface-overlay":"#fdfcf9","--rule":"#1a1711","--leader":"#88867f","--primary":"#0000ee","--primary-foreground":"#ffffff","--primary-hover":"#0000c3","--primary-active":"#000099","--accent":"#f8e574","--accent-foreground":"#1a1711","--box-link":"#1a1711","--box-link-hover":"#1a1711","--box-ring":"#1a1711","--box-rule":"#1a1711","--box-muted":"#4b483c","--link":"#1a1711","--link-hover":"#1a1711","--link-visited":"#5e5a53","--turn":"#0000ee","--ring":"#1a1711","--field":"#ffffff","--field-border":"#88867f","--control-border":"#88867f","--selection":"#e2e0d7","--selection-foreground":"#1a1711","--selection-border":"#1a1711","--positive":"#007835","--positive-foreground":"#ffffff","--positive-soft":"#e8f9eb","--positive-border":"#abd8b3","--positive-fill":"#16833f","--warning":"#9a5700","--warning-foreground":"#ffffff","--warning-soft":"#fff1e5","--warning-border":"#ecc19c","--warning-fill":"#a96000","--critical":"#d0003c","--critical-foreground":"#ffffff","--critical-soft":"#ffefef","--critical-border":"#f5b9b9","--critical-fill":"#c24954","--number-slot":"8.5rem","--radius":"0.25rem","--radius-page":"0rem","--radius-tab":"9999px","--icon-stroke":"2","--ease-house":"cubic-bezier(0.2, 0, 0, 1)","--duration-micro":"120ms","--duration-state":"150ms","--text-caption":"0.75rem","--leading-caption":"1.4","--text-small":"0.875rem","--leading-small":"1.45","--text-body":"1rem","--leading-body":"1.55","--text-lead":"1.125rem","--leading-lead":"1.6","--text-d1":"1.5rem","--leading-d1":"1.1","--tracking-d1":"0.01em","--text-d2":"2rem","--leading-d2":"1.05","--tracking-d2":"0.005em","--text-d3":"clamp(2rem, 1.6rem + 1.6vw, 2.666rem)","--leading-d3":"1","--tracking-d3":"0.005em","--text-d4":"clamp(2.5rem, 1.8rem + 2.6vw, 3.553rem)","--leading-d4":"0.95","--tracking-d4":"0","--text-d5":"clamp(3rem, 2rem + 3.8vw, 4.736rem)","--leading-d5":"0.92","--tracking-d5":"0","--text-d6":"clamp(3.553rem, 1.6rem + 5.9vw, 6.313rem)","--leading-d6":"0.9","--tracking-d6":"0","--tracking-label":"0.06em","--tracking-heading":"0.03em","--weight-line":"400","--weight-medium":"500","--weight-bold":"700","--weight-box":"800","--weight-display":"800","--font-display":"var(--font-guideword-display), \"Arial Narrow\", Impact, sans-serif","--font-text":"var(--font-guideword-text), \"Franklin Gothic\", ui-sans-serif, system-ui, sans-serif","--font-sans":"var(--font-text)","--font-figures":"var(--font-guideword-figures), var(--font-guideword-text), ui-sans-serif, system-ui, sans-serif"},"tokensDark":{"--background":"#141310","--foreground":"#ece9e1","--card":"#1d1c18","--card-foreground":"#ece9e1","--secondary":"#2b2a26","--secondary-foreground":"#ece9e1","--muted":"#0f0e0b","--muted-foreground":"#aca9a1","--border":"#373531","--surface-overlay":"#262420","--rule":"#ece9e1","--leader":"#76746f","--primary":"#0000ee","--primary-foreground":"#ffffff","--primary-hover":"#0000c3","--primary-active":"#000099","--accent":"#edd55e","--accent-foreground":"#1a1711","--box-link":"#1a1711","--box-link-hover":"#1a1711","--box-ring":"#1a1711","--box-rule":"#1a1711","--box-muted":"#4b483c","--link":"#ece9e1","--link-hover":"#ece9e1","--link-visited":"#aca9a1","--turn":"#8ba6fd","--ring":"#ece9e1","--field":"#0d0c0a","--field-border":"#76746f","--control-border":"#76746f","--selection":"#302e28","--selection-foreground":"#ece9e1","--selection-border":"#ece9e1","--positive":"#27b058","--positive-foreground":"#141310","--positive-soft":"#112917","--positive-border":"#295233","--positive-fill":"#309b52","--warning":"#e18200","--warning-foreground":"#141310","--warning-soft":"#321d0a","--warning-border":"#623e1c","--warning-fill":"#c77304","--critical":"#f76d77","--critical-foreground":"#141310","--critical-soft":"#36191a","--critical-border":"#683739","--critical-fill":"#de5e68","--number-slot":"8.5rem","--radius":"0.25rem","--radius-page":"0rem","--radius-tab":"9999px","--icon-stroke":"2","--ease-house":"cubic-bezier(0.2, 0, 0, 1)","--duration-micro":"120ms","--duration-state":"150ms","--text-caption":"0.75rem","--leading-caption":"1.4","--text-small":"0.875rem","--leading-small":"1.45","--text-body":"1rem","--leading-body":"1.55","--text-lead":"1.125rem","--leading-lead":"1.6","--text-d1":"1.5rem","--leading-d1":"1.1","--tracking-d1":"0.01em","--text-d2":"2rem","--leading-d2":"1.05","--tracking-d2":"0.005em","--text-d3":"clamp(2rem, 1.6rem + 1.6vw, 2.666rem)","--leading-d3":"1","--tracking-d3":"0.005em","--text-d4":"clamp(2.5rem, 1.8rem + 2.6vw, 3.553rem)","--leading-d4":"0.95","--tracking-d4":"0","--text-d5":"clamp(3rem, 2rem + 3.8vw, 4.736rem)","--leading-d5":"0.92","--tracking-d5":"0","--text-d6":"clamp(3.553rem, 1.6rem + 5.9vw, 6.313rem)","--leading-d6":"0.9","--tracking-d6":"0","--tracking-label":"0.06em","--tracking-heading":"0.03em","--weight-line":"400","--weight-medium":"500","--weight-bold":"700","--weight-box":"800","--weight-display":"800","--font-display":"var(--font-guideword-display), \"Arial Narrow\", Impact, sans-serif","--font-text":"var(--font-guideword-text), \"Franklin Gothic\", ui-sans-serif, system-ui, sans-serif","--font-sans":"var(--font-text)","--font-figures":"var(--font-guideword-figures), var(--font-guideword-text), ui-sans-serif, system-ui, sans-serif"},"compatibility":{"next":">=15 <17","react":">=19 <20","tailwind":">=4 <5"},"dependencies":["lucide-react"],"editions":{"react":{"source":"src","runtime":"react"},"html":{"source":"html/src","output":"html/dist","engine":"nunjucks","runtime":"vanilla","buildRequired":false}},"design":{"typefaces":{"display":"Big Shoulders Display","text":"Libre Franklin","mono":""},"typeRatio":1.333,"signature":"The directory page: every listing surface is set as a numbered printed page, with guide words at its head (the first and last heading, name or match on it) beside the folio, two columns under a full-ink rule, and an A–Z thumb index down the fore-edge with the current letter reversed in a half-round tab. An entry prints in three weights, line, bold and box, and those weights are the paid tiers, each paid one labelled 'Paid listing' in words. typeset() cuts the pages at one canonical geometry and throws at build on a box taller than a column, two boxes in a column, a carried paid entry, a paid entry with no term, or a heading whose set count disagrees with the rows it was given. Implemented in src/components/ui/directory-page.tsx, src/components/ui/entry.tsx, src/components/ui/thumb-index.tsx and src/fixtures/derive.ts (typeset, measure, balance); it recurs on /, /trades/[slug]/[page], /a-z/[letter]/[page], /search, /listing/[slug] (as printed), /amendments and /list-your-business (the proof slip).","heroArchetype":"A5","sanctionedDeviation":"The directory's rules print at full ink: the column rule, the classified-heading rules, the guide-word rule and the box rule are --rule = --foreground (15.96:1 light, 15.31:1 dark), never the soft --border. Entries have no card ground, so the rules are the only structure and the page reads as printed. Scoped to directory-page.tsx, entry.tsx, thumb-index.tsx, proof-slip.tsx and amendment.tsx; fields, buttons and the header keep the soft tier.","motionPersonality":"near-static: a printed page is turned, not animated","undertone":"newsprint and ink, one link blue, one directory yellow","surface_kind":"marketing","built_against":"2026-10-26","recipe":{"primary":"the printed trade directory","secondary":"the early web's link ink"},"brand_pyramid":["findable","honestly paid","kept"],"levers":{"theme":"light","density":"compact","accent_mode":"duotone","motion":"still","borders":"hard","radius":"zero","texture":"none","shadow":"none"},"icons":{"set":"lucide","stroke":2,"ladder":["size-4","size-5","size-6"],"contexts":{"nav":"none","panel_header":"none","fact_row":"none","feature_grid":"none"}},"disclosure":{"helper_line":"one-clause","sentence":"hint","paragraph":"details","parallel_views":"tabs","secondary_object":"route"},"cta":{"header":"quiet","hero":"filled","repeats":["end"],"mobile":"inline"},"colour_budget":{"brand_max_pct":null,"concentration_pct":60,"regions":["action","box"]},"exemplars":[{"name":"a printed city trade directory","slice":"guide words at the page head, classified headings with see also, three paid weights in ruled columns, a thumb index cut into the edge"},{"name":"the first web directories","slice":"underlined unvisited-link blue as the one ink a reader acts on"}],"anti_list":["a centred H1 over a search bar and a 'trusted by' row","a uniform grid of logo cards","'Featured' pills, gradient badges or coloured left-border placement markers","ad cards interleaved with entries, or a pay-to-top paywall","reviews, stars, upvotes, visitor counts or 'N+ listings'","a yellow canvas, the 'Yellow Pages' name or the walking-fingers mark","map tiles, a drawn map or a live 'open now'","AI-tools fiction","infinite scroll as the default"],"strict":["harmony"]}}