/*
   Servicedesk design system.

   Shared visual language introduced with the scan/inventarisatie redesign
   (2026-08-05). Opt-in: pages include this file explicitly via
   @section styles { <link href="~/Content/design-system.css" ...> } rather
   than through the global bundle, so it only affects pages that have been
   redesigned so far. Every component class is prefixed `ds-` to avoid
   colliding with existing Bootstrap/site classes on pages that haven't been
   redesigned yet.

   Pair with Google Fonts Roboto (light/regular/bold only):
   <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
*/

:root {
    --ds-bg: #f4f4df;
    --ds-surface: #fffefa;
    --ds-warm: #f5f0ea;
    --ds-ink: #33331f;
    --ds-ink-soft: #82815f;
    --ds-accent: #b2b66f;
    --ds-accent-deep: #6f7a3a;
    --ds-done: #6aa51c;
    --ds-attention: #c98a3e;
    --ds-danger: #d9534f;
    --ds-line: rgba(51, 51, 31, 0.08);
    --ds-font-display: 'Roboto', sans-serif;
    --ds-font-body: 'Roboto', sans-serif;

    /* Shell/rail — introduced with the icon-rail navigation redesign (2026-08-10) */
    --ds-rail-bg: var(--ds-accent);
    --ds-rail-bg-2: #f4f4df;
    --ds-rail-ink: #363636;
    --ds-rail-ink-soft: rgba(54, 54, 54, 0.85);
    --ds-rail-active-bg: var(--ds-rail-bg-2);
    --ds-rail-active-ink: var(--ds-rail-ink);
    --ds-rail-line: rgba(54, 54, 54, 0.14);

    /* Motion — introduced with the shell motion pass (2026-10-06). Kept
       short and subtle on purpose: this is a tool people use all day. */
    --ds-dur-fast: 120ms;
    --ds-dur: 200ms;
    --ds-ease: cubic-bezier(.2, .7, .2, 1);
    --ds-ease-in-out: cubic-bezier(.4, 0, .2, 1);
}

/* While body has .ds-preload (set server-side in _Layout, removed after the
   first frame) nothing transitions, so restoring state on page load — e.g. a
   collapsed side panel — never visibly animates. */
body.ds-preload *,
body.ds-preload *::before,
body.ds-preload *::after {
    transition: none !important;
}

.ds-eyebrow {
    font-family: var(--ds-font-body);
    text-transform: uppercase;
    letter-spacing: .12em;
    font-size: .68rem;
    font-weight: 400;
    color: var(--ds-accent-deep);
    margin: 0 0 .2rem;
}

.ds-heading {
    font-family: var(--ds-font-display);
    font-weight: 700;
    color: var(--ds-ink);
    margin: 0;
}

.ds-sub {
    font-family: var(--ds-font-body);
    font-weight: 300;
    color: var(--ds-ink-soft);
}

/* Stat strip: gradient accent panel used to surface the one number that matters */
.ds-statstrip {
    padding: 1rem 1.15rem;
    border-radius: 1.1rem;
    background: linear-gradient(135deg, var(--ds-accent) 0%, var(--ds-accent-deep) 100%);
    color: #fff;
    display: flex;
    align-items: center;
    gap: .9rem;
    box-shadow: 0 10px 24px -12px rgba(111, 122, 58, 0.55);
    font-family: var(--ds-font-body);
}

.ds-statstrip .ds-num {
    font-family: var(--ds-font-display);
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1;
}

.ds-statstrip .ds-label {
    font-size: .82rem;
    opacity: .92;
    line-height: 1.25;
}

.ds-statstrip .ds-icon {
    font-size: 1.4rem;
    opacity: .85;
}

.ds-sectiontitle {
    font-family: var(--ds-font-body);
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--ds-ink-soft);
    margin: 0 0 .65rem .1rem;
    display: flex;
    align-items: center;
    gap: .4rem;
}

/* Cards */
.ds-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-line);
    border-radius: 1rem;
    box-shadow: 0 4px 14px -8px rgba(51, 51, 31, 0.12);
    font-family: var(--ds-font-body);
    color: var(--ds-ink);
}

.ds-card.ds-done {
    opacity: .7;
    background: transparent;
    border-style: dashed;
    box-shadow: none;
}

.ds-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .85rem 1.1rem;
    border-bottom: 1px solid var(--ds-line);
    font-family: var(--ds-font-display);
    font-weight: 700;
    font-size: .92rem;
    color: var(--ds-ink);
}

.ds-card-header.ds-card-header-danger {
    background: rgba(217, 83, 79, .08);
    color: var(--ds-danger);
    border-bottom-color: rgba(217, 83, 79, .16);
}

.ds-card-header.ds-card-header-attention {
    background: rgba(201, 138, 62, .1);
    color: var(--ds-attention);
    border-bottom-color: rgba(201, 138, 62, .18);
}

.ds-card-body {
    padding: 1.1rem;
}

/* Page section panel — the "white card wrapping a page section" idiom,
   replacing the old ad hoc container-white / inline-style duplication. */
.ds-panel {
    background: var(--ds-surface);
    border: 1px solid var(--ds-line);
    border-radius: 1rem;
    box-shadow: 0 4px 14px -8px rgba(51, 51, 31, 0.12);
    padding: 1.25rem;
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
}

/* A panel that opens the page (nothing above it but invisible siblings:
   the fixed-position toast container most views start with, or an inline
   <style>/<script>) sits right at the content area's own top padding, so
   every page starts its content at the same height below the topbar.
   Panels below a heading, toolbar or alert keep their 1.5rem gap. */
.body-content > .ds-panel:not(:not(style, script, .toast-container) ~ *) {
    margin-top: 0;
}

/* The page's own top padding already provides breathing room under the
   topbar, so the first panel on a page doesn't need its own margin-top too. */
.container.body-content > .ds-panel:first-child {
    margin-top: 0;
}

/* Panel toolbar row: title/count on the left, actions on the right — top
   aligned so a taller right-hand side (e.g. a search form with a validation
   line) never vertically re-centers the title against it. */
.ds-panel-toolbar {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: .75rem;
    margin-bottom: 1rem;
}

/* Bootstrap's .row carries negative gutter margins meant to be absorbed by
   a .col/.container ancestor. Nested directly in the toolbar instead (e.g.
   the shared _Zoek search partial, which opens with <div class="row">),
   those margins push its content past the card's own padding — neutralize
   them here rather than touching .row globally. */
.ds-panel-toolbar > .row {
    margin: 0;
    min-width: 0;
    flex: 0 1 420px;
}

/* Search row with an inline filter chip (.ds-filter-chip) needs room for it.
   _Zoek wraps its .row in a <form>, so the form is the flex item here. */
.ds-panel-toolbar > form:has(> .ds-search-wide) {
    flex: 0 1 820px;
    min-width: 0;
}

.ds-panel-toolbar .row.ds-search-wide {
    margin: 0;
}

/* The free-text field carries the longest placeholder; let it take more of
   the row than the short ID fields. */
.ds-search-wide .ds-input[name="Trefwoord"] {
    flex-grow: 1.6;
}

/* Badges */
.ds-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-family: var(--ds-font-body);
    font-size: .68rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: .05em;
    padding: .22rem .55rem;
    border-radius: .5rem;
}

.ds-badge-attention {
    color: #fff;
    background: var(--ds-attention);
}

.ds-badge-done {
    color: #fff;
    background: #198754;
}

.ds-badge-muted {
    color: #fff;
    background: var(--ds-ink-soft);
}

.ds-badge-accent {
    color: #fff;
    background: var(--ds-accent-deep);
}

.ds-badge-danger {
    color: #fff;
    background: var(--ds-danger);
}

.ds-badge-ink {
    color: #fff;
    background: var(--ds-ink);
}

/* Larger variant for prominent, page-level status pills (e.g. next to an
   <h1>), vs. the compact uppercase badges used inline in tables/toolbars. */
.ds-badge-lg {
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .02em;
    padding: .4rem .9rem;
    border-radius: .7rem;
}

/* Raw Bootstrap .badge.bg-success/-warning/-danger/-primary/-dark — kept
   literal (instead of .ds-badge-*) in a handful of spots where JS writes
   that exact markup back after an AJAX call (e.g. Contactlog's "mark as
   handled" toggle in _Layout.cshtml) — restyled here to the same solid
   ds- palette so they don't stand out as stock Bootstrap green/yellow/red
   next to actual .ds-badge elements. bootstrap.css's .bg-* utilities carry
   !important, so these must too. */
.badge.bg-success {
    background-color: #198754 !important;
}

.badge.bg-warning {
    background-color: var(--ds-attention) !important;
    color: #fff !important;
}

.badge.bg-danger {
    background-color: var(--ds-danger) !important;
}

.badge.bg-primary {
    background-color: var(--ds-accent-deep) !important;
}

.badge.bg-dark {
    background-color: var(--ds-ink) !important;
}

/* Buttons */
.ds-btn {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-family: var(--ds-font-body);
    font-weight: 400;
    font-size: .88rem;
    padding: .65rem 1.1rem;
    border-radius: .8rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    line-height: 1.2;
    transition: background-color var(--ds-dur-fast) var(--ds-ease),
                border-color var(--ds-dur-fast) var(--ds-ease),
                color var(--ds-dur-fast) var(--ds-ease),
                transform var(--ds-dur-fast) var(--ds-ease);
}

.ds-btn:active:not(:disabled):not(.disabled) {
    transform: translateY(1px);
}

.ds-btn-primary {
    background: var(--ds-accent);
    color: #fff;
}

.ds-btn-primary:hover, .ds-btn-primary:focus {
    background: var(--ds-accent-deep);
    color: #fff;
}

/* Site.css's raw .btn-green is still the *old* brand green (#bdbf10) —
   kept literal (instead of ds-btn-primary) on the scan-station pages
   (CheckMulti/CheckSingle/CheckRetourbon) where JS reads/sets this exact
   class name on buttons it swaps at runtime. Recolor to match
   .ds-btn-primary here rather than touching that JS. */
.btn-green {
    background-color: var(--ds-accent) !important;
}

.btn-green:hover, .btn-green:focus {
    background-color: var(--ds-accent-deep) !important;
}

.ds-btn-outline {
    background: var(--ds-surface);
    border-color: var(--ds-line);
    color: var(--ds-ink);
}

.ds-btn-outline:hover, .ds-btn-outline:focus {
    border-color: var(--ds-accent);
    color: var(--ds-ink);
}

.ds-btn-danger {
    background: var(--ds-danger);
    color: #fff;
}

.ds-btn-danger:hover, .ds-btn-danger:focus {
    background: #b84643;
    color: #fff;
}

.ds-btn-success {
    background: #198754;
    color: #fff;
}

.ds-btn-success:hover, .ds-btn-success:focus {
    background: #157347;
    color: #fff;
}

.ds-btn-attention {
    background: var(--ds-attention);
    color: #fff;
}

.ds-btn-attention:hover, .ds-btn-attention:focus {
    background: #a86f2f;
    color: #fff;
}

.ds-btn:disabled,
.ds-btn.disabled {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Circular progress ring, e.g. <svg class="ds-ring"><circle class="ds-ring-track">...<circle class="ds-ring-progress"> */
.ds-ring {
    flex: none;
}

.ds-ring circle {
    fill: none;
    stroke-width: 4;
}

.ds-ring .ds-ring-track {
    stroke: var(--ds-line);
}

.ds-ring .ds-ring-progress {
    stroke: var(--ds-done);
    stroke-linecap: round;
    transform: rotate(-90deg);
    transform-origin: 50% 50%;
    transition: stroke-dashoffset .6s ease .1s;
}

.ds-ring text {
    font-family: var(--ds-font-display);
    font-weight: 700;
    fill: var(--ds-ink);
    text-anchor: middle;
    dominant-baseline: central;
}

/* Table */
.ds-table-wrap {
    border-radius: 1rem;
    overflow: hidden;
    border: 1px solid var(--ds-line);
}

.ds-table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--ds-font-body);
    background: var(--ds-surface);
}

.ds-table th {
    text-align: left;
    font-size: .7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--ds-ink-soft);
    padding: .8rem .9rem;
    background: var(--ds-bg);
    border-bottom: 1px solid var(--ds-line);
    white-space: nowrap;
}

.ds-table td {
    padding: .75rem .9rem;
    border-bottom: 1px solid var(--ds-line);
    font-size: .86rem;
    color: var(--ds-ink);
    vertical-align: middle;
}

.ds-table tr:last-child td {
    border-bottom: none;
}

.ds-table tbody tr:hover td {
    background: rgba(178, 182, 111, 0.07);
}

/* Modal chrome — opt-in skin for a redesigned modal's .modal-content/-header/-body.
   Bootstrap's own .modal-content/.modal-header classes are left untouched so
   not-yet-redesigned modals keep their current look. */
.ds-modal-content {
    background: var(--ds-surface);
    border: 1px solid var(--ds-line);
    border-radius: 1rem;
    box-shadow: 0 4px 14px -8px rgba(51, 51, 31, 0.12);
}

.ds-modal-header {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--ds-line);
}

.ds-modal-header .modal-title {
    font-family: var(--ds-font-display);
    font-weight: 700;
    color: var(--ds-ink);
}

.ds-modal-body {
    padding: 1.25rem;
    font-family: var(--ds-font-body);
    color: var(--ds-ink);
}

.ds-modal-footer {
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--ds-line);
}

/* Bootstrap .alert/.alert-success/.alert-danger rendered inside a redesigned
   modal body, or inside any element marked .ds-alert-target (e.g. an
   AJAX-form's UpdateTargetId div living outside a modal, like a tab pane) —
   AJAX success/error messages toggled by existing JS via addClass, or raw
   alert markup returned by a controller action, picked up here so they read
   as ds- without touching that JS/controller code. */
.ds-modal-body .alert,
.ds-alert-target .alert {
    font-family: var(--ds-font-body);
    font-size: .85rem;
    padding: .75rem 1rem;
    border-radius: .8rem;
    border: none;
}

.ds-modal-body .alert-success,
.ds-alert-target .alert-success {
    background: rgba(106, 165, 28, .1);
    color: var(--ds-done);
}

.ds-modal-body .alert-danger,
.ds-alert-target .alert-danger {
    background: rgba(217, 83, 79, .1);
    color: var(--ds-danger);
}

.ds-modal-body .alert-warning,
.ds-alert-target .alert-warning {
    background: rgba(201, 138, 62, .12);
    color: var(--ds-attention);
}

/* Empty state */
.ds-empty {
    padding: 3rem 1rem;
    text-align: center;
    color: var(--ds-ink-soft);
    font-family: var(--ds-font-body);
    font-weight: 300;
}

.ds-empty i {
    font-size: 2rem;
    color: var(--ds-accent);
    display: block;
    margin-bottom: .5rem;
}

/* Form fields */
.ds-field {
    margin-bottom: 1rem;
}

.ds-field label {
    display: block;
    font-family: var(--ds-font-body);
    font-size: .82rem;
    font-weight: 400;
    color: var(--ds-ink);
    margin-bottom: .35rem;
}

/* Default size — compact, for dense forms (multi-field edit forms, modal
   forms, filter bars). Matches the datepicker field on the MissingItems
   overview page. */
.ds-input {
    width: 100%;
    font-family: var(--ds-font-body);
    font-size: .92rem;
    padding: .6rem .85rem;
    border-radius: .7rem;
    border: 1.5px solid var(--ds-line);
    background: var(--ds-bg);
    color: var(--ds-ink);
    transition: border-color var(--ds-dur-fast) var(--ds-ease),
                box-shadow var(--ds-dur) var(--ds-ease);
}

.ds-input:focus {
    outline: none;
    border-color: var(--ds-accent);
    box-shadow: 0 0 0 3px rgba(178, 182, 111, .22);
}

/* Large variant — for a page's one hero field (login form, a barcode/scan
   input meant to be worked with a scanner gun or on a touch device). Opt in
   with .ds-input.ds-input-lg. */
.ds-input.ds-input-lg {
    font-size: 1.05rem;
    padding: 1rem 1.15rem;
    border-radius: .9rem;
    background: var(--ds-surface);
}

.ds-input::placeholder {
    color: var(--ds-ink-soft);
    opacity: .7;
}

/* .ds-input's own width:100% otherwise wins as the flex-basis and forces
   an adjoining .ds-btn (e.g. a datepicker's calendar-icon addon) to wrap
   onto its own line inside a Bootstrap .input-group. */
.input-group > .ds-input {
    flex: 1 1 auto;
    width: 1%;
    min-width: 0;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.input-group > .ds-btn {
    flex: 0 0 auto;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    margin-left: -1.5px;
}

.ds-btn-block {
    width: 100%;
    justify-content: center;
    padding: 1rem 1.1rem;
    font-size: 1rem;
}

/* Inline search bar, e.g. the order/return search form in a page header —
   a compact variant of .ds-input sized to line up with .ds-btn beside it. */
.ds-searchbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    min-width: 0;
}

.ds-searchbar .ds-input {
    width: auto;
    flex: 1 1 150px;
    min-width: 110px;
    padding: .65rem 1rem;
    font-size: .92rem;
    border-radius: .8rem;
}

.ds-searchbar .ds-btn {
    flex: none;
}

.ds-searchbar .form-check {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-family: var(--ds-font-body);
    font-size: .88rem;
    color: var(--ds-ink-soft);
}

/* Filter toggle that sits inside a .ds-searchbar row, between the fields
   and the submit button: same height, border and radius as the inputs,
   with a small switch instead of a bare checkbox. The real checkbox stays
   in the label (visually hidden) so the form post is unchanged. Use ~, not
   +: Html.CheckBoxFor emits a hidden input right after the checkbox. */
.ds-filter-chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    align-self: stretch;
    gap: .55rem;
    flex: none;
    margin: 0;
    padding: 0 .95rem;
    border: 1.5px solid var(--ds-line);
    border-radius: .8rem;
    background: var(--ds-bg);
    font-family: var(--ds-font-body);
    font-size: .88rem;
    color: var(--ds-ink-soft);
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: border-color var(--ds-dur-fast) var(--ds-ease),
                background-color var(--ds-dur-fast) var(--ds-ease),
                color var(--ds-dur-fast) var(--ds-ease);
}

.ds-filter-chip:hover {
    border-color: rgba(178, 182, 111, .55);
    color: var(--ds-ink);
}

.ds-filter-chip input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ds-filter-chip-switch {
    position: relative;
    flex: none;
    width: 28px;
    height: 16px;
    border-radius: 999px;
    background: rgba(51, 51, 31, .18);
    transition: background-color var(--ds-dur) var(--ds-ease);
}

.ds-filter-chip-switch::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(51, 51, 31, .25);
    transition: transform var(--ds-dur) var(--ds-ease);
}

.ds-filter-chip input:checked ~ .ds-filter-chip-switch {
    background: var(--ds-accent-deep);
}

.ds-filter-chip input:checked ~ .ds-filter-chip-switch::after {
    transform: translateX(12px);
}

.ds-filter-chip input:focus-visible ~ .ds-filter-chip-switch {
    box-shadow: 0 0 0 3px rgba(178, 182, 111, .35);
}

.ds-filter-chip:has(input:checked) {
    border-color: var(--ds-accent);
    background: rgba(178, 182, 111, .14);
    color: var(--ds-ink);
}

/* Bootstrap 5.0 checkboxes, radios and switches hardcode its blue
   (#0d6efd, focus #86b7fe) instead of using variables, so recolor them
   here to match .ds-filter-chip: deep olive when on, warm grey when off,
   the same soft olive focus ring. Native inputs without Bootstrap classes
   pick up the olive through accent-color. */
input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--ds-accent-deep);
}

.form-check-input {
    border-color: rgba(51, 51, 31, .28);
}

.form-check-input:focus {
    border-color: var(--ds-accent);
    box-shadow: 0 0 0 3px rgba(178, 182, 111, .35);
}

.form-check-input:checked,
.form-check-input[type=checkbox]:indeterminate {
    background-color: var(--ds-accent-deep);
    border-color: var(--ds-accent-deep);
}

/* Switch: filled grey track with a white knob when off (instead of
   Bootstrap's outlined track and grey knob), deep olive track when on. */
.form-switch .form-check-input,
.form-switch .form-check-input:focus {
    background-color: rgba(51, 51, 31, .18);
    border-color: transparent;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
}

.form-switch .form-check-input:checked {
    background-color: var(--ds-accent-deep);
    border-color: var(--ds-accent-deep);
}

/* The rest of Bootstrap 5.0's hardcoded blue that the views still reach.
   Resting looks stay as they are (legacy .btn buttons, Site.css's dark
   .btn-primary); only the blue hover/focus/active states are replaced. */

/* Focus ring: the same soft olive ring as .ds-input. Bootstrap's coloured
   variants (success/danger/dark/...) keep their own matching rings. */
.btn:not(.btn-success):not(.btn-danger):not(.btn-dark):not(.btn-warning):not(.btn-info):not(.btn-secondary):not(.btn-light):focus,
.btn-check:focus + .btn-primary,
.btn-primary:focus,
.btn-primary:active:focus,
.btn-primary.active:focus,
.btn-close:focus,
.accordion-button:focus {
    box-shadow: 0 0 0 3px rgba(178, 182, 111, .35);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--ds-accent);
    box-shadow: 0 0 0 3px rgba(178, 182, 111, .22);
}

.accordion-button:focus {
    border-color: var(--ds-accent);
}

/* .btn-primary is near-black at rest (Site.css); keep it in that family
   instead of flashing Bootstrap blue on hover/press. */
.btn-primary:hover,
.btn-primary:focus,
.btn-check:focus + .btn-primary,
.btn-primary:active,
.btn-primary.active,
.btn-check:checked + .btn-primary,
.btn-check:active + .btn-primary,
.show > .btn-primary.dropdown-toggle {
    color: #fff;
    background-color: #000;
    border-color: #000;
}

.btn-primary:disabled,
.btn-primary.disabled {
    background-color: #212529;
    border-color: #212529;
}

.btn-link,
.nav-link {
    color: var(--ds-accent-deep);
}

.btn-link:hover,
.nav-link:hover,
.nav-link:focus {
    color: var(--ds-ink);
}

.dropdown-item.active,
.dropdown-item:active {
    color: #fff;
    background-color: var(--ds-accent-deep);
}

.text-primary {
    color: var(--ds-accent-deep) !important;
}

/* bootstrap-datepicker ships Bootstrap 3's blue (#337ab7 and tints) across
   dozens of state selectors (:hover/.focus/.disabled/... combinations), so
   these use !important rather than mirroring each one. Selected day/month/
   year = deep olive, highlighted and range days = light olive tint, today
   = olive ring with bold text (instead of the plugin's yellow), so it
   stays distinct from the selected day. Order matters: today comes first,
   so a highlighted/range tint and the selected fill win when they overlap
   it. */
.datepicker table tr td.today,
.datepicker table tr td.today:hover {
    color: var(--ds-accent-deep) !important;
    font-weight: 700;
    background-color: transparent !important;
    background-image: none !important;
    border-color: transparent !important;
    box-shadow: inset 0 0 0 1.5px var(--ds-accent);
}

.datepicker table tr td.today:hover {
    background-color: rgba(178, 182, 111, .2) !important;
}

.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.highlighted,
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover {
    color: #fff !important;
    background-color: var(--ds-accent-deep) !important;
    background-image: none !important;
    border-color: var(--ds-accent-deep) !important;
    text-shadow: none !important;
    box-shadow: none;
}

.datepicker table tr td.highlighted,
.datepicker table tr td.range,
.datepicker table tr td.range.highlighted {
    color: var(--ds-ink) !important;
    background-color: rgba(178, 182, 111, .2) !important;
    border-color: transparent !important;
}

.datepicker table tr td.highlighted:hover,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.highlighted:hover {
    background-color: rgba(178, 182, 111, .35) !important;
}

.ds-alert {
    font-family: var(--ds-font-body);
    font-size: .85rem;
    padding: .75rem 1rem;
    border-radius: .8rem;
    background: rgba(217, 83, 79, .1);
    color: var(--ds-danger);
    margin-bottom: 1.1rem;
}

.ds-alert-success {
    background: rgba(106, 165, 28, .1);
    color: var(--ds-done);
}

.ds-alert-warning {
    background: rgba(201, 138, 62, .12);
    color: var(--ds-attention);
}

.ds-alert ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Split-screen auth shell: form panel + illustration panel */
.ds-authshell {
    min-height: 100vh;
    display: flex;
    background: var(--ds-warm);
}

.ds-authform {
    flex: 1 1 48%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 4rem clamp(2rem, 6vw, 6rem);
}

.ds-authform-inner {
    width: 100%;
    max-width: 26rem;
    margin: 0 auto;
}

/*
   Visual panel. Flat brand green, no gradients (not part of the TLGB brand
   language) — carried entirely by a big fashion-editorial type treatment.
   To swap in real product photography later, add a background-image here:

   .ds-authvisual {
       background-image: url('/Content/images/login-visual.jpg');
       background-size: cover;
       background-position: center;
   }
*/
.ds-authvisual {
    flex: 1 1 52%;
    position: relative;
    overflow: hidden;
    background-color: var(--ds-accent);
}

/* Visual panel contents: an oversized, slowly drifting brand mark behind
   big editorial type. Still flat brand green — the mark is a darker tint of
   the same green, not a gradient. Decorative only (aria-hidden in markup). */
.ds-authvisual {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: clamp(2rem, 5vw, 4.5rem);
    color: var(--ds-rail-ink);
}

.ds-authvisual-mark {
    position: absolute;
    top: 10%;
    right: -10%;
    width: min(70%, 620px);
    aspect-ratio: 43.91 / 32.67;
    background-color: var(--ds-accent-deep);
    opacity: .16;
    -webkit-mask: url('/Content/images/tlgb-beeldmerk.svg') no-repeat center / contain;
    mask: url('/Content/images/tlgb-beeldmerk.svg') no-repeat center / contain;
    animation: ds-auth-float 14s ease-in-out infinite alternate;
}

@keyframes ds-auth-float {
    from {
        transform: translate(0, 0) rotate(-2deg);
    }

    to {
        transform: translate(-14px, 18px) rotate(2deg);
    }
}

.ds-authvisual-copy {
    position: relative;
}

.ds-authvisual-eyebrow {
    font-size: .72rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: .16em;
    margin: 0;
    opacity: .75;
}

.ds-authvisual-title {
    font-family: var(--ds-font-display);
    font-weight: 700;
    font-size: clamp(3rem, 6.5vw, 6.5rem);
    line-height: .95;
    letter-spacing: -.02em;
    margin: .5rem 0 0;
}

.ds-authvisual-tag {
    font-weight: 300;
    font-size: 1.05rem;
    max-width: 28rem;
    margin: 1.25rem 0 0;
    opacity: .85;
}

/* Entrance: elements marked .ds-authenter fade up one after another; the
   order comes from an inline --ds-i on each element. */
@keyframes ds-auth-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.ds-authenter {
    animation: ds-auth-in 360ms var(--ds-ease) backwards;
    animation-delay: calc(var(--ds-i, 0) * 60ms + 60ms);
}

/* Failed login: the form gives one short shake once it has faded in. */
@keyframes ds-auth-shake {
    0%, 100% { transform: none; }
    20% { transform: translateX(-8px); }
    40% { transform: translateX(7px); }
    60% { transform: translateX(-5px); }
    80% { transform: translateX(3px); }
}

form.ds-auth-error {
    animation: ds-auth-shake 380ms var(--ds-ease-in-out) 520ms;
}

/* Submit feedback: spinner + disabled button while the login posts. */
.ds-spinner {
    display: none;
    width: 1em;
    height: 1em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: ds-spin .7s linear infinite;
}

@keyframes ds-spin {
    to {
        transform: rotate(360deg);
    }
}

.ds-btn.ds-loading .ds-spinner {
    display: inline-block;
}

.ds-btn.ds-loading:disabled {
    opacity: .9;
    cursor: progress;
}

@media (prefers-reduced-motion: reduce) {
    .ds-authvisual-mark,
    .ds-authenter,
    form.ds-auth-error,
    .ds-spinner {
        animation: none !important;
    }
}

@media (max-width: 991.98px) {
    .ds-authvisual {
        padding: 1.5rem 1.75rem;
    }

    .ds-authvisual-mark {
        top: -10%;
        right: -6%;
        width: 48%;
    }

    .ds-authvisual-title {
        font-size: 2.2rem;
    }

    .ds-authvisual-tag {
        display: none;
    }
}

@media (max-width: 991.98px) {
    .ds-authshell {
        flex-direction: column;
    }

    .ds-authvisual {
        flex: none;
        min-height: 160px;
    }

    .ds-authform {
        justify-content: center;
        padding: 2.5rem 1.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .ds-ring .ds-ring-progress {
        transition: none;
    }
}

/* =====================================================================
   App shell: icon rail + docked panel, replacing the two stacked
   topbar headers. Introduced 2026-08-10. See CLAUDE.md / design plan.

   Structure rendered by _Layout.cshtml when ViewBag.ToonMenu != "No":
     <nav class="ds-rail-primary">   -- fixed, icon-only, always 84px
     <div class="ds-rail-secondary"> -- fixed, docked panel, 0 or 268px
     <div class="ds-topbar">         -- desktop topbar (page title, bell, user)
     <div class="ds-mobile-topbar">  -- mobile-only topbar (hamburger)
     <div class="ds-mobile-overlay"> -- mobile-only full-screen drawer

   Body gets class `ds-has-shell` whenever the shell renders, plus
   `ds-panel-open` when the current page has a matching docked panel,
   and `ds-submenu-collapsed` (toggled client-side, persisted in
   localStorage) when the user has collapsed the docked panel.
   ===================================================================== */

body.ds-has-shell {
    font-family: var(--ds-font-body);
    background: #f7f7f5;
}

body.ds-has-shell .container.body-content {
    padding-top: 2rem;
    padding-bottom: 2rem;
}

.ds-rail-primary,
.ds-rail-secondary,
.ds-topbar,
.ds-mobile-topbar,
.ds-mobile-overlay {
    box-sizing: border-box;
}

.ds-rail-primary *,
.ds-rail-secondary *,
.ds-topbar *,
.ds-mobile-topbar *,
.ds-mobile-overlay * {
    box-sizing: border-box;
}

/* ---- primary icon rail ---- */
.ds-rail-primary {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 84px;
    background: var(--ds-rail-bg);
    color: var(--ds-rail-ink);
}

.ds-rail-brand {
    padding: 1.1rem 0 .9rem;
}

.ds-rail-mark {
    display: block;
    width: 38px;
    height: 38px;
    background: transparent;
    background-color: var(--ds-rail-ink);
    -webkit-mask: url('/Content/images/tlgb-beeldmerk.svg') no-repeat center / contain;
    mask: url('/Content/images/tlgb-beeldmerk.svg') no-repeat center / contain;
}

.ds-rail-nav {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
    padding: 0 .7rem;
}

.ds-rail-item {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: .7rem;
    border: none;
    border-radius: .75rem;
    background: transparent;
    color: var(--ds-rail-ink-soft);
    text-decoration: none;
    cursor: pointer;
    position: relative;
    transition: background-color var(--ds-dur-fast) var(--ds-ease),
                color var(--ds-dur-fast) var(--ds-ease),
                transform var(--ds-dur-fast) var(--ds-ease);
}

.ds-rail-item:active {
    transform: scale(.96);
}

.ds-rail-item i {
    font-size: 1.3rem;
    line-height: 1;
    transition: transform var(--ds-dur) var(--ds-ease-in-out);
}

.ds-rail-item:hover {
    background: rgba(54, 54, 54, .1);
    color: var(--ds-rail-ink);
}

.ds-rail-item.ds-active {
    background: var(--ds-rail-active-bg);
    color: var(--ds-rail-active-ink);
}

/* Active indicator bar: present on every item but collapsed, so it can
   grow into place when an item becomes active. */
.ds-rail-item::before {
    content: "";
    position: absolute;
    left: -.7rem;
    top: .45rem;
    bottom: .45rem;
    width: 4px;
    border-radius: 2px;
    background: var(--ds-rail-active-ink);
    opacity: 0;
    transform: scaleY(0);
    transition: transform var(--ds-dur) var(--ds-ease),
                opacity var(--ds-dur) var(--ds-ease);
}

.ds-rail-item.ds-active::before {
    opacity: .35;
    transform: scaleY(1);
}

/* Collapse toggle: one chevron that rotates, instead of swapping icons. */
body.ds-submenu-collapsed #ds-submenu-toggle-icon {
    transform: rotate(180deg);
}

.ds-rail-spacer {
    flex: 1;
}

.ds-rail-foot {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
    padding: 0 .7rem 1.2rem;
}

/* ---- docked secondary panel ---- */
.ds-rail-secondary {
    display: flex;
    flex-direction: column;
    width: 268px;
    overflow: hidden;
    background: var(--ds-rail-bg-2);
    color: var(--ds-rail-ink);
}

.ds-rail-secondary-panel {
    display: flex;
    flex-direction: column;
    width: 268px;
    flex: none;
    height: 100%;
}

.ds-rail-secondary-panel[hidden] {
    display: none;
}

.ds-rail-secondary-head {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: 1.15rem 1.1rem 1rem;
    border-bottom: 1px solid var(--ds-rail-line);
    flex: none;
}

.ds-rail-secondary-head .ds-rail-mark-sm {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: .55rem;
    background: rgba(54, 54, 54, .1);
    flex: none;
}

.ds-rail-secondary-head .ds-rail-mark-sm i {
    font-size: 1rem;
}

.ds-rail-secondary-head .t {
    font-family: var(--ds-font-display);
    font-weight: 700;
    font-size: 1.02rem;
    white-space: nowrap;
}

.ds-rail-secondary-body {
    flex: 1;
    overflow-y: auto;
    padding: .6rem .6rem .9rem;
}

.ds-rail-secondary-eyebrow {
    display: inline-block;
    font-size: .64rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 700;
    color: var(--ds-rail-ink);
    background: rgba(54, 54, 54, .08);
    padding: .2rem .55rem;
    border-radius: .4rem;
    margin: 1rem .6rem .5rem;
    white-space: nowrap;
}

.ds-rail-secondary-eyebrow:first-child {
    margin-top: .4rem;
}

.ds-rail-secondary-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
    width: 100%;
    padding: .62rem .7rem;
    border-radius: .6rem;
    color: var(--ds-rail-ink);
    text-decoration: none;
    font-size: .92rem;
    font-weight: 400;
    white-space: nowrap;
    position: relative;
    transition: background-color var(--ds-dur-fast) var(--ds-ease);
}

/* Staggered reveal of the panel's contents — CSS only, driven by the same
   body classes that slide the panel (see the desktop media query below).
   Being transitions (not keyframes), .ds-preload suppresses them on page
   load, so navigating with the panel already open stays calm. */
@media (min-width: 992px) {
    .ds-rail-secondary-head,
    .ds-rail-secondary-body > * {
        transition: opacity 160ms var(--ds-ease),
                    transform 160ms var(--ds-ease),
                    background-color var(--ds-dur-fast) var(--ds-ease);
    }

    /* Delays are per property (opacity, transform, background-color) so the
       stagger never delays an item's hover colour. */
    .ds-rail-secondary-body > :nth-child(1) { transition-delay: 12ms, 12ms, 0s; }
    .ds-rail-secondary-body > :nth-child(2) { transition-delay: 24ms, 24ms, 0s; }
    .ds-rail-secondary-body > :nth-child(3) { transition-delay: 36ms, 36ms, 0s; }
    .ds-rail-secondary-body > :nth-child(4) { transition-delay: 48ms, 48ms, 0s; }
    .ds-rail-secondary-body > :nth-child(5) { transition-delay: 60ms, 60ms, 0s; }
    .ds-rail-secondary-body > :nth-child(6) { transition-delay: 72ms, 72ms, 0s; }
    .ds-rail-secondary-body > :nth-child(7) { transition-delay: 84ms, 84ms, 0s; }
    .ds-rail-secondary-body > :nth-child(n+8) { transition-delay: 96ms, 96ms, 0s; }

    /* Closed: reset only after the slide-out has finished (delay = --ds-dur),
       so the panel doesn't empty out while it's still moving. */
    body.ds-has-shell.ds-submenu-collapsed .ds-rail-secondary-head,
    body.ds-has-shell.ds-submenu-collapsed .ds-rail-secondary-body > *,
    body.ds-has-shell:not(.ds-panel-open) .ds-rail-secondary-head,
    body.ds-has-shell:not(.ds-panel-open) .ds-rail-secondary-body > * {
        opacity: 0;
        transform: translateX(-6px);
        transition: opacity 0s linear var(--ds-dur),
                    transform 0s linear var(--ds-dur);
    }
}

.ds-rail-secondary-item:hover {
    background: rgba(54, 54, 54, .08);
    color: var(--ds-rail-ink);
}

.ds-rail-secondary-item .role {
    display: block;
    font-size: .7rem;
    font-weight: 300;
    color: var(--ds-rail-ink-soft);
    margin-top: .1rem;
    white-space: normal;
}

/* The existing #label-x AJAX badge spans (bg-warning rounded-pill, toggled
   via .d-none) are repositioned as a small dot instead of Bootstrap's
   translate-middle pill, without touching the JS that toggles them. */
.ds-rail-secondary-item .position-relative {
    display: inline-flex;
}

.ds-rail-secondary-item [id^="label-"] {
    position: static;
    display: inline-flex;
    width: 8px;
    height: 8px;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    background: var(--ds-danger) !important;
    transform: none;
    top: auto;
    left: auto;
}

.ds-rail-secondary-item [id^="label-"] i {
    display: none;
}

/* ---- topbar (desktop) ---- */
.ds-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.6rem;
    background: var(--ds-surface);
    border-bottom: 1px solid var(--ds-line);
    position: sticky;
    top: 0;
    z-index: 500;
}

/* Green "rail" treatment for pages with no icon-rail sidebar (the
   scan-station layout: CheckMulti/CheckSingle/CheckBestelling/
   CheckRetourbon) — matches the icon rail's brand color instead of the
   plain white topbar used by the full admin shell. */
.ds-topbar.ds-topbar-rail {
    background: var(--ds-rail-bg);
    border-bottom: none;
}

.ds-topbar.ds-topbar-rail .ds-topbar-crumbs {
    color: var(--ds-rail-ink);
}

.ds-topbar.ds-topbar-rail .ds-topbar-user {
    color: var(--ds-rail-ink-soft);
}

.ds-topbar.ds-topbar-rail .ds-iconbtn {
    background: rgba(54, 54, 54, .08);
    border-color: transparent;
    color: var(--ds-rail-ink);
}

.ds-topbar.ds-topbar-rail .ds-iconbtn:hover {
    background: rgba(54, 54, 54, .16);
    border-color: transparent;
    color: var(--ds-rail-ink);
}

.ds-topbar.ds-topbar-rail .ds-rail-mark {
    background-color: var(--ds-rail-ink);
}

/* Black topbar treatment for Cowboysbag-branded scan-station pages —
   same layout as .ds-topbar-rail, distinct brand color instead of the
   TLGB green. */
.ds-topbar.ds-topbar-cbb {
    background: #16181a;
    border-bottom: none;
}

.ds-topbar.ds-topbar-cbb .ds-topbar-crumbs {
    color: #f5f5f5;
}

.ds-topbar.ds-topbar-cbb .ds-topbar-user {
    color: rgba(245, 245, 245, .75);
}

.ds-topbar.ds-topbar-cbb .ds-iconbtn {
    background: rgba(245, 245, 245, .1);
    border-color: transparent;
    color: #f5f5f5;
}

.ds-topbar.ds-topbar-cbb .ds-iconbtn:hover {
    background: rgba(245, 245, 245, .18);
    border-color: transparent;
    color: #f5f5f5;
}

/* CBB_logo.svg is a flat black mark (fill:#000000) meant for light
   backgrounds elsewhere in the app; inverting it here turns it white
   for the black topbar without needing a second logo asset. */
.ds-topbar.ds-topbar-cbb .ds-cbb-logo {
    filter: invert(1);
}

.ds-topbar-crumbs {
    display: flex;
    align-items: center;
    font-family: var(--ds-font-display);
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ds-ink);
}

.ds-topbar-crumbs-sep {
    color: var(--ds-ink-soft);
    font-weight: 300;
    margin: 0 .45rem;
}

.ds-topbar-crumbs-sub {
    font-weight: 400;
    color: var(--ds-ink-soft);
    text-transform: capitalize;
}

.ds-topbar-scroll-badge {
    margin-left: .7rem;
}

.ds-topbar-scroll-badge[hidden] {
    display: none;
}

.ds-topbar-right {
    display: flex;
    align-items: center;
    gap: .8rem;
}

.ds-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: .65rem;
    border: 1px solid var(--ds-line);
    background: var(--ds-surface);
    color: var(--ds-ink-soft);
    text-decoration: none;
    cursor: pointer;
    position: relative;
    transition: background-color var(--ds-dur-fast) var(--ds-ease),
                border-color var(--ds-dur-fast) var(--ds-ease),
                color var(--ds-dur-fast) var(--ds-ease),
                transform var(--ds-dur-fast) var(--ds-ease);
}

.ds-iconbtn:active {
    transform: scale(.95);
}

.ds-iconbtn:hover {
    color: var(--ds-ink);
    border-color: var(--ds-accent);
}

.ds-iconbtn i {
    font-size: 1.05rem;
}

.ds-topbar-user {
    font-family: var(--ds-font-body);
    font-size: .85rem;
    color: var(--ds-ink-soft);
    margin-right: .2rem;
}

.ds-notif-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 17px;
    height: 17px;
    padding: 0 3px;
    font-size: .62rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ds-iconbtn.dropdown-toggle::after {
    display: none;
}

/* ---- collapse / no-panel widths (desktop) ---- */
@media (min-width: 992px) {
    .ds-rail-primary {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 1030;
    }

    .ds-rail-secondary {
        position: fixed;
        top: 0;
        left: 84px;
        bottom: 0;
        z-index: 1029;
        transition: transform var(--ds-dur) var(--ds-ease-in-out),
                    visibility 0s linear 0s;
    }

    /* Closed: slid back behind the primary rail (z-index 1030) rather than
       squeezed to width 0, so its contents move with it instead of being
       clipped. visibility flips only after the slide finishes, which keeps
       the hidden links out of the tab order. */
    body.ds-has-shell.ds-submenu-collapsed .ds-rail-secondary,
    body.ds-has-shell:not(.ds-panel-open) .ds-rail-secondary {
        transform: translateX(-100%);
        visibility: hidden;
        transition: transform var(--ds-dur) var(--ds-ease-in-out),
                    visibility 0s linear var(--ds-dur);
    }

    body.ds-has-shell .ds-topbar,
    body.ds-has-shell .ds-legacy-subnav,
    body.ds-has-shell .container.body-content {
        margin-left: 84px;
        transition: margin-left var(--ds-dur) var(--ds-ease-in-out);
    }

    /* Bootstrap's .container still caps max-width and centers with
       margin-right:auto — combined with the margin-left offset above that
       leaves a lopsided empty gap on wide screens. Make it fluid instead so
       it fills the space next to the rail evenly on both sides. */
    body.ds-has-shell .container.body-content {
        max-width: none;
        width: auto;
        margin-right: 0;
        padding-left: 2rem;
        padding-right: 2rem;
    }

    .ds-subnav {
        padding-left: 2rem;
        padding-right: 2rem;
    }

    /* Safety net for pages that still nest a raw Bootstrap .container
       (the pre-ds- "container p-3 mt-4 container-white" idiom) directly
       inside body-content or the legacy subnav. Without this, that inner
       .container keeps Bootstrap's own max-width cap and auto-centering,
       so it renders narrower and off-center relative to the now-fluid
       .body-content around it — the same stair-step misalignment the
       TaskManager header and legacy subnav had. Neutralize it wherever it
       still occurs instead of chasing every page one by one; a page that's
       been fully migrated to .ds-panel/.ds-table-wrap etc. never has a
       nested .container in the first place, so this is a no-op there. */
    body.ds-has-shell .container.body-content .container,
    body.ds-has-shell .ds-legacy-subnav .container {
        max-width: none;
        width: auto;
        margin-left: 0;
        margin-right: 0;
        padding-left: 0;
        padding-right: 0;
    }

    body.ds-has-shell.ds-panel-open:not(.ds-submenu-collapsed) .ds-topbar,
    body.ds-has-shell.ds-panel-open:not(.ds-submenu-collapsed) .ds-legacy-subnav,
    body.ds-has-shell.ds-panel-open:not(.ds-submenu-collapsed) .container.body-content {
        margin-left: 352px;
    }

    .ds-mobile-topbar,
    .ds-mobile-overlay,
    .ds-mobile-backdrop,
    .ds-topbar .ds-hamburger {
        display: none !important;
    }
}

/* ---- mobile (<992px): hamburger + full-screen drawer ---- */
@media (max-width: 991.98px) {
    .ds-rail-primary,
    .ds-rail-secondary,
    body.ds-has-shell .ds-topbar {
        display: none;
    }

    .ds-mobile-topbar {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .6rem;
        padding: .8rem 1rem;
        background: var(--ds-rail-bg);
        color: var(--ds-rail-ink);
    }

    .ds-mobile-topbar .ds-hamburger {
        background: none;
        border: none;
        color: var(--ds-rail-ink);
        padding: .2rem;
        font-size: 1.3rem;
        line-height: 1;
    }

    .ds-mobile-topbar .word {
        font-family: var(--ds-font-display);
        font-weight: 700;
        font-size: 1rem;
    }

    .ds-mobile-topbar .ds-mobile-right {
        display: flex;
        align-items: center;
        gap: .5rem;
    }
}

/* Mobile drawer: slides in from the left over a dimmed backdrop. Open state
   is the .ds-open class (toggled by the shell script); closed it stays
   rendered but off-canvas, with visibility flipping only after the slide so
   its links are out of the tab order. Level 1 (main list) and level 2
   (submenu) share one grid cell and slide sideways via .ds-level-2. */
.ds-mobile-overlay {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(88vw, 380px);
    z-index: 1050;
    background: var(--ds-rail-bg);
    color: var(--ds-rail-ink);
    display: grid;
    grid-template: minmax(0, 1fr) / minmax(0, 1fr);
    overflow: hidden;
    box-shadow: 8px 0 32px -12px rgba(30, 30, 20, .35);
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform var(--ds-dur) var(--ds-ease-in-out),
                visibility 0s linear var(--ds-dur);
}

.ds-mobile-overlay.ds-open {
    transform: none;
    visibility: visible;
    transition: transform var(--ds-dur) var(--ds-ease),
                visibility 0s linear 0s;
}

.ds-mobile-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1049;
    background: rgba(30, 30, 20, .4);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--ds-dur) var(--ds-ease-in-out),
                visibility 0s linear var(--ds-dur);
}

.ds-mobile-backdrop.ds-open {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--ds-dur) var(--ds-ease),
                visibility 0s linear 0s;
}

/* No page scrolling behind the open drawer. */
body.ds-drawer-open {
    overflow: hidden;
}

.ds-mobile-l1,
.ds-mobile-l2 {
    grid-area: 1 / 1;
    transition: transform var(--ds-dur) var(--ds-ease-in-out),
                opacity var(--ds-dur) var(--ds-ease-in-out),
                visibility 0s linear 0s;
}

.ds-mobile-overlay.ds-level-2 .ds-mobile-l1 {
    transform: translateX(-25%);
    opacity: 0;
    visibility: hidden;
    transition: transform var(--ds-dur) var(--ds-ease-in-out),
                opacity var(--ds-dur) var(--ds-ease-in-out),
                visibility 0s linear var(--ds-dur);
}

.ds-mobile-overlay:not(.ds-level-2) .ds-mobile-l2 {
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--ds-dur) var(--ds-ease-in-out),
                visibility 0s linear var(--ds-dur);
}

.ds-mobile-ov-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.1rem .6rem;
    flex: none;
}

.ds-mobile-ov-head .word {
    font-family: var(--ds-font-display);
    font-weight: 700;
    font-size: 1.05rem;
}

.ds-mobile-close {
    width: 34px;
    height: 34px;
    border-radius: .6rem;
    border: 1px solid var(--ds-rail-line);
    background: none;
    color: var(--ds-rail-ink);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.ds-mobile-l1 {
    overflow-y: auto;
    padding: .4rem .6rem 1rem;
}

.ds-mobile-l1-eyebrow {
    display: inline-block;
    font-size: .64rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 700;
    color: var(--ds-rail-ink);
    background: rgba(54, 54, 54, .08);
    padding: .2rem .55rem;
    border-radius: .4rem;
    margin: 1rem .8rem .5rem;
}

.ds-mobile-l1-item {
    display: flex;
    align-items: center;
    gap: .85rem;
    width: 100%;
    padding: .85rem .8rem;
    border-radius: .75rem;
    border: none;
    background: transparent;
    color: var(--ds-rail-ink);
    text-decoration: none;
    font-weight: 400;
    font-size: .98rem;
    text-align: left; /* the Beheer/Tools entries are <button>s, which center by default */
}

.ds-mobile-l1-item i.ds-mobile-l1-icon {
    font-size: 1.2rem;
    width: 22px;
    flex: none;
}

.ds-mobile-l1-item .lbl {
    flex: 1;
}

.ds-mobile-l1-item .bi-chevron-right {
    color: var(--ds-rail-ink-soft);
    flex: none;
}

.ds-mobile-l1-item:hover {
    background: rgba(54, 54, 54, .08);
}

.ds-mobile-l2 {
    display: flex;
    min-height: 0;
    background: var(--ds-rail-bg);
}

.ds-mobile-l2-rail {
    width: 58px;
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: .6rem .4rem;
    border-right: 1px solid var(--ds-rail-line);
    overflow-y: auto;
}

.ds-mobile-l2-rail button {
    width: 100%;
    padding: .6rem;
    border-radius: .6rem;
    background: none;
    border: none;
    color: var(--ds-rail-ink-soft);
    display: flex;
    justify-content: center;
    cursor: pointer;
}

.ds-mobile-l2-rail button i {
    font-size: 1.2rem;
}

.ds-mobile-l2-rail button.ds-active {
    background: var(--ds-rail-active-bg);
    color: var(--ds-rail-active-ink);
}

.ds-mobile-l2-panel {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.ds-mobile-l2-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: 1rem 1.1rem .8rem;
    border-bottom: 1px solid var(--ds-rail-line);
    flex: none;
}

.ds-mobile-l2-back {
    background: none;
    border: none;
    color: var(--ds-rail-ink-soft);
    padding: 0;
    display: flex;
    cursor: pointer;
    font-size: 1.15rem;
}

.ds-mobile-l2-head .t {
    font-family: var(--ds-font-display);
    font-weight: 700;
    font-size: 1rem;
}

.ds-mobile-l2-body {
    padding: .5rem .5rem 1rem;
    overflow-y: auto;
}

.ds-mobile-l2-body a,
.ds-mobile-l2-body button {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    color: var(--ds-rail-ink);
    text-decoration: none;
    font-weight: 400;
    font-size: .9rem;
    padding: .62rem .7rem;
    border-radius: .6rem;
    cursor: pointer;
}

.ds-mobile-l2-body a:hover,
.ds-mobile-l2-body button:hover {
    background: rgba(54, 54, 54, .08);
}

/* ---- legacy subnav rows (Todo / Sample Sale) — a horizontal tab bar
   under the topbar for pages with 2 sub-views. Padding matches
   .container.body-content's own gutter (.75rem mobile / 2rem desktop, the
   latter set alongside the other shell offset rules) so the tabs line up
   with the page content below instead of centering as a nested Bootstrap
   .container would. ---- */
.ds-legacy-subnav {
    background: var(--ds-surface);
    border-bottom: 1px solid var(--ds-line);
}

.ds-subnav {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    padding: .6rem .75rem;
}

.ds-subnav-item {
    display: inline-flex;
    align-items: center;
    padding: .5rem 1rem;
    border-radius: .7rem;
    font-family: var(--ds-font-body);
    font-size: .88rem;
    font-weight: 400;
    color: var(--ds-ink-soft);
    text-decoration: none;
    transition: background .12s ease, color .12s ease;
}

.ds-subnav-item:hover {
    background: rgba(178, 182, 111, .12);
    color: var(--ds-ink);
}

.ds-subnav-item.ds-active {
    background: var(--ds-accent);
    color: #fff;
    font-weight: 700;
}

/* ---- plain Bootstrap components re-themed to the current brand color.
   bootstrap.css ships with the *old* brand green (#bdbf10) hardcoded into
   .page-item.active/.page-link:focus — override with the current tokens. ---- */
.page-link:focus {
    color: var(--ds-accent-deep);
    box-shadow: 0 0 0 .25rem rgba(178, 182, 111, 0.25);
}

.page-item.active .page-link {
    color: #fff;
    background-color: var(--ds-accent);
    border-color: var(--ds-accent);
}

/* bootstrap.css only rounds the outer corners of the first/last page-link
   (a "connected strip" look) — give every page-link the same full pill
   rounding as .ds-btn, spaced out instead of joined, so pagination reads
   as the same button language as the rest of the app. */
.pagination {
    gap: .35rem;
}

.page-link {
    border-radius: .8rem !important;
}

.page-item:not(:first-child) .page-link {
    margin-left: 0;
}

/* bootstrap.css's plain `a` default is #21252f with an underline, turning
   the stock Bootstrap link-blue (#0a58ca) on hover — replace with the
   brand palette. Bootstrap's own components (buttons, nav-links, dropdown
   items, page-links, etc.) already set their own more specific
   text-decoration/color, so this only affects plain inline content links
   (e.g. an order/return ID linked from a table cell). */
a {
    color: var(--ds-accent-deep);
    text-decoration: none;
}

a:hover,
a:focus {
    color: var(--ds-ink);
    text-decoration: none;
}

/* ---- page content: entrance, topbar scroll shadow, clickable cards ---- */

/* One short fade-up of the page content on load. Only while body has
   .ds-page-enter (set server-side, removed when the animation ends by the inline
   script at the top of <body>), and cancelled the moment a Bootstrap modal
   opens (body.modal-open): a transformed/translucent ancestor would
   otherwise misplace a modal that opens on load (e.g. #defectModal) or trap
   it under its backdrop. No fill-mode forwards, so nothing lingers after. */
@keyframes ds-page-in {
    from {
        opacity: 0;
        transform: translateY(6px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

body.ds-has-shell.ds-page-enter:not(.modal-open) .container.body-content {
    animation: ds-page-in 220ms var(--ds-ease) backwards;
}

/* Soft shadow under the sticky topbar once the page is scrolled — CSS
   scroll-driven, no JS. Browsers without scroll timelines keep the plain
   border, which is the current look. */
@keyframes ds-topbar-shadow {
    from {
        box-shadow: 0 6px 18px -10px rgba(51, 51, 31, 0);
    }

    to {
        box-shadow: 0 6px 18px -10px rgba(51, 51, 31, .28);
    }
}

@supports (animation-timeline: scroll()) {
    body.ds-has-shell .ds-topbar {
        animation: ds-topbar-shadow linear both;
        animation-timeline: scroll(root);
        animation-range: 0 40px;
    }
}

/* Clickable cards lift slightly on hover. Matches cards that are links or
   carry an onclick, so a new clickable card gets it without extra classes. */
a.ds-card,
.ds-card[onclick] {
    transition: transform var(--ds-dur) var(--ds-ease),
                box-shadow var(--ds-dur) var(--ds-ease),
                border-color var(--ds-dur) var(--ds-ease);
}

a.ds-card:hover,
.ds-card[onclick]:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 24px -12px rgba(51, 51, 31, .22);
    border-color: rgba(178, 182, 111, .45);
}

/* Rail logo: once, right after load (just behind the page entrance), a
   soft cream halo swells behind the mark while it flips once over its
   vertical (Y) axis in 3D, with a slight overshoot. The perspective()
   is part of each transform so the flip gets depth without a perspective
   on the rail. The halo is a pseudo-element instead of a drop-shadow
   filter because the mark itself is a CSS mask, which would clip its own
   shadow. Hovering flips the link (not the mark), so the hover flip can't
   replay the load animation when the pointer leaves. */
@keyframes ds-mark-spin {
    from {
        transform: perspective(160px) rotateY(0deg);
    }

    to {
        transform: perspective(160px) rotateY(360deg);
    }
}

@keyframes ds-mark-glow {
    0% {
        opacity: 0;
        transform: scale(.7);
    }

    31% {
        opacity: 1;
        transform: scale(1.15);
    }

    100% {
        opacity: 0;
        transform: scale(1);
    }
}

.ds-rail-brand a {
    position: relative;
    display: block;
    isolation: isolate;
}

.ds-rail-brand a::before,
.ds-rail-brand a::after {
    content: "";
    position: absolute;
    inset: -10px;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(244, 244, 223, .95) 0%, rgba(244, 244, 223, .45) 45%, rgba(244, 244, 223, 0) 70%);
    opacity: 0;
    pointer-events: none;
}

.ds-rail-brand a::before {
    animation: ds-mark-glow 2.2s ease-in-out 400ms both;
}

/* Hover halo lives on ::after: overriding ::before's animation on hover
   would replay the load glow the moment the pointer leaves. */
.ds-rail-brand a::after {
    transform: scale(.8);
    transition: opacity var(--ds-dur) var(--ds-ease),
                transform var(--ds-dur) var(--ds-ease);
}

.ds-rail-brand a:hover::after {
    opacity: 1;
    transform: scale(1.1);
}

.ds-rail-brand .ds-rail-mark {
    animation: ds-mark-spin 1.25s cubic-bezier(.6, 0, .25, 1.2) 400ms;
}

@keyframes ds-mark-hover {
    from {
        transform: perspective(160px) rotateY(0deg);
    }

    to {
        transform: perspective(160px) rotateY(360deg);
    }
}

.ds-rail-brand a:hover {
    animation: ds-mark-hover 1.25s cubic-bezier(.6, 0, .25, 1.2);
}

@media (prefers-reduced-motion: reduce) {
    body.ds-has-shell.ds-page-enter .container.body-content,
    .ds-rail-brand a::before,
    .ds-rail-brand a:hover,
    .ds-rail-brand .ds-rail-mark {
        animation: none !important;
    }

    .ds-rail-brand a::after,
    .ds-filter-chip,
    .ds-filter-chip-switch,
    .ds-filter-chip-switch::after,
    .ds-option {
        transition: none !important;
    }

    a.ds-card,
    .ds-card[onclick] {
        transition: none !important;
    }

    a.ds-card:hover,
    .ds-card[onclick]:hover {
        transform: none !important;
    }
}

@media (prefers-reduced-motion: reduce) {
    .ds-rail-secondary,
    .ds-topbar,
    .ds-legacy-subnav,
    .container.body-content,
    .ds-btn,
    .ds-input,
    .ds-iconbtn,
    .ds-rail-item,
    .ds-rail-item i,
    .ds-rail-item::before,
    .ds-rail-secondary-item {
        transition: none !important;
    }

    .ds-btn:active,
    .ds-iconbtn:active,
    .ds-rail-item:active {
        transform: none !important;
    }

    .ds-rail-secondary-head,
    .ds-rail-secondary-body > *,
    .ds-mobile-overlay,
    .ds-mobile-backdrop,
    .ds-mobile-l1,
    .ds-mobile-l2 {
        transition: none !important;
    }
}

/* ---- multi-step flows (introduced with the Retourmelden restyle) ---- */

/* Step indicator: <ol class="ds-steps"> with <li class="ds-done|ds-current">,
   each holding <span class="n">number</span><span>label</span>. Done steps
   show a check, the current one is emphasised, later ones are muted. */
.ds-steps {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    list-style: none;
    margin: 0 0 1.25rem;
    padding: 0;
    font-family: var(--ds-font-body);
    font-size: .82rem;
    color: var(--ds-ink-soft);
}

.ds-steps li {
    display: flex;
    align-items: center;
    gap: .5rem;
}

/* connector line between steps */
.ds-steps li + li::before {
    content: "";
    width: 28px;
    height: 1.5px;
    margin-right: .1rem;
    background: var(--ds-line);
    border-radius: 1px;
}

.ds-steps li.ds-done + li::before {
    background: var(--ds-accent);
}

.ds-steps .n {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1.5px solid rgba(51, 51, 31, .18);
    font-size: .72rem;
    font-weight: 700;
    color: var(--ds-ink-soft);
    background: var(--ds-surface);
}

.ds-steps li.ds-current {
    color: var(--ds-ink);
    font-weight: 700;
}

.ds-steps li.ds-current .n {
    border-color: var(--ds-accent-deep);
    background: var(--ds-accent-deep);
    color: #fff;
}

.ds-steps li.ds-done .n {
    border-color: var(--ds-accent);
    background: rgba(178, 182, 111, .18);
    color: var(--ds-accent-deep);
    font-size: 0;
}

.ds-steps li.ds-done .n::after {
    content: "\f633";
    font-family: bootstrap-icons !important;
    font-size: .9rem;
    line-height: 1;
}

/* Square product thumbnail for table rows and cards. */
.ds-thumb {
    width: 56px;
    height: 56px;
    flex: none;
    object-fit: cover;
    border-radius: .6rem;
    border: 1px solid var(--ds-line);
    background: var(--ds-bg);
}

/* Compact field for use inside table rows. */
.ds-input.ds-input-sm {
    padding: .45rem .7rem;
    font-size: .85rem;
    border-radius: .6rem;
}

/* Selectable option card around a radio/checkbox: the real input stays
   visible on the left; the card picks up the accent when it is checked. */
.ds-option {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    margin: 0;
    padding: .85rem 1rem;
    border: 1.5px solid var(--ds-line);
    border-radius: .8rem;
    background: var(--ds-bg);
    font-family: var(--ds-font-body);
    font-size: .88rem;
    color: var(--ds-ink);
    cursor: pointer;
    transition: border-color var(--ds-dur-fast) var(--ds-ease),
                background-color var(--ds-dur-fast) var(--ds-ease);
}

.ds-option .form-check-input {
    flex: none;
    margin: .15rem 0 0;
}

.ds-option:hover {
    border-color: rgba(178, 182, 111, .55);
}

.ds-option:has(input:checked) {
    border-color: var(--ds-accent);
    background: rgba(178, 182, 111, .12);
}

/* Outcome card for the last step of a flow: a round status icon, a title
   and the key reference number. Add .ds-result-error for the failure. */
.ds-result {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
}

.ds-result-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: rgba(106, 165, 28, .12);
    color: var(--ds-done);
    font-size: 1.5rem;
}

.ds-result-error .ds-result-icon {
    background: rgba(217, 83, 79, .1);
    color: var(--ds-danger);
}

.ds-result-number {
    font-family: var(--ds-font-display);
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--ds-ink);
    letter-spacing: .01em;
}

/* Vertical pill nav — restyles Bootstrap's .nav-pills (data-bs-toggle="pill")
   left-hand tab list, e.g. a detail page's "Gegevens wijzigen / Contact log /
   ..." section switcher. Bootstrap's own .nav/.nav-pills/.nav-link/.active
   classes stay (its JS keys off them) — these are additive. */
.ds-tabnav .nav-link {
    display: block;
    width: 100%;
    text-align: left;
    padding: .7rem .9rem;
    border-radius: .7rem;
    font-family: var(--ds-font-body);
    font-size: .9rem;
    font-weight: 400;
    color: var(--ds-ink-soft);
    background: transparent;
}

.ds-tabnav .nav-link:hover {
    background: rgba(178, 182, 111, 0.1);
    color: var(--ds-ink);
}

.ds-tabnav .nav-link.active {
    background: var(--ds-accent);
    color: #fff;
    font-weight: 700;
}

/* Picklijsten "niet gevonden" toggle button — ViewBag.ScriptPart ==
   "Picklijst" in _Layout.cshtml toggles the literal .btn-dark/.btn-danger
   classes on click, so those exact class names have to stay; recolor them
   to the ds- palette here rather than touching that JS. */
.ds-btn.nietgevonden.btn-dark {
    background: var(--ds-ink);
    color: #fff;
    border-color: var(--ds-ink);
}

.ds-btn.nietgevonden.btn-danger {
    background: var(--ds-danger);
    color: #fff;
    border-color: var(--ds-danger);
}
