Move the console onto ReUI PRO

Install ReUI (MCP, skill, @reui registry, Tailwind v4, shadcn base-nova) and move
the shared UI onto it: Button, Tag, Check, Input/Textarea, Segmented, Alert, Panel,
Dialog, Tooltip, Menu and Select (Popover), Toast (sonner), the Table frame
(DataGrid), the Dashboard KPI strip, the shnt Ops palette, Geist and the type scale.

Design only: behaviour, texts and roles are unchanged. Tests that asserted the old
DOM were updated; the tests now format numbers in English wherever they run.
docs/reui-migration-plan.md records the plan and its decisions.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
DenozordecandClaude Sonnet 5.5 committed 2026-10-27 00:06:06 +07:00
commit f3531c64f9
680 files changed
+139836

No files matched your search

+135
View File
@@ -0,0 +1,135 @@
/*
The Lists tab. Every value is a token of theme/tokens.css.
*/
/* The save bar of Settings, sticky at the bottom: same piece, same place. */
.bar { composes: bar from '../../ui/PanelForm.module.css'; }
.spacer { flex: 1; }
/* The figures are the shared ones (`.kpi*`, Blocking.module.css). A count the server is
still reloading: dimmed, and its sub-line says why, at the sub-line's size so the
card does not change height. */
.stale { opacity: var(--dim); }
.pending { color: var(--mute); font-size: var(--t-2); }
/*
"Add a list" on a grid. The first column is the URL's: its field, its error, its
hint and, on a line of its own, Quick Add, as wide as the URL. The two Add buttons
sit beside the URL field, bottom-aligned with it, and their column stays empty
below. Rows are separated by each item's own margin, not by `row-gap`, so the
error and the hint keep hugging their field.
*/
.add {
display: grid;
grid-template-columns: minmax(0, 1fr) auto auto;
align-items: end;
column-gap: var(--s-5);
}
.add > .invalid,
.add > .help,
.add > .quick { grid-column: 1; }
.quick { margin-top: var(--s-10); }
/*
`--bp-stack`: one column. The URL keeps its error and hint right under it, the two
buttons share the next line in halves, and Quick Add closes. Rows are explicit
because the DOM order puts the buttons before the hint; the error's row collapses
to nothing while there is no error.
*/
@media (max-width: 560px) {
.add { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.add > :first-child { grid-column: 1 / -1; grid-row: 1; }
.add > .invalid { grid-column: 1 / -1; grid-row: 2; }
.add > .help { grid-column: 1 / -1; grid-row: 3; }
.add > :nth-child(2),
.add > :nth-child(3) { grid-row: 4; margin-top: var(--s-8); }
/* A locked button comes inside the tooltip's wrapper: the wrapper takes the half. */
.add > :nth-child(2) > button,
.add > :nth-child(3) > button { width: 100%; }
.add > .quick { grid-column: 1 / -1; grid-row: 5; }
}
/* The validation sentence under its field, with the field's border in `--dan`
(the design rule: the error goes next to its field, once). */
.bad[aria-invalid],
.bad[aria-invalid]:focus { border-color: var(--dan); }
.invalid { color: var(--dan); font-size: var(--t-2); margin-top: var(--s-4); }
.help { color: var(--faint); font-size: var(--t-2); margin-top: var(--s-5); }
/*
The row switch: `ui/Check`'s switch drawn on a bare checkbox. `Check` always paints
its label, and here the label would repeat the URL the next cell already shows; the
row's name goes in `aria-label` instead, as the table checkboxes of Zones do.
It takes BOTH classes `Check` gives its own DOM: `check` on the label (the 26 px
target and the input's alignment) and `toggle` for the switch drawing.
*/
.switch { composes: check toggle from '../../ui/Check.module.css'; }
.name { font-weight: 600; }
/* The URL wraps after its separators (`ui/UrlText`), not at whatever letter meets the
edge: `anywhere` drew `raw.githubuser` / `content.com` at 390 px. */
.url { font-family: var(--font-mono); color: var(--mute); overflow-wrap: break-word; }
/* A switched-off list: its name and kind fade, its controls do not. */
.off { opacity: var(--dim); }
.kind { display: inline-flex; align-items: center; gap: var(--s-2); }
.block { color: var(--ch-block); }
/*
`--ok`, the text green, and not `--ch-ok`, the line green: the same value in dark;
in light the series is tuned against the other ten lines and gives 4.45:1 under
the row hover, the text tone 5.0:1.
*/
.allow { color: var(--ok); }
/* Move up, Move down and Remove, hard against the row's end as Delete is in Rules. */
.actions { text-align: right; white-space: nowrap; }
.rowActions { display: inline-flex; align-items: center; gap: var(--s-2); }
/*
The kind has two places: its own column, and under the URL. Only one is drawn at a
time (`display: none` also takes the other out of what a screen reader reads).
*/
.kindInline { display: none; }
/*
`--bp-stack`. Four columns and three row buttons left the URL six characters a line
at 390: the Type column folds into the List cell, under the URL, and the row's
buttons stack in their column, so the URL keeps most of the width.
*/
@media (max-width: 560px) {
.kindCell { display: none; }
.kindInline { display: inline-flex; margin-top: var(--s-2); }
.rowActions { flex-direction: column; align-items: flex-end; }
}
/*
"Add to group", over the URL and Quick Add because it serves both. As wide as a
help column: a group name is short, and a field across the whole panel would read
as a second URL.
*/
.target { max-width: var(--help-col); margin-bottom: var(--s-10); }
/*
A group heading: a row across the table on the raised step, as the table's own
header is, so the lists under it read as its rows. Its name weighs as a row's
entity; its count is metadata. The cell is a `th` in the body, so it is reset from
the header's small capitals.
*/
.groupRow > th {
background: var(--pan2);
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line2);
padding: var(--s-5) var(--s-7);
text-align: left;
font-weight: 400;
}
.groupHead { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-5); }
.groupName { font-size: var(--t-5); font-weight: 600; color: var(--ink); overflow-wrap: break-word; }
.groupCount { color: var(--mute); font-size: var(--t-2); }
/* The heading's name being written, in the heading's own row. */
.editor { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-5); }
.editorField { flex: 1 1 var(--s-12); min-width: 0; max-width: var(--help-col); }
.editor > .invalid { flex-basis: 100%; margin-top: 0; }
.foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-5); padding: var(--s-7) var(--s-9); color: var(--mute); }