| <!-- |
| ~ Licensed to the Apache Software Foundation (ASF) under one or more |
| ~ contributor license agreements. See the NOTICE file distributed with |
| ~ this work for additional information regarding copyright ownership. |
| ~ The ASF licenses this file to You under the Apache License, Version 2.0 |
| ~ (the "License"); you may not use this file except in compliance with |
| ~ the License. You may obtain a copy of the License at |
| ~ |
| ~ http://www.apache.org/licenses/LICENSE-2.0 |
| ~ |
| ~ Unless required by applicable law or agreed to in writing, software |
| ~ distributed under the License is distributed on an "AS IS" BASIS, |
| ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ~ See the License for the specific language governing permissions and |
| ~ limitations under the License. |
| ~ |
| --> |
| |
| --- |
| name: "Apache StreamPipes" |
| description: "A calm control-room system for clear and dependable industrial data work." |
| colors: |
| deep-signal-indigo: "#1b1464" |
| deep-signal-indigo-dark: "#83a3de" |
| operational-green: "#39b54a" |
| operational-green-dark: "#7ac98a" |
| telemetry-blue: "#0062a0" |
| canvas: "#fafafa" |
| surface: "#ffffff" |
| surface-high: "#eeeeee" |
| surface-highest: "#e0e0e0" |
| ink: "#1a1a1a" |
| ink-muted: "#5e5e5e" |
| night-canvas: "#121212" |
| night-surface: "#1e1e1e" |
| night-ink: "#e0e0e0" |
| info: "#2563eb" |
| success: "#16a34a" |
| warning: "#f59e0b" |
| error: "#dc2626" |
| data-view: "#60a5fa" |
| dashboard: "#4f81bd" |
| adapter: "#b48c5f" |
| data-source: "#eab308" |
| pipeline: "#4ab69b" |
| measurement: "#38b2ac" |
| file: "#a855f7" |
| processor: "#009688" |
| sink: "#3f51b5" |
| typography: |
| display: |
| fontFamily: "Roboto, Arial, sans-serif" |
| fontSize: "clamp(1.7rem, 1.55rem + 0.55vw, 2.1rem)" |
| fontWeight: 700 |
| lineHeight: 1.2 |
| headline: |
| fontFamily: "Roboto, Arial, sans-serif" |
| fontSize: "clamp(1.35rem, 1.28rem + 0.38vw, 1.7rem)" |
| fontWeight: 600 |
| lineHeight: 1.2 |
| title: |
| fontFamily: "Roboto, Arial, sans-serif" |
| fontSize: "clamp(1.22rem, 1.14rem + 0.3vw, 1.4rem)" |
| fontWeight: 600 |
| lineHeight: 1.2 |
| body: |
| fontFamily: "Roboto-Regular, Arial, sans-serif" |
| fontSize: "clamp(0.96rem, 0.92rem + 0.16vw, 1.05rem)" |
| fontWeight: 400 |
| lineHeight: 1.4 |
| label: |
| fontFamily: "Roboto-Regular, Arial, sans-serif" |
| fontSize: "clamp(0.83rem, 0.79rem + 0.12vw, 0.9rem)" |
| fontWeight: 500 |
| lineHeight: 1.4 |
| letterSpacing: "-0.01em" |
| rounded: |
| xs: "0.25rem" |
| sm: "0.5rem" |
| md: "0.75rem" |
| lg: "1rem" |
| pill: "999px" |
| spacing: |
| 2xs: "clamp(0.15rem, 0.12rem + 0.15vw, 0.25rem)" |
| xs: "clamp(0.25rem, 0.22rem + 0.2vw, 0.4rem)" |
| sm: "clamp(0.4rem, 0.35rem + 0.25vw, 0.6rem)" |
| md: "clamp(0.6rem, 0.5rem + 0.35vw, 0.9rem)" |
| lg: "clamp(0.9rem, 0.75rem + 0.4vw, 1.2rem)" |
| xl: "clamp(1.2rem, 1rem + 0.55vw, 1.6rem)" |
| 2xl: "clamp(1.6rem, 1.3rem + 0.7vw, 2.2rem)" |
| components: |
| button-primary: |
| backgroundColor: "{colors.deep-signal-indigo}" |
| textColor: "#cccccc" |
| typography: "{typography.label}" |
| rounded: "{rounded.sm}" |
| padding: "0 1.3rem" |
| height: "2.5rem" |
| button-secondary: |
| backgroundColor: "{colors.surface}" |
| textColor: "{colors.deep-signal-indigo}" |
| typography: "{typography.label}" |
| rounded: "{rounded.sm}" |
| padding: "0 1.3rem" |
| height: "2.5rem" |
| input-outlined: |
| backgroundColor: "{colors.surface}" |
| textColor: "{colors.ink}" |
| typography: "{typography.body}" |
| rounded: "{rounded.sm}" |
| padding: "0.5rem 1rem" |
| height: "2.5rem" |
| status-label: |
| backgroundColor: "{colors.surface-high}" |
| textColor: "{colors.ink}" |
| typography: "{typography.label}" |
| rounded: "{rounded.pill}" |
| padding: "0.2rem 0.55rem" |
| --- |
| |
| # Design System: Apache StreamPipes |
| |
| **Related documents.** `PRODUCT.md` states who this product is for, its brand personality |
| and the anti-references these rules serve. `ui/STYLEGUIDE.md` holds the concrete component |
| markup. This file is normative for tokens, colour roles, typography, layout, elevation and |
| the named rules; where `ui/STYLEGUIDE.md` and this file disagree, this file wins and the |
| styleguide is corrected. Agents working under `ui/` reach this file from `ui/AGENTS.md`. |
| |
| ## Overview |
| |
| **Creative North Star: "The Calm Control Room"** |
| |
| StreamPipes should feel like a calm, well-organized control room: technically |
| capable, operationally trustworthy, and immediately legible. Its visual system |
| uses restrained surfaces, compact controls, clear hierarchy, and semantic |
| color so industrial domain experts can work confidently with complex data and |
| stateful workflows. |
| |
| The visual identity is deliberately subordinate to the task. Beauty comes from |
| alignment, rhythm, consistent interaction states, and an uncluttered reading |
| order—not from decoration. The interface should never feel like a flashy |
| consumer product, a dense legacy enterprise application, or a collection of |
| unfamiliar custom controls. |
| |
| The palette is deployment-configurable by design. Default brand values live in |
| `ui/deployment/theme/` and are copied into `ui/src/scss/custom-theme/` by the |
| prebuild script; operators may replace them through `THEME_VARIABLES` and |
| `THEME_COLORS`. Components must consume semantic CSS variables rather than |
| embedding the default hex values documented here. |
| |
| **Key Characteristics:** |
| |
| - Restrained, information-first product surfaces in light and dark modes. |
| - Compact but readable density suited to dashboards, editors, forms, and tables. |
| - Deep indigo and operational green defaults, with semantic state and data colors. |
| - Familiar Angular Material interaction patterns refined through shared tokens. |
| - Responsive structure, visible focus, reduced-motion support, and translatable copy. |
| |
| ## Colors |
| |
| The default palette pairs grounded indigo with clear operational green and a |
| telemetry-blue tertiary, set against neutral tonal layers. These are default |
| role values, not tenant-locked brand colors. |
| |
| ### Primary |
| |
| - **Deep Signal Indigo** (`#1b1464`): Default primary action, focus, selection, |
| step, and identity color. Use through `--color-primary` or Material system |
| roles so operator themes remain effective. |
| - **Deep Signal Indigo—Dark** (`#83a3de`): Accessible primary role on dark |
| surfaces, exposed as `--color-primary-dark`. |
| |
| ### Secondary |
| |
| - **Operational Green** (`#39b54a`): Default navigation and complementary |
| brand role. It communicates active, connected operation without replacing |
| the distinct success token. |
| - **Operational Green—Dark** (`#7ac98a`): Dark-mode counterpart for the |
| secondary role. |
| |
| ### Tertiary |
| |
| - **Telemetry Blue** (`#0062a0`): Material tertiary role for secondary emphasis |
| and data-oriented accents when primary and semantic colors are already occupied. |
| |
| ### Neutral |
| |
| - **Canvas** (`#fafafa`): Default page background and low surface layer. |
| - **Surface** (`#ffffff`): Primary content, input, table, and dialog surface. |
| - **Surface High** (`#eeeeee`) and **Surface Highest** (`#e0e0e0`): Dividers, |
| grouped regions, inactive controls, and structural layering. |
| - **Ink** (`#1a1a1a`): Default light-mode foreground. |
| - **Muted Ink** (`#5e5e5e`): Supporting copy that still needs readable contrast. |
| - **Night Canvas** (`#121212`), **Night Surface** (`#1e1e1e`), and **Night Ink** |
| (`#e0e0e0`): Dark-mode background, surface, and foreground foundations. |
| - **Info** (`#2563eb`), **Success** (`#16a34a`), **Warning** (`#f59e0b`), and |
| **Error** (`#dc2626`): Dedicated semantic roles. Always pair them with text, |
| iconography, or shape; never communicate state through hue alone. |
| - **Data roles:** Data View (`#60a5fa`), Dashboard (`#4f81bd`), Adapter |
| (`#b48c5f`), Data Source (`#eab308`), Pipeline (`#4ab69b`), Measurement |
| (`#38b2ac`), File (`#a855f7`), Processor (`#009688`), and Sink (`#3f51b5`). |
| These distinguish domain objects and must not be repurposed as generic state colors. |
| |
| ### Named Rules |
| |
| **The Theme Boundary Rule.** Default values belong in `ui/deployment/theme/`. |
| Feature and shared-component styles use semantic CSS variables; do not edit the |
| generated `ui/src/scss/custom-theme/` output as the source of truth or hard-code |
| default brand hex values in components. |
| |
| **The Operational Signal Rule.** Primary color marks action and selection; |
| semantic colors communicate state; domain colors identify object types. Do not |
| collapse these three vocabularies into one ambiguous accent system. |
| |
| ## Typography |
| |
| **Display Font:** Roboto (with Arial and sans-serif fallback) |
| **Body Font:** Roboto Regular (with Arial and sans-serif fallback) |
| **Label/Mono Font:** Roboto Regular for labels; the configured editor font for code |
| |
| **Character:** A single pragmatic sans-serif family keeps dense product screens |
| coherent and familiar. Weight, size, spacing, and surface hierarchy—not a |
| decorative font pairing—create emphasis. |
| |
| ### Hierarchy |
| |
| - **Display** (700, `--font-size-3xl`, 1.2): Page-level headings and the largest |
| in-product titles; avoid marketing-scale typography in working screens. |
| - **Headline** (600, `--font-size-2xl`, 1.2): Primary page headers and major panels. |
| - **Title** (600, `--font-size-xl`, 1.2): Section titles and prominent card headers. |
| - **Body** (400, `--font-size-md`, 1.4; 1.6 for prose): Instructions, descriptions, |
| and primary content. Keep explanatory prose within roughly 65–75 characters. |
| - **Label** (500, `--font-size-sm`, `-0.01em`): Buttons, form labels, table controls, |
| and compact UI. Uppercase is reserved for real categorical labels, not every heading. |
| |
| ### Named Rules |
| |
| **The One Working Voice Rule.** Use the shared Roboto scale and weight tokens |
| across labels, data, navigation, and headings. Do not introduce display fonts or |
| component-local type scales into product workflows. |
| |
| ## Layout |
| |
| Page-level working views follow one stable vertical hierarchy: `sp-page-header` |
| establishes identity and global actions, optional `sp-page-nav-tabs` provides |
| sibling-view navigation directly beneath it, and the active content follows |
| after one `--space-lg` interval. The composition lives inside |
| `sp-basic-view` with `hideNavbar` and token-driven padding; do not add an outer |
| page margin or a second padded navigation shell. |
| |
| Pages that share identity across routes—details, settings, and monitoring |
| views—should provide a small feature layout component that owns the header, |
| tabs, loading and not-found states, and responsive behavior. Route components |
| then supply only their content and projected `pageActions`. On narrow |
| containers, header actions wrap below the identity, tabs scroll horizontally, |
| and the content interval reduces to `--space-md` without changing DOM order. |
| |
| **The One Page Identity Rule.** A working view has one page header. Page-wide |
| status, identifiers, and actions belong in its action area; route names belong |
| in the tab row; section titles belong in `sp-split-section`. |
| |
| ## Elevation & Depth |
| |
| The system is tonal and structural by default. Most hierarchy comes from |
| surface-container steps, one-pixel dividers, and selected-state tints. Shadows |
| are reserved for content that genuinely floats above the working plane—dialogs, |
| menus, popovers, and persistent navigation—not ordinary cards or buttons. |
| |
| ### Shadow Vocabulary |
| |
| - **Overlay** (`0 12px 32px rgba(0, 0, 0, 0.16)`): Dialogs, menus, and other |
| temporary layers above the application surface. |
| - **Navigation depth** (`0 10px 30px rgba(0, 0, 0, 0.25)` plus an inset divider): |
| The persistent sidebar boundary; do not repeat this treatment on content panels. |
| - **Keycap** (`0 2px 6px rgb(0 0 0 / 18%)`): Keyboard-shortcut hints only. |
| |
| ### Named Rules |
| |
| **The Flat Working Plane Rule.** Content surfaces are flat at rest. Use tonal |
| layers or a border for structure; use a shadow only when the element is spatially |
| above adjacent content. |
| |
| ## Components |
| |
| Shared components are compact, dependable, and familiar. Prefer the existing |
| `sp-*` and Angular Material patterns before creating a feature-local equivalent. |
| |
| ### Buttons |
| |
| - **Shape:** Soft rectangle using `--radius-sm` (`0.5rem`). |
| - **Primary:** `mat-flat-button` with the theme primary fill, medium-weight label, |
| `-0.01em` tracking, and `1.3rem` horizontal padding. |
| - **Hover / Focus:** Hover and active states mix the current theme color rather |
| than introduce a new hue. Keyboard focus uses the shared three-pixel focus ring. |
| - **Secondary / Warning:** Secondary actions use a subtle primary-tinted surface; |
| destructive actions use the dedicated error role. Both stay flat at rest. |
| |
| ### Chips |
| |
| - **Style:** `sp-label` supports solid, soft, and outline variants with semantic |
| or domain-specific color input. Default labels use a pill shape (`999px`) and |
| compact horizontal padding. |
| - **State:** Use text and icons alongside color. Badge shapes are slightly tighter |
| and heavier than general-purpose pills. |
| |
| ### Cards / Containers |
| |
| - **Corner Style:** Shared surfaces generally use `--radius-sm` to |
| `--radius-md` (`0.5rem`–`0.75rem`); large rounding is not part of the system. |
| - **Background:** Use Material surface and surface-container roles. |
| - **Shadow Strategy:** Flat for ordinary content; follow the elevation vocabulary |
| for true overlays. |
| - **Border:** One-pixel subtle borders are acceptable for structural separation. |
| - **Internal Padding:** Prefer the shared `--space-md` through `--space-xl` scale. |
| |
| ### Inputs / Fields |
| |
| - **Style:** Outlined Angular Material fields on the surface color, `2.5rem` high, |
| with `--radius-sm`. Wrap feature inputs in `sp-form-field`; do not use floating labels. |
| - **Focus:** Primary-colored outline plus shared focus semantics. |
| - **Error / Disabled:** Error uses the Material error role; disabled fields shift |
| to a higher neutral surface and reduce saturation without disappearing. |
| |
| ### Navigation |
| |
| The persistent sidebar expands from `62px` to `260px`, groups product areas, |
| and uses icons, labels, hover fills, and `aria-current` for orientation. Motion is |
| short (`120–220ms`) and state-driven. Preserve collapse behavior and ensure the |
| operator-configured navigation colors retain readable foregrounds. |
| |
| Within a page, use `sp-page-nav-tabs` directly below `sp-page-header`. Tabs may |
| include established Material icons, use the primary theme role for active and |
| focus states, and scroll horizontally when space is constrained. |
| When the same position switches local content instead of navigating between |
| routes, use `mat-tab-group` with the shared `sp-page-tabs` class and disable |
| stretched tabs. This preserves the same height, spacing, typography, divider, |
| active indicator, focus treatment, and narrow-screen behavior without making |
| local state look like route navigation. |
| `sp-basic-nav-tabs` is a legacy compatibility wrapper and must not be introduced |
| in new page-level work or retained when that page is migrated to the current |
| shell. |
| |
| ### Tables |
| |
| Use `sp-table` for paging, sorting, grouping, selection, and action menus. Headers |
| are semibold on the base surface; rows use subtle hover and selected-state fills. |
| Dense tabular information is appropriate when hierarchy and keyboard focus remain clear. |
| |
| ### Alerts |
| |
| Use `sp-alert-banner` for info, success, warning, and error messages. Each alert |
| combines a tinted background, semantic foreground, one-pixel border, icon, title, |
| and optional description or action. |
| |
| ## Do's and Don'ts |
| |
| ### Do: |
| |
| - **Do** use shared spacing, typography, radius, motion, surface, and semantic tokens. |
| - **Do** treat `ui/deployment/theme/` as the source of default theme values and |
| preserve operator overrides through the prebuild pipeline. |
| - **Do** compose page-level views from `sp-basic-view`, `sp-page-header`, and, |
| when needed, `sp-page-nav-tabs`; use `sp-split-section`, `sp-form-field`, |
| `sp-table`, and alert components within page content. |
| - **Do** place page-wide actions, status, and identifiers in `pageActions` and |
| keep section-specific actions with their section. |
| - **Do** keep controls keyboard-operable, focus-visible, translatable, and clear |
| without color; target WCAG 2.2 AA. |
| - **Do** communicate loading, empty, success, and error states without removing |
| the user's workflow context. |
| |
| ### Don't: |
| |
| - **Don't** hard-code the default indigo or green in feature components; users |
| can supply their own styles through `THEME_VARIABLES` and `THEME_COLORS`. |
| - **Don't** build against the anti-references in `PRODUCT.md`; they apply here verbatim. |
| - **Don't** pair a decorative one-pixel card border with a broad soft shadow; |
| ordinary content belongs on the flat working plane. |
| - **Don't** use colored side stripes, gradient text, decorative glass cards, |
| oversized rounding, or ornamental motion. |
| - **Don't** bypass shared components with one-off local versions of buttons, |
| fields, tables, navigation, alerts, or loading indicators. |
| - **Don't** use `sp-basic-nav-tabs` for new or migrated page-level views, or add |
| a second title beneath `sp-page-header`. |