:root {
    --profix-sidebar-width: 260px;
}

/* Hide spin buttons on number inputs in dialogs */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

html {
    font-size: 14px;  /* DevExpress standaard = 16px, wij schalen alles ~12% kleiner */
}

html, body {
    height: 100%;
}

app {
    display: block;
    height: 100%;
}

.header-logo-wrapper {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.header-logo {
    width: 93px;
    height: 36px;
    background-image: url('../images/profix-logo.png');
    background-size: contain;
    background-position: left center;
    background-repeat: no-repeat;
}

.header-tenant-name {
    color: inherit;
    font-weight: bold;
    font-size: 13px;
    line-height: 16px;
    white-space: nowrap;
    display: block;
    text-align: center;
}

#blazor-error-ui {
    background: inherit;
    bottom: 0;
    display: none;
    position: fixed;
    width: 100%;
    height: 100%;
    z-index: 100001;
}

/* Hamburger knop alleen verbergen op desktop (brede schermen) */
@media (min-width: 769px) {
    .btn-hamburger {
        display: none !important;
    }
}

.xaf-sidebar{
    width: var(--profix-sidebar-width);
    min-width: var(--profix-sidebar-width);
}

.header-left-side {
    width: var(--profix-sidebar-width);
    min-width: var(--profix-sidebar-width);
    flex-shrink: 0;
}

/* Mobiel: sidebar als overlay, standaard verborgen, zichtbaar na toggle */
@media (max-width: 768px) {
    .xaf-sidebar {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        height: 100%;
        z-index: 1000;
        width: var(--profix-sidebar-width);
        min-width: var(--profix-sidebar-width);
        overflow-y: auto;
        box-shadow: 2px 0 8px rgba(0,0,0,0.3);
    }

    /* XAF zet .d-flex via JS toggle — sidebar wordt zichtbaar */
    .xaf-sidebar.d-flex {
        display: flex !important;
    }

    .header-left-side {
        width: auto;
        min-width: unset;
    }

    /* Overlay achter sidebar op mobiel */
    .sidebar-sm-shadow {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,0.4);
        z-index: 999;
    }

    .sidebar-sm-shadow.d-block {
        display: block !important;
    }
}

.xaf-sidebar .dxbl-accordion-item-text-container .dxbl-text,
.xaf-sidebar .xaf-nav-link span {
    font-size: 12px;
}

.xaf-sidebar .dxbl-group-header {
    min-height: 28px !important;
}

/* Een menu-item dat op slot zit grijs maken.

   XAF blokkeert het item wel (klikken doet niets) maar zet er geen dxbl-disabled op. Het enige
   verschil in de opmaak is dat de klasse xaf-action op het klikvlak WEGVALT. Daarop mikken we dus.
   Nagekeken in de DOM: een werkend item heeft "xaf-action xaf-navigation-link-click-area", een
   geblokkeerd item alleen "xaf-navigation-link-click-area".

   :has() is nodig omdat we vanaf het klikvlak naar het hele item omhoog moeten. Alle browsers die
   Blazor Server ondersteunen kennen dat inmiddels.

   Groepen moeten er expliciet uit. Een groep heeft ook geen xaf-action - er zit immers geen scherm
   achter - en werd daarom net zo goed grijs. Het onderscheid zit in het uitklappijltje: bij een blad
   staat dat op dxbl-invisible (er valt niets uit te klappen), bij een groep is het zichtbaar.
   aria-expanded is de tweede zekering; dat staat alleen op iets dat open en dicht kan.

   De regel is bewust streng. Een groep die ten onrechte grijs is valt meteen op en is fout; een
   geblokkeerd item dat niet grijs wordt is hooguit een gemiste hint. */
.xaf-sidebar .dxbl-accordion-item-content:not([aria-expanded]):has(.dxbl-group-expand-btn.dxbl-invisible):has(.xaf-navigation-link-click-area:not(.xaf-action)) {
    opacity: .45;
    cursor: default;
}

.xaf-sidebar .dxbl-accordion-item-text-container {
    padding-top: 2px;
    padding-bottom: 2px;
}

/* Voorkom dat de horizontale scrollbar over data records heen valt */
#main-view-content .dxbl-grid {
    min-height: 200px;
}

/* 17px alleen reserveren als er GEEN footer-rij is: anders duwt de padding de sticky footer omhoog
   en zweeft 'ie boven de onderkant. De tfoot wordt alleen gerenderd als de footer zichtbaar is. */
.dxbl-grid .dxbl-scroll-viewer-content:not(:has(tfoot)) {
    padding-bottom: 17px;
}

/* Deze klasse hangt op een <span> BINNEN de cel, niet op de cel zelf — zie
   FormattingListviewViewController. Als pseudo-element op de cel sprong het icoon naar de hoek zodra
   het grid de celinhoud bij selectie in een eigen element zette. Als gewone inline-inhoud loopt het
   mee met de tekst, en de cel behoudt zijn uitlijning (getallen blijven rechts). */
.cell-icon {
    display: inline-block;
    white-space: nowrap;
}

.cell-icon::before {
    vertical-align: middle;
    margin-right: 4px;
}

.green-check::before {
    content: '';
    flex-shrink: 0;
    display: inline-block;
    width: 16px;
    height: 16px;
    background: url('../images/GreenCheck.svg') no-repeat center;
    background-size: contain;
}

.yellow-exclamation::before {
    content: '';
    flex-shrink: 0;
    display: inline-block;
    width: 16px;
    height: 16px;
    background: url('../images/YellowExclamation.svg') no-repeat center;
    background-size: contain;
}

.red-cross::before {
    content: '';
    flex-shrink: 0;
    display: inline-block;
    width: 16px;
    height: 16px;
    background: url('../images/RedCross.svg') no-repeat center;
    background-size: contain;
}

/* Hide custom field layout items when field is not applicable */
.dxbl-fl-item:has(.cf-hidden-field) {
    display: none !important;
}

/* Variety generator popup: beide grids het popup-venster laten vullen i.p.v. auto-groeien (popup is 1200x800) */
.variety-generator-grid {
    height: 640px !important;
}

/* FIFO-indicatie op de ExpiryDate-cel in de Lot picker: bijna verlopen = oranje,
   reeds verlopen = rood. Drempel per Product instelbaar via Product.FifoNearExpiryDays. */
.profix-picker-expiry-soon {
    background-color: #ffe0b2 !important;
    color: #8a4d00 !important;
    font-weight: 600;
}

.profix-picker-expiry-expired {
    background-color: #ffcdd2 !important;
    color: #8a0000 !important;
    font-weight: 600;
}

/* Bulk edit filter editor: text box is read-only unless Advanced Mode is active.
   When advancedMode = false the container lacks the "advanced" CSS class, so
   pointer-events are blocked and the editor looks disabled. When the user checks
   "Advanced Mode" DevExpress adds .advanced to the container, restoring editing.
   Scoped to popup-filter-wrapper so it only applies inside the criteria popup. */
.popup-filter-wrapper .dx-filtereditor-text-container:not(.advanced) {
    pointer-events: none;
    opacity: 0.5;
    cursor: default;
}

/* Bulk edit field validation error: red highlight on Field to Edit and New Value editors.
   .profix-field-error is applied via CssClass on DxComboBox/DxTextBox when IsError=true.
   DxComboBox renders as <dxbl-combo-box class="dxbl-text-edit profix-field-error">
   with <input class="dxbl-text-edit-input"> as a direct child (no .dxbl-text-edit-template
   wrapper in standard mode). DxTextBox renders similarly as <dxbl-input-editor>. */
.profix-field-error > input.dxbl-text-edit-input,
.profix-field-error input.dxbl-text-edit-input,
.profix-field-error > textarea {
    background-color: #FFDDDD !important;
    color: #CC0000 !important;
}
/* Fallback for any template-wrapped mode */
.profix-field-error .dxbl-text-edit-template,
.profix-field-error .dxbl-text-edit-template input {
    background-color: #FFDDDD !important;
    color: #CC0000 !important;
}

/* Tab header indicator when a validation error is hidden behind that tab.
   Applied by ValidationTabHighlightController via profix.markTabsWithErrors(). */
dxbl-tab-item.profix-tab-error {
    border-bottom: 2px solid #CC0000 !important;
}
dxbl-tab-item.profix-tab-error .dxbl-text {
    color: #CC0000 !important;
}



/* ============================================================================
   X Modern — component-classes voor de gemoderniseerde ListViews
   (gerenderd door RelationListViewModernController; werkt in elk theme)
   ============================================================================ */
.pfx-tags { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.pfx-tag {
    display: inline-flex; align-items: center;
    padding: 2px 9px; border-radius: 999px;
    font-size: 11.5px; font-weight: 600; line-height: 1.5; white-space: nowrap;
}
.pfx-tag-customer { background: #E7EFF8; color: #1A4E86; }
.pfx-tag-supplier { background: #E7F4EC; color: #1F7A46; }
.pfx-tag-carrier  { background: #FBF0E1; color: #8A5A16; }
.pfx-tag-grower   { background: #E6F5F3; color: #1F6F63; }
.pfx-tag-prospect { background: #F0EAF9; color: #5B3E9E; }

.pfx-pill {
    display: inline-flex; align-items: center;
    padding: 2px 10px; border-radius: 7px;
    background: #EEF2F6; color: #334155;
    font-size: 11.5px; font-weight: 700;
}

.pfx-name { display: flex; align-items: center; gap: 9px; min-width: 0; }
.pfx-avatar {
    width: 28px; height: 28px; flex: none; border-radius: 8px;
    color: #fff; font-size: 11px; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
}
.pfx-name-text { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pfx-contact { line-height: 1.35; }
.pfx-contact-email { color: #17406B; font-weight: 600; }
.pfx-contact-phone { color: #8A96A5; font-size: 12px; }

/* ---------------------------------------------------------------------------
   Loading-indicator: exact hetzelfde beeld als het splashscreen bij het opstarten
   — het X-logo met een pulserende ring eromheen. Kleuren, maten en timing komen
   uit ProfixSplashScreen.razor, zodat opstarten en laden één geheel zijn.

   XAF rendert dit in LoadingIndicatorComponent (DevExpress.ExpressApp.Blazor):
     <div id="xaf-loading" class="xaf-loading">
       <div class="xaf-loading-content"><div class="spinner-border"></div><span>Loading</span></div>
     </div>
   Alles staat in de light DOM, dus de pill, de tekst en de spinner zijn puur met
   CSS te vervangen. Het voordeel boven een eigen overlay: DevExpress toont de
   indicator pas na 200 ms, dus korte serverrondjes geven geen flits.

   Niet aankomen:
   - visibility op .xaf-loading-content — die zet DevExpress inline en gebruikt
     hij om te tonen/verbergen; overschrijven laat de indicator permanent staan.
   - de class op #xaf-loading — isShowing() vergelijkt className exact, dus een
     extra class laat DevExpress denken dat de indicator uit staat.
   Volgorde: site.css wordt ná het DevExpress-stylesheet geladen, dus gelijke
   specificiteit is genoeg om de spinner-regels te overschrijven.
   --------------------------------------------------------------------------- */

/* De pill eromheen weg: geen kader, geen schaduw, geen achtergrond. De
   achtergrondkleur zet DevExpress inline op de body-kleur — vandaar !important,
   want een inline declaratie wint anders van het stylesheet. */
.xaf-loading-content {
    background: transparent !important;
    border: none;
    box-shadow: none;
    height: auto;
}

/* De tekst "Loading" weg: dat er iets laadt blijkt al uit de vervaagde
   achtergrond en het pulserende logo. */
.xaf-loading-content > span {
    display: none;
}

/* De spinner-div wordt de houder voor ring plus logo. Het logo staat als
   achtergrond op het element zelf, de ring is een ::before — zo pulseert alléén
   de ring en blijft het logo stil staan, net als in het splashscreen. */
.xaf-loading-content .spinner-border {
    position: relative;
    width: 58px;
    height: 58px;
    margin: 0;
    border: none;
    border-radius: 0;
    animation: none;
    background: url('../images/profix-x.svg') center / 26px 26px no-repeat;
}

.xaf-loading-content .spinner-border::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 4px solid rgba(15, 45, 91, 0.2);
    animation: pfx-loader-pulse 1.5s ease-in-out infinite;
}

@keyframes pfx-loader-pulse {
    0%, 100% { transform: scale(0.9); border-color: rgba(15, 45, 91, 0.2); }
    50%      { transform: scale(1.1); border-color: rgba(15, 45, 91, 0.8); }
}

/* Brickx: eigen logo en eigen ringkleur, zelfde als in het splashscreen. */
html[data-pfx-brand="brickx"] .xaf-loading-content .spinner-border {
    background-image: url('../images/brickx-x.svg');
}

html[data-pfx-brand="brickx"] .xaf-loading-content .spinner-border::before {
    animation-name: pfx-loader-pulse-brickx;
}

@keyframes pfx-loader-pulse-brickx {
    0%, 100% { transform: scale(0.9); border-color: rgba(18, 40, 76, 0.2); }
    50%      { transform: scale(1.1); border-color: rgba(18, 40, 76, 0.8); }
}

/* Donker thema: een donkerblauwe ring valt weg tegen een donkere achtergrond.
   Staat ná de brickx-regel, dus geldt voor beide merken in dark mode. */
html[data-pfx-theme="dark"] .xaf-loading-content .spinner-border::before {
    animation-name: pfx-loader-pulse-dark;
}

@keyframes pfx-loader-pulse-dark {
    0%, 100% { transform: scale(0.9); border-color: rgba(255, 255, 255, 0.18); }
    50%      { transform: scale(1.1); border-color: rgba(255, 255, 255, 0.75); }
}

/* Geen schaalanimatie voor wie beweging heeft uitgezet; alleen nog rustig aan/uit. */
@media (prefers-reduced-motion: reduce) {
    .xaf-loading-content .spinner-border::before {
        animation: pfx-loader-fade 2s ease-in-out infinite;
    }

    @keyframes pfx-loader-fade {
        0%, 100% { opacity: 0.45; }
        50%      { opacity: 1; }
    }
}
