/* ============================================================================
   AIToolsay — DARK SYSTEM (§DKSYS)
   The one place the site's dark palette is defined. Loaded on every layout.
   ----------------------------------------------------------------------------
   WHY THIS FILE EXISTS
   Before it, the site painted dark mode out of 159 different neutral hexes
   spread over 164 stylesheets. Two families had grown side by side: the
   homepage's NEUTRAL near-black (#0E0E11 / #17171B / #F4F5F7) and a
   NAVY-tinted one inherited from Tabler and Tailwind's slate ramp
   (#111827 / #0F172A / #1E293B / #CBD5E1). Both are defensible on their own;
   together they read as two different websites, because moving from the
   homepage to a listing page shifted the page background AND its hue.

   THE MASTER IS THE HOMEPAGE. Every value below is the homepage's own dark
   token, read out of `hp_tokens.value_dark` — the row an admin edits on the
   theme screen. `ThemeCompiler` emits those same values as `--hpx-*` under
   `body.theme-dark .hpx`; this file restates them as `--dk-*` so the other
   ~300 URLs can consume the identical palette without depending on the
   homepage kit being on the page.

   HOW TO USE IT
   Never hard-code a dark neutral again. Write:

       body.theme-dark .my-card { background: var(--dk-surface-2, #17171B); }

   ALWAYS PASS THE FALLBACK. Some surfaces (the installer, the error shell,
   an e-mail preview) render without this sheet, and a `var()` that cannot
   resolve makes the whole declaration invalid — a card with no background at
   all, which is worse than a slightly stale hex. The fallback is also what
   makes this file safe to load in any order.

   SCOPE DISCIPLINE
   Everything here is inside `body.theme-dark`. Light mode reads only the
   `:root` block, which restates the site's existing light values and changes
   nothing. If you find yourself wanting an unscoped rule in this file, it
   belongs in custom.*.css instead.
   ========================================================================= */


/* ---------------------------------------------------------------------------
   1. Tokens — light
   These are declarations, not a redesign: each one is the value the site
   already used. They exist so `var(--dk-…)` resolves in both themes and so a
   component can be written once instead of twice.
   ------------------------------------------------------------------------ */
:root {
    /* Canvas */
    --dk-bg:            #FFFFFF;
    --dk-bg-deep:       #EEF3F9;
    --dk-surface:       #F7F9FC;
    --dk-surface-2:     #FFFFFF;
    --dk-surface-3:     #F9FAFC;
    --dk-surface-4:     #F1F4F9;
    --dk-glass:         rgba(255,255,255,.72);

    /* Lines */
    --dk-line:          #E7ECF3;
    --dk-line-soft:     #F0F3F8;
    --dk-line-strong:   #D6DEE9;
    --dk-line-solid:    #E7ECF3;
    --dk-line-solid-2:  #D6DEE9;

    /* Ink */
    --dk-text:          #0B1220;
    --dk-text-2:        #3D4757;
    --dk-text-3:        #6B7686;
    --dk-text-4:        #98A2B3;
    --dk-text-invert:   #FFFFFF;
    --dk-icon:          #3D4757;

    /* Accent */
    --dk-accent:        #3680ED;
    --dk-accent-hover:  #2060C0;
    --dk-accent-active: #1B4E9C;
    --dk-accent-ink:    #1B5BB5;
    --dk-accent-soft:   #EAF2FD;
    --dk-accent-line:   #CFE0FA;
    --dk-accent-glow:   rgba(54,128,237,.28);

    /* The PLATE cut of the brand blue. #3680ED under a white glyph is
       3.84:1 — fine as ink, short as a fill. Same hue, walked to 4.64:1.
       NOT themed: a plate carries white in either theme, so it is declared
       once here and read by both the admin shell and the v2 base. */
    --dk-brand-plate:   #1C6FEB;

    /* Controls */
    --dk-input:         #FFFFFF;
    --dk-input-border:  #D6DEE9;
    --dk-input-ph:      #98A2B3;
    --dk-disabled:      #F1F4F9;

    /* ── Tone plates ──────────────────────────────────────────────
       The fill behind a WHITE glyph on a coloured icon chip or pill.

       Kits used to fill those with the tone's `-ink` token, which works by
       day (the light ink is a saturated dark hue) and fails at night, because
       every dark ink twin on this site is a PASTEL authored to sit as text on
       a tint — white on #8CBEFA measures 2.4:1. Six kits independently
       papered over that with the same flat scrim, which buys the contrast
       back by draining the chroma twice and is why the chips read as dusty.

       A plate is the same hue as its ink, lifted to the brightest point that
       still carries white at 4.6:1 — the rule light mode already follows, and
       the reason amber is bronze and emerald forest by day. FILL with these;
       keep using `-ink` for text, hairlines and markers.

       The homepage reads the same eleven values from hp_tokens (`t-*-plate`),
       because every colour on that page has to stay admin-editable. Change
       one here, change its row there. */
    --dk-tone-blue-plate:      #1B5BB5;
    --dk-tone-violet-plate:    #5B33C4;
    --dk-tone-emerald-plate:   #08795A;
    --dk-tone-amber-plate:     #A85B08;
    --dk-tone-rose-plate:      #B31D3C;
    --dk-tone-cyan-plate:      #0A6E88;
    --dk-tone-indigo-plate:    #3540B0;
    --dk-tone-orange-plate:    #B4500C;
    --dk-tone-teal-plate:      #0B6E68;
    --dk-tone-pink-plate:      #A81E75;
    --dk-tone-slate-plate:     #38455A;

    /* Depth */
    --dk-overlay:       rgba(11,18,32,.45);
    --dk-shadow:        0 1px 2px rgba(16,24,40,.04), 0 6px 20px rgba(16,24,40,.05);
    --dk-shadow-lift:   0 2px 6px rgba(16,24,40,.06), 0 18px 44px rgba(16,24,40,.10);
    --dk-focus:         0 0 0 3px rgba(54,128,237,.28);
}


/* ---------------------------------------------------------------------------
   2. Tokens — dark  ·  THE MASTER PALETTE
   Sourced 1:1 from hp_tokens.value_dark (the homepage). Six surface rungs,
   four inks, three hairlines. If a value is not on this list, dark mode does
   not have it.

       bg          #0E0E11   page canvas, edge to edge
       bg-deep     #0A0A0C   recessed: wells, code blocks, behind a sticky bar
       surface     #131317   a band that lifts off the canvas but is not a card
       surface-2   #17171B   THE CARD. panels, modals, dropdowns, popovers
       surface-3   #1D1D22   raised inside a card: inputs, table heads, chips
       surface-4   #24242A   hover/active step above surface-3

   The 9-unit gap between bg and the card is what makes cards read as objects.
   Painting the canvas at #141416 (as the site did outside the homepage) left
   a 3-unit gap and the cards visually dissolved into the page.
   ------------------------------------------------------------------------ */
body.theme-dark {
    /* Canvas */
    --dk-bg:            #0E0E11;
    --dk-bg-deep:       #0A0A0C;
    --dk-surface:       #131317;
    --dk-surface-2:     #17171B;
    --dk-surface-3:     #1D1D22;
    --dk-surface-4:     #24242A;
    --dk-glass:         rgba(28,28,33,.72);

    /* Lines — alpha, not hex, so a hairline reads correctly on every rung.
       A solid #2C2C31 border is right on the card and too heavy on the
       canvas; white-at-10% is right on both. The two `-solid` twins are for
       the handful of places alpha cannot be used (over an image, or where a
       border-image needs a resolved colour). */
    --dk-line:          rgba(255,255,255,.10);
    --dk-line-soft:     rgba(255,255,255,.06);
    --dk-line-strong:   rgba(255,255,255,.16);
    --dk-line-solid:    #2C2C31;
    --dk-line-solid-2:  #3A3A42;

    /* Ink — four rungs, measured against --dk-surface-2 (#17171B):
       text 16.39:1 · text-2 10.89:1 · text-3 6.80:1 · text-4 3.92:1.
       (On the canvas #0E0E11 each is a little higher: 17.67 / 11.75 / 7.33.)
       text-4 is for DISABLED and decorative use only — 3.92:1 clears the 3:1
       non-text minimum but not AA for body copy, so it must never carry a
       sentence. */
    --dk-text:          #F4F5F7;
    --dk-text-2:        #C7CAD1;
    --dk-text-3:        #9AA0AB;
    --dk-text-4:        #71767F;
    --dk-text-invert:   #FFFFFF;
    --dk-icon:          #C7CAD1;

    /* Accent — the brand blue lifted for a dark canvas. #3680ED measures
       4.65:1 on #17171B: it scrapes AA for body text and fails it outright
       under white (3.84:1 — see ai-contrast-fix.css, which exists because of
       exactly that). #60A4F5 is 6.92:1 with real headroom for links, glyphs
       and small text, and still unmistakably the brand. */
    --dk-accent:        #60A4F5;
    --dk-accent-hover:  #4A8FE8;
    --dk-accent-active: #3B7BD4;
    --dk-accent-ink:    #8CBEFA;
    --dk-accent-soft:   rgba(54,128,237,.16);
    --dk-accent-line:   rgba(96,164,245,.28);
    --dk-accent-glow:   rgba(96,164,245,.32);

    /* Controls — a field sits one rung ABOVE the card it lives on, never
       below it. Sunken fields look disabled on a dark surface because the
       eye reads "further away" as "unavailable". */
    --dk-input:         #1D1D22;
    --dk-input-border:  rgba(255,255,255,.14);
    --dk-input-ph:      #71767F;
    --dk-disabled:      #17171B;


    /* ── Tone plates · the lifted twins ──────────────────────────────────────────────
       The fill behind a WHITE glyph on a coloured icon chip or pill.

       Kits used to fill those with the tone's `-ink` token, which works by
       day (the light ink is a saturated dark hue) and fails at night, because
       every dark ink twin on this site is a PASTEL authored to sit as text on
       a tint — white on #8CBEFA measures 2.4:1. Six kits independently
       papered over that with the same flat scrim, which buys the contrast
       back by draining the chroma twice and is why the chips read as dusty.

       A plate is the same hue as its ink, lifted to the brightest point that
       still carries white at 4.6:1 — the rule light mode already follows, and
       the reason amber is bronze and emerald forest by day. FILL with these;
       keep using `-ink` for text, hairlines and markers.

       The homepage reads the same eleven values from hp_tokens (`t-*-plate`),
       because every colour on that page has to stay admin-editable. Change
       one here, change its row there. */
    --dk-tone-blue-plate:      #2572DF;
    --dk-tone-violet-plate:    #8060D6;
    --dk-tone-emerald-plate:   #098563;
    --dk-tone-amber-plate:     #B16008;
    --dk-tone-rose-plate:      #DD2C51;
    --dk-tone-cyan-plate:      #0C7F9D;
    --dk-tone-indigo-plate:    #616BCF;
    --dk-tone-orange-plate:    #BF550D;
    --dk-tone-teal-plate:      #0D837C;
    --dk-tone-pink-plate:      #D52694;
    --dk-tone-slate-plate:     #60769A;

    /* Depth — on a dark canvas a shadow cannot be "darker than the page", so
       these lean on opacity rather than spread, and elevation is carried by
       the surface rung. The overlay is near-black, not the light theme's
       navy: a navy scrim over a neutral page tints the whole viewport. */
    --dk-overlay:       rgba(6,6,8,.72);
    --dk-shadow:        0 1px 2px rgba(0,0,0,.4), 0 6px 20px rgba(0,0,0,.34);
    --dk-shadow-lift:   0 2px 6px rgba(0,0,0,.46), 0 18px 44px rgba(0,0,0,.5);
    --dk-focus:         0 0 0 3px rgba(96,164,245,.32);
}


/* ---------------------------------------------------------------------------
   3. color-scheme
   custom.*.css already declares this for the public site and
   aitoolsay-admin.css for the admin, but v2-plain, the installer and the
   error shell load neither. Without it the browser paints native UI —
   <select> popups, number spinners, autofill, the default scrollbar — from
   the OS preference, so a visitor on a light OS who chose dark on the site
   gets white system widgets on a black page. See the note in custom.ltr.css.
   ------------------------------------------------------------------------ */
body.theme-light { color-scheme: light; }
body.theme-dark  { color-scheme: dark; }

/* The ROOT scrollbar — and anything else the UA paints outside <body> —
   resolves from the DOCUMENT colour-scheme, which a declaration on body
   cannot reach. pwa-head ships `<meta name="color-scheme" content="light
   dark">`, and that resolves against the OS, so on a light OS with the site
   in dark the root scrollbar came back light. `:has()` lets the root follow
   the body class, which is the visitor's choice rather than the machine's.
   Browsers without `:has()` fall back to the meta, i.e. to today's behaviour. */
html:has(body.theme-light) { color-scheme: light; }
html:has(body.theme-dark)  { color-scheme: dark; }


/* ---------------------------------------------------------------------------
   4. Selection
   Unstyled ::selection in dark mode is the UA's own blue-on-white, which
   flashes light every time a visitor drags across a paragraph.
   ------------------------------------------------------------------------ */
body.theme-dark ::selection {
    background: rgba(96,164,245,.30);
    color: var(--dk-text, #F4F5F7);
}


/* ---------------------------------------------------------------------------
   5. Autofill
   Chrome paints its own #E8F0FE over any field it has autofilled and there is
   no property that overrides it — the only lever is an inset shadow large
   enough to cover the box, plus -webkit-text-fill-color for the value. The
   long transition is the standard trick to outrun the UA's own repaint.
   ------------------------------------------------------------------------ */
body.theme-dark input:-webkit-autofill,
body.theme-dark input:-webkit-autofill:hover,
body.theme-dark input:-webkit-autofill:focus,
body.theme-dark input:-webkit-autofill:active,
body.theme-dark textarea:-webkit-autofill,
body.theme-dark select:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px var(--dk-input, #1D1D22) inset !important;
            box-shadow: 0 0 0 1000px var(--dk-input, #1D1D22) inset !important;
    -webkit-text-fill-color: var(--dk-text, #F4F5F7) !important;
    caret-color: var(--dk-text, #F4F5F7);
    transition: background-color 600000s 0s, color 600000s 0s;
}


/* ---------------------------------------------------------------------------
   6. Native date / time / colour pickers
   The calendar and clock glyphs Chrome draws inside these inputs are black
   bitmaps. invert() is the only way to reach them.
   ------------------------------------------------------------------------ */
body.theme-dark input[type="date"]::-webkit-calendar-picker-indicator,
body.theme-dark input[type="time"]::-webkit-calendar-picker-indicator,
body.theme-dark input[type="datetime-local"]::-webkit-calendar-picker-indicator,
body.theme-dark input[type="month"]::-webkit-calendar-picker-indicator,
body.theme-dark input[type="week"]::-webkit-calendar-picker-indicator {
    filter: invert(1) brightness(.85);
    opacity: .8;
}
body.theme-dark input[type="date"]::-webkit-calendar-picker-indicator:hover,
body.theme-dark input[type="time"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }


/* ---------------------------------------------------------------------------
   7. Bootstrap / Tabler primitives custom.*.css does not reach
   Everything else (modal, dropdown, tooltip, popover, toast, list-group,
   form-control, form-select, pagination, accordion, table, placeholder) is
   already twinned there and is deliberately NOT restated here — a second
   copy at a different specificity is how these things start disagreeing.
   ------------------------------------------------------------------------ */

/* Offcanvas — the mobile nav / filter drawer. No dark twin existed. */
body.theme-dark .offcanvas,
body.theme-dark .offcanvas-start,
body.theme-dark .offcanvas-end,
body.theme-dark .offcanvas-top,
body.theme-dark .offcanvas-bottom {
    background-color: var(--dk-surface-2, #17171B);
    color: var(--dk-text, #F4F5F7);
    border-color: var(--dk-line, rgba(255,255,255,.10));
}
body.theme-dark .offcanvas-header,
body.theme-dark .offcanvas-footer { border-color: var(--dk-line, rgba(255,255,255,.10)); }
body.theme-dark .offcanvas-title { color: var(--dk-text, #F4F5F7); }
body.theme-dark .offcanvas-backdrop.show { background: var(--dk-overlay, rgba(6,6,8,.72)); opacity: 1; }

/* The dismiss "×" is a black SVG data-URI in Bootstrap. Without this it is
   invisible on every dark modal, offcanvas, alert and toast on the site. */
body.theme-dark .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
    opacity: .65;
}
body.theme-dark .btn-close:hover,
body.theme-dark .btn-close:focus-visible { opacity: 1; }

/* Modal backdrop — Bootstrap's default is #000 at .5, which over a #0E0E11
   page is barely a change and leaves the modal looking unanchored. */
body.theme-dark .modal-backdrop.show { background-color: #000; opacity: .72; }

/* NOT here: a global :focus-visible outline colour. `body.theme-dark
   :focus-visible` computes to (0,2,1) and would silently outrank the
   (0,2,0) focus rule almost every kit on the site writes — repainting a
   destructive button's red ring brand-blue as a side effect of a dark-mode
   fix. The UA ring is already correct once `color-scheme: dark` is declared
   (section 3), which is the actual reason focus went invisible on the
   layouts that were missing it. */


/* ---------------------------------------------------------------------------
   8. Choices.js  (the searchable <select> used across public forms)
   The vendor sheet inside custom.*.css paints the dropdown, its input and
   its disabled state #fff / #eaeaea with no dark twin anywhere — a white
   panel dropping out of a dark field, which is the single most visible
   dark-mode break on the site's forms.
   ------------------------------------------------------------------------ */
body.theme-dark .choices__inner {
    background-color: var(--dk-input, #1D1D22);
    border-color: var(--dk-input-border, rgba(255,255,255,.14));
    color: var(--dk-text, #F4F5F7);
}
body.theme-dark .choices.is-disabled .choices__inner,
body.theme-dark .choices.is-disabled .choices__input,
body.theme-dark .choices[data-type*="select-one"] .choices__input,
body.theme-dark .choices__input,
body.theme-dark .choices__list--dropdown,
body.theme-dark .choices__list[aria-expanded] {
    background-color: var(--dk-surface-2, #17171B);
    color: var(--dk-text, #F4F5F7);
}
body.theme-dark .choices.is-disabled .choices__inner,
body.theme-dark .choices.is-disabled .choices__input { background-color: var(--dk-disabled, #17171B); color: var(--dk-text-4, #71767F); }
body.theme-dark .choices__list--dropdown,
body.theme-dark .choices__list[aria-expanded] {
    border-color: var(--dk-line, rgba(255,255,255,.10));
    box-shadow: var(--dk-shadow-lift, 0 2px 6px rgba(0,0,0,.46), 0 18px 44px rgba(0,0,0,.5));
}
body.theme-dark .choices__list--dropdown .choices__item--selectable.is-highlighted,
body.theme-dark .choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
    background-color: var(--dk-surface-4, #24242A);
    color: var(--dk-text, #F4F5F7);
}
body.theme-dark .choices__list--dropdown .choices__item,
body.theme-dark .choices__list[aria-expanded] .choices__item { color: var(--dk-text-2, #C7CAD1); }
body.theme-dark .choices__placeholder { color: var(--dk-input-ph, #71767F); opacity: 1; }
body.theme-dark .choices__list--multiple .choices__item {
    background-color: var(--dk-accent-soft, rgba(54,128,237,.16));
    border-color: var(--dk-accent-line, rgba(96,164,245,.28));
    color: var(--dk-accent-ink, #8CBEFA);
}
body.theme-dark .choices__heading { color: var(--dk-text-3, #9AA0AB); border-color: var(--dk-line, rgba(255,255,255,.10)); }
body.theme-dark .choices-light { background-color: var(--dk-surface-3, #1D1D22); }
body.theme-dark .choices-white  { background-color: var(--dk-surface-2, #17171B); }


/* ---------------------------------------------------------------------------
   9. noUiSlider  (price / range filters)
   Track, handle and tooltip were #fafafa / #fff / #fff with no dark twin —
   a white pill on a dark rail.
   ------------------------------------------------------------------------ */
body.theme-dark .noUi-target {
    background: var(--dk-surface-3, #1D1D22);
    border-color: var(--dk-line, rgba(255,255,255,.10));
    box-shadow: none;
}
body.theme-dark .noUi-connect { background: var(--dk-accent, #60A4F5); }
body.theme-dark .noUi-handle {
    background: var(--dk-text, #F4F5F7);
    border-color: var(--dk-line-strong, rgba(255,255,255,.16));
    box-shadow: var(--dk-shadow, 0 1px 2px rgba(0,0,0,.4), 0 6px 20px rgba(0,0,0,.34));
}
body.theme-dark .noUi-handle:after,
body.theme-dark .noUi-handle:before { background: var(--dk-surface-3, #1D1D22); }
body.theme-dark .noUi-tooltip {
    background: var(--dk-surface-2, #17171B);
    border-color: var(--dk-line, rgba(255,255,255,.10));
    color: var(--dk-text, #F4F5F7);
}
body.theme-dark .noUi-marker,
body.theme-dark .noUi-marker-large,
body.theme-dark .noUi-marker-sub { background: var(--dk-line-solid, #2C2C31); }
body.theme-dark .noUi-value { color: var(--dk-text-3, #9AA0AB); }


/* ---------------------------------------------------------------------------
   10. Diff / revision highlights
   The pastel red + green a revision diff paints are ~90% luminance; on a
   #0E0E11 page they are two glowing slabs and the black text inside them is
   the only readable thing on the screen.
   ------------------------------------------------------------------------ */
body.theme-dark .result del,
body.theme-dark ins.diffmod,
body.theme-dark del.diffmod { background: rgba(244,63,94,.20); color: #FB9BB0; }
body.theme-dark .result ins { background: rgba(16,185,129,.18); color: #6EE7BE; }


/* ---------------------------------------------------------------------------
   11. The canvas
   ONE page background for the whole public site, in BOTH themes.

   This is the only place in this file that reads a `--dk-*` token outside a
   `body.theme-dark` rule, and it is deliberate: `--dk-bg` holds #FFFFFF on
   :root and #0E0E11 under .theme-dark, so a single declaration paints the
   canvas correctly either way. Everywhere else the dark-scope rule still
   applies — see the note at the top of the file. If you add another unscoped
   consumer, add it to the allow-list in the leak checker too, or the next
   person cannot tell your deliberate one from an accident.

   WHY IT HAD TO BE CENTRALISED. Light mode was running four different
   canvases: #FFFFFF on the homepage (the `.hpx` root paints it), #f6f8fc on
   the 51 v2 routes, #FAFAFA on the business pages, and Tabler's #f1f5f9
   everywhere else. Dark had the same split until the sweep. One token now
   answers for all of it.

   `--tblr-body-bg` is deliberately NOT repointed: three other Tabler rules
   read it — `.form-fieldset` most visibly — and a fieldset that loses its
   tint on a white card reads as a missing box rather than a cleaner one.
   Painting the canvas explicitly leaves those alone.

   Deliberately NOT !important: a kit that wants its own canvas still wins on
   specificity or order. This is a floor, not a ceiling. It doubles as the
   flash guard on a theme swap — the canvas is already right before any kit
   has had a chance to paint.
   ------------------------------------------------------------------------ */
body:not(.admin-shell),
body:not(.admin-shell) > .page,
body:not(.admin-shell) .page-wrapper,
body:not(.admin-shell) .page-wrapper > .page-content,
body:not(.admin-shell) .page-body,
body:not(.admin-shell) #parallax {
    background-color: var(--dk-bg, #FFFFFF);
}

/* Ink is dark-only here. The light body colour is Tabler's --tblr-body-color
   and several kits are drawn against it; moving it is a typography decision,
   not a canvas one. */
body.theme-dark { color: var(--dk-text, #F4F5F7); }
