fj-field
Labeled native controls. The binding wires disabled and invalid state to native attributes, while the CSS keeps controls one row tall unless the control is explicitly multiline.
input
Label, control and hint; no app page assembles the three separately.
Use lower-case words separated by hyphens.
focus-visible
The native control owns the same square focus ring as fj-btn.
invalid
The control carries aria-invalid and the message carries a sign, so hue is never the only carrier.
Use lowercase ASCII, numbers and hyphens.
disabled
Disabled remains legible and keeps native disabled semantics.
Derived from the repository path.
select
textarea
A multiline field is a bordered region, not an oversized row.
checkbox
The text sits beside the control rather than above it, so it takes the control's rung and not the label's.
Applies to every branch that targets the default branch.
radio group
A group name is not a label for any one control in the group, so it is a span with an id and the group points aria-labelledby at it.
disabled check
The row is the hit target, so the row is what stops being one.
wrapping label
Each line is a row on the same pitch and the box is centred on the first of them, not on the block.
input
Label, control and hint; no app page assembles the three separately.
Use lower-case words separated by hyphens.
focus-visible
The native control owns the same square focus ring as fj-btn.
invalid
The control carries aria-invalid and the message carries a sign, so hue is never the only carrier.
Use lowercase ASCII, numbers and hyphens.
disabled
Disabled remains legible and keeps native disabled semantics.
Derived from the repository path.
select
textarea
A multiline field is a bordered region, not an oversized row.
checkbox
The text sits beside the control rather than above it, so it takes the control's rung and not the label's.
Applies to every branch that targets the default branch.
radio group
A group name is not a label for any one control in the group, so it is a span with an id and the group points aria-labelledby at it.
disabled check
The row is the hit target, so the row is what stops being one.
wrapping label
Each line is a row on the same pitch and the box is centred on the first of them, not on the block.