/*
 * Filament, adjusted to the tokens where a variable cannot reach.
 *
 * NOT A BUILD INPUT. This file is registered as a Filament CSS asset in
 * SharedServiceProvider, exactly like resources/js/synco-eyes.js, and is
 * published by `php artisan filament:assets`. No bundler, no npm; the
 * design-token bundle beside it is generated and this one is written by hand,
 * because what it changes is a RULE and not a value.
 *
 * FOCUS RINGS ARE NOT MIXED TO 50 PERCENT (palette decision, 2026-09-03).
 * Filament paints the focus ring of a filled button as
 * `color-mix(in oklab, var(--color-500) 50%, transparent)`, an outlined one
 * at 40%, a badge at 75%. Measured (docs/palette-measurement.md, §3-4): the
 * mixed ring reads 1.87:1 against white on the app panel and 1.60:1 on the
 * admin panel, under the 3:1 a UI shape needs (WCAG 1.4.11). The unmixed
 * slot reads 3.74:1 on white and 8.10:1 on the dark page. A thicker ring
 * changes neither number, so it is the mix that goes.
 *
 * The selectors repeat Filament's own (app.css, 5.7.6). These rules win because
 * they are UNLAYERED and Filament's sit in `@layer components` -- this sheet is
 * served before app.css, measured in #528, so it is not load order; see the
 * status icon block at the end. `!important` would also win and would hide the
 * day Filament renames a class, which is the day this file has to be read
 * again. If a ring ever comes back at half strength, that is the sign.
 */

/* Filled button, light: slot 500 -- the same slot Filament chose, unmixed. */
.fi-btn:not(.fi-outlined).fi-color:not(label).fi-force-enabled,
.fi-btn:not(.fi-outlined).fi-color:not(label):not(.fi-disabled):not([disabled]):focus-visible {
    --tw-ring-color: var(--color-500);
}

/* Filled button, dark: slot 400. */
.fi-btn:not(.fi-outlined).fi-color:not(label).fi-force-enabled:where(.dark, .dark *),
.fi-btn:not(.fi-outlined).fi-color:not(label):not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible {
    --tw-ring-color: var(--color-400);
}

/* A filled button rendered as a <label> around a checked input (toggle buttons). */
input:checked:focus-visible + label.fi-btn:not(.fi-outlined).fi-color:not(.fi-disabled):not([disabled]) {
    --tw-ring-color: var(--color-500);
}

input:checked:focus-visible + label.fi-btn:not(.fi-outlined).fi-color:not(.fi-disabled):not([disabled]):where(.dark, .dark *) {
    --tw-ring-color: var(--color-400);
}

/* Outlined button: Filament mixes to 40%; same slots, unmixed. */
.fi-btn.fi-outlined.fi-color.fi-force-enabled,
.fi-btn.fi-outlined.fi-color:not(.fi-disabled):not([disabled]):focus-visible {
    --tw-ring-color: var(--color-500);
}

.fi-btn.fi-outlined.fi-color.fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-outlined.fi-color:not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible {
    --tw-ring-color: var(--color-400);
}

/* Badge: Filament mixes slot 700 (light) and 300 (dark) to 75%. */
.fi-badge.fi-force-enabled,
.fi-badge:not(.fi-disabled):not([disabled]):focus-visible {
    --tw-ring-color: var(--color-700);
}

.fi-badge.fi-force-enabled:where(.dark, .dark *),
.fi-badge:not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible {
    --tw-ring-color: var(--color-300);
}

/*
 * A BADGE'S WORDS HAVE A SPACE BETWEEN THEM THAT CAN BE SEEN (#539).
 *
 * Filament sets badges at 12px, weight 500, and Manrope's space there is
 * 2.40px -- so badges read as "Notemplate", "Inprogress". The system font gives
 * 3.28px at the same size and weight, which is the floor Pim's decision aims
 * at. Measured in Chromium as the rendered width of "No template" minus
 * "Notemplate" inside a real `.fi-badge`, per size class.
 *
 * THE SIZE A TABLE USES IS TIGHTER STILL, which the card did not have: a
 * `TextColumn` badge defaults to `fi-size-sm` (`TextSize::Small`), and Filament
 * gives that size `tracking-tight` (-0.025em) and `fi-size-xs` `tracking-tighter`
 * (-0.05em). Letter-spacing applies to the space character too, so in the
 * product list the space was 2.10px, and 1.80px at xs. A flat 0.08em reached
 * 3.36px at md and lg but only 3.06px at sm and 2.76px at xs -- under the floor
 * exactly where the defect was reported.
 *
 * SO THE SPACING GIVES BACK THE BADGE'S OWN TRACKING FIRST. Filament's size
 * rules set `--tw-tracking` beside `letter-spacing`; subtracting it cancels the
 * tightening on the space, and 0.08em (0.96px at 12px) is then added at every
 * size: 3.36px at xs, sm, md and lg alike. Letters keep their tracking; only
 * the gap between words changes. The text is untouched: the spaces were always
 * in the data and in the HTML (`BadgeWordSpacingTest`).
 *
 * UNLAYERED, like every rule here: Filament declares no word-spacing on a
 * badge, so there is no layered rule to lose to.
 */
.fi-badge {
    word-spacing: calc(0.08em - var(--tw-tracking, 0em));
}

/* Checked radio: Filament mixes primary-500 (light) and primary-400 (dark) to 50%. */
input[type="radio"].fi-radio-input:checked:focus {
    --tw-ring-color: var(--primary-500);
}

input[type="radio"].fi-radio-input:where(.dark, .dark *):checked:focus {
    --tw-ring-color: var(--primary-400);
}

input[type="radio"].fi-radio-input.fi-invalid:checked:focus {
    --tw-ring-color: var(--danger-500);
}

input[type="radio"].fi-radio-input.fi-invalid:where(.dark, .dark *):checked:focus {
    --tw-ring-color: var(--danger-400);
}

/*
 * THE RING RULE, CARRIED TO SUCCESS, WARNING AND INFO (block 3 of the
 * vasculara round). Measured in #123: unmixed slot 500 reads 2.15-2.49:1 on
 * white for these three -- their 500 is pale by design -- while slot 600
 * reads 5.47-7.13:1. Primary keeps slot 500 (3.74:1), the decision as
 * taken. Same form as above, one class more specific, so these win over the
 * generic rules for exactly these families and nothing else. Dark mode is
 * untouched: slot 400 reads 6.45-12.38:1 for all four.
 */
.fi-btn.fi-color-success:not(.fi-outlined):not(label).fi-force-enabled,
.fi-btn.fi-color-success:not(.fi-outlined):not(label):not(.fi-disabled):not([disabled]):focus-visible,
.fi-btn.fi-color-success.fi-outlined.fi-force-enabled,
.fi-btn.fi-color-success.fi-outlined:not(.fi-disabled):not([disabled]):focus-visible {
    --tw-ring-color: var(--color-600);
}

.fi-btn.fi-color-warning:not(.fi-outlined):not(label).fi-force-enabled,
.fi-btn.fi-color-warning:not(.fi-outlined):not(label):not(.fi-disabled):not([disabled]):focus-visible,
.fi-btn.fi-color-warning.fi-outlined.fi-force-enabled,
.fi-btn.fi-color-warning.fi-outlined:not(.fi-disabled):not([disabled]):focus-visible {
    --tw-ring-color: var(--color-600);
}

.fi-btn.fi-color-info:not(.fi-outlined):not(label).fi-force-enabled,
.fi-btn.fi-color-info:not(.fi-outlined):not(label):not(.fi-disabled):not([disabled]):focus-visible,
.fi-btn.fi-color-info.fi-outlined.fi-force-enabled,
.fi-btn.fi-color-info.fi-outlined:not(.fi-disabled):not([disabled]):focus-visible {
    --tw-ring-color: var(--color-600);
}

/* The dark rules above still apply to these families: they come later in the file only for reading order, so restate them at the same specificity. */
.fi-btn.fi-color-success:not(.fi-outlined):not(label).fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-color-success:not(.fi-outlined):not(label):not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible,
.fi-btn.fi-color-success.fi-outlined.fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-color-success.fi-outlined:not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible,
.fi-btn.fi-color-warning:not(.fi-outlined):not(label).fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-color-warning:not(.fi-outlined):not(label):not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible,
.fi-btn.fi-color-warning.fi-outlined.fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-color-warning.fi-outlined:not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible,
.fi-btn.fi-color-info:not(.fi-outlined):not(label).fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-color-info:not(.fi-outlined):not(label):not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible,
.fi-btn.fi-color-info.fi-outlined.fi-force-enabled:where(.dark, .dark *),
.fi-btn.fi-color-info.fi-outlined:not(.fi-disabled):not([disabled]):where(.dark, .dark *):focus-visible {
    --tw-ring-color: var(--color-400);
}

/*
 * A TABLE HEADER HAS A GROUND (#385 item 7; design
 * `cultiva-productbeheer/README.md` line 56: "de kopcel boven de actiekolom van
 * DataTable heeft geen achtergrond; geef alle thead th `--surface-hover`").
 *
 * MEASURED IN THE BROWSER, and the measurement corrected what this comment
 * first claimed. It said Filament paints the real header cells and skips the
 * bare `<th></th>` ones, so only the corners were wrong. That is not what
 * Filament 5.7.6 does. With this rule removed, every header cell on the product
 * list computes to `rgba(0, 0, 0, 0)`:
 *
 *   header-cell bg=rgba(0, 0, 0, 0)  text="Naam"
 *   header-cell bg=rgba(0, 0, 0, 0)  text="Status"
 *   ...
 *
 * and with it, every one computes to `rgb(248, 250, 252)`, which is
 * `--surface-hover` in the light theme. So the header row had NO ground at all
 * and now has one -- a bigger change than the design's sentence suggests, and
 * the design's own example is not reproducible here: the bare `<th></th>`
 * elements do exist in Filament's table view, but they are conditional on
 * selectable rows, a reorder handle and the actions position, and this table
 * renders none of them.
 *
 * ON `th` AND NOT ON `.fi-ta-header-cell`, which still matters: the rule has to
 * cover whichever bare cells a future table does render, and those are exactly
 * the ones without that class.
 *
 * The selector repeats Filament's own nesting rather than reaching for
 * `!important`, for the reason this file's header gives: equal specificity and
 * a later sheet wins, and the day Filament renames `fi-ta-table` this stops
 * working visibly instead of invisibly.
 */
.fi-ta-table thead th {
    background-color: var(--surface-hover);
}

/*
 * A per-language field that is off screen takes no room either (#384).
 *
 * The product page keeps every language's text fields in the form and hides
 * all but one with an inline style (`ProductResource::shownOnlyFor()`), because
 * a field hidden with `->visible()` is not saved. The style reaches the field's
 * wrapper, not the grid cell around it, so each hidden language still left a
 * cell and a gap -- measured as a blank band above the first field on the SEO
 * tab. The cell follows its field.
 */
.fi-grid-col:has(> .fi-sc-component > [data-content-language][style*="display: none"]) {
    display: none;
}

/*
 * STATUS ICONS IN CALLOUTS AND TOASTS (#528).
 *
 * Filament paints both with `text-color-400` and no `dark:` variant -- slot 400
 * in light AND dark (callout.css, notification.css, 5.7.6). Everywhere else it
 * paints 600 in light and 400 in dark (button.css, modal.css), and
 * DesignTokenPalette::status() is built on that: the LIGHT role on 600, the
 * DARK role on 400. So these two drew the dark role on a light card: warning
 * #fcd34d on #fffbf0 at 1.39:1, danger #f87171 on #fff1f0 at 2.52:1, where a
 * status icon needs 3:1 (WCAG 1.4.11).
 *
 * THE PALETTE IS LEFT ALONE, by Pim's decision of 14-09 (form A): slot 400 is
 * the dark paint slot of every other component, so moving a role onto it would
 * break their dark theme to fix these two. What changes is the rule for these
 * two: the light role in light, the dark role in dark, like the rest.
 *
 * UNLAYERED, AND THAT IS MEASURED RATHER THAN PREFERRED. This sheet is served
 * BEFORE Filament's app.css (the login page lists design-tokens, then this
 * file, then app.css). Written inside `@layer components` it therefore DECLARED
 * that layer first, ahead of Filament's `properties`, `theme` and `base`, and
 * the base reset then beat every component rule: the sign-in card lost its
 * padding and its button colour (screenshot on the pull request). Unlayered,
 * a normal declaration wins over any layered one whatever the order or the
 * specificity -- the cascade rule, and the reason the focus-ring rules above
 * win too, not the load order their comment assumed. No `!important`: inside
 * the layer contest that is the form that inverts and loses (#400).
 *
 * The dark rule adds `:where(.dark, .dark *)`, which adds no specificity, and
 * comes later in this file, so in dark it wins over the light one.
 *
 * `StatusIconContrastTest` holds this: it fails when Filament stops naming
 * these classes or painting them 400, when these rules go or move into a layer,
 * and when the palette gives a status a light role under 3:1 on the callout's
 * own ground.
 */
.fi-callout .fi-callout-icon.fi-color {
    color: var(--color-600);
}

.fi-callout .fi-callout-icon.fi-color:where(.dark, .dark *) {
    color: var(--color-400);
}

.fi-no-notification .fi-no-notification-icon.fi-color {
    color: var(--color-600);
}

.fi-no-notification .fi-no-notification-icon.fi-color:where(.dark, .dark *) {
    color: var(--color-400);
}

/*
 * SLOT 500 OF A STATUS CARRIES THE LIGHT ROLE IN THE LIGHT THEME (#588).
 *
 * Filament paints eleven status icons with slot 500 in light mode -- section
 * and schema icons, dropdown icons, the empty state, badge and input icons,
 * text items, stat descriptions, chart lines -- and slot 500 is the family's
 * pale 500: 34 of those 44 combinations read under 3:1 on their own ground
 * (the table is on #588). Pim's decision is form B: the SLOT differs per theme,
 * rather than eleven component rules.
 *
 * A VARIABLE AND NOT THE PALETTE REGISTERED WITH FILAMENT, and that difference
 * is measured, not a preference. Filament picks slots IN PHP while rendering
 * (`getColorMap()`), by contrast against the registered ramp, and that ramp
 * serves both themes. With 500 set to the light role there, 45 choices in 27
 * components moved -- an icon button in success, warning or info hovered from
 * 600 to 500 (the same colour now) and from 400 to 300 in dark (also the same),
 * so it lost its hover in both themes. Here the ramp stays as it is, every
 * runtime choice with it, and only the light theme's value of the variable
 * changes. Where Filament itself chose 500 in light (the danger icon of an
 * icon column, an icon entry, a count summary) it now paints the light role,
 * which is darker on white, so the contrast it checked only improves.
 *
 * NO HEX HERE: each line reads the ROLE from roles.css, so a role moves and
 * nothing is typed. `:root:not(.dark)` rather than `:root`, twice over: it is
 * the light theme and nothing else, and it outranks the `:root` block Filament
 * prints inline AFTER this sheet, where equal specificity would lose on order.
 * Unlayered, for the reason the #528 rules above give.
 *
 * WHAT ELSE READS THESE FOUR NAMES, all measured: the design-token bundle
 * defines the same names and loses to Filament's block already; the readiness
 * dot on the product page (`var(--<state>-500)`) and the invalid radio ring
 * above follow, darker and above 3:1 on white. The one place this does not
 * reach 3:1: a DANGER empty state, #b91c1c on its #f87171 bol at 2.34:1 --
 * stated on #588 with the number, and no screen of ours renders one today.
 */
:root:not(.dark) {
    --danger-500: var(--color-error);
    --success-500: var(--color-success);
    --warning-500: var(--color-warning);
    --info-500: var(--color-info);
}

/*
 * THE REST BORDER OF A FORM CONTROL READS 3:1 (#601).
 *
 * Filament draws a field's border as a ring: `ring-gray-950/10` in light and
 * `ring-white/20` in dark, measured on #601 at 1.25:1 on the white card and
 * 1.87:1 on the dark one -- under the 3:1 a control's boundary needs (WCAG
 * 1.4.11). Pim decided on 15-09: every input border becomes `--border-input`,
 * which is slate-500 in both themes (4.76:1 on white, 3.75:1 on Filament's dark
 * card, 3.30:1 on its dark field fill). The ratios are computed from the token
 * files in tests/Feature/Shared/InputBorderContrastTest.php, not quoted here.
 *
 * ONE RULE PER CONTROL AND NOT ONE PER THEME. The token already changes with
 * the theme (`[data-theme="dark"], .dark` in the bundle), so a `.dark` copy of
 * each selector would say the same thing twice.
 *
 * THE REST STATE ONLY, AND THAT IS THE CORRECTION TO THE CARD. The card
 * proposed `.fi-input-wrp { --tw-ring-color: var(--border-input) }`. These
 * rules are unlayered and Filament's sit in `@layer components`, so an
 * unlayered rule wins over EVERY layered one, whatever its specificity -- the
 * proposed rule would also have painted the focus ring (`focus-within:
 * ring-primary-600`), the error ring (`ring-danger-600`) and the disabled ring
 * slate-500. Each selector below therefore names the states it leaves to
 * Filament. Read from vendor/filament/support/resources/css/components/
 * input/{wrapper,checkbox,radio}.css and button.css, Filament 5.7.6.
 *
 * NOT HERE: hover. The design system has `--border-input-hover` and Filament
 * draws no hover on a field's border; adding one would be new behaviour, not
 * a contrast repair. A toggle has no ring at all and is not measured here.
 */

/* The field wrapper: text, select, textarea, date. An action inside that holds
   focus keeps the rest ring in Filament, so it keeps it here too. */
.fi-input-wrp:not(.fi-disabled):not(.fi-invalid):not(:focus-within),
.fi-input-wrp:not(.fi-disabled):not(.fi-invalid):has(.fi-ac-action:focus) {
    --tw-ring-color: var(--border-input);
}

/* An unticked checkbox or radio. Ticked ones carry no ring (`checked:ring-0`). */
input[type="checkbox"].fi-checkbox-input:not(:checked):not(:disabled):not(:focus):not(.fi-invalid),
input[type="radio"].fi-radio-input:not(:checked):not(:disabled):not(:focus):not(.fi-invalid) {
    --tw-ring-color: var(--border-input);
}

/* The secondary button: a button without a colour ("Annuleren"), and a toggle
   button that is not chosen. Filament gives both `ring-gray-950/10` /
   `ring-white/20`; a coloured or chosen one keeps its own ring. */
.fi-btn:not(.fi-color):not(label):not(.fi-disabled):not([disabled]):not(.fi-outlined:focus-visible),
input:not(:checked) + label.fi-btn:not(.fi-disabled):not([disabled]) {
    --tw-ring-color: var(--button-secondary-border);
}

/*
 * THE INSTELLINGEN GROUP SITS AT THE BOTTOM OF THE SIDEBAR ON DESKTOP (#462).
 *
 * CSS ON FILAMENT'S OWN MARKUP, NOT A REWRITTEN SIDEBAR. A copied sidebar view
 * drifts away from the original with every upgrade (the #400 argument); this
 * needs three facts about the markup and no more: `.fi-sidebar-nav` is the
 * scroll container and a flex column, `.fi-sidebar-nav-groups` is a flex
 * column inside it, and a group carries the attributes its NavigationGroup was
 * given. The group is marked `data-sidebar-pinned` in AppPanelProvider, so
 * nothing here can reach the admin panel.
 *
 * - The list grows to the height of the nav and the group takes `margin-top:
 *   auto`, so on a short list it stands at the bottom rather than after the
 *   last module.
 * - On a long list or a short viewport the nav scrolls, and `position: sticky;
 *   bottom` keeps the group in view at the bottom of the scroll area while
 *   everything above it scrolls past behind it. Nothing is cut off: the modules
 *   stay reachable by scrolling, which a `position: fixed` group would not
 *   guarantee.
 * - The background is the page's, so what scrolls under the group does not
 *   show through, and the hairline says where the pinned part starts. "The
 *   page's" means what Filament paints `.fi-body` with, `--gray-50` and in
 *   the dark `--gray-950`, which AppPanelProvider fills from the design
 *   tokens' gray ramp. `--surface-page` was tried first and is one step off
 *   in the dark (#0a1120 against the body), which showed as a lighter band.
 *   The
 *   negative inline margin with its matching padding widens the background to
 *   the nav's padding edge (px-6 on the nav, -mx-2 on the list).
 *
 * FROM 1024 PX, WHICH IS FILAMENT'S OWN `lg` AND THE WIDTH WHERE ITS SIDEBAR
 * STOPS BEING A DRAWER. Below it the sidebar is an overlay you open for one
 * choice and close again; pinning inside a drawer buys nothing, so the group
 * returns to the normal flow there.
 *
 * `bottom` is the negative of the nav's bottom padding (py-8), so the group
 * rests on the nav's edge instead of floating 32 px above it with the list
 * visible underneath.
 */
@media (min-width: 1024px) {
    .fi-main-sidebar .fi-sidebar-nav-groups {
        flex-grow: 1;
    }

    .fi-main-sidebar .fi-sidebar-group[data-sidebar-pinned] {
        margin-top: auto;
        position: sticky;
        bottom: -2rem;
        z-index: 1;
        margin-inline: -1rem;
        padding: 12px 1rem 2rem;
        background: var(--gray-50);
        border-top: 1px solid var(--border-line);
    }

    .fi-main-sidebar .fi-sidebar-group[data-sidebar-pinned]:where(.dark, .dark *) {
        background: var(--gray-950);
    }
}
