Date and time
tier 2 — classes.form-input on a date, time, month or week input. The box is the text field's;
what the class adds is the parts the browser draws in its own colours, and the two things
iOS does to a date input that a desktop never shows.
The four inputs
date, time, datetime-local and month,
each a .form-input. Pick the type for the picker and the keyboard the platform
gives you, and keep value in the wire format — 2026-09-18,
08:30 — whatever the reader's locale shows. A
datetime-local is local to the browser and carries no zone: the hint says
which zone the server will read it in, or two people book the same hour.
Local to the browser. Say which zone the server will read it in.
<div class="sedna-grid sedna-grid--sm sedna-grid--fit" style="max-width:560px">
<div class="form-field">
<label class="form-label" for="dt-date">Delivery date</label>
<input class="form-input" id="dt-date" type="date" value="2026-09-18" />
</div>
<div class="form-field">
<label class="form-label" for="dt-time">Not before</label>
<input class="form-input" id="dt-time" type="time" value="08:30" />
</div>
<div class="form-field">
<label class="form-label" for="dt-local">Maintenance window starts</label>
<input class="form-input" id="dt-local" type="datetime-local" value="2026-09-20T22:00" />
<p class="form-hint">Local to the browser. Say which zone the server will read it in.</p>
</div>
<div class="form-field">
<label class="form-label" for="dt-month">Billing period</label>
<input class="form-input" id="dt-month" type="month" value="2026-09" />
</div>
</div>
From and to
Two dates in a .sedna-grid inside one
.form-section, so the legend names the pair. min and
max are what the picker greys out; move the end's min with the
start, or the picker offers a range that the server will reject.
<fieldset class="form-section" style="max-width:560px">
<legend>Report period</legend>
<div class="form-section-body">
<div class="sedna-grid sedna-grid--sm sedna-grid--fit">
<div class="form-field">
<label class="form-label" for="dt-from">From</label>
<input class="form-input" id="dt-from" type="date" value="2026-09-01" min="2026-01-01" max="2026-09-30" />
</div>
<div class="form-field">
<label class="form-label" for="dt-to">To</label>
<input class="form-input" id="dt-to" type="date" value="2026-09-13" min="2026-09-01" max="2026-09-30"
aria-describedby="dt-to-hint" />
<p class="form-hint" id="dt-to-hint">No later than today. The end moves with the start.</p>
</div>
</div>
</div>
</fieldset>
Slots and weeks
step in seconds turns a time input into slots — 900 is a quarter hour
— and min/max bound the day. week is for a
planning horizon; its value is the ISO week, 2026-W38.
Quarter hours between 08:00 and 18:00.
<div class="sedna-grid sedna-grid--sm sedna-grid--fit" style="max-width:560px">
<div class="form-field">
<label class="form-label" for="dt-slot">Pickup slot</label>
<input class="form-input" id="dt-slot" type="time" value="14:00" min="08:00" max="18:00" step="900"
aria-describedby="dt-slot-hint" />
<p class="form-hint" id="dt-slot-hint">Quarter hours between 08:00 and 18:00.</p>
</div>
<div class="form-field">
<label class="form-label" for="dt-week">Planning week</label>
<input class="form-input" id="dt-week" type="week" value="2026-W38" />
</div>
</div>
Three sizes
The input's own tiers, .form-input-sm and -lg, so a date beside
a button is the button's height. A date is a fixed shape, so it takes a
.sedna-w width rather than filling the row.
<div class="sedna-col sedna-gap-3" style="max-width:560px">
<div class="sedna-row sedna-gap-2">
<input class="form-input form-input-sm sedna-w sedna-w--md" type="date" value="2026-09-18" aria-label="Date, small" />
<button class="btn btn-sm" type="button">Apply</button>
</div>
<div class="sedna-row sedna-gap-2">
<input class="form-input sedna-w sedna-w--md" type="date" value="2026-09-18" aria-label="Date, default" />
<button class="btn" type="button">Apply</button>
</div>
<div class="sedna-row sedna-gap-2">
<input class="form-input form-input-lg sedna-w sedna-w--md" type="date" value="2026-09-18" aria-label="Date, large" />
<button class="btn btn-lg" type="button">Apply</button>
</div>
</div>
Read-only, disabled and rejected
The same three states as a text field: readonly is still submitted,
disabled is not, and a rejected date carries aria-invalid and a
.form-error that says what a valid one would be.
Set when the contract was signed. Still submitted.
Follows the contract start. Not submitted.
In the past. Go-live has to be a working day from tomorrow on.
<div class="sedna-grid sedna-grid--sm sedna-grid--fit" style="max-width:560px">
<div class="form-field">
<label class="form-label" for="dt-locked">Contract start</label>
<input class="form-input" id="dt-locked" type="date" value="2024-03-01" readonly />
<p class="form-hint">Set when the contract was signed. Still submitted.</p>
</div>
<div class="form-field">
<label class="form-label" for="dt-off">Renewal</label>
<input class="form-input" id="dt-off" type="date" value="2027-03-01" disabled />
<p class="form-hint">Follows the contract start. Not submitted.</p>
</div>
<div class="form-field sedna-span-full">
<label class="form-label form-label--required" for="dt-bad">Go-live</label>
<input class="form-input" id="dt-bad" type="date" value="2026-09-10" required
aria-invalid="true" aria-describedby="dt-bad-err" />
<p class="form-error" id="dt-bad-err"><i class="ri-error-warning-line"></i> <span>In the past. Go-live has to be a working day from tomorrow on.</span></p>
</div>
</div>
What the browser draws
The calendar glyph is a browser glyph in a fixed colour, invisible on a dark surface until it
is inverted — --picker-invert flips it with the theme — and the picker
panel follows color-scheme, set on <html> from
--color-scheme. On iOS a date input has an intrinsic width and centres its value,
and both ignore the class, so the field ran past its column and its text sat in the middle;
the stylesheet gives it min-width: 0 and appearance: none and starts
the value where every other field's starts. The picker still opens on tap.