Input

Markup canonic · components/input.json

sursa = JSON · generat de scripts/build-catalog.py

Reguli

Padding interior (orizontal)

Egal cu radius-ul: 16px pe input default (h 40, r 20), 20px pe input .lg (h 44, r 20). Textul începe unde se termină curba — aliniat optic.

Padding exterior (vertical)

Gap label → input → help: 4px. Densitate strânsă, label pare ancorat de câmp. Între câmpuri în formular: 16px (margin-bottom pe .field).

Aliniere label → text

Label și help padding-left 16px (= padding interior input md). Label, text input și help încep de la aceeași coloană verticală.

Tipografie

Label: Inter 12 / 500 / sentence case / tracking 0.04em, color fog (label-quiet — discret, nu strigă). Text input: Inter 14 / 400 (md) sau 16 / 400 (lg), color ink. Help: Inter 12 / 400, color fog.

A · Input alb pe card bej-1 (default — context Dublin)

Cazul comun: card „Acțiuni" / dashboard / modal pe pagină bej-0. Input alb iese clar peste cardul bej-1.

Default + label + help
Apare pe facturile emise.
Search input
⌘K
Focus state · border fog + halo 3px
Border fog + halo neutru 3px.
Success state
✓ Validat în Registrul Comerțului.
Error state
Format email invalid.
Disabled
Large · 44h / fs 16 / pad-x 20

D · Input-em (emphasis — doar client-facing: Dublin, landing)

Variantă cu accent: label-ul brand stă în interiorul câmpului — pink în repaus, pink-deep pe focus. Borderul rămâne neutru (fog + halo), ca la orice control. Se folosește pe suprafețe client-facing (Dublin, landing); formularele interne folosesc .field neutru.

input-em · repaus (label pink brand)
input-em · focus (label pink-deep + halo neutru)
Comparație · input regular (label fog, deasupra)
input-em · textarea (redimensionabil vertical — trage de colț)
input-em · textarea cu OVERFLOW (scroll intern, label pinned)

Când textul depășește înălțimea, textarea face scroll intern — label-ul e element separat deasupra, deci textul derulat se decupează sub el, nu urcă peste label. Utilizatorul poate redimensiona vertical (mânerul din colț); regula label-ului rămâne valabilă la orice înălțime.

E · Simulare — inputs pe canvas bej-0 cu dot grid (context flow)

Contextul de flow (ex. emitere factură): câmpurile stau direct pe canvas-ul bej-0 cu dot grid (.has-grid), nu pe un card. Borderul --c-input-border (ink @ 30%) ține fiecare câmp lizibil peste pattern. Câmpurile de mai jos sunt live — click / tab / scrie în ele ca să vezi stările reale.

Border --c-input-border peste dot grid.
⌘K
✓ Validat în Registrul Comerțului.
Format email invalid.

Focus state

:focus-visible · border fog + halo 3px (rgba 14%)
Focus simulat cu .is-focused. Border --c-fog + halo neutru.

B · Input tonal pe card alb (excepție — formulare dedicate)

Cazul rar: pagini de setup, formulare dedicate sau wizard pe card alb. Input bej-0 (.input.tonal) — fundalul dă doar căldură câmpului; peste alb separarea e 1.04:1, deci limita controlului o duce singur conturul, iar conturul e mai închis decât pe inputul default: --c-input-border-tonal (ink @ 46%, 3.16:1 peste bej-0) în loc de --c-input-border (ink @ 30%, 2.00:1 — sub pragul de 3:1 din WCAG 1.4.11).

Tonal default
Apare pe contractul de servicii.
Tonal large

C · Modal — formular dedicat (lg)

Modal-ul e un context dedicat pentru o acțiune principală. Folosește exclusiv mărimea lg (44h / fs 16) — input și buton la aceeași dimensiune. Card bej-1 cu radius 24 (--r-xl), halo outline 1px white + offset 16, backdrop var(--c-backdrop) + blur var(--scrim-blur) (ink 25% + 6px) — scrimul canonic, comun cu .doc-sheet-backdrop și .flow-sheet-scrim.

Container

Card bej-1, max-width 480, padding 32, radius 24, halo white outline 1px / offset 16. Centrat în viewport pe backdrop blur.

Inputs

Toate input-urile: 44h / fs 16 / radius 20 / pad-x 20. Background alb peste cardul bej-1 = contrast clar. Border ink @ 30%. Focus = border fog + halo neutru.

Submit

Buton primary full-width 44h / fs 16 / radius 24. Pe modal, butonul este the acțiune — generos, ușor de țintit.

Header

Eyebrow pink (Inter 11 / 600 / 0.10em / uppercase) + T28 cu T-em italic pe accent pink + lead T14 fog. Acțiunea exprimată ca întrebare („Către cine emitem factura?").

Două etichete, două lucruri

Sistemul are două lucruri care s-au numit „label”. Nu sunt interschimbabile și nu arată la fel.

.field-label   eticheta unui CÂMP, deasupra lui
               12px / 500 · 0.04em · --c-fog · padding-left 16px

.label         eticheta unui CONTROL, lângă el
.check-label   15px / 22px · 400 · --c-ink
.radio-label   .sublabel dedesubt: 13px / 18px · --c-fog

.label e forma generică a lui .check-label / .radio-label — aceeași regulă, sub un nume care nu presupune un checkbox. Folosește-o pentru orice control care are eticheta lângă el, nu deasupra. Maparea completă a celor cinci nume: Fieldset.

Textarea · două variante de label

Aceleași două variante de câmp, aplicate unui textarea: label deasupra (.field) sau label în interior (.field.input-em). Varianta „inboard” exista deja; cea neutră nu — și moștenea height: 40px de la .input, deci se strângea la un rând.

textarea.input          height auto · min-height 88px (~4 rânduri)
                        padding 10px 16px · line-height 20px
                        resize vertical · scroll intern

.field.input-em
  textarea.input        min-height 60px (~3 rânduri) · padding 0
                        borderul e pe wrapper, nu pe control

resize: vertical în ambele — niciodată orizontal, care rupe layout-ul. Pe varianta inboard, label-ul e element separat deasupra textarea-ului, nu absolut peste el, deci textul derulat se decupează sub label și nu urcă niciodată sub el.

OTP

Semnat. Celula e un .input obișnuit — singurele lucruri pe care OTP-ul le schimbă sunt mărimea și forma. Suprafața nu e a lui: se ia după aceeași regulă de context ca orice câmp (secțiunile A și B de mai sus) — alb pe card bej-1, .tonal pe card alb. Mărimea urcă o treaptă peste .input.lg pe X și trei pe Y: celula 48 lățime (44→48) × 56 înălțime (44→48→52→56), cifra 16→18→20. Motivul: câmpul de OTP e de obicei singurul din pagină, deci nu concurează cu nimic și poate respira. Treptele merg aproape toate pe Y fiindcă axele nu au același buget — lățimea e plătită de rând, unde șase celule trebuie să încapă pe un telefon, iar înălțimea nu e plătită de nimic. Radius-ul rămâne --r-md — dreptunghi rotunjit, nu pastilă, la orice mărime.

A · pe card bej-1 → celule albe (.input)
B · pe card alb → celule tonale (.input.tonal)
.otp .input      48 x 56 · center · 20px / 500 · tabular
                 = .input.lg + 1 treaptă pe X (44→48), 3 pe Y (→56)
                 radius --r-md la orice mărime — --r-lg aici dă o pastilă
                 flex 0 1 48px · min-width 0 — 48 e lățimea, nu un minim:
                 nu crește peste ea, se strânge dacă rândul nu-i încape
                 înălțimea nu cedează — 56 fix pe orice lățime
suprafață        NU e a OTP-ului — regula de context a inputului:
                 card bej-1 → .input (alb) · card alb → .input.tonal
.otp             gap 8px
.otp-sep         separator opțional la mijloc — --c-mist
mobil            doar gap 6px — mărimile nu se schimbă
Semnat 2026-08-27, revizuit 2026-08-31. Separatorul de la mijloc rămâne, 6 cifre e lungimea implicită. Revizuirea: celula nu-și mai impune fundalul (era .input.tonal hardcodat, deci tonal și pe card bej-1, unde conturul tonal pică la 2.78:1) și urcă o treaptă de mărime pe X, trei pe Y — 48 × 56, nu mai e pătrată. Rămâne de implementat, nu de decis: la paste o valoare lipită umple toate celulele, iar starea de eroare e mesaj sub câmp — nu contur roșu pe fiecare celulă, care ar face șase erori din una.