/* Custom styles for CoreliaOS */

/* CSS Custom Properties for Theme System (shadcn-inspired) */
:root {
  /* Light theme colors */
  --background: 248 250 252;           /* #f8fafc */
  --foreground: 15 23 42;              /* #0f172a */
  --card: 255 255 255;                 /* #ffffff */
  --card-foreground: 15 23 42;         /* #0f172a */
  --popover: 255 255 255;              /* #ffffff */
  --popover-foreground: 15 23 42;      /* #0f172a */
  --primary: 15 118 110;               /* #0f766e */
  --primary-foreground: 248 250 252;   /* #f8fafc */
  --secondary: 241 245 249;            /* #f1f5f9 */
  --secondary-foreground: 15 23 42;    /* #0f172a */
  --muted: 241 245 249;                /* #f1f5f9 */
  --muted-foreground: 88 100 116;      /* #586474 */
  --accent: 241 245 249;               /* #f1f5f9 */
  --accent-foreground: 15 23 42;       /* #0f172a */
  --destructive: 220 38 38;            /* #dc2626 — one shade deeper so a white label clears AA; #ef4444 gave 3.6:1 */
  --destructive-foreground: 248 250 252; /* #f8fafc */
  --border: 226 232 240;               /* #e2e8f0 */
  --input: 226 232 240;                /* #e2e8f0 */
  --ring: 15 118 110;                  /* #0f766e */
  --success: 34 197 94;                /* #22c55e */
  --success-foreground: 15 23 42;       /* #0f172a — dark on a
     bright green fill; white was 2.18:1 */
  --warning: 245 158 11;               /* #f59e0b */
  --warning-foreground: 15 23 42;      /* #0f172a */
  --info: 59 130 246;                  /* #3b82f6 */
  --info-text: 29 78 216;              /* #1d4ed8 — --info is a
     fill; as text it is 3.7:1 on white, so text gets its own. */
  --success-text: 22 101 52;           /* #166534 — 5.64:1 on the heaviest
     green tint the app paints (0.18). #15803d measured 3.97 there. */
  --destructive-text: 153 27 27;       /* #991b1b — 5.14:1 on the heaviest
     red tint the app actually paints (0.25). #b91c1c measured 4.00 there. */
  --warning-text: 146 64 14;           /* #92400e */
  --primary-text: 17 94 89;            /* #115e59 — 5.28:1 on the heaviest
     primary tint the app paints (0.2). It used to be 15 118 110, the same
     value the primary fill holds: identical to that fill in light and distinct
     only in dark, so it protected nothing on the theme that needed it. Used on
     a primary tint; the fill token itself stays the accent on a plain surface,
     where it clears AA in both themes and is the app's signature colour.
     (No colon after a token name in these comments — the test that reads this
     block parses `--name: value` and would take the sentence as the value.) */
  --chart-2-text: 29 78 216;           /* #1d4ed8 — the chart blue is a
     series fill; as text it is 3.52:1 on white. */
  --chart-5-text: 126 34 206;          /* #7e22ce — likewise the violet. */
  --info-foreground: 2 6 23;           /* #020617 — the info blue is light
     enough that white on it is 3.68:1, so a solid info badge takes near-black
     (5.48:1). Bootstrap's own .badge default was that white. */
  --secondary-text: 51 65 85;          /* #334155 — the outline-secondary ink.
     `--secondary` is a SURFACE; using it as text is the surface on itself. */

  /* ── The categorical tint palette ──────────────────────────────────────
     A status chip, a build state, a priority tag, a symbol kind: all the same
     shape — a hue at 10-20% behind a label in that hue. Three pages each
     invented their own set of literals for it, every one picked while looking
     at a single theme, and between them they put "Completed" at 1.44:1 and
     "Failed" at 2.23:1 on a white card.

     The HUE is shared across themes on purpose: colour follows the entity, so
     a violet has to be the same violet on both or the app teaches two colour
     languages. Only the INK flips. Every pair below was measured against its
     own hue at 0.1-0.2 over all three grounds of its theme; the worst is
     5.50:1. Reach for these before writing a hex. */
  --tint-slate-ink: 51 65 85;
  --tint-blue-ink: 30 64 175;
  --tint-green-ink: 22 101 52;
  --tint-amber-ink: 146 64 14;
  --tint-orange-ink: 154 52 18;
  --tint-red-ink: 153 27 27;
  --tint-violet-ink: 91 33 182;
  --tint-pink-ink: 157 23 77;
  --tint-indigo-ink: 55 48 163;
  --tint-violet-foreground: 2 6 23;

  /* GRADIENT COMPANIONS. A gradient fill has two colours and one label, so
     both stops have to carry the same ink — and no gate reads
     `background-image`, which is how white-on-amber shipped at 1.87:1 on
     /admin/slack-bot and a green-to-teal page header failed in BOTH themes.
     Each companion is the same hue in the same lightness band as its base, so
     the base's own -foreground works at either end. Verified against both
     stops: worst pair 5.42:1 light, 8.31:1 dark. */
  --primary-gradient-to: 17 94 89;     /* #115e59 — 7.25:1 with primary-foreground */
  --success-gradient-to: 22 163 74;    /* #16a34a — 5.42:1 */
  --warning-gradient-to: 251 191 36;   /* #fbbf24 — 10.69:1 */
  --chart-1: 15 118 110;               /* #0f766e */
  --chart-2: 59 130 246;               /* #3b82f6 */
  --chart-3: 245 158 11;               /* #f59e0b */
  --chart-4: 239 68 68;                /* #ef4444 */
  --chart-5: 168 85 247;               /* #a855f7 */
  /* Categorical data-viz slots. Eight hues, assigned to a series in a fixed
  order and never cycled — a ninth series folds into "Other" rather than
  inventing a hue. Both columns are selected for their own surface, not an
  automatic flip of one another, and the set passes all six dataviz checks
  against this app's card surfaces (light #ffffff, dark #030710): lightness
  band, chroma floor, adjacent CVD separation, normal-vision separation, and
  contrast. Three light-mode slots sit under 3:1 on white, so any chart
  using them ships a legend AND a table view — never colour alone.
  Re-run scripts/validate_palette.js in the dataviz skill before editing. */
  --cat-1: 42 120 214;                 /* #2a78d6 blue */
  --cat-2: 235 104 52;                 /* #eb6834 orange */
  --cat-3: 27 175 122;                 /* #1baf7a aqua */
  --cat-4: 237 161 0;                  /* #eda100 yellow */
  --cat-5: 232 123 164;                /* #e87ba4 magenta */
  --cat-6: 0 131 0;                    /* #008300 green */
  --cat-7: 74 58 167;                  /* #4a3aa7 violet */
  --cat-8: 227 73 72;                  /* #e34948 red */

  /* Status colours as TEXT. The `--eng-*` triplets are tuned for chart fills
     and solid badges on a dark ground; used as text on a white card they
     measure 2.28:1 (good), 1.92:1 (warn) and 3.76:1 (bad), all below the 4.5:1
     AA floor. These are the same hues darkened until they clear it, and they
     exist so a status can be readable as words without dulling the fills.
     Defined here rather than in a component's `:host` because custom
     properties inherit through the shadow boundary, so one definition serves
     every Lit component and no `:host-context` is needed. */
  --eng-good-text: 21 128 61;          /* 5.02:1 on white */
  /* A denser tint needs darker ink. The strongest verdict chips sit on a 14%
     fill rather than 7%, which took the ordinary -text tokens to 4.45:1. */
  --eng-good-text-strong: 19 110 53;   /* 5.63:1 on a 14% green tint */
  --eng-bad-text-strong: 160 25 25;    /* 6.60:1 on a 14% red tint */
  --eng-warn-text: 161 98 7;           /* 4.92:1 on white */
  --eng-bad-text: 185 28 28;           /* 6.47:1 on white */

  /* Radius */
  --radius: 0.5rem;
}

[data-theme="dark"] {
  /* Dark theme colors */
  --eng-good-text: 34 197 94;          /* 8.82:1 on the dark card */
  --eng-good-text-strong: 34 197 94;   /* the dark fills are 3% of a dark card */
  --eng-bad-text-strong: 239 68 68;
  --eng-warn-text: 234 179 8;          /* 10.49:1 */
  --eng-bad-text: 239 68 68;           /* 5.34:1 */
  --background: 2 6 6;                 /* #020606 */
  --foreground: 248 250 252;           /* #f8fafc */
  --card: 5 7 16;                      /* #030710 */
  --card-foreground: 248 250 252;      /* #f8fafc */
  --popover: 5 7 16;                   /* #030710 */
  --popover-foreground: 248 250 252;   /* #f8fafc */
  --primary: 34 197 98;                /* #22c55e */
  --primary-foreground: 2 6 23;        /* #020617 */
  --secondary: 25 35 45;               /* #1e293b */
  --secondary-foreground: 248 250 252; /* #f8fafc */
  --muted: 30 41 50;                   /* #1e293b */
  --muted-foreground: 148 163 184;     /* #94a3b8 */
  --accent: 30 41 50;                  /* #1e293b */
  --accent-foreground: 248 250 252;    /* #f8fafc */
  --destructive: 220 38 38;            /* #dc2626 — one shade deeper so a white label clears AA; #ef4444 gave 3.6:1 */
  --destructive-foreground: 248 250 252; /* #f8fafc */
  --border: 30 41 50;                  /* #1e293b */
  --input: 30 41 50;                   /* #1e293b */
  --ring: 34 197 98;                   /* #22c55e */
  --success: 34 197 98;                /* #22c55e */
  --success-foreground: 2 6 23;        /* #020617 */
  --warning: 245 158 11;               /* #f59e0b */
  --warning-foreground: 15 23 42;      /* #0f172a */
  --info: 59 130 246;                  /* #3b82f6 */
  --info-text: 157 192 251;            /* #9dc0fb */
  --success-text: 126 226 168;         /* #7ee2a8 */
  --destructive-text: 252 165 165;     /* #fca5a5 */
  --warning-text: 251 207 120;         /* #fbcf78 */
  --primary-text: 126 226 168;         /* #7ee2a8 */
  --chart-2-text: 157 192 251;         /* #9dc0fb */
  --chart-5-text: 216 180 254;         /* #d8b4fe */
  --info-foreground: 2 6 23;           /* #020617 — same fill, same answer */
  --secondary-text: 203 213 225;       /* #cbd5e1 */
  /* Same hues as light — only the ink flips. */
  --tint-slate-ink: 203 213 225;
  --tint-blue-ink: 147 197 253;
  --tint-green-ink: 134 239 172;
  --tint-amber-ink: 252 211 77;
  --tint-orange-ink: 253 186 116;
  --tint-red-ink: 252 165 165;
  --tint-violet-ink: 196 181 253;
  --tint-pink-ink: 249 168 212;
  --tint-indigo-ink: 165 180 252;
  --tint-violet-foreground: 2 6 23;
  --primary-gradient-to: 74 222 128;   /* #4ade80 — 11.58:1 */
  --success-gradient-to: 74 222 128;   /* #4ade80 — 11.58:1 */
  --warning-gradient-to: 251 191 36;   /* #fbbf24 — 10.69:1 */
  --chart-1: 34 197 98;                /* #22c55e */
  --chart-2: 59 130 246;               /* #3b82f6 */
  --chart-3: 245 158 11;               /* #f59e0b */
  --chart-4: 230 70 70;                /* #ef4444 */
  --chart-5: 168 85 247;               /* #a855f7 */
  --cat-1: 57 135 229;                 /* #3987e5 blue */
  --cat-2: 217 89 38;                  /* #d95926 orange */
  --cat-3: 25 158 112;                 /* #199e70 aqua */
  --cat-4: 201 133 0;                  /* #c98500 yellow */
  --cat-5: 213 81 129;                 /* #d55181 magenta */
  --cat-6: 0 131 0;                    /* #008300 green */
  --cat-7: 144 133 233;                /* #9085e9 violet */
  --cat-8: 230 103 103;                /* #e66767 red */
}

/* Auto theme detection */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    /* Apply dark theme variables when system prefers dark and no theme is set */
    --eng-good-text: 34 197 94;          /* 8.82:1 on the dark card */
    --eng-good-text-strong: 34 197 94;
    --eng-bad-text-strong: 239 68 68;
  --eng-good-text-strong: 34 197 94;   /* the dark fills are 3% of a dark card */
  --eng-bad-text-strong: 239 68 68;
    --eng-warn-text: 234 179 8;          /* 10.49:1 */
    --eng-bad-text: 239 68 68;           /* 5.34:1 */
    --background: 2 6 6;                 /* #020606 */
    --foreground: 248 250 252;           /* #f8fafc */
    --card: 5 7 16;                      /* #030710 */
    --card-foreground: 248 250 252;      /* #f8fafc */
    --popover: 5 7 16;                   /* #030710 */
    --popover-foreground: 248 250 252;   /* #f8fafc */
    --primary: 34 197 98;                /* #22c55e */
    --primary-foreground: 2 6 23;        /* #020617 */
    --secondary: 25 35 45;               /* #1e293b */
    --secondary-foreground: 248 250 252; /* #f8fafc */
    --muted: 30 41 59;                   /* #1e293b */
    --muted-foreground: 148 163 184;     /* #94a3b8 */
    --accent: 30 41 59;                  /* #1e293b */
    --accent-foreground: 248 250 252;    /* #f8fafc */
    --destructive: 220 38 38;            /* #dc2626 — one shade deeper so a white label clears AA; #ef4444 gave 3.6:1 */
    --destructive-foreground: 248 250 252; /* #f8fafc */
    --border: 30 41 59;                  /* #1e293b */
    --input: 30 41 59;                   /* #1e293b */
    --ring: 34 197 98;                   /* #22c55e */
    --success: 34 197 98;                /* #22c55e */
    --success-foreground: 2 6 23;        /* #020617 */
    --warning: 245 158 11;               /* #f59e0b */
    --warning-foreground: 15 23 42;      /* #0f172a */
    --info: 59 130 246;                  /* #3b82f6 */
    --info-text: 157 192 251;            /* #9dc0fb */
    --success-text: 126 226 168;         /* #7ee2a8 */
    --destructive-text: 252 165 165;     /* #fca5a5 */
    --warning-text: 251 207 120;         /* #fbcf78 */
    --primary-text: 126 226 168;         /* #7ee2a8 */
    --chart-2-text: 157 192 251;         /* #9dc0fb */
    --chart-5-text: 216 180 254;         /* #d8b4fe */
    --info-foreground: 2 6 23;           /* #020617 */
    --secondary-text: 203 213 225;       /* #cbd5e1 */
  --tint-slate-ink: 203 213 225;
    --tint-blue-ink: 147 197 253;
    --tint-green-ink: 134 239 172;
    --tint-amber-ink: 252 211 77;
    --tint-orange-ink: 253 186 116;
    --tint-red-ink: 252 165 165;
    --tint-violet-ink: 196 181 253;
    --tint-pink-ink: 249 168 212;
    --tint-indigo-ink: 165 180 252;
    --tint-violet-foreground: 2 6 23;
    --primary-gradient-to: 74 222 128;
    --success-gradient-to: 74 222 128;
    --warning-gradient-to: 251 191 36;
    --chart-1: 34 197 98;                /* #22c55e */
    --chart-2: 59 130 246;               /* #3b82f6 */
    --chart-3: 245 158 11;               /* #f59e0b */
    --chart-4: 230 70 70;                /* #ef4444 */
    --chart-5: 168 85 247;               /* #a855f7 */
    --cat-1: 57 135 229;                 /* #3987e5 blue */
    --cat-2: 217 89 38;                  /* #d95926 orange */
    --cat-3: 25 158 112;                 /* #199e70 aqua */
    --cat-4: 201 133 0;                  /* #c98500 yellow */
    --cat-5: 213 81 129;                 /* #d55181 magenta */
    --cat-6: 0 131 0;                    /* #008300 green */
    --cat-7: 144 133 233;                /* #9085e9 violet */
    --cat-8: 230 103 103;                /* #e66767 red */
  }
}

/* Base element styling using CSS variables */
* {
  border-color: rgb(var(--border));
}

html {
  transition: background-color 0.2s ease, color 0.2s ease;
}

body {
  background-color: rgb(var(--background));
  color: rgb(var(--foreground));
  transition: background-color 0.2s ease, color 0.2s ease;
}


.card {
    background-color: rgb(var(--card));
    color: rgb(var(--card-foreground));
    border: 1px solid rgb(var(--border));
    box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
    border-radius: var(--radius);
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.list-group-item {
    background-color: rgb(var(--card));
    color: rgb(var(--foreground));
    border-color: rgb(var(--border));
}

.card-header {
    background-color: rgb(var(--muted) / 0.5);
    border-bottom: 1px solid rgb(var(--border));
    font-weight: 600;
    color: rgb(var(--card-foreground));
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.server-card {
    transition: transform 0.2s, box-shadow 0.2s;
    cursor: pointer;
}

.server-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

.status-badge {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
}

.status-active {
    background-color: rgb(var(--success));
    color: rgb(var(--success-foreground));
}

.status-inactive {
    background-color: rgb(var(--muted));
    color: rgb(var(--muted-foreground));
}

.status-error {
    background-color: rgb(var(--destructive));
    color: rgb(var(--destructive-foreground));
}

.status-starting {
    background-color: rgb(var(--warning));
    color: rgb(var(--warning-foreground));
}

.status-stopping {
    background-color: rgb(var(--destructive) / 0.8);
    color: rgb(var(--destructive-foreground));
}

.server-actions {
    opacity: 0;
    transition: opacity 0.2s;
}

.server-card:hover .server-actions {
    opacity: 1;
}

.config-preview {
    background-color: rgb(var(--muted));
    border: 1px solid rgb(var(--border));
    border-radius: var(--radius);
    padding: 0.75rem;
    font-family: 'Courier New', monospace;
    font-size: 0.875rem;
    max-height: 200px;
    overflow-y: auto;
    color: rgb(var(--foreground));
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

/* ===== Corelia Official Spinner =====
   Usage:
     Inline:  <span class="corelia-spinner"></span>
     Small:   <span class="corelia-spinner sm"></span>
     Large:   <span class="corelia-spinner lg"></span>
     XLarge:  <span class="corelia-spinner xl"></span>
     Colors:  <span class="corelia-spinner success"></span>
              <span class="corelia-spinner warning"></span>
              <span class="corelia-spinner danger"></span>
   Legacy .loading-spinner maps to same styles.
*/
.corelia-spinner, .loading-spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 2px solid rgb(var(--border));
    border-top-color: rgb(var(--primary));
    border-radius: 50%;
    animation: corelia-spin 0.7s linear infinite;
    /* Spinners live inside flex rows (link-row, result-wip-banner,
       button labels). Without flex-shrink:0 they get squeezed into
       ovals when the sibling text is long. It's an icon — never
       meant to shrink. */
    flex-shrink: 0;
}
.corelia-spinner.sm { width: 0.75rem; height: 0.75rem; border-width: 1.5px; }
.corelia-spinner.lg { width: 1.5rem; height: 1.5rem; border-width: 2.5px; }
.corelia-spinner.xl { width: 2.5rem; height: 2.5rem; border-width: 3px; }
.corelia-spinner.success { border-top-color: rgb(var(--success)); }
.corelia-spinner.warning { border-top-color: #fbbf24; }
.corelia-spinner.danger  { border-top-color: rgb(var(--destructive)); }

@keyframes corelia-spin {
    to { transform: rotate(360deg); }
}
/* Legacy compat */
@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.btn-action {
    padding: 0.25rem 0.5rem;
    margin-right: 0.25rem;
    margin-bottom: 0.25rem;
}

.env-var-group {
    background-color: rgb(var(--muted));
    border-radius: var(--radius);
    padding: 0.5rem;
    margin-bottom: 0.5rem;
    color: rgb(var(--muted-foreground));
    transition: background-color 0.2s ease, color 0.2s ease;
}

.type-icon {
    width: 20px;
    height: 20px;
    display: inline-block;
    margin-right: 0.5rem;
}

.python-icon {
    color: rgb(var(--chart-2-text));
}

.nodejs-icon {
    color: rgb(var(--success-text));
}

.docker-icon {
    color: rgb(var(--chart-2-text));
}

.transport-icon {
    color: rgb(var(--primary-text));
}

.navbar-brand {
    font-weight: bold;
}

.footer {
    margin-top: auto;
}

/* The categorical tint HUES. Deliberately OUTSIDE the three theme blocks,
   because they are the one part of the palette that does not vary by theme:
   colour follows the entity, so a violet has to be the same violet on both
   grounds or the app teaches two colour languages. Their inks DO flip and live
   in the theme blocks above, one `--tint-*-ink` per hue.

   Living out here is not tidiness — the parity test asserts the three theme
   blocks define the same token set, and a value that is meant to be shared
   would have to be written three times to satisfy it, which is three chances
   for one of them to drift. */
:root {
    --tint-slate: 100 116 139;
    --tint-blue: 59 130 246;
    --tint-green: 34 197 94;
    --tint-amber: 245 158 11;
    --tint-orange: 249 115 22;
    --tint-red: 239 68 68;
    --tint-violet: 139 92 246;
    --tint-pink: 236 72 153;
    --tint-indigo: 99 102 241;

    /* DEEP variants: the same hue mixed 50% over #090b14. A saturated card
       with a white label wants a fill dark enough to carry it, and the vivid
       hues are not — white on the amber is 2.15:1 and on the green 2.28:1.

       The mix is 50% rather than the 62% first tried, for HEADROOM: a card
       like this carries a secondary label as well as a title, and those are
       conventionally set at 75-85% alpha. At 62% the title cleared (4.88) and
       both secondary labels did not (4.02 and 3.51) — fixing that by pushing
       every label to full white would have flattened the hierarchy the design
       is built on. Deeper fill, alphas intact: 6.61 / 5.29 / 4.51.

       Theme-independent for the same reason as the hues above: a saturated
       coloured card is one look on both grounds. */
    --tint-slate-deep: 54 64 80;
    --tint-blue-deep: 34 70 133;
    --tint-green-deep: 22 104 57;
    --tint-amber-deep: 127 84 16;
    --tint-orange-deep: 129 63 21;
    --tint-red-deep: 124 40 44;
    --tint-violet-deep: 74 52 133;
    --tint-pink-deep: 122 42 86;
    --tint-indigo-deep: 54 56 130;
}

/* ── Bootstrap's own colour layer ──────────────────────────────────────────
   Bootstrap ships one palette and no concept of a second theme, so every
   utility below is a fixed value that is right on at most one of our two
   grounds. Each is repointed at the token that already answers the same
   question. Fixing them here rather than per page is the whole point: the
   alternative is finding them one component at a time, forever.

   Measured before, in the theme where each was worst:
     .text-warning  #ffc107  1.63:1 light      .text-success  #198754  4.44 dark
     .text-danger   #dc3545  4.44:1 dark       .text-primary  #0d6efd  4.11 light
     code           #d63384  3.29:1 dark       kbd            white    1.10 light
     .page-link     white on --primary 2.27 dark
     --bs-secondary #6c757d  4.29:1 dark (141 elements on /plugins alone) */

.text-success { color: rgb(var(--success-text)) !important; }
.text-danger  { color: rgb(var(--destructive-text)) !important; }
.text-warning { color: rgb(var(--warning-text)) !important; }
.text-info    { color: rgb(var(--info-text)) !important; }
.text-primary { color: rgb(var(--primary-text)) !important; }
.text-body-secondary { color: rgb(var(--muted-foreground)) !important; }

/* Bootstrap's variable layer. Six of our own rules read `var(--bs-secondary)`
   and friends directly; redefining them here means those consumers follow the
   theme without each having to be found and rewritten. */
:root {
    --bs-primary: rgb(var(--primary));
    --bs-primary-rgb: var(--primary);
    --bs-secondary: rgb(var(--muted-foreground));
    --bs-secondary-color: rgb(var(--muted-foreground));
    --bs-success: rgb(var(--success-text));
    --bs-body-color: rgb(var(--foreground));
    --bs-border-color: rgb(var(--border));
    --bs-primary-text-emphasis: rgb(var(--primary-text));
    --bs-primary-bg-subtle: rgb(var(--primary) / 0.12);
}

/* Bootstrap 5.1.3, not 5.3: there is no --bs-link-color or --bs-code-color in
   this version, so links and <code> are hardcoded (#0d6efd, #d63384) and have
   to be overridden as rules rather than as variables. Worth knowing before
   reaching for a --bs-* variable and finding it silently does nothing. */
a {
    color: rgb(var(--primary-text));
}

a:hover {
    color: rgb(var(--primary));
}

/* `code` is Bootstrap's pink #d63384 — a colour chosen against white and left
   there. It carries API paths and command names, which is text somebody has to
   read character by character. */
code, .text-code {
    color: rgb(var(--destructive-text));
}

/* `kbd` is white on #212529, the same fixed-dark trap as .table-dark: on the
   light theme the key cap kept its near-white label and lost its dark ground,
   so "Enter" rendered at 1.10:1 — a blank key. */
kbd {
    /* !important on both halves: Bootstrap sets the pair on `kbd` itself, so
       overriding only one gives near-white on near-white, which is worse than
       leaving it alone — and is exactly what the first attempt produced. */
    background-color: rgb(var(--foreground)) !important;
    color: rgb(var(--background)) !important;
}

/* Pagination. The active page is a solid --primary fill; Bootstrap labels it
   white, which is 2.27:1 on the dark theme's bright green. Both selector
   spellings, because 5.1.3 uses `.page-item.active .page-link` and later
   versions use `.active > .page-link`. */
/* The BACKGROUND matters as much as the ink here: Bootstrap gives every page
   link a fixed white fill, so giving it a theme-aware ink alone produced the
   dark theme's pale mint on a white chip — 1.58:1, worse than what it
   replaced. A fixed surface under a theme-aware ink is the .table-dark trap
   again, and it is worth expecting every time one of these is touched. */
.page-link {
    color: rgb(var(--primary-text));
    background-color: rgb(var(--card));
    border-color: rgb(var(--border));
}
.page-item.disabled .page-link {
    color: rgb(var(--muted-foreground));
    background-color: rgb(var(--card));
}
.page-item.active .page-link,
.active > .page-link,
.page-link.active {
    background-color: rgb(var(--primary)) !important;
    border-color: rgb(var(--primary)) !important;
    color: rgb(var(--primary-foreground)) !important;
}

/* Bootstrap's .text-muted is a fixed #6c757d that knows nothing about the
   theme, so it fails in BOTH: 4.48:1 on the light background and ~4.3:1 on the
   dark one. It is used all over the app for secondary copy — the footer, empty
   states, table captions — so it is pointed at the theme's own muted colour,
   which is tuned per theme and clears AA on either. */
.text-muted,
.text-secondary {
    color: rgb(var(--muted-foreground)) !important;
}

/* Same story for .bg-light: a fixed near-white panel. In dark mode it stays
   near-white while the text inside inherits the theme's near-white foreground
   — white on white. One page had already patched this for its own panel
   (plugins.html, #skillsListPanel), which is the tell that it was biting in
   practice; this fixes it everywhere rather than one place at a time. */
.bg-light {
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--foreground));
}

/* And .table-dark, which is .bg-light's mirror: a fixed #212529 panel. The
   dashboard's "Recent activity" header used it, and the .text-muted override
   above then painted the theme's light-mode grey onto that fixed dark ground
   — 2.56:1, in the LIGHT theme, on a page nobody would think to check in dark.
   Two theme-blind utilities meeting is worse than either alone: each looks
   right on its own and the pair is unreadable. Same treatment, so the header
   is a surface of the current theme rather than a hole punched through it. */
.table-dark {
    --bs-table-bg: rgb(var(--muted));
    --bs-table-color: rgb(var(--foreground));
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--foreground)) !important;
}

/* The cells need saying separately: .text-muted's own !important beats
   inheritance, which is how the header text was the muted grey rather than
   Bootstrap's white in the first place. */
.table-dark th {
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--foreground)) !important;
    border-color: rgb(var(--border));
}

/* Chart containers */
.chart-container {
    position: relative;
    height: 300px;
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .server-actions {
        opacity: 1;
    }
    
    .btn-action {
        font-size: 0.75rem;
        padding: 0.125rem 0.25rem;
    }
}

/* Modal improvements */
.modal-lg {
    max-width: 800px;
}

.config-section {
    border: 1px solid rgb(var(--border));
    border-radius: var(--radius);
    padding: 1rem;
    margin-bottom: 1rem;
    background-color: rgb(var(--muted));
    color: rgb(var(--foreground));
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.config-section h6 {
    color: rgb(var(--muted-foreground));
    margin-bottom: 0.75rem;
}

/* Alert improvements */
.alert {
    border: none;
    border-radius: 0.5rem;
}

/* Notification system */
.notification-container {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 1060;
    max-width: 400px;
    pointer-events: none;
}

.notification {
    pointer-events: auto;
    margin-bottom: 10px;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    border-left: 4px solid;
}

.notification.alert-success {
    border-left-color: rgb(var(--success));
}

.notification.alert-danger {
    border-left-color: rgb(var(--destructive));
}

.notification.alert-warning {
    border-left-color: rgb(var(--warning));
}

.notification.alert-info {
    border-left-color: rgb(var(--info));
}

@media (max-width: 768px) {
    .notification-container {
        top: 10px;
        right: 10px;
        left: 10px;
        max-width: none;
    }
}

/* Table improvements */
.table-hover tbody tr:hover {
    background-color: rgb(var(--accent) / 0.1);
    transition: background-color 0.15s ease;
}

.table {
    color: rgb(var(--foreground));
    transition: color 0.2s ease;
}

.table th {
    color: rgb(var(--muted-foreground));
    border-bottom: 1px solid rgb(var(--border));
}

.table td {
    border-bottom: 1px solid rgb(var(--border) / 0.5);
}

/* Log viewer */
.log-viewer {
    background-color: rgb(var(--muted));
    color: rgb(var(--foreground));
    padding: 1rem;
    border-radius: var(--radius);
    border: 1px solid rgb(var(--border));
    font-family: 'Courier New', monospace;
    font-size: 0.875rem;
    max-height: 400px;
    overflow-y: auto;
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.log-line {
    margin-bottom: 0.25rem;
}

.log-timestamp {
    color: rgb(var(--muted-foreground));
}

.log-level-error {
    color: rgb(var(--destructive-text));
}

.log-level-warning {
    color: rgb(var(--warning-text));
}

.log-level-info {
    color: rgb(var(--info-text));
}

.log-level-debug {
    color: rgb(var(--chart-5-text));
}

/* Cost Widget Styles */
.cost-widget {
    position: relative;
    display: inline-block;
    transition: all 0.2s ease-in-out;
    animation: none;
}

.cost-widget:hover {
    transform: scale(1.05);
}

.cost-widget .cost-loading {
    display: inline-block;
}

.cost-widget .cost-loading .fa-spinner {
    animation: spin 1s linear infinite;
}

.cost-widget .cost-amount {
    font-weight: 600;
    letter-spacing: -0.02em;
}

.cost-widget.bg-warning {
    color: rgb(var(--warning-foreground)) !important;
}

.cost-widget.bg-warning .cost-amount {
    color: rgb(var(--warning-foreground)) !important;
}

.cost-widget.bg-success .cost-amount {
    color: rgb(var(--success-foreground));
}

.cost-widget.bg-danger .cost-amount {
    color: rgb(var(--destructive-foreground));
}

.cost-widget.bg-dark .cost-amount {
    color: rgb(var(--background));
}

/* Cost dropdown enhancements */
.dropdown-menu .cost-summary-item {
    display: flex;
    justify-content: between;
    align-items: center;
    padding: 0.25rem 0;
    font-size: 0.875rem;
}

.dropdown-menu .cost-summary-item:not(:last-child) {
    border-bottom: 1px solid rgb(var(--border));
    margin-bottom: 0.25rem;
    padding-bottom: 0.5rem;
}

.dropdown-menu .cost-summary-item .cost-label {
    color: rgb(var(--muted-foreground));
    font-weight: 500;
}

.dropdown-menu .cost-summary-item .cost-value {
    font-weight: 600;
    margin-left: auto;
}

.dropdown-menu .cost-summary-item .cost-value.monthly {
    color: rgb(var(--success-text));
}

.dropdown-menu .cost-summary-item .cost-value.daily {
    color: rgb(var(--chart-2-text));
}

.dropdown-menu .cost-summary-item .cost-value.updated {
    color: rgb(var(--muted-foreground));
    font-size: 0.75rem;
    font-weight: 400;
}

/* Cost widget pulse animation for updates */
.cost-widget.updating {
    animation: cost-pulse 0.8s ease-in-out;
}

@keyframes cost-pulse {
    0% {
        box-shadow: 0 0 0 0 rgb(var(--success) / 0.7);
    }
    50% {
        box-shadow: 0 0 0 4px rgb(var(--success) / 0.2);
    }
    100% {
        box-shadow: 0 0 0 0 rgb(var(--success) / 0);
    }
}

/* High spending alert animation */
.cost-widget.bg-danger {
    animation: cost-warning-pulse 2s ease-in-out infinite;
}

@keyframes cost-warning-pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.8;
    }
}

/* Mobile responsive cost widget */
@media (max-width: 768px) {
    .cost-widget {
        font-size: 0.5em !important;
        padding: 0.25rem 0.4rem !important;
    }
    
    .dropdown-menu .cost-summary-item {
        font-size: 0.8rem;
    }
}

/* Theme Toggle Button */
.theme-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    border: 1px solid rgb(var(--border));
    background-color: rgb(var(--background));
    color: rgb(var(--foreground));
    cursor: pointer;
    transition: all 0.2s ease;
    font-size: 1rem;
    margin-left: 0.5rem;
}

.theme-toggle:hover {
    background-color: rgb(var(--accent));
    transform: scale(1.05);
}

.theme-toggle:active {
    transform: scale(0.95);
}

.theme-toggle .theme-icon {
    transition: transform 0.3s ease, opacity 0.2s ease;
    position: absolute;
}

.theme-toggle .theme-icon.hidden {
    transform: rotate(180deg);
    opacity: 0;
}

/* Dark mode specific overrides for Bootstrap components */
[data-theme="dark"] .navbar-dark {
    background-color: rgb(var(--card)) !important;
    border-bottom: 1px solid rgb(var(--border));
}

[data-theme="dark"] .navbar-dark .navbar-nav .nav-link {
    color: rgb(var(--foreground)) !important;
}

[data-theme="dark"] .navbar-dark .navbar-nav .nav-link:hover {
    color: rgb(var(--primary-text)) !important;
}

[data-theme="dark"] .navbar-dark .navbar-brand {
    color: rgb(var(--foreground)) !important;
}

.dropdown-menu {
    z-index: 9999 !important;
}

[data-theme="dark"] .dropdown-menu {
    background-color: rgb(var(--popover));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--popover-foreground));
}

[data-theme="dark"] .dropdown-item {
    color: rgb(var(--popover-foreground));
}

[data-theme="dark"] .dropdown-item:hover,
[data-theme="dark"] .dropdown-item:focus {
    background-color: rgb(var(--accent));
    color: rgb(var(--accent-foreground));
}

[data-theme="dark"] .dropdown-divider {
    border-color: rgb(var(--border));
}

[data-theme="dark"] .modal-content {
    background-color: rgb(var(--card));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--card-foreground));
}

[data-theme="dark"] .modal-header {
    border-bottom: 1px solid rgb(var(--border));
}

[data-theme="dark"] .modal-footer {
    border-top: 1px solid rgb(var(--border));
}

[data-theme="dark"] .btn-close {
    filter: invert(1);
}

/* Enhanced Form elements in dark mode - darker backgrounds for better eye comfort */
[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select,
[data-theme="dark"] .form-control-plaintext,
[data-theme="dark"] input[type="text"],
[data-theme="dark"] input[type="email"],
[data-theme="dark"] input[type="password"],
[data-theme="dark"] input[type="number"],
[data-theme="dark"] input[type="search"],
[data-theme="dark"] input[type="url"],
[data-theme="dark"] input[type="tel"],
[data-theme="dark"] input[type="date"],
[data-theme="dark"] input[type="datetime-local"],
[data-theme="dark"] input[type="time"],
[data-theme="dark"] textarea {
    background-color: rgb(var(--card));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--foreground));
    transition: all 0.2s ease;
}

[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus,
[data-theme="dark"] input:focus,
[data-theme="dark"] textarea:focus {
    background-color: rgb(var(--card));
    border-color: rgb(var(--ring));
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25);
    color: rgb(var(--foreground));
}

[data-theme="dark"] .form-control::placeholder,
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
    color: rgb(var(--muted-foreground));
    opacity: 0.8;
}

[data-theme="dark"] .form-control:disabled,
[data-theme="dark"] .form-select:disabled,
[data-theme="dark"] input:disabled,
[data-theme="dark"] textarea:disabled {
    background-color: rgb(var(--muted));
    color: rgb(var(--muted-foreground));
    opacity: 0.7;
}

/* Form check elements (checkboxes, radios) */
[data-theme="dark"] .form-check-input {
    background-color: rgb(var(--card));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--primary-text));
}

[data-theme="dark"] .form-check-input:focus {
    border-color: rgb(var(--ring));
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25);
}

[data-theme="dark"] .form-check-input:checked {
    background-color: rgb(var(--primary));
    border-color: rgb(var(--primary));
}

/* Input groups */
[data-theme="dark"] .input-group-text {
    background-color: rgb(var(--muted));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--foreground));
}

/* Form labels */
[data-theme="dark"] .form-label,
[data-theme="dark"] label {
    color: rgb(var(--foreground));
}

/* Form text/help text */
[data-theme="dark"] .form-text {
    color: rgb(var(--muted-foreground));
}

/* Form floating labels */
[data-theme="dark"] .form-floating label {
    color: rgb(var(--muted-foreground));
}

[data-theme="dark"] .form-floating .form-control:focus ~ label,
[data-theme="dark"] .form-floating .form-control:not(:placeholder-shown) ~ label {
    color: rgb(var(--ring));
}

/* Switch/toggle styling */
[data-theme="dark"] .form-switch .form-check-input {
    background-color: rgb(var(--muted));
    background-image: none;
}

[data-theme="dark"] .form-switch .form-check-input:checked {
    background-color: rgb(var(--primary));
}

/* File inputs */
[data-theme="dark"] .form-control[type="file"] {
    background-color: rgb(var(--card));
    border: 1px solid rgb(var(--border));
}

[data-theme="dark"] .form-control[type="file"]::-webkit-file-upload-button {
    background-color: rgb(var(--muted));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--foreground));
}

/* Range inputs */
[data-theme="dark"] .form-range {
    background: transparent;
}

[data-theme="dark"] .form-range::-webkit-slider-track {
    background-color: rgb(var(--border));
}

[data-theme="dark"] .form-range::-webkit-slider-thumb {
    background-color: rgb(var(--primary));
    border: 2px solid rgb(var(--card));
}

[data-theme="dark"] .form-range::-moz-range-track {
    background-color: rgb(var(--border));
}

[data-theme="dark"] .form-range::-moz-range-thumb {
    background-color: rgb(var(--primary));
    border: 2px solid rgb(var(--card));
}

/* Auto theme detection for form elements */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .form-control,
  :root:not([data-theme]) .form-select,
  :root:not([data-theme]) .form-control-plaintext,
  :root:not([data-theme]) input[type="text"],
  :root:not([data-theme]) input[type="email"],
  :root:not([data-theme]) input[type="password"],
  :root:not([data-theme]) input[type="number"],
  :root:not([data-theme]) input[type="search"],
  :root:not([data-theme]) input[type="url"],
  :root:not([data-theme]) input[type="tel"],
  :root:not([data-theme]) input[type="date"],
  :root:not([data-theme]) input[type="datetime-local"],
  :root:not([data-theme]) input[type="time"],
  :root:not([data-theme]) textarea {
    background-color: rgb(var(--card));
    border: 1px solid rgb(var(--border));
    color: rgb(var(--foreground));
    transition: all 0.2s ease;
  }

  :root:not([data-theme]) .form-control:focus,
  :root:not([data-theme]) .form-select:focus,
  :root:not([data-theme]) input:focus,
  :root:not([data-theme]) textarea:focus {
    background-color: rgb(var(--card));
    border-color: rgb(var(--ring));
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25);
    color: rgb(var(--foreground));
  }

  :root:not([data-theme]) .form-control::placeholder,
  :root:not([data-theme]) input::placeholder,
  :root:not([data-theme]) textarea::placeholder {
    color: rgb(var(--muted-foreground));
    opacity: 0.8;
  }

  :root:not([data-theme]) .form-check-input {
    background-color: rgb(var(--card));
    border: 1px solid rgb(var(--border));
  }

  :root:not([data-theme]) .form-check-input:focus {
    border-color: rgb(var(--ring));
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25);
  }

  :root:not([data-theme]) .form-check-input:checked {
    background-color: rgb(var(--primary));
    border-color: rgb(var(--primary));
  }

  :root:not([data-theme]) .form-label,
  :root:not([data-theme]) .form-text {
    color: rgb(var(--foreground));
  }

  :root:not([data-theme]) .form-floating label {
    color: rgb(var(--muted-foreground));
  }

  :root:not([data-theme]) .form-floating .form-control:focus ~ label,
  :root:not([data-theme]) .form-floating .form-control:not(:placeholder-shown) ~ label {
    color: rgb(var(--ring));
  }
}

/* Alert components */
[data-theme="dark"] .alert-success {
    background-color: rgb(var(--success) / 0.1);
    border-color: rgb(var(--success) / 0.2);
    color: rgb(var(--success-text));
}

[data-theme="dark"] .alert-danger {
    background-color: rgb(var(--destructive) / 0.1);
    border-color: rgb(var(--destructive) / 0.2);
    color: rgb(var(--destructive-text));
}

[data-theme="dark"] .alert-warning {
    background-color: rgb(var(--warning) / 0.1);
    border-color: rgb(var(--warning) / 0.2);
    color: rgb(var(--warning-text));
}

[data-theme="dark"] .alert-info {
    background-color: rgb(var(--info) / 0.1);
    border-color: rgb(var(--info) / 0.2);
    color: rgb(var(--info-text));
}

/* Footer */
[data-theme="dark"] .bg-light,
[data-theme="dark"] footer.bg-light {
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--muted-foreground)) !important;
}

/* Auto theme footer for dark mode */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .bg-light,
  :root:not([data-theme]) footer.bg-light {
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--muted-foreground)) !important;
  }
}

/* Modal overrides for dark theme */
[data-theme="dark"] .modal-content {
    background-color: rgb(var(--card)) !important;
    color: rgb(var(--card-foreground)) !important;
    border: 1px solid rgb(var(--border)) !important;
}

/* Custom badge classes using CSS variables */
.badge-success-custom {
    background-color: rgb(var(--success));
    color: white;
}

.badge-muted-custom {
    background-color: rgb(var(--muted));
    color: rgb(var(--muted-foreground));
}

.badge-destructive-custom {
    background-color: rgb(var(--destructive));
    color: white;
}

.badge-warning-custom {
    background-color: rgb(var(--warning));
    color: rgb(var(--warning-foreground));
}

.badge-dark-custom {
    background-color: rgb(var(--foreground));
    color: rgb(var(--background));
}

.badge-info-custom {
    background-color: rgb(var(--info));
    color: white;
}

.badge-primary-custom {
    background-color: rgb(var(--primary));
    color: white;
}

[data-theme="dark"] .modal-header {
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--foreground)) !important;
    border-bottom: 1px solid rgb(var(--border)) !important;
}

[data-theme="dark"] .modal-footer {
    background-color: rgb(var(--muted)) !important;
    border-top: 1px solid rgb(var(--border)) !important;
}

[data-theme="dark"] .modal-body {
    background-color: rgb(var(--card)) !important;
    color: rgb(var(--card-foreground)) !important;
}

/* Specific styling for Task Information textarea in dark mode - with higher specificity */
[data-theme="dark"] .modal-body #editTaskInfo,
[data-theme="dark"] #editTaskModal #editTaskInfo,
[data-theme="dark"] textarea#editTaskInfo,
[data-theme="dark"] .form-control#editTaskInfo {
    background-color: rgb(15 23 42) !important;  /* Darker background for better contrast */
    color: rgb(248 250 252) !important;  /* Light text */
    border: 1px solid rgb(51 65 85) !important;  /* Visible border */
}

[data-theme="dark"] .modal-body #editTaskInfo:focus,
[data-theme="dark"] #editTaskModal #editTaskInfo:focus,
[data-theme="dark"] textarea#editTaskInfo:focus,
[data-theme="dark"] .form-control#editTaskInfo:focus {
    background-color: rgb(15 23 42) !important;
    border-color: rgb(var(--ring)) !important;
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25) !important;
    color: rgb(248 250 252) !important;
    outline: none !important;
}

[data-theme="dark"] #editTaskInfo::placeholder {
    color: rgb(148 163 184) !important;  /* Muted placeholder text */
    opacity: 1 !important;
}

/* Also target the description textarea for consistency */
[data-theme="dark"] .modal-body #editTaskDescription,
[data-theme="dark"] #editTaskModal #editTaskDescription,
[data-theme="dark"] textarea#editTaskDescription,
[data-theme="dark"] .form-control#editTaskDescription {
    background-color: rgb(15 23 42) !important;
    color: rgb(248 250 252) !important;
    border: 1px solid rgb(51 65 85) !important;
}

[data-theme="dark"] .modal-body #editTaskDescription:focus,
[data-theme="dark"] #editTaskModal #editTaskDescription:focus,
[data-theme="dark"] textarea#editTaskDescription:focus,
[data-theme="dark"] .form-control#editTaskDescription:focus {
    background-color: rgb(15 23 42) !important;
    border-color: rgb(var(--ring)) !important;
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25) !important;
    color: rgb(248 250 252) !important;
    outline: none !important;
}

/* Auto theme modals for dark mode */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .modal-content {
    background-color: rgb(var(--card)) !important;
    color: rgb(var(--card-foreground)) !important;
    border: 1px solid rgb(var(--border)) !important;
  }
  
  /* Auto theme for Task Information textarea with higher specificity */
  :root:not([data-theme]) .modal-body #editTaskInfo,
  :root:not([data-theme]) #editTaskModal #editTaskInfo,
  :root:not([data-theme]) textarea#editTaskInfo,
  :root:not([data-theme]) .form-control#editTaskInfo {
    background-color: rgb(15 23 42) !important;
    color: rgb(248 250 252) !important;
    border: 1px solid rgb(51 65 85) !important;
  }
  
  :root:not([data-theme]) .modal-body #editTaskInfo:focus,
  :root:not([data-theme]) #editTaskModal #editTaskInfo:focus,
  :root:not([data-theme]) textarea#editTaskInfo:focus,
  :root:not([data-theme]) .form-control#editTaskInfo:focus {
    background-color: rgb(15 23 42) !important;
    border-color: rgb(var(--ring)) !important;
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25) !important;
    color: rgb(248 250 252) !important;
    outline: none !important;
  }
  
  :root:not([data-theme]) #editTaskInfo::placeholder {
    color: rgb(148 163 184) !important;
    opacity: 1 !important;
  }
  
  /* Auto theme for Description textarea */
  :root:not([data-theme]) .modal-body #editTaskDescription,
  :root:not([data-theme]) #editTaskModal #editTaskDescription,
  :root:not([data-theme]) textarea#editTaskDescription,
  :root:not([data-theme]) .form-control#editTaskDescription {
    background-color: rgb(15 23 42) !important;
    color: rgb(248 250 252) !important;
    border: 1px solid rgb(51 65 85) !important;
  }
  
  :root:not([data-theme]) .modal-body #editTaskDescription:focus,
  :root:not([data-theme]) #editTaskModal #editTaskDescription:focus,
  :root:not([data-theme]) textarea#editTaskDescription:focus,
  :root:not([data-theme]) .form-control#editTaskDescription:focus {
    background-color: rgb(15 23 42) !important;
    border-color: rgb(var(--ring)) !important;
    box-shadow: 0 0 0 0.125rem rgb(var(--ring) / 0.25) !important;
    color: rgb(248 250 252) !important;
    outline: none !important;
  }
  
  :root:not([data-theme]) .modal-header {
    background-color: rgb(var(--muted)) !important;
    color: rgb(var(--foreground)) !important;
    border-bottom: 1px solid rgb(var(--border)) !important;
  }
  
  :root:not([data-theme]) .modal-footer {
    background-color: rgb(var(--muted)) !important;
    border-top: 1px solid rgb(var(--border)) !important;
  }
  
  :root:not([data-theme]) .modal-body {
    background-color: rgb(var(--card)) !important;
    color: rgb(var(--card-foreground)) !important;
  }
}

/* Button overrides */
.btn-primary {
    background-color: rgb(var(--primary));
    border-color: rgb(var(--primary));
    color: rgb(var(--primary-foreground));
}

.btn-primary:hover {
    background-color: rgb(var(--primary) / 0.9);
    border-color: rgb(var(--primary) / 0.9);
}

.btn-secondary {
    background-color: rgb(var(--secondary));
    border-color: rgb(var(--secondary));
    color: rgb(var(--secondary-foreground));
}

.btn-secondary:hover {
    background-color: rgb(var(--secondary) / 0.8);
    border-color: rgb(var(--secondary) / 0.8);
}

.btn-outline-primary {
    border-color: rgb(var(--primary));
    color: rgb(var(--primary-text));
}

.btn-outline-primary:hover {
    background-color: rgb(var(--primary));
    color: rgb(var(--primary-foreground));
}

/* Badge components */
.badge {
    transition: all 0.2s ease;
}

/* EVERY solid badge names its own label colour.
   Only .bg-warning did. The other three set the fill and let Bootstrap's
   `.badge { color: #fff }` stand — and none of these fills is dark enough to
   carry white: 2.28:1 on the success green (seen on /assistant and /goals),
   3.68:1 on the info blue. The -foreground token exists for exactly this and
   flips per theme; the fill stays the vivid one. */
.badge.bg-success {
    background-color: rgb(var(--success)) !important;
    color: rgb(var(--success-foreground)) !important;
}

.badge.bg-warning {
    background-color: rgb(var(--warning)) !important;
    color: rgb(var(--warning-foreground)) !important;
}

.badge.bg-danger {
    background-color: rgb(var(--destructive)) !important;
    color: rgb(var(--destructive-foreground)) !important;
}

.badge.bg-info {
    background-color: rgb(var(--info)) !important;
    color: rgb(var(--info-foreground)) !important;
}

.badge.bg-primary {
    background-color: rgb(var(--primary)) !important;
    color: rgb(var(--primary-foreground)) !important;
}

.badge.bg-secondary {
    background-color: rgb(var(--secondary)) !important;
    color: rgb(var(--secondary-foreground)) !important;
}

/* `.bg-green` is not a Bootstrap class and has no rule anywhere in the app, so
   a badge wearing it painted no fill at all and Bootstrap's white label landed
   on the page background — 1.05:1, an empty capsule on /assistant. The class
   name comes from stored data rather than from a template, so it cannot simply
   be renamed at the call site; it is answered here instead. */
.badge.bg-green {
    background-color: rgb(var(--success)) !important;
    color: rgb(var(--success-foreground)) !important;
}

/* The outline family, which was raw Bootstrap everywhere except inside
   `.job-card`. Bootstrap's own $warning and $info are a light amber and a
   light cyan meant to be READ AS A FILL; as an outline button's label they
   measured 1.49:1 ("Remove All", a bulk destructive action, on
   /admin/permissions) and 1.79:1. Each takes its -text ink, and the filled
   hover state takes the matching -foreground. */
/* `--bs-btn-color`, not `color`. Bootstrap 5 buttons resolve their ink through
   that variable — `.btn { color: var(--bs-btn-color) }` — so a plain `color:`
   on the variant class is overwritten by `.btn` itself, and the raw #6c757d
   survived at 4.29-4.48:1 across ten pages even after being "fixed". Setting
   the variable is the only spelling that reaches; the plain declaration stays
   beside it for anything that reads the property directly. */
.btn-outline-success {
    --bs-btn-color: rgb(var(--success-text));
    --bs-btn-border-color: rgb(var(--success));
    --bs-btn-hover-color: rgb(var(--success-foreground));
    --bs-btn-hover-bg: rgb(var(--success));
    --bs-btn-hover-border-color: rgb(var(--success));
    border-color: rgb(var(--success));
    color: rgb(var(--success-text));
}
.btn-outline-warning {
    --bs-btn-color: rgb(var(--warning-text));
    --bs-btn-border-color: rgb(var(--warning));
    --bs-btn-hover-color: rgb(var(--warning-foreground));
    --bs-btn-hover-bg: rgb(var(--warning));
    --bs-btn-hover-border-color: rgb(var(--warning));
    border-color: rgb(var(--warning));
    color: rgb(var(--warning-text));
}
.btn-outline-danger {
    --bs-btn-color: rgb(var(--destructive-text));
    --bs-btn-border-color: rgb(var(--destructive));
    --bs-btn-hover-color: rgb(var(--destructive-foreground));
    --bs-btn-hover-bg: rgb(var(--destructive));
    --bs-btn-hover-border-color: rgb(var(--destructive));
    border-color: rgb(var(--destructive));
    color: rgb(var(--destructive-text));
}
.btn-outline-info {
    --bs-btn-color: rgb(var(--info-text));
    --bs-btn-border-color: rgb(var(--info));
    --bs-btn-hover-color: rgb(var(--info-foreground));
    --bs-btn-hover-bg: rgb(var(--info));
    --bs-btn-hover-border-color: rgb(var(--info));
    border-color: rgb(var(--info));
    color: rgb(var(--info-text));
}

/* `--secondary` is a SURFACE token, so Bootstrap's grey outline had no ink of
   its own. It borrows --border for the edge and --secondary-text for the ink. */
.btn-outline-secondary {
    --bs-btn-color: rgb(var(--secondary-text));
    --bs-btn-border-color: rgb(var(--border));
    --bs-btn-hover-color: rgb(var(--secondary-foreground));
    --bs-btn-hover-bg: rgb(var(--secondary));
    --bs-btn-hover-border-color: rgb(var(--border));
    border-color: rgb(var(--border));
    color: rgb(var(--secondary-text));
}
