/* ==========================================================================
   Infiniti UI — Design Tokens
   --------------------------------------------------------------------------
   The single source of truth for colour, type, space, radius, elevation and
   motion in the Infiniti UI theme.

   Rules:
     1. No component stylesheet may hardcode a hex value, px size or shadow.
        Every value below is exposed as a custom property — use it.
     2. Light is the base palette on bare :root. Dark only *redefines* tokens.
     3. Never write `left`/`right`. Use CSS logical properties, so one
        stylesheet serves both LTR and RTL. See §Direction at the bottom.
     4. Bootstrap 5 variables are re-pointed at these tokens at the bottom of
        this file, so Bootstrap components inherit the system for free.

   This file is imported by `theme.css`, which is the Tailwind entry point.
   Tailwind's @theme block aliases these tokens rather than duplicating them,
   so `tw:bg-brand-600` and `var(--inf-brand-600)` are always the same colour.

   Load order in theme.html:
        bootstrap[.rtl].min.css → infiniti.css (compiled) → plugin overrides
   ========================================================================== */

:root {
  /* ---------- Brand ramp -------------------------------------------------- */
  --inf-brand-950: #08213D;
  --inf-brand-900: #0F2B4C;   /* topbar background */
  --inf-brand-800: #123C6B;
  --inf-brand-700: #14508C;
  --inf-brand-600: #1668C6;   /* primary action */
  --inf-brand-500: #2B7FD9;
  --inf-brand-300: #8FBEEE;
  --inf-brand-100: #DCEAFB;
  --inf-brand-50:  #EEF5FD;

  /* ---------- Application chrome ----------------------------------------- */
  --inf-topbar-bg: var(--inf-brand-800);
  --inf-topbar-fg: var(--inf-text-invert);   /* everything sitting on the app bar */

  /* ---------- Semantic status -------------------------------------------- */
  --inf-success-600: #12805C;
  --inf-success-100: #D7F2E6;
  --inf-warning-600: #B54708;
  --inf-warning-100: #FDF0DC;
  --inf-danger-600:  #B42318;
  --inf-danger-100:  #FDE4E2;
  --inf-info-600:    #0B6BCB;
  --inf-info-100:    #DCEAFB;
  --inf-neutral-600: #4B5B72;
  --inf-neutral-100: #EDF0F4;

  /* Ink for text sitting ON a *-100 tint (status pills, count badges).
     It cannot just be the -600 step: in dark the tints become dark, so a dark
     ink on them collapses — the Filters count pill measured 1.82:1 that way.
     These flip to a light step under [data-inf-theme="dark"] below. */
  --inf-brand-on-tint:   var(--inf-brand-700);
  --inf-success-on-tint: var(--inf-success-600);
  --inf-warning-on-tint: var(--inf-warning-600);
  --inf-danger-on-tint:  var(--inf-danger-600);
  --inf-info-on-tint:    var(--inf-info-600);
  --inf-neutral-on-tint: var(--inf-neutral-600);

  /* ---------- Surfaces & text -------------------------------------------- */
  --inf-canvas:        #F4F6F8;  /* page background behind cards */
  --inf-surface:       #FFFFFF;  /* cards, sheets, table body */
  --inf-surface-sunk:  #F8FAFC;  /* table header, muted panels */
  --inf-surface-hover: #F1F5FB;  /* row hover */
  --inf-surface-sel:   #E6F0FC;  /* row selected */
  --inf-overlay:       rgba(15, 43, 76, 0.45);

  --inf-text:        #1C2434;
  --inf-text-muted:  #5A6B84;
  --inf-text-subtle: #8A99AE;
  --inf-text-invert: #FFFFFF;
  --inf-link:        #0B6BCB;

  --inf-border:        #E3E8EF;
  --inf-border-strong: #C9D2DF;
  --inf-focus-ring:    rgba(22, 104, 198, 0.35);
  --inf-border-width:  1px;

  /* ---------- Type -------------------------------------------------------- */
  --inf-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
                   Roboto, "Helvetica Neue", Arial, sans-serif;
  --inf-font-mono: "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace;

  /* ERP density: base is 14.3px (13px +10%, see below), not 16px.
     Every value in this block is the original ×1.1 — a deliberate, uniform
     +10% bump across the whole type/space/radius/layout-metric scale, not a
     root font-size override (that would also scale every Bootstrap utility
     class across all 2,702 blueprint templates, a much bigger blast radius
     than "the theme"). Ratios between steps are preserved exactly because
     every step was multiplied by the same factor. */
  --inf-fs-2xs:  0.7563rem;  /* 12.1px — chips, meta */
  --inf-fs-xs:   0.825rem;   /* 13.2px — table body, help text */
  --inf-fs-sm:   0.8938rem;  /* 14.3px — BASE: labels, inputs, body */
  --inf-fs-md:   0.9625rem;  /* 15.4px — emphasis, buttons */
  --inf-fs-lg:   1.1rem;     /* 17.6px — card titles */
  --inf-fs-xl:   1.375rem;   /* 22px   — page title */
  --inf-fs-2xl:  1.65rem;    /* 26.4px — KPI value */
  --inf-fs-3xl:  1.925rem;   /* 30.8px — form record title */

  --inf-fw-regular: 400;
  --inf-fw-medium:  500;
  --inf-fw-semi:    600;
  --inf-fw-bold:    700;

  --inf-lh-tight:  1.25;
  --inf-lh-normal: 1.45;
  --inf-lh-loose:  1.6;

  /* ---------- Space (4.4px base, was 4px — see +10% note above) ----------- */
  --inf-space-0: 0;
  --inf-space-1: 0.275rem;  /* 4.4  */
  --inf-space-2: 0.55rem;   /* 8.8  */
  --inf-space-3: 0.825rem;  /* 13.2 */
  --inf-space-4: 1.1rem;    /* 17.6 */
  --inf-space-5: 1.65rem;   /* 26.4 */
  --inf-space-6: 2.2rem;    /* 35.2 */
  --inf-space-7: 3.3rem;    /* 52.8 */

  /* ---------- Radius (+10%; pill is a "fully round" sentinel, not a real
     measurement, so it stays as-is) ------------------------------------- */
  --inf-radius-xs:   3.3px;
  --inf-radius-sm:   4.4px;
  --inf-radius-md:   6.6px;
  --inf-radius-lg:   11px;
  --inf-radius-pill: 999px;

  /* ---------- Elevation --------------------------------------------------- */
  --inf-shadow-xs: 0 1px 2px rgba(16, 30, 54, 0.06);
  --inf-shadow-sm: 0 1px 3px rgba(16, 30, 54, 0.10), 0 1px 2px rgba(16, 30, 54, 0.06);
  --inf-shadow-md: 0 4px 12px rgba(16, 30, 54, 0.10);
  --inf-shadow-lg: 0 12px 32px rgba(16, 30, 54, 0.16);
  --inf-shadow-form: 0 2px 8px rgba(21, 40, 58, 0.10);

  /* ---------- Layout metrics (+10%, rounded to whole px) ------------------ */
  --inf-topbar-h:      46px;   /* compact fixed app bar */
  --inf-controlbar-h:  39px;   /* compact breadcrumb + actions row */
  --inf-sidebar-w:     211px;  /* compact legacy sidebar layout */
  --inf-sidebar-w-min: 53px;
  --inf-chatter-w:     343px;  /* compact form-view right rail */
  --inf-row-h:         30px;   /* compact list row */
  --inf-control-h:     26px;   /* compact input / button height */
  --inf-content-max:   1848px;

  /* ---------- Motion ------------------------------------------------------ */
  --inf-ease:        cubic-bezier(0.2, 0, 0.2, 1);
  --inf-dur-fast:    120ms;
  --inf-dur-normal:  200ms;
  --inf-dur-slow:    320ms;

  /* ---------- Z-index scale ----------------------------------------------- */
  --inf-z-sticky:   100;
  --inf-z-topbar:   1030;
  --inf-z-launcher: 1040;
  --inf-z-dropdown: 1060;
  --inf-z-modal:    1070;
  --inf-z-select2:  1080;  /* must clear modal — see theme-tweaks precedent */
  --inf-z-toast:    1090;
}

/* ==========================================================================
   Dark mode — redefines tokens only, never introduces a new one.
   Honours both the explicit [data-inf-theme="dark"] switch and OS preference.
   ========================================================================== */

/* ==========================================================================
   Dark mode is OPT-IN ONLY: [data-inf-theme="dark"], never prefers-color-scheme.
   --------------------------------------------------------------------------
   There used to be an `@media (prefers-color-scheme: dark)` block here guarded
   by `:root:not([data-inf-theme="light"])`, on the assumption that stamping
   data-inf-theme="light" would hold it off. It does not: something in the
   page's own JS strips every attribute from <html> during parsing, so the
   guard evaporates and any viewer whose OS is in dark mode gets the dark
   palette applied to a UI whose dark coverage is incomplete - a near-black
   page with white-on-white text, reported from a phone.

   Until the shells are replaced and dark is genuinely finished, dark is
   reachable only by an explicit opt-in that no attribute-stripping can
   accidentally trigger. Re-adding an OS-preference block before then
   reintroduces exactly that bug.
   ========================================================================== */


:root[data-inf-theme="dark"] {
  --inf-canvas:        #0E1520;
  --inf-surface:       #151E2C;
  --inf-surface-sunk:  #1B2634;
  --inf-surface-hover: #1E2A3A;
  --inf-surface-sel:   #1B3350;
  --inf-overlay:       rgba(3, 9, 17, 0.65);

  --inf-text:        #E6ECF4;
  --inf-text-muted:  #9AAABF;
  --inf-text-subtle: #6D7F97;
  --inf-link:        #6FB0F2;

  --inf-border:        #253244;
  --inf-border-strong: #35465C;

  --inf-brand-900: #0B1826;
  --inf-brand-600: #2B7FD9;
  --inf-brand-100: #12283F;
  --inf-brand-50:  #101E2E;

  --inf-success-100: #10301F;
  --inf-warning-100: #33220C;
  --inf-danger-100:  #3A1A17;
  --inf-info-100:    #12283F;
  --inf-neutral-100: #1E2A3A;

  /* On a dark tint the ink has to be the light step, not the saturated one. */
  --inf-brand-on-tint:   #8FBEEE;
  --inf-success-on-tint: #6FD3AC;
  --inf-warning-on-tint: #E9B87A;
  --inf-danger-on-tint:  #F2A29B;
  --inf-info-on-tint:    #8FBEEE;
  --inf-neutral-on-tint: #AEBBCC;

  --inf-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
  --inf-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5);
  --inf-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
  --inf-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.6);
}

/* ==========================================================================
   Per-tenant brand override hook
   --------------------------------------------------------------------------
   A site may repaint the brand ramp without forking the theme by emitting a
   <style> block from sites/{site}/templates/, or by setting BRAND_* keys in
   sites/{site}/settings.py which theme.html renders into :root.
   Only these six are safe to override; everything else derives from them.
   ========================================================================== */

/*
:root {
  --inf-brand-900: <topbar>;
  --inf-brand-700: <hover>;
  --inf-brand-600: <primary action>;
  --inf-brand-100: <tint>;
  --inf-brand-50:  <tint-faint>;
  --inf-link:      <link>;
}
*/

/* ==========================================================================
   Bootstrap 5 bridge — re-point Bootstrap at the tokens above.
   Keeps the 2,700 existing blueprint templates (btn-primary, card, badge,
   form-control, table) on the new system with no markup changes.
   ========================================================================== */

:root {
  --bs-body-bg:          var(--inf-canvas);
  --bs-body-color:       var(--inf-text);
  --bs-body-font-family: var(--inf-font-sans);
  --bs-body-font-size:   var(--inf-fs-sm);
  --bs-body-line-height: var(--inf-lh-normal);

  --bs-primary:   var(--inf-brand-600);
  --bs-secondary: var(--inf-neutral-600);
  --bs-success:   var(--inf-success-600);
  --bs-info:      var(--inf-info-600);
  --bs-warning:   var(--inf-warning-600);
  --bs-danger:    var(--inf-danger-600);
  --bs-light:     var(--inf-surface-sunk);
  --bs-dark:      var(--inf-brand-950);

  --bs-link-color:       var(--inf-link);
  --bs-link-hover-color: var(--inf-brand-700);

  --bs-border-color:  var(--inf-border);
  --bs-border-radius: var(--inf-radius-md);

  --bs-card-bg:           var(--inf-surface);
  --bs-card-border-color: var(--inf-border);
}

/* ==========================================================================
   §Direction — RTL
   --------------------------------------------------------------------------
   `dir` is set once, on <html>, from the active locale:

       <html lang="{{ get_locale() }}"
             dir="{{ 'rtl' if get_locale() in config['RTL_LOCALES'] else 'ltr' }}">

   Everything below then follows automatically, provided component CSS obeys
   rule 3: no `left`, no `right`, no `margin-left`, no `text-align: left`.

   Use instead:
     margin-left        → margin-inline-start   (Tailwind: tw:ms-*)
     margin-right       → margin-inline-end     (Tailwind: tw:me-*)
     padding-left       → padding-inline-start  (Tailwind: tw:ps-*)
     padding-right      → padding-inline-end    (Tailwind: tw:pe-*)
     left / right       → inset-inline-start / -end
     border-left        → border-inline-start
     text-align: left   → text-align: start     (Tailwind: tw:text-start)
     float: left        → float: inline-start

   For the cases logical properties cannot express — a chevron, a caret, a
   progress chevron's clip-path, a directional icon — multiply by --inf-flip
   instead of writing a [dir="rtl"] override:

       .chevron { transform: scaleX(var(--inf-flip)); }
   ========================================================================== */

:root      { --inf-flip:  1; --inf-start: left;  --inf-end: right; }
[dir="rtl"]{ --inf-flip: -1; --inf-start: right; --inf-end: left;  }

/* --------------------------------------------------------------------------
   Things that must NOT flip in RTL.

   An ERP is mostly numbers, and numbers stay LTR in every locale. A money
   column, an account code, a document number, a date, a phone number and an
   IBAN all read left-to-right inside an RTL page. Getting this wrong is the
   single most visible RTL bug in a finance UI — "1,234.56" rendered as
   "56.234,1" is not a styling nit, it is a wrong number on screen.

   Apply .inf-ltr (or dir="ltr") to any such cell. Numeric table columns get it
   by default in the list and report components.
   -------------------------------------------------------------------------- */

.inf-ltr {
  direction: ltr;
  unicode-bidi: isolate;
  text-align: end;              /* stays flush to the column edge in both dirs */
  font-variant-numeric: tabular-nums;
}

/* Free-text a user typed — could be either direction. Let the browser decide
   per string rather than forcing the page direction onto it. */
.inf-auto { unicode-bidi: plaintext; }

/* --------------------------------------------------------------------------
   Bootstrap under RTL
   --------------------------------------------------------------------------
   Bootstrap 5.1.3 ships a separate compiled RTL bundle. theme.html swaps it in
   rather than trying to patch the LTR one:

       <link rel="stylesheet" href="…/bootstrap{{ '.rtl' if is_rtl }}.min.css">

   That covers the ~2,700 blueprint templates emitting Bootstrap class names
   (`ms-3`, `text-end`, `float-start`, the grid) with no template change. The
   theme's own CSS still must use logical properties — the RTL bundle only
   fixes Bootstrap's own utilities, not ours.
   -------------------------------------------------------------------------- */
