﻿/* The line-item sheet shared by every financial document editor.
   ---------------------------------------------------------------------------------------------
   Borderless cells and hairline rules, so a dense document reads like a spreadsheet instead of a
   stack of boxed inputs. Every colour comes from a Tabler variable with a fallback, so the sheet
   follows the light/dark theme without a second palette.

   This is a GLOBAL stylesheet rather than a component's scoped one, on purpose: the sheet is drawn
   by each editor's own markup, and a scoped file only reaches the component that owns it. It also
   means no `::deep` - a global rule already matches the controls that FormattedInput, Typeahead and
   the pickers render inside a cell.

   `.inv-sheet` is the supplier invoice's original class, carried alongside `.doc-sheet` so the page
   that this pattern came from keeps working while the rest of the family adopts the new name. */

.doc-sheet,
.inv-sheet {
    --doc-rule: var(--tblr-border-color, #e2e8f0);
    --doc-muted: var(--tblr-secondary-color, #64748b);
    table-layout: auto;
    font-variant-numeric: tabular-nums;
    margin-bottom: 0;
}

.doc-sheet thead th,
.inv-sheet thead th {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--doc-muted);
    border-bottom: 2px solid var(--doc-rule);
    padding: 0 0.5rem 0.5rem;
    white-space: nowrap;
}

/* Two digits is all the row number ever needs. `width` alone is only a suggestion under
   table-layout: auto, so a crowded sheet squeezed this column to 27px on the supplier invoice while
   a roomier one kept the full 36px - the same column, two widths, on pages meant to look alike. */
.doc-sheet .doc-col-no,
.doc-sheet .inv-col-no,
.inv-sheet .inv-col-no {
    width: 2.25rem;
    min-width: 2.25rem;
    text-align: right;
    color: var(--doc-muted);
    font-size: 0.8125rem;
}

.doc-sheet .doc-col-type,
.doc-sheet .inv-col-type,
.inv-sheet .inv-col-type {
    width: 6.5rem;
    min-width: 6.5rem;
}

.doc-sheet tbody td,
.inv-sheet tbody td {
    border-bottom: 1px solid var(--doc-rule);
    border-top: 0;
    vertical-align: middle;
    padding: 0.15rem 0.5rem;
}

/* The hairline between columns is what makes it read as a sheet rather than a list. */
.doc-sheet tbody td + td,
.doc-sheet thead th + th,
.inv-sheet tbody td + td,
.inv-sheet thead th + th {
    border-left: 1px solid var(--doc-rule);
}

/* Inputs lose their own frame inside the sheet and fill the cell; the ring comes back on focus,
   drawn inside the cell so nothing reflows as you tab across.

   The !important is not decoration: FormattedInput tags its input with Bootstrap's `border-info`
   utility, and every Bootstrap border utility carries !important, so a plain border-color here
   loses to it. This only re-colours the ones inside a sheet; the controls keep their own look
   everywhere else on the page. */
.doc-sheet tbody td .form-control,
.doc-sheet tbody td .form-select,
.inv-sheet tbody td .form-control,
.inv-sheet tbody td .form-select {
    border-color: transparent !important;
    /* Square, and flush inside the cell's own padding. Bootstrap's 8px radius drew a pill floating
       9px inside the cell on every side, which is the one thing a spreadsheet never looks like. */
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    padding-left: 0;
    padding-right: 0;
}

/* The control keeps no frame of its own on focus either - the cell takes that job below. */
.doc-sheet tbody td .form-control:focus,
.doc-sheet tbody td .form-select:focus,
.inv-sheet tbody td .form-control:focus,
.inv-sheet tbody td .form-select:focus {
    border-color: transparent !important;
    background: transparent;
    box-shadow: none;
}

/* A faint ring on the cell under the pointer says which cells take typing, without drawing a
   control that is not there. */
.doc-sheet tbody td:hover:has(input, select, textarea),
.inv-sheet tbody td:hover:has(input, select, textarea) {
    box-shadow: inset 0 0 0 1px var(--doc-rule);
}

/* The active cell, the way a spreadsheet draws it: the ring belongs to the cell, not to a control
   inside it. Inset so it stays within the cell rather than spilling onto its neighbour, square
   because a sheet has no rounded cells, and 2px so the active cell is obvious at a glance.

   It comes after the hover rule so focus wins while the pointer is still over the cell. */
.doc-sheet tbody td:has(input:focus),
.doc-sheet tbody td:has(select:focus),
.doc-sheet tbody td:has(textarea:focus),
.inv-sheet tbody td:has(input:focus),
.inv-sheet tbody td:has(select:focus),
.inv-sheet tbody td:has(textarea:focus) {
    box-shadow: inset 0 0 0 2px var(--tblr-primary, #206bc4);
}

/* The pickers' own wrappers add margin the sheet does not want. */
.doc-sheet tbody td .form-group,
.doc-sheet tbody td .mb-3,
.inv-sheet tbody td .form-group,
.inv-sheet tbody td .mb-3 {
    margin-bottom: 0 !important;
}

/* The item picker is a Typeahead: an .input-group-flat holding a .form-control and an
   .input-group-text with the clear/search glyph. Left alone it is a 39px control with 9px of vertical
   padding and a bordered 37px button on the end - a form field parked in a cell. In a sheet the cell
   IS the field, so the group loses its frame and the glyph shrinks to something you notice only when
   you want it. */
.doc-sheet tbody td .input-group,
.doc-sheet tbody td .input-group-flat,
.inv-sheet tbody td .input-group,
.inv-sheet tbody td .input-group-flat {
    flex-wrap: nowrap;
    /* The group is a control in its own right, with its own 8px radius, and Tabler rings it on
       :focus-within with a 4px halo. Stripping the inner .form-control was never going to reach
       either: what showed inside the cell was the group's rounded corner and its glow, not the
       input's. In a sheet the cell is the field, so the group draws nothing at all. */
    border-radius: 0;
    background: transparent;
}

.doc-sheet tbody td .input-group:focus-within,
.doc-sheet tbody td .input-group-flat:focus-within,
.inv-sheet tbody td .input-group:focus-within,
.inv-sheet tbody td .input-group-flat:focus-within {
    box-shadow: none;
    border-color: transparent;
    outline: 0;
}

.doc-sheet tbody td .form-control,
.doc-sheet tbody td .input-group-text,
.inv-sheet tbody td .form-control,
.inv-sheet tbody td .input-group-text {
    min-height: 0;
    height: auto;
    padding-top: 0.15rem;
    padding-bottom: 0.15rem;
    line-height: 1.35;
    font-size: 0.8125rem;
}

.doc-sheet tbody td .input-group-text,
.inv-sheet tbody td .input-group-text {
    padding-right: 0.25rem;
    padding-left: 0.15rem;
    margin-left: 0;
    border-color: transparent !important;
    background: transparent;
    color: var(--doc-muted);
    opacity: 0.55;
}

.doc-sheet tbody tr:hover td .input-group-text,
.inv-sheet tbody tr:hover td .input-group-text {
    opacity: 1;
}

.doc-sheet tbody td .input-group-text svg,
.doc-sheet tbody td .input-group-text i,
.inv-sheet tbody td .input-group-text svg,
.inv-sheet tbody td .input-group-text i {
    width: 0.875rem;
    height: 0.875rem;
    font-size: 0.875rem;
}

/* The type badge and the account sub-line set the row height once the controls stop doing it. */
.doc-sheet tbody td .text-muted,
.inv-sheet tbody td .text-muted {
    font-size: 0.6875rem;
}

.doc-type-badge,
.inv-type-badge {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: 0.2rem 0.45rem;
}

/* Semi-transparent fills read correctly in both themes; the text colour is the darker shade so it
   stays legible on a light card. */
.doc-type-goods,
.inv-type-goods {
    background: rgba(32, 107, 196, 0.15);
    color: #1c5aa6;
}

.doc-type-cogs,
.inv-type-cogs {
    background: rgba(12, 166, 120, 0.15);
    color: #047857;
}

.doc-type-expenses,
.inv-type-expenses {
    background: rgba(247, 103, 7, 0.15);
    color: #b45309;
}

.doc-type-asset,
.inv-type-asset {
    background: rgba(174, 62, 201, 0.15);
    color: #8a31a1;
}

.doc-type-untyped,
.inv-type-untyped {
    background: rgba(214, 57, 57, 0.15);
    color: #b02a2a;
}

/* The trailing blanks: present, tabbable, and visibly not part of the document yet. */
.doc-blank-row td,
.inv-blank-row td {
    background: transparent;
}

.doc-dash,
.inv-dash {
    color: var(--doc-muted);
    opacity: 0.45;
}

.doc-blank-row:hover td,
.inv-blank-row:hover td {
    background: var(--tblr-bg-surface-secondary, #f8fafc);
}

.doc-sheet-footnote,
.inv-sheet-footnote {
    margin-top: 0.5rem;
    padding: 0.4rem 0.5rem;
    font-size: 0.75rem;
    color: var(--tblr-secondary-color, #64748b);
    border-top: 1px solid var(--tblr-border-color, #e2e8f0);
}

.doc-sheet-footnote kbd,
.inv-sheet-footnote kbd {
    font-size: 0.6875rem;
    padding: 0.1rem 0.3rem;
}

/* The essentials pair up two to a row with the label above the field, which is what stops a
   three-column label gutter eating the width of a narrow column. */
.doc-form-stacked .form-group.row {
    display: block;
    margin-left: 0;
    margin-right: 0;
    margin-bottom: 0.75rem;
}

.doc-form-stacked .form-group.row > label {
    display: block;
    width: 100%;
    padding: 0 0 0.25rem;
    font-size: 0.75rem;
}

.doc-form-stacked .form-group.row > div[class*="col-"] {
    width: 100%;
    flex: 0 0 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
}

.doc-essentials {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 1rem;
}

@media (max-width: 575.98px) {
    .doc-essentials {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* An invitation to finish something, as distinct from a panel's own action. Tabler has no dashed
   border utility, and a solid outline here read as a second primary button beside Record. */
.border-dashed {
    border-style: dashed !important;
}

/* A hint worth one sentence, kept out of the column's rhythm. The stacked form is a run of short
   label-and-field rows, and a line of grey prose under one of them breaks that run for something
   most people read once and never again. */
/* `.required::after` draws the asterisk at the very end of the label, so an inline "?" button lands
   between the name and the star: "Supplier Reference ? *". Making the label a flex line lets the
   button take the last place instead, and the star stays beside the word it qualifies. */
.doc-form-stacked .form-group.row > label:has(.doc-help) {
    display: flex;
    align-items: center;
}

.doc-help {
    order: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    margin-left: 0.3125rem;
    padding: 0;
    border: 1px solid var(--tblr-border-color, #e5e7eb);
    border-radius: 999px;
    background: transparent;
    color: var(--tblr-secondary, #667382);
    font-size: 0.625rem;
    font-weight: 600;
    line-height: 1;
    vertical-align: text-top;
    cursor: help;
}

.doc-help:hover {
    border-color: var(--tblr-primary, #206bc4);
    color: var(--tblr-primary, #206bc4);
}

/* Whether the document is backed by a validated e-Invoice: a state in words, then what can be done
   about it. Three bare icons said neither. */
.doc-einvoice {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.doc-einvoice-state {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
}

.doc-einvoice-state .ti {
    font-size: 1rem;
}

.doc-einvoice-state.is-matched {
    color: var(--tblr-green, #2fb344);
}

.doc-einvoice-state.is-missing {
    color: var(--tblr-secondary, #667382);
}

/* The other half of the masthead: the band under the title, carrying whoever the document is with
   and what it is worth. It lives here rather than in DocumentPartyChip's scoped stylesheet because
   the masthead is one thing and its two halves belong in one file - and because a document with no
   counterparty (a journal entry has none) still wants the band, and scoped CSS would not reach the
   markup such a page writes for itself. */
.doc-summary {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    /* Same surface and the same 20px inset as the title above it and the cards below, so the whole
       column shares one left edge. Closed with a rule, which is what separates the masthead from the
       form - without it the chip and the tiles just float in the gap. */
    padding: 0.875rem calc(1.25rem + 1px);
    margin-bottom: 1rem;
    background: var(--tblr-bg-surface, #fff);
    border-bottom: 1px solid var(--tblr-border-color, #e5e7eb);
}

@media (max-width: 991.98px) {
    .doc-summary {
        flex-wrap: wrap;
        align-items: flex-start;
        gap: 0.75rem;
    }
}

/* The masthead is its own register: the title and the summary band share one surface, lifted off the
   page, and the form cards start below it. `:has(.doc-summary)` scopes that to the document editors -
   .page-header is Tabler's and every other page in the app uses it too.

   The inline padding is the point. A panel with a background needs its content held off the edge, and
   20px is what every card on the page already uses - so the title, the supplier and the first card's
   heading all land on the same line, and the masthead reads as part of the same column rather than a
   panel that forgot its margins. The extra pixel is the card's border: a card insets its content by
   its border plus its padding, and without it the masthead sits one pixel to the left of every
   heading below it.

   `.mb-3` on the header is a Bootstrap utility, so it carries `!important` and a plain declaration
   loses to it - the gap it leaves would split the masthead in two. */
.container-xl:has(.doc-summary) > .page-header {
    padding: 0.75rem calc(1.25rem + 1px);
    margin-bottom: 0 !important;
    background: var(--tblr-bg-surface, #fff);
    border-bottom: 1px solid var(--tblr-border-color, #e5e7eb);
}

/* A field and the single control that acts on it, sharing one line. The field takes what is left
   after the control, and `min-width: 0` lets it actually shrink - a flex item defaults to its
   content's width, which would push the control off the end of a long supplier name. */
.doc-field-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.doc-field-row > :first-child {
    flex: 1 1 auto;
    min-width: 0;
}
