From 6fe263444a0641f5f4b098a4c9cdf7192b8fd353 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 9 Aug 2026 01:31:00 +0200 Subject: [PATCH] Extract authenticated coulomb.social design language via designlang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session probe lands on /vw_pages (Research). Use main designlang extract with --cookie-file — pack ignores auth. 39 artifacts under docs/design-extract; tolerate designlang late summary crash when cores exist. --- docs/design-extract-auth.md | 16 +- docs/design-extract/LICENSE.txt | 20 - docs/design-extract/PROVENANCE.md | 28 +- docs/design-extract/README.md | 63 -- docs/design-extract/components/anatomy.tsx | 4 - docs/design-extract/coulomb-social-AGENT.md | 115 +++ docs/design-extract/coulomb-social-DESIGN.md | 109 +++ .../design-extract/coulomb-social-anatomy.tsx | 15 + .../coulomb-social-design-language.md | 578 +++++++++++++ ...json => coulomb-social-design-tokens.json} | 108 ++- ...on => coulomb-social-figma-variables.json} | 266 ++++-- .../coulomb-social-form-states.json | 23 + .../coulomb-social-gradients.css | 2 + .../coulomb-social-gradients.json | 7 + .../coulomb-social-icon-system.json | 199 +++++ .../design-extract/coulomb-social-intent.json | 24 + .../coulomb-social-library.json | 12 + docs/design-extract/coulomb-social-mcp.json | 275 ++++++ ...json => coulomb-social-motion-tokens.json} | 8 +- docs/design-extract/coulomb-social-motion.css | 38 + .../coulomb-social-motion.framer.js | 70 ++ .../coulomb-social-motion.gsap.js | 49 ++ .../design-extract/coulomb-social-motion.html | 138 +++ .../coulomb-social-motion.one.js | 58 ++ .../coulomb-social-motion.tailwind.js | 67 ++ .../coulomb-social-motion.waapi.js | 44 + .../coulomb-social-preview.html | 433 ++++++++++ .../claude-artifacts.md | 6 +- .../coulomb-social-prompts/cursor.md | 18 + .../coulomb-social-prompts/lovable.txt | 12 + .../coulomb-social-prompts/recipe-button.md | 28 + .../v0.txt | 16 +- docs/design-extract/coulomb-social-reset.css | 81 ++ .../coulomb-social-routes-report.md | 15 + docs/design-extract/coulomb-social-seo.json | 40 + .../coulomb-social-shadcn-theme.css | 15 + .../coulomb-social-stack-intel.json | 12 + .../coulomb-social-tailwind-v4.css | 55 ++ ...g.js => coulomb-social-tailwind.config.js} | 71 +- .../theme.js => coulomb-social-theme.js} | 80 +- .../coulomb-social-tokens-routes/index.json | 82 ++ ...hunk-1767965374100x901547861536145400.json | 88 ++ ...hunk-1784305925912x322414739506593800.json | 91 ++ ...hunk-1784904857383x503270614975381500.json | 91 ++ ...hunk-1785501127011x363256181345746940.json | 88 ++ ...hunk-1785501151364x921456713843343400.json | 88 ++ ...hunk-1786106348475x662489469743530000.json | 99 +++ .../coulomb-social-tokens-shared.json | 92 ++ .../design-extract/coulomb-social-tokens.d.ts | 49 ++ ...ables.css => coulomb-social-variables.css} | 47 +- .../coulomb-social-visual-dna.json | 53 ++ docs/design-extract/coulomb-social-voice.json | 71 ++ .../coulomb-social-wordpress-theme.json | 175 ++++ docs/design-extract/coulomb-social.brand.html | 795 ++++++++++++++++++ docs/design-extract/extras/prompt-pack.md | 120 --- docs/design-extract/extras/voice.json | 13 - docs/design-extract/prompts/cursor.md | 18 - docs/design-extract/prompts/lovable.txt | 12 - docs/design-extract/prompts/recipes/button.md | 28 - docs/design-extract/starter/index.html | 41 - .../storybook/.storybook/main.ts | 8 - .../storybook/.storybook/preview.ts | 10 - docs/design-extract/storybook/README.md | 15 - docs/design-extract/storybook/package.json | 26 - .../storybook/stories/Tokens.mdx | 15 - .../storybook/stories/tokens.css | 11 - docs/design-extract/storybook/tsconfig.json | 15 - docs/design-extract/tokens/tokens.flat.json | 127 --- scripts/capture-auth-state.mjs | 49 +- scripts/probe-auth-session.mjs | 21 + scripts/run-design-extract.sh | 80 +- 71 files changed, 4939 insertions(+), 797 deletions(-) delete mode 100644 docs/design-extract/LICENSE.txt delete mode 100644 docs/design-extract/README.md delete mode 100644 docs/design-extract/components/anatomy.tsx create mode 100644 docs/design-extract/coulomb-social-AGENT.md create mode 100644 docs/design-extract/coulomb-social-DESIGN.md create mode 100644 docs/design-extract/coulomb-social-anatomy.tsx create mode 100644 docs/design-extract/coulomb-social-design-language.md rename docs/design-extract/{tokens/design-tokens.json => coulomb-social-design-tokens.json} (66%) rename docs/design-extract/{tokens/figma-variables.json => coulomb-social-figma-variables.json} (69%) create mode 100644 docs/design-extract/coulomb-social-form-states.json create mode 100644 docs/design-extract/coulomb-social-gradients.css create mode 100644 docs/design-extract/coulomb-social-gradients.json create mode 100644 docs/design-extract/coulomb-social-icon-system.json create mode 100644 docs/design-extract/coulomb-social-intent.json create mode 100644 docs/design-extract/coulomb-social-library.json create mode 100644 docs/design-extract/coulomb-social-mcp.json rename docs/design-extract/{tokens/motion-tokens.json => coulomb-social-motion-tokens.json} (59%) create mode 100644 docs/design-extract/coulomb-social-motion.css create mode 100644 docs/design-extract/coulomb-social-motion.framer.js create mode 100644 docs/design-extract/coulomb-social-motion.gsap.js create mode 100644 docs/design-extract/coulomb-social-motion.html create mode 100644 docs/design-extract/coulomb-social-motion.one.js create mode 100644 docs/design-extract/coulomb-social-motion.tailwind.js create mode 100644 docs/design-extract/coulomb-social-motion.waapi.js create mode 100644 docs/design-extract/coulomb-social-preview.html rename docs/design-extract/{prompts => coulomb-social-prompts}/claude-artifacts.md (58%) create mode 100644 docs/design-extract/coulomb-social-prompts/cursor.md create mode 100644 docs/design-extract/coulomb-social-prompts/lovable.txt create mode 100644 docs/design-extract/coulomb-social-prompts/recipe-button.md rename docs/design-extract/{prompts => coulomb-social-prompts}/v0.txt (52%) create mode 100644 docs/design-extract/coulomb-social-reset.css create mode 100644 docs/design-extract/coulomb-social-routes-report.md create mode 100644 docs/design-extract/coulomb-social-seo.json create mode 100644 docs/design-extract/coulomb-social-shadcn-theme.css create mode 100644 docs/design-extract/coulomb-social-stack-intel.json create mode 100644 docs/design-extract/coulomb-social-tailwind-v4.css rename docs/design-extract/{tokens/tailwind.config.js => coulomb-social-tailwind.config.js} (63%) rename docs/design-extract/{tokens/theme.js => coulomb-social-theme.js} (62%) create mode 100644 docs/design-extract/coulomb-social-tokens-routes/index.json create mode 100644 docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1767965374100x901547861536145400.json create mode 100644 docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784305925912x322414739506593800.json create mode 100644 docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784904857383x503270614975381500.json create mode 100644 docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501127011x363256181345746940.json create mode 100644 docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501151364x921456713843343400.json create mode 100644 docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1786106348475x662489469743530000.json create mode 100644 docs/design-extract/coulomb-social-tokens-shared.json create mode 100644 docs/design-extract/coulomb-social-tokens.d.ts rename docs/design-extract/{tokens/variables.css => coulomb-social-variables.css} (74%) create mode 100644 docs/design-extract/coulomb-social-visual-dna.json create mode 100644 docs/design-extract/coulomb-social-voice.json create mode 100644 docs/design-extract/coulomb-social-wordpress-theme.json create mode 100644 docs/design-extract/coulomb-social.brand.html delete mode 100644 docs/design-extract/extras/prompt-pack.md delete mode 100644 docs/design-extract/extras/voice.json delete mode 100644 docs/design-extract/prompts/cursor.md delete mode 100644 docs/design-extract/prompts/lovable.txt delete mode 100644 docs/design-extract/prompts/recipes/button.md delete mode 100644 docs/design-extract/starter/index.html delete mode 100644 docs/design-extract/storybook/.storybook/main.ts delete mode 100644 docs/design-extract/storybook/.storybook/preview.ts delete mode 100644 docs/design-extract/storybook/README.md delete mode 100644 docs/design-extract/storybook/package.json delete mode 100644 docs/design-extract/storybook/stories/Tokens.mdx delete mode 100644 docs/design-extract/storybook/stories/tokens.css delete mode 100644 docs/design-extract/storybook/tsconfig.json delete mode 100644 docs/design-extract/tokens/tokens.flat.json create mode 100755 scripts/probe-auth-session.mjs diff --git a/docs/design-extract-auth.md b/docs/design-extract-auth.md index 4dc3ed3..203477a 100644 --- a/docs/design-extract-auth.md +++ b/docs/design-extract-auth.md @@ -113,11 +113,25 @@ Until a catalog id exists, treat this as: ## designlang auth flags (reference) +**Important:** use the **main** `designlang ` command, not `designlang pack`. +The `pack` subcommand ignores `--cookie-file` and crawls anonymously. + ```bash +# Prefer the wrapper (probes session, applies cookies, correct out dir): +./scripts/run-design-extract.sh + +# Or manually: npx designlang https://coulomb.social \ --cookie-file ~/.config/coulomb-social/auth/storage-state.json \ -o docs/design-extract \ - --depth 5 + -n coulomb-social \ + --wait 5000 \ + --depth 2 \ + --interactions ``` +Bubble reuses the same `coulomb_*` cookie **names** for guests and members. +A real member session is verified by landing on an app route (e.g. `/vw_pages`) +after load, not by cookie count. + Chrome extension path (optional): log in in desktop Chrome, use designlang’s extension for a one-click handoff if you prefer not to use Playwright capture. diff --git a/docs/design-extract/LICENSE.txt b/docs/design-extract/LICENSE.txt deleted file mode 100644 index f739846..0000000 --- a/docs/design-extract/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Design System Pack — Provenance -================================ - -Source: https://coulomb.social -Captured: 2026-08-08 -Tool: designlang (https://designlang.app, MIT) - -The token values, type scale, spacing system, and component anatomy in -this pack were inferred from the publicly-accessible computed styles of -the source URL via a headless browser. No source files, proprietary -assets, or copyrighted media were accessed or included. - -You are free to use these values as a starting point, reference, or -inspiration. The packaging itself (this README, the bundle layout, the -emitter output formats) is released under MIT by the designlang project. - -Trademarks, logos, brand names, and other identifiable assets of the -source remain the property of their respective owners and are not -licensed by this pack. Do not pass off this pack as the original site's -official design system without permission. diff --git a/docs/design-extract/PROVENANCE.md b/docs/design-extract/PROVENANCE.md index 6a99cf2..32b33d8 100644 --- a/docs/design-extract/PROVENANCE.md +++ b/docs/design-extract/PROVENANCE.md @@ -3,14 +3,24 @@ | Field | Value | |-------|--------| | Source | https://coulomb.social | -| Tool | designlang pack v12.21.0 | -| Captured | 2026-08-09 (local) | -| Auth | Cookie file present, but session matches **anonymous Bubble** defaults (3× `coulomb_*` cookies; only `algoliasearch-client-js` localStorage). Treat as **public shell** baseline, not logged-in product UI. | -| Grade | B (86/100) — thin signal (6 palette colours; voice stats 0 buttons / 0 headings) | -| Location | `docs/design-extract/` | +| Tool | designlang main extract (not `pack`) | +| Captured | 2026-08-09 | +| Auth | Playwright storageState via `--cookie-file` | +| Session probe | https://coulomb.social/vw_pages (Research \| Coulomb) | +| Pages | 7 analyzed · 3445 elements | +| Primary | `#d08728` | +| designlang exit | 1 (late summary crash after writing core files) | -## Next +## Important -1. Re-run `./scripts/capture-auth-state.sh` after a full member login (wait for app UI). -2. Script now refuses to overwrite `storage-state.json` with anonymous sessions (exit 2). -3. Re-run `./scripts/run-design-extract.sh --wait 5000` (and optionally a multi-page crawl via plain `designlang` with `--depth`) for authenticated surfaces. +`designlang pack` **does not apply cookies**. Always use +`./scripts/run-design-extract.sh` (main extract command). + +## Key artifacts + +- `coulomb-social-design-language.md` — LLM-oriented full description +- `coulomb-social-DESIGN.md` — agent-native DESIGN.md +- `coulomb-social-design-tokens.json` — DTCG tokens +- `coulomb-social-variables.css` / `coulomb-social-tailwind.config.js` +- `coulomb-social-preview.html` — visual preview +- `coulomb-social-voice.json` — UI chrome (Material icon buttons on Research view) diff --git a/docs/design-extract/README.md b/docs/design-extract/README.md deleted file mode 100644 index 335ed11..0000000 --- a/docs/design-extract/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# coulomb.social — design system pack - -> Built from `https://coulomb.social` on 2026-08-08 by [designlang](https://designlang.app) v12.21.0. - -A single, polished bundle of every artifact designlang emits for coulomb.social: tokens, components, a runnable Storybook, a minimal starter, and paste-ready prompts for v0 / Lovable / Cursor / Claude Artifacts. - -## At a glance - -- **Grade:** B (86/100) -- **Stack:** unknown · component library: unknown -- **Type families:** Times New Roman, Helvetica, Inter -- **Palette:** 6 colors -- **Spacing base:** 2 - -## What's in this pack - -``` -coulomb-social-design-system/ -├── README.md ← you are here -├── LICENSE.txt -├── tokens/ ← DTCG + Tailwind + CSS vars + Figma vars + motion + theme.js -├── components/ ← typed React stubs (anatomy.tsx) -├── storybook/ ← runnable Storybook project -├── starter/ ← minimal starter app -├── prompts/ ← v0 · Lovable · Cursor · Claude Artifacts -└── extras/ ← voice fingerprint + recipe cards -``` - -## Install the tokens - -### Tailwind - -```js -// tailwind.config.js -import config from './tokens/tailwind.config.js'; -export default config; -``` - -### CSS variables - -```html - -``` - -### Figma - -In Figma → Variables panel → import `tokens/figma-variables.json`. - -### Storybook - -```bash -cd storybook && npm install && npm run storybook -``` - -## Provenance - -This pack was extracted from a publicly-accessible URL and represents the *observable design language* of that site at the time of capture. Token values are inferred from computed styles — no source files were accessed. See `LICENSE.txt` for usage guidance. - -Re-pack at any time: - -```bash -npx designlang pack coulomb.social -``` diff --git a/docs/design-extract/components/anatomy.tsx b/docs/design-extract/components/anatomy.tsx deleted file mode 100644 index 0529c08..0000000 --- a/docs/design-extract/components/anatomy.tsx +++ /dev/null @@ -1,4 +0,0 @@ -// Auto-generated by designlang — component anatomy v2. -// Scaffolds. Wire into your token system; not a runtime library. - -import * as React from 'react'; diff --git a/docs/design-extract/coulomb-social-AGENT.md b/docs/design-extract/coulomb-social-AGENT.md new file mode 100644 index 0000000..83e27cb --- /dev/null +++ b/docs/design-extract/coulomb-social-AGENT.md @@ -0,0 +1,115 @@ +# You are building UI in the coulomb.social design system. + +Source: https://coulomb.social +Extracted by designlang on 2026-08-08. + +## Brand at a glance + +- title Research | Coulomb +- page intent landing +- material flat +- design grade B + +## Colour + +- primary #d08728 +- neutrals #000000 · #efefef · #616161 · #373737 · #171717 · #ffffff + +## Typography + +- families Helvetica · Arial · Times New Roman · Inter +- weights 400 · 500 · 600 · 700 +- base size 16px + +## Spacing + +- scale 1px · 24px · 32px · 40px · 60px · 80px · 96px · 320px + +## Radii + +- scale 4px · 8px · 12px · 15px · 20px + +## Motion + +- durations 250ms + +## Voice + +- tone neutral +- pronoun third-person +- headings unknown +- CTA verbs content · favorite · format · filter · add · arrow + +## Component anatomy + +- button variants: [object Object] · slots: true · true · false + +## Accessibility + +- WCAG score 100% · failing pairs: 0 + +## Build rules + +1. Use the colours above. **Never invent a new hex.** If you need a + shade between two existing colours, derive it via HSL adjustment + from the closest extracted colour and call out the derivation. +2. Use the extracted typography families. If you need a missing weight, + pick the nearest available weight from the list and note it. +3. Snap spacing values to the scale above. No off-scale paddings or + margins. +4. Snap border radii to the scale above. +5. Match the voice: same tone, same pronoun stance, same heading + style. Reuse the listed CTA verbs. +6. Aim for WCAG AA contrast minimum. When the brand colours fail, + prefer the foreground colour on the background colour rather than + mid-tone neutrals. +7. Reuse component anatomy when it exists — do not invent novel + structures for things the site already has. + +## Available context files + +designlang wrote these alongside this prompt. Reach for them when +you need ground truth: + +- `-design-tokens.json` — DTCG primitive · semantic · composite tokens +- `-tailwind.config.js` — Tailwind v3 config +- `-tailwind-v4.css` — Tailwind v4 `@theme` block +- `-tokens.d.ts` — TypeScript literal-union types +- `-variables.css` — bare CSS custom properties +- `-reset.css` — brand-aware base styles +- `-gradients.css` — `.grad-N` utility classes +- `-anatomy.tsx` — typed React component scaffolds +- `-shadcn-theme.css` — shadcn/ui theme +- `-theme.js` — React / Vue / Svelte theme object +- `-mcp.json` — MCP server payload (load via stdio) +- `.brand.pdf` — print-ready 13-chapter brand book + +When you reference the system in code, prefer importing from these +files over hard-coding values. + +## Output expectations + +When asked to "build a pricing page" or "make a card" or any UI: + +- Produce a single self-contained component file in the appropriate + framework (React / Vue / Svelte — match what the user is using). +- Use Tailwind utility classes wired to the v4 `@theme` if Tailwind + is available; otherwise use the CSS custom properties from + `variables.css`. +- Write the headline copy using the brand voice; do not invent + generic Lorem. +- Annotate any choice where you had to bend the system, with a + one-line `// note:` comment explaining what and why. + +## One-line install + +```bash +npx designlang coulomb.social +``` + +Run this against any other URL to extract its system in the same +shape as the one above. + +--- + +Generated by designlang. Re-extract by running `npx designlang coulomb.social`. diff --git a/docs/design-extract/coulomb-social-DESIGN.md b/docs/design-extract/coulomb-social-DESIGN.md new file mode 100644 index 0000000..d87a22d --- /dev/null +++ b/docs/design-extract/coulomb-social-DESIGN.md @@ -0,0 +1,109 @@ +--- +site: "Research | Coulomb" +url: "https://coulomb.social" +generated_at: "2026-08-08T23:30:22.030Z" +generator: "designlang@12.21.0" +intent: landing +material: flat +tokens: + colors: + primary: "#d08728" + background: "#ffffff" + foreground: "#000000" + typography: + sans: Helvetica + spacing: + base: 4 + scale: "[1, 24, 32, 40, 60, 80, 96, 320]" + radii: + sm: 4 + md: 8 + lg: 15 + xl: 20 + shadows: + sm: "rgb(170, 170, 170) 2px 2px 4px 0px" + md: "rgba(23, 23, 23, 0.1) 2px 2px 8px 2px" +--- + +# Overview + +A **landing** page (heuristic confidence 0.45), dressed in **flat** material. + +> "Research | Coulomb" + +The author writes in a **neutral** voice; headings tend to be **unknown** case and **tight**. + +Reading order detected on the source: `—`. + +Source: . + +# Colors + +| role | hex | usage | +|---|---|---| +| primary | `#d08728` | 8 | +| background | `#ffffff` | — | +| foreground | `#000000` | — | + +**Neutrals:** `#000000` · `#efefef` · `#616161` · `#373737` · `#171717` + +**Total unique colors detected:** 8. + +# Typography + +**Families** +- `Helvetica` · 1739 uses +- `Arial` · 761 uses +- `Times New Roman` · 450 uses +- `Inter` · 397 uses + +# Layout + +**Spacing base:** `4px` increments. +**Scale:** `1px` · `24px` · `32px` · `40px` · `60px` · `80px` · `96px` · `320px` + +**Layout primitives:** 123 grid containers · 1256 flex containers. + +# Elevation and Depth + +**Shadow scale** +- `sm` — `rgb(170, 170, 170) 2px 2px 4px 0px` +- `md` — `rgba(23, 23, 23, 0.1) 2px 2px 8px 2px` + +**Z-index layers:** 35 + +# Shapes + +**Radius scale** +- `sm` — `4px` +- `md` — `8px` +- `lg` — `12px` +- `lg` — `15px` +- `xl` — `20px` + +# Components + +**Detected patterns:** `buttons` · `cards` · `inputs` · `links` · `modals` + +**Anatomy** +| kind | variants | sizes | instances | +|---|---|---|---| +| button | — | — | 56 | + +# Do's and Don'ts + +**Do's** +- Use `content`, `favorite`, `format` as the primary verbs in CTAs — these dominate the source. +- Write headings in **unknown** case, **tight** length. +- Address the reader with the pronoun posture **third-person**. +- Stay inside the **flat** material — match shadow and radius habits. + +**Don'ts** +- Don't 4 font families — consider limiting to 2 (heading + body). +- Don't 140 !important rules — prefer specificity over overrides. +- Don't 81% of css is unused — consider purging. +- Don't 6545 duplicate css declarations. + +--- +_Generated by [designlang](https://github.com/Manavarya09/design-extract) v12.21.0 from ._ +_Compatible with the DESIGN.md convention pioneered by [design-extractor.com](https://www.design-extractor.com) — extended with intent, material, voice, anatomy, and library detection._ diff --git a/docs/design-extract/coulomb-social-anatomy.tsx b/docs/design-extract/coulomb-social-anatomy.tsx new file mode 100644 index 0000000..05279fe --- /dev/null +++ b/docs/design-extract/coulomb-social-anatomy.tsx @@ -0,0 +1,15 @@ +// Auto-generated by designlang — component anatomy v2. +// Scaffolds. Wire into your token system; not a runtime library. + +import * as React from 'react'; + +export interface ButtonProps { + variant?: 'default'; + size?: 'md'; + leadingIcon?: React.ReactNode; + children?: React.ReactNode; +} + +export function Button({ variant = 'default', size = 'md', ...rest }: ButtonProps) { + return React.createElement('button', { 'data-variant': variant, 'data-size': size, ...rest }); +} diff --git a/docs/design-extract/coulomb-social-design-language.md b/docs/design-extract/coulomb-social-design-language.md new file mode 100644 index 0000000..9ff1248 --- /dev/null +++ b/docs/design-extract/coulomb-social-design-language.md @@ -0,0 +1,578 @@ +# Design Language: Research | Coulomb + +> Extracted from `https://coulomb.social` on August 9, 2026 +> 3445 elements analyzed across 7 pages + +This document describes the complete design language of the website. It is structured for AI/LLM consumption — use it to faithfully recreate the visual design in any framework. + +## Color Palette + +### Primary Colors + +| Role | Hex | RGB | HSL | Usage Count | +|------|-----|-----|-----|-------------| +| Primary | `#d08728` | rgb(208, 135, 40) | hsl(34, 68%, 49%) | 8 | + +### Neutral Colors + +| Hex | HSL | Usage Count | +|-----|-----|-------------| +| `#000000` | hsl(0, 0%, 0%) | 5304 | +| `#efefef` | hsl(0, 0%, 94%) | 610 | +| `#616161` | hsl(0, 0%, 38%) | 556 | +| `#373737` | hsl(0, 0%, 22%) | 462 | +| `#171717` | hsl(0, 0%, 9%) | 401 | +| `#ffffff` | hsl(0, 0%, 100%) | 242 | +| `#e5e5e5` | hsl(0, 0%, 90%) | 217 | + +### Background Colors + +Used on large-area elements: `#ffffff`, `#e5e5e5`, `#171717`, `#f5f5f5` + +### Text Colors + +Text color palette: `#000000`, `#171717`, `#373737`, `#616161`, `#ffffff` + +### Full Color Inventory + +| Hex | Contexts | Count | +|-----|----------|-------| +| `#000000` | text, border, background | 5304 | +| `#efefef` | background | 610 | +| `#616161` | text, border | 556 | +| `#373737` | text, border | 462 | +| `#171717` | text, border, background | 401 | +| `#ffffff` | background, border, text | 242 | +| `#e5e5e5` | border, background | 217 | +| `#d08728` | background | 8 | + +## Typography + +### Font Families + +- **Helvetica** — used for body (1739 elements) +- **Arial** — used for body (761 elements) +- **Times New Roman** — used for body (450 elements) +- **Inter** — used for body (397 elements) + +### Type Scale + +| Size (px) | Size (rem) | Weight | Line Height | Letter Spacing | Used On | +|-----------|------------|--------|-------------|----------------|---------| +| 50px | 3.125rem | 400 | 50px | normal | text | +| 42px | 2.625rem | 700 | normal | normal | input | +| 24px | 1.5rem | 600 | 36px | normal | a | +| 18px | 1.125rem | 600 | 18px | normal | div | +| 16px | 1rem | 400 | normal | normal | html, head, meta, title | +| 14px | 0.875rem | 500 | 19.6px | normal | div, a | +| 13.3333px | 0.8333rem | 400 | normal | normal | button, svg, use | + +### Font Weights in Use + +`400` (3048x), `500` (287x), `600` (102x), `700` (8x) + +## Spacing + +**Base unit:** 4px + +| Token | Value | Rem | +|-------|-------|-----| +| spacing-1 | 1px | 0.0625rem | +| spacing-24 | 24px | 1.5rem | +| spacing-32 | 32px | 2rem | +| spacing-40 | 40px | 2.5rem | +| spacing-60 | 60px | 3.75rem | +| spacing-80 | 80px | 5rem | +| spacing-96 | 96px | 6rem | +| spacing-320 | 320px | 20rem | + +## Border Radii + +| Label | Value | Count | +|-------|-------|-------| +| sm | 4px | 119 | +| md | 8px | 122 | +| lg | 12px | 110 | +| lg | 15px | 6 | +| xl | 20px | 12 | + +## Box Shadows + +**sm** — blur: 4px +```css +box-shadow: rgb(170, 170, 170) 2px 2px 4px 0px; +``` + +**md** — blur: 8px +```css +box-shadow: rgba(23, 23, 23, 0.1) 2px 2px 8px 2px; +``` + +## CSS Custom Properties + +### Colors + +```css +--color_primary_default: rgba(2, 5, 211, 1); +--color_primary_default_rgb: 2, 5, 211; +--color_primary_contrast_default: rgba(255, 255, 255, 1); +--color_primary_contrast_default_rgb: 255, 255, 255; +--color_text_default: rgba(9, 23, 71, 1); +--color_text_default_rgb: 9, 23, 71; +--color_surface_default: rgba(255, 255, 255, 1); +--color_surface_default_rgb: 255, 255, 255; +--color_background_default: rgba(255, 255, 255, 0); +--color_background_default_rgb: 255, 255, 255; +--color_destructive_default: rgba(255, 0, 0, 1); +--color_destructive_default_rgb: 255, 0, 0; +--color_success_default: rgba(23, 219, 78, 1); +--color_success_default_rgb: 23, 219, 78; +--color_alert_default: rgba(250, 181, 21, 1); +--color_alert_default_rgb: 250, 181, 21; +--color_danger_default_rgb: rgba(176, 32, 12, 1); +--color_bTRUr_default_rgb: 208,135,40; +--color_bTOCs_default: rgba(55,55,55,1); +--color_bTHZK_default_rgb: 229,229,229; +--color_bTOCs_default_rgb: 55,55,55; +--color_bTINZ_default_rgb: 23,23,23; +--color_bTRUs_default_rgb: 227,230,235; +--color_bTINZ_default: rgba(23,23,23,0.36); +--color_bTRUr_default: rgba(208,135,40,0.1); +--color_bTHZK_default: rgba(229,229,229,1); +--color_bTHfJ_default_rgb: 97,97,97; +--color_bTMap_default: rgba(113,2,139,1); +--color_bTHfJ_default: rgba(97,97,97,1); +--color_bTMap_default_rgb: 113,2,139; +--color_bTRUs_default: rgba(227,230,235,1); +``` + +### Typography + +```css +--font_default: 'Lato'; +--font_bTRUx_default: "Inter"; +--font_bTRUt_default: "Inter"; +``` + +### Semantic + +```css +success: [object Object]; +warning: [object Object]; +error: [object Object]; +info: [object Object]; +``` + +## Transitions & Animations + +**Durations:** `0.25s` + +### Common Transitions + +```css +transition: all; +transition: background 0.25s; +``` + +### Keyframe Animations + +**highlight-in** +```css +@keyframes highlight-in { + 0% { background-color: rgb(200, 0, 0); } +} +``` + +**fa-spin** +```css +@keyframes fa-spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(359deg); } +} +``` + +**opacity-70-25-0-13** +```css +@keyframes opacity-70-25-0-13 { + 0% { opacity: 0.25; } + 0.01% { opacity: 0.25; } + 0.02% { opacity: 1; } + 70.01% { opacity: 0.25; } + 100% { opacity: 0.25; } +} +``` + +**opacity-70-25-1-13** +```css +@keyframes opacity-70-25-1-13 { + 0% { opacity: 0.25; } + 7.70231% { opacity: 0.25; } + 7.71231% { opacity: 1; } + 77.7023% { opacity: 0.25; } + 100% { opacity: 0.25; } +} +``` + +**opacity-70-25-2-13** +```css +@keyframes opacity-70-25-2-13 { + 0% { opacity: 0.25; } + 15.3946% { opacity: 0.25; } + 15.4046% { opacity: 1; } + 85.3946% { opacity: 0.25; } + 100% { opacity: 0.25; } +} +``` + +**opacity-70-25-3-13** +```css +@keyframes opacity-70-25-3-13 { + 0% { opacity: 0.25; } + 23.0869% { opacity: 0.25; } + 23.0969% { opacity: 1; } + 93.0869% { opacity: 0.25; } + 100% { opacity: 0.25; } +} +``` + +**opacity-70-25-4-13** +```css +@keyframes opacity-70-25-4-13 { + 0% { opacity: 0.258349; } + 30.7792% { opacity: 0.25; } + 30.7892% { opacity: 1; } + 0.779231% { opacity: 0.25; } + 100% { opacity: 0.258349; } +} +``` + +**opacity-70-25-5-13** +```css +@keyframes opacity-70-25-5-13 { + 0% { opacity: 0.340766; } + 38.4715% { opacity: 0.25; } + 38.4815% { opacity: 1; } + 8.47154% { opacity: 0.25; } + 100% { opacity: 0.340766; } +} +``` + +**opacity-70-25-6-13** +```css +@keyframes opacity-70-25-6-13 { + 0% { opacity: 0.423184; } + 46.1638% { opacity: 0.25; } + 46.1738% { opacity: 1; } + 16.1638% { opacity: 0.25; } + 100% { opacity: 0.423184; } +} +``` + +**opacity-70-25-7-13** +```css +@keyframes opacity-70-25-7-13 { + 0% { opacity: 0.505602; } + 53.8562% { opacity: 0.25; } + 53.8662% { opacity: 1; } + 23.8562% { opacity: 0.25; } + 100% { opacity: 0.505602; } +} +``` + +## Component Patterns + +Detected UI component patterns and their most common styles: + +### Buttons (643 instances) + +```css +.button { + background-color: rgb(239, 239, 239); + color: rgb(0, 0, 0); + font-size: 13.3333px; + font-weight: 400; + padding-top: 1px; + padding-right: 6px; + border-radius: 0px; +} +``` + +### Cards (36 instances) + +```css +.card { + background-color: rgb(255, 255, 255); + border-radius: 4px; + box-shadow: rgb(170, 170, 170) 2px 2px 4px 0px; + padding-top: 4px; + padding-right: 4px; +} +``` + +### Inputs (16 instances) + +```css +.input { + color: rgb(23, 23, 23); + border-color: rgb(255, 255, 255); + border-radius: 8px; + font-size: 16px; + padding-top: 2px; + padding-right: 2px; +} +``` + +### Links (130 instances) + +```css +.link { + color: rgb(23, 23, 23); + font-size: 16px; + font-weight: 500; +} +``` + +### Modals (78 instances) + +```css +.modal { + background-color: rgb(255, 255, 255); + border-radius: 12px; + padding-top: 24px; + padding-right: 0px; + max-width: 280px; +} +``` + +## Component Clusters + +Reusable component instances grouped by DOM structure and style similarity: + +### Button — 55 instances, 1 variant + +**Variant 1** (55 instances) + +```css + background: rgba(0, 0, 0, 0); + color: rgb(55, 55, 55); + padding: 0px 0px 0px 0px; + border-radius: 4px; + border: 0px none rgb(55, 55, 55); + font-size: 13.3333px; + font-weight: 400; +``` + +### Button — 1 instance, 1 variant + +**Variant 1** (1 instance) + +```css + background: rgb(239, 239, 239); + color: rgb(0, 0, 0); + padding: 1px 6px 1px 6px; + border-radius: 0px; + border: 2px outset rgb(0, 0, 0); + font-size: 13.3333px; + font-weight: 400; +``` + +## Layout System + +**123 grid containers** and **1256 flex containers** detected. + +### Container Widths + +| Max Width | Padding | +|-----------|---------| +| 1200px | 0px | +| 100% | 0px | +| 992px | 0px | + +### Grid Column Patterns + +| Columns | Usage Count | +|---------|-------------| +| 1-column | 122x | +| 2-column | 1x | + +### Grid Templates + +```css +grid-template-columns: 592px 592px; +gap: 16px; +grid-template-columns: 32px; +grid-template-columns: 32px; +grid-template-columns: 32px; +grid-template-columns: 32px; +``` + +### Flex Patterns + +| Direction/Wrap | Count | +|----------------|-------| +| column/nowrap | 470x | +| row/nowrap | 71x | +| row/wrap | 715x | + +**Gap values:** `0px 12px`, `0px 20px`, `0px 24px`, `0px 4px`, `0px 8px`, `0px normal`, `12px normal`, `16px`, `18px normal`, `24px`, `24px normal`, `4px normal`, `8px normal` + +## Interaction States + +### Button States + +**""** +```css +/* Focus */ +outline: rgb(208, 135, 40) none 3px → rgba(0, 0, 0, 0) dotted 0px; +``` + +### Link Hover + +```css +text-decoration: none → underline; +``` + +## Accessibility (WCAG 2.1) + +**Overall Score: 100%** — 0 passing, 0 failing color pairs + +## Design System Score + +**Overall: 85/100 (Grade: B)** + +| Category | Score | +|----------|-------| +| Color Discipline | 100/100 | +| Typography Consistency | 50/100 | +| Spacing System | 100/100 | +| Shadow Consistency | 100/100 | +| Border Radius Consistency | 90/100 | +| Accessibility | 100/100 | +| CSS Tokenization | 100/100 | + +**Strengths:** Tight, disciplined color palette, Well-defined spacing scale, Clean elevation system, Consistent border radii, Strong accessibility compliance, Good CSS variable tokenization + +**Issues:** +- 4 font families — consider limiting to 2 (heading + body) +- 140 !important rules — prefer specificity over overrides +- 81% of CSS is unused — consider purging +- 6545 duplicate CSS declarations + +## Z-Index Map + +**35 unique z-index values** across 3 layers. + +| Layer | Range | Elements | +|-------|-------|----------| +| modal | 1503,2105 | div.b.u.b.b.l.e.-.e.l.e.m.e.n.t. .C.u.s.t.o.m.E.l.e.m.e.n.t. .b.a.T.a.K.a.Q.a.X. .f.l.o.a.t.i.n.g.-.g.r.o.u.p. .b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .c.o.l.u.m.n, div.b.u.b.b.l.e.-.e.l.e.m.e.n.t. .C.u.s.t.o.m.E.l.e.m.e.n.t. .b.a.T.a.K.a.Q.a.X. .f.l.o.a.t.i.n.g.-.g.r.o.u.p. .b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .c.o.l.u.m.n, div.b.u.b.b.l.e.-.e.l.e.m.e.n.t. .C.u.s.t.o.m.E.l.e.m.e.n.t. .b.a.T.a.K.a.Q.a.X. .f.l.o.a.t.i.n.g.-.g.r.o.u.p. .b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .c.o.l.u.m.n | +| sticky | 10,30 | div.b.u.b.b.l.e.-.e.l.e.m.e.n.t. .G.r.o.u.p. .b.a.T.a.N.a.I.d. .b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .r.o.w, div.b.u.b.b.l.e.-.e.l.e.m.e.n.t. .T.e.x.t. .b.a.T.a.N.a.I.q, textarea.b.u.b.b.l.e.-.e.l.e.m.e.n.t. .M.u.l.t.i.L.i.n.e.I.n.p.u.t. .a.1.7.8.6.2.3.1.7.9.1.3.3.1.x.5.4.4.4 | +| base | 0,9 | div.b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .c.o.l.u.m.n, div.b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .c.o.l.u.m.n, div.b.u.b.b.l.e.-.r.-.c.o.n.t.a.i.n.e.r. .f.l.e.x. .c.o.l.u.m.n | + +## SVG Icons + +**7 unique SVG icons** detected. Dominant style: **filled**. + +| Size Class | Count | +|------------|-------| +| md | 4 | +| lg | 2 | +| xl | 1 | + +**Icon colors:** `rgb(0, 0, 0)` + +## Font Files + +| Family | Source | Weights | Styles | +|--------|--------|---------|--------| +| FontAwesome | self-hosted | normal | normal | +| Material Icons | self-hosted | 400 | normal | +| Material Icons Outline | self-hosted | 400 | normal | +| Inter | google-fonts | 300, 400, 500, 600, 700 | normal | + +**Google Fonts URL:** `https://fonts.googleapis.com/css?family=Inter:300%7CInter:regular%7CInter:500%7CInter:600%7CInter:700` + +## Image Style Patterns + +| Pattern | Count | Key Styles | +|---------|-------|------------| +| thumbnail | 28 | objectFit: contain, borderRadius: 8px, shape: rounded | +| general | 1 | objectFit: cover, borderRadius: 20px, shape: pill | + +**Aspect ratios:** 1:1 (28x), 2:3 (1x) + +## Motion Language + +**Feel:** mixed · **Scroll-linked:** yes + +### Duration Tokens + +| name | value | ms | +|---|---|---| +| `sm` | `250ms` | 250 | + +## Component Anatomy + +### button — 56 instances + +**Slots:** label, icon + +## Brand Voice + +**Tone:** neutral · **Pronoun:** third-person · **Headings:** unknown (tight) + +### Top CTA Verbs + +- **content** (25) +- **favorite** (25) +- **format** (1) +- **filter** (1) +- **add** (1) +- **arrow** (1) +- **note** (1) + +### Button Copy Patterns + +- "content_copy" (25×) +- "favorite_border" (25×) +- "format_line_spacing" (1×) +- "filter_list" (1×) +- "add_circle_outline" (1×) +- "arrow_drop_down" (1×) +- "note_alt" (1×) + +## Page Intent + +**Type:** `landing` (confidence 0.45) +**Description:** A tool to brainstorm, discuss, refine implement and promote ideas. +A social network for building stuff and influencing how stuff is built. +A marketplace for challenges, methods and solutions. +A platfo + +## Material Language + +**Label:** `flat` (confidence 0) + +| Metric | Value | +|--------|-------| +| Avg saturation | 0.101 | +| Shadow profile | soft | +| Avg shadow blur | 0px | +| Max radius | 20px | +| backdrop-filter in use | no | +| Gradients | 0 | + +## Imagery Style + +**Label:** `mixed` (confidence 0) +**Counts:** total 29, svg 0, icon 1, screenshot-like 0, photo-like 0 +**Dominant aspect:** square-ish +**Radius profile on images:** soft + +## Quick Start + +To recreate this design in a new project: + +1. **Install fonts:** Add `Helvetica` from Google Fonts or your font provider +2. **Import CSS variables:** Copy `variables.css` into your project +3. **Tailwind users:** Use the generated `tailwind.config.js` to extend your theme +4. **Design tokens:** Import `design-tokens.json` for tooling integration diff --git a/docs/design-extract/tokens/design-tokens.json b/docs/design-extract/coulomb-social-design-tokens.json similarity index 66% rename from docs/design-extract/tokens/design-tokens.json rename to docs/design-extract/coulomb-social-design-tokens.json index 4a69a18..2cf05ec 100644 --- a/docs/design-extract/tokens/design-tokens.json +++ b/docs/design-extract/coulomb-social-design-tokens.json @@ -4,7 +4,7 @@ "version": "7.0.0", "spec": "https://design-tokens.github.io/community-group/format/", "source": "https://coulomb.social", - "generatedAt": "2026-08-08T23:21:16.292Z" + "generatedAt": "2026-08-08T23:30:13.743Z" }, "primitive": { "color": { @@ -20,18 +20,26 @@ "$type": "color" }, "n200": { - "$value": "#171717", + "$value": "#efefef", "$type": "color" }, "n300": { - "$value": "#ffffff", - "$type": "color" - }, - "n400": { "$value": "#616161", "$type": "color" }, + "n400": { + "$value": "#373737", + "$type": "color" + }, "n500": { + "$value": "#171717", + "$type": "color" + }, + "n600": { + "$value": "#ffffff", + "$type": "color" + }, + "n700": { "$value": "#e5e5e5", "$type": "color" } @@ -42,7 +50,15 @@ "$type": "color" }, "bg1": { - "$value": "#616161", + "$value": "#e5e5e5", + "$type": "color" + }, + "bg2": { + "$value": "#171717", + "$type": "color" + }, + "bg3": { + "$value": "#f5f5f5", "$type": "color" } }, @@ -52,30 +68,54 @@ "$type": "color" }, "text1": { - "$value": "#ffffff", - "$type": "color" - }, - "text2": { "$value": "#171717", "$type": "color" }, + "text2": { + "$value": "#373737", + "$type": "color" + }, "text3": { - "$value": "#d08728", + "$value": "#616161", + "$type": "color" + }, + "text4": { + "$value": "#ffffff", "$type": "color" } } }, "spacing": { "s0": { - "$value": "2px", + "$value": "1px", "$type": "dimension" }, "s1": { - "$value": "32px", + "$value": "24px", "$type": "dimension" }, "s2": { - "$value": "68px", + "$value": "32px", + "$type": "dimension" + }, + "s3": { + "$value": "40px", + "$type": "dimension" + }, + "s4": { + "$value": "60px", + "$type": "dimension" + }, + "s5": { + "$value": "80px", + "$type": "dimension" + }, + "s6": { + "$value": "96px", + "$type": "dimension" + }, + "s7": { + "$value": "320px", "$type": "dimension" } }, @@ -87,29 +127,45 @@ "r1": { "$value": "8px", "$type": "dimension" + }, + "r2": { + "$value": "12px", + "$type": "dimension" + }, + "r3": { + "$value": "15px", + "$type": "dimension" + }, + "r4": { + "$value": "20px", + "$type": "dimension" } }, "shadow": { "sh0": { - "$value": "rgb(97, 97, 97) 2px 2px 8px 0px", + "$value": "rgb(170, 170, 170) 2px 2px 4px 0px", + "$type": "shadow" + }, + "sh1": { + "$value": "rgba(23, 23, 23, 0.1) 2px 2px 8px 2px", "$type": "shadow" } }, "fontFamily": { "f0": { - "$value": "Times New Roman", - "$type": "fontFamily" - }, - "f1": { "$value": "Helvetica", "$type": "fontFamily" }, + "f1": { + "$value": "Arial", + "$type": "fontFamily" + }, "f2": { - "$value": "Inter", + "$value": "Times New Roman", "$type": "fontFamily" }, "f3": { - "$value": "Arial", + "$value": "Inter", "$type": "fontFamily" } } @@ -138,10 +194,10 @@ "typography": { "body": { "$value": { - "fontFamily": "Times New Roman", - "fontSize": "48px", - "fontWeight": "700", - "lineHeight": "67.2px" + "fontFamily": "Helvetica", + "fontSize": "50px", + "fontWeight": "400", + "lineHeight": "50px" }, "$type": "typography" } diff --git a/docs/design-extract/tokens/figma-variables.json b/docs/design-extract/coulomb-social-figma-variables.json similarity index 69% rename from docs/design-extract/tokens/figma-variables.json rename to docs/design-extract/coulomb-social-figma-variables.json index 9626fdc..2e8036e 100644 --- a/docs/design-extract/tokens/figma-variables.json +++ b/docs/design-extract/coulomb-social-figma-variables.json @@ -35,9 +35,9 @@ "type": "COLOR", "values": { "light": { - "r": 0.09019607843137255, - "g": 0.09019607843137255, - "b": 0.09019607843137255, + "r": 0.9372549019607843, + "g": 0.9372549019607843, + "b": 0.9372549019607843, "a": 1 } } @@ -45,18 +45,6 @@ { "name": "color/neutral/200", "type": "COLOR", - "values": { - "light": { - "r": 1, - "g": 1, - "b": 1, - "a": 1 - } - } - }, - { - "name": "color/neutral/300", - "type": "COLOR", "values": { "light": { "r": 0.3803921568627451, @@ -66,9 +54,45 @@ } } }, + { + "name": "color/neutral/300", + "type": "COLOR", + "values": { + "light": { + "r": 0.21568627450980393, + "g": 0.21568627450980393, + "b": 0.21568627450980393, + "a": 1 + } + } + }, { "name": "color/neutral/400", "type": "COLOR", + "values": { + "light": { + "r": 0.09019607843137255, + "g": 0.09019607843137255, + "b": 0.09019607843137255, + "a": 1 + } + } + }, + { + "name": "color/neutral/500", + "type": "COLOR", + "values": { + "light": { + "r": 1, + "g": 1, + "b": 1, + "a": 1 + } + } + }, + { + "name": "color/neutral/600", + "type": "COLOR", "values": { "light": { "r": 0.8980392156862745, @@ -95,9 +119,33 @@ "type": "COLOR", "values": { "light": { - "r": 0.3803921568627451, - "g": 0.3803921568627451, - "b": 0.3803921568627451, + "r": 0.8980392156862745, + "g": 0.8980392156862745, + "b": 0.8980392156862745, + "a": 1 + } + } + }, + { + "name": "color/background/2", + "type": "COLOR", + "values": { + "light": { + "r": 0.09019607843137255, + "g": 0.09019607843137255, + "b": 0.09019607843137255, + "a": 1 + } + } + }, + { + "name": "color/background/3", + "type": "COLOR", + "values": { + "light": { + "r": 0.9607843137254902, + "g": 0.9607843137254902, + "b": 0.9607843137254902, "a": 1 } } @@ -119,9 +167,9 @@ "type": "COLOR", "values": { "light": { - "r": 1, - "g": 1, - "b": 1, + "r": 0.09019607843137255, + "g": 0.09019607843137255, + "b": 0.09019607843137255, "a": 1 } } @@ -131,9 +179,9 @@ "type": "COLOR", "values": { "light": { - "r": 0.09019607843137255, - "g": 0.09019607843137255, - "b": 0.09019607843137255, + "r": 0.21568627450980393, + "g": 0.21568627450980393, + "b": 0.21568627450980393, "a": 1 } } @@ -143,9 +191,21 @@ "type": "COLOR", "values": { "light": { - "r": 0.8156862745098039, - "g": 0.5294117647058824, - "b": 0.1568627450980392, + "r": 0.3803921568627451, + "g": 0.3803921568627451, + "b": 0.3803921568627451, + "a": 1 + } + } + }, + { + "name": "color/text/4", + "type": "COLOR", + "values": { + "light": { + "r": 1, + "g": 1, + "b": 1, "a": 1 } } @@ -159,45 +219,59 @@ ], "variables": [ { - "name": "font/size/48", + "name": "font/size/50", "type": "FLOAT", "values": { - "default": 48 + "default": 50 } }, { - "name": "font/weight/48", + "name": "font/weight/50", + "type": "FLOAT", + "values": { + "default": 400 + } + }, + { + "name": "font/lineHeight/50", + "type": "FLOAT", + "values": { + "default": 50 + } + }, + { + "name": "font/size/42", + "type": "FLOAT", + "values": { + "default": 42 + } + }, + { + "name": "font/weight/42", "type": "FLOAT", "values": { "default": 700 } }, { - "name": "font/lineHeight/48", + "name": "font/size/24", "type": "FLOAT", "values": { - "default": 67.2 + "default": 24 } }, { - "name": "font/size/32", - "type": "FLOAT", - "values": { - "default": 32 - } - }, - { - "name": "font/weight/32", + "name": "font/weight/24", "type": "FLOAT", "values": { "default": 600 } }, { - "name": "font/lineHeight/32", + "name": "font/lineHeight/24", "type": "FLOAT", "values": { - "default": 44.8 + "default": 36 } }, { @@ -218,7 +292,7 @@ "name": "font/lineHeight/18", "type": "FLOAT", "values": { - "default": 25.2 + "default": 18 } }, { @@ -269,48 +343,6 @@ "values": { "default": 400 } - }, - { - "name": "font/size/12", - "type": "FLOAT", - "values": { - "default": 12 - } - }, - { - "name": "font/weight/12", - "type": "FLOAT", - "values": { - "default": 500 - } - }, - { - "name": "font/lineHeight/12", - "type": "FLOAT", - "values": { - "default": 16.8 - } - }, - { - "name": "font/size/8", - "type": "FLOAT", - "values": { - "default": 8 - } - }, - { - "name": "font/weight/8", - "type": "FLOAT", - "values": { - "default": 500 - } - }, - { - "name": "font/lineHeight/8", - "type": "FLOAT", - "values": { - "default": 11.2 - } } ] }, @@ -321,10 +353,17 @@ ], "variables": [ { - "name": "spacing/2", + "name": "spacing/1", "type": "FLOAT", "values": { - "default": 2 + "default": 1 + } + }, + { + "name": "spacing/24", + "type": "FLOAT", + "values": { + "default": 24 } }, { @@ -335,10 +374,38 @@ } }, { - "name": "spacing/68", + "name": "spacing/40", "type": "FLOAT", "values": { - "default": 68 + "default": 40 + } + }, + { + "name": "spacing/60", + "type": "FLOAT", + "values": { + "default": 60 + } + }, + { + "name": "spacing/80", + "type": "FLOAT", + "values": { + "default": 80 + } + }, + { + "name": "spacing/96", + "type": "FLOAT", + "values": { + "default": 96 + } + }, + { + "name": "spacing/320", + "type": "FLOAT", + "values": { + "default": 320 } }, { @@ -354,6 +421,27 @@ "values": { "default": 8 } + }, + { + "name": "radius/lg", + "type": "FLOAT", + "values": { + "default": 12 + } + }, + { + "name": "radius/lg", + "type": "FLOAT", + "values": { + "default": 15 + } + }, + { + "name": "radius/xl", + "type": "FLOAT", + "values": { + "default": 20 + } } ] } diff --git a/docs/design-extract/coulomb-social-form-states.json b/docs/design-extract/coulomb-social-form-states.json new file mode 100644 index 0000000..b19b1de --- /dev/null +++ b/docs/design-extract/coulomb-social-form-states.json @@ -0,0 +1,23 @@ +{ + "flags": [], + "forms": { + "count": 0, + "families": {} + }, + "inputTypesSeen": { + "textarea": 10, + "input": 6 + }, + "modals": [], + "toastLibraries": [], + "loading": { + "skeleton": 0, + "spinner": 0 + }, + "empty": { + "count": 0 + }, + "error": { + "count": 0 + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-gradients.css b/docs/design-extract/coulomb-social-gradients.css new file mode 100644 index 0000000..5382e28 --- /dev/null +++ b/docs/design-extract/coulomb-social-gradients.css @@ -0,0 +1,2 @@ +/* designlang — no gradients detected on the source page. */ +/* Run with --interactions to capture hover backgrounds. */ diff --git a/docs/design-extract/coulomb-social-gradients.json b/docs/design-extract/coulomb-social-gradients.json new file mode 100644 index 0000000..8779877 --- /dev/null +++ b/docs/design-extract/coulomb-social-gradients.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://designlang.app/schemas/gradients.json", + "source": "https://coulomb.social", + "generated": "2026-08-08T23:30:22.006Z", + "count": 0, + "gradients": [] +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-icon-system.json b/docs/design-extract/coulomb-social-icon-system.json new file mode 100644 index 0000000..a02fed2 --- /dev/null +++ b/docs/design-extract/coulomb-social-icon-system.json @@ -0,0 +1,199 @@ +{ + "library": "unknown", + "confidence": 0, + "alternates": [], + "stats": { + "count": 55, + "strokeOnly": 0, + "fillOnly": 55, + "mixed": 0, + "avgStrokeWidth": 0, + "gridDistribution": {}, + "roundedCapsFraction": 0 + }, + "signals": [ + "fillDominant" + ], + "icons": [ + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + }, + { + "class": "", + "grid": null, + "strokeWidth": null, + "style": "fill" + } + ] +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-intent.json b/docs/design-extract/coulomb-social-intent.json new file mode 100644 index 0000000..4f54168 --- /dev/null +++ b/docs/design-extract/coulomb-social-intent.json @@ -0,0 +1,24 @@ +{ + "pageIntent": { + "type": "landing", + "confidence": 0.45, + "path": "/", + "title": "Research | Coulomb", + "description": "A tool to brainstorm, discuss, refine implement and promote ideas.\nA social network for building stuff and influencing how stuff is built.\nA marketplace for challenges, methods and solutions.\nA platfo", + "signals": [ + { + "kind": "url", + "type": "landing", + "weight": 0.45, + "detail": "root-path" + } + ], + "alternates": [], + "needsSmart": true + }, + "sectionRoles": { + "sections": [], + "counts": {}, + "readingOrder": [] + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-library.json b/docs/design-extract/coulomb-social-library.json new file mode 100644 index 0000000..4fc4ffb --- /dev/null +++ b/docs/design-extract/coulomb-social-library.json @@ -0,0 +1,12 @@ +{ + "library": "unknown", + "confidence": 0, + "evidence": [], + "alternates": [], + "signals": { + "tailwindLike": 0.136, + "radixAttrCount": 0, + "classSampleSize": 467 + }, + "needsSmart": true +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-mcp.json b/docs/design-extract/coulomb-social-mcp.json new file mode 100644 index 0000000..2bfad0e --- /dev/null +++ b/docs/design-extract/coulomb-social-mcp.json @@ -0,0 +1,275 @@ +{ + "colors": { + "all": [ + { + "hex": "#000000", + "rgb": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 0 + }, + "count": 5304, + "contexts": [ + "text", + "border", + "background" + ] + }, + { + "hex": "#efefef", + "rgb": { + "r": 239, + "g": 239, + "b": 239, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 94 + }, + "count": 610, + "contexts": [ + "background" + ] + }, + { + "hex": "#616161", + "rgb": { + "r": 97, + "g": 97, + "b": 97, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 38 + }, + "count": 556, + "contexts": [ + "text", + "border" + ] + }, + { + "hex": "#373737", + "rgb": { + "r": 55, + "g": 55, + "b": 55, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 22 + }, + "count": 462, + "contexts": [ + "text", + "border" + ] + }, + { + "hex": "#171717", + "rgb": { + "r": 23, + "g": 23, + "b": 23, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 9 + }, + "count": 401, + "contexts": [ + "text", + "border", + "background" + ] + }, + { + "hex": "#ffffff", + "rgb": { + "r": 255, + "g": 255, + "b": 255, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 100 + }, + "count": 242, + "contexts": [ + "background", + "border", + "text" + ] + }, + { + "hex": "#e5e5e5", + "rgb": { + "r": 229, + "g": 229, + "b": 229, + "a": 1 + }, + "hsl": { + "h": 0, + "s": 0, + "l": 90 + }, + "count": 217, + "contexts": [ + "border", + "background" + ] + }, + { + "hex": "#d08728", + "rgb": { + "r": 208, + "g": 135, + "b": 40, + "a": 1 + }, + "hsl": { + "h": 34, + "s": 68, + "l": 49 + }, + "count": 8, + "contexts": [ + "background" + ] + } + ] + }, + "regions": [], + "componentClusters": [ + { + "kind": "button", + "structuralHash": "button>svg", + "instanceCount": 55, + "variants": [ + { + "css": { + "background": "rgba(0, 0, 0, 0)", + "color": "rgb(55, 55, 55)", + "padding": "0px 0px 0px 0px", + "borderRadius": "4px", + "border": "0px none rgb(55, 55, 55)", + "fontSize": "13.3333px", + "fontWeight": "400" + }, + "instanceCount": 55 + } + ] + }, + { + "kind": "button", + "structuralHash": "button", + "instanceCount": 1, + "variants": [ + { + "css": { + "background": "rgb(239, 239, 239)", + "color": "rgb(0, 0, 0)", + "padding": "1px 6px 1px 6px", + "borderRadius": "0px", + "border": "2px outset rgb(0, 0, 0)", + "fontSize": "13.3333px", + "fontWeight": "400" + }, + "instanceCount": 1 + } + ] + } + ], + "accessibility": { + "remediation": [] + }, + "cssHealth": { + "sheets": [ + { + "url": "https://fonts.googleapis.com/css?family=Inter:300%7CInter:regular%7CInter:500%7CInter:600%7CInter:700", + "totalBytes": 11585, + "usedBytes": 0, + "unusedBytes": 11585, + "unusedPercent": 100 + }, + { + "url": "https://coulomb.social/package/run_css/0591b05f69514365ec03deea8134e9c2ff462a44dd0474f9fb551cb47e38e201/coulomb/live/vw_pages/xfalse/xfalse/run.css", + "totalBytes": 228282, + "usedBytes": 45959, + "unusedBytes": 182323, + "unusedPercent": 80 + }, + { + "url": "https://coulomb.social/vw_pages?resume=1786231781137x912895168994024000", + "totalBytes": 821, + "usedBytes": 0, + "unusedBytes": 821, + "unusedPercent": 100 + }, + { + "url": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.0/styles/default.min.css", + "totalBytes": 1144, + "usedBytes": 0, + "unusedBytes": 1144, + "unusedPercent": 100 + } + ], + "totalBytes": 241832, + "usedBytes": 45959, + "unusedBytes": 195873, + "unusedPercent": 81, + "importantCount": 140, + "duplicates": 6545, + "vendorPrefixes": { + "webkit": 139, + "moz": 436, + "ms": 96, + "o": 34 + }, + "keyframes": [ + { + "name": "highlight-in", + "steps": 1 + }, + { + "name": "fa-spin", + "steps": 2 + } + ], + "specificity": { + "max": [ + 1, + 7, + 46 + ], + "average": [ + 0, + 1.84, + 0.38 + ], + "count": 2001 + }, + "issues": [ + "140 !important rules", + "6545 duplicate declarations", + "81% unused CSS" + ] + } +} \ No newline at end of file diff --git a/docs/design-extract/tokens/motion-tokens.json b/docs/design-extract/coulomb-social-motion-tokens.json similarity index 59% rename from docs/design-extract/tokens/motion-tokens.json rename to docs/design-extract/coulomb-social-motion-tokens.json index 404619d..357ae54 100644 --- a/docs/design-extract/tokens/motion-tokens.json +++ b/docs/design-extract/coulomb-social-motion-tokens.json @@ -1,6 +1,12 @@ { "$description": "Motion tokens extracted by designlang", - "duration": {}, + "duration": { + "sm": { + "$value": "250ms", + "$type": "duration", + "ms": 250 + } + }, "easing": {}, "spring": {}, "$meta": { diff --git a/docs/design-extract/coulomb-social-motion.css b/docs/design-extract/coulomb-social-motion.css new file mode 100644 index 0000000..349be56 --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.css @@ -0,0 +1,38 @@ +/* Motion CSS — generated by designlang (motionlang) + * Source: https://coulomb.social + * 2026-08-08T23:30:22.011Z + * + * + *
+ */ + +:root { + --duration-sm: 250ms; + --ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1); +} + +@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } +@keyframes slide-up { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } } +@keyframes scale-in { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } } +@keyframes pop { 0% { transform: scale(0.9); } 60% { transform: scale(1.03); } 100% { transform: scale(1); } } + +.mo-animate, +[class^="mo-"], [class*=" mo-"] { + animation-duration: var(--duration-sm, 250ms); + animation-timing-function: var(--ease-standard); + animation-fill-mode: both; +} + +.mo-fade-in { animation-name: fade-in; } +.mo-slide-up { animation-name: slide-up; } +.mo-scale-in { animation-name: scale-in; } +.mo-pop { animation-name: pop; animation-timing-function: var(--ease-standard); } + +@media (prefers-reduced-motion: reduce) { + *, ::before, ::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} diff --git a/docs/design-extract/coulomb-social-motion.framer.js b/docs/design-extract/coulomb-social-motion.framer.js new file mode 100644 index 0000000..fb6691c --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.framer.js @@ -0,0 +1,70 @@ +// Framer Motion presets — generated by designlang (motionlang) +// Source: https://coulomb.social +// 2026-08-08T23:30:22.009Z +// +// import { transitions, variants } from './coulomb.social-motion.framer'; +// + +/** Easing curves extracted from the live page, as Framer cubic-bezier arrays. */ +export const easings = { + standard: [0.25, 1, 0.5, 1], +}; + +/** Duration presets (seconds), extracted from the live page. */ +export const durations = { + sm: 0.25, +}; + +/** Spring presets — pass to a Framer Motion `transition` prop. */ +export const springs = { + soft: { type: 'spring', stiffness: 320, damping: 30, mass: 1 }, +}; + +/** Ready-to-spread Framer Motion transition objects. */ +export const transitions = { + base: { duration: 0.25, ease: easings.standard }, + fast: { duration: 0.125, ease: easings.standard }, + slow: { duration: 0.450, ease: easings.standard }, + spring: springs.soft, +}; + +/** Common variants wired to the extracted timing. */ +export const variants = { + fade: { + hidden: { opacity: 0 }, + show: { opacity: 1, transition: transitions.base }, + }, + slideUp: { + hidden: { opacity: 0, y: 16 }, + show: { opacity: 1, y: 0, transition: transitions.base }, + }, + scaleIn: { + hidden: { opacity: 0, scale: 0.96 }, + show: { opacity: 1, scale: 1, transition: transitions.base }, + }, + pop: { + hidden: { opacity: 0, scale: 0.9 }, + show: { opacity: 1, scale: 1, transition: springs.soft }, + }, + stagger: { + hidden: {}, + show: { transition: { staggerChildren: 0.063 } }, + }, +}; + +/** Site uses scroll- or view-timeline. Drop-in `whileInView` props. */ +export const inView = { + fadeIn: { + initial: variants.fade.hidden, + whileInView: variants.fade.show, + viewport: { once: true, amount: 0.3 }, + }, + riseIn: { + initial: variants.slideUp.hidden, + whileInView: variants.slideUp.show, + viewport: { once: true, amount: 0.3 }, + }, +}; + +export default { easings, durations, springs, transitions, variants, inView }; diff --git a/docs/design-extract/coulomb-social-motion.gsap.js b/docs/design-extract/coulomb-social-motion.gsap.js new file mode 100644 index 0000000..a7c884e --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.gsap.js @@ -0,0 +1,49 @@ +// GSAP presets — generated by designlang (motionlang) +// Source: https://coulomb.social +// 2026-08-08T23:30:22.015Z +// +// import gsap from 'gsap'; +// import { registerEases, reveals } from './coulomb.social-motion.gsap.js'; +// registerEases(gsap); // one-time: registers CustomEases +// reveals.slideUp('.card'); + +/** CustomEase path data extracted from the live page, keyed by family. */ +export const eases = { + standard: 'M0,0 C0.25,0.1 0.25,1 1,1', +}; + +/** Duration presets (seconds), extracted from the live page. */ +export const durations = { + sm: 0.25, +}; + +/** Register every extracted curve as a named GSAP CustomEase. Call once. */ +export function registerEases(gsap) { + const CustomEase = gsap.plugins?.CustomEase || (typeof window !== 'undefined' && window.CustomEase); + if (!CustomEase) { + console.warn('[motion.gsap] CustomEase plugin not registered — call gsap.registerPlugin(CustomEase) first.'); + return; + } + for (const [name, path] of Object.entries(eases)) CustomEase.create(name, path); +} + +/** gsap.from() reveal helpers. Pass any GSAP target + optional vars override. */ +export const reveals = { + fadeIn: (target, vars = {}) => gsap.from(target, { opacity: 0, duration: 0.25, ease: 'standard', ...vars }), + slideUp: (target, vars = {}) => gsap.from(target, { opacity: 0, y: 24, duration: 0.25, ease: 'standard', ...vars }), + slideDown: (target, vars = {}) => gsap.from(target, { opacity: 0, y: -24, duration: 0.25, ease: 'standard', ...vars }), + scaleIn: (target, vars = {}) => gsap.from(target, { opacity: 0, scale: 0.96, duration: 0.25, ease: 'standard', ...vars }), + pop: (target, vars = {}) => gsap.from(target, { scale: 0.9, duration: 0.25, ease: 'standard', ...vars }), +}; + +/** Site uses scroll-/view-timeline. Batch-reveals elements as they enter. */ +/** Requires: gsap.registerPlugin(ScrollTrigger). */ +export function revealOnScroll(targets, vars = {}) { + return gsap.utils.toArray(targets).map((el) => + gsap.from(el, { + opacity: 0, y: 24, duration: 0.25, ease: 'standard', ...vars, + scrollTrigger: { trigger: el, start: 'top 85%', toggleActions: 'play none none reverse' }, + })); +} + +export default { eases, durations, registerEases, reveals }; diff --git a/docs/design-extract/coulomb-social-motion.html b/docs/design-extract/coulomb-social-motion.html new file mode 100644 index 0000000..bbeef60 --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.html @@ -0,0 +1,138 @@ + + + + + +coulomb.social — motion lab · designlang + + + +
+
+

motionlang · motion lab

+

coulomb.social in motion

+

Every easing curve, duration and keyframe animation designlang read off the live coulomb.social page — drawn, timed and replayed. Generated 2026-08-08.

+
+ +

Easing curves

+
No easing curves detected. Re-run with --interactions to capture hover transitions.
+ +

Durations

+
+
+ sm + + 250ms +
+ +

Keyframe animations

+ +
+
@keyframes highlight-in
+

+    
+
+
@keyframes fa-spin
+

+    
+
+
@keyframes opacity-70-25-0-13
+

+    
+
+
@keyframes opacity-70-25-1-13
+

+    
+
+
@keyframes opacity-70-25-2-13
+

+    
+
+
@keyframes opacity-70-25-3-13
+

+    
+
+
@keyframes opacity-70-25-4-13
+

+    
+
+
@keyframes opacity-70-25-5-13
+

+    
+
+
@keyframes opacity-70-25-6-13
+

+    
+
+
@keyframes opacity-70-25-7-13
+

+    
+
+
@keyframes opacity-70-25-8-13
+

+    
+
+
@keyframes opacity-70-25-9-13
+

+    
+ +
+ Generated by designlang · motionlang · designlang.app · re-extract with npx designlang coulomb.social --motion +
+
+ + \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-motion.one.js b/docs/design-extract/coulomb-social-motion.one.js new file mode 100644 index 0000000..4749f54 --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.one.js @@ -0,0 +1,58 @@ +// Motion One presets — generated by designlang (motionlang) +// Source: https://coulomb.social +// 2026-08-08T23:30:22.010Z +// +// import { animate } from 'motion'; +// import { animations, easings, durations } from './coulomb.social-motion.one.js'; +// +// animations.fadeIn('#hero'); +// animations.slideUp('.card', { delay: 0.1 }); + +/** Easing curves extracted from the live page, as Motion One cubic-bezier arrays. */ +export const easings = { + standard: [0.25, 0.1, 0.25, 1], +}; + +/** Duration presets (seconds), extracted from the live page. */ +export const durations = { + sm: 0.25, +}; + +/** Motion One spring options — pass as the `type: 'spring'` block of an animate() call. */ +export const springs = { + soft: { type: 'spring', stiffness: 320, damping: 30, mass: 1 }, +}; + +/** No on-page @keyframes were attached to elements; emit empty for shape parity. */ +export const keyframes = {}; + +/** Animate-on-call helpers. Each takes a Motion One target + optional override. */ +import { animate } from 'motion'; + +const _t = { duration: 0.25, easing: easings.standard }; + +export const animations = { + fadeIn: (target, opts = {}) => + animate(target, { opacity: [0, 1] }, { ..._t, ...opts }), + fadeOut: (target, opts = {}) => + animate(target, { opacity: [1, 0] }, { ..._t, ...opts }), + slideUp: (target, opts = {}) => + animate(target, { opacity: [0, 1], y: [16, 0] }, { ..._t, ...opts }), + slideDown: (target, opts = {}) => + animate(target, { opacity: [0, 1], y: [-16, 0] }, { ..._t, ...opts }), + scaleIn: (target, opts = {}) => + animate(target, { opacity: [0, 1], scale: [0.96, 1] }, { ..._t, ...opts }), + pop: (target, opts = {}) => + animate(target, { scale: [0.9, 1] }, { ...springs.soft, ...opts }), +}; + +/** Site uses scroll- or view-timeline. Helpers wired to Motion One's `inView` / `scroll`. */ +import { inView, scroll } from 'motion'; + +export const enterOnView = (target, variant = animations.slideUp) => + inView(target, (el) => { variant(el.target); }); + +export const parallaxY = (target, distance = 80) => + scroll(animate(target, { y: [0, -distance] }, { easing: 'linear' })); + +export default { easings, durations, springs, keyframes, animations }; diff --git a/docs/design-extract/coulomb-social-motion.tailwind.js b/docs/design-extract/coulomb-social-motion.tailwind.js new file mode 100644 index 0000000..04f0524 --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.tailwind.js @@ -0,0 +1,67 @@ +// Tailwind motion preset — generated by designlang (motionlang) +// Source: https://coulomb.social +// 2026-08-08T23:30:22.014Z +// +// Merge `extend` into your tailwind.config theme.extend, e.g.: +// const motion = require('./coulomb.social-motion.tailwind'); +// module.exports = { theme: { extend: { ...motion.extend } } }; +// +// Then:
or `duration-md ease-spring`. + +const extend = { + "transitionDuration": { + "sm": "250ms" + }, + "transitionTimingFunction": { + "standard": "cubic-bezier(0.25, 0.1, 0.25, 1)" + }, + "keyframes": { + "fade-in": { + "0%": { + "opacity": "0" + }, + "100%": { + "opacity": "1" + } + }, + "slide-up": { + "0%": { + "opacity": "0", + "transform": "translateY(16px)" + }, + "100%": { + "opacity": "1", + "transform": "none" + } + }, + "scale-in": { + "0%": { + "opacity": "0", + "transform": "scale(0.96)" + }, + "100%": { + "opacity": "1", + "transform": "none" + } + }, + "pop": { + "0%": { + "transform": "scale(0.9)" + }, + "60%": { + "transform": "scale(1.03)" + }, + "100%": { + "transform": "scale(1)" + } + } + }, + "animation": { + "fade-in": "fade-in 250ms var(--tw-ease-standard, cubic-bezier(0.25, 0.1, 0.25, 1)) both", + "slide-up": "slide-up 250ms var(--tw-ease-standard, cubic-bezier(0.25, 0.1, 0.25, 1)) both", + "scale-in": "scale-in 250ms var(--tw-ease-standard, cubic-bezier(0.25, 0.1, 0.25, 1)) both", + "pop": "pop 250ms var(--tw-ease-standard, cubic-bezier(0.25, 0.1, 0.25, 1)) both" + } +}; + +module.exports = { extend }; diff --git a/docs/design-extract/coulomb-social-motion.waapi.js b/docs/design-extract/coulomb-social-motion.waapi.js new file mode 100644 index 0000000..ef0b25c --- /dev/null +++ b/docs/design-extract/coulomb-social-motion.waapi.js @@ -0,0 +1,44 @@ +// Web Animations API presets — generated by designlang (motionlang) +// Source: https://coulomb.social +// 2026-08-08T23:30:22.016Z +// +// Zero-dependency. Runs on the browser-native Element.animate(). +// import { animations } from './coulomb.social-motion.waapi.js'; +// animations.fadeIn(document.querySelector('#hero')); +// await animations.slideUp(card, { delay: 80 }).finished; + +/** Easing curves extracted from the live page, as WAAPI easing strings. */ +export const easings = { + standard: 'cubic-bezier(0.25, 0.1, 0.25, 1)', +}; + +/** Duration presets (milliseconds), extracted from the live page. */ +export const durations = { + sm: 250, +}; + +/** No on-page @keyframes were attached to elements; emit empty for shape parity. */ +export const keyframes = {}; + +/** Honours the user's reduced-motion preference. */ +export const prefersReducedMotion = () => + typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches; + +const _timing = { duration: 250, easing: easings.standard, fill: 'both' }; + +function _animate(el, frames, opts = {}) { + const timing = { ..._timing, ...opts }; + if (prefersReducedMotion()) timing.duration = 0; + return el.animate(frames, timing); +} + +/** Animate-on-call helpers. Each returns the live Animation (await `.finished`). */ +export const animations = { + fadeIn: (el, opts = {}) => _animate(el, [{ opacity: 0 }, { opacity: 1 }], opts), + fadeOut: (el, opts = {}) => _animate(el, [{ opacity: 1 }, { opacity: 0 }], opts), + slideUp: (el, opts = {}) => _animate(el, [{ opacity: 0, transform: 'translateY(16px)' }, { opacity: 1, transform: 'translateY(0)' }], opts), + slideDown: (el, opts = {}) => _animate(el, [{ opacity: 0, transform: 'translateY(-16px)' }, { opacity: 1, transform: 'translateY(0)' }], opts), + scaleIn: (el, opts = {}) => _animate(el, [{ opacity: 0, transform: 'scale(0.96)' }, { opacity: 1, transform: 'scale(1)' }], opts), +}; + +export default { easings, durations, keyframes, animations, prefersReducedMotion }; diff --git a/docs/design-extract/coulomb-social-preview.html b/docs/design-extract/coulomb-social-preview.html new file mode 100644 index 0000000..612241e --- /dev/null +++ b/docs/design-extract/coulomb-social-preview.html @@ -0,0 +1,433 @@ + + + + + +Design Language: Research | Coulomb + + + +
+ +
+

Research | Coulomb

+ +
+
+ https://coulomb.social + 3445 elements + 8/9/2026 + 7 pages crawled +
+ +
+
8
Colors
+
4
Font Families
+
8
Spacing Values
+
2
Shadows
+
5
Border Radii
+
5
Components
+
100%
A11y Score
+
+ + +

Color Palette

+ + +

Brand Colors

+
+
+
+
+
#d08728
+
Primary
+
8 uses
+
+
+ + +
+ + +

Neutrals

+
+
+
+
+
#000000
+ +
5304 uses
+
+
+
+
+
+
#efefef
+ +
610 uses
+
+
+
+
+
+
#616161
+ +
556 uses
+
+
+
+
+
+
#373737
+ +
462 uses
+
+
+
+
+
+
#171717
+ +
401 uses
+
+
+
+
+
+
#ffffff
+ +
242 uses
+
+
+
+
+
+
#e5e5e5
+ +
217 uses
+
+
+
+ + +

Full Palette

+
+
+
+
+
#000000
+
text, border, background
+
5304 uses
+
+
+
+
+
+
#efefef
+
background
+
610 uses
+
+
+
+
+
+
#616161
+
text, border
+
556 uses
+
+
+
+
+
+
#373737
+
text, border
+
462 uses
+
+
+
+
+
+
#171717
+
text, border, background
+
401 uses
+
+
+
+
+
+
#ffffff
+
background, border, text
+
242 uses
+
+
+
+
+
+
#e5e5e5
+
border, background
+
217 uses
+
+
+
+
+
+
#d08728
+
background
+
8 uses
+
+
+
+ + + + +

Typography

+ + +

Font Families

+
+ Helvetica (body, 1739x)Arial (body, 761x)Times New Roman (body, 450x)Inter (body, 397x) +
+ + +

Type Scale

+
+ +
+ 50px + The quick brown fox + 400 / 50px +
+
+ 42px + The quick brown fox + 700 / normal +
+
+ 24px + The quick brown fox + 600 / 36px +
+
+ 18px + The quick brown fox + 600 / 18px +
+
+ 16px + The quick brown fox + 400 / normal +
+
+ 14px + The quick brown fox + 500 / 19.6px +
+
+ 13.3333px + The quick brown fox + 400 / normal +
+
+ + + +

Spacing Scale (base: 4px)

+
+ +
+ 1px +
+
+
+ 24px +
+
+
+ 32px +
+
+
+ 40px +
+
+
+ 60px +
+
+
+ 80px +
+
+
+ 96px +
+
+
+ 320px +
+
+
+ + + +

Box Shadows

+
+ +
+ sm +
+
+ md +
+
+ + + +

Border Radii

+
+ +
+
4px
+
sm
+
+
+
8px
+
md
+
+
+
12px
+
lg
+
+
+
15px
+
lg
+
+
+
20px
+
xl
+
+
+ + + +

Accessibility

+
+
100%
+
+
WCAG Contrast Score
+
0 passing / 0 failing color pairs
+
+
+ +

Color Pair Analysis

+ + + + + + +
+ + + \ No newline at end of file diff --git a/docs/design-extract/prompts/claude-artifacts.md b/docs/design-extract/coulomb-social-prompts/claude-artifacts.md similarity index 58% rename from docs/design-extract/prompts/claude-artifacts.md rename to docs/design-extract/coulomb-social-prompts/claude-artifacts.md index 1da09db..b3b9c02 100644 --- a/docs/design-extract/prompts/claude-artifacts.md +++ b/docs/design-extract/coulomb-social-prompts/claude-artifacts.md @@ -1,10 +1,10 @@ Create a React artifact that reproduces this brand's design language. Page intent: landing. Material language: flat. -Voice: Tone: neutral · Headings: unknown. -Colors to use: #000000, #171717, #d08728, #ffffff, #616161, #e5e5e5. +Voice: Tone: neutral · Headings: unknown · CTA verbs: [object Object], [object Object], [object Object], [object Object], [object Object], [object Object]. +Colors to use: #000000, #efefef, #616161, #373737, #171717, #ffffff, #e5e5e5, #d08728. Fonts: [object Object], [object Object], [object Object], [object Object]. -Radius vocabulary: 4, 8. +Radius vocabulary: 4, 8, 12, 15, 20. Sections: - hero - features diff --git a/docs/design-extract/coulomb-social-prompts/cursor.md b/docs/design-extract/coulomb-social-prompts/cursor.md new file mode 100644 index 0000000..c532f00 --- /dev/null +++ b/docs/design-extract/coulomb-social-prompts/cursor.md @@ -0,0 +1,18 @@ +# Design brief +Page type: **landing**. +Material language: **flat**. +Voice: Tone: neutral · Headings: unknown · CTA verbs: [object Object], [object Object], [object Object], [object Object], [object Object], [object Object]. +## Tokens +```ts +export const tokens = { + colors: ['#000000', '#efefef', '#616161', '#373737', '#171717', '#ffffff', '#e5e5e5', '#d08728'], + fonts: ['[object Object]', '[object Object]', '[object Object]', '[object Object]'], + radii: ['4', '8', '12', '15', '20'], + shadows: ['rgb(170, 170, 170) 2px 2px 4px 0px', 'rgba(23, 23, 23, 0.1) 2px 2px 8px 2px'], +}; +``` +## Sections +- hero +- features +- cta +- footer \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-prompts/lovable.txt b/docs/design-extract/coulomb-social-prompts/lovable.txt new file mode 100644 index 0000000..5569421 --- /dev/null +++ b/docs/design-extract/coulomb-social-prompts/lovable.txt @@ -0,0 +1,12 @@ +Clone the design language of this landing page and build a fresh equivalent. +Visual feel: flat. Tone: neutral · Headings: unknown · CTA verbs: [object Object], [object Object], [object Object], [object Object], [object Object], [object Object] +Primary palette: #000000, #efefef, #616161, #373737, #171717. +Typography: [object Object], [object Object], [object Object], [object Object]. +Corner radius vocabulary: 4, 8, 12, 15, 20. +Shadow vocabulary: rgb(170, 170, 170) 2px 2px 4px 0px | rgba(23, 23, 23, 0.1) 2px 2px 8px 2px. +Page structure: +- hero +- features +- social proof +- cta +- footer \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-prompts/recipe-button.md b/docs/design-extract/coulomb-social-prompts/recipe-button.md new file mode 100644 index 0000000..142496f --- /dev/null +++ b/docs/design-extract/coulomb-social-prompts/recipe-button.md @@ -0,0 +1,28 @@ +# Recipe: button +Build one button component that matches this brand. +Palette: #000000, #efefef, #616161, #373737, #171717, #ffffff +Typography: [object Object], [object Object], [object Object], [object Object] +Material: flat +Signals: Radius: 4, 8, 12, 15, 20 · Shadows: rgb(170, 170, 170) 2px 2px 4px 0px | rgba(23, 23, 23, 0.1) 2px 2px 8px 2px +## Anatomy (detected) +```json +{ + "kind": "button", + "structuralHash": "button", + "instanceCount": 1, + "variants": [ + { + "css": { + "background": "rgb(239, 239, 239)", + "color": "rgb(0, 0, 0)", + "padding": "1px 6px 1px 6px", + "borderRadius": "0px", + "border": "2px outset rgb(0, 0, 0)", + "fontSize": "13.3333px", + "fontWeight": "400" + }, + "instanceCount": 1 + } + ] +} +``` \ No newline at end of file diff --git a/docs/design-extract/prompts/v0.txt b/docs/design-extract/coulomb-social-prompts/v0.txt similarity index 52% rename from docs/design-extract/prompts/v0.txt rename to docs/design-extract/coulomb-social-prompts/v0.txt index 150772c..a5ca0ac 100644 --- a/docs/design-extract/prompts/v0.txt +++ b/docs/design-extract/coulomb-social-prompts/v0.txt @@ -1,17 +1,19 @@ Build a landing page with this exact visual language. COLORS: #000000 - #171717 - #d08728 - #ffffff + #efefef #616161 + #373737 + #171717 + #ffffff #e5e5e5 + #d08728 FONTS: [object Object], [object Object], [object Object], [object Object] -SPACING: 2, 32, 68 -RADIUS: 4, 8 -SHADOWS: rgb(97, 97, 97) 2px 2px 8px 0px +SPACING: 1, 24, 32, 40, 60, 80, 96, 320 +RADIUS: 4, 8, 12, 15, 20 +SHADOWS: rgb(170, 170, 170) 2px 2px 4px 0px | rgba(23, 23, 23, 0.1) 2px 2px 8px 2px MATERIAL LANGUAGE: flat -VOICE: Tone: neutral · Headings: unknown +VOICE: Tone: neutral · Headings: unknown · CTA verbs: [object Object], [object Object], [object Object], [object Object], [object Object], [object Object] SECTIONS (in order): - hero - features diff --git a/docs/design-extract/coulomb-social-reset.css b/docs/design-extract/coulomb-social-reset.css new file mode 100644 index 0000000..b9f0c50 --- /dev/null +++ b/docs/design-extract/coulomb-social-reset.css @@ -0,0 +1,81 @@ +/* ────────────────────────────────────────────────────────────── + Brand-aware reset — generated by designlang + Research | Coulomb + 2026-08-08T23:30:22.005Z + ────────────────────────────────────────────────────────────── */ + +*, *::before, *::after { box-sizing: border-box; } + +html, body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, blockquote, figure, +form, fieldset, table, hr { + margin: 0; + padding: 0; +} + +html { + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; + font-family: "Helvetica", system-ui, -apple-system, 'Segoe UI', sans-serif; + font-size: 16px; + line-height: 1.5; +} + +body { + background-color: #ffffff; + color: #000000; + font-weight: 400; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +h1, h2, h3, h4, h5, h6 { + font-family: "Helvetica", system-ui, -apple-system, sans-serif; + font-weight: 600; + line-height: 1.15; + letter-spacing: -0.015em; +} + +a { + color: #d08728; + text-decoration: none; + background-color: transparent; +} +a:hover { text-decoration: underline; } +a:focus-visible { outline: 2px solid #d08728; outline-offset: 2px; border-radius: 4px; } + +img, picture, video, canvas, svg { + display: block; + max-width: 100%; + height: auto; +} + +input, textarea, select, button { + font: inherit; + color: inherit; +} +button { cursor: pointer; background: none; border: 0; padding: 0; } + +code, pre, kbd, samp { + font-family: ui-monospace, ui-monospace, 'SF Mono', Menlo, monospace; +} + +hr { + border: 0; + border-top: 1px solid #e5e5e5; +} + +::selection { + background: #d08728; + color: #ffffff; +} + +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.001ms !important; + transition-duration: 0.001ms !important; + scroll-behavior: auto !important; + } +} diff --git a/docs/design-extract/coulomb-social-routes-report.md b/docs/design-extract/coulomb-social-routes-report.md new file mode 100644 index 0000000..6acd239 --- /dev/null +++ b/docs/design-extract/coulomb-social-routes-report.md @@ -0,0 +1,15 @@ +# Multi-route Token Reconciliation + +- Routes crawled: **7** +- Shared tokens: **17** +- Total unique tokens across routes: **41** +- Cross-route drift entries: **148** + +## Per-route contributions +- `/` (index): 0 added, 19 changed +- `/pg_chunk/1786106348475x662489469743530000` (pg-chunk-1786106348475x662489469743530000): 1 added, 22 changed +- `/pg_chunk/1767965374100x901547861536145400` (pg-chunk-1767965374100x901547861536145400): 0 added, 21 changed +- `/pg_chunk/1785501151364x921456713843343400` (pg-chunk-1785501151364x921456713843343400): 0 added, 21 changed +- `/pg_chunk/1784904857383x503270614975381500` (pg-chunk-1784904857383x503270614975381500): 0 added, 22 changed +- `/pg_chunk/1785501127011x363256181345746940` (pg-chunk-1785501127011x363256181345746940): 0 added, 21 changed +- `/pg_chunk/1784305925912x322414739506593800` (pg-chunk-1784305925912x322414739506593800): 0 added, 22 changed diff --git a/docs/design-extract/coulomb-social-seo.json b/docs/design-extract/coulomb-social-seo.json new file mode 100644 index 0000000..4d3fe62 --- /dev/null +++ b/docs/design-extract/coulomb-social-seo.json @@ -0,0 +1,40 @@ +{ + "openGraph": { + "title": "An Ideas Come To Life Community!", + "site_name": "Coulomb Social", + "description": "A tool to brainstorm, discuss, refine implement and promote ideas.\nA social network for building stuff and influencing how stuff is built.\nA marketplace for challenges, methods and solutions.\nA platform to monetize curiosity.", + "image": "https://13a55be71f3a6a4c9ea356833df823c4.cdn.bubble.io/cdn-cgi/image/w=,h=,f=auto,dpr=1,fit=contain/f1750630995632x205964292977919070/Coulomb%20Logo.png", + "url": "https://coulomb.social/vw_pages?resume=1786231781137x912895168994024000", + "type": "website" + }, + "twitter": { + "title": "An Ideas Come To Life Community!", + "site_name": "Coulomb Social", + "description": "A tool to brainstorm, discuss, refine implement and promote ideas.\nA social network for building stuff and influencing how stuff is built.\nA marketplace for challenges, methods and solutions.\nA platform to monetize curiosity.", + "image:src": "https://13a55be71f3a6a4c9ea356833df823c4.cdn.bubble.io/cdn-cgi/image/w=,h=,f=auto,dpr=1,fit=contain/f1750630995632x205964292977919070/Coulomb%20Logo.png", + "card": "summary_large_image" + }, + "description": "A tool to brainstorm, discuss, refine implement and promote ideas.\nA social network for building stuff and influencing how stuff is built.\nA marketplace for challenges, methods and solutions.\nA platform to monetize curiosity.", + "canonical": null, + "themeColor": null, + "viewport": "width=device-width,initial-scale=1.0", + "favicons": [ + { + "rel": "icon", + "href": "https://13a55be71f3a6a4c9ea356833df823c4.cdn.bubble.io/cdn-cgi/image/w=128,h=,f=auto,dpr=1,fit=contain/f1738533145653x421346820735372100/Coulomb%20Logo.png", + "sizes": "", + "type": "image/png" + } + ], + "manifest": null, + "structuredData": [], + "score": { + "hasOg": true, + "hasTwitter": true, + "hasDescription": true, + "hasCanonical": false, + "hasStructuredData": false, + "hasFavicon": true, + "hasThemeColor": false + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-shadcn-theme.css b/docs/design-extract/coulomb-social-shadcn-theme.css new file mode 100644 index 0000000..4dd69bd --- /dev/null +++ b/docs/design-extract/coulomb-social-shadcn-theme.css @@ -0,0 +1,15 @@ +/* shadcn/ui Theme — extracted from https://coulomb.social */ +/* Paste into your globals.css */ + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 0 0% 0%; + --primary: 34 68% 49%; + --primary-foreground: 0 0% 100%; + --muted: 0 0% 90%; + --muted-foreground: 0 0% 0%; + --border: 0 0% 9%; + --radius: 8px; + } +} diff --git a/docs/design-extract/coulomb-social-stack-intel.json b/docs/design-extract/coulomb-social-stack-intel.json new file mode 100644 index 0000000..2457150 --- /dev/null +++ b/docs/design-extract/coulomb-social-stack-intel.json @@ -0,0 +1,12 @@ +{ + "cms": [ + "webflow", + "bubble" + ], + "analytics": [], + "experimentation": [], + "signals": { + "scriptCount": 10, + "metaCount": 15 + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tailwind-v4.css b/docs/design-extract/coulomb-social-tailwind-v4.css new file mode 100644 index 0000000..2bfe39b --- /dev/null +++ b/docs/design-extract/coulomb-social-tailwind-v4.css @@ -0,0 +1,55 @@ +/* ────────────────────────────────────────────────────────────── + Tailwind v4 @theme — generated by designlang + site: Research | Coulomb + 2026-08-08T23:30:22.003Z + Drop this above `@import "tailwindcss";`. + ────────────────────────────────────────────────────────────── */ + +@import "tailwindcss"; + +@theme { + --color-primary-50: hsl(34 68% 97%); + --color-primary-100: hsl(34 68% 94%); + --color-primary-200: hsl(34 68% 86%); + --color-primary-300: hsl(34 68% 76%); + --color-primary-400: hsl(34 68% 64%); + --color-primary-500: hsl(34 68% 50%); + --color-primary-600: hsl(34 68% 40%); + --color-primary-700: hsl(34 68% 32%); + --color-primary-800: hsl(34 68% 24%); + --color-primary-900: hsl(34 68% 16%); + --color-primary-950: hsl(34 68% 10%); + --color-primary: #d08728; + --color-neutral-50: #000000; + --color-neutral-100: #efefef; + --color-neutral-200: #616161; + --color-neutral-300: #373737; + --color-neutral-400: #171717; + --color-neutral-500: #ffffff; + --color-neutral-600: #e5e5e5; + --color-background: #ffffff; + --color-foreground: #000000; + --font-sans: "Helvetica", system-ui, sans-serif; + --spacing-1: 1px; + --spacing-2: 24px; + --spacing-3: 32px; + --spacing-4: 40px; + --spacing-5: 60px; + --spacing-6: 80px; + --spacing-7: 96px; + --spacing-8: 320px; + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 15px; + --radius-2xl: 20px; + --shadow-sm: rgb(170, 170, 170) 2px 2px 4px 0px; + --shadow-md: rgba(23, 23, 23, 0.1) 2px 2px 8px 2px; + --animate-duration-fast: undefined; +} + +/* Optional base reset that maps body/heading to the extracted tokens. */ +@layer base { + html { font-family: var(--font-sans); } + body { background-color: var(--color-background); color: var(--color-foreground, currentColor); } +} diff --git a/docs/design-extract/tokens/tailwind.config.js b/docs/design-extract/coulomb-social-tailwind.config.js similarity index 63% rename from docs/design-extract/tokens/tailwind.config.js rename to docs/design-extract/coulomb-social-tailwind.config.js index fc46802..f260b6a 100644 --- a/docs/design-extract/tokens/tailwind.config.js +++ b/docs/design-extract/coulomb-social-tailwind.config.js @@ -18,36 +18,22 @@ export default { DEFAULT: '#d08728' }, 'neutral-50': '#000000', - 'neutral-100': '#171717', - 'neutral-200': '#ffffff', - 'neutral-300': '#616161', - 'neutral-400': '#e5e5e5', + 'neutral-100': '#efefef', + 'neutral-200': '#616161', + 'neutral-300': '#373737', + 'neutral-400': '#171717', + 'neutral-500': '#ffffff', + 'neutral-600': '#e5e5e5', background: '#ffffff', foreground: '#000000' }, fontFamily: { body: [ - 'Arial', - 'sans-serif' - ], - font2: [ 'Inter', 'sans-serif' ] }, fontSize: { - '8': [ - '8px', - { - lineHeight: '11.2px' - } - ], - '12': [ - '12px', - { - lineHeight: '16.8px' - } - ], '14': [ '14px', { @@ -63,19 +49,25 @@ export default { '18': [ '18px', { - lineHeight: '25.2px' + lineHeight: '18px' } ], - '32': [ - '32px', + '24': [ + '24px', { - lineHeight: '44.8px' + lineHeight: '36px' } ], - '48': [ - '48px', + '42': [ + '42px', { - lineHeight: '67.2px' + lineHeight: 'normal' + } + ], + '50': [ + '50px', + { + lineHeight: '50px' } ], '13.3333': [ @@ -86,23 +78,34 @@ export default { ] }, spacing: { - '1': '2px', - '16': '32px', - '34': '68px' + '6': '24px', + '8': '32px', + '10': '40px', + '15': '60px', + '20': '80px', + '24': '96px', + '80': '320px', + '1px': '1px' }, borderRadius: { sm: '4px', - md: '8px' + md: '8px', + lg: '15px', + xl: '20px' }, boxShadow: { - md: 'rgb(97, 97, 97) 2px 2px 8px 0px' + sm: 'rgb(170, 170, 170) 2px 2px 4px 0px', + md: 'rgba(23, 23, 23, 0.1) 2px 2px 8px 2px' + }, + transitionDuration: { + '250': '0.25s' }, container: { center: true, - padding: '32px' + padding: '0px' }, maxWidth: { - container: '1080px' + container: '1200px' } }, }, diff --git a/docs/design-extract/tokens/theme.js b/docs/design-extract/coulomb-social-theme.js similarity index 62% rename from docs/design-extract/tokens/theme.js rename to docs/design-extract/coulomb-social-theme.js index 0f65492..4dd24f0 100644 --- a/docs/design-extract/tokens/theme.js +++ b/docs/design-extract/coulomb-social-theme.js @@ -14,30 +14,39 @@ neutral200: string; neutral300: string; neutral400: string; + neutral500: string; + neutral600: string; * }; * fonts: { body: string; * }; * fontSizes: { - '8': string; - '12': string; '14': string; '16': string; '18': string; - '32': string; - '48': string; + '24': string; + '42': string; + '50': string; '13.3333': string; * }; * space: { - '2': string; + '1': string; + '24': string; '32': string; - '68': string; + '40': string; + '60': string; + '80': string; + '96': string; + '320': string; * }; * radii: { sm: string; md: string; + lg: string; + xl: string; * }; * shadows: { + sm: string; md: string; * }; * states: { @@ -55,35 +64,44 @@ export const theme = { "background": "#ffffff", "foreground": "#000000", "neutral50": "#000000", - "neutral100": "#171717", - "neutral200": "#ffffff", - "neutral300": "#616161", - "neutral400": "#e5e5e5" + "neutral100": "#efefef", + "neutral200": "#616161", + "neutral300": "#373737", + "neutral400": "#171717", + "neutral500": "#ffffff", + "neutral600": "#e5e5e5" }, "fonts": { - "body": "'Arial', sans-serif" + "body": "'Inter', sans-serif" }, "fontSizes": { - "8": "8px", - "12": "12px", "14": "14px", "16": "16px", "18": "18px", - "32": "32px", - "48": "48px", + "24": "24px", + "42": "42px", + "50": "50px", "13.3333": "13.3333px" }, "space": { - "2": "2px", + "1": "1px", + "24": "24px", "32": "32px", - "68": "68px" + "40": "40px", + "60": "60px", + "80": "80px", + "96": "96px", + "320": "320px" }, "radii": { "sm": "4px", - "md": "8px" + "md": "8px", + "lg": "15px", + "xl": "20px" }, "shadows": { - "md": "rgb(97, 97, 97) 2px 2px 8px 0px" + "sm": "rgb(170, 170, 170) 2px 2px 4px 0px", + "md": "rgba(23, 23, 23, 0.1) 2px 2px 8px 2px" }, "states": { "hover": { @@ -111,19 +129,24 @@ export const muiTheme = { }, "background": { "default": "#ffffff", - "paper": "#616161" + "paper": "#e5e5e5" }, "text": { "primary": "#000000", - "secondary": "#ffffff" + "secondary": "#171717" } }, "typography": { - "fontFamily": "'Times New Roman', sans-serif", + "fontFamily": "'Helvetica', sans-serif", "h1": { - "fontSize": "32px", + "fontSize": "42px", + "fontWeight": "700", + "lineHeight": "normal" + }, + "h2": { + "fontSize": "24px", "fontWeight": "600", - "lineHeight": "44.8px" + "lineHeight": "36px" }, "body1": { "fontSize": "16px", @@ -131,16 +154,17 @@ export const muiTheme = { "lineHeight": "normal" }, "body2": { - "fontSize": "13.3333px", - "fontWeight": "400", - "lineHeight": "normal" + "fontSize": "14px", + "fontWeight": "500", + "lineHeight": "19.6px" } }, "shape": { "borderRadius": 8 }, "shadows": [ - "rgb(97, 97, 97) 2px 2px 8px 0px" + "rgb(170, 170, 170) 2px 2px 4px 0px", + "rgba(23, 23, 23, 0.1) 2px 2px 8px 2px" ] }; diff --git a/docs/design-extract/coulomb-social-tokens-routes/index.json b/docs/design-extract/coulomb-social-tokens-routes/index.json new file mode 100644 index 0000000..1fb273b --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/index.json @@ -0,0 +1,82 @@ +{ + "url": "https://coulomb.social", + "path": "/", + "added": {}, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#000000" + } + }, + "neutral": { + "n200": { + "$value": "#373737" + }, + "n300": { + "$value": "#616161" + }, + "n400": { + "$value": "#171717" + }, + "n500": { + "$value": "#efefef" + }, + "n600": { + "$value": "#ffffff" + }, + "n700": { + "$value": "#e5e5e5" + } + }, + "background": { + "bg1": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#373737" + }, + "text3": { + "$value": "#616161" + } + } + }, + "spacing": { + "s1": { + "$value": "24px" + }, + "s2": { + "$value": "32px" + }, + "s3": { + "$value": "40px" + }, + "s4": { + "$value": "82px" + }, + "s5": { + "$value": "96px" + } + }, + "radius": { + "r3": { + "$value": "20px" + } + }, + "fontFamily": { + "f1": { + "$value": "Inter" + }, + "f2": { + "$value": "Arial" + }, + "f3": { + "$value": "Times New Roman" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1767965374100x901547861536145400.json b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1767965374100x901547861536145400.json new file mode 100644 index 0000000..118953c --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1767965374100x901547861536145400.json @@ -0,0 +1,88 @@ +{ + "url": "https://coulomb.social/pg_chunk/1767965374100x901547861536145400", + "path": "/pg_chunk/1767965374100x901547861536145400", + "added": {}, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#d08728" + } + }, + "neutral": { + "n200": { + "$value": "#efefef" + }, + "n300": { + "$value": "#e5e5e5" + }, + "n400": { + "$value": "#616161" + }, + "n500": { + "$value": "#171717" + }, + "n600": { + "$value": "#ffffff" + }, + "n700": { + "$value": "#373737" + } + }, + "background": { + "bg1": { + "$value": "#171717" + }, + "bg2": { + "$value": "#f5f5f5" + }, + "bg3": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#616161" + }, + "text3": { + "$value": "#373737" + } + } + }, + "spacing": { + "s1": { + "$value": "60px" + }, + "s2": { + "$value": "80px" + }, + "s3": { + "$value": "96px" + }, + "s4": { + "$value": "320px" + } + }, + "radius": { + "r3": { + "$value": "15px" + }, + "r4": { + "$value": "20px" + } + }, + "fontFamily": { + "f1": { + "$value": "Arial" + }, + "f2": { + "$value": "Times New Roman" + }, + "f3": { + "$value": "Inter" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784305925912x322414739506593800.json b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784305925912x322414739506593800.json new file mode 100644 index 0000000..105e900 --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784305925912x322414739506593800.json @@ -0,0 +1,91 @@ +{ + "url": "https://coulomb.social/pg_chunk/1784305925912x322414739506593800", + "path": "/pg_chunk/1784305925912x322414739506593800", + "added": {}, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#d08728" + } + }, + "neutral": { + "n200": { + "$value": "#efefef" + }, + "n300": { + "$value": "#616161" + }, + "n400": { + "$value": "#373737" + }, + "n500": { + "$value": "#e5e5e5" + }, + "n600": { + "$value": "#171717" + }, + "n700": { + "$value": "#ffffff" + } + }, + "background": { + "bg1": { + "$value": "#171717" + }, + "bg2": { + "$value": "#f5f5f5" + }, + "bg3": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#616161" + }, + "text3": { + "$value": "#373737" + }, + "text4": { + "$value": "#ffffff" + } + } + }, + "spacing": { + "s1": { + "$value": "60px" + }, + "s2": { + "$value": "80px" + }, + "s3": { + "$value": "96px" + }, + "s4": { + "$value": "320px" + } + }, + "radius": { + "r3": { + "$value": "15px" + }, + "r4": { + "$value": "20px" + } + }, + "fontFamily": { + "f1": { + "$value": "Arial" + }, + "f2": { + "$value": "Times New Roman" + }, + "f3": { + "$value": "Inter" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784904857383x503270614975381500.json b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784904857383x503270614975381500.json new file mode 100644 index 0000000..47eb8a0 --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1784904857383x503270614975381500.json @@ -0,0 +1,91 @@ +{ + "url": "https://coulomb.social/pg_chunk/1784904857383x503270614975381500", + "path": "/pg_chunk/1784904857383x503270614975381500", + "added": {}, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#d08728" + } + }, + "neutral": { + "n200": { + "$value": "#efefef" + }, + "n300": { + "$value": "#616161" + }, + "n400": { + "$value": "#373737" + }, + "n500": { + "$value": "#e5e5e5" + }, + "n600": { + "$value": "#171717" + }, + "n700": { + "$value": "#ffffff" + } + }, + "background": { + "bg1": { + "$value": "#171717" + }, + "bg2": { + "$value": "#f5f5f5" + }, + "bg3": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#616161" + }, + "text3": { + "$value": "#373737" + }, + "text4": { + "$value": "#ffffff" + } + } + }, + "spacing": { + "s1": { + "$value": "60px" + }, + "s2": { + "$value": "80px" + }, + "s3": { + "$value": "96px" + }, + "s4": { + "$value": "320px" + } + }, + "radius": { + "r3": { + "$value": "15px" + }, + "r4": { + "$value": "20px" + } + }, + "fontFamily": { + "f1": { + "$value": "Arial" + }, + "f2": { + "$value": "Times New Roman" + }, + "f3": { + "$value": "Inter" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501127011x363256181345746940.json b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501127011x363256181345746940.json new file mode 100644 index 0000000..86f4b42 --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501127011x363256181345746940.json @@ -0,0 +1,88 @@ +{ + "url": "https://coulomb.social/pg_chunk/1785501127011x363256181345746940", + "path": "/pg_chunk/1785501127011x363256181345746940", + "added": {}, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#d08728" + } + }, + "neutral": { + "n200": { + "$value": "#efefef" + }, + "n300": { + "$value": "#e5e5e5" + }, + "n400": { + "$value": "#616161" + }, + "n500": { + "$value": "#171717" + }, + "n600": { + "$value": "#ffffff" + }, + "n700": { + "$value": "#373737" + } + }, + "background": { + "bg1": { + "$value": "#171717" + }, + "bg2": { + "$value": "#f5f5f5" + }, + "bg3": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#616161" + }, + "text3": { + "$value": "#373737" + } + } + }, + "spacing": { + "s1": { + "$value": "60px" + }, + "s2": { + "$value": "80px" + }, + "s3": { + "$value": "96px" + }, + "s4": { + "$value": "320px" + } + }, + "radius": { + "r3": { + "$value": "15px" + }, + "r4": { + "$value": "20px" + } + }, + "fontFamily": { + "f1": { + "$value": "Arial" + }, + "f2": { + "$value": "Times New Roman" + }, + "f3": { + "$value": "Inter" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501151364x921456713843343400.json b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501151364x921456713843343400.json new file mode 100644 index 0000000..c38167b --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1785501151364x921456713843343400.json @@ -0,0 +1,88 @@ +{ + "url": "https://coulomb.social/pg_chunk/1785501151364x921456713843343400", + "path": "/pg_chunk/1785501151364x921456713843343400", + "added": {}, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#d08728" + } + }, + "neutral": { + "n200": { + "$value": "#efefef" + }, + "n300": { + "$value": "#e5e5e5" + }, + "n400": { + "$value": "#171717" + }, + "n500": { + "$value": "#616161" + }, + "n600": { + "$value": "#ffffff" + }, + "n700": { + "$value": "#373737" + } + }, + "background": { + "bg1": { + "$value": "#171717" + }, + "bg2": { + "$value": "#f5f5f5" + }, + "bg3": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#616161" + }, + "text3": { + "$value": "#373737" + }, + "text4": { + "$value": "#ffffff" + } + } + }, + "spacing": { + "s1": { + "$value": "60px" + }, + "s2": { + "$value": "80px" + }, + "s3": { + "$value": "96px" + }, + "s4": { + "$value": "320px" + } + }, + "radius": { + "r3": { + "$value": "15px" + } + }, + "fontFamily": { + "f1": { + "$value": "Arial" + }, + "f2": { + "$value": "Times New Roman" + }, + "f3": { + "$value": "Inter" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1786106348475x662489469743530000.json b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1786106348475x662489469743530000.json new file mode 100644 index 0000000..434b1ae --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-routes/pg-chunk-1786106348475x662489469743530000.json @@ -0,0 +1,99 @@ +{ + "url": "https://coulomb.social/pg_chunk/1786106348475x662489469743530000", + "path": "/pg_chunk/1786106348475x662489469743530000", + "added": { + "primitive": { + "spacing": { + "s6": { + "$value": "320px" + } + } + } + }, + "changed": { + "primitive": { + "color": { + "brand": { + "primary": { + "$value": "#d08728" + } + }, + "neutral": { + "n200": { + "$value": "#efefef" + }, + "n300": { + "$value": "#616161" + }, + "n400": { + "$value": "#171717" + }, + "n500": { + "$value": "#ffffff" + }, + "n600": { + "$value": "#373737" + }, + "n700": { + "$value": "#e5e5e5" + } + }, + "background": { + "bg1": { + "$value": "#171717" + }, + "bg2": { + "$value": "#f5f5f5" + }, + "bg3": { + "$value": "#e5e5e5" + } + }, + "text": { + "text2": { + "$value": "#616161" + }, + "text3": { + "$value": "#373737" + } + } + }, + "spacing": { + "s1": { + "$value": "24px" + }, + "s2": { + "$value": "32px" + }, + "s3": { + "$value": "40px" + }, + "s4": { + "$value": "80px" + }, + "s5": { + "$value": "96px" + } + }, + "radius": { + "r3": { + "$value": "15px" + }, + "r4": { + "$value": "20px" + } + }, + "fontFamily": { + "f1": { + "$value": "Arial" + }, + "f2": { + "$value": "Times New Roman" + }, + "f3": { + "$value": "Inter" + } + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens-shared.json b/docs/design-extract/coulomb-social-tokens-shared.json new file mode 100644 index 0000000..6cc2c46 --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens-shared.json @@ -0,0 +1,92 @@ +{ + "primitive": { + "color": { + "neutral": { + "n100": { + "$value": "#000000" + } + }, + "background": { + "bg0": { + "$value": "#ffffff" + } + }, + "text": { + "text0": { + "$value": "#000000" + }, + "text1": { + "$value": "#171717" + } + } + }, + "spacing": { + "s0": { + "$value": "1px" + } + }, + "radius": { + "r0": { + "$value": "4px" + }, + "r1": { + "$value": "8px" + }, + "r2": { + "$value": "12px" + } + }, + "shadow": { + "sh0": { + "$value": "rgb(170, 170, 170) 2px 2px 4px 0px" + }, + "sh1": { + "$value": "rgba(23, 23, 23, 0.1) 2px 2px 8px 2px" + } + }, + "fontFamily": { + "f0": { + "$value": "Helvetica" + } + } + }, + "semantic": { + "color": { + "action": { + "primary": { + "$value": "{primitive.color.brand.primary}" + } + }, + "surface": { + "default": { + "$value": "{primitive.color.background.bg0}" + } + }, + "text": { + "body": { + "$value": "{primitive.color.text.text0}" + } + } + }, + "typography": { + "body": { + "$value": { + "fontFamily": "Helvetica", + "fontSize": "50px", + "fontWeight": "400", + "lineHeight": "50px" + } + } + }, + "radius": { + "control": { + "$value": "{primitive.radius.r0}" + } + }, + "shadow": { + "elevated": { + "$value": "{primitive.shadow.sh0}" + } + } + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-tokens.d.ts b/docs/design-extract/coulomb-social-tokens.d.ts new file mode 100644 index 0000000..21a6484 --- /dev/null +++ b/docs/design-extract/coulomb-social-tokens.d.ts @@ -0,0 +1,49 @@ +// Auto-generated by designlang. Do not edit by hand. +// Re-extract with `npx designlang ` to refresh. +// +// Import next to your token JSON to get type-safe access: +// +// import type { ColorToken, SpacingToken } from './-tokens'; +// import tokens from './-design-tokens.json'; +// +// Source: https://coulomb.social +// Generated: 2026-08-08T23:30:22.004Z + +export type Hex = `#${string}`; +export type Px = `${number}px`; +export type Ms = `${number}ms`; + +export type ColorRole = 'primary'; +export type ColorHex = '#000000' | '#efefef' | '#616161' | '#373737' | '#171717' | '#ffffff' | '#e5e5e5' | '#d08728'; +export type ColorToken = ColorRole | ColorHex; + +export type FontFamilyToken = 'Helvetica' | 'Arial' | 'Times New Roman' | 'Inter'; +export type FontSizeToken = never; +export type FontWeightToken = '400' | '500' | '600' | '700'; + +export type SpacingToken = '1px' | '24px' | '32px' | '40px' | '60px' | '80px' | '96px' | '320px'; + +export type RadiusToken = '4px' | '8px' | '12px' | '15px' | '20px'; + +export type DurationToken = '250ms'; +export type EasingToken = never; + +export type MaterialLanguage = 'flat'; + +export interface DesignTokens { + color: { [role in ColorRole]: ColorHex }; + typography: { + family: FontFamilyToken; + size: FontSizeToken; + weight: FontWeightToken; + }; + spacing: ReadonlyArray; + radius: ReadonlyArray; + motion: { + duration: ReadonlyArray; + easing: ReadonlyArray; + }; +} + +declare const tokens: DesignTokens; +export default tokens; diff --git a/docs/design-extract/tokens/variables.css b/docs/design-extract/coulomb-social-variables.css similarity index 74% rename from docs/design-extract/tokens/variables.css rename to docs/design-extract/coulomb-social-variables.css index 2e12413..784e844 100644 --- a/docs/design-extract/tokens/variables.css +++ b/docs/design-extract/coulomb-social-variables.css @@ -4,48 +4,61 @@ /* Colors — Neutrals */ --color-neutral-50: #000000; - --color-neutral-100: #171717; - --color-neutral-200: #ffffff; - --color-neutral-300: #616161; - --color-neutral-400: #e5e5e5; + --color-neutral-100: #efefef; + --color-neutral-200: #616161; + --color-neutral-300: #373737; + --color-neutral-400: #171717; + --color-neutral-500: #ffffff; + --color-neutral-600: #e5e5e5; /* Colors — Backgrounds */ --color-bg: #ffffff; - --color-bg-1: #616161; + --color-bg-1: #e5e5e5; + --color-bg-2: #171717; + --color-bg-3: #f5f5f5; /* Colors — Text */ --color-text: #000000; - --color-text-1: #ffffff; - --color-text-2: #171717; - --color-text-3: #d08728; + --color-text-1: #171717; + --color-text-2: #373737; + --color-text-3: #616161; + --color-text-4: #ffffff; /* Typography — Families */ - --font-body: 'Times New Roman', sans-serif; --font-body: 'Helvetica', sans-serif; - --font-font-2: 'Inter', sans-serif; --font-body: 'Arial', sans-serif; + --font-body: 'Times New Roman', sans-serif; + --font-body: 'Inter', sans-serif; /* Typography — Scale */ - --font-size-48: 48px; - --font-size-32: 32px; + --font-size-50: 50px; + --font-size-42: 42px; + --font-size-24: 24px; --font-size-18: 18px; --font-size-16: 16px; --font-size-14: 14px; --font-size-13.3333: 13.3333px; - --font-size-12: 12px; - --font-size-8: 8px; /* Spacing */ - --spacing-2: 2px; + --spacing-1: 1px; + --spacing-24: 24px; --spacing-32: 32px; - --spacing-68: 68px; + --spacing-40: 40px; + --spacing-60: 60px; + --spacing-80: 80px; + --spacing-96: 96px; + --spacing-320: 320px; /* Border Radius */ --radius-sm: 4px; --radius-md: 8px; + --radius-lg: 12px; + --radius-lg: 15px; + --radius-xl: 20px; /* Box Shadows */ - --shadow-md: rgb(97, 97, 97) 2px 2px 8px 0px; + --shadow-sm: rgb(170, 170, 170) 2px 2px 4px 0px; + --shadow-md: rgba(23, 23, 23, 0.1) 2px 2px 8px 2px; /* Original Site Variables */ /* — colors — */ diff --git a/docs/design-extract/coulomb-social-visual-dna.json b/docs/design-extract/coulomb-social-visual-dna.json new file mode 100644 index 0000000..b75343b --- /dev/null +++ b/docs/design-extract/coulomb-social-visual-dna.json @@ -0,0 +1,53 @@ +{ + "materialLanguage": { + "label": "flat", + "confidence": 0, + "signals": [], + "metrics": { + "saturation": 0.101, + "shadowProfile": "soft", + "avgShadowBlur": 0, + "maxShadowBlur": 0, + "insetShadows": 0, + "avgRadius": 11.8, + "maxRadius": 20, + "hasPill": false, + "hasBackdropBlur": false, + "gradientCount": 0 + }, + "alternates": [] + }, + "imageryStyle": { + "label": "mixed", + "confidence": 0, + "counts": { + "total": 29, + "svg": 0, + "icon": 1, + "hero": 0, + "screenshot": 0, + "photoLike": 0 + }, + "dominantAspect": "square-ish", + "radiusProfile": "soft", + "alternates": [], + "signals": [] + }, + "backgroundPatterns": { + "labels": [ + "plain" + ], + "counts": { + "noise": 0, + "dotGrid": 0, + "lineGrid": 0, + "meshCount": 0, + "svgPattern": 0 + }, + "gradientTotals": { + "radial": 0, + "linear": 0 + }, + "samples": [] + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-voice.json b/docs/design-extract/coulomb-social-voice.json new file mode 100644 index 0000000..ecf977e --- /dev/null +++ b/docs/design-extract/coulomb-social-voice.json @@ -0,0 +1,71 @@ +{ + "tone": "neutral", + "pronoun": "third-person", + "headingStyle": "unknown", + "headingLengthClass": "tight", + "ctaVerbs": [ + { + "value": "content", + "count": 25 + }, + { + "value": "favorite", + "count": 25 + }, + { + "value": "format", + "count": 1 + }, + { + "value": "filter", + "count": 1 + }, + { + "value": "add", + "count": 1 + }, + { + "value": "arrow", + "count": 1 + }, + { + "value": "note", + "count": 1 + } + ], + "buttonPatterns": [ + { + "value": "content_copy", + "count": 25 + }, + { + "value": "favorite_border", + "count": 25 + }, + { + "value": "format_line_spacing", + "count": 1 + }, + { + "value": "filter_list", + "count": 1 + }, + { + "value": "add_circle_outline", + "count": 1 + }, + { + "value": "arrow_drop_down", + "count": 1 + }, + { + "value": "note_alt", + "count": 1 + } + ], + "sampleHeadings": [], + "stats": { + "buttons": 55, + "headings": 0 + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social-wordpress-theme.json b/docs/design-extract/coulomb-social-wordpress-theme.json new file mode 100644 index 0000000..3819fca --- /dev/null +++ b/docs/design-extract/coulomb-social-wordpress-theme.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://schemas.wp.org/trunk/theme.json", + "version": 3, + "settings": { + "color": { + "palette": [ + { + "slug": "primary", + "color": "#d08728", + "name": "Primary" + }, + { + "slug": "neutral-1", + "color": "#000000", + "name": "Neutral 1" + }, + { + "slug": "neutral-2", + "color": "#efefef", + "name": "Neutral 2" + }, + { + "slug": "neutral-3", + "color": "#616161", + "name": "Neutral 3" + }, + { + "slug": "neutral-4", + "color": "#373737", + "name": "Neutral 4" + }, + { + "slug": "neutral-5", + "color": "#171717", + "name": "Neutral 5" + }, + { + "slug": "bg-ffffff", + "color": "#ffffff", + "name": "Background #ffffff" + }, + { + "slug": "bg-e5e5e5", + "color": "#e5e5e5", + "name": "Background #e5e5e5" + }, + { + "slug": "bg-171717", + "color": "#171717", + "name": "Background #171717" + } + ], + "gradients": [] + }, + "typography": { + "fontFamilies": [ + { + "fontFamily": "Helvetica", + "slug": "helvetica", + "name": "Helvetica" + }, + { + "fontFamily": "Arial", + "slug": "arial", + "name": "Arial" + }, + { + "fontFamily": "Times New Roman", + "slug": "times-new-roman", + "name": "Times New Roman" + }, + { + "fontFamily": "Inter", + "slug": "inter", + "name": "Inter" + } + ], + "fontSizes": [ + { + "size": "50px", + "slug": "size-50", + "name": "50px" + }, + { + "size": "42px", + "slug": "size-42", + "name": "42px" + }, + { + "size": "24px", + "slug": "size-24", + "name": "24px" + }, + { + "size": "18px", + "slug": "size-18", + "name": "18px" + }, + { + "size": "16px", + "slug": "size-16", + "name": "16px" + }, + { + "size": "14px", + "slug": "size-14", + "name": "14px" + }, + { + "size": "13.3333px", + "slug": "size-13.3333", + "name": "13.3333px" + } + ] + }, + "spacing": { + "spacingSizes": [ + { + "size": "1px", + "slug": "spacing-1", + "name": "1px" + }, + { + "size": "24px", + "slug": "spacing-24", + "name": "24px" + }, + { + "size": "32px", + "slug": "spacing-32", + "name": "32px" + }, + { + "size": "40px", + "slug": "spacing-40", + "name": "40px" + }, + { + "size": "60px", + "slug": "spacing-60", + "name": "60px" + }, + { + "size": "80px", + "slug": "spacing-80", + "name": "80px" + }, + { + "size": "96px", + "slug": "spacing-96", + "name": "96px" + }, + { + "size": "320px", + "slug": "spacing-320", + "name": "320px" + } + ] + }, + "layout": { + "contentSize": "1200px", + "wideSize": "1400px" + } + }, + "styles": { + "color": { + "background": "#ffffff", + "text": "#000000" + }, + "typography": { + "fontFamily": "Helvetica" + }, + "spacing": {} + } +} \ No newline at end of file diff --git a/docs/design-extract/coulomb-social.brand.html b/docs/design-extract/coulomb-social.brand.html new file mode 100644 index 0000000..0c8ad76 --- /dev/null +++ b/docs/design-extract/coulomb-social.brand.html @@ -0,0 +1,795 @@ + + + + + +coulomb.social · brand guidelines + + + + + + + + + + + +
+ + +
+ +
+ +
+
+ Brand guidelines + #d08728 +
+
+

August 9, 2026

+

coulomb.social

+

A reading of the visual language at https://coulomb.social. Every token, every rule, every component — captured from the live site.

+
+
Page intent
landing
+
System grade
B 85/100
+
Tokens
8 colours · 7 sizes
+
Generated
designlang
+
+
+
+ + + +
+ +
+ Chapter 01 +

About

+
+
+
Page intent
landing 45% confidence
+
Material language
flat
+
Imagery style
mixed
+
Component library
unknown
+
Stack
unknown · Tailwind
+
Voice tone
neutral
+
+
+ + + +
+ +
+ Chapter 03 +

Colour

+
+

1 primary · 7 neutrals · 8 total

+ +
+
+
+ Primary + #D08728 +
+
+
RGB
208, 135, 40
+
HSL
34°, 68%, 49%
+
+
+ + + + +

Neutrals

+
+
#000000
#EFEFEF
#616161
#373737
#171717
#FFFFFF
#E5E5E5
+
+ + +

Full palette

+
+
#000000
#EFEFEF
#616161
#373737
#171717
#FFFFFF
#E5E5E5
#D08728
+
+ + +

WCAG 100% · 0 passing pairs · 0 failing. Full breakdown in §11.

+ +
+ +
+ +
+ Chapter 04 +

Typography

+
+

4 families · 7 sizes · 4 weights

+ +
+
Display
Helvetica
+
Body
Arial
+
Weights
400, 500, 600, 700
+
+ +

Specimen

+
+
Quick brown fox jumps over the lazy dog.
+
AaBbCc 0123456789 ?!&
+
+ +

Scale

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StepSizeSample
t0050pxQuick brown fox jumps over t
t0142pxQuick brown fox jumps over t
t0224pxQuick brown fox jumps over t
t0318pxQuick brown fox jumps over t
t0416pxQuick brown fox jumps over t
t0514pxQuick brown fox jumps over t
t0613.3333pxQuick brown fox jumps over t
+
+ +
+ +
+ Chapter 05 +

Spacing

+
+

Base 4px · 8 steps captured

+ +

Rhythm

+
+ +
+
+ 1px +
+ +
+
+ 24px +
+ +
+
+ 32px +
+ +
+
+ 40px +
+ +
+
+ 60px +
+ +
+
+ 80px +
+ +
+
+ 96px +
+ +
+
+ 320px +
+ +
+
+ +
+ +
+ Chapter 06 +

Shape

+
+

5 radii · 2 elevation tiers

+ +

Border radii

+
+ +
+
+ 4px +
+ +
+
+ 8px +
+ +
+
+ 12px +
+ +
+
+ 15px +
+ +
+
+ 20px +
+ +
+ + +

Elevation

+
+ +
+
+ xs +
+ +
+
+ sm +
+ +
+ +
+ +
+ +
+ Chapter 07 +

Iconography

+
+

unknown · 24 captured

+ +
+
Library
unknown
+
Confidence
0%
+
Stroke style
fillDominant
+
+ + +
+
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
icon
+
+ +
+ +
+ +
+ Chapter 08 +

Motion

+
+

Feel: mixed · 1 durations · 0 easings

+ + +

Duration scale

+
+ +
+
+ 250ms +
+ +
+ + + +
+ +
+ +
+ Chapter 09 +

Components

+
+

unknown · 1 component patterns captured

+ +

Mocks

+
+
+ + +
+
+ Card +

Built from these tokens

+

Radius, primary, surface, text — all sampled from the live site.

+ Read more → +
+
+ + +

Detected patterns

+
+ +
+

button

+
+
Slots
label, icon, badge
+
Variants
+
Sizes
+
+
+ +
+ +
+ +
+ +
+ Chapter 10 +

Voice

+
+

neutral · — · —

+ + + + +

CTA verbs

+
    +
  • ×25
  • ×25
  • ×1
  • ×1
  • ×1
  • ×1
  • ×1
  • +
+ +
+ +
+ +
+ Chapter 11 +

Accessibility

+
+ +
+ 100% + WCAG 2.1 contrast
0 passing · 0 failing
+
+ +

No failing contrast pairs detected.

+ + +
+ +
+ +
+ Chapter 12 +

Tokens

+
+

Drop-in code for the most common stacks. All values from the live extraction.

+ +
+
CSS variablesvariables.css
+
:root {
+  --color-primary: #d08728;
+  --font-display: "Helvetica";
+  --space-base: 4px;
+  --radius-md: 8px;
+}
+
+ +
+
Tailwind configtailwind.config.js
+
// tailwind.config.js
+module.exports = {
+  theme: {
+    extend: {
+      colors: { brand: '#d08728' },
+      fontFamily: { display: ['Helvetica', 'serif'] },
+      spacing: { base: '4px' },
+      borderRadius: { md: '8px' },
+    },
+  },
+};
+
+ +

Run npx designlang pack coulomb.social for the full bundle (DTCG, shadcn, Figma vars, motion, anatomy, Storybook).

+
+ +
+ +
+ Chapter 13 +

Usage

+
+
    + +
  1. +

    Lead with the primary.

    +

    It belongs on calls-to-action and one accent moment per screen. Not on body copy.

    +
  2. + +
  3. +

    Two type families, three weights.

    +

    Display for headlines, body for paragraphs. Resist a third unless there is a real reason.

    +
  4. + +
  5. +

    Snap to the spacing scale.

    +

    Padding, margin, and gap should land on the values in §05. One-off pixels accumulate into noise.

    +
  6. + +
  7. +

    Treat accessibility as a hard constraint.

    +

    When a colour pair fails WCAG, fix the colour — not the contrast check.

    +
  8. + +
+
+ +
+
+
designlang
+
Re-run: npx designlang brand coulomb.social
+
+
Aug 9, 2026 · v12.21.0
+
+
+ + + + \ No newline at end of file diff --git a/docs/design-extract/extras/prompt-pack.md b/docs/design-extract/extras/prompt-pack.md deleted file mode 100644 index 982ace5..0000000 --- a/docs/design-extract/extras/prompt-pack.md +++ /dev/null @@ -1,120 +0,0 @@ -# Prompt pack - -Paste-ready prompts for coulomb.social. Use the variant that matches your tool. - -## v0.txt - -``` -Build a landing page with this exact visual language. -COLORS: - #000000 - #171717 - #d08728 - #ffffff - #616161 - #e5e5e5 -FONTS: [object Object], [object Object], [object Object], [object Object] -SPACING: 2, 32, 68 -RADIUS: 4, 8 -SHADOWS: rgb(97, 97, 97) 2px 2px 8px 0px -MATERIAL LANGUAGE: flat -VOICE: Tone: neutral · Headings: unknown -SECTIONS (in order): -- hero -- features -- cta -- footer -Use Tailwind. Match these tokens exactly. Keep the material language consistent. -``` - -## lovable.txt - -``` -Clone the design language of this landing page and build a fresh equivalent. -Visual feel: flat. Tone: neutral · Headings: unknown -Primary palette: #000000, #171717, #d08728, #ffffff, #616161. -Typography: [object Object], [object Object], [object Object], [object Object]. -Corner radius vocabulary: 4, 8. -Shadow vocabulary: rgb(97, 97, 97) 2px 2px 8px 0px. -Page structure: -- hero -- features -- social proof -- cta -- footer -``` - -## cursor.md - -``` -# Design brief -Page type: **landing**. -Material language: **flat**. -Voice: Tone: neutral · Headings: unknown. -## Tokens -```ts -export const tokens = { - colors: ['#000000', '#171717', '#d08728', '#ffffff', '#616161', '#e5e5e5'], - fonts: ['[object Object]', '[object Object]', '[object Object]', '[object Object]'], - radii: ['4', '8'], - shadows: ['rgb(97, 97, 97) 2px 2px 8px 0px'], -}; -``` -## Sections -- hero -- features -- cta -- footer -``` - -## claude-artifacts.md - -``` -Create a React artifact that reproduces this brand's design language. -Page intent: landing. -Material language: flat. -Voice: Tone: neutral · Headings: unknown. -Colors to use: #000000, #171717, #d08728, #ffffff, #616161, #e5e5e5. -Fonts: [object Object], [object Object], [object Object], [object Object]. -Radius vocabulary: 4, 8. -Sections: -- hero -- features -- cta -- footer -Use Tailwind via CDN, lucide-react for icons, and keep the material language consistent across sections. Do not add extra decorative elements outside this vocabulary. -``` - -## Recipes - -### button - -# Recipe: button -Build one button component that matches this brand. -Palette: #000000, #171717, #d08728, #ffffff, #616161, #e5e5e5 -Typography: [object Object], [object Object], [object Object], [object Object] -Material: flat -Signals: Radius: 4, 8 · Shadows: rgb(97, 97, 97) 2px 2px 8px 0px -## Anatomy (detected) -```json -{ - "kind": "button", - "structuralHash": "button>svg", - "instanceCount": 1, - "variants": [ - { - "css": { - "background": "rgba(0, 0, 0, 0)", - "color": "rgb(208, 135, 40)", - "padding": "5px 5px 5px 5px", - "borderRadius": "4px", - "border": "0px none rgb(208, 135, 40)", - "fontSize": "13.3333px", - "fontWeight": "400" - }, - "instanceCount": 1 - } - ] -} -``` - diff --git a/docs/design-extract/extras/voice.json b/docs/design-extract/extras/voice.json deleted file mode 100644 index 05ef569..0000000 --- a/docs/design-extract/extras/voice.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "tone": "neutral", - "pronoun": "third-person", - "headingStyle": "unknown", - "headingLengthClass": "tight", - "ctaVerbs": [], - "buttonPatterns": [], - "sampleHeadings": [], - "stats": { - "buttons": 0, - "headings": 0 - } -} \ No newline at end of file diff --git a/docs/design-extract/prompts/cursor.md b/docs/design-extract/prompts/cursor.md deleted file mode 100644 index 34c8196..0000000 --- a/docs/design-extract/prompts/cursor.md +++ /dev/null @@ -1,18 +0,0 @@ -# Design brief -Page type: **landing**. -Material language: **flat**. -Voice: Tone: neutral · Headings: unknown. -## Tokens -```ts -export const tokens = { - colors: ['#000000', '#171717', '#d08728', '#ffffff', '#616161', '#e5e5e5'], - fonts: ['[object Object]', '[object Object]', '[object Object]', '[object Object]'], - radii: ['4', '8'], - shadows: ['rgb(97, 97, 97) 2px 2px 8px 0px'], -}; -``` -## Sections -- hero -- features -- cta -- footer \ No newline at end of file diff --git a/docs/design-extract/prompts/lovable.txt b/docs/design-extract/prompts/lovable.txt deleted file mode 100644 index b483b09..0000000 --- a/docs/design-extract/prompts/lovable.txt +++ /dev/null @@ -1,12 +0,0 @@ -Clone the design language of this landing page and build a fresh equivalent. -Visual feel: flat. Tone: neutral · Headings: unknown -Primary palette: #000000, #171717, #d08728, #ffffff, #616161. -Typography: [object Object], [object Object], [object Object], [object Object]. -Corner radius vocabulary: 4, 8. -Shadow vocabulary: rgb(97, 97, 97) 2px 2px 8px 0px. -Page structure: -- hero -- features -- social proof -- cta -- footer \ No newline at end of file diff --git a/docs/design-extract/prompts/recipes/button.md b/docs/design-extract/prompts/recipes/button.md deleted file mode 100644 index 81bcbe4..0000000 --- a/docs/design-extract/prompts/recipes/button.md +++ /dev/null @@ -1,28 +0,0 @@ -# Recipe: button -Build one button component that matches this brand. -Palette: #000000, #171717, #d08728, #ffffff, #616161, #e5e5e5 -Typography: [object Object], [object Object], [object Object], [object Object] -Material: flat -Signals: Radius: 4, 8 · Shadows: rgb(97, 97, 97) 2px 2px 8px 0px -## Anatomy (detected) -```json -{ - "kind": "button", - "structuralHash": "button>svg", - "instanceCount": 1, - "variants": [ - { - "css": { - "background": "rgba(0, 0, 0, 0)", - "color": "rgb(208, 135, 40)", - "padding": "5px 5px 5px 5px", - "borderRadius": "4px", - "border": "0px none rgb(208, 135, 40)", - "fontSize": "13.3333px", - "fontWeight": "400" - }, - "instanceCount": 1 - } - ] -} -``` \ No newline at end of file diff --git a/docs/design-extract/starter/index.html b/docs/design-extract/starter/index.html deleted file mode 100644 index 210a8d8..0000000 --- a/docs/design-extract/starter/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - -coulomb.social starter - - - - -
-

Built from coulomb.social

-

This starter is wired to the tokens in tokens/variables.css. Edit the variables and watch this page change. Drop in your own components and use the same tokens to keep the visual language consistent.

- Get started -

Generated by designlang. Re-pack with npx designlang pack coulomb.social.

-
- - diff --git a/docs/design-extract/storybook/.storybook/main.ts b/docs/design-extract/storybook/.storybook/main.ts deleted file mode 100644 index 9f1965f..0000000 --- a/docs/design-extract/storybook/.storybook/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { StorybookConfig } from '@storybook/react-vite'; - -const config: StorybookConfig = { - stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(ts|tsx)'], - addons: ['@storybook/addon-essentials', '@storybook/addon-docs'], - framework: { name: '@storybook/react-vite', options: {} }, -}; -export default config; diff --git a/docs/design-extract/storybook/.storybook/preview.ts b/docs/design-extract/storybook/.storybook/preview.ts deleted file mode 100644 index 1d8241b..0000000 --- a/docs/design-extract/storybook/.storybook/preview.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { Preview } from '@storybook/react'; -import './../stories/tokens.css'; - -const preview: Preview = { - parameters: { - backgrounds: { default: 'paper' }, - controls: { matchers: { color: /(background|color)$/i } }, - }, -}; -export default preview; diff --git a/docs/design-extract/storybook/README.md b/docs/design-extract/storybook/README.md deleted file mode 100644 index 7fb1694..0000000 --- a/docs/design-extract/storybook/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Index | Coulomb · Storybook - -Auto-generated by `designlang --storybook`. - -## Stories -_No anatomy detected on the source page._ - -## Run - -``` -npm install -npm run storybook -``` - -Opens at http://localhost:6006. diff --git a/docs/design-extract/storybook/package.json b/docs/design-extract/storybook/package.json deleted file mode 100644 index e772307..0000000 --- a/docs/design-extract/storybook/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "index---coulomb-storybook", - "private": true, - "version": "0.1.0", - "type": "module", - "scripts": { - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" - }, - "dependencies": { - "react": "^19.0.0", - "react-dom": "^19.0.0" - }, - "devDependencies": { - "@storybook/addon-essentials": "^8.0.0", - "@storybook/addon-docs": "^8.0.0", - "@storybook/blocks": "^8.0.0", - "@storybook/react": "^8.0.0", - "@storybook/react-vite": "^8.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "storybook": "^8.0.0", - "typescript": "^5.0.0", - "vite": "^5.0.0" - } -} \ No newline at end of file diff --git a/docs/design-extract/storybook/stories/Tokens.mdx b/docs/design-extract/storybook/stories/Tokens.mdx deleted file mode 100644 index 708ae92..0000000 --- a/docs/design-extract/storybook/stories/Tokens.mdx +++ /dev/null @@ -1,15 +0,0 @@ -import { Meta, ColorPalette, ColorItem, Typeset } from '@storybook/blocks'; - - - -# Design tokens - -Extracted from https://coulomb.social by [designlang](https://github.com/Manavarya09/design-extract). - - - - - - - - diff --git a/docs/design-extract/storybook/stories/tokens.css b/docs/design-extract/storybook/stories/tokens.css deleted file mode 100644 index 47ecb3f..0000000 --- a/docs/design-extract/storybook/stories/tokens.css +++ /dev/null @@ -1,11 +0,0 @@ -:root { - --color-primary: #d08728; - --color-secondary: #8b5cf6; - --color-accent: #f59e0b; - --color-background: #ffffff; - --color-foreground: #000000; - --radius: 8px; - --shadow: rgb(97, 97, 97) 2px 2px 8px 0px; - --font-sans: 'Times New Roman', system-ui, sans-serif; -} -body { background: var(--color-background); color: var(--color-foreground); font-family: var(--font-sans); } diff --git a/docs/design-extract/storybook/tsconfig.json b/docs/design-extract/storybook/tsconfig.json deleted file mode 100644 index 68637fc..0000000 --- a/docs/design-extract/storybook/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "Bundler", - "jsx": "react-jsx", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true - }, - "include": [ - "stories/**/*", - ".storybook/**/*" - ] -} \ No newline at end of file diff --git a/docs/design-extract/tokens/tokens.flat.json b/docs/design-extract/tokens/tokens.flat.json deleted file mode 100644 index 48f437f..0000000 --- a/docs/design-extract/tokens/tokens.flat.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "color": { - "primary": { - "$value": "#d08728", - "$type": "color" - }, - "neutral-0": { - "$value": "#000000", - "$type": "color" - }, - "neutral-1": { - "$value": "#171717", - "$type": "color" - }, - "neutral-2": { - "$value": "#ffffff", - "$type": "color" - }, - "neutral-3": { - "$value": "#616161", - "$type": "color" - }, - "neutral-4": { - "$value": "#e5e5e5", - "$type": "color" - }, - "background-0": { - "$value": "#ffffff", - "$type": "color" - }, - "background-1": { - "$value": "#616161", - "$type": "color" - }, - "text-0": { - "$value": "#000000", - "$type": "color" - }, - "text-1": { - "$value": "#ffffff", - "$type": "color" - }, - "text-2": { - "$value": "#171717", - "$type": "color" - }, - "text-3": { - "$value": "#d08728", - "$type": "color" - } - }, - "fontFamily": { - "body": { - "$value": "Arial", - "$type": "fontFamily" - }, - "inter": { - "$value": "Inter", - "$type": "fontFamily" - } - }, - "fontSize": { - "8": { - "$value": "8px", - "$type": "dimension" - }, - "12": { - "$value": "12px", - "$type": "dimension" - }, - "14": { - "$value": "14px", - "$type": "dimension" - }, - "16": { - "$value": "16px", - "$type": "dimension" - }, - "18": { - "$value": "18px", - "$type": "dimension" - }, - "32": { - "$value": "32px", - "$type": "dimension" - }, - "48": { - "$value": "48px", - "$type": "dimension" - }, - "13.3333": { - "$value": "13.3333px", - "$type": "dimension" - } - }, - "spacing": { - "1": { - "$value": "2px", - "$type": "dimension" - }, - "16": { - "$value": "32px", - "$type": "dimension" - }, - "34": { - "$value": "68px", - "$type": "dimension" - } - }, - "borderRadius": { - "sm": { - "$value": "4px", - "$type": "dimension" - }, - "md": { - "$value": "8px", - "$type": "dimension" - } - }, - "shadow": { - "md": { - "$value": "rgb(97, 97, 97) 2px 2px 8px 0px", - "$type": "shadow" - } - }, - "breakpoint": {} -} \ No newline at end of file diff --git a/scripts/capture-auth-state.mjs b/scripts/capture-auth-state.mjs index 736a6e4..7e1e0ea 100755 --- a/scripts/capture-auth-state.mjs +++ b/scripts/capture-auth-state.mjs @@ -142,39 +142,33 @@ async function main() { const lsKeys = (state.origins || []).flatMap((o) => (o.localStorage || []).map((e) => e.name), ); - // Bubble always sets coulomb_* session cookies for anonymous visitors. - // A real login usually adds more localStorage keys and/or more cookies. - const onlyDefaultBubbleCookies = - cookieCount <= 3 && - (state.cookies || []).every((c) => - String(c.name || "").startsWith("coulomb_"), - ); - const thinLocalStorage = - lsKeys.length === 0 || - (lsKeys.length === 1 && lsKeys[0] === "algoliasearch-client-js"); - if (onlyDefaultBubbleCookies && thinLocalStorage) { + // Bubble often keeps the same coulomb_* cookie *names* for guests and + // members — names alone are not a login signal. Probe the live page: + // authenticated app usually leaves the bare landing path. + let probeUrl = page.url(); + let probeTitle = await page.title().catch(() => ""); + const path = (() => { + try { + return new URL(probeUrl).pathname; + } catch { + return ""; + } + })(); + const looksLikeLanding = path === "/" || path === ""; + + if (looksLikeLanding && !fromPasswordFiles) { console.error(""); console.error( - "WARNING: This looks like an anonymous Bubble session, not a logged-in user.", + "WARNING: Still on the site root after capture — login may not have completed.", ); + console.error(` url: ${probeUrl}`); + console.error(` title: ${probeTitle}`); console.error( - ` cookies=${cookieCount} (only default coulomb_* names)`, + "Log in fully, open an app page (e.g. Research / Pages), then press Enter.", ); - console.error(` localStorage keys: ${lsKeys.join(", ") || "(none)"}`); - console.error(""); - console.error("Do not use this for authenticated design extract."); - console.error("Re-run, fully log in, wait until the app UI is loaded,"); - console.error("then press Enter. If login uses a popup, complete it first."); - process.exitCode = 2; - // Still write so you can inspect, but mark filename - const weakPath = STATE_PATH.replace(/\.json$/, ".anonymous.json"); - writeFileSync(weakPath, JSON.stringify(state, null, 2) + "\n", { - mode: 0o600, - }); - chmodSync(weakPath, 0o600); - console.error(`Wrote weak session for inspection only: ${weakPath}`); - return; + // Continue to save anyway — Bubble guest+member share cookie names; user + // may still have a valid session that only reveals itself after navigation. } writeFileSync(STATE_PATH, JSON.stringify(state, null, 2) + "\n", { @@ -186,6 +180,7 @@ async function main() { console.log( `Saved storageState (${cookieCount} cookies, ${originCount} origins, localStorage keys: ${lsKeys.length}).`, ); + console.log(` page at save: ${probeUrl} — ${probeTitle}`); console.log(`File: ${STATE_PATH}`); console.log("Next: ./scripts/run-design-extract.sh"); } finally { diff --git a/scripts/probe-auth-session.mjs b/scripts/probe-auth-session.mjs new file mode 100755 index 0000000..075a1bf --- /dev/null +++ b/scripts/probe-auth-session.mjs @@ -0,0 +1,21 @@ +#!/usr/bin/env node +/** Print final URL after loading coulomb.social with storageState (no secrets). */ +import { chromium } from "playwright"; +import { homedir } from "os"; +import { join } from "path"; + +const statePath = + process.env.COULOMB_SOCIAL_STORAGE_STATE || + join(homedir(), ".config/coulomb-social/auth/storage-state.json"); +const url = process.env.COULOMB_SOCIAL_URL || "https://coulomb.social"; + +const browser = await chromium.launch({ headless: true }); +try { + const context = await browser.newContext({ storageState: statePath }); + const page = await context.newPage(); + await page.goto(url, { waitUntil: "domcontentloaded", timeout: 45000 }); + await page.waitForTimeout(3000); + console.log(page.url()); +} finally { + await browser.close(); +} diff --git a/scripts/run-design-extract.sh b/scripts/run-design-extract.sh index 712b18c..a2d8f90 100755 --- a/scripts/run-design-extract.sh +++ b/scripts/run-design-extract.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash # Run designlang against coulomb.social using a captured Playwright storageState. -# Does not print secrets. Requires: ./scripts/capture-auth-state.mjs first. +# Does not print secrets. Requires: ./scripts/capture-auth-state.sh first. +# +# NOTE: designlang's `pack` subcommand does NOT pass --cookie-file into the +# crawler (it calls extractDesignLanguage(url) with no auth options). Use the +# main extract command, which does apply cookies from storageState. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" @@ -8,6 +12,7 @@ AUTH_DIR="${COULOMB_SOCIAL_AUTH_DIR:-$HOME/.config/coulomb-social/auth}" STATE_PATH="${COULOMB_SOCIAL_STORAGE_STATE:-$AUTH_DIR/storage-state.json}" OUT_DIR="${COULOMB_SOCIAL_EXTRACT_OUT:-$ROOT/docs/design-extract}" URL="${COULOMB_SOCIAL_URL:-https://coulomb.social}" +WAIT_MS="${COULOMB_SOCIAL_EXTRACT_WAIT:-5000}" if [[ ! -f "$STATE_PATH" ]]; then echo "ERROR: No auth session at $STATE_PATH" >&2 @@ -22,21 +27,78 @@ if [[ "$mode" != "600" && "$mode" != "0600" ]]; then echo "warning: $STATE_PATH mode is $mode (prefer 600)" >&2 fi +echo "==> probing session (no secrets printed)…" +PROBE_URL="$( + cd "$ROOT/scripts" && \ + COULOMB_SOCIAL_STORAGE_STATE="$STATE_PATH" \ + COULOMB_SOCIAL_URL="$URL" \ + node ./probe-auth-session.mjs +)" || PROBE_URL="" +if [[ -n "$PROBE_URL" ]]; then + echo " session lands on: $PROBE_URL" + if [[ "$PROBE_URL" == "https://coulomb.social/" || "$PROBE_URL" == "https://coulomb.social" ]]; then + echo "warning: session still on site root — may be guest; re-run capture-auth-state.sh if extract looks empty" >&2 + fi +fi + mkdir -p "$OUT_DIR" -echo "==> designlang extract" +echo "==> designlang extract (main command — cookies applied)" echo " url: $URL" echo " auth: $STATE_PATH (session file present; not printed)" echo " out: $OUT_DIR" +echo " wait: ${WAIT_MS}ms" echo " extra: $*" -# Global flags (auth, name) must precede the subcommand; pack only accepts -o/--with-clone/--open. -# --cookie-file accepts Playwright storageState JSON. -# Extra args after -- are appended to pack (e.g. --with-clone). -mkdir -p "$(dirname "$OUT_DIR")" -exec npx --yes designlang \ +# Main command supports --cookie-file. Prefer a rich capture of the live app UI. +set +e +npx --yes designlang "$URL" \ --cookie-file "$STATE_PATH" \ - --name coulomb-social \ - pack "$URL" \ -o "$OUT_DIR" \ + -n coulomb-social \ + --wait "$WAIT_MS" \ + --depth "${COULOMB_SOCIAL_EXTRACT_DEPTH:-2}" \ + --interactions \ + --verbose \ "$@" +dl_ec=$? +set -e + +# designlang can crash late while printing summary (Buffer.byteLength on undefined +# content for optional emitters) after already writing the useful artifacts. +if [[ $dl_ec -ne 0 ]]; then + if [[ -f "$OUT_DIR/coulomb-social-design-language.md" && -f "$OUT_DIR/coulomb-social-design-tokens.json" ]]; then + echo "warning: designlang exited $dl_ec after writing core artifacts (known late summary bug); treating as success" >&2 + else + echo "ERROR: designlang failed (exit $dl_ec) and core artifacts are missing" >&2 + exit "$dl_ec" + fi +fi + +# Drop root-level pack leftovers from earlier mistaken `pack` runs (no cookies). +if [[ -d "$ROOT/coulomb-social-design-system" ]]; then + echo "==> removing unauthenticated pack leftover: coulomb-social-design-system/" + rm -rf "$ROOT/coulomb-social-design-system" +fi + +# Provenance (no secrets) +cat > "$OUT_DIR/PROVENANCE.md" < done. Inspect: $OUT_DIR" +ls -la "$OUT_DIR" | head -50