﻿/* =====================================================================
   Tender module - shared form / list styling
   Loaded globally from App.razor (dialog content renders outside the
   owning component's scope, so scoped .razor.css would not reach it).
   Every selector is namespaced under .tender-* to keep it off the rest
   of the application.
   ===================================================================== */

.tender-form,
.tender-list-page {
    --tender-accent: #2564cf;
    --tender-accent-soft: #eef5ff;
    --tender-border: #e1e6ec;
    --tender-surface-subtle: #f7f9fc;
    --tender-text: #1f2937;
    --tender-muted: #667085;
}

.tender-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 4px 2px 8px 2px;

    /* The dialog body gives the form a fixed box. Without min-width:0 the
       Fluent web components report their intrinsic width (~280px each) as the
       minimum content size and the whole form grows past the dialog. */
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

/* Same reason, one level down: a grid/flex child defaults to min-width:auto. */
.tender-form *,
.tender-form *::before,
.tender-form *::after {
    box-sizing: border-box;
}

.tender-section,
.tender-grid > *,
.tender-alert-row > * {
    min-width: 0;
}

/* -------------------------------------------------------------------------
   FIELD WRAPPER  (required, not cosmetic)

   This build of Microsoft.FluentUI renders a component's Label as a SIBLING
   <label> element rather than nesting it inside the web component:

       <label for="x">Tender Qty</label>
       <fluent-number-field id="x">

   Dropped straight into a CSS grid that is two grid items, so the label lands
   in one column and its input in the next - which is exactly how the columns
   appeared to "go outside" the form. Every labelled Fluent input in the Tender
   forms is wrapped in .tender-field so the pair counts as one grid item.
   ------------------------------------------------------------------------- */
.tender-field {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 2px;
    min-width: 0;
    max-width: 100%;
}

.tender-field > label {
    font-size: 12px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--neutral-foreground-rest, #242424);
}

/* A wrapper that also spans columns must not collapse its child. */
.tender-span-2 > .tender-field,
.tender-span-full > .tender-field {
    height: 100%;
}

/* -------------------------------------------------------------------------
   DIALOG SHELL

   The Tender forms are taller than any sensible dialog, so the body has to be
   the scroll region - header and footer stay pinned. Without this the content
   simply painted past the bottom edge of the dialog panel.
   ------------------------------------------------------------------------- */
fluent-dialog .tender-form {
    max-width: 100%;
}

/* FluentUI already lays the dialog out as header / body / footer grid rows once
   a FluentDialogBody is present - do NOT override ::part(control) or that
   breaks. What it leaves out is containment: the body is height:auto with
   min-height:80px and no overflow, and the body sits in a `1fr` track whose
   automatic minimum is min-content. Tall content therefore grows the track and
   paints straight past the fixed-height dialog panel.

   min-height:0 lets the track shrink to the panel; overflow-y makes the body
   the scroll region so header and footer stay pinned. */
fluent-dialog .fluent-dialog-body {
    overflow-y: auto;
}

fluent-dialog:has(.tender-form) .fluent-dialog-body {
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding-right: 6px;
}

.tender-dirty-dot {
    color: #d13438;
    margin-left: 6px;
    font-size: 12px;
}

/* ---------- error banner ---------- */

.tender-form-error {
    background: #fdf3f4;
    border: 1px solid #f1bcc0;
    border-left: 4px solid #d13438;
    color: #a4262c;
    border-radius: 6px;
    padding: 8px 12px;
    font-size: 13px;
}

/* ---------- ERP record summary ---------- */

.tender-form-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 14px;
    border: 1px solid #cfe0f5;
    border-left: 4px solid var(--tender-accent);
    border-radius: 8px;
    background: linear-gradient(90deg, var(--tender-accent-soft), #ffffff 72%);
}

.tender-form-summary-main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.tender-form-summary-main strong {
    color: var(--tender-text);
    font-size: 15px;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

.tender-form-summary-main > span:last-child {
    color: var(--tender-muted);
    font-size: 12px;
}

.tender-form-eyebrow {
    color: var(--tender-accent);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.tender-form-summary-badges {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 6px;
}

.tender-summary-chip {
    display: inline-block;
    max-width: 220px;
    padding: 2px 9px;
    overflow: hidden;
    color: #344054;
    background: #ffffff;
    border: 1px solid #d0d5dd;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------- sections ---------- */

.tender-section {
    border: 1px solid var(--tender-border);
    border-radius: 8px;
    padding: 12px 14px 14px 14px;
    background: #fff;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .03);
}

.tender-status-section {
    background: var(--tender-surface-subtle);
}

.tender-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.tender-section-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #4b5563;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.tender-section-head .tender-section-title {
    margin-bottom: 0;
}

.tender-section-actions {
    display: flex;
    gap: 4px;
    margin-bottom: 6px;
}

.tender-count-pill {
    background: #eef2ff;
    color: #3730a3;
    border-radius: 999px;
    padding: 1px 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
}

/* ---------- grids ---------- */

.tender-grid {
    display: grid;
    gap: 12px 14px;
    align-items: end;
}

/* Stretch so a two-line label in one column does not misalign its neighbours. */
.tender-grid > .tender-field,
.tender-grid > .tender-span-2,
.tender-grid > .tender-span-full {
    align-self: stretch;
}

.tender-grid-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.tender-grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.tender-grid-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.tender-span-2 {
    grid-column: span 2;
}

.tender-span-full {
    grid-column: 1 / -1;
}

/* Fluent inputs default to a fixed intrinsic width; force them to fill their
   cell so the grid columns line up and nothing overflows the dialog. */
.tender-form fluent-text-field,
.tender-form fluent-number-field,
.tender-form fluent-select,
.tender-form fluent-text-area,
.tender-form fluent-search,
.tender-form .fluent-input-wrapper,
.tender-form .fluent-popup-root {
    width: 100% !important;
    min-width: 0 !important;
    max-width: 100% !important;
}

.tender-form fluent-text-field::part(root),
.tender-form fluent-number-field::part(root),
.tender-form fluent-select::part(control),
.tender-form fluent-text-area::part(control) {
    width: 100%;
    min-width: 0;
}

/* Tab panels are grid/flex children too. */
.tender-form fluent-tabs,
.tender-form fluent-tab-panel {
    width: 100%;
    min-width: 0;
    max-width: 100%;
}

.tender-form fluent-tab-panel {
    overflow-x: hidden;
    padding-top: 12px;
}

.tender-form fluent-tab-panel > .tender-section + .tender-section {
    margin-top: 12px;
}

/* Long tab strips wrap instead of stretching the dialog. */
.tender-form fluent-tabs::part(tablist) {
    flex-wrap: wrap;
}

/* The dialog is the containing block, so these breakpoints are driven by the
   dialog width via the min(px, vw) sizing the forms request. */
@media (max-width: 1100px) {
    .tender-grid-4 {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 900px) {
    .tender-grid-3,
    .tender-grid-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .tender-span-full {
        grid-column: 1 / -1;
    }
}

@media (max-width: 620px) {
    .tender-grid-2,
    .tender-grid-3,
    .tender-grid-4 {
        grid-template-columns: minmax(0, 1fr);
    }

    .tender-span-2 {
        grid-column: span 1;
    }

    .tender-form-summary {
        align-items: flex-start;
        flex-direction: column;
    }

    .tender-form-summary-badges {
        justify-content: flex-start;
    }
}

/* ---------- documents for dispatch ---------- */

/* GenericPopup's dropdown sizes itself to its widest column, which can reach
   past the right edge of the dialog. Cap it and let the table scroll. */
.tender-form .fluent-popup {
    max-width: min(560px, 88vw);
}

.tender-form .fluent-table-wrapper {
    overflow: auto;
    max-width: 100%;
}

.tender-audit {
    margin-top: 8px;
    font-size: 11px;
    color: #9ca3af;
}

.tender-doc-extra {
    margin-top: 10px;
    padding: 7px 10px;
    color: #475467;
    background: var(--tender-surface-subtle);
    border-left: 3px solid #98a2b3;
    border-radius: 4px;
    font-size: 12px;
}

/* ---------- penalty table ---------- */

.tender-penalty-table {
    width: 100%;

    /* Fixed layout stops the number fields from dictating column widths;
       min-width keeps the row readable and lets the wrapper scroll instead
       of the dialog growing. */
    table-layout: fixed;
    min-width: 660px;

    border-collapse: separate;
    border-spacing: 0;
    font-size: 12px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    overflow: hidden;
}

.tender-penalty-table th:first-child,
.tender-penalty-table td:first-child {
    width: 170px;
}

.tender-penalty-table td fluent-number-field {
    width: 100% !important;
    min-width: 0 !important;
}

.tender-penalty-table th {
    text-align: left;
    background: #f3f4f6;
    color: #4b5563;
    font-weight: 600;
    padding: 7px 10px;
    white-space: nowrap;
}

.tender-penalty-table td {
    padding: 5px 10px;
    border-top: 1px solid #f1f2f4;
    vertical-align: middle;
}

.tender-penalty-table tbody tr:nth-child(even) {
    background: #fbfbfc;
}

.tender-penalty-label {
    font-weight: 600;
    color: #374151;
    white-space: nowrap;
}

.tender-penalty-nil {
    color: #9ca3af;
    font-style: italic;
}

.tender-table-scroll {
    overflow-x: auto;
    max-width: 100%;
    min-width: 0;
}

/* ---------- alert day swatches ---------- */

.tender-alert-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}

.tender-alert-cell {
    border-radius: 6px;
    padding: 8px 10px;
    border: 1px solid transparent;
}

.tender-alert-green  { background: #dcfce7; border-color: #86efac; }
.tender-alert-yellow { background: #fef9c3; border-color: #fde047; }
.tender-alert-orange { background: #ffedd5; border-color: #fdba74; }
.tender-alert-blue   { background: #dbeafe; border-color: #93c5fd; }
.tender-alert-red    { background: #fee2e2; border-color: #fca5a5; }

.tender-alert-caption {
    font-size: 11px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 4px;
}

/* ---------- list page header ---------- */

.tender-context-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding: 10px 16px;
    margin-bottom: 10px;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-left: 4px solid var(--tender-accent);
    border-radius: 8px;
}

.tender-list-page {
    min-width: 0;
}

.tender-list-page .erp-master-page {
    min-width: 0;
}

.tender-context-name {
    font-size: 15px;
    font-weight: 600;
    color: #111827;
}

.tender-context-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    font-size: 12px;
    color: #6b7280;
}

.tender-context-meta strong {
    color: #374151;
}

.tender-context-spacer {
    margin-left: auto;
}

/* -------------------------------------------------------------------------
   GRID ROWS THAT CARRY A MERGED CELL

   IMPORTANT - what the grid actually renders.
   Microsoft.FluentUI 4.x does NOT render <fluent-data-grid> web components.
   FluentDataGrid emits a real  <table class="fluent-data-grid grid">  whose
   thead / tbody / tr are display:contents, so every <td> is a grid item of
   the table itself. Any selector written against fluent-data-grid-row /
   fluent-data-grid-cell (there are some left in app.css and
   MasterListBase.razor.css) matches NOTHING and is dead code - that is why
   the earlier row-height override never took effect.

   The package styles every cell as
       td { padding: 6px 16px; overflow: hidden; text-overflow: ellipsis;
            white-space: nowrap; align-content: center; }
   so a two-line cell is sliced in half: the primary line shows, the second
   one is cut by the row divider.

   Fix: match the real <td>, let it wrap, pin the content to the top of the
   cell and give the cell a min-height. min-height on a grid item feeds the
   row track sizing, so the row is guaranteed to have room for two lines
   instead of relying on the browser measuring wrapped text correctly.
   ------------------------------------------------------------------------- */

.tender-cell-wrap {
    /* two text lines at 1.3 line-height */
    --tender-line: 1.3em;
    --tender-lines: 2;
}

.tender-list-page td:has(.tender-cell-wrap) {
    height: auto !important;
    min-height: 46px;
    white-space: normal !important;
    overflow: hidden;
    text-overflow: clip !important;
    align-content: start !important;
    align-items: start;
    line-height: 1.3;
    vertical-align: top;
}

/* -------------------------------------------------------------------------
   ONE CONTINUOUS ROW DIVIDER

   The package draws the divider as  td { border-bottom }  and the grid host
   is  align-items: center , so every cell is only as tall as its OWN content
   and each one paints its border at a different height: a two-line text cell
   ends 20px lower than the chip cell beside it, and the "row line" comes out
   as a staircase. It also means the hover highlight only covers part of the
   row.

   Stretching the cells to the row track fixes both. This is deliberately a
   plain selector rather than the :has() version below - :has() is a nice to
   have, this has to work everywhere, and stretch is invisible on the
   single-line rows every other module shows.
   ------------------------------------------------------------------------- */
.tender-list-page table.fluent-data-grid,
.tender-list-page table.fluent-data-grid > thead,
.tender-list-page table.fluent-data-grid > tbody {
    align-items: stretch !important;
}

.tender-list-page table.fluent-data-grid td,
.tender-list-page table.fluent-data-grid th {
    align-self: stretch !important;
}

/* -------------------------------------------------------------------------
   THE SAME FIX, WITHOUT DEPENDING ON THE TABLE'S CLASS

   The two blocks above only work if the grid host really carries
   class="fluent-data-grid". Measuring the live page showed it does not take
   effect: every cell WITHOUT a .tender-cell-wrap (select checkbox, Lines,
   Status, Open, Actions) stayed exactly 40px tall inside an 84px row, so each
   painted its border-bottom 44px above the text cells - the staircase divider,
   and the "Status / Open / Actions are out of line" report.

   align-self on the ITEM beats align-items on the container, so the row-scoped
   rule below needs nothing from the table at all: it matches the <tr> that
   carries a merged cell and stretches every one of that row's cells to the
   row track. height:auto is restated because a grid item with a definite
   height cannot stretch - it silently falls back to start.

   Scoped to :has(.tender-cell-wrap) on the ROW, so single-line grids in other
   modules keep the package's centred look.
   ------------------------------------------------------------------------- */
.tender-list-page tr:has(.tender-cell-wrap) > td,
.tender-list-page tr:has(.tender-cell-wrap) > th {
    align-self: stretch !important;
    height: auto !important;
    align-content: start !important;
}

/* The action icons are 23px tall against a ~16px first text line, so a flush
   top would read as 4px low. Centre them inside one line box instead. */
.tender-list-page tr:has(.tender-cell-wrap) > td .erp-row-actions {
    min-height: 1.3em;
    align-items: center;
}

/* The checkbox column is narrow and the package pads every cell 16px on each
   side, so a 42px track left ~10px for a 20px checkbox: it overflowed and
   text-overflow painted an ellipsis next to every checkbox. Give the first
   column its own padding instead of widening the track. */
.tender-list-page table.fluent-data-grid td:first-child,
.tender-list-page table.fluent-data-grid th:first-child {
    padding-left: 10px !important;
    padding-right: 4px !important;
    overflow: visible;
    text-overflow: clip;
}

/* Content stays vertically centred in the now full-height cell (that is the
   package default) - except a multi-line cell, which reads better from the
   top. .tender-cell-wrap fills its cell so the two behave the same way. */
.tender-cell-wrap {
    height: 100%;
    justify-content: flex-start;
}

/* Never let a cell be cut mid-line: clamp it to a whole number of lines and
   ellipsise the rest. The full value stays available through the cell's
   title attribute. */
.tender-cell-strong,
.tender-cell-wrap > span {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
    max-width: 100%;
}

.tender-cell-sub,
.tender-cell-wrap > span.tender-cell-sub {
    -webkit-line-clamp: 1;
    line-clamp: 1;
}

/* A chip is not text - clamping would crop its rounded background. */
.tender-cell-wrap > span.tender-chip {
    display: inline-block;
    overflow: visible;
}

/* ---------- grid cell chips ---------- */

.tender-chip {
    display: inline-block;
    border-radius: 999px;
    padding: 1px 9px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

.tender-chip-active   { background: #dcfce7; color: #166534; }
.tender-chip-inactive { background: #fee2e2; color: #991b1b; }
.tender-chip-count    { background: #eef2ff; color: #3730a3; }
.tender-chip-zero     { background: #f3f4f6; color: #6b7280; }
.tender-chip-expired  { background: #fee2e2; color: #991b1b; }
.tender-chip-soon     { background: #ffedd5; color: #9a3412; }
.tender-chip-ok       { background: #f3f4f6; color: #374151; }

.tender-cell-strong {
    font-weight: 600;
    color: #111827;
}

.tender-cell-sub {
    /* display is set by the clamp rule above - do not reset it to block here,
       that is what re-enabled the mid-line slicing. */
    font-size: 11px;
    color: #6b7280;
}

/* A merged cell holds a primary line and an optional secondary line. Flex
   column keeps them stacked while a chip child still sizes to its own text
   (a block-level chip would stretch to the full column width). */
.tender-cell-wrap {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    white-space: normal;
    line-height: 1.3;
    padding: 2px 0;
}

/* Helpers return "" when there is nothing to say - do not reserve a line. */
.tender-cell-sub:empty,
.tender-cell-wrap > span:empty {
    display: none;
}

.tender-num {
    font-variant-numeric: tabular-nums;
}

.tender-cell-wrap > .tender-num {
    align-self: stretch;
}

/* Chips inside a merged cell sit under their line, not beside it. */
.tender-cell-wrap > .tender-chip {
    margin-top: 1px;
}


/* -------------------------------------------------------------------------
   RICH TEXT EDITOR  (RichTextEditor.razor + js/richTextEditor.js)

   Quill's snow theme ships its own chrome from the CDN stylesheet; these
   rules only make it sit in the Tender dialog like the Fluent inputs around
   it - matching border, radius and label, and a fixed typing height so the
   dialog body stays the single scroll region instead of growing by 400px the
   moment two editors appear.

   --navi-rte-height comes from the component's Height parameter.
   ------------------------------------------------------------------------- */
.tender-form .navi-rte {
    min-width: 0;
    max-width: 100%;

    /* .tender-field bottom-aligns its content so single-line inputs line up
       across a grid row; an editor is a block, so start from the top. */
    justify-content: flex-start;
}

.tender-form .navi-rte > label {
    font-size: 12px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--neutral-foreground-rest, #242424);
}

.tender-form .navi-rte-shell {
    min-width: 0;
    max-width: 100%;
}

.tender-form .navi-rte .ql-toolbar.ql-snow {
    border: 1px solid #d1d5db;
    border-bottom: 0;
    border-radius: 6px 6px 0 0;
    background: #f8f9fa;
    padding: 4px 6px;

    /* The pickers (font, size, colour) drop out of the toolbar absolutely;
       without a stacking context of their own they land behind the editor. */
    position: relative;
    z-index: 3;
}

.tender-form .navi-rte .ql-container.ql-snow {
    /* Quill's core CSS sets .ql-container{height:100%}. The shell is a
       stretched grid item, so 100% resolves to the WHOLE cell and the toolbar
       then pushes the editor 57px past it. Size to .ql-editor instead. */
    height: auto;

    border: 1px solid #d1d5db;
    border-radius: 0 0 6px 6px;
    background: #fff;

    /* Inherit the form's font rather than Quill's Helvetica stack. */
    font-family: inherit;
    font-size: 13px;
}

.tender-form .navi-rte .ql-editor {
    height: var(--navi-rte-height, 190px);
    overflow-y: auto;
    padding: 8px 10px;
}

.tender-form .navi-rte .ql-editor.ql-blank::before {
    font-style: normal;
    color: #9ca3af;
}

/* View mode: no toolbar, and the body reads as a disabled field. */
.tender-form .navi-rte-readonly .ql-toolbar.ql-snow {
    display: none;
}

.tender-form .navi-rte-readonly .ql-container.ql-snow {
    border-radius: 6px;
    background: #f3f4f6;
}
