/* ============================================================
   components/fields.css — Majestic V2 field foundation
   ------------------------------------------------------------
   The strict field shell for text-like native controls. Structure
   is authored explicitly — the runtime never reparents generic DOM:

     <div class="majestic-field">
         <div class="majestic-field__control">
             <input class="majestic-control" id="x" name="x" placeholder="…">
             <label class="majestic-field__label" for="x">Label</label>
             <span   class="majestic-field__leading">…</span>
             <button class="majestic-field__action" type="button">…</button>
         </div>
         <p class="majestic-field__hint" id="x-hint">Helpful context.</p>
         <p class="majestic-field__message" id="x-message"></p>
     </div>

   Floating notch label: at rest the label is vertically centred over
   the value; on focus / when filled / on autofill it lifts to an 11px
   uppercase notch cut into the top border. The notch background reads
   the *surrounding surface* through --field-context so it looks like a
   real border cutout on cards, inner surfaces, dialogs, or the page.

   State is expressed through native + ARIA attributes; the runtime
   mirrors validity onto .majestic-field--invalid / --warning / --success.

   Loads after majestic.css (tokens) in the shared component manifest.
   ============================================================ */

/* --- Surface-context notch token ----------------------------------------- */
/* The notch background must match whatever surface the field sits on. Fields
   most commonly live inside a card, so that is the default; containers set
   --field-context to override, and the two explicit modifiers cover the
   page background and nested inner surfaces without a wrapping element. */
.inner-card,
.inner-tile { --field-context: var(--inner-card-background); }

.majestic-field {
    --field-surface: var(--field-context, var(--card-background));
    --field-border: var(--input-border-color);
    --field-border-strong: var(--border-color-strong);
    --field-bg: var(--input-background);
    --field-accent: var(--primary-color);

    display: grid;
    gap: 6px;
    min-width: 0;
    font-family: var(--font-input);
}

.majestic-field--on-page { --field-surface: var(--surface-0); }
.majestic-field--on-inner { --field-surface: var(--inner-card-background); }

/* Compact / max-width fields are explicit; normal fields fill their cell. */
.majestic-field--compact { max-width: 220px; }
.majestic-field--wide { grid-column: 1 / -1; }

/* --- Control shell -------------------------------------------------------- */

.majestic-field__control {
    position: relative;
    display: flex;
    align-items: stretch;
    min-height: var(--control-height);
    border: 1px solid var(--field-border);
    border-radius: var(--radius-control);
    background: var(--field-bg);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.12);
    transition:
        border-color var(--motion-default) var(--ease-out),
        background-color var(--motion-default) var(--ease-out),
        box-shadow var(--motion-default) var(--ease-out);
}

.majestic-field__control:hover {
    border-color: var(--field-border-strong);
    background: var(--input-hover-background);
}

/* Focus strengthens the border and adds a compact soft glow (not the mutton
   dash — that exception is buttons only). */
.majestic-field__control:focus-within {
    border-color: var(--field-accent);
    background: var(--input-focus-background);
    box-shadow: 0 0 0 3px var(--focus-ring-color);
}

/* --- Native control ------------------------------------------------------- */

.majestic-control {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    height: calc(var(--control-height) - 2px);
    padding: 0 12px;
    border: 0;
    background: transparent;
    color: var(--text-color);
    font: inherit;
    font-size: 0.875rem;
    line-height: 1.35;
    caret-color: var(--field-accent);
    appearance: none;
    outline: none;
}

/* The legacy foundation still provides generic input/select focus and hover
   shadows. A V2 field owns focus at the shell level, so its native control
   stays visually transparent and only the shell draws the focus state. */
input.majestic-control,
select.majestic-control,
textarea.majestic-control,
input.majestic-control:hover,
select.majestic-control:hover,
textarea.majestic-control:hover,
input.majestic-control:focus,
select.majestic-control:focus,
textarea.majestic-control:focus,
.majestic-control:focus-visible {
    background: transparent !important;
    box-shadow: none !important;
    outline: none;
}

.majestic-control::placeholder { color: transparent; }
/* The real placeholder only surfaces once the label has floated away. */
.majestic-field__control:focus-within .majestic-control::placeholder {
    color: var(--text-subtle-color);
    transition: color var(--motion-default) var(--ease-out);
}

/* Touch / coarse-pointer contexts use the larger 16px value size. */
@media (pointer: coarse) {
    .majestic-control { font-size: 1rem; }
}

/* Textarea sits on the shell with a consistent minimum height and only
   grows vertically; auto-grow is never forced globally. */
textarea.majestic-control {
    height: auto;
    min-height: 96px;
    padding: 10px 12px;
    line-height: 1.5;
    resize: vertical;
}

/* --- Floating notch label ------------------------------------------------- */

.majestic-field__label {
    position: absolute;
    left: 8px;
    top: 50%;
    z-index: 1;
    max-width: calc(100% - 16px);
    padding: 0 4px;
    transform: translateY(-50%);
    color: var(--text-muted-color);
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    background: transparent;
    transition:
        top var(--motion-default) var(--ease-out),
        font-size var(--motion-default) var(--ease-out),
        color var(--motion-default) var(--ease-out);
}

/* An empty, unfocused textarea rests its label near the first line.  Scope
   this rule to the resting state: a broader :has(textarea) selector has more
   specificity than the float rules below and would otherwise keep the small
   focused/filled label at 18px, directly over typed text. */
.majestic-field__control:has(textarea.majestic-control:placeholder-shown):not(:focus-within) .majestic-field__label { top: 18px; }

/* Float when focused, filled, or explicitly forced (selects). */
.majestic-field__control:focus-within .majestic-field__label,
.majestic-control:not(:placeholder-shown) ~ .majestic-field__label,
.majestic-field--floated .majestic-field__label {
    top: 0;
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background: var(--field-surface);
}

/* Autofill lives in isolated rules: an engine that doesn't recognise the
   pseudo-class drops only this rule, never the float rule above. */
.majestic-control:-webkit-autofill ~ .majestic-field__label {
    top: 0;
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background: var(--field-surface);
}
.majestic-control:autofill ~ .majestic-field__label {
    top: 0;
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background: var(--field-surface);
}

.majestic-field__control:focus-within .majestic-field__label { color: var(--field-accent); }

/* Required marker in the label — native `required` stays authoritative. */
.majestic-field--required .majestic-field__label::after {
    content: " *";
    color: var(--danger-color);
}

/* --- Bare fields (no visible floating label) ------------------------------ */
/* Opts out of the notch; the accessible name must come from aria-label. */
.majestic-field--bare .majestic-field__label { display: none; }
.majestic-field--bare .majestic-control::placeholder { color: var(--text-subtle-color); }

/* --- Leading adornment + trailing action + prefix/suffix ------------------ */

.majestic-field__leading,
.majestic-field__prefix,
.majestic-field__suffix {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    color: var(--text-subtle-color);
    pointer-events: none;
}

/* DOM order is fixed by the authoring contract (control first, so the
   floating-label sibling selectors resolve); flex order places the slots
   visually: leading | prefix | control | suffix | action. */
.majestic-field__leading { order: -2; padding-left: 12px; font-size: 1.05rem; }
.majestic-field__leading .majestic-icon { width: 1.05rem; height: 1.05rem; }

.majestic-field__prefix { order: -1; padding-left: 12px; }
.majestic-field__suffix { order: 1; padding-right: 12px; }
.majestic-field__prefix,
.majestic-field__suffix {
    color: var(--text-muted-color);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}

/* Real, focusable icon buttons living inside the shell (clear/reveal/copy). */
.majestic-field__action {
    order: 2;
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: calc(var(--control-height) - 6px);
    margin: 2px 2px 2px 0;
    padding: 0;
    color: var(--text-muted-color);
    background: transparent;
    border: 0;
    border-radius: calc(var(--radius-control) - 2px);
    cursor: pointer;
    transition:
        color var(--motion-fast) var(--ease-out),
        background-color var(--motion-fast) var(--ease-out);
}
.majestic-field__action .majestic-icon { width: 1.05rem; height: 1.05rem; }
.majestic-field__action:hover { color: var(--text-color); background: var(--surface-hover); }
.majestic-field__action:focus-visible { outline: 2px solid var(--primary-color); outline-offset: -1px; }

/* When adornments are present the value gets breathing room so nothing
   overlaps the label or the value text. */
.majestic-field__control:has(.majestic-field__leading) .majestic-control { padding-left: 6px; }
.majestic-field__control:has(.majestic-field__leading) .majestic-field__label { left: 40px; }
.majestic-field__control:has(.majestic-field__prefix) .majestic-control { padding-left: 4px; }
.majestic-field__control:has(.majestic-field__action) .majestic-control { padding-right: 4px; }

/* --- Hint, message, counter ---------------------------------------------- */
/* These flow naturally below the shell. No blank line is reserved: an empty
   message collapses so error text never shifts a neighbouring control. */

.majestic-field__hint {
    margin: 0;
    color: var(--text-muted-color);
    font-size: 0.75rem;
    line-height: 1.4;
}

.majestic-field__message {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0;
    color: var(--text-muted-color);
    font-size: 0.75rem;
    line-height: 1.4;
}
.majestic-field__message:empty { display: none; }
.majestic-field__message .majestic-icon { width: 0.9rem; height: 0.9rem; margin-top: 0.1em; flex: 0 0 auto; }

.majestic-field__meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
}
.majestic-field__meta .majestic-field__message,
.majestic-field__meta .majestic-field__hint { flex: 1 1 auto; }

.majestic-field__counter {
    flex: 0 0 auto;
    color: var(--text-subtle-color);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.majestic-field__counter--over { color: var(--danger-color); }

/* --- Validation states ---------------------------------------------------- */
/* The runtime toggles the modifier class alongside aria-invalid; both are
   honoured so no-JS validity styling still lands. */

.majestic-field--invalid .majestic-field__control,
.majestic-field__control:has(.majestic-control[aria-invalid="true"]) {
    border-color: var(--danger-border-color);
    background: var(--danger-background);
}
.majestic-field--invalid .majestic-field__control:focus-within,
.majestic-field__control:has(.majestic-control[aria-invalid="true"]):focus-within {
    border-color: var(--danger-color);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger-color) 30%, transparent);
}
.majestic-field--invalid .majestic-field__label,
.majestic-field--invalid .majestic-field__message { color: var(--danger-color); }

.majestic-field--warning .majestic-field__control {
    border-color: var(--warning-border-color);
    background: var(--warning-background);
}
.majestic-field--warning .majestic-field__control:focus-within {
    border-color: var(--warning-color);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning-color) 28%, transparent);
}
.majestic-field--warning .majestic-field__message { color: var(--warning-color); }

.majestic-field--success .majestic-field__control {
    border-color: var(--success-border-color);
}
.majestic-field--success .majestic-field__control:focus-within {
    border-color: var(--success-color);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--success-color) 26%, transparent);
}
.majestic-field--success .majestic-field__message { color: var(--success-color); }

/* --- Readonly + disabled -------------------------------------------------- */

.majestic-field__control:has(.majestic-control[readonly]) {
    background: color-mix(in srgb, var(--surface-2) 60%, var(--input-background));
    border-style: dashed;
}
.majestic-control[readonly] { cursor: default; }

.majestic-field__control:has(.majestic-control:disabled),
.majestic-field--disabled .majestic-field__control {
    opacity: 0.55;
    background: var(--surface-1);
    box-shadow: none;
}
.majestic-control:disabled { cursor: not-allowed; color: var(--disabled-text-color, var(--text-subtle-color)); }
.majestic-field__control:has(.majestic-control:disabled):hover { border-color: var(--field-border); }

/* --- Sizes ---------------------------------------------------------------- */

.majestic-field--sm { --control-height: var(--control-height-sm); }
.majestic-field--sm .majestic-control { font-size: 0.8125rem; }
.majestic-field--sm .majestic-field__label { font-size: 0.8125rem; }
.majestic-field--sm .majestic-field__control:focus-within .majestic-field__label,
.majestic-field--sm .majestic-control:not(:placeholder-shown) ~ .majestic-field__label { font-size: 0.625rem; }

.majestic-field--lg { --control-height: var(--control-height-lg); }
.majestic-field--lg .majestic-control { font-size: 1rem; }

/* --- Form grid ------------------------------------------------------------ */
/* Container-query driven so a form reflows to its own width, not the viewport.
   Same-row controls top-align, so a taller field (hint/error) never stretches
   or pushes its neighbour's control surface. */

.majestic-form-grid {
    display: grid;
    grid-template-columns: 1fr;
    align-items: start;
    gap: var(--space-4);
    container-type: inline-size;
}

@container (min-width: 30rem) {
    .majestic-form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container (min-width: 60rem) {
    .majestic-form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Field + inline action pairs keep an 8px gap and are not visually fused. */
.majestic-field-row {
    display: flex;
    align-items: start;
    gap: var(--space-2);
}
.majestic-field-row .majestic-field { flex: 1 1 auto; }
.majestic-field-row > .mutton,
.majestic-field-row > .mini-button { flex: 0 0 auto; margin-top: 0; }

@media (max-width: 40rem) {
    .majestic-field-row { flex-wrap: wrap; }
}

/* --- Error summary (opt-in for long forms) -------------------------------- */

.majestic-error-summary {
    display: grid;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    color: var(--danger-color);
    background: var(--danger-background);
    border: 1px solid var(--danger-border-color);
    border-left-width: 3px;
    border-radius: var(--radius-inner);
}
.majestic-error-summary[hidden] { display: none; }
.majestic-error-summary__title {
    margin: 0;
    color: var(--danger-color);
    font-size: 0.875rem;
    font-weight: 650;
}
.majestic-error-summary__list { margin: 0; padding-left: var(--space-4); display: grid; gap: 2px; }
.majestic-error-summary__list a {
    color: var(--danger-color);
    font-size: 0.8125rem;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.majestic-error-summary__list a:hover,
.majestic-error-summary__list a:focus-visible { color: var(--text-color); }

/* --- Dirty save bar ------------------------------------------------------- */
/* Injected by the runtime for form[data-majestic-dirty]; hidden until the
   form differs from its server-rendered snapshot. */

.majestic-save-bar {
    position: fixed;
    left: 50%;
    bottom: var(--space-5);
    z-index: var(--z-sticky);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    max-width: calc(100vw - 2 * var(--space-4));
    padding: 10px 10px 10px var(--space-4);
    color: var(--text-color);
    background: var(--surface-2);
    border: 1px solid var(--border-color-strong);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-floating);
    transform: translate(-50%, calc(100% + var(--space-6)));
    opacity: 0;
    pointer-events: none;
    transition:
        transform var(--motion-expressive) var(--ease-out),
        opacity var(--motion-default) var(--ease-out);
}
.majestic-save-bar--visible {
    transform: translate(-50%, 0);
    opacity: 1;
    pointer-events: auto;
}
.majestic-save-bar__text {
    font-size: 0.8125rem;
    font-weight: 500;
}
.majestic-save-bar__actions { display: flex; align-items: center; gap: var(--space-2); }

@media (max-width: 40rem) {
    .majestic-save-bar {
        left: var(--space-3);
        right: var(--space-3);
        bottom: var(--space-3);
        max-width: none;
        transform: translateY(calc(100% + var(--space-6)));
    }
    .majestic-save-bar--visible { transform: translateY(0); }
}

/* --- Reduced motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .majestic-field__control,
    .majestic-field__label,
    .majestic-field__action,
    .majestic-save-bar {
        transition-duration: 0.01ms;
    }
    .majestic-save-bar { transition-property: opacity; transform: translate(-50%, 0); }
    .majestic-save-bar:not(.majestic-save-bar--visible) { transform: translate(-50%, 0); }
    @media (max-width: 40rem) {
        .majestic-save-bar,
        .majestic-save-bar--visible { transform: translateY(0); }
    }
}

/* --- Forced colors -------------------------------------------------------- */

@media (forced-colors: active) {
    .majestic-field__control { border: 1px solid ButtonText; }
    .majestic-field__control:focus-within { border-color: Highlight; box-shadow: none; outline: 2px solid Highlight; outline-offset: 1px; }
    .majestic-field__label { background: Canvas; }
    .majestic-field--invalid .majestic-field__control,
    .majestic-field--warning .majestic-field__control { border-color: ButtonText; }
    .majestic-field__action:focus-visible { outline: 2px solid Highlight; }
    .majestic-save-bar { border: 1px solid ButtonText; }
}
