From 4818b99562e663de4537fb0dae4b2ff6570e048e Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Mon, 19 Oct 2026 13:25:31 +0800 Subject: [PATCH] docs: trim DESIGN.md to match the code and drop duplicated rules DESIGN.md made claims the code contradicts (project count, radius usage, a blanket !important ban, sponsor band placement), said "the user" for the maintainer, duplicated token values from style.css that can drift, and repeated rules across several sections. Co-Authored-By: Claude --- DESIGN.md | 88 ++++++++++++++++++------------------------------------- 1 file changed, 28 insertions(+), 60 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index a4c0946c..69b99542 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -6,9 +6,9 @@ description: Warm editorial Python index. Light cream canvas, brown-red interact # awesome-python.com DESIGN.md -awesome-python.com is a searchable, filterable index of ~500 curated Python projects. It is a reference tool, not a landing page and not a GitHub README mirror. +awesome-python.com is a searchable, filterable index of curated Python projects. It is a reference tool, not a landing page and not a GitHub README mirror. -This file follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/overview/). The source of truth for token values lives in `website/static/style.css`. Color tokens here are written in OKLCH because the project mandates OKLCH over hex, which is a deliberate divergence from the spec's hex-only token requirement. +This file follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/overview). Token values live in `website/static/style.css`; this file names each token's role. Colors are OKLCH, a deliberate divergence from the spec's hex-only token requirement. ## Overview @@ -58,29 +58,27 @@ Design principles: Warm editorial palette. Light theme only (`color-scheme: light`). OKLCH only. -Each token below shows the OKLCH value (canonical, lives in `style.css`) followed by an approximate hex sRGB equivalent for spec linters and any tool that expects hex. - Surfaces: -- `--bg-page` `oklch(96.8% 0.018 80)` ≈ `#FBF3E7`. Cream/ivory canvas, the body floor. The body uses a vertical gradient between `--bg-page-top` `oklch(95.2% 0.018 78)` ≈ `#F7EFE3`, `--bg-page` at 24rem, and `--bg-page-end` `oklch(98.4% 0.01 80)` ≈ `#FCF8F0`, with a soft radial highlight in the top-left corner. -- `--bg-paper` `oklch(98.6% 0.01 80)` ≈ `#FEFAF3`. Warm white for the content shell. -- `--bg-paper-strong` `oklch(95.7% 0.016 76)` ≈ `#F7F0E5`. Tinted paper for sponsor band, CTA backgrounds, static decoration. -- `--hero-bg-start` `oklch(14% 0.03 32)` ≈ `#130503` through `--hero-bg-mid` `oklch(19% 0.035 35)` ≈ `#22120B` to `--hero-bg-end` `oklch(28% 0.05 42)` ≈ `#3D2014`. Dark earthy hero gradient. -- `--footer-bg` `oklch(16% 0.025 35)` ≈ `#170906`. Dark warm charcoal footer, part of the same system. +- `--bg-page`. Cream/ivory canvas, the body floor. The body uses a vertical gradient from `--bg-page-top` through `--bg-page` (at 24rem) to `--bg-page-end`, with a soft radial highlight in the top-left corner. +- `--bg-paper`. Warm white for the content shell. +- `--bg-paper-strong`. Tinted paper for sponsor band, CTA backgrounds, static decoration. +- `--hero-bg-start` → `--hero-bg-mid` → `--hero-bg-end`. Dark earthy hero gradient. +- `--footer-bg`. Dark warm charcoal footer, part of the same system. Ink: -- `--ink` `oklch(22% 0.02 55)` ≈ `#221812`. Body text. -- `--ink-soft` `oklch(38% 0.018 55)` ≈ `#4A4039`. Secondary copy. -- `--ink-muted` `oklch(52% 0.02 55)` ≈ `#72665E`. Meta rows, captions, static labels. +- `--ink`. Body text. +- `--ink-soft`. Secondary copy. +- `--ink-muted`. Meta rows, captions, static labels. - `--line` / `--line-strong`. Hairlines and dividers. Accent (warm brown-red, reserved for interactive): -- `--accent` `oklch(58% 0.16 45)` ≈ `#C4530F`. Primary accent. -- `--accent-deep` `oklch(44% 0.15 42)` ≈ `#922900`. Link text, hover. -- `--accent-soft` `oklch(92% 0.045 55)` ≈ `#FDDDC9`. Tinted background for filter tags. -- `--accent-underline` `oklch(58% 0.16 45 / 0.4)` ≈ `#C4530F66`. Subtle text-decoration-color. +- `--accent`. Primary accent. +- `--accent-deep`. Link text, hover. +- `--accent-soft`. Tinted background for filter tags. +- `--accent-underline`. Subtle text-decoration-color. Rules: @@ -91,7 +89,7 @@ Rules: Aversions: -- **No green.** The user rejected it when picking the palette. Warm brown-red, ivory, and dark earthy tones are the established system. Do not introduce green even for success states or ancillary accents. +- **No green.** The maintainer rejected it when picking the palette. Warm brown-red, ivory, and dark earthy tones are the established system. Do not introduce green even for success states or ancillary accents. - No cyan, no neon gradients, no pure grays, no cool blues. ## Typography @@ -107,15 +105,15 @@ Scale: | ---------------- | ----------------- | ----------------------------- | ------------------ | --------- | ---------------------------------------------- | | Hero headline | (literal `clamp`) | `clamp(4.5rem, 11vw, 8.5rem)` | Cormorant Garamond | 600 | Magazine-cover scale, single use on the hero | | Body large | `--text-lg` | `1.125rem` | Manrope | 400 | Content-heavy passages | -| Body | `--text-base` | `1rem` (16px) | Manrope | 400 | Body floor, do not go smaller | +| Body | `--text-base` | `1rem` (16px) | Manrope | 400 | Body floor | | Meta / secondary | `--text-sm` | `0.95rem` | Manrope | 400 / 600 | Meta rows, secondary copy | | Caption / pill | `--text-xs` | `0.8rem` (12.8px) | Manrope | 600 / 700 | Smallest token, pills, badges, tags, footnotes | Hard-won sizing rules (do not relax): - **Body type floor is 16px.** Do not go smaller. -- **Absolute minimum font size is 12px (`0.75rem`) for ANY text**, including pills, badges, tags, captions, footnotes. Anything smaller hits Chrome's default minimum-font-size floor and renders inconsistently across browsers and user accessibility settings. Use `var(--text-xs)` (`0.8rem`) as the smallest token in code. -- **When in doubt, pick one step larger** than what generic scale references suggest (`--text-base` over `--text-sm`, 1.75rem over 1.5rem for a heading). The user has corrected sizes upward 11+ times across 8 sessions. Footer, meta rows, expand content, labels, and headings all trend too small by default. **Never reduce an existing size unprompted.** +- **Absolute minimum font size is 12px (`0.75rem`) for ANY text**, including pills, badges, tags, captions, footnotes. Anything smaller hits Chrome's default minimum-font-size floor and renders inconsistently across browsers and user accessibility settings. +- **When in doubt, pick one step larger** than what generic scale references suggest (`--text-base` over `--text-sm`, 1.75rem over 1.5rem for a heading). The maintainer has corrected sizes upward 11+ times across 8 sessions. Footer, meta rows, expand content, labels, and headings all trend too small by default. **Never reduce an existing size unprompted.** - Adjacent heading levels differ by at least 0.25rem of rendered size. - Row numbers in the table: left-align, no leading zeros. Zero-padding was tried and rejected. - **Never `text-transform`.** Write the casing in the markup. @@ -123,8 +121,7 @@ Hard-won sizing rules (do not relax): ## Layout - **Single width cap: `--shell-max: 84rem` (~1344px) applied via `.section-shell`.** This is the ONLY width cap in the project. Widescreen monitors are the default viewing context. -- **Do NOT add `max-width`** to sections, cards, table cells, table rows, expanded rows, CTA backgrounds, sponsor descriptions, hero subcopy, paragraphs, or list items. The user has removed narrow inner caps repeatedly (`56ch`, `65-75ch`, etc.). Default is no inner cap; remove any inner cap you come across. -- The "cap line length at ~65-75ch" rule does NOT apply here. Ignore it. Readability at wide widths is carried by vertical rhythm, leading, and the modular type scale instead. +- **Do NOT add `max-width`** to sections, cards, table cells, table rows, expanded rows, CTA backgrounds, sponsor descriptions, hero subcopy, paragraphs, or list items. The maintainer has removed narrow inner caps repeatedly (`56ch`, `65-75ch`, etc.). Default is no inner cap; remove any inner cap you come across. The "cap line length at ~65-75ch" rule does NOT apply here: readability at wide widths is carried by vertical rhythm, leading, and the modular type scale instead. - If a width cap is genuinely necessary for a specific element, ask first with a concrete reason before adding it. - Shell padding: `--shell-pad: clamp(1.25rem, 3vw, 2.5rem)`. Symmetric gutters: logo left-gap equals logo right-gap, column paddings match across header and body. - `gap` over child margins in flex and grid. @@ -133,7 +130,7 @@ Hard-won sizing rules (do not relax): - CSS custom properties for all colors and repeated values. - Sibling components (card lists, grid items) share identical spacing. - Use flexbox or grid for layout. Avoid floats and absolute positioning except for genuine overlay cases (focus rings, sticky headers). -- Never `!important`. Fix specificity instead. +- Never `!important`, except in the `prefers-reduced-motion` reset. Fix specificity instead. ## Elevation & Depth @@ -151,7 +148,7 @@ Depth comes from **tonal layers**, not heavy shadows. The shape language is overwhelmingly **pill on small, zero radius on large**. - **Pills** (`border-radius: 999px`) for tags, search, sponsor logo chip, source badges, back-to-top, and primary CTA buttons. -- **`0.4rem`** is used in exactly one place: inline `` inside `.sponsorship-body`. Do not introduce a tokenized radius scale. The project does not need one. +- **`0.4rem`** is used only on inline `` in category intros, the guide band, and `.sponsorship-body`. Do not introduce a tokenized radius scale. The project does not need one. - Containers use the page surface itself, not rounded panels. When a panel is needed, prefer pill on small chips and zero radius on large surfaces. - **No `border-left` or `border-right` greater than 1px as a colored accent stripe** on cards, list items, callouts, or alerts. Use a different structure. @@ -165,45 +162,22 @@ The component vocabulary is small and table-led. Source of truth: `website/stati - **Hero**. Magazine-cover headline, dark earthy ground, kicker and proof microcopy, primary CTA button using `--hero-btn-start` / `--hero-btn-end`. Subtle grid plus slow sheen. Respects `prefers-reduced-motion`. - **Jump links**. One per use case in a category hero, plus one for the guide. Underlined like the intro's links, with a trailing ↓. Never tag-styled: tags filter the table or open another page, jump links only scroll. - **Guide band**. Everything in a category intro after its "How to choose" list. It sits below the table on the hero's dark gradient, with its H2 above the text. -- **Sponsor band**. Sits in the README header on `--bg-paper-strong`. Editorial layout, not a logo wall. Sponsor links share the global accent treatment. +- **Sponsor band**. Sits below the hero on the home page, on `--bg-paper-strong`. Editorial layout, not a logo wall. Sponsor links share the global accent treatment. - **CTA**. Warm `--cta-bg`, full-bleed within shell. The button itself uses accent tokens. - **Footer**. Dark warm charcoal, part of the same system. Footer links share the global hover and focus treatment. - **Search**. Pill input with `--search-inset` interior and `--search-focus-ring` focus ring. Focus shadow uses `--search-focus-shadow`. -- **Source badge / inline code**. Static decoration on `--bg-paper-strong`. `.source-badge` uses `--ink-soft` text in pill shape; `.sponsorship-body code` uses `--ink` text with the lone `0.4rem` radius. Never the accent. - -Peer-consistency check (run before shipping any visual change): - -- Hover and focus states: if one link type gets a treatment, peer links (hero topbar, footer, project names, sponsor names, expand-meta) share it. -- Tag variants inherit the base `.tag` style. Differ only where a real difference is needed. -- Typography tiers: labels that play the same role share size, weight, and letter-spacing. -- Symmetric gutters: logo left-gap equals logo right-gap, column paddings match across header and body. -- Role-based color tokens: same role uses the same token everywhere. +- **Source badge / inline code**. Static decoration on `--bg-paper-strong`. `.source-badge` uses `--ink-soft` text in pill shape; `.sponsorship-body code` uses `--ink` text with the `0.4rem` radius. Never the accent. ## Do's and Don'ts -- **Do** keep the table the focal point. Hero, sponsor band, and CTA must not compete. -- **Do** use accent tokens only on interactive elements. -- **Do** prefer density over whitespace expansion. -- **Do** check peer elements before shipping a visual change. -- **Do** use OKLCH for every new color. - **Don't** replace the table with a card grid, modal details, or pagination. -- **Don't** add inner `max-width` to anything. The shell handles width. -- **Don't** introduce green, cyan, neon, pure gray, or cool blue. -- **Don't** add a dark mode, theme picker, or alternate palette. - **Don't** use gradient text (`background-clip: text` on gradients). Solid color only. -- **Don't** use `!important`. Fix specificity instead. -- **Don't** use `text-transform`. Write the casing in markup. -- **Don't** use a `border-left` or `border-right` greater than 1px as an accent stripe. -- **Don't** use bounce or elastic easing. -- **Don't** use glassmorphism as default decoration. -- **Don't** mimic generic dark developer-tool sites, other awesome-\* sites, or SaaS marketing pages. ## Narrow-Screen Behavior -The user actively tests `< 960px` and `< 680px`. Narrow screens must stay functional. +The maintainer actively tests `< 960px` and `< 680px`. Narrow screens must stay functional. -- Do not drop features the user might want (sort affordance, filter chips, sticky header where reasonable). Hiding is a last resort and requires justification. -- Always run the `playwright-cli` skill at a narrow viewport after any layout change. +- Do not drop features readers might want (sort affordance, filter chips, sticky header where reasonable). Hiding is a last resort and requires justification. ## Iteration Guide @@ -211,17 +185,11 @@ Run this audit after generating or modifying a screen. Failure on any item means 1. **Width caps.** Inspect every section, card, paragraph, table cell, expanded row, CTA, sponsor description, hero subcopy. Only `.section-shell` (`--shell-max: 84rem`) may cap width. Anything else with a `max-width` is wrong. 2. **Accent reservation.** Grep the changed CSS for `--accent`, `--accent-deep`, `--accent-soft`. Each match must back an interactive element (link, button, focus ring, filter tag). Static decoration must use ink tokens (`--ink`, `--ink-soft`, `--ink-muted`) on `--bg-paper-strong` or `--bg-paper`. -3. **Shape language.** Containers are square or pill. Anything in the 4px-to-16px radius range is suspect. The lone `0.4rem` on `.sponsorship-body code` is the only allowed exception. +3. **Shape language.** Containers are square or pill. Anything in the 4px-to-16px radius range is suspect. The `0.4rem` on inline code is the only allowed exception. 4. **Type sizes.** Confirm no rendered text falls below 12px. If a size feels small to a mid-senior reader on a 27-inch display, bump one step up. Never reduce an existing size. -5. **Peer consistency.** Compare against the closest peer element (sibling link type, sibling tag variant, sibling label). Hover, focus, color token, and gutter must match unless there is a stated reason to differ. -6. **Narrow viewport.** Run the `playwright-cli` skill at `< 960px` and `< 680px`. Sort affordance, filter chips, and sticky header must remain functional. +5. **Peer consistency.** Compare against the closest peer element. Peer links (hero topbar, footer, project names, sponsor names, expand-meta) share hover and focus treatment; tag variants inherit the base `.tag` style; labels that play the same role share size, weight, and letter-spacing. Color token and gutter must match unless there is a stated reason to differ. +6. **Browser check.** Run the `playwright-cli` skill at full width, `< 960px`, and `< 680px`. Check layout and interactive behavior; sort affordance, filter chips, and sticky header must remain functional. Do not claim a UI change works based on code alone. ## Known Gaps -- **Color format diverges from the Stitch spec.** The official linter requires hex sRGB (`/^#([0-9a-fA-F]{3,8})$/`). The project mandates OKLCH in `style.css`. The Colors section above resolves this by showing both: OKLCH is canonical, hex is the linter-friendly approximation. -- **YAML frontmatter is minimal.** Only `version`, `name`, and `description` are encoded. The project has no JSON / Figma export pipeline that would consume token-level frontmatter, so the prose-led format is preferred for everything else. - **No formal spacing or radius scale.** The codebase uses `clamp()` and ad-hoc rem values rather than a tokenized scale. Adding one would be invention, not documentation. - -## Verification - -After any frontend change, use the `playwright-cli` skill to visually verify in a real browser. Check layout, responsiveness, and interactive behavior. Do not claim a UI change works based on code alone.