Quiet fields: base.css field baseline, --field tokens, 3:1 border-strong, app-wide migration

This commit is contained in:
2026-06-13 00:06:33 +03:00
parent ebdeac7747
commit e0806bf3db
19 changed files with 218 additions and 232 deletions
+43
View File
@@ -55,6 +55,49 @@ body {
outline-offset: 2px;
}
/*
* Field baseline (arch 09 §4) — the quiet field: a fill one step off its surface
* plus a bottom border only, no box. The fill comes from the contextual --field
* token (elevated surfaces set `--field: var(--field-02)` on their container,
* the same mechanism as --control-hover-fill); the underline is --border-strong,
* which meets 3:1 non-text contrast in both themes. Declared once here at zero
* specificity (:where) so modules add only their idiosyncrasies — width, mono
* font, padding — never a competing border recipe. Monaco's internal widgets
* (find/replace inputs) keep their own styling and are excluded.
*/
:where(
input:not([type]),
input[type='text'],
input[type='search'],
input[type='number'],
input[type='url'],
textarea
):where(:not(.monaco-editor *)) {
font: inherit;
color: var(--text);
background: var(--field);
border: none;
border-block-end: var(--border-width) solid var(--border-strong);
border-radius: var(--radius);
}
:where(input, textarea)::placeholder {
color: var(--text-placeholder);
}
/* On a field the ring hugs the box — an offset ring reads as a second border
where there is no longer a box to anchor it. */
:where(
input:not([type]),
input[type='text'],
input[type='search'],
input[type='number'],
input[type='url'],
textarea
):where(:not(.monaco-editor *)):focus-visible {
outline-offset: -2px;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
+22 -2
View File
@@ -65,6 +65,12 @@
/* Focus ring defaults to the accent. */
--focus: var(--accent);
/* Contextual field fill — elevated surfaces set `--field: var(--field-02)`
(and `--field-hover: var(--field-hover-02)`) once on their container, the
same mechanism as --control-hover-fill. */
--field: var(--field-01);
--field-hover: var(--field-hover-01);
}
/* --- Neutral roles: LIGHT theme (Carbon gray ramp) --- */
@@ -73,7 +79,16 @@
--layer-01: #f4f4f4;
--layer-02: #e0e0e0;
--border: #e0e0e0;
--border-strong: #c6c6c6;
/* Component boundaries need 3:1 against the surface (WCAG 1.4.11); gray-50 is
3.32:1 on the canvas and 3.02:1 on --layer-01 (Carbon's $border-strong-01). */
--border-strong: #8d8d8d;
/* Field fills (arch 09 §4): a field is a fill one step off its surface plus a
bottom border — --field-01 on the canvas, --field-02 on an elevated surface.
Surfaces flip the contextual --field token; components consume --field only. */
--field-01: #f4f4f4;
--field-02: #ffffff;
--field-hover-01: #e8e8e8;
--field-hover-02: #e8e8e8;
--text: #161616;
--text-secondary: #525252;
--text-placeholder: #a8a8a8;
@@ -85,7 +100,12 @@
--layer-01: #262626;
--layer-02: #393939;
--border: #393939;
--border-strong: #525252;
/* 3.60:1 on the dark canvas (Carbon g100 $border-strong-01). */
--border-strong: #6f6f6f;
--field-01: #262626;
--field-02: #393939;
--field-hover-01: #333333;
--field-hover-02: #474747;
--text: #f4f4f4;
--text-secondary: #a8a8a8;
--text-placeholder: #6f6f6f;