On category pages desc-rows are always visible. On the index page they
were always hidden. Now they become visible whenever a tag/category
filter is applied, giving filtered results the same richness as category
pages.
Also tightens two related CSS rules: border-bottom suppression only
fires when the adjacent desc-row is actually visible, and the expand-row
description is hidden while the desc-row is already showing to avoid
duplicate text.
Co-Authored-By: Claude <noreply@anthropic.com>
- Extract render_category() helper to deduplicate the three category/group/builtin
rendering blocks in build.py
- Replace synthetic dict literals with synthetic_category() helper
- Rewrite subcategory rendering to avoid O(n²) loop using precomputed dicts
- Pass filter_urls (not just JSON) to templates so Jinja can look up group URLs
directly instead of applying the slugify filter at render time
- Remove slugify from env.filters (no longer used in templates)
- Replace isIndexPage() wrapper with isIndexDocument constant in main.js
- Fix: call applyFilters() on page load when activeFilter is set
- Remove dead else branch in tag click handler (category pages with no URL)
- Switch .hero-category-links from CSS columns to CSS grid for more even layout
- Remove max-width cap on .category-subtitle
Co-Authored-By: Claude <noreply@anthropic.com>
Adds a dedicated sponsorship page at /sponsorship/ built from the Jinja2
template, with hero stats, tier cards, and CSS. Updates the index.html
sponsor sidebar link to point to /sponsorship/ instead of the GitHub
SPONSORSHIP.md. Adds the URL to the sitemap and test fixtures.
Also renames .impeccable.md to DESIGN.md.
Co-Authored-By: Claude <noreply@anthropic.com>
Add search input, filter chips, no-results block, and back-to-top
button to category/group/subcategory pages. Pass filter_urls_json to
all page types so tag-chip navigation works site-wide. Fix JS so
filter-clear and no-results-clear redirect to / on non-index pages
instead of trying to filter a non-existent local table. Remove the
now-redundant .category-results CSS overrides.
Co-Authored-By: Claude <noreply@anthropic.com>
Removes inline .category-row-desc from the name cell and renders
entry.description inside .expand-content instead, matching the
index page pattern. Drops the now-unused CSS rules for
.category-row-desc and the overridden .category-table .expand-content
padding.
Co-Authored-By: Claude <noreply@anthropic.com>
The results-intro grid (1fr + 28rem note column) squeezed the heading on
category pages with long names, e.g. "Python Projects in Environment
Management" wrapped onto two lines.
Scope a single-column override to .category-results so the heading takes
the full row and the note drops below right-aligned. Index page layout
is untouched since its heading is short.
The "All projects" link in the category-page topbar pointed to
/#library-index so the browser would scroll to the library section on
arrival. The hash stayed in the URL, which looked like an internal anchor
state rather than a clean homepage URL.
On homepage load, if the hash is #library-index, scroll to the section
explicitly and use history.replaceState to drop the hash from the URL.
The scrollIntoView call covers the case where the script runs before the
browser's native anchor scroll, since replaceState removes the hash the
browser would have used.
Tag clicks on / pushState a category/group/subcategory path; on static
pages they fully navigate. Search and sort stay in querystring. Built-in
source tag has no data-url and stays as an in-page filter. The
isIndexDocument flag is captured at load time so toggling on the index
keeps working after pushState changes location.pathname.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the .category-subtitle a underline style for visual cohesion in
the hero, and locks in the gating behavior with a negative assertion so
a regression that drops the page_kind guard would be caught.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Swaps --line-strong for --accent-underline on the 'Become a sponsor'
text-decoration-color so the underline matches the tan hover underline
on project-name links like thealgorithms.
Co-Authored-By: Claude <noreply@anthropic.com>
Swap the border-bottom + padding-bottom fake underline on .sponsor-become
for a native text-decoration underline with text-underline-offset so the
line hugs the text at the same distance as the hero @vinta/@JinyangWang27
links, rather than sitting a fixed 0.2rem gap away.
Co-Authored-By: Claude <noreply@anthropic.com>
Override font-size to var(--text-lg) inside .sponsor-meta so the
Sponsors heading is larger, while the shared .section-label class
remains --text-sm everywhere else.
Co-Authored-By: Claude <noreply@anthropic.com>
Parse the # Sponsors heading in README.md into structured data and
render a dedicated sponsor band above the library index on the site.
Co-Authored-By: Claude <noreply@anthropic.com>
The flex properties (align-items, flex-direction, flex-wrap, justify-content)
were overriding the default layout unnecessarily on mobile.
Co-Authored-By: Claude <noreply@anthropic.com>
- Hoist reducedMotion and sortHeaders to module scope to avoid repeated
DOM queries on every call
- collapseAll now queries within tbody instead of the full document
- Replace indexOf with includes for tag filtering
- Remove null check on activeSort (always initialized)
- Drop inline section comments that just restate the code
Co-Authored-By: Claude <noreply@anthropic.com>
Only the canonical 'filter' query param is supported. The 'category'
and 'group' aliases were never documented and silently accepted wrong
spellings; removing them prevents hidden coupling to old URL shapes.
Co-Authored-By: Claude <noreply@anthropic.com>
Replace the { type, value } filter object with a plain string value.
Merge data-cats and data-groups row attributes into a single data-tags
attribute. Drop data-type from tag buttons. Consolidate category/group
URL params into a single filter param, keeping backward-compat fallback.
Co-Authored-By: Claude <noreply@anthropic.com>
The same matchMedia query was inlined twice (hero scroll and back-to-top).
Extracted into a shared helper. Also renamed loop variable and reformatted
a chained querySelector call for readability. No behavior change.
Co-Authored-By: Claude <noreply@anthropic.com>
Was in a standalone @media (max-width: 960px) block; now lives inside
the existing mobile breakpoint block alongside sibling expand-row rules.
No visual change.
Co-Authored-By: Claude <noreply@anthropic.com>
Gives the focus ring a bit more breathing room so it doesn't
overlap the button text at the new border-radius.
Co-Authored-By: Claude <noreply@anthropic.com>
Add a data-scroll-to attribute to the hero 'Browse the List' anchor
and a JS handler that calls scrollIntoView instead of letting the
browser follow the href, so the URL hash is never written.
Respects prefers-reduced-motion.
Co-Authored-By: Claude <noreply@anthropic.com>
Footer text was too small to read comfortably. Bumping to --text-sm
improves legibility without breaking the footer layout.
Co-Authored-By: Claude <noreply@anthropic.com>
Moves overflow-x: clip from the 680px breakpoint into the 960px
breakpoint, removing the duplicate rule. The value was applied twice
across two consecutive breakpoints with no override in between.
Co-Authored-By: Claude <noreply@anthropic.com>
Replaces the width/padding/overflow hack with a clean display:none.
The previous approach collapsed the cells to zero size but kept them
in the layout flow; display:none removes them entirely.
Co-Authored-By: Claude <noreply@anthropic.com>
Add an expand-commit span inside the expand row that displays the last
commit date. Hidden on desktop, visible only on mobile (max-width: 960px)
via media query, mirroring the commit column that appears in the full
table. Relative time formatting is applied via JS on page load.
Co-Authored-By: Claude <noreply@anthropic.com>
Expand the .tag::after pseudo-element inset and add explicit min-height/
min-width of 44px so the interactive hit area satisfies WCAG 2.5.5. Also
nudge mobile tag padding and font-size slightly for visual consistency.
Co-Authored-By: Claude <noreply@anthropic.com>
Appends a small northeast arrow (↗) after target="_blank" anchors
in hero subtitle, expand description, expand also-see, and footer
sections to signal outbound navigation to keyboard and sighted users.
Co-Authored-By: Claude <noreply@anthropic.com>
Move cursor/hover/user-select styles from .sort-btn to th[data-sort]
so the entire column header cell is the interactive target, not just
the button text node.
Co-Authored-By: Claude <noreply@anthropic.com>
col-cat and expand-row cells need different treatment on mobile:
- col-cat uses display:none (whole column hidden)
- expand-row first/last cells collapse via width/padding/overflow
rather than display:none to avoid breaking table layout
Co-Authored-By: Claude <noreply@anthropic.com>
Table sort triggers were bare th elements, which are not keyboard
focusable or announced as interactive by screen readers. Replace with
button elements inside th so keyboard users can activate sorting and
get proper focus-visible ring.
Co-Authored-By: Claude <noreply@anthropic.com>
Swap the hardcoded 'smooth' scroll behavior for a runtime check so users
who have enabled reduced-motion in their OS get instant (auto) scrolling
instead of the animated kind.
Co-Authored-By: Claude <noreply@anthropic.com>