/* Bridges the DevExtreme Fluent SaaS theme onto the raxwel Docs palette.
 *
 * Loaded AFTER dx.fluent.saas.{light,dark}.css in _Layout.cshtml, so these rules win on equal specificity. It is a
 * single file for both themes on purpose: everything below resolves through `var(--rx-*)`, and docs.css already
 * redefines those per `:root[data-theme]`. One rule therefore serves light, dark AND a tenant's custom accent.
 *
 * ── Why this file exists at all, and why it is not just a block of custom properties ──────────────────────────────
 *
 * The obvious implementation is `:root { --dx-color-primary: var(--rx-accent); }`. That does NOTHING, and it fails
 * silently, which is worse. Fluent SaaS DECLARES `--dx-color-primary` in its `:root` but never REFERENCES it: the
 * accent is baked into the stylesheet as a literal hex at ThemeBuilder time. Verified against the shipped 26.1.3 file:
 *
 *     grep -c 'var(--dx-color-primary'  dx.fluent.saas.light.css   →  0
 *     grep -c '#5486ff'                 dx.fluent.saas.light.css   →  126
 *
 * So the accent has to be RE-EXPRESSED against the rules that carry it. The selectors below are not invented — they
 * are the accent-bearing rules extracted from the shipped stylesheet, filtered to the widgets this app actually
 * renders (Button, CheckBox, TextBox/SelectBox/NumberBox, TabPanel, DataGrid + its pager, LoadIndicator, Popup).
 * Widgets Docs never mounts (Scheduler, Diagram, Gantt, Chart, CardView, FileUploader…) are deliberately NOT bridged:
 * they would be ~60 more rules of dead weight, and if one is ever introduced its stock accent is a visible prompt to
 * come back here rather than a silent mismatch.
 *
 * The stock accents differ per cut — #5486ff light, #5492F6 dark — which is the other reason a single custom-property
 * override could not have worked.
 *
 * ── Tenant branding ───────────────────────────────────────────────────────────────────────────────────────────────
 *
 * This is what carries a tenant's accent into the widgets. _Layout.cshtml emits `--rx-accent` for a branded tenant
 * into `:root, :root[data-theme="light"], :root[data-theme="dark"]`; because every rule here reads that variable
 * rather than a fixed colour, a tenant's DataGrid selection, buttons and focus rings follow its brand with no
 * per-tenant stylesheet and nothing to rebuild. Pinned by DevExtremeThemeTests.
 *
 * IF THIS FILE IS REGENERATED after a DevExtreme upgrade: re-extract the accent-bearing rules from the new cut. A
 * version bump can add or rename them, and a stale bridge degrades to stock DevExtreme blue on the affected widget.
 */

/* The token layer. Declared for correctness and for any widget that reads it at runtime (some newer widgets do), but
   the rules below are what actually paint — see the header. */
:root {
    --dx-color-primary: var(--rx-accent);
    --dx-color-link: var(--rx-accent);
    --dx-border-radius: var(--rx-radius-sm);
}

/* ── Button ─────────────────────────────────────────────────────────────── */
.dx-button.dx-button-default { background-color: var(--rx-accent); }
.dx-button-mode-text.dx-button-default,
.dx-button-mode-text.dx-button-default .dx-icon { color: var(--rx-accent); }
.dx-button-mode-outlined.dx-button-default { border: 1px solid var(--rx-accent); color: var(--rx-accent); }
.dx-button-mode-outlined.dx-button-default .dx-icon { color: var(--rx-accent); }

/* HOVER — and note the selector: DevExtreme hover is the JS-applied class `.dx-state-hover`, NOT the `:hover`
   pseudo-class. A rule written as `.dx-button:hover` compiles, ships and never fires; the widget sets/clears
   dx-state-hover from its own pointer handling, which is also how it keeps hover off during a drag.
 *
 * These exist because the resting rules above WITHOUT them are the bug they were reported as: the button paints
 * raxwel accent at rest, then reverts to Fluent SaaS's baked-in hover colours on pointer-over — #6FA3F6 (dark cut) /
 * #3B6FE0 (light) for default, #FA5454 for danger. So an adopted Save/Delete visibly changed brand mid-hover while
 * the plain .editor-btn beside it (styled by docs.css, which does use :hover) did not. Every accent-bearing rule has
 * to be bridged in BOTH states or the mismatch only shows on interaction, which is exactly where it is most obvious.
 *
 * --rx-accent-strong is the palette's own hover step and is defined per theme in docs.css (#57B0E0 dark, #004B70
 * light), so one rule serves both cuts and a branded tenant. Danger has no -strong companion, so it uses
 * colour-mix against the foreground to darken/lighten by the same idea without inventing a second token. */
.dx-button.dx-state-hover { background-color: var(--rx-surface-2); }
.dx-button.dx-button-default.dx-state-hover { background-color: var(--rx-accent-strong); }
.dx-button-mode-text.dx-button-default.dx-state-hover,
.dx-button-mode-outlined.dx-button-default.dx-state-hover { color: var(--rx-accent-strong); background-color: var(--rx-accent-soft); }

/* The contained default button's LABEL is per-theme for the same reason as danger below: --rx-accent-strong is the
   palette's hover step, and it moves in OPPOSITE directions per cut — #004B70 in light (darker than the resting
   #016699) but #57B0E0 in dark (LIGHTER than the resting #1E92CC). A flat white label therefore measured 9.37:1 on
   light hover but only 2.42:1 on dark hover, failing AA exactly where the theme is already dim. The dark cut's own
   label colour is the near-black #141E28, which is why the resting dark button reads fine; the fix is to keep that
   dark label through hover rather than forcing white over a light blue. */
.dx-button.dx-button-default.dx-state-hover,
.dx-button.dx-button-default.dx-state-hover .dx-icon { color: var(--rx-bg); }
:root[data-theme="light"] .dx-button.dx-button-default.dx-state-hover,
:root[data-theme="light"] .dx-button.dx-button-default.dx-state-hover .dx-icon { color: #fff; }

/* DANGER, and the on-fill text colour is per-theme rather than a flat #fff — the one place in this file where a
   single rule genuinely could NOT serve both cuts.
 *
 * --rx-danger is not one colour playing two roles: it is #CF222E in light (a deep red) but #FF7B72 in dark (a light
 * salmon). Both are tuned as TEXT on the page background, which is what docs.css uses them for. Filling a button with
 * the dark-theme value and putting white on it measures 2.52:1 — below WCAG AA's 4.5:1, and the hover step made it
 * 2.23:1, i.e. hovering made the label HARDER to read. Measured, not estimated.
 *
 * So the fill keeps --rx-danger (it is the palette's red, and the button must read as destructive in both themes) and
 * the LABEL flips to the dark ground colour in dark mode, where the fill is light. Light theme keeps white on the deep
 * red at 5.36:1. Hover then moves each fill AWAY from its own label — darker under white, lighter under dark text — so
 * contrast improves on hover in both cuts instead of degrading in one. */
.dx-button.dx-button-danger { background-color: var(--rx-danger); color: #fff; }
.dx-button.dx-button-danger .dx-icon { color: #fff; }
.dx-button.dx-button-danger.dx-state-hover { background-color: color-mix(in srgb, var(--rx-danger) 82%, #000); }
.dx-button.dx-button-danger.dx-state-hover,
.dx-button.dx-button-danger.dx-state-hover .dx-icon { color: #fff; }

:root:not([data-theme="light"]) .dx-button.dx-button-danger,
:root:not([data-theme="light"]) .dx-button.dx-button-danger .dx-icon,
:root:not([data-theme="light"]) .dx-button.dx-button-danger.dx-state-hover,
:root:not([data-theme="light"]) .dx-button.dx-button-danger.dx-state-hover .dx-icon { color: var(--rx-bg); }
:root:not([data-theme="light"]) .dx-button.dx-button-danger.dx-state-hover { background-color: color-mix(in srgb, var(--rx-danger) 82%, #fff); }

/* ── CheckBox / RadioGroup / Switch ─────────────────────────────────────── */
.dx-checkbox-checked .dx-checkbox-icon { border-color: var(--rx-accent); background-color: var(--rx-accent); }
.dx-checkbox-indeterminate .dx-checkbox-icon { border-color: var(--rx-accent); }
.dx-checkbox-indeterminate .dx-checkbox-icon::before { background-color: var(--rx-accent); }
.dx-radiobutton-icon-checked { border-color: var(--rx-accent); }
.dx-radiobutton-icon-checked .dx-radiobutton-icon-dot { background-color: var(--rx-accent); }
.dx-switch-on-value .dx-switch-container::before { background-color: var(--rx-accent); border-color: var(--rx-accent); }

/* ── Text editors (TextBox / SelectBox / NumberBox) ─────────────────────── */
.dx-texteditor.dx-state-focused .dx-texteditor-label { color: var(--rx-accent); }
.dx-texteditor.dx-state-active::before,
.dx-texteditor.dx-state-focused::before { border-bottom: 2px solid var(--rx-accent); }
.dx-texteditor.dx-editor-filled::before,
.dx-texteditor.dx-editor-outlined::before { border-bottom-color: var(--rx-accent); }

/* ── Tabs / TabPanel (the product editor's three panes) ─────────────────── */
.dx-tabs-styling-mode-primary.dx-tab-indicator-position-bottom .dx-tab-selected::after,
.dx-tabs-styling-mode-primary.dx-tab-indicator-position-bottom .dx-tab-selected.dx-state-focused::after,
.dx-tabs-styling-mode-primary.dx-tab-indicator-position-top .dx-tab-selected::after,
.dx-tabs-styling-mode-primary.dx-tab-indicator-position-top .dx-tab-selected.dx-state-focused::after,
.dx-tabs-styling-mode-secondary.dx-tab-indicator-position-bottom .dx-tab.dx-tab-selected .dx-tab-content::after,
.dx-tabs-styling-mode-secondary.dx-tab-indicator-position-bottom .dx-tab.dx-tab-selected.dx-state-focused .dx-tab-content::after,
.dx-tabs-styling-mode-secondary.dx-tab-indicator-position-top .dx-tab.dx-tab-selected .dx-tab-content::after,
.dx-tabs-styling-mode-secondary.dx-tab-indicator-position-top .dx-tab.dx-tab-selected.dx-state-focused .dx-tab-content::after {
    background-color: var(--rx-accent);
}
.dx-tab.dx-tab-selected .dx-icon { color: var(--rx-accent); }

/* ── Pager (DataGrid paging) ────────────────────────────────────────────── */
.dx-pager .dx-page-sizes .dx-selection,
.dx-pager .dx-pages .dx-selection,
.dx-pagination .dx-page-sizes .dx-selection,
.dx-pagination .dx-pages .dx-selection { background-color: var(--rx-accent); }

/* ── Misc widgets Docs mounts ───────────────────────────────────────────── */
.dx-badge { background-color: var(--rx-accent); }
.dx-loadindicator-segment-inner { border-color: var(--rx-accent) var(--rx-accent) transparent; }
.dx-menu-item a { color: var(--rx-accent); }
.dx-progressbar-range { background-color: var(--rx-accent); }
.dx-toolbar-menu-section .dx-toolbar-hidden-button .dx-button-default,
.dx-toolbar-menu-section .dx-toolbar-hidden-button .dx-button-default .dx-icon { color: var(--rx-accent); }

/* Utility classes the theme exposes for app code to opt into the accent. */
.dx-theme-accent-as-text-color { color: var(--rx-accent) !important; }
.dx-theme-accent-as-background-color { background-color: var(--rx-accent) !important; fill: var(--rx-accent) !important; }
.dx-theme-accent-as-border-color { border-color: var(--rx-accent) !important; }

/* ── Surface alignment ──────────────────────────────────────────────────────
 * Fluent SaaS ships a near-white (#FAFBFF) ground that reads as a foreign panel inside the Docs editor's own
 * surfaces, and its dark cut does not match the navy-tinted --rx-bg either. Only the container-level colours are
 * bridged: enough to seat the widget in the page, without repainting internals the theme handles better. */
.dx-widget { font-family: var(--rx-sans); }
.dx-datagrid,
.dx-datagrid-headers,
.dx-datagrid-rowsview,
.dx-datagrid .dx-datagrid-headers .dx-datagrid-table,
.dx-datagrid .dx-row > td { background-color: transparent; }
.dx-datagrid { color: var(--rx-fg); }
.dx-datagrid-borders > .dx-datagrid-headers,
.dx-datagrid-borders > .dx-datagrid-rowsview,
.dx-datagrid-headers { border-color: var(--rx-border); }

/* ── Grid row action links (Edit / Manage / Restore) ────────────────────────
 * The anchors actionLink() builds in the four editor-*-grids.js adopters. Their LAYOUT (nowrap, icon gap) is in
 * docs.css; the colour has to be here, and the selector has to carry `.dx-datagrid`.
 *
 * SPECIFICITY IS THE WHOLE POINT. Fluent ships `.dx-datagrid .dx-link { color: #5486FF; text-decoration: underline }`
 * — two classes, in a stylesheet loaded AFTER docs.css. The first cut of this styled a bare `.editor-link-action`
 * (one class) and lost outright: measured resting colour stayed rgb(84,134,255) with the underline intact, i.e. the
 * declarations shipped and did nothing. Matching `.dx-datagrid .editor-link-action` ties on specificity and wins on
 * order. Anything added here that the theme also sets on `.dx-link` needs the same treatment.
 *
 * COLOUR ONLY, NO FILL. The resting colour is --rx-accent, which is the Save button's resting *fill* — so the glyph
 * reads as the same blue the author sees on that button, just as text. A filled chip was tried and rejected: these sit
 * in a dense buttons column where a block of colour per row reads as a selection state rather than a hover.
 *
 * HOVER IS --rx-accent-strong: the EXACT colour .editor-btn-primary moves to, so the pair matches token-for-token in
 * both states and in both cuts. Verified by measuring the two side by side — Save's computed fill against the glyph's
 * computed colour — at rgb(1,102,153) → rgb(0,75,112) in light and rgb(30,146,204) → rgb(87,176,224) in dark.
 *
 * An earlier cut mixed this token halfway to --rx-fg to widen the step, because on a 16px glyph the accent →
 * accent-strong move (ΔE≈13) is subtler than it is across a button-sized slab of fill. That was the wrong trade: it
 * broke the match with Save, which is the thing being asked for here. If the hover ever needs to read harder, change
 * BOTH components together — do not re-introduce a divergence.
 *
 * Written as the `:hover` PSEUDO-CLASS, and that is NOT an inconsistency with the dx-state-hover rules above:
 * DevExtreme sets dx-state-hover from its own pointer handling on widgets it owns, but these anchors come from our
 * template callback and the widget never tracks them, so a dx-state-hover rule here would compile, ship and never
 * fire — the same dead-rule shape as the specificity bug above. */
.dx-datagrid .editor-link-action {
    color: var(--rx-accent);
    text-decoration: none;
    transition: color .12s;
}
.dx-datagrid .editor-link-action .dx-icon { color: inherit; }
.dx-datagrid .editor-link-action:hover,
.dx-datagrid .editor-link-action:hover .dx-icon { color: var(--rx-accent-strong); }

/* ── The product icon tile's file input (editor-product-icon.js) ───────────────────────────────────────────────────
 *
 * MUST LIVE HERE, NOT IN docs.css. The theme sets `.dx-fileuploader-input { display: none }`, and _Layout.cshtml
 * loads docs.css BEFORE the theme — so the identical rule in docs.css compiles, ships and loses the cascade. The
 * symptom is not a styling glitch: a `display: none` input cannot be clicked, so the tile is simply dead while
 * Remove (a separate button) keeps working, which reads like a JS bug and is not one.
 *
 * editor-product-icon.js moves this input OUT of the widget and onto the tile, then relies on it covering the tile so
 * a click lands natively on it — the only way a file dialog opens, since a synthetic input.click() does not carry
 * user activation. Everything below exists to make that hit area real.
 *
 * Scoped to .editor-icon-file (the class the script adds) so the uploader's OTHER inputs, if the widget ever renders
 * one, keep the theme's own behaviour. */
.editor-icon .editor-icon-file.dx-fileuploader-input,
.editor-icon-tile > .editor-icon-file {
    display: block;
    /* z-index 3 — ABOVE the overlay, and above the change button it covers, so a click anywhere on the tile lands on
     * the input. The overlay is purely decorative (`aria-hidden`, no handlers), so having the input over it costs
     * nothing; the reverse would make the tile unclickable wherever the overlay is painted.
     *
     * The corner Remove is raised ABOVE this (z-index 4 in docs.css) — it is the one control that must stay
     * reachable, and an input covering the whole tile would otherwise swallow every attempt to clear the icon. */
    position: absolute; inset: 0; z-index: 3;
    width: 100%; height: 100%; margin: 0; padding: 0;
    opacity: 0; cursor: pointer;
    /* Keeps Safari from sizing the native control past the tile and spilling the hit area. */
    font-size: 0;
}
/* The tile's own cursor, for the pixels the input does not cover and for the button underneath — without this the
 * placeholder and the hover overlay read as inert text rather than something clickable. */
.editor-icon-tile,
.editor-icon-tile .editor-icon-change:not(:disabled),
.editor-icon-tile .editor-icon-preview,
.editor-icon-tile .editor-icon-overlay { cursor: pointer; }

/* ── Category parent picker: why a candidate is refused ──────────────────────
 *
 * A dxTreeView greys a disabled node and stops there, which says "not this one" without saying why. The picker's
 * itemTemplate marks the refused nodes with this class and a `title` tooltip carrying the localized reason (see
 * categoryTreePicker in editor-product-form.js).
 *
 * `cursor: help` is the visible half of the affordance: greying alone is easy to read as a rendering glitch, and a
 * help cursor is the conventional cue that hovering explains something. The tooltip itself is the native `title`
 * deliberately — it needs no positioning code, survives the dropdown overlay's stacking context (a custom popup
 * inside another popup is exactly the nesting DevExtreme handles badly), and is announced by screen readers, which
 * a purely visual cue would not be.
 *
 * NOT `pointer-events: none` — that would suppress the tooltip along with the clicks. DevExtreme already refuses
 * selection on a disabled node, so the pointer may reach it safely.
 *
 * The class lands on the element DevExtreme hands the itemTemplate, which is a WRAPPER INSIDE `.dx-treeview-item`,
 * not the item itself — verified in the browser rather than assumed. Both are selected here so the rule holds if a
 * future DevExtreme version passes the item element directly.
 *
 * THE CURSOR SELECTOR IS SPECIFICITY-DRIVEN, and the extra classes are not decorative. The theme ships
 * `.dx-state-disabled { cursor: pointer }` (verified by walking the matching rules in the browser — a lone
 * `.editor-tree-item-blocked` lost to it and the help cursor silently never applied). DevExtreme puts
 * `dx-state-disabled` on this very element, so pairing the two classes outranks it without an `!important`. */
.dx-treeview-item .editor-tree-item-blocked.dx-state-disabled,
.editor-tree-item-blocked.dx-state-disabled,
.dx-treeview-item.editor-tree-item-blocked { cursor: help; }
/* The dotted underline marks the label as "there is an explanation here" at a glance, rather than only on hover. */
.editor-tree-item-blocked { text-decoration: underline dotted currentColor; text-underline-offset: 3px; }
