/* src/components/basic/XWUIInputText/XWUIInputText.css */
/**
 * XWUIInputText Component Styles
 * 
 * Style Dependencies:
 * - Base: reset.css, typography.css, utilities.css
 * - Brand: brand/xwui/brand.css
 * - Style: style/modern/spacing.css, style/modern/shadows.css
 * - Theme: theme/colors/{selected-theme}.css (MANDATORY - provides all color variables)
 * - Theme: theme/accents/{selected-accent}.css (MANDATORY - provides accent color variables)
 * - Lines: theme/lines/input/*.css (component-specific border widths)
 * - Roundness: theme/roundness/input/*.css (component-specific roundness)
 * - Typography: theme/typography/*.css
 */

.xwui-input-text-wrapper {
    display: flex;
    flex-direction: column;
    gap: var(--xwui-field-label-gap, 0.375rem);
}

.xwui-input-text-full-width {
    width: 100%;
}

/* Label */
.xwui-input-text-label {
    font-family: var(--xwui-field-label-family, var(--font-label-family, var(--font-family-base, sans-serif)));
    font-size: var(--xwui-field-label-size, var(--font-size-sm, 0.875rem));
    font-weight: var(--xwui-field-label-weight, var(--font-weight-medium, 500));
    line-height: var(--xwui-field-label-line-height, 1.5);
    color: var(--xwui-field-label-color, var(--text-primary));
}

.xwui-input-text-required {
    color: var(--role-danger-ink, var(--accent-error));
}

/* Input container - fixed min-height so height does not change when typing */
.xwui-input-text-container {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs, 0.5rem);
    border-radius: var(--radius-input, var(--radius-md, 6px));
    transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
    box-sizing: border-box;
    height: var(--xwui-input-height-md);
    min-height: var(--xwui-input-height-md); /* default md; overridden per size */
    /* The whole painted field is an effective click target: presses on the
       container's padding delegate focus to the input (WCAG 2.5.8), so the
       cursor must advertise text entry across the full box, not just the
       input's own line box. */
    cursor: text;
}

/* Leading visual wrap - reference: FormControl-input-leadingVisualWrap */
.xwui-input-text-leading-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--text-secondary);
}

.xwui-input-text-leading-visual {
    display: flex;
    align-items: center;
    justify-content: center;
}

.xwui-input-text-leading-wrap svg,
.xwui-input-text-leading-visual svg {
    width: 18px;
    height: 18px;
    color: var(--text-secondary);
}

/* Input wrapper - reference: QueryBuilder-InputWrapper (flex grow, contains input) */
.xwui-input-text-input-wrap {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
}

/* Outlined variant - one surface for the whole control.
   WHY --bg-input / --control-bg (not --bg-primary): on dark themes the page
   surface and the bordered field were both --bg-primary while the native
   <input> still painted a lighter UA fill → nested "pill inside shell".
   A single control token + transparent inner input keeps one cohesive field. */
.xwui-input-text-outlined .xwui-input-text-container {
    border: var(--border-input-width, var(--border-width-regular, 1.5px)) var(--border-input-style, solid) var(--border-input-color, var(--border-color));
    background: var(--bg-input, var(--control-bg, var(--bg-primary)));
}

.xwui-input-text-outlined .xwui-input-text-container:hover {
    border-color: var(--border-strong);
}

.xwui-input-text-outlined .xwui-input-text-container.xwui-input-text-focused {
    border-color: var(--accent-primary);
    box-shadow: var(--glow-input-focus, var(--shadow-xs));
}

/* A visible ring on the field while focus is inside it, in every variant. The border recolour alone was the only
   signal, and dark themes give the focused border nearly the resting colour, so a Tab walk lost the field (WCAG 2.4.7,
   found in xwmail-web as X-A11Y-3). */
.xwui-input-text-container:focus-within {
    outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color, var(--accent-primary));
    outline-offset: var(--focus-ring-offset, 1px);
}

/* Filled variant - uses a tinted overlay of the text colour rather than a
   named bg token. Why: several themes (dark, night, azure-forge, catppuccin-*)
   define --bg-card === --bg-secondary, so the old `background: var(--bg-secondary)`
   made the filled input disappear against the surrounding card. color-mix on
   --text-primary produces a consistent subtle elevation against *any* card
   surface the input sits on. The var(...) line below is a fallback for
   browsers without color-mix support. */
.xwui-input-text-filled .xwui-input-text-container {
    border: var(--border-input-width, var(--border-width-regular, 1.5px)) var(--border-input-style, solid) transparent;
    background: var(--bg-tertiary, var(--bg-secondary));
    background: color-mix(in srgb, var(--text-primary) 6%, transparent);
}

.xwui-input-text-filled .xwui-input-text-container:hover {
    background: var(--bg-tertiary);
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}

.xwui-input-text-filled .xwui-input-text-container.xwui-input-text-focused {
    background: var(--bg-primary);
    border-color: var(--accent-primary);
    box-shadow: var(--glow-input-focus, none);
}

/* Underlined variant */
.xwui-input-text-underlined .xwui-input-text-container {
    border: none;
    border-bottom: var(--border-input-width, var(--border-width-thick, 2px)) var(--border-input-style, solid) var(--border-input-color, var(--border-color));
    border-radius: 0;
    background: transparent;
}

.xwui-input-text-underlined .xwui-input-text-container:hover {
    border-bottom-color: var(--border-strong);
}

.xwui-input-text-underlined .xwui-input-text-container.xwui-input-text-focused {
    border-bottom-color: var(--accent-primary);
    box-shadow: var(--glow-input-focus, none);
}

/* Input element - stable height, with enough line-height that descenders
   (j, g, y, p, q) have room to render even at the smallest font sizes.
   line-height: 1.25 was too tight: at 15px font that's ~18.75px line, which
   puts the baseline only ~1.9px above the content-box bottom - the tail of
   a 'g' is ~3-4px and got clipped. 1.5 gives ~3.75px of bottom clearance,
   which fits every common font at every supported size. */
.xwui-input-text-container .xwui-input {
    flex: 1;
    /* `none` leaves Chromium/Windows free to paint the UA inset frame. */
    border: 0 solid transparent;
    border-radius: 0;
    background: transparent;
    background-color: transparent;
    outline: none;
    outline-offset: 0;
    font-family: var(--font-input-family, var(--font-family-base, inherit));
    color: var(--text-primary);
    width: 100%;
    min-width: 0;
    /* Glyph line stays 1.5 so descenders clear (see comment above). The
       painted field is the container, which locks height to the token. */
    line-height: 1.5;
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    min-height: 0; /* let container control height */
    /* Inherit theme so UA chrome doesn't invent a second light field. */
    color-scheme: inherit;
    -webkit-appearance: none;
    appearance: none;
}

/* Autofill paints an opaque light wash inside the shell - match the control surface. */
.xwui-input-text-container .xwui-input:-webkit-autofill,
.xwui-input-text-container .xwui-input:-webkit-autofill:hover,
.xwui-input-text-container .xwui-input:-webkit-autofill:focus,
.xwui-input-text-container .xwui-input:autofill {
    -webkit-text-fill-color: var(--text-primary, currentColor);
    caret-color: var(--text-primary, currentColor);
    border-radius: inherit;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-transition: background-color 99999s ease-out 0s;
    transition: background-color 99999s ease-out 0s;
    box-shadow: 0 0 0 1000px var(--bg-input, var(--control-bg, var(--bg-primary, transparent))) inset;
}

/* Suppress global :focus-visible outline on inner input so only container border shows */
.xwui-input-text-container .xwui-input:focus,
.xwui-input-text-container .xwui-input:focus-visible {
    outline: none;
    outline-offset: 0;
}

.xwui-input::placeholder {
    color: var(--text-tertiary);
}

/* Trigger mode (conf_comp.trigger) - the inner control is a native <button>
   that opens something, kept on the flat .xwui-input look above. These rules
   undo what a UA button adds: centred text (start-align it like typed text,
   so RTL follows), wrapping (one line, ellipsis), and the text cursor the
   container advertises for typing (a trigger is pressed, not typed into). */
.xwui-input-text-trigger-mode .xwui-input-text-container {
    cursor: pointer;
}
.xwui-input-text-container .xwui-input-text-trigger {
    display: block;
    text-align: start;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: inherit;
}
/* The placeholder is a trigger's visible NAME, not a hint beside a text box,
   so it must meet 4.5:1 (WCAG 1.4.3). --text-tertiary is 3.6:1 to 4.0:1 on the
   light themes (bootstrap-light, bits-light, ark-light); --text-secondary is
   not, and is still visibly lighter than a chosen value in --text-primary. */
.xwui-input-text-container .xwui-input-text-trigger-placeholder {
    color: var(--text-secondary);
}
/* The container already paints focus (border + glow), as it does for the
   input. (0,4,0) beats the global `*:focus-visible` ring, which loads later at
   (0,3,0) and is only lifted for input/textarea/select inside field shells,
   so keyboard focus on the trigger shows one ring, not two. */
.xwui-input-text-container .xwui-input-text-trigger.xwui-input:focus-visible {
    outline: none;
    outline-offset: 0;
}

/*
 * Kill the UA search-cancel glyph. Chromium still paints a full-width “X”
 * when only `appearance: none` is set (display:none alone is ignored on the
 * pseudo). Zero box + opacity is what actually removes it; we draw our own
 * clear control when clearable.
 */
.xwui-input-text-container input[type="search"]::-webkit-search-cancel-button,
.xwui-input-text-container input[type="search"]::-webkit-search-decoration,
.xwui-input-text-container input[type="search"]::-webkit-search-results-button,
.xwui-input-text-container input[type="search"]::-webkit-search-results-decoration {
    -webkit-appearance: none !important;
    appearance: none !important;
    display: none !important;
    width: 0 !important;
    height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    opacity: 0 !important;
    pointer-events: none !important;
}
.xwui-input-text-container input[type="search"]::-moz-search-cancel-button {
    appearance: none !important;
    -moz-appearance: none !important;
    display: none !important;
    width: 0 !important;
    height: 0 !important;
    opacity: 0 !important;
}

/* Size variants - use the canonical short-form scale (xs/sm/md/lg/xl)
   that XWUIInputText.ts actually emits on the wrapper. The previous
   selectors used legacy long names (-small/-medium/-large) that no
   longer match any rendered class, so the padding never applied and
   inputs had a 0px inner box which clipped glyph descenders. Pads use
   literal rems (not spacing tokens) so they survive any theme that
   redefines --spacing-sm to a small value. */
/* Canonical 11-step size scale: xxxxs|xxxs|xxs|xs|sm|md|lg|xl|xxl|xxxl|xxxxl.
   Smaller-than-xs sizes are needed for tight grid/cell embeds (e.g.
   PropertiesGrid rows in 28-32px row heights). Larger-than-xl sizes mirror
   the rest of the xwui scale. */
:is(.xwui-input-text-4xs,.xwui-input-text-xxxxs) .xwui-input-text-container {
    height: var(--xwui-input-height-xxxxs);
    min-height: var(--xwui-input-height-xxxxs);
    padding: var(--xwui-size-pad-y-xxxxs, 1px) var(--xwui-size-pad-x-xxxxs, 3px);
}
:is(.xwui-input-text-4xs,.xwui-input-text-xxxxs) .xwui-input { font-size: var(--xwui-size-font-xxxxs, 8px); }

:is(.xwui-input-text-3xs,.xwui-input-text-xxxs) .xwui-input-text-container {
    height: var(--xwui-input-height-xxxs);
    min-height: var(--xwui-input-height-xxxs);
    padding: var(--xwui-size-pad-y-xxxs, 1px) var(--xwui-size-pad-x-xxxs, 4px);
}
:is(.xwui-input-text-3xs,.xwui-input-text-xxxs) .xwui-input { font-size: var(--xwui-size-font-xxxs, 9px); }

:is(.xwui-input-text-2xs,.xwui-input-text-xxs) .xwui-input-text-container {
    height: var(--xwui-input-height-xxs);
    min-height: var(--xwui-input-height-xxs);
    padding: var(--xwui-size-pad-y-xxs, 2px) var(--xwui-size-pad-x-xxs, 6px);
}
:is(.xwui-input-text-2xs,.xwui-input-text-xxs) .xwui-input { font-size: var(--xwui-size-font-xxs, 10px); }

.xwui-input-text-xs .xwui-input-text-container {
    height: var(--xwui-input-height-xs);
    min-height: var(--xwui-input-height-xs);
    padding: var(--xwui-size-pad-y-xs, 3px) var(--xwui-size-pad-x-xs, 8px);
}
.xwui-input-text-xs .xwui-input { font-size: var(--xwui-size-font-xs, 11px); }

:is(.xwui-input-text-s,.xwui-input-text-sm) .xwui-input-text-container {
    height: var(--xwui-input-height-sm);
    min-height: var(--xwui-input-height-sm);
    padding: var(--xwui-size-pad-y-sm, 4px) var(--xwui-size-pad-x-sm, 10px);
}
:is(.xwui-input-text-s,.xwui-input-text-sm) .xwui-input { font-size: var(--xwui-size-font-sm, 12px); }

:is(.xwui-input-text-m,.xwui-input-text-md) .xwui-input-text-container {
    height: var(--xwui-input-height-md);
    min-height: var(--xwui-input-height-md);
    padding: var(--xwui-size-pad-y-md, 6px) var(--xwui-size-pad-x-md, 14px);
}
:is(.xwui-input-text-m,.xwui-input-text-md) .xwui-input { font-size: var(--xwui-size-font-md, 14px); }

:is(.xwui-input-text-l,.xwui-input-text-lg) .xwui-input-text-container {
    height: var(--xwui-input-height-lg);
    min-height: var(--xwui-input-height-lg);
    padding: var(--xwui-size-pad-y-lg, 8px) var(--xwui-size-pad-x-lg, 18px);
}
:is(.xwui-input-text-l,.xwui-input-text-lg) .xwui-input { font-size: var(--xwui-size-font-lg, 16px); }

.xwui-input-text-xl .xwui-input-text-container {
    height: var(--xwui-input-height-xl);
    min-height: var(--xwui-input-height-xl);
    padding: var(--xwui-size-pad-y-xl, 10px) var(--xwui-size-pad-x-xl, 22px);
}
.xwui-input-text-xl .xwui-input { font-size: var(--xwui-size-font-xl, 20px); }

:is(.xwui-input-text-2xl,.xwui-input-text-xxl) .xwui-input-text-container {
    height: var(--xwui-input-height-xxl);
    min-height: var(--xwui-input-height-xxl);
    padding: var(--xwui-size-pad-y-xxl, 12px) var(--xwui-size-pad-x-xxl, 28px);
}
:is(.xwui-input-text-2xl,.xwui-input-text-xxl) .xwui-input { font-size: var(--xwui-size-font-xxl, 24px); }

:is(.xwui-input-text-3xl,.xwui-input-text-xxxl) .xwui-input-text-container {
    height: var(--xwui-input-height-xxxl);
    min-height: var(--xwui-input-height-xxxl);
    padding: var(--xwui-size-pad-y-xxxl, 16px) var(--xwui-size-pad-x-xxxl, 36px);
}
:is(.xwui-input-text-3xl,.xwui-input-text-xxxl) .xwui-input { font-size: var(--xwui-size-font-xxxl, 32px); }

:is(.xwui-input-text-4xl,.xwui-input-text-xxxxl) .xwui-input-text-container {
    height: var(--xwui-input-height-xxxxl);
    min-height: var(--xwui-input-height-xxxxl);
    padding: var(--xwui-size-pad-y-xxxxl, 24px) var(--xwui-size-pad-x-xxxxl, 56px);
}
:is(.xwui-input-text-4xl,.xwui-input-text-xxxxl) .xwui-input { font-size: var(--xwui-size-font-xxxxl, 48px); }

/* Density (M3, Fluent, Carbon) */
.xwui-input-text-wrapper[data-density="compact"] .xwui-input-text-container {
    padding: var(--control-padding-y-compact) var(--control-padding-x-compact);
}
.xwui-input-text-wrapper[data-density="comfortable"] .xwui-input-text-container {
    padding: var(--control-padding-y-comfortable) var(--control-padding-x-comfortable);
}
.xwui-input-text-wrapper[data-density="spacious"] .xwui-input-text-container {
    padding: var(--control-padding-y-spacious) var(--control-padding-x-spacious);
}

/* Prefix and suffix */
.xwui-input-text-prefix,
.xwui-input-text-suffix {
    display: flex;
    align-items: center;
    color: var(--text-secondary);
    flex-shrink: 0;
}

.xwui-input-text-prefix svg,
.xwui-input-text-suffix svg {
    width: 18px;
    height: 18px;
}

/* Clear wrap - compact trailing slot; never steal the input’s flex space. */
.xwui-input-text-clear-wrap[hidden] {
    display: none !important;
}

.xwui-input-text-clear-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: auto;
    max-width: 2rem;
    min-width: 0;
    min-height: 0;
    align-self: center;
    order: 99;
    position: static;
    margin: 0;
}

/* Clear button - fixed square hit target so it cannot expand across the field. */
.xwui-input-text-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    min-width: 1.5rem;
    max-width: 1.5rem;
    height: 1.5rem;
    min-height: 1.5rem;
    max-height: 1.5rem;
    line-height: 1;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm, 4px);
    background: transparent;
    cursor: pointer;
    color: var(--text-tertiary);
    transition: color 0.2s, background 0.2s;
    flex: 0 0 1.5rem;
    box-sizing: border-box;
}

/* XWUIIcon renders the glyph inside a <div class="xwui-icon"> with inline
   width/height style. Cap that wrapper and its nested <svg> so the X can
   never end up at 100% of the input bar width, even if a component-level
   rule elsewhere sets svg { width: 100% } or a theme injects unexpected
   sizing. Without this cap the clear glyph briefly rendered as a huge X
   in the middle of the search input while the icon child was resolving. */
.xwui-input-text-clear > .xwui-icon {
    width: 18px !important;
    height: 18px !important;
    flex-shrink: 0;
}
.xwui-input-text-clear > .xwui-icon svg {
    width: 100%;
    height: 100%;
    display: block;
}

.xwui-input-text-clear:hover {
    color: var(--text-secondary);
    background: var(--bg-secondary, rgba(0, 0, 0, 0.04));
}

.xwui-input-text-clear:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.xwui-input-text-clear svg {
    width: 16px;
    height: 16px;
}

/* Password toggle */
.xwui-input-text-password-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--text-tertiary);
    transition: color 0.2s;
    flex-shrink: 0;
}

.xwui-input-text-password-toggle:hover {
    color: var(--text-secondary);
}

.xwui-input-text-password-toggle svg {
    width: 18px;
    height: 18px;
}

/* Helper text */
.xwui-input-text-helper {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.xwui-input-text-helper-error {
    color: var(--role-danger-ink, var(--accent-error));
}

/* Format validation feedback (pattern, minLength, maxLength) */
.xwui-input-text-format-feedback {
    font-size: var(--font-size-xs, 0.75rem);
    margin-top: calc(var(--spacing-xs, 0.25rem) * -0.5);
}

.xwui-input-text-format-feedback--valid {
    color: var(--role-success-tonal-ink, var(--accent-success, #198754));
}

.xwui-input-text-format-feedback--invalid {
    color: var(--role-danger-ink, var(--accent-error));
}

/* Format valid: border/ring success (do not override explicit error) */
.xwui-input-text-format-valid:not(.xwui-input-text-error) .xwui-input-text-container {
    border-color: var(--accent-success, #198754);
}

.xwui-input-text-format-valid:not(.xwui-input-text-error) .xwui-input-text-container.xwui-input-text-focused {
    /* Success-state focus ring - themed via accent-success-light (20% alpha
       success) so it follows the universal semantic palette on every theme.
       Fallback preserved for browsers without color-mix. */
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.2);
    box-shadow: 0 0 0 2px var(--accent-success-light);
}

/* Format invalid: border/ring error (only when not already in error state from setError) */
.xwui-input-text-format-invalid:not(.xwui-input-text-error) .xwui-input-text-container {
    border-color: var(--accent-error);
}

.xwui-input-text-format-invalid:not(.xwui-input-text-error) .xwui-input-text-container.xwui-input-text-focused {
    /* Error-state focus ring - themed via accent-error-light. */
    box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.2);
    box-shadow: 0 0 0 2px var(--accent-error-light);
}

/* Error state */
.xwui-input-text-error .xwui-input-text-container {
    border-color: var(--accent-error) !important;
}

.xwui-input-text-error .xwui-input-text-container.xwui-input-text-focused {
    box-shadow: var(--glow-input-error, var(--shadow-xs));
}

.xwui-input-text-error .xwui-input-text-label {
    color: var(--role-danger-ink, var(--accent-error));
}

/* Success / valid state - green border, ring, and helper (semantic palette). */
.xwui-input-text-success .xwui-input-text-container {
    border-color: var(--accent-success, #198754) !important;
}
.xwui-input-text-success .xwui-input-text-container.xwui-input-text-focused {
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.2);
    box-shadow: 0 0 0 2px var(--accent-success-light);
}
.xwui-input-text-helper-success {
    color: var(--role-success-tonal-ink, var(--accent-success, #198754));
}
/* Symmetry with the error state (which tints its label red): the success
   label is tinted green, so valid/invalid read the same way at a glance. */
.xwui-input-text-success .xwui-input-text-label {
    color: var(--role-success-tonal-ink, var(--accent-success, #198754));
}

/* Trailing state icon - red alert (error) / green check (success). The glyph
   inherits the state colour via currentColor on the wrap. */
.xwui-input-text-state-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding-inline-end: 0.6rem;
}
.xwui-input-text-state-icon svg { width: 18px; height: 18px; }
.xwui-input-text-error .xwui-input-text-state-icon { color: var(--accent-error); }
.xwui-input-text-success .xwui-input-text-state-icon { color: var(--accent-success, #198754); }

/* Disabled state - clean, legible grays (no muddy global opacity). Explicit
   token colours keep the text/icon readable, matching a clear "read-only" look. */
.xwui-input-text-disabled .xwui-input-text-container {
    background: var(--bg-secondary);
    border-color: var(--border-color);
    cursor: not-allowed;
}
.xwui-input-text-disabled .xwui-input {
    cursor: not-allowed;
    /* Readable medium gray (#6c757d), not the washed-out tertiary (#adb5bd):
       a disabled value should still be legible, like a clear read-only field. */
    color: var(--text-secondary);
    -webkit-text-fill-color: var(--text-secondary);
}
.xwui-input-text-disabled .xwui-input-text-label,
.xwui-input-text-disabled .xwui-input-text-helper {
    color: var(--text-secondary);
}
.xwui-input-text-disabled .xwui-input-text-leading-wrap {
    color: var(--text-secondary);
}

/* ── Floating label ─────────────────────────────────────────────────────────
   The label rides inside the field, centred like a placeholder when empty and
   floating up when focused or filled (Material style). Outlined notches the top
   border with the field background; filled floats the label inside the fill. */
.xwui-input-text-floating .xwui-input-text-container {
    position: relative;
}
.xwui-input-text-floating .xwui-input-text-label {
    margin: 0;
}
.xwui-input-text-float-label {
    position: absolute;
    left: 0.85rem;
    top: 50%;
    transform: translateY(-50%);
    padding: 0 0.25rem;
    max-width: calc(100% - 1.7rem);
    color: var(--text-tertiary);
    font-size: var(--font-size-sm, 0.875rem);
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    transform-origin: left center;
    transition: top 0.16s ease, transform 0.16s ease, color 0.16s ease, left 0.16s ease, right 0.16s ease;
}
/* Resting float title sits in the text lane after a leading icon (not on top of it).
   When floated up for the outline notch, snap back to the field start edge. */
.xwui-input-text-container:has(> .xwui-input-text-leading-wrap) .xwui-input-text-float-label {
    left: calc(0.85rem + 18px + var(--spacing-xs, 0.5rem));
    max-width: calc(100% - 0.85rem - 18px - var(--spacing-xs, 0.5rem) - 0.85rem);
}
.xwui-input-text-container:has(> .xwui-input-text-leading-wrap).xwui-input-text-float-active .xwui-input-text-float-label {
    left: 0.85rem;
}
html[dir="rtl"] .xwui-input-text-float-label {
    left: auto;
    right: 0.85rem;
    transform-origin: right center;
}
html[dir="rtl"] .xwui-input-text-container:has(> .xwui-input-text-leading-wrap) .xwui-input-text-float-label {
    left: auto;
    right: calc(0.85rem + 18px + var(--spacing-xs, 0.5rem));
}
html[dir="rtl"] .xwui-input-text-container:has(> .xwui-input-text-leading-wrap).xwui-input-text-float-active .xwui-input-text-float-label {
    right: 0.85rem;
}
/* Floated (focused OR filled). */
.xwui-input-text-float-active .xwui-input-text-float-label {
    top: 0;
    transform: translateY(-50%) scale(0.8);
    color: var(--accent-primary);
}
.xwui-input-text-floating.xwui-input-text-error .xwui-input-text-float-active .xwui-input-text-float-label { color: var(--role-danger-ink, var(--accent-error)); }
.xwui-input-text-floating.xwui-input-text-success .xwui-input-text-float-active .xwui-input-text-float-label { color: var(--role-success-tonal-ink, var(--accent-success)); }

/* Outlined: notch the border by painting the field background behind the label. */
.xwui-input-text-floating.xwui-input-text-outlined .xwui-input-text-float-active .xwui-input-text-float-label {
    background: var(--bg-input, var(--control-bg, var(--bg-primary, #ffffff)));
}
/* Filled: float to inside-top; give the input headroom so text clears the label. */
.xwui-input-text-floating.xwui-input-text-filled .xwui-input-text-container {
    /* Filled float needs a second text line; do not lock to the md token. */
    height: auto;
}
.xwui-input-text-floating.xwui-input-text-filled .xwui-input {
    padding-top: 1.2rem;
    padding-bottom: 0.45rem;
}
.xwui-input-text-floating.xwui-input-text-filled .xwui-input-text-float-active .xwui-input-text-float-label {
    top: 0.6rem;
    transform: scale(0.8);
}
/* Underlined floating (variant="underlined") - the "line under the input"
   mode: no box, just a bottom rule that turns accent on focus, with the label
   floating above it. The float label needs no notch (no top border to break),
   so it sits flush-left with no background fill. */
.xwui-input-text-floating.xwui-input-text-underlined .xwui-input-text-float-label {
    left: 0;
    padding-left: 0;
}
.xwui-input-text-floating.xwui-input-text-underlined .xwui-input-text-float-active .xwui-input-text-float-label {
    background: transparent;
    transform-origin: left top;
    transform: scale(0.8);
}
/* The two rules above pin the label to the PHYSICAL left, and they out-rank the
   generic html[dir="rtl"] float-label rules, so an Arabic underlined field
   rested its label 13px in from the start edge and then jumped to the far left
   once floated (measured in Chromium: 73px from the start edge, LTR 0px). This
   mirrors them with logical offsets; the selector is as specific as the RTL
   leading-icon rules above and comes after them. transform-origin has no
   logical form, so it is the one physical value left, and it is what makes the
   0.8 scale shrink toward the start edge instead of away from it. */
html[dir="rtl"] .xwui-input-text-floating.xwui-input-text-underlined .xwui-input-text-container .xwui-input-text-float-label {
    inset-inline-start: 0;
    inset-inline-end: auto;
    padding-inline-start: 0;
    transform-origin: right top;
}

/* In-field slotted adornments - light-DOM children placed INSIDE the field.
   Mirrors XWUIButton's slotted-label support: authors drop <xwui-button>,
   <xwui-icon>, a kbd chip, a unit label, etc. between the tags and they render
   inside the field at the leading or trailing edge (data-slot routes the side). */
.xwui-input-text-slot {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs, 0.375rem);
    flex-shrink: 0;
    color: var(--text-secondary);
}
.xwui-input-text-slot-leading {
    margin-inline-end: var(--spacing-xs, 0.25rem);
}
/* Trailing slot sits after the clear button (order:99) at the rightmost edge. */
.xwui-input-text-slot-trailing {
    order: 100;
    margin-inline-start: var(--spacing-xs, 0.4rem);
    margin-inline-end: 0.35rem;
}
/* Cap a resolving <xwui-icon> so it can't briefly paint huge. */
.xwui-input-text-slot > .xwui-icon { width: 18px; height: 18px; flex-shrink: 0; }
.xwui-input-text-slot > .xwui-icon svg { width: 100%; height: 100%; display: block; }

/* Note: Dark theme support is handled automatically via theme/colors/{theme}.css files */

