Per Phase A finding A2 — `_timetable.scss` was functionally pure CSS: only :root custom properties + @keyframes + one .tt-cascade-pulse class. The only SCSS-specific syntax was `// line comments`. Zero $vars, @use, @mixin, @function, nesting, or color functions. Why move to .css: Vitest+jsdom can `import '@/styles/tokens/_timetable.css'` directly so getComputedStyle() resolves var(--tt-…) in component tests (needed for the upcoming PerformanceBlock visual-state assertions). SCSS imports require Vite's SCSS plugin, which the vitest.config.ts intentionally skips for unit-test speed. Changes: - `_timetable.scss` → `_timetable.css` (line comments converted to /* */ block comments; everything else byte-identical) - `assets/styles/styles.scss`: switch from `@use "@/styles/tokens/timetable"` to `@import "@/styles/tokens/_timetable.css"` - Production `npm run build` passes (16s, no asset warnings) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
146 lines
4.8 KiB
CSS
146 lines
4.8 KiB
CSS
/* RFC-TIMETABLE v0.2 D21 — status colour tokens for the timetable canvas.
|
|
*
|
|
* Per-status colour pairs (background + border + foreground + dot) live as
|
|
* CSS custom properties so PerformanceBlock + WachtrijCard + popovers all
|
|
* resolve through `var(--tt-status-{status}-*)`.
|
|
*
|
|
* ART-14 (deferred) will let an organisation override the palette by
|
|
* scoping these custom properties on a `[data-org-id="…"]` selector.
|
|
*
|
|
* Geometry tokens (lane height, time-axis spacing, block padding) live
|
|
* next to the colours so any rendering tweak is one stop.
|
|
*
|
|
* NOTE: this file is plain CSS (not SCSS) so that vitest+jsdom can load
|
|
* it via `import '@/styles/tokens/_timetable.css'` from mountWithVuexy
|
|
* — getComputedStyle() then resolves var(--tt-…) in component tests.
|
|
*/
|
|
|
|
:root {
|
|
/* ─── Status palettes (8 visible + cancelled overlay) ───────────── */
|
|
|
|
--tt-status-draft-bg: #f1efe9;
|
|
--tt-status-draft-border: #dcd9d1;
|
|
--tt-status-draft-fg: #3a3830;
|
|
--tt-status-draft-dot: #a09c92;
|
|
|
|
--tt-status-requested-bg: #fff6e0;
|
|
--tt-status-requested-border:#f0d99a;
|
|
--tt-status-requested-fg: #5d4612;
|
|
--tt-status-requested-dot: #d9a93c;
|
|
|
|
--tt-status-option-bg: #f3eefa;
|
|
--tt-status-option-border: #d8c8ee;
|
|
--tt-status-option-fg: #4b2d75;
|
|
--tt-status-option-dot: #8b5cd0;
|
|
|
|
--tt-status-offered-bg: #fef5e7;
|
|
--tt-status-offered-border: #f4d6a3;
|
|
--tt-status-offered-fg: #6d4406;
|
|
--tt-status-offered-dot: #e0992c;
|
|
|
|
--tt-status-confirmed-bg: #e8f8f0;
|
|
--tt-status-confirmed-border:#a8dec5;
|
|
--tt-status-confirmed-fg: #1a5b3b;
|
|
--tt-status-confirmed-dot: #2fa66a;
|
|
|
|
--tt-status-contracted-bg: #e6f1fb;
|
|
--tt-status-contracted-border:#a4c8eb;
|
|
--tt-status-contracted-fg: #134474;
|
|
--tt-status-contracted-dot: #2a78c8;
|
|
|
|
--tt-status-cancelled-bg: #f5f3ef;
|
|
--tt-status-cancelled-border:#cfcdc7;
|
|
--tt-status-cancelled-fg: #75706a;
|
|
--tt-status-cancelled-dot: #999591;
|
|
|
|
--tt-status-rejected-bg: #fbeaec;
|
|
--tt-status-rejected-border: #ecb6bd;
|
|
--tt-status-rejected-fg: #75162a;
|
|
--tt-status-rejected-dot: #c5354b;
|
|
|
|
--tt-status-declined-bg: #f7eee9;
|
|
--tt-status-declined-border: #ddc6b9;
|
|
--tt-status-declined-fg: #6b3915;
|
|
--tt-status-declined-dot: #b56331;
|
|
|
|
/* ─── Cancelled hatch overlay ───────────────────────────────────── */
|
|
|
|
--tt-cancelled-hatch: repeating-linear-gradient(
|
|
135deg,
|
|
transparent 0,
|
|
transparent 6px,
|
|
rgba(0, 0, 0, 0.05) 6px,
|
|
rgba(0, 0, 0, 0.05) 8px
|
|
);
|
|
|
|
/* ─── Warnings + B2B ────────────────────────────────────────────── */
|
|
|
|
--tt-conflict-border: #d63d4b;
|
|
--tt-conflict-glow: rgba(214, 61, 75, 0.25);
|
|
|
|
--tt-capacity-warn: #e0992c;
|
|
--tt-capacity-critical: #c5354b;
|
|
|
|
--tt-b2b-dot: #2a78c8;
|
|
--tt-b2b-dot-size: 6px;
|
|
|
|
--tt-trashed-overlay: rgba(0, 0, 0, 0.35);
|
|
--tt-trashed-icon: #75706a;
|
|
|
|
/* ─── Geometry ──────────────────────────────────────────────────── */
|
|
|
|
--tt-lane-height: 44px;
|
|
--tt-lane-gap: 4px;
|
|
--tt-lane-pad: 4px;
|
|
|
|
--tt-block-radius: 6px;
|
|
--tt-block-pad-x: 8px;
|
|
--tt-block-pad-y: 4px;
|
|
--tt-block-min-width: 24px;
|
|
|
|
--tt-row-divider: #e6e3dc;
|
|
--tt-axis-tick: #cfcdc7;
|
|
--tt-axis-tick-major: #a09c92;
|
|
--tt-axis-label-fg: #4b4b48;
|
|
|
|
--tt-canvas-bg: #fbfaf7;
|
|
--tt-canvas-grid-major: rgba(0, 0, 0, 0.06);
|
|
--tt-canvas-grid-minor: rgba(0, 0, 0, 0.025);
|
|
|
|
/* ─── Drop / drag visuals ───────────────────────────────────────── */
|
|
|
|
--tt-ghost-bg: rgba(255, 215, 90, 0.18);
|
|
--tt-ghost-border:#f0c45a;
|
|
|
|
--tt-focus-ring: #1f7ad1;
|
|
|
|
/* ─── Day-tab chrome ────────────────────────────────────────────── */
|
|
|
|
--tt-tab-active-bg: #1f7ad1;
|
|
--tt-tab-active-fg: #ffffff;
|
|
--tt-tab-hover-bg: #eef2f7;
|
|
}
|
|
|
|
/* ─── Animations ─────────────────────────────────────────────────────── */
|
|
|
|
@keyframes tt-cascade-pulse {
|
|
0% {
|
|
box-shadow: 0 0 0 0 rgba(31, 122, 209, 0.55);
|
|
transform: scale(1);
|
|
}
|
|
|
|
60% {
|
|
box-shadow: 0 0 0 7px rgba(31, 122, 209, 0);
|
|
transform: scale(1.015);
|
|
}
|
|
|
|
100% {
|
|
box-shadow: 0 0 0 0 rgba(31, 122, 209, 0);
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
.tt-cascade-pulse {
|
|
animation: tt-cascade-pulse 1.5s ease-out 1;
|
|
}
|