Text inputs, text areas, native selects and money inputs share one field frame: label above, control, helper below. Borders clear 3:1 against the page so the control is findable (the as-is border was 2.9:1). Focus turns the border blue with a 1px inner ring. Errors colour both the border and the helper.
States
Shown on proposals
Enter a full email address, like name@company.com
Sizes
32 for dense tables, 40 by default, 48 for touch-first forms. A form uses one size throughout, including its selects (the as-is form mixed 48px fields with 40px selects).
Select, text area, money, search
Native select for short lists; long searchable lists use the picker dialog
$per sq ft
Rules
- Every control has a visible label. Placeholder text is an example, never the label.
- Empty values stay empty: never render "null" or "$0.00" for an unset price (the as-is settings page shows "null").
- Error text says how to fix it, in sentence case.
- One search field design app-wide (the audit found four).
<div class="field">
<label class="field-label" for="email">Email</label>
<input class="input" id="email" type="email" aria-describedby="email-help">
<p class="field-helper" id="email-help">We send proposal replies here</p>
</div>