/* ==========================================================================
 * Kulima Accessibility & Offline-UI Foundation — Phase 20
 * --------------------------------------------------------------------------
 * AgroDB / Kulima FMIS — multi-tenant farm management for Uganda's agriculture,
 * used on low-end devices and in the field on intermittent connectivity.
 *
 * This file LAYERS ON TOP of the Phase 18 tokens (kulima-tokens.css) and the
 * thin helper layer (kulima-theme.css). It MUST load AFTER both of them. It is
 * additive and opt-in by design: it adds accessibility primitives (visually
 * hidden text, a focus-revealed skip link, a stronger focus-ring fallback), an
 * offline/online status banner style, opt-in minimum touch-target utilities,
 * and a few mobile-first responsive helpers. It does NOT restyle existing
 * Bootstrap/APEX components, so existing pages keep their current look.
 *
 * Everything here reuses the Phase 18 custom properties (--kulima-*). No new
 * colour literals are introduced except where a token does not exist for the
 * purpose (e.g. the offline banner reuses the warning role). No "!important"
 * storms — the single guarded !important is the reduced-motion safety valve,
 * matching the pattern already established in kulima-theme.css §9.
 *
 * WCAG 2.2 AA intent addressed here (see docs/accessibility/):
 *   - 2.4.1 Bypass Blocks            -> .kulima-skip-link
 *   - 2.4.7 Focus Visible / 2.4.11   -> :focus-visible fallback (defence in depth
 *                                       over the Phase 18 ring)
 *   - 1.3.1 Info & Relationships     -> .visually-hidden names for landmarks/icons
 *   - 4.1.3 Status Messages          -> .kulima-offline-banner (aria-live region)
 *   - 2.5.8 Target Size (Minimum)    -> .kulima-tap / .kulima-tap--comfy
 *   - 1.4.10 Reflow                  -> mobile-first responsive helpers
 *   - 2.3.3 Animation from Interactions (AAA, house floor) -> reduced-motion guard
 * ========================================================================== */

/* --------------------------------------------------------------------------
 * 1. Visually-hidden text (a.k.a. .sr-only).
 * Removes content from the visual layout while keeping it in the accessibility
 * tree for screen readers. Used for landmark/icon-only accessible names and as
 * the resting state of the skip link. The clip-rect technique is the portable
 * one that works on the low-end / older mobile browsers common in the field.
 * Both class names are provided so existing Bootstrap markup (.sr-only) and new
 * markup (.visually-hidden) resolve to the same behaviour.
 * ------------------------------------------------------------------------ */
.visually-hidden,
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* The focusable variant reveals itself when it (or a descendant) gains focus —
 * this is exactly what the "Skip to main content" link needs: invisible until a
 * keyboard user Tabs to it, then shown. */
.visually-hidden-focusable:not(:focus):not(:focus-within),
.sr-only-focusable:not(:focus):not(:focus-within) {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* --------------------------------------------------------------------------
 * 2. Skip link (WCAG 2.4.1 Bypass Blocks).
 * Rendered as the first focusable element in header.php. Off-screen until
 * focused, then it animates onto the top-left so a keyboard/screen-reader user
 * can jump straight past the navbar and menu to #main-content.
 * ------------------------------------------------------------------------ */
.kulima-skip-link {
  position: absolute;
  top: var(--kulima-space-2, 0.5rem);
  left: var(--kulima-space-2, 0.5rem);
  z-index: var(--kulima-z-toast, 1300); /* above the fixed navbar + menu */
  display: inline-flex;
  align-items: center;
  min-height: var(--kulima-touch-target-min, 44px);
  padding: var(--kulima-space-2, 0.5rem) var(--kulima-space-4, 1rem);
  background-color: var(--kulima-color-primary, #1f7340);
  color: var(--kulima-color-on-primary, #fcfdfc);
  font-family: var(--kulima-font-heading, system-ui, sans-serif);
  font-weight: var(--kulima-font-weight-semibold, 600);
  font-size: var(--kulima-font-size-sm, 0.9375rem);
  line-height: 1.2;
  text-decoration: none;
  border-radius: var(--kulima-radius-md, 0.5rem);
  box-shadow: var(--kulima-shadow-md, 0 4px 10px rgba(0, 0, 0, 0.2));
  /* Hidden off-screen until focused (does not reserve layout space). */
  transform: translateY(-150%);
  transition: transform var(--kulima-motion-base, 200ms)
    var(--kulima-easing-standard, ease);
}
.kulima-skip-link:focus,
.kulima-skip-link:focus-visible {
  transform: translateY(0);
}

/* --------------------------------------------------------------------------
 * 3. Focus-visible fallback (defence in depth over kulima-theme.css §1).
 * kulima-theme.css already defines a :focus-visible ring. This repeats a floor
 * so that even if a later/legacy stylesheet strips an outline, keyboard focus
 * stays perceivable at >=3:1 (WCAG 2.4.7 / 2.4.11). scroll-margin keeps a
 * focused target clear of the fixed header (2.4.11 focus-not-obscured).
 * ------------------------------------------------------------------------ */
.kulima-focus-ring:focus-visible,
a.kulima-skip-link:focus-visible {
  outline: 3px solid var(--kulima-color-focus, #2f8d50);
  outline-offset: 2px;
}

/* Keep keyboard-focused anchors/buttons from hiding under the fixed navbar. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  scroll-margin-top: calc(var(--kulima-space-8, 4rem) + var(--kulima-space-4, 1rem));
}

/* --------------------------------------------------------------------------
 * 4. Connection and sync banner (WCAG 4.1.3 Status Messages, 1.4.1).
 * Markup in includes/header.php; js/kulima-offline.js renders it from the
 * offline outbox. Hidden via [hidden] when there is nothing to say. The message
 * line is the aria-live region. Every tone pairs a colour with an icon and a
 * sentence, so state never rests on colour alone. Tones:
 *   offline   amber   - no connection (with or without changes waiting)
 *   pending   raised  - changes waiting, online
 *   syncing   raised  - sending now
 *   attention red     - the server refused a change, or a newer version won
 *   done      green   - everything sent (shown for a few seconds)
 * ------------------------------------------------------------------------ */
.kulima-offline-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--kulima-z-toast, 1300);
  max-height: 70vh;
  overflow-y: auto;
  padding: var(--kulima-space-2, 0.5rem) var(--kulima-space-4, 1rem);
  background-color: var(--kulima-color-surface-raised, #f5f8f5);
  color: var(--kulima-color-text, #1d231f);
  border-top: 1px solid var(--kulima-color-border-strong, #8a978e);
  font-family: var(--kulima-font-body, system-ui, sans-serif);
  font-size: var(--kulima-font-size-sm, 0.9375rem);
  line-height: 1.4;
  box-shadow: var(--kulima-shadow-lg, 0 -4px 12px rgba(0, 0, 0, 0.2));
}
.kulima-offline-banner--offline {
  background-color: var(--kulima-color-warning, #8f6305);
  color: var(--kulima-color-on-warning, #fcfdfc);
  border-top-color: var(--kulima-amber-900, #5f4100);
}
.kulima-offline-banner--attention {
  background-color: var(--kulima-color-danger-subtle, #f9dcd8);
  color: var(--kulima-red-700, #8a2318);
  border-top-color: var(--kulima-color-danger, #a52a1e);
}
.kulima-offline-banner--done {
  background-color: var(--kulima-color-success-subtle, #d6ecdb);
  color: var(--kulima-green-900, #10331d);
  border-top-color: var(--kulima-color-success, #1f7340);
}
.kulima-offline-banner__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--kulima-space-2, 0.5rem) var(--kulima-space-3, 0.75rem);
  max-width: 72rem;
  margin: 0 auto;
}
.kulima-offline-banner__icon {
  flex: 0 0 auto;
  font-size: 1.25em;
  line-height: 1;
}
.kulima-offline-banner__text {
  flex: 1 1 16rem;
  margin: 0;
  font-weight: var(--kulima-font-weight-semibold, 600);
}
.kulima-offline-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kulima-space-2, 0.5rem);
}
/* 48px tall: these are used outdoors, one-handed (WCAG 2.5.8 + field use). */
.kulima-offline-banner__action {
  min-height: var(--kulima-touch-target-comfy, 48px);
  min-width: var(--kulima-touch-target-comfy, 48px);
  padding: 0 var(--kulima-space-4, 1rem);
  border: 2px solid currentColor;
  border-radius: var(--kulima-radius-md, 0.5rem);
  background-color: var(--kulima-color-primary, #1f7340);
  border-color: var(--kulima-color-primary, #1f7340);
  color: var(--kulima-color-on-primary, #fcfdfc);
  font: inherit;
  font-weight: var(--kulima-font-weight-bold, 700);
  cursor: pointer;
}
.kulima-offline-banner__action:hover {
  background-color: var(--kulima-color-primary-hover, #185c33);
}
.kulima-offline-banner__action--quiet {
  background-color: transparent;
  border-color: currentColor;
  color: inherit;
}
.kulima-offline-banner__action--quiet:hover {
  background-color: rgba(0, 0, 0, 0.06);
}
.kulima-offline-banner__action:focus-visible,
.kulima-offline-banner__link:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 2px;
}
.kulima-offline-banner__details {
  max-width: 72rem;
  margin: var(--kulima-space-2, 0.5rem) auto 0;
  padding-top: var(--kulima-space-2, 0.5rem);
  border-top: 1px solid currentColor;
}
.kulima-offline-banner__heading {
  margin: var(--kulima-space-2, 0.5rem) 0 var(--kulima-space-1, 0.25rem);
  font-family: var(--kulima-font-heading, inherit);
  font-size: var(--kulima-font-size-sm, 0.9375rem);
  font-weight: var(--kulima-font-weight-bold, 700);
  color: inherit;
}
.kulima-offline-banner__list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.kulima-offline-banner__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--kulima-space-1, 0.25rem) var(--kulima-space-3, 0.75rem);
  padding: var(--kulima-space-1, 0.25rem) 0;
}
.kulima-offline-banner__item p {
  flex: 1 1 18rem;
  margin: 0;
}
.kulima-offline-banner__link {
  min-height: var(--kulima-touch-target-min, 44px);
  padding: 0 var(--kulima-space-3, 0.75rem);
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-weight: var(--kulima-font-weight-bold, 700);
  text-decoration: underline;
  cursor: pointer;
}
/* The [hidden] attribute is the source of truth for visibility; make sure no
 * display rule accidentally overrides the native hidden behaviour. */
.kulima-offline-banner[hidden],
.kulima-offline-banner [hidden] {
  display: none;
}
@media (prefers-reduced-motion: no-preference) {
  .kulima-offline-banner--syncing .kulima-offline-banner__icon {
    animation: kulima-sync-turn 1.2s linear infinite;
  }
}
@keyframes kulima-sync-turn {
  to { transform: rotate(360deg); }
}

/* While the banner shows, pad the page so the fixed banner never hides the
 * footer or a focused control at the very bottom of the page. */
body.kulima-is-offline,
body.kulima-has-sync-banner {
  padding-bottom: calc(var(--kulima-touch-target-comfy, 48px) + var(--kulima-space-5, 1.5rem));
}

/* --------------------------------------------------------------------------
 * 5. Minimum touch-target utilities (WCAG 2.5.8; field-use ergonomics).
 * Opt-in, scoped names so they never collide with Bootstrap. These complement
 * the .kulima-touch helper in kulima-theme.css; .kulima-tap is the terse alias
 * intended to be dropped onto existing nav links / icon buttons without
 * changing their visual box beyond enforcing a tappable minimum.
 * ------------------------------------------------------------------------ */
.kulima-tap {
  min-height: var(--kulima-touch-target-min, 44px);
  min-width: var(--kulima-touch-target-min, 44px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.kulima-tap--comfy {
  min-height: var(--kulima-touch-target-comfy, 48px);
  min-width: var(--kulima-touch-target-comfy, 48px);
}

/* Opt-in: enforce tappable minimums on nav links inside a container that adds
 * this class. Kept behind a class so the global navbar is not restyled unless a
 * page/author chooses it. */
.kulima-nav-tappable .nav-link,
.kulima-nav-tappable .dropdown-item {
  min-height: var(--kulima-touch-target-min, 44px);
  display: flex;
  align-items: center;
}

/* --------------------------------------------------------------------------
 * 6. Responsive helpers for small / low-end screens (WCAG 1.4.10 Reflow).
 * Mobile-first: base rules target the phone, @media (min-width) layers up. Values
 * align with the Phase 18 breakpoint tokens (documented in kulima-tokens.css).
 * ------------------------------------------------------------------------ */

/* Show only on small screens; hide from >=768px (Bootstrap md). */
.kulima-show-sm-only {
  display: block;
}
/* Hide on small screens; reveal from >=768px. */
.kulima-hide-sm-only {
  display: none;
}

@media (min-width: 768px) {
  .kulima-show-sm-only {
    display: none;
  }
  .kulima-hide-sm-only {
    display: block;
  }
}

/* A content container that stays readable and never forces horizontal scroll at
 * 320px / 200% zoom. Opt-in wrapper for new field forms. */
.kulima-fluid {
  width: 100%;
  max-width: 100%;
  overflow-wrap: break-word;
  word-break: break-word;
}

/* Let wide data tables scroll on their own axis instead of breaking the page
 * layout at narrow widths (2D content is the sanctioned reflow exception). */
.kulima-table-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* --------------------------------------------------------------------------
 * 7. Reduced-motion guard for the Phase 20 additions.
 * Mirrors kulima-theme.css §9: honour Reduce Motion (WCAG 2.3.3, AAA house
 * floor) for the skip link and offline banner transitions.
 * ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .kulima-skip-link,
  .kulima-offline-banner {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* --------------------------------------------------------------------------
 * 9. Contrast corrections for the APEX template colours (WCAG 1.4.3, 1.4.11).
 * Phase 20 automated pass (tools/a11y/axe-audit.mjs) measured these failures on
 * the rendered pages: APEX purple #975AFF buttons/text (4.0:1 and 3.75:1),
 * APEX success #40C057 with white text (2.4:1) and APEX .text-muted #BDBDBD
 * (1.8:1). The APEX build is Bootstrap 4 with hard-coded colours (it ignores
 * --bs-* variables), so the bridge cannot reach them; these rules re-point them
 * to Kulima roles. APEX marks its utilities !important, so the overrides must
 * too.
 * ------------------------------------------------------------------------ */
.text-muted {
  color: var(--kulima-color-text-muted, #6f7d74) !important;
}
.text-primary {
  color: var(--kulima-color-primary, #1f7340) !important;
}
.bg-primary,
.badge-primary {
  background-color: var(--kulima-color-primary, #1f7340) !important;
  color: var(--kulima-color-on-primary, #fcfdfc);
}
.badge-success,
.bg-success {
  background-color: var(--kulima-color-success, #1f7340) !important;
  color: var(--kulima-color-on-success, #fcfdfc);
}
.btn-primary,
.btn-success {
  background-color: var(--kulima-color-primary, #1f7340);
  border-color: var(--kulima-color-primary, #1f7340);
  color: var(--kulima-color-on-primary, #fcfdfc);
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active,
.btn-success:hover,
.btn-success:focus,
.btn-success:not(:disabled):not(.disabled):active {
  background-color: var(--kulima-color-primary-hover, #185c33);
  border-color: var(--kulima-color-primary-hover, #185c33);
  color: var(--kulima-color-on-primary, #fcfdfc);
}
.btn-outline-primary {
  color: var(--kulima-color-primary, #1f7340);
  border-color: var(--kulima-color-primary, #1f7340);
}
.btn-outline-primary:hover {
  background-color: var(--kulima-color-primary, #1f7340);
  color: var(--kulima-color-on-primary, #fcfdfc);
}
/* Shared footer: copyright text and link on the APEX footer grey. */
.footer,
.footer .text-muted {
  color: var(--kulima-color-text-muted, #6f7d74) !important;
}
.footer a {
  color: var(--kulima-color-link, #185c33);
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
 * 10. Touch targets on phones (WCAG 2.5.8 floor; 44-48px field target).
 * .kulima-touch-target was defined as a token but never applied. Below the
 * tablet breakpoint every standalone control gets the 44px minimum; inline
 * links inside running text are exempt (2.5.8 exception).
 * ------------------------------------------------------------------------ */
.kulima-touch-target {
  min-height: var(--kulima-touch-target-comfy, 48px);
  min-width: var(--kulima-touch-target-comfy, 48px);
}
@media (max-width: 767.98px) {
  /* Centre labels in the taller buttons. The template hides some buttons with
   * a class-level display:none (e.g. .scroll-top until the page scrolls), so
   * those are left alone rather than forced visible. */
  .btn:not(.scroll-top):not(.d-none):not([hidden]) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kulima-space-1, 0.25rem);
  }
  .btn-block:not(.d-none):not([hidden]) {
    display: flex;
  }
  .btn,
  .form-control,
  .custom-select,
  select,
  .page-link,
  .nav-link,
  .dropdown-item {
    min-height: var(--kulima-touch-target-min, 44px);
  }
  .btn-sm,
  .btn-group-sm > .btn {
    min-height: var(--kulima-touch-target-min, 44px);
    min-width: var(--kulima-touch-target-min, 44px);
  }
  input[type="checkbox"],
  input[type="radio"] {
    min-width: 24px;
    min-height: 24px;
  }
}

/* Form text: APEX sets #75787D on white (4.4:1); use the body text role. */
.form-control,
.custom-select {
  color: var(--kulima-color-text, #1d231f);
}
.form-control::placeholder {
  color: var(--kulima-color-text-muted, #6f7d74);
  opacity: 1;
}

/* APEX status colours with white text measured 2.6-3.5:1 (warning #F77E17,
 * danger #F55252, info #2F8BE6) and purple tab text 4.0:1; re-pointed to the
 * Kulima status roles, which carry white text at 5.3:1 or better. */
.btn-warning,
.btn-danger,
.btn-info,
.alert-danger,
.alert-info {
  color: var(--kulima-color-on-primary, #fcfdfc);
}
.btn-warning { background-color: var(--kulima-color-warning, #8f6305); border-color: var(--kulima-color-warning, #8f6305); }
.btn-danger { background-color: var(--kulima-color-danger, #a52a1e); border-color: var(--kulima-color-danger, #a52a1e); }
.btn-info { background-color: var(--kulima-color-info, #205677); border-color: var(--kulima-color-info, #205677); }
/* colors.css paints alerts with !important solid fills. */
.alert-danger { background-color: var(--kulima-color-danger, #a52a1e) !important; border-color: var(--kulima-color-danger, #a52a1e) !important; }
.alert-info { background-color: var(--kulima-color-info, #205677) !important; border-color: var(--kulima-color-info, #205677) !important; }
.btn-warning:hover,
.btn-warning:focus { background-color: var(--kulima-amber-900, #5f4100); border-color: var(--kulima-amber-900, #5f4100); color: var(--kulima-color-on-primary, #fcfdfc); }
.btn-danger:hover,
.btn-danger:focus { background-color: var(--kulima-red-700, #8a2318); border-color: var(--kulima-red-700, #8a2318); color: var(--kulima-color-on-primary, #fcfdfc); }
.btn-info:hover,
.btn-info:focus { background-color: var(--kulima-blue-700, #205677); filter: brightness(0.9); color: var(--kulima-color-on-primary, #fcfdfc); }
.text-info { color: var(--kulima-color-info, #205677) !important; }
.text-warning { color: var(--kulima-color-warning, #8f6305) !important; }
.text-danger { color: var(--kulima-color-danger, #a52a1e) !important; }
.text-success { color: var(--kulima-color-success, #1f7340) !important; }
.nav-tabs .nav-link,
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link,
.nav-pills .nav-link {
  color: var(--kulima-color-link, #185c33);
}
.nav-tabs .nav-link.active {
  border-bottom-color: var(--kulima-color-primary, #1f7340);
}
.page-item.disabled .page-link {
  color: var(--kulima-color-text-muted, #576359);
}

/* Spinning icon for "working…" states (replaces Font Awesome's fa-spin after
 * the admin pages moved to Bootstrap Icons). Still when Reduce Motion is on. */
@media (prefers-reduced-motion: no-preference) {
  .kulima-spin {
    display: inline-block;
    animation: kulima-sync-turn 1s linear infinite;
  }
}
