@yottagraph-app/aether-instructions 1.1.23 → 1.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/update_branding.md +35 -87
- package/package.json +1 -1
- package/rules/branding.mdc +19 -27
- package/rules/design.mdc +2 -1
- package/skills/data-model/bny/DATA_DICTIONARY.md +184 -0
- package/skills/data-model/bny/schema.yaml +598 -0
- package/skills/data-model/edgar/schema.yaml +1 -1
- package/skills/elemental-api/SKILL.md +41 -4
- package/skills/elemental-api/entities.md +241 -114
- package/skills/elemental-api/find.md +59 -9
- package/skills/elemental-api/mcp.md +180 -0
- package/skills/elemental-api/overview.md +73 -20
- package/skills/elemental-api/relationships.md +163 -0
- package/skills/elemental-api/schema.md +54 -8
- package/skills/lovelace-branding/BRANDING.md +176 -0
- package/skills/lovelace-branding/SKILL.md +25 -0
- package/skills/lovelace-branding/assets/LL-logo-full-white-green.svg +35 -0
- package/skills/lovelace-branding/assets/LL-logo-full-wht.svg +39 -0
- package/skills/lovelace-branding/assets/LL-mark-green.svg +21 -0
- package/skills/lovelace-branding/assets/entity-styles.json +42 -0
- package/skills/lovelace-branding/assets/help-circle.svg +4 -0
- package/skills/lovelace-branding/fonts.md +147 -0
- package/skills/lovelace-branding/overview.md +136 -0
- package/skills/lovelace-branding/patterns.md +263 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 643.71 84.78">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #3fea00;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-2 {
|
|
10
|
+
fill: #fff;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
</defs>
|
|
14
|
+
<g id="Layer_1-2" data-name="Layer 1">
|
|
15
|
+
<g>
|
|
16
|
+
<path class="cls-2" d="M108.53,69.1V5.86h18.75v56.13h34.92v16.48h-44.08c-6.08,0-9.58-3.19-9.58-9.37Z"/>
|
|
17
|
+
<path class="cls-2" d="M198.24,4.42c23.59,0,38.01,16.27,38.01,37.7s-14.42,37.8-38.01,37.8-38.21-16.27-38.21-37.8,14.52-37.7,38.21-37.7ZM198.24,62.92c12.57,0,18.75-7.62,18.75-20.81s-6.28-20.7-18.75-20.7-18.85,7.62-18.85,20.7,6.28,20.81,18.85,20.81Z"/>
|
|
18
|
+
<path class="cls-2" d="M229.96,5.86h19.88l20.6,65.82,20.6-65.82h19.67l-23.28,72.61h-34.3L229.96,5.86Z"/>
|
|
19
|
+
<path class="cls-2" d="M313.7,5.86h57.78v16.38h-38.93v12.15h33.78v15.45h-33.78v12.26h38.93v16.38h-57.78V5.86Z"/>
|
|
20
|
+
<path class="cls-2" d="M376.01,69.1V5.86h18.75v56.13h34.92v16.48h-44.08c-6.08,0-9.58-3.19-9.58-9.37Z"/>
|
|
21
|
+
<path class="cls-2" d="M455.94,5.86h34.3l23.17,72.61h-19.88l-6.8-21.94h-27.6l-6.8,21.94h-19.67l23.28-72.61ZM481.59,40.16l-8.65-27.71-8.65,27.71h17.3Z"/>
|
|
22
|
+
<path class="cls-2" d="M507.54,42.11c0-21.42,14.73-37.7,38.52-37.7,20.81,0,34.61,11.23,36.77,29.46h-19.26c-1.54-7.83-8.24-12.46-17.41-12.46-11.23,0-19.26,6.39-19.26,20.7s8.03,20.81,19.26,20.81c9.17,0,15.86-4.74,17.41-12.57h19.26c-2.16,18.33-15.96,29.56-36.77,29.56-23.79,0-38.52-16.27-38.52-37.8Z"/>
|
|
23
|
+
<path class="cls-2" d="M585.92,5.86h57.78v16.38h-38.93v12.15h33.78v15.45h-33.78v12.26h38.93v16.38h-57.78V5.86Z"/>
|
|
24
|
+
</g>
|
|
25
|
+
<path class="cls-1" d="M84.78,42.39h0c0,23.41-18.98,42.39-42.39,42.39h0C18.98,84.78,0,65.8,0,42.39h0C0,18.98,18.98,0,42.39,0h0c23.41,0,42.39,18.98,42.39,42.39Z"/>
|
|
26
|
+
<g>
|
|
27
|
+
<circle cx="67.39" cy="50.72" r="6.4"/>
|
|
28
|
+
<circle cx="67.39" cy="34.05" r="6.4"/>
|
|
29
|
+
<circle cx="50.72" cy="50.72" r="6.4"/>
|
|
30
|
+
<circle cx="34.05" cy="34.05" r="6.4"/>
|
|
31
|
+
<circle cx="17.39" cy="34.05" r="6.4"/>
|
|
32
|
+
<circle cx="17.39" cy="50.72" r="6.4"/>
|
|
33
|
+
</g>
|
|
34
|
+
</g>
|
|
35
|
+
</svg>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 643.71 84.78">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #e6e6e6;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-2 {
|
|
10
|
+
fill: #3fea00;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cls-3 {
|
|
14
|
+
fill: #fff;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</defs>
|
|
18
|
+
<g id="Layer_1-2" data-name="Layer 1">
|
|
19
|
+
<g>
|
|
20
|
+
<path class="cls-3" d="M108.53,69.1V5.86h18.75v56.13h34.92v16.48h-44.08c-6.08,0-9.58-3.19-9.58-9.37Z"/>
|
|
21
|
+
<path class="cls-3" d="M198.24,4.42c23.59,0,38.01,16.27,38.01,37.7s-14.42,37.8-38.01,37.8-38.21-16.27-38.21-37.8,14.52-37.7,38.21-37.7ZM198.24,62.92c12.57,0,18.75-7.62,18.75-20.81s-6.28-20.7-18.75-20.7-18.85,7.62-18.85,20.7,6.28,20.81,18.85,20.81Z"/>
|
|
22
|
+
<path class="cls-3" d="M229.96,5.86h19.88l20.6,65.82,20.6-65.82h19.67l-23.28,72.61h-34.3L229.96,5.86Z"/>
|
|
23
|
+
<path class="cls-3" d="M313.7,5.86h57.78v16.38h-38.93v12.15h33.78v15.45h-33.78v12.26h38.93v16.38h-57.78V5.86Z"/>
|
|
24
|
+
<path class="cls-3" d="M376.01,69.1V5.86h18.75v56.13h34.92v16.48h-44.08c-6.08,0-9.58-3.19-9.58-9.37Z"/>
|
|
25
|
+
<path class="cls-3" d="M455.94,5.86h34.3l23.17,72.61h-19.88l-6.8-21.94h-27.6l-6.8,21.94h-19.67l23.28-72.61ZM481.59,40.16l-8.65-27.71-8.65,27.71h17.3Z"/>
|
|
26
|
+
<path class="cls-3" d="M507.54,42.11c0-21.42,14.73-37.7,38.52-37.7,20.81,0,34.61,11.23,36.77,29.46h-19.26c-1.54-7.83-8.24-12.46-17.41-12.46-11.23,0-19.26,6.39-19.26,20.7s8.03,20.81,19.26,20.81c9.17,0,15.86-4.74,17.41-12.57h19.26c-2.16,18.33-15.96,29.56-36.77,29.56-23.79,0-38.52-16.27-38.52-37.8Z"/>
|
|
27
|
+
<path class="cls-3" d="M585.92,5.86h57.78v16.38h-38.93v12.15h33.78v15.45h-33.78v12.26h38.93v16.38h-57.78V5.86Z"/>
|
|
28
|
+
</g>
|
|
29
|
+
<path class="cls-1" d="M84.78,42.39h0c0,23.41-18.98,42.39-42.39,42.39h0C18.98,84.78,0,65.8,0,42.39h0C0,18.98,18.98,0,42.39,0h0c23.41,0,42.39,18.98,42.39,42.39Z"/>
|
|
30
|
+
<g>
|
|
31
|
+
<circle class="cls-2" cx="67.39" cy="50.72" r="6.4"/>
|
|
32
|
+
<circle class="cls-2" cx="67.39" cy="34.05" r="6.4"/>
|
|
33
|
+
<circle class="cls-2" cx="50.72" cy="50.72" r="6.4"/>
|
|
34
|
+
<circle class="cls-2" cx="34.05" cy="34.05" r="6.4"/>
|
|
35
|
+
<circle class="cls-2" cx="17.39" cy="34.05" r="6.4"/>
|
|
36
|
+
<circle class="cls-2" cx="17.39" cy="50.72" r="6.4"/>
|
|
37
|
+
</g>
|
|
38
|
+
</g>
|
|
39
|
+
</svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84.78 84.78">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #3fea00;
|
|
7
|
+
}
|
|
8
|
+
</style>
|
|
9
|
+
</defs>
|
|
10
|
+
<g id="Layer_1-2" data-name="Layer 1">
|
|
11
|
+
<path class="cls-1" d="M84.78,42.39h0c0,23.41-18.98,42.39-42.39,42.39h0C18.98,84.78,0,65.8,0,42.39h0C0,18.98,18.98,0,42.39,0h0c23.41,0,42.39,18.98,42.39,42.39Z"/>
|
|
12
|
+
<g>
|
|
13
|
+
<circle cx="67.39" cy="50.72" r="6.4"/>
|
|
14
|
+
<circle cx="67.39" cy="34.05" r="6.4"/>
|
|
15
|
+
<circle cx="50.72" cy="50.72" r="6.4"/>
|
|
16
|
+
<circle cx="34.05" cy="34.05" r="6.4"/>
|
|
17
|
+
<circle cx="17.39" cy="34.05" r="6.4"/>
|
|
18
|
+
<circle cx="17.39" cy="50.72" r="6.4"/>
|
|
19
|
+
</g>
|
|
20
|
+
</g>
|
|
21
|
+
</svg>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "Medium Red",
|
|
4
|
+
"color": "#FF0000",
|
|
5
|
+
"size": 20
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"name": "Medium Green",
|
|
9
|
+
"color": "#00FF00",
|
|
10
|
+
"size": 20
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "Medium Blue",
|
|
14
|
+
"color": "#0000FF",
|
|
15
|
+
"size": 20
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Medium Yellow",
|
|
19
|
+
"color": "#FFFF00",
|
|
20
|
+
"size": 20
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Small Red",
|
|
24
|
+
"color": "#FF0000",
|
|
25
|
+
"size": 20
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "Small Green",
|
|
29
|
+
"color": "#00FF00",
|
|
30
|
+
"size": 20
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "Small Blue",
|
|
34
|
+
"color": "#0000FF",
|
|
35
|
+
"size": 20
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "Small Yellow",
|
|
39
|
+
"color": "#FFFF00",
|
|
40
|
+
"size": 20
|
|
41
|
+
}
|
|
42
|
+
]
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="main">
|
|
2
|
+
<path
|
|
3
|
+
d="M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Lovelace Font Setup
|
|
2
|
+
|
|
3
|
+
FK Grotesk is the primary font family for Lovelace branding. This document covers setup, fallbacks, and deployment considerations.
|
|
4
|
+
|
|
5
|
+
## Required Font Files
|
|
6
|
+
|
|
7
|
+
FK Grotesk is a commercial font. Font files are **not committed to git**.
|
|
8
|
+
|
|
9
|
+
### Minimum Required
|
|
10
|
+
|
|
11
|
+
At minimum, you need these three files:
|
|
12
|
+
|
|
13
|
+
- `FKGrotesk-Regular.otf` — Body text
|
|
14
|
+
- `FKGrotesk-Bold.otf` — Strong text
|
|
15
|
+
- `FKGroteskMono-Regular.otf` — Headlines, buttons, code
|
|
16
|
+
|
|
17
|
+
### Full Set (Optional)
|
|
18
|
+
|
|
19
|
+
**FK Grotesk (Proportional):**
|
|
20
|
+
- `FKGrotesk-Thin.otf`, `FKGrotesk-ThinItalic.otf`
|
|
21
|
+
- `FKGrotesk-Light.otf`, `FKGrotesk-LightItalic.otf`
|
|
22
|
+
- `FKGrotesk-Regular.otf`, `FKGrotesk-Italic.otf`
|
|
23
|
+
- `FKGrotesk-Medium.otf`, `FKGrotesk-MediumItalic.otf`
|
|
24
|
+
- `FKGrotesk-Bold.otf`, `FKGrotesk-BoldItalic.otf`
|
|
25
|
+
- `FKGrotesk-Black.otf`, `FKGrotesk-BlackItalic.otf`
|
|
26
|
+
|
|
27
|
+
**FK Grotesk Mono:**
|
|
28
|
+
- `FKGroteskMono-Thin.otf`, `FKGroteskMono-ThinItalic.otf`
|
|
29
|
+
- `FKGroteskMono-Light.otf`, `FKGroteskMono-LightItalic.otf`
|
|
30
|
+
- `FKGroteskMono-Regular.otf`, `FKGroteskMono-Italic.otf`
|
|
31
|
+
- `FKGroteskMono-Medium.otf`, `FKGroteskMono-MediumItalic.otf`
|
|
32
|
+
- `FKGroteskMono-Bold.otf`, `FKGroteskMono-BoldItalic.otf`
|
|
33
|
+
- `FKGroteskMono-Black.otf`, `FKGroteskMono-BlackItalic.otf`
|
|
34
|
+
|
|
35
|
+
## @font-face Declarations
|
|
36
|
+
|
|
37
|
+
```css
|
|
38
|
+
@font-face {
|
|
39
|
+
font-family: 'FK Grotesk';
|
|
40
|
+
src: url('/fonts/FKGrotesk-Regular.otf') format('opentype');
|
|
41
|
+
font-weight: 400;
|
|
42
|
+
font-style: normal;
|
|
43
|
+
font-display: swap;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@font-face {
|
|
47
|
+
font-family: 'FK Grotesk';
|
|
48
|
+
src: url('/fonts/FKGrotesk-Bold.otf') format('opentype');
|
|
49
|
+
font-weight: 700;
|
|
50
|
+
font-style: normal;
|
|
51
|
+
font-display: swap;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@font-face {
|
|
55
|
+
font-family: 'FK Grotesk Mono';
|
|
56
|
+
src: url('/fonts/FKGroteskMono-Regular.otf') format('opentype');
|
|
57
|
+
font-weight: 400;
|
|
58
|
+
font-style: normal;
|
|
59
|
+
font-display: swap;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## CSS Variable Setup
|
|
64
|
+
|
|
65
|
+
```css
|
|
66
|
+
:root {
|
|
67
|
+
--font-primary: 'FK Grotesk', 'Inter', system-ui, -apple-system, sans-serif;
|
|
68
|
+
--font-headline: 'FK Grotesk Mono', 'Inter', system-ui, sans-serif;
|
|
69
|
+
--font-brand: 'Inter', system-ui, -apple-system, sans-serif;
|
|
70
|
+
--font-mono: 'FK Grotesk Mono', 'JetBrains Mono', 'Fira Code', monospace;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Fallback Strategy
|
|
75
|
+
|
|
76
|
+
When FK Grotesk is not available, the CSS falls back gracefully:
|
|
77
|
+
|
|
78
|
+
| Role | Primary | Fallback |
|
|
79
|
+
|------|---------|----------|
|
|
80
|
+
| Body text | FK Grotesk | Inter, system-ui |
|
|
81
|
+
| Headlines | FK Grotesk Mono | Inter, system-ui |
|
|
82
|
+
| Code/Buttons | FK Grotesk Mono | JetBrains Mono, Fira Code |
|
|
83
|
+
| Brand wordmark | Inter | system-ui |
|
|
84
|
+
|
|
85
|
+
**Inter** is a widely available system font on modern operating systems and provides a similar aesthetic to FK Grotesk.
|
|
86
|
+
|
|
87
|
+
**JetBrains Mono** is a free, open-source monospace font that works well as a fallback for FK Grotesk Mono.
|
|
88
|
+
|
|
89
|
+
## Usage Examples
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
/* Body text */
|
|
93
|
+
body {
|
|
94
|
+
font-family: var(--font-primary);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Headlines */
|
|
98
|
+
h1, h2, h3 {
|
|
99
|
+
font-family: var(--font-headline);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Buttons */
|
|
103
|
+
button {
|
|
104
|
+
font-family: var(--font-mono);
|
|
105
|
+
text-transform: uppercase;
|
|
106
|
+
letter-spacing: 0.05em;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Code blocks */
|
|
110
|
+
code, pre {
|
|
111
|
+
font-family: var(--font-mono);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Deployment Considerations
|
|
116
|
+
|
|
117
|
+
### Static Hosting
|
|
118
|
+
|
|
119
|
+
Place font files in your `public/fonts/` directory. They'll be served as static assets.
|
|
120
|
+
|
|
121
|
+
### Docker
|
|
122
|
+
|
|
123
|
+
Include fonts in your Docker build. Since fonts are git-ignored, add them before building:
|
|
124
|
+
|
|
125
|
+
```dockerfile
|
|
126
|
+
COPY fonts/ /app/public/fonts/
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Cloud Run / Kubernetes
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
1. Copy fonts to the image before building
|
|
133
|
+
2. Mount fonts as a secret or ConfigMap volume
|
|
134
|
+
3. Fetch fonts from secure storage in a CI/CD step
|
|
135
|
+
|
|
136
|
+
### CI/CD
|
|
137
|
+
|
|
138
|
+
Add a step to fetch fonts from secure storage (e.g., GCS bucket, 1Password) before building:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
- name: Fetch fonts
|
|
142
|
+
run: gsutil cp gs://your-bucket/fonts/*.otf public/fonts/
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Licensing
|
|
146
|
+
|
|
147
|
+
FK Grotesk requires a commercial license. Contact the font foundry for licensing terms. Do not commit font files to public repositories.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Lovelace Branding Quick Reference
|
|
2
|
+
|
|
3
|
+
Quick-start guide for implementing Lovelace visual identity.
|
|
4
|
+
|
|
5
|
+
## Key Principles
|
|
6
|
+
|
|
7
|
+
- **Dark-first**: Jet Black (#0A0A0A) backgrounds, white text
|
|
8
|
+
- **Green accents**: Cyber Green (#3FEA00) for interactive elements, CTAs, success states
|
|
9
|
+
- **WCAG AA accessibility**: All color pairings meet minimum contrast requirements
|
|
10
|
+
- **Monospace for emphasis**: FK Grotesk Mono for headlines, buttons, code
|
|
11
|
+
- **Minimal decoration**: Clean surfaces, subtle borders, purposeful color
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
Minimal CSS variable setup to get started:
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
:root {
|
|
19
|
+
/* Core colors */
|
|
20
|
+
--lv-black: #0A0A0A;
|
|
21
|
+
--lv-white: #FFFFFF;
|
|
22
|
+
--lv-green: #3FEA00;
|
|
23
|
+
--lv-silver: #757575;
|
|
24
|
+
|
|
25
|
+
/* Surfaces */
|
|
26
|
+
--lv-surface: #141414;
|
|
27
|
+
--lv-surface-light: #1E1E1E;
|
|
28
|
+
|
|
29
|
+
/* Typography */
|
|
30
|
+
--font-primary: 'FK Grotesk', 'Inter', system-ui, sans-serif;
|
|
31
|
+
--font-headline: 'FK Grotesk Mono', 'Inter', system-ui, sans-serif;
|
|
32
|
+
--font-mono: 'FK Grotesk Mono', 'JetBrains Mono', monospace;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Core Colors
|
|
37
|
+
|
|
38
|
+
| Name | Hex | CSS Variable | Usage |
|
|
39
|
+
|------|-----|--------------|-------|
|
|
40
|
+
| Jet Black | `#0A0A0A` | `--lv-black` | Primary backgrounds |
|
|
41
|
+
| Pure White | `#FFFFFF` | `--lv-white` | Primary text on dark surfaces |
|
|
42
|
+
| Sonic Silver | `#757575` | `--lv-silver` | Muted text, secondary elements |
|
|
43
|
+
| Cyber Green | `#3FEA00` | `--lv-green` | Primary accent, CTAs, success |
|
|
44
|
+
|
|
45
|
+
## Secondary Colors
|
|
46
|
+
|
|
47
|
+
| Name | Hex | CSS Variable | Usage |
|
|
48
|
+
|------|-----|--------------|-------|
|
|
49
|
+
| Electric Blue | `#003BFF` | `--lv-blue` | Accent, links, finance/data |
|
|
50
|
+
| Blaze Orange | `#FF5C00` | `--lv-orange` | Warnings, highlights, secondary CTA |
|
|
51
|
+
| Amber | `#FF9F0A` | `--lv-yellow` | Warnings |
|
|
52
|
+
| Red | `#EF4444` | — | Errors |
|
|
53
|
+
|
|
54
|
+
## Surface Colors
|
|
55
|
+
|
|
56
|
+
| Name | Hex | CSS Variable | Usage |
|
|
57
|
+
|------|-----|--------------|-------|
|
|
58
|
+
| Surface | `#141414` | `--lv-surface` | Card backgrounds, elevated surfaces |
|
|
59
|
+
| Surface Light | `#1E1E1E` | `--lv-surface-light` | Hover states, lighter panels |
|
|
60
|
+
| Panel | `#111111` | — | Table headers, dark panels |
|
|
61
|
+
| Border | `#2A2A2A` | — | Subtle borders |
|
|
62
|
+
|
|
63
|
+
## Color Usage Proportions
|
|
64
|
+
|
|
65
|
+
- **70%** — Jet Black + Pure White (dark backgrounds, white text)
|
|
66
|
+
- **15%** — Cyber Green (accents, interactive elements, success states)
|
|
67
|
+
- **10%** — Sonic Silver (muted text, borders, secondary elements)
|
|
68
|
+
- **5%** — Electric Blue + Blaze Orange (sparingly, for specific semantic purposes)
|
|
69
|
+
|
|
70
|
+
## Typography
|
|
71
|
+
|
|
72
|
+
### Font Families
|
|
73
|
+
|
|
74
|
+
| Role | Font | CSS Variable |
|
|
75
|
+
|------|------|--------------|
|
|
76
|
+
| Body / Primary | FK Grotesk | `--font-primary` |
|
|
77
|
+
| Headlines | FK Grotesk Mono | `--font-headline` |
|
|
78
|
+
| Buttons / Code | FK Grotesk Mono | `--font-mono` |
|
|
79
|
+
| Brand wordmark | Inter | `--font-brand` |
|
|
80
|
+
|
|
81
|
+
### Type Hierarchy
|
|
82
|
+
|
|
83
|
+
| Level | Font | Weight | Style |
|
|
84
|
+
|-------|------|--------|-------|
|
|
85
|
+
| Headlines (h1) | FK Grotesk Mono | Regular | Normal |
|
|
86
|
+
| Subheaders (h2, h3) | FK Grotesk Mono | Regular | Normal |
|
|
87
|
+
| Body Copy | FK Grotesk | Regular | Normal |
|
|
88
|
+
| Body Strong | FK Grotesk | Bold (700) | Normal |
|
|
89
|
+
| Buttons & UI | FK Grotesk Mono | Regular | UPPERCASE, letter-spacing 0.05em |
|
|
90
|
+
|
|
91
|
+
## Full CSS Variables
|
|
92
|
+
|
|
93
|
+
Complete `:root` block for all brand variables:
|
|
94
|
+
|
|
95
|
+
```css
|
|
96
|
+
:root {
|
|
97
|
+
/* Core */
|
|
98
|
+
--lv-black: #0A0A0A;
|
|
99
|
+
--lv-surface: #141414;
|
|
100
|
+
--lv-surface-light: #1E1E1E;
|
|
101
|
+
--lv-white: #FFFFFF;
|
|
102
|
+
--lv-silver: #757575;
|
|
103
|
+
|
|
104
|
+
/* Primary */
|
|
105
|
+
--lv-green: #3FEA00;
|
|
106
|
+
--lv-green-dim: #30BC00;
|
|
107
|
+
--lv-green-light: #57FF19;
|
|
108
|
+
|
|
109
|
+
/* Secondary */
|
|
110
|
+
--lv-orange: #FF5C00;
|
|
111
|
+
--lv-orange-dim: #D04E02;
|
|
112
|
+
--lv-blue: #003BFF;
|
|
113
|
+
--lv-blue-dim: #0230D0;
|
|
114
|
+
--lv-blue-light: #2E5DFF;
|
|
115
|
+
|
|
116
|
+
/* Semantic */
|
|
117
|
+
--lv-yellow: #FF9F0A;
|
|
118
|
+
--lv-finance-blue: #003BFF;
|
|
119
|
+
|
|
120
|
+
/* Typography */
|
|
121
|
+
--font-primary: 'FK Grotesk', 'Inter', system-ui, -apple-system, sans-serif;
|
|
122
|
+
--font-headline: 'FK Grotesk Mono', 'Inter', system-ui, sans-serif;
|
|
123
|
+
--font-brand: 'Inter', system-ui, -apple-system, sans-serif;
|
|
124
|
+
--font-mono: 'FK Grotesk Mono', 'JetBrains Mono', 'Fira Code', monospace;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Accessibility
|
|
129
|
+
|
|
130
|
+
All color pairings must meet WCAG AA contrast ratio at minimum:
|
|
131
|
+
|
|
132
|
+
- White text on Jet Black: **passes AAA**
|
|
133
|
+
- Cyber Green on Jet Black: **passes AA**
|
|
134
|
+
- Electric Blue on Jet Black: **passes AA**
|
|
135
|
+
|
|
136
|
+
Use the color ramps (see BRANDING.md) to find appropriate pairings for other combinations.
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Lovelace CSS Patterns
|
|
2
|
+
|
|
3
|
+
Framework-agnostic CSS patterns for implementing Lovelace brand styling. These patterns are extracted from the News UI theme styles and can be adapted for React, Vue, Tailwind, or plain CSS.
|
|
4
|
+
|
|
5
|
+
## Card Styling
|
|
6
|
+
|
|
7
|
+
### Basic Card
|
|
8
|
+
|
|
9
|
+
```css
|
|
10
|
+
.card {
|
|
11
|
+
background-color: var(--lv-surface);
|
|
12
|
+
border: 1px solid #2A2A2A;
|
|
13
|
+
color: var(--lv-white);
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Card Header with Gradient
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
.card-header {
|
|
21
|
+
background: linear-gradient(135deg, var(--lv-surface), var(--lv-surface-light));
|
|
22
|
+
border-bottom: 1px solid var(--lv-green-dim);
|
|
23
|
+
color: var(--lv-white);
|
|
24
|
+
padding: 12px 16px;
|
|
25
|
+
height: 56px;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Metric Card
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
.metric-card {
|
|
33
|
+
background-color: var(--lv-surface);
|
|
34
|
+
border: 1px solid #2A2A2A;
|
|
35
|
+
color: var(--lv-white);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.metric-label {
|
|
39
|
+
color: #A0AEC0;
|
|
40
|
+
font-size: 0.875rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.metric-value {
|
|
44
|
+
color: var(--lv-white);
|
|
45
|
+
font-weight: 600;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Button Patterns
|
|
50
|
+
|
|
51
|
+
### Active/Selected Button
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
.btn-active {
|
|
55
|
+
background-color: var(--lv-green);
|
|
56
|
+
color: var(--lv-black);
|
|
57
|
+
border-color: var(--lv-green);
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
box-shadow: 0 0 12px rgba(63, 234, 0, 0.3);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Inactive Button
|
|
64
|
+
|
|
65
|
+
```css
|
|
66
|
+
.btn-inactive {
|
|
67
|
+
background-color: transparent;
|
|
68
|
+
color: rgba(255, 255, 255, 0.9);
|
|
69
|
+
border: 1px solid #2A2A2A;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.btn-inactive:hover {
|
|
73
|
+
background-color: rgba(255, 255, 255, 0.1);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Button Group Sizing
|
|
78
|
+
|
|
79
|
+
```css
|
|
80
|
+
.btn-group .btn {
|
|
81
|
+
transition: all 0.2s ease;
|
|
82
|
+
border-radius: 4px;
|
|
83
|
+
padding: 0 16px;
|
|
84
|
+
min-height: 36px;
|
|
85
|
+
letter-spacing: normal;
|
|
86
|
+
text-transform: none;
|
|
87
|
+
font-weight: 500;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Data Table Patterns
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
.data-table {
|
|
95
|
+
background-color: var(--lv-surface);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.data-table th {
|
|
99
|
+
background-color: #111111;
|
|
100
|
+
color: var(--lv-white);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.data-table td {
|
|
104
|
+
color: var(--lv-white);
|
|
105
|
+
border-bottom: 1px solid #2A2A2A;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## List Patterns
|
|
110
|
+
|
|
111
|
+
### Interactive List
|
|
112
|
+
|
|
113
|
+
```css
|
|
114
|
+
.list {
|
|
115
|
+
background-color: transparent;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.list-item {
|
|
119
|
+
color: var(--lv-white);
|
|
120
|
+
background-color: transparent;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.list-item:hover {
|
|
124
|
+
background-color: var(--lv-surface-light);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### List Item States
|
|
129
|
+
|
|
130
|
+
```css
|
|
131
|
+
.list-item-title {
|
|
132
|
+
color: var(--lv-white);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.list-item-subtitle {
|
|
136
|
+
color: #A0AEC0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.list-item-disabled .list-item-title {
|
|
140
|
+
color: #A0AEC0;
|
|
141
|
+
opacity: 0.6;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Text Utility Classes
|
|
146
|
+
|
|
147
|
+
```css
|
|
148
|
+
.text-primary {
|
|
149
|
+
color: var(--lv-white);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.text-secondary {
|
|
153
|
+
color: #A0AEC0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.text-muted {
|
|
157
|
+
color: var(--lv-silver);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Background Colors
|
|
162
|
+
|
|
163
|
+
```css
|
|
164
|
+
.bg-surface {
|
|
165
|
+
background-color: var(--lv-surface);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.bg-card {
|
|
169
|
+
background-color: var(--lv-surface-light);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.bg-panel {
|
|
173
|
+
background-color: #111111;
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Input Styling
|
|
178
|
+
|
|
179
|
+
```css
|
|
180
|
+
.input:focus {
|
|
181
|
+
background-color: rgba(255, 255, 255, 0.08);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.input {
|
|
185
|
+
color: white;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Visual Effects
|
|
190
|
+
|
|
191
|
+
### Glow Effects
|
|
192
|
+
|
|
193
|
+
```css
|
|
194
|
+
.glow-green {
|
|
195
|
+
box-shadow: 0 0 12px rgba(63, 234, 0, 0.3);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.glow-orange {
|
|
199
|
+
box-shadow: 0 0 12px rgba(255, 92, 0, 0.3);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.glow-blue {
|
|
203
|
+
box-shadow: 0 0 12px rgba(0, 59, 255, 0.3);
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Text Glow
|
|
208
|
+
|
|
209
|
+
```css
|
|
210
|
+
.text-glow {
|
|
211
|
+
text-shadow: 0 0 8px rgba(63, 234, 0, 0.5);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Border Accent
|
|
216
|
+
|
|
217
|
+
```css
|
|
218
|
+
.border-accent {
|
|
219
|
+
border-color: var(--lv-green-dim);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## CSS Variable Naming Conventions
|
|
224
|
+
|
|
225
|
+
| Prefix | Purpose | Example |
|
|
226
|
+
|--------|---------|---------|
|
|
227
|
+
| `--lv-*` | Brand colors (static) | `--lv-green`, `--lv-surface` |
|
|
228
|
+
| `--theme-*` | Theme-aware aliases | `--theme-primary`, `--theme-text` |
|
|
229
|
+
| `--dynamic-*` | JS-set runtime values | `--dynamic-primary`, `--dynamic-surface` |
|
|
230
|
+
| `--font-*` | Typography | `--font-primary`, `--font-mono` |
|
|
231
|
+
|
|
232
|
+
## Framework Adaptation Notes
|
|
233
|
+
|
|
234
|
+
### React
|
|
235
|
+
|
|
236
|
+
Use CSS modules or styled-components. Import the CSS variables in your global styles.
|
|
237
|
+
|
|
238
|
+
### Vue
|
|
239
|
+
|
|
240
|
+
Use scoped styles with `<style scoped>`. The variables work naturally with Vue's reactivity.
|
|
241
|
+
|
|
242
|
+
### Tailwind
|
|
243
|
+
|
|
244
|
+
Extend your `tailwind.config.js` with the brand colors:
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
module.exports = {
|
|
248
|
+
theme: {
|
|
249
|
+
extend: {
|
|
250
|
+
colors: {
|
|
251
|
+
'lv-black': '#0A0A0A',
|
|
252
|
+
'lv-green': '#3FEA00',
|
|
253
|
+
'lv-surface': '#141414',
|
|
254
|
+
// ...
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Plain CSS
|
|
262
|
+
|
|
263
|
+
Include the CSS variables in your `:root` and use them directly.
|