Add designlang public-shell pack; tighten auth capture checks

Ran authenticated extract against coulomb.social; session metadata
matched anonymous Bubble defaults, so treat docs/design-extract as a
public shell baseline (PROVENANCE.md). Capture script now refuses to
overwrite storage-state.json with thin anonymous sessions.
This commit is contained in:
tegwick 2026-08-09 01:22:15 +02:00
parent 0bf740017e
commit 319dd00465
28 changed files with 1524 additions and 6 deletions

View file

@ -0,0 +1,20 @@
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.

View file

@ -0,0 +1,16 @@
# Design extract provenance
| 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/` |
## Next
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.

View file

@ -0,0 +1,63 @@
# 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
<link rel="stylesheet" href="tokens/variables.css">
```
### 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
```

View file

@ -0,0 +1,4 @@
// Auto-generated by designlang — component anatomy v2.
// Scaffolds. Wire into your token system; not a runtime library.
import * as React from 'react';

View file

@ -0,0 +1,120 @@
# 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
}
]
}
```

View file

@ -0,0 +1,13 @@
{
"tone": "neutral",
"pronoun": "third-person",
"headingStyle": "unknown",
"headingLengthClass": "tight",
"ctaVerbs": [],
"buttonPatterns": [],
"sampleHeadings": [],
"stats": {
"buttons": 0,
"headings": 0
}
}

View file

@ -0,0 +1,13 @@
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.

View file

@ -0,0 +1,18 @@
# 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

View file

@ -0,0 +1,12 @@
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

View file

@ -0,0 +1,28 @@
# 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
}
]
}
```

View file

@ -0,0 +1,20 @@
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.

View file

@ -0,0 +1,41 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>coulomb.social starter</title>
<link rel="stylesheet" href="../tokens/variables.css">
<style>
body {
margin: 0;
font-family: "Times New Roman", -apple-system, BlinkMacSystemFont, sans-serif;
background: var(--color-background, #fff);
color: var(--color-text, #111);
line-height: 1.5;
}
main { max-width: 840px; margin: 0 auto; padding: 64px 32px; }
h1 { font-size: clamp(40px, 6vw, 72px); line-height: 1.05; margin: 0 0 18px; }
p { font-size: 18px; max-width: 56ch; color: var(--color-text-secondary, #555); }
.cta {
display: inline-block;
padding: 14px 28px;
margin-top: 28px;
background: var(--color-primary, #0a0a0a);
color: var(--color-on-primary, #fff);
border-radius: var(--radius-md, 8px);
text-decoration: none;
font-weight: 600;
}
.cta:hover { opacity: 0.9; }
.meta { margin-top: 64px; font-size: 12px; color: #888; }
.meta a { color: inherit; }
</style>
</head>
<body>
<main>
<h1>Built from coulomb.social</h1>
<p>This starter is wired to the tokens in <code>tokens/variables.css</code>. Edit the variables and watch this page change. Drop in your own components and use the same tokens to keep the visual language consistent.</p>
<a class="cta" href="#">Get started</a>
<p class="meta">Generated by <a href="https://designlang.app">designlang</a>. Re-pack with <code>npx designlang pack coulomb.social</code>.</p>
</main>
</body>
</html>

View file

@ -0,0 +1,8 @@
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;

View file

@ -0,0 +1,10 @@
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;

View file

@ -0,0 +1,15 @@
# Index | Coulomb · Storybook
Auto-generated by `designlang <url> --storybook`.
## Stories
_No anatomy detected on the source page._
## Run
```
npm install
npm run storybook
```
Opens at http://localhost:6006.

View file

@ -0,0 +1,26 @@
{
"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"
}
}

View file

@ -0,0 +1,15 @@
import { Meta, ColorPalette, ColorItem, Typeset } from '@storybook/blocks';
<Meta title="Extracted/Tokens" />
# Design tokens
Extracted from https://coulomb.social by [designlang](https://github.com/Manavarya09/design-extract).
<ColorPalette>
<ColorItem title="primary" colors={{ primary: '#d08728' }} />
<ColorItem title="secondary" colors={{ secondary: '#8b5cf6' }} />
<ColorItem title="accent" colors={{ accent: '#f59e0b' }} />
<ColorItem title="background" colors={{ background: '#ffffff' }} />
<ColorItem title="foreground" colors={{ foreground: '#000000' }} />
</ColorPalette>

View file

@ -0,0 +1,11 @@
: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); }

View file

@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": [
"stories/**/*",
".storybook/**/*"
]
}

View file

@ -0,0 +1,162 @@
{
"$metadata": {
"generator": "designlang",
"version": "7.0.0",
"spec": "https://design-tokens.github.io/community-group/format/",
"source": "https://coulomb.social",
"generatedAt": "2026-08-08T23:21:16.292Z"
},
"primitive": {
"color": {
"brand": {
"primary": {
"$value": "#d08728",
"$type": "color"
}
},
"neutral": {
"n100": {
"$value": "#000000",
"$type": "color"
},
"n200": {
"$value": "#171717",
"$type": "color"
},
"n300": {
"$value": "#ffffff",
"$type": "color"
},
"n400": {
"$value": "#616161",
"$type": "color"
},
"n500": {
"$value": "#e5e5e5",
"$type": "color"
}
},
"background": {
"bg0": {
"$value": "#ffffff",
"$type": "color"
},
"bg1": {
"$value": "#616161",
"$type": "color"
}
},
"text": {
"text0": {
"$value": "#000000",
"$type": "color"
},
"text1": {
"$value": "#ffffff",
"$type": "color"
},
"text2": {
"$value": "#171717",
"$type": "color"
},
"text3": {
"$value": "#d08728",
"$type": "color"
}
}
},
"spacing": {
"s0": {
"$value": "2px",
"$type": "dimension"
},
"s1": {
"$value": "32px",
"$type": "dimension"
},
"s2": {
"$value": "68px",
"$type": "dimension"
}
},
"radius": {
"r0": {
"$value": "4px",
"$type": "dimension"
},
"r1": {
"$value": "8px",
"$type": "dimension"
}
},
"shadow": {
"sh0": {
"$value": "rgb(97, 97, 97) 2px 2px 8px 0px",
"$type": "shadow"
}
},
"fontFamily": {
"f0": {
"$value": "Times New Roman",
"$type": "fontFamily"
},
"f1": {
"$value": "Helvetica",
"$type": "fontFamily"
},
"f2": {
"$value": "Inter",
"$type": "fontFamily"
},
"f3": {
"$value": "Arial",
"$type": "fontFamily"
}
}
},
"semantic": {
"color": {
"action": {
"primary": {
"$value": "{primitive.color.brand.primary}",
"$type": "color"
}
},
"surface": {
"default": {
"$value": "{primitive.color.background.bg0}",
"$type": "color"
}
},
"text": {
"body": {
"$value": "{primitive.color.text.text0}",
"$type": "color"
}
}
},
"typography": {
"body": {
"$value": {
"fontFamily": "Times New Roman",
"fontSize": "48px",
"fontWeight": "700",
"lineHeight": "67.2px"
},
"$type": "typography"
}
},
"radius": {
"control": {
"$value": "{primitive.radius.r0}",
"$type": "dimension"
}
},
"shadow": {
"elevated": {
"$value": "{primitive.shadow.sh0}",
"$type": "shadow"
}
}
}
}

View file

@ -0,0 +1,361 @@
{
"collections": [
{
"name": "Brand",
"modes": [
"light"
],
"variables": [
{
"name": "color/primary",
"type": "COLOR",
"values": {
"light": {
"r": 0.8156862745098039,
"g": 0.5294117647058824,
"b": 0.1568627450980392,
"a": 1
}
}
},
{
"name": "color/neutral/50",
"type": "COLOR",
"values": {
"light": {
"r": 0,
"g": 0,
"b": 0,
"a": 1
}
}
},
{
"name": "color/neutral/100",
"type": "COLOR",
"values": {
"light": {
"r": 0.09019607843137255,
"g": 0.09019607843137255,
"b": 0.09019607843137255,
"a": 1
}
}
},
{
"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,
"g": 0.3803921568627451,
"b": 0.3803921568627451,
"a": 1
}
}
},
{
"name": "color/neutral/400",
"type": "COLOR",
"values": {
"light": {
"r": 0.8980392156862745,
"g": 0.8980392156862745,
"b": 0.8980392156862745,
"a": 1
}
}
},
{
"name": "color/background/default",
"type": "COLOR",
"values": {
"light": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
}
}
},
{
"name": "color/background/1",
"type": "COLOR",
"values": {
"light": {
"r": 0.3803921568627451,
"g": 0.3803921568627451,
"b": 0.3803921568627451,
"a": 1
}
}
},
{
"name": "color/text/default",
"type": "COLOR",
"values": {
"light": {
"r": 0,
"g": 0,
"b": 0,
"a": 1
}
}
},
{
"name": "color/text/1",
"type": "COLOR",
"values": {
"light": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
}
}
},
{
"name": "color/text/2",
"type": "COLOR",
"values": {
"light": {
"r": 0.09019607843137255,
"g": 0.09019607843137255,
"b": 0.09019607843137255,
"a": 1
}
}
},
{
"name": "color/text/3",
"type": "COLOR",
"values": {
"light": {
"r": 0.8156862745098039,
"g": 0.5294117647058824,
"b": 0.1568627450980392,
"a": 1
}
}
}
]
},
{
"name": "Typography",
"modes": [
"default"
],
"variables": [
{
"name": "font/size/48",
"type": "FLOAT",
"values": {
"default": 48
}
},
{
"name": "font/weight/48",
"type": "FLOAT",
"values": {
"default": 700
}
},
{
"name": "font/lineHeight/48",
"type": "FLOAT",
"values": {
"default": 67.2
}
},
{
"name": "font/size/32",
"type": "FLOAT",
"values": {
"default": 32
}
},
{
"name": "font/weight/32",
"type": "FLOAT",
"values": {
"default": 600
}
},
{
"name": "font/lineHeight/32",
"type": "FLOAT",
"values": {
"default": 44.8
}
},
{
"name": "font/size/18",
"type": "FLOAT",
"values": {
"default": 18
}
},
{
"name": "font/weight/18",
"type": "FLOAT",
"values": {
"default": 600
}
},
{
"name": "font/lineHeight/18",
"type": "FLOAT",
"values": {
"default": 25.2
}
},
{
"name": "font/size/16",
"type": "FLOAT",
"values": {
"default": 16
}
},
{
"name": "font/weight/16",
"type": "FLOAT",
"values": {
"default": 400
}
},
{
"name": "font/size/14",
"type": "FLOAT",
"values": {
"default": 14
}
},
{
"name": "font/weight/14",
"type": "FLOAT",
"values": {
"default": 500
}
},
{
"name": "font/lineHeight/14",
"type": "FLOAT",
"values": {
"default": 19.6
}
},
{
"name": "font/size/13.3333",
"type": "FLOAT",
"values": {
"default": 13.3333
}
},
{
"name": "font/weight/13.3333",
"type": "FLOAT",
"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
}
}
]
},
{
"name": "Spacing",
"modes": [
"default"
],
"variables": [
{
"name": "spacing/2",
"type": "FLOAT",
"values": {
"default": 2
}
},
{
"name": "spacing/32",
"type": "FLOAT",
"values": {
"default": 32
}
},
{
"name": "spacing/68",
"type": "FLOAT",
"values": {
"default": 68
}
},
{
"name": "radius/sm",
"type": "FLOAT",
"values": {
"default": 4
}
},
{
"name": "radius/md",
"type": "FLOAT",
"values": {
"default": 8
}
}
]
}
]
}

View file

@ -0,0 +1,10 @@
{
"$description": "Motion tokens extracted by designlang",
"duration": {},
"easing": {},
"spring": {},
"$meta": {
"feel": "mixed",
"scrollLinked": true
}
}

View file

@ -0,0 +1,109 @@
/** @type {import('tailwindcss').Config} */
export default {
theme: {
extend: {
colors: {
primary: {
'50': 'hsl(34, 68%, 97%)',
'100': 'hsl(34, 68%, 94%)',
'200': 'hsl(34, 68%, 86%)',
'300': 'hsl(34, 68%, 76%)',
'400': 'hsl(34, 68%, 64%)',
'500': 'hsl(34, 68%, 50%)',
'600': 'hsl(34, 68%, 40%)',
'700': 'hsl(34, 68%, 32%)',
'800': 'hsl(34, 68%, 24%)',
'900': 'hsl(34, 68%, 16%)',
'950': 'hsl(34, 68%, 10%)',
DEFAULT: '#d08728'
},
'neutral-50': '#000000',
'neutral-100': '#171717',
'neutral-200': '#ffffff',
'neutral-300': '#616161',
'neutral-400': '#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',
{
lineHeight: '19.6px'
}
],
'16': [
'16px',
{
lineHeight: 'normal'
}
],
'18': [
'18px',
{
lineHeight: '25.2px'
}
],
'32': [
'32px',
{
lineHeight: '44.8px'
}
],
'48': [
'48px',
{
lineHeight: '67.2px'
}
],
'13.3333': [
'13.3333px',
{
lineHeight: 'normal'
}
]
},
spacing: {
'1': '2px',
'16': '32px',
'34': '68px'
},
borderRadius: {
sm: '4px',
md: '8px'
},
boxShadow: {
md: 'rgb(97, 97, 97) 2px 2px 8px 0px'
},
container: {
center: true,
padding: '32px'
},
maxWidth: {
container: '1080px'
}
},
},
};

View file

@ -0,0 +1,147 @@
// React Theme — extracted from https://coulomb.social
// Compatible with: Chakra UI, Stitches, Vanilla Extract, or any CSS-in-JS
/**
* TypeScript type definition for this theme:
*
* interface Theme {
* colors: {
primary: string;
background: string;
foreground: string;
neutral50: string;
neutral100: string;
neutral200: string;
neutral300: string;
neutral400: string;
* };
* fonts: {
body: string;
* };
* fontSizes: {
'8': string;
'12': string;
'14': string;
'16': string;
'18': string;
'32': string;
'48': string;
'13.3333': string;
* };
* space: {
'2': string;
'32': string;
'68': string;
* };
* radii: {
sm: string;
md: string;
* };
* shadows: {
md: string;
* };
* states: {
* hover: { opacity: number };
* focus: { opacity: number };
* active: { opacity: number };
* disabled: { opacity: number };
* };
* }
*/
export const theme = {
"colors": {
"primary": "#d08728",
"background": "#ffffff",
"foreground": "#000000",
"neutral50": "#000000",
"neutral100": "#171717",
"neutral200": "#ffffff",
"neutral300": "#616161",
"neutral400": "#e5e5e5"
},
"fonts": {
"body": "'Arial', sans-serif"
},
"fontSizes": {
"8": "8px",
"12": "12px",
"14": "14px",
"16": "16px",
"18": "18px",
"32": "32px",
"48": "48px",
"13.3333": "13.3333px"
},
"space": {
"2": "2px",
"32": "32px",
"68": "68px"
},
"radii": {
"sm": "4px",
"md": "8px"
},
"shadows": {
"md": "rgb(97, 97, 97) 2px 2px 8px 0px"
},
"states": {
"hover": {
"opacity": 0.08
},
"focus": {
"opacity": 0.12
},
"active": {
"opacity": 0.16
},
"disabled": {
"opacity": 0.38
}
}
};
// MUI v5 theme
export const muiTheme = {
"palette": {
"primary": {
"main": "#d08728",
"light": "hsl(34, 68%, 64%)",
"dark": "hsl(34, 68%, 34%)"
},
"background": {
"default": "#ffffff",
"paper": "#616161"
},
"text": {
"primary": "#000000",
"secondary": "#ffffff"
}
},
"typography": {
"fontFamily": "'Times New Roman', sans-serif",
"h1": {
"fontSize": "32px",
"fontWeight": "600",
"lineHeight": "44.8px"
},
"body1": {
"fontSize": "16px",
"fontWeight": "400",
"lineHeight": "normal"
},
"body2": {
"fontSize": "13.3333px",
"fontWeight": "400",
"lineHeight": "normal"
}
},
"shape": {
"borderRadius": 8
},
"shadows": [
"rgb(97, 97, 97) 2px 2px 8px 0px"
]
};
export default theme;

View file

@ -0,0 +1,127 @@
{
"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": {}
}

View file

@ -0,0 +1,93 @@
:root {
/* Colors — Primary */
--color-primary: #d08728;
/* Colors — Neutrals */
--color-neutral-50: #000000;
--color-neutral-100: #171717;
--color-neutral-200: #ffffff;
--color-neutral-300: #616161;
--color-neutral-400: #e5e5e5;
/* Colors — Backgrounds */
--color-bg: #ffffff;
--color-bg-1: #616161;
/* Colors — Text */
--color-text: #000000;
--color-text-1: #ffffff;
--color-text-2: #171717;
--color-text-3: #d08728;
/* 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;
/* Typography — Scale */
--font-size-48: 48px;
--font-size-32: 32px;
--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-32: 32px;
--spacing-68: 68px;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
/* Box Shadows */
--shadow-md: rgb(97, 97, 97) 2px 2px 8px 0px;
/* Original Site Variables */
/* — colors — */
--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 — */
--font_default: 'Lato';
--font_bTRUx_default: "Inter";
--font_bTRUt_default: "Inter";
/* — semantic — */
success: [object Object];
warning: [object Object];
error: [object Object];
info: [object Object];
}

View file

@ -137,16 +137,54 @@ async function main() {
}
const state = await context.storageState();
const cookieCount = state.cookies?.length ?? 0;
const originCount = state.origins?.length ?? 0;
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) {
console.error("");
console.error(
"WARNING: This looks like an anonymous Bubble session, not a logged-in user.",
);
console.error(
` cookies=${cookieCount} (only default coulomb_* names)`,
);
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;
}
writeFileSync(STATE_PATH, JSON.stringify(state, null, 2) + "\n", {
mode: 0o600,
});
chmodSync(STATE_PATH, 0o600);
const cookieCount = state.cookies?.length ?? 0;
const originCount = state.origins?.length ?? 0;
console.log("");
console.log(
`Saved storageState (${cookieCount} cookies, ${originCount} origins).`,
`Saved storageState (${cookieCount} cookies, ${originCount} origins, localStorage keys: ${lsKeys.length}).`,
);
console.log(`File: ${STATE_PATH}`);
console.log("Next: ./scripts/run-design-extract.sh");

View file

@ -30,10 +30,13 @@ echo " auth: $STATE_PATH (session file present; not printed)"
echo " out: $OUT_DIR"
echo " extra: $*"
# Default pack is useful for agent rebuild; caller can pass more flags.
# Global flags (auth, name) must precede the subcommand; pack only accepts -o/--with-clone/--open.
# --cookie-file accepts Playwright storageState JSON.
exec npx --yes designlang pack "$URL" \
# Extra args after -- are appended to pack (e.g. --with-clone).
mkdir -p "$(dirname "$OUT_DIR")"
exec npx --yes designlang \
--cookie-file "$STATE_PATH" \
-o "$OUT_DIR" \
--name coulomb-social \
pack "$URL" \
-o "$OUT_DIR" \
"$@"