/* sl-form-fields.css
 * ---------------------------------------------------------------------------
 * ONE VISIBLE EDGE ON EVERY FORM FIELD IN THE APP.
 *
 * The app ships 1,919 text-like controls across the five signed-in shells.
 * 421 of them declared no border utility at all, so they rendered as
 * placeholder text floating on a white card with nothing to aim at:
 * "Add an appliance" on /dashboard/property-assets showed Type, Make, Model,
 * Serial number, Install date and Warranty expires as six grey words in a row,
 * and only the two enhanced selects beside them looked clickable.
 *
 * The other 1,475 were bordered, but by three near-identical greys that did
 * not agree with each other:
 *
 *     border-slate-300   859     #cbd5e1
 *     border-slate-200   517     #e2e8f0
 *     border-app-border  182     #e2e8f0
 *     border-hairline      4     #eef2f7
 *
 * Two things make the lighter rungs disappear in practice. The shells render
 * at `zoom: 0.9`, which thins a declared 1px hairline to roughly 0.74px before
 * the display scales it again, and the fields sit on a WHITE card rather than
 * on the ice-blue page canvas, so there is no surface contrast doing the work
 * for them. #e2e8f0 at 0.74px on #ffffff is close to nothing.
 *
 * --border-strong (#cbd5e1, tokens.css:165) is the rung that survives that,
 * and it is already the plurality choice in the markup, so this unifies onto
 * the majority rather than inventing a fourth grey. No new colour is declared
 * here (Rule 51).
 *
 * WHAT THIS FILE DELIBERATELY DOES NOT DO
 *
 *   - No background fill. A forced fill would paint over the handful of
 *     controls that live on dark cards, and the border alone is what was
 *     missing. Fills stay with the template.
 *   - No focus treatment. dashboard_base.html already owns a global focus
 *     halo and calendar.html:112 documents deferring to it.
 *   - No radius override that can win. The radius rule below is wrapped in
 *     :where(), which contributes zero specificity, so ANY declared
 *     `rounded-*` utility or component radius beats it. It exists only so
 *     that the 421 controls with no styling at all do not come out square
 *     next to their rounded neighbours.
 *
 * SCOPE. <main> is the obvious root and it is NOT enough on its own. The
 * shells render `{% block modals %}` AFTER `</main>`, so a page's dialogs are
 * body-level siblings: /dashboard/rent-collection has 48 controls and only 6
 * of them are inside main. The whole Add-charge sheet sits outside it. So the
 * root group below also names the dialog wrappers this app actually uses:
 *
 *     .es-scrim    the shared editor sheet, _editor_sheet.html
 *     .ltp-shell   calendar.html, accounting.html
 *     .lps-back    listing_published.html
 *     [role=dialog], dialog, and anything with "modal" in its id or class
 *
 * What stays out of range, on structure rather than on a class list: the
 * sidebar, the header, the Mozart bar and the global search box. The public
 * marketing shell does not link this file at all; only apply.html opts in,
 * because a renter filling a rental application is doing the same job as a
 * landlord filling any other form.
 *
 * HOVER AND FOCUS ARE NOT OURS. dashboard_base.html carries a global
 * `input:hover` / `input:focus` pair marked !important (the Gradient Halo,
 * DESIGN.md Forms), so it outranks everything here no matter the specificity.
 * That is deliberate: this file owns the RESTING edge and nothing else.
 */

/* Shape only, and it loses every tie on purpose. Both halves are wrapped in
   `:where()`, which contributes zero specificity, so this whole selector
   scores (0,0,0) and ANY declared radius beats it: a Tailwind `rounded-xl`, a
   component's own `border-radius: 1rem`, anything. It exists for one case
   only, the controls that carry no styling at all, so they do not come out
   square next to their rounded neighbours. */
:where(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) :where(
  input[type="text"], input[type="email"], input[type="tel"],
  input[type="number"], input[type="password"], input[type="url"],
  input[type="search"], input[type="date"], input[type="time"],
  input[type="datetime-local"], input[type="month"], input[type="week"],
  input:not([type]), select, textarea
) {
  border-radius: var(--radius-md, 8px);
}

/* The edge itself, and it wins every tie on purpose.
 *
 * The exclusion chain is not defensive padding, each entry is a control that
 * is SUPPOSED to look different and would be flattened otherwise:
 *
 *   .slus__native        the 1px clipped select behind an enhanced picker
 *   .sr-only, .hidden    helper selects in document_studio.html
 *   .mz-input            the Mozart composer, which owns its own chrome
 *   border-white/*       fields on dark cards (12 of them)
 *   border-slate-700     the same, one instance
 *   border-transparent   deliberate, 3 instances
 *   border-none, -0      deliberate, 5 instances
 *   border-b             underline-only fields, 2 instances
 *   border-rose/red      validation state, which must outrank a neutral grey
 *   border-indigo        one accent field
 */
:is(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) input:is(
  [type="text"], [type="email"], [type="tel"], [type="number"],
  [type="password"], [type="url"], [type="search"], [type="date"],
  [type="time"], [type="datetime-local"], [type="month"], [type="week"],
  :not([type])
):not(.slus__native):not(.sr-only):not(.hidden):not(.mz-input):not([class*="border-white/"]):not([class~="border-slate-700"]):not([class~="border-transparent"]):not([class~="border-none"]):not([class~="border-0"]):not([class~="border-b"]):not([class*="border-rose"]):not([class*="border-red"]):not([class*="border-indigo"]),
:is(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) select:not([multiple]):not(.slus__native):not(.sr-only):not(.hidden):not(.mz-input):not([class*="border-white/"]):not([class~="border-slate-700"]):not([class~="border-transparent"]):not([class~="border-none"]):not([class~="border-0"]):not([class~="border-b"]):not([class*="border-rose"]):not([class*="border-red"]):not([class*="border-indigo"]),
:is(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) textarea:not([multiple]):not(.slus__native):not(.sr-only):not(.hidden):not(.mz-input):not([class*="border-white/"]):not([class~="border-slate-700"]):not([class~="border-transparent"]):not([class~="border-none"]):not([class~="border-0"]):not([class~="border-b"]):not([class*="border-rose"]):not([class*="border-red"]):not([class*="border-indigo"]) {
  border-width: 1px;
  border-style: solid;
  border-color: var(--border-strong, #cbd5e1);
}

/* A disabled field still needs an edge, it just should not shout as loudly as
   the one the cursor is heading for. It drops one rung to --border rather than
   losing the border, because a field with no edge is the thing this file
   exists to stop. */
:is(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) input:disabled:not(.slus__native),
:is(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) select:disabled:not(.slus__native),
:is(main, dialog, [role="dialog"], .es-scrim, .ltp-shell, .lps-back, [class*="modal"], [id*="modal"]) textarea:disabled {
  border-color: var(--border, #e2e8f0);
}
