/* ============================================================
   SHARED COMPONENTS  —  the reusable UI vocabulary of the app:
   page headers, cards, form fields, buttons, detail grids,
   badges and empty states. Built entirely on tokens.css.

   Loaded globally (base.html) AFTER base.css, so it is always
   available — a page never renders "unstyled" for forgetting to
   load a chrome stylesheet. Per-page CSS loads later still (the
   {% block extra_css %} slot), so a genuinely bespoke page can
   override any of these without a specificity fight.

   Canonical values here = the base.css / most-common variant.
   Phase 2 (consistency) tunes them; per-page copies get deleted.
   ============================================================ */

/* ---------- PAGE HEADER ---------- */
.page-header-create,
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 15px;
    padding: 20px 30px;
    border-bottom: 1px solid var(--line);
}

.page-header-create h1,
.page-header h1 {
    font-size: 1.2rem;
    font-weight: bold;
    color: var(--ink);
    margin: 0;
}

/* ---------- DETAIL SUMMARY STRIP ----------
   The identity header for a record detail page: what this record IS
   (its number, large) and what state it is in (a pill), over a row of
   reference metadata. Replaces the older pattern of a tall label/value
   grid that spent ~190px on one line's worth of information.

   Used by the requisition and LPO detail pages. Deliberately NOT
   .lpo-info-container / .info-* — those are still shared by the GRN
   pages and keep their own, taller treatment.

     <section class="detail-summary">
       <div class="detail-summary-top">
         <div>
           <span class="detail-summary-eyebrow">Requisition</span>
           <span class="detail-summary-number">042</span>
         </div>
         <span class="status-pill status-pill--ok">Open</span>
       </div>
       <div class="detail-summary-meta">
         <div>
           <span class="detail-meta-label">Date</span>
           <span class="detail-meta-value">12 Jul 2026</span>
         </div>
         …
       </div>
     </section>
   ---------------------------------------------------------------- */
.detail-summary {
    background-color: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: 18px 24px;
}

.detail-summary-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--line);
}

.detail-summary-eyebrow {
    display: block;
    font-size: 0.68rem;
    font-weight: bold;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 2px;
}

.detail-summary-number {
    display: block;
    font-size: 1.6rem;
    font-weight: bold;
    line-height: 1.1;
    color: var(--blue);
}

/* ---------------------------------------------------------------
   DETAIL PAGE TITLE
   The record's number labels the whole page, so it sits on the
   background ABOVE the summary card rather than inside it. The card
   below is then free to be what it is: the record's facts, not its
   identity.

     <header class="detail-page-title">
       <span class="detail-summary-eyebrow">Local purchase order</span>
       <h1>047</h1>
     </header>
   --------------------------------------------------------------- */
.detail-page-title {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-bottom: -6px;
}

.detail-page-title h1 {
    margin: 0;
    font-size: 1.9rem;
    font-weight: bold;
    letter-spacing: -0.01em;
    color: var(--blue);
}

/* ---------------------------------------------------------------
   SIGNATORIES (prepared by / approved by)
   Opens .detail-summary-top on the detail pages: with the number
   moved out to the page title, accountability is the first thing
   the card says and the paperwork closes it.

   margin-right: auto is what holds that. Without it, space-between
   would push this group toward the middle of the band; the auto
   margin dumps all the free space on its RIGHT instead, so the block
   stays put and only the actions go to the edge. It also means the
   geometry does not shift when the approval half is absent — one
   column or two, nothing else moves.
   --------------------------------------------------------------- */
.detail-signatories {
    display: flex;
    align-items: flex-start;
    gap: 28px;
    margin-right: auto;
}

.detail-signatory {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Names run to a person's full length; without a ceiling a long one drags
       the pill off the band on a mid-width screen. */
    max-width: 180px;
}

.detail-signatory-name {
    font-size: 0.8rem;
    font-weight: bold;
    line-height: 1.3;
    color: var(--ink);
}

/* Not a name — an admission that no name was recorded. Muted so it reads as
   absence rather than as data. */
.detail-signatory-name--unknown { color: var(--muted); font-weight: normal; }

/* When the action happened, not who they are: raised date under the preparer,
   approval date under the approver. */
.detail-signatory-when {
    font-size: 0.72rem;
    line-height: 1.3;
    color: var(--muted);
    margin-top: 1px;
}

/* Narrow screens: .detail-summary-top wraps, and once this group is on its own
   line the auto margin is holding it against nothing. */
@media (max-width: 720px) {
    .detail-signatories {
        margin: 0;
        gap: 20px;
        flex-wrap: wrap;
    }
}

/* Capped column width so the fields group and stay scannable together
   rather than stretching to the far corners of a wide card. */
.detail-summary-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 200px));
    justify-content: start;
    gap: 12px 32px;
    padding-top: 12px;
}

.detail-meta-label {
    display: block;
    font-size: 0.68rem;
    font-weight: bold;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 3px;
}

.detail-meta-value {
    display: block;
    font-size: 0.9rem;
    color: var(--ink);
}

.detail-meta-value a {
    color: var(--blue);
    font-weight: bold;
    text-decoration: none;
}

.detail-meta-value a:hover { text-decoration: underline; }

/* ---------- STATUS PILL ----------
   Tones carry severity, not identity. Where two states share a tone
   (pending and closed are both neutral), the caller's icon is what
   tells them apart — so keep an icon on any neutral pill. */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.72rem;
    font-weight: bold;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 5px 14px;
    border-radius: var(--radius-pill);
    white-space: nowrap;
    background-color: var(--line);
    color: var(--slate);
}

.status-pill--ok      { background-color: var(--green-soft);  color: var(--green-ink); }
.status-pill--warn    { background-color: #fff3e0;            color: #b45309; }
.status-pill--danger  { background-color: var(--danger-soft); color: var(--danger-deep); }
.status-pill--neutral { background-color: var(--line);        color: var(--slate); }

@media (max-width: 600px) {
    .detail-summary { padding: 16px; }
    .detail-summary-number { font-size: 1.35rem; }
    .detail-summary-meta { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- CARD ---------- */
.card {
    background-color: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-md);
    padding: 24px;
    box-shadow: var(--shadow-card);
}

/* ---------- TABLE WRAPPER (padded scroll region for index tables) ---------- */
.table-wrapper {
    padding: 20px 30px;
    overflow-x: auto;
}

/* ---------- FILTER REFUSAL ----------
   Rendered by core/partials/filter_errors.html when a filter form cannot be
   understood. Global rather than per-app because it appears on index pages across
   six apps, which load six different chrome stylesheets.

   --danger, not a series colour: this is a status, and the only status the reader
   needs is "the table below is empty because I could not read your question". */
.filter-errors {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    margin-bottom: 12px;
    padding: 10px 14px;
    border: 1px solid var(--danger);
    /* Tinted, not filled: it explains an empty table, it is not an error state of
       the page itself, and a solid red bar would out-shout the data. */
    border-left-width: 3px;
    border-radius: var(--radius-sm);
    background: var(--danger-soft);
    color: var(--ink);
    font-size: 0.8rem;
    line-height: 1.45;
}

.filter-errors i { color: var(--danger); margin-top: 2px; }
.filter-errors ul { margin: 4px 0 0; padding-left: 18px; }
.filter-errors li { margin-top: 2px; }
.filter-errors__field { font-weight: bold; }

/* ---------- FORM ---------- */
/* Standard form card shell (historically named .gatelog-form-wrapper). */
.gatelog-form-wrapper {
    max-width: 500px;
    width: 100%;
    padding: 30px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 18px;
}

.form-group label {
    font-size: 0.78rem;
    font-weight: bold;
    color: var(--slate);
    text-transform: uppercase;
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    color: var(--ink);
    background: var(--surface);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--green);
    box-shadow: 0 0 0 2px rgba(140, 198, 63, 0.15);
}

/* ---------- BUTTONS ---------- */
.button-group {
    display: flex;
    gap: 12px;
    margin-top: 10px;
}

/* Primary action (green). Aliases cover the names already in use. */
.btn-primary,
.btn-save,
.btn-submit {
    background-color: var(--green);
    color: #fff;
    border: none;
    border-radius: var(--radius-btn);
    padding: 10px 24px;
    font-size: 0.9rem;
    font-weight: bold;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.btn-primary:hover,
.btn-save:hover,
.btn-submit:hover {
    background-color: var(--green-deep);
}

/* Export to a file (Excel). A labelled outline button, deliberately quieter
   than the green create action beside it — exporting is a side errand, not the
   page's primary job. Resets background/border so it can't inherit the native
   grey <button> chrome the old icon-only .btn-xsl showed through. */
.btn-export {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background-color: var(--surface);
    color: var(--slate);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-btn);
    padding: 9px 16px;
    font-size: 0.82rem;
    font-weight: bold;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.btn-export i { font-size: 0.95rem; color: var(--green-ink); }

.btn-export:hover {
    background-color: var(--soft);
    border-color: var(--slate);
    color: var(--ink);
}

/* Secondary / cancel (neutral outline). */
.btn-cancel {
    background-color: var(--surface);
    color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-btn);
    padding: 10px 20px;
    font-size: 0.9rem;
    font-weight: bold;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    transition: opacity 0.2s ease;
}

.btn-cancel:hover {
    opacity: 0.7;
}

/* "New record" pill used on index page headers. */
.btn-new {
    background-color: var(--green);
    color: #fff;
    border: none;
    padding: 8px 20px;
    border-radius: var(--radius-btn);
    font-size: 0.85rem;
    font-weight: bold;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.btn-new:hover {
    background-color: var(--green-deep);
}

/* ---------- DETAIL FIELD (label / value stack) ---------- */
.detail-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px 24px;
    border-bottom: 1px solid var(--line);
}

.detail-label {
    font-size: 0.68rem;
    font-weight: bold;
    text-transform: uppercase;
    color: var(--muted);
}

.detail-value {
    font-size: 0.9rem;
    color: var(--ink);
    font-weight: 500;
}

/* ---------- BADGE / STATUS PILL ---------- */
.badge {
    display: inline-block;
    padding: 3px 11px;
    border-radius: var(--radius-pill);
    font-size: 0.68rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.badge--success { background: var(--green-soft); color: var(--green-ink); }
.badge--danger  { background: var(--danger-soft); color: var(--danger-deep); }
.badge--warning { background: #fff7ed; color: #b45309; }
.badge--info    { background: var(--blue-soft); color: var(--blue); }
.badge--muted   { background: var(--rule); color: var(--slate); }

/* ---------- EMPTY STATE ---------- */
.empty-state {
    text-align: center;
    color: var(--muted);
    font-style: italic;
    padding: 32px;
}

/* ---------- INDEX ROW COUNTER ----------
   The 1,2,3 column down the left of an index table (core.tables.RowNumberColumn).
   As narrow as its digits and set in the muted tone: it answers "how far down the
   list am I", and it must never be the first thing the eye lands on in a row whose
   subject is the record beside it. Tabular figures so the digits stay in column. */
/* An explicit width, not the usual `width: 1%` shrink trick: #table-container sets
   table-layout: fixed, which honours the declared width literally and would crush the
   cell inside its own padding. 56px carries 24px of that padding plus four digits. */
.col-rownum {
    width: 56px;
    white-space: nowrap;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

td.col-rownum {
    color: var(--muted);
    font-size: 0.76rem;
}
