Changelog

ca11b2f

Visual category selector on Fonts, plus a grid breakpoint fix

  • The Fonts category filter is now visual: a row of tiles above the cards, each showing a big 'Aa' in a font representative of that style (Playfair Display for Serif, Space Grotesk for Sans, Anton for Display, Space Mono for Mono, Pacifico for Script; All in the UI sans). The selected tile inverts to dark-on-light.
  • The search box moved to the far right and gained a magnifying-glass icon; the old text pills are gone.
  • Fixed a layout gap: between roughly 640 and 784px the grid showed a single narrow card stranded in the middle. It now stays a full-width single card until two cards genuinely fit.
  • The Colors page now opens on the Swatches view by default.
Key files
  • app/components/CategoryTiles.tsx — the Aa specimen tiles (representative fonts in a single TILES constant)
  • app/components/BrowseView.tsx — search moved right + icon, pills replaced by CategoryTiles
  • app/components/ui/Grid.tsx — switch to 22rem columns at min-[49rem] (when two fit), not sm
  • app/components/ColorsView.tsx — default to the Swatches view
305ce07

Pairing cards: paragraph support, always-on fonts, and pivot to a partner

  • Pairing cards now include the paragraph too (in the text font) when you turn paragraph on in the gear — so the visibility setting reaches pairings, not just single fonts.
  • A pairing always shows both of its fonts: the title and subtitle stay visible on pairing cards no matter your hide settings, since hiding one would hide half the pairing. Only the paragraph is optional there.
  • Click the partner font's name in a pairing's footer to open its own pairings in a new tab — so you can branch off to explore it without losing your place. The font you're already viewing isn't a link; on the home and favorites cards both names link.
Key files
  • app/components/PairingCard.tsx — paragraph passthrough, pairing flag, partner-name links (new tab)
  • app/components/SpecimenCard.tsx — `pairing` forces title+subtitle visible; only paragraph follows visibility
  • app/components/PairingsView.tsx — passes the source font so only the partner links
  • app/components/SuggestedPairings.tsx + FavoritesView.tsx — paragraph override threaded through
990bc89

Show/hide title, subtitle, and paragraph on cards from the gear

  • The voice editor (the gear) now has an eyeball next to each element — title, subtitle, paragraph — to show or hide it on every card across the app.
  • Cards now show just the title and subtitle by default; the longer paragraph is hidden until you turn it on (a cleaner, more compact default).
  • At least one element always stays visible — the last one's eyeball is disabled so a card can never be blank.
  • Your choice is remembered across visits.
Key files
  • app/components/VoiceProvider.tsx — global, persisted visibility state + constrained toggle
  • app/components/TypographicVoiceModal.tsx — per-element eyeball toggles in the gear
  • app/components/SpecimenCard.tsx — every card honors the visibility preference
  • lib/types.ts — VoiceVisibility
c01964d

Discover fonts by feeling — clickable tag pills on every card

  • Every font card now shows its Google 'feeling' tags (Cute, Playful, Futuristic, Sophisticated…) as small pills beneath the name.
  • Click a feeling to focus the Fonts grid on fonts that share it, strongest match first — browse by mood instead of by name.
  • The focused view is a shareable URL (e.g. /?tag=cute) with an active-feeling chip you can clear; browser back/forward and direct links work.
  • These tags come from Google Fonts' own semantic data, now refreshed into the catalog — 99% of families are tagged.
Key files
  • scripts/build-catalog.mjs — fetches FAMILY_TAGS, writes per-font feelings into data/fonts.json
  • lib/feelings.ts — the 20 /Expressive moods + slug/label helpers
  • app/api/fonts/route.ts — ?tag filter, sorted by feeling strength
  • app/components/BrowseView.tsx — URL-driven feeling filter + active-feeling chip
  • app/components/FontSpecimenCard.tsx — feeling pills on each card
  • app/page.tsx — Suspense boundary so the URL filter keeps the route static
f7e9ee7

Customizable page-chrome colors, and the card-theme toggle in the gear

  • You can now recolor the whole app's chrome — the shell behind the cards, the nav and footer, and the active-control highlight. The Colors page has a swatch editor under Page chrome with a color picker per role and a Restore defaults button; changes apply site-wide instantly and persist.
  • The Randomize / Use selected theme switch is now also in the gear menu (it has an app-wide effect, so it's reachable from anywhere). The gear and the Colors page share one setting and stay in sync; pick which theme on the Colors page.
  • Page-chrome colors now flow through CSS variables, so a single edit repaints the entire shell at once. Defaults are unchanged — nothing looks different until you customize.
Key files
  • lib/card-themes.ts — PAGE_THEME/HIGHLIGHT now reference --page-* CSS vars; literals kept as *_DEFAULT + PAGE_CHROME_DEFAULTS for the editor
  • app/globals.css — --page-bg/-fg/-muted/-accent/-highlight defaults; body grounds on --page-bg
  • app/components/CardThemeProvider.tsx — per-role page-chrome overrides written to the document root and persisted
  • app/components/ColorsView.tsx — PageChromeEditor (color picker per role + Restore defaults)
  • app/components/TypographicVoiceModal.tsx — Card color (Randomize / Use selected theme) section in the gear
3890452

Colors page: preview, swatch view, and a pick-a-theme-for-everything setting

  • Added a Colors page (in the nav) that shows every card color theme. It opens as a split panel like the pairings page: a sample font card on the left, the themes on the right — click a theme and it paints onto the sample.
  • A Preview / Swatches toggle flips the theme cards between full sample cards and tight square-swatch strips for scanning the palette at a glance.
  • You can now pick one theme and apply it to every card across the whole app. A Randomize / Use selected theme toggle under the sample card decides whether cards cycle through all themes (the default) or all use your chosen one.
  • Your chosen theme now persists — it survives a refresh and is remembered across the app, instead of resetting each visit.
  • The page also shows the fixed page-chrome colors (the shell behind the grid and the active-control highlight).
Key files
  • app/colors/page.tsx — the /colors route
  • app/components/ColorsView.tsx — split-panel preview, Preview/Swatches toggle, Randomize/Use-selected toggle
  • app/components/CardThemeProvider.tsx — global card-color preference (selected theme + apply mode), persisted to localStorage
  • app/components/SpecimenCard.tsx — every card reads the preference: one selected theme app-wide, or cycle as before
  • app/components/GlobalNav.tsx — Colors nav item
  • app/layout.tsx — wraps the app in CardThemeProvider
477476d

Split-panel pairings page and scroll memory on the way back

  • Redesigned the per-font pairings page: the font you picked now sits on its own to the left as a full specimen, with its partners laid out in their own grid to the right — so the pairing relationship reads at a glance.
  • The selected font stays put (sticky) as you scroll its partners, keeping the comparison anchored.
  • Gave the pairings page room to breathe — it now spreads to the full width of the window so more partners show at once, instead of the four-across measure the rest of the app uses.
  • Returning from a pairings page now drops you right back where you were on the Fonts grid — your search, category, how many fonts you'd loaded, and your scroll position are all remembered, instead of resetting to the top.
Key files
  • app/components/PairingsView.tsx — two-column split layout, sticky source card, scroll-to-top on open
  • app/pairings/[slug]/page.tsx — full-bleed page, back-caret gutter guard, scroll={false} on the back link
  • app/components/BrowseView.tsx — per-tab snapshot restores filters, loaded count, and scroll on return
  • app/components/FontSpecimenCard.tsx — Get Pairings link opts out of scroll-to-top so the browse position survives
5ea4f53

Bookmarkable pairings, a Fonts-first nav, and backlog status

  • Opening a font's pairings now changes the URL instead of a pop-up, so any pairing can be bookmarked and shared — every font has its own /pairings/{font} page.
  • Renamed and reordered the nav: the font browser is now the home page under "Fonts", the old home page of suggested pairings moved under "Pairings", and Favorites is unchanged.
  • Cleaned up the pairings page — one "Pairings for {Font}" heading lined up with the cards, all pairings shown as a single set, and a round back button tucked into the left margin opposite the voice gear.
  • Gave the backlog an open/closed view: two pills toggle between active ideas and shipped ones, with closed items set apart in blue.
  • Marked "Bookmarkable pairing routes" as shipped — the first closed backlog item.
Key files
  • app/pairings/[slug]/page.tsx — per-font pairings page (SSG, one per font)
  • app/pairings/page.tsx — the suggested-pairings showcase (was the home page)
  • app/page.tsx — root is now the Fonts browser; /explorer redirects here
  • app/components/PairingsView.tsx — shared pairings grid (replaced the modal)
  • lib/slug.ts — font-name <-> URL-slug, the single source of truth
  • app/backlog/BacklogList.tsx — Open/Closed pills and the closed (blue) card theme
52e9f0e

Unified page header, neutral palette, and a footer

  • Unified every view's header into one element — the title sits in the same place and style on Home, Explorer, Favorites, and Changelog; the eyebrow and descriptive sub-text were dropped for a cleaner read.
  • Folded the Explorer search and category filters into that shared header, and removed the sort options — results default to most popular.
  • Made page headers line up with the cards at every width, and the changelog header line up with its narrower card column.
  • Repainted the whole site in a neutral near-black, with the nav blending into the page.
  • Settled on a single amber highlight for active controls (filter pills, the voice gear), keeping the red as a small accent.
  • Added a global footer with the license and a GitHub link — it sits below the content, or at the bottom of short pages.
  • Gave the light voice pop-up bold labels and trimmed its heading.
Key files
  • app/components/ui/PageHeader.tsx — the one shared page header
  • app/components/ui/GridAlign.tsx — pins headers to the centered card block
  • app/components/Footer.tsx + app/layout.tsx — the global footer and sticky-footer layout
  • app/components/BrowseView.tsx — Explorer in the unified layout (filters in header, no sort)
  • lib/card-themes.ts — neutral PAGE_THEME background + the HIGHLIGHT accent
  • app/components/TypographicVoiceModal.tsx — bold light-mode labels
6a66e3e

Global typographic voice, unified cards, and this changelog

  • Made the typographic voice global: one editor pop-up, opened from a gear at the right of the nav, now drives Explorer specimens, Home and favorite pairings alike — replacing the two separate editors that had drifted apart.
  • Reworked that editor into a light-mode pop-up with stacked, auto-growing fields, reachable from any page and any scroll depth.
  • Unified every card surface (Explorer, Home, pairings, favorites) onto one card component and one grid — a single fluid column on small screens, then fixed-width cards instead of stretching.
  • Added this changelog at /changelog — a card per dated entry — plus the /changes command and README notes for keeping it current.
Key files
  • app/components/VoiceProvider.tsx — global voice state + the single editor pop-up
  • app/components/SpecimenCard.tsx — the shared card; FontSpecimenCard / PairingCard wrap it
  • app/components/ChangelogCard.tsx + app/changelog/page.tsx — the changelog surface
  • app/globals.css — the theme-light inverted-surface convention