92b68ca21a
The design system was only ever expressed in the production card's stylesheet (custom_components/cubecraft_production/www/ cubecraft-production-card.js), which is gitignored, so the dashboards had no way to share it. Mirror those tokens into an HA theme and apply the card's own motifs to the wall panels. themes/cubecraft.yaml carries the brand gradient, Nunito, the 4px scale, radii, shadows and semantic colours. It uses `modes:` so it follows HA's light/dark setting: light is the system as authored, dark uses violet-tinted neutrals with the primary lifted to #8B8AF2 (5.6:1 on the card surface) since #3B3AB8 is unreadable as an accent on dark. The gradient itself is unchanged in both modes -- white clears AA across its whole span. At-a-Glance, Family Hub and Voice Alarms pick up three motifs from the card: the .title gradient bar, .column header section labels, and the 4px brand left rule on each tile. Tile colour is cut back to brand indigo, with green/amber/red reserved for real signals (printer offline, bin full) -- the same discipline the card uses, where only a blocked order goes red. CubeOps gets the theme too, so the board and the dashboards land on the same ramp instead of the card improvising against HA's defaults. The card injects its @font-face only on its own page, so a small frontend module declares Nunito document-wide. It points at the woff2 the integration already serves rather than vendoring a second copy, which needed a .gitignore carve-out since www/ is excluded wholesale. dakboard-dark is left in place; switching a dashboard back is a one-line change. Not yet validated by `ha core check` -- this worktree is outside the config tree HA actually loads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
306 lines
13 KiB
YAML
306 lines
13 KiB
YAML
# CubeCraft Creations display system — Home Assistant theme
|
|
#
|
|
# Source of truth for the tokens below is the production card's stylesheet:
|
|
# custom_components/cubecraft_production/www/cubecraft-production-card.js
|
|
# Keep the two in sync. The card reads HA theme variables for its surfaces, so
|
|
# once this theme is active the CubeOps board and the rest of a dashboard end up
|
|
# on the same surfaces, borders and text colours automatically.
|
|
#
|
|
# The theme carries `modes:`, so it follows HA's light/dark setting. The brand
|
|
# gradient, type, radii and semantic colours are identical in both modes; only
|
|
# the surface and text ramps flip.
|
|
#
|
|
# TUNED FOR WALL PANELS: `header-height: 0px` near the bottom collapses the HA
|
|
# toolbar, matching what dakboard-dark did on these dashboards. If you ever want
|
|
# CubeCraft on a phone or desktop where you still need the toolbar, copy this
|
|
# file to themes/cubecraft-desktop.yaml, rename the top-level key, and delete
|
|
# that one line. (HA themes cannot inherit from each other, and this repo's YAML
|
|
# is loaded by HA's own loader, so a `<<:` merge anchor is not worth the risk of
|
|
# taking the whole themes include down.)
|
|
#
|
|
# Hiding the sidebar as well needs the kiosk-mode frontend plugin (HACS), which
|
|
# is not currently installed — see dashboards/views/cubeops-dashboard.yaml.
|
|
|
|
cubecraft:
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# Brand tokens — mirrors the `:host` block in cubecraft-production-card.js.
|
|
# Exposed as --cc-* so dashboard card_mod blocks can reference them by name
|
|
# instead of hard-coding hexes in a dozen places.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
cc-blue: "#3B3AB8"
|
|
cc-purple: "#A035CC"
|
|
cc-gradient: "linear-gradient(135deg, #3B3AB8 0%, #A035CC 100%)"
|
|
|
|
cc-primary-50: "#EBEBF8"
|
|
cc-primary-500: "#3B3AB8"
|
|
cc-primary-700: "#201F7A"
|
|
|
|
cc-neutral-0: "#FFFFFF"
|
|
cc-neutral-50: "#FAFAFA"
|
|
cc-neutral-100: "#F4F4F6"
|
|
cc-neutral-150: "#EDEDF1"
|
|
cc-neutral-200: "#E4E4EA"
|
|
cc-neutral-400: "#9898A8"
|
|
cc-neutral-600: "#52525E"
|
|
cc-neutral-900: "#18181D"
|
|
|
|
cc-success: "#16A34A"
|
|
cc-warning: "#D97706"
|
|
cc-warning-bg: "#FEF3C7"
|
|
cc-error: "#DC2626"
|
|
cc-error-bg: "#FEE2E2"
|
|
|
|
# 4px spacing scale
|
|
cc-space-1: "4px"
|
|
cc-space-2: "8px"
|
|
cc-space-3: "12px"
|
|
cc-space-4: "16px"
|
|
cc-space-5: "20px"
|
|
cc-space-6: "24px"
|
|
cc-space-7: "28px"
|
|
|
|
cc-radius-sm: "6px"
|
|
cc-radius-md: "8px"
|
|
cc-radius-lg: "12px"
|
|
cc-radius-xl: "16px"
|
|
cc-radius-brand: "20px"
|
|
cc-radius-full: "9999px"
|
|
|
|
cc-shadow-sm: "0 2px 6px 0 rgba(0,0,0,.08)"
|
|
cc-shadow-md: "0 4px 12px 0 rgba(0,0,0,.10)"
|
|
cc-shadow-brand: "0 4px 20px 0 rgba(59,58,184,.25)"
|
|
|
|
cc-ease: "cubic-bezier(0,0,.2,1)"
|
|
cc-dur: "200ms"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# Typography — Nunito 400..800.
|
|
# The @font-face has to be declared in the document, not a shadow root; that
|
|
# is what www/cubecraft/cubecraft-brand-font.js does (wired up via
|
|
# frontend.extra_module_url in configuration.yaml). Without it everything
|
|
# below falls back to system-ui and the rest of the theme still works.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
cc-font: "'Nunito', 'Nunito Fallback', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
|
|
primary-font-family: "var(--cc-font)"
|
|
ha-font-family-body: "var(--cc-font)"
|
|
ha-font-family-heading: "var(--cc-font)"
|
|
mdc-typography-font-family: "var(--cc-font)"
|
|
paper-font-common-base_-_font-family: "var(--cc-font)"
|
|
paper-font-common-nowrap_-_font-family: "var(--cc-font)"
|
|
paper-font-body1_-_font-family: "var(--cc-font)"
|
|
paper-font-subhead_-_font-family: "var(--cc-font)"
|
|
paper-font-headline_-_font-family: "var(--cc-font)"
|
|
paper-font-title_-_font-family: "var(--cc-font)"
|
|
paper-font-caption_-_font-family: "var(--cc-font)"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# Shape — brand radius on cards, pills on controls.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
ha-card-border-radius: "var(--cc-radius-brand)"
|
|
ha-card-border-width: "0"
|
|
ha-dialog-border-radius: "var(--cc-radius-brand)"
|
|
ha-badge-border-radius: "var(--cc-radius-full)"
|
|
mdc-shape-small: "var(--cc-radius-full)"
|
|
mdc-shape-medium: "var(--cc-radius-lg)"
|
|
mdc-shape-large: "var(--cc-radius-xl)"
|
|
button-border-radius: "var(--cc-radius-full)"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# Colour — brand ramp. Surfaces/text live in the mode blocks below.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
success-color: "var(--cc-success)"
|
|
warning-color: "var(--cc-warning)"
|
|
error-color: "var(--cc-error)"
|
|
|
|
label-badge-green: "var(--cc-success)"
|
|
label-badge-yellow: "var(--cc-warning)"
|
|
label-badge-red: "var(--cc-error)"
|
|
|
|
# Text sitting on top of primary-color (buttons, selected states). White
|
|
# clears AA against both ends of the gradient (8.5:1 on the blue, 5.4:1 on
|
|
# the purple), so it is safe wherever the gradient is used.
|
|
text-primary-color: "#FFFFFF"
|
|
app-header-text-color: "#FFFFFF"
|
|
mdc-theme-on-primary: "#FFFFFF"
|
|
|
|
# Wall-panel chrome: collapse the HA toolbar. Delete this line for a variant
|
|
# you navigate by hand (see the header comment).
|
|
header-height: "0px"
|
|
|
|
modes:
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
# Light — the design system as authored: white surfaces, neutral sunken
|
|
# backgrounds, near-black text.
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
light:
|
|
cc-surface: "var(--cc-neutral-0)"
|
|
cc-surface-sunken: "var(--cc-neutral-100)"
|
|
cc-text: "var(--cc-neutral-900)"
|
|
cc-text-muted: "var(--cc-neutral-600)"
|
|
cc-border: "var(--cc-neutral-150)"
|
|
cc-accent: "var(--cc-primary-500)"
|
|
cc-accent-soft: "var(--cc-primary-50)"
|
|
|
|
primary-color: "#3B3AB8"
|
|
accent-color: "#A035CC"
|
|
dark-primary-color: "#201F7A"
|
|
light-primary-color: "#EBEBF8"
|
|
info-color: "#3B3AB8"
|
|
|
|
primary-text-color: "#18181D"
|
|
secondary-text-color: "#52525E"
|
|
disabled-text-color: "#9898A8"
|
|
|
|
primary-background-color: "#F4F4F6"
|
|
secondary-background-color: "#EDEDF1"
|
|
card-background-color: "#FFFFFF"
|
|
ha-card-background: "#FFFFFF"
|
|
divider-color: "#EDEDF1"
|
|
ha-card-box-shadow: "0 4px 12px 0 rgba(0,0,0,.10)"
|
|
|
|
app-header-background-color: "#3B3AB8"
|
|
more-info-header-background: "#F4F4F6"
|
|
|
|
sidebar-background-color: "#FFFFFF"
|
|
sidebar-text-color: "#52525E"
|
|
sidebar-icon-color: "#9898A8"
|
|
sidebar-selected-text-color: "#3B3AB8"
|
|
sidebar-selected-icon-color: "#3B3AB8"
|
|
|
|
state-icon-color: "#3B3AB8"
|
|
state-icon-active-color: "#A035CC"
|
|
state-unavailable-color: "#9898A8"
|
|
paper-item-icon-color: "#9898A8"
|
|
paper-item-icon-active-color: "#3B3AB8"
|
|
|
|
switch-checked-color: "#3B3AB8"
|
|
switch-checked-track-color: "#3B3AB8"
|
|
switch-unchecked-color: "#9898A8"
|
|
switch-unchecked-track-color: "#E4E4EA"
|
|
slider-color: "#3B3AB8"
|
|
slider-bar-color: "#E4E4EA"
|
|
|
|
label-badge-blue: "#3B3AB8"
|
|
label-badge-gray: "#9898A8"
|
|
label-badge-text-color: "#18181D"
|
|
ha-label-badge-background-color: "#FFFFFF"
|
|
ha-label-badge-border-color: "#EDEDF1"
|
|
|
|
table-row-background-color: "#FFFFFF"
|
|
table-row-alternative-background-color: "#FAFAFA"
|
|
markdown-code-background-color: "#F4F4F6"
|
|
code-editor-background-color: "#FAFAFA"
|
|
|
|
paper-card-background-color: "#FFFFFF"
|
|
paper-card-header-color: "#18181D"
|
|
paper-dialog-background-color: "#FFFFFF"
|
|
paper-listbox-background-color: "#FFFFFF"
|
|
input-fill-color: "#F4F4F6"
|
|
input-ink-color: "#18181D"
|
|
input-label-ink-color: "#52525E"
|
|
iron-overlay-backdrop-background-color: "rgba(24,24,29,.32)"
|
|
|
|
mdc-theme-primary: "#3B3AB8"
|
|
mdc-theme-secondary: "#A035CC"
|
|
mdc-theme-surface: "#FFFFFF"
|
|
|
|
# Weather glyphs, kept in the brand family rather than default sky blue.
|
|
weather-icon-sun-color: "#D97706"
|
|
weather-icon-rain-color: "#3B3AB8"
|
|
weather-icon-cloud-front-color: "#9898A8"
|
|
weather-icon-cloud-back-color: "#E4E4EA"
|
|
weather-icon-moon-color: "#52525E"
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
# Dark — violet-tinted neutrals so the brand gradient sits in the same
|
|
# family as the surfaces rather than floating on plain grey. The primary
|
|
# is lightened to #8B8AF2 (5.6:1 on the card surface); #3B3AB8 itself is
|
|
# too dark to read as an accent here, though it stays correct inside the
|
|
# gradient, which is left untouched.
|
|
# ═══════════════════════════════════════════════════════════════════════
|
|
dark:
|
|
cc-surface: "#1C1C27"
|
|
cc-surface-sunken: "#16161F"
|
|
cc-text: "#EDEDF1"
|
|
cc-text-muted: "#9898A8"
|
|
cc-border: "#2A2A38"
|
|
cc-accent: "#8B8AF2"
|
|
cc-accent-soft: "#252438"
|
|
|
|
primary-color: "#8B8AF2"
|
|
accent-color: "#C77BEE"
|
|
dark-primary-color: "#3B3AB8"
|
|
light-primary-color: "#C9C8FA"
|
|
info-color: "#8B8AF2"
|
|
|
|
primary-text-color: "#EDEDF1"
|
|
secondary-text-color: "#9898A8"
|
|
disabled-text-color: "#6A6A7C"
|
|
|
|
primary-background-color: "#0E0E14"
|
|
secondary-background-color: "#16161F"
|
|
card-background-color: "#1C1C27"
|
|
ha-card-background: "#1C1C27"
|
|
divider-color: "#2A2A38"
|
|
ha-card-box-shadow: "0 4px 12px 0 rgba(0,0,0,.45)"
|
|
|
|
app-header-background-color: "#16161F"
|
|
more-info-header-background: "#16161F"
|
|
|
|
sidebar-background-color: "#0E0E14"
|
|
sidebar-text-color: "#9898A8"
|
|
sidebar-icon-color: "#6A6A7C"
|
|
sidebar-selected-text-color: "#8B8AF2"
|
|
sidebar-selected-icon-color: "#8B8AF2"
|
|
|
|
state-icon-color: "#8B8AF2"
|
|
state-icon-active-color: "#C77BEE"
|
|
state-unavailable-color: "#6A6A7C"
|
|
paper-item-icon-color: "#6A6A7C"
|
|
paper-item-icon-active-color: "#8B8AF2"
|
|
|
|
switch-checked-color: "#8B8AF2"
|
|
switch-checked-track-color: "#8B8AF2"
|
|
switch-unchecked-color: "#6A6A7C"
|
|
switch-unchecked-track-color: "#2A2A38"
|
|
slider-color: "#8B8AF2"
|
|
slider-bar-color: "#2A2A38"
|
|
|
|
# Semantic colours lifted for dark surfaces; the light-mode values are
|
|
# too dense to read at a distance on #1C1C27.
|
|
success-color: "#4ADE80"
|
|
warning-color: "#FBBF24"
|
|
error-color: "#F87171"
|
|
label-badge-green: "#4ADE80"
|
|
label-badge-yellow: "#FBBF24"
|
|
label-badge-red: "#F87171"
|
|
label-badge-blue: "#8B8AF2"
|
|
label-badge-gray: "#6A6A7C"
|
|
label-badge-text-color: "#EDEDF1"
|
|
ha-label-badge-background-color: "#1C1C27"
|
|
ha-label-badge-border-color: "#2A2A38"
|
|
|
|
table-row-background-color: "#1C1C27"
|
|
table-row-alternative-background-color: "#20202C"
|
|
markdown-code-background-color: "#252433"
|
|
code-editor-background-color: "#16161F"
|
|
|
|
paper-card-background-color: "#1C1C27"
|
|
paper-card-header-color: "#EDEDF1"
|
|
paper-dialog-background-color: "#1C1C27"
|
|
paper-listbox-background-color: "#1C1C27"
|
|
input-fill-color: "#252433"
|
|
input-ink-color: "#EDEDF1"
|
|
input-label-ink-color: "#9898A8"
|
|
iron-overlay-backdrop-background-color: "rgba(0,0,0,.6)"
|
|
|
|
mdc-theme-primary: "#8B8AF2"
|
|
mdc-theme-secondary: "#C77BEE"
|
|
mdc-theme-surface: "#1C1C27"
|
|
|
|
weather-icon-sun-color: "#FBBF24"
|
|
weather-icon-rain-color: "#8B8AF2"
|
|
weather-icon-cloud-front-color: "#9898A8"
|
|
weather-icon-cloud-back-color: "#3A3A4A"
|
|
weather-icon-moon-color: "#C9C8FA"
|