/**
 * Fluid Framework - Form Components
 * @layer components (the honeypot and conditional fields: @layer utilities)
 *
 * Forms should feel welcoming, not like paperwork.
 * Clear labels, gentle feedback, graceful validation.
 *
 * Includes:
 * - Form groups and layouts
 * - Custom checkboxes and radios
 * - Toggle switches
 * - Input groups and addons
 * - Form validation states
 * - Honeypot and conditional fields
 */

@layer components {
  /* ========================================
     FORM GROUP
     Label + input combinations
     ======================================== */

  .form-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
  }

  /* Stack form groups vertically with spacing (but not inside grid rows) */
  .form-group + .form-group:not(.form-row .form-group) {
    margin-block-start: var(--space-5);
  }

  /* Inside form-row, remove margin to let grid handle spacing */
  .form-row .form-group {
    margin-block-start: 0;
  }

  /* Inline form group */
  .form-group[data-inline] {
    flex-direction: row;
    align-items: center;
    gap: var(--space-4);
  }

  .form-group[data-inline] label {
    flex-shrink: 0;
    margin-block-end: 0;
  }

  /* Label styling */
  .form-label {
    font-size: var(--step--1);
    font-weight: calc(600 + var(--_dark-weight));
    color: var(--color-text);
  }

  /* Required indicator */
  .form-label[data-required]::after {
    content: " *";
    color: var(--color-error);
  }

  /* Help text */
  .form-help {
    font-size: var(--step--1);
    color: var(--color-text-muted);
    margin-block-start: var(--space-1);
  }

  /* Error message */
  .form-error {
    font-size: var(--step--1);
    color: var(--color-error);
    margin-block-start: var(--space-1);
  }


  /* ========================================
     INPUT GROUP
     Inputs with addons
     ======================================== */

  .input-group {
    display: flex;
    align-items: stretch;
  }

  .input-group > input,
  .input-group > select {
    flex: 1;
    min-inline-size: 0;
    border-radius: 0;
  }

  .input-group > input:first-child,
  .input-group > select:first-child {
    border-start-start-radius: var(--radius-control);
    border-end-start-radius: var(--radius-control);
  }

  .input-group > input:last-child,
  .input-group > select:last-child {
    border-start-end-radius: var(--radius-control);
    border-end-end-radius: var(--radius-control);
  }

  .input-group__addon {
    display: flex;
    align-items: center;
    padding-inline: var(--space-3);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    background-color: var(--color-surface);
    border: var(--border-width) solid var(--color-border-strong);
  }

  .input-group__addon:first-child {
    border-inline-end: none;
    border-start-start-radius: var(--radius-control);
    border-end-start-radius: var(--radius-control);
  }

  .input-group__addon:last-child {
    border-inline-start: none;
    border-start-end-radius: var(--radius-control);
    border-end-end-radius: var(--radius-control);
  }


  /* ========================================
     CUSTOM CHECKBOX
     Beautiful checkmarks
     ======================================== */

  .checkbox {
    display: inline-flex;
    align-items: flex-start;
    gap: var(--space-3);
    cursor: pointer;
    user-select: none;
  }

  .checkbox__input {
    /* Hide native but keep accessible */
    position: absolute;
    opacity: 0;
    inline-size: 0;
    block-size: 0;
  }

  .checkbox__box {
    flex-shrink: 0;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    border: var(--border-width-thick) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background-color: var(--color-background);
    display: flex;
    align-items: center;
    justify-content: center;
    transition:
      background-color var(--duration-fast) var(--ease-fluid),
      border-color var(--duration-fast) var(--ease-fluid);
  }

  /* Checkmark icon */
  .checkbox__box::after {
    content: "";
    inline-size: 0.5rem;
    block-size: 0.25rem;
    border-inline-start: var(--border-width-thick) solid var(--on-accent);
    border-block-end: var(--border-width-thick) solid var(--on-accent);
    transform: rotate(-45deg) scale(0);
    transition: transform var(--duration-fast) var(--ease-settle);
  }

  /* Hover state */
  .checkbox:hover .checkbox__box {
    border-color: var(--accent);
  }

  /* Focus state */
  .checkbox__input:focus-visible + .checkbox__box {
    outline: var(--focus-ring-width) solid var(--color-focus);
    outline-offset: 2px;
  }

  /* Checked state */
  .checkbox__input:checked + .checkbox__box {
    background-color: var(--accent);
    border-color: var(--accent);
  }

  .checkbox__input:checked + .checkbox__box::after {
    transform: rotate(-45deg) scale(1);
  }

  /* Indeterminate state */
  .checkbox__input:indeterminate + .checkbox__box::after {
    inline-size: 0.5rem;
    block-size: 0;
    border-inline-start: none;
    transform: rotate(0) scale(1);
  }

  /* Disabled state */
  .checkbox__input:disabled + .checkbox__box {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .checkbox__input:disabled ~ .checkbox__label {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .checkbox__label {
    font-size: var(--font-size-base);
    line-height: 1.25rem;
  }


  /* ========================================
     CUSTOM RADIO
     Circular selection
     ======================================== */

  .radio {
    display: inline-flex;
    align-items: flex-start;
    gap: var(--space-3);
    cursor: pointer;
    user-select: none;
  }

  .radio__input {
    position: absolute;
    opacity: 0;
    inline-size: 0;
    block-size: 0;
  }

  .radio__circle {
    flex-shrink: 0;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    border: var(--border-width-thick) solid var(--color-border-strong);
    border-radius: var(--radius-full);
    background-color: var(--color-background);
    display: flex;
    align-items: center;
    justify-content: center;
    transition:
      border-color var(--duration-normal) var(--ease-fluid);
  }

  .radio__circle::after {
    content: "";
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: var(--radius-full);
    background-color: var(--accent);
    transform: scale(0);
    transition: transform var(--duration-fast) var(--ease-settle);
  }

  .radio:hover .radio__circle {
    border-color: var(--accent);
  }

  .radio__input:focus-visible + .radio__circle {
    outline: var(--focus-ring-width) solid var(--color-focus);
    outline-offset: 2px;
  }

  .radio__input:checked + .radio__circle {
    border-color: var(--accent);
  }

  .radio__input:checked + .radio__circle::after {
    transform: scale(1);
  }

  .radio__input:disabled + .radio__circle {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .radio__input:disabled ~ .radio__label {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .radio__label {
    font-size: var(--font-size-base);
    line-height: 1.25rem;
  }

  /* Radio group */
  .radio-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  .radio-group[data-inline] {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-5);
  }


  /* ========================================
     TOGGLE SWITCH
     On/off control
     Add role="switch" to <input> for ARIA compliance
     ======================================== */

  .switch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    cursor: pointer;
    user-select: none;
  }

  .switch__input {
    position: absolute;
    opacity: 0;
    inline-size: 0;
    block-size: 0;
  }

  /* Square track and thumb (the radius knob); the thumb moves along the
     inline axis with inset-inline-start, so RTL works. */
  .switch__track {
    position: relative;
    flex-shrink: 0;
    inline-size: 2.75rem;
    block-size: 1.5rem;
    background-color: var(--color-background);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-control);
    transition: background-color var(--duration-fast) var(--ease-fluid);
  }

  .switch__thumb {
    position: absolute;
    inset-block-start: 0.125rem;
    inset-inline-start: 0.125rem;
    inline-size: calc(1.25rem - 2 * var(--border-width));
    block-size: calc(1.25rem - 2 * var(--border-width));
    background-color: var(--color-text);
    border-radius: var(--radius-control);
    transition:
      inset-inline-start var(--duration-normal) var(--ease-settle),
      background-color var(--duration-fast) var(--ease-fluid);
  }

  .switch__input:focus-visible + .switch__track {
    outline: var(--focus-ring-width) solid var(--color-focus);
    outline-offset: 2px;
  }

  .switch__input:checked + .switch__track {
    background-color: var(--accent);
    border-color: var(--accent);
  }

  .switch__input:checked + .switch__track .switch__thumb {
    inset-inline-start: calc(100% - 1.25rem + 2 * var(--border-width) - 0.125rem);
    background-color: var(--on-accent);
  }

  .switch__input:disabled + .switch__track {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .switch__input:disabled ~ .switch__label {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .switch__label {
    font-size: var(--font-size-base);
  }

  /* Small switch */
  .switch[data-size="sm"] .switch__track {
    inline-size: 2rem;
    block-size: 1.125rem;
  }

  .switch[data-size="sm"] .switch__thumb {
    inline-size: 0.875rem;
    block-size: 0.875rem;
  }

  .switch[data-size="sm"] .switch__input:checked + .switch__track .switch__thumb {
    inset-inline-start: calc(100% - 0.875rem - 0.125rem);
  }


  /* ========================================
     VALIDATION STATES
     Clear feedback
     ======================================== */

  /* Valid/Success state */
  input[data-valid],
  textarea[data-valid],
  select[data-valid],
  .form-group[data-valid] input,
  .form-group[data-valid] textarea,
  .form-group[data-valid] select {
    border-color: var(--color-success);
  }

  /* Invalid/Error state */
  input[data-invalid],
  textarea[data-invalid],
  select[data-invalid],
  input[aria-invalid="true"],
  textarea[aria-invalid="true"],
  select[aria-invalid="true"],
  .form-group[data-invalid] input,
  .form-group[data-invalid] textarea,
  .form-group[data-invalid] select {
    border-color: var(--color-error);
    border-inline-start-width: calc(var(--border-width) * 4);
  }

  /* Browser validation shows only after someone has edited or submitted the
     field (:user-invalid). The old :invalid:not(:placeholder-shown) only
     waited on fields with a placeholder, so an empty required field without
     one was red on page load (the Fluid Stack's sign-up form, 2026-10-09).
     Separate rules: a browser without :user-invalid drops only these. */
  :is(input, textarea, select):user-invalid {
    border-color: var(--color-error);
    border-inline-start-width: calc(var(--border-width) * 4);
  }

  /* An invalid field says so twice: the error colour and a heavy start
     edge, so the state survives where the colour cannot be seen (on an
     accent-strong band --color-error is --on-accent, the resting edge's
     colour too). Focus adds the base outline (base.css) on top. */


  /* ========================================
     FORM LAYOUT
     Multi-column forms
     ======================================== */

  .form-row {
    display: grid;
    gap: var(--space-5);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  }

  .form-actions {
    display: flex;
    gap: var(--space-3);
    margin-block-start: var(--space-6);
    padding-block-start: var(--space-6);
    border-block-start: var(--border-width) solid var(--color-border);
  }

  .form-actions[data-align="end"] {
    justify-content: flex-end;
  }

  .form-actions[data-align="between"] {
    justify-content: space-between;
  }


  /* FIELDSET: .form-fieldset is the base fieldset (no box, a top hairline,
     the legend in the label voice; base.css). */


  /* ========================================
     REDUCED MOTION
     ======================================== */

  /* Accessibility: reduced motion */
  /* Reduced motion: the reset shortens every transition. */
}


/* ========================================
   HONEYPOT AND CONDITIONAL FIELDS
   Functional rules the day-one forms depend on (the-fluid-stack
   playbook forms.md D26c, security.md "Forms"). In @layer utilities,
   like .sr-only, so they outrank a child theme in @layer themes (a
   child theme outside a layer, or with !important, still wins).
   ======================================== */
@layer utilities {
  /* <div class="form-group hp" aria-hidden="true"> around
     <input name="website" tabindex="-1" autocomplete="off">, last in the
     form. Clipped to a 1px box where it stands, like .sr-only. A -10000px
     offset scrolled the page sideways: a physical one on any RTL page, a
     logical (inline-start) one whenever the form's direction differed
     from the page's. display: block stops a theme's display: contents
     from undoing it. */
  .hp {
    display: block;
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* A field with data-show-if="<reason>" (space-separated for several)
     shows only while its form's select[name="reason"] has that value
     (forms.md pattern 7). No script. revert-layer hands display back to
     the component or child theme. Without :has() every field shows, which
     is safe. A field this rule hides must never block the submit: never
     required, and no constraint a hidden value can fail (no type=number,
     email or url, pattern, min, max, step or minlength; use type="text"
     inputmode="numeric" and check it on the server, forms.md pattern 2).
     Option values must be these exact lowercase words. */
  @supports selector(:has(*)) {
    form:has(select[name="reason"]) [data-show-if] { display: none; }
    form:has(select[name="reason"] option[value="advertise"]:checked) [data-show-if~="advertise"],
    form:has(select[name="reason"] option[value="partner"]:checked) [data-show-if~="partner"],
    form:has(select[name="reason"] option[value="buy-site"]:checked) [data-show-if~="buy-site"],
    form:has(select[name="reason"] option[value="buy-domain"]:checked) [data-show-if~="buy-domain"],
    form:has(select[name="reason"] option[value="hire"]:checked) [data-show-if~="hire"],
    form:has(select[name="reason"] option[value="other"]:checked) [data-show-if~="other"] {
      display: revert-layer;
    }
  }
}
