AI Implementation feature(880): Authenticated Shell, Quick Tabs and Change Password 1.04 (#19)

This commit was merged in pull request #19.
This commit is contained in:
2026-07-22 09:37:10 +00:00
parent d134a56abe
commit 90e570c43c
12 changed files with 248 additions and 242 deletions
+17 -8
View File
@@ -3,7 +3,7 @@ type: guide
title: Authenticated Shell
description: How a signed-in user experiences the post-login shell, including authenticated event streaming.
tags: [guide, shell, header, sse, navigation, tester]
timestamp: 2026-07-22T09:22:34Z
timestamp: 2026-07-22T09:35:00Z
---
# When this view is available
@@ -35,20 +35,29 @@ before the shell mounts.
# Event LED colors
The LED is rendered by `ShellHeaderComponent` as a `<span class="led">` with one of four state classes attached via `[class.led-<state>]`. Its component-scoped styling is declared in `frontend/src/app/features/shell/header/shell-header.component.ts` and is driven entirely by the existing theme color tokens — there is no per-state color in TypeScript.
The LED is rendered by `ShellHeaderComponent` as a `<span class="led">` with one of four state classes attached via `[class.led-<state>]` and a `[style.background-color]` bound directly from a pure TypeScript helper.
| Event state | CSS class | Color token | Approx. hex | Visual |
|-------------------|-----------------------|-----------------------|-------------|--------|
| `countdown` | `led led-countdown` | `--color-warning` | `#f59e0b` | Yellow filled dot |
| `running` | `led led-running` | `--color-success` | `#10b981` | Green filled dot |
| `stopped` | `led led-stopped` | `--color-danger` | `#ef4444` | Red filled dot |
| `unconfigured` | `led led-unconfigured`| `--color-secondary` | `#64748b` | Neutral gray filled dot |
| Event state | CSS class | Color token (`[style.background-color]` value) | Approx. hex | Visual |
|-------------------|-----------------------|------------------------------------------------|-------------|--------|
| `countdown` | `led led-countdown` | `var(--color-warning)` | `#f59e0b` | Yellow filled dot |
| `running` | `led led-running` | `var(--color-success)` | `#10b981` | Green filled dot |
| `stopped` | `led led-stopped` | `var(--color-danger)` | `#ef4444` | Red filled dot |
| `unconfigured` | `led led-unconfigured`| `var(--color-secondary)` | `#64748b` | Neutral gray filled dot |
The mapping is defined in [`frontend/src/app/core/services/event-status.pure.ts`](/architecture/frontend-structure.md#event-status-pure-helpers) as the constant `LED_COLOR_BY_STATE` and exposed through the helper `ledBackgroundColor(state)`. `ShellHeaderComponent` exposes it on the DOM via a `computed` signal called `ledColor()`, so the active theme token resolves at runtime and the LED is never painted with `transparent`.
The base `.led` rule paints a 10×10 circular `inline-block`, so the LED
is always the same size and shape — only the background color changes
between states. The element also carries
`aria-label="Event status: <state>"` for assistive tech.
# What the tester should see
* The 10×10 LED is visible (not transparent, not invisible) in every state.
* The LED color matches the table above for the active `EventState`.
* Switching the event window (countdown → running → stopped → unconfigured) flips the dot color in real time.
* The `aria-label` updates to `Event status: <state>` and never relies on color alone.
## Quick tabs
The tab strip `[data-testid="quick-tabs"]` contains `Challenges`, `Scoreboard`, and
+86
View File
@@ -0,0 +1,86 @@
---
type: guide
title: Event LED Color Mapping
description: Single source of truth mapping each event window state to the themed background color painted on the authenticated shell's status LED.
tags: [guide, shell, led, theming, event-window, tester]
timestamp: 2026-07-22T09:35:00Z
---
# Purpose
The 10×10 status dot in the authenticated shell LED
(`[data-testid="shell-led"]` in
[`ShellHeaderComponent`](/architecture/frontend-structure.md)) reflects the
current event window state. Its background color is driven by a single pure
helper so the dot is **never transparent** and the active theme token always
resolves at runtime.
# Mapping
Defined in
`frontend/src/app/core/services/event-status.pure.ts` and re-exported via
`frontend/src/app/core/services/event-status.store.ts`:
| `EventState` | `ledBackgroundColor(state)` | Theme CSS variable |
|--------------|------------------------------|------------------------|
| `countdown` | `var(--color-warning)` | `--color-warning` |
| `running` | `var(--color-success)` | `--color-success` |
| `stopped` | `var(--color-danger)` | `--color-danger` |
| `unconfigured` | `var(--color-secondary)` | `--color-secondary` |
Backing constant: `LED_COLOR_BY_STATE: Readonly<Record<EventState, string>>`.
The accessor function `ledBackgroundColor(state)` returns the same string for
each state.
# How it reaches the DOM
1. `HomeComponent` forwards the `state` signal from
[`EventStatusStore`](/architecture/frontend-structure.md) to
`ShellHeaderComponent` via its `eventState` input.
2. `ShellHeaderComponent.ledColor` is a `computed` signal defined as
`computed(() => ledBackgroundColor(this.eventState()))`.
3. The template binds it directly:
`[style.background-color]="ledColor()"`.
4. The LED's base `.led` rule is shape-only (`inline-block`, 10×10, circular,
`vertical-align: middle`); no `transparent` fallback is applied, so the
author background color is always visible.
5. The legacy `.led-running`, `.led-countdown`, `.led-stopped`,
`.led-unconfigured` CSS selectors remain on the element and continue to be
useful hooks for selectors and tests, but they no longer declare the color.
# Examples
## Programmatic lookup
```ts
import { ledBackgroundColor, LED_COLOR_BY_STATE } from
'./frontend/src/app/core/services/event-status.pure';
ledBackgroundColor('running'); // 'var(--color-success)'
ledBackgroundColor('stopped'); // 'var(--color-danger)'
LED_COLOR_BY_STATE.unconfigured; // 'var(--color-secondary)'
```
## Verifying in the DOM
```ts
const dot = document.querySelector('[data-testid="shell-led"]') as HTMLElement;
dot.style.backgroundColor; // resolves to the current theme token, never empty
dot.getAttribute('aria-label'); // 'Event status: running'
```
# Tester checklist
* The LED is **visible** in every state (no transparent or missing dot).
* The LED color matches the mapping table when the event window is forced
into each state via the [event window settings](/guides/event-window.md).
* Switching states live updates both the dot color and the
`aria-label="Event status: <state>"` attribute.
* The four `led-<state>` classes are still applied to the element.
# See also
- [Authenticated Shell](/guides/authenticated-shell.md)
- [Event Window](/guides/event-window.md)
- [Frontend Structure](/architecture/frontend-structure.md)
- [Theming](/guides/theming.md)