﻿/* ==========================================================================
   FMT internal application styling.

   Layered on top of bootstrap.css, which is kept only for its grid and form
   structure -- everything visual below overrides it. No build step, no CDN:
   this file is served straight through the existing ASP.NET style bundle.

   Organised as: tokens -> base -> layout -> components -> utilities.
   ========================================================================== */

/* --------------------------------------------------------------- tokens -- */
:root {
    --bg:            #f5f6f8;
    --surface:       #ffffff;
    --surface-alt:   #fafbfc;
    --border:        #e2e5ea;
    --border-strong: #cbd1d9;

    --text:          #1c2430;
    --text-muted:    #667085;
    --text-subtle:   #8b94a3;

    --brand:         #1f5fa9;
    --brand-hover:   #17497f;
    --brand-soft:    #e8f0fa;

    --ok:            #1a7f52;
    --ok-soft:       #e3f4ec;
    --warn:          #9a6206;
    --warn-soft:     #fdf1dc;
    --danger:        #b3261e;
    --danger-soft:   #fbe9e8;
    --info:          #1f5fa9;
    --info-soft:     #e8f0fa;
    --neutral-soft:  #eef0f3;

    --radius:        8px;
    --radius-sm:     5px;
    --shadow:        0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .08);
    --shadow-lg:     0 4px 12px rgba(16, 24, 40, .1);

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --mono: "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg:            #14171c;
        --surface:       #1b1f26;
        --surface-alt:   #21262e;
        --border:        #2c333d;
        --border-strong: #3a424e;

        --text:          #e6e9ef;
        --text-muted:    #9aa4b2;
        --text-subtle:   #7c8695;

        --brand:         #6ba5e7;
        --brand-hover:   #8fbcef;
        --brand-soft:    #1c2c3f;

        --ok:            #5cc08d;
        --ok-soft:       #16301f;
        --warn:          #e0a63f;
        --warn-soft:     #33270e;
        --danger:        #ef7b72;
        --danger-soft:   #351a19;
        --info:          #6ba5e7;
        --info-soft:     #1c2c3f;
        --neutral-soft:  #262c35;

        --shadow:        0 1px 2px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .35);
        --shadow-lg:     0 4px 14px rgba(0, 0, 0, .45);
    }
}

/* ----------------------------------------------------------------- base -- */
html, body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;

    /* Site.css (the stock MVC template) sets body { padding-top: 50px } to clear
       Bootstrap's fixed navbar. That navbar is gone, so the padding just leaves
       an empty strip above the app. Cleared here rather than by editing
       Site.css, which the auth views still rely on. */
    margin: 0;
    padding: 0;
}

body.body-content, .body-content { padding-top: 0; }

a { color: var(--brand); text-decoration: none; }
a:hover, a:focus { color: var(--brand-hover); text-decoration: underline; }

h1, h2, h3, h4, h5 { color: var(--text); font-weight: 600; margin-top: 0; }
h1 { font-size: 22px; letter-spacing: -.01em; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }

hr { border-color: var(--border); }
code, pre, .mono { font-family: var(--mono); }

/* --------------------------------------------------------------- layout -- */
.app-shell { display: flex; min-height: 100vh; }

/* Impersonation banner. Spans the full width above the shell so the mode is
   impossible to mistake for normal use. */
.impersonation-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 9px 20px;
    background: var(--warn-soft);
    border-bottom: 2px solid var(--warn);
    color: var(--warn);
    font-size: 13px;
    font-weight: 500;
}
.impersonation-bar .impersonation-text { flex: 1 1 auto; min-width: 0; }
.impersonation-bar form { margin: 0; }
.impersonation-bar .btn { border-color: var(--warn); color: var(--warn); background: var(--surface); }
.impersonation-bar .btn:hover { background: var(--surface-alt); border-color: var(--warn); }


.app-nav {
    width: 216px;
    flex: 0 0 216px;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.app-brand {
    padding: 18px 18px 14px;
    border-bottom: 1px solid var(--border);
}
.app-brand a { color: var(--text); font-weight: 700; font-size: 15px; letter-spacing: -.01em; }
.app-brand a:hover { text-decoration: none; color: var(--brand); }
.app-brand small { display: block; color: var(--text-subtle); font-size: 11px; font-weight: 500; margin-top: 2px; }

.app-nav-group { padding: 14px 10px 4px; }
.app-nav-group-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--text-subtle);
    padding: 0 8px 6px;
}

.app-nav a.nav-item {
    display: block;
    padding: 7px 10px;
    margin-bottom: 1px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-weight: 500;
    font-size: 13.5px;
}
.app-nav a.nav-item:hover { background: var(--surface-alt); color: var(--text); text-decoration: none; }
.app-nav a.nav-item.active { background: var(--brand-soft); color: var(--brand); font-weight: 600; }

.app-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

/* Top bar: the screen's own header on the left, the signed-in account pinned
   to the right. The bar owns the bottom border so the two halves cannot
   disagree about it. */
.app-topbar {
    display: flex;
    align-items: stretch;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}
.app-topbar-main { flex: 1 1 auto; min-width: 0; }
.app-topbar .app-header { border-bottom: 0; }

.app-user {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 20px;
    border-left: 1px solid var(--border);
}
.app-user form { margin: 0; }
.app-user-id { text-align: right; line-height: 1.3; }
.app-user-id .who {
    display: block;
    color: var(--text);
    font-weight: 600;
    font-size: 13px;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.app-user-id .roles {
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-subtle);
}

.app-header {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}
.app-header h1 { margin: 0; }
.app-header .spacer { flex: 1 1 auto; }

@media (max-width: 760px) {
    /* Stack rather than squeeze the title against the account block. */
    .app-topbar { flex-direction: column; align-items: stretch; }
    .app-user {
        border-left: 0;
        border-top: 1px solid var(--border);
        padding: 10px 16px;
        justify-content: flex-end;
    }
}

.app-body { padding: 20px 24px 48px; }

.breadcrumbs { font-size: 12.5px; color: var(--text-subtle); margin-bottom: 4px; }
.breadcrumbs a { color: var(--text-muted); }
.breadcrumbs span.sep { padding: 0 6px; color: var(--border-strong); }

@media (max-width: 900px) {
    .app-shell { flex-direction: column; }
    .app-nav { width: auto; flex: none; height: auto; position: static; border-right: 0; border-bottom: 1px solid var(--border); }
    .app-nav-group { display: flex; flex-wrap: wrap; gap: 4px; }
    .app-nav-group-label { width: 100%; }
    .app-body { padding: 16px; }
}

/* ------------------------------------------------------------------ card -- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin-bottom: 18px;
}
.card-head {
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
}
.card-head h2, .card-head h3 { margin: 0; font-size: 14px; font-weight: 600; }
.card-head .spacer { flex: 1 1 auto; }
.card-body { padding: 16px; }
.card-body.tight { padding: 0; }
.card-foot {
    padding: 10px 16px;
    border-top: 1px solid var(--border);
    background: var(--surface-alt);
    border-radius: 0 0 var(--radius) var(--radius);
    font-size: 12.5px;
}
/* Save / Cancel sit together at the end of a form. */
.card-foot.form-actions { display: flex; align-items: center; gap: 8px; padding: 12px 16px; }

/* ----------------------------------------------------------------- stats -- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: 12px;
    margin-bottom: 18px;
}
.stat {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    box-shadow: var(--shadow);
}
.stat .label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-subtle);
}
.stat .value { font-size: 26px; font-weight: 700; letter-spacing: -.02em; margin-top: 4px; }
.stat .sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.stat.is-warn .value { color: var(--warn); }
.stat.is-danger .value { color: var(--danger); }
.stat.is-ok .value { color: var(--ok); }
a.stat:hover { text-decoration: none; border-color: var(--border-strong); box-shadow: var(--shadow-lg); }
a.stat:hover .value { color: var(--brand); }

/* ------------------------------------------------- troubleshooting page -- */
.env-strip {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 16px;
    font-size: 13px;
    color: var(--text-muted);
}
.env-strip strong { color: var(--text); font-variant-numeric: tabular-nums; }
.env-strip .sep { color: var(--border-strong); }

.shortcut-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 12px;
    margin-bottom: 18px;
}
.shortcut {
    display: block;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    box-shadow: var(--shadow);
    color: inherit;
}
a.shortcut:hover {
    text-decoration: none;
    border-color: var(--brand);
    box-shadow: var(--shadow-lg);
}
a.shortcut:hover .shortcut-title { color: var(--brand); }
.shortcut-title { font-weight: 600; font-size: 14px; margin-bottom: 3px; }
.shortcut-sub { font-size: 12.5px; color: var(--text-muted); }
/* An unconfigured link is shown, not hidden, so it is obvious it needs setting. */
.shortcut.is-empty { border-style: dashed; }
.shortcut.is-empty .shortcut-title { color: var(--text-subtle); }

.env-list { font-size: 12.5px; line-height: 1.7; margin-top: 4px; }
.env-list .env-key {
    display: inline-block;
    min-width: 78px;
    color: var(--text-subtle);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* ---------------------------------------------------------------- tables -- */
.table-wrap { overflow-x: auto; }

table.data {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}
table.data th {
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-subtle);
    padding: 9px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-alt);
    white-space: nowrap;
}
table.data td {
    padding: 9px 12px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}
table.data tbody tr:hover { background: var(--surface-alt); }

/* Sortable headers. The link fills the cell so the whole header is clickable. */
table.data th a.sort-link {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: -9px -12px;
    padding: 9px 12px;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    white-space: nowrap;
}
table.data th a.sort-link:hover { color: var(--text); text-decoration: none; background: var(--neutral-soft); }
table.data th.num a.sort-link { justify-content: flex-end; }
table.data th.sorted { color: var(--brand); }
table.data th.sorted a.sort-link { color: var(--brand); }
.sort-arrow { font-size: 9px; line-height: 1; opacity: .9; }
/* Reserve the arrow's width so headers do not shift when sorting changes. */
table.data th a.sort-link .sort-arrow { min-width: 7px; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.nowrap, table.data th.nowrap { white-space: nowrap; }
table.data .primary-cell { font-weight: 600; }

.empty {
    padding: 32px 16px;
    text-align: center;
    color: var(--text-subtle);
    font-size: 13px;
}

/* ----------------------------------------------------------- definition -- */
.def-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 2px 20px;
}
.def {
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
    min-width: 0;
}
.def dt {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-subtle);
}
.def dd {
    margin: 2px 0 0;
    font-size: 13.5px;
    word-break: break-word;
}
.def dd.empty-val { color: var(--text-subtle); font-style: italic; }

/* ---------------------------------------------------------------- chips -- */
.chip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 100px;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    background: var(--neutral-soft);
    color: var(--text-muted);
}
.chip.ok      { background: var(--ok-soft);     color: var(--ok); }
.chip.warn    { background: var(--warn-soft);   color: var(--warn); }
.chip.danger  { background: var(--danger-soft); color: var(--danger); }
.chip.info    { background: var(--info-soft);   color: var(--info); }

/* ------------------------------------------------------------- progress -- */
.progress-track {
    height: 6px;
    background: var(--neutral-soft);
    border-radius: 100px;
    overflow: hidden;
    min-width: 70px;
}
.progress-fill { height: 100%; background: var(--brand); border-radius: 100px; }
.progress-fill.ok { background: var(--ok); }

.bar-row { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.bar-row .bar-label { flex: 0 0 190px; font-size: 12.5px; color: var(--text-muted); }
.bar-row .bar-track { flex: 1 1 auto; height: 18px; background: var(--surface-alt); border-radius: var(--radius-sm); overflow: hidden; }
.bar-row .bar-fill { height: 100%; background: var(--brand); border-radius: var(--radius-sm); min-width: 2px; }
.bar-row .bar-count { flex: 0 0 40px; text-align: right; font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- timeline -- */
.timeline { list-style: none; padding: 0; margin: 0; }
.timeline li {
    position: relative;
    padding: 0 0 16px 26px;
    border-left: 2px solid var(--border);
    margin-left: 7px;
}
/* The rail connects one step to the next, so the last step has none.
   Written with the state class rather than as a bare :last-child: that reads
   as (0,2,1), exactly the same specificity as `.timeline li.done` below, which
   sets the same property and wins on source order. The result was a green tail
   hanging off a completed final step, but only when it was complete, which is
   why it showed on the art track and not the list track. */
.timeline li:last-child,
.timeline li.done:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li .dot {
    position: absolute;
    left: -8px;
    top: 1px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--border-strong);
}
.timeline li.done { border-left-color: var(--ok); }
.timeline li.done .dot { background: var(--ok); border-color: var(--ok); }
.timeline li.current .dot { background: var(--warn); border-color: var(--warn); box-shadow: 0 0 0 4px var(--warn-soft); }
.timeline .stage-name { font-weight: 600; font-size: 13.5px; }
.timeline .stage-meta { font-size: 12px; color: var(--text-muted); }
.timeline li.pending .stage-name { color: var(--text-subtle); font-weight: 500; }

/* Skipped: no date recorded, but the job has demonstrably moved past it.
   Distinct from pending, which is still genuinely ahead of the job. */
.timeline li.skipped .stage-name { color: var(--text-subtle); font-weight: 500; }
.timeline li.skipped .stage-meta { color: var(--warn); font-style: italic; }
.timeline li.skipped .dot {
    background: var(--surface);
    border-color: var(--warn);
    border-style: dotted;
}

/* Parallel: steps that are independent of one another rather than a sequence.
   The connecting rail is what says "this follows that", so it comes off, and
   the steps sit side by side instead of stacking. Production works this way --
   print, sample ship and mail drop happen in whatever order the plant works in,
   and a job may ship no samples at all. */
.timeline.parallel {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 4px 18px;
}
.timeline.parallel li {
    border-left: none;
    margin-left: 0;
    padding: 0 0 10px 22px;
}
.timeline.parallel li .dot { left: 0; }

/* Two intake tracks shown side by side. */
.track-split { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 620px) { .track-split { grid-template-columns: 1fr; } }
.track-head {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 10px;
}

/* --------------------------------------------------------------- forms -- */
.toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

input[type="text"], input[type="search"], input[type="password"],
input[type="email"], input[type="number"], select, textarea {
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    color: var(--text);
    padding: 6px 10px;
    font-size: 13.5px;
    font-family: inherit;
    height: auto;
    box-shadow: none;
    max-width: 100%;
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}
label { font-size: 12px; font-weight: 600; color: var(--text-muted); margin-bottom: 3px; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px 16px;
}
.field { display: flex; flex-direction: column; min-width: 0; }
.field.wide { grid-column: 1 / -1; }
.field .hint { font-size: 11.5px; color: var(--text-subtle); margin-top: 3px; }
.field-error { color: var(--danger); font-size: 12px; margin-top: 3px; display: block; }

.checkbox-row { display: flex; align-items: center; gap: 7px; padding: 5px 0; }
.checkbox-row label { margin: 0; font-weight: 500; font-size: 13.5px; color: var(--text); }

.fieldset-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-subtle);
    margin: 20px 0 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.fieldset-title:first-child { margin-top: 0; }

/* -------------------------------------------------------------- buttons -- */
.btn, a.btn, button.btn {
    display: inline-block;
    padding: 6px 13px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text);
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    line-height: 1.5;
    text-shadow: none;
    box-shadow: none;
}
.btn:hover, a.btn:hover { background: var(--surface-alt); color: var(--text); text-decoration: none; border-color: var(--text-subtle); }
.btn:focus { outline: none; box-shadow: 0 0 0 3px var(--brand-soft); }

.btn.primary, a.btn.primary {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
}
.btn.primary:hover, a.btn.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: #fff; }

.btn.danger, a.btn.danger { color: var(--danger); border-color: var(--danger); background: var(--surface); }
.btn.danger:hover { background: var(--danger-soft); color: var(--danger); }

.btn.sm { padding: 3px 9px; font-size: 12px; }
.btn.link { border-color: transparent; background: transparent; color: var(--brand); }
.btn.link:hover { background: var(--brand-soft); border-color: transparent; }

/* ------------------------------------------------------------------ docs -- */
/* Multi-column flow rather than a grid. Grid rows align to the tallest card,
   which leaves ragged gaps under the short ones; columns let each card pack
   against the one above it. Capped at two columns so the measure stays
   readable on a wide monitor. */
.doc {
    columns: 440px 2;
    column-gap: 18px;
}
.doc .card {
    /* Keep a card whole rather than splitting it across a column break. */
    break-inside: avoid;
    page-break-inside: avoid;
    display: inline-block;
    width: 100%;
    margin-top: 0;
}
@media (max-width: 900px) { .doc { columns: 1; } }
.doc p { font-size: 13.5px; line-height: 1.65; }
.doc ul, .doc ol { font-size: 13.5px; line-height: 1.7; padding-left: 20px; margin: 0 0 12px; }
.doc li { margin-bottom: 4px; }
.doc .card-body > p:first-child { margin-top: 0; }
.doc .card-body > p:last-child { margin-bottom: 0; }

.doc-list { margin: 0; font-size: 13.5px; }
.doc-list dt {
    font-weight: 600;
    color: var(--text);
    margin-top: 14px;
}
.doc-list dt:first-child { margin-top: 0; }
.doc-list dd {
    margin: 3px 0 0;
    color: var(--text-muted);
    line-height: 1.6;
}

/* The bit someone will regret not reading. */
.consequence-note {
    background: var(--warn-soft);
    border-left: 3px solid var(--warn);
    color: var(--warn);
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    font-weight: 500;
}

/* --------------------------------------------------------------- modal -- */
/* Prefixed on purpose. Bootstrap 3 is still loaded and defines .modal with
   display:none plus .modal-backdrop; sharing those names left the box
   permanently invisible while the backdrop rendered fine. */
.fmt-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 900;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(16, 24, 40, .5);
}
.fmt-modal-backdrop[hidden] { display: none; }

.fmt-modal {
    width: 100%;
    max-width: 470px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.fmt-modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 20px 0;
}
.fmt-modal-head h2 { margin: 0; font-size: 16px; }
.fmt-modal-body { padding: 12px 20px 18px; }
.fmt-modal-body p { margin: 0 0 10px; font-size: 13.5px; }
.fmt-modal-body p:last-child { margin-bottom: 0; }
.fmt-modal-body .consequence {
    background: var(--warn-soft);
    border-left: 3px solid var(--warn);
    color: var(--warn);
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    font-weight: 500;
}
.fmt-modal-foot {
    display: flex;
    gap: 8px;
    padding: 12px 20px;
    border-top: 1px solid var(--border);
    background: var(--surface-alt);
}

/* --------------------------------------------------------------- alerts -- */
.flash {
    padding: 10px 14px;
    border-radius: var(--radius-sm);
    margin-bottom: 16px;
    font-size: 13.5px;
    font-weight: 500;
    border: 1px solid transparent;
}
.flash.ok     { background: var(--ok-soft);     color: var(--ok);     border-color: var(--ok); }
.flash.warn   { background: var(--warn-soft);   color: var(--warn);   border-color: var(--warn); }
.flash.danger { background: var(--danger-soft); color: var(--danger); border-color: var(--danger); }
.flash.info   { background: var(--info-soft);   color: var(--info);   border-color: var(--info); }

.validation-summary-errors { color: var(--danger); font-size: 13px; }
.validation-summary-errors ul { padding-left: 18px; margin: 0; }

/* ------------------------------------------------------------ pagination -- */
.pager {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 4px 0;
    font-size: 13px;
    color: var(--text-muted);
}
.pager .spacer { flex: 1 1 auto; }
.pager strong { color: var(--text); font-variant-numeric: tabular-nums; }

.pager-pages, .pager-size { display: flex; align-items: center; gap: 3px; }
.pager-size { gap: 3px; margin-left: 4px; }

.pager .page-link {
    display: inline-block;
    min-width: 30px;
    padding: 4px 8px;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.4;
}
a.page-link:hover {
    background: var(--surface-alt);
    border-color: var(--border-strong);
    color: var(--text);
    text-decoration: none;
}
.pager .page-link.current {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
}
.pager .page-link.disabled { opacity: .4; cursor: default; }
.pager .page-gap { padding: 0 2px; color: var(--text-subtle); }

@media (max-width: 760px) {
    .pager { gap: 8px; }
    .pager-range { width: 100%; }
}

/* ----------------------------------------------------------- log viewer -- */
.log-view {
    background: #0f1319;
    color: #d5dae2;
    border-radius: var(--radius-sm);
    padding: 12px 14px;
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1.55;
    max-height: 640px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}
.log-view .line { display: block; padding: 1px 0; border-radius: 2px; }
.log-view .line.error { color: #ff9d94; background: rgba(179, 38, 30, .14); }
.log-view .line.warn  { color: #ffcf7a; }
.log-view .line.info  { color: #9fb4cc; }

/* -------------------------------------------------------- proof viewer -- */
.proof-frame {
    width: 100%;
    height: 76vh;
    min-height: 440px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
}
.proof-split { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 1100px) { .proof-split { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------ utilities -- */
.muted    { color: var(--text-muted); }
.subtle   { color: var(--text-subtle); }
.small    { font-size: 12px; }
.strong   { font-weight: 600; }
.nowrap   { white-space: nowrap; }
.right    { text-align: right; }
.mt0 { margin-top: 0; }  .mt8 { margin-top: 8px; }  .mt16 { margin-top: 16px; }
.mb0 { margin-bottom: 0; } .mb8 { margin-bottom: 8px; } .mb16 { margin-bottom: 16px; }
.row-actions { display: flex; gap: 6px; align-items: center; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 1000px) { .grid-2 { grid-template-columns: 1fr; } }

/* Bootstrap 3's fixed-width container fights the sidebar shell; the layout
   below supplies its own padding. Left as an override rather than editing
   bootstrap.css so the vendored file stays pristine. */
.container, .container-fluid { width: auto; max-width: none; padding: 0; margin: 0; }
.body-content { padding: 0; }

/* Auth screens still carry Bootstrap 3 form markup. */
.form-horizontal .control-label { text-align: left; padding-top: 7px; }
.form-control { width: 100%; }
.auth-shell { max-width: 380px; margin: 8vh auto; }
.auth-shell .card-body { padding: 24px; }
.auth-shell h1 { font-size: 19px; margin-bottom: 4px; }
.auth-shell .lead { font-size: 13px; color: var(--text-muted); margin-bottom: 18px; }
