# Silo Style Guide > Living reference for the Silo web UI. All modules must follow these conventions to maintain visual consistency across the platform. --- ## Color System Silo uses the [Catppuccin Mocha](https://github.com/catppuccin/catppuccin) palette exclusively. All colors are referenced via CSS custom properties defined at `:root`. ### Palette ``` --ctp-rosewater: #f5e0dc --ctp-flamingo: #f2cdcd --ctp-pink: #f5c2e7 --ctp-mauve: #cba6f7 --ctp-red: #f38ba8 --ctp-maroon: #eba0ac --ctp-peach: #fab387 --ctp-yellow: #f9e2af --ctp-green: #a6e3a1 --ctp-teal: #94e2d5 --ctp-sky: #89dceb --ctp-sapphire: #74c7ec --ctp-blue: #89b4fa --ctp-lavender: #b4befe --ctp-text: #cdd6f4 --ctp-subtext1: #bac2de --ctp-subtext0: #a6adc8 --ctp-overlay2: #9399b2 --ctp-overlay1: #7f849c --ctp-overlay0: #6c7086 --ctp-surface2: #585b70 --ctp-surface1: #45475a --ctp-surface0: #313244 --ctp-base: #1e1e2e --ctp-mantle: #181825 --ctp-crust: #11111b ``` ### Semantic Roles | Role | Token | Usage | |------|-------|-------| | Page background | `--ctp-base` | Main content area | | Panel background | `--ctp-mantle` | Sidebars, detail panes, headers | | Inset/input background | `--ctp-crust` | Form inputs, code blocks, drop zones | | Primary accent | `--ctp-mauve` | Primary buttons, active states, links, selection highlights | | Secondary accent | `--ctp-blue` | Informational highlights, secondary actions | | Success | `--ctp-green` | Confirmations, positive status | | Warning | `--ctp-yellow` | Caution states, pending actions | | Danger | `--ctp-red` | Destructive actions, errors, required indicators | | Informational | `--ctp-teal` | Auto-generated metadata, system-assigned values | | Body text | `--ctp-text` | Primary content | | Secondary text | `--ctp-subtext1` | Descriptions, timestamps | | Muted text | `--ctp-overlay1` | Placeholders, disabled states | | Borders | `--ctp-surface0` | Dividers, panel edges | | Hover borders | `--ctp-surface1` | Interactive element borders, row separators | | Focus ring | `rgba(203, 166, 247, 0.25)` | `box-shadow` on focused inputs (mauve at 25%) | ### Accent Usage for Data Types | Data type | Color | Token | |-----------|-------|-------| | Assembly | `--ctp-mauve` | Badge, icon tint | | Part | `--ctp-green` | Badge, icon tint | | Document | `--ctp-blue` | Badge, icon tint | | Purchased | `--ctp-peach` | Badge, icon tint | | Phantom | `--ctp-overlay1` | Badge, icon tint | These mappings are used anywhere item types appear: list badges, detail pane headers, BOM entries, tree views. --- ## Typography ### Scale | Role | Size | Weight | Token/Color | Transform | |------|------|--------|-------------|-----------| | Page title | 1.1rem | 600 | `--ctp-text` | None | | Section header | 11px | 600 | `--ctp-overlay0` | Uppercase, `letter-spacing: 0.06em` | | Form label | 11px | 600 | `--ctp-overlay1` | Uppercase, `letter-spacing: 0.05em` | | Body text | 13px | 400 | `--ctp-text` | None | | Table cell | 12px | 400 | `--ctp-text` | None | | Caption / metadata | 11px | 400 | `--ctp-subtext0` | None | | Badge text | 10px | 600 | Varies | Uppercase | | Breadcrumb segment | 13px | 500 | `--ctp-subtext1` | None | | Breadcrumb active | 13px | 600 | `--ctp-text` | None | ### Font Stack ```css font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; ``` No external font dependencies. System fonts ensure fast rendering and native feel across platforms. ### Rules - Never use font sizes below 10px. - Use `font-weight: 600` for emphasis instead of bold (700). Reserve 700 for page titles only when extra weight is needed. - `text-transform: uppercase` is reserved for section headers, form labels, and badges. Never uppercase body text or descriptions. --- ## Spacing Base unit: **4px**. All spacing values are multiples of 4. | Token | Value | Usage | |-------|-------|-------| | `xs` | 4px (0.25rem) | Tight gaps: icon-to-label, tag internal padding | | `sm` | 8px (0.5rem) | Compact spacing: between related fields, badge padding | | `md` | 12px (0.75rem) | Standard: form group gaps, sidebar section padding | | `lg` | 16px (1rem) | Section separation, card padding | | `xl` | 24px (1.5rem) | Page-level padding, major section breaks | | `2xl` | 32px (2rem) | Page horizontal padding | ### Application - **Page padding:** `1.5rem 2rem` (24px vertical, 32px horizontal) - **Sidebar section padding:** `1rem 1.25rem` - **Form grid gap:** `1.25rem 1.5rem` (row gap × column gap) - **Table row height:** 36px minimum (padding included) - **Table cell padding:** `0.4rem 0.75rem` --- ## Layout ### Page Structure Every module page follows the same shell: ``` ┌─────────────────────────────────────────────────┐ │ Top Nav (52px) │ ├──────────┬──────────────────────────────────────┤ │ App Menu │ Page Header (58px) │ │ (icons) ├──────────────────────┬───────────────┤ │ │ Content Area │ Detail Pane │ │ │ │ (360px) │ │ │ │ │ │ │ │ │ └──────────┴──────────────────────┴───────────────┘ ``` - **Top nav:** `52px` height, `--ctp-mantle` background, `1px solid --ctp-surface0` bottom border. - **App menu sidebar:** Icon strip on the left. Module icons, tooltips on hover. Active module highlighted with `--ctp-mauve` indicator. - **Page header:** `58px` height, `--ctp-mantle` background. Contains page title (with module icon), action buttons right-aligned. - **Content area:** `--ctp-base` background. Scrollable. Contains list views, kanban boards, or other primary content. - **Detail pane:** `360px` fixed width, `--ctp-mantle` background, `1px solid --ctp-surface0` left border. Appears on record selection. ### Grid Patterns **Two-column form:** ```css display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem 1.5rem; max-width: 800px; ``` **List + detail:** ```css display: grid; grid-template-columns: 1fr 360px; min-height: calc(100vh - 52px - 58px); ``` ### Breakpoints Not currently required. Silo targets desktop browsers on engineering workstations. If mobile support is added later, breakpoints will be defined at `768px` and `1024px`. --- ## Components ### Buttons Four tiers. All buttons share a base style: ```css display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.4rem 0.85rem; border-radius: 6px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.15s; ``` | Tier | Name | Background | Border | Text | Hover | |------|------|-----------|--------|------|-------| | Primary | `.btn-primary` | `--ctp-mauve` | `--ctp-mauve` | `--ctp-crust` | `--ctp-lavender` bg + border | | Secondary | `.btn` (default) | `--ctp-surface0` | `--ctp-surface1` | `--ctp-text` | `--ctp-surface1` bg, `--ctp-overlay0` border | | Ghost | `.btn-ghost` | transparent | transparent | `--ctp-subtext0` | `--ctp-surface0` bg, `--ctp-text` text | | Danger | `.btn-danger` | transparent | `--ctp-surface1` | `--ctp-red` | `rgba(243, 139, 168, 0.1)` bg, `--ctp-red` border | Primary is used once per visible context (the main action). All other actions use secondary or ghost. Danger is only for destructive actions and always requires confirmation. ### Badges Used for type indicators, status labels, and tags. ```css display: inline-flex; align-items: center; padding: 0.15rem 0.5rem; border-radius: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; ``` Badges use a translucent background derived from their accent color: ```css /* Example: assembly badge */ background: rgba(203, 166, 247, 0.15); /* --ctp-mauve at 15% */ color: var(--ctp-mauve); ``` Standard badge colors follow the [accent usage table](#accent-usage-for-data-types). Status badges: | Status | Color | |--------|-------| | Active / Released | `--ctp-green` | | Draft / In Progress | `--ctp-blue` | | Review / Pending | `--ctp-yellow` | | Obsolete / Rejected | `--ctp-red` | | Locked | `--ctp-overlay1` | ### Form Inputs All inputs share a base style: ```css background: var(--ctp-crust); border: 1px solid var(--ctp-surface1); border-radius: 6px; padding: 0.45rem 0.65rem; font-size: 12px; color: var(--ctp-text); transition: border-color 0.15s; ``` | State | Border | Shadow | |-------|--------|--------| | Default | `--ctp-surface1` | None | | Hover | `--ctp-overlay0` | None | | Focus | `--ctp-mauve` | `0 0 0 0.2rem rgba(203, 166, 247, 0.25)` | | Error | `--ctp-red` | `0 0 0 0.2rem rgba(243, 139, 168, 0.15)` | | Disabled | `--ctp-surface0` | None, `opacity: 0.5` | Placeholder text: `--ctp-overlay0`. Labels sit above inputs (never inline or floating). ### Tag Input Used for multi-value fields (projects, tags): ```css display: flex; flex-wrap: wrap; gap: 0.3rem; padding: 0.35rem 0.5rem; background: var(--ctp-crust); border: 1px solid var(--ctp-surface1); border-radius: 6px; min-height: 36px; ``` Individual tags use the badge pattern: `rgba(accent, 0.15)` background with accent text. Remove button (×) at `opacity: 0.6`, `1.0` on hover. ### Tables ```css width: 100%; border-collapse: collapse; font-size: 12px; ``` | Element | Style | |---------|-------| | Header row | `background: --ctp-mantle`, `font-size: 11px`, uppercase, `--ctp-overlay1` text | | Body row | `border-bottom: 1px solid --ctp-surface0` | | Row hover | `background: --ctp-surface0` | | Row selected | `background: rgba(203, 166, 247, 0.08)` | | Cell padding | `0.4rem 0.75rem` | | Text columns | Left-aligned | | Number columns | Right-aligned | | Date columns | Right-aligned | | Action columns | Center-aligned | Row actions use icon buttons (not text links). Icons at 14px, `--ctp-overlay1` default, `--ctp-text` on hover. ### Tabs Used in detail panes and module sub-views: ```css display: flex; gap: 0; border-bottom: 2px solid var(--ctp-surface0); ``` | State | Style | |-------|-------| | Default | `padding: 0.5rem 1rem`, `--ctp-subtext0` text, no border | | Hover | `--ctp-text` text | | Active | `--ctp-text` text, `font-weight: 600`, `border-bottom: 2px solid --ctp-mauve` (overlaps container border) | ### Section Dividers Used to visually group form fields: ```css display: flex; align-items: center; gap: 0.75rem; grid-column: 1 / -1; /* span full form grid */ margin-top: 0.75rem; ``` Contains a label (`11px`, uppercase, `--ctp-overlay0`) and a horizontal line (`flex: 1`, `1px solid --ctp-surface0`). ### Sidebar Sections Stacked vertically within detail panes: ```css padding: 1rem 1.25rem; border-bottom: 1px solid var(--ctp-surface0); ``` Last section has no bottom border. Section titles follow the section header typography (11px, uppercase, `--ctp-overlay0`). ### Tooltips Appear on hover after a 300ms delay. Position: above the target element by default, flip below if insufficient space. ```css background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 4px; padding: 0.3rem 0.6rem; font-size: 11px; color: var(--ctp-text); box-shadow: 0 4px 12px rgba(17, 17, 27, 0.4); ``` ### Breadcrumbs Module navigation breadcrumbs: ``` Module Name > List View > Record Name > Sub-view ``` Separator: `>` character in `--ctp-overlay0`. Segments are clickable links in `--ctp-subtext1`. Active (final) segment is `--ctp-text` at `font-weight: 600`. ### Dropdowns / Selects Follow the input base style. The dropdown menu: ```css background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 6px; box-shadow: 0 8px 24px rgba(17, 17, 27, 0.5); padding: 0.25rem; max-height: 240px; overflow-y: auto; ``` Menu items: ```css padding: 0.4rem 0.65rem; border-radius: 4px; font-size: 12px; color: var(--ctp-text); cursor: pointer; ``` Hover: `background: --ctp-surface1`. Selected: `background: rgba(203, 166, 247, 0.12)`, `color: --ctp-mauve`, `font-weight: 600`. --- ## Icons Use [Lucide](https://lucide.dev) icons. Size: 14px for inline/table contexts, 16px for buttons and navigation, 20px for page headers and empty states. Stroke width: 1.5px (Lucide default). Color inherits from parent text color unless explicitly set. Do not mix icon libraries. If Lucide does not have a suitable icon, request one be added or create a custom SVG following Lucide's 24×24 grid and stroke conventions. --- ## Transitions & Animation All interactive state changes use `transition: all 0.15s ease`. This applies to hover, focus, active, and open/close states. No entrance animations on page load. Content renders immediately. Skeleton loaders are acceptable for async data using a pulsing `--ctp-surface0` → `--ctp-surface1` gradient. Dropdown menus and tooltips appear instantly (no slide/fade). Collapse/expand panels (if used) transition `max-height` at `0.2s ease`. --- ## Styling Implementation Silo's React frontend uses **inline `React.CSSProperties` objects** with `var(--ctp-*)` token references. This is the project convention and must not be changed. ### Rules - No CSS modules, no Tailwind, no external CSS-in-JS libraries. - Styles are defined as `const` objects at the top of each component file. - Shared style patterns (button base, input base) can be extracted to a `styles/` directory as exported `CSSProperties` objects. - Use `as const` or `as React.CSSProperties` for type safety. - Pseudo-classes (`:hover`, `:focus`) require state-driven inline styles or a thin CSS file for the base pseudo-class rules. ### Example ```typescript const styles = { container: { display: 'grid', gridTemplateColumns: '1fr 360px', height: '100%', overflow: 'hidden', } as React.CSSProperties, sidebar: { background: 'var(--ctp-mantle)', borderLeft: '1px solid var(--ctp-surface0)', display: 'flex', flexDirection: 'column' as const, overflowY: 'auto' as const, } as React.CSSProperties, }; ``` ### Pseudo-class CSS A single `silo-base.css` file provides pseudo-class rules that cannot be expressed inline: ```css /* Hover, focus, and active states for core interactive elements */ .silo-input:hover { border-color: var(--ctp-overlay0); } .silo-input:focus { border-color: var(--ctp-mauve); box-shadow: 0 0 0 0.2rem rgba(203, 166, 247, 0.25); } .silo-btn:hover { /* per-tier overrides */ } .silo-row:hover { background: var(--ctp-surface0); } ``` Components apply the corresponding class names alongside their inline styles. This is the only place class-based styling is used. --- ## Do / Don't | Do | Don't | |----|-------| | Use `var(--ctp-*)` for every color | Hardcode hex values | | Use the 4px spacing scale | Use arbitrary padding/margins | | Use Lucide icons at standard sizes | Mix icon libraries | | Use inline `CSSProperties` | Use CSS modules or Tailwind | | One primary button per visible context | Multiple competing primary buttons | | Use translucent accent backgrounds for badges | Use solid bright backgrounds for badges | | Use icon buttons for row-level table actions | Use text links in table rows | | Define styles as `const` at file top | Inline style objects in JSX | | Show tooltips on icon-only buttons | Leave icon buttons unlabeled | | Use section dividers to group form fields | Use cards or borders around field groups | | Follow the breadcrumb pattern for navigation | Use nested tab bars | --- ## Appendix: CSS Custom Properties Block Paste this at the root of the application stylesheet: ```css :root { --ctp-rosewater: #f5e0dc; --ctp-flamingo: #f2cdcd; --ctp-pink: #f5c2e7; --ctp-mauve: #cba6f7; --ctp-red: #f38ba8; --ctp-maroon: #eba0ac; --ctp-peach: #fab387; --ctp-yellow: #f9e2af; --ctp-green: #a6e3a1; --ctp-teal: #94e2d5; --ctp-sky: #89dceb; --ctp-sapphire: #74c7ec; --ctp-blue: #89b4fa; --ctp-lavender: #b4befe; --ctp-text: #cdd6f4; --ctp-subtext1: #bac2de; --ctp-subtext0: #a6adc8; --ctp-overlay2: #9399b2; --ctp-overlay1: #7f849c; --ctp-overlay0: #6c7086; --ctp-surface2: #585b70; --ctp-surface1: #45475a; --ctp-surface0: #313244; --ctp-base: #1e1e2e; --ctp-mantle: #181825; --ctp-crust: #11111b; } ```