﻿/* Whatever reason, don't put custom styles at the end of this file. They must go here */

/* The row last edited on another page (?lastEdited=<id> on the way back, ReturnNavigation.MarkClass). */
tr.last-edited > td {
    background-color: #e6f4ff !important;
    box-shadow: inset 0 1px 0 #91caff, inset 0 -1px 0 #91caff;
}

body.dark tr.last-edited > td {
    background-color: #111d2c !important;
    box-shadow: inset 0 1px 0 #15417e, inset 0 -1px 0 #15417e;
}

/* Native browser UI follows the theme: scrollbars (the Workbench scrolls in three columns),
   text-field carets and default form controls. Without it they stay light on a dark page. */
body.dark {
    color-scheme: dark;
}

body.light,
body:not(.dark):not(.light) {
    color-scheme: light;
}

/* Theme-based pre element styling */
body.dark .pre-themed {
    background-color: #1f1f1f;
    color: #d4d4d4;
    border: 1px solid #333;
    padding: 12px;
    border-radius: 4px;
    box-shadow: 0 1px 2px -2px rgba(255, 255, 255, 0.16), 0 3px 6px 0 rgba(255, 255, 255, 0.12), 0 5px 12px 4px rgba(255, 255, 255, 0.09);
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

body.light .pre-themed, 
body:not(.dark):not(.light) .pre-themed {
    background-color: #f6f8fa;
    color: #24292e;
    border: 1px solid #e1e4e8;
    padding: 12px;
    border-radius: 4px;
    box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09);
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
/* stylelint-disable no-duplicate-selectors */
/* stylelint-disable */
/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */

/* Ticket System */

.fill-width {
    flex-grow: 1;
}

.fill-width.fx-5 {
    max-width: 20%;
}

.fill-width.fx-3 {
    max-width: 33%;
}

.float-right {
    float: right;
}

.ticket-meta {
    display: flex;
    gap: 5px;
    margin-bottom: 10px;
    flex-wrap: wrap;
    position: relative;
}

.ticket-meta > div {
    margin-right: 15px;
}

    .task-card {
        position: relative;
        margin-bottom: 10px;
    }

    /* Dark mode: subtle border for task cards */
    body.dark .task-card .ant-card {
        border-color: rgba(255, 255, 255, 0.1);
    }

.ticket-list-item {
    border: 1px solid #f0f0f0;
    border-bottom: 1px solid #f0f0f0 !important;
    padding: 10px;
    margin-bottom: 10px;
    position: relative;
}

/* Dark mode: subtle border for ticket list items */
body.dark .ticket-list-item {
    border-color: rgba(255, 255, 255, 0.1) !important;
}

        .ticket-list-item .ant-btn-dangerous  {
            position: absolute;
            right: 10px;
            top: 10px;
        }

            .ticket-list-item:hover {
                cursor: pointer;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            }

    .ticket-description {
        font-size: 16px;
        color: #808080;
    }

.ticket-assignee-photo {
    display: inline-block;
    width: 20px;
    height: 20px;
    border-radius: 100%;
    position: relative;
    bottom: 2px;
    margin-right: 5px;
}

    .ticket-assignee-photo.faded {
        background: #d7d7d7;
    }

.ant-select-selector .ticket-assignee {
    position: relative;
    top: 4px;
}

.task-card .ant-card-head-title {
    white-space: unset !important;
}

.task-card .ant-btn-dangerous {
    margin-left: 0 !important;
}

/* Ticket/task board (BoardColumn.razor): every column scrolls on its own and virtualizes its
   cards. A card slot has a fixed height that is also the Virtualize ItemSize, so the card
   content is clamped to fit; the full content is on the detail page. */
/* The column width comes from the flex row only: without the containment the nowrap card lines
   (e.g. a long "Leistung positions" list) raise the min-content width of the column and of every
   ancestor, widening the whole page. */
.board-column {
    contain: inline-size;
    min-width: 0;
}

.board-column > .ant-card-body {
    padding: 12px;
}

/* Long titles wrap instead of hiding the item count behind an ellipsis. */
.board-column > .ant-card-head .ant-card-head-title {
    white-space: normal;
}

/* A server-loaded card that has not arrived yet (BoardColumn LoadPage mode). */
.board-card-placeholder {
    height: 100%;
    border: 1px solid #f0f0f0;
    border-radius: 8px;
    background: linear-gradient(90deg, rgba(0, 0, 0, 0.04) 25%, rgba(0, 0, 0, 0.08) 37%, rgba(0, 0, 0, 0.04) 63%);
    background-size: 400% 100%;
    animation: board-card-placeholder 1.4s ease infinite;
}

body.dark .board-card-placeholder {
    border-color: rgba(255, 255, 255, 0.1);
    background-image: linear-gradient(90deg, rgba(255, 255, 255, 0.04) 25%, rgba(255, 255, 255, 0.08) 37%, rgba(255, 255, 255, 0.04) 63%);
}

@keyframes board-card-placeholder {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* The columns take the viewport height minus what the page shows above (and below) them: --board-offset, set by a
   page with a smaller head (the order board, .order-page). */
.board-column-scroll {
    max-height: calc(100vh - var(--board-offset, 340px));
    min-height: 300px;
    overflow-x: hidden;
    overflow-y: auto;
}

/* Kanban drag and drop (KanbanBoard.razor): a drop column fills its height so the whole column
   accepts a card; while dragging, the cards ignore the pointer so dragenter/dragleave only fire
   for the column itself. */
.board-column-drop {
    min-height: calc(100vh - var(--board-offset, 340px));
    border-radius: 8px;
    transition: background-color .1s ease-in-out;
}

.board-column-drop-active {
    background-color: rgba(22, 119, 255, 0.08);
    outline: 2px dashed #1677ff;
    outline-offset: -2px;
}

.kanban-dragging .board-column-scroll * {
    pointer-events: none;
}

.kanban-card {
    height: 100%;
    cursor: grab;
}

.kanban-card:active {
    cursor: grabbing;
}

.kanban-card.kanban-card-locked,
.kanban-card.kanban-card-locked:active {
    cursor: pointer;
}

/* Where a dragged card would land (KanbanBoard with Reorder): placed by KanbanBoard.razor.js in the gap between two cards
   of the column under the pointer; the column is its containing block and scrolls it with the cards. */
.board-column-drop[data-kanban-column] {
    position: relative;
}

.kanban-drop-indicator {
    display: none;
    position: absolute;
    left: 2px;
    right: 2px;
    height: 3px;
    border-radius: 2px;
    background: #1677ff;
    z-index: 2;
    pointer-events: none;
}

/* Hosts a board inside the page container: width 0 keeps the columns from widening the page (the AntD Pro
   page container is a flex item with min-width:auto), min-width 100% gives the board the full width to scroll in. */
.board-scroll-host {
    width: 0;
    min-width: 100%;
}

/* Order board page (OrderBoard.razor): its head has two rows, so the columns start higher; their heads are smaller
   and take one line also for "Warte auf Rückmeldung", so the cards of all columns start at the same height. */
.order-page {
    --board-offset: 270px;
}

.order-page .board-column > .ant-card-head {
    min-height: 44px;
    padding: 0 12px;
}

.order-page .board-column > .ant-card-head .ant-card-head-title {
    padding: 10px 0;
    font-size: 14px;
}

/* Order board card (OrderCard.razor) — fixed slot height BoardCardHeights.Order. */
.order-card {
    position: relative;
    box-sizing: border-box;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 10px 8px 14px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
    cursor: pointer;
}

.order-card:hover {
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12);
}

body.dark .order-card {
    background: #1f1f1f;
    border-color: #424242;
}

/* The assignee's colour as a stripe on the left (clipped by the rounded card); nobody: a dashed grey stripe. */
.order-card-assigned::before,
.order-card-unassigned::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 5px;
}

.order-card-assigned::before {
    background: var(--assignee-color);
}

.order-card-unassigned::before {
    background: repeating-linear-gradient(to bottom, #bfbfbf 0 6px, transparent 6px 11px);
}

body.dark .order-card-unassigned::before {
    background: repeating-linear-gradient(to bottom, #5c5c5c 0 6px, transparent 6px 11px);
}

/* Open longer than 10 / 14 days (OrderAge): a subtle yellow / red tint, also on the list rows. */
.order-card.order-card-age-warn {
    background: #fffbeb;
    border-color: #fcd34d;
}

.order-card.order-card-age-alert {
    background: #fef2f2;
    border-color: #fca5a5;
}

body.dark .order-card.order-card-age-warn {
    background: rgba(250, 204, 21, 0.07);
    border-color: rgba(250, 204, 21, 0.38);
}

body.dark .order-card.order-card-age-alert {
    background: rgba(248, 113, 113, 0.09);
    border-color: rgba(248, 113, 113, 0.45);
}

.order-card-age-warn .order-age-text,
.order-row-age-warn .order-age-text {
    color: #b45309;
}

.order-card-age-alert .order-age-text,
.order-row-age-alert .order-age-text {
    color: #dc2626;
}

body.dark .order-card-age-warn .order-age-text,
body.dark .order-row-age-warn .order-age-text {
    color: #fcd34d;
}

body.dark .order-card-age-alert .order-age-text,
body.dark .order-row-age-alert .order-age-text {
    color: #fca5a5;
}

/* The age steps in the filter (OrderBoard.razor): the dot shows the marking of an open order of that age. */
.order-age-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 100%;
    vertical-align: middle;
    background: #d9d9d9;
}

.order-age-dot.order-age-dot-warn {
    background: #f59e0b;
}

.order-age-dot.order-age-dot-alert {
    background: #ef4444;
}

body.dark .order-age-dot {
    background: #595959;
}

body.dark .order-age-dot.order-age-dot-warn {
    background: #fcd34d;
}

body.dark .order-age-dot.order-age-dot-alert {
    background: #fca5a5;
}

.order-row-age-warn > td {
    background-color: #fffbeb;
}

.order-row-age-alert > td {
    background-color: #fef2f2;
}

body.dark .order-row-age-warn > td {
    background-color: rgba(250, 204, 21, 0.06);
}

body.dark .order-row-age-alert > td {
    background-color: rgba(248, 113, 113, 0.08);
}

/* After the tints: the selected card stays blue in both modes. */
.order-card.order-card-selected,
body.dark .order-card.order-card-selected {
    border-color: #1677ff;
    box-shadow: 0 0 0 2px rgba(22, 119, 255, 0.25);
}

.order-card-title {
    font-weight: 600;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* Assignee colours (AssigneeColors, AssigneeAvatar Colored): mid tones on light, lighter tones on dark; no red or yellow,
   which mark old orders and priorities. */
.assignee-c0 { --assignee-color: #2563eb; }
.assignee-c1 { --assignee-color: #16a34a; }
.assignee-c2 { --assignee-color: #9333ea; }
.assignee-c3 { --assignee-color: #db2777; }
.assignee-c4 { --assignee-color: #0891b2; }
.assignee-c5 { --assignee-color: #65a30d; }
.assignee-c6 { --assignee-color: #4338ca; }
.assignee-c7 { --assignee-color: #c026d3; }
.assignee-c8 { --assignee-color: #0f766e; }
.assignee-c9 { --assignee-color: #92400e; }

body.dark .assignee-c0 { --assignee-color: #60a5fa; }
body.dark .assignee-c1 { --assignee-color: #4ade80; }
body.dark .assignee-c2 { --assignee-color: #c084fc; }
body.dark .assignee-c3 { --assignee-color: #f472b6; }
body.dark .assignee-c4 { --assignee-color: #22d3ee; }
body.dark .assignee-c5 { --assignee-color: #a3e635; }
body.dark .assignee-c6 { --assignee-color: #818cf8; }
body.dark .assignee-c7 { --assignee-color: #e879f9; }
body.dark .assignee-c8 { --assignee-color: #2dd4bf; }
body.dark .assignee-c9 { --assignee-color: #d6a16b; }

/* Same box as .ticket-assignee-photo: a circle with the initials in the user's colour, or dashed for nobody. */
.assignee-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    border-radius: 100%;
    position: relative;
    bottom: 1px;
    margin-right: 5px;
    vertical-align: middle;
    font-size: 9px;
    font-weight: 700;
    line-height: 1;
    color: #fff;
    background: var(--assignee-color);
}

body.dark .assignee-badge {
    color: #141414;
}

.assignee-badge.assignee-none {
    background: transparent;
    border: 1.5px dashed #a3a3a3;
}

body.dark .assignee-badge.assignee-none {
    border-color: #6b6b6b;
}

.assignee-none-text {
    font-style: italic;
}

.ticket-assignee-photo.assignee-ring {
    box-shadow: 0 0 0 2px var(--assignee-color);
}

/* The "Fertig" question (OrderFertigContent): AntDesign's confirm is 416 px wide (inline style), too narrow for its
   three buttons in one row. */
.ant-modal.ant-modal-confirm:has(.order-fertig) {
    width: 580px !important;
    max-width: calc(100vw - 32px);
}

/* Read-only facts in the order detail drawer. */
.order-facts td {
    padding: 3px 0;
    vertical-align: top;
}

.order-facts td:first-child {
    width: 11rem;
    color: #6b7280;
}

/* Data tables of the order board pages: the tbl utility only draws the borders. Utilities on a
   cell (text-right, ...) still win — Tailwind is imported as important. */
.order-table th,
.order-table td {
    padding: 4px 8px;
    vertical-align: top;
}

.order-table th {
    text-align: left;
}

/* The gap between cards is padding inside the slot: margins between virtualized items would
   distort the Virtualize spacer measurement. */
.board-card-slot {
    box-sizing: border-box;
    padding-bottom: 10px;
    overflow: hidden;
}

.board-card-slot > .task-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    margin-bottom: 0;
}

.board-card > .ant-card-head {
    flex: none;
    min-height: 0;
    padding: 0 12px;
}

.board-card > .ant-card-head .ant-card-head-title {
    padding: 8px 0;
}

.board-card > .ant-card-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    padding: 12px;
}

.board-card .board-last-comment > .ant-card-head {
    min-height: 0;
    padding: 0 8px;
}

.board-card .board-last-comment > .ant-card-head .ant-card-head-title {
    padding: 4px 0;
}

.board-card .board-last-comment > .ant-card-body {
    padding: 8px;
}

.board-card .ant-card-head-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    white-space: normal !important;
}

.board-card .ticket-meta {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
}

.board-card .ticket-meta > div {
    margin-right: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-card .board-desc,
.board-card .board-last-comment p {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    margin-bottom: 8px;
}

.board-card .board-last-comment .ant-card-head-title {
    -webkit-line-clamp: 1;
}

.import-file-select {
    padding: 5px;
    border: 1px solid #e5e7eb;
}

.flex.align-center {
    align-items: center;
}