Session picker: phase strips, status dots, live polling

- SessionRow (extracted, exported for tests): leftmost phase strip
  (bookmark tick, per-phase color: probe/plan/teach) + status dot left of
  the title — pulsing amber attention dot when an answer is owed, quiet
  breathing dot while the teacher works, nothing when it's the learner's
  turn. A pending answer outranks 'working'.
- globals.css: phase + attention color tokens (one system shared with the
  upcoming header chip and dividers) and the two dot animations, both
  disabled under prefers-reduced-motion.
- SessionsSidebar polls /api/chats every 2.5s while open (payload is tiny
  now that busy/phase/pendingQuestion come from the list) and pauses while
  the tab is hidden; fetch-on-navigation preserved.
This commit is contained in:
Amos
2026-09-01 18:28:35 +03:00
parent 1c3d288d08
commit 05359301e2
3 changed files with 263 additions and 30 deletions
+73
View File
@@ -157,3 +157,76 @@ body {
overflow-x: auto;
overflow-y: hidden;
}
/* ============================================================
* Session status — phase colors + status dots
* (picker strips, header chip, transcript dividers: one language)
* ============================================================ */
/* Phase colors: blue = probing, violet = planning, green = teaching.
Tuned per theme (light needs darker, dark lighter). The attention color
(an answer the learner owes) is deliberately outside the phase system —
dots and strips are separate channels and must not read as one. */
:root {
--phase-probe: oklch(0.55 0.17 253);
--phase-plan: oklch(0.54 0.19 300);
--phase-teach: oklch(0.55 0.14 160);
--attention: oklch(0.62 0.15 65);
}
.dark {
--phase-probe: oklch(0.72 0.13 250);
--phase-plan: oklch(0.72 0.14 300);
--phase-teach: oklch(0.74 0.12 160);
--attention: oklch(0.8 0.15 75);
}
@theme inline {
--color-phase-probe: var(--phase-probe);
--color-phase-plan: var(--phase-plan);
--color-phase-teach: var(--phase-teach);
--color-attention: var(--attention);
}
/* Status dots (session picker). Attention — a slow expanding ring, drawing
the eye to "your move". Working — a quiet breathing dot, opacity only,
never loud enough to compete with the attention ring. */
@keyframes lh-dot-attention {
0% {
box-shadow: 0 0 0 0 color-mix(in oklab, var(--attention) 60%, transparent);
}
70%,
100% {
box-shadow: 0 0 0 5px transparent;
}
}
.lh-dot-attention {
animation: lh-dot-attention 1.6s ease-out infinite;
}
@keyframes lh-dot-breathe {
0%,
100% {
opacity: 0.35;
transform: scale(0.75);
}
50% {
opacity: 1;
transform: scale(1);
}
}
.lh-dot-breathe {
animation: lh-dot-breathe 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
.lh-dot-attention,
.lh-dot-breathe {
animation: none;
}
}