/* ============================================================================
   Form controls — IntellSchool ERP shell
   ----------------------------------------------------------------------------
   WHY THIS EXISTS — the bundled form components render every control with one
   shared Tailwind base string:

       focus:border-primary block w-full border-0 border-gray-300 bg-inherit
       focus:ring-0 ... border-b-2

   i.e. a Material-style *underline*: no box, no radius, transparent fill. In a
   dense Arabic data-entry screen that reads as a page of floating lines — the
   hit target is invisible until you look for the rule under it, and a select
   is indistinguishable from a text field because the app renders selects as an
   <input> with a chevron overlaid, sharing that exact base string.

   This file re-houses those controls in a box: a real border, a radius, a
   filled surface, and a focus state you can see from across the room. The
   bundle is a prebuilt vendor artifact with no source or build step in this
   repo, so it is overridden here rather than edited — the same approach the
   other files in public/custom already take.

   HOOK — `[class*="focus:border-primary"]` matches every variant of that base
   string (plain, `border-b-2`, `rounded-md shadow-xs`, `bg-transparent pl-10`)
   and nothing else in the app. Padding is deliberately NOT set: the base gives
   8px/12px, and icon variants add `pl-10`/`pr-10` for their leading glyph.
   Overriding the shorthand would collapse those icons onto the text.

   Heights are left at the bundle's 38px so nothing reflows — this is a change
   of surface, not of layout.
   ========================================================================== */

#root {
    --fx-field-bg: #f8f7fb;
    --fx-field-bg-focus: #ffffff;
    --fx-field-border: #dcd8e6;
    --fx-field-border-hover: #c2b9d6;
    --fx-field-radius: 8px;
    --fx-field-ring: rgba(51, 15, 87, 0.14);
    --fx-field-disabled-bg: #eeecf2;
    --fx-field-disabled-text: #8b8698;
}

/* Tinted rather than neutral grey: the border picks up the brand purple so the
   fields sit in the same family as the sidebar instead of reading as a generic
   admin theme dropped on top of it. */
@supports (color: color-mix(in oklab, red, red)) {
    #root {
        --fx-field-ring: color-mix(in oklab, var(--color-primary, #330f57) 16%, transparent);
    }
}

.dark #root,
#root .dark {
    --fx-field-bg: rgba(255, 255, 255, 0.04);
    --fx-field-bg-focus: rgba(255, 255, 255, 0.07);
    --fx-field-border: rgba(255, 255, 255, 0.14);
    --fx-field-border-hover: rgba(255, 255, 255, 0.26);
    --fx-field-disabled-bg: rgba(255, 255, 255, 0.03);
    --fx-field-disabled-text: rgba(255, 255, 255, 0.38);
}

/* --------------------------------------------------------------------------
   1. The box
   -------------------------------------------------------------------------- */

#root :is(input, select, textarea)[class*="focus:border-primary"] {
    border: 1px solid var(--fx-field-border);
    border-radius: var(--fx-field-radius);
    background-color: var(--fx-field-bg);
    box-shadow: none;
    transition:
        border-color 140ms ease,
        box-shadow 140ms ease,
        background-color 140ms ease;
}

#root :is(input, select, textarea)[class*="focus:border-primary"]:hover:not(:focus):not(:disabled):not([readonly]) {
    border-color: var(--fx-field-border-hover);
}

/* One ring, brand-coloured, drawn outside the border so the field does not
   change size on focus. `focus:ring-0` in the base string zeroes Tailwind's own
   ring; this replaces it rather than fighting it. */
#root :is(input, select, textarea)[class*="focus:border-primary"]:focus {
    border-color: var(--color-primary, #330f57);
    background-color: var(--fx-field-bg-focus);
    box-shadow: 0 0 0 3px var(--fx-field-ring);
    outline: none;
}

.dark #root :is(input, select, textarea)[class*="focus:border-primary"]:focus {
    border-color: rgba(226, 167, 255, 0.72);
}

#root :is(input, select, textarea)[class*="focus:border-primary"]:disabled,
#root :is(input, select, textarea)[class*="focus:border-primary"][readonly]:not([role="combobox"]) {
    border-color: var(--fx-field-border);
    background-color: var(--fx-field-disabled-bg);
    color: var(--fx-field-disabled-text);
    cursor: not-allowed;
}

/* Placeholders sit one step back from entered values so a filled form reads
   differently from an empty one at a glance. */
#root :is(input, textarea)[class*="focus:border-primary"]::placeholder {
    color: #a7a2b5;
    opacity: 1;
}

.dark #root :is(input, textarea)[class*="focus:border-primary"]::placeholder {
    color: rgba(255, 255, 255, 0.34);
}

/* --------------------------------------------------------------------------
   2. Textarea — the bundle leaves it at input height with a free resize grip,
      which is why the description box renders as a one-line field with a
      stray handle. Give it room and constrain resizing to one axis so it
      cannot be dragged out over the layout.
   -------------------------------------------------------------------------- */

#root textarea[class*="focus:border-primary"] {
    min-height: 88px;
    padding-block: 10px;
    line-height: 1.65;
    resize: vertical;
}

/* --------------------------------------------------------------------------
   3. Select affordance
      The app renders a select as an <input> with a chevron in an absolutely
      positioned, pointer-events-none overlay — visually identical to a text
      field. `:has()` picks out only the overlays holding a chevron (leading
      icons on text inputs use the same wrapper class), and turns that corner
      into a tinted well so a dropdown announces itself as one.
      Browsers without :has() simply keep the current look.
   -------------------------------------------------------------------------- */

#root div.relative > div.absolute:has(> .fa-chevron-down, > i.fa-caret-down, > svg) {
    border-radius: 0 var(--fx-field-radius) var(--fx-field-radius) 0;
    background: linear-gradient(to left, rgba(51, 15, 87, 0.06), transparent);
    color: var(--color-primary, #330f57);
    pointer-events: none;
}

[dir="ltr"] #root div.relative > div.absolute:has(> .fa-chevron-down, > i.fa-caret-down, > svg) {
    border-radius: var(--fx-field-radius) 0 0 var(--fx-field-radius);
    background: linear-gradient(to right, rgba(51, 15, 87, 0.06), transparent);
}

.dark #root div.relative > div.absolute:has(> .fa-chevron-down, > i.fa-caret-down, > svg) {
    background: linear-gradient(to left, rgba(255, 255, 255, 0.07), transparent);
    color: #e9ddf2;
}

/* Native selects, wherever the app still uses one. */
#root select[class*="focus:border-primary"] {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23330f57' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: left 12px center;
    background-size: 14px;
    padding-inline-end: 34px;
}

[dir="ltr"] #root select[class*="focus:border-primary"] {
    background-position: right 12px center;
}

/* --------------------------------------------------------------------------
   4. Labels
      The label is a sibling of the control wrapper, so :has() can light it up
      while its own field has focus. In a 12-field form that is the cheapest
      possible "you are here" — no extra markup, no JS.
   -------------------------------------------------------------------------- */

#root label.text-label {
    margin-bottom: 6px;
    font-weight: 600;
    letter-spacing: 0;
    transition: color 140ms ease;
}

#root label.text-label:has(+ div :is(input, select, textarea):focus) {
    color: var(--color-primary, #330f57);
}

.dark #root label.text-label:has(+ div :is(input, select, textarea):focus) {
    color: #e2a7ff;
}

/* --------------------------------------------------------------------------
   5. Choice controls — 16px is below the 24px comfortable target for a
      mouse-driven admin tool, and the brand tick reads better than the default.
   -------------------------------------------------------------------------- */

#root input[type="checkbox"][class*="text-primary"],
#root input[type="radio"][class*="text-primary"] {
    width: 1.125rem;
    height: 1.125rem;
    border-color: var(--fx-field-border-hover);
    border-radius: 5px;
    transition:
        border-color 140ms ease,
        box-shadow 140ms ease;
}

#root input[type="radio"][class*="text-primary"] {
    border-radius: 50%;
}

#root :is(input[type="checkbox"], input[type="radio"])[class*="text-primary"]:focus-visible {
    box-shadow: 0 0 0 3px var(--fx-field-ring);
    outline: none;
}

/* --------------------------------------------------------------------------
   6. Validation
      The bundle colours the message but leaves the field itself untouched, so
      on a long form the invalid control is only findable by reading every
      caption. Tie the box to its error.
   -------------------------------------------------------------------------- */

#root :is(input, select, textarea)[class*="focus:border-primary"][aria-invalid="true"],
#root :is(input, select, textarea)[class*="border-red"],
#root :is(input, select, textarea)[class*="focus:border-primary"].is-invalid {
    border-color: var(--color-danger, #e11d48);
    background-color: rgba(225, 29, 72, 0.04);
}

#root :is(input, select, textarea)[class*="focus:border-primary"][aria-invalid="true"]:focus {
    border-color: var(--color-danger, #e11d48);
    box-shadow: 0 0 0 3px rgba(225, 29, 72, 0.16);
}

/* --------------------------------------------------------------------------
   7. Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    #root :is(input, select, textarea)[class*="focus:border-primary"],
    #root label.text-label {
        transition: none;
    }
}
