diff --git a/docs/static/v2_elite.css b/docs/static/v2_elite.css index df0dce7b..956d71a4 100644 --- a/docs/static/v2_elite.css +++ b/docs/static/v2_elite.css @@ -1804,3 +1804,108 @@ input[type="text"] { + +/* =================================================================== + The Awesome Lists page: high-impact hero + category card grid. + Used by other-awesome-lists.md (header injected by src/awesome_page.py). + =================================================================== */ +.awesome-hero { + margin: 1.2rem 0 1.6rem; + padding: 2.2rem 1.5rem; + border-radius: 16px; + text-align: center; + color: #fff; + background: + radial-gradient(120% 140% at 50% 0%, + color-mix(in srgb, var(--md-accent-fg-color) 70%, #6d28d9) 0%, + color-mix(in srgb, var(--md-primary-fg-color) 80%, #111827) 75%); + box-shadow: 0 10px 34px -12px color-mix(in srgb, var(--md-accent-fg-color) 60%, transparent); + overflow: hidden; +} +.awesome-hero__badge { + font-size: clamp(1.4rem, 3.2vw, 2.2rem); + font-weight: 800; + letter-spacing: 0.06em; + line-height: 1.15; + text-shadow: 0 2px 12px rgba(0, 0, 0, 0.28); +} +.awesome-hero__sub { + margin-top: 0.5rem; + font-size: 0.95rem; + opacity: 0.92; +} +.awesome-hero__sub code { + background: rgba(255, 255, 255, 0.18); + color: #fff; + padding: 0.05em 0.35em; + border-radius: 5px; +} +.awesome-hero__stats { + margin-top: 1.3rem; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.7rem 1.4rem; +} +.awesome-hero__stat { + display: flex; + flex-direction: column; + align-items: center; + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.08em; + opacity: 0.9; +} +.awesome-hero__stat strong { + font-size: 1.55rem; + line-height: 1; + font-weight: 800; +} + +.awesome-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); + gap: 0.85rem; + margin: 1.4rem 0 2rem; +} +.awesome-card { + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 0.6rem; + min-height: 84px; + padding: 0.85rem 1rem; + border-radius: 12px; + border: 1px solid color-mix(in srgb, var(--md-accent-fg-color) 24%, transparent); + background: var(--md-default-bg-color); + color: var(--md-default-fg-color); + text-decoration: none; + transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease; +} +.awesome-card:hover { + transform: translateY(-3px); + border-color: var(--md-accent-fg-color); + box-shadow: 0 12px 26px -14px color-mix(in srgb, var(--md-accent-fg-color) 70%, transparent); +} +.awesome-card__name { + font-weight: 700; + font-size: 0.95rem; + line-height: 1.25; +} +.awesome-card__meta { + display: flex; + align-items: baseline; + gap: 0.4rem; +} +.awesome-card__count { + font-size: 1.35rem; + font-weight: 800; + color: var(--md-accent-fg-color); + line-height: 1; +} +.awesome-card__stars { + font-size: 0.7rem; + text-transform: uppercase; + letter-spacing: 0.06em; + opacity: 0.7; +} diff --git a/src/awesome_page.py b/src/awesome_page.py new file mode 100644 index 00000000..5cd043e4 --- /dev/null +++ b/src/awesome_page.py @@ -0,0 +1,74 @@ +"""High-impact header for the V2 "Awesome Lists" page. + +The Awesome Lists page (``other-awesome-lists.md``, derived from V1's +``/v1/other-awesome-lists/``) is a curated, AI-classified directory of the best +external ``awesome-*`` lists across the Cloud Native ecosystem. This module +builds the flagship hero banner + a category grid (cards that jump to each +in-page section), generated from the page's own rendered ``##`` headings so it +stays in sync no matter how the AI re-clusters the categories. + +Pure stdlib so it can run inside ``src.v2_optimizer`` and be tested standalone. +""" + +import re + +_H2_RE = re.compile(r"^##\s+(.+?)\s*$", re.MULTILINE) +_LINK_RE = re.compile(r"\]\(https?://") + + +def _slug(text: str) -> str: + """Slug matching python-markdown/toc anchors (lowercase, no punctuation).""" + s = text.lower().replace("&", " ") + s = re.sub(r"[()]", "", s) + s = re.sub(r"[^a-z0-9]+", "-", s).strip("-") + return s + + +def _sections(body_md: str): + """Return [(title, anchor, link_count), ...] for each H2 section in order.""" + matches = list(_H2_RE.finditer(body_md)) + out = [] + for i, m in enumerate(matches): + title = m.group(1).strip() + start = m.end() + end = matches[i + 1].start() if i + 1 < len(matches) else len(body_md) + count = len(_LINK_RE.findall(body_md[start:end])) + out.append((title, _slug(title), count)) + return out + + +def build_awesome_lists_header(body_md: str) -> str: + """Build the hero + category grid that precedes the Awesome Lists body.""" + sections = _sections(body_md) + total_lists = sum(c for _, _, c in sections) + n_cats = len(sections) + + md = ( + "
awesome-* lists · AI-classified · link-validatedawesome-* lists · AI-classified · link-validated