/* The palette. One file, loaded first by every shell.
 *
 * WHY THIS EXISTS
 * ---------------
 * The product had three identities and no agreement between them:
 *
 *     the public site    Microsoft blue   #0078d4
 *     the customer portal deep indigo     #1a237e
 *     the admin          emerald green    #10b981
 *
 * plus a configured accent of bright green, a teal, two purples, five different
 * blues, and ninety-seven gradients. Nothing was wrong in isolation; together
 * they read as a page assembled from parts of other products.
 *
 * ONE ACCENT. Everything that is "the brand" is `--brand`. A component wanting
 * the brand colour uses the token; a component wanting to stand out uses weight,
 * size or space instead. Adding a second accent is how the first one stopped
 * meaning anything.
 *
 * NO GRADIENTS ON CONTROLS. A gradient on a button says nothing a solid colour
 * does not, costs contrast at one end of the sweep, and is the single strongest
 * signal that a page was assembled rather than designed. Gradients survive only
 * where they are the SUBJECT -- a hero backdrop, a dark band -- never on
 * anything a person is meant to click.
 *
 * STATUS COLOURS ARE NOT DECORATION AND ARE KEPT. Green for success, red for
 * danger and amber for warning carry meaning that colour is the fastest way to
 * convey: a suspended account rendered in brand blue looks like every other
 * row. They appear ONLY on badges, alerts and status dots -- never on a button,
 * an icon tile or a heading.
 */

:root {
  /* ---- the one accent ---------------------------------------------------
   * Overridden per-install from Admin > Branding, which is why every rule
   * below refers to the token rather than the hex. The value here is the
   * default, not the authority. */
  --brand: #2563eb;
  --brand-dark: #1d4ed8;   /* hover and pressed */
  --brand-darker: #1e40af; /* active, and text on very light tints */
  --brand-soft: #eff4ff;   /* tinted backgrounds, selected rows */
  --brand-rgb: 37, 99, 235;

  /* ---- ink -------------------------------------------------------------- */
  --ink: #0f172a;          /* headings */
  --ink-body: #475569;     /* body copy */
  --ink-muted: #64748b;    /* labels, captions */
  --ink-faint: #94a3b8;    /* placeholders, disabled */

  /* ---- surfaces --------------------------------------------------------- */
  --surface: #ffffff;
  --surface-sunken: #f8fafc;
  --surface-line: #e2e8f0;

  /* Dark bands. One pair, so every dark section on the site is the same dark. */
  --dark: #0d1120;
  --dark-raised: #141b31;
  --dark-line: rgba(148, 163, 184, 0.16);
  --dark-ink: #f1f5f9;
  --dark-ink-muted: #94a3b8;

  /* ---- status, and only status ------------------------------------------ */
  /* #059669 (emerald-600) was wrong from the day this palette was written, and
     wrong in BOTH directions: 3.77:1 as text on white, and 3.77:1 for the white
     text of a filled `.badge.bg-success`. It was chosen by eye and never
     measured. #047857 is 5.48:1 either way.
     Amber and red were already fine -- green is the colour that looks legible
     at this lightness and is not. */
  --ok: #047857;
  --ok-soft: #ecfdf5;
  --warn: #b45309;
  --warn-soft: #fffbeb;
  --bad: #dc2626;
  --bad-soft: #fef2f2;

  /* Triplets, for the Bootstrap bridge below -- its utilities are written as
     rgba(var(--bs-*-rgb), var(--bs-bg-opacity)) and cannot take a hex. */
  --ok-rgb: 4, 120, 87;
  --warn-rgb: 180, 83, 9;
  --bad-rgb: 220, 38, 38;

  /* TEXT ON THE SOFT BACKGROUND OF THE SAME STATUS.
     A status colour chosen to be legible on WHITE is not automatically legible
     on its own tint, and the gap is not small: measured on the real pages,
     `--ok` on `--ok-soft` came to 3.58:1 and `--bad` on `--bad-soft` to 4.41:1.
     Both fail, and both look perfectly fine to anyone who is not measuring --
     which is why an alert nobody could quite read shipped and stayed. */
  --ok-strong: #065f46;    /* 7.29:1 on --ok-soft */
  --warn-strong: #92400e;  /* 6.84:1 on --warn-soft */
  --bad-strong: #b91c1c;   /* 5.91:1 on --bad-soft */
}

/* ---- Bootstrap ------------------------------------------------------------
 *
 * The portal, the admin and the auth pages all load Bootstrap 5.3 from a CDN,
 * and it arrives with a complete palette of its own:
 *
 *     --bs-primary   #0d6efd    a sixth blue, on every link and .btn-primary
 *     --bs-success   #198754    a second green
 *     --bs-danger    #dc3545    a second red
 *     --bs-info      #0dcaf0    a cyan
 *     --bs-warning   #ffc107    a yellow
 *
 * Sweeping our own stylesheets could never reach these. Worse, Bootstrap's
 * colour UTILITIES (`.bg-success`, `.text-danger`) are declared `!important`,
 * so `.stat-icon.bg-success { background: var(--brand) }` -- more specific,
 * and loaded later -- silently lost. That is why the admin dashboard still had
 * green, yellow and cyan tiles after every hex in the project was replaced.
 *
 * Retinting Bootstrap's TOKENS rather than fighting its rules is what works:
 * the utilities keep their `!important` and resolve to our colours. And since
 * `--brand-rgb` is itself overridden from Admin > Branding, Bootstrap follows
 * the operator's choice along with everything else.
 *
 * Mapping:
 *   primary, link, info  -> the brand. `info` is not a status anyone acts on;
 *                           it was decoration with a hue.
 *   secondary            -> muted ink, which is what it is used for.
 *   success/warn/danger  -> OUR status colours, so there is one green rather
 *                           than two that differ by a few percent.
 */
:root {
  --bs-primary: var(--brand);
  --bs-primary-rgb: var(--brand-rgb);
  --bs-link-color: var(--brand);
  --bs-link-color-rgb: var(--brand-rgb);
  --bs-link-hover-color: var(--brand-dark);
  --bs-link-hover-color-rgb: var(--brand-rgb);

  --bs-info: var(--brand);
  --bs-info-rgb: var(--brand-rgb);

  --bs-secondary: var(--ink-muted);
  --bs-secondary-rgb: 100, 116, 139;

  --bs-success: var(--ok);
  --bs-success-rgb: var(--ok-rgb);
  --bs-warning: var(--warn);
  --bs-warning-rgb: var(--warn-rgb);
  --bs-danger: var(--bad);
  --bs-danger-rgb: var(--bad-rgb);

  /* 5.3 added a second, quieter set for alerts and subtle badges, and they are
     separate variables -- so an alert kept Bootstrap's green while the badge
     beside it used ours. Two greens on one screen, differing enough to look
     like a mistake and not enough to look deliberate. */
  --bs-primary-bg-subtle: var(--brand-soft);
  --bs-primary-border-subtle: rgba(var(--brand-rgb), 0.28);
  --bs-primary-text-emphasis: var(--brand-darker);

  --bs-info-bg-subtle: var(--brand-soft);
  --bs-info-border-subtle: rgba(var(--brand-rgb), 0.28);
  --bs-info-text-emphasis: var(--brand-darker);

  --bs-success-bg-subtle: var(--ok-soft);
  --bs-success-border-subtle: rgba(var(--ok-rgb), 0.28);
  --bs-success-text-emphasis: var(--ok-strong);

  --bs-warning-bg-subtle: var(--warn-soft);
  --bs-warning-border-subtle: rgba(var(--warn-rgb), 0.28);
  --bs-warning-text-emphasis: var(--warn-strong);

  --bs-danger-bg-subtle: var(--bad-soft);
  --bs-danger-border-subtle: rgba(var(--bad-rgb), 0.28);
  --bs-danger-text-emphasis: var(--bad-strong);

  --bs-secondary-bg-subtle: var(--surface-sunken);
  --bs-secondary-border-subtle: var(--surface-line);
  --bs-secondary-text-emphasis: var(--ink-muted);
}

/* A stat tile's colour is DECORATION, not status.
 *
 * The markup says `.stat-icon.bg-success` on "Total users" and `.bg-warning` on
 * "Credits issued" -- neither is a success or a warning, they were just four
 * tiles that wanted four colours. So the tile is the brand regardless of which
 * utility it carries, and `!important` is required here because that is what it
 * is competing with. It is the narrowest possible use: one element type, one
 * property.
 *
 * Badges and alerts are deliberately NOT included. There the colour IS the
 * message. */
.stat-icon[class*="bg-"] {
  background-color: var(--brand) !important;
}

/* Every control, everywhere: one shape, one colour, no gradient.
 *
 * Declared here rather than in each stylesheet because the three shells each
 * had their own button and they had drifted -- different radii, different
 * weights, and in one case a label that disappeared on hover. */
.btn-brand,
.btn-brand:link,
.btn-brand:visited {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 20px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: var(--brand);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.btn-brand:hover,
.btn-brand:focus-visible {
  background: var(--brand-dark);
  /* Restated. A `.something a` rule elsewhere is (0,1,1) and would otherwise
     out-specify this at (0,1,0) and take the label off the button -- which has
     happened twice in this project already. */
  color: #fff;
}
.btn-brand:active { background: var(--brand-darker); }
.btn-brand:disabled,
.btn-brand[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }

/* The quiet twin: same shape, no fill. For the second action in a pair, where
   two solid buttons would compete. */
.btn-quiet,
.btn-quiet:link,
.btn-quiet:visited {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 20px;
  border: 1px solid var(--surface-line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.btn-quiet:hover,
.btn-quiet:focus-visible {
  background: var(--surface-sunken);
  border-color: var(--ink-faint);
  color: var(--ink);
}

/* On a dark band the quiet button inverts, or it is a white slab on black. */
.on-dark .btn-quiet,
.on-dark .btn-quiet:link,
.on-dark .btn-quiet:visited {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--dark-line);
  color: var(--dark-ink);
}
.on-dark .btn-quiet:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
