/* ==========================================================================
   Accessibility: contrast and legibility (WCAG 2.1 AA)

   Theme-agnostic on purpose. The active Metronic theme is a per-tenant/per-user
   setting, so there are 13 possible style bundles and 13 matching
   Common/Styles/Themes/{theme}/metronic-customize.less files. Putting these
   rules in any one of them fixes only the users who happen to be on that theme.
   This file is linked from the layouts AFTER the Styles razor section, which is
   where the theme bundle and its customize file render, so it wins the cascade
   no matter which theme is selected.

   Every value here is solved to >= 4.80:1 for text and >= 3.00:1 for control
   boundaries, against the worst background that combination actually faces.
   All 13 themes share the same semantic palette (verified against default and
   theme8), so one set of values covers them.

   Strategy: keep the brand fills as they are and fix the FOREGROUND on them.
   Darkening green/amber/red enough for white text to pass would turn the status
   tiles into dark olive and maroon; dark ink on the unchanged fills reaches
   7.94 / 10.70 / 4.67 instead, so the colour coding survives intact.

   Note: Themes/theme8/metronic-customize.less already carries earlier
   readability work (font scale, muted grays, table rules). Overlapping
   declarations here are deliberate and use the same intent, so theme8 users see
   no regression, and every other theme gains the same protection.
   ========================================================================== */
/* --- 1. Root font size ---------------------------------------------------
   Stock Metronic pins the root at 13px (12px under 768px) with !important, and
   theme8 raises it to 14px. All are below the 16px browser default, and because
   they are px + !important they also discard the user's own font-size
   preference. body carries its own `body, html` rule in the theme bundle, so
   overriding html alone leaves body text behind. */
body,
html {
  font-size: 16px !important;
}
@media (max-width: 991.98px) {
  body,
  html {
    font-size: 16px !important;
  }
}
@media (max-width: 767.98px) {
  body,
  html {
    font-size: 16px !important;
  }
}
/* --- 2. Muted text and the gray ramp -------------------------------------
   #99A1B7 on white is 2.58:1. It carries the member field labels and the KPI
   captions, so it has to read as body text, not decoration. Only the
   text-facing steps are remapped; gray-100..400 are left alone because they
   drive backgrounds and borders.

   Light: #636E8D is 5.07:1 on white and 4.81:1 on the gray-100 panels. The
   earlier theme8 value (#6C7293) passed on white at 4.70:1 but dropped to
   4.47:1 on those panels, so it is superseded here. */
:root,
[data-bs-theme="light"] {
  --bs-text-muted: #636E8D;
  --bs-gray-500: #636E8D;
  --bs-gray-600: #5E6278;
  /* 6.01:1, was #78829D at 3.83:1 */
  --bs-gray-700: #3F4254;
  /* 9.91:1, deepens body-adjacent text */
}
[data-bs-theme="dark"] {
  --bs-text-muted: #9A9CAE;
  /* 6.61:1 on #15171C, was #636674 at 3.14:1 */
  --bs-gray-500: #9A9CAE;
  --bs-gray-600: #A1A5B7;
}
/* Raise the floor on the smallest utility sizes Metronic uses in tables and
   labels. At a 16px root these land at 14.4px and 13.2px. */
.fs-8 {
  font-size: 0.9rem !important;
}
.fs-9 {
  font-size: 0.825rem !important;
}
/* --- 3. Semantic colours used AS TEXT ------------------------------------
   .text-*, .badge-light-* and .btn-light-* paint the brand colour onto a very
   light tint of itself: badge-light-warning is 1.58:1. Solved against the tint,
   which is the harder background, so the on-white case passes too. */
:root,
[data-bs-theme="light"] {
  --ilrp-a11y-primary-text: #0065DC;
  --ilrp-a11y-success-text: #0F7E35;
  --ilrp-a11y-warning-text: #886A00;
  --ilrp-a11y-danger-text: #D40738;
  --ilrp-a11y-info-text: #7239EA;
  --ilrp-a11y-control-border: #8794B6;
  --ilrp-a11y-surface-border: #C2C7D6;
}
[data-bs-theme="dark"] {
  --ilrp-a11y-primary-text: #2B8DFF;
  --ilrp-a11y-success-text: #00A261;
  --ilrp-a11y-warning-text: #C59A00;
  --ilrp-a11y-danger-text: #EB6081;
  --ilrp-a11y-info-text: #883FFF;
  --ilrp-a11y-control-border: #6E7385;
  --ilrp-a11y-surface-border: #3A3D48;
}
.text-primary {
  color: var(--ilrp-a11y-primary-text) !important;
}
.text-success {
  color: var(--ilrp-a11y-success-text) !important;
}
.text-warning {
  color: var(--ilrp-a11y-warning-text) !important;
}
.text-danger {
  color: var(--ilrp-a11y-danger-text) !important;
}
.text-info {
  color: var(--ilrp-a11y-info-text) !important;
}
.badge-light-primary,
.btn.btn-light-primary,
.btn.btn-light-primary i,
.btn.btn-light-primary .svg-icon {
  color: var(--ilrp-a11y-primary-text);
}
.badge-light-success,
.btn.btn-light-success,
.btn.btn-light-success i,
.btn.btn-light-success .svg-icon {
  color: var(--ilrp-a11y-success-text);
}
.badge-light-warning,
.btn.btn-light-warning,
.btn.btn-light-warning i,
.btn.btn-light-warning .svg-icon {
  color: var(--ilrp-a11y-warning-text);
}
.badge-light-danger,
.btn.btn-light-danger,
.btn.btn-light-danger i,
.btn.btn-light-danger .svg-icon {
  color: var(--ilrp-a11y-danger-text);
}
.badge-light-info,
.btn.btn-light-info,
.btn.btn-light-info i,
.btn.btn-light-info .svg-icon {
  color: var(--ilrp-a11y-info-text);
}
/* --- 4. Text on solid brand fills ----------------------------------------
   White on the stock green/amber/red is 2.27 / 1.69 / 3.86:1. The member
   dashboard status tiles are the worst case in the app. */
:root,
[data-bs-theme="light"] {
  --bs-success-inverse: #071437;
  --bs-warning-inverse: #071437;
  --bs-danger-inverse: #071437;
}
[data-bs-theme="dark"] {
  --bs-success-inverse: #071437;
  --bs-warning-inverse: #071437;
}
/* The member dashboard and Data Submissions Hub tiles hard-code .text-white in
   markup, which carries !important, so match on both classes and let
   specificity decide. */
.bg-success.text-white,
.bg-warning.text-white,
.bg-danger.text-white,
.bg-light-success.text-white,
.bg-light-warning.text-white,
.bg-light-danger.text-white {
  color: #071437 !important;
}
/* In dark mode the red fill reaches only 4.44:1 against white and 4.07:1
   against ink, so the fill itself is deepened and keeps white lettering. */
[data-bs-theme="dark"] .bg-danger {
  background-color: #C21742 !important;
}
[data-bs-theme="dark"] .bg-danger.text-white {
  color: #ffffff !important;
}
/* --- 5. Solid primary button --------------------------------------------
   White on #1B84FF is 3.63:1. The theme paints .btn.btn-primary with
   background-color: var(--bs-primary) directly, so setting --bs-btn-bg alone
   does nothing. Re-pointing the primary tokens inside the button makes every
   stock rule, including the !important hover, resolve to the darker blue,
   while links and accents elsewhere keep the lighter brand colour. */
.btn.btn-primary {
  --bs-primary: #0065DC;
  --bs-primary-active: #0057BE;
  --bs-btn-bg: #0065DC;
  --bs-btn-border-color: #0065DC;
  --bs-btn-hover-bg: #0057BE;
  --bs-btn-hover-border-color: #0057BE;
  --bs-btn-active-bg: #0057BE;
  --bs-btn-active-border-color: #0057BE;
}
/* --- 6. Control boundaries (WCAG 1.4.11, 3:1) ---------------------------
   Input and select borders were #DBDFE9 on white, 1.33:1. The -solid variants
   are two-class selectors and outrank a bare .form-control, and they are what
   the Account forms and most modals actually use. */
.form-control,
.form-select,
.form-check-input,
.input-group-text,
.form-control.form-control-solid,
.form-select.form-select-solid,
.input-group-text.input-group-solid {
  border-color: var(--ilrp-a11y-control-border);
  border-style: solid;
  border-width: 1px;
}
/* Card edges were #F1F1F4 on white, 1.13:1, with a 3% shadow doing no rescue
   work. Kept softer than controls so the page does not read as a wireframe. */
.card {
  border-color: var(--ilrp-a11y-surface-border);
}
/* Dashed row separators are 1.33:1. Solid and one step darker reads as a real
   grid line. Selector shape copied from the theme so specificity matches and
   load order decides. */
.table:not(.table-bordered).table-row-dashed tr {
  border-bottom-style: solid;
  border-bottom-color: var(--ilrp-a11y-surface-border);
}
/* The header band needs a stronger rule than the data rows to separate from
   them. The thead selector must carry .table-row-dashed too, otherwise the rule
   above outranks it on class count. */
.table:not(.table-bordered).table-row-dashed thead tr {
  border-bottom-width: 2px;
  border-bottom-color: var(--ilrp-a11y-control-border);
}
/* Progress bar fills are deliberately NOT remapped. The amber fill is only
   1.6:1 against its gray-100 track, but every bar in the app states its value
   in adjacent text: the Field Coverage widget renders
   "<assigned> / <total> Associated Acres (<n>%)" immediately above the bar, and
   adds a written warning when below target. That makes the bar a supplementary
   view of information already available as text, so 1.4.11 does not force 3:1
   on it. Darkening the fill to reach 3:1 turns amber into a dark olive that
   reads as "stale" rather than "incomplete", which is a real loss of meaning
   for a worse outcome. Left bright on purpose.

   If more definition is ever wanted here, darken the TRACK rather than the
   fill; amber sits too close to light grays in luminance for a light track to
   ever separate from it. */
/* --- 7. Focus visibility (WCAG 2.4.7) -----------------------------------
   The stock bundle emits `box-shadow:false,0 0 0 .25rem rgba(...)` on nine
   :focus rules. `false` is not a valid box-shadow value, so the whole
   declaration is dropped while the `outline:0` beside it survives, leaving text
   inputs, selects and checkboxes with no focus indicator at all. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
.form-control.form-control-solid:focus,
.form-select.form-select-solid:focus,
.form-control.is-valid:focus,
.form-select.is-valid:focus,
.form-control.is-invalid:focus,
.form-select.is-invalid:focus,
.was-validated .form-control:valid:focus,
.was-validated .form-select:valid:focus,
.was-validated .form-control:invalid:focus,
.was-validated .form-select:invalid:focus {
  border-color: var(--ilrp-a11y-primary-text);
  outline: 2px solid var(--ilrp-a11y-primary-text);
  outline-offset: 1px;
  box-shadow: 0 0 0 0.2rem rgba(0, 101, 220, 0.25);
}
/* Keyboard focus for everything else reachable by tab. */
a:focus-visible,
.btn:focus-visible,
.nav-link:focus-visible,
.page-link:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--ilrp-a11y-primary-text);
  outline-offset: 2px;
}
/* --- 8. Placeholder text --------------------------------------------------
   Placeholders default to --bs-gray-500 (#99A1B7), 2.45:1 against the solid
   field background. The Account forms ship no <label> elements at all, so the
   placeholder is the only thing naming the field and has to be readable. */
.form-control::placeholder,
.form-select::placeholder,
.form-control.form-control-solid::placeholder {
  color: var(--bs-text-muted);
  opacity: 1;
}
/* --- 9. Number field spinners (WCAG 2.5.5 target size, and data integrity) -
   Browsers paint a pair of stacked step arrows inside every input[type=number].
   They are roughly 8px tall each, sit directly under the pointer on the right
   edge of the field, and carry no label, so a click aimed at the field itself
   silently changes the value instead of placing the caret. Every money and
   acreage field in the app is a number input (parcel acres, line item quantity
   and unit price, payment amount, reporting year fees, the Data Submissions
   questionnaire), so a stray click there writes a wrong figure into a record
   that is later billed on.

   Applied to the bare element selector rather than a class so it also covers
   the inputs built at runtime (the FormBuilder preview, the PaymentBatch
   allocation rows, SingleLineStringInputType) and the stock ASP.NET Zero
   settings views, none of which carry an app-specific class.

   type=number is kept. It still gives the numeric keypad on mobile, browser
   range validation from min/max/step, and the up/down arrow keys, which are the
   deliberate keyboard affordance for a spinbutton and cannot be hit by a
   misclick. Only the pointer target is removed. Mouse wheel stepping is already
   neutralised app-wide in Common/Scripts/helpers.js, which blurs the field on
   wheel, so between that and this rule the value can only change from typing or
   an intentional key press. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}
/* Firefox, and Chromium 121+ / Safari, honour the standard property on the
   element itself. Safe alongside the pseudo-element rule above: .form-control
   sets its own background, border and radius, so nothing falls back to the
   native textfield look. */
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
