Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ef53a8f46 | ||
|
|
db5496ae19 |
File diff suppressed because one or more lines are too long
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="./support.js"></script>
|
||||
<template id="__bundler_thumbnail" data-bg-color="#2c2c30">
|
||||
<svg viewBox="0 0 1200 800" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="1200" height="800" fill="#2c2c30"/>
|
||||
<g transform="translate(600 400)">
|
||||
<rect x="-210" y="-210" width="200" height="200" fill="#36363a" stroke="#4e4e57" stroke-width="4"/>
|
||||
<rect x="10" y="-210" width="200" height="200" fill="#8f7ae0"/>
|
||||
<rect x="-210" y="10" width="200" height="200" fill="#7a63cc"/>
|
||||
<rect x="10" y="10" width="200" height="200" fill="#232327" stroke="#4e4e57" stroke-width="4"/>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<link rel="stylesheet" href="_ds/cubecraftlabs-design-system-2b6768ed-3ea8-4585-ac7e-108f768354a6/tokens/fonts.css">
|
||||
<link rel="stylesheet" href="_ds/cubecraftlabs-design-system-2b6768ed-3ea8-4585-ac7e-108f768354a6/tokens/colors.css">
|
||||
<link rel="stylesheet" href="_ds/cubecraftlabs-design-system-2b6768ed-3ea8-4585-ac7e-108f768354a6/tokens/typography.css">
|
||||
<link rel="stylesheet" href="_ds/cubecraftlabs-design-system-2b6768ed-3ea8-4585-ac7e-108f768354a6/tokens/spacing.css">
|
||||
<link rel="stylesheet" href="_ds/cubecraftlabs-design-system-2b6768ed-3ea8-4585-ac7e-108f768354a6/styles.css">
|
||||
<script src="_ds/cubecraftlabs-design-system-2b6768ed-3ea8-4585-ac7e-108f768354a6/_ds_bundle.js"></script>
|
||||
<style>
|
||||
body { margin: 0; background: var(--ccl-charcoal); }
|
||||
a { color: var(--ccl-purple); text-decoration: none; }
|
||||
a:hover { color: var(--ccl-purple-dim); text-decoration: underline; }
|
||||
</style>
|
||||
</helmet>
|
||||
|
||||
<div style="min-height:100vh;background:var(--ccl-charcoal);color:var(--ccl-text);font-family:'JetBrains Mono',monospace;padding:56px 64px 80px;display:flex;flex-direction:column;gap:56px">
|
||||
|
||||
<header style="display:flex;align-items:flex-end;justify-content:space-between;gap:32px;border-bottom:1px solid var(--ccl-border-2);padding-bottom:24px">
|
||||
<div style="display:flex;flex-direction:column;gap:10px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--ccl-text-muted)">Color profile · revision 02</span>
|
||||
<h1 style="margin:0;font-size:34px;font-weight:800;letter-spacing:0.02em;line-height:1.2">CubeCraft<span style="color:var(--ccl-purple)">Labs</span> — grey bench, violet accent</h1>
|
||||
<p style="margin:0;max-width:62ch;font-size:14px;line-height:1.7;color:var(--ccl-text-muted);text-wrap:pretty">The ground moves from near-black charcoal to a medium grey, and gold is replaced by a single violet accent. Structure is untouched: square corners, hairline borders, JetBrains Mono, flat surfaces.</p>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:20px">
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.CubeMark" variant="exploded" size="76" hint-size="76px,76px"></x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Badge" tone="success" hint-size="auto,22px">tokens updated</x-import>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section style="display:flex;flex-direction:column;gap:20px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--ccl-text-muted)">Base scale</span>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:1px;background:var(--ccl-border-2);border:1px solid var(--ccl-border-2)">
|
||||
<sc-for list="{{ swatches }}" as="s" hint-placeholder-count="8">
|
||||
<div style="background:var(--ccl-charcoal-2);padding:16px;display:flex;flex-direction:column;gap:14px">
|
||||
<div style="height:56px;border:1px solid var(--ccl-border-2);background:{{ s.hex }}"></div>
|
||||
<div style="display:flex;flex-direction:column;gap:4px">
|
||||
<span style="font-size:12px;font-weight:700">{{ s.token }}</span>
|
||||
<span style="font-size:12px;color:var(--ccl-text-muted)">{{ s.hex }}</span>
|
||||
<span style="font-size:11px;color:var(--ccl-text-muted);letter-spacing:0.02em">{{ s.role }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</sc-for>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display:grid;grid-template-columns:1.15fr 1fr;gap:32px;align-items:start">
|
||||
<div style="display:flex;flex-direction:column;gap:20px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--ccl-text-muted)">In context</span>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Card" eyebrow="build queue" title="run-0294 · lattice bracket" accent="{{ true }}" hint-size="100%,300px">
|
||||
<div style="display:flex;flex-direction:column;gap:20px;font-size:13px;line-height:1.7;color:var(--ccl-text-muted)">
|
||||
<p style="margin:0">Violet carries the same job gold did — mark, active state, one primary action per view. On the lighter ground it needs to sit a step brighter to hold contrast.</p>
|
||||
<div style="display:flex;gap:10px;flex-wrap:wrap">
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Button" variant="primary" hint-size="auto,40px">START BUILD</x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Button" variant="secondary" hint-size="auto,40px">SPEC</x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Button" variant="ghost" hint-size="auto,40px">CANCEL</x-import>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Tag" hash="{{ true }}" hint-size="auto,22px">petg</x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Tag" hash="{{ true }}" hint-size="auto,22px">0.12mm</x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Badge" tone="default" hint-size="auto,22px">queued</x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Badge" tone="error" hint-size="auto,22px">tolerance</x-import>
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:12px;max-width:340px">
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Input" prompt="{{ true }}" placeholder="make bracket --rev 02" hint-size="100%,36px"></x-import>
|
||||
<div style="display:flex;gap:24px;align-items:center">
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Checkbox" checked="{{ true }}" label="purge nozzle" hint-size="auto,20px"></x-import>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Switch" checked="{{ true }}" label="verbose log" hint-size="auto,20px"></x-import>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-import>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;flex-direction:column;gap:20px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--ccl-text-muted)">Terminal surface</span>
|
||||
<x-import component-from-global-scope="CubeCraftLabsDesignSystem_2b6768.Terminal" title="~/labs/tokens" lines="{{ lines }}" hint-size="100%,260px"></x-import>
|
||||
<p style="margin:0;font-size:12px;line-height:1.7;color:var(--ccl-text-muted);text-wrap:pretty">Code and input wells now recess <em style="font-style:normal;color:var(--ccl-text)">below</em> the page instead of rising above it — on a medium ground, darker reads as inset.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<sc-if value="{{ showComparison }}" hint-placeholder-val="{{ true }}">
|
||||
<section style="display:flex;flex-direction:column;gap:20px;border-top:1px solid var(--ccl-border-2);padding-top:32px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--ccl-text-muted)">Before / after</span>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:24px">
|
||||
<div style="background:#1a1a1a;border:1px solid #333;padding:24px;display:flex;flex-direction:column;gap:16px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:#6b6b6b">rev 01 — charcoal + gold</span>
|
||||
<div style="display:flex;gap:8px">
|
||||
<span style="width:44px;height:44px;background:#1a1a1a;border:1px solid #333"></span>
|
||||
<span style="width:44px;height:44px;background:#202020;border:1px solid #333"></span>
|
||||
<span style="width:44px;height:44px;background:#e5c07b"></span>
|
||||
<span style="width:44px;height:44px;background:#caa869"></span>
|
||||
</div>
|
||||
<span style="font-size:13px;color:#d4d4d4">Cube<span style="color:#e5c07b">Craft</span> · <span style="color:#e5c07b">✓ build complete</span></span>
|
||||
</div>
|
||||
<div style="background:var(--ccl-charcoal);border:1px solid var(--ccl-border-2);padding:24px;display:flex;flex-direction:column;gap:16px">
|
||||
<span style="font-size:11px;font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--ccl-text-muted)">rev 02 — grey + violet</span>
|
||||
<div style="display:flex;gap:8px">
|
||||
<span style="width:44px;height:44px;background:var(--ccl-charcoal);border:1px solid var(--ccl-border-2)"></span>
|
||||
<span style="width:44px;height:44px;background:var(--ccl-charcoal-2);border:1px solid var(--ccl-border-2)"></span>
|
||||
<span style="width:44px;height:44px;background:var(--ccl-purple)"></span>
|
||||
<span style="width:44px;height:44px;background:var(--ccl-purple-dim)"></span>
|
||||
</div>
|
||||
<span style="font-size:13px;color:var(--ccl-text)">Cube<span style="color:var(--ccl-purple)">Craft</span> · <span style="color:var(--ccl-purple)">✓ build complete</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</sc-if>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props="{"accentColor":{"editor":"color","default":"#8f7ae0","tsType":"string","options":["#8f7ae0","#a78bfa","#b79cf0","#7a63cc"],"section":"Palette"},"pageGrey":{"editor":"color","default":"#2c2c30","tsType":"string","options":["#242428","#2c2c30","#35353a","#3f3f45"],"section":"Palette"},"showComparison":{"editor":"boolean","default":true,"tsType":"boolean","section":"Layout"}}">
|
||||
class Component extends DCLogic {
|
||||
componentDidMount() { this.applyTokens(); }
|
||||
componentDidUpdate() { this.applyTokens(); }
|
||||
|
||||
applyTokens() {
|
||||
const r = document.documentElement.style;
|
||||
const accent = this.props.accentColor ?? "#8f7ae0";
|
||||
const grey = this.props.pageGrey ?? "#2c2c30";
|
||||
r.setProperty("--ccl-gold", accent);
|
||||
r.setProperty("--ccl-gold-dim", this.shift(accent, -0.12));
|
||||
r.setProperty("--ccl-purple-wash", this.rgba(accent, 0.12));
|
||||
r.setProperty("--ccl-charcoal", grey);
|
||||
r.setProperty("--ccl-charcoal-2", this.shift(grey, 0.06));
|
||||
r.setProperty("--ccl-charcoal-3", this.shift(grey, -0.38));
|
||||
r.setProperty("--ccl-border", this.shift(grey, 0.14));
|
||||
r.setProperty("--ccl-border-2", this.shift(grey, 0.26));
|
||||
}
|
||||
|
||||
parse(hex) {
|
||||
const h = hex.replace("#", "");
|
||||
return [0, 2, 4].map(i => parseInt(h.slice(i, i + 2), 16));
|
||||
}
|
||||
shift(hex, amt) {
|
||||
const to = amt > 0 ? 255 : 0;
|
||||
const p = Math.abs(amt);
|
||||
const [r, g, b] = this.parse(hex).map(v => Math.round(v + (to - v) * p));
|
||||
return "#" + [r, g, b].map(v => v.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
rgba(hex, a) { return `rgba(${this.parse(hex).join(",")},${a})`; }
|
||||
|
||||
renderVals() {
|
||||
const accent = this.props.accentColor ?? "#8f7ae0";
|
||||
const grey = this.props.pageGrey ?? "#2c2c30";
|
||||
const swatches = [
|
||||
{ token: "--ccl-grey", hex: grey, role: "page background", css: "var(--ccl-charcoal)" },
|
||||
{ token: "--ccl-grey-2", hex: this.shift(grey, 0.06), role: "raised surface", css: "var(--ccl-charcoal-2)" },
|
||||
{ token: "--ccl-grey-3", hex: this.shift(grey, -0.38), role: "input / code well", css: "var(--ccl-charcoal-3)" },
|
||||
{ token: "--ccl-purple", hex: accent, role: "brand accent", css: "var(--ccl-gold)" },
|
||||
{ token: "--ccl-purple-dim", hex: this.shift(accent, -0.12), role: "hover / pressed", css: "var(--ccl-gold-dim)" },
|
||||
{ token: "--ccl-text", hex: "#f4f4f6", role: "primary text", css: "var(--ccl-text)" },
|
||||
{ token: "--ccl-text-muted", hex: "#b2b2ba", role: "secondary text", css: "var(--ccl-text-muted)" },
|
||||
{ token: "--ccl-border-2", hex: this.shift(grey, 0.26), role: "rules / grid lines", css: "var(--ccl-border-2)" },
|
||||
{ token: "--ccl-green", hex: "#a9d88b", role: "success", css: "var(--ccl-green)" },
|
||||
{ token: "--ccl-red", hex: "#f08b93", role: "error", css: "var(--ccl-red)" }
|
||||
].map(s => ({ ...s, style: { "--sw": s.css } }));
|
||||
return {
|
||||
swatches,
|
||||
showComparison: this.props.showComparison ?? true,
|
||||
lines: [
|
||||
{ tone: "muted", text: "$ ccl tokens set --ground grey --accent violet" },
|
||||
{ tone: "out", text: "resolving 11 tokens" },
|
||||
{ tone: "gold", text: "--ccl-gold #e5c07b -> " + accent },
|
||||
{ tone: "gold", text: "--ccl-charcoal #1a1a1a -> " + grey },
|
||||
{ tone: "out", text: "corners 0 · borders hairline · mono unchanged" },
|
||||
{ tone: "green", text: "\u2713 profile written" }
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+357
@@ -0,0 +1,357 @@
|
||||
{
|
||||
"plugins": [
|
||||
"react",
|
||||
"import"
|
||||
],
|
||||
"rules": {
|
||||
"react/forbid-elements": [
|
||||
"warn",
|
||||
{
|
||||
"forbid": []
|
||||
}
|
||||
],
|
||||
"no-restricted-imports": [
|
||||
"warn",
|
||||
{
|
||||
"patterns": [
|
||||
{
|
||||
"group": [
|
||||
"components/core/**",
|
||||
"components/forms/**",
|
||||
"components/icons/**",
|
||||
"components/surfaces/**"
|
||||
],
|
||||
"message": "Import design-system components from 'index.js', not component internals."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-restricted-syntax": [
|
||||
"warn",
|
||||
{
|
||||
"selector": "Literal[value=/#[0-9a-fA-F]{3,8}\\b/]",
|
||||
"message": "Raw hex color — use a design-system color token via var()."
|
||||
},
|
||||
{
|
||||
"selector": "Literal[value=/\\b\\d+px\\b/]",
|
||||
"message": "Raw px value — use a design-system spacing token via var()."
|
||||
},
|
||||
{
|
||||
"selector": "Literal[value=/font-family\\s*:\\s*(?!['\\\"]?(?:JetBrains Mono))/i]",
|
||||
"message": "Font not provided by the design system. Available: JetBrains Mono."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Badge'] > JSXAttribute > JSXIdentifier[name!=/^(?:tone|children|key|ref|className|style|children)$/]",
|
||||
"message": "<Badge> doesn't accept that prop. Declared props: tone, children."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Badge'] > JSXAttribute[name.name='tone'] > Literal[value!=/^(?:default|success|error|muted)$/]",
|
||||
"message": "<Badge> tone must be one of 'default' | 'success' | 'error' | 'muted'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|size|disabled|children|key|ref|className|style|children)$/]",
|
||||
"message": "<Button> doesn't accept that prop. Declared props: variant, size, disabled, children."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:primary|secondary|ghost)$/]",
|
||||
"message": "<Button> variant must be one of 'primary' | 'secondary' | 'ghost'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]",
|
||||
"message": "<Button> size must be one of 'sm' | 'md' | 'lg'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Card'] > JSXAttribute > JSXIdentifier[name!=/^(?:title|eyebrow|actions|footer|accent|padding|children|key|ref|className|style|children)$/]",
|
||||
"message": "<Card> doesn't accept that prop. Declared props: title, eyebrow, actions, footer, accent, padding, children."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Checkbox'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|key|ref|className|style|children)$/]",
|
||||
"message": "<Checkbox> doesn't accept that prop. Declared props: label."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='CubeMark'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|size|color|strokeWidth|style|key|ref|className|style|children)$/]",
|
||||
"message": "<CubeMark> doesn't accept that prop. Declared props: variant, size, color, strokeWidth, style."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='CubeMark'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:wireframe|exploded|grid)$/]",
|
||||
"message": "<CubeMark> variant must be one of 'wireframe' | 'exploded' | 'grid'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Field'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|hint|error|required|htmlFor|children|key|ref|className|style|children)$/]",
|
||||
"message": "<Field> doesn't accept that prop. Declared props: label, hint, error, required, htmlFor, children."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Icon'] > JSXAttribute > JSXIdentifier[name!=/^(?:name|set|size|color|strokeWidth|key|ref|className|style|children)$/]",
|
||||
"message": "<Icon> doesn't accept that prop. Declared props: name, set, size, color, strokeWidth."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Icon'] > JSXAttribute[name.name='set'] > Literal[value!=/^(?:lucide|terminal)$/]",
|
||||
"message": "<Icon> set must be one of 'lucide' | 'terminal'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute > JSXIdentifier[name!=/^(?:name|set|variant|size|disabled|label|key|ref|className|style|children)$/]",
|
||||
"message": "<IconButton> doesn't accept that prop. Declared props: name, set, variant, size, disabled, label."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute[name.name='set'] > Literal[value!=/^(?:lucide|terminal)$/]",
|
||||
"message": "<IconButton> set must be one of 'lucide' | 'terminal'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:ghost|outline|solid)$/]",
|
||||
"message": "<IconButton> variant must be one of 'ghost' | 'outline' | 'solid'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]",
|
||||
"message": "<IconButton> size must be one of 'sm' | 'md' | 'lg'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Input'] > JSXAttribute > JSXIdentifier[name!=/^(?:size|invalid|prompt|key|ref|className|style|children)$/]",
|
||||
"message": "<Input> doesn't accept that prop. Declared props: size, invalid, prompt."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Input'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]",
|
||||
"message": "<Input> size must be one of 'sm' | 'md' | 'lg'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Radio'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|key|ref|className|style|children)$/]",
|
||||
"message": "<Radio> doesn't accept that prop. Declared props: label."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Select'] > JSXAttribute > JSXIdentifier[name!=/^(?:size|invalid|children|key|ref|className|style|children)$/]",
|
||||
"message": "<Select> doesn't accept that prop. Declared props: size, invalid, children."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Select'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]",
|
||||
"message": "<Select> size must be one of 'sm' | 'md' | 'lg'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Switch'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|key|ref|className|style|children)$/]",
|
||||
"message": "<Switch> doesn't accept that prop. Declared props: label."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Tag'] > JSXAttribute > JSXIdentifier[name!=/^(?:hash|onRemove|children|key|ref|className|style|children)$/]",
|
||||
"message": "<Tag> doesn't accept that prop. Declared props: hash, onRemove, children."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='TerminalLine'] > JSXAttribute > JSXIdentifier[name!=/^(?:text|prompt|tone|key|ref|className|style|children)$/]",
|
||||
"message": "<TerminalLine> doesn't accept that prop. Declared props: text, prompt, tone."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='TerminalLine'] > JSXAttribute[name.name='tone'] > Literal[value!=/^(?:out|muted|gold|green|red)$/]",
|
||||
"message": "<TerminalLine> tone must be one of 'out' | 'muted' | 'gold' | 'green' | 'red'."
|
||||
},
|
||||
{
|
||||
"selector": "JSXOpeningElement[name.name='Textarea'] > JSXAttribute > JSXIdentifier[name!=/^(?:invalid|key|ref|className|style|children)$/]",
|
||||
"message": "<Textarea> doesn't accept that prop. Declared props: invalid."
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/index.js"
|
||||
],
|
||||
"rules": {
|
||||
"no-restricted-imports": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"x-omelette": {
|
||||
"components": {
|
||||
"Badge": {
|
||||
"replaces": []
|
||||
},
|
||||
"Button": {
|
||||
"replaces": []
|
||||
},
|
||||
"Card": {
|
||||
"replaces": []
|
||||
},
|
||||
"Checkbox": {
|
||||
"replaces": []
|
||||
},
|
||||
"CubeMark": {
|
||||
"replaces": []
|
||||
},
|
||||
"Field": {
|
||||
"replaces": []
|
||||
},
|
||||
"Icon": {
|
||||
"replaces": []
|
||||
},
|
||||
"IconButton": {
|
||||
"replaces": []
|
||||
},
|
||||
"Input": {
|
||||
"replaces": []
|
||||
},
|
||||
"Radio": {
|
||||
"replaces": []
|
||||
},
|
||||
"Select": {
|
||||
"replaces": []
|
||||
},
|
||||
"Switch": {
|
||||
"replaces": []
|
||||
},
|
||||
"Tag": {
|
||||
"replaces": []
|
||||
},
|
||||
"TerminalLine": {
|
||||
"replaces": []
|
||||
},
|
||||
"Textarea": {
|
||||
"replaces": []
|
||||
}
|
||||
},
|
||||
"tokens": [
|
||||
"--accent",
|
||||
"--accent-hover",
|
||||
"--border",
|
||||
"--border-accent",
|
||||
"--border-hairline",
|
||||
"--border-strong",
|
||||
"--border-strong-rule",
|
||||
"--border-width",
|
||||
"--ccl-border",
|
||||
"--ccl-border-2",
|
||||
"--ccl-charcoal",
|
||||
"--ccl-charcoal-2",
|
||||
"--ccl-charcoal-3",
|
||||
"--ccl-gold",
|
||||
"--ccl-gold-dim",
|
||||
"--ccl-green",
|
||||
"--ccl-red",
|
||||
"--ccl-text",
|
||||
"--ccl-text-muted",
|
||||
"--ccl-white",
|
||||
"--dur-base",
|
||||
"--dur-fast",
|
||||
"--ease-out",
|
||||
"--focus-ring",
|
||||
"--font-body",
|
||||
"--font-display",
|
||||
"--font-mono",
|
||||
"--fs-body",
|
||||
"--fs-body-lg",
|
||||
"--fs-caption",
|
||||
"--fs-display",
|
||||
"--fs-h1",
|
||||
"--fs-h2",
|
||||
"--fs-h3",
|
||||
"--fs-label",
|
||||
"--fw-bold",
|
||||
"--fw-display",
|
||||
"--fw-medium",
|
||||
"--fw-regular",
|
||||
"--lh-body",
|
||||
"--lh-snug",
|
||||
"--lh-tight",
|
||||
"--radius-md",
|
||||
"--radius-none",
|
||||
"--radius-sm",
|
||||
"--scrollbar-thumb",
|
||||
"--scrollbar-thumb-hover",
|
||||
"--scrollbar-width",
|
||||
"--shadow-none",
|
||||
"--shadow-raised",
|
||||
"--space-1",
|
||||
"--space-10",
|
||||
"--space-14",
|
||||
"--space-16",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--space-4",
|
||||
"--space-5",
|
||||
"--space-6",
|
||||
"--space-8",
|
||||
"--status-error",
|
||||
"--status-success",
|
||||
"--surface-code",
|
||||
"--surface-page",
|
||||
"--surface-raised",
|
||||
"--text-on-gold",
|
||||
"--text-primary",
|
||||
"--text-secondary",
|
||||
"--tracking-caps",
|
||||
"--tracking-caps-wide",
|
||||
"--tracking-wordmark"
|
||||
],
|
||||
"tokenKinds": {
|
||||
"--ccl-charcoal": "color",
|
||||
"--ccl-charcoal-2": "color",
|
||||
"--ccl-charcoal-3": "color",
|
||||
"--ccl-gold": "color",
|
||||
"--ccl-gold-dim": "color",
|
||||
"--ccl-text": "font",
|
||||
"--ccl-text-muted": "font",
|
||||
"--ccl-border": "color",
|
||||
"--ccl-border-2": "color",
|
||||
"--ccl-green": "color",
|
||||
"--ccl-red": "color",
|
||||
"--ccl-white": "color",
|
||||
"--surface-page": "color",
|
||||
"--surface-raised": "color",
|
||||
"--surface-code": "color",
|
||||
"--text-primary": "font",
|
||||
"--text-secondary": "font",
|
||||
"--text-on-gold": "font",
|
||||
"--accent": "color",
|
||||
"--accent-hover": "color",
|
||||
"--border-hairline": "color",
|
||||
"--border-strong": "color",
|
||||
"--status-success": "color",
|
||||
"--status-error": "color",
|
||||
"--focus-ring": "color",
|
||||
"--font-mono": "font",
|
||||
"--font-body": "font",
|
||||
"--font-display": "font",
|
||||
"--fw-regular": "font",
|
||||
"--fw-medium": "font",
|
||||
"--fw-bold": "font",
|
||||
"--fw-display": "font",
|
||||
"--fs-caption": "spacing",
|
||||
"--fs-label": "spacing",
|
||||
"--fs-body": "spacing",
|
||||
"--fs-body-lg": "spacing",
|
||||
"--fs-h3": "spacing",
|
||||
"--fs-h2": "spacing",
|
||||
"--fs-h1": "spacing",
|
||||
"--fs-display": "spacing",
|
||||
"--lh-tight": "font",
|
||||
"--lh-snug": "font",
|
||||
"--lh-body": "font",
|
||||
"--tracking-wordmark": "font",
|
||||
"--tracking-caps": "font",
|
||||
"--tracking-caps-wide": "font",
|
||||
"--space-1": "spacing",
|
||||
"--space-2": "spacing",
|
||||
"--space-3": "spacing",
|
||||
"--space-4": "spacing",
|
||||
"--space-5": "spacing",
|
||||
"--space-6": "spacing",
|
||||
"--space-8": "spacing",
|
||||
"--space-10": "spacing",
|
||||
"--space-14": "spacing",
|
||||
"--space-16": "spacing",
|
||||
"--radius-none": "radius",
|
||||
"--radius-sm": "radius",
|
||||
"--radius-md": "radius",
|
||||
"--border-width": "spacing",
|
||||
"--border": "color",
|
||||
"--border-strong-rule": "color",
|
||||
"--border-accent": "color",
|
||||
"--shadow-none": "shadow",
|
||||
"--shadow-raised": "shadow",
|
||||
"--ease-out": "other",
|
||||
"--dur-fast": "other",
|
||||
"--dur-base": "other",
|
||||
"--scrollbar-width": "spacing",
|
||||
"--scrollbar-thumb": "color",
|
||||
"--scrollbar-thumb-hover": "color"
|
||||
},
|
||||
"fontFamilies": [
|
||||
"JetBrains Mono"
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,191 @@
|
||||
# CubeCraftLabs Design System
|
||||
|
||||
> **Design. Prototype. Ship.**
|
||||
|
||||
**CubeCraftLabs** is the maker / R&D branch of [CubeCraft Creations](../). Where Creations is the storefront of finished handmade goods — warm, rounded, blue→purple gradient, Nunito — **Labs is the workshop bench where things get designed and built**: technical, dark, precise. The two brands share exactly two things — the **cube** motif and the **CubeCraft** name. Everything else deliberately diverges so Labs reads as its own identity.
|
||||
|
||||
This is a standalone design system so the two brands can evolve independently: edits here never touch Creations, and vice versa.
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
- **CubeCraft Creations design system** — the parent brand this diverges from (cube DNA + name only). Its guide describes the warm/gradient storefront identity.
|
||||
- **CubeCraftLabs logo exploration** — `CubeCraftLabs Logo.dc.html` (working lockups) and `CubeCraftLabs Brand Spec.dc.html` (spec sheet), authored in the originating project.
|
||||
- **PNG exports** — `assets/logos/CubeCraftLabs_*.png`.
|
||||
|
||||
No external codebase or Figma file backs this system yet; it was authored from the logo exploration. If a Labs product codebase appears later, build UI kits from it.
|
||||
|
||||
---
|
||||
|
||||
## CONTENT FUNDAMENTALS
|
||||
|
||||
### Voice & Tone
|
||||
Labs speaks like an **engineer at the bench** — precise, dry, confident. It's the same maker as Creations, but in "build log" mode rather than "shop" mode.
|
||||
|
||||
- **First-person plural ("we")** for the team; **second-person ("you")** for the reader.
|
||||
- **Sentence case** for prose; **lowercase** for tags/badges; **UPPERCASE** for buttons and eyebrow labels only.
|
||||
- **Short, declarative sentences.** Command-line cadence. "Printed fresh. Hand-finished. Versioned."
|
||||
- **Build/maker vocabulary** — build, ship, prototype, iterate, spec, tolerance, revision. Terminal metaphors (`$ make …`, `✓ build complete`) are on-brand for headers and hero moments.
|
||||
- **Restrained.** Fewer exclamation points than Creations. Precision over enthusiasm.
|
||||
- **No emoji** in UI. Status is shown with the green/red tokens or a `✓`/`✗` glyph, not emoji.
|
||||
|
||||
**Tagline:** *Design. Prototype. Ship.*
|
||||
|
||||
### Casing
|
||||
- Headlines: Sentence case
|
||||
- Nav items: Title Case
|
||||
- Buttons: UPPERCASE, 0.08em tracking
|
||||
- Eyebrows / section labels: UPPERCASE, 0.14em tracking
|
||||
- Tags/badges: lowercase
|
||||
- Body: sentence case
|
||||
|
||||
---
|
||||
|
||||
## VISUAL FOUNDATIONS
|
||||
|
||||
### Color
|
||||
A dark "workshop bench" palette. **Charcoal ground, gold as the single brand accent**, terminal green/red for status. There is no gradient — the Creations blue→purple is explicitly absent.
|
||||
|
||||
| Token | Hex | Role |
|
||||
|---|---|---|
|
||||
| `--ccl-charcoal` | `#1a1a1a` | Page background |
|
||||
| `--ccl-charcoal-2` | `#202020` | Raised surface |
|
||||
| `--ccl-charcoal-3` | `#262626` | Input / code block |
|
||||
| `--ccl-gold` | `#e5c07b` | Brand accent + logo mark |
|
||||
| `--ccl-gold-dim` | `#caa869` | Gold hover / pressed |
|
||||
| `--ccl-text` | `#d4d4d4` | Primary text |
|
||||
| `--ccl-text-muted` | `#6b6b6b` | Secondary text |
|
||||
| `--ccl-border` | `#2a2a2a` | Hairline borders |
|
||||
| `--ccl-border-2` | `#333333` | Stronger border / grid lines |
|
||||
| `--ccl-green` | `#98c379` | Success |
|
||||
| `--ccl-red` | `#e06c75` | Error |
|
||||
|
||||
Gold is precious — reserve it for the mark, "Labs", links, active states, and the single primary action per view. Never flood a surface with gold; never fill a large area with it.
|
||||
|
||||
### Typography
|
||||
**JetBrains Mono** is the sole typeface (loaded from Google Fonts), at weights 400 / 500 / 700 / 800. The monospace grid is the point — it signals code, precision, and the bench.
|
||||
|
||||
- **Display / Wordmark:** 800, mixed case, 0.02em tracking. Wordmark = `CubeCraft` in text color + `Labs` in gold, optional gold cursor block.
|
||||
- **Headings:** 700
|
||||
- **Body:** 400, line-height 1.7
|
||||
- **Buttons:** 700, UPPERCASE, 0.08em
|
||||
- **Eyebrows:** 700, UPPERCASE, 0.14em
|
||||
|
||||
No second family. No serif. Mono does everything.
|
||||
|
||||
### Spacing
|
||||
4px base unit. Generous breathing room around the mark. Section padding 40–64px vertical.
|
||||
|
||||
### Corners & Borders
|
||||
- **Square everywhere — `border-radius: 0`.** This is a hard rule and the sharpest tell against Creations' rounded system.
|
||||
- Borders do the work shadows would: `1px solid #2a2a2a` hairlines, `#333` for stronger rules and grid lines.
|
||||
- Accent/outline elements: `1.5px solid #e5c07b`.
|
||||
|
||||
### Backgrounds & Surfaces
|
||||
- **Page:** flat charcoal `#1a1a1a`. No gradients, no photographic hero washes.
|
||||
- **Surfaces:** raised by a hair (`#202020`) or bounded by a border, not by shadow.
|
||||
- **Graph-paper grid** (`#333` at ~32px) is a legitimate background texture for badge/blueprint contexts.
|
||||
- **Terminal window** chrome (dot header + `~/path`) is a recurring motif for headers and hero blocks.
|
||||
|
||||
### Shadows
|
||||
Effectively flat. At most a 1px seam (`--shadow-raised`). No soft drop shadows — they read "consumer app", which is the wrong brand.
|
||||
|
||||
### Motion
|
||||
- Easing `cubic-bezier(0.2, 0, 0, 1)`; 100ms micro, 160ms base.
|
||||
- Interactions are crisp, not bouncy. Buttons nudge 1px down on press. A blinking cursor block is the one signature animation (use sparingly).
|
||||
|
||||
### Hover & Interaction States
|
||||
- **Primary button:** gold → gold-dim.
|
||||
- **Secondary/ghost:** faint gold wash / text turns gold.
|
||||
- **Links:** underline or color to gold; never a gradient.
|
||||
- **Scrollbar:** 6px slim, thumb `#333` → gold on hover.
|
||||
|
||||
---
|
||||
|
||||
## ICONOGRAPHY
|
||||
|
||||
- **Lucide Icons** (stroke-based, 2px, from CDN `https://unpkg.com/lucide@latest`) — inherited from the Creations toolchain, recolored to `--ccl-text` / `--ccl-gold`. Same clean line style suits the mono aesthetic.
|
||||
- **Terminal glyphs** — `$`, `✓`, `✗`, `>` — are used as functional icons in headers and status lines.
|
||||
- **No emoji.** No hand-drawn UI SVGs.
|
||||
- **The cube mark is not an icon** — it's the logo. Use the `CubeMark` component or the SVGs in `assets/logos/`, never redraw it.
|
||||
|
||||
### Logo assets (`assets/logos/`)
|
||||
- `cube-wireframe.svg` — assembled gold wireframe cube (inline/compact)
|
||||
- `cube-exploded.svg` — exploded cube, the **primary** mark
|
||||
- `cube-grid-stamp.svg` — cube on graph paper (badge)
|
||||
- `cubecraftlabs-lockup.svg` — horizontal cube + wordmark lockup
|
||||
- `CubeCraftLabs_*.png` — rendered PNG lockups (primary, inline, terminal, grid stamp)
|
||||
|
||||
The cube geometry is fixed: viewBox `0 0 200 200`, top vertex `(100,44)`, shoulders `(146,70)`/`(54,70)`, waist `(100,96)`, base `(100,150)`. Never recolor the faces or add faces beyond the three visible.
|
||||
|
||||
---
|
||||
|
||||
## FILE INDEX
|
||||
|
||||
```
|
||||
/
|
||||
├── styles.css ← root stylesheet (link this)
|
||||
├── readme.md ← this file
|
||||
├── SKILL.md ← Agent Skill definition
|
||||
│
|
||||
├── tokens/
|
||||
│ ├── fonts.css ← JetBrains Mono @import
|
||||
│ ├── colors.css ← color custom properties
|
||||
│ ├── typography.css ← type scale + weights + tracking
|
||||
│ └── spacing.css ← spacing, radius(0), border, motion
|
||||
│
|
||||
├── assets/logos/ ← cube SVGs + PNG lockups
|
||||
│
|
||||
├── components/
|
||||
│ ├── core/ Button · Badge · Tag · CubeMark + core.card.html
|
||||
│ ├── icons/ Icon (lucide + terminal) · IconButton
|
||||
│ ├── forms/ Input · Textarea · Select · Checkbox · Radio · Switch · Field + forms.card.html
|
||||
│ └── surfaces/ Card · Terminal + surfaces.card.html
|
||||
│ (each component: .jsx / .d.ts / .prompt.md)
|
||||
│
|
||||
└── guidelines/
|
||||
├── colors/ accent · neutrals · status
|
||||
├── typography/ wordmark · scale
|
||||
├── spacing/ spacing & corners
|
||||
├── brand/ cube marks · lockup · app-logo
|
||||
├── workflows/ label-library
|
||||
└── ui-kits/ build-console
|
||||
```
|
||||
|
||||
### Components
|
||||
| Component | Group | Description |
|
||||
|---|---|---|
|
||||
| `Button` | core | Square, uppercase, mono action — primary / secondary / ghost |
|
||||
| `Badge` | core | Square outlined lowercase status chip — default / success / error / muted |
|
||||
| `Tag` | core | Lowercase content tag — optional `#`, removable `×` |
|
||||
| `CubeMark` | core | The cube logo as inline SVG — wireframe / exploded / grid |
|
||||
| `Icon` | icons | Two sets in one API: `lucide` (UI chrome) + `terminal` (CLI glyphs, brand-signature) |
|
||||
| `IconButton` | icons | Square icon-only action, same variants as `Button` |
|
||||
| `Input` | forms | Square mono text field, gold focus, optional `$` prompt |
|
||||
| `Textarea` | forms | Multi-line field, same well, vertical resize |
|
||||
| `Select` | forms | Native select, square well, gold chevron |
|
||||
| `Checkbox` | forms | Square box, gold check |
|
||||
| `Radio` | forms | Square with inner gold square (never a circle) |
|
||||
| `Switch` | forms | Square track + square knob, gold when on |
|
||||
| `Field` | forms | Label + control + hint/error row wrapper |
|
||||
| `Card` | surfaces | Flat bordered panel — eyebrow/title/actions/footer, optional gold rail |
|
||||
| `Terminal` | surfaces | Console / code block — title bar + toned mono lines (brand-signature surface) |
|
||||
|
||||
### Intentional additions
|
||||
No source component library existed — everything was authored from the brand guidelines. `CubeMark` exists because the cube is the core brand asset and needs a first-class API. The `terminal` icon set and the `Terminal` surface encode the build-log / CLI motif that defines Labs. All form controls are deliberately **square** (checkbox, radio, switch) to hold the hard no-radius rule. The **Build Console** UI kit (`guidelines/ui-kits/`) shows the whole system composed into a print-farm dashboard.
|
||||
|
||||
---
|
||||
|
||||
## Relationship to CubeCraft Creations
|
||||
|
||||
| | Creations | Labs |
|
||||
|---|---|---|
|
||||
| Purpose | Storefront, finished goods | Workshop, prototyping, R&D |
|
||||
| Ground | White / lavender-gray | Charcoal `#1a1a1a` |
|
||||
| Accent | Blue→purple gradient | Gold `#e5c07b` |
|
||||
| Type | Nunito (rounded) | JetBrains Mono |
|
||||
| Corners | 8–20px rounded | Square (0) |
|
||||
| Shared | **Cube motif · "CubeCraft" name** | ← same |
|
||||
|
||||
Keep them apart. Do not import Creations gradient/Nunito/rounded tokens into a Labs design, or vice versa.
|
||||
@@ -0,0 +1,6 @@
|
||||
/* CubeCraftLabs Design System — root stylesheet.
|
||||
Consumers link this one file. It is a list of @imports only. */
|
||||
@import "./tokens/fonts.css";
|
||||
@import "./tokens/colors.css";
|
||||
@import "./tokens/typography.css";
|
||||
@import "./tokens/spacing.css";
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/* CubeCraftLabs — Color tokens (v2: grey bench + purple accent)
|
||||
Medium-grey ground with a single violet brand accent. Token NAMES are kept
|
||||
(--ccl-charcoal-*, --ccl-gold-*) so every component keeps working; only the
|
||||
values changed. Prefer the --ccl-grey-* / --ccl-purple-* aliases in new work. */
|
||||
:root {
|
||||
/* --- Base scale --- */
|
||||
--ccl-charcoal: #2c2c30; /* page background — medium grey */
|
||||
--ccl-charcoal-2: #36363a; /* raised surface */
|
||||
--ccl-charcoal-3: #1b1b1e; /* input / code block (recessed) */
|
||||
--ccl-gold: #8f7ae0; /* brand accent — violet */
|
||||
--ccl-gold-dim: #7a63cc; /* accent hover / pressed */
|
||||
--ccl-text: #f4f4f6; /* primary text */
|
||||
--ccl-text-muted: #b2b2ba; /* secondary text */
|
||||
--ccl-border: #3d3d44; /* hairline borders */
|
||||
--ccl-border-2: #4e4e57; /* stronger border / grid lines */
|
||||
--ccl-green: #a9d88b; /* success */
|
||||
--ccl-red: #f08b93; /* error */
|
||||
--ccl-white: #ffffff;
|
||||
--ccl-ink: #2a2431; /* text on accent */
|
||||
|
||||
/* --- Preferred aliases --- */
|
||||
--ccl-grey: var(--ccl-charcoal);
|
||||
--ccl-grey-2: var(--ccl-charcoal-2);
|
||||
--ccl-grey-3: var(--ccl-charcoal-3);
|
||||
--ccl-purple: var(--ccl-gold);
|
||||
--ccl-purple-dim: var(--ccl-gold-dim);
|
||||
--ccl-purple-wash: rgba(143,122,224,0.12);
|
||||
|
||||
/* --- Semantic aliases --- */
|
||||
--surface-page: var(--ccl-charcoal);
|
||||
--surface-raised: var(--ccl-charcoal-2);
|
||||
--surface-code: var(--ccl-charcoal-3);
|
||||
--text-primary: var(--ccl-text);
|
||||
--text-secondary: var(--ccl-text-muted);
|
||||
--text-on-gold: var(--ccl-ink);
|
||||
--text-on-accent: var(--ccl-ink);
|
||||
--accent: var(--ccl-purple);
|
||||
--accent-hover: var(--ccl-purple-dim);
|
||||
--border-hairline: var(--ccl-border);
|
||||
--border-strong: var(--ccl-border-2);
|
||||
--status-success: var(--ccl-green);
|
||||
--status-error: var(--ccl-red);
|
||||
--focus-ring: var(--ccl-purple);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* CubeCraftLabs — Webfonts
|
||||
JetBrains Mono is the sole typeface, loaded from Google Fonts.
|
||||
The @import below pulls in the @font-face declarations (weights 400/500/700/800). */
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;0,700;0,800;1,400&display=swap');
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/* CubeCraftLabs — Spacing, radius, border, shadow, motion tokens
|
||||
4px base unit. Square corners everywhere. Borders do the work shadows would. */
|
||||
:root {
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-10: 40px;
|
||||
--space-14: 56px;
|
||||
--space-16: 64px;
|
||||
|
||||
/* Radius — the brand is square. 0 is the rule. */
|
||||
--radius-none: 0px;
|
||||
--radius-sm: 0px;
|
||||
--radius-md: 0px;
|
||||
|
||||
/* Borders */
|
||||
--border-width: 1px;
|
||||
--border: var(--border-width) solid var(--ccl-border);
|
||||
--border-strong-rule: var(--border-width) solid var(--ccl-border-2);
|
||||
--border-accent: 1.5px solid var(--ccl-gold);
|
||||
|
||||
/* Shadows — flat brand. Only a faint lift where truly needed. */
|
||||
--shadow-none: none;
|
||||
--shadow-raised: 0 1px 0 0 var(--ccl-border);
|
||||
|
||||
/* Motion */
|
||||
--ease-out: cubic-bezier(0.2, 0, 0, 1); /* @kind other */
|
||||
--dur-fast: 100ms; /* @kind other */
|
||||
--dur-base: 160ms; /* @kind other */
|
||||
|
||||
/* Scrollbar */
|
||||
--scrollbar-width: 6px;
|
||||
--scrollbar-thumb: var(--ccl-border-2);
|
||||
--scrollbar-thumb-hover: var(--ccl-gold);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/* CubeCraftLabs — Typography tokens
|
||||
One family: JetBrains Mono. Mixed-case wordmark, uppercase tracked labels. */
|
||||
:root {
|
||||
--font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
--font-body: var(--font-mono);
|
||||
--font-display: var(--font-mono);
|
||||
|
||||
/* Weights */
|
||||
--fw-regular: 400; /* @kind font */
|
||||
--fw-medium: 500; /* @kind font */
|
||||
--fw-bold: 700; /* @kind font */
|
||||
--fw-display: 800; /* @kind font */
|
||||
|
||||
/* Type scale (px) */
|
||||
--fs-caption: 11px;
|
||||
--fs-label: 12px;
|
||||
--fs-body: 14px;
|
||||
--fs-body-lg: 15px;
|
||||
--fs-h3: 18px;
|
||||
--fs-h2: 22px;
|
||||
--fs-h1: 28px;
|
||||
--fs-display: 40px;
|
||||
|
||||
/* Line heights */
|
||||
--lh-tight: 1.15; /* @kind font */
|
||||
--lh-snug: 1.35; /* @kind font */
|
||||
--lh-body: 1.7; /* @kind font */
|
||||
|
||||
/* Tracking */
|
||||
--tracking-wordmark: 0.02em; /* CubeCraftLabs wordmark */
|
||||
--tracking-caps: 0.08em; /* uppercase labels / buttons */
|
||||
--tracking-caps-wide:0.14em; /* section eyebrows */
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+395
File diff suppressed because one or more lines are too long
+1911
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Reference in New Issue
Block a user