Skip to content

Form Inputs

Inputs should feel calm and uncluttered. The user is already under cognitive load from their condition — form fields should reduce friction, not add it. Default styling uses the warm palette with gentle borders; state changes are communicated through border color shifts rather than layout movement.


The base input. Used for short single-line text: names, emails, session goals.

Token source: tokens/component/input.json

Default
Focus
Error Enter a valid email address
Success Looks good
Disabled
Textarea — Default
Textarea — Disabled
Search — Empty
Search — Filled
Password — Masked
Password — Visible
PropertyTokenResolved value
Backgroundprimitive.color.white#FFFFFF
Text colorsemantic.color.text.primary#3D2E2A (warm-dark)
Placeholder colorsemantic.color.text.muted#B09A90 (dim-brown)
Border colorsemantic.color.border.default#F2C087 (warm-gold)
Border width1px
Border radiusprimitive.radius.md8px
Padding Yprimitive.spacing.1010px
Padding Xprimitive.spacing.1212px
Font sizeprimitive.font-size.1515px
Font weightprimitive.font-weight.regular400
Transitionprimitive.transition.fast150ms ease
StateBorder colorBackgroundOpacity
Default#F2C087 (warm-gold)#FFFFFF1
Focus#A55838 (burnt-sienna-deep) + 2px ring#FFFFFF1
Error#DC2626#FFFFFF1
Success#98D398 (soft-sage)#FFFFFF1
Disabled#F2C087 (warm-gold)#F9DFAE (pale-wheat)0.4

Multi-line text input for open-ended responses — experience descriptions, feedback, journal entries.

Shares all base text field tokens. Additional tokens in input.textarea:

PropertyTokenResolved value
Min height120px
Resizevertical
Line height1.5

Search field with a left-aligned magnifying glass icon and an optional clear button. Uses the Lucide icon sprite.

Additional tokens in input.search:

PropertyTokenResolved value
Icon colorsemantic.color.text.muted#B09A90
Icon sizeprimitive.spacing.1616px
Clear colorsemantic.color.text.muted#B09A90
Clear hoversemantic.color.text.primary#3D2E2A
Left paddingprimitive.spacing.4040px

Password input with a show/hide visibility toggle icon on the right.

Additional tokens in input.password:

PropertyTokenResolved value
Toggle colorsemantic.color.text.muted#B09A90
Toggle hoversemantic.color.text.primary#3D2E2A
Toggle sizeprimitive.spacing.2020px
Right paddingprimitive.spacing.4040px

Token source: tokens/component/checkbox.json

Independent boolean selections. Each checkbox operates independently — use for consent forms, preference lists, multi-select filters.

Unchecked
Checked
Disabled
Error
This field is required
In context
PropertyTokenResolved value
Sizeprimitive.spacing.2020px
Border radiusprimitive.radius.sm4px
Border colorsemantic.color.border.default#F2C087 (warm-gold)
Backgroundprimitive.color.white#FFFFFF
Checked bgsemantic.color.action.primary#A55838 (burnt-sienna-deep)
Checkmarkprimitive.color.white#FFFFFF
Label sizeprimitive.font-size.1515px
StateBorderBackgroundNotes
Uncheckedwarm-goldwhiteDefault
Checkedburnt-sienna-deepburnt-sienna-deepWhite checkmark visible
Hovermuted-copperBorder darkens
Focus+ 2px ringBurnt-sienna ring at 20%
Disabled40% opacity on wrapper
ErrorredRed border, error message below

Token source: tokens/component/radio.json

Mutually exclusive single selection within a group. Use when exactly one option must be chosen from a small set (2–4 options).

Default
Selected
Disabled
Error
Please select an option
In context How would you describe your tinnitus?
PropertyTokenResolved value
Sizeprimitive.spacing.2020px
Border radiusprimitive.radius.full9999px
Border colorsemantic.color.border.default#F2C087 (warm-gold)
Backgroundprimitive.color.white#FFFFFF
Selected bordersemantic.color.action.primary#A55838 (burnt-sienna-deep)
Dot colorsemantic.color.action.primary#A55838
Dot sizeprimitive.spacing.1010px
Label sizeprimitive.font-size.1515px
StateBorderDotNotes
Unselectedwarm-goldhiddenDefault
Selectedburnt-sienna-deepburnt-sienna-deepDot scales in
Hovermuted-copperBorder darkens
Focus+ 2px ringBurnt-sienna ring at 20%
Disabled40% opacity on wrapper
ErrorredRed border, error message below

Token source: tokens/component/select.json

Native <select> with custom styling. Use for longer option lists (5+ items) where radio buttons would be unwieldy.

Default
Filled
Focus
Disabled
Error
Please select a duration
PropertyTokenResolved value
Backgroundprimitive.color.white#FFFFFF
Text colorsemantic.color.text.primary#3D2E2A
Border colorsemantic.color.border.default#F2C087
Border radiusprimitive.radius.md8px
Arrow colorsemantic.color.text.muted#B09A90
Font sizeprimitive.font-size.1515px
StateBorder colorBackgroundOpacity
Defaultwarm-goldwhite1
Focusburnt-sienna-deep + 2px ringwhite1
Errorredwhite1
Disabledwarm-goldpale-wheat0.4

Token source: tokens/component/toggle.json

The Toggle is the correct control for any setting that activates the moment the user flips it — sound masking on, sleep mode off, notifications silenced. Unlike a checkbox (which represents a selection that only takes effect on form submit), a Toggle communicates immediate action through its affordance: a thumb that slides from one state to another along a pill-shaped track. In the tinnitus context this matters more than usual: users adjusting sound therapy settings expect the change to be live, and any ambiguity between “I selected this” versus “this is active” adds unnecessary cognitive friction.

The component is implemented using a native <input type="checkbox"> hidden off-screen, with a <label> acting as the visible track and a <span> as the thumb. The :checked pseudo-class drives all visual state changes — no JavaScript required.

Off
On
Disabled
In context
Sound Masking
Sleep mode
Notifications
TokenCSS custom propertyResolved value
component.toggle.track-width--component-toggle-track-width44px (minimum touch target)
component.toggle.track-height--component-toggle-track-height24px (spacing.24)
component.toggle.track-radius--component-toggle-track-radius9999px (radius.full)
component.toggle.track-background-off--component-toggle-track-background-off#F2C087 (border.default → warm-gold)
component.toggle.track-background-on--component-toggle-track-background-on#A55838 (action.primary → burnt-sienna-deep)
component.toggle.track-background-hover-off--component-toggle-track-background-hover-off#E09370 (border.strong → muted-copper)
component.toggle.track-background-hover-on--component-toggle-track-background-hover-on#914D31 (action.primary-hover → burnt-sienna-deep-hover)
component.toggle.thumb-size--component-toggle-thumb-size20px (spacing.20)
component.toggle.thumb-background--component-toggle-thumb-background#FFFFFF (color.white)
component.toggle.thumb-shadow--component-toggle-thumb-shadow0 1px 2px rgba(0,0,0,0.05) (shadow.sm)
component.toggle.transition--component-toggle-transition150ms ease (transition.fast)
component.toggle.label-color--component-toggle-label-color#3D2E2A (text.primary → warm-dark)
component.toggle.label-font-size--component-toggle-label-font-size14px (font-size.14)
component.toggle.disabled-opacity--component-toggle-disabled-opacity0.4 (opacity.disabled)

Off. The track renders in warm-gold (border.default). The white thumb sits against the left edge with a 2px offset, with a soft drop shadow for tactile depth.

On. The thumb slides 20px right and the track transitions to burnt-sienna-deep (action.primary), signalling an active setting.

Hover. Off state moves to muted-copper (border.strong), on state deepens to burnt-sienna-deep-hover (action.primary-hover).

Focus. A 2px semi-transparent sienna ring (rgba(165, 88, 56, 0.3)) via focus-visible, matching buttons and inputs.

Disabled. The entire row reduces to 0.4 opacity. Cursor changes to not-allowed.


  • Labels above, not inside. Placeholder text disappears on focus, which creates cognitive overhead for users who may already be attention-depleted. Always pair inputs with visible labels.
  • One field at a time where possible. Multi-field forms should be broken into steps, especially during onboarding. One idea per view.
  • Generous spacing between fields. Use spacing.24 or spacing.32 between form groups to give the layout breathing room.
  • Checkbox vs Toggle. Use checkboxes for consent and multi-select lists. Use toggles for on/off settings where the effect is immediate.
  • Radio vs Select. Use radio buttons for 2–4 visible options. Use a dropdown for 5+ options or when screen space is constrained.
  • Textarea min-height. Set a reasonable minimum (120px default) so the field looks inviting, not cramped.
  • Search: always include a clear button. Users should be able to reset the search with one tap.
  • Password: always include a visibility toggle. Reduces frustration and supports accessibility.
  • Error messages: be specific and calm. “Please enter a valid email” — not “Error!” For a tinnitus audience, form errors should never create urgency or a sense of failure.
  • Toggle touch target. The track-width of 44px meets WCAG 2.5.5 minimum. Do not reduce.
  • Toggle labels describe the setting, not the state. “Sound Masking” is correct; “Sound Masking On/Off” is redundant — the toggle position communicates the state.
  • Toggle ARIA. The native <input type="checkbox"> is preferred — screen readers announce it correctly and Space toggles it without scripting.