myoperator-design
Generates production-ready React/Tailwind CSS code matching the myOperator design system. Code is standalone — does not require the myoperator-ui package but visually matches its components. Always include the full CSS variables block in output.
Design Philosophy
myOperator's design language is professional, clean, and purposeful:
- Blue-gray primary palette (#343E55) — sophisticated and business-appropriate
- Turquoise accent (#2BBCCA) — fresh, modern brand identity
- Clean typography with Source Sans Pro — readable and professional
- Subtle interactions — focus rings, hover states, smooth transitions
- Semantic color usage — success/error/warning states are clear and consistent
The aesthetic is enterprise SaaS — trustworthy, efficient, uncluttered. NOT flashy, NOT playful, NOT experimental.
Brand Color Usage
Turquoise (#2BBCCA) is ONLY for:
- Focus rings on inputs
- Active/selected states (toggle switches, nav items)
- Interactive badges (e.g., "Live" indicator)
- Links and clickable text
DO NOT use turquoise for: charts, graphs, decorative elements, large backgrounds, non-interactive content.
For charts/graphs: use --semantic-primary (#343E55) as default data color. Use semantic state colors for meaning (success green = positive, error red = negative).
Color System
Always include this :root block in generated output. For the full primitive color scale (50–950 steps), see references/design-tokens.md.
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap');
:root {
/* Primary UI */
--semantic-primary: #343E55;
--semantic-primary-hover: #2F384D;
--semantic-primary-selected: #777E8D;
--semantic-primary-highlighted: #252C3C;
--semantic-primary-surface: #EBECEE;
/* Brand Accent (Turquoise — interactive elements only) */
--semantic-brand: #2BBCCA;
--semantic-brand-hover: #1F858F;
--semantic-brand-selected: #71D2DB;
--semantic-brand-surface: #EAF8FA;
/* Backgrounds */
--semantic-bg-primary: #FFFFFF;
--semantic-bg-secondary: #0C0F12;
--semantic-bg-ui: #F5F5F5;
--semantic-bg-grey: #E9EAEB;
--semantic-bg-hover: #D5D7DA;
--semantic-bg-inverted: #000000;
/* Text */
--semantic-text-primary: #181D27;
--semantic-text-secondary: #343E55;
--semantic-text-muted: #717680;
--semantic-text-placeholder: #A2A6B1;
--semantic-text-link: #4275D6;
--semantic-text-inverted: #FFFFFF;
/* Borders */
--semantic-border-primary: #343E55;
--semantic-border-secondary: #777E8D;
--semantic-border-accent: #27ABB8;
--semantic-border-layout: #E9EAEB;
--semantic-border-input: #E9EAEB;
--semantic-border-input-focus: #2BBCCA;
/* Disabled */
--semantic-disabled-primary: #A2A6B1;
--semantic-disabled-secondary: #EBECEE;
--semantic-disabled-text: #717680;
--semantic-disabled-border: #D5D7DA;
/* Error */
--semantic-error-primary: #F04438;
--semantic-error-hover: #D92D20;
--semantic-error-surface: #FEF3F2;
--semantic-error-text: #B42318;
--semantic-error-border: #FDA29B;
/* Warning */
--semantic-warning-primary: #F79009;
--semantic-warning-surface: #FFFAEB;
--semantic-warning-text: #B54708;
--semantic-warning-border: #FEC84B;
/* Success */
--semantic-success-primary: #17B26A;
--semantic-success-surface: #ECFDF3;
--semantic-success-text: #067647;
--semantic-success-border: #75E0A7;
/* Info */
--semantic-info-primary: #4275D6;
--semantic-info-surface: #ECF1FB;
--semantic-info-text: #2F5398;
--semantic-info-border: #C4D4F2;
}
body {
font-family: 'Source Sans Pro', sans-serif;
background: var(--semantic-bg-primary);
color: var(--semantic-text-primary);
margin: 0;
padding: 0;
}
Typography
Font: 'Source Sans Pro', sans-serif — always import with weights 400;600;700.
Convention: Default body is 16px. Use 14px for secondary/helper text only. 12px for rare metadata.
| Kind | Size | Weight | Use Case |
|---|---|---|---|
| headline/large | 32px | 600 | Page titles |
| headline/medium | 28px | 600 | Section titles |
| headline/small | 24px | 600 | Card titles |
| title/large | 18px | 600 | Subsection headers |
| title/medium | 16px | 600 | Component titles |
| body/large | 16px | 400 | Default body text |
| body/small | 14px | 400 | Secondary/helper text |
| label/large | 14px | 600 | Form labels |
| label/medium | 12px | 600 | Small labels |
Component Patterns
Buttons
{/* Primary */}
<button className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium
min-w-20 py-2.5 px-4 bg-[var(--semantic-primary)] text-[var(--semantic-text-inverted)]
hover:bg-[var(--semantic-primary-hover)] transition-all duration-200
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--semantic-primary)] focus-visible:ring-offset-2
disabled:opacity-50 disabled:pointer-events-none">
Save Changes
</button>
{/* Outline */}
<button className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium
min-w-20 py-2.5 px-4 border border-[var(--semantic-border-primary)] bg-transparent text-[var(--semantic-text-secondary)]
hover:bg-[var(--semantic-primary-surface)] transition-all duration-200
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--semantic-primary)] focus-visible:ring-offset-2
disabled:opacity-50 disabled:pointer-events-none">
Cancel
</button>
{/* Destructive */}
<button className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium
min-w-20 py-2.5 px-4 bg-[var(--semantic-error-primary)] text-[var(--semantic-text-inverted)]
hover:bg-[var(--semantic-error-hover)] transition-all duration-200
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--semantic-error-primary)] focus-visible:ring-offset-2
disabled:opacity-50 disabled:pointer-events-none">
Delete
</button>
Input
{/* Default */}
<input className="h-10 w-full rounded px-4 py-2.5 text-sm
bg-[var(--semantic-bg-primary)] text-[var(--semantic-text-primary)]
border border-[var(--semantic-border-input)]
placeholder:text-[var(--semantic-text-placeholder)]
focus:outline-none focus:border-[var(--semantic-border-input-focus)]
focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]
disabled:cursor-not-allowed disabled:bg-[var(--semantic-disabled-secondary)] disabled:text-[var(--semantic-disabled-text)] disabled:border-[var(--semantic-disabled-border)]
transition-all" />
{/* Error state */}
<input className="h-10 w-full rounded px-4 py-2.5 text-sm
bg-[var(--semantic-bg-primary)] text-[var(--semantic-text-primary)]
border border-[var(--semantic-error-border)]
placeholder:text-[var(--semantic-text-placeholder)]
focus:outline-none focus:border-[var(--semantic-error-primary)]
focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]
transition-all" />
<p className="mt-1.5 text-sm text-[var(--semantic-error-primary)]">Error message</p>
Form Field with Label
<div className="space-y-1.5">
<label className="text-sm font-semibold leading-5 text-[var(--semantic-text-secondary)]">
Email Address <span className="text-[var(--semantic-error-primary)]">*</span>
</label>
<input type="email" placeholder="you@example.com" className="/* input classes */" />
<p className="text-xs text-[var(--semantic-text-muted)]">Helper text goes here.</p>
</div>
Card
<div className="rounded-lg border border-[var(--semantic-border-layout)] bg-[var(--semantic-bg-primary)] p-6 shadow-sm">
<h3 className="text-lg font-semibold text-[var(--semantic-text-primary)]">Card Title</h3>
<p className="mt-2 text-sm text-[var(--semantic-text-muted)]">Description</p>
</div>
Badge
{/* Active */}
<span className="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium
bg-[var(--semantic-success-surface)] text-[var(--semantic-success-primary)]">Active</span>
{/* Failed */}
<span className="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium
bg-[var(--semantic-error-surface)] text-[var(--semantic-error-primary)]">Failed</span>
{/* Outline/Pending */}
<span className="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium
border border-[var(--semantic-border-layout)] text-[var(--semantic-text-primary)]">Pending</span>
Modal/Dialog
Always use
z-[9999]— the host app's navbar sits atz-index: 1000+. Never usez-50.
{/* Backdrop */}
<div className="fixed inset-0 z-[9999] bg-black/50" />
{/* Dialog */}
<div className="fixed left-1/2 top-1/2 z-[9999] -translate-x-1/2 -translate-y-1/2
w-full max-w-lg rounded-lg border border-[var(--semantic-border-layout)]
bg-[var(--semantic-bg-primary)] p-6 shadow-lg">
<h2 className="text-lg font-semibold text-[var(--semantic-text-primary)]">Title</h2>
<p className="mt-1 text-sm text-[var(--semantic-text-muted)]">Description</p>
<div className="mt-6 flex justify-end gap-2">
{/* Outline cancel + Primary confirm */}
</div>
{/* Close button */}
<button className="absolute right-4 top-4 rounded-sm opacity-70 hover:opacity-100
focus:outline-none focus:ring-2 focus:ring-[var(--semantic-primary)] focus:ring-offset-2">
✕
</button>
</div>
Sizes: max-w-sm / max-w-lg / max-w-2xl / max-w-4xl
Table
<div className="rounded-lg border border-[var(--semantic-border-layout)] overflow-hidden">
<table className="w-full text-sm">
<thead className="bg-[var(--semantic-bg-ui)]">
<tr>
<th className="px-4 py-3 text-left font-semibold text-[var(--semantic-text-secondary)]">Name</th>
<th className="px-4 py-3 text-left font-semibold text-[var(--semantic-text-secondary)]">Status</th>
</tr>
</thead>
<tbody>
<tr className="border-t border-[var(--semantic-border-layout)] hover:bg-[var(--semantic-bg-ui)] transition-colors">
<td className="px-4 py-3 text-[var(--semantic-text-primary)]">Item Name</td>
<td className="px-4 py-3">
<span className="/* badge classes */">Active</span>
</td>
</tr>
</tbody>
</table>
</div>
Alert
{/* Error */}
<div className="rounded-lg border border-[var(--semantic-error-border)] bg-[var(--semantic-error-surface)] p-4">
<div className="flex items-start gap-3">
<div>
<h4 className="text-sm font-semibold text-[var(--semantic-error-text)]">Error</h4>
<p className="mt-1 text-sm text-[var(--semantic-error-text)]">Something went wrong.</p>
</div>
</div>
</div>
{/* Success */}
<div className="rounded-lg border border-[var(--semantic-success-border)] bg-[var(--semantic-success-surface)] p-4">
<div className="flex items-start gap-3">
<div>
<h4 className="text-sm font-semibold text-[var(--semantic-success-text)]">Success</h4>
<p className="mt-1 text-sm text-[var(--semantic-success-text)]">Changes saved.</p>
</div>
</div>
</div>
Sidebar Navigation
<aside className="w-64 h-screen bg-[var(--semantic-primary)] flex flex-col shrink-0">
{/* Logo */}
<div className="px-6 py-5 border-b border-white/10">
<span className="text-lg font-semibold text-[var(--semantic-text-inverted)]">myOperator</span>
</div>
{/* Nav items */}
<nav className="flex-1 px-3 py-4 space-y-1 overflow-y-auto">
{/* Active */}
<a href="#" className="flex items-center gap-3 px-3 py-2 rounded text-sm font-medium
bg-white/10 text-[var(--semantic-text-inverted)]">
Dashboard
</a>
{/* Inactive */}
<a href="#" className="flex items-center gap-3 px-3 py-2 rounded text-sm font-medium
text-white/70 hover:bg-white/10 hover:text-[var(--semantic-text-inverted)] transition-colors">
Reports
</a>
</nav>
</aside>
Page Layout (Sidebar + Content)
<div className="flex h-screen bg-[var(--semantic-bg-ui)]">
{/* Sidebar */}
<aside className="w-64 shrink-0">{/* sidebar */}</aside>
{/* Main area */}
<div className="flex-1 flex flex-col overflow-hidden">
{/* Top bar */}
<header className="h-16 bg-[var(--semantic-bg-primary)] border-b border-[var(--semantic-border-layout)]
px-6 flex items-center justify-between shrink-0">
<h1 className="text-lg font-semibold text-[var(--semantic-text-primary)]">Page Title</h1>
<div className="flex items-center gap-3">{/* actions */}</div>
</header>
{/* Scrollable content */}
<main className="flex-1 overflow-auto p-6 space-y-6">
{/* content */}
</main>
</div>
</div>
Output Format
Always output complete, runnable code:
- Single file preferred — inline
<style>tag with CSS variables + JSX component - Two files for larger components —
styles.css+Component.jsx - Include
useState/useEffectwhen the UI needs interactive state - Include SVG icons inline rather than importing packages
- Plain JSX by default — only TypeScript if the user asks
// Recommended single-file structure
const css = `
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap');
:root { /* all tokens */ }
body { font-family: 'Source Sans Pro', sans-serif; }
`;
export function MyComponent() {
return (
<>
<style>{css}</style>
{/* JSX */}
</>
);
}
Implementation Rules
- Always include CSS variables — full
:rootblock in every output - Never hardcode colors — always
var(--token-name)references - z-index for overlays: always
z-[9999], neverz-50 - Disabled states: use
--semantic-disabled-*tokens, not justopacity-50 - Focus states:
focus-visible:ring-2on all interactive elements - Transitions:
transition-all duration-200for hover/interactive states - Border radius:
rounded(4px) for buttons/inputs,rounded-lg(8px) for cards/modals - Spacing:
p-6cards,py-2.5 px-4buttons,px-4 py-2.5inputs
What NOT to Do
- No hardcoded hex colors — always use CSS variable tokens
- No generic fonts — always Source Sans Pro
- No
z-50for modals — must usez-[9999] - No turquoise in charts/data viz — use primary blue-gray
- No
rounded-fullon containers — only on badges and avatars - No flashy animations — subtle
transition-all duration-200only - No heavy shadows —
shadow-smfor cards,shadow-lgfor modals only
References
- Full primitive color scale (50–950 steps for all palettes):
references/design-tokens.md - Component catalog (44 components, props, install commands):
references/component-catalog.md
More from ankish8/storybook-npm
storybook generator
Generates comprehensive Storybook stories following the Button/AlertConfiguration pattern with installation instructions, design tokens table, typography table, and usage examples. Activate when creating component documentation.
26component analysis
Analyzes codebase to check if component exists, suggests creating variants vs new components, and identifies reusable subcomponents. Activate when creating new components to avoid duplication and ensure proper architecture.
21design system validator
Ensures CSS variables are used instead of hardcoded colors, validates semantic tokens, checks responsive design patterns, and enforces design system consistency. Activate when creating or validating components.
20