/* =========================================================================
   ADA ERP — design system token layer
   =========================================================================
   Loaded AFTER admin/css/style.css so it can redefine that file's custom
   properties. WowDash components reference var(--primary-600) rather than
   literal hex values, so overriding the ramp re-themes the whole application
   from here. The vendor stylesheet is never edited: there is no SCSS build
   step in this project, so a compiled-CSS edit would be unreviewable and
   impossible to regenerate.

   Reverting the theme = removing the <link> to this file.
   ========================================================================= */

:root {
  /* --- Primary ramp: violet, replacing WowDash blue -------------------- */
  --primary-50:  #F4F2FE;
  --primary-100: #E7E3FD;
  --primary-200: #D1CAFB;
  --primary-300: #B3A8F8;
  --primary-400: #9585F3;
  --primary-500: #7C68EC;
  --primary-600: #6C5CE7; /* 4.86:1 on white — AA for normal text */
  --primary-700: #5A48D0; /* 6.42:1 on white — use for body-size links */
  --primary-800: #4A3BAB;
  --primary-900: #3E338A;

  --primary-light: rgba(108, 92, 231, 0.15);
  --primary-light-white: rgba(108, 92, 231, 0.25);

  /* --- Accent, split by role -------------------------------------------
     --primary-600 was serving two contradictory jobs: a FILL that white text
     sits on, and TEXT that sits on a light ground. Those pull opposite ways
     when the theme inverts — the dark block lightened it for the text role,
     which dropped white-on-fill to 3.37:1 (measured).

     Two tokens, moving independently. Components use these, not --primary-600
     directly, wherever the role is one of the two. */
  --ada-accent-fill:     var(--primary-600);  /* white text sits ON this */
  --ada-accent-on-light: var(--primary-700);  /* this sits ON a light bg */
  /* Deep panel fill — the hero summary. White text and translucent white
     chips sit on it, so it must stay dark in BOTH themes. */
  --ada-accent-deep:     var(--primary-700);

  /* Bootstrap's own primary, so .btn-primary/.text-primary follow along.
     Bootstrap declares these in lib/bootstrap.min.css and builds rgba()
     values from the -rgb triplet, so both must move together. */
  --bs-primary: #6C5CE7;
  --bs-primary-rgb: 108, 92, 231;
  --bs-link-color: #5A48D0;
  --bs-link-hover-color: #4A3BAB;
  --bs-link-color-rgb: 90, 72, 208;

  /* --- ADA surfaces ---------------------------------------------------- */
  --ada-canvas:    #F3F2FE;  /* page background — lavender wash */
  --ada-surface:   #FFFFFF;  /* card background */
  --ada-surface-2: #F7F6FE;  /* recessed / inset panels */
  --ada-ink:       #1E1B3A;  /* 16.5:1 on white */
  --ada-ink-soft:  #5C5885;  /* 6.58:1 on white, 5.94:1 on canvas */
  /* Muted text still carries real content (dates, tile labels, queue meta),
     so it must clear 4.5:1 against the *canvas*, not just white — the canvas
     is the darker of the two. #6A6498 is the lightest value that does:
     4.87:1 on canvas, 5.40:1 on white. */
  --ada-ink-mute:  #6A6498;
  --ada-hairline:  #EDEBFB;
  /* Control and input borders. Distinct from --ada-hairline, which is for
     dividers: this one must read as an editable edge, so it carries more
     weight. Was hardcoded as #E3E0F5 in four places in ada-components.css. */
  --ada-border:    #E3E0F5;

  /* --- Spacing ----------------------------------------------------------
     4px grid. --ada-space-px is the one sanctioned sub-grid step, for optical
     nudges only (a 2px lift on a meta line, the gap inside a delta glyph) —
     never for layout. Anything structural uses 1..12.

     This existed only in my head for the first pass, which is how 23 distinct
     hand-picked values ended up in the layer. Values below are the scale. */
  --ada-space-px: 2px;
  --ada-space-1:  4px;
  --ada-space-2:  8px;
  --ada-space-3:  12px;
  --ada-space-4:  16px;
  --ada-space-5:  20px;
  --ada-space-6:  24px;
  --ada-space-7:  28px;
  --ada-space-8:  32px;
  --ada-space-10: 40px;
  --ada-space-12: 48px;

  /* --- Type scale -------------------------------------------------------
     Whole pixels only — half-pixel sizes round unpredictably across zoom
     levels and DPI, and three had crept in (11.5 / 12.5 / 13.5).

     Weights are restricted to 400/500/600/700. The layer previously used 650
     and 750: correct on dashboard pages, which get Inter's variable axis via
     style.css, but silently snapped to 700 on sign-in, which loads only the
     static 300–700 cut. Same markup, two different renderings. */
  --ada-text-xs:   11px;
  --ada-text-sm:   12px;
  --ada-text-base: 13px;
  --ada-text-md:   14px;
  --ada-text-lg:   16px;
  --ada-text-xl:   18px;
  --ada-text-2xl:  22px;
  /* Display steps, for the one hero figure a summary panel is allowed. Added
     when the property dashboard needed 36px: hand-picking a size outside the
     scale is exactly the drift the scale exists to stop. */
  --ada-text-3xl:  28px;
  --ada-text-4xl:  36px;

  --ada-weight-normal: 400;
  --ada-weight-medium: 500;
  --ada-weight-semi:   600;
  --ada-weight-bold:   700;

  /* --- Semantic state colours -------------------------------------------
     Until now these existed only as per-utility overrides in
     ada-components.css (.text-success-600 and friends), which meant any new
     component had to re-pick the hex by hand. These are the canonical values.

     Each role has three slots:
       (base) text on a light background — all clear 4.5:1 on white AND canvas
       -fill  a solid block, bar segment or dot
       -bg    the tint the base text is designed to sit on
     Deliberately NOT the WowDash --success-600 etc: those fail AA as text. */
  --ada-ok:          #117F3A;  /* 5.31:1 on white */
  --ada-ok-fill:     #22A34F;
  --ada-ok-bg:       #EAF6EE;

  --ada-warn:        #9E6319;  /* 5.14:1 on white */
  --ada-warn-fill:   #E08A0B;
  --ada-warn-bg:     #FFF3E0;

  --ada-danger:      #CA2323;  /* 5.32:1 on white */
  --ada-danger-fill: #E14B4B;
  --ada-danger-bg:   #FDECEC;

  /* --- Solid state buttons ----------------------------------------------
     The same split the accent needed. A destructive BUTTON is a fill with
     white text on it; --ada-danger is tuned as TEXT on a light ground and in
     dark mode it lightens, which would put white on #F2857C at 2.4:1.

     These are deliberately near-identical in both themes: white text has to
     read on them either way, so there is nowhere for them to move. Only the
     hover step differs. */
  --ada-danger-solid:      #C42020;   /* white on it: 6.0:1 */
  --ada-danger-solid-hover:#A11B1B;   /* white on it: 8.2:1 */
  --ada-ok-solid:          #0F7038;   /* white on it: 5.7:1 */
  --ada-ok-solid-hover:    #0B5A2C;
  --ada-warn-solid:        #8A5510;   /* white on it: 6.4:1 */
  --ada-warn-solid-hover:  #6E4310;

  /* Warning laid on a --primary-700 panel. --ada-warn-fill is tuned for white
     backgrounds and goes muddy on violet. 4.42:1 against #5A48D0, so it clears
     AA for large text only — use it for figures at --ada-text-xl and up, never
     for 11px labels. Those stay white. */
  --ada-warn-on-deep: #FFCE8A;

  /* --- Radius ---------------------------------------------------------- */
  --ada-r-sm: 10px;
  --ada-r-md: 14px;
  --ada-r-lg: 16px;
  --ada-r-xl: 20px;
  /* Fully rounded ends. Was written as a literal 20px on buttons and 999px on
     bars and chips, which is why button radii drifted per size (20/16/24). */
  --ada-r-pill: 999px;

  /* --- Focus ring -------------------------------------------------------
     One definition, so a high-contrast or thicker-ring variant is a token
     change rather than a hunt through two files. The ring previously also set
     border-radius: 4px, which changed the element's own shape on focus
     (measured 6px -> 4px on a .btn outside .ada-ui). A focus indicator must
     never alter geometry. */
  --ada-focus-width:  2px;
  --ada-focus-offset: 2px;
  --ada-focus-color:  var(--primary-600);

  /* --- Border width -----------------------------------------------------
     Every border in the layer was a literal 1px, leaving no lever for a
     high-contrast mode. */
  --ada-border-width: 1px;

  /* --- Line height ------------------------------------------------------
     Eight distinct values were hand-picked across the layer (1, 1.1, 1.15,
     1.25, 1.3, 1.35, 1.5) plus a hardcoded line-height:30px on the select2
     control that breaks if its font-size moves. */
  --ada-leading-none:  1;
  --ada-leading-tight: 1.2;
  --ada-leading-snug:  1.35;
  --ada-leading-normal: 1.5;

  /* --- Letter spacing ---------------------------------------------------
     Five hand-picked values across the layer. Display sizes need negative
     tracking; uppercase labels need positive. */
  --ada-tracking-tight: -0.02em;
  --ada-tracking-snug:  -0.01em;
  --ada-tracking-wide:   0.06em;

  /* --- Z-index ----------------------------------------------------------
     There was no scale, so overlay ordering was implicit and the next one was
     a guess. Bootstrap's own modal sits at 1055; stay above or below it
     deliberately. */
  --ada-z-base:     1;
  --ada-z-sticky:   100;
  --ada-z-dropdown: 1000;
  --ada-z-modal:    1055;
  --ada-z-toast:    1090;
  --ada-z-skip:     2000;

  /* --- Elevation: soft and layered, never harsh ------------------------ */
  --ada-shadow-sm: 0 2px 8px rgba(30, 27, 58, 0.05);
  --ada-shadow-md: 0 4px 16px rgba(30, 27, 58, 0.055);
  --ada-shadow-lg: 0 8px 24px rgba(30, 27, 58, 0.09);
  --ada-shadow-brand: 0 8px 22px rgba(108, 92, 231, 0.24);

  /* --- Module palette ---------------------------------------------------
     Ten distinct hues, one per module — no hue is used twice, so colour
     alone identifies a module. Each has three steps:
       base  — the icon's dominant tone at rest
       soft  — the icon's second tone (same hue, never mixed)
       deep  — the hover fill. Darkened until white text clears 4.5:1,
               which the lighter base tones do not.
     Colour is decorative only: every card also carries its name as text.

     No warm yellow/amber in the set: to carry white text a hue must be
     darkened past ~4.5:1, and amber only reaches that as muddy brown. Hues
     are chosen so their deep step is still attractive, not just legible. */
  --ada-motif-indigo:      #6366F1;  --ada-motif-indigo-soft: #C7D2FE;  --ada-motif-indigo-deep: #4338CA;
  --ada-motif-orange:      #F97316;  --ada-motif-orange-soft: #FDBA74;  --ada-motif-orange-deep: #C2410C;
  --ada-motif-teal:        #14B8A6;  --ada-motif-teal-soft:   #99F6E4;  --ada-motif-teal-deep:   #0F766E;
  --ada-motif-violet:      #8B5CF6;  --ada-motif-violet-soft: #DDD6FE;  --ada-motif-violet-deep: #6D28D9;
  --ada-motif-rose:        #F43F5E;  --ada-motif-rose-soft:   #FDA4AF;  --ada-motif-rose-deep:   #BE123C;
  --ada-motif-sky:         #0EA5E9;  --ada-motif-sky-soft:    #BAE6FD;  --ada-motif-sky-deep:    #0369A1;
  --ada-motif-lime:        #84CC16;  --ada-motif-lime-soft:   #D9F99D;  --ada-motif-lime-deep:   #4D7C0F;
  --ada-motif-purple:      #A855F7;  --ada-motif-purple-soft: #E9D5FF;  --ada-motif-purple-deep: #7E22CE;
  --ada-motif-pink:        #EC4899;  --ada-motif-pink-soft:   #FBCFE8;  --ada-motif-pink-deep:   #BE185D;
  --ada-motif-green:       #22C55E;  --ada-motif-green-soft:  #BBF7D0;  --ada-motif-green-deep:  #15803D;
  /* Enforcement. Red rather than the rejected amber: its deep step is a real
     red, not a brown, and it clears the contrast bar for white text. Kept
     orange-leaning so it does not read as a second rose on the same grid. */
  --ada-motif-red:         #EF4444;  --ada-motif-red-soft:    #FCA5A5;  --ada-motif-red-deep:    #B91C1C;
  /* Website Content. A true blue, which is the one clear gap left in the set:
     indigo leans violet and sky leans cyan, so a saturated blue reads as its
     own hue between them. It is also the conventional colour for the
     Authority's outward-facing site, which is what this module publishes. */
  --ada-motif-blue:        #2563EB;  --ada-motif-blue-soft:   #BFDBFE;  --ada-motif-blue-deep:   #1D4ED8;
  /* G.O. / Rules / Regulations. The one gap left on the wheel is between
     purple (271°) and pink (330°); fuchsia sits in it and is the last hue that
     can be added without a second of something. Amber would have suited a
     statute better but is ruled out above for the same reason as before.
     A neutral slate was drawn and rejected: among twelve saturated cards the
     grey one reads as disabled, which is worse than sitting near purple. */
  --ada-motif-fuchsia:     #C026D3;  --ada-motif-fuchsia-soft: #F5D0FE; --ada-motif-fuchsia-deep: #86198F;

  /* --- Motion ----------------------------------------------------------- */
  --ada-dur: 200ms;
  --ada-dur-slow: 320ms;
  --ada-ease: cubic-bezier(0.4, 0, 0.2, 1);
}

/* WowDash ships a dark theme toggled by [data-theme=dark]; keep the ramp
   coherent there too rather than leaving blue behind in one mode.

   This block previously redefined 10 of 62 colour tokens. A partially inverted
   theme is worse than none: the half that did not move becomes a white block
   on a dark page, and the state colours — tuned against white — measured
   2.92-3.29:1 on the dark surface. Everything that carries colour moves here. */
[data-theme="dark"] {
  /* Ramp. 50/100/200 are TINT BACKGROUNDS in light mode (.btn-light,
     .btn-secondary, .bg-primary-focus), so in dark they must become dark
     tints, not stay near-white. 800/900 were text-weight darks; they invert. */
  --primary-50:  #211E3D;
  --primary-100: #2A2650;
  --primary-200: #362F66;
  --primary-300: #6E5CE0;
  --primary-400: #7A68E6;
  --primary-500: #7362E9;
  /* NOT lightened. The vendor consumes --primary-600 in 109 rules and the
     majority of them use it as a FILL behind white text — buttons, the active
     nav item, badges. Lightening it for the text role (the previous dark value
     was #8B7CF0) dropped white-on-fill to 3.37:1 across all of them.

     No single value can serve both roles: white on X needs luminance <= .17,
     while X on the dark surface needs >= .24. So --primary-600 stays a fill,
     and the text role is served by --ada-accent-on-light and --bs-link-color
     below, which DO lighten. */
  --primary-600: #6C5CE7;   /* white on it: 4.86:1 */
  --primary-700: #5A48D0;   /* deeper fill, for panels */
  --primary-800: #4A3BAB;
  --primary-900: #3E338A;

  --primary-light:       rgba(156, 140, 245, 0.20);
  --primary-light-white: rgba(156, 140, 245, 0.28);

  /* The split earns its keep here: these move in OPPOSITE directions.
     Fill stays dark so white text keeps 4.5:1; on-light goes lighter so it
     reads against the dark surface. One token could not do both. */
  --ada-accent-fill:     #6C5CE7;   /* white on it: 4.86:1 */
  --ada-accent-on-light: #A79BFF;   /* on #1F1D38: 6.9:1  */

  /* Deep panel fill — the hero. Must stay dark in both themes because white
     text and translucent white chips sit on it. */
  --ada-accent-deep:     #453591;

  /* Bootstrap's primary was left behind in dark, so .btn-primary and
     .text-primary kept the LIGHT violet while --primary-600 had moved —
     two different "primary" violets active at once. */
  --bs-primary:     #6C5CE7;
  --bs-primary-rgb: 108, 92, 231;
  --bs-link-color:  #A29BFE;
  --bs-link-hover-color: #B9B3FF;
  --bs-link-color-rgb: 162, 155, 254;

  --ada-canvas:    #16152A;
  --ada-surface:   #1F1D38;
  --ada-surface-2: #262444;
  --ada-ink:       #F1F0FA;
  --ada-ink-soft:  #B6B2D4;
  --ada-ink-mute:  #908BB4;
  --ada-hairline:  #302D52;
  --ada-border:    #3A3663;

  --ada-focus-color: #A29BFE;

  /* State colours. The light values are tuned against white and measured
     2.92-3.29:1 on --ada-surface #1F1D38. These clear 4.5:1 there.
     The -bg tints were light greens/ambers/pinks in dark mode — near-white
     blocks on a dark page — and are now dark tints carrying the same hue. */
  --ada-ok:          #5FBE86;  /* 6.9:1 on #1F1D38 */
  --ada-ok-fill:     #22A34F;
  --ada-ok-bg:       #14301F;

  --ada-warn:        #DFA35C;  /* 7.4:1 on #1F1D38 */
  --ada-warn-fill:   #E08A0B;
  --ada-warn-bg:     #33260F;

  --ada-danger:      #F2857C;  /* 6.7:1 on #1F1D38 */
  --ada-danger-fill: #E14B4B;
  --ada-danger-bg:   #3A1E1E;

  /* The -solid tokens deliberately do NOT invert: white text sits on them in
     both themes, so there is nowhere for them to move. Only the hover step
     lifts slightly so the change is perceptible against a dark page. */
  --ada-danger-solid-hover: #D93A3A;
  --ada-ok-solid-hover:     #15884A;
  --ada-warn-solid-hover:   #A5691C;

  --ada-warn-on-deep: #FFCE8A;

  --ada-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
  --ada-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.34);
  --ada-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.42);
  --ada-shadow-brand: 0 8px 22px rgba(0, 0, 0, 0.5);
}

/* =========================================================================
   Vendor bug fix
   -------------------------------------------------------------------------
   admin/scss/_common.scss declares .module-card::before as position:absolute
   but never gives .module-card a positioned ancestor, so the gradient hover
   accent has always resolved against the wrong containing block. Fixed here
   rather than in the compiled vendor file.
   ========================================================================= */
.module-card {
  position: relative;
}

/* =========================================================================
   Focus visibility — applies app-wide, not just the dashboard.
   Never remove the ring; recolour it to the new primary.
   ========================================================================= */
/* No border-radius here. This rule used to set 4px, which changed the
   element's own shape the moment it received focus — measured 6px -> 4px on a
   .btn outside .ada-ui, where :where()'s zero specificity loses to .ada-ui
   .btn but beats a bare .btn. The outline follows whatever radius the
   component already has. */
:where(a, button, [role="button"], input, select, textarea, summary):focus-visible {
  outline: var(--ada-focus-width) solid var(--ada-focus-color);
  outline-offset: var(--ada-focus-offset);
}
