Atom · Input
Input Fields
A complete set of Apple-inspired form primitives — standard, glassmorphism,
floating-label, OTP/PIN, compound, and more. All colours resolve from
colors.css tokens. Zero hex literals in input.css.
/Atom/input/input.css.
To change any colour, edit colors.css only — every component adapts automatically including dark mode.
01
Standard Inputs
The base .input class covers every native input type.
Add .input-sm or .input-lg for size variants.
All inputs sit on a tinted --color-bg-grouped stage so the
white surface is clearly visible.
Text & Email
<div class="field"> <label class="field-label" for="name">Full name</label> <input class="input" id="name" type="text" placeholder="e.g. Rahul Verma" /> <span class="field-helper">As it appears on your ID.</span> </div>
Sizes
<input class="input input-sm" type="text" placeholder="Small" /> <input class="input" type="text" placeholder="Medium (default)" /> <input class="input input-lg" type="text" placeholder="Large" />
States
<input class="input is-error" type="email" aria-invalid="true" aria-describedby="err" /> <span class="field-helper is-error" id="err">Please enter a valid email.</span> <input class="input is-success" type="email" value="ok@email.com" /> <input class="input" type="text" disabled />
With Icons
<!-- Leading --> <div class="input-wrap"> <span class="input-icon" aria-hidden="true">…svg…</span> <input class="input input-search" type="search" /> </div> <!-- Trailing --> <div class="input-wrap icon-right"> <input class="input" type="email" /> <span class="input-icon" aria-hidden="true">…svg…</span> </div> <!-- Both --> <div class="input-wrap icon-both"> <span class="input-icon">…</span> <input class="input" /> <span class="input-icon input-icon-right">…</span> </div>
Password
<div class="input-wrap icon-right">
<input class="input" id="pw" type="password" placeholder="Min. 8 characters" />
<button class="pw-toggle" type="button"
aria-label="Show password"
onclick="togglePw(this,'pw')">…eye svg…</button>
</div>
Number Stepper
<div class="number-wrap">
<input class="input" id="guests" type="number" value="2" min="1" max="16" />
<div class="number-stepper">
<button class="stepper-btn" onclick="step('guests', 1)" aria-label="Increase">…▲…</button>
<button class="stepper-btn" onclick="step('guests', -1)" aria-label="Decrease">…▼…</button>
</div>
</div>
Phone Number
<div class="phone-wrap">
<select class="country-select" aria-label="Country code">
<option value="+91">🇮🇳 +91</option>
</select>
<input class="input" type="tel" placeholder="98765 43210" />
</div>
Select / Dropdown
<div class="select-wrap">
<select class="select-native" id="type">
<option value="">Select a type…</option>
<option>Apartment</option>
</select>
<span class="select-caret" aria-hidden="true">…chevron svg…</span>
</div>
Date & Time
<input class="input" type="date" /> <input class="input" type="time" value="14:00" /> <input class="input" type="datetime-local" />
Textarea
<textarea class="textarea" maxlength="300" rows="4"
oninput="countChars(this,'count-id',300)"></textarea>
<div class="textarea-footer">
<span class="field-helper">Helper text</span>
<span class="textarea-count" id="count-id">0 / 300</span>
</div>
Range Slider
<div class="range-wrap">
<input type="range" id="price"
min="0" max="20000" value="5000" step="500"
style="--pct:25%"
oninput="syncRange(this,'rv','₹')" />
<span class="range-val" id="rv">₹5,000</span>
</div>
Checkbox & Radio
<label class="checkbox-wrap">
<input type="checkbox" checked />
<span class="checkbox-label">
Entire home
<span class="checkbox-sub">You'll have the place to yourself.</span>
</span>
</label>
<label class="radio-wrap">
<input type="radio" name="sort" checked />
<span class="checkbox-label">Recommended</span>
</label>
Compound / Row Layout
Input Groups
<div class="input-group"> <span class="input-addon">https://</span> <input class="input" type="text" placeholder="yourdomain.com" /> </div>
Floating Label
<div class="float-field"> <!-- placeholder=" " (single space) is required --> <input class="float-input" id="name" type="text" placeholder=" " /> <label class="float-label" for="name">Full name</label> </div>
Tag Input
<div class="tag-input-wrap">
<span class="tag-pill">
WiFi <button class="tag-pill-remove" aria-label="Remove WiFi">×</button>
</span>
<input class="tag-input-inner" type="text"
placeholder="Add amenity…"
onkeydown="handleTag(event)" />
</div>
02
OTP / PIN
Squared single-character cells. Auto-advances on input, backtracks on delete,
supports clipboard paste and arrow-key navigation. Classes:
.otp-input · .otp-input-lg · .otp-input-sm
Standard · 6-digit OTP
Large · 4-digit PIN
Error state
Incorrect code. Please try again.
<div class="otp-wrap" id="otp6" role="group" aria-label="One-time passcode">
<input class="otp-input" type="text" inputmode="numeric"
maxlength="1" pattern="[0-9]" aria-label="Digit 1" />
<!-- × 5 more -->
</div>
<!-- Large PIN -->
<div class="otp-wrap" id="otp4" role="group" aria-label="PIN code">
<input class="otp-input otp-input-lg" type="text" inputmode="numeric"
maxlength="1" pattern="[0-9]" aria-label="Digit 1" />
<!-- × 3 more -->
</div>
<script>initOTP('otp6'); initOTP('otp4');</script>
03
Glassmorphism Set
Apple liquid-glass aesthetic — frosted backdrop blur, luminous border, layered depth shadow.
Wrap in .glass-panel over a coloured / blurred background stage.
Classes: .input-glass · .textarea-glass · .select-glass · .input-glass-search
Glass Sign-in Card
Welcome back
Sign in to Holidayseva
<div class="glass-panel">
<div class="glass-field">
<label class="glass-label" for="email">Email address</label>
<input class="input-glass" id="email" type="email" placeholder="you@email.com" />
</div>
<div class="glass-field">
<label class="glass-label" for="pw">Password</label>
<input class="input-glass" id="pw" type="password" />
</div>
</div>
Glass Search Bar
Glass OTP Verification
Glass Textarea & Select
04
Specifications
--color-border--color-border-focus--focus-ring-blue--focus-ring coral--color-surface--color-glass-bg05
JavaScript API
Lightweight helpers in input.js — no framework required.
| Function | Signature | Description |
|---|---|---|
togglePw(btn, id) |
(El, string) |
Toggles password visibility; updates aria-label and eye icon. |
step(id, delta) |
(string, number) |
Increments / decrements number input, respects min/max. |
countChars(el, id, max) |
(El, string, number) |
Updates textarea character counter; adds .is-near / .is-max. |
syncRange(el, id, …) |
(El, string, str?, str?) |
Syncs CSS --pct track fill and value label for range inputs. |
initOTP(groupId) |
(string) |
Wires auto-advance, backspace, paste and arrow keys for an OTP group. |
handleTag(event) |
(KeyboardEvent) |
Creates a tag pill on Enter inside .tag-input-inner. |
removeTag(btn) |
(El) |
Removes the closest .tag-pill from the tag input wrap. |
06
Integration
Three file includes — tokens first, then component CSS, then JS.
<!-- ① Token layer — always first -->
<link rel="stylesheet" href="/colors.css" />
<!-- ② Component CSS — zero hex literals inside -->
<link rel="stylesheet" href="/Atom/input/input.css" />
<!-- ③ Helper JS (OTP, password, range, stepper, tags) -->
<script src="/Atom/input/input.js" defer></script>
<?php
$partials = __DIR__ . '/../../';
?>
<?php include $partials . 'header.php'; ?>
<?php include $partials . 'drawer_sidebar.php'; ?>
<div class="page-layout">
<aside class="sidebar-left" style="z-index:10000;">
<?php include $partials . 'left_sidebar.php'; ?>
</aside>
<main class="main-content">
<!-- content -->
</main>
<aside class="sidebar-right">
<?php include $partials . 'right_sidebar.php'; ?>
</aside>
</div>
rgba(), or hsl() literals in input.css.
All colour decisions live exclusively in colors.css.
07
Accessibility
-
Every
<input>must have an associated<label>via matchingfor/id. Never useplaceholderas the only label. -
Error states: set
aria-invalid="true"on the input andaria-describedbypointing to the error message. -
OTP groups:
role="group"+aria-labelon the wrapper; individualaria-label="Digit N"on each cell. -
Focus rings must never be suppressed without a custom high-contrast replacement. Tokens
--focus-ringand--focus-ring-bluemeet 3:1 contrast. -
Password toggle:
aria-labelmust reflect current action — "Show password" or "Hide password" — not a static label. -
Range sliders: expose the current value via
aria-valuenow,aria-valuemin, andaria-valuemax. -
Tag input wrap: add
role="group"+aria-label; each pill remove button needs a descriptivearia-label. -
All decorative SVGs must carry
aria-hidden="true".