aria-grid-demo: live examples of @jambotron/aria-grid with Jambotron light/dark and Synthwave themes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-06 03:10:36 +01:00
co-authored by Claude Opus 5.5
commit 9d2c1e0b4c
32 changed files with 7519 additions and 0 deletions
+417
View File
@@ -0,0 +1,417 @@
// Three themes on one attribute: <html data-theme="jambotron-light | jambotron-dark | synthwave">.
// The grid is painted only by --jt-* variables (its defaults sit on :where(:root), so any value below wins);
// Material (checkboxes, buttons, dialog, snack bar of the grid) takes its colors from the same variables.
@use '@angular/material' as mat;
@use '@jambotron/aria-grid/styles/aria-grid';
// ---------------------------------------------------------------------------------------------------------------------
// Jambotron light — the tokens of jambotron.com (_tokens.scss), the part the grid and this page use
[data-theme='jambotron-light'] {
color-scheme: light;
--app-bg: radial-gradient(1200px 600px at 10% -10%, #d7f6fb 0%, transparent 60%),
radial-gradient(900px 500px at 110% 10%, #fde9c4 0%, transparent 55%), #eef2f7;
--app-panel: #e7edf3c2;
--app-panel-border: rgba(10, 16, 48, 0.12);
--app-surface: #f3f6fa;
--app-code-bg: rgba(10, 16, 48, 0.05);
--app-font: Roboto, 'Helvetica Neue', sans-serif;
--app-font-display: Orbitron, Roboto, sans-serif;
--app-title: #0b6e80;
--jt-accent: #14c8e6;
--jt-accent-text: #074b5a;
--jt-on-accent: #050a24;
--jt-on-accent-text: #ffffff;
--jt-danger: #ef4444;
--jt-danger-text: #8a1414;
--jt-success: #22c55e;
--jt-success-text: #0c4f26;
--jt-warning: #ff9a2e;
--jt-warning-text: #6b3a00;
--jt-text: #141a33;
--jt-text-muted: #39425f;
--jt-text-disabled: rgba(20, 26, 51, 0.45);
--jt-divider: rgba(10, 16, 48, 0.12);
--jt-field-bg: rgba(255, 255, 255, 0.55);
--jt-field-border: rgba(10, 16, 48, 0.28);
--jt-focus-ring: 0 0 0 3px rgba(20, 200, 230, 0.45);
--jt-glow-accent: 0 0 10px rgba(20, 200, 230, 0.35);
--jt-popup-bg: #eef2f7e6;
--jt-popup-border: rgba(10, 16, 48, 0.12);
--jt-shadow-lg: 0 16px 48px rgba(10, 16, 48, 0.2);
}
// Jambotron dark — night sky, neon cyan
[data-theme='jambotron-dark'] {
color-scheme: dark;
--app-bg: radial-gradient(1200px 700px at 15% -10%, #1c2a6b 0%, transparent 60%),
radial-gradient(900px 600px at 110% 0%, #3b1d5e 0%, transparent 55%), #050a24;
--app-panel: rgba(10, 16, 44, 0.72);
--app-panel-border: rgba(62, 230, 255, 0.22);
--app-surface: #0c1234;
--app-code-bg: rgba(5, 10, 36, 0.6);
--app-font: Roboto, 'Helvetica Neue', sans-serif;
--app-font-display: Orbitron, Roboto, sans-serif;
--app-title: #7ff0ff;
--jt-accent: #3ee6ff;
--jt-accent-text: #7ff0ff;
--jt-on-accent: #050a24;
--jt-on-accent-text: #050a24;
--jt-danger: #f87171;
--jt-danger-text: #fecaca;
--jt-success: #34d399;
--jt-success-text: #86efac;
--jt-warning: #ff9a2e;
--jt-warning-text: #ffd98a;
--jt-text: #eef2ff;
--jt-text-muted: #ccd4ec;
--jt-text-disabled: rgba(238, 242, 255, 0.45);
--jt-divider: rgba(195, 204, 230, 0.16);
--jt-field-bg: rgba(5, 10, 36, 0.55);
--jt-field-border: rgba(195, 204, 230, 0.3);
--jt-focus-ring: 0 0 0 3px rgba(62, 230, 255, 0.5);
--jt-glow-accent: 0 0 14px rgba(62, 230, 255, 0.55);
--jt-popup-bg: rgba(8, 12, 36, 0.95);
--jt-popup-border: rgba(62, 230, 255, 0.22);
--jt-shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.55);
}
// Synthwave — the colors of reactive-mail-server's web mail (frontend/src/material.scss there)
[data-theme='synthwave'] {
color-scheme: dark;
--app-bg: linear-gradient(180deg, transparent 55%, rgba(255, 0, 127, 0.18) 100%),
repeating-linear-gradient(90deg, rgba(255, 0, 127, 0.12) 0 1px, transparent 1px 64px),
repeating-linear-gradient(0deg, rgba(0, 240, 255, 0.08) 0 1px, transparent 1px 64px), #0d0221;
--app-panel: rgba(15, 12, 35, 0.78);
--app-panel-border: rgba(255, 0, 127, 0.4);
--app-surface: #140a2e;
--app-code-bg: rgba(2, 6, 23, 0.7);
--app-font: Rajdhani, sans-serif;
--app-font-display: Orbitron, sans-serif;
--app-title: #ff007f;
--jt-accent: #00f0ff;
--jt-accent-text: #00f0ff;
--jt-on-accent: #0d0221;
--jt-on-accent-text: #0d0221;
--jt-danger: #ff4d6d;
--jt-danger-text: #ff8fa3;
--jt-success: #00ff88;
--jt-success-text: #7dffbf;
--jt-warning: #ffbe0b;
--jt-warning-text: #ffd76a;
--jt-text: #e2e8f0;
--jt-text-muted: #94a3b8;
--jt-text-disabled: rgba(226, 232, 240, 0.4);
--jt-divider: rgba(0, 240, 255, 0.14);
--jt-field-bg: rgba(2, 6, 23, 0.6);
--jt-field-border: rgba(0, 240, 255, 0.35);
--jt-focus-ring: 0 0 0 3px #ffbe0b;
--jt-glow-accent: 0 0 12px rgba(0, 240, 255, 0.6);
--jt-popup-bg: rgba(10, 5, 24, 0.97);
--jt-popup-border: rgba(255, 0, 127, 0.45);
--jt-shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.6), 0 0 20px rgba(255, 0, 127, 0.25);
--jt-radius-sm: 8px;
--jt-radius-md: 12px;
.jt-table {
font-size: 0.95rem;
th {
font-family: Orbitron, sans-serif;
font-size: 0.68rem;
letter-spacing: 0.08em;
color: #00f0ff;
}
}
}
// ---------------------------------------------------------------------------------------------------------------------
// Material: light or dark by color-scheme (set by the theme above), roles mapped to the --jt-* variables
html {
@include mat.theme(
(
color: (primary: mat.$cyan-palette, tertiary: mat.$violet-palette, theme-type: color-scheme),
typography: (plain-family: var(--app-font), brand-family: var(--app-font-display)),
density: 0,
),
(
primary: var(--jt-accent-text),
on-primary: var(--jt-on-accent-text),
error: var(--jt-danger-text),
on-error: var(--jt-on-accent-text),
background: var(--app-surface),
on-background: var(--jt-text),
surface: var(--app-surface),
on-surface: var(--jt-text),
on-surface-variant: var(--jt-text-muted),
surface-container: var(--app-surface),
surface-container-high: var(--app-surface),
surface-container-highest: var(--app-surface),
outline: var(--jt-field-border),
outline-variant: var(--jt-divider),
inverse-surface: var(--jt-text),
inverse-on-surface: var(--app-surface),
)
);
@include mat.checkbox-overrides((
selected-icon-color: var(--jt-accent),
selected-hover-icon-color: var(--jt-accent),
selected-focus-icon-color: var(--jt-accent),
selected-checkmark-color: var(--jt-on-accent),
));
}
// ---------------------------------------------------------------------------------------------------------------------
// Page
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
min-height: 100%;
}
body {
background: var(--app-bg);
background-attachment: fixed;
color: var(--jt-text);
font-family: var(--app-font);
line-height: 1.5;
transition: background var(--jt-duration-base) var(--jt-easing), color var(--jt-duration-base) var(--jt-easing);
}
a {
color: var(--jt-accent-text);
}
code {
font-family: 'JetBrains Mono', Consolas, monospace;
font-size: 0.85em;
}
.top {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 16px;
max-width: 1180px;
margin: 0 auto;
padding: 28px 16px 8px;
}
.brand {
display: flex;
align-items: center;
gap: 14px;
h1 {
margin: 0;
font-family: var(--app-font-display);
font-size: clamp(1.2rem, 3vw, 1.7rem);
color: var(--app-title);
text-shadow: var(--jt-glow-accent);
}
p {
margin: 2px 0 0;
color: var(--jt-text-muted);
}
}
.brand-mark {
display: grid;
place-items: center;
width: 44px;
height: 44px;
border-radius: var(--jt-radius-md);
background: var(--jt-accent);
color: var(--jt-on-accent);
font-size: 1.6rem;
box-shadow: var(--jt-glow-accent);
}
.switches {
display: flex;
flex-wrap: wrap;
gap: 12px;
jt-select {
min-width: 220px;
}
}
main {
display: grid;
gap: 24px;
max-width: 1180px;
margin: 0 auto;
padding: 16px;
}
.panel {
min-width: 0;
padding: 20px;
border: 1px solid var(--app-panel-border);
border-radius: var(--jt-radius-md);
background: var(--app-panel);
backdrop-filter: blur(8px);
h2 {
display: flex;
align-items: center;
gap: 10px;
margin: 0 0 6px;
font-family: var(--app-font-display);
font-size: 1.05rem;
letter-spacing: 0.02em;
span {
display: grid;
place-items: center;
width: 26px;
height: 26px;
border-radius: 50%;
background: var(--jt-accent);
color: var(--jt-on-accent);
font-size: 0.8rem;
}
}
}
.lead {
margin: 0 0 16px;
color: var(--jt-text-muted);
max-width: 85ch;
}
.filter {
display: inline-flex;
flex-direction: column;
gap: 4px;
margin-bottom: 12px;
font-size: 0.8rem;
color: var(--jt-text-muted);
input {
width: min(320px, 80vw);
padding: 8px 12px;
border: 1px solid var(--jt-field-border);
border-radius: var(--jt-radius-sm);
background: var(--jt-field-bg);
color: var(--jt-text);
font: inherit;
font-size: 0.95rem;
&:focus-visible {
outline: none;
box-shadow: var(--jt-focus-ring);
}
}
}
.chip {
display: inline-block;
margin-right: 4px;
padding: 1px 8px;
border-radius: var(--jt-radius-pill);
font-size: 0.75rem;
font-weight: 500;
border: 1px solid currentColor;
}
.chip--running {
color: var(--jt-success-text);
}
.chip--stopped {
color: var(--jt-text-muted);
}
.chip--error {
color: var(--jt-danger-text);
}
.chip--locked {
color: var(--jt-warning-text);
}
// CPU load bar
.meter {
display: inline-flex;
align-items: center;
justify-content: flex-end;
width: 90px;
height: 18px;
padding: 0 6px;
border-radius: var(--jt-radius-sm);
background: linear-gradient(90deg, color-mix(in srgb, var(--jt-accent) 35%, transparent) calc(var(--value) * 1%), var(--jt-divider) 0);
font-variant-numeric: tabular-nums;
font-size: 0.8rem;
}
.log {
min-height: 1.5em;
margin: 12px 0 4px;
color: var(--jt-text-muted);
font-size: 0.9rem;
}
.details {
margin-top: 12px;
padding: 10px 14px;
border-left: 3px solid var(--jt-accent);
border-radius: var(--jt-radius-sm);
background: color-mix(in srgb, var(--jt-accent) 10%, transparent);
}
.link {
margin-left: 8px;
padding: 0;
border: 0;
background: none;
color: var(--jt-accent-text);
font: inherit;
text-decoration: underline;
cursor: pointer;
}
.code {
margin-top: 12px;
summary {
cursor: pointer;
color: var(--jt-accent-text);
font-weight: 500;
}
pre {
overflow-x: auto;
margin: 8px 0 0;
padding: 14px;
border: 1px solid var(--jt-divider);
border-radius: var(--jt-radius-sm);
background: var(--app-code-bg);
font-size: 0.82rem;
line-height: 1.45;
}
}
// The grid's own empty state uses this class
.jt-muted {
color: var(--jt-text-muted);
}
.foot {
max-width: 1180px;
margin: 0 auto;
padding: 8px 16px 32px;
color: var(--jt-text-muted);
font-size: 0.85rem;
}