Inputs
Text fields, selects, and form controls designed for clarity and accessibility. Every input should feel effortless.
Text Input
Sizes
Three sizes to fit different contexts and information hierarchy.
<input type="text" class="input input-sm" placeholder="Small">
<input type="text" class="input input-md" placeholder="Medium">
<input type="text" class="input input-lg" placeholder="Large">
States
Visual feedback for different interaction states.
<!-- Error state -->
<input type="text" class="input input-error" value="invalid">
<span class="input-hint input-hint-error">Enter a valid email</span>
<!-- Success state -->
<input type="text" class="input input-success" value="valid">
<span class="input-hint input-hint-success">Looks good!</span>
With Icons
Icons provide visual context and improve scannability.
<div class="input-with-icon">
<svg class="input-icon input-icon-left">...</svg>
<input type="text" class="input has-icon-left" placeholder="Search...">
</div>
Textarea
Basic Textarea
Multi-line text input for longer content.
<textarea class="textarea" rows="4" placeholder="What's on your mind?"></textarea>
Auto-resize
Textarea that grows with content for a seamless writing experience.
<textarea class="textarea textarea-auto" rows="2"></textarea>
<script>
textarea.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
});
</script>
Select
Basic Select
Dropdown selection for choosing from predefined options.
<div class="select-wrapper">
<select class="select">
<option value="">Choose a persona...</option>
<option value="ferni">Ferni</option>
<option value="maya">Maya</option>
</select>
<svg class="select-icon">...</svg>
</div>
Checkbox & Radio
Checkboxes
Multiple selections with clear visual feedback.
<label class="checkbox-wrapper">
<input type="checkbox" class="checkbox" checked>
<span class="checkbox-control"></span>
<span class="checkbox-label">Enable notifications</span>
</label>
Radio Buttons
Single selection from a group of options.
<label class="radio-wrapper">
<input type="radio" name="theme" class="radio" checked>
<span class="radio-control"></span>
<span class="radio-label">Light theme</span>
</label>
Toggle Switch
Basic Toggle
On/off controls for binary settings.
<label class="toggle-wrapper">
<input type="checkbox" class="toggle-input" checked>
<span class="toggle-control"></span>
<span class="toggle-label">Voice responses</span>
</label>
CSS Implementation
/* Base Input */
.input {
width: 100%;
font-family: var(--font-body);
font-size: var(--text-sm);
color: var(--text-primary);
background: var(--bg-tertiary);
border: 1px solid var(--border-medium);
border-radius: var(--radius-md);
transition: all var(--duration-fast) var(--ease-ease-out);
}
.input:focus {
outline: none;
border-color: var(--accent-primary);
box-shadow: 0 0 0 3px var(--accent-subtle);
}
.input::placeholder {
color: var(--text-muted);
}
/* Sizes */
.input-sm { padding: var(--space-2) var(--space-3); font-size: var(--text-xs); }
.input-md { padding: var(--space-3) var(--space-4); }
.input-lg { padding: var(--space-4) var(--space-5); font-size: var(--text-base); }
/* States */
.input-error {
border-color: var(--error);
}
.input-error:focus {
box-shadow: 0 0 0 3px rgba(var(--error-rgb), 0.15);
}
.input-success {
border-color: var(--success);
}
.input:disabled {
opacity: 0.5;
cursor: not-allowed;
background: var(--bg-secondary);
}
/* Hints */
.input-hint {
display: block;
font-size: var(--text-xs);
color: var(--text-muted);
margin-top: var(--space-1);
}
.input-hint-error { color: var(--error); }
.input-hint-success { color: var(--success); }
/* Checkbox */
.checkbox-wrapper {
display: flex;
align-items: center;
gap: var(--space-3);
cursor: pointer;
}
.checkbox {
position: absolute;
opacity: 0;
}
.checkbox-control {
width: 20px;
height: 20px;
border: 2px solid var(--border-medium);
border-radius: var(--radius-sm);
transition: all var(--duration-fast) var(--ease-ease-out);
position: relative;
}
.checkbox:checked + .checkbox-control {
background: var(--accent-primary);
border-color: var(--accent-primary);
}
.checkbox:checked + .checkbox-control::after {
content: '';
position: absolute;
left: 6px;
top: 2px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
/* Toggle */
.toggle-control {
width: 44px;
height: 24px;
background: var(--bg-tertiary);
border: 1px solid var(--border-medium);
border-radius: var(--radius-full);
position: relative;
transition: all var(--duration-fast) var(--ease-ease-out);
}
.toggle-control::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 18px;
height: 18px;
background: white;
border-radius: 50%;
box-shadow: var(--shadow-sm);
transition: transform var(--duration-fast) var(--ease-spring);
}
.toggle-input:checked + .toggle-control {
background: var(--accent-primary);
border-color: var(--accent-primary);
}
.toggle-input:checked + .toggle-control::after {
transform: translateX(20px);
}
Accessibility
Labels Required
Every input must have an associated <label> for screen readers. Never use placeholder as the only label.
Focus Indicators
Clear focus states with sufficient contrast. The accent ring provides 3:1 contrast against backgrounds.
Error Messaging
Errors use aria-describedby to connect inputs to their error messages for screen readers.
Keyboard Navigation
All inputs are keyboard accessible. Checkboxes and radios respond to Space, selects to Arrow keys.