Input

Text inputs are the primary data-entry surface. Settld uses a paper-white field with a warm hairline border, a teal focus ring, and a dedicated amount variant with a monospace rupee prefix. Labels always sit above the field — never inside it as a floating placeholder.

Variants

What did you split?

Default is the standard text input — body font, 48px tall, 14px border-radius. Covers names, labels, notes, search.

Amount is the rupee-entry field. Monospace font, 64px tall, bold ₹ prefix aligned to the baseline of the number. inputmode="decimal" surfaces the numeric keyboard on mobile without forcing a type="number" spinner UI.

Multiline is a <textarea> styled identically to the default input but with auto-height. Used for notes, descriptions, and group names that may wrap.

Sizes

SizeClassHeightFont sizeRadiusUse case
Large.input-lg56px16px16pxHero entry, modal primary field
Medium.input-md48px15px14pxDefault — forms, sheets, inline editing
Amount.input-amount64px24px mono16pxRupee entry — always paired with ₹ prefix

States

Enter a valid amount in rupees
StateVisual changeTransition
EmptyPlaceholder text at --ink-mute
FilledInk-colored user text
Focused1px teal border, 3px teal glow rgba(14,124,102,0.12)140ms ease-out
Error1px coral border, coral helper text below140ms ease-out
Error focused1px coral border, 3px coral glow rgba(231,111,81,0.12)140ms ease-out
DisabledWarm background --s-warm, 60% opacity, no-cursor

On dark surfaces

On dark surfaces, the field background becomes --dark-elevated, borders use --dark-border, and text is --dark-text. The focus ring remains teal — it has enough contrast on both light and dark surfaces.

Anatomy

Label ↓
Expense name
1px border — teal when focused
3px glow ring
Helper text ↓
What did you split?
PartElementNotes
Label<label>Always above the field. Never inside as placeholder. 13px/600 --ink-body. Linked to input via for/id.
Field<input> or <textarea>Paper background, hairline border, 14px radius. Focus: teal border + glow. Error: coral border.
Prefix.input-amount-prefixAmount variant only. Absolute-positioned ₹ in mono, aligned to the input baseline.
Helper text.field-helperBelow the field. 12px, muted. Turns coral (.error) for validation messages.

Usage

Do Always use a visible label above the field. Placeholders disappear on entry and are inaccessible to screen readers as labels. Keep placeholder text as an example, not as the label ("Farzi Cafe dinner", not "Enter expense name").
Don't Don't use floating labels that animate inside the field. They create layout shift and are confusing when a value is present. Don't put helper text above the field — it belongs below.
Do Use inputmode="decimal" on amount fields. It surfaces the numeric keyboard on iOS and Android without the awkward number-spinner arrows of type="number".
Don't Don't show error state before the user has interacted with the field. Validate on blur or on submit — not on every keystroke.

Accessibility

Labels Every input must have a <label> linked via for/id. Never use aria-label as a substitute for a visible label — it disappears from the UI.
Error messages Link error text to the field using aria-describedby. Set aria-invalid="true" on the input when in error state. This ensures screen readers announce the error when the field receives focus.
Focus ring Never remove the teal focus ring. It is the only visual indicator for keyboard users. The 3px glow with 0.12 alpha provides visible contrast on both light and dark surfaces.

Code

HTML

<!-- Default field -->
<div class="field">
  <label class="field-label" for="expense-name">Expense name</label>
  <input class="input input-md" id="expense-name" type="text" placeholder="Farzi Cafe dinner">
  <span class="field-helper">What did you split?</span>
</div>

<!-- Amount field -->
<div class="field">
  <label class="field-label" for="amount">Amount</label>
  <div class="input-amount-wrap">
    <span class="input-amount-prefix" aria-hidden="true"></span>
    <input class="input input-amount" id="amount" type="text" inputmode="decimal" placeholder="0" aria-label="Amount in rupees">
  </div>
</div>

<!-- Error state -->
<div class="field is-error">
  <label class="field-label" for="amt-err">Amount</label>
  <input class="input input-md error" id="amt-err" aria-invalid="true" aria-describedby="amt-err-msg">
  <span class="field-helper error" id="amt-err-msg" role="alert">Enter a valid amount in rupees</span>
</div>

CSS classes

ClassPurpose
.fieldWrapper — column flex with 6px gap
.field-labelAbove-field label — 13px/600
.field-helperBelow-field helper or error text
.field-helper.errorCoral error message
.inputBase input — resets, border, focus ring
.input-lg56px / 16px / 16px radius
.input-md48px / 15px / 14px radius (default)
.input-amountMono 24px, 64px tall, for rupee entry
.input-amount-wrapRelative wrapper for the ₹ prefix
.input-amount-prefixAbsolute ₹ symbol
.input-multilineTextarea variant — auto height, resizable
.input.errorCoral border and focus ring

Design tokens used

TokenValueRole
--s-paper#FBF8F0Field background
--ink-line#DDD2B8Default border
--teal#0E7C66Focus border
--error#E76F51Error border and helper text
--ink-mute#8A8276Placeholder and helper text
--r-md14pxDefault border-radius
--font-monoJetBrains MonoAmount prefix and value
--d-fast140msFocus/error transition