diff --git a/README.md b/README.md index 960ac4d2..73fd5343 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,46 @@ The RadicalxChange www site is built on [11ty](https://www.11ty.dev/). It's styl ## Design +> A refinement effort is tightening the site's craft _within_ the existing brand +> (hierarchy, spacing, component consistency, restraint). See `DESIGN_DIRECTION.md` +> for the audit and plan. The tokens below are the shared foundation that work builds on. + +### Palette + +Three brand colors, nothing else: + +| Token | Hex | Role | +| ---------------- | --------- | ----------------------------------------------------------- | +| `black` | `#000000` | Primary ink; black section bands ("the big moments"). | +| `white` | `#FFFFFF` | Default page surface. | +| `golden-fizz` | `#EDFF38` | Brand **yellow** — punctuation only. | + +**Yellow is punctuation, not wallpaper.** Use it for accents (underlines, icon +circles, highlight marks, number circles, a single key callout) and the rare, +countable full-bleed jolt (newsletter, donate CTA, 404). Reach for **black +sections** — not yellow fills — for big confident moments. Default surface is white. + +**Contrast rule (ADA), from the Brand Book:** black-on-yellow, black-on-white, or +white/yellow-on-black only — **never** yellow/white on yellow/white, and never +yellow text on white. + +`gray` and `red` remain in the config but are **restricted, non-brand** colors kept +only for functional data-viz on the Community Week NYC microsite (pass / disagree vote +bars). **They are retained intentionally — please don't "tidy them up."** There the +colors carry _meaning_ (data encoding), not decoration, so they're a different category +from the brand surface and removing them would break the vote bars. The brand rule +(black / white / yellow) governs brand surfaces; a data-viz legend is exempt. Revisit +the encoding only if/when CWNYC gets a visual refresh on its own merits. Don't use them +on brand surfaces, and don't introduce new usages. + +### Surface & color scheme + +`global.css` sets `color-scheme: light` and a white `body` background so no page can +fall through to the browser's dark canvas (which previously made black text invisible +in OS dark mode). These live on low-specificity selectors, so any utility +(`bg-black`, `bg-golden-fizz`, a page's `bodyBg`) still overrides them — intentionally +dark or yellow bands are unaffected. + ### Grid Pages are laid out on grids. A grid has fixed-width margins, fixed-width gutters and fluid columns. Desktop pages are on a 12-column or 16-column grid. Mobile pages are on a 4-column grid. @@ -48,12 +88,45 @@ We use TailWind's built-in scale for general size and space. These utilities use For typography heavy pages, we use a multiple of line height for vertical spacing. The utilities use `em` units. +#### Section rhythm + +For the gaps **between** structural blocks, prefer the documented rhythm tokens over +ad-hoc `mb-16` / `mb-8` one-offs, so every page shares one calm cadence: + +| Token | Value | Use | +| --------- | ------------------------ | ------------------------------------- | +| `section` | `clamp(4rem, 8vw, 8rem)` | Between major page sections. | +| `block` | `clamp(2rem, 4vw, 3rem)` | Between blocks within a section. | +| `element` | `1.5rem` | Between elements within a block. | + +Apply as any Tailwind spacing utility, e.g. `mb-section`, `space-y-block`, `py-section`, +`gap-element`. + ### Typography We use a [fluid type scale](https://utopia.fyi/blog/designing-with-fluid-type-scales) for almost all text. This scale provides a base text size and "steps" up and down from that. If you assign a step size to text, it will automatically scale relative to the width of the browser. For text written in Messer font, use font-size in the `vw` unit instead. +#### Type roles + +Two families, a small set of roles. **Only one Messer weight is licensed for web** +(`MesserV2.0-Condensed`, 400) — so display hierarchy comes from **size, not weight**. +Keep to these roles rather than inventing per-page sizes: + +| Role | Font (`font-…`) | Treatment | Notes | +| ------------------- | ---------------------- | ------------------------------------------- | ------------------------------------------------ | +| Display / page title | `display` (Messer) | **ALL CAPS**, `size-lg/display`+ | One per page. Caps only — Messer is a caps face. | +| Hero statement | `display` (Messer caps) | short, oversized | Keep it short (≈4–8 words); long copy → standfirst. | +| Section header | `body` bold (Suisse) | `size-2`, with a hairline rule beneath | Pairs with the eyebrow below. | +| Eyebrow / kicker | `body` bold (Suisse) | uppercase, `size--1`, letter-spaced, quiet | A small label, **not** a headline. | +| Body | `body` (Suisse) | `size-0` | Brand body face is Suisse Book.¹ | +| Meta (author/date/tag) | `body` (Suisse) | `size--1` | One consistent size for all metadata. | + +¹ The Brand Book specifies **Suisse Int'l Book** for paragraph text; today `font-body` +resolves to Suisse Int'l _Regular_. A small, deliberate drift to reconcile in a later +typography pass — flagged, not silently changed. + ## Code Layout 11ty builds from _src/site_. Read 11ty's documentation to understand a lot about this directory. We outline only notable quirks here: diff --git a/src/site/_includes/components/button.njk b/src/site/_includes/components/button.njk new file mode 100644 index 00000000..2d6b7862 --- /dev/null +++ b/src/site/_includes/components/button.njk @@ -0,0 +1,37 @@ + +{# + Buttons — two weights, one rhythm. + + primary — pill with sliding arrow. The page's main call to action. + (Matches the existing action-button so adoption is a rename.) + secondary — uppercase text + thick underline. For lower-priority actions + and "see all"-style links that aren't a section header. + + Use at most one primary per view; reach for secondary otherwise. +#} +{% macro primary(href, label) %} + + {{ label }} + + + +{% endmacro %} + +{% macro secondary(href, label) %} +{{ label }} +{% endmacro %} diff --git a/src/site/_includes/components/content-card.njk b/src/site/_includes/components/content-card.njk new file mode 100644 index 00000000..4fc7660d --- /dev/null +++ b/src/site/_includes/components/content-card.njk @@ -0,0 +1,43 @@ + +{# + Content card — the ONE canonical card, promoted from the (good) Updates + card and made uniform-height without the old min-height hack. + + Structure: tag · title · optional description · meta (author / date), + pinned to the bottom so meta aligns across a row. The whole card is the + link. Drop it in any CSS grid; `h-full` + the grid's stretch makes every + card in a row equal height, and `mt-auto` keeps the meta on the baseline. + + Args: + href (required) + title (required) + tag (optional) — small uppercase label (e.g. "Blog Post", "Project") + description (optional) — short standfirst (used by Projects/Proposals cards) + meta1 (optional) — e.g. author + meta2 (optional) — e.g. date +#} +{% macro render(href, title, tag, description, meta1, meta2) %} + + + {% if tag %} +

+ {{ tag }} +

+ {% endif %} + + + {% if description %} +

{{ description }}

+ {% endif %} + + {% if meta1 or meta2 %} +
+ {% if meta1 %}

{{ meta1 }}

{% endif %} + {% if meta2 %}

{{ meta2 }}

{% endif %} +
+ {% endif %} +
+{% endmacro %} diff --git a/src/site/_includes/components/popup.njk b/src/site/_includes/components/popup.njk index 550b1eed..60afa251 100644 --- a/src/site/_includes/components/popup.njk +++ b/src/site/_includes/components/popup.njk @@ -38,7 +38,7 @@
-