🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@kooshapari/design

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kooshapari/design - npm Package Compare versions

Comparing version
1.0.1
to
2.0.0
+1
dist/application/__init__.d.ts
//# sourceMappingURL=__init__.d.ts.map
{"version":3,"file":"__init__.d.ts","sourceRoot":"","sources":["../../src/application/__init__.ts"],"names":[],"mappings":""}
import type { Composer, DesignError, DesignSpec, GeneratedDesign, Renderer, Result, Validator } from '../domain/types';
export interface GeneratorDeps {
renderer: Renderer;
composer: Composer;
validator: Validator;
}
export interface GeneratorOptions {
/** Per-step timeout in milliseconds. Default: 30_000. */
stepTimeout?: number;
/** Optional AbortSignal for cancellation. */
signal?: AbortSignal;
}
export declare class DesignGenerator {
private readonly spec;
private readonly deps;
private readonly options;
private readonly logPrefix;
constructor(spec: DesignSpec, deps: GeneratorDeps, options?: GeneratorOptions);
generate(): Promise<Result<GeneratedDesign, DesignError>>;
/**
* Wraps a promise with a configurable timeout and optional external
* AbortSignal. Throws on timeout (TimeoutError) or cancellation
* (AbortError) so the caller handles a single error channel.
*/
private withTimeout;
private toDesignError;
private wrapError;
private logStep;
}
//# sourceMappingURL=generator.d.ts.map
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/application/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,QAAQ,EACR,MAAM,EACN,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,qBAAa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;gBAG7B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,gBAAqB;IAGpC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IA4EtE;;;;OAIG;YACW,WAAW;IA4DzB,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,OAAO;CAGhB"}
export class DesignGenerator {
spec;
deps;
options;
logPrefix = '[DesignGenerator]';
constructor(spec, deps, options = {}) {
this.spec = spec;
this.deps = deps;
this.options = options;
}
async generate() {
const timeout = this.options.stepTimeout ?? 30_000;
const signal = this.options.signal;
try {
// ── validate ──────────────────────────────────────────────────
this.logStep('validate:start', { specId: this.spec.id });
const validationResult = await this.withTimeout(this.deps.validator.validate(this.spec), timeout, signal, 'validate');
if (!validationResult.ok) {
this.logStep('validate:failed', validationResult.error);
return {
ok: false,
error: this.wrapError(validationResult.error, 'validate'),
};
}
this.logStep('validate:complete', {
warnings: validationResult.value.warnings.length,
});
// ── compose ───────────────────────────────────────────────────
this.logStep('compose:start', { specId: this.spec.id });
const composeResult = await this.withTimeout(this.deps.composer.compose(this.spec), timeout, signal, 'compose');
if (!composeResult.ok) {
return { ok: false, error: this.wrapError(composeResult.error, 'compose') };
}
this.logStep('compose:complete', {
sectionCount: composeResult.value.sections.length,
});
// ── render ────────────────────────────────────────────────────
this.logStep('render:start', { specId: this.spec.id });
const renderResult = await this.withTimeout(this.deps.renderer.render({
spec: this.spec,
layout: composeResult.value,
warnings: validationResult.value.warnings,
}), timeout, signal, 'render');
if (!renderResult.ok) {
return { ok: false, error: this.wrapError(renderResult.error, 'render') };
}
this.logStep('render:complete', {
format: renderResult.value.format,
outputId: renderResult.value.id,
});
return { ok: true, value: renderResult.value };
}
catch (err) {
return {
ok: false,
error: this.toDesignError(err, 'unknown'),
};
}
}
// ── helpers ─────────────────────────────────────────────────────
/**
* Wraps a promise with a configurable timeout and optional external
* AbortSignal. Throws on timeout (TimeoutError) or cancellation
* (AbortError) so the caller handles a single error channel.
*/
async withTimeout(promise, ms, signal, step) {
// Fast-path: already aborted
if (signal?.aborted) {
throw Object.assign(new DOMException(`Step "${step}" cancelled before start`, 'AbortError'), { step });
}
const controller = new AbortController();
const onParentAbort = () => {
controller.abort(signal?.reason);
};
if (signal) {
signal.addEventListener('abort', onParentAbort, { once: true });
}
const timer = setTimeout(() => {
controller.abort(Object.assign(new DOMException(`Step "${step}" timed out after ${ms}ms`, 'TimeoutError'), { step }));
}, ms);
// Enrich rejections from the original promise with step context
const enriched = promise.catch((err) => {
const enriched = err instanceof Error ? err : new Error(String(err));
enriched.step = step;
throw enriched;
});
try {
return await Promise.race([
enriched,
new Promise((_, reject) => {
controller.signal.addEventListener('abort', () => {
reject(controller.signal.reason);
}, { once: true });
}),
]);
}
finally {
clearTimeout(timer);
if (signal) {
signal.removeEventListener('abort', onParentAbort);
}
}
}
toDesignError(err, step) {
if (err instanceof DOMException) {
const typed = err;
if (err.name === 'TimeoutError') {
return {
code: 'TIMEOUT',
message: err.message,
step: typed.step ?? step,
hint: 'The generation step took too long. Try a simpler design spec or increase the stepTimeout option.',
};
}
if (err.name === 'AbortError') {
return {
code: 'CANCELLED',
message: err.message,
step: typed.step ?? step,
hint: 'The operation was cancelled by the caller.',
};
}
}
// Generic / unexpected error — try to extract step from enriched error
const enriched = err;
const actualStep = enriched.step ?? step;
return {
code: 'INTERNAL_ERROR',
message: `Step "${actualStep}" failed: ${err instanceof Error ? err.message : String(err)}`,
cause: err instanceof Error ? err.message : String(err),
step: actualStep,
};
}
wrapError(err, step) {
return {
...err,
step: err.step ?? step,
hint: err.hint ?? `The "${step}" step failed. Check the error details above.`,
};
}
logStep(step, payload) {
console.info(this.logPrefix, step, payload);
}
}
export interface DesignSpec {
id: string;
prompt: string;
constraints: string[];
metadata: Record<string, string>;
}
export interface LayoutSection {
id: string;
kind: string;
content: string;
}
export interface LayoutPlan {
sections: LayoutSection[];
}
export interface ValidationSummary {
warnings: string[];
}
export interface DesignError {
code: string;
message: string;
cause?: string;
/** Human-readable hint for recovery */
hint?: string;
/** The step name where the error originated */
step?: string;
}
export type Result<TValue, TError> = {
ok: true;
value: TValue;
} | {
ok: false;
error: TError;
};
export interface GeneratedDesign {
id: string;
format: 'json' | 'svg' | 'html';
output: string;
warnings: string[];
}
export interface Validator {
validate(spec: DesignSpec): Promise<Result<ValidationSummary, DesignError>>;
}
export interface Composer {
compose(spec: DesignSpec): Promise<Result<LayoutPlan, DesignError>>;
}
export interface RenderInput {
spec: DesignSpec;
layout: LayoutPlan;
warnings: string[];
}
export interface Renderer {
render(input: RenderInput): Promise<Result<GeneratedDesign, DesignError>>;
}
//# sourceMappingURL=types.d.ts.map
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/domain/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,IAC7B;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,MAAM,CAAA;CACd,GACD;IACE,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAEL,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC,CAAA;CAC5E;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;CACpE;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,UAAU,CAAA;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAAA;CAC1E"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA"}
export { keycap, type KeycapTokens } from './keycap';
export { MATERIALS, type Materials } from './materials';
export { POLYGONS, type PolygonLayer, type PolygonPreset, type Polygons } from './polygons';
export { NEUMORPHISM, type Neumorphism } from './neumorphism';
export declare const designTokens: {
readonly keycap: {
readonly accent: "#7ebab5";
readonly accentHover: "#95ccc8";
readonly accentActive: "#6aa8a3";
readonly accentDim: "#569691";
readonly accentContrast: "#4a9c97";
readonly slate: "#353a40";
readonly dark: {
readonly bg: "#090a0c";
readonly bgAlt: "#0e1014";
readonly bgSoft: "#14171b";
readonly bgElv: "#1a1e24";
readonly text1: "#f6f5f5";
readonly text2: "#a8adb5";
readonly text3: "#6b7280";
readonly divider: "#1f2329";
readonly gutter: "#0c0d0f";
readonly codeBlockBg: "#060708";
};
readonly light: {
readonly bg: "#f8f9fa";
readonly bgAlt: "#f0f1f3";
readonly bgSoft: "#e8eaed";
readonly bgElv: "#ffffff";
readonly text1: "#1a1c1e";
readonly text2: "#4a4f57";
readonly text3: "#6b7280";
readonly divider: "#d4d7dc";
readonly gutter: "#e8eaed";
readonly codeBlockBg: "#f0f1f3";
};
readonly font: {
readonly base: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
readonly mono: "'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace";
};
};
readonly materials: {
readonly windows: {
readonly base: "mica";
readonly acrylic: "rgba(9,10,12,0.7) + backdrop-blur(20px) + saturate(180%)";
readonly card: "rgba(126,186,181,0.08) + border: 1px solid rgba(126,186,181,0.15)";
};
readonly macos: {
readonly base: "liquid-glass";
readonly vibrancy: "rgba(126,186,181,0.12) + backdrop-filter: blur(40px) saturate(200%) brightness(1.1)";
readonly chromaShift: "1px rgba(126,186,181,0.3)";
};
readonly android: {
readonly base: "material-you";
readonly surface: "linear-gradient(135deg, #0d1117 0%, #161b22 100%)";
readonly card: "rgba(126,186,181,0.06) + border: 1px solid rgba(126,186,181,0.1)";
};
readonly web: {
readonly base: "glassmorphism";
readonly panel: "rgba(9,10,12,0.6) + backdrop-filter: blur(16px) saturate(150%)";
readonly border: "1px solid rgba(126,186,181,0.2)";
};
};
readonly polygons: {
readonly hexagon: {
readonly baseShape: "hexagon";
readonly clipPath: "polygon(25% 6%, 75% 6%, 100% 50%, 75% 94%, 25% 94%, 0 50%)";
readonly layers: readonly [{
readonly rotation: 0;
readonly scale: 1;
readonly opacity: 0.34;
}, {
readonly rotation: 4;
readonly scale: 0.94;
readonly opacity: 0.24;
}, {
readonly rotation: -3;
readonly scale: 0.88;
readonly opacity: 0.16;
}];
};
readonly diamond: {
readonly baseShape: "diamond";
readonly clipPath: "polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)";
readonly layers: readonly [{
readonly rotation: 45;
readonly scale: 1;
readonly opacity: 0.3;
}, {
readonly rotation: 45;
readonly scale: 0.92;
readonly opacity: 0.2;
}, {
readonly rotation: 45;
readonly scale: 0.84;
readonly opacity: 0.12;
}];
};
readonly pentagon: {
readonly baseShape: "pentagon";
readonly clipPath: "polygon(50% 0%, 95% 35%, 78% 100%, 22% 100%, 5% 35%)";
readonly layers: readonly [{
readonly rotation: 0;
readonly scale: 1;
readonly opacity: 0.3;
}, {
readonly rotation: 8;
readonly scale: 0.92;
readonly opacity: 0.2;
}, {
readonly rotation: -6;
readonly scale: 0.84;
readonly opacity: 0.14;
}, {
readonly rotation: 0;
readonly scale: 0.76;
readonly opacity: 0.08;
}];
};
readonly triangle: {
readonly baseShape: "triangle";
readonly clipPath: "polygon(50% 0%, 100% 100%, 0% 100%)";
readonly layers: readonly [{
readonly rotation: 0;
readonly scale: 1;
readonly opacity: 0.32;
}, {
readonly rotation: 180;
readonly scale: 0.9;
readonly opacity: 0.18;
}, {
readonly rotation: 0;
readonly scale: 0.8;
readonly opacity: 0.12;
}, {
readonly rotation: 0;
readonly scale: 0.7;
readonly opacity: 0.06;
}];
};
};
readonly neumorphism: {
readonly lightSource: "315deg";
readonly extrudeDepth: "4px";
readonly shadow: "4px 4px 8px rgba(0,0,0,0.5), -4px -4px 8px rgba(126,186,181,0.1)";
readonly shadowOffset: "4px";
readonly highlightOffset: "-4px";
};
};
export type DesignTokens = typeof designTokens;
//# sourceMappingURL=index.d.ts.map
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC3F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AAE7D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKf,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAA"}
import { keycap } from './keycap';
import { MATERIALS } from './materials';
import { POLYGONS } from './polygons';
import { NEUMORPHISM } from './neumorphism';
export { keycap } from './keycap';
export { MATERIALS } from './materials';
export { POLYGONS } from './polygons';
export { NEUMORPHISM } from './neumorphism';
export const designTokens = {
keycap,
materials: MATERIALS,
polygons: POLYGONS,
neumorphism: NEUMORPHISM,
};
/**
* Keycap Palette — Design Tokens
*
* Programmatic access to the Phenotype design system colors.
* For CSS usage, import the CSS files directly.
*/
export declare const keycap: {
readonly accent: "#7ebab5";
readonly accentHover: "#95ccc8";
readonly accentActive: "#6aa8a3";
readonly accentDim: "#569691";
readonly accentContrast: "#4a9c97";
readonly slate: "#353a40";
readonly dark: {
readonly bg: "#090a0c";
readonly bgAlt: "#0e1014";
readonly bgSoft: "#14171b";
readonly bgElv: "#1a1e24";
readonly text1: "#f6f5f5";
readonly text2: "#a8adb5";
readonly text3: "#6b7280";
readonly divider: "#1f2329";
readonly gutter: "#0c0d0f";
readonly codeBlockBg: "#060708";
};
readonly light: {
readonly bg: "#f8f9fa";
readonly bgAlt: "#f0f1f3";
readonly bgSoft: "#e8eaed";
readonly bgElv: "#ffffff";
readonly text1: "#1a1c1e";
readonly text2: "#4a4f57";
readonly text3: "#6b7280";
readonly divider: "#d4d7dc";
readonly gutter: "#e8eaed";
readonly codeBlockBg: "#f0f1f3";
};
readonly font: {
readonly base: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
readonly mono: "'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace";
};
};
export type KeycapTokens = typeof keycap;
//# sourceMappingURL=keycap.d.ts.map
{"version":3,"file":"keycap.d.ts","sourceRoot":"","sources":["../../src/tokens/keycap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCT,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,OAAO,MAAM,CAAA"}
/**
* Keycap Palette — Design Tokens
*
* Programmatic access to the Phenotype design system colors.
* For CSS usage, import the CSS files directly.
*/
export const keycap = {
accent: '#7ebab5',
accentHover: '#95ccc8',
accentActive: '#6aa8a3',
accentDim: '#569691',
accentContrast: '#4a9c97',
slate: '#353a40',
dark: {
bg: '#090a0c',
bgAlt: '#0e1014',
bgSoft: '#14171b',
bgElv: '#1a1e24',
text1: '#f6f5f5',
text2: '#a8adb5',
text3: '#6b7280',
divider: '#1f2329',
gutter: '#0c0d0f',
codeBlockBg: '#060708',
},
light: {
bg: '#f8f9fa',
bgAlt: '#f0f1f3',
bgSoft: '#e8eaed',
bgElv: '#ffffff',
text1: '#1a1c1e',
text2: '#4a4f57',
text3: '#6b7280',
divider: '#d4d7dc',
gutter: '#e8eaed',
codeBlockBg: '#f0f1f3',
},
font: {
base: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
mono: "'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace",
},
};
export declare const MATERIALS: {
readonly windows: {
readonly base: "mica";
readonly acrylic: "rgba(9,10,12,0.7) + backdrop-blur(20px) + saturate(180%)";
readonly card: "rgba(126,186,181,0.08) + border: 1px solid rgba(126,186,181,0.15)";
};
readonly macos: {
readonly base: "liquid-glass";
readonly vibrancy: "rgba(126,186,181,0.12) + backdrop-filter: blur(40px) saturate(200%) brightness(1.1)";
readonly chromaShift: "1px rgba(126,186,181,0.3)";
};
readonly android: {
readonly base: "material-you";
readonly surface: "linear-gradient(135deg, #0d1117 0%, #161b22 100%)";
readonly card: "rgba(126,186,181,0.06) + border: 1px solid rgba(126,186,181,0.1)";
};
readonly web: {
readonly base: "glassmorphism";
readonly panel: "rgba(9,10,12,0.6) + backdrop-filter: blur(16px) saturate(150%)";
readonly border: "1px solid rgba(126,186,181,0.2)";
};
};
export type Materials = typeof MATERIALS;
//# sourceMappingURL=materials.d.ts.map
{"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/tokens/materials.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;CAqBZ,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAA"}
export const MATERIALS = {
windows: {
base: 'mica',
acrylic: 'rgba(9,10,12,0.7) + backdrop-blur(20px) + saturate(180%)',
card: 'rgba(126,186,181,0.08) + border: 1px solid rgba(126,186,181,0.15)',
},
macos: {
base: 'liquid-glass',
vibrancy: 'rgba(126,186,181,0.12) + backdrop-filter: blur(40px) saturate(200%) brightness(1.1)',
chromaShift: '1px rgba(126,186,181,0.3)',
},
android: {
base: 'material-you',
surface: 'linear-gradient(135deg, #0d1117 0%, #161b22 100%)',
card: 'rgba(126,186,181,0.06) + border: 1px solid rgba(126,186,181,0.1)',
},
web: {
base: 'glassmorphism',
panel: 'rgba(9,10,12,0.6) + backdrop-filter: blur(16px) saturate(150%)',
border: '1px solid rgba(126,186,181,0.2)',
},
};
export declare const NEUMORPHISM: {
readonly lightSource: "315deg";
readonly extrudeDepth: "4px";
readonly shadow: "4px 4px 8px rgba(0,0,0,0.5), -4px -4px 8px rgba(126,186,181,0.1)";
readonly shadowOffset: "4px";
readonly highlightOffset: "-4px";
};
export type Neumorphism = typeof NEUMORPHISM;
//# sourceMappingURL=neumorphism.d.ts.map
{"version":3,"file":"neumorphism.d.ts","sourceRoot":"","sources":["../../src/tokens/neumorphism.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;;CAOd,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAA"}
export const NEUMORPHISM = {
lightSource: '315deg',
extrudeDepth: '4px',
shadow: '4px 4px 8px rgba(0,0,0,0.5), -4px -4px 8px rgba(126,186,181,0.1)',
shadowOffset: '4px',
highlightOffset: '-4px',
};
export type PolygonLayer = {
readonly rotation: number;
readonly scale: number;
readonly opacity: number;
};
export type PolygonPreset = {
readonly baseShape: 'hexagon' | 'diamond' | 'pentagon' | 'triangle';
readonly clipPath: string;
readonly layers: readonly PolygonLayer[];
};
export declare const POLYGONS: {
readonly hexagon: {
readonly baseShape: "hexagon";
readonly clipPath: "polygon(25% 6%, 75% 6%, 100% 50%, 75% 94%, 25% 94%, 0 50%)";
readonly layers: readonly [{
readonly rotation: 0;
readonly scale: 1;
readonly opacity: 0.34;
}, {
readonly rotation: 4;
readonly scale: 0.94;
readonly opacity: 0.24;
}, {
readonly rotation: -3;
readonly scale: 0.88;
readonly opacity: 0.16;
}];
};
readonly diamond: {
readonly baseShape: "diamond";
readonly clipPath: "polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)";
readonly layers: readonly [{
readonly rotation: 45;
readonly scale: 1;
readonly opacity: 0.3;
}, {
readonly rotation: 45;
readonly scale: 0.92;
readonly opacity: 0.2;
}, {
readonly rotation: 45;
readonly scale: 0.84;
readonly opacity: 0.12;
}];
};
readonly pentagon: {
readonly baseShape: "pentagon";
readonly clipPath: "polygon(50% 0%, 95% 35%, 78% 100%, 22% 100%, 5% 35%)";
readonly layers: readonly [{
readonly rotation: 0;
readonly scale: 1;
readonly opacity: 0.3;
}, {
readonly rotation: 8;
readonly scale: 0.92;
readonly opacity: 0.2;
}, {
readonly rotation: -6;
readonly scale: 0.84;
readonly opacity: 0.14;
}, {
readonly rotation: 0;
readonly scale: 0.76;
readonly opacity: 0.08;
}];
};
readonly triangle: {
readonly baseShape: "triangle";
readonly clipPath: "polygon(50% 0%, 100% 100%, 0% 100%)";
readonly layers: readonly [{
readonly rotation: 0;
readonly scale: 1;
readonly opacity: 0.32;
}, {
readonly rotation: 180;
readonly scale: 0.9;
readonly opacity: 0.18;
}, {
readonly rotation: 0;
readonly scale: 0.8;
readonly opacity: 0.12;
}, {
readonly rotation: 0;
readonly scale: 0.7;
readonly opacity: 0.06;
}];
};
};
export type Polygons = typeof POLYGONS;
//# sourceMappingURL=polygons.d.ts.map
{"version":3,"file":"polygons.d.ts","sourceRoot":"","sources":["../../src/tokens/polygons.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CACzC,CAAA;AAED,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuC6B,CAAA;AAElD,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAA"}
export const POLYGONS = {
hexagon: {
baseShape: 'hexagon',
clipPath: 'polygon(25% 6%, 75% 6%, 100% 50%, 75% 94%, 25% 94%, 0 50%)',
layers: [
{ rotation: 0, scale: 1, opacity: 0.34 },
{ rotation: 4, scale: 0.94, opacity: 0.24 },
{ rotation: -3, scale: 0.88, opacity: 0.16 },
],
},
diamond: {
baseShape: 'diamond',
clipPath: 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)',
layers: [
{ rotation: 45, scale: 1, opacity: 0.3 },
{ rotation: 45, scale: 0.92, opacity: 0.2 },
{ rotation: 45, scale: 0.84, opacity: 0.12 },
],
},
pentagon: {
baseShape: 'pentagon',
clipPath: 'polygon(50% 0%, 95% 35%, 78% 100%, 22% 100%, 5% 35%)',
layers: [
{ rotation: 0, scale: 1, opacity: 0.3 },
{ rotation: 8, scale: 0.92, opacity: 0.2 },
{ rotation: -6, scale: 0.84, opacity: 0.14 },
{ rotation: 0, scale: 0.76, opacity: 0.08 },
],
},
triangle: {
baseShape: 'triangle',
clipPath: 'polygon(50% 0%, 100% 100%, 0% 100%)',
layers: [
{ rotation: 0, scale: 1, opacity: 0.32 },
{ rotation: 180, scale: 0.9, opacity: 0.18 },
{ rotation: 0, scale: 0.8, opacity: 0.12 },
{ rotation: 0, scale: 0.7, opacity: 0.06 },
],
},
};
{"version":3,"file":"vitepress.d.ts","sourceRoot":"","sources":["../src/vitepress.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH,eAAO,MAAM,sBAAsB;;;CAGzB,CAAA;AAEV,eAAO,MAAM,eAAe;;;;;;;;;CAM3B,CAAA"}
+1
-1

@@ -87,3 +87,3 @@ /* ═══════════════════════════════════════════════════════════════

--vp-home-hero-name-background: linear-gradient(135deg, #f6f5f5 0%, #7ebab5 100%);
--vp-home-hero-name-background: linear-gradient(135deg, #95ccc8 0%, #569691 100%);

@@ -90,0 +90,0 @@ --vp-c-default-1: #353a40;

@@ -1,2 +0,2 @@

export { keycap } from './tokens';
export type { KeycapTokens } from './tokens';
export * from './tokens';
//# sourceMappingURL=index.d.ts.map

@@ -1,1 +0,1 @@

export { keycap } from './tokens';
export * from './tokens';

@@ -1,43 +0,2 @@

/**
* Keycap Palette — Design Tokens
*
* Programmatic access to the Phenotype design system colors.
* For CSS usage, import the CSS files directly.
*/
export declare const keycap: {
readonly accent: "#7ebab5";
readonly accentHover: "#95ccc8";
readonly accentActive: "#6aa8a3";
readonly accentDim: "#569691";
readonly accentContrast: "#4a9c97";
readonly slate: "#353a40";
readonly dark: {
readonly bg: "#090a0c";
readonly bgAlt: "#0e1014";
readonly bgSoft: "#14171b";
readonly bgElv: "#1a1e24";
readonly text1: "#f6f5f5";
readonly text2: "#a8adb5";
readonly text3: "#6b7280";
readonly divider: "#1f2329";
readonly gutter: "#0c0d0f";
readonly codeBlockBg: "#060708";
};
readonly light: {
readonly bg: "#f8f9fa";
readonly bgAlt: "#f0f1f3";
readonly bgSoft: "#e8eaed";
readonly bgElv: "#ffffff";
readonly text1: "#1a1c1e";
readonly text2: "#4a4f57";
readonly text3: "#6b7280";
readonly divider: "#d4d7dc";
readonly gutter: "#e8eaed";
readonly codeBlockBg: "#f0f1f3";
};
readonly font: {
readonly base: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
readonly mono: "'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace";
};
};
export type KeycapTokens = typeof keycap;
export * from './tokens/index';
//# sourceMappingURL=tokens.d.ts.map

@@ -1,42 +0,1 @@

/**
* Keycap Palette — Design Tokens
*
* Programmatic access to the Phenotype design system colors.
* For CSS usage, import the CSS files directly.
*/
export const keycap = {
accent: '#7ebab5',
accentHover: '#95ccc8',
accentActive: '#6aa8a3',
accentDim: '#569691',
accentContrast: '#4a9c97',
slate: '#353a40',
dark: {
bg: '#090a0c',
bgAlt: '#0e1014',
bgSoft: '#14171b',
bgElv: '#1a1e24',
text1: '#f6f5f5',
text2: '#a8adb5',
text3: '#6b7280',
divider: '#1f2329',
gutter: '#0c0d0f',
codeBlockBg: '#060708',
},
light: {
bg: '#f8f9fa',
bgAlt: '#f0f1f3',
bgSoft: '#e8eaed',
bgElv: '#ffffff',
text1: '#1a1c1e',
text2: '#4a4f57',
text3: '#6b7280',
divider: '#d4d7dc',
gutter: '#e8eaed',
codeBlockBg: '#f0f1f3',
},
font: {
base: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
mono: "'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace",
},
};
export * from './tokens/index';

@@ -25,1 +25,2 @@ /**

};
//# sourceMappingURL=vitepress.d.ts.map

@@ -0,1 +1,3 @@

// Copyright (c) 2026 Phenotype Enterprise. All rights reserved.
// Licensed under the Phenotype Standard License.
/**

@@ -2,0 +4,0 @@ * VitePress theme helper for Phenotype projects.

{
"name": "@kooshapari/design",
"version": "1.0.1",
"version": "2.0.0",
"description": "Keycap palette — shared design tokens, VitePress theme, and style guide for Phenotype projects",

@@ -22,16 +22,35 @@ "type": "module",

"scripts": {
"build": "tsc && cp -r css dist/css",
"build": "tsc && cp -R css dist/css",
"dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs",
"lint": "markdownlint docs/**/*.md"
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"lint": "oxlint",
"typecheck": "tsc --noEmit",
"format": "oxfmt --write ."
},
"dependencies": {},
"devDependencies": {
"markdownlint-cli": "^0.42.0",
"typescript": "^5.5.0",
"vitepress": "^1.5.0",
"vue": "^3.5.0"
"@vitest/coverage-v8": "^4.1.2",
"oxlint": "latest",
"typescript": "latest",
"vitepress": "latest",
"vitest": "^4.1.2",
"vue": "latest"
},
"keywords": ["phenotype", "design-system", "keycap", "vitepress-theme", "design-tokens"],
"overrides": {
"brace-expansion": "5.0.5",
"esbuild": "0.27.4",
"postcss": "^8.5.10",
"vite": "^6.4.2"
},
"keywords": [
"phenotype",
"design-system",
"keycap",
"vitepress-theme",
"design-tokens"
],
"license": "MIT",

@@ -41,3 +60,4 @@ "repository": {

"url": "https://github.com/KooshaPari/phenotype-design"
}
},
"packageManager": "bun"
}

@@ -1,9 +0,34 @@

# @phenotype/design
<!-- AI-DD-META:START -->
<!-- This repository is planned, maintained, and managed by AI Agents only. -->
<!-- Slop issues are expected and intentionally present as part of an HITL-less -->
<!-- /minimized AI-DD metaproject of learning, refining, and building brute-force -->
<!-- training for both agents and the human operator. -->
![Downloads](https://img.shields.io/github/downloads/KooshaPari/phenoDesign/total?style=flat-square&label=downloads&color=blue)
![GitHub release](https://img.shields.io/github/v/release/KooshaPari/phenoDesign?style=flat-square&label=release)
![License](https://img.shields.io/github/license/KooshaPari/phenoDesign?style=flat-square)
![AI-Slop](https://img.shields.io/badge/AI--DD-Slop%20Expected-orange?style=flat-square)
![AI-Only-Maintained](https://img.shields.io/badge/Planned%20%26%20Maintained%20by-AI%20Agents%20Only-red?style=flat-square)
![HITL-less](https://img.shields.io/badge/HITL--less%20AI--DD-metaproject-yellow?style=flat-square)
Keycap palette — shared design tokens, VitePress theme, and component styles for the Phenotype ecosystem.
> ⚠️ **AI-Agent-Only Repository**
>
> This repo is **planned, maintained, and managed exclusively by AI Agents**.
> Slop issues, rough edges, and AI artifacts are **expected and intentionally
> present** as part of an **HITL-less / minimized AI-DD** metaproject focused
> on learning, refining, and brute-force training both the agents and the
> human operator. Bug reports and contributions are still welcome, but please
> expect AI-generated code, comments, and documentation throughout.
<!-- AI-DD-META:END -->
# @kooshapari/design
> **Active.** Previously archived; un-archived 2026-06-08. See [ARCHIVED.md](ARCHIVED.md) for history.
## Status
- Archived on 2026-03-25
## Install
```bash
bun add @phenotype/design
bun add @kooshapari/design
```

@@ -16,3 +41,3 @@

import DefaultTheme from 'vitepress/theme'
import '@phenotype/design/css/vitepress-theme.css'
import '@kooshapari/design/css/vitepress-theme.css'

@@ -19,0 +44,0 @@ export default { extends: DefaultTheme }

/* ═══════════════════════════════════════════════════════════════
* Keycap Components — Badges, Cards, Pipeline
* @phenotype/design v1.0.0
*
* Requires keycap-palette.css for --kc-* tokens.
* Framework-agnostic — works with any HTML/CSS setup.
* ═══════════════════════════════════════════════════════════════ */
/* ── Layer Badges (PhenoDocs 5-layer taxonomy) ── */
.layer-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
}
/* Dark mode */
.dark .layer-0, [data-theme="dark"] .layer-0 { background: rgba(220, 38, 38, 0.15); color: #f87171; }
.dark .layer-1, [data-theme="dark"] .layer-1 { background: rgba(234, 88, 12, 0.15); color: #fb923c; }
.dark .layer-2, [data-theme="dark"] .layer-2 { background: rgba(202, 138, 4, 0.15); color: #fbbf24; }
.dark .layer-3, [data-theme="dark"] .layer-3 { background: rgba(22, 163, 74, 0.15); color: #4ade80; }
.dark .layer-4, [data-theme="dark"] .layer-4 { background: rgba(37, 99, 235, 0.15); color: #60a5fa; }
/* Light mode */
:root .layer-0 { background: #fde8e8; color: #991b1b; }
:root .layer-1 { background: #fff0e0; color: #9a3412; }
:root .layer-2 { background: #fef6d8; color: #854d0e; }
:root .layer-3 { background: #dcfce7; color: #166534; }
:root .layer-4 { background: #dbeafe; color: #1e40af; }
/* ── Status Badges ── */
.status-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.dark .status-draft, [data-theme="dark"] .status-draft { background: rgba(107, 114, 128, 0.15); color: #9ca3af; }
.dark .status-active, [data-theme="dark"] .status-active { background: rgba(126, 186, 181, 0.15); color: #7ebab5; }
.dark .status-published, [data-theme="dark"] .status-published { background: rgba(22, 163, 74, 0.15); color: #4ade80; }
.dark .status-archived, [data-theme="dark"] .status-archived { background: rgba(220, 38, 38, 0.15); color: #f87171; }
:root .status-draft { background: #f3f4f6; color: #4b5563; }
:root .status-active { background: #e8f5f3; color: #2d7a75; }
:root .status-published { background: #dcfce7; color: #166534; }
:root .status-archived { background: #fde8e8; color: #991b1b; }
/* ── Doc Type Grid ── */
.doc-type-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 12px;
margin: 24px 0;
}
.doc-type-card {
padding: 16px;
background: var(--kc-bg-soft);
border: 1px solid var(--kc-divider);
border-radius: 8px;
transition: border-color 0.2s, transform 0.2s;
}
.doc-type-card:hover {
border-color: var(--kc-accent);
transform: translateY(-1px);
}
.doc-type-card .card-title {
font-weight: 600;
font-size: 14px;
color: var(--kc-text-1);
margin-bottom: 4px;
}
.doc-type-card .card-desc {
font-size: 12px;
color: var(--kc-text-3);
line-height: 1.5;
}
/* ── Pipeline Visualization ── */
.pipeline {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin: 24px 0;
font-family: var(--kc-font-mono);
font-size: 13px;
}
.pipeline .stage {
padding: 6px 14px;
background: var(--kc-bg-soft);
border: 1px solid var(--kc-divider);
border-radius: 6px;
color: var(--kc-text-2);
transition: all 0.15s;
}
.pipeline .stage:hover {
border-color: var(--kc-accent);
color: var(--kc-accent);
}
.pipeline .arrow {
color: var(--kc-text-3);
font-size: 11px;
}
/* ═══════════════════════════════════════════════════════════════
* Keycap Palette — Design Tokens as CSS Custom Properties
* @phenotype/design v1.0.0
*
* This file contains ONLY color tokens and font declarations.
* For VitePress component styles, import vitepress-theme.css.
* For badge/card components, import components.css.
*
* Palette:
* Accent: #7ebab5 (teal) Light accent: #4a9c97
* Dark BG: #090a0c (midnight) Light BG: #f8f9fa (paper)
* Slate: #353a40 Text: #f6f5f5 / #1a1c1e
*
* All text/bg combos meet WCAG AA (4.5:1 minimum).
* ═══════════════════════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
:root {
/* ── Palette Tokens ── */
--kc-accent: #7ebab5;
--kc-accent-hover: #95ccc8;
--kc-accent-active: #6aa8a3;
--kc-accent-dim: #569691;
--kc-accent-contrast: #4a9c97;
--kc-slate: #353a40;
/* ── Fonts ── */
--kc-font-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--kc-font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace;
/* ── Light Mode (default) ── */
--kc-bg: #f8f9fa;
--kc-bg-alt: #f0f1f3;
--kc-bg-soft: #e8eaed;
--kc-bg-elv: #ffffff;
--kc-text-1: #1a1c1e;
--kc-text-2: #4a4f57;
--kc-text-3: #6b7280;
--kc-divider: #d4d7dc;
--kc-gutter: #e8eaed;
--kc-code-bg: #f0f1f3;
}
/* ── Dark Mode ── */
.dark, [data-theme="dark"] {
--kc-bg: #090a0c;
--kc-bg-alt: #0e1014;
--kc-bg-soft: #14171b;
--kc-bg-elv: #1a1e24;
--kc-text-1: #f6f5f5;
--kc-text-2: #a8adb5;
--kc-text-3: #6b7280;
--kc-divider: #1f2329;
--kc-gutter: #0c0d0f;
--kc-code-bg: #060708;
}
@media (prefers-color-scheme: dark) {
:root:not(.light):not([data-theme="light"]) {
--kc-bg: #090a0c;
--kc-bg-alt: #0e1014;
--kc-bg-soft: #14171b;
--kc-bg-elv: #1a1e24;
--kc-text-1: #f6f5f5;
--kc-text-2: #a8adb5;
--kc-text-3: #6b7280;
--kc-divider: #1f2329;
--kc-gutter: #0c0d0f;
--kc-code-bg: #060708;
}
}
/* ═══════════════════════════════════════════════════════════════
* Keycap VitePress Theme — Full theme override
* @phenotype/design v1.0.0
*
* Import this single file in your VitePress theme to get
* the complete Keycap palette + all component styles.
*
* Usage in .vitepress/theme/index.ts:
* import '@phenotype/design/css/vitepress-theme.css'
*
* Or if installed locally:
* import './keycap-palette.css' (copy from this package)
* ═══════════════════════════════════════════════════════════════ */
@import './keycap-palette.css';
@import './components.css';
/* ── VitePress Variable Mapping ── */
:root {
--vp-font-family-base: var(--kc-font-base);
--vp-font-family-mono: var(--kc-font-mono);
--vp-c-brand-1: #7ebab5;
--vp-c-brand-2: #6aa8a3;
--vp-c-brand-3: #569691;
--vp-c-bg: var(--kc-bg);
--vp-c-bg-alt: var(--kc-bg-alt);
--vp-c-bg-soft: var(--kc-bg-soft);
--vp-c-bg-elv: var(--kc-bg-elv);
--vp-c-text-1: var(--kc-text-1);
--vp-c-text-2: var(--kc-text-2);
--vp-c-text-3: var(--kc-text-3);
--vp-c-divider: var(--kc-divider);
--vp-c-gutter: var(--kc-gutter);
--vp-c-tip-1: var(--kc-accent-contrast);
--vp-c-tip-bg: var(--kc-bg-soft);
--vp-c-tip-soft: var(--kc-bg-alt);
--vp-code-block-bg: var(--kc-code-bg);
--vp-code-bg: var(--kc-bg-soft);
--vp-button-brand-bg: var(--kc-accent-dim);
--vp-button-brand-text: #ffffff;
--vp-button-brand-hover-bg: #4a8a85;
--vp-button-brand-hover-text: #ffffff;
--vp-button-brand-active-bg: #3e7e79;
--vp-button-brand-active-text: #ffffff;
--vp-button-alt-bg: var(--kc-bg-soft);
--vp-button-alt-text: var(--kc-text-2);
--vp-button-alt-hover-bg: var(--kc-divider);
--vp-button-alt-hover-text: var(--kc-text-1);
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(135deg, var(--kc-text-1) 0%, var(--kc-accent-contrast) 100%);
--vp-c-default-1: var(--kc-divider);
--vp-c-default-2: var(--kc-bg-soft);
--vp-c-default-3: var(--kc-bg-alt);
--vp-c-default-soft: var(--kc-bg-alt);
}
.dark {
--vp-c-brand-1: #7ebab5;
--vp-c-brand-2: #6aa8a3;
--vp-c-brand-3: #569691;
--vp-c-tip-1: #7ebab5;
--vp-button-brand-bg: #7ebab5;
--vp-button-brand-text: #090a0c;
--vp-button-brand-hover-bg: #95ccc8;
--vp-button-brand-hover-text: #060708;
--vp-button-brand-active-bg: #6aa8a3;
--vp-button-brand-active-text: #090a0c;
--vp-button-alt-bg: #353a40;
--vp-button-alt-text: #a8adb5;
--vp-button-alt-hover-bg: #3e444b;
--vp-button-alt-hover-text: #f6f5f5;
--vp-home-hero-name-background: linear-gradient(135deg, #95ccc8 0%, #569691 100%);
--vp-c-default-1: #353a40;
}
/* ── Typography ── */
.vp-doc { line-height: 1.75; }
.vp-doc h1 { font-weight: 700; letter-spacing: -0.03em; }
.vp-doc h2 { font-weight: 600; letter-spacing: -0.02em; border-top: none; padding-top: 32px; }
.vp-doc h3 { font-weight: 600; letter-spacing: -0.01em; }
.vp-doc a { text-decoration-color: rgba(126, 186, 181, 0.3); }
.vp-doc a:hover { text-decoration-color: var(--kc-accent); }
:root .vp-doc a { color: #4a9c97; }
:root .vp-doc a:hover { color: #3e8a85; }
.dark .vp-doc a { color: #7ebab5; }
.dark .vp-doc a:hover { color: #95ccc8; }
/* ── Nav ── */
.VPNav { border-bottom: 1px solid var(--vp-c-divider) !important; }
.dark .VPNav { background: rgba(9, 10, 12, 0.88) !important; backdrop-filter: blur(12px); }
:root .VPNav { background: rgba(248, 249, 250, 0.88) !important; backdrop-filter: blur(12px); }
/* ── Sidebar ── */
.VPSidebar { background: var(--vp-c-bg) !important; border-right: 1px solid var(--vp-c-divider); }
.VPSidebarItem .text { font-size: 13px; }
.dark .VPSidebarItem.is-active > .item > .link > .text { color: #7ebab5; font-weight: 600; }
:root .VPSidebarItem.is-active > .item > .link > .text { color: #4a9c97; font-weight: 600; }
/* ── Code blocks ── */
.vp-code-group .tabs label { background: transparent; border-bottom: 2px solid transparent; }
.vp-code-group .tabs label.active { border-bottom-color: var(--vp-c-brand-1); }
.dark .vp-code-group .tabs label.active { color: #f6f5f5; }
div[class*='language-'] { border: 1px solid var(--vp-c-divider); border-radius: 8px; }
div[class*='language-'] code { font-size: 13px; }
/* ── Hero ── */
.VPHero .name { font-size: 56px !important; font-weight: 800; letter-spacing: -0.04em; line-height: 1.1; }
.VPHero .text { font-size: 20px !important; color: var(--vp-c-text-2); font-weight: 400; letter-spacing: -0.01em; }
.VPHero .tagline { font-size: 16px !important; color: var(--vp-c-text-3); line-height: 1.6; }
.VPHero .actions .action { margin-right: 12px; }
/* ── Feature cards ── */
.VPFeature { background: var(--vp-c-bg-soft) !important; border: 1px solid var(--vp-c-divider) !important; border-radius: 12px; transition: border-color 0.2s, transform 0.2s; }
.dark .VPFeature:hover { border-color: #7ebab5 !important; transform: translateY(-2px); }
:root .VPFeature:hover { border-color: #4a9c97 !important; transform: translateY(-2px); }
.VPFeature .title { font-weight: 600; font-size: 15px; }
.VPFeature .details { font-size: 13px; color: var(--vp-c-text-3); line-height: 1.6; }
/* ── Tables ── */
.vp-doc table { border-collapse: collapse; }
.vp-doc tr { border-top: 1px solid var(--vp-c-divider); }
.vp-doc th { font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--vp-c-text-3); }
.vp-doc td { font-size: 14px; }
/* ── Quick start block ── */
.quick-start { margin: 32px 0; padding: 24px; background: var(--vp-c-bg-soft); border: 1px solid var(--vp-c-divider); border-radius: 12px; }
.quick-start h3 { margin-top: 0; font-size: 14px; text-transform: uppercase; letter-spacing: 0.05em; }
:root .quick-start h3 { color: #4a9c97; }
.dark .quick-start h3 { color: #7ebab5; }
/* ── Footer ── */
.VPFooter { border-top: 1px solid var(--vp-c-divider); }