@ -2,141 +2,16 @@
* MaskField — single-line masked input for fixed-literal patterns ( phone ,
* national id , credit card , IBAN , postal code , plate ) .
*
* Mirrors the shared text-input chrome ( border , radius , focus ring , padding ,
* disabled opacity ) so every field in the system reads the same — the mask is
* a value affordance inside the control , not a structural change . The control
* stays a single flex row : the bordered box IS the provider , the borderless
* input fills it .
*
* No transitions on the chrome : an external ` invalid ` flip ( e . g . a form
* re-validating onChange ) would otherwise replay the border transition ; the
* box snaps to its target state instead .
* mask-field IS-A Field control , collapsed onto one box ( no label / segment stack ) :
* the box chrome ( border / radius / bg / height / padding / hover / focus / invalid /
* disabled / variant / size ) and the bare-input reset are ALL owned by field . css via
* the ` data-field ` + ` data-field-control ` + ` data-field-input ` identity ( fieldRole ) .
* The mask is a value affordance inside the input , not a structural change — so the
* ONLY mask-specific rule is the input ' s tabular figures .
* /
[ data-mask-field ] {
--_mask-field-height : var ( --mask-field-height-md ) ;
--_mask-field-padding-inline : var ( --mask-field-padding-inline-md ) ;
--_mask-field-font-size : var ( --mask-field-font-size-md ) ;
/* Focus accent per data-color (foundation role tokens; default primary). */
--_mask-field-accent-border : var ( --color-primary-border ) ;
--_mask-field-border-color : var ( --mask-field-border ) ;
--_mask-field-bg : var ( --mask-field-bg ) ;
display : flex ;
align-items : center ;
inline-size : 100 % ;
min-inline-size : 0 ;
min-block-size : var ( --_mask-field-height ) ;
padding-inline : var ( --_mask-field-padding-inline ) ;
border : var ( --mask-field-border-width ) solid var ( --_mask-field-border-color ) ;
border-radius : var ( --mask-field-radius ) ;
background : var ( --_mask-field-bg ) ;
color : var ( --mask-field-color ) ;
font-family : var ( --mask-field-font-family ) ;
font-size : var ( --_mask-field-font-size ) ;
line-height : var ( --mask-field-line-height ) ;
}
/* ── Input ─────────────────────────────────────────────────────────── */
[ data-mask-field-input ] {
min-inline-size : 0 ;
inline-size : 100 % ;
border : 0 ;
padding : 0 ;
background : transparent ;
color : inherit ;
font : inherit ;
font-weight : var ( --font-weight-medium ) ;
outline : none ;
/* Masked patterns are digit-heavy — keep glyph columns aligned. */
/ * Masked patterns are digit-heavy — keep glyph columns aligned so the caret and
fixed literals don ' t shift as the mask fills . * /
font-variant-numeric : tabular-nums ;
}
[ data-mask-field-input ] :: placeholder {
color : var ( --mask-field-placeholder-color ) ;
}
[ data-mask-field-input ] [ data-disabled ] {
cursor : not-allowed ;
}
/* ── Color accents (focus border tint) ─────────────────────────────── */
[ data-mask-field ] [ data-color = 'secondary' ] {
--_mask-field-accent-border : var ( --color-secondary-border ) ;
}
[ data-mask-field ] [ data-color = 'neutral' ] {
--_mask-field-accent-border : var ( --color-neutral-border ) ;
}
[ data-mask-field ] [ data-color = 'affirm' ] {
--_mask-field-accent-border : var ( --color-affirm-border ) ;
}
[ data-mask-field ] [ data-color = 'fulfill' ] {
--_mask-field-accent-border : var ( --color-fulfill-border ) ;
}
[ data-mask-field ] [ data-color = 'risk' ] {
--_mask-field-accent-border : var ( --color-risk-border ) ;
}
[ data-mask-field ] [ data-color = 'threat' ] {
--_mask-field-accent-border : var ( --color-threat-border ) ;
}
[ data-mask-field ] [ data-color = 'loss' ] {
--_mask-field-accent-border : var ( --color-loss-border ) ;
}
/* ── Sizes ─────────────────────────────────────────────────────────── */
[ data-mask-field ] [ data-size = 'xs' ] {
--_mask-field-height : var ( --mask-field-height-xs ) ;
--_mask-field-padding-inline : var ( --mask-field-padding-inline-xs ) ;
--_mask-field-font-size : var ( --mask-field-font-size-xs ) ;
}
[ data-mask-field ] [ data-size = 'sm' ] {
--_mask-field-height : var ( --mask-field-height-sm ) ;
--_mask-field-padding-inline : var ( --mask-field-padding-inline-sm ) ;
--_mask-field-font-size : var ( --mask-field-font-size-sm ) ;
}
[ data-mask-field ] [ data-size = 'lg' ] {
--_mask-field-height : var ( --mask-field-height-lg ) ;
--_mask-field-padding-inline : var ( --mask-field-padding-inline-lg ) ;
--_mask-field-font-size : var ( --mask-field-font-size-lg ) ;
}
[ data-mask-field ] [ data-size = 'xl' ] {
--_mask-field-height : var ( --mask-field-height-xl ) ;
--_mask-field-padding-inline : var ( --mask-field-padding-inline-xl ) ;
--_mask-field-font-size : var ( --mask-field-font-size-xl ) ;
}
/* ── Variants ──────────────────────────────────────────────────────── */
[ data-mask-field ] [ data-variant = 'outline' ] {
--_mask-field-bg : transparent ;
}
[ data-mask-field ] [ data-variant = 'ghost' ] {
--_mask-field-border-color : transparent ;
--_mask-field-bg : transparent ;
padding-inline : 0 ;
}
/* ── State chrome ──────────────────────────────────────────────────── */
[ data-mask-field ] : hover : not ( [ data-disabled ] ) : not ( [ data-focused ] ) {
--_mask-field-border-color : var ( --color-border-strong ) ;
}
[ data-mask-field ] [ data-focused ] {
--_mask-field-border-color : var ( --_mask-field-accent-border ) ;
/* Flush outline ring (no offset → no gap) so it survives forced-colors. */
outline : var ( --focus-ring-width ) solid var ( --focus-ring-color ) ;
outline-offset : 0 ;
}
[ data-mask-field ] [ data-invalid ] {
--_mask-field-border-color : var ( --mask-field-border-invalid ) ;
}
[ data-mask-field ] [ data-disabled ] {
opacity : var ( --mask-field-disabled-opacity ) ;
cursor : not-allowed ;
}