/**
 * LeanCMS — Form control substrate (lcms-forms)
 *
 * The single owned, vanilla form-control layer. DaisyUI-*inspired*, hand-rolled
 * (no `dui-*`, no DaisyUI components) — forms are on the vanilla side of the
 * line per G39 + the vanilla-default dependency policy. This is the SOURCE OF
 * TRUTH for front-end form-control styling; `lcms-gforms.css` and the companion
 * theme's `base.css` defer to it and keep only structural/layout bits.
 *
 * Scope is opt-in: `.lcms-form` (our front-end consumer forms — search, login,
 * comments, password gate) and `.gform_wrapper` (Gravity Forms). It never styles
 * bare/global `input`/`select`/`textarea`, so it cannot bleed into the active
 * theme, page-builders, or wp-admin — honouring the non-interference invariant.
 *
 * Token-driven: `--lcms-input-*` read brand-config vars with sane fallbacks, so
 * `framework` / `brand` / `inherited` theme modes all flow through one set of
 * rules. Sites override by setting the brand vars (or the `--lcms-input-*` token
 * directly) — no rule forking.
 *
 * Buttons are deliberately out of scope (the brand button system / G9 owns
 * them); only a minimal `.lcms-form` submit is provided for our own forms.
 *
 * @package lcms
 */

/* ── Tokens ────────────────────────────────────────────────
   Defined at :root so any front-end form consumer can reference them — the
   form-control rules below, the theme's compact search bar
   (.lcms-search-form__input), and future components — keeping one source of
   truth for the values. Inert until referenced. The error hue (oklch red) is
   shared by the invalid state, the required marker, and the form-level error
   box. Sites override by setting these (or the underlying brand vars). */
:root {
    --lcms-input-fg: var(--color-text-primary, #101010);
    --lcms-input-bg: var(--input-bg, var(--color-bg-secondary, #f5f5f5));
    --lcms-input-border: var(--color-border, oklch(0.8 0 0));
    /* Field radius follows the brand button radius by default; --input-radius
       is the per-site override hook (cf. --nav-radius). */
    --lcms-input-radius: var(--input-radius, var(--button-radius, var(--border-radius, 0.5rem)));
    --lcms-input-accent: var(--color-brand-primary, oklch(0.6 0.2 250));
    /* Error/danger ink — the system-wide --color-error (brand-config
       colors.feedback.error) so form validation matches every other error
       surface. Falls back to the canonical oklch red. */
    --lcms-input-error: var(--color-error, oklch(0.637 0.237 25.331));
    --lcms-input-muted: var(--color-text-secondary, #6c757d);
    /* Focus ring derived from the live accent so it tracks the brand. */
    --lcms-input-ring: color-mix(in oklch, var(--lcms-input-accent) 20%, transparent);
}

/* ── Reading measure ───────────────────────────────────────
   `.lcms-form` is capped to --lcms-form-measure and centred. Default cascade:
   brand-config `forms.measure` → the shared article reading column
   (--lcms-article-measure) → the plugin narrow measure (--lcms-measure-narrow,
   48rem) — so forms read at the same width as content by default. Set
   `forms.measure` to deliberately narrow them. Gravity Forms gets the same token
   via the theme's .gform_body rule — one token, both surfaces. The compact
   .lcms-search-form is unaffected (different component). */
.lcms-form {
    max-width: var(--lcms-form-measure, var(--lcms-article-measure, var(--lcms-measure-narrow, 48rem)));
    margin-inline: auto;
}

/* The password gate reads better tight — keep it at the narrower form measure
   while general forms default to the article reading column. */
.post-password-form {
    --lcms-form-measure: 36rem;
}

/* ── Text-like controls ────────────────────────────────────
   inputs (text family), textarea, select. Checkbox/radio/range styled
   separately below. */
:is(.lcms-form, .gform_wrapper) :is(
    input[type="text"],
    input[type="email"],
    input[type="url"],
    input[type="tel"],
    input[type="number"],
    input[type="password"],
    input[type="search"],
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="month"],
    input[type="week"],
    input[type="file"],
    textarea,
    select
) {
    display: flex;
    height: 3rem;
    width: 100%;
    padding: 0.75rem 1rem;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--lcms-input-fg);
    background-color: var(--lcms-input-bg);
    border: 1px solid var(--lcms-input-border);
    border-radius: var(--lcms-input-radius);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

:is(.lcms-form, .gform_wrapper) textarea {
    height: auto;
    min-height: 6rem;
    resize: vertical;
}

/* Native select keeps its disclosure affordance; just normalise the box. */
:is(.lcms-form, .gform_wrapper) select {
    cursor: pointer;
}

:is(.lcms-form, .gform_wrapper) input[type="file"] {
    height: auto;
    padding: 0.5rem 0.75rem;
    cursor: pointer;
}

:is(.lcms-form, .gform_wrapper) :is(input, textarea)::placeholder {
    color: var(--lcms-input-muted);
    opacity: 1;
}

/* ── Focus ─────────────────────────────────────────────────
   :focus-visible covers keyboard focus AND mouse focus on text controls
   (browsers treat text-entry focus as always visible). */
:is(.lcms-form, .gform_wrapper) :is(input, textarea, select):focus-visible {
    outline: 2px solid transparent;
    outline-offset: 2px;
    border-color: var(--lcms-input-accent);
    box-shadow: 0 0 0 3px var(--lcms-input-ring);
}

/* ── Disabled / readonly ───────────────────────────────────*/
:is(.lcms-form, .gform_wrapper) :is(input, textarea, select):disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

:is(.lcms-form, .gform_wrapper) :is(input, textarea, select)[readonly] {
    background-color: color-mix(in oklch, var(--lcms-input-bg) 60%, transparent);
    cursor: default;
}

/* ── Invalid / error state ─────────────────────────────────
   Generic: aria-invalid (the a11y contract) or an `.is-error` field wrapper.
   Gravity Forms: its `.gfield_error` wrapper. */
:is(.lcms-form, .gform_wrapper) :is(input, textarea, select)[aria-invalid="true"],
.lcms-form .is-error :is(input, textarea, select),
.gform_wrapper .gfield_error :is(input, textarea, select) {
    border-color: var(--lcms-input-error);
}

:is(.lcms-form, .gform_wrapper) :is(input, textarea, select)[aria-invalid="true"]:focus-visible,
.lcms-form .is-error :is(input, textarea, select):focus-visible,
.gform_wrapper .gfield_error :is(input, textarea, select):focus-visible {
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--lcms-input-error) 20%, transparent);
}

/* ── Checkbox & radio ──────────────────────────────────────*/
:is(.lcms-form, .gform_wrapper) :is(input[type="checkbox"], input[type="radio"]) {
    width: 1.25rem;
    height: 1.25rem;
    accent-color: var(--lcms-input-accent);
    cursor: pointer;
}

:is(.lcms-form, .gform_wrapper) :is(input[type="checkbox"], input[type="radio"]):disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ── Range ─────────────────────────────────────────────────*/
:is(.lcms-form, .gform_wrapper) input[type="range"] {
    width: 100%;
    accent-color: var(--lcms-input-accent);
}

/* ── Labels ────────────────────────────────────────────────
   Generic `.lcms-form label` + Gravity Forms `.gfield_label`. */
.lcms-form label,
.gform_wrapper .gfield_label {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--lcms-input-fg);
}

/* Required marker — GF emits `.gfield_required`; generic forms can mark up
   `.lcms-form__required`. */
.lcms-form .lcms-form__required,
.gform_wrapper .gfield_required {
    color: var(--lcms-input-error);
    margin-left: 0.25rem;
}

.gform_wrapper .gfield_required_text {
    font-size: 0.75rem;
    font-weight: 400;
}

/* ── Help / description text ───────────────────────────────*/
.lcms-form__help,
.gform_wrapper .gfield_description:not(.validation_message) {
    font-size: 0.75rem;
    color: var(--lcms-input-muted);
    margin-top: 0.25rem;
}

/* ── Field-level validation message ────────────────────────*/
.lcms-form__error,
.gform_wrapper .gfield_validation_message {
    font-size: 0.75rem;
    color: var(--lcms-input-error);
    margin-top: 0.25rem;
}

/* ── Form-level error summary ──────────────────────────────*/
.lcms-form__errors,
.gform_wrapper .gform_validation_errors {
    background-color: color-mix(in oklch, var(--lcms-input-error) 10%, transparent);
    border: 1px solid var(--lcms-input-error);
    border-radius: var(--lcms-input-radius);
    padding: 1rem;
    margin-bottom: 1.5rem;
    color: var(--lcms-input-error);
    font-size: 0.875rem;
}

/* ── Submit for our own (.lcms-form) forms ─────────────────
   Consumes the SAME brand button tokens as the .btn-primary component
   (--button-padding / --button-radius / --btn-primary-*), so a form submit
   matches site buttons and the Gravity Forms submit — all brand-tunable from
   one place (brand-config `buttons.*`). We don't force the `.btn` class onto
   core-generated form markup (the block bundle that defines .btn-primary isn't
   guaranteed loaded on every form page); these token-aligned rules give the
   same look robustly. Fallbacks resolve to --color-brand-primary when the
   button vars are unset. */
.lcms-form :is(button[type="submit"], input[type="submit"], .lcms-form__submit) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--button-padding, 0.75rem 1.75rem);
    font-size: 1rem;
    font-weight: 600;
    color: var(--btn-primary-color, var(--color-text-on-brand, #fff));
    background-color: var(--btn-primary-bg, var(--lcms-input-accent));
    border: 1px solid var(--btn-primary-border, var(--btn-primary-bg, var(--lcms-input-accent)));
    border-radius: var(--button-radius, 9999px);
    box-shadow: var(--shadow-btn, none);
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.lcms-form :is(button[type="submit"], input[type="submit"], .lcms-form__submit):hover {
    background-color: var(--btn-primary-bg-hover, var(--color-brand-primary-hover, var(--lcms-input-accent)));
    color: var(--btn-primary-color-hover, var(--button-color-hover, var(--color-text-on-brand, #fff)));
}

.lcms-form :is(button[type="submit"], input[type="submit"], .lcms-form__submit):disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ── Field layout helpers (generic forms) ──────────────────
   GF brings its own `.gform_fields` / `.gfield` layout (kept structural in
   lcms-gforms.css + theme base.css). For our own forms, opt-in helpers. */
.lcms-form__fields {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.lcms-form__field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Multi-column row — lay `.lcms-form__field` children side by side. Auto-fit
   wraps to fewer columns as space tightens and stacks on narrow screens; the
   `min(100%, …)` floor stops a child overflowing a container narrower than the
   track. No fixed column count, so 2-up / 3-up just work by how many fields you
   drop in. */
.lcms-form__row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    gap: 1rem;
}

/* Fieldset grouping — generic. (GF/comment markup rarely uses fieldset; this is
   for hand-authored .lcms-form groups, e.g. a set of checkboxes/radios.) */
.lcms-form fieldset {
    border: 1px solid var(--lcms-input-border);
    border-radius: var(--lcms-input-radius);
    padding: 1rem;
    margin: 0;
}

.lcms-form legend {
    padding: 0 0.5rem;
    font-weight: 600;
    color: var(--lcms-input-fg);
}

/* Inline option — a checkbox/radio sitting beside its label on one row. */
.lcms-form__check {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
}

/* ══ Forms on dark / brand section backgrounds ═════════════
   DEFAULT-ON contrast fix: labels / legend / help invert to light ink so
   they're legible on a dark or brand section (mirrors how headings/prose
   invert). Inputs stay light cards by default — opt into dark fields via the
   `forms.dark_inputs` flag below. The error ink (red) reads fine on dark, so
   the required marker / validation messages are left as-is. */
:is(.lcms-bg-dark, .lcms-bg-dark-alt, .lcms-bg-brand, .lcms-bg-brand-alt) :is(.lcms-form label, .lcms-form legend) {
    color: var(--color-text-light, #fff);
}

:is(.lcms-bg-dark, .lcms-bg-dark-alt, .lcms-bg-brand, .lcms-bg-brand-alt) .lcms-form__help {
    color: color-mix(in oklch, var(--color-text-light, #fff) 75%, transparent);
}

:is(.lcms-bg-dark, .lcms-bg-dark-alt, .lcms-bg-brand, .lcms-bg-brand-alt) .lcms-form fieldset {
    border-color: color-mix(in oklch, var(--color-text-light, #fff) 25%, transparent);
}

/* ══ Opt-in: dark inputs (brand-config forms.dark_inputs) ══
   Body class `lcms-forms-dark-inputs`. On dark/brand sections the fields
   themselves go translucent-light instead of light cards. */
.lcms-forms-dark-inputs :is(.lcms-bg-dark, .lcms-bg-dark-alt, .lcms-bg-brand, .lcms-bg-brand-alt) :is(.lcms-form, .gform_wrapper) :is(input[type="text"], input[type="email"], input[type="url"], input[type="tel"], input[type="number"], input[type="password"], input[type="search"], input[type="date"], textarea, select) {
    color: var(--color-text-light, #fff);
    background-color: color-mix(in oklch, var(--color-text-light, #fff) 8%, transparent);
    border-color: color-mix(in oklch, var(--color-text-light, #fff) 25%, transparent);
}

.lcms-forms-dark-inputs :is(.lcms-bg-dark, .lcms-bg-dark-alt, .lcms-bg-brand, .lcms-bg-brand-alt) :is(.lcms-form, .gform_wrapper) :is(input, textarea)::placeholder {
    color: color-mix(in oklch, var(--color-text-light, #fff) 55%, transparent);
}

/* ══ Opt-in: autofill restyle (brand-config forms.autofill_restyle) ══
   Body class `lcms-forms-autofill`. Stops the browser's yellow/blue autofill
   fill from overriding the field tokens (WebKit/Blink). */
.lcms-forms-autofill :is(.lcms-form, .gform_wrapper) :is(input):-webkit-autofill {
    -webkit-text-fill-color: var(--lcms-input-fg);
    -webkit-box-shadow: 0 0 0 1000px var(--lcms-input-bg) inset;
    caret-color: var(--lcms-input-fg);
    border-radius: var(--lcms-input-radius);
}

/* ══ Opt-in: custom select chevron (brand-config forms.select_chevron) ══
   Body class `lcms-forms-chevron`. Replaces the native select arrow with a
   consistent inline chevron. */
.lcms-forms-chevron :is(.lcms-form, .gform_wrapper) select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    background-size: 1rem;
    padding-right: 2.5rem;
}

/* Reduced motion — drop the control transitions. */
@media (prefers-reduced-motion: reduce) {
    :is(.lcms-form, .gform_wrapper) :is(input, textarea, select),
    .lcms-form :is(button[type="submit"], input[type="submit"], .lcms-form__submit) {
        transition: none;
    }
}
